-
-
Notifications
You must be signed in to change notification settings - Fork 725
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
216 additions
and
3 deletions.
There are no files selected for viewing
71 changes: 71 additions & 0 deletions
71
frontend/src/component/common/FilterDateItem/DateRangePresets.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import { Box, List, ListItem, ListItemButton, Typography } from '@mui/material'; | ||
import type { FilterItemParams } from '../../filter/FilterItem/FilterItem'; | ||
import type { FC } from 'react'; | ||
import { calculateDateRange, type RangeType } from './calculateDateRange'; | ||
|
||
export const DateRangePresets: FC<{ | ||
onRangeChange: (value: { | ||
from: FilterItemParams; | ||
to: FilterItemParams; | ||
}) => void; | ||
}> = ({ onRangeChange }) => { | ||
const rangeChangeHandler = (rangeType: RangeType) => () => { | ||
const [start, end] = calculateDateRange(rangeType); | ||
onRangeChange({ | ||
from: { | ||
operator: 'IS', | ||
values: [start], | ||
}, | ||
to: { | ||
operator: 'IS', | ||
values: [end], | ||
}, | ||
}); | ||
}; | ||
|
||
return ( | ||
<Box> | ||
<Typography variant='h3' sx={{ pb: 1, pl: 2 }}> | ||
Presets | ||
</Typography> | ||
<List disablePadding sx={{ pb: 2 }}> | ||
<ListItem disablePadding> | ||
<ListItemButton onClick={rangeChangeHandler('thisMonth')}> | ||
This month | ||
</ListItemButton> | ||
</ListItem> | ||
<ListItem disablePadding> | ||
<ListItemButton | ||
onClick={rangeChangeHandler('previousMonth')} | ||
> | ||
Previous month | ||
</ListItemButton> | ||
</ListItem> | ||
<ListItem disablePadding> | ||
<ListItemButton onClick={rangeChangeHandler('thisQuarter')}> | ||
This quarter | ||
</ListItemButton> | ||
</ListItem> | ||
<ListItem disablePadding> | ||
<ListItemButton | ||
onClick={rangeChangeHandler('previousQuarter')} | ||
> | ||
Previous quarter | ||
</ListItemButton> | ||
</ListItem> | ||
<ListItem disablePadding> | ||
<ListItemButton onClick={rangeChangeHandler('thisYear')}> | ||
This year | ||
</ListItemButton> | ||
</ListItem> | ||
<ListItem disablePadding> | ||
<ListItemButton | ||
onClick={rangeChangeHandler('previousYear')} | ||
> | ||
Previous year | ||
</ListItemButton> | ||
</ListItem> | ||
</List> | ||
</Box> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
frontend/src/component/common/FilterDateItem/calculateDateRange.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { calculateDateRange, type RangeType } from './calculateDateRange'; | ||
|
||
describe('calculateDateRange', () => { | ||
const fixedDate = new Date('2024-06-16'); | ||
|
||
test.each<[RangeType, string, string]>([ | ||
['thisMonth', '2024-06-01', '2024-06-30'], | ||
['previousMonth', '2024-05-01', '2024-05-31'], | ||
['thisQuarter', '2024-04-01', '2024-06-30'], | ||
['previousQuarter', '2024-01-01', '2024-03-31'], | ||
['thisYear', '2024-01-01', '2024-12-31'], | ||
['previousYear', '2023-01-01', '2023-12-31'], | ||
])( | ||
'should return correct range for %s', | ||
(rangeType, expectedStart, expectedEnd) => { | ||
const [start, end] = calculateDateRange(rangeType, fixedDate); | ||
expect(start).toBe(expectedStart); | ||
expect(end).toBe(expectedEnd); | ||
}, | ||
); | ||
|
||
test('should default to previousMonth if rangeType is invalid', () => { | ||
const [start, end] = calculateDateRange( | ||
'invalidRange' as RangeType, | ||
fixedDate, | ||
); | ||
expect(start).toBe('2024-05-01'); | ||
expect(end).toBe('2024-05-31'); | ||
}); | ||
|
||
test('should handle edge case for previousMonth at year boundary', () => { | ||
const yearBoundaryDate = new Date('2024-01-15'); | ||
const [start, end] = calculateDateRange( | ||
'previousMonth', | ||
yearBoundaryDate, | ||
); | ||
expect(start).toBe('2023-12-01'); | ||
expect(end).toBe('2023-12-31'); | ||
}); | ||
}); |
66 changes: 66 additions & 0 deletions
66
frontend/src/component/common/FilterDateItem/calculateDateRange.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import { | ||
endOfMonth, | ||
endOfQuarter, | ||
endOfYear, | ||
format, | ||
startOfMonth, | ||
startOfQuarter, | ||
startOfYear, | ||
subMonths, | ||
subQuarters, | ||
subYears, | ||
} from 'date-fns'; | ||
|
||
export type RangeType = | ||
| 'thisMonth' | ||
| 'previousMonth' | ||
| 'thisQuarter' | ||
| 'previousQuarter' | ||
| 'thisYear' | ||
| 'previousYear'; | ||
|
||
export const calculateDateRange = ( | ||
rangeType: RangeType, | ||
today = new Date(), | ||
): [string, string] => { | ||
let start: Date; | ||
let end: Date; | ||
|
||
switch (rangeType) { | ||
case 'thisMonth': { | ||
start = startOfMonth(today); | ||
end = endOfMonth(today); | ||
break; | ||
} | ||
case 'thisQuarter': { | ||
start = startOfQuarter(today); | ||
end = endOfQuarter(today); | ||
break; | ||
} | ||
case 'previousQuarter': { | ||
const previousQuarter = subQuarters(today, 1); | ||
start = startOfQuarter(previousQuarter); | ||
end = endOfQuarter(previousQuarter); | ||
break; | ||
} | ||
case 'thisYear': { | ||
start = startOfYear(today); | ||
end = endOfYear(today); | ||
break; | ||
} | ||
case 'previousYear': { | ||
const lastYear = subYears(today, 1); | ||
start = startOfYear(lastYear); | ||
end = endOfYear(lastYear); | ||
break; | ||
} | ||
|
||
default: { | ||
const lastMonth = subMonths(today, 1); | ||
start = startOfMonth(lastMonth); | ||
end = endOfMonth(lastMonth); | ||
} | ||
} | ||
|
||
return [format(start, 'yyyy-MM-dd'), format(end, 'yyyy-MM-dd')]; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters