Skip to content

Commit f0e92a9

Browse files
committed
feat: implement date range filter on crud module
1 parent f61aeb9 commit f0e92a9

File tree

4 files changed

+76
-7
lines changed

4 files changed

+76
-7
lines changed

packages/react-material-ui/src/components/DateRangePicker/index.tsx

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import React, { useState, useRef, FieldsetHTMLAttributes } from 'react';
1+
import React, {
2+
useState,
3+
useRef,
4+
useEffect,
5+
FieldsetHTMLAttributes,
6+
} from 'react';
27
import {
38
Box,
49
Popover,
@@ -35,7 +40,7 @@ import ChevronRight from '@mui/icons-material/ChevronRight';
3540
import DateInput from './DateInput';
3641
import { CustomCalendarHeaderRoot } from './styles';
3742

38-
interface DateRange {
43+
export interface DateRange {
3944
startDate: Date | null;
4045
endDate: Date | null;
4146
}
@@ -46,7 +51,9 @@ enum DateSelectionMode {
4651
}
4752

4853
export type DateRangePickerProps = {
54+
type?: string;
4955
label?: string;
56+
value?: DateRange;
5057
sx?: SxProps;
5158
error?: string;
5259
onRangeUpdate?: (range: DateRange) => void;
@@ -55,6 +62,7 @@ export type DateRangePickerProps = {
5562
const DateRangePicker = ({
5663
label,
5764
error,
65+
value,
5866
onRangeUpdate,
5967
...props
6068
}: DateRangePickerProps) => {
@@ -203,6 +211,30 @@ const DateRangePicker = ({
203211
}
204212
};
205213

214+
useEffect(() => {
215+
if (value?.startDate && !startDateInputValue) {
216+
setStartDateInputValue(format(value.startDate, 'yyyy-MM-dd'));
217+
}
218+
219+
if (value?.startDate && !dateRange.startDate) {
220+
setDateRange({
221+
...dateRange,
222+
startDate: new Date(value.startDate),
223+
});
224+
}
225+
226+
if (value?.endDate && !endDateInputValue) {
227+
setEndDateInputValue(format(value.endDate, 'yyyy-MM-dd'));
228+
}
229+
230+
if (value?.endDate && !dateRange.endDate) {
231+
setDateRange({
232+
...dateRange,
233+
endDate: new Date(value.endDate),
234+
});
235+
}
236+
}, [value, dateRange]);
237+
206238
const renderDay = (props: PickersDayProps<Date>) => {
207239
const isSelected =
208240
(dateRange.startDate && isSameDay(props.day, dateRange.startDate)) ||
@@ -250,7 +282,6 @@ const DateRangePicker = ({
250282
: alpha(theme.palette.common.black, 0.23)
251283
}`,
252284
borderRadius: '4px',
253-
width: 'fit-content',
254285
height: '40px',
255286
fontSize: '1rem',
256287
padding: '8px',
@@ -283,7 +314,7 @@ const DateRangePicker = ({
283314
</Typography>
284315
)}
285316

286-
<Box display="flex">
317+
<Box display="flex" alignItems="center" justifyContent="center">
287318
<DateInput
288319
ref={startDateInputRef}
289320
value={startDateInputValue}

packages/react-material-ui/src/components/Filter/Filter.tsx

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ import { SearchFieldProps } from '../../components/SearchField/SearchField';
1616
import { OrderableDropDown, ListItem } from '../OrderableDropDown';
1717
import { DatePickerProps } from '@mui/x-date-pickers';
1818
import DatePickerField from '../../components/DatePickerField';
19+
import DateRangePicker, {
20+
DateRangePickerProps,
21+
} from '../../components/DateRangePicker';
1922

2023
/**
2124
* Type of filter variants available.
@@ -25,7 +28,8 @@ export type FilterVariant =
2528
| 'autocomplete'
2629
| 'select'
2730
| 'multiSelect'
28-
| 'date';
31+
| 'date'
32+
| 'dateRange';
2933

3034
/**
3135
* Common properties for all filters.
@@ -64,6 +68,16 @@ type DateFilter = {
6468
} & FilterCommon &
6569
DatePickerProps<Date>;
6670

71+
/**
72+
* Properties for the date range filter.
73+
*/
74+
type DateRangeFilter = {
75+
type: 'dateRange';
76+
onChange?: (value: Date | null) => void;
77+
onDebouncedSearchChange?: (value: Date) => void;
78+
} & FilterCommon &
79+
DateRangePickerProps;
80+
6781
/**
6882
* Properties for the autocomplete filter.
6983
*/
@@ -110,6 +124,7 @@ type MultiSelectFilter = {
110124
export type FilterType =
111125
| TextFilter
112126
| DateFilter
127+
| DateRangeFilter
113128
| AutocompleteFilter
114129
| SelectFilter
115130
| MultiSelectFilter;
@@ -156,6 +171,15 @@ const renderComponent = (filter: FilterType) => {
156171
/>
157172
);
158173

174+
case 'dateRange':
175+
return (
176+
<DateRangePicker
177+
label={filter.label}
178+
value={filter.value}
179+
onRangeUpdate={filter.onRangeUpdate}
180+
/>
181+
);
182+
159183
case 'select':
160184
return (
161185
<SelectField

packages/react-material-ui/src/components/submodules/Filter/index.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
} from '../../../components/Filter';
99
import { SelectOption } from '../../../components/SelectField/SelectField';
1010
import { useCrudRoot, FilterValues } from '../../../modules/crud/useCrudRoot';
11+
import { DateRange } from '../../../components/DateRangePicker';
1112

1213
type Operator =
1314
| 'eq'
@@ -140,7 +141,7 @@ const FilterSubmodule = (props: Props) => {
140141

141142
const onFilterChange = (
142143
id: string,
143-
value: string | string[] | Date | null,
144+
value: string | string[] | Date | null | DateRange,
144145
updateFilter?: boolean,
145146
reference?: FilterDetails['reference'],
146147
referenceValidationFn?: FilterDetails['referenceValidationFn'],
@@ -265,6 +266,15 @@ const FilterSubmodule = (props: Props) => {
265266
onFilterChange(id, val, true, reference, referenceValidationFn),
266267
};
267268

269+
case 'dateRange':
270+
return {
271+
...commonFields,
272+
type,
273+
value: value as DateRange,
274+
onRangeUpdate: (dateRange: DateRange) =>
275+
onFilterChange(id, dateRange, true),
276+
};
277+
268278
default:
269279
break;
270280
}

packages/react-material-ui/src/modules/crud/useCrudRoot.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@ import { createContext, useContext } from 'react';
22
import { UseTableResult } from '../../components/Table/useTable';
33
import { Search, SimpleFilter } from '../../components/Table/types';
44
import { FilterDetails } from '../../components/submodules/Filter';
5+
import { DateRange } from '../../components/DateRangePicker';
56

6-
export type FilterValues = Record<string, string | string[] | Date | null>;
7+
export type FilterValues = Record<
8+
string,
9+
string | string[] | Date | null | DateRange
10+
>;
711

812
export type CrudContextProps = {
913
/**

0 commit comments

Comments
 (0)