UNPKG

@hitachivantara/uikit-react-core

Version:
247 lines (246 loc) 8.46 kB
import { HvWarningText } from "../../FormElement/WarningText/WarningText.js"; import { uniqueId } from "../../utils/helpers.js"; import { HvDatePicker } from "../../DatePicker/DatePicker.js"; import { useQueryBuilderContext } from "../Context.js"; import { HvTimePicker } from "../../TimePicker/TimePicker.js"; import { theme } from "@hitachivantara/uikit-styles"; import { createClasses } from "@hitachivantara/uikit-react-utils"; import { useCallback, useMemo, useState } from "react"; import { jsx, jsxs } from "react/jsx-runtime"; import { useTheme as useTheme$1 } from "@mui/material/styles"; import useMediaQuery from "@mui/material/useMediaQuery"; //#region src/QueryBuilder/Value/DateTimeValue.tsx function formatDate(date) { if (!date) return void 0; return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate())).toISOString().slice(0, 10); } function formatTime(time) { if (!time) return void 0; const { hours, minutes, seconds } = time; return new Date(Date.UTC(2020, 8, 8, hours, minutes, seconds)).toISOString().slice(11, 19); } function parseDate(date) { return date ? new Date(date) : void 0; } function parseTime(time) { if (!time) return null; const parts = time.split(":"); return { hours: Number(parts[0]), minutes: Number(parts[1]), seconds: Number(parts[2]) || 0 }; } var { useClasses } = createClasses("HvQueryBuilderDateTimeValue", { root: { display: "flex", flexDirection: "column" }, row: {}, vertical: { display: "flex", flexDirection: "column" }, horizontal: { display: "flex", "& > div:not(:last-child)": { marginRight: theme.space.md } }, isMdDown: { "& > div:not(:last-child)": { marginRight: `calc(${theme.space.md} / 2)` } }, datePicker: { flex: 1 }, timePicker: { flex: 1 } }); var DateTimeValue = ({ id, operator, value: valueProp = {}, initialTouched = false }) => { const { classes, cx } = useClasses(); const { breakpoints } = useTheme$1(); const isMdDown = useMediaQuery(breakpoints.down("md")); const isRange = operator === "range"; const { labels, dispatchAction, readOnly } = useQueryBuilderContext(); const elementId = uniqueId(`datetime${id}`); const [touchedDate, setTouchedDate] = useState(initialTouched); const [touchedTime, setTouchedTime] = useState(initialTouched); const [touchedEndDate, setTouchedEndDate] = useState(initialTouched); const [touchedEndTime, setTouchedEndTime] = useState(initialTouched); const onDateChange = useCallback((data) => { setTouchedDate(true); const date = formatDate(data); if (date !== (!isRange ? valueProp?.date : valueProp?.start?.date)) { let value; if (!isRange) value = { date, time: valueProp?.time }; else value = { start: { date, time: valueProp?.start?.time }, end: valueProp?.end }; dispatchAction({ type: "set-value", id, value }); } }, [ dispatchAction, id, isRange, valueProp ]); const onTimeChange = useCallback((data) => { setTouchedTime(true); const time = formatTime(data); if (time !== (!isRange ? valueProp?.time : valueProp?.start?.time)) { let value; if (!isRange) value = { date: valueProp?.date, time }; else value = { start: { date: valueProp?.start?.date, time }, end: valueProp?.end }; dispatchAction({ type: "set-value", id, value }); } }, [ dispatchAction, id, isRange, valueProp ]); const onEndDateChange = useCallback((data) => { setTouchedEndDate(true); const date = formatDate(data); if (date !== valueProp?.end?.date) dispatchAction({ type: "set-value", id, value: { start: valueProp?.start, end: { date, time: valueProp?.end?.time } } }); }, [ dispatchAction, id, valueProp ]); const onEndTimeChange = useCallback((data) => { setTouchedEndTime(true); const time = formatTime(data); if (time !== valueProp?.end?.time) dispatchAction({ type: "set-value", id, value: { start: valueProp?.start, end: { date: valueProp?.end?.date, time } } }); }, [ dispatchAction, id, valueProp ]); const startDate = isRange ? valueProp?.start?.date : valueProp?.date; const datePickerValue = useMemo(() => parseDate(startDate), [startDate]); const datePickerStatus = datePickerValue != null ? "valid" : "invalid"; const startTime = (isRange ? valueProp?.start?.time : valueProp?.time) ?? ""; const timePickerValue = useMemo(() => parseTime(startTime), [startTime]); const timePickerStatus = timePickerValue != null ? "valid" : "invalid"; const endDate = isRange ? valueProp?.end?.date : null; const endDatePickerValue = useMemo(() => parseDate(endDate), [endDate]); const endTime = isRange ? valueProp?.end?.time : null; const endTimePickerValue = useMemo(() => parseTime(endTime), [endTime]); const dateStatus = !touchedDate ? "standBy" : datePickerStatus; const timeStatus = !touchedTime ? "standBy" : timePickerStatus; const endDateTimeIsBefore = startDate != null && endDate != null && endDate < startDate || startDate != null && endDate != null && endDate === startDate && startTime != null && endTime != null && endTime <= startTime; const endDateStatus = !touchedEndDate ? "standBy" : endDatePickerValue == null || endDateTimeIsBefore ? "invalid" : "valid"; const endTimeStatus = !touchedEndTime ? "standBy" : endTimePickerValue == null || endDateTimeIsBefore ? "invalid" : "valid"; return /* @__PURE__ */ jsxs("div", { className: classes.root, children: [/* @__PURE__ */ jsxs("div", { className: cx(classes.row, classes.horizontal, { [classes.isMdDown]: isMdDown }), children: [/* @__PURE__ */ jsx(HvDatePicker, { className: classes.datePicker, name: `${elementId}-date`, required: true, status: dateStatus, statusMessage: labels.rule.value.datetime.validation.required, label: isRange ? labels.rule.value.datetime.startDateLabel : labels.rule.value.datetime.dateLabel, placeholder: isRange ? labels.rule.value.datetime.startDatePlaceholder : labels.rule.value.datetime.datePlaceholder, value: datePickerValue, onChange: onDateChange, readOnly }), /* @__PURE__ */ jsx(HvTimePicker, { className: classes.timePicker, timeFormat: "24", name: `${elementId}-time`, required: true, status: timeStatus, statusMessage: labels.rule.value.datetime.validation.required, label: isRange ? labels.rule.value.datetime.startTimeLabel : labels.rule.value.datetime.timeLabel, placeholder: isRange ? labels.rule.value.datetime.startTimePlaceholder : labels.rule.value.datetime.timePlaceholder, value: timePickerValue || void 0, onChange: onTimeChange, onToggle: (_evt, open) => { if (!open && !touchedTime) setTouchedTime(true); }, readOnly })] }), isRange && /* @__PURE__ */ jsxs("div", { className: cx(classes.row, classes.vertical), children: [/* @__PURE__ */ jsxs("div", { className: cx(classes.horizontal, { [classes.isMdDown]: isMdDown }), children: [/* @__PURE__ */ jsx(HvDatePicker, { className: classes.datePicker, name: `${elementId}-endDate`, required: true, status: endDateStatus, statusMessage: labels.rule.value.datetime.validation.required, "aria-errormessage": endDateTimeIsBefore ? `${elementId}-combined-error` : void 0, label: labels.rule.value.datetime.endDateLabel, placeholder: labels.rule.value.datetime.endDatePlaceholder, value: endDatePickerValue, onChange: onEndDateChange, readOnly }), /* @__PURE__ */ jsx(HvTimePicker, { className: classes.timePicker, timeFormat: "24", name: `${elementId}-endTime`, required: true, status: endTimeStatus, statusMessage: labels.rule.value.datetime.validation.required, "aria-errormessage": endDateTimeIsBefore ? `${elementId}-combined-error` : void 0, label: labels.rule.value.datetime.endTimeLabel, placeholder: labels.rule.value.datetime.endTimePlaceholder, value: endTimePickerValue || void 0, onChange: onEndTimeChange, onToggle: (_evt, open) => { if (!open && !touchedEndTime) setTouchedEndTime(true); }, readOnly })] }), /* @__PURE__ */ jsx(HvWarningText, { disableBorder: true, id: `${elementId}-combined-error`, isVisible: endDateTimeIsBefore, children: labels.rule.value.datetime.validation.invalidInterval })] })] }); }; //#endregion export { DateTimeValue };