2023-01-11 02:18:59 +01:00
|
|
|
import { useState } from 'react';
|
2023-02-15 02:23:20 +01:00
|
|
|
import { Icon, Modal, Dropdown, Item, Text, Flexbox } from 'react-basics';
|
|
|
|
import { endOfYear, isSameDay } from 'date-fns';
|
2023-01-11 02:18:59 +01:00
|
|
|
import DatePickerForm from 'components/metrics/DatePickerForm';
|
2024-02-03 07:35:46 +01:00
|
|
|
import { useLocale, useMessages } from 'components/hooks';
|
2023-12-03 12:07:03 +01:00
|
|
|
import Icons from 'components/icons';
|
2024-01-30 22:46:16 +01:00
|
|
|
import { formatDate, parseDateValue } from 'lib/date';
|
2023-12-03 12:07:03 +01:00
|
|
|
|
|
|
|
export interface DateFilterProps {
|
|
|
|
value: string;
|
|
|
|
startDate: Date;
|
|
|
|
endDate: Date;
|
2024-02-01 07:08:48 +01:00
|
|
|
offset?: number;
|
2023-12-03 12:07:03 +01:00
|
|
|
className?: string;
|
|
|
|
onChange?: (value: string) => void;
|
|
|
|
showAllTime?: boolean;
|
|
|
|
alignment?: 'start' | 'center' | 'end';
|
|
|
|
}
|
2020-07-28 10:17:45 +02:00
|
|
|
|
2023-05-18 08:20:06 +02:00
|
|
|
export function DateFilter({
|
|
|
|
startDate,
|
|
|
|
endDate,
|
2024-01-30 22:46:16 +01:00
|
|
|
value,
|
2024-02-01 07:08:48 +01:00
|
|
|
offset = 0,
|
2023-05-18 08:20:06 +02:00
|
|
|
className,
|
|
|
|
onChange,
|
|
|
|
showAllTime = false,
|
|
|
|
alignment = 'end',
|
2023-12-03 12:07:03 +01:00
|
|
|
}: DateFilterProps) {
|
2023-03-22 22:05:55 +01:00
|
|
|
const { formatMessage, labels } = useMessages();
|
2020-09-13 10:26:54 +02:00
|
|
|
const [showPicker, setShowPicker] = useState(false);
|
2024-01-30 22:46:16 +01:00
|
|
|
const { locale } = useLocale();
|
2023-01-11 02:18:59 +01:00
|
|
|
|
|
|
|
const options = [
|
2024-03-20 23:29:59 +01:00
|
|
|
{ label: formatMessage(labels.today), value: '0day' },
|
2023-01-11 02:18:59 +01:00
|
|
|
{
|
2023-02-15 02:23:20 +01:00
|
|
|
label: formatMessage(labels.lastHours, { x: 24 }),
|
2023-01-11 02:18:59 +01:00
|
|
|
value: '24hour',
|
|
|
|
},
|
|
|
|
{
|
2023-02-15 02:23:20 +01:00
|
|
|
label: formatMessage(labels.thisWeek),
|
2024-03-20 23:29:59 +01:00
|
|
|
value: '0week',
|
2023-01-11 02:18:59 +01:00
|
|
|
divider: true,
|
|
|
|
},
|
|
|
|
{
|
2023-02-15 02:23:20 +01:00
|
|
|
label: formatMessage(labels.lastDays, { x: 7 }),
|
2023-01-11 02:18:59 +01:00
|
|
|
value: '7day',
|
|
|
|
},
|
|
|
|
{
|
2023-02-15 02:23:20 +01:00
|
|
|
label: formatMessage(labels.thisMonth),
|
2024-03-20 23:29:59 +01:00
|
|
|
value: '0month',
|
2023-01-11 02:18:59 +01:00
|
|
|
divider: true,
|
|
|
|
},
|
|
|
|
{
|
2023-02-15 02:23:20 +01:00
|
|
|
label: formatMessage(labels.lastDays, { x: 30 }),
|
2023-01-11 02:18:59 +01:00
|
|
|
value: '30day',
|
|
|
|
},
|
|
|
|
{
|
2023-02-15 02:23:20 +01:00
|
|
|
label: formatMessage(labels.lastDays, { x: 90 }),
|
2023-01-11 02:18:59 +01:00
|
|
|
value: '90day',
|
|
|
|
},
|
2024-03-20 23:29:59 +01:00
|
|
|
{ label: formatMessage(labels.thisYear), value: '0year' },
|
2023-05-18 08:20:06 +02:00
|
|
|
showAllTime && {
|
2023-02-15 02:23:20 +01:00
|
|
|
label: formatMessage(labels.allTime),
|
2023-01-11 02:18:59 +01:00
|
|
|
value: 'all',
|
|
|
|
divider: true,
|
|
|
|
},
|
|
|
|
{
|
2023-02-15 02:23:20 +01:00
|
|
|
label: formatMessage(labels.customRange),
|
2023-01-11 02:18:59 +01:00
|
|
|
value: 'custom',
|
|
|
|
divider: true,
|
|
|
|
},
|
2023-04-25 23:41:54 +02:00
|
|
|
].filter(n => n);
|
2023-01-11 02:18:59 +01:00
|
|
|
|
2023-12-03 12:07:03 +01:00
|
|
|
const handleChange = (value: string) => {
|
2020-09-13 10:26:54 +02:00
|
|
|
if (value === 'custom') {
|
|
|
|
setShowPicker(true);
|
|
|
|
return;
|
|
|
|
}
|
2023-05-18 08:20:06 +02:00
|
|
|
onChange(value);
|
2023-01-11 02:18:59 +01:00
|
|
|
};
|
2020-07-28 10:17:45 +02:00
|
|
|
|
2023-12-03 12:07:03 +01:00
|
|
|
const handlePickerChange = (value: string) => {
|
2020-09-13 10:26:54 +02:00
|
|
|
setShowPicker(false);
|
2023-05-18 08:20:06 +02:00
|
|
|
onChange(value);
|
2023-01-11 02:18:59 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
const handleClose = () => setShowPicker(false);
|
2020-09-13 10:26:54 +02:00
|
|
|
|
2024-01-30 22:46:16 +01:00
|
|
|
const renderValue = (value: string) => {
|
2024-02-16 20:51:48 +01:00
|
|
|
const { unit } = parseDateValue(value) || {};
|
2024-01-30 22:46:16 +01:00
|
|
|
|
|
|
|
if (offset && unit === 'year') {
|
|
|
|
return formatDate(startDate, 'yyyy', locale);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (offset && unit === 'month') {
|
|
|
|
return formatDate(startDate, 'MMMM yyyy', locale);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (value.startsWith('range') || offset) {
|
|
|
|
return (
|
|
|
|
<CustomRange
|
|
|
|
startDate={startDate}
|
|
|
|
endDate={endDate}
|
|
|
|
unit={unit}
|
|
|
|
onClick={() => handleChange('custom')}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2024-03-27 10:06:16 +01:00
|
|
|
return options.find(e => e.value === value)?.label;
|
2024-01-30 22:46:16 +01:00
|
|
|
};
|
|
|
|
|
2020-08-02 06:20:52 +02:00
|
|
|
return (
|
2020-09-13 10:26:54 +02:00
|
|
|
<>
|
2023-01-11 02:18:59 +01:00
|
|
|
<Dropdown
|
2020-09-13 10:26:54 +02:00
|
|
|
className={className}
|
2023-01-11 02:18:59 +01:00
|
|
|
items={options}
|
|
|
|
renderValue={renderValue}
|
|
|
|
value={value}
|
2023-05-18 08:20:06 +02:00
|
|
|
alignment={alignment}
|
|
|
|
placeholder={formatMessage(labels.selectDate)}
|
2024-01-19 01:46:40 +01:00
|
|
|
onChange={key => handleChange(key as any)}
|
2023-01-11 02:18:59 +01:00
|
|
|
>
|
2023-02-15 02:23:20 +01:00
|
|
|
{({ label, value, divider }) => (
|
|
|
|
<Item key={value} divider={divider}>
|
|
|
|
{label}
|
|
|
|
</Item>
|
|
|
|
)}
|
2023-01-11 02:18:59 +01:00
|
|
|
</Dropdown>
|
2020-09-13 10:26:54 +02:00
|
|
|
{showPicker && (
|
2023-01-11 02:18:59 +01:00
|
|
|
<Modal onClose={handleClose}>
|
2020-09-13 10:26:54 +02:00
|
|
|
<DatePickerForm
|
|
|
|
startDate={startDate}
|
|
|
|
endDate={endDate}
|
|
|
|
minDate={new Date(2000, 0, 1)}
|
|
|
|
maxDate={endOfYear(new Date())}
|
|
|
|
onChange={handlePickerChange}
|
|
|
|
onClose={() => setShowPicker(false)}
|
|
|
|
/>
|
|
|
|
</Modal>
|
|
|
|
)}
|
|
|
|
</>
|
2020-08-02 06:20:52 +02:00
|
|
|
);
|
2020-07-28 10:17:45 +02:00
|
|
|
}
|
2020-09-13 20:33:57 +02:00
|
|
|
|
2024-01-30 22:46:16 +01:00
|
|
|
const CustomRange = ({ startDate, endDate, unit, onClick }) => {
|
2021-06-30 03:41:34 +02:00
|
|
|
const { locale } = useLocale();
|
2020-09-13 20:33:57 +02:00
|
|
|
|
2024-01-30 22:46:16 +01:00
|
|
|
const monthFormat = unit === 'month';
|
2023-08-22 00:53:19 +02:00
|
|
|
|
2020-09-13 20:33:57 +02:00
|
|
|
function handleClick(e) {
|
|
|
|
e.stopPropagation();
|
|
|
|
|
|
|
|
onClick();
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
2023-02-15 02:23:20 +01:00
|
|
|
<Flexbox gap={10} alignItems="center" wrap="nowrap">
|
2022-12-27 01:57:59 +01:00
|
|
|
<Icon className="mr-2" onClick={handleClick}>
|
2023-02-15 02:23:20 +01:00
|
|
|
<Icons.Calendar />
|
2022-12-27 01:57:59 +01:00
|
|
|
</Icon>
|
2023-02-15 02:23:20 +01:00
|
|
|
<Text>
|
2023-08-22 00:53:19 +02:00
|
|
|
{monthFormat ? (
|
|
|
|
<>{formatDate(startDate, 'MMMM yyyy', locale)}</>
|
|
|
|
) : (
|
|
|
|
<>
|
|
|
|
{formatDate(startDate, 'd LLL y', locale)}
|
|
|
|
{!isSameDay(startDate, endDate) && ` — ${formatDate(endDate, 'd LLL y', locale)}`}
|
|
|
|
</>
|
|
|
|
)}
|
2023-02-15 02:23:20 +01:00
|
|
|
</Text>
|
|
|
|
</Flexbox>
|
2020-09-13 20:33:57 +02:00
|
|
|
);
|
|
|
|
};
|
2021-02-16 12:47:02 +01:00
|
|
|
|
|
|
|
export default DateFilter;
|