@bsol-oss/react-datatable5 12.0.0-beta.57 → 12.0.0-beta.58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +24 -1
- package/dist/index.js +413 -54
- package/dist/index.mjs +414 -55
- package/dist/types/components/DatePicker/DatePicker.d.ts +23 -0
- package/dist/types/components/DatePicker/DateTimePicker.d.ts +11 -0
- package/dist/types/components/DatePicker/DurationPicker.d.ts +12 -0
- package/dist/types/components/DatePicker/IsoTimePicker.d.ts +16 -0
- package/dist/types/components/DatePicker/PickerDemo.d.ts +1 -0
- package/dist/types/components/DatePicker/UniversalPicker.d.ts +9 -0
- package/dist/types/components/DatePicker/index.d.ts +7 -0
- package/dist/types/components/Form/SchemaFormContext.d.ts +1 -0
- package/dist/types/components/Form/components/fields/DateTimePicker.d.ts +2 -0
- package/dist/types/components/Form/components/viewers/DateTimeViewer.d.ts +7 -0
- package/dist/types/components/Form/components/viewers/TimeViewer.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import * as React from 'react';
|
|
|
5
5
|
import React__default, { createContext, useContext, useState, useEffect, useRef } from 'react';
|
|
6
6
|
import { LuX, LuCheck, LuChevronRight, LuChevronDown } from 'react-icons/lu';
|
|
7
7
|
import { MdOutlineSort, MdFilterAlt, MdSearch, MdOutlineViewColumn, MdFilterListAlt, MdPushPin, MdCancel, MdClear, MdOutlineChecklist, MdDateRange } from 'react-icons/md';
|
|
8
|
-
import { FaUpDown, FaGripLinesVertical } from 'react-icons/fa6';
|
|
8
|
+
import { FaUpDown, FaGripLinesVertical, FaTrash } from 'react-icons/fa6';
|
|
9
9
|
import { BiDownArrow, BiUpArrow, BiError } from 'react-icons/bi';
|
|
10
10
|
import { CgClose, CgTrash } from 'react-icons/cg';
|
|
11
11
|
import Dayzed from '@bsol-oss/dayzed-react19';
|
|
@@ -34,6 +34,7 @@ import zh_TW from 'ajv-i18n/localize/zh-TW';
|
|
|
34
34
|
import zh_CN from 'ajv-i18n/localize/zh';
|
|
35
35
|
import dayjs from 'dayjs';
|
|
36
36
|
import utc from 'dayjs/plugin/utc';
|
|
37
|
+
import timezone from 'dayjs/plugin/timezone';
|
|
37
38
|
import { TiDeleteOutline } from 'react-icons/ti';
|
|
38
39
|
|
|
39
40
|
const DataTableContext = createContext({
|
|
@@ -181,7 +182,7 @@ const monthNamesFull = [
|
|
|
181
182
|
"November",
|
|
182
183
|
"December",
|
|
183
184
|
];
|
|
184
|
-
const weekdayNamesShort
|
|
185
|
+
const weekdayNamesShort = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
185
186
|
function Calendar$1({ calendars, getBackProps, getForwardProps, getDateProps, selected = [], firstDayOfWeek = 0, }) {
|
|
186
187
|
const [hoveredDate, setHoveredDate] = useState();
|
|
187
188
|
const onMouseLeave = () => {
|
|
@@ -216,7 +217,7 @@ function Calendar$1({ calendars, getBackProps, getForwardProps, getDateProps, se
|
|
|
216
217
|
offset: 12,
|
|
217
218
|
}), children: ">>" })] }), jsx(Grid, { templateColumns: "repeat(2, auto)", justifyContent: "center", gap: 4, children: calendars.map((calendar) => (jsxs(Grid, { gap: 4, children: [jsxs(Grid, { justifyContent: "center", children: [monthNamesFull[calendar.month], " ", calendar.year] }), jsx(Grid, { templateColumns: "repeat(7, auto)", justifyContent: "center", children: [0, 1, 2, 3, 4, 5, 6].map((weekdayNum) => {
|
|
218
219
|
const weekday = (weekdayNum + firstDayOfWeek) % 7;
|
|
219
|
-
return (jsx(Box, { minWidth: "48px", textAlign: "center", children: weekdayNamesShort
|
|
220
|
+
return (jsx(Box, { minWidth: "48px", textAlign: "center", children: weekdayNamesShort[weekday] }, `${calendar.month}${calendar.year}${weekday}`));
|
|
220
221
|
}) }), jsx(Grid, { templateColumns: "repeat(7, auto)", justifyContent: "center", children: calendar.weeks.map((week, windex) => week.map((dateObj, index) => {
|
|
221
222
|
const key = `${calendar.month}${calendar.year}${windex}${index}`;
|
|
222
223
|
if (!dateObj) {
|
|
@@ -3673,6 +3674,7 @@ const SchemaFormContext = createContext({
|
|
|
3673
3674
|
rowNumber: 0,
|
|
3674
3675
|
requestOptions: {},
|
|
3675
3676
|
validationLocale: 'en',
|
|
3677
|
+
timezone: 'Asia/Hong_Kong',
|
|
3676
3678
|
});
|
|
3677
3679
|
|
|
3678
3680
|
const useSchemaContext = () => {
|
|
@@ -3979,27 +3981,14 @@ const CustomInput = ({ column, schema, prefix }) => {
|
|
|
3979
3981
|
}));
|
|
3980
3982
|
};
|
|
3981
3983
|
|
|
3982
|
-
const monthNamesShort = [
|
|
3983
|
-
"Jan",
|
|
3984
|
-
"Feb",
|
|
3985
|
-
"Mar",
|
|
3986
|
-
"Apr",
|
|
3987
|
-
"May",
|
|
3988
|
-
"Jun",
|
|
3989
|
-
"Jul",
|
|
3990
|
-
"Aug",
|
|
3991
|
-
"Sep",
|
|
3992
|
-
"Oct",
|
|
3993
|
-
"Nov",
|
|
3994
|
-
"Dec",
|
|
3995
|
-
];
|
|
3996
|
-
const weekdayNamesShort = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
3997
3984
|
const Calendar = ({ calendars, getBackProps, getForwardProps, getDateProps, firstDayOfWeek = 0, }) => {
|
|
3985
|
+
const { labels } = useContext(DatePickerContext);
|
|
3986
|
+
const { monthNamesShort, weekdayNamesShort, backButtonLabel, forwardButtonLabel } = labels;
|
|
3998
3987
|
if (calendars.length) {
|
|
3999
3988
|
return (jsxs(Grid, { children: [jsxs(Grid, { templateColumns: "repeat(4, auto)", justifyContent: "center", children: [jsx(Button$1, { variant: "ghost", ...getBackProps({
|
|
4000
3989
|
calendars,
|
|
4001
3990
|
offset: 12,
|
|
4002
|
-
}), children: "<<" }), jsx(Button$1, { variant: "ghost", ...getBackProps({ calendars }), children:
|
|
3991
|
+
}), children: "<<" }), jsx(Button$1, { variant: "ghost", ...getBackProps({ calendars }), children: backButtonLabel }), jsx(Button$1, { variant: "ghost", ...getForwardProps({ calendars }), children: forwardButtonLabel }), jsx(Button$1, { variant: "ghost", ...getForwardProps({
|
|
4003
3992
|
calendars,
|
|
4004
3993
|
offset: 12,
|
|
4005
3994
|
}), children: ">>" })] }), jsx(Grid, { templateColumns: "repeat(2, auto)", justifyContent: "center", children: calendars.map((calendar) => (jsxs(Grid, { gap: 4, children: [jsxs(Grid, { justifyContent: "center", children: [monthNamesShort[calendar.month], " ", calendar.year] }), jsxs(Grid, { templateColumns: "repeat(7, auto)", justifyContent: "center", children: [[0, 1, 2, 3, 4, 5, 6].map((weekdayNum) => {
|
|
@@ -4042,9 +4031,52 @@ const Calendar = ({ calendars, getBackProps, getForwardProps, getDateProps, firs
|
|
|
4042
4031
|
}
|
|
4043
4032
|
return null;
|
|
4044
4033
|
};
|
|
4034
|
+
const DatePickerContext = createContext({
|
|
4035
|
+
labels: {
|
|
4036
|
+
monthNamesShort: [
|
|
4037
|
+
"Jan",
|
|
4038
|
+
"Feb",
|
|
4039
|
+
"Mar",
|
|
4040
|
+
"Apr",
|
|
4041
|
+
"May",
|
|
4042
|
+
"Jun",
|
|
4043
|
+
"Jul",
|
|
4044
|
+
"Aug",
|
|
4045
|
+
"Sep",
|
|
4046
|
+
"Oct",
|
|
4047
|
+
"Nov",
|
|
4048
|
+
"Dec",
|
|
4049
|
+
],
|
|
4050
|
+
weekdayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
|
|
4051
|
+
backButtonLabel: "Back",
|
|
4052
|
+
forwardButtonLabel: "Next",
|
|
4053
|
+
},
|
|
4054
|
+
});
|
|
4045
4055
|
let DatePicker$1 = class DatePicker extends React__default.Component {
|
|
4046
4056
|
render() {
|
|
4047
|
-
|
|
4057
|
+
const { labels = {
|
|
4058
|
+
monthNamesShort: [
|
|
4059
|
+
"Jan",
|
|
4060
|
+
"Feb",
|
|
4061
|
+
"Mar",
|
|
4062
|
+
"Apr",
|
|
4063
|
+
"May",
|
|
4064
|
+
"Jun",
|
|
4065
|
+
"Jul",
|
|
4066
|
+
"Aug",
|
|
4067
|
+
"Sep",
|
|
4068
|
+
"Oct",
|
|
4069
|
+
"Nov",
|
|
4070
|
+
"Dec",
|
|
4071
|
+
],
|
|
4072
|
+
weekdayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
|
|
4073
|
+
backButtonLabel: "Back",
|
|
4074
|
+
forwardButtonLabel: "Next",
|
|
4075
|
+
}, } = this.props;
|
|
4076
|
+
return (jsx(DatePickerContext.Provider, { value: { labels }, children: jsx(Dayzed, { onDateSelected: this.props.onDateSelected, selected: this.props.selected, firstDayOfWeek: this.props.firstDayOfWeek, showOutsideDays: this.props.showOutsideDays, date: this.props.date, minDate: this.props.minDate, maxDate: this.props.maxDate, monthsToDisplay: this.props.monthsToDisplay, render:
|
|
4077
|
+
// @ts-expect-error - Dayzed types need to be fixed
|
|
4078
|
+
(dayzedData) => (jsx(Calendar, { ...dayzedData,
|
|
4079
|
+
firstDayOfWeek: this.props.firstDayOfWeek })) }) }));
|
|
4048
4080
|
}
|
|
4049
4081
|
};
|
|
4050
4082
|
|
|
@@ -4066,24 +4098,27 @@ const PopoverRoot = Popover.Root;
|
|
|
4066
4098
|
const PopoverBody = Popover.Body;
|
|
4067
4099
|
const PopoverTrigger = Popover.Trigger;
|
|
4068
4100
|
|
|
4101
|
+
function translateWrapper({ prefix, column, label, translate, }) {
|
|
4102
|
+
return translate.t(removeIndex(`${prefix}${column}.${label}`));
|
|
4103
|
+
}
|
|
4104
|
+
|
|
4069
4105
|
dayjs.extend(utc);
|
|
4106
|
+
dayjs.extend(timezone);
|
|
4070
4107
|
const DatePicker = ({ column, schema, prefix }) => {
|
|
4071
4108
|
const { watch, formState: { errors }, setValue, } = useFormContext();
|
|
4072
|
-
const { translate } = useSchemaContext();
|
|
4073
|
-
const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD", dateFormat = "YYYY-MM-DD
|
|
4109
|
+
const { translate, timezone } = useSchemaContext();
|
|
4110
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD", dateFormat = "YYYY-MM-DD", } = schema;
|
|
4074
4111
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4075
4112
|
const colLabel = `${prefix}${column}`;
|
|
4076
4113
|
const [open, setOpen] = useState(false);
|
|
4077
4114
|
const selectedDate = watch(colLabel);
|
|
4078
|
-
const displayDate = dayjs
|
|
4115
|
+
const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
|
|
4079
4116
|
useEffect(() => {
|
|
4080
4117
|
try {
|
|
4081
4118
|
if (selectedDate) {
|
|
4082
4119
|
// Parse the selectedDate as UTC or in a specific timezone to avoid +8 hour shift
|
|
4083
4120
|
// For example, parse as UTC:
|
|
4084
|
-
const parsedDate = dayjs
|
|
4085
|
-
// Or if you want to parse in local timezone without shifting:
|
|
4086
|
-
// const parsedDate = dayjs.tz(selectedDate, dayjs.tz.guess());
|
|
4121
|
+
const parsedDate = dayjs(selectedDate).tz(timezone);
|
|
4087
4122
|
if (!parsedDate.isValid())
|
|
4088
4123
|
return;
|
|
4089
4124
|
// Format according to dateFormat from schema
|
|
@@ -4101,19 +4136,48 @@ const DatePicker = ({ column, schema, prefix }) => {
|
|
|
4101
4136
|
console.error(e);
|
|
4102
4137
|
}
|
|
4103
4138
|
}, [selectedDate, dateFormat, colLabel, setValue]);
|
|
4104
|
-
|
|
4139
|
+
const customTranslate = (label) => {
|
|
4140
|
+
return translateWrapper({ prefix, column, label, translate });
|
|
4141
|
+
};
|
|
4142
|
+
return (jsxs(Field, { label: `${customTranslate(`field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
4105
4143
|
gridRow, children: [jsxs(PopoverRoot, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsx(PopoverTrigger, { asChild: true, children: jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
|
|
4106
4144
|
setOpen(true);
|
|
4107
|
-
}, justifyContent: "start", children: [jsx(MdDateRange, {}), selectedDate !== undefined ? `${displayDate}` : ""] }) }), jsx(PopoverContent, { children: jsxs(PopoverBody, { children: [jsx(PopoverTitle, {}), jsx(DatePicker$1
|
|
4108
|
-
// @ts-expect-error TODO: find appropriate types
|
|
4109
|
-
, {
|
|
4110
|
-
// @ts-expect-error TODO: find appropriate types
|
|
4111
|
-
selected: new Date(selectedDate),
|
|
4112
|
-
// @ts-expect-error TODO: find appropriate types
|
|
4113
|
-
onDateSelected: ({ date }) => {
|
|
4145
|
+
}, justifyContent: "start", children: [jsx(MdDateRange, {}), selectedDate !== undefined ? `${displayDate}` : ""] }) }), jsx(PopoverContent, { children: jsxs(PopoverBody, { children: [jsx(PopoverTitle, {}), jsx(DatePicker$1, { selected: new Date(selectedDate), onDateSelected: ({ date }) => {
|
|
4114
4146
|
setValue(colLabel, dayjs(date).format(dateFormat));
|
|
4115
4147
|
setOpen(false);
|
|
4116
|
-
}
|
|
4148
|
+
}, labels: {
|
|
4149
|
+
monthNamesShort: [
|
|
4150
|
+
translate.t(`common.month_1`, { defaultValue: "January" }),
|
|
4151
|
+
translate.t(`common.month_2`, { defaultValue: "February" }),
|
|
4152
|
+
translate.t(`common.month_3`, { defaultValue: "March" }),
|
|
4153
|
+
translate.t(`common.month_4`, { defaultValue: "April" }),
|
|
4154
|
+
translate.t(`common.month_5`, { defaultValue: "May" }),
|
|
4155
|
+
translate.t(`common.month_6`, { defaultValue: "June" }),
|
|
4156
|
+
translate.t(`common.month_7`, { defaultValue: "July" }),
|
|
4157
|
+
translate.t(`common.month_8`, { defaultValue: "August" }),
|
|
4158
|
+
translate.t(`common.month_9`, { defaultValue: "September" }),
|
|
4159
|
+
translate.t(`common.month_10`, { defaultValue: "October" }),
|
|
4160
|
+
translate.t(`common.month_11`, { defaultValue: "November" }),
|
|
4161
|
+
translate.t(`common.month_12`, { defaultValue: "December" }),
|
|
4162
|
+
],
|
|
4163
|
+
weekdayNamesShort: [
|
|
4164
|
+
translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
|
|
4165
|
+
translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
|
|
4166
|
+
translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
|
|
4167
|
+
translate.t(`common.weekday_4`, {
|
|
4168
|
+
defaultValue: "Wed",
|
|
4169
|
+
}),
|
|
4170
|
+
translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
|
|
4171
|
+
translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
|
|
4172
|
+
translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
|
|
4173
|
+
],
|
|
4174
|
+
backButtonLabel: translate.t(`common.back_button`, {
|
|
4175
|
+
defaultValue: "Back",
|
|
4176
|
+
}),
|
|
4177
|
+
forwardButtonLabel: translate.t(`common.forward_button`, {
|
|
4178
|
+
defaultValue: "Forward",
|
|
4179
|
+
}),
|
|
4180
|
+
} })] }) })] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: customTranslate(`field_required`) }))] }));
|
|
4117
4181
|
};
|
|
4118
4182
|
|
|
4119
4183
|
function filterArray(array, searchTerm) {
|
|
@@ -5096,22 +5160,23 @@ function TimePicker$1({ hour, setHour, minute, setMinute, meridiem, setMeridiem,
|
|
|
5096
5160
|
return (jsx(Flex, { direction: "column", gap: 3, children: jsxs(Grid, { justifyContent: "center", alignItems: "center", templateColumns: "60px 10px 60px 90px auto", gap: "2", width: "auto", minWidth: "250px", children: [jsx(Input, { ref: hourInputRef, type: "text", value: hour === null ? "" : hour.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "hour"), placeholder: "HH", maxLength: 2, textAlign: "center" }), jsx(Text, { children: ":" }), jsx(Input, { ref: minuteInputRef, type: "text", value: minute === null ? "" : minute.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "minute"), placeholder: "MM", maxLength: 2, textAlign: "center" }), jsxs(Flex, { gap: "1", children: [jsx(Button$1, { size: "sm", colorScheme: meridiem === "am" ? "blue" : "gray", variant: meridiem === "am" ? "solid" : "outline", onClick: () => handleMeridiemClick("am"), width: "40px", children: meridiemLabel.am }), jsx(Button$1, { size: "sm", colorScheme: meridiem === "pm" ? "blue" : "gray", variant: meridiem === "pm" ? "solid" : "outline", onClick: () => handleMeridiemClick("pm"), width: "40px", children: meridiemLabel.pm })] }), jsx(Button$1, { onClick: handleClear, size: "sm", variant: "ghost", children: jsx(MdCancel, {}) })] }) }));
|
|
5097
5161
|
}
|
|
5098
5162
|
|
|
5163
|
+
dayjs.extend(timezone);
|
|
5099
5164
|
const TimePicker = ({ column, schema, prefix }) => {
|
|
5100
5165
|
const { watch, formState: { errors }, setValue, } = useFormContext();
|
|
5101
|
-
const { translate } = useSchemaContext();
|
|
5102
|
-
const { required, gridColumn = "span 4", gridRow = "span 1", timeFormat = "HH:mm:
|
|
5166
|
+
const { translate, timezone } = useSchemaContext();
|
|
5167
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", timeFormat = "HH:mm:ssZ", displayTimeFormat = "hh:mm A", } = schema;
|
|
5103
5168
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
5104
5169
|
const colLabel = `${prefix}${column}`;
|
|
5105
5170
|
const [open, setOpen] = useState(false);
|
|
5106
5171
|
const value = watch(colLabel);
|
|
5107
|
-
const displayedTime = dayjs(`1970-01-01T${value}
|
|
5108
|
-
? dayjs(`1970-01-01T${value}
|
|
5172
|
+
const displayedTime = dayjs(`1970-01-01T${value}`).tz(timezone).isValid()
|
|
5173
|
+
? dayjs(`1970-01-01T${value}`).tz(timezone).format(displayTimeFormat)
|
|
5109
5174
|
: "";
|
|
5110
5175
|
// Parse the initial time parts from the ISO time string (HH:mm:ss)
|
|
5111
5176
|
const parseTime = (isoTime) => {
|
|
5112
5177
|
if (!isoTime)
|
|
5113
5178
|
return { hour: 12, minute: 0, meridiem: "am" };
|
|
5114
|
-
const parsed = dayjs(`1970-01-01T${isoTime}
|
|
5179
|
+
const parsed = dayjs(`1970-01-01T${isoTime}`).tz(timezone);
|
|
5115
5180
|
if (!parsed.isValid())
|
|
5116
5181
|
return { hour: 12, minute: 0, meridiem: "am" };
|
|
5117
5182
|
let hour = parsed.hour();
|
|
@@ -5142,8 +5207,8 @@ const TimePicker = ({ column, schema, prefix }) => {
|
|
|
5142
5207
|
h = 0;
|
|
5143
5208
|
else if (meridiem === "pm" && hour < 12)
|
|
5144
5209
|
h = hour + 12;
|
|
5145
|
-
return dayjs(`1970-01-01T${h.toString().padStart(2, "0")}:${minute.toString().padStart(2, "0")}:
|
|
5146
|
-
.
|
|
5210
|
+
return dayjs(`1970-01-01T${h.toString().padStart(2, "0")}:${minute.toString().padStart(2, "0")}:00`)
|
|
5211
|
+
.tz(timezone)
|
|
5147
5212
|
.format(timeFormat);
|
|
5148
5213
|
};
|
|
5149
5214
|
// Handle changes to time parts
|
|
@@ -5159,11 +5224,289 @@ const TimePicker = ({ column, schema, prefix }) => {
|
|
|
5159
5224
|
gridRow, children: [jsxs(Popover.Root, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsx(Popover.Trigger, { asChild: true, children: jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
|
|
5160
5225
|
setOpen(true);
|
|
5161
5226
|
}, justifyContent: "start", children: [jsx(IoMdClock, {}), !!value ? `${displayedTime}` : ""] }) }), jsx(Portal, { children: jsx(Popover.Positioner, { children: jsx(Popover.Content, { ref: containerRef, children: jsx(Popover.Body, { children: jsx(TimePicker$1, { hour: hour, setHour: setHour, minute: minute, setMinute: setMinute, meridiem: meridiem, setMeridiem: setMeridiem, onChange: handleTimeChange, meridiemLabel: {
|
|
5162
|
-
am: translate.t(
|
|
5163
|
-
pm: translate.t(
|
|
5227
|
+
am: translate.t(`common.am`, { defaultValue: "AM" }),
|
|
5228
|
+
pm: translate.t(`common.pm`, { defaultValue: "PM" }),
|
|
5164
5229
|
} }) }) }) }) })] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
5165
5230
|
};
|
|
5166
5231
|
|
|
5232
|
+
function IsoTimePicker({ hour, setHour, minute, setMinute, second, setSecond, onChange = (_newValue) => { }, }) {
|
|
5233
|
+
// Refs for focus management
|
|
5234
|
+
const hourInputRef = useRef(null);
|
|
5235
|
+
const minuteInputRef = useRef(null);
|
|
5236
|
+
const secondInputRef = useRef(null);
|
|
5237
|
+
// Centralized handler for key events, value changes, and focus management
|
|
5238
|
+
const handleKeyDown = (e, field) => {
|
|
5239
|
+
const input = e.target;
|
|
5240
|
+
const value = input.value;
|
|
5241
|
+
// Handle navigation between fields
|
|
5242
|
+
if (e.key === "Tab") {
|
|
5243
|
+
return;
|
|
5244
|
+
}
|
|
5245
|
+
if (e.key === ":" && field === "hour") {
|
|
5246
|
+
e.preventDefault();
|
|
5247
|
+
minuteInputRef.current?.focus();
|
|
5248
|
+
return;
|
|
5249
|
+
}
|
|
5250
|
+
if (e.key === ":" && field === "minute") {
|
|
5251
|
+
e.preventDefault();
|
|
5252
|
+
secondInputRef.current?.focus();
|
|
5253
|
+
return;
|
|
5254
|
+
}
|
|
5255
|
+
if (e.key === "Backspace" && value === "") {
|
|
5256
|
+
e.preventDefault();
|
|
5257
|
+
if (field === "minute") {
|
|
5258
|
+
hourInputRef.current?.focus();
|
|
5259
|
+
}
|
|
5260
|
+
else if (field === "second") {
|
|
5261
|
+
minuteInputRef.current?.focus();
|
|
5262
|
+
}
|
|
5263
|
+
return;
|
|
5264
|
+
}
|
|
5265
|
+
// Handle number inputs
|
|
5266
|
+
if (field === "hour") {
|
|
5267
|
+
if (e.key.match(/^[0-9]$/)) {
|
|
5268
|
+
const newValue = value + e.key;
|
|
5269
|
+
const numValue = parseInt(newValue, 10);
|
|
5270
|
+
if (numValue > 23) {
|
|
5271
|
+
const digitValue = parseInt(e.key, 10);
|
|
5272
|
+
setHour(digitValue);
|
|
5273
|
+
onChange({ hour: digitValue, minute, second });
|
|
5274
|
+
return;
|
|
5275
|
+
}
|
|
5276
|
+
if (numValue >= 0 && numValue <= 23) {
|
|
5277
|
+
setHour(numValue);
|
|
5278
|
+
onChange({ hour: numValue, minute, second });
|
|
5279
|
+
e.preventDefault();
|
|
5280
|
+
minuteInputRef.current?.focus();
|
|
5281
|
+
}
|
|
5282
|
+
}
|
|
5283
|
+
}
|
|
5284
|
+
else if (field === "minute") {
|
|
5285
|
+
if (e.key.match(/^[0-9]$/)) {
|
|
5286
|
+
const newValue = value + e.key;
|
|
5287
|
+
const numValue = parseInt(newValue, 10);
|
|
5288
|
+
if (numValue > 59) {
|
|
5289
|
+
const digitValue = parseInt(e.key, 10);
|
|
5290
|
+
setMinute(digitValue);
|
|
5291
|
+
onChange({ hour, minute: digitValue, second });
|
|
5292
|
+
return;
|
|
5293
|
+
}
|
|
5294
|
+
if (numValue >= 0 && numValue <= 59) {
|
|
5295
|
+
setMinute(numValue);
|
|
5296
|
+
onChange({ hour, minute: numValue, second });
|
|
5297
|
+
e.preventDefault();
|
|
5298
|
+
secondInputRef.current?.focus();
|
|
5299
|
+
}
|
|
5300
|
+
}
|
|
5301
|
+
}
|
|
5302
|
+
else if (field === "second") {
|
|
5303
|
+
if (e.key.match(/^[0-9]$/)) {
|
|
5304
|
+
const newValue = value + e.key;
|
|
5305
|
+
const numValue = parseInt(newValue, 10);
|
|
5306
|
+
if (numValue > 59) {
|
|
5307
|
+
const digitValue = parseInt(e.key, 10);
|
|
5308
|
+
setSecond(digitValue);
|
|
5309
|
+
onChange({ hour, minute, second: digitValue });
|
|
5310
|
+
return;
|
|
5311
|
+
}
|
|
5312
|
+
if (numValue >= 0 && numValue <= 59) {
|
|
5313
|
+
setSecond(numValue);
|
|
5314
|
+
onChange({ hour, minute, second: numValue });
|
|
5315
|
+
}
|
|
5316
|
+
}
|
|
5317
|
+
}
|
|
5318
|
+
};
|
|
5319
|
+
const handleClear = () => {
|
|
5320
|
+
setHour(null);
|
|
5321
|
+
setMinute(null);
|
|
5322
|
+
setSecond(null);
|
|
5323
|
+
onChange({ hour: null, minute: null, second: null });
|
|
5324
|
+
hourInputRef.current?.focus();
|
|
5325
|
+
};
|
|
5326
|
+
return (jsx(Flex, { direction: "column", gap: 3, children: jsxs(Grid, { justifyContent: "center", alignItems: "center", templateColumns: "60px 10px 60px 10px 60px auto", gap: "2", width: "auto", minWidth: "300px", children: [jsx(Input, { ref: hourInputRef, type: "text", value: hour === null ? "" : hour.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "hour"), placeholder: "HH", maxLength: 2, textAlign: "center" }), jsx(Text, { children: ":" }), jsx(Input, { ref: minuteInputRef, type: "text", value: minute === null ? "" : minute.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "minute"), placeholder: "MM", maxLength: 2, textAlign: "center" }), jsx(Text, { children: ":" }), jsx(Input, { ref: secondInputRef, type: "text", value: second === null ? "" : second.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "second"), placeholder: "SS", maxLength: 2, textAlign: "center" }), jsx(Button$1, { onClick: handleClear, size: "sm", variant: "ghost", children: jsx(MdCancel, {}) })] }) }));
|
|
5327
|
+
}
|
|
5328
|
+
|
|
5329
|
+
function DateTimePicker$1({ value, onChange, format = "date-time", showSeconds = false, labels = {
|
|
5330
|
+
monthNamesShort: [
|
|
5331
|
+
"Jan",
|
|
5332
|
+
"Feb",
|
|
5333
|
+
"Mar",
|
|
5334
|
+
"Apr",
|
|
5335
|
+
"May",
|
|
5336
|
+
"Jun",
|
|
5337
|
+
"Jul",
|
|
5338
|
+
"Aug",
|
|
5339
|
+
"Sep",
|
|
5340
|
+
"Oct",
|
|
5341
|
+
"Nov",
|
|
5342
|
+
"Dec",
|
|
5343
|
+
],
|
|
5344
|
+
weekdayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
|
|
5345
|
+
backButtonLabel: "Back",
|
|
5346
|
+
forwardButtonLabel: "Next",
|
|
5347
|
+
}, timezone = "Asia/Hong_Kong", }) {
|
|
5348
|
+
const [selectedDate, setSelectedDate] = useState(value || "");
|
|
5349
|
+
// Time state for 12-hour format
|
|
5350
|
+
const [hour12, setHour12] = useState(value ? dayjs(value).hour() % 12 || 12 : null);
|
|
5351
|
+
const [minute, setMinute] = useState(value ? dayjs(value).minute() : null);
|
|
5352
|
+
const [meridiem, setMeridiem] = useState(value ? (dayjs(value).hour() >= 12 ? "pm" : "am") : null);
|
|
5353
|
+
// Time state for 24-hour format
|
|
5354
|
+
const [hour24, setHour24] = useState(value ? dayjs(value).hour() : null);
|
|
5355
|
+
const [second, setSecond] = useState(value ? dayjs(value).second() : null);
|
|
5356
|
+
const handleDateChange = (date) => {
|
|
5357
|
+
setSelectedDate(date);
|
|
5358
|
+
updateDateTime(dayjs(date).tz(timezone).toISOString());
|
|
5359
|
+
};
|
|
5360
|
+
const handleTimeChange = (timeData) => {
|
|
5361
|
+
if (format === "iso-date-time") {
|
|
5362
|
+
setHour24(timeData.hour);
|
|
5363
|
+
setMinute(timeData.minute);
|
|
5364
|
+
if (showSeconds)
|
|
5365
|
+
setSecond(timeData.second);
|
|
5366
|
+
}
|
|
5367
|
+
else {
|
|
5368
|
+
setHour12(timeData.hour);
|
|
5369
|
+
setMinute(timeData.minute);
|
|
5370
|
+
setMeridiem(timeData.meridiem);
|
|
5371
|
+
}
|
|
5372
|
+
updateDateTime(dayjs(selectedDate).tz(timezone).toISOString(), timeData);
|
|
5373
|
+
};
|
|
5374
|
+
const updateDateTime = (date, timeData) => {
|
|
5375
|
+
if (!date) {
|
|
5376
|
+
onChange?.(undefined);
|
|
5377
|
+
return;
|
|
5378
|
+
}
|
|
5379
|
+
// use dayjs to convert the date to the timezone
|
|
5380
|
+
const newDate = dayjs(date).tz(timezone).toDate();
|
|
5381
|
+
if (format === "iso-date-time") {
|
|
5382
|
+
const h = timeData?.hour ?? hour24;
|
|
5383
|
+
const m = timeData?.minute ?? minute;
|
|
5384
|
+
const s = showSeconds ? timeData?.second ?? second : 0;
|
|
5385
|
+
if (h !== null)
|
|
5386
|
+
newDate.setHours(h);
|
|
5387
|
+
if (m !== null)
|
|
5388
|
+
newDate.setMinutes(m);
|
|
5389
|
+
if (s !== null)
|
|
5390
|
+
newDate.setSeconds(s);
|
|
5391
|
+
}
|
|
5392
|
+
else {
|
|
5393
|
+
const h = timeData?.hour ?? hour12;
|
|
5394
|
+
const m = timeData?.minute ?? minute;
|
|
5395
|
+
const mer = timeData?.meridiem ?? meridiem;
|
|
5396
|
+
if (h !== null && mer !== null) {
|
|
5397
|
+
let hour24 = h;
|
|
5398
|
+
if (mer === "am" && h === 12)
|
|
5399
|
+
hour24 = 0;
|
|
5400
|
+
else if (mer === "pm" && h < 12)
|
|
5401
|
+
hour24 = h + 12;
|
|
5402
|
+
newDate.setHours(hour24);
|
|
5403
|
+
}
|
|
5404
|
+
if (m !== null)
|
|
5405
|
+
newDate.setMinutes(m);
|
|
5406
|
+
newDate.setSeconds(0);
|
|
5407
|
+
}
|
|
5408
|
+
onChange?.(dayjs(newDate).tz(timezone).toISOString());
|
|
5409
|
+
};
|
|
5410
|
+
const handleClear = () => {
|
|
5411
|
+
setSelectedDate("");
|
|
5412
|
+
setHour12(null);
|
|
5413
|
+
setHour24(null);
|
|
5414
|
+
setMinute(null);
|
|
5415
|
+
setSecond(null);
|
|
5416
|
+
setMeridiem(null);
|
|
5417
|
+
onChange?.(undefined);
|
|
5418
|
+
};
|
|
5419
|
+
const isISO = format === "iso-date-time";
|
|
5420
|
+
return (jsxs(Flex, { direction: "column", gap: 4, p: 4, border: "1px solid", borderColor: "gray.200", borderRadius: "md", children: [jsx(DatePicker$1, { selected: selectedDate
|
|
5421
|
+
? dayjs(selectedDate).tz(timezone).toDate()
|
|
5422
|
+
: new Date(), onDateSelected: ({ date }) => handleDateChange(dayjs(date).tz(timezone).toISOString()), monthsToDisplay: 1, labels: labels }), jsxs(Grid, { templateColumns: "1fr auto", alignItems: "center", gap: 4, children: [isISO ? (jsx(IsoTimePicker, { hour: hour24, setHour: setHour24, minute: minute, setMinute: setMinute, second: second, setSecond: setSecond, onChange: handleTimeChange })) : (jsx(TimePicker$1, { hour: hour12, setHour: setHour12, minute: minute, setMinute: setMinute, meridiem: meridiem, setMeridiem: setMeridiem, onChange: handleTimeChange })), jsx(Button$1, { onClick: handleClear, size: "sm", variant: "outline", colorScheme: "red", children: jsx(Icon, { as: FaTrash }) })] }), selectedDate && (jsxs(Flex, { gap: 2, children: [jsx(Text, { fontSize: "sm", color: { base: "gray.600", _dark: "gray.600" }, children: dayjs(value).format(isISO
|
|
5423
|
+
? showSeconds
|
|
5424
|
+
? "YYYY-MM-DD HH:mm:ss"
|
|
5425
|
+
: "YYYY-MM-DD HH:mm"
|
|
5426
|
+
: "YYYY-MM-DD hh:mm A ") }), jsx(Text, { fontSize: "sm", color: { base: "gray.600", _dark: "gray.600" }, children: dayjs(value).tz(timezone).format("Z") }), jsx(Text, { fontSize: "sm", color: { base: "gray.600", _dark: "gray.600" }, children: timezone })] }))] }));
|
|
5427
|
+
}
|
|
5428
|
+
|
|
5429
|
+
dayjs.extend(utc);
|
|
5430
|
+
dayjs.extend(timezone);
|
|
5431
|
+
const DateTimePicker = ({ column, schema, prefix, }) => {
|
|
5432
|
+
const { watch, formState: { errors }, setValue, } = useFormContext();
|
|
5433
|
+
const { translate, timezone } = useSchemaContext();
|
|
5434
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD HH:mm:ss",
|
|
5435
|
+
// with timezone
|
|
5436
|
+
dateFormat = "YYYY-MM-DD[T]HH:mm:ssZ", } = schema;
|
|
5437
|
+
const isRequired = required?.some((columnId) => columnId === column);
|
|
5438
|
+
const colLabel = `${prefix}${column}`;
|
|
5439
|
+
const [open, setOpen] = useState(false);
|
|
5440
|
+
const selectedDate = watch(colLabel);
|
|
5441
|
+
const displayDate = dayjs(selectedDate)
|
|
5442
|
+
.tz(timezone)
|
|
5443
|
+
.format(displayDateFormat);
|
|
5444
|
+
useEffect(() => {
|
|
5445
|
+
try {
|
|
5446
|
+
if (selectedDate) {
|
|
5447
|
+
// Parse the selectedDate as UTC or in a specific timezone to avoid +8 hour shift
|
|
5448
|
+
// For example, parse as UTC:
|
|
5449
|
+
const parsedDate = dayjs(selectedDate).tz(timezone);
|
|
5450
|
+
if (!parsedDate.isValid())
|
|
5451
|
+
return;
|
|
5452
|
+
// Format according to dateFormat from schema
|
|
5453
|
+
const formatted = parsedDate.format(dateFormat);
|
|
5454
|
+
// Update the form value only if different to avoid loops
|
|
5455
|
+
if (formatted !== selectedDate) {
|
|
5456
|
+
setValue(colLabel, formatted, {
|
|
5457
|
+
shouldValidate: true,
|
|
5458
|
+
shouldDirty: true,
|
|
5459
|
+
});
|
|
5460
|
+
}
|
|
5461
|
+
}
|
|
5462
|
+
}
|
|
5463
|
+
catch (e) {
|
|
5464
|
+
console.error(e);
|
|
5465
|
+
}
|
|
5466
|
+
}, [selectedDate, dateFormat, colLabel, setValue]);
|
|
5467
|
+
const customTranslate = (label) => {
|
|
5468
|
+
return translateWrapper({ prefix, column, label, translate });
|
|
5469
|
+
};
|
|
5470
|
+
return (jsxs(Field, { label: `${customTranslate(`field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
5471
|
+
gridRow, children: [jsxs(PopoverRoot, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsx(PopoverTrigger, { asChild: true, children: jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
|
|
5472
|
+
setOpen(true);
|
|
5473
|
+
}, justifyContent: "start", children: [jsx(MdDateRange, {}), selectedDate !== undefined ? `${displayDate}` : ""] }) }), jsx(PopoverContent, { minW: "450px", children: jsxs(PopoverBody, { children: [jsx(PopoverTitle, {}), jsx(DateTimePicker$1, { value: selectedDate, onChange: (date) => {
|
|
5474
|
+
setValue(colLabel, dayjs(date).tz(timezone).format(dateFormat));
|
|
5475
|
+
}, timezone: timezone, labels: {
|
|
5476
|
+
monthNamesShort: [
|
|
5477
|
+
translate.t(`common.month_1`, { defaultValue: "January" }),
|
|
5478
|
+
translate.t(`common.month_2`, { defaultValue: "February" }),
|
|
5479
|
+
translate.t(`common.month_3`, { defaultValue: "March" }),
|
|
5480
|
+
translate.t(`common.month_4`, { defaultValue: "April" }),
|
|
5481
|
+
translate.t(`common.month_5`, { defaultValue: "May" }),
|
|
5482
|
+
translate.t(`common.month_6`, { defaultValue: "June" }),
|
|
5483
|
+
translate.t(`common.month_7`, { defaultValue: "July" }),
|
|
5484
|
+
translate.t(`common.month_8`, { defaultValue: "August" }),
|
|
5485
|
+
translate.t(`common.month_9`, { defaultValue: "September" }),
|
|
5486
|
+
translate.t(`common.month_10`, { defaultValue: "October" }),
|
|
5487
|
+
translate.t(`common.month_11`, { defaultValue: "November" }),
|
|
5488
|
+
translate.t(`common.month_12`, { defaultValue: "December" }),
|
|
5489
|
+
],
|
|
5490
|
+
weekdayNamesShort: [
|
|
5491
|
+
translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
|
|
5492
|
+
translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
|
|
5493
|
+
translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
|
|
5494
|
+
translate.t(`common.weekday_4`, {
|
|
5495
|
+
defaultValue: "Wed",
|
|
5496
|
+
}),
|
|
5497
|
+
translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
|
|
5498
|
+
translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
|
|
5499
|
+
translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
|
|
5500
|
+
],
|
|
5501
|
+
backButtonLabel: translate.t(`common.back_button`, {
|
|
5502
|
+
defaultValue: "Back",
|
|
5503
|
+
}),
|
|
5504
|
+
forwardButtonLabel: translate.t(`common.forward_button`, {
|
|
5505
|
+
defaultValue: "Forward",
|
|
5506
|
+
}),
|
|
5507
|
+
} })] }) })] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: customTranslate(`field_required`) }))] }));
|
|
5508
|
+
};
|
|
5509
|
+
|
|
5167
5510
|
const SchemaRenderer = ({ schema, prefix, column, }) => {
|
|
5168
5511
|
const colSchema = schema;
|
|
5169
5512
|
const { type, variant, properties: innerProperties, foreign_key, format, items, } = schema;
|
|
@@ -5184,6 +5527,9 @@ const SchemaRenderer = ({ schema, prefix, column, }) => {
|
|
|
5184
5527
|
if (format === "time") {
|
|
5185
5528
|
return jsx(TimePicker, { schema: colSchema, prefix, column });
|
|
5186
5529
|
}
|
|
5530
|
+
if (format === "date-time") {
|
|
5531
|
+
return jsx(DateTimePicker, { schema: colSchema, prefix, column });
|
|
5532
|
+
}
|
|
5187
5533
|
if (variant === "text-area") {
|
|
5188
5534
|
return jsx(TextAreaInput, { schema: colSchema, prefix, column });
|
|
5189
5535
|
}
|
|
@@ -5275,20 +5621,16 @@ const CustomViewer = ({ column, schema, prefix }) => {
|
|
|
5275
5621
|
|
|
5276
5622
|
const DateViewer = ({ column, schema, prefix }) => {
|
|
5277
5623
|
const { watch, formState: { errors }, } = useFormContext();
|
|
5278
|
-
const { translate } = useSchemaContext();
|
|
5624
|
+
const { translate, timezone } = useSchemaContext();
|
|
5279
5625
|
const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD", } = schema;
|
|
5280
5626
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
5281
5627
|
const colLabel = `${prefix}${column}`;
|
|
5282
5628
|
const selectedDate = watch(colLabel);
|
|
5283
|
-
const displayDate = dayjs
|
|
5629
|
+
const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
|
|
5284
5630
|
return (jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
5285
5631
|
gridRow, children: [jsxs(Text, { children: [" ", selectedDate !== undefined ? displayDate : ""] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
|
|
5286
5632
|
};
|
|
5287
5633
|
|
|
5288
|
-
function translateWrapper({ prefix, column, label, translate, }) {
|
|
5289
|
-
return translate.t(removeIndex(`${prefix}${column}.${label}`));
|
|
5290
|
-
}
|
|
5291
|
-
|
|
5292
5634
|
const EnumViewer = ({ column, isMultiple = false, schema, prefix, }) => {
|
|
5293
5635
|
const { watch, formState: { errors }, } = useFormContext();
|
|
5294
5636
|
const { translate } = useSchemaContext();
|
|
@@ -5544,20 +5886,34 @@ const TextAreaViewer = ({ column, schema, prefix, }) => {
|
|
|
5544
5886
|
return (jsx(Fragment, { children: jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn: gridColumn, gridRow: gridRow, children: [jsx(Text, { whiteSpace: "pre-wrap", children: value }), " ", errors[colLabel] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }) }));
|
|
5545
5887
|
};
|
|
5546
5888
|
|
|
5547
|
-
const TimeViewer = ({ column, schema, prefix
|
|
5889
|
+
const TimeViewer = ({ column, schema, prefix }) => {
|
|
5548
5890
|
const { watch, formState: { errors }, } = useFormContext();
|
|
5549
|
-
const { translate } = useSchemaContext();
|
|
5550
|
-
const { required, gridColumn = "span 4", gridRow = "span 1", displayTimeFormat = "hh:mm A" } = schema;
|
|
5891
|
+
const { translate, timezone } = useSchemaContext();
|
|
5892
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", displayTimeFormat = "hh:mm A", } = schema;
|
|
5551
5893
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
5552
5894
|
const colLabel = `${prefix}${column}`;
|
|
5553
5895
|
const selectedDate = watch(colLabel);
|
|
5554
|
-
const displayedTime = dayjs(`1970-01-01T${selectedDate}
|
|
5555
|
-
|
|
5896
|
+
const displayedTime = dayjs(`1970-01-01T${selectedDate}`)
|
|
5897
|
+
.tz(timezone)
|
|
5898
|
+
.isValid()
|
|
5899
|
+
? dayjs(`1970-01-01T${selectedDate}`).tz(timezone).format(displayTimeFormat)
|
|
5556
5900
|
: "";
|
|
5557
5901
|
return (jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
5558
5902
|
gridRow, children: [jsx(Text, { children: displayedTime }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
|
|
5559
5903
|
};
|
|
5560
5904
|
|
|
5905
|
+
const DateTimeViewer = ({ column, schema, prefix }) => {
|
|
5906
|
+
const { watch, formState: { errors }, } = useFormContext();
|
|
5907
|
+
const { translate, timezone } = useSchemaContext();
|
|
5908
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD HH:mm:ss", } = schema;
|
|
5909
|
+
const isRequired = required?.some((columnId) => columnId === column);
|
|
5910
|
+
const colLabel = `${prefix}${column}`;
|
|
5911
|
+
const selectedDate = watch(colLabel);
|
|
5912
|
+
const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
|
|
5913
|
+
return (jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
5914
|
+
gridRow, children: [jsxs(Text, { children: [" ", selectedDate !== undefined ? displayDate : ""] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
|
|
5915
|
+
};
|
|
5916
|
+
|
|
5561
5917
|
const SchemaViewer = ({ schema, prefix, column, }) => {
|
|
5562
5918
|
const colSchema = schema;
|
|
5563
5919
|
const { type, variant, properties: innerProperties, foreign_key, items, format, } = schema;
|
|
@@ -5578,6 +5934,9 @@ const SchemaViewer = ({ schema, prefix, column, }) => {
|
|
|
5578
5934
|
if (format === "date") {
|
|
5579
5935
|
return jsx(DateViewer, { schema: colSchema, prefix, column });
|
|
5580
5936
|
}
|
|
5937
|
+
if (format === "date-time") {
|
|
5938
|
+
return jsx(DateTimeViewer, { schema: colSchema, prefix, column });
|
|
5939
|
+
}
|
|
5581
5940
|
if (variant === "text-area") {
|
|
5582
5941
|
return jsx(TextAreaViewer, { schema: colSchema, prefix, column });
|
|
5583
5942
|
}
|