-
-
Notifications
You must be signed in to change notification settings - Fork 730
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
11 changed files
with
281 additions
and
23 deletions.
There are no files selected for viewing
81 changes: 81 additions & 0 deletions
81
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,81 @@ | ||
import { | ||
Box, | ||
List, | ||
ListItem, | ||
ListItemButton, | ||
styled, | ||
Typography, | ||
} from '@mui/material'; | ||
import type { FilterItemParams } from '../../filter/FilterItem/FilterItem'; | ||
import type { FC } from 'react'; | ||
import { calculateDateRange, type RangeType } from './calculateDateRange'; | ||
|
||
export const PresetsHeader = styled(Typography)(({ theme }) => ({ | ||
paddingLeft: theme.spacing(2), | ||
paddingBottom: theme.spacing(1), | ||
})); | ||
|
||
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> | ||
<PresetsHeader variant='h3'>Presets</PresetsHeader> | ||
<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
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
Oops, something went wrong.