ui: fix custom comparison period

This commit is contained in:
nick-delirium 2024-12-23 14:49:03 +01:00
parent 2c189f983a
commit b3f642e772
No known key found for this signature in database
GPG key ID: 93ABD695DF5FDBA0
2 changed files with 144 additions and 78 deletions

View file

@ -17,12 +17,26 @@ import { DateTime, Interval } from 'luxon';
import styles from './dateRangePopup.module.css';
function DateRangePopup(props: any) {
const [range, setRange] = React.useState(props.selectedDateRange || Interval.fromDateTimes(DateTime.now(), DateTime.now()));
const [range, setRange] = React.useState(
props.selectedDateRange ||
Interval.fromDateTimes(DateTime.now(), DateTime.now())
);
const [value, setValue] = React.useState<string | null>(null);
const selectCustomRange = (range) => {
const updatedRange = Interval.fromDateTimes(DateTime.fromJSDate(range[0]), DateTime.fromJSDate(range[1]));
setRange(updatedRange);
let newRange;
if (props.singleDay) {
newRange = Interval.fromDateTimes(
DateTime.fromJSDate(range),
DateTime.fromJSDate(range)
);
} else {
newRange = Interval.fromDateTimes(
DateTime.fromJSDate(range[0]),
DateTime.fromJSDate(range[1])
);
}
setRange(newRange);
setValue(CUSTOM_RANGE);
};
@ -53,8 +67,12 @@ function DateRangePopup(props: any) {
};
const { onCancel } = props;
const isUSLocale = navigator.language === 'en-US' || navigator.language.startsWith('en-US');
const rangeForDisplay = [range.start!.startOf('day').ts, range.end!.startOf('day').ts]
const isUSLocale =
navigator.language === 'en-US' || navigator.language.startsWith('en-US');
const rangeForDisplay = props.singleDay
? range.start.ts
: [range.start!.startOf('day').ts, range.end!.startOf('day').ts];
return (
<div className={styles.wrapper}>
<div className={`${styles.body} h-fit`}>
@ -84,41 +102,51 @@ function DateRangePopup(props: any) {
isOpen
maxDate={new Date()}
value={rangeForDisplay}
calendarProps={{
tileDisabled: props.isTileDisabled,
selectRange: props.singleDay ? false : true,
}}
/>
</div>
</div>
<div className="flex items-center justify-between py-2 px-3">
<div className="flex items-center gap-2">
<label>From: </label>
<span>{range.start.toFormat(isUSLocale ? "MM/dd" : "dd/MM")} </span>
<TimePicker
format={isUSLocale ? 'hh:mm a' : "HH:mm"}
value={range.start}
onChange={setRangeTimeStart}
needConfirm={false}
showNow={false}
style={{ width: isUSLocale ? 102 : 76 }}
/>
<label>To: </label>
<span>{range.end.toFormat(isUSLocale ? "MM/dd" : "dd/MM")} </span>
<TimePicker
format={isUSLocale ? 'hh:mm a' : "HH:mm"}
value={range.end}
onChange={setRangeTimeEnd}
needConfirm={false}
showNow={false}
style={{ width: isUSLocale ? 102 : 76 }}
/>
</div>
{props.singleDay ? (
<div>
Compare from {range.start.toFormat('MMM dd, yyyy')}
</div>
) : (
<div className="flex items-center gap-2">
<label>From: </label>
<span>{range.start.toFormat(isUSLocale ? 'MM/dd' : 'dd/MM')} </span>
<TimePicker
format={isUSLocale ? 'hh:mm a' : 'HH:mm'}
value={range.start}
onChange={setRangeTimeStart}
needConfirm={false}
showNow={false}
style={{ width: isUSLocale ? 102 : 76 }}
/>
<label>To: </label>
<span>{range.end.toFormat(isUSLocale ? 'MM/dd' : 'dd/MM')} </span>
<TimePicker
format={isUSLocale ? 'hh:mm a' : 'HH:mm'}
value={range.end}
onChange={setRangeTimeEnd}
needConfirm={false}
showNow={false}
style={{ width: isUSLocale ? 102 : 76 }}
/>
</div>
)}
<div className="flex items-center">
<Button onClick={onCancel}>{"Cancel"}</Button>
<Button onClick={onCancel}>{'Cancel'}</Button>
<Button
type="primary"
className="ml-2"
onClick={onApply}
disabled={!range}
>
{"Apply"}
{'Apply'}
</Button>
</div>
</div>
@ -126,4 +154,4 @@ function DateRangePopup(props: any) {
);
}
export default DateRangePopup;
export default DateRangePopup;

View file

@ -14,7 +14,6 @@ import { Calendar } from 'lucide-react';
import DateRangePopup from 'Shared/DateRangeDropdown/DateRangePopup';
import OutsideClickDetectingDiv from 'Shared/OutsideClickDetectingDiv';
import Select from 'Shared/Select';
import AntlikeDropdown from "Shared/Dropdown";
interface Props {
period: any | null;
@ -24,7 +23,7 @@ interface Props {
timezone?: string;
isAnt?: boolean;
small?: boolean;
useButtonStyle?: boolean;
useButtonStyle?: boolean;
compPeriod?: any | null;
onChangeComparison?: (data: any) => void;
comparison?: boolean;
@ -52,37 +51,55 @@ function SelectDateRange(props: Props) {
);
const onChange = (value: any) => {
if (value === CUSTOM_RANGE) {
setTimeout(() => {
setIsCustom(true);
}, 1);
return;
}
if (props.comparison && props.onChangeComparison) {
if (!value) return props.onChangeComparison(null);
const newPeriod = new Period({
start: props.period.start,
end: props.period.end,
substract: value
substract: value,
});
props.onChangeComparison(newPeriod);
return;
}
if (value === CUSTOM_RANGE) {
setTimeout(() => {
setIsCustom(true);
}, 1);
} else {
props.onChange(new Period({ rangeName: value }));
}
};
const onApplyDateRange = (value: any) => {
const range = new Period({
rangeName: CUSTOM_RANGE,
start: value.start,
end: value.end,
});
props.onChange(range);
const onApplyDateRange = (value: { start: any; end: any }) => {
if (props.comparison) {
const day = 86400000;
const originalPeriodLength = Math.ceil(
(props.period.end - props.period.start) / day
);
const start = value.start.ts;
const end = value.start.ts + originalPeriodLength * day;
const compRange = new Period({
start,
end,
rangeName: CUSTOM_RANGE,
});
props.onChangeComparison(compRange);
} else {
const range = new Period({
rangeName: CUSTOM_RANGE,
start: value.start,
end: value.end,
});
props.onChange(range);
}
setIsCustom(false);
};
const isCustomRange = usedPeriod ? usedPeriod.rangeName === CUSTOM_RANGE : false;
const isCustomRange = usedPeriod
? usedPeriod.rangeName === CUSTOM_RANGE
: false;
const isUSLocale =
navigator.language === 'en-US' || navigator.language.startsWith('en-US');
const customRange = isCustomRange
@ -91,20 +108,29 @@ function SelectDateRange(props: Props) {
)
: '';
const isTileDisabled = ({ date, view }) => {
if (view !== 'month' || !props.comparison) return false;
return (
date.getTime() >= props.period.start && date.getTime() <= props.period.end
);
};
if (props.isAnt) {
return <AndDateRange
{...props}
options={options}
selectedValue={selectedValue}
onChange={onChange}
isCustomRange={isCustomRange}
isCustom={isCustom}
customRange={customRange}
setIsCustom={setIsCustom}
onApplyDateRange={onApplyDateRange}
isUSLocale={isUSLocale}
useButtonStyle={useButtonStyle}
/>;
return (
<AndDateRange
{...props}
options={options}
selectedValue={selectedValue}
onChange={onChange}
isCustomRange={isCustomRange}
isCustom={isCustom}
customRange={customRange}
setIsCustom={setIsCustom}
onApplyDateRange={onApplyDateRange}
isUSLocale={isUSLocale}
useButtonStyle={useButtonStyle}
isTileDisabled={isTileDisabled}
/>
);
}
return (
@ -125,7 +151,7 @@ function SelectDateRange(props: Props) {
}}
period={period}
right={true}
style={{ width: '100%', }}
style={{ width: '100%' }}
/>
{isCustom && (
<OutsideClickDetectingDiv
@ -179,6 +205,7 @@ function AndDateRange({
isCustom,
isUSLocale,
onApplyDateRange,
isTileDisabled,
}: Props) {
const menuProps = {
items: options.map((opt) => ({
@ -191,37 +218,46 @@ function AndDateRange({
},
};
const comparisonValue = isCustomRange && selectedValue ? customRange : selectedValue?.label;
const comparisonValue =
isCustomRange && selectedValue ? customRange : selectedValue?.label;
return (
<div className={'relative'}>
{comparison ? (
<div className={'flex items-center gap-0'}>
<Dropdown menu={menuProps} trigger={['click']} className={'px-2 py-1 gap-1'}>
<Button type='text' variant='text' className='flex items-center btn-compare-card-data' size='small'>
<Dropdown
menu={menuProps}
trigger={['click']}
className={'px-2 py-1 gap-1'}
>
<Button
type="text"
variant="text"
className="flex items-center btn-compare-card-data"
size="small"
>
<span>{`Compare to ${comparisonValue || ''}`}</span>
{selectedValue && (
<Tooltip title='Reset'>
<SyncOutlined
className='cursor-pointer p-2 py-1.5 hover:bg-neutral-200/50 text-sm'
onClick={(e) => {
e.stopPropagation();
onChange(null);
}}
/>
<Tooltip title="Reset">
<SyncOutlined
className="cursor-pointer p-2 py-1.5 hover:bg-neutral-200/50 text-sm"
onClick={(e) => {
e.stopPropagation();
onChange(null);
}}
/>
</Tooltip>
)}
<DownOutlined className='ms-1' />
<DownOutlined className="ms-1" />
</Button>
</Dropdown>
</div>
) : (
<Dropdown menu={menuProps} trigger={['click']}>
<Button
type="text"
size='small'
<Button
type="text"
size="small"
className="flex items-center btn-card-period-range"
icon={useButtonStyle ? <Calendar size={16} /> : null}
icon={useButtonStyle ? <Calendar size={16} /> : null}
>
{isCustomRange ? customRange : selectedValue?.label}
<DownOutlined />
@ -260,6 +296,8 @@ function AndDateRange({
onCancel={() => setIsCustom(false)}
selectedDateRange={period.range}
className="h-fit"
isTileDisabled={isTileDisabled}
singleDay={comparison}
/>
</div>
</OutsideClickDetectingDiv>