@hitachivantara/uikit-react-core
Version:
UI Kit Core React components.
247 lines (246 loc) • 8.46 kB
JavaScript
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 };