-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update DateRange.tsx #2050
Update DateRange.tsx #2050
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,7 +18,7 @@ import Typography from "@mui/material/Typography"; | |
import { DatePicker, DatePickerProps } from "@mui/x-date-pickers/DatePicker"; | ||
import { BaseDateTimePickerSlotProps } from "@mui/x-date-pickers/DateTimePicker/shared"; | ||
import { DateTimePicker, DateTimePickerProps } from "@mui/x-date-pickers/DateTimePicker"; | ||
import { isValid } from "date-fns"; | ||
import { isValid, setMinutes, setHours } from "date-fns"; | ||
import { ErrorBoundary } from "react-error-boundary"; | ||
|
||
import { createSendUpdateAction } from "../../context/taipyReducers"; | ||
|
@@ -40,40 +40,26 @@ interface DateRangeProps extends TaipyActiveProps, TaipyChangeProps { | |
labelEnd?: string; | ||
separator?: string; | ||
width?: string | number; | ||
timeStep?: number; // New prop to define time step rounding (e.g., 15 for 15 minutes) | ||
} | ||
|
||
const textFieldProps = { textField: { margin: "dense" } } as BaseDateTimePickerSlotProps<Date>; | ||
|
||
const getRangeDateTime = ( | ||
json: string | string[] | undefined, | ||
tz: string, | ||
withTime: boolean | ||
): [Date | null, Date | null] => { | ||
let dates: string[] = []; | ||
if (typeof json == "string") { | ||
try { | ||
dates = JSON.parse(json); | ||
} catch { | ||
// too bad | ||
} | ||
} else { | ||
dates = json as string[]; | ||
} | ||
if (Array.isArray(dates) && dates.length) { | ||
return dates.map((d) => getDateTime(d, tz, withTime)) as [Date, Date]; | ||
} | ||
return [null, null]; | ||
// Function to round the time based on the given step | ||
const roundToStep = (date: Date | null, step: number | undefined): Date | null => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should go in a dateUtils.ts so that we can reuse it in dateSelector.tsx and timeSelector.tsx ... |
||
if (!date || !step) return date; | ||
const roundedMinutes = Math.ceil(date.getMinutes() / step) * step; | ||
return setMinutes(setHours(date, date.getHours()), roundedMinutes); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what happens if step = 40 and current min = 50 ? |
||
}; | ||
|
||
const DateRange = (props: DateRangeProps) => { | ||
const { updateVarName, withTime = false, id, propagate = true, separator = "-" } = props; | ||
const { updateVarName, withTime = false, id, propagate = true, separator = "-", timeStep } = props; | ||
const dispatch = useDispatch(); | ||
const formatConfig = useFormatConfig(); | ||
const tz = formatConfig.timeZone; | ||
const [value, setValue] = useState<[Date | null, Date | null]>([null, null]); | ||
const [startProps, setStartProps] = useState<DateProps>({}); | ||
const [endProps, setEndProps] = useState<DateProps>({}); | ||
const module = useModule(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why ? |
||
|
||
const className = useClassNames(props.libClassName, props.dynamicClassName, props.className); | ||
const active = useDynamicProperty(props.active, props.defaultActive, true); | ||
|
@@ -86,7 +72,9 @@ const DateRange = (props: DateRangeProps) => { | |
(v: Date | null, start: boolean) => { | ||
setValue((dates) => { | ||
if (v !== null && isValid(v)) { | ||
const newDate = getTimeZonedDate(v, tz, withTime); | ||
// Apply rounding to the selected time if timeStep is defined | ||
const roundedDate = roundToStep(v, timeStep); | ||
const newDate = getTimeZonedDate(roundedDate || v, tz, withTime); | ||
const otherDate = start | ||
? dates[1] && getTimeZonedDate(dates[1], tz, withTime) | ||
: dates[0] && getTimeZonedDate(dates[0], tz, withTime); | ||
|
@@ -106,19 +94,18 @@ const DateRange = (props: DateRangeProps) => { | |
propagate | ||
) | ||
); | ||
(start ? setEndProps : setStartProps)((p) => getProps(p, start, v, withTime)); | ||
(start ? setEndProps : setStartProps)((p) => getProps(p, start, roundedDate || v, withTime)); | ||
} | ||
|
||
return [start ? v : dates[0], start ? dates[1] : v]; | ||
}); | ||
}, | ||
[updateVarName, dispatch, withTime, propagate, tz, props.onChange, module] | ||
[updateVarName, dispatch, withTime, propagate, tz, props.onChange, module, timeStep] | ||
); | ||
|
||
const handleChangeStart = useCallback((v: Date | null) => handleChange(v, true), [handleChange]); | ||
const handleChangeEnd = useCallback((v: Date | null) => handleChange(v, false), [handleChange]); | ||
|
||
// Run every time props.value get updated | ||
useEffect(() => { | ||
if (props.dates !== undefined || props.defaultDates) { | ||
const dates = getRangeDateTime(props.dates === undefined ? props.defaultDates : props.dates, tz, withTime); | ||
|
@@ -231,7 +218,6 @@ const DateRange = (props: DateRangeProps) => { | |
/> | ||
</> | ||
)} | ||
{props.children} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why ? |
||
</Stack> | ||
</Tooltip> | ||
</ErrorBoundary> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why ?