Skip to content

Commit

Permalink
Update date component
Browse files Browse the repository at this point in the history
  • Loading branch information
OksanaTC committed Apr 3, 2024
1 parent d6dc8e8 commit 38007fc
Show file tree
Hide file tree
Showing 8 changed files with 257 additions and 36 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "13.8.5",
"version": "13.9.5",
"license": "MIT",
"main": "dist/cjs/index.js",
"module": "dist/esm/index.js",
Expand Down
3 changes: 3 additions & 0 deletions src/components/data-grid/DataGrid.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export default {
} as Meta;

const Template: Story<DataGridProps> = (args) => {
const [dates, setDates] = useState([new Date()]);
const [views, setViews] = useState<DataGridView[]>([
{
id: '1',
Expand Down Expand Up @@ -119,6 +120,8 @@ const Template: Story<DataGridProps> = (args) => {
onCreateView={(input: CreateViewInput) => handleCreateView(input)}
onSaveViewState={(id: string, viewState: string) => handleSaveView(id, viewState)}
onReady={(data) => console.log(data)}
dates={dates}
setDates={setDates}
/>
);
};
Expand Down
2 changes: 1 addition & 1 deletion src/components/data-grid/defaultFormatSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { FormatSettings } from './types';
export const defaultFormatSettings: FormatSettings = {
timeFormat: 'HH:mm',
durationFormat: 'HH:mm',
dateFormat: 'DD/MM/YYYY',
dateFormat: 'dd/MM/yyyy',
currency: 'USD',
numberFormat: NumberFormat.Dot,
language: 'en',
Expand Down
38 changes: 5 additions & 33 deletions src/components/data-grid/filters/ColumnFilters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import { Dropdown, DropdownItem } from '../../dropdown';
import { MinusIcon } from '../../icons/minus';
import { AddLineIcon } from '../../icons/add-line';
import { useTheme } from '../../../providers';
import { DatepickerPopover } from '../../datepicker-popover';
import { FilterButton } from './FilterButton';
import { Button } from '../../button';
import { ButtonKind } from '../../../models';
import { ParagraphSmall } from 'baseui/typography';
import { FixedSizeSelect } from '../../fixed-size-select';
import { MultiFilter } from './MultiFilter';
import { CustomDatepicker } from 'components/datepicker';

const LESS_FILTERS_BUTTON_TEST_ID = 'less-filters-button';
const MORE_FILTERS_BUTTON_TEST_ID = 'more-filters-button';
Expand All @@ -38,7 +38,6 @@ export const ColumnFilters = ({
onShowLessFiltersChange,
}: ColumnFiltersProps) => {
const [showLessFilters, setShowLessFilters] = useState<boolean>(initialShowLessFilters ?? true);
const [datepickerIsOpen, setDatepickerIsOpen] = useState<boolean>(false);
const [internalDates, setInternalDates] = useState<Date[]>([]);

const {
Expand Down Expand Up @@ -107,12 +106,8 @@ export const ColumnFilters = ({
[filterOnValue, isSelectValueActive],
);

const dateFilterIsActive = () => dates?.length === 2;

const isSetFilterActive = (columnField: string) => !!selectedFilterIds[columnField]?.length;

const getDateIconColor = () => (dateFilterIsActive() ? primary : contentSecondary);

const getSetIconColor = (columnField: string) => (isSetFilterActive(columnField) ? primary : contentSecondary);

const getSelectActiveItem = (columnField: string, values?: string[] | FilterValue[]) => {
Expand All @@ -135,11 +130,6 @@ export const ColumnFilters = ({
};
};

const getDateTitleFormat = (date: Date) => new TcDate(date).format(dateFormat);

const getDateTitle = (title: string) =>
dates && dateFilterIsActive() ? `${getDateTitleFormat(dates[0])} - ${getDateTitleFormat(dates[1])}` : title;

const getSetTitle = (columnField: string, title: string) => {
if (!isSetFilterActive(columnField)) {
return title;
Expand All @@ -148,14 +138,6 @@ export const ColumnFilters = ({
return `${length} ${title}`;
};

const toggleDatePicker = () => {
if (datepickerIsOpen) {
setDatepickerIsOpen(false);
return setInternalDates([]);
}
return setDatepickerIsOpen(true);
};

const onDateSelect = ({ date: selectedDates, columnField }: { date: Date | Date[]; columnField: string }) => {
if (!setDates) {
return;
Expand All @@ -169,7 +151,7 @@ export const ColumnFilters = ({

if (selectedDates.length > 1) {
setDates(selectedDates);
toggleDatePicker();
// toggleDatePicker();
filterOnDate(columnField, selectedDates);
}
};
Expand Down Expand Up @@ -240,23 +222,13 @@ export const ColumnFilters = ({
const filterTypes = {
[FilterType.date]: (
<>
<FilterButton
onClick={() => setDatepickerIsOpen(!datepickerIsOpen)}
startEnhancer={Icon && <Icon color={getDateIconColor()} />}
size={SIZE.compact}
title={getDateTitle(title)}
arrows
/>
<DatepickerPopover
<CustomDatepicker
onChange={(date) => onDateSelect({ date, columnField })}
date={internalDates.length ? internalDates : dates}
isOpen={datepickerIsOpen}
setIsOpen={toggleDatePicker}
monthsShown={2}
range
quickSelect
locale={locale}
range
translations={datepickerTranslations}
dateFormat={dateFormat}
/>
</>
),
Expand Down
31 changes: 31 additions & 0 deletions src/components/datepicker/CustomDatepicker.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';
import { Story, Meta } from '@storybook/react/types-6-0';

import { TcDate } from '@timechimp/timechimp-typescript-helpers';
import { CustomDatepicker } from './CustomDatepicker';
import { CustomDatepickerProps } from './types';

export default {
title: 'Components/CustomDatepicker',
component: CustomDatepicker,
} as Meta;

let isOpen = true;

const Template: Story<CustomDatepickerProps> = (args) => {
const [date, setDate] = React.useState<[Date, Date]>([
new TcDate().startOf('month').toDate(),
new TcDate().endOf('month').toDate(),
]);

return <CustomDatepicker {...args} date={date} onChange={(date) => setDate(date as [Date, Date])} />;
};

export const Default = Template.bind({});
Default.args = {
placement: 'bottomLeft',
date: [new TcDate().startOf('month').toDate(), new TcDate().endOf('month').toDate()],
isOpen: true,
setIsOpen: () => (isOpen = !isOpen),
quickSelect: true,
};
202 changes: 202 additions & 0 deletions src/components/datepicker/CustomDatepicker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
import React, { useEffect, useMemo, useState } from 'react';
import { useTheme } from '../../providers';
import { TcDate } from '@timechimp/timechimp-typescript-helpers';
import { DatepickerOption } from '../datepicker-popover/types';
import { SingleSelect } from 'components/select';
import { Datepicker } from 'components/datepicker/Datepicker';
import { FlexItem } from 'components/flex-item';
import { Block } from 'baseui/block';
import { CustomDatepickerProps } from './types';

export const CustomDatepicker = ({ date, translations, onChange, dateFormat, ...rest }: CustomDatepickerProps) => {
const [isDatepickerOpen, setIsDatepickerOpen] = useState(false);
const [value, setValue] = useState([new Date()]);

const {
theme: {
current: {
sizing: { scale200, scale300, scale4800 },
customSizing: { scale6000 },
},
},
} = useTheme();

const quickSelectOptions: DatepickerOption[] = [
{
id: translations?.allPeriods ?? 'All periods',
beginDate: new TcDate().subtract(1, 'year').startOf('year').toDate(),
endDate: new TcDate().endOf('year').toDate(),
},
{
id: translations?.today ?? 'Today',
beginDate: new Date(),
endDate: new Date(),
},
{
id: translations?.yesterday ?? 'Yesterday',
beginDate: new TcDate().subtract(1, 'day').toDate(),
endDate: new TcDate().subtract(1, 'day').toDate(),
},
{
id: translations?.thisWeek ?? 'This week',
beginDate: new TcDate().startOf('week', 1).getDateWithoutTimeAsUTC(),
endDate: new TcDate().endOf('week', 1).getDateWithoutTimeAsUTC(),
},
{
id: translations?.thisMonth ?? 'This month',
beginDate: new TcDate().startOf('month').toDate(),
endDate: new TcDate().endOf('month').toDate(),
},
{
id: translations?.thisQuarter ?? 'This quarter',
beginDate: new TcDate().startOf('quarter').toDate(),
endDate: new TcDate().endOf('quarter').toDate(),
},
{
id: translations?.thisYear ?? 'This year',
beginDate: new TcDate().startOf('year').toDate(),
endDate: new TcDate().endOf('year').toDate(),
},
{
id: translations?.previousWeek ?? 'Previous week',
beginDate: new TcDate().subtract(1, 'week').startOf('week', 1).toDate(),
endDate: new TcDate().subtract(1, 'week').endOf('week', 1).toDate(),
},
{
id: translations?.previousMonth ?? 'Previous month',
beginDate: new TcDate().subtract(1, 'month').startOf('month').toDate(),
endDate: new TcDate().subtract(1, 'month').endOf('month').toDate(),
},
{
id: translations?.previousQuarter ?? 'Previous quarter',
beginDate: new TcDate().subtract(1, 'quarter').startOf('quarter').toDate(),
endDate: new TcDate().subtract(1, 'quarter').endOf('quarter').toDate(),
},
{
id: translations?.previousYear ?? 'Previous year',
beginDate: new TcDate().subtract(1, 'year').startOf('year').toDate(),
endDate: new TcDate().subtract(1, 'year').endOf('year').toDate(),
},
{ id: translations?.custom ?? 'Custom' },
];

const isSameDates = (option: DatepickerOption, _date: Date[]) => {
const selectedBeginDate = _date[0];
const selectedEndDate = _date[1];
const optionBeginDate = new TcDate(option.beginDate);
const optionEndDate = new TcDate(option.endDate);

return optionBeginDate.isSame(selectedBeginDate, 'day') && optionEndDate.isSame(selectedEndDate, 'day');
};

const isSameSingleDate = (option: DatepickerOption, _date: Date) => {
const selectedDate = _date;
const optionBeginDate = new TcDate(option.beginDate);

return optionBeginDate.isSame(selectedDate, 'day');
};

useEffect(() => {
if (!date) {
return;
}

let quickSelectOption;

if (!Array.isArray(date)) {
quickSelectOption = quickSelectOptions.find((option) => isSameSingleDate(option, date));
} else {
quickSelectOption = quickSelectOptions.find((option) => isSameDates(option, date));
}

if (quickSelectOption) {
return;
}

setIsDatepickerOpen(true);

if (Array.isArray(date)) {
setValue(date);
return;
}

setValue([date]);
}, [date]);

const isDateInQuickSelectOptions = useMemo(() => {
if (!date) {
return false;
}

if (!Array.isArray(date)) {
return quickSelectOptions.some((option) => isSameSingleDate(option, date));
}
return quickSelectOptions.some((option) => isSameDates(option, date));
}, [date, quickSelectOptions]);

const quickSelectValue = useMemo(() => {
if (!date) {
return undefined;
}

if (!isDateInQuickSelectOptions) {
return quickSelectOptions.find((option) => option.id === 'Custom');
}

if (!Array.isArray(date)) {
const quickSelectOption = quickSelectOptions.find((option) => isSameSingleDate(option, date));
return quickSelectOption;
}

const quickSelectOption = quickSelectOptions.find((option) => isSameDates(option, date));
return quickSelectOption;
}, [date, quickSelectOptions, isDateInQuickSelectOptions]);

const handleQuickOptionsClick = (value: DatepickerOption | null) => {
if (!value) {
return;
}

if (value.id === 'Custom') {
setIsDatepickerOpen(true);
} else {
setIsDatepickerOpen(false);
onChange([value.beginDate, value.endDate]);
}
};

const handleDateClick = (date: Date[]) => {
if (date.length > 1) {
onChange(date);
return;
}

setValue(date);
};

return (
<FlexItem width="auto">
<Block flex={1} paddingTop={scale200} paddingRight={scale300} minWidth={scale4800}>
<SingleSelect
defaultValue={quickSelectValue || quickSelectOptions[0]}
valueKey="id"
labelKey="id"
disableSortOptions
options={quickSelectOptions}
onChange={handleQuickOptionsClick}
/>
</Block>
{isDatepickerOpen && (
<Block flex={1} paddingTop={scale200} paddingRight={scale300} minWidth={scale6000}>
<Datepicker
{...rest}
range
customValue={value || [new Date()]}
onChange={({ date }) => handleDateClick(date)}
formatString={dateFormat}
/>
</Block>
)}
</FlexItem>
);
};
1 change: 1 addition & 0 deletions src/components/datepicker/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './Datepicker';
export * from './DatePickerTemplate';
export * from './types';
export * from './CustomDatepicker';
Loading

0 comments on commit 38007fc

Please sign in to comment.