@bsol-oss/react-datatable5 12.0.0-beta.7 → 12.0.0-beta.70
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/README.md +192 -0
- package/dist/index.d.ts +277 -83
- package/dist/index.js +1577 -469
- package/dist/index.mjs +1585 -477
- package/dist/types/components/DataTable/DataTable.d.ts +3 -1
- package/dist/types/components/DataTable/DataTableServer.d.ts +6 -4
- package/dist/types/components/DataTable/DefaultTable.d.ts +6 -9
- package/dist/types/components/DataTable/context/DataTableContext.d.ts +21 -3
- package/dist/types/components/DataTable/context/useDataTableContext.d.ts +2 -2
- package/dist/types/components/DataTable/controls/ReloadButton.d.ts +1 -2
- package/dist/types/components/DataTable/controls/ResetFilteringButton.d.ts +1 -4
- package/dist/types/components/DataTable/controls/ResetSelectionButton.d.ts +1 -4
- package/dist/types/components/DataTable/controls/ResetSortingButton.d.ts +1 -4
- package/dist/types/components/DataTable/controls/TableControls.d.ts +10 -2
- package/dist/types/components/DataTable/display/TableBody.d.ts +1 -2
- package/dist/types/components/DataTable/display/TableCardContainer.d.ts +6 -3
- package/dist/types/components/DataTable/display/TableDataDisplay.d.ts +6 -1
- package/dist/types/components/DataTable/display/TableFooter.d.ts +1 -5
- package/dist/types/components/DataTable/display/TableHeader.d.ts +46 -8
- package/dist/types/components/DataTable/useDataTableServer.d.ts +55 -3
- 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/Filter/TagFilter.d.ts +5 -1
- package/dist/types/components/Form/SchemaFormContext.d.ts +8 -1
- package/dist/types/components/Form/components/core/DefaultForm.d.ts +1 -0
- package/dist/types/components/Form/components/core/FormRoot.d.ts +9 -2
- package/dist/types/components/Form/components/fields/CustomInput.d.ts +8 -0
- package/dist/types/components/Form/components/fields/DatePicker.d.ts +2 -7
- package/dist/types/components/Form/components/fields/DateTimePicker.d.ts +2 -0
- package/dist/types/components/Form/components/fields/EnumPicker.d.ts +2 -1
- package/dist/types/components/Form/components/fields/FilePicker.d.ts +2 -5
- package/dist/types/components/Form/components/fields/StringInputField.d.ts +19 -5
- package/dist/types/components/Form/components/fields/TextAreaInput.d.ts +12 -0
- package/dist/types/components/Form/components/fields/TimePicker.d.ts +7 -0
- package/dist/types/components/Form/components/fields/types.d.ts +6 -0
- package/dist/types/components/Form/components/types/CustomJSONSchema7.d.ts +19 -1
- package/dist/types/components/Form/components/viewers/CustomViewer.d.ts +8 -0
- package/dist/types/components/Form/components/viewers/DateTimeViewer.d.ts +7 -0
- package/dist/types/components/Form/components/viewers/TextAreaViewer.d.ts +12 -0
- package/dist/types/components/Form/components/viewers/TimeViewer.d.ts +7 -0
- package/dist/types/components/Form/utils/translateWrapper.d.ts +6 -0
- package/dist/types/components/Form/utils/validateData.d.ts +9 -0
- package/dist/types/components/Form/utils/validation.d.ts +104 -0
- package/dist/types/components/TextArea/TextArea.d.ts +22 -0
- package/dist/types/components/TimePicker/TimePicker.d.ts +21 -0
- package/dist/types/index.d.ts +17 -2
- package/package.json +9 -2
package/dist/index.js
CHANGED
|
@@ -29,7 +29,12 @@ var gr = require('react-icons/gr');
|
|
|
29
29
|
var reactI18next = require('react-i18next');
|
|
30
30
|
var axios = require('axios');
|
|
31
31
|
var reactHookForm = require('react-hook-form');
|
|
32
|
+
var Ajv = require('ajv');
|
|
33
|
+
var addFormats = require('ajv-formats');
|
|
34
|
+
var addErrors = require('ajv-errors');
|
|
32
35
|
var dayjs = require('dayjs');
|
|
36
|
+
var utc = require('dayjs/plugin/utc');
|
|
37
|
+
var timezone = require('dayjs/plugin/timezone');
|
|
33
38
|
var ti = require('react-icons/ti');
|
|
34
39
|
|
|
35
40
|
function _interopNamespaceDefault(e) {
|
|
@@ -57,6 +62,56 @@ const DataTableContext = React.createContext({
|
|
|
57
62
|
setGlobalFilter: () => { },
|
|
58
63
|
type: "client",
|
|
59
64
|
translate: {},
|
|
65
|
+
data: [],
|
|
66
|
+
columns: [],
|
|
67
|
+
columnOrder: [],
|
|
68
|
+
columnFilters: [],
|
|
69
|
+
density: "sm",
|
|
70
|
+
sorting: [],
|
|
71
|
+
setPagination: function () {
|
|
72
|
+
throw new Error("Function not implemented.");
|
|
73
|
+
},
|
|
74
|
+
setSorting: function () {
|
|
75
|
+
throw new Error("Function not implemented.");
|
|
76
|
+
},
|
|
77
|
+
setColumnFilters: function () {
|
|
78
|
+
throw new Error("Function not implemented.");
|
|
79
|
+
},
|
|
80
|
+
setRowSelection: function () {
|
|
81
|
+
throw new Error("Function not implemented.");
|
|
82
|
+
},
|
|
83
|
+
setColumnOrder: function () {
|
|
84
|
+
throw new Error("Function not implemented.");
|
|
85
|
+
},
|
|
86
|
+
setDensity: function () {
|
|
87
|
+
throw new Error("Function not implemented.");
|
|
88
|
+
},
|
|
89
|
+
setColumnVisibility: function () {
|
|
90
|
+
throw new Error("Function not implemented.");
|
|
91
|
+
},
|
|
92
|
+
pagination: {
|
|
93
|
+
pageIndex: 0,
|
|
94
|
+
pageSize: 10,
|
|
95
|
+
},
|
|
96
|
+
rowSelection: {},
|
|
97
|
+
columnVisibility: {},
|
|
98
|
+
tableLabel: {
|
|
99
|
+
view: "View",
|
|
100
|
+
edit: "Edit",
|
|
101
|
+
filterButtonText: "Filter",
|
|
102
|
+
filterTitle: "Filter",
|
|
103
|
+
filterReset: "Reset",
|
|
104
|
+
filterClose: "Close",
|
|
105
|
+
reloadTooltip: "Reload",
|
|
106
|
+
reloadButtonText: "Reload",
|
|
107
|
+
resetSelection: "Reset Selection",
|
|
108
|
+
resetSorting: "Reset Sorting",
|
|
109
|
+
rowCountText: "Row Count",
|
|
110
|
+
hasErrorText: "Has Error",
|
|
111
|
+
globalFilterPlaceholder: "Search",
|
|
112
|
+
trueLabel: "True",
|
|
113
|
+
falseLabel: "False",
|
|
114
|
+
},
|
|
60
115
|
});
|
|
61
116
|
|
|
62
117
|
const useDataTableContext = () => {
|
|
@@ -112,11 +167,13 @@ const TableSorter = () => {
|
|
|
112
167
|
}) }))) }));
|
|
113
168
|
};
|
|
114
169
|
|
|
115
|
-
const ResetSortingButton = (
|
|
170
|
+
const ResetSortingButton = () => {
|
|
116
171
|
const { table } = useDataTableContext();
|
|
172
|
+
const { tableLabel } = useDataTableContext();
|
|
173
|
+
const { resetSorting } = tableLabel;
|
|
117
174
|
return (jsxRuntime.jsx(react.Button, { onClick: () => {
|
|
118
175
|
table.resetSorting();
|
|
119
|
-
}, children:
|
|
176
|
+
}, children: resetSorting }));
|
|
120
177
|
};
|
|
121
178
|
|
|
122
179
|
const EditSortingButton = ({ text, icon = jsxRuntime.jsx(md.MdOutlineSort, {}), title = "Edit Sorting", }) => {
|
|
@@ -144,7 +201,7 @@ const monthNamesFull = [
|
|
|
144
201
|
"November",
|
|
145
202
|
"December",
|
|
146
203
|
];
|
|
147
|
-
const weekdayNamesShort
|
|
204
|
+
const weekdayNamesShort = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
148
205
|
function Calendar$1({ calendars, getBackProps, getForwardProps, getDateProps, selected = [], firstDayOfWeek = 0, }) {
|
|
149
206
|
const [hoveredDate, setHoveredDate] = React.useState();
|
|
150
207
|
const onMouseLeave = () => {
|
|
@@ -179,7 +236,7 @@ function Calendar$1({ calendars, getBackProps, getForwardProps, getDateProps, se
|
|
|
179
236
|
offset: 12,
|
|
180
237
|
}), children: ">>" })] }), jsxRuntime.jsx(react.Grid, { templateColumns: "repeat(2, auto)", justifyContent: "center", gap: 4, children: calendars.map((calendar) => (jsxRuntime.jsxs(react.Grid, { gap: 4, children: [jsxRuntime.jsxs(react.Grid, { justifyContent: "center", children: [monthNamesFull[calendar.month], " ", calendar.year] }), jsxRuntime.jsx(react.Grid, { templateColumns: "repeat(7, auto)", justifyContent: "center", children: [0, 1, 2, 3, 4, 5, 6].map((weekdayNum) => {
|
|
181
238
|
const weekday = (weekdayNum + firstDayOfWeek) % 7;
|
|
182
|
-
return (jsxRuntime.jsx(react.Box, { minWidth: "48px", textAlign: "center", children: weekdayNamesShort
|
|
239
|
+
return (jsxRuntime.jsx(react.Box, { minWidth: "48px", textAlign: "center", children: weekdayNamesShort[weekday] }, `${calendar.month}${calendar.year}${weekday}`));
|
|
183
240
|
}) }), jsxRuntime.jsx(react.Grid, { templateColumns: "repeat(7, auto)", justifyContent: "center", children: calendar.weeks.map((week, windex) => week.map((dateObj, index) => {
|
|
184
241
|
const key = `${calendar.month}${calendar.year}${windex}${index}`;
|
|
185
242
|
if (!dateObj) {
|
|
@@ -300,8 +357,17 @@ const Tag = React__namespace.forwardRef(function Tag(props, ref) {
|
|
|
300
357
|
return (jsxRuntime.jsxs(react.Tag.Root, { ref: ref, ...rest, children: [startElement && (jsxRuntime.jsx(react.Tag.StartElement, { children: startElement })), jsxRuntime.jsx(react.Tag.Label, { children: children }), endElement && (jsxRuntime.jsx(react.Tag.EndElement, { children: endElement })), closable && (jsxRuntime.jsx(react.Tag.EndElement, { children: jsxRuntime.jsx(react.Tag.CloseTrigger, { onClick: onClose }) }))] }));
|
|
301
358
|
});
|
|
302
359
|
|
|
303
|
-
const TagFilter = ({ availableTags, selectedTags, onTagChange, }) => {
|
|
360
|
+
const TagFilter = ({ availableTags, selectedTags, onTagChange, selectOne = false, }) => {
|
|
304
361
|
const toggleTag = (tag) => {
|
|
362
|
+
if (selectOne) {
|
|
363
|
+
if (selectedTags.includes(tag)) {
|
|
364
|
+
onTagChange([]);
|
|
365
|
+
}
|
|
366
|
+
else {
|
|
367
|
+
onTagChange([tag]);
|
|
368
|
+
}
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
305
371
|
if (selectedTags.includes(tag)) {
|
|
306
372
|
onTagChange(selectedTags.filter((t) => t !== tag));
|
|
307
373
|
}
|
|
@@ -309,10 +375,14 @@ const TagFilter = ({ availableTags, selectedTags, onTagChange, }) => {
|
|
|
309
375
|
onTagChange([...selectedTags, tag]);
|
|
310
376
|
}
|
|
311
377
|
};
|
|
312
|
-
return (jsxRuntime.jsx(react.Flex, { flexFlow: "wrap", p: "0.5rem", gap: "0.5rem", children: availableTags.map((tag) =>
|
|
378
|
+
return (jsxRuntime.jsx(react.Flex, { flexFlow: "wrap", p: "0.5rem", gap: "0.5rem", children: availableTags.map((tag) => {
|
|
379
|
+
const { label, value } = tag;
|
|
380
|
+
return (jsxRuntime.jsx(Tag, { variant: selectedTags.includes(value) ? "solid" : "outline", cursor: "pointer", closable: selectedTags.includes(value) ? true : undefined, onClick: () => toggleTag(value), children: label ?? value }));
|
|
381
|
+
}) }));
|
|
313
382
|
};
|
|
314
383
|
|
|
315
384
|
const Filter = ({ column }) => {
|
|
385
|
+
const { tableLabel } = useDataTableContext();
|
|
316
386
|
const { filterVariant } = column.columnDef.meta ?? {};
|
|
317
387
|
const displayName = column.columnDef.meta?.displayName ?? column.id;
|
|
318
388
|
const filterOptions = column.columnDef.meta?.filterOptions ?? [];
|
|
@@ -327,10 +397,14 @@ const Filter = ({ column }) => {
|
|
|
327
397
|
if (filterVariant === "select") {
|
|
328
398
|
return (jsxRuntime.jsxs(react.Flex, { flexFlow: "column", gap: "0.25rem", children: [jsxRuntime.jsx(react.Text, { children: displayName }), jsxRuntime.jsx(RadioGroup, { value: column.getFilterValue() ? String(column.getFilterValue()) : "", onValueChange: (details) => {
|
|
329
399
|
column.setFilterValue(details.value);
|
|
330
|
-
}, children: jsxRuntime.
|
|
400
|
+
}, children: jsxRuntime.jsxs(react.Flex, { flexFlow: "wrap", gap: "0.5rem", children: [filterOptions.length === 0 && jsxRuntime.jsx(react.Text, { children: "No filter options" }), filterOptions.length > 0 &&
|
|
401
|
+
filterOptions.map((item) => (jsxRuntime.jsx(Radio, { value: item.value, children: item.label }, item.value)))] }) })] }, column.id));
|
|
331
402
|
}
|
|
332
403
|
if (filterVariant === "tag") {
|
|
333
|
-
return (jsxRuntime.jsxs(react.Flex, { flexFlow: "column", gap: "0.25rem", children: [jsxRuntime.jsx(react.Text, { children: displayName }), jsxRuntime.jsx(TagFilter, { availableTags: filterOptions
|
|
404
|
+
return (jsxRuntime.jsxs(react.Flex, { flexFlow: "column", gap: "0.25rem", children: [jsxRuntime.jsx(react.Text, { children: displayName }), jsxRuntime.jsx(TagFilter, { availableTags: filterOptions.map((item) => ({
|
|
405
|
+
label: item.label,
|
|
406
|
+
value: item.value,
|
|
407
|
+
})), selectedTags: (column.getFilterValue() ?? []), onTagChange: (tags) => {
|
|
334
408
|
if (tags.length === 0) {
|
|
335
409
|
return column.setFilterValue(undefined);
|
|
336
410
|
}
|
|
@@ -338,7 +412,11 @@ const Filter = ({ column }) => {
|
|
|
338
412
|
} })] }, column.id));
|
|
339
413
|
}
|
|
340
414
|
if (filterVariant === "boolean") {
|
|
341
|
-
|
|
415
|
+
const { trueLabel, falseLabel } = tableLabel;
|
|
416
|
+
return (jsxRuntime.jsxs(react.Flex, { flexFlow: "column", gap: "0.25rem", children: [jsxRuntime.jsx(react.Text, { children: displayName }), jsxRuntime.jsx(TagFilter, { availableTags: [
|
|
417
|
+
{ label: trueLabel, value: "true" },
|
|
418
|
+
{ label: falseLabel, value: "false" },
|
|
419
|
+
], selectedTags: (column.getFilterValue() ?? []), onTagChange: (tags) => {
|
|
342
420
|
if (tags.length === 0) {
|
|
343
421
|
return column.setFilterValue(undefined);
|
|
344
422
|
}
|
|
@@ -393,17 +471,20 @@ const TableFilter = () => {
|
|
|
393
471
|
}) }));
|
|
394
472
|
};
|
|
395
473
|
|
|
396
|
-
const ResetFilteringButton = (
|
|
474
|
+
const ResetFilteringButton = () => {
|
|
397
475
|
const { table } = useDataTableContext();
|
|
476
|
+
const { tableLabel } = useDataTableContext();
|
|
477
|
+
const { filterReset } = tableLabel;
|
|
398
478
|
return (jsxRuntime.jsx(react.Button, { onClick: () => {
|
|
399
479
|
table.resetColumnFilters();
|
|
400
|
-
}, children:
|
|
480
|
+
}, children: filterReset }));
|
|
401
481
|
};
|
|
402
482
|
|
|
403
483
|
const FilterDialog = ({ icon = jsxRuntime.jsx(md.MdFilterAlt, {}), }) => {
|
|
404
484
|
const filterModal = react.useDisclosure();
|
|
405
|
-
const {
|
|
406
|
-
|
|
485
|
+
const { tableLabel } = useDataTableContext();
|
|
486
|
+
const { filterButtonText, filterTitle, filterClose } = tableLabel;
|
|
487
|
+
return (jsxRuntime.jsxs(DialogRoot, { size: ["full", "full", "md", "md"], open: filterModal.open, children: [jsxRuntime.jsx(DialogTrigger, { asChild: true, children: jsxRuntime.jsxs(react.Button, { as: react.Box, variant: "ghost", onClick: filterModal.onOpen, children: [icon, " ", filterButtonText] }) }), jsxRuntime.jsxs(DialogContent, { children: [jsxRuntime.jsx(DialogHeader, { children: jsxRuntime.jsx(DialogTitle, { children: filterTitle }) }), jsxRuntime.jsx(DialogBody, { display: "flex", flexFlow: "column", children: jsxRuntime.jsx(TableFilter, {}) }), jsxRuntime.jsxs(DialogFooter, { children: [jsxRuntime.jsx(ResetFilteringButton, {}), jsxRuntime.jsx(react.Button, { onClick: filterModal.onClose, variant: "subtle", children: filterClose })] }), jsxRuntime.jsx(DialogCloseTrigger, { onClick: filterModal.onClose })] })] }));
|
|
407
488
|
};
|
|
408
489
|
|
|
409
490
|
const MenuContent = React__namespace.forwardRef(function MenuContent(props, ref) {
|
|
@@ -522,11 +603,13 @@ const Pagination = () => {
|
|
|
522
603
|
}, children: jsxRuntime.jsxs(react.HStack, { children: [jsxRuntime.jsx(PaginationPrevTrigger, {}), jsxRuntime.jsx(PaginationItems, {}), jsxRuntime.jsx(PaginationNextTrigger, {})] }) }));
|
|
523
604
|
};
|
|
524
605
|
|
|
525
|
-
const ResetSelectionButton = (
|
|
606
|
+
const ResetSelectionButton = () => {
|
|
526
607
|
const { table } = useDataTableContext();
|
|
608
|
+
const { tableLabel } = useDataTableContext();
|
|
609
|
+
const { resetSelection } = tableLabel;
|
|
527
610
|
return (jsxRuntime.jsx(react.Button, { onClick: () => {
|
|
528
611
|
table.resetRowSelection();
|
|
529
|
-
}, children:
|
|
612
|
+
}, children: resetSelection }));
|
|
530
613
|
};
|
|
531
614
|
|
|
532
615
|
const RowCountText = () => {
|
|
@@ -2441,8 +2524,8 @@ react.CheckboxCard.Indicator;
|
|
|
2441
2524
|
function ColumnCard({ columnId }) {
|
|
2442
2525
|
const ref = React.useRef(null);
|
|
2443
2526
|
const [dragging, setDragging] = React.useState(false); // NEW
|
|
2444
|
-
const { table } = useDataTableContext();
|
|
2445
|
-
const displayName = columnId;
|
|
2527
|
+
const { table, translate } = useDataTableContext();
|
|
2528
|
+
const displayName = translate.t(columnId);
|
|
2446
2529
|
const column = table.getColumn(columnId);
|
|
2447
2530
|
invariant(column);
|
|
2448
2531
|
React.useEffect(() => {
|
|
@@ -2457,7 +2540,7 @@ function ColumnCard({ columnId }) {
|
|
|
2457
2540
|
onDrop: () => setDragging(false), // NEW
|
|
2458
2541
|
});
|
|
2459
2542
|
}, [columnId, table]);
|
|
2460
|
-
return (jsxRuntime.jsxs(react.Grid, { ref: ref, templateColumns: "auto 1fr", gap: "0.5rem", alignItems: "center", style: dragging ? { opacity: 0.4 } : {}, children: [jsxRuntime.jsx(react.Flex, { alignItems: "center", padding: "0", cursor: "grab", children: jsxRuntime.jsx(fa6.FaGripLinesVertical, { color: "
|
|
2543
|
+
return (jsxRuntime.jsxs(react.Grid, { ref: ref, templateColumns: "auto 1fr", gap: "0.5rem", alignItems: "center", style: dragging ? { opacity: 0.4 } : {}, children: [jsxRuntime.jsx(react.Flex, { alignItems: "center", padding: "0", cursor: "grab", children: jsxRuntime.jsx(fa6.FaGripLinesVertical, { color: "colorPalette.400" }) }), jsxRuntime.jsx(react.Flex, { justifyContent: "space-between", alignItems: "center", children: jsxRuntime.jsx(CheckboxCard, { variant: "surface", label: displayName, checked: column.getIsVisible(), onChange: column.getToggleVisibilityHandler() }) })] }));
|
|
2461
2544
|
}
|
|
2462
2545
|
function CardContainer({ location, children }) {
|
|
2463
2546
|
const ref = React.useRef(null);
|
|
@@ -2476,7 +2559,6 @@ function CardContainer({ location, children }) {
|
|
|
2476
2559
|
onDrop: () => setIsDraggedOver(false),
|
|
2477
2560
|
});
|
|
2478
2561
|
}, [location]);
|
|
2479
|
-
// const isDark = (location + location) % 2 === 1;
|
|
2480
2562
|
function getColor(isDraggedOver) {
|
|
2481
2563
|
if (isDraggedOver) {
|
|
2482
2564
|
return {
|
|
@@ -2486,7 +2568,6 @@ function CardContainer({ location, children }) {
|
|
|
2486
2568
|
},
|
|
2487
2569
|
};
|
|
2488
2570
|
}
|
|
2489
|
-
// return isDark ? "lightgrey" : "white";
|
|
2490
2571
|
return {
|
|
2491
2572
|
backgroundColor: undefined,
|
|
2492
2573
|
_dark: {
|
|
@@ -2537,8 +2618,9 @@ const TableViewer = () => {
|
|
|
2537
2618
|
|
|
2538
2619
|
const ViewDialog = ({ icon = jsxRuntime.jsx(io.IoMdEye, {}) }) => {
|
|
2539
2620
|
const viewModel = react.useDisclosure();
|
|
2540
|
-
const {
|
|
2541
|
-
|
|
2621
|
+
const { tableLabel } = useDataTableContext();
|
|
2622
|
+
const { view } = tableLabel;
|
|
2623
|
+
return (jsxRuntime.jsxs(DialogRoot, { children: [jsxRuntime.jsx(react.DialogBackdrop, {}), jsxRuntime.jsx(DialogTrigger, { asChild: true, children: jsxRuntime.jsxs(react.Button, { as: react.Box, variant: "ghost", onClick: viewModel.onOpen, children: [icon, " ", view] }) }), jsxRuntime.jsxs(DialogContent, { children: [jsxRuntime.jsx(DialogCloseTrigger, {}), jsxRuntime.jsx(DialogHeader, { children: jsxRuntime.jsx(DialogTitle, { children: view }) }), jsxRuntime.jsx(DialogBody, { children: jsxRuntime.jsx(TableViewer, {}) }), jsxRuntime.jsx(DialogFooter, {})] })] }));
|
|
2542
2624
|
};
|
|
2543
2625
|
|
|
2544
2626
|
const CardHeader = ({ row, imageColumnId = undefined, titleColumnId = undefined, tagColumnId = undefined, tagIcon = undefined, showTag = true, imageProps = {}, }) => {
|
|
@@ -2589,7 +2671,7 @@ const RecordDisplay = ({ object, boxProps, translate, prefix = "", }) => {
|
|
|
2589
2671
|
return jsxRuntime.jsx(jsxRuntime.Fragment, { children: "null" });
|
|
2590
2672
|
}
|
|
2591
2673
|
return (jsxRuntime.jsx(react.Grid, { rowGap: 1, padding: 1, overflow: "auto", ...boxProps, children: Object.entries(object).map(([field, value]) => {
|
|
2592
|
-
return (jsxRuntime.jsxs(react.Grid, { columnGap: 2, gridTemplateColumns: "auto 1fr", children: [jsxRuntime.jsx(react.Text, { color: "
|
|
2674
|
+
return (jsxRuntime.jsxs(react.Grid, { columnGap: 2, gridTemplateColumns: "auto 1fr", children: [jsxRuntime.jsx(react.Text, { color: "colorPalette.400", children: getColumn({ field }) }), typeof value === "object" ? (jsxRuntime.jsx(RecordDisplay, { object: value, prefix: `${prefix}${field}.`, translate: translate })) : (jsxRuntime.jsx(react.Text, { children: JSON.stringify(value) }))] }, field));
|
|
2593
2675
|
}) }));
|
|
2594
2676
|
};
|
|
2595
2677
|
|
|
@@ -2639,7 +2721,7 @@ const CellRenderer = ({ cell }) => {
|
|
|
2639
2721
|
paddingY: 2,
|
|
2640
2722
|
}, object: value })] }, cell.id));
|
|
2641
2723
|
}
|
|
2642
|
-
return (jsxRuntime.jsxs(react.Box, { gridColumn, gridRow, children: [jsxRuntime.jsx(react.Box, { color:
|
|
2724
|
+
return (jsxRuntime.jsxs(react.Box, { gridColumn, gridRow, children: [jsxRuntime.jsx(react.Box, { color: "colorPalette.400", children: getLabel({ columnId: cell.column.id }) }), jsxRuntime.jsx(react.Box, { wordBreak: "break-word", textOverflow: "ellipsis", overflow: "hidden", children: `${formatValue(cell.getValue())}` })] }, cell.id));
|
|
2643
2725
|
};
|
|
2644
2726
|
const DataDisplay = ({ variant = "" }) => {
|
|
2645
2727
|
const { table, translate } = useDataTableContext();
|
|
@@ -2761,7 +2843,23 @@ const fuzzyFilter = (row, columnId, value, addMeta) => {
|
|
|
2761
2843
|
*
|
|
2762
2844
|
* @link https://tanstack.com/table/latest/docs/guide/column-defs
|
|
2763
2845
|
*/
|
|
2764
|
-
function DataTable({ columns, data, enableRowSelection = true, enableMultiRowSelection = true, enableSubRowSelection = true, columnOrder, columnFilters, columnVisibility, density, globalFilter, pagination, sorting, rowSelection, setPagination, setSorting, setColumnFilters, setRowSelection, setGlobalFilter, setColumnOrder, setDensity, setColumnVisibility, translate, children,
|
|
2846
|
+
function DataTable({ columns, data, enableRowSelection = true, enableMultiRowSelection = true, enableSubRowSelection = true, columnOrder, columnFilters, columnVisibility, density, globalFilter, pagination, sorting, rowSelection, setPagination, setSorting, setColumnFilters, setRowSelection, setGlobalFilter, setColumnOrder, setDensity, setColumnVisibility, translate, children, tableLabel = {
|
|
2847
|
+
view: "View",
|
|
2848
|
+
edit: "Edit",
|
|
2849
|
+
filterButtonText: "Filter",
|
|
2850
|
+
filterTitle: "Filter",
|
|
2851
|
+
filterReset: "Reset",
|
|
2852
|
+
filterClose: "Close",
|
|
2853
|
+
reloadTooltip: "Reload",
|
|
2854
|
+
reloadButtonText: "Reload",
|
|
2855
|
+
resetSelection: "Reset Selection",
|
|
2856
|
+
resetSorting: "Reset Sorting",
|
|
2857
|
+
rowCountText: "Row Count",
|
|
2858
|
+
hasErrorText: "Has Error",
|
|
2859
|
+
globalFilterPlaceholder: "Search",
|
|
2860
|
+
trueLabel: "True",
|
|
2861
|
+
falseLabel: "False",
|
|
2862
|
+
}, }) {
|
|
2765
2863
|
const table = reactTable.useReactTable({
|
|
2766
2864
|
_features: [DensityFeature],
|
|
2767
2865
|
data: data,
|
|
@@ -2814,7 +2912,7 @@ function DataTable({ columns, data, enableRowSelection = true, enableMultiRowSel
|
|
|
2814
2912
|
setGlobalFilter,
|
|
2815
2913
|
type: "client",
|
|
2816
2914
|
translate,
|
|
2817
|
-
columns,
|
|
2915
|
+
columns: columns,
|
|
2818
2916
|
sorting,
|
|
2819
2917
|
setSorting,
|
|
2820
2918
|
columnFilters,
|
|
@@ -2829,6 +2927,8 @@ function DataTable({ columns, data, enableRowSelection = true, enableMultiRowSel
|
|
|
2829
2927
|
setDensity,
|
|
2830
2928
|
columnVisibility,
|
|
2831
2929
|
setColumnVisibility,
|
|
2930
|
+
data,
|
|
2931
|
+
tableLabel,
|
|
2832
2932
|
}, children: children }));
|
|
2833
2933
|
}
|
|
2834
2934
|
|
|
@@ -2843,10 +2943,26 @@ function DataTable({ columns, data, enableRowSelection = true, enableMultiRowSel
|
|
|
2843
2943
|
*
|
|
2844
2944
|
* @link https://tanstack.com/table/latest/docs/guide/column-defs
|
|
2845
2945
|
*/
|
|
2846
|
-
function DataTableServer({ columns, enableRowSelection = true, enableMultiRowSelection = true, enableSubRowSelection = true, columnOrder, columnFilters, columnVisibility, density, globalFilter, pagination, sorting, rowSelection, setPagination, setSorting, setColumnFilters, setRowSelection, setGlobalFilter, setColumnOrder, setDensity, setColumnVisibility, query, url, translate, children,
|
|
2946
|
+
function DataTableServer({ columns, enableRowSelection = true, enableMultiRowSelection = true, enableSubRowSelection = true, columnOrder, columnFilters, columnVisibility, density, globalFilter, pagination, sorting, rowSelection, setPagination, setSorting, setColumnFilters, setRowSelection, setGlobalFilter, setColumnOrder, setDensity, setColumnVisibility, query, url, translate, children, tableLabel = {
|
|
2947
|
+
view: "View",
|
|
2948
|
+
edit: "Edit",
|
|
2949
|
+
filterButtonText: "Filter",
|
|
2950
|
+
filterTitle: "Filter",
|
|
2951
|
+
filterReset: "Reset",
|
|
2952
|
+
filterClose: "Close",
|
|
2953
|
+
reloadTooltip: "Reload",
|
|
2954
|
+
reloadButtonText: "Reload",
|
|
2955
|
+
resetSelection: "Reset Selection",
|
|
2956
|
+
resetSorting: "Reset Sorting",
|
|
2957
|
+
rowCountText: "Row Count",
|
|
2958
|
+
hasErrorText: "Has Error",
|
|
2959
|
+
globalFilterPlaceholder: "Search",
|
|
2960
|
+
trueLabel: "True",
|
|
2961
|
+
falseLabel: "False",
|
|
2962
|
+
}, }) {
|
|
2847
2963
|
const table = reactTable.useReactTable({
|
|
2848
2964
|
_features: [DensityFeature],
|
|
2849
|
-
data: query.data?.data ?? [],
|
|
2965
|
+
data: (query.data?.data ?? []),
|
|
2850
2966
|
rowCount: query.data?.count ?? 0,
|
|
2851
2967
|
columns: columns,
|
|
2852
2968
|
getCoreRowModel: reactTable.getCoreRowModel(),
|
|
@@ -2892,12 +3008,12 @@ function DataTableServer({ columns, enableRowSelection = true, enableMultiRowSel
|
|
|
2892
3008
|
// for tanstack-table ts bug end
|
|
2893
3009
|
});
|
|
2894
3010
|
return (jsxRuntime.jsx(DataTableContext.Provider, { value: {
|
|
2895
|
-
table:
|
|
3011
|
+
table: table,
|
|
2896
3012
|
globalFilter,
|
|
2897
3013
|
setGlobalFilter,
|
|
2898
3014
|
type: "server",
|
|
2899
3015
|
translate,
|
|
2900
|
-
columns,
|
|
3016
|
+
columns: columns,
|
|
2901
3017
|
sorting,
|
|
2902
3018
|
setSorting,
|
|
2903
3019
|
columnFilters,
|
|
@@ -2912,98 +3028,11 @@ function DataTableServer({ columns, enableRowSelection = true, enableMultiRowSel
|
|
|
2912
3028
|
setDensity,
|
|
2913
3029
|
columnVisibility,
|
|
2914
3030
|
setColumnVisibility,
|
|
3031
|
+
data: query.data?.data ?? [],
|
|
3032
|
+
tableLabel,
|
|
2915
3033
|
}, children: jsxRuntime.jsx(DataTableServerContext.Provider, { value: { url, query }, children: children }) }));
|
|
2916
3034
|
}
|
|
2917
3035
|
|
|
2918
|
-
const Checkbox = React__namespace.forwardRef(function Checkbox(props, ref) {
|
|
2919
|
-
const { icon, children, inputProps, rootRef, ...rest } = props;
|
|
2920
|
-
return (jsxRuntime.jsxs(react.Checkbox.Root, { ref: rootRef, ...rest, children: [jsxRuntime.jsx(react.Checkbox.HiddenInput, { ref: ref, ...inputProps }), jsxRuntime.jsx(react.Checkbox.Control, { children: icon || jsxRuntime.jsx(react.Checkbox.Indicator, {}) }), children != null && (jsxRuntime.jsx(react.Checkbox.Label, { children: children }))] }));
|
|
2921
|
-
});
|
|
2922
|
-
|
|
2923
|
-
const TableBody = ({ pinnedBgColor = { light: "gray.50", dark: "gray.700" }, showSelector = false, alwaysShowSelector = true, canResize = true, }) => {
|
|
2924
|
-
"use no memo";
|
|
2925
|
-
const { table } = useDataTableContext();
|
|
2926
|
-
const SELECTION_BOX_WIDTH = 20;
|
|
2927
|
-
const [hoveredRow, setHoveredRow] = React.useState(-1);
|
|
2928
|
-
const handleRowHover = (index) => {
|
|
2929
|
-
setHoveredRow(index);
|
|
2930
|
-
};
|
|
2931
|
-
const getTdProps = (cell) => {
|
|
2932
|
-
const tdProps = cell.column.getIsPinned()
|
|
2933
|
-
? {
|
|
2934
|
-
left: showSelector
|
|
2935
|
-
? `${cell.column.getStart("left") + SELECTION_BOX_WIDTH + table.getDensityValue() * 2}px`
|
|
2936
|
-
: `${cell.column.getStart("left")}px`,
|
|
2937
|
-
background: pinnedBgColor.light,
|
|
2938
|
-
position: "sticky",
|
|
2939
|
-
zIndex: -1,
|
|
2940
|
-
_dark: {
|
|
2941
|
-
backgroundColor: pinnedBgColor.dark,
|
|
2942
|
-
},
|
|
2943
|
-
}
|
|
2944
|
-
: {};
|
|
2945
|
-
return tdProps;
|
|
2946
|
-
};
|
|
2947
|
-
const getTrProps = ({ hoveredRow, index, }) => {
|
|
2948
|
-
if (hoveredRow === -1) {
|
|
2949
|
-
return {};
|
|
2950
|
-
}
|
|
2951
|
-
if (hoveredRow === index) {
|
|
2952
|
-
return {
|
|
2953
|
-
opacity: "1",
|
|
2954
|
-
};
|
|
2955
|
-
}
|
|
2956
|
-
return {
|
|
2957
|
-
opacity: "0.8",
|
|
2958
|
-
};
|
|
2959
|
-
};
|
|
2960
|
-
return (jsxRuntime.jsx(react.Table.Body, { children: table.getRowModel().rows.map((row, index) => {
|
|
2961
|
-
return (jsxRuntime.jsxs(react.Table.Row, { display: "flex", zIndex: 1, onMouseEnter: () => handleRowHover(index), onMouseLeave: () => handleRowHover(-1), ...getTrProps({ hoveredRow, index }), children: [showSelector && (jsxRuntime.jsx(TableRowSelector, { index: index, row: row, hoveredRow: hoveredRow, alwaysShowSelector: alwaysShowSelector })), row.getVisibleCells().map((cell, index) => {
|
|
2962
|
-
return (jsxRuntime.jsx(react.Table.Cell, { padding: `${table.getDensityValue()}px`,
|
|
2963
|
-
// styling resize and pinning start
|
|
2964
|
-
flex: `${canResize ? "0" : "1"} 0 ${cell.column.getSize()}px`, backgroundColor: "white", ...getTdProps(cell), _dark: {
|
|
2965
|
-
backgroundColor: "gray.950",
|
|
2966
|
-
}, children: reactTable.flexRender(cell.column.columnDef.cell, cell.getContext()) }, `chakra-table-rowcell-${cell.id}-${index}`));
|
|
2967
|
-
})] }, `chakra-table-row-${row.id}`));
|
|
2968
|
-
}) }));
|
|
2969
|
-
};
|
|
2970
|
-
const TableRowSelector = ({ index, row, hoveredRow, pinnedBgColor = { light: "gray.50", dark: "gray.700" }, alwaysShowSelector = true, }) => {
|
|
2971
|
-
const { table } = useDataTableContext();
|
|
2972
|
-
const SELECTION_BOX_WIDTH = 20;
|
|
2973
|
-
const isCheckBoxVisible = (current_index, current_row) => {
|
|
2974
|
-
if (alwaysShowSelector) {
|
|
2975
|
-
return true;
|
|
2976
|
-
}
|
|
2977
|
-
if (current_row.getIsSelected()) {
|
|
2978
|
-
return true;
|
|
2979
|
-
}
|
|
2980
|
-
if (hoveredRow == current_index) {
|
|
2981
|
-
return true;
|
|
2982
|
-
}
|
|
2983
|
-
return false;
|
|
2984
|
-
};
|
|
2985
|
-
return (jsxRuntime.jsxs(react.Table.Cell, { padding: `${table.getDensityValue()}px`, ...(table.getIsSomeColumnsPinned("left")
|
|
2986
|
-
? {
|
|
2987
|
-
left: `0px`,
|
|
2988
|
-
backgroundColor: pinnedBgColor.light,
|
|
2989
|
-
position: "sticky",
|
|
2990
|
-
zIndex: 1,
|
|
2991
|
-
_dark: { backgroundColor: pinnedBgColor.dark },
|
|
2992
|
-
}
|
|
2993
|
-
: {}),
|
|
2994
|
-
// styling resize and pinning end
|
|
2995
|
-
display: "grid", children: [!isCheckBoxVisible(index, row) && (jsxRuntime.jsx(react.Box, { as: "span", margin: "0rem", display: "grid", justifyItems: "center", alignItems: "center", width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px` })), isCheckBoxVisible(index, row) && (jsxRuntime.jsx(react.Box, { margin: "0rem", display: "grid", justifyItems: "center", alignItems: "center", children: jsxRuntime.jsx(Checkbox, { width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px`, isChecked: row.getIsSelected(),
|
|
2996
|
-
disabled: !row.getCanSelect(),
|
|
2997
|
-
onChange: row.getToggleSelectedHandler() }) }))] }));
|
|
2998
|
-
};
|
|
2999
|
-
|
|
3000
|
-
const Tooltip = React__namespace.forwardRef(function Tooltip(props, ref) {
|
|
3001
|
-
const { showArrow, children, disabled, portalled, content, contentProps, portalRef, ...rest } = props;
|
|
3002
|
-
if (disabled)
|
|
3003
|
-
return children;
|
|
3004
|
-
return (jsxRuntime.jsxs(react.Tooltip.Root, { ...rest, children: [jsxRuntime.jsx(react.Tooltip.Trigger, { asChild: true, children: children }), jsxRuntime.jsx(react.Portal, { disabled: !portalled, container: portalRef, children: jsxRuntime.jsx(react.Tooltip.Positioner, { children: jsxRuntime.jsxs(react.Tooltip.Content, { ref: ref, ...contentProps, children: [showArrow && (jsxRuntime.jsx(react.Tooltip.Arrow, { children: jsxRuntime.jsx(react.Tooltip.ArrowTip, {}) })), content] }) }) })] }));
|
|
3005
|
-
});
|
|
3006
|
-
|
|
3007
3036
|
const InputGroup = React__namespace.forwardRef(function InputGroup(props, ref) {
|
|
3008
3037
|
const { startElement, startElementProps, endElement, endElementProps, children, startOffset = "6px", endOffset = "6px", ...rest } = props;
|
|
3009
3038
|
return (jsxRuntime.jsxs(react.Group, { ref: ref, ...rest, children: [startElement && (jsxRuntime.jsx(react.InputElement, { pointerEvents: "none", ...startElementProps, children: startElement })), React__namespace.cloneElement(children, {
|
|
@@ -3017,7 +3046,8 @@ const InputGroup = React__namespace.forwardRef(function InputGroup(props, ref) {
|
|
|
3017
3046
|
});
|
|
3018
3047
|
|
|
3019
3048
|
const GlobalFilter = () => {
|
|
3020
|
-
const { table } = useDataTableContext();
|
|
3049
|
+
const { table, tableLabel } = useDataTableContext();
|
|
3050
|
+
const { globalFilterPlaceholder } = tableLabel;
|
|
3021
3051
|
const [searchTerm, setSearchTerm] = React.useState("");
|
|
3022
3052
|
const debouncedSearchTerm = usehooks.useDebounce(searchTerm, 500);
|
|
3023
3053
|
React.useEffect(() => {
|
|
@@ -3026,42 +3056,31 @@ const GlobalFilter = () => {
|
|
|
3026
3056
|
};
|
|
3027
3057
|
searchHN();
|
|
3028
3058
|
}, [debouncedSearchTerm]);
|
|
3029
|
-
return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsx(InputGroup, { flex: "1", startElement: jsxRuntime.jsx(md.MdSearch, {}), children: jsxRuntime.jsx(react.Input, { placeholder:
|
|
3059
|
+
return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsx(InputGroup, { flex: "1", startElement: jsxRuntime.jsx(md.MdSearch, {}), children: jsxRuntime.jsx(react.Input, { placeholder: globalFilterPlaceholder, variant: "outline", onChange: (e) => {
|
|
3030
3060
|
setSearchTerm(e.target.value);
|
|
3031
3061
|
} }) }) }));
|
|
3032
3062
|
};
|
|
3033
3063
|
|
|
3034
|
-
const
|
|
3064
|
+
const Tooltip = React__namespace.forwardRef(function Tooltip(props, ref) {
|
|
3065
|
+
const { showArrow, children, disabled, portalled, content, contentProps, portalRef, ...rest } = props;
|
|
3066
|
+
if (disabled)
|
|
3067
|
+
return children;
|
|
3068
|
+
return (jsxRuntime.jsxs(react.Tooltip.Root, { ...rest, children: [jsxRuntime.jsx(react.Tooltip.Trigger, { asChild: true, children: children }), jsxRuntime.jsx(react.Portal, { disabled: !portalled, container: portalRef, children: jsxRuntime.jsx(react.Tooltip.Positioner, { children: jsxRuntime.jsxs(react.Tooltip.Content, { ref: ref, ...contentProps, children: [showArrow && (jsxRuntime.jsx(react.Tooltip.Arrow, { children: jsxRuntime.jsx(react.Tooltip.ArrowTip, {}) })), content] }) }) })] }));
|
|
3069
|
+
});
|
|
3070
|
+
|
|
3071
|
+
const ReloadButton = ({ variant = "icon", }) => {
|
|
3035
3072
|
const { url } = useDataTableServerContext();
|
|
3036
3073
|
const queryClient = reactQuery.useQueryClient();
|
|
3074
|
+
const { tableLabel } = useDataTableContext();
|
|
3075
|
+
const { reloadTooltip, reloadButtonText } = tableLabel;
|
|
3037
3076
|
if (variant === "icon") {
|
|
3038
|
-
return (jsxRuntime.jsx(Tooltip, { showArrow: true, content:
|
|
3077
|
+
return (jsxRuntime.jsx(Tooltip, { showArrow: true, content: reloadTooltip, children: jsxRuntime.jsx(Button, { variant: "ghost", onClick: () => {
|
|
3039
3078
|
queryClient.invalidateQueries({ queryKey: [url] });
|
|
3040
3079
|
}, "aria-label": "refresh", children: jsxRuntime.jsx(io5.IoReload, {}) }) }));
|
|
3041
3080
|
}
|
|
3042
3081
|
return (jsxRuntime.jsxs(Button, { variant: "ghost", onClick: () => {
|
|
3043
3082
|
queryClient.invalidateQueries({ queryKey: [url] });
|
|
3044
|
-
}, children: [jsxRuntime.jsx(io5.IoReload, {}), " ",
|
|
3045
|
-
};
|
|
3046
|
-
|
|
3047
|
-
const FilterOptions = ({ column }) => {
|
|
3048
|
-
const { table } = useDataTableContext();
|
|
3049
|
-
const tableColumn = table.getColumn(column);
|
|
3050
|
-
const options = tableColumn?.columnDef.meta?.filterOptions ?? [];
|
|
3051
|
-
return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: options.map((option) => {
|
|
3052
|
-
const selected = table.getColumn(column)?.getFilterValue() === option;
|
|
3053
|
-
return (jsxRuntime.jsxs(react.Button, { size: "sm", onClick: () => {
|
|
3054
|
-
if (selected) {
|
|
3055
|
-
table.setColumnFilters((state) => {
|
|
3056
|
-
return state.filter((filter) => {
|
|
3057
|
-
return filter.id !== column;
|
|
3058
|
-
});
|
|
3059
|
-
});
|
|
3060
|
-
return;
|
|
3061
|
-
}
|
|
3062
|
-
table.getColumn(column)?.setFilterValue(option);
|
|
3063
|
-
}, variant: selected ? "solid" : "outline", display: "flex", gap: "0.25rem", children: [option, selected && jsxRuntime.jsx(md.MdClose, {})] }, option));
|
|
3064
|
-
}) }));
|
|
3083
|
+
}, children: [jsxRuntime.jsx(io5.IoReload, {}), " ", reloadButtonText] }));
|
|
3065
3084
|
};
|
|
3066
3085
|
|
|
3067
3086
|
const TableFilterTags = () => {
|
|
@@ -3075,16 +3094,99 @@ const TableFilterTags = () => {
|
|
|
3075
3094
|
}) }));
|
|
3076
3095
|
};
|
|
3077
3096
|
|
|
3078
|
-
const TableControls = ({ fitTableWidth = false, fitTableHeight = false, children = jsxRuntime.jsx(jsxRuntime.Fragment, {}), showGlobalFilter = false, showFilter = false, showFilterName = false, showFilterTags = false, showReload = false, showPagination = true, showPageSizeControl = true, showPageCountText = true, showView = true,
|
|
3079
|
-
const {
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3097
|
+
const TableControls = ({ fitTableWidth = false, fitTableHeight = false, children = jsxRuntime.jsx(jsxRuntime.Fragment, {}), showGlobalFilter = false, showFilter = false, showFilterName = false, showFilterTags = false, showReload = false, showPagination = true, showPageSizeControl = true, showPageCountText = true, showView = true, filterTagsOptions = [], extraItems = jsxRuntime.jsx(jsxRuntime.Fragment, {}), loading = false, hasError = false, gridProps = {}, }) => {
|
|
3098
|
+
const { tableLabel, table } = useDataTableContext();
|
|
3099
|
+
const { rowCountText, hasErrorText } = tableLabel;
|
|
3100
|
+
return (jsxRuntime.jsxs(react.Grid, { templateRows: "auto 1fr", width: fitTableWidth ? "fit-content" : "100%", height: fitTableHeight ? "fit-content" : "100%", gap: "0.5rem", ...gridProps, children: [jsxRuntime.jsxs(react.Flex, { flexFlow: "column", gap: 2, children: [jsxRuntime.jsxs(react.Flex, { justifyContent: "space-between", children: [jsxRuntime.jsx(react.Box, { children: showView && jsxRuntime.jsx(ViewDialog, { icon: jsxRuntime.jsx(md.MdOutlineViewColumn, {}) }) }), jsxRuntime.jsxs(react.Flex, { gap: "0.5rem", alignItems: "center", justifySelf: "end", children: [loading && jsxRuntime.jsx(react.Spinner, { size: "sm" }), hasError && (jsxRuntime.jsx(Tooltip, { content: hasErrorText, children: jsxRuntime.jsx(react.Icon, { as: bs.BsExclamationCircleFill, color: "red.400" }) })), showGlobalFilter && jsxRuntime.jsx(GlobalFilter, {}), showFilter && jsxRuntime.jsx(FilterDialog, {}), showReload && jsxRuntime.jsx(ReloadButton, {}), extraItems] })] }), filterTagsOptions.length > 0 && (jsxRuntime.jsx(react.Flex, { flexFlow: "column", gap: "0.5rem", children: filterTagsOptions.map((option) => {
|
|
3101
|
+
const { column, options } = option;
|
|
3102
|
+
const tableColumn = table.getColumn(column);
|
|
3103
|
+
return (jsxRuntime.jsxs(react.Flex, { alignItems: "center", flexFlow: "wrap", gap: "0.5rem", children: [tableColumn?.columnDef.meta?.displayName && (jsxRuntime.jsx(react.Text, { children: tableColumn?.columnDef.meta?.displayName })), jsxRuntime.jsx(TagFilter, { availableTags: options, selectedTags: tableColumn?.getFilterValue() ?? [], selectOne: true, onTagChange: (tags) => {
|
|
3104
|
+
if (tags.length === 0) {
|
|
3105
|
+
return tableColumn?.setFilterValue(undefined);
|
|
3106
|
+
}
|
|
3107
|
+
tableColumn?.setFilterValue(tags);
|
|
3108
|
+
} })] }, column));
|
|
3109
|
+
}) })), showFilterTags && (jsxRuntime.jsx(react.Flex, { children: jsxRuntime.jsx(TableFilterTags, {}) }))] }), jsxRuntime.jsx(react.Grid, { overflow: "auto", bg: { base: "colorPalette.50", _dark: "colorPalette.950" }, children: children }), (showPageSizeControl || showPageCountText || showPagination) && (jsxRuntime.jsxs(react.Flex, { justifyContent: "space-between", children: [jsxRuntime.jsxs(react.Flex, { gap: "1rem", alignItems: "center", children: [showPageSizeControl && jsxRuntime.jsx(PageSizeControl, {}), showPageCountText && (jsxRuntime.jsxs(react.Flex, { children: [jsxRuntime.jsx(react.Text, { paddingRight: "0.5rem", children: rowCountText }), jsxRuntime.jsx(RowCountText, {})] }))] }), jsxRuntime.jsx(react.Box, { justifySelf: "end", children: showPagination && jsxRuntime.jsx(Pagination, {}) })] }))] }));
|
|
3110
|
+
};
|
|
3111
|
+
|
|
3112
|
+
const EmptyState = React__namespace.forwardRef(function EmptyState(props, ref) {
|
|
3113
|
+
const { title, description, icon, children, ...rest } = props;
|
|
3114
|
+
return (jsxRuntime.jsx(react.EmptyState.Root, { ref: ref, ...rest, children: jsxRuntime.jsxs(react.EmptyState.Content, { children: [icon && (jsxRuntime.jsx(react.EmptyState.Indicator, { children: icon })), description ? (jsxRuntime.jsxs(react.VStack, { textAlign: "center", children: [jsxRuntime.jsx(react.EmptyState.Title, { children: title }), jsxRuntime.jsx(react.EmptyState.Description, { children: description })] })) : (jsxRuntime.jsx(react.EmptyState.Title, { children: title })), children] }) }));
|
|
3115
|
+
});
|
|
3116
|
+
|
|
3117
|
+
const EmptyResult = (jsxRuntime.jsx(EmptyState, { icon: jsxRuntime.jsx(hi.HiColorSwatch, {}), title: "No results found", description: "Try adjusting your search", children: jsxRuntime.jsxs(react.List.Root, { variant: "marker", children: [jsxRuntime.jsx(react.List.Item, { children: "Try removing filters" }), jsxRuntime.jsx(react.List.Item, { children: "Try different keywords" })] }) }));
|
|
3118
|
+
const Table = ({ children, emptyComponent = EmptyResult, canResize = true, ...props }) => {
|
|
3119
|
+
const { table } = useDataTableContext();
|
|
3120
|
+
if (table.getRowModel().rows.length <= 0) {
|
|
3121
|
+
return emptyComponent;
|
|
3122
|
+
}
|
|
3123
|
+
return (jsxRuntime.jsx(react.Table.Root, { stickyHeader: true, variant: "outline", width: canResize ? table.getCenterTotalSize() : undefined, display: "grid", alignContent: "start", overflowY: "auto", bg: { base: "colorPalette.50", _dark: "colorPalette.950" }, ...props, children: children }));
|
|
3124
|
+
};
|
|
3125
|
+
|
|
3126
|
+
const Checkbox = React__namespace.forwardRef(function Checkbox(props, ref) {
|
|
3127
|
+
const { icon, children, inputProps, rootRef, ...rest } = props;
|
|
3128
|
+
return (jsxRuntime.jsxs(react.Checkbox.Root, { ref: rootRef, ...rest, children: [jsxRuntime.jsx(react.Checkbox.HiddenInput, { ref: ref, ...inputProps }), jsxRuntime.jsx(react.Checkbox.Control, { children: icon || jsxRuntime.jsx(react.Checkbox.Indicator, {}) }), children != null && (jsxRuntime.jsx(react.Checkbox.Label, { children: children }))] }));
|
|
3129
|
+
});
|
|
3130
|
+
|
|
3131
|
+
const TableBody = ({ showSelector = false, canResize = true, }) => {
|
|
3132
|
+
"use no memo";
|
|
3133
|
+
const { table } = useDataTableContext();
|
|
3134
|
+
const SELECTION_BOX_WIDTH = 20;
|
|
3135
|
+
const [hoveredRow, setHoveredRow] = React.useState(-1);
|
|
3136
|
+
const handleRowHover = (index) => {
|
|
3137
|
+
setHoveredRow(index);
|
|
3138
|
+
};
|
|
3139
|
+
const getTdProps = (cell) => {
|
|
3140
|
+
const tdProps = cell.column.getIsPinned()
|
|
3141
|
+
? {
|
|
3142
|
+
left: showSelector
|
|
3143
|
+
? `${cell.column.getStart("left") + SELECTION_BOX_WIDTH + table.getDensityValue() * 2}px`
|
|
3144
|
+
: `${cell.column.getStart("left")}px`,
|
|
3145
|
+
position: "relative",
|
|
3146
|
+
}
|
|
3147
|
+
: {};
|
|
3148
|
+
return tdProps;
|
|
3149
|
+
};
|
|
3150
|
+
const getTrProps = ({ hoveredRow, index, }) => {
|
|
3151
|
+
if (hoveredRow === -1) {
|
|
3152
|
+
return {};
|
|
3153
|
+
}
|
|
3154
|
+
if (hoveredRow === index) {
|
|
3155
|
+
return {
|
|
3156
|
+
opacity: "1",
|
|
3157
|
+
};
|
|
3158
|
+
}
|
|
3159
|
+
return {
|
|
3160
|
+
opacity: "0.8",
|
|
3161
|
+
};
|
|
3162
|
+
};
|
|
3163
|
+
return (jsxRuntime.jsx(react.Table.Body, { children: table.getRowModel().rows.map((row, index) => {
|
|
3164
|
+
return (jsxRuntime.jsxs(react.Table.Row, { display: "flex", zIndex: 1, onMouseEnter: () => handleRowHover(index), onMouseLeave: () => handleRowHover(-1), ...getTrProps({ hoveredRow, index }), children: [showSelector && (jsxRuntime.jsx(TableRowSelector, { index: index, row: row, hoveredRow: hoveredRow })), row.getVisibleCells().map((cell, index) => {
|
|
3165
|
+
return (jsxRuntime.jsx(react.Table.Cell, { padding: `${table.getDensityValue()}px`,
|
|
3166
|
+
// styling resize and pinning start
|
|
3167
|
+
flex: `${canResize ? "0" : "1"} 0 ${cell.column.getSize()}px`,
|
|
3168
|
+
// this is to avoid the cell from being too wide
|
|
3169
|
+
minWidth: `0`, color: {
|
|
3170
|
+
base: "colorPalette.900",
|
|
3171
|
+
_dark: "colorPalette.100",
|
|
3172
|
+
},
|
|
3173
|
+
bg: { base: "colorPalette.50", _dark: "colorPalette.950" }, ...getTdProps(cell), children: reactTable.flexRender(cell.column.columnDef.cell, cell.getContext()) }, `chakra-table-rowcell-${cell.id}-${index}`));
|
|
3174
|
+
})] }, `chakra-table-row-${row.id}`));
|
|
3175
|
+
}) }));
|
|
3176
|
+
};
|
|
3177
|
+
const TableRowSelector = ({ row, }) => {
|
|
3178
|
+
const { table } = useDataTableContext();
|
|
3179
|
+
const SELECTION_BOX_WIDTH = 20;
|
|
3180
|
+
return (jsxRuntime.jsx(react.Table.Cell, { padding: `${table.getDensityValue()}px`, display: "grid", color: {
|
|
3181
|
+
base: "colorPalette.900",
|
|
3182
|
+
_dark: "colorPalette.100",
|
|
3183
|
+
},
|
|
3184
|
+
bg: { base: "colorPalette.50", _dark: "colorPalette.950" }, justifyItems: "center", alignItems: "center", children: jsxRuntime.jsx(Checkbox, { width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px`, checked: row.getIsSelected(),
|
|
3185
|
+
disabled: !row.getCanSelect(),
|
|
3186
|
+
onCheckedChange: row.getToggleSelectedHandler() }) }));
|
|
3085
3187
|
};
|
|
3086
3188
|
|
|
3087
|
-
const TableFooter = ({
|
|
3189
|
+
const TableFooter = ({ showSelector = false, alwaysShowSelector = true, }) => {
|
|
3088
3190
|
const table = useDataTableContext().table;
|
|
3089
3191
|
const SELECTION_BOX_WIDTH = 20;
|
|
3090
3192
|
const [hoveredCheckBox, setHoveredCheckBox] = React.useState(false);
|
|
@@ -3103,65 +3205,62 @@ const TableFooter = ({ pinnedBgColor = { light: "gray.50", dark: "gray.700" }, s
|
|
|
3103
3205
|
}
|
|
3104
3206
|
return false;
|
|
3105
3207
|
};
|
|
3106
|
-
|
|
3107
|
-
const thProps = header.column.getIsPinned()
|
|
3108
|
-
? {
|
|
3109
|
-
left: showSelector
|
|
3110
|
-
? `${header.getStart("left") + SELECTION_BOX_WIDTH + table.getDensityValue() * 2}px`
|
|
3111
|
-
: `${header.getStart("left") + table.getDensityValue() * 2}px`,
|
|
3112
|
-
background: pinnedBgColor.light,
|
|
3113
|
-
position: "sticky",
|
|
3114
|
-
zIndex: 1,
|
|
3115
|
-
_dark: {
|
|
3116
|
-
backgroundColor: pinnedBgColor.dark,
|
|
3117
|
-
},
|
|
3118
|
-
}
|
|
3119
|
-
: {};
|
|
3120
|
-
return thProps;
|
|
3121
|
-
};
|
|
3122
|
-
return (jsxRuntime.jsx(react.Table.Footer, { children: table.getFooterGroups().map((footerGroup) => (jsxRuntime.jsxs(react.Table.Row, { display: "flex", children: [showSelector && (jsxRuntime.jsxs(react.Table.Header
|
|
3123
|
-
// styling resize and pinning start
|
|
3124
|
-
, {
|
|
3125
|
-
// styling resize and pinning start
|
|
3126
|
-
padding: `${table.getDensityValue()}px`, ...(table.getIsSomeColumnsPinned("left")
|
|
3127
|
-
? {
|
|
3128
|
-
left: `0px`,
|
|
3129
|
-
backgroundColor: pinnedBgColor.light,
|
|
3130
|
-
position: "sticky",
|
|
3131
|
-
zIndex: 1,
|
|
3132
|
-
_dark: { backgroundColor: pinnedBgColor.dark },
|
|
3133
|
-
}
|
|
3134
|
-
: {}),
|
|
3135
|
-
// styling resize and pinning end
|
|
3136
|
-
onMouseEnter: () => handleRowHover(true), onMouseLeave: () => handleRowHover(false), display: "grid", children: [isCheckBoxVisible() && (jsxRuntime.jsx(react.Box, { margin: "0rem", display: "grid", justifyItems: "center", alignItems: "center", children: jsxRuntime.jsx(Checkbox, { width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px`, isChecked: table.getIsAllRowsSelected(),
|
|
3208
|
+
return (jsxRuntime.jsx(react.Table.Footer, { children: table.getFooterGroups().map((footerGroup) => (jsxRuntime.jsxs(react.Table.Row, { display: "flex", children: [showSelector && (jsxRuntime.jsxs(react.Table.Header, { padding: `${table.getDensityValue()}px`, onMouseEnter: () => handleRowHover(true), onMouseLeave: () => handleRowHover(false), display: "grid", children: [isCheckBoxVisible() && (jsxRuntime.jsx(react.Box, { margin: "0rem", display: "grid", justifyItems: "center", alignItems: "center", children: jsxRuntime.jsx(Checkbox, { width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px`, isChecked: table.getIsAllRowsSelected(),
|
|
3137
3209
|
// indeterminate: table.getIsSomeRowsSelected(),
|
|
3138
3210
|
onChange: table.getToggleAllRowsSelectedHandler() }) })), !isCheckBoxVisible() && (jsxRuntime.jsx(react.Box, { as: "span", margin: "0rem", display: "grid", justifyItems: "center", alignItems: "center", width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px` }))] })), footerGroup.headers.map((header) => (jsxRuntime.jsx(react.Table.Cell, { padding: "0", columnSpan: `${header.colSpan}`,
|
|
3139
3211
|
// styling resize and pinning start
|
|
3140
|
-
maxWidth: `${header.getSize()}px`, width: `${header.getSize()}px`, display: "grid",
|
|
3212
|
+
maxWidth: `${header.getSize()}px`, width: `${header.getSize()}px`, display: "grid", children: jsxRuntime.jsx(react.MenuRoot, { children: jsxRuntime.jsx(react.MenuTrigger, { asChild: true, children: jsxRuntime.jsx(react.Box, { padding: `${table.getDensityValue()}px`, display: "flex", alignItems: "center", justifyContent: "start", borderRadius: "0rem", children: jsxRuntime.jsxs(react.Flex, { gap: "0.5rem", alignItems: "center", children: [header.isPlaceholder
|
|
3141
3213
|
? null
|
|
3142
|
-
: reactTable.flexRender(header.column.columnDef.footer, header.getContext()), jsxRuntime.jsx(react.Box, { children: header.column.getCanSort() && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [header.column.getIsSorted() === false && (
|
|
3143
|
-
// <UpDownIcon />
|
|
3144
|
-
jsxRuntime.jsx(jsxRuntime.Fragment, {})), header.column.getIsSorted() === "asc" && (jsxRuntime.jsx(bi.BiUpArrow, {})), header.column.getIsSorted() === "desc" && (jsxRuntime.jsx(bi.BiDownArrow, {}))] })) })] }) }) }) }) }, `chakra-table-footer-${header.column.id}-${footerGroup.id}`)))] }, `chakra-table-footergroup-${footerGroup.id}`))) }));
|
|
3214
|
+
: reactTable.flexRender(header.column.columnDef.footer, header.getContext()), jsxRuntime.jsx(react.Box, { children: header.column.getCanSort() && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [header.column.getIsSorted() === false && jsxRuntime.jsx(jsxRuntime.Fragment, {}), header.column.getIsSorted() === "asc" && (jsxRuntime.jsx(bi.BiUpArrow, {})), header.column.getIsSorted() === "desc" && (jsxRuntime.jsx(bi.BiDownArrow, {}))] })) })] }) }) }) }) }, `chakra-table-footer-${header.column.id}-${footerGroup.id}`)))] }, `chakra-table-footergroup-${footerGroup.id}`))) }));
|
|
3145
3215
|
};
|
|
3146
3216
|
|
|
3147
|
-
|
|
3217
|
+
// Default text values
|
|
3218
|
+
const DEFAULT_HEADER_TEXTS = {
|
|
3219
|
+
pinColumn: "Pin Column",
|
|
3220
|
+
cancelPin: "Cancel Pin",
|
|
3221
|
+
sortAscending: "Sort Ascending",
|
|
3222
|
+
sortDescending: "Sort Descending",
|
|
3223
|
+
clearSorting: "Clear Sorting",
|
|
3224
|
+
};
|
|
3225
|
+
/**
|
|
3226
|
+
* TableHeader component with configurable text strings.
|
|
3227
|
+
*
|
|
3228
|
+
* @example
|
|
3229
|
+
* // Using default texts
|
|
3230
|
+
* <TableHeader />
|
|
3231
|
+
*
|
|
3232
|
+
* @example
|
|
3233
|
+
* // Customizing default texts for all columns
|
|
3234
|
+
* <TableHeader
|
|
3235
|
+
* defaultTexts={{
|
|
3236
|
+
* pinColumn: "Pin This Column",
|
|
3237
|
+
* sortAscending: "Sort A-Z"
|
|
3238
|
+
* }}
|
|
3239
|
+
* />
|
|
3240
|
+
*
|
|
3241
|
+
* @example
|
|
3242
|
+
* // Customizing texts per column via meta
|
|
3243
|
+
* const columns = [
|
|
3244
|
+
* columnHelper.accessor("name", {
|
|
3245
|
+
* header: "Name",
|
|
3246
|
+
* meta: {
|
|
3247
|
+
* headerTexts: {
|
|
3248
|
+
* pinColumn: "Pin Name Column",
|
|
3249
|
+
* sortAscending: "Sort Names A-Z"
|
|
3250
|
+
* }
|
|
3251
|
+
* }
|
|
3252
|
+
* })
|
|
3253
|
+
* ];
|
|
3254
|
+
*/
|
|
3255
|
+
const TableHeader = ({ canResize = true, showSelector = false, isSticky = true, tableHeaderProps = {}, tableRowProps = {}, defaultTexts = {}, }) => {
|
|
3148
3256
|
const { table } = useDataTableContext();
|
|
3149
3257
|
const SELECTION_BOX_WIDTH = 20;
|
|
3150
|
-
|
|
3151
|
-
const
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
return true;
|
|
3157
|
-
}
|
|
3158
|
-
if (table.getIsAllRowsSelected()) {
|
|
3159
|
-
return true;
|
|
3160
|
-
}
|
|
3161
|
-
if (hoveredCheckBox) {
|
|
3162
|
-
return true;
|
|
3163
|
-
}
|
|
3164
|
-
return false;
|
|
3258
|
+
// Merge default texts with provided defaults
|
|
3259
|
+
const mergedDefaultTexts = { ...DEFAULT_HEADER_TEXTS, ...defaultTexts };
|
|
3260
|
+
// Helper function to get text for a specific header
|
|
3261
|
+
const getHeaderText = (header, key) => {
|
|
3262
|
+
const columnMeta = header.column.columnDef.meta;
|
|
3263
|
+
return columnMeta?.headerTexts?.[key] || mergedDefaultTexts[key];
|
|
3165
3264
|
};
|
|
3166
3265
|
const getThProps = (header) => {
|
|
3167
3266
|
const thProps = header.column.getIsPinned()
|
|
@@ -3169,12 +3268,8 @@ const TableHeader = ({ canResize = true, pinnedBgColor = { light: "gray.50", dar
|
|
|
3169
3268
|
left: showSelector
|
|
3170
3269
|
? `${header.getStart("left") + SELECTION_BOX_WIDTH + table.getDensityValue() * 2}px`
|
|
3171
3270
|
: `${header.getStart("left")}px`,
|
|
3172
|
-
background: pinnedBgColor.light,
|
|
3173
3271
|
position: "sticky",
|
|
3174
3272
|
zIndex: 100 + 1,
|
|
3175
|
-
_dark: {
|
|
3176
|
-
backgroundColor: pinnedBgColor.dark,
|
|
3177
|
-
},
|
|
3178
3273
|
}
|
|
3179
3274
|
: {};
|
|
3180
3275
|
return thProps;
|
|
@@ -3183,21 +3278,13 @@ const TableHeader = ({ canResize = true, pinnedBgColor = { light: "gray.50", dar
|
|
|
3183
3278
|
position: "sticky",
|
|
3184
3279
|
top: 0,
|
|
3185
3280
|
};
|
|
3186
|
-
return (jsxRuntime.jsx(react.Table.Header, { ...(isSticky ? stickyProps : {}), ...
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
zIndex: 1,
|
|
3194
|
-
_dark: { backgroundColor: pinnedBgColor.dark },
|
|
3195
|
-
}
|
|
3196
|
-
: {}),
|
|
3197
|
-
// styling resize and pinning end
|
|
3198
|
-
padding: `${table.getDensityValue()}px`, onMouseEnter: () => handleRowHover(true), onMouseLeave: () => handleRowHover(false), display: "grid", children: [isCheckBoxVisible() && (jsxRuntime.jsx(react.Box, { margin: "0rem", display: "grid", justifyItems: "center", alignItems: "center", children: jsxRuntime.jsx(Checkbox, { width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px`, isChecked: table.getIsAllRowsSelected(),
|
|
3199
|
-
// indeterminate: table.getIsSomeRowsSelected(),
|
|
3200
|
-
onChange: table.getToggleAllRowsSelectedHandler() }) })), !isCheckBoxVisible() && (jsxRuntime.jsx(react.Box, { as: "span", margin: "0rem", display: "grid", justifyItems: "center", alignItems: "center", width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px` }))] })), headerGroup.headers.map((header) => {
|
|
3281
|
+
return (jsxRuntime.jsx(react.Table.Header, { ...(isSticky ? stickyProps : {}), bgColor: "transparent", ...tableHeaderProps, children: table.getHeaderGroups().map((headerGroup) => (jsxRuntime.jsxs(react.Table.Row, { display: "flex", bgColor: "transparent", ...tableRowProps, children: [showSelector && (jsxRuntime.jsx(react.Table.ColumnHeader, { padding: `${table.getDensityValue()}px`, display: "grid", color: {
|
|
3282
|
+
base: "colorPalette.900",
|
|
3283
|
+
_dark: "colorPalette.100",
|
|
3284
|
+
},
|
|
3285
|
+
bg: { base: "colorPalette.50", _dark: "colorPalette.950" }, justifyItems: "center", alignItems: "center", children: jsxRuntime.jsx(Checkbox, { width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px`, checked: table.getIsAllRowsSelected(),
|
|
3286
|
+
// indeterminate: table.getIsSomeRowsSelected(),
|
|
3287
|
+
onChange: table.getToggleAllRowsSelectedHandler() }) })), headerGroup.headers.map((header) => {
|
|
3201
3288
|
const resizeProps = {
|
|
3202
3289
|
onMouseDown: header.getResizeHandler(),
|
|
3203
3290
|
onTouchStart: header.getResizeHandler(),
|
|
@@ -3205,18 +3292,32 @@ const TableHeader = ({ canResize = true, pinnedBgColor = { light: "gray.50", dar
|
|
|
3205
3292
|
};
|
|
3206
3293
|
return (jsxRuntime.jsxs(react.Table.ColumnHeader, { padding: 0, columnSpan: `${header.colSpan}`,
|
|
3207
3294
|
// styling resize and pinning start
|
|
3208
|
-
flex: `${canResize ? "0" : "1"} 0 ${header.column.getSize()}px`, display: "grid", gridTemplateColumns: "1fr auto", zIndex: 1500 + header.index,
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3295
|
+
flex: `${canResize ? "0" : "1"} 0 ${header.column.getSize()}px`, display: "grid", gridTemplateColumns: "1fr auto", zIndex: 1500 + header.index, color: {
|
|
3296
|
+
base: "colorPalette.800",
|
|
3297
|
+
_dark: "colorPalette.200",
|
|
3298
|
+
},
|
|
3299
|
+
bg: { base: "colorPalette.100", _dark: "colorPalette.900" }, ...getThProps(header), children: [jsxRuntime.jsxs(MenuRoot, { children: [jsxRuntime.jsx(MenuTrigger, { asChild: true, children: jsxRuntime.jsx(react.Flex, { padding: `${table.getDensityValue()}px`, alignItems: "center", justifyContent: "start", borderRadius: "0rem", overflow: "auto", color: {
|
|
3300
|
+
base: "colorPalette.800",
|
|
3301
|
+
_dark: "colorPalette.200",
|
|
3302
|
+
_hover: {
|
|
3303
|
+
base: "colorPalette.700",
|
|
3304
|
+
_dark: "colorPalette.300",
|
|
3305
|
+
},
|
|
3306
|
+
},
|
|
3307
|
+
bg: {
|
|
3308
|
+
base: "colorPalette.100",
|
|
3309
|
+
_dark: "colorPalette.900",
|
|
3310
|
+
_hover: {
|
|
3311
|
+
base: "colorPalette.200",
|
|
3312
|
+
_dark: "colorPalette.800",
|
|
3212
3313
|
},
|
|
3213
3314
|
}, children: jsxRuntime.jsxs(react.Flex, { gap: "0.5rem", alignItems: "center", children: [header.isPlaceholder
|
|
3214
3315
|
? null
|
|
3215
3316
|
: reactTable.flexRender(header.column.columnDef.header, header.getContext()), jsxRuntime.jsx(react.Box, { children: header.column.getCanSort() && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [header.column.getIsSorted() === false && jsxRuntime.jsx(jsxRuntime.Fragment, {}), header.column.getIsSorted() === "asc" && (jsxRuntime.jsx(bi.BiUpArrow, {})), header.column.getIsSorted() === "desc" && (jsxRuntime.jsx(bi.BiDownArrow, {}))] })) }), jsxRuntime.jsx(react.Box, { children: header.column.getIsFiltered() && jsxRuntime.jsx(md.MdFilterListAlt, {}) })] }) }) }), jsxRuntime.jsxs(MenuContent, { children: [!header.column.getIsPinned() && (jsxRuntime.jsx(MenuItem, { asChild: true, value: "pin-column", children: jsxRuntime.jsxs(Button, { variant: "ghost", onClick: () => {
|
|
3216
3317
|
header.column.pin("left");
|
|
3217
|
-
}, children: [jsxRuntime.jsx(md.MdPushPin, {}),
|
|
3318
|
+
}, children: [jsxRuntime.jsx(md.MdPushPin, {}), getHeaderText(header, "pinColumn")] }) })), header.column.getIsPinned() && (jsxRuntime.jsx(MenuItem, { asChild: true, value: "cancel-pin", children: jsxRuntime.jsxs(Button, { variant: "ghost", onClick: () => {
|
|
3218
3319
|
header.column.pin(false);
|
|
3219
|
-
}, children: [jsxRuntime.jsx(md.MdCancel, {}),
|
|
3320
|
+
}, children: [jsxRuntime.jsx(md.MdCancel, {}), getHeaderText(header, "cancelPin")] }) })), header.column.getCanSort() && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(MenuItem, { asChild: true, value: "sort-ascend", children: jsxRuntime.jsxs(Button, { variant: "ghost", onClick: () => {
|
|
3220
3321
|
table.setSorting((state) => {
|
|
3221
3322
|
return [
|
|
3222
3323
|
...state.filter((column) => {
|
|
@@ -3225,7 +3326,7 @@ const TableHeader = ({ canResize = true, pinnedBgColor = { light: "gray.50", dar
|
|
|
3225
3326
|
{ id: header.id, desc: false },
|
|
3226
3327
|
];
|
|
3227
3328
|
});
|
|
3228
|
-
}, children: [jsxRuntime.jsx(gr.GrAscend, {}),
|
|
3329
|
+
}, children: [jsxRuntime.jsx(gr.GrAscend, {}), getHeaderText(header, "sortAscending")] }) }), jsxRuntime.jsx(MenuItem, { asChild: true, value: "sort-descend", children: jsxRuntime.jsxs(Button, { variant: "ghost", onClick: () => {
|
|
3229
3330
|
table.setSorting((state) => {
|
|
3230
3331
|
return [
|
|
3231
3332
|
...state.filter((column) => {
|
|
@@ -3234,42 +3335,30 @@ const TableHeader = ({ canResize = true, pinnedBgColor = { light: "gray.50", dar
|
|
|
3234
3335
|
{ id: header.id, desc: true },
|
|
3235
3336
|
];
|
|
3236
3337
|
});
|
|
3237
|
-
}, children: [jsxRuntime.jsx(gr.GrDescend, {}),
|
|
3338
|
+
}, children: [jsxRuntime.jsx(gr.GrDescend, {}), getHeaderText(header, "sortDescending")] }) }), header.column.getIsSorted() && (jsxRuntime.jsx(MenuItem, { asChild: true, value: "clear-sorting", children: jsxRuntime.jsxs(Button, { variant: "ghost", onClick: () => {
|
|
3238
3339
|
header.column.clearSorting();
|
|
3239
|
-
}, children: [jsxRuntime.jsx(md.MdClear, {}),
|
|
3340
|
+
}, children: [jsxRuntime.jsx(md.MdClear, {}), getHeaderText(header, "clearSorting")] }) }))] }))] })] }), canResize && (jsxRuntime.jsx(react.Box, { borderRight: "0.2rem solid", borderRightColor: header.column.getIsResizing()
|
|
3341
|
+
? "colorPalette.700"
|
|
3342
|
+
: "transparent", position: "relative", right: "0.1rem", width: "2px", height: "100%", userSelect: "none", style: { touchAction: "none" }, _hover: {
|
|
3240
3343
|
borderRightColor: header.column.getIsResizing()
|
|
3241
|
-
? "
|
|
3242
|
-
: "
|
|
3344
|
+
? "colorPalette.700"
|
|
3345
|
+
: "colorPalette.400",
|
|
3243
3346
|
}, ...resizeProps }))] }, `chakra-table-header-${header.id}`));
|
|
3244
3347
|
})] }, `chakra-table-headergroup-${headerGroup.id}`))) }));
|
|
3245
3348
|
};
|
|
3246
3349
|
|
|
3247
|
-
const
|
|
3248
|
-
const { title, description, icon, children, ...rest } = props;
|
|
3249
|
-
return (jsxRuntime.jsx(react.EmptyState.Root, { ref: ref, ...rest, children: jsxRuntime.jsxs(react.EmptyState.Content, { children: [icon && (jsxRuntime.jsx(react.EmptyState.Indicator, { children: icon })), description ? (jsxRuntime.jsxs(react.VStack, { textAlign: "center", children: [jsxRuntime.jsx(react.EmptyState.Title, { children: title }), jsxRuntime.jsx(react.EmptyState.Description, { children: description })] })) : (jsxRuntime.jsx(react.EmptyState.Title, { children: title })), children] }) }));
|
|
3250
|
-
});
|
|
3251
|
-
|
|
3252
|
-
const EmptyResult = (jsxRuntime.jsx(EmptyState, { icon: jsxRuntime.jsx(hi.HiColorSwatch, {}), title: "No results found", description: "Try adjusting your search", children: jsxRuntime.jsxs(react.List.Root, { variant: "marker", children: [jsxRuntime.jsx(react.List.Item, { children: "Try removing filters" }), jsxRuntime.jsx(react.List.Item, { children: "Try different keywords" })] }) }));
|
|
3253
|
-
const Table = ({ children, emptyComponent = EmptyResult, canResize = true, ...props }) => {
|
|
3254
|
-
const { table } = useDataTableContext();
|
|
3255
|
-
if (table.getRowModel().rows.length <= 0) {
|
|
3256
|
-
return emptyComponent;
|
|
3257
|
-
}
|
|
3258
|
-
return (jsxRuntime.jsx(react.Table.Root, { stickyHeader: true, variant: "outline", width: canResize ? table.getCenterTotalSize() : undefined, display: "grid", alignContent: "start", overflowY: "auto", ...props, children: children }));
|
|
3259
|
-
};
|
|
3260
|
-
|
|
3261
|
-
const DefaultTable = ({ showFooter = false, tableProps = {}, tableHeaderProps = {}, tableBodyProps = {}, controlProps = {}, tableFooterProps = {}, variant = "", }) => {
|
|
3350
|
+
const DefaultTable = ({ showFooter = false, tableProps = {}, tableHeaderProps = {}, tableBodyProps = {}, tableFooterProps = {}, controlProps = {}, variant = "", }) => {
|
|
3262
3351
|
if (variant === "greedy") {
|
|
3263
3352
|
return (jsxRuntime.jsx(TableControls, { ...controlProps, children: jsxRuntime.jsxs(Table, { canResize: false, ...{ ...tableProps }, children: [jsxRuntime.jsx(TableHeader, { canResize: false, ...tableHeaderProps }), jsxRuntime.jsx(TableBody, { canResize: false, ...tableBodyProps }), showFooter && (jsxRuntime.jsx(TableFooter, { canResize: false, ...tableFooterProps }))] }) }));
|
|
3264
3353
|
}
|
|
3265
3354
|
return (jsxRuntime.jsx(TableControls, { ...controlProps, children: jsxRuntime.jsxs(Table, { ...tableProps, children: [jsxRuntime.jsx(TableHeader, { ...tableHeaderProps }), jsxRuntime.jsx(TableBody, { ...tableBodyProps }), showFooter && jsxRuntime.jsx(TableFooter, { ...tableFooterProps })] }) }));
|
|
3266
3355
|
};
|
|
3267
3356
|
|
|
3268
|
-
const TableCardContainer = ({ children, variant = "", ...props }) => {
|
|
3357
|
+
const TableCardContainer = ({ children, variant = "", gap = "1rem", gridTemplateColumns = "repeat(auto-fit, minmax(20rem, 1fr))", direction = "row", ...props }) => {
|
|
3269
3358
|
if (variant === "carousel") {
|
|
3270
|
-
return (jsxRuntime.jsx(react.Flex, { overflow: "
|
|
3359
|
+
return (jsxRuntime.jsx(react.Flex, { overflow: "auto", gap: gap, direction: direction, ...props, children: children }));
|
|
3271
3360
|
}
|
|
3272
|
-
return (jsxRuntime.jsx(react.Grid, { gridTemplateColumns:
|
|
3361
|
+
return (jsxRuntime.jsx(react.Grid, { gridTemplateColumns: gridTemplateColumns, gap: gap, ...props, children: children }));
|
|
3273
3362
|
};
|
|
3274
3363
|
|
|
3275
3364
|
const DefaultCardTitle = () => {
|
|
@@ -3298,8 +3387,8 @@ const TableComponent = ({ render = () => {
|
|
|
3298
3387
|
};
|
|
3299
3388
|
|
|
3300
3389
|
const TableLoadingComponent = ({ render, }) => {
|
|
3301
|
-
const {
|
|
3302
|
-
return jsxRuntime.jsx(jsxRuntime.Fragment, { children: render(
|
|
3390
|
+
const { query } = useDataTableServerContext();
|
|
3391
|
+
return jsxRuntime.jsx(jsxRuntime.Fragment, { children: render(query.isLoading) });
|
|
3303
3392
|
};
|
|
3304
3393
|
|
|
3305
3394
|
const SelectAllRowsToggle = ({ selectAllIcon = jsxRuntime.jsx(md.MdOutlineChecklist, {}), clearAllIcon = jsxRuntime.jsx(md.MdClear, {}), selectAllText = "", clearAllText = "", }) => {
|
|
@@ -3385,50 +3474,43 @@ const useDataTable = ({ default: { sorting: defaultSorting = [], pagination: def
|
|
|
3385
3474
|
};
|
|
3386
3475
|
};
|
|
3387
3476
|
|
|
3388
|
-
const useDataTableServer = (
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
pagination
|
|
3477
|
+
const useDataTableServer = (props) => {
|
|
3478
|
+
const { url, default: defaultProps, keyPrefix, placeholderData, queryFn: customQueryFn, } = props;
|
|
3479
|
+
const { sorting: defaultSorting, pagination: defaultPagination, rowSelection: defaultRowSelection, columnFilters: defaultColumnFilters, columnOrder: defaultColumnOrder, columnVisibility: defaultColumnVisibility, globalFilter: defaultGlobalFilter, density: defaultDensity, } = defaultProps || {};
|
|
3480
|
+
const [sorting, setSorting] = React.useState(defaultSorting || []);
|
|
3481
|
+
const [columnFilters, setColumnFilters] = React.useState(defaultColumnFilters || []); // can set initial column filter state here
|
|
3482
|
+
const [pagination, setPagination] = React.useState(defaultPagination || {
|
|
3394
3483
|
pageIndex: 0, //initial page index
|
|
3395
|
-
pageSize: 10, //
|
|
3396
|
-
}
|
|
3397
|
-
rowSelection
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
}, keyPrefix, }) => {
|
|
3404
|
-
const [sorting, setSorting] = React.useState(defaultSorting);
|
|
3405
|
-
const [columnFilters, setColumnFilters] = React.useState(defaultColumnFilters); // can set initial column filter state here
|
|
3406
|
-
const [pagination, setPagination] = React.useState(defaultPagination);
|
|
3407
|
-
const [rowSelection, setRowSelection] = React.useState(defaultRowSelection);
|
|
3408
|
-
const [columnOrder, setColumnOrder] = React.useState(defaultColumnOrder);
|
|
3409
|
-
const [globalFilter, setGlobalFilter] = React.useState(defaultGlobalFilter);
|
|
3410
|
-
const [density, setDensity] = React.useState(defaultDensity);
|
|
3411
|
-
const [columnVisibility, setColumnVisibility] = React.useState(defaultColumnVisibility);
|
|
3484
|
+
pageSize: 10, //default page size
|
|
3485
|
+
});
|
|
3486
|
+
const [rowSelection, setRowSelection] = React.useState(defaultRowSelection || {});
|
|
3487
|
+
const [columnOrder, setColumnOrder] = React.useState(defaultColumnOrder || []);
|
|
3488
|
+
const [globalFilter, setGlobalFilter] = React.useState(defaultGlobalFilter || "");
|
|
3489
|
+
const [density, setDensity] = React.useState(defaultDensity || "sm");
|
|
3490
|
+
const [columnVisibility, setColumnVisibility] = React.useState(defaultColumnVisibility || {});
|
|
3491
|
+
const { pageSize, pageIndex } = pagination;
|
|
3412
3492
|
const params = {
|
|
3413
|
-
offset:
|
|
3414
|
-
limit:
|
|
3493
|
+
offset: pageIndex * pageSize,
|
|
3494
|
+
limit: pageSize,
|
|
3415
3495
|
sorting,
|
|
3416
3496
|
where: columnFilters,
|
|
3417
3497
|
searching: globalFilter,
|
|
3418
3498
|
};
|
|
3499
|
+
const defaultQueryFn = async () => {
|
|
3500
|
+
if (!url) {
|
|
3501
|
+
throw new Error("url is required");
|
|
3502
|
+
}
|
|
3503
|
+
const response = await axios.get(url, {
|
|
3504
|
+
params,
|
|
3505
|
+
});
|
|
3506
|
+
return response.data;
|
|
3507
|
+
};
|
|
3419
3508
|
const query = reactQuery.useQuery({
|
|
3420
3509
|
queryKey: [url, JSON.stringify(params)],
|
|
3421
|
-
queryFn:
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
})
|
|
3426
|
-
.then((res) => res.data);
|
|
3427
|
-
},
|
|
3428
|
-
placeholderData: {
|
|
3429
|
-
count: 0,
|
|
3430
|
-
data: [],
|
|
3431
|
-
},
|
|
3510
|
+
queryFn: customQueryFn !== undefined
|
|
3511
|
+
? () => customQueryFn(params)
|
|
3512
|
+
: defaultQueryFn,
|
|
3513
|
+
placeholderData,
|
|
3432
3514
|
});
|
|
3433
3515
|
const translate = reactI18next.useTranslation("", { keyPrefix });
|
|
3434
3516
|
return {
|
|
@@ -3518,7 +3600,71 @@ const getColumns = ({ schema, include = [], ignore = [], width = [], meta = {},
|
|
|
3518
3600
|
return columns;
|
|
3519
3601
|
};
|
|
3520
3602
|
|
|
3521
|
-
const
|
|
3603
|
+
const TableDataDisplay = ({ colorPalette, emptyComponent, }) => {
|
|
3604
|
+
const { columns, translate, data } = useDataTableContext();
|
|
3605
|
+
const columnsMap = Object.fromEntries(columns.map((def) => {
|
|
3606
|
+
const { accessorKey, id } = def;
|
|
3607
|
+
if (accessorKey) {
|
|
3608
|
+
return [accessorKey, def];
|
|
3609
|
+
}
|
|
3610
|
+
return [id, def];
|
|
3611
|
+
}));
|
|
3612
|
+
const columnHeaders = Object.keys(columnsMap);
|
|
3613
|
+
const totalWidths = columns
|
|
3614
|
+
.map(({ size }) => {
|
|
3615
|
+
if (!!size === false) {
|
|
3616
|
+
return 0;
|
|
3617
|
+
}
|
|
3618
|
+
if (typeof size === "number") {
|
|
3619
|
+
return size;
|
|
3620
|
+
}
|
|
3621
|
+
return 0;
|
|
3622
|
+
})
|
|
3623
|
+
.reduce((previous, current) => previous + current, 0);
|
|
3624
|
+
const columnWidths = columns
|
|
3625
|
+
.map(({ size }) => {
|
|
3626
|
+
if (!!size === false) {
|
|
3627
|
+
return "1fr";
|
|
3628
|
+
}
|
|
3629
|
+
return `minmax(${size}px, ${(size / totalWidths) * 100}%)`;
|
|
3630
|
+
})
|
|
3631
|
+
.join(" ");
|
|
3632
|
+
console.log({ columnWidths }, "hadfg");
|
|
3633
|
+
const cellProps = {
|
|
3634
|
+
flex: "1 0 0%",
|
|
3635
|
+
overflow: "auto",
|
|
3636
|
+
paddingX: "2",
|
|
3637
|
+
py: "1",
|
|
3638
|
+
color: { base: "colorPalette.900", _dark: "colorPalette.100" },
|
|
3639
|
+
bgColor: { base: "colorPalette.50", _dark: "colorPalette.950" },
|
|
3640
|
+
borderBottomColor: { base: "colorPalette.200", _dark: "colorPalette.800" },
|
|
3641
|
+
borderBottomWidth: "1px",
|
|
3642
|
+
...{ colorPalette },
|
|
3643
|
+
};
|
|
3644
|
+
if (data.length <= 0) {
|
|
3645
|
+
return jsxRuntime.jsx(jsxRuntime.Fragment, { children: emptyComponent });
|
|
3646
|
+
}
|
|
3647
|
+
return (jsxRuntime.jsxs(react.Grid, { templateColumns: `${columnWidths}`, overflow: "auto", borderWidth: "1px", color: { base: "colorPalette.900", _dark: "colorPalette.100" }, borderColor: { base: "colorPalette.200", _dark: "colorPalette.800" }, colorPalette, children: [jsxRuntime.jsx(react.Grid, { templateColumns: `${columnWidths}`, column: `1/span ${columns.length}`, bg: { base: "colorPalette.200", _dark: "colorPalette.800" }, colorPalette, children: columnHeaders.map((header) => {
|
|
3648
|
+
return (jsxRuntime.jsx(react.Box, { flex: "1 0 0%", paddingX: "2", py: "1", overflow: "auto", textOverflow: "ellipsis", children: translate.t(`column_header.${header}`) }));
|
|
3649
|
+
}) }), data.map((record) => {
|
|
3650
|
+
return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: columnHeaders.map((header) => {
|
|
3651
|
+
const { cell } = columnsMap[header];
|
|
3652
|
+
const value = record[header];
|
|
3653
|
+
if (!!record === false) {
|
|
3654
|
+
return (jsxRuntime.jsx(react.Box, { ...cellProps, children: translate.t(`column_cell.placeholder`) }));
|
|
3655
|
+
}
|
|
3656
|
+
if (cell) {
|
|
3657
|
+
return (jsxRuntime.jsx(react.Box, { ...cellProps, children: cell({ row: { original: record } }) }));
|
|
3658
|
+
}
|
|
3659
|
+
if (typeof value === "object") {
|
|
3660
|
+
return (jsxRuntime.jsx(react.Box, { ...cellProps, children: jsxRuntime.jsx(RecordDisplay, { object: value }) }));
|
|
3661
|
+
}
|
|
3662
|
+
return jsxRuntime.jsx(react.Box, { ...cellProps, children: value });
|
|
3663
|
+
}) }));
|
|
3664
|
+
})] }));
|
|
3665
|
+
};
|
|
3666
|
+
|
|
3667
|
+
const AccordionItemTrigger = React__namespace.forwardRef(function AccordionItemTrigger(props, ref) {
|
|
3522
3668
|
const { children, indicatorPlacement = "end", ...rest } = props;
|
|
3523
3669
|
return (jsxRuntime.jsxs(react.Accordion.ItemTrigger, { ...rest, ref: ref, children: [indicatorPlacement === "start" && (jsxRuntime.jsx(react.Accordion.ItemIndicator, { rotate: { base: "-90deg", _open: "0deg" }, children: jsxRuntime.jsx(lu.LuChevronDown, {}) })), jsxRuntime.jsx(react.HStack, { gap: "4", flex: "1", textAlign: "start", width: "full", children: children }), indicatorPlacement === "end" && (jsxRuntime.jsx(react.Accordion.ItemIndicator, { children: jsxRuntime.jsx(lu.LuChevronDown, {}) }))] }));
|
|
3524
3670
|
});
|
|
@@ -3539,6 +3685,12 @@ const SchemaFormContext = React.createContext({
|
|
|
3539
3685
|
onSubmit: async () => { },
|
|
3540
3686
|
rowNumber: 0,
|
|
3541
3687
|
requestOptions: {},
|
|
3688
|
+
timezone: 'Asia/Hong_Kong',
|
|
3689
|
+
displayConfig: {
|
|
3690
|
+
showSubmitButton: true,
|
|
3691
|
+
showResetButton: true,
|
|
3692
|
+
showTitle: true,
|
|
3693
|
+
},
|
|
3542
3694
|
});
|
|
3543
3695
|
|
|
3544
3696
|
const useSchemaContext = () => {
|
|
@@ -3549,6 +3701,24 @@ const clearEmptyString = (object) => {
|
|
|
3549
3701
|
return Object.fromEntries(Object.entries(object).filter(([, value]) => value !== ""));
|
|
3550
3702
|
};
|
|
3551
3703
|
|
|
3704
|
+
const validateData = (data, schema) => {
|
|
3705
|
+
const ajv = new Ajv({
|
|
3706
|
+
strict: false,
|
|
3707
|
+
allErrors: true,
|
|
3708
|
+
});
|
|
3709
|
+
addFormats(ajv);
|
|
3710
|
+
addErrors(ajv);
|
|
3711
|
+
const validate = ajv.compile(schema);
|
|
3712
|
+
const validationResult = validate(data);
|
|
3713
|
+
const errors = validate.errors;
|
|
3714
|
+
console.log(errors, data);
|
|
3715
|
+
return {
|
|
3716
|
+
isValid: validationResult,
|
|
3717
|
+
validate,
|
|
3718
|
+
errors,
|
|
3719
|
+
};
|
|
3720
|
+
};
|
|
3721
|
+
|
|
3552
3722
|
const idPickerSanityCheck = (column, foreign_key) => {
|
|
3553
3723
|
if (!!foreign_key == false) {
|
|
3554
3724
|
throw new Error(`The key foreign_key does not exist in properties of column ${column} when using id-picker.`);
|
|
@@ -3564,7 +3734,11 @@ const idPickerSanityCheck = (column, foreign_key) => {
|
|
|
3564
3734
|
throw new Error(`The key column does not exist in properties of column ${column} when using id-picker.`);
|
|
3565
3735
|
}
|
|
3566
3736
|
};
|
|
3567
|
-
const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, children, order = [], ignore = [], include = [], onSubmit = undefined, rowNumber = undefined, requestOptions = {}, getUpdatedData = () => { },
|
|
3737
|
+
const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, children, order = [], ignore = [], include = [], onSubmit = undefined, rowNumber = undefined, requestOptions = {}, getUpdatedData = () => { }, customErrorRenderer, displayConfig = {
|
|
3738
|
+
showSubmitButton: true,
|
|
3739
|
+
showResetButton: true,
|
|
3740
|
+
showTitle: true,
|
|
3741
|
+
}, }) => {
|
|
3568
3742
|
const [isSuccess, setIsSuccess] = React.useState(false);
|
|
3569
3743
|
const [isError, setIsError] = React.useState(false);
|
|
3570
3744
|
const [isSubmiting, setIsSubmiting] = React.useState(false);
|
|
@@ -3597,11 +3771,13 @@ const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, childre
|
|
|
3597
3771
|
error,
|
|
3598
3772
|
setError,
|
|
3599
3773
|
getUpdatedData,
|
|
3774
|
+
customErrorRenderer,
|
|
3775
|
+
displayConfig,
|
|
3600
3776
|
}, children: jsxRuntime.jsx(reactHookForm.FormProvider, { ...form, children: children }) }));
|
|
3601
3777
|
};
|
|
3602
3778
|
|
|
3603
3779
|
function removeIndex(str) {
|
|
3604
|
-
return str.replace(/\.\d+\./g,
|
|
3780
|
+
return str.replace(/\.\d+\./g, ".");
|
|
3605
3781
|
}
|
|
3606
3782
|
|
|
3607
3783
|
const ArrayRenderer = ({ schema, column, prefix, }) => {
|
|
@@ -3613,13 +3789,17 @@ const ArrayRenderer = ({ schema, column, prefix, }) => {
|
|
|
3613
3789
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
3614
3790
|
const { formState: { errors }, setValue, watch, } = reactHookForm.useFormContext();
|
|
3615
3791
|
const fields = (watch(colLabel) ?? []);
|
|
3616
|
-
return (jsxRuntime.jsxs(react.
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3792
|
+
return (jsxRuntime.jsxs(react.Flex, { gridRow, gridColumn, flexFlow: "column", gap: 2, children: [jsxRuntime.jsxs(react.Box, { as: "label", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsxRuntime.jsx("span", { children: "*" })] }), jsxRuntime.jsx(react.Flex, { flexFlow: "column", gap: 2, children: fields.map((field, index) => (jsxRuntime.jsxs(react.Grid, { gridTemplateColumns: '1fr auto', gap: 2, bgColor: { base: "colorPalette.100", _dark: "colorPalette.900" }, p: 2, borderRadius: 4, borderWidth: 1, borderColor: {
|
|
3793
|
+
base: "colorPalette.200",
|
|
3794
|
+
_dark: "colorPalette.800",
|
|
3795
|
+
}, children: [jsxRuntime.jsx(react.Grid, { gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: jsxRuntime.jsx(SchemaRenderer, { column: `${index}`,
|
|
3796
|
+
prefix: `${colLabel}.`,
|
|
3797
|
+
// @ts-expect-error find suitable types
|
|
3798
|
+
schema: { showLabel: false, ...(items ?? {}) } }) }), jsxRuntime.jsx(react.Flex, { justifyContent: "end", children: jsxRuntime.jsx(react.Button, { variant: "ghost", onClick: () => {
|
|
3799
|
+
setValue(colLabel, fields.filter((_, curIndex) => {
|
|
3800
|
+
return curIndex !== index;
|
|
3801
|
+
}));
|
|
3802
|
+
}, children: jsxRuntime.jsx(react.Icon, { children: jsxRuntime.jsx(cg.CgTrash, {}) }) }) })] }, `${colLabel}.${index}`))) }), jsxRuntime.jsx(react.Flex, { children: jsxRuntime.jsx(react.Button, { onClick: () => {
|
|
3623
3803
|
if (type === "number") {
|
|
3624
3804
|
setValue(colLabel, [...fields, 0]);
|
|
3625
3805
|
return;
|
|
@@ -3633,7 +3813,7 @@ const ArrayRenderer = ({ schema, column, prefix, }) => {
|
|
|
3633
3813
|
return;
|
|
3634
3814
|
}
|
|
3635
3815
|
setValue(colLabel, [...fields, {}]);
|
|
3636
|
-
}, children: translate.t(removeIndex(`${colLabel}.add`)) }) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.
|
|
3816
|
+
}, children: translate.t(removeIndex(`${colLabel}.add`)) }) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
3637
3817
|
};
|
|
3638
3818
|
|
|
3639
3819
|
const Field = React__namespace.forwardRef(function Field(props, ref) {
|
|
@@ -3644,37 +3824,36 @@ const Field = React__namespace.forwardRef(function Field(props, ref) {
|
|
|
3644
3824
|
const BooleanPicker = ({ schema, column, prefix }) => {
|
|
3645
3825
|
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
3646
3826
|
const { translate } = useSchemaContext();
|
|
3647
|
-
const { required, gridColumn, gridRow } = schema;
|
|
3827
|
+
const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
|
|
3648
3828
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
3649
3829
|
const colLabel = `${prefix}${column}`;
|
|
3650
3830
|
const value = watch(colLabel);
|
|
3651
|
-
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.
|
|
3831
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
3652
3832
|
gridRow, children: [jsxRuntime.jsx(CheckboxCard, { checked: value, variant: "surface", onChange: () => {
|
|
3653
3833
|
setValue(colLabel, !value);
|
|
3654
|
-
} }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.
|
|
3834
|
+
} }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
3835
|
+
};
|
|
3836
|
+
|
|
3837
|
+
const CustomInput = ({ column, schema, prefix }) => {
|
|
3838
|
+
const formContext = reactHookForm.useFormContext();
|
|
3839
|
+
const { inputRender } = schema;
|
|
3840
|
+
return (inputRender &&
|
|
3841
|
+
inputRender({
|
|
3842
|
+
column,
|
|
3843
|
+
schema,
|
|
3844
|
+
prefix,
|
|
3845
|
+
formContext,
|
|
3846
|
+
}));
|
|
3655
3847
|
};
|
|
3656
3848
|
|
|
3657
|
-
const monthNamesShort = [
|
|
3658
|
-
"Jan",
|
|
3659
|
-
"Feb",
|
|
3660
|
-
"Mar",
|
|
3661
|
-
"Apr",
|
|
3662
|
-
"May",
|
|
3663
|
-
"Jun",
|
|
3664
|
-
"Jul",
|
|
3665
|
-
"Aug",
|
|
3666
|
-
"Sep",
|
|
3667
|
-
"Oct",
|
|
3668
|
-
"Nov",
|
|
3669
|
-
"Dec",
|
|
3670
|
-
];
|
|
3671
|
-
const weekdayNamesShort = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
3672
3849
|
const Calendar = ({ calendars, getBackProps, getForwardProps, getDateProps, firstDayOfWeek = 0, }) => {
|
|
3850
|
+
const { labels } = React.useContext(DatePickerContext);
|
|
3851
|
+
const { monthNamesShort, weekdayNamesShort, backButtonLabel, forwardButtonLabel } = labels;
|
|
3673
3852
|
if (calendars.length) {
|
|
3674
3853
|
return (jsxRuntime.jsxs(react.Grid, { children: [jsxRuntime.jsxs(react.Grid, { templateColumns: "repeat(4, auto)", justifyContent: "center", children: [jsxRuntime.jsx(react.Button, { variant: "ghost", ...getBackProps({
|
|
3675
3854
|
calendars,
|
|
3676
3855
|
offset: 12,
|
|
3677
|
-
}), children: "<<" }), jsxRuntime.jsx(react.Button, { variant: "ghost", ...getBackProps({ calendars }), children:
|
|
3856
|
+
}), children: "<<" }), jsxRuntime.jsx(react.Button, { variant: "ghost", ...getBackProps({ calendars }), children: backButtonLabel }), jsxRuntime.jsx(react.Button, { variant: "ghost", ...getForwardProps({ calendars }), children: forwardButtonLabel }), jsxRuntime.jsx(react.Button, { variant: "ghost", ...getForwardProps({
|
|
3678
3857
|
calendars,
|
|
3679
3858
|
offset: 12,
|
|
3680
3859
|
}), children: ">>" })] }), jsxRuntime.jsx(react.Grid, { templateColumns: "repeat(2, auto)", justifyContent: "center", children: calendars.map((calendar) => (jsxRuntime.jsxs(react.Grid, { gap: 4, children: [jsxRuntime.jsxs(react.Grid, { justifyContent: "center", children: [monthNamesShort[calendar.month], " ", calendar.year] }), jsxRuntime.jsxs(react.Grid, { templateColumns: "repeat(7, auto)", justifyContent: "center", children: [[0, 1, 2, 3, 4, 5, 6].map((weekdayNum) => {
|
|
@@ -3717,9 +3896,52 @@ const Calendar = ({ calendars, getBackProps, getForwardProps, getDateProps, firs
|
|
|
3717
3896
|
}
|
|
3718
3897
|
return null;
|
|
3719
3898
|
};
|
|
3899
|
+
const DatePickerContext = React.createContext({
|
|
3900
|
+
labels: {
|
|
3901
|
+
monthNamesShort: [
|
|
3902
|
+
"Jan",
|
|
3903
|
+
"Feb",
|
|
3904
|
+
"Mar",
|
|
3905
|
+
"Apr",
|
|
3906
|
+
"May",
|
|
3907
|
+
"Jun",
|
|
3908
|
+
"Jul",
|
|
3909
|
+
"Aug",
|
|
3910
|
+
"Sep",
|
|
3911
|
+
"Oct",
|
|
3912
|
+
"Nov",
|
|
3913
|
+
"Dec",
|
|
3914
|
+
],
|
|
3915
|
+
weekdayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
|
|
3916
|
+
backButtonLabel: "Back",
|
|
3917
|
+
forwardButtonLabel: "Next",
|
|
3918
|
+
},
|
|
3919
|
+
});
|
|
3720
3920
|
let DatePicker$1 = class DatePicker extends React.Component {
|
|
3721
3921
|
render() {
|
|
3722
|
-
|
|
3922
|
+
const { labels = {
|
|
3923
|
+
monthNamesShort: [
|
|
3924
|
+
"Jan",
|
|
3925
|
+
"Feb",
|
|
3926
|
+
"Mar",
|
|
3927
|
+
"Apr",
|
|
3928
|
+
"May",
|
|
3929
|
+
"Jun",
|
|
3930
|
+
"Jul",
|
|
3931
|
+
"Aug",
|
|
3932
|
+
"Sep",
|
|
3933
|
+
"Oct",
|
|
3934
|
+
"Nov",
|
|
3935
|
+
"Dec",
|
|
3936
|
+
],
|
|
3937
|
+
weekdayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
|
|
3938
|
+
backButtonLabel: "Back",
|
|
3939
|
+
forwardButtonLabel: "Next",
|
|
3940
|
+
}, } = this.props;
|
|
3941
|
+
return (jsxRuntime.jsx(DatePickerContext.Provider, { value: { labels }, children: jsxRuntime.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:
|
|
3942
|
+
// @ts-expect-error - Dayzed types need to be fixed
|
|
3943
|
+
(dayzedData) => (jsxRuntime.jsx(Calendar, { ...dayzedData,
|
|
3944
|
+
firstDayOfWeek: this.props.firstDayOfWeek })) }) }));
|
|
3723
3945
|
}
|
|
3724
3946
|
};
|
|
3725
3947
|
|
|
@@ -3741,28 +3963,86 @@ const PopoverRoot = react.Popover.Root;
|
|
|
3741
3963
|
const PopoverBody = react.Popover.Body;
|
|
3742
3964
|
const PopoverTrigger = react.Popover.Trigger;
|
|
3743
3965
|
|
|
3966
|
+
function translateWrapper({ prefix, column, label, translate, }) {
|
|
3967
|
+
return translate.t(removeIndex(`${prefix}${column}.${label}`));
|
|
3968
|
+
}
|
|
3969
|
+
|
|
3970
|
+
dayjs.extend(utc);
|
|
3971
|
+
dayjs.extend(timezone);
|
|
3744
3972
|
const DatePicker = ({ column, schema, prefix }) => {
|
|
3745
3973
|
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
3746
|
-
const { translate } = useSchemaContext();
|
|
3747
|
-
const { required, gridColumn, gridRow } = schema;
|
|
3974
|
+
const { translate, timezone } = useSchemaContext();
|
|
3975
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD", dateFormat = "YYYY-MM-DD", } = schema;
|
|
3748
3976
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
3749
3977
|
const colLabel = `${prefix}${column}`;
|
|
3750
3978
|
const [open, setOpen] = React.useState(false);
|
|
3751
3979
|
const selectedDate = watch(colLabel);
|
|
3752
|
-
const
|
|
3753
|
-
|
|
3754
|
-
|
|
3980
|
+
const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
|
|
3981
|
+
React.useEffect(() => {
|
|
3982
|
+
try {
|
|
3983
|
+
if (selectedDate) {
|
|
3984
|
+
// Parse the selectedDate as UTC or in a specific timezone to avoid +8 hour shift
|
|
3985
|
+
// For example, parse as UTC:
|
|
3986
|
+
const parsedDate = dayjs(selectedDate).tz(timezone);
|
|
3987
|
+
if (!parsedDate.isValid())
|
|
3988
|
+
return;
|
|
3989
|
+
// Format according to dateFormat from schema
|
|
3990
|
+
const formatted = parsedDate.format(dateFormat);
|
|
3991
|
+
// Update the form value only if different to avoid loops
|
|
3992
|
+
if (formatted !== selectedDate) {
|
|
3993
|
+
setValue(colLabel, formatted, {
|
|
3994
|
+
shouldValidate: true,
|
|
3995
|
+
shouldDirty: true,
|
|
3996
|
+
});
|
|
3997
|
+
}
|
|
3998
|
+
}
|
|
3999
|
+
}
|
|
4000
|
+
catch (e) {
|
|
4001
|
+
console.error(e);
|
|
4002
|
+
}
|
|
4003
|
+
}, [selectedDate, dateFormat, colLabel, setValue]);
|
|
4004
|
+
const customTranslate = (label) => {
|
|
4005
|
+
return translateWrapper({ prefix, column, label, translate });
|
|
4006
|
+
};
|
|
4007
|
+
return (jsxRuntime.jsxs(Field, { label: `${customTranslate(`field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
4008
|
+
gridRow, children: [jsxRuntime.jsxs(PopoverRoot, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: jsxRuntime.jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
|
|
3755
4009
|
setOpen(true);
|
|
3756
|
-
}, children: selectedDate !== undefined ? `${
|
|
3757
|
-
|
|
3758
|
-
, {
|
|
3759
|
-
// @ts-expect-error TODO: find appropriate types
|
|
3760
|
-
selected: new Date(selectedDate),
|
|
3761
|
-
// @ts-expect-error TODO: find appropriate types
|
|
3762
|
-
onDateSelected: ({ date }) => {
|
|
3763
|
-
setValue(colLabel, dayjs(date).format("YYYY-MM-DD"));
|
|
4010
|
+
}, justifyContent: "start", children: [jsxRuntime.jsx(md.MdDateRange, {}), selectedDate !== undefined ? `${displayDate}` : ""] }) }), jsxRuntime.jsx(PopoverContent, { children: jsxRuntime.jsxs(PopoverBody, { children: [jsxRuntime.jsx(PopoverTitle, {}), jsxRuntime.jsx(DatePicker$1, { selected: new Date(selectedDate), onDateSelected: ({ date }) => {
|
|
4011
|
+
setValue(colLabel, dayjs(date).format(dateFormat));
|
|
3764
4012
|
setOpen(false);
|
|
3765
|
-
}
|
|
4013
|
+
}, labels: {
|
|
4014
|
+
monthNamesShort: [
|
|
4015
|
+
translate.t(`common.month_1`, { defaultValue: "January" }),
|
|
4016
|
+
translate.t(`common.month_2`, { defaultValue: "February" }),
|
|
4017
|
+
translate.t(`common.month_3`, { defaultValue: "March" }),
|
|
4018
|
+
translate.t(`common.month_4`, { defaultValue: "April" }),
|
|
4019
|
+
translate.t(`common.month_5`, { defaultValue: "May" }),
|
|
4020
|
+
translate.t(`common.month_6`, { defaultValue: "June" }),
|
|
4021
|
+
translate.t(`common.month_7`, { defaultValue: "July" }),
|
|
4022
|
+
translate.t(`common.month_8`, { defaultValue: "August" }),
|
|
4023
|
+
translate.t(`common.month_9`, { defaultValue: "September" }),
|
|
4024
|
+
translate.t(`common.month_10`, { defaultValue: "October" }),
|
|
4025
|
+
translate.t(`common.month_11`, { defaultValue: "November" }),
|
|
4026
|
+
translate.t(`common.month_12`, { defaultValue: "December" }),
|
|
4027
|
+
],
|
|
4028
|
+
weekdayNamesShort: [
|
|
4029
|
+
translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
|
|
4030
|
+
translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
|
|
4031
|
+
translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
|
|
4032
|
+
translate.t(`common.weekday_4`, {
|
|
4033
|
+
defaultValue: "Wed",
|
|
4034
|
+
}),
|
|
4035
|
+
translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
|
|
4036
|
+
translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
|
|
4037
|
+
translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
|
|
4038
|
+
],
|
|
4039
|
+
backButtonLabel: translate.t(`common.back_button`, {
|
|
4040
|
+
defaultValue: "Back",
|
|
4041
|
+
}),
|
|
4042
|
+
forwardButtonLabel: translate.t(`common.forward_button`, {
|
|
4043
|
+
defaultValue: "Forward",
|
|
4044
|
+
}),
|
|
4045
|
+
} })] }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: customTranslate(`field_required`) }))] }));
|
|
3766
4046
|
};
|
|
3767
4047
|
|
|
3768
4048
|
function filterArray(array, searchTerm) {
|
|
@@ -3775,12 +4055,12 @@ function filterArray(array, searchTerm) {
|
|
|
3775
4055
|
});
|
|
3776
4056
|
}
|
|
3777
4057
|
|
|
3778
|
-
const EnumPicker = ({ column, isMultiple = false, schema, prefix, }) => {
|
|
4058
|
+
const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLimit = false, }) => {
|
|
3779
4059
|
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
3780
4060
|
const { translate } = useSchemaContext();
|
|
3781
|
-
const { required } = schema;
|
|
4061
|
+
const { required, variant } = schema;
|
|
3782
4062
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
3783
|
-
const { gridColumn, gridRow, renderDisplay } = schema;
|
|
4063
|
+
const { gridColumn = "span 4", gridRow = "span 1", renderDisplay } = schema;
|
|
3784
4064
|
const [searchText, setSearchText] = React.useState();
|
|
3785
4065
|
const [limit, setLimit] = React.useState(10);
|
|
3786
4066
|
const [openSearchResult, setOpenSearchResult] = React.useState();
|
|
@@ -3795,28 +4075,61 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, }) => {
|
|
|
3795
4075
|
setSearchText(event.target.value);
|
|
3796
4076
|
setLimit(10);
|
|
3797
4077
|
};
|
|
3798
|
-
|
|
4078
|
+
if (variant === "radio") {
|
|
4079
|
+
return (jsxRuntime.jsx(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
4080
|
+
gridRow, children: jsxRuntime.jsx(react.RadioGroup.Root, { defaultValue: "1", children: jsxRuntime.jsx(react.HStack, { gap: "6", children: filterArray(dataList, searchText ?? "").map((item) => {
|
|
4081
|
+
return (jsxRuntime.jsxs(react.RadioGroup.Item, { onClick: () => {
|
|
4082
|
+
if (!isMultiple) {
|
|
4083
|
+
setOpenSearchResult(false);
|
|
4084
|
+
setValue(colLabel, item);
|
|
4085
|
+
return;
|
|
4086
|
+
}
|
|
4087
|
+
const newSet = new Set([...(watchEnums ?? []), item]);
|
|
4088
|
+
setValue(colLabel, [...newSet]);
|
|
4089
|
+
}, value: item, children: [jsxRuntime.jsx(react.RadioGroup.ItemHiddenInput, {}), jsxRuntime.jsx(react.RadioGroup.ItemIndicator, {}), jsxRuntime.jsx(react.RadioGroup.ItemText, { children: !!renderDisplay === true
|
|
4090
|
+
? renderDisplay(item)
|
|
4091
|
+
: translate.t(removeIndex(`${colLabel}.${item}`)) })] }, `${colLabel}-${item}`));
|
|
4092
|
+
}) }) }) }));
|
|
4093
|
+
}
|
|
4094
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
3799
4095
|
gridRow, children: [isMultiple && (jsxRuntime.jsxs(react.Flex, { flexFlow: "wrap", gap: 1, children: [watchEnums.map((enumValue) => {
|
|
3800
4096
|
const item = enumValue;
|
|
3801
|
-
if (item ===
|
|
3802
|
-
return jsxRuntime.jsx(jsxRuntime.Fragment, {
|
|
4097
|
+
if (!!item === false) {
|
|
4098
|
+
return jsxRuntime.jsx(jsxRuntime.Fragment, {});
|
|
3803
4099
|
}
|
|
3804
|
-
return (jsxRuntime.jsx(Tag, { closable: true, onClick: () => {
|
|
3805
|
-
// setSelectedEnums((state) => state.filter((id) => id != item));
|
|
4100
|
+
return (jsxRuntime.jsx(Tag, { size: "lg", closable: true, onClick: () => {
|
|
3806
4101
|
setValue(column, watchEnums.filter((id) => id != item));
|
|
3807
4102
|
}, children: !!renderDisplay === true
|
|
3808
4103
|
? renderDisplay(item)
|
|
3809
|
-
: translate.t(removeIndex(`${colLabel}.${item}`)) }));
|
|
3810
|
-
}), jsxRuntime.jsx(Tag, { cursor: "pointer", onClick: () => {
|
|
4104
|
+
: translate.t(removeIndex(`${colLabel}.${item}`)) }, item));
|
|
4105
|
+
}), jsxRuntime.jsx(Tag, { size: "lg", cursor: "pointer", onClick: () => {
|
|
3811
4106
|
setOpenSearchResult(true);
|
|
3812
|
-
}, children: translate.t(removeIndex(`${colLabel}.
|
|
4107
|
+
}, children: translate.t(removeIndex(`${colLabel}.add_more`)) }, `${colLabel}-add-more-tag`)] })), !isMultiple && (jsxRuntime.jsx(Button, { variant: "outline", onClick: () => {
|
|
3813
4108
|
setOpenSearchResult(true);
|
|
3814
|
-
}, children: watchEnum ===
|
|
4109
|
+
}, justifyContent: "start", children: !!watchEnum === false
|
|
3815
4110
|
? ""
|
|
3816
|
-
: translate.t(removeIndex(`${colLabel}.${watchEnum}`)) })), jsxRuntime.jsxs(PopoverRoot, { open: openSearchResult, onOpenChange: (e) => setOpenSearchResult(e.open), closeOnInteractOutside: true, initialFocusEl: () => ref.current, positioning: { placement: "bottom-start" }, children: [jsxRuntime.jsx(PopoverTrigger, {}), jsxRuntime.jsx(PopoverContent, { children: jsxRuntime.jsxs(PopoverBody, { display: "grid", gap: 1, children: [jsxRuntime.jsx(react.Input, { placeholder: translate.t(`${
|
|
4111
|
+
: translate.t(removeIndex(`${colLabel}.${watchEnum ?? "null"}`)) })), jsxRuntime.jsxs(PopoverRoot, { open: openSearchResult, onOpenChange: (e) => setOpenSearchResult(e.open), closeOnInteractOutside: true, initialFocusEl: () => ref.current, positioning: { placement: "bottom-start" }, children: [jsxRuntime.jsx(PopoverTrigger, {}), jsxRuntime.jsx(PopoverContent, { portalled: false, children: jsxRuntime.jsxs(PopoverBody, { display: "grid", gap: 1, children: [jsxRuntime.jsx(react.Input, { placeholder: translate.t(`${colLabel}.type_to_search`), onChange: (event) => {
|
|
3817
4112
|
onSearchChange(event);
|
|
3818
4113
|
setOpenSearchResult(true);
|
|
3819
|
-
}, autoComplete: "off", ref: ref }), jsxRuntime.jsx(PopoverTitle, {}), jsxRuntime.jsx(react.Text, { children: `${translate.t(`${
|
|
4114
|
+
}, autoComplete: "off", ref: ref }), jsxRuntime.jsx(PopoverTitle, {}), showTotalAndLimit && (jsxRuntime.jsx(react.Text, { children: `${translate.t(removeIndex(`${colLabel}.total`))}: ${count}, ${translate.t(removeIndex(`${colLabel}.showing`))} ${limit}` })), jsxRuntime.jsxs(react.Grid, { overflow: "auto", maxHeight: "20rem", children: [jsxRuntime.jsx(react.Flex, { flexFlow: "column wrap", children: dataList
|
|
4115
|
+
.filter((item) => {
|
|
4116
|
+
const searchTerm = (searchText || "").toLowerCase();
|
|
4117
|
+
if (!searchTerm)
|
|
4118
|
+
return true;
|
|
4119
|
+
// Check if the original enum value contains the search text
|
|
4120
|
+
const enumValueMatch = item
|
|
4121
|
+
.toLowerCase()
|
|
4122
|
+
.includes(searchTerm);
|
|
4123
|
+
// Check if the display value (translation) contains the search text
|
|
4124
|
+
const displayValue = !!renderDisplay === true
|
|
4125
|
+
? renderDisplay(item)
|
|
4126
|
+
: translate.t(removeIndex(`${colLabel}.${item}`));
|
|
4127
|
+
// Convert to string and check if it includes the search term
|
|
4128
|
+
const displayValueString = String(displayValue).toLowerCase();
|
|
4129
|
+
const displayValueMatch = displayValueString.includes(searchTerm);
|
|
4130
|
+
return enumValueMatch || displayValueMatch;
|
|
4131
|
+
})
|
|
4132
|
+
.map((item) => {
|
|
3820
4133
|
const selected = isMultiple
|
|
3821
4134
|
? watchEnums.some((enumValue) => item === enumValue)
|
|
3822
4135
|
: watchEnum == item;
|
|
@@ -3828,10 +4141,10 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, }) => {
|
|
|
3828
4141
|
}
|
|
3829
4142
|
const newSet = new Set([...(watchEnums ?? []), item]);
|
|
3830
4143
|
setValue(colLabel, [...newSet]);
|
|
3831
|
-
}, ...(selected ? { color: "
|
|
4144
|
+
}, ...(selected ? { color: "colorPalette.400/50" } : {}), children: !!renderDisplay === true
|
|
3832
4145
|
? renderDisplay(item)
|
|
3833
4146
|
: translate.t(removeIndex(`${colLabel}.${item}`)) }, `${colLabel}-${item}`));
|
|
3834
|
-
}) }), isDirty && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: dataList.length <= 0 && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: translate.t(removeIndex(`${colLabel}.
|
|
4147
|
+
}) }), isDirty && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: dataList.length <= 0 && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: translate.t(removeIndex(`${colLabel}.empty_search_result`)) })) }))] })] }) })] }), errors[`${colLabel}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
3835
4148
|
};
|
|
3836
4149
|
|
|
3837
4150
|
function isEnteringWindow(_ref) {
|
|
@@ -4183,17 +4496,17 @@ const FileDropzone = ({ children = undefined, gridProps = {}, onDrop = () => { }
|
|
|
4183
4496
|
const filesArray = [...event.target.files];
|
|
4184
4497
|
onDrop({ files: filesArray });
|
|
4185
4498
|
};
|
|
4186
|
-
return (jsxRuntime.jsxs(react.Grid, { ...getColor(isDraggedOver), ref: ref, cursor: "pointer", onClick: handleClick, borderStyle: "dashed", borderColor: "
|
|
4499
|
+
return (jsxRuntime.jsxs(react.Grid, { ...getColor(isDraggedOver), ref: ref, cursor: "pointer", onClick: handleClick, borderStyle: "dashed", borderColor: "colorPalette.400", alignContent: "center", justifyContent: "center", borderWidth: 1, borderRadius: 4, ...gridProps, children: [children, !!children === false && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(react.Flex, { children: placeholder }), jsxRuntime.jsx(react.Input, { type: "file", multiple: true, style: { display: "none" }, ref: fileInput, onChange: handleChange })] }))] }));
|
|
4187
4500
|
};
|
|
4188
4501
|
|
|
4189
4502
|
const FilePicker = ({ column, schema, prefix }) => {
|
|
4190
4503
|
const { setValue, formState: { errors }, watch, } = reactHookForm.useFormContext();
|
|
4191
4504
|
const { translate } = useSchemaContext();
|
|
4192
|
-
const { required, gridColumn, gridRow } = schema;
|
|
4505
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", } = schema;
|
|
4193
4506
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4194
4507
|
const currentFiles = (watch(column) ?? []);
|
|
4195
4508
|
const colLabel = `${prefix}${column}`;
|
|
4196
|
-
return (jsxRuntime.jsxs(Field, { label: `${translate.t(`${colLabel}.
|
|
4509
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(`${colLabel}.field_label`)}`, required: isRequired, gridColumn: gridColumn ?? "span 4", gridRow: gridRow ?? "span 1", display: "grid", gridTemplateRows: "auto 1fr auto", alignItems: "stretch", children: [jsxRuntime.jsx(FileDropzone, { onDrop: ({ files }) => {
|
|
4197
4510
|
const newFiles = files.filter(({ name }) => !currentFiles.some((cur) => cur.name === name));
|
|
4198
4511
|
setValue(colLabel, [...currentFiles, ...newFiles]);
|
|
4199
4512
|
}, placeholder: translate.t(removeIndex(`${colLabel}.fileDropzone`)) }), jsxRuntime.jsx(react.Flex, { flexFlow: "column", gap: 1, children: currentFiles.map((file) => {
|
|
@@ -4201,10 +4514,19 @@ const FilePicker = ({ column, schema, prefix }) => {
|
|
|
4201
4514
|
setValue(column, currentFiles.filter(({ name }) => {
|
|
4202
4515
|
return name !== file.name;
|
|
4203
4516
|
}));
|
|
4204
|
-
}, display: "flex", flexFlow: "row", alignItems: "center", padding: "2", children: [jsxRuntime.jsx(react.Box, { children: file.name }), jsxRuntime.jsx(ti.TiDeleteOutline, {})] }) }, file.name));
|
|
4205
|
-
}) }), errors[`${colLabel}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.
|
|
4517
|
+
}, display: "flex", flexFlow: "row", alignItems: "center", padding: "2", children: [file.type.startsWith("image/") && (jsxRuntime.jsx(react.Image, { src: URL.createObjectURL(file), alt: file.name, boxSize: "50px", objectFit: "cover", borderRadius: "md", marginRight: "2" })), jsxRuntime.jsx(react.Box, { children: file.name }), jsxRuntime.jsx(ti.TiDeleteOutline, {})] }) }, file.name));
|
|
4518
|
+
}) }), errors[`${colLabel}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4206
4519
|
};
|
|
4207
4520
|
|
|
4521
|
+
const ToggleTip = React__namespace.forwardRef(function ToggleTip(props, ref) {
|
|
4522
|
+
const { showArrow, children, portalled = true, content, portalRef, ...rest } = props;
|
|
4523
|
+
return (jsxRuntime.jsxs(react.Popover.Root, { ...rest, positioning: { ...rest.positioning, gutter: 4 }, children: [jsxRuntime.jsx(react.Popover.Trigger, { asChild: true, children: children }), jsxRuntime.jsx(react.Portal, { disabled: !portalled, container: portalRef, children: jsxRuntime.jsx(react.Popover.Positioner, { children: jsxRuntime.jsxs(react.Popover.Content, { width: "auto", px: "2", py: "1", textStyle: "xs", rounded: "sm", ref: ref, children: [showArrow && (jsxRuntime.jsx(react.Popover.Arrow, { children: jsxRuntime.jsx(react.Popover.ArrowTip, {}) })), content] }) }) })] }));
|
|
4524
|
+
});
|
|
4525
|
+
const InfoTip = React__namespace.forwardRef(function InfoTip(props, ref) {
|
|
4526
|
+
const { children, ...rest } = props;
|
|
4527
|
+
return (jsxRuntime.jsx(ToggleTip, { content: children, ...rest, ref: ref, children: jsxRuntime.jsx(react.IconButton, { variant: "ghost", "aria-label": "info", size: "2xs", colorPalette: "colorPalette", children: jsxRuntime.jsx(hi.HiOutlineInformationCircle, {}) }) }));
|
|
4528
|
+
});
|
|
4529
|
+
|
|
4208
4530
|
const getTableData = async ({ serverUrl, in_table, searching = "", where = [], limit = 10, offset = 0, }) => {
|
|
4209
4531
|
if (serverUrl === undefined || serverUrl.length == 0) {
|
|
4210
4532
|
throw new Error("The serverUrl is missing");
|
|
@@ -4236,24 +4558,38 @@ const getTableData = async ({ serverUrl, in_table, searching = "", where = [], l
|
|
|
4236
4558
|
const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
4237
4559
|
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
4238
4560
|
const { serverUrl, idMap, setIdMap, translate, schema: parentSchema, } = useSchemaContext();
|
|
4239
|
-
const { required, gridColumn, gridRow, renderDisplay, foreign_key } = schema;
|
|
4561
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", renderDisplay, foreign_key, } = schema;
|
|
4240
4562
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4241
|
-
const { table, column: column_ref, display_column, } = foreign_key;
|
|
4242
|
-
const [searchText, setSearchText] = React.useState();
|
|
4563
|
+
const { table, column: column_ref, display_column, customQueryFn, } = foreign_key;
|
|
4564
|
+
const [searchText, setSearchText] = React.useState("");
|
|
4243
4565
|
const [limit, setLimit] = React.useState(10);
|
|
4244
4566
|
const [openSearchResult, setOpenSearchResult] = React.useState();
|
|
4245
4567
|
const [page, setPage] = React.useState(0);
|
|
4246
4568
|
const ref = React.useRef(null);
|
|
4247
4569
|
const colLabel = `${prefix}${column}`;
|
|
4570
|
+
const watchId = watch(colLabel);
|
|
4571
|
+
const watchIds = isMultiple ? (watch(colLabel) ?? []) : [];
|
|
4572
|
+
// Query for search results
|
|
4248
4573
|
const query = reactQuery.useQuery({
|
|
4249
4574
|
queryKey: [`idpicker`, { column, searchText, limit, page }],
|
|
4250
4575
|
queryFn: async () => {
|
|
4576
|
+
if (customQueryFn) {
|
|
4577
|
+
const { data, idMap } = await customQueryFn({
|
|
4578
|
+
searching: searchText ?? "",
|
|
4579
|
+
limit: limit,
|
|
4580
|
+
offset: page * limit,
|
|
4581
|
+
});
|
|
4582
|
+
setIdMap((state) => {
|
|
4583
|
+
return { ...state, ...idMap };
|
|
4584
|
+
});
|
|
4585
|
+
return data;
|
|
4586
|
+
}
|
|
4251
4587
|
const data = await getTableData({
|
|
4252
4588
|
serverUrl,
|
|
4253
4589
|
searching: searchText ?? "",
|
|
4254
4590
|
in_table: table,
|
|
4255
4591
|
limit: limit,
|
|
4256
|
-
offset: page *
|
|
4592
|
+
offset: page * limit,
|
|
4257
4593
|
});
|
|
4258
4594
|
const newMap = Object.fromEntries((data ?? { data: [] }).data.map((item) => {
|
|
4259
4595
|
return [
|
|
@@ -4268,27 +4604,38 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4268
4604
|
});
|
|
4269
4605
|
return data;
|
|
4270
4606
|
},
|
|
4271
|
-
enabled:
|
|
4607
|
+
enabled: openSearchResult === true,
|
|
4272
4608
|
staleTime: 300000,
|
|
4273
4609
|
});
|
|
4274
|
-
|
|
4275
|
-
const
|
|
4276
|
-
const count = data?.count ?? 0;
|
|
4277
|
-
const isDirty = (searchText?.length ?? 0) > 0;
|
|
4278
|
-
const watchId = watch(colLabel);
|
|
4279
|
-
const watchIds = (watch(colLabel) ?? []);
|
|
4280
|
-
reactQuery.useQuery({
|
|
4610
|
+
// Query for currently selected items (to display them properly)
|
|
4611
|
+
const queryDefault = reactQuery.useQuery({
|
|
4281
4612
|
queryKey: [
|
|
4282
|
-
`idpicker`,
|
|
4283
|
-
{ form: parentSchema.title, column,
|
|
4613
|
+
`idpicker-default`,
|
|
4614
|
+
{ form: parentSchema.title, column, id: isMultiple ? watchIds : watchId },
|
|
4284
4615
|
],
|
|
4285
4616
|
queryFn: async () => {
|
|
4617
|
+
if (customQueryFn) {
|
|
4618
|
+
const { data, idMap } = await customQueryFn({
|
|
4619
|
+
searching: watchIds.join(","),
|
|
4620
|
+
limit: isMultiple ? watchIds.length : 1,
|
|
4621
|
+
offset: 0,
|
|
4622
|
+
});
|
|
4623
|
+
setIdMap((state) => {
|
|
4624
|
+
return { ...state, ...idMap };
|
|
4625
|
+
});
|
|
4626
|
+
return data;
|
|
4627
|
+
}
|
|
4628
|
+
if (!watchId && (!watchIds || watchIds.length === 0)) {
|
|
4629
|
+
return { data: [] };
|
|
4630
|
+
}
|
|
4631
|
+
const searchValue = isMultiple ? watchIds.join(",") : watchId;
|
|
4286
4632
|
const data = await getTableData({
|
|
4287
4633
|
serverUrl,
|
|
4288
|
-
searching:
|
|
4634
|
+
searching: searchValue,
|
|
4289
4635
|
in_table: table,
|
|
4290
|
-
|
|
4291
|
-
|
|
4636
|
+
where: [{ id: column_ref, value: isMultiple ? watchIds : watchId }],
|
|
4637
|
+
limit: isMultiple ? watchIds.length : 1,
|
|
4638
|
+
offset: 0,
|
|
4292
4639
|
});
|
|
4293
4640
|
const newMap = Object.fromEntries((data ?? { data: [] }).data.map((item) => {
|
|
4294
4641
|
return [
|
|
@@ -4303,12 +4650,45 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4303
4650
|
});
|
|
4304
4651
|
return data;
|
|
4305
4652
|
},
|
|
4653
|
+
enabled: isMultiple
|
|
4654
|
+
? Array.isArray(watchIds) && watchIds.length > 0
|
|
4655
|
+
: !!watchId,
|
|
4306
4656
|
});
|
|
4657
|
+
// Effect to load selected values when component mounts
|
|
4658
|
+
React.useEffect(() => {
|
|
4659
|
+
if (isMultiple ? watchIds.length > 0 : !!watchId) {
|
|
4660
|
+
queryDefault.refetch();
|
|
4661
|
+
}
|
|
4662
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4663
|
+
}, []);
|
|
4664
|
+
// Effect to trigger initial data fetch when popover opens
|
|
4665
|
+
React.useEffect(() => {
|
|
4666
|
+
if (openSearchResult) {
|
|
4667
|
+
// Reset search text when opening the popover
|
|
4668
|
+
setSearchText("");
|
|
4669
|
+
// Reset page to first page
|
|
4670
|
+
setPage(0);
|
|
4671
|
+
// Fetch initial data
|
|
4672
|
+
query.refetch();
|
|
4673
|
+
}
|
|
4674
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4675
|
+
}, [openSearchResult]);
|
|
4307
4676
|
const onSearchChange = async (event) => {
|
|
4308
4677
|
setSearchText(event.target.value);
|
|
4309
4678
|
setPage(0);
|
|
4310
|
-
|
|
4679
|
+
query.refetch();
|
|
4311
4680
|
};
|
|
4681
|
+
const handleLimitChange = (event) => {
|
|
4682
|
+
const newLimit = Number(event.target.value);
|
|
4683
|
+
setLimit(newLimit);
|
|
4684
|
+
// Reset to first page when changing limit
|
|
4685
|
+
setPage(0);
|
|
4686
|
+
// Trigger a new search with the updated limit
|
|
4687
|
+
query.refetch();
|
|
4688
|
+
};
|
|
4689
|
+
const { isLoading, isFetching, data, isPending, isError } = query;
|
|
4690
|
+
const dataList = data?.data ?? [];
|
|
4691
|
+
const count = data?.count ?? 0;
|
|
4312
4692
|
const getPickedValue = () => {
|
|
4313
4693
|
if (Object.keys(idMap).length <= 0) {
|
|
4314
4694
|
return "";
|
|
@@ -4317,52 +4697,67 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4317
4697
|
if (record === undefined) {
|
|
4318
4698
|
return "";
|
|
4319
4699
|
}
|
|
4700
|
+
if (!!renderDisplay === true) {
|
|
4701
|
+
return renderDisplay(record);
|
|
4702
|
+
}
|
|
4320
4703
|
return record[display_column];
|
|
4321
4704
|
};
|
|
4322
|
-
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(removeIndex(`${column}.
|
|
4705
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(removeIndex(`${column}.field_label`)))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
4323
4706
|
gridRow, children: [isMultiple && (jsxRuntime.jsxs(react.Flex, { flexFlow: "wrap", gap: 1, children: [watchIds.map((id) => {
|
|
4324
4707
|
const item = idMap[id];
|
|
4325
4708
|
if (item === undefined) {
|
|
4326
4709
|
return (jsxRuntime.jsx(react.Text, { children: translate.t(removeIndex(`${colLabel}.undefined`)) }, id));
|
|
4327
4710
|
}
|
|
4328
4711
|
return (jsxRuntime.jsx(Tag, { closable: true, onClick: () => {
|
|
4329
|
-
setValue(
|
|
4712
|
+
setValue(colLabel, watchIds.filter((itemId) => itemId !== item[column_ref]));
|
|
4330
4713
|
}, children: !!renderDisplay === true
|
|
4331
4714
|
? renderDisplay(item)
|
|
4332
4715
|
: item[display_column] }, id));
|
|
4333
4716
|
}), jsxRuntime.jsx(Tag, { cursor: "pointer", onClick: () => {
|
|
4334
4717
|
setOpenSearchResult(true);
|
|
4335
|
-
}, children: translate.t(removeIndex(`${colLabel}.
|
|
4718
|
+
}, children: translate.t(removeIndex(`${colLabel}.add_more`)) })] })), !isMultiple && (jsxRuntime.jsx(Button, { variant: "outline", onClick: () => {
|
|
4336
4719
|
setOpenSearchResult(true);
|
|
4337
|
-
}, children: getPickedValue() })), jsxRuntime.jsxs(PopoverRoot, { open: openSearchResult, onOpenChange: (e) => setOpenSearchResult(e.open), closeOnInteractOutside: true, initialFocusEl: () => ref.current, positioning: { placement: "bottom-start", strategy: "fixed" }, children: [jsxRuntime.jsx(PopoverTrigger, {}), jsxRuntime.jsx(PopoverContent, { children: jsxRuntime.jsxs(PopoverBody, { display: "grid", gap: 1, children: [jsxRuntime.jsx(react.Input, { placeholder: translate.t(removeIndex(`${colLabel}.
|
|
4338
|
-
|
|
4339
|
-
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
|
|
4355
|
-
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
|
|
4720
|
+
}, justifyContent: "start", children: queryDefault.isLoading ? jsxRuntime.jsx(react.Spinner, { size: "sm" }) : getPickedValue() })), jsxRuntime.jsxs(PopoverRoot, { open: openSearchResult, onOpenChange: (e) => setOpenSearchResult(e.open), closeOnInteractOutside: true, initialFocusEl: () => ref.current, positioning: { placement: "bottom-start", strategy: "fixed" }, children: [jsxRuntime.jsx(PopoverTrigger, {}), jsxRuntime.jsx(PopoverContent, { portalled: false, children: jsxRuntime.jsxs(PopoverBody, { display: "grid", gap: 1, children: [jsxRuntime.jsx(react.Input, { placeholder: translate.t(removeIndex(`${colLabel}.type_to_search`)), onChange: onSearchChange, autoComplete: "off", ref: ref, value: searchText }), jsxRuntime.jsx(PopoverTitle, {}), openSearchResult && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [(isFetching || isLoading || isPending) && jsxRuntime.jsx(react.Spinner, {}), isError && (jsxRuntime.jsx(react.Icon, { color: "red.400", children: jsxRuntime.jsx(bi.BiError, {}) })), jsxRuntime.jsxs(react.Flex, { justifyContent: "space-between", alignItems: "center", children: [jsxRuntime.jsxs(react.Flex, { alignItems: "center", gap: "2", children: [jsxRuntime.jsx(InfoTip, { children: `${translate.t(removeIndex(`${colLabel}.total`))} ${count}, ${translate.t(removeIndex(`${colLabel}.showing`))} ${limit} ${translate.t(removeIndex(`${colLabel}.per_page`), "per page")}` }), jsxRuntime.jsxs(react.Text, { fontSize: "sm", fontWeight: "bold", children: [count, jsxRuntime.jsxs(react.Text, { as: "span", fontSize: "xs", ml: "1", color: "gray.500", children: ["/", " ", count > 0
|
|
4721
|
+
? `${page * limit + 1}-${Math.min((page + 1) * limit, count)}`
|
|
4722
|
+
: "0"] })] })] }), jsxRuntime.jsx(react.Box, { children: jsxRuntime.jsxs("select", { value: limit, onChange: handleLimitChange, style: {
|
|
4723
|
+
padding: "4px 8px",
|
|
4724
|
+
borderRadius: "4px",
|
|
4725
|
+
border: "1px solid #ccc",
|
|
4726
|
+
fontSize: "14px",
|
|
4727
|
+
}, children: [jsxRuntime.jsx("option", { value: "5", children: "5" }), jsxRuntime.jsx("option", { value: "10", children: "10" }), jsxRuntime.jsx("option", { value: "20", children: "20" }), jsxRuntime.jsx("option", { value: "30", children: "30" })] }) })] }), jsxRuntime.jsx(react.Grid, { overflowY: "auto", children: dataList.length > 0 ? (jsxRuntime.jsx(react.Flex, { flexFlow: "column wrap", gap: 1, children: dataList.map((item) => {
|
|
4728
|
+
const selected = isMultiple
|
|
4729
|
+
? watchIds.some((id) => item[column_ref] === id)
|
|
4730
|
+
: watchId === item[column_ref];
|
|
4731
|
+
return (jsxRuntime.jsx(react.Box, { cursor: "pointer", onClick: () => {
|
|
4732
|
+
if (!isMultiple) {
|
|
4733
|
+
setOpenSearchResult(false);
|
|
4734
|
+
setValue(colLabel, item[column_ref]);
|
|
4735
|
+
return;
|
|
4736
|
+
}
|
|
4737
|
+
// For multiple selection, don't add if already selected
|
|
4738
|
+
if (selected)
|
|
4739
|
+
return;
|
|
4740
|
+
const newSet = new Set([
|
|
4741
|
+
...(watchIds ?? []),
|
|
4742
|
+
item[column_ref],
|
|
4743
|
+
]);
|
|
4744
|
+
setValue(colLabel, [...newSet]);
|
|
4745
|
+
}, opacity: 0.7, _hover: { opacity: 1 }, ...(selected
|
|
4746
|
+
? {
|
|
4747
|
+
color: "colorPalette.400/50",
|
|
4748
|
+
fontWeight: "bold",
|
|
4749
|
+
}
|
|
4750
|
+
: {}), children: !!renderDisplay === true
|
|
4751
|
+
? renderDisplay(item)
|
|
4752
|
+
: item[display_column] }, item[column_ref]));
|
|
4753
|
+
}) })) : (jsxRuntime.jsx(react.Text, { children: searchText
|
|
4754
|
+
? translate.t(removeIndex(`${colLabel}.empty_search_result`))
|
|
4755
|
+
: translate.t(removeIndex(`${colLabel}.initial_results`)) })) }), jsxRuntime.jsx(PaginationRoot, { justifySelf: "center", count: count, pageSize: limit, defaultPage: 1, page: page + 1, onPageChange: (e) => setPage(e.page - 1), children: jsxRuntime.jsxs(react.HStack, { gap: "4", children: [jsxRuntime.jsx(PaginationPrevTrigger, {}), count > 0 && jsxRuntime.jsx(PaginationPageText, {}), jsxRuntime.jsx(PaginationNextTrigger, {})] }) })] }))] }) })] }), errors[`${colLabel}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4361
4756
|
};
|
|
4362
4757
|
|
|
4363
4758
|
const NumberInputRoot = React__namespace.forwardRef(function NumberInput(props, ref) {
|
|
4364
4759
|
const { children, ...rest } = props;
|
|
4365
|
-
return (jsxRuntime.
|
|
4760
|
+
return (jsxRuntime.jsx(react.NumberInput.Root, { ref: ref, variant: "outline", ...rest, children: children }));
|
|
4366
4761
|
});
|
|
4367
4762
|
const NumberInputField$1 = react.NumberInput.Input;
|
|
4368
4763
|
react.NumberInput.Scrubber;
|
|
@@ -4371,17 +4766,17 @@ react.NumberInput.Label;
|
|
|
4371
4766
|
const NumberInputField = ({ schema, column, prefix, }) => {
|
|
4372
4767
|
const { setValue, formState: { errors }, watch, } = reactHookForm.useFormContext();
|
|
4373
4768
|
const { translate } = useSchemaContext();
|
|
4374
|
-
const { required, gridColumn, gridRow } = schema;
|
|
4769
|
+
const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
|
|
4375
4770
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4376
4771
|
const colLabel = `${prefix}${column}`;
|
|
4377
4772
|
const value = watch(`${colLabel}`);
|
|
4378
|
-
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.
|
|
4773
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn, gridRow, children: [jsxRuntime.jsx(NumberInputRoot, { children: jsxRuntime.jsx(NumberInputField$1, { required: isRequired, value: value, onChange: (event) => {
|
|
4379
4774
|
setValue(`${colLabel}`, Number(event.target.value));
|
|
4380
|
-
} }) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.
|
|
4775
|
+
} }) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4381
4776
|
};
|
|
4382
4777
|
|
|
4383
4778
|
const ObjectInput = ({ schema, column, prefix }) => {
|
|
4384
|
-
const { properties,
|
|
4779
|
+
const { properties, gridColumn = "span 12", gridRow = "span 1", required, showLabel = true, } = schema;
|
|
4385
4780
|
const { translate } = useSchemaContext();
|
|
4386
4781
|
const colLabel = `${prefix}${column}`;
|
|
4387
4782
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
@@ -4389,25 +4784,28 @@ const ObjectInput = ({ schema, column, prefix }) => {
|
|
|
4389
4784
|
if (properties === undefined) {
|
|
4390
4785
|
throw new Error(`properties is undefined when using ObjectInput`);
|
|
4391
4786
|
}
|
|
4392
|
-
return (jsxRuntime.jsxs(react.Box, { gridRow, gridColumn, children: [jsxRuntime.jsxs(react.Box, { as: "label",
|
|
4787
|
+
return (jsxRuntime.jsxs(react.Box, { gridRow, gridColumn, children: [showLabel && (jsxRuntime.jsxs(react.Box, { as: "label", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsxRuntime.jsx("span", { children: "*" })] })), jsxRuntime.jsx(react.Grid, { bgColor: { base: "colorPalette.100", _dark: "colorPalette.900" }, p: 2, borderRadius: 4, borderWidth: 1, borderColor: {
|
|
4788
|
+
base: "colorPalette.200",
|
|
4789
|
+
_dark: "colorPalette.800",
|
|
4790
|
+
}, gap: "4", padding: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: Object.keys(properties ?? {}).map((key) => {
|
|
4393
4791
|
return (
|
|
4394
4792
|
// @ts-expect-error find suitable types
|
|
4395
4793
|
jsxRuntime.jsx(ColumnRenderer, { column: `${key}`,
|
|
4396
4794
|
prefix: `${prefix}${column}.`,
|
|
4397
4795
|
properties }, `form-${colLabel}-${key}`));
|
|
4398
|
-
}) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.
|
|
4796
|
+
}) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4399
4797
|
};
|
|
4400
4798
|
|
|
4401
4799
|
const RecordInput$1 = ({ column, schema, prefix }) => {
|
|
4402
4800
|
const { formState: { errors }, setValue, getValues, } = reactHookForm.useFormContext();
|
|
4403
4801
|
const { translate } = useSchemaContext();
|
|
4404
|
-
const { required, gridColumn, gridRow } = schema;
|
|
4802
|
+
const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
|
|
4405
4803
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4406
4804
|
const entries = Object.entries(getValues(column) ?? {});
|
|
4407
4805
|
const [showNewEntries, setShowNewEntries] = React.useState(false);
|
|
4408
4806
|
const [newKey, setNewKey] = React.useState();
|
|
4409
4807
|
const [newValue, setNewValue] = React.useState();
|
|
4410
|
-
return (jsxRuntime.jsxs(Field, { label: `${translate.t(`${column}.
|
|
4808
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(`${column}.field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn, gridRow, children: [entries.map(([key, value]) => {
|
|
4411
4809
|
return (jsxRuntime.jsxs(react.Grid, { templateColumns: "1fr 1fr auto", gap: 1, children: [jsxRuntime.jsx(react.Input, { value: key, onChange: (e) => {
|
|
4412
4810
|
const filtered = entries.filter(([target]) => {
|
|
4413
4811
|
return target !== key;
|
|
@@ -4447,16 +4845,16 @@ const RecordInput$1 = ({ column, schema, prefix }) => {
|
|
|
4447
4845
|
setShowNewEntries(true);
|
|
4448
4846
|
setNewKey(undefined);
|
|
4449
4847
|
setNewValue(undefined);
|
|
4450
|
-
}, children: translate.t(`${column}.addNew`) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(`${column}.
|
|
4848
|
+
}, children: translate.t(`${column}.addNew`) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
|
|
4451
4849
|
};
|
|
4452
4850
|
|
|
4453
4851
|
const StringInputField = ({ column, schema, prefix, }) => {
|
|
4454
4852
|
const { register, formState: { errors }, } = reactHookForm.useFormContext();
|
|
4455
4853
|
const { translate } = useSchemaContext();
|
|
4456
|
-
const { required, gridColumn, gridRow } = schema;
|
|
4854
|
+
const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
|
|
4457
4855
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4458
4856
|
const colLabel = `${prefix}${column}`;
|
|
4459
|
-
return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.
|
|
4857
|
+
return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn: gridColumn, gridRow: gridRow, children: [jsxRuntime.jsx(react.Input, { ...register(`${colLabel}`, { required: isRequired }), autoComplete: "off" }), errors[colLabel] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }) }));
|
|
4460
4858
|
};
|
|
4461
4859
|
|
|
4462
4860
|
const RadioCardItem = React__namespace.forwardRef(function RadioCardItem(props, ref) {
|
|
@@ -4554,9 +4952,576 @@ const TagPicker = ({ column, schema, prefix }) => {
|
|
|
4554
4952
|
}), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: (errors[`${column}`]?.message ?? "No error message") }))] }));
|
|
4555
4953
|
};
|
|
4556
4954
|
|
|
4955
|
+
const Textarea = React.forwardRef(({ value, defaultValue, placeholder, onChange, onFocus, onBlur, disabled = false, readOnly = false, className, rows = 4, maxLength, autoFocus = false, invalid = false, required = false, label, helperText, errorText, ...props }, ref) => {
|
|
4956
|
+
const contentEditableRef = React.useRef(null);
|
|
4957
|
+
const isControlled = value !== undefined;
|
|
4958
|
+
// Handle input changes
|
|
4959
|
+
const handleInput = (e) => {
|
|
4960
|
+
const text = e.currentTarget.textContent || "";
|
|
4961
|
+
// Check maxLength if specified
|
|
4962
|
+
if (maxLength && text.length > maxLength) {
|
|
4963
|
+
e.currentTarget.textContent = text.slice(0, maxLength);
|
|
4964
|
+
// Move cursor to end
|
|
4965
|
+
const selection = window.getSelection();
|
|
4966
|
+
if (selection) {
|
|
4967
|
+
selection.selectAllChildren(e.currentTarget);
|
|
4968
|
+
selection.collapseToEnd();
|
|
4969
|
+
}
|
|
4970
|
+
return;
|
|
4971
|
+
}
|
|
4972
|
+
onChange?.(text);
|
|
4973
|
+
};
|
|
4974
|
+
// Handle paste events to strip formatting and respect maxLength
|
|
4975
|
+
const handlePaste = (e) => {
|
|
4976
|
+
e.preventDefault();
|
|
4977
|
+
const text = e.clipboardData.getData('text/plain');
|
|
4978
|
+
const currentText = e.currentTarget.textContent || "";
|
|
4979
|
+
let pasteText = text;
|
|
4980
|
+
if (maxLength) {
|
|
4981
|
+
const remainingLength = maxLength - currentText.length;
|
|
4982
|
+
pasteText = text.slice(0, remainingLength);
|
|
4983
|
+
}
|
|
4984
|
+
document.execCommand('insertText', false, pasteText);
|
|
4985
|
+
};
|
|
4986
|
+
// Set initial content
|
|
4987
|
+
React.useEffect(() => {
|
|
4988
|
+
if (contentEditableRef.current && !isControlled) {
|
|
4989
|
+
const initialValue = defaultValue || "";
|
|
4990
|
+
if (contentEditableRef.current.textContent !== initialValue) {
|
|
4991
|
+
contentEditableRef.current.textContent = initialValue;
|
|
4992
|
+
}
|
|
4993
|
+
}
|
|
4994
|
+
}, [defaultValue, isControlled]);
|
|
4995
|
+
// Update content when value changes (controlled mode)
|
|
4996
|
+
React.useEffect(() => {
|
|
4997
|
+
if (contentEditableRef.current && isControlled && value !== undefined) {
|
|
4998
|
+
if (contentEditableRef.current.textContent !== value) {
|
|
4999
|
+
contentEditableRef.current.textContent = value;
|
|
5000
|
+
}
|
|
5001
|
+
}
|
|
5002
|
+
}, [value, isControlled]);
|
|
5003
|
+
// Auto focus
|
|
5004
|
+
React.useEffect(() => {
|
|
5005
|
+
if (autoFocus && contentEditableRef.current) {
|
|
5006
|
+
contentEditableRef.current.focus();
|
|
5007
|
+
}
|
|
5008
|
+
}, [autoFocus]);
|
|
5009
|
+
// Forward ref
|
|
5010
|
+
React.useEffect(() => {
|
|
5011
|
+
if (typeof ref === 'function') {
|
|
5012
|
+
ref(contentEditableRef.current);
|
|
5013
|
+
}
|
|
5014
|
+
else if (ref) {
|
|
5015
|
+
ref.current = contentEditableRef.current;
|
|
5016
|
+
}
|
|
5017
|
+
}, [ref]);
|
|
5018
|
+
const textareaElement = (jsxRuntime.jsx(react.Box, { ref: contentEditableRef, contentEditable: !disabled && !readOnly, onInput: handleInput, onPaste: handlePaste, onFocus: onFocus, onBlur: onBlur, className: className, minHeight: `${rows * 1.5}em`, padding: "2", border: "1px solid", borderColor: invalid ? "red.500" : "gray.200", borderRadius: "md", outline: "none", _focus: {
|
|
5019
|
+
borderColor: invalid ? "red.500" : "blue.500",
|
|
5020
|
+
boxShadow: `0 0 0 1px ${invalid ? "red.500" : "blue.500"}`,
|
|
5021
|
+
}, _disabled: {
|
|
5022
|
+
opacity: 0.6,
|
|
5023
|
+
cursor: "not-allowed",
|
|
5024
|
+
bg: "gray.50",
|
|
5025
|
+
}, _empty: {
|
|
5026
|
+
_before: {
|
|
5027
|
+
content: placeholder ? `"${placeholder}"` : undefined,
|
|
5028
|
+
color: "gray.400",
|
|
5029
|
+
pointerEvents: "none",
|
|
5030
|
+
}
|
|
5031
|
+
}, whiteSpace: "pre-wrap", overflowWrap: "break-word", overflow: "auto", maxHeight: `${rows * 4}em`, suppressContentEditableWarning: true, ...props }));
|
|
5032
|
+
// If we have additional field props, wrap in Field component
|
|
5033
|
+
if (label || helperText || errorText || required) {
|
|
5034
|
+
return (jsxRuntime.jsxs(react.Field.Root, { invalid: invalid, required: required, children: [label && (jsxRuntime.jsxs(react.Field.Label, { children: [label, required && jsxRuntime.jsx(react.Field.RequiredIndicator, {})] })), textareaElement, helperText && jsxRuntime.jsx(react.Field.HelperText, { children: helperText }), errorText && jsxRuntime.jsx(react.Field.ErrorText, { children: errorText })] }));
|
|
5035
|
+
}
|
|
5036
|
+
return textareaElement;
|
|
5037
|
+
});
|
|
5038
|
+
Textarea.displayName = "Textarea";
|
|
5039
|
+
|
|
5040
|
+
const TextAreaInput = ({ column, schema, prefix, }) => {
|
|
5041
|
+
const { register, formState: { errors }, } = reactHookForm.useFormContext();
|
|
5042
|
+
const { translate } = useSchemaContext();
|
|
5043
|
+
const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
|
|
5044
|
+
const isRequired = required?.some((columnId) => columnId === column);
|
|
5045
|
+
const colLabel = `${prefix}${column}`;
|
|
5046
|
+
const form = reactHookForm.useFormContext();
|
|
5047
|
+
const { setValue, watch } = form;
|
|
5048
|
+
const watchValue = watch(colLabel);
|
|
5049
|
+
return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn: gridColumn ?? "span 4", gridRow: gridRow ?? "span 1", display: "grid", children: [jsxRuntime.jsx(Textarea, { value: watchValue, onChange: (value) => setValue(colLabel, value) }), errors[colLabel] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }) }));
|
|
5050
|
+
};
|
|
5051
|
+
|
|
5052
|
+
function TimePicker$1({ hour, setHour, minute, setMinute, meridiem, setMeridiem, meridiemLabel = {
|
|
5053
|
+
am: "am",
|
|
5054
|
+
pm: "pm",
|
|
5055
|
+
}, onChange = (_newValue) => { }, timezone = "Asia/Hong_Kong", }) {
|
|
5056
|
+
const handleClear = () => {
|
|
5057
|
+
setHour(null);
|
|
5058
|
+
setMinute(null);
|
|
5059
|
+
setMeridiem(null);
|
|
5060
|
+
setInputValue("");
|
|
5061
|
+
setShowInput(false);
|
|
5062
|
+
onChange({ hour: null, minute: null, meridiem: null });
|
|
5063
|
+
};
|
|
5064
|
+
const getTimeString = (hour, minute, meridiem) => {
|
|
5065
|
+
if (hour === null || minute === null || meridiem === null) {
|
|
5066
|
+
return "";
|
|
5067
|
+
}
|
|
5068
|
+
// if the hour is 24, set the hour to 0
|
|
5069
|
+
if (hour === 24) {
|
|
5070
|
+
return dayjs().tz(timezone).hour(0).minute(minute).format("HH:mmZ");
|
|
5071
|
+
}
|
|
5072
|
+
// use dayjs to format the time at current timezone
|
|
5073
|
+
// if meridiem is pm, add 12 hours
|
|
5074
|
+
let newHour = hour;
|
|
5075
|
+
if (meridiem === "pm" && hour !== 12) {
|
|
5076
|
+
newHour = hour + 12;
|
|
5077
|
+
}
|
|
5078
|
+
// if the hour is 12, set the meridiem to am, and set the hour to 0
|
|
5079
|
+
else if (meridiem === "am" && hour === 12) {
|
|
5080
|
+
newHour = 0;
|
|
5081
|
+
}
|
|
5082
|
+
return dayjs().tz(timezone).hour(newHour).minute(minute).format("HH:mmZ");
|
|
5083
|
+
};
|
|
5084
|
+
const stringTime = getTimeString(hour, minute, meridiem);
|
|
5085
|
+
const [inputValue, setInputValue] = React.useState("");
|
|
5086
|
+
const [showInput, setShowInput] = React.useState(false);
|
|
5087
|
+
const handleBlur = (text) => {
|
|
5088
|
+
// ignore all non-numeric characters
|
|
5089
|
+
if (!text) {
|
|
5090
|
+
return;
|
|
5091
|
+
}
|
|
5092
|
+
const value = text.replace(/[^0-9apm]/g, "");
|
|
5093
|
+
if (value === "") {
|
|
5094
|
+
handleClear();
|
|
5095
|
+
return;
|
|
5096
|
+
}
|
|
5097
|
+
// if the value is a valid time, parse it and set the hour, minute, and meridiem
|
|
5098
|
+
// if the value is not a valid time, set the stringTime to the value
|
|
5099
|
+
// first two characters are the hour
|
|
5100
|
+
// next two characters are the minute
|
|
5101
|
+
// final two characters are the meridiem
|
|
5102
|
+
const hour = parseInt(value.slice(0, 2));
|
|
5103
|
+
const minute = parseInt(value.slice(2, 4));
|
|
5104
|
+
const meridiem = value.slice(4, 6);
|
|
5105
|
+
// validate the hour and minute
|
|
5106
|
+
if (isNaN(hour) || isNaN(minute)) {
|
|
5107
|
+
setInputValue("");
|
|
5108
|
+
return;
|
|
5109
|
+
}
|
|
5110
|
+
// if the hour is larger than 24, set the hour to 24
|
|
5111
|
+
if (hour > 24) {
|
|
5112
|
+
setInputValue("");
|
|
5113
|
+
return;
|
|
5114
|
+
}
|
|
5115
|
+
let newHour = hour;
|
|
5116
|
+
let newMinute = minute;
|
|
5117
|
+
let newMeridiem = meridiem;
|
|
5118
|
+
// if the hour is 24, set the meridiem to am, and set the hour to 0
|
|
5119
|
+
if (hour === 24) {
|
|
5120
|
+
newMeridiem = "am";
|
|
5121
|
+
newHour = 0;
|
|
5122
|
+
}
|
|
5123
|
+
// if the hour is greater than 12, set the meridiem to pm, and subtract 12 from the hour
|
|
5124
|
+
else if (hour > 12) {
|
|
5125
|
+
newMeridiem = "pm";
|
|
5126
|
+
newHour = hour - 12;
|
|
5127
|
+
}
|
|
5128
|
+
// if the hour is 12, set the meridiem to pm, and set the hour to 12
|
|
5129
|
+
else if (hour === 12) {
|
|
5130
|
+
newMeridiem = "pm";
|
|
5131
|
+
newHour = 12;
|
|
5132
|
+
}
|
|
5133
|
+
// if the hour is 0, set the meridiem to am, and set the hour to 12
|
|
5134
|
+
else if (hour === 0) {
|
|
5135
|
+
newMeridiem = "am";
|
|
5136
|
+
newHour = 12;
|
|
5137
|
+
}
|
|
5138
|
+
else {
|
|
5139
|
+
newMeridiem = meridiem ?? "am";
|
|
5140
|
+
newHour = hour;
|
|
5141
|
+
}
|
|
5142
|
+
if (minute > 59) {
|
|
5143
|
+
newMinute = 0;
|
|
5144
|
+
}
|
|
5145
|
+
else {
|
|
5146
|
+
newMinute = minute;
|
|
5147
|
+
}
|
|
5148
|
+
onChange({
|
|
5149
|
+
hour: newHour,
|
|
5150
|
+
minute: newMinute,
|
|
5151
|
+
meridiem: newMeridiem,
|
|
5152
|
+
});
|
|
5153
|
+
setShowInput(false);
|
|
5154
|
+
};
|
|
5155
|
+
const handleKeyDown = (e) => {
|
|
5156
|
+
if (e.key === "Enter") {
|
|
5157
|
+
handleBlur(e.currentTarget.value);
|
|
5158
|
+
}
|
|
5159
|
+
};
|
|
5160
|
+
const inputRef = React.useRef(null);
|
|
5161
|
+
return (jsxRuntime.jsxs(react.Grid, { justifyContent: "center", alignItems: "center", templateColumns: "200px auto", gap: "2", width: "auto", minWidth: "250px", children: [jsxRuntime.jsx(react.Input, { onKeyDown: handleKeyDown, onChange: (e) => {
|
|
5162
|
+
setInputValue(e.currentTarget.value);
|
|
5163
|
+
}, onBlur: (e) => {
|
|
5164
|
+
handleBlur(e.currentTarget.value);
|
|
5165
|
+
}, onFocus: (e) => {
|
|
5166
|
+
e.currentTarget.select();
|
|
5167
|
+
}, value: inputValue, display: showInput ? undefined : "none", ref: inputRef }), jsxRuntime.jsxs(react.Button, { onClick: () => {
|
|
5168
|
+
setShowInput(true);
|
|
5169
|
+
setInputValue(dayjs(`1970-01-01T${getTimeString(hour, minute, meridiem)}`, "hh:mmZ").format("HH:mm"));
|
|
5170
|
+
inputRef.current?.focus();
|
|
5171
|
+
}, display: showInput ? "none" : "flex", alignItems: "center", justifyContent: "start", variant: "outline", gap: 2, children: [jsxRuntime.jsx(react.Icon, { size: "sm", children: jsxRuntime.jsx(bs.BsClock, {}) }), jsxRuntime.jsx(react.Text, { fontSize: "sm", children: stringTime
|
|
5172
|
+
? dayjs(`1970-01-01T${stringTime}`, "hh:mmZ").format("hh:mm a")
|
|
5173
|
+
: "" })] }), jsxRuntime.jsx(react.Button, { onClick: handleClear, size: "sm", variant: "ghost", children: jsxRuntime.jsx(md.MdCancel, {}) })] }));
|
|
5174
|
+
}
|
|
5175
|
+
|
|
5176
|
+
dayjs.extend(timezone);
|
|
5177
|
+
const TimePicker = ({ column, schema, prefix }) => {
|
|
5178
|
+
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
5179
|
+
const { translate, timezone } = useSchemaContext();
|
|
5180
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", timeFormat = "HH:mm:ssZ", displayTimeFormat = "hh:mm A", } = schema;
|
|
5181
|
+
const isRequired = required?.some((columnId) => columnId === column);
|
|
5182
|
+
const colLabel = `${prefix}${column}`;
|
|
5183
|
+
const [open, setOpen] = React.useState(false);
|
|
5184
|
+
const value = watch(colLabel);
|
|
5185
|
+
const displayedTime = dayjs(`1970-01-01T${value}`).tz(timezone).isValid()
|
|
5186
|
+
? dayjs(`1970-01-01T${value}`).tz(timezone).format(displayTimeFormat)
|
|
5187
|
+
: "";
|
|
5188
|
+
// Parse the initial time parts from the time string (HH:mm:ssZ)
|
|
5189
|
+
const parseTime = (time) => {
|
|
5190
|
+
if (!time)
|
|
5191
|
+
return { hour: 12, minute: 0, meridiem: "am" };
|
|
5192
|
+
const parsed = dayjs(`1970-01-01T${time}`).tz(timezone);
|
|
5193
|
+
if (!parsed.isValid()) {
|
|
5194
|
+
return { hour: 12, minute: 0, meridiem: "am" };
|
|
5195
|
+
}
|
|
5196
|
+
let hour = parsed.hour();
|
|
5197
|
+
const minute = parsed.minute();
|
|
5198
|
+
const meridiem = hour >= 12 ? "pm" : "am";
|
|
5199
|
+
if (hour === 0)
|
|
5200
|
+
hour = 12;
|
|
5201
|
+
else if (hour > 12)
|
|
5202
|
+
hour -= 12;
|
|
5203
|
+
return { hour, minute, meridiem };
|
|
5204
|
+
};
|
|
5205
|
+
const initialTime = parseTime(value);
|
|
5206
|
+
const [hour, setHour] = React.useState(initialTime.hour);
|
|
5207
|
+
const [minute, setMinute] = React.useState(initialTime.minute);
|
|
5208
|
+
const [meridiem, setMeridiem] = React.useState(initialTime.meridiem);
|
|
5209
|
+
React.useEffect(() => {
|
|
5210
|
+
const { hour, minute, meridiem } = parseTime(value);
|
|
5211
|
+
setHour(hour);
|
|
5212
|
+
setMinute(minute);
|
|
5213
|
+
setMeridiem(meridiem);
|
|
5214
|
+
}, [value]);
|
|
5215
|
+
const getTimeString = (hour, minute, meridiem) => {
|
|
5216
|
+
if (hour === null || minute === null || meridiem === null)
|
|
5217
|
+
return null;
|
|
5218
|
+
let newHour = hour;
|
|
5219
|
+
if (meridiem === "pm" && hour !== 12) {
|
|
5220
|
+
newHour = hour + 12;
|
|
5221
|
+
}
|
|
5222
|
+
return dayjs().tz(timezone).hour(newHour).minute(minute).second(0).format(timeFormat);
|
|
5223
|
+
};
|
|
5224
|
+
// Handle changes to time parts
|
|
5225
|
+
const handleTimeChange = ({ hour: newHour, minute: newMinute, meridiem: newMeridiem, }) => {
|
|
5226
|
+
setHour(newHour);
|
|
5227
|
+
setMinute(newMinute);
|
|
5228
|
+
setMeridiem(newMeridiem);
|
|
5229
|
+
const timeString = getTimeString(newHour, newMinute, newMeridiem);
|
|
5230
|
+
setValue(colLabel, timeString, { shouldValidate: true, shouldDirty: true });
|
|
5231
|
+
};
|
|
5232
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
5233
|
+
gridRow, children: [jsxRuntime.jsxs(react.Popover.Root, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsxRuntime.jsx(react.Popover.Trigger, { asChild: true, children: jsxRuntime.jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
|
|
5234
|
+
setOpen(true);
|
|
5235
|
+
}, justifyContent: "start", children: [jsxRuntime.jsx(io.IoMdClock, {}), !!value ? `${displayedTime}` : ""] }) }), jsxRuntime.jsx(react.Popover.Positioner, { children: jsxRuntime.jsx(react.Popover.Content, { children: jsxRuntime.jsx(react.Popover.Body, { children: jsxRuntime.jsx(TimePicker$1, { hour: hour, setHour: setHour, minute: minute, setMinute: setMinute, meridiem: meridiem, setMeridiem: setMeridiem, onChange: handleTimeChange, meridiemLabel: {
|
|
5236
|
+
am: translate.t(`common.am`, { defaultValue: "AM" }),
|
|
5237
|
+
pm: translate.t(`common.pm`, { defaultValue: "PM" }),
|
|
5238
|
+
} }) }) }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
5239
|
+
};
|
|
5240
|
+
|
|
5241
|
+
function IsoTimePicker({ hour, setHour, minute, setMinute, second, setSecond, onChange = (_newValue) => { }, }) {
|
|
5242
|
+
// Refs for focus management
|
|
5243
|
+
const hourInputRef = React.useRef(null);
|
|
5244
|
+
const minuteInputRef = React.useRef(null);
|
|
5245
|
+
const secondInputRef = React.useRef(null);
|
|
5246
|
+
// Centralized handler for key events, value changes, and focus management
|
|
5247
|
+
const handleKeyDown = (e, field) => {
|
|
5248
|
+
const input = e.target;
|
|
5249
|
+
const value = input.value;
|
|
5250
|
+
// Handle navigation between fields
|
|
5251
|
+
if (e.key === "Tab") {
|
|
5252
|
+
return;
|
|
5253
|
+
}
|
|
5254
|
+
if (e.key === ":" && field === "hour") {
|
|
5255
|
+
e.preventDefault();
|
|
5256
|
+
minuteInputRef.current?.focus();
|
|
5257
|
+
return;
|
|
5258
|
+
}
|
|
5259
|
+
if (e.key === ":" && field === "minute") {
|
|
5260
|
+
e.preventDefault();
|
|
5261
|
+
secondInputRef.current?.focus();
|
|
5262
|
+
return;
|
|
5263
|
+
}
|
|
5264
|
+
if (e.key === "Backspace" && value === "") {
|
|
5265
|
+
e.preventDefault();
|
|
5266
|
+
if (field === "minute") {
|
|
5267
|
+
hourInputRef.current?.focus();
|
|
5268
|
+
}
|
|
5269
|
+
else if (field === "second") {
|
|
5270
|
+
minuteInputRef.current?.focus();
|
|
5271
|
+
}
|
|
5272
|
+
return;
|
|
5273
|
+
}
|
|
5274
|
+
// Handle number inputs
|
|
5275
|
+
if (field === "hour") {
|
|
5276
|
+
if (e.key.match(/^[0-9]$/)) {
|
|
5277
|
+
const newValue = value + e.key;
|
|
5278
|
+
const numValue = parseInt(newValue, 10);
|
|
5279
|
+
if (numValue > 23) {
|
|
5280
|
+
const digitValue = parseInt(e.key, 10);
|
|
5281
|
+
setHour(digitValue);
|
|
5282
|
+
onChange({ hour: digitValue, minute, second });
|
|
5283
|
+
return;
|
|
5284
|
+
}
|
|
5285
|
+
if (numValue >= 0 && numValue <= 23) {
|
|
5286
|
+
setHour(numValue);
|
|
5287
|
+
onChange({ hour: numValue, minute, second });
|
|
5288
|
+
e.preventDefault();
|
|
5289
|
+
minuteInputRef.current?.focus();
|
|
5290
|
+
}
|
|
5291
|
+
}
|
|
5292
|
+
}
|
|
5293
|
+
else if (field === "minute") {
|
|
5294
|
+
if (e.key.match(/^[0-9]$/)) {
|
|
5295
|
+
const newValue = value + e.key;
|
|
5296
|
+
const numValue = parseInt(newValue, 10);
|
|
5297
|
+
if (numValue > 59) {
|
|
5298
|
+
const digitValue = parseInt(e.key, 10);
|
|
5299
|
+
setMinute(digitValue);
|
|
5300
|
+
onChange({ hour, minute: digitValue, second });
|
|
5301
|
+
return;
|
|
5302
|
+
}
|
|
5303
|
+
if (numValue >= 0 && numValue <= 59) {
|
|
5304
|
+
setMinute(numValue);
|
|
5305
|
+
onChange({ hour, minute: numValue, second });
|
|
5306
|
+
e.preventDefault();
|
|
5307
|
+
secondInputRef.current?.focus();
|
|
5308
|
+
}
|
|
5309
|
+
}
|
|
5310
|
+
}
|
|
5311
|
+
else if (field === "second") {
|
|
5312
|
+
if (e.key.match(/^[0-9]$/)) {
|
|
5313
|
+
const newValue = value + e.key;
|
|
5314
|
+
const numValue = parseInt(newValue, 10);
|
|
5315
|
+
if (numValue > 59) {
|
|
5316
|
+
const digitValue = parseInt(e.key, 10);
|
|
5317
|
+
setSecond(digitValue);
|
|
5318
|
+
onChange({ hour, minute, second: digitValue });
|
|
5319
|
+
return;
|
|
5320
|
+
}
|
|
5321
|
+
if (numValue >= 0 && numValue <= 59) {
|
|
5322
|
+
setSecond(numValue);
|
|
5323
|
+
onChange({ hour, minute, second: numValue });
|
|
5324
|
+
}
|
|
5325
|
+
}
|
|
5326
|
+
}
|
|
5327
|
+
};
|
|
5328
|
+
const handleClear = () => {
|
|
5329
|
+
setHour(null);
|
|
5330
|
+
setMinute(null);
|
|
5331
|
+
setSecond(null);
|
|
5332
|
+
onChange({ hour: null, minute: null, second: null });
|
|
5333
|
+
hourInputRef.current?.focus();
|
|
5334
|
+
};
|
|
5335
|
+
return (jsxRuntime.jsx(react.Flex, { direction: "column", gap: 3, children: jsxRuntime.jsxs(react.Grid, { justifyContent: "center", alignItems: "center", templateColumns: "60px 10px 60px 10px 60px auto", gap: "2", width: "auto", minWidth: "300px", children: [jsxRuntime.jsx(react.Input, { ref: hourInputRef, type: "text", value: hour === null ? "" : hour.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "hour"), placeholder: "HH", maxLength: 2, textAlign: "center" }), jsxRuntime.jsx(react.Text, { children: ":" }), jsxRuntime.jsx(react.Input, { ref: minuteInputRef, type: "text", value: minute === null ? "" : minute.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "minute"), placeholder: "MM", maxLength: 2, textAlign: "center" }), jsxRuntime.jsx(react.Text, { children: ":" }), jsxRuntime.jsx(react.Input, { ref: secondInputRef, type: "text", value: second === null ? "" : second.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "second"), placeholder: "SS", maxLength: 2, textAlign: "center" }), jsxRuntime.jsx(react.Button, { onClick: handleClear, size: "sm", variant: "ghost", children: jsxRuntime.jsx(md.MdCancel, {}) })] }) }));
|
|
5336
|
+
}
|
|
5337
|
+
|
|
5338
|
+
function DateTimePicker$1({ value, onChange, format = "date-time", showSeconds = false, labels = {
|
|
5339
|
+
monthNamesShort: [
|
|
5340
|
+
"Jan",
|
|
5341
|
+
"Feb",
|
|
5342
|
+
"Mar",
|
|
5343
|
+
"Apr",
|
|
5344
|
+
"May",
|
|
5345
|
+
"Jun",
|
|
5346
|
+
"Jul",
|
|
5347
|
+
"Aug",
|
|
5348
|
+
"Sep",
|
|
5349
|
+
"Oct",
|
|
5350
|
+
"Nov",
|
|
5351
|
+
"Dec",
|
|
5352
|
+
],
|
|
5353
|
+
weekdayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
|
|
5354
|
+
backButtonLabel: "Back",
|
|
5355
|
+
forwardButtonLabel: "Next",
|
|
5356
|
+
}, timezone = "Asia/Hong_Kong", }) {
|
|
5357
|
+
const [selectedDate, setSelectedDate] = React.useState(value || "");
|
|
5358
|
+
// Time state for 12-hour format
|
|
5359
|
+
const [hour12, setHour12] = React.useState(value ? dayjs(value).hour() % 12 || 12 : null);
|
|
5360
|
+
const [minute, setMinute] = React.useState(value ? dayjs(value).minute() : null);
|
|
5361
|
+
const [meridiem, setMeridiem] = React.useState(value ? (dayjs(value).hour() >= 12 ? "pm" : "am") : null);
|
|
5362
|
+
// Time state for 24-hour format
|
|
5363
|
+
const [hour24, setHour24] = React.useState(value ? dayjs(value).hour() : null);
|
|
5364
|
+
const [second, setSecond] = React.useState(value ? dayjs(value).second() : null);
|
|
5365
|
+
const handleDateChange = (date) => {
|
|
5366
|
+
setSelectedDate(date);
|
|
5367
|
+
updateDateTime(dayjs(date).tz(timezone).toISOString());
|
|
5368
|
+
};
|
|
5369
|
+
const handleTimeChange = (timeData) => {
|
|
5370
|
+
if (format === "iso-date-time") {
|
|
5371
|
+
setHour24(timeData.hour);
|
|
5372
|
+
setMinute(timeData.minute);
|
|
5373
|
+
if (showSeconds)
|
|
5374
|
+
setSecond(timeData.second);
|
|
5375
|
+
}
|
|
5376
|
+
else {
|
|
5377
|
+
setHour12(timeData.hour);
|
|
5378
|
+
setMinute(timeData.minute);
|
|
5379
|
+
setMeridiem(timeData.meridiem);
|
|
5380
|
+
}
|
|
5381
|
+
updateDateTime(dayjs(selectedDate).tz(timezone).toISOString(), timeData);
|
|
5382
|
+
};
|
|
5383
|
+
const updateDateTime = (date, timeData) => {
|
|
5384
|
+
if (!date) {
|
|
5385
|
+
onChange?.(undefined);
|
|
5386
|
+
return;
|
|
5387
|
+
}
|
|
5388
|
+
// use dayjs to convert the date to the timezone
|
|
5389
|
+
const newDate = dayjs(date).tz(timezone).toDate();
|
|
5390
|
+
if (format === "iso-date-time") {
|
|
5391
|
+
const h = timeData?.hour ?? hour24;
|
|
5392
|
+
const m = timeData?.minute ?? minute;
|
|
5393
|
+
const s = showSeconds ? timeData?.second ?? second : 0;
|
|
5394
|
+
if (h !== null)
|
|
5395
|
+
newDate.setHours(h);
|
|
5396
|
+
if (m !== null)
|
|
5397
|
+
newDate.setMinutes(m);
|
|
5398
|
+
if (s !== null)
|
|
5399
|
+
newDate.setSeconds(s);
|
|
5400
|
+
}
|
|
5401
|
+
else {
|
|
5402
|
+
const h = timeData?.hour ?? hour12;
|
|
5403
|
+
const m = timeData?.minute ?? minute;
|
|
5404
|
+
const mer = timeData?.meridiem ?? meridiem;
|
|
5405
|
+
if (h !== null && mer !== null) {
|
|
5406
|
+
let hour24 = h;
|
|
5407
|
+
if (mer === "am" && h === 12)
|
|
5408
|
+
hour24 = 0;
|
|
5409
|
+
else if (mer === "pm" && h < 12)
|
|
5410
|
+
hour24 = h + 12;
|
|
5411
|
+
newDate.setHours(hour24);
|
|
5412
|
+
}
|
|
5413
|
+
if (m !== null)
|
|
5414
|
+
newDate.setMinutes(m);
|
|
5415
|
+
newDate.setSeconds(0);
|
|
5416
|
+
}
|
|
5417
|
+
onChange?.(dayjs(newDate).tz(timezone).toISOString());
|
|
5418
|
+
};
|
|
5419
|
+
const handleClear = () => {
|
|
5420
|
+
setSelectedDate("");
|
|
5421
|
+
setHour12(null);
|
|
5422
|
+
setHour24(null);
|
|
5423
|
+
setMinute(null);
|
|
5424
|
+
setSecond(null);
|
|
5425
|
+
setMeridiem(null);
|
|
5426
|
+
onChange?.(undefined);
|
|
5427
|
+
};
|
|
5428
|
+
const isISO = format === "iso-date-time";
|
|
5429
|
+
return (jsxRuntime.jsxs(react.Flex, { direction: "column", gap: 4, p: 4, border: "1px solid", borderColor: "gray.200", borderRadius: "md", children: [jsxRuntime.jsx(DatePicker$1, { selected: selectedDate
|
|
5430
|
+
? dayjs(selectedDate).tz(timezone).toDate()
|
|
5431
|
+
: new Date(), onDateSelected: ({ date }) => handleDateChange(dayjs(date).tz(timezone).toISOString()), monthsToDisplay: 1, labels: labels }), jsxRuntime.jsxs(react.Grid, { templateColumns: "1fr auto", alignItems: "center", gap: 4, children: [isISO ? (jsxRuntime.jsx(IsoTimePicker, { hour: hour24, setHour: setHour24, minute: minute, setMinute: setMinute, second: second, setSecond: setSecond, onChange: handleTimeChange })) : (jsxRuntime.jsx(TimePicker$1, { hour: hour12, setHour: setHour12, minute: minute, setMinute: setMinute, meridiem: meridiem, setMeridiem: setMeridiem, onChange: handleTimeChange })), jsxRuntime.jsx(react.Button, { onClick: handleClear, size: "sm", variant: "outline", colorScheme: "red", children: jsxRuntime.jsx(react.Icon, { as: fa6.FaTrash }) })] }), selectedDate && (jsxRuntime.jsxs(react.Flex, { gap: 2, children: [jsxRuntime.jsx(react.Text, { fontSize: "sm", color: { base: "gray.600", _dark: "gray.600" }, children: dayjs(value).format(isISO
|
|
5432
|
+
? showSeconds
|
|
5433
|
+
? "YYYY-MM-DD HH:mm:ss"
|
|
5434
|
+
: "YYYY-MM-DD HH:mm"
|
|
5435
|
+
: "YYYY-MM-DD hh:mm A ") }), jsxRuntime.jsx(react.Text, { fontSize: "sm", color: { base: "gray.600", _dark: "gray.600" }, children: dayjs(value).tz(timezone).format("Z") }), jsxRuntime.jsx(react.Text, { fontSize: "sm", color: { base: "gray.600", _dark: "gray.600" }, children: timezone })] }))] }));
|
|
5436
|
+
}
|
|
5437
|
+
|
|
5438
|
+
dayjs.extend(utc);
|
|
5439
|
+
dayjs.extend(timezone);
|
|
5440
|
+
const DateTimePicker = ({ column, schema, prefix, }) => {
|
|
5441
|
+
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
5442
|
+
const { translate, timezone } = useSchemaContext();
|
|
5443
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD HH:mm:ss",
|
|
5444
|
+
// with timezone
|
|
5445
|
+
dateFormat = "YYYY-MM-DD[T]HH:mm:ssZ", } = schema;
|
|
5446
|
+
const isRequired = required?.some((columnId) => columnId === column);
|
|
5447
|
+
const colLabel = `${prefix}${column}`;
|
|
5448
|
+
const [open, setOpen] = React.useState(false);
|
|
5449
|
+
const selectedDate = watch(colLabel);
|
|
5450
|
+
const displayDate = dayjs(selectedDate)
|
|
5451
|
+
.tz(timezone)
|
|
5452
|
+
.format(displayDateFormat);
|
|
5453
|
+
React.useEffect(() => {
|
|
5454
|
+
try {
|
|
5455
|
+
if (selectedDate) {
|
|
5456
|
+
// Parse the selectedDate as UTC or in a specific timezone to avoid +8 hour shift
|
|
5457
|
+
// For example, parse as UTC:
|
|
5458
|
+
const parsedDate = dayjs(selectedDate).tz(timezone);
|
|
5459
|
+
if (!parsedDate.isValid())
|
|
5460
|
+
return;
|
|
5461
|
+
// Format according to dateFormat from schema
|
|
5462
|
+
const formatted = parsedDate.format(dateFormat);
|
|
5463
|
+
// Update the form value only if different to avoid loops
|
|
5464
|
+
if (formatted !== selectedDate) {
|
|
5465
|
+
setValue(colLabel, formatted, {
|
|
5466
|
+
shouldValidate: true,
|
|
5467
|
+
shouldDirty: true,
|
|
5468
|
+
});
|
|
5469
|
+
}
|
|
5470
|
+
}
|
|
5471
|
+
}
|
|
5472
|
+
catch (e) {
|
|
5473
|
+
console.error(e);
|
|
5474
|
+
}
|
|
5475
|
+
}, [selectedDate, dateFormat, colLabel, setValue]);
|
|
5476
|
+
const customTranslate = (label) => {
|
|
5477
|
+
return translateWrapper({ prefix, column, label, translate });
|
|
5478
|
+
};
|
|
5479
|
+
return (jsxRuntime.jsxs(Field, { label: `${customTranslate(`field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
5480
|
+
gridRow, children: [jsxRuntime.jsxs(PopoverRoot, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: jsxRuntime.jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
|
|
5481
|
+
setOpen(true);
|
|
5482
|
+
}, justifyContent: "start", children: [jsxRuntime.jsx(md.MdDateRange, {}), selectedDate !== undefined ? `${displayDate}` : ""] }) }), jsxRuntime.jsx(PopoverContent, { minW: "450px", children: jsxRuntime.jsxs(PopoverBody, { children: [jsxRuntime.jsx(PopoverTitle, {}), jsxRuntime.jsx(DateTimePicker$1, { value: selectedDate, onChange: (date) => {
|
|
5483
|
+
setValue(colLabel, dayjs(date).tz(timezone).format(dateFormat));
|
|
5484
|
+
}, timezone: timezone, labels: {
|
|
5485
|
+
monthNamesShort: [
|
|
5486
|
+
translate.t(`common.month_1`, { defaultValue: "January" }),
|
|
5487
|
+
translate.t(`common.month_2`, { defaultValue: "February" }),
|
|
5488
|
+
translate.t(`common.month_3`, { defaultValue: "March" }),
|
|
5489
|
+
translate.t(`common.month_4`, { defaultValue: "April" }),
|
|
5490
|
+
translate.t(`common.month_5`, { defaultValue: "May" }),
|
|
5491
|
+
translate.t(`common.month_6`, { defaultValue: "June" }),
|
|
5492
|
+
translate.t(`common.month_7`, { defaultValue: "July" }),
|
|
5493
|
+
translate.t(`common.month_8`, { defaultValue: "August" }),
|
|
5494
|
+
translate.t(`common.month_9`, { defaultValue: "September" }),
|
|
5495
|
+
translate.t(`common.month_10`, { defaultValue: "October" }),
|
|
5496
|
+
translate.t(`common.month_11`, { defaultValue: "November" }),
|
|
5497
|
+
translate.t(`common.month_12`, { defaultValue: "December" }),
|
|
5498
|
+
],
|
|
5499
|
+
weekdayNamesShort: [
|
|
5500
|
+
translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
|
|
5501
|
+
translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
|
|
5502
|
+
translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
|
|
5503
|
+
translate.t(`common.weekday_4`, {
|
|
5504
|
+
defaultValue: "Wed",
|
|
5505
|
+
}),
|
|
5506
|
+
translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
|
|
5507
|
+
translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
|
|
5508
|
+
translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
|
|
5509
|
+
],
|
|
5510
|
+
backButtonLabel: translate.t(`common.back_button`, {
|
|
5511
|
+
defaultValue: "Back",
|
|
5512
|
+
}),
|
|
5513
|
+
forwardButtonLabel: translate.t(`common.forward_button`, {
|
|
5514
|
+
defaultValue: "Forward",
|
|
5515
|
+
}),
|
|
5516
|
+
} })] }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: customTranslate(`field_required`) }))] }));
|
|
5517
|
+
};
|
|
5518
|
+
|
|
4557
5519
|
const SchemaRenderer = ({ schema, prefix, column, }) => {
|
|
4558
5520
|
const colSchema = schema;
|
|
4559
|
-
const { type, variant, properties: innerProperties, foreign_key, items, } = schema;
|
|
5521
|
+
const { type, variant, properties: innerProperties, foreign_key, format, items, } = schema;
|
|
5522
|
+
if (variant === "custom-input") {
|
|
5523
|
+
return jsxRuntime.jsx(CustomInput, { schema: colSchema, prefix, column });
|
|
5524
|
+
}
|
|
4560
5525
|
if (type === "string") {
|
|
4561
5526
|
if ((schema.enum ?? []).length > 0) {
|
|
4562
5527
|
return jsxRuntime.jsx(EnumPicker, { schema: colSchema, prefix, column });
|
|
@@ -4565,9 +5530,18 @@ const SchemaRenderer = ({ schema, prefix, column, }) => {
|
|
|
4565
5530
|
idPickerSanityCheck(column, foreign_key);
|
|
4566
5531
|
return jsxRuntime.jsx(IdPicker, { schema: colSchema, prefix, column });
|
|
4567
5532
|
}
|
|
4568
|
-
if (
|
|
5533
|
+
if (format === "date") {
|
|
4569
5534
|
return jsxRuntime.jsx(DatePicker, { schema: colSchema, prefix, column });
|
|
4570
5535
|
}
|
|
5536
|
+
if (format === "time") {
|
|
5537
|
+
return jsxRuntime.jsx(TimePicker, { schema: colSchema, prefix, column });
|
|
5538
|
+
}
|
|
5539
|
+
if (format === "date-time") {
|
|
5540
|
+
return jsxRuntime.jsx(DateTimePicker, { schema: colSchema, prefix, column });
|
|
5541
|
+
}
|
|
5542
|
+
if (variant === "text-area") {
|
|
5543
|
+
return jsxRuntime.jsx(TextAreaInput, { schema: colSchema, prefix, column });
|
|
5544
|
+
}
|
|
4571
5545
|
return jsxRuntime.jsx(StringInputField, { schema: colSchema, prefix, column });
|
|
4572
5546
|
}
|
|
4573
5547
|
if (type === "number" || type === "integer") {
|
|
@@ -4593,6 +5567,15 @@ const SchemaRenderer = ({ schema, prefix, column, }) => {
|
|
|
4593
5567
|
if (variant === "file-picker") {
|
|
4594
5568
|
return jsxRuntime.jsx(FilePicker, { schema: colSchema, prefix, column });
|
|
4595
5569
|
}
|
|
5570
|
+
if (variant === "enum-picker") {
|
|
5571
|
+
const { items } = colSchema;
|
|
5572
|
+
const { enum: enumItems } = items;
|
|
5573
|
+
const enumSchema = {
|
|
5574
|
+
type: "string",
|
|
5575
|
+
enum: enumItems,
|
|
5576
|
+
};
|
|
5577
|
+
return (jsxRuntime.jsx(EnumPicker, { isMultiple: true, schema: enumSchema, prefix, column }));
|
|
5578
|
+
}
|
|
4596
5579
|
if (items) {
|
|
4597
5580
|
return jsxRuntime.jsx(ArrayRenderer, { schema: colSchema, prefix, column });
|
|
4598
5581
|
}
|
|
@@ -4614,39 +5597,56 @@ const ColumnRenderer = ({ column, properties, prefix, }) => {
|
|
|
4614
5597
|
};
|
|
4615
5598
|
|
|
4616
5599
|
const ArrayViewer = ({ schema, column, prefix }) => {
|
|
4617
|
-
const {
|
|
5600
|
+
const { gridColumn = "span 12", gridRow = "span 1", required, items, } = schema;
|
|
4618
5601
|
const { translate } = useSchemaContext();
|
|
4619
5602
|
const colLabel = `${prefix}${column}`;
|
|
4620
5603
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4621
5604
|
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
4622
5605
|
const values = watch(colLabel) ?? [];
|
|
4623
|
-
return (jsxRuntime.jsxs(react.Box, { gridRow, gridColumn, children: [jsxRuntime.jsxs(react.Box, { as: "label", gridColumn: "1/span12", children: [`${translate.t(removeIndex(`${colLabel}.
|
|
4624
|
-
|
|
4625
|
-
|
|
5606
|
+
return (jsxRuntime.jsxs(react.Box, { gridRow, gridColumn, children: [jsxRuntime.jsxs(react.Box, { as: "label", gridColumn: "1/span12", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsxRuntime.jsx("span", { children: "*" })] }), jsxRuntime.jsx(react.Flex, { flexFlow: "column", gap: 1, children: values.map((field, index) => (jsxRuntime.jsx(react.Flex, { flexFlow: "column", bgColor: { base: "colorPalette.100", _dark: "colorPalette.900" }, p: "2", borderRadius: "md", borderWidth: "thin", borderColor: {
|
|
5607
|
+
base: "colorPalette.200",
|
|
5608
|
+
_dark: "colorPalette.800",
|
|
5609
|
+
}, children: jsxRuntime.jsx(react.Grid, { gap: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: jsxRuntime.jsx(SchemaViewer, { column: `${index}`,
|
|
5610
|
+
prefix: `${colLabel}.`,
|
|
5611
|
+
// @ts-expect-error find suitable types
|
|
5612
|
+
schema: { showLabel: false, ...(items ?? {}) } }) }) }, `form-${prefix}${column}.${index}`))) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4626
5613
|
};
|
|
4627
5614
|
|
|
4628
5615
|
const BooleanViewer = ({ schema, column, prefix, }) => {
|
|
4629
5616
|
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
4630
5617
|
const { translate } = useSchemaContext();
|
|
4631
|
-
const { required, gridColumn, gridRow } = schema;
|
|
5618
|
+
const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
|
|
4632
5619
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4633
5620
|
const colLabel = `${prefix}${column}`;
|
|
4634
5621
|
const value = watch(colLabel);
|
|
4635
|
-
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.
|
|
5622
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
4636
5623
|
gridRow, children: [jsxRuntime.jsx(react.Text, { children: value
|
|
4637
5624
|
? translate.t(removeIndex(`${colLabel}.true`))
|
|
4638
|
-
: translate.t(removeIndex(`${colLabel}.false`)) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.
|
|
5625
|
+
: translate.t(removeIndex(`${colLabel}.false`)) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
5626
|
+
};
|
|
5627
|
+
|
|
5628
|
+
const CustomViewer = ({ column, schema, prefix }) => {
|
|
5629
|
+
const formContext = reactHookForm.useFormContext();
|
|
5630
|
+
const { inputViewerRender } = schema;
|
|
5631
|
+
return (inputViewerRender &&
|
|
5632
|
+
inputViewerRender({
|
|
5633
|
+
column,
|
|
5634
|
+
schema,
|
|
5635
|
+
prefix,
|
|
5636
|
+
formContext,
|
|
5637
|
+
}));
|
|
4639
5638
|
};
|
|
4640
5639
|
|
|
4641
5640
|
const DateViewer = ({ column, schema, prefix }) => {
|
|
4642
5641
|
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
4643
|
-
const { translate } = useSchemaContext();
|
|
4644
|
-
const { required, gridColumn, gridRow } = schema;
|
|
5642
|
+
const { translate, timezone } = useSchemaContext();
|
|
5643
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD", } = schema;
|
|
4645
5644
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4646
5645
|
const colLabel = `${prefix}${column}`;
|
|
4647
5646
|
const selectedDate = watch(colLabel);
|
|
4648
|
-
|
|
4649
|
-
|
|
5647
|
+
const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
|
|
5648
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
5649
|
+
gridRow, children: [jsxRuntime.jsxs(react.Text, { children: [" ", selectedDate !== undefined ? displayDate : ""] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
|
|
4650
5650
|
};
|
|
4651
5651
|
|
|
4652
5652
|
const EnumViewer = ({ column, isMultiple = false, schema, prefix, }) => {
|
|
@@ -4654,45 +5654,41 @@ const EnumViewer = ({ column, isMultiple = false, schema, prefix, }) => {
|
|
|
4654
5654
|
const { translate } = useSchemaContext();
|
|
4655
5655
|
const { required } = schema;
|
|
4656
5656
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4657
|
-
const { gridColumn, gridRow, renderDisplay } = schema;
|
|
5657
|
+
const { gridColumn = "span 4", gridRow = "span 1", renderDisplay } = schema;
|
|
4658
5658
|
const colLabel = `${prefix}${column}`;
|
|
4659
5659
|
const watchEnum = watch(colLabel);
|
|
4660
5660
|
const watchEnums = (watch(colLabel) ?? []);
|
|
4661
|
-
|
|
5661
|
+
const customTranslate = (label) => {
|
|
5662
|
+
return translateWrapper({ prefix, column, label, translate });
|
|
5663
|
+
};
|
|
5664
|
+
return (jsxRuntime.jsxs(Field, { label: `${customTranslate(`field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
4662
5665
|
gridRow, children: [isMultiple && (jsxRuntime.jsx(react.Flex, { flexFlow: "wrap", gap: 1, children: watchEnums.map((enumValue) => {
|
|
4663
5666
|
const item = enumValue;
|
|
4664
5667
|
if (item === undefined) {
|
|
4665
5668
|
return jsxRuntime.jsx(jsxRuntime.Fragment, { children: "undefined" });
|
|
4666
5669
|
}
|
|
4667
|
-
return (jsxRuntime.jsx(Tag, {
|
|
5670
|
+
return (jsxRuntime.jsx(Tag, { size: "lg", children: !!renderDisplay === true
|
|
4668
5671
|
? renderDisplay(item)
|
|
4669
|
-
:
|
|
4670
|
-
}) })), !isMultiple &&
|
|
5672
|
+
: customTranslate(item) }, item));
|
|
5673
|
+
}) })), !isMultiple && jsxRuntime.jsx(react.Text, { children: customTranslate(watchEnum) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: customTranslate(`field_required`) }))] }));
|
|
4671
5674
|
};
|
|
4672
5675
|
|
|
4673
5676
|
const FileViewer = ({ column, schema, prefix }) => {
|
|
4674
|
-
const {
|
|
5677
|
+
const { watch } = reactHookForm.useFormContext();
|
|
4675
5678
|
const { translate } = useSchemaContext();
|
|
4676
|
-
const { required, gridColumn, gridRow } = schema;
|
|
5679
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", } = schema;
|
|
4677
5680
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4678
5681
|
const currentFiles = (watch(column) ?? []);
|
|
4679
5682
|
const colLabel = `${prefix}${column}`;
|
|
4680
|
-
return (jsxRuntime.
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
}, placeholder: translate.t(`${colLabel}.fileDropzone`) }), jsxRuntime.jsx(react.Flex, { flexFlow: "column", gap: 1, children: currentFiles.map((file) => {
|
|
4684
|
-
return (jsxRuntime.jsx(react.Card.Root, { variant: "subtle", children: jsxRuntime.jsxs(react.Card.Body, { gap: "2", cursor: "pointer", onClick: () => {
|
|
4685
|
-
setValue(column, currentFiles.filter(({ name }) => {
|
|
4686
|
-
return name !== file.name;
|
|
4687
|
-
}));
|
|
4688
|
-
}, display: "flex", flexFlow: "row", alignItems: "center", padding: "2", children: [jsxRuntime.jsx(react.Box, { children: file.name }), jsxRuntime.jsx(ti.TiDeleteOutline, {})] }) }, file.name));
|
|
4689
|
-
}) }), errors[`${colLabel}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.fieldRequired`)) }))] }));
|
|
5683
|
+
return (jsxRuntime.jsx(Field, { label: `${translate.t(`${colLabel}.field_label`)}`, required: isRequired, gridColumn: gridColumn, gridRow: gridRow, display: "grid", gridTemplateRows: "auto 1fr auto", alignItems: "stretch", children: jsxRuntime.jsx(react.Flex, { flexFlow: "column", gap: 1, children: currentFiles.map((file) => {
|
|
5684
|
+
return (jsxRuntime.jsx(react.Card.Root, { variant: "subtle", children: jsxRuntime.jsxs(react.Card.Body, { gap: "2", display: "flex", flexFlow: "row", alignItems: "center", padding: "2", children: [file.type.startsWith("image/") && (jsxRuntime.jsx(react.Image, { src: URL.createObjectURL(file), alt: file.name, boxSize: "50px", objectFit: "cover", borderRadius: "md", marginRight: "2" })), jsxRuntime.jsx(react.Box, { children: file.name })] }) }, file.name));
|
|
5685
|
+
}) }) }));
|
|
4690
5686
|
};
|
|
4691
5687
|
|
|
4692
5688
|
const IdViewer = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
4693
5689
|
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
4694
5690
|
const { idMap, translate } = useSchemaContext();
|
|
4695
|
-
const { required, gridColumn, gridRow, renderDisplay, foreign_key } = schema;
|
|
5691
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", renderDisplay, foreign_key, } = schema;
|
|
4696
5692
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4697
5693
|
const { display_column } = foreign_key;
|
|
4698
5694
|
const colLabel = `${prefix}${column}`;
|
|
@@ -4708,7 +5704,7 @@ const IdViewer = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4708
5704
|
}
|
|
4709
5705
|
return record[display_column];
|
|
4710
5706
|
};
|
|
4711
|
-
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${column}.
|
|
5707
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
4712
5708
|
gridRow, children: [isMultiple && (jsxRuntime.jsx(react.Flex, { flexFlow: "wrap", gap: 1, children: watchIds.map((id) => {
|
|
4713
5709
|
const item = idMap[id];
|
|
4714
5710
|
if (item === undefined) {
|
|
@@ -4717,21 +5713,21 @@ const IdViewer = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4717
5713
|
return (jsxRuntime.jsx(Tag, { closable: true, children: !!renderDisplay === true
|
|
4718
5714
|
? renderDisplay(item)
|
|
4719
5715
|
: item[display_column] }, id));
|
|
4720
|
-
}) })), !isMultiple && jsxRuntime.jsx(react.Text, { children: getPickedValue() }), errors[`${colLabel}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.
|
|
5716
|
+
}) })), !isMultiple && jsxRuntime.jsx(react.Text, { children: getPickedValue() }), errors[`${colLabel}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4721
5717
|
};
|
|
4722
5718
|
|
|
4723
5719
|
const NumberViewer = ({ schema, column, prefix, }) => {
|
|
4724
5720
|
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
4725
5721
|
const { translate } = useSchemaContext();
|
|
4726
|
-
const { required, gridColumn, gridRow } = schema;
|
|
5722
|
+
const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
|
|
4727
5723
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4728
5724
|
const colLabel = `${prefix}${column}`;
|
|
4729
5725
|
const value = watch(colLabel);
|
|
4730
|
-
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.
|
|
5726
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn, gridRow, children: [jsxRuntime.jsx(react.Text, { children: value }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4731
5727
|
};
|
|
4732
5728
|
|
|
4733
5729
|
const ObjectViewer = ({ schema, column, prefix }) => {
|
|
4734
|
-
const { properties,
|
|
5730
|
+
const { properties, gridColumn = "span 12", gridRow = "span 1", required, showLabel = true, } = schema;
|
|
4735
5731
|
const { translate } = useSchemaContext();
|
|
4736
5732
|
const colLabel = `${prefix}${column}`;
|
|
4737
5733
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
@@ -4739,25 +5735,28 @@ const ObjectViewer = ({ schema, column, prefix }) => {
|
|
|
4739
5735
|
if (properties === undefined) {
|
|
4740
5736
|
throw new Error(`properties is undefined when using ObjectInput`);
|
|
4741
5737
|
}
|
|
4742
|
-
return (jsxRuntime.jsxs(react.Box, { gridRow, gridColumn, children: [jsxRuntime.jsxs(react.Box, { as: "label",
|
|
5738
|
+
return (jsxRuntime.jsxs(react.Box, { gridRow, gridColumn, children: [showLabel && (jsxRuntime.jsxs(react.Box, { as: "label", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsxRuntime.jsx("span", { children: "*" })] })), jsxRuntime.jsx(react.Grid, { gap: "4", padding: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", bgColor: { base: "colorPalette.100", _dark: "colorPalette.900" }, p: "1", borderRadius: "md", borderWidth: "thin", borderColor: {
|
|
5739
|
+
base: "colorPalette.200",
|
|
5740
|
+
_dark: "colorPalette.800",
|
|
5741
|
+
}, children: Object.keys(properties ?? {}).map((key) => {
|
|
4743
5742
|
return (
|
|
4744
5743
|
// @ts-expect-error find suitable types
|
|
4745
5744
|
jsxRuntime.jsx(ColumnViewer, { column: `${key}`,
|
|
4746
5745
|
prefix: `${prefix}${column}.`,
|
|
4747
5746
|
properties }, `form-objectviewer-${colLabel}-${key}`));
|
|
4748
|
-
}) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.
|
|
5747
|
+
}) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4749
5748
|
};
|
|
4750
5749
|
|
|
4751
5750
|
const RecordInput = ({ column, schema, prefix }) => {
|
|
4752
5751
|
const { formState: { errors }, setValue, getValues, } = reactHookForm.useFormContext();
|
|
4753
5752
|
const { translate } = useSchemaContext();
|
|
4754
|
-
const { required, gridColumn, gridRow } = schema;
|
|
5753
|
+
const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
|
|
4755
5754
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4756
5755
|
const entries = Object.entries(getValues(column) ?? {});
|
|
4757
5756
|
const [showNewEntries, setShowNewEntries] = React.useState(false);
|
|
4758
5757
|
const [newKey, setNewKey] = React.useState();
|
|
4759
5758
|
const [newValue, setNewValue] = React.useState();
|
|
4760
|
-
return (jsxRuntime.jsxs(Field, { label: `${translate.t(`${column}.
|
|
5759
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(`${column}.field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn, gridRow, children: [entries.map(([key, value]) => {
|
|
4761
5760
|
return (jsxRuntime.jsxs(react.Grid, { templateColumns: "1fr 1fr auto", gap: 1, children: [jsxRuntime.jsx(react.Input, { value: key, onChange: (e) => {
|
|
4762
5761
|
const filtered = entries.filter(([target]) => {
|
|
4763
5762
|
return target !== key;
|
|
@@ -4797,7 +5796,17 @@ const RecordInput = ({ column, schema, prefix }) => {
|
|
|
4797
5796
|
setShowNewEntries(true);
|
|
4798
5797
|
setNewKey(undefined);
|
|
4799
5798
|
setNewValue(undefined);
|
|
4800
|
-
}, children: translate.t(`${column}.addNew`) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(`${column}.
|
|
5799
|
+
}, children: translate.t(`${column}.addNew`) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
|
|
5800
|
+
};
|
|
5801
|
+
|
|
5802
|
+
const StringViewer = ({ column, schema, prefix, }) => {
|
|
5803
|
+
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
5804
|
+
const { translate } = useSchemaContext();
|
|
5805
|
+
const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
|
|
5806
|
+
const isRequired = required?.some((columnId) => columnId === column);
|
|
5807
|
+
const colLabel = `${prefix}${column}`;
|
|
5808
|
+
const value = watch(colLabel);
|
|
5809
|
+
return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn: gridColumn ?? "span 4", gridRow: gridRow ?? "span 1", children: [jsxRuntime.jsx(react.Text, { children: value }), errors[colLabel] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }) }));
|
|
4801
5810
|
};
|
|
4802
5811
|
|
|
4803
5812
|
const TagViewer = ({ column, schema, prefix }) => {
|
|
@@ -4885,19 +5894,50 @@ const TagViewer = ({ column, schema, prefix }) => {
|
|
|
4885
5894
|
}), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: (errors[`${column}`]?.message ?? "No error message") }))] }));
|
|
4886
5895
|
};
|
|
4887
5896
|
|
|
4888
|
-
const
|
|
5897
|
+
const TextAreaViewer = ({ column, schema, prefix, }) => {
|
|
4889
5898
|
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
4890
5899
|
const { translate } = useSchemaContext();
|
|
4891
|
-
const { required, gridColumn, gridRow } = schema;
|
|
5900
|
+
const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
|
|
4892
5901
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4893
5902
|
const colLabel = `${prefix}${column}`;
|
|
4894
5903
|
const value = watch(colLabel);
|
|
4895
|
-
return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.
|
|
5904
|
+
return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn: gridColumn, gridRow: gridRow, children: [jsxRuntime.jsx(react.Text, { whiteSpace: "pre-wrap", children: value }), " ", errors[colLabel] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }) }));
|
|
5905
|
+
};
|
|
5906
|
+
|
|
5907
|
+
const TimeViewer = ({ column, schema, prefix }) => {
|
|
5908
|
+
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
5909
|
+
const { translate, timezone } = useSchemaContext();
|
|
5910
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", displayTimeFormat = "hh:mm A", } = schema;
|
|
5911
|
+
const isRequired = required?.some((columnId) => columnId === column);
|
|
5912
|
+
const colLabel = `${prefix}${column}`;
|
|
5913
|
+
const selectedDate = watch(colLabel);
|
|
5914
|
+
const displayedTime = dayjs(`1970-01-01T${selectedDate}`)
|
|
5915
|
+
.tz(timezone)
|
|
5916
|
+
.isValid()
|
|
5917
|
+
? dayjs(`1970-01-01T${selectedDate}`).tz(timezone).format(displayTimeFormat)
|
|
5918
|
+
: "";
|
|
5919
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
5920
|
+
gridRow, children: [jsxRuntime.jsx(react.Text, { children: displayedTime }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
|
|
5921
|
+
};
|
|
5922
|
+
|
|
5923
|
+
const DateTimeViewer = ({ column, schema, prefix }) => {
|
|
5924
|
+
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
5925
|
+
const { translate, timezone } = useSchemaContext();
|
|
5926
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD HH:mm:ss", } = schema;
|
|
5927
|
+
const isRequired = required?.some((columnId) => columnId === column);
|
|
5928
|
+
const colLabel = `${prefix}${column}`;
|
|
5929
|
+
const selectedDate = watch(colLabel);
|
|
5930
|
+
const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
|
|
5931
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
5932
|
+
gridRow, children: [jsxRuntime.jsxs(react.Text, { children: [" ", selectedDate !== undefined ? displayDate : ""] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
|
|
4896
5933
|
};
|
|
4897
5934
|
|
|
4898
5935
|
const SchemaViewer = ({ schema, prefix, column, }) => {
|
|
4899
5936
|
const colSchema = schema;
|
|
4900
|
-
const { type, variant, properties: innerProperties, foreign_key, items, } = schema;
|
|
5937
|
+
const { type, variant, properties: innerProperties, foreign_key, items, format, } = schema;
|
|
5938
|
+
if (variant === "custom-input") {
|
|
5939
|
+
return jsxRuntime.jsx(CustomViewer, { schema: colSchema, prefix, column });
|
|
5940
|
+
}
|
|
4901
5941
|
if (type === "string") {
|
|
4902
5942
|
if ((schema.enum ?? []).length > 0) {
|
|
4903
5943
|
return jsxRuntime.jsx(EnumViewer, { schema: colSchema, prefix, column });
|
|
@@ -4906,9 +5946,18 @@ const SchemaViewer = ({ schema, prefix, column, }) => {
|
|
|
4906
5946
|
idPickerSanityCheck(column, foreign_key);
|
|
4907
5947
|
return jsxRuntime.jsx(IdViewer, { schema: colSchema, prefix, column });
|
|
4908
5948
|
}
|
|
4909
|
-
if (
|
|
5949
|
+
if (format === "time") {
|
|
5950
|
+
return jsxRuntime.jsx(TimeViewer, { schema: colSchema, prefix, column });
|
|
5951
|
+
}
|
|
5952
|
+
if (format === "date") {
|
|
4910
5953
|
return jsxRuntime.jsx(DateViewer, { schema: colSchema, prefix, column });
|
|
4911
5954
|
}
|
|
5955
|
+
if (format === "date-time") {
|
|
5956
|
+
return jsxRuntime.jsx(DateTimeViewer, { schema: colSchema, prefix, column });
|
|
5957
|
+
}
|
|
5958
|
+
if (variant === "text-area") {
|
|
5959
|
+
return jsxRuntime.jsx(TextAreaViewer, { schema: colSchema, prefix, column });
|
|
5960
|
+
}
|
|
4912
5961
|
return jsxRuntime.jsx(StringViewer, { schema: colSchema, prefix, column });
|
|
4913
5962
|
}
|
|
4914
5963
|
if (type === "number" || type === "integer") {
|
|
@@ -4934,6 +5983,15 @@ const SchemaViewer = ({ schema, prefix, column, }) => {
|
|
|
4934
5983
|
if (variant === "file-picker") {
|
|
4935
5984
|
return jsxRuntime.jsx(FileViewer, { schema: colSchema, prefix, column });
|
|
4936
5985
|
}
|
|
5986
|
+
if (variant === "enum-picker") {
|
|
5987
|
+
const { items } = schema;
|
|
5988
|
+
const { enum: enumItems } = items;
|
|
5989
|
+
const enumSchema = {
|
|
5990
|
+
type: "string",
|
|
5991
|
+
enum: enumItems,
|
|
5992
|
+
};
|
|
5993
|
+
return (jsxRuntime.jsx(EnumViewer, { isMultiple: true, schema: enumSchema, prefix, column }));
|
|
5994
|
+
}
|
|
4937
5995
|
if (items) {
|
|
4938
5996
|
return jsxRuntime.jsx(ArrayViewer, { schema: colSchema, prefix, column });
|
|
4939
5997
|
}
|
|
@@ -4957,10 +6015,20 @@ const ColumnViewer = ({ column, properties, prefix, }) => {
|
|
|
4957
6015
|
};
|
|
4958
6016
|
|
|
4959
6017
|
const SubmitButton = () => {
|
|
4960
|
-
const { translate, setValidatedData, setIsError, setIsConfirming } = useSchemaContext();
|
|
6018
|
+
const { translate, setValidatedData, setIsError, setIsConfirming, setError, schema, } = useSchemaContext();
|
|
4961
6019
|
const methods = reactHookForm.useFormContext();
|
|
4962
6020
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4963
6021
|
const onValid = (data) => {
|
|
6022
|
+
const { isValid, errors } = validateData(data, schema);
|
|
6023
|
+
if (!isValid) {
|
|
6024
|
+
setError({
|
|
6025
|
+
type: "validation",
|
|
6026
|
+
errors,
|
|
6027
|
+
});
|
|
6028
|
+
setIsError(true);
|
|
6029
|
+
return;
|
|
6030
|
+
}
|
|
6031
|
+
// If validation passes, proceed to confirmation
|
|
4964
6032
|
setValidatedData(data);
|
|
4965
6033
|
setIsError(false);
|
|
4966
6034
|
setIsConfirming(true);
|
|
@@ -4971,7 +6039,8 @@ const SubmitButton = () => {
|
|
|
4971
6039
|
};
|
|
4972
6040
|
|
|
4973
6041
|
const FormBody = () => {
|
|
4974
|
-
const { schema, requestUrl, order, ignore, include, onSubmit,
|
|
6042
|
+
const { schema, requestUrl, order, ignore, include, onSubmit, translate, requestOptions, isSuccess, setIsSuccess, isError, setIsError, isSubmiting, setIsSubmiting, isConfirming, setIsConfirming, validatedData, setValidatedData, error, setError, getUpdatedData, customErrorRenderer, displayConfig, } = useSchemaContext();
|
|
6043
|
+
const { showSubmitButton, showResetButton } = displayConfig;
|
|
4975
6044
|
const methods = reactHookForm.useFormContext();
|
|
4976
6045
|
const { properties } = schema;
|
|
4977
6046
|
const onBeforeSubmit = () => {
|
|
@@ -4987,6 +6056,26 @@ const FormBody = () => {
|
|
|
4987
6056
|
const onSubmitSuccess = () => {
|
|
4988
6057
|
setIsSuccess(true);
|
|
4989
6058
|
};
|
|
6059
|
+
const validateFormData = (data) => {
|
|
6060
|
+
try {
|
|
6061
|
+
const { isValid, errors } = validateData(data, schema);
|
|
6062
|
+
return {
|
|
6063
|
+
isValid,
|
|
6064
|
+
errors,
|
|
6065
|
+
};
|
|
6066
|
+
}
|
|
6067
|
+
catch (error) {
|
|
6068
|
+
return {
|
|
6069
|
+
isValid: false,
|
|
6070
|
+
errors: [
|
|
6071
|
+
{
|
|
6072
|
+
field: "validation",
|
|
6073
|
+
message: error instanceof Error ? error.message : "Unknown error",
|
|
6074
|
+
},
|
|
6075
|
+
],
|
|
6076
|
+
};
|
|
6077
|
+
}
|
|
6078
|
+
};
|
|
4990
6079
|
const defaultOnSubmit = async (promise) => {
|
|
4991
6080
|
try {
|
|
4992
6081
|
onBeforeSubmit();
|
|
@@ -5011,12 +6100,28 @@ const FormBody = () => {
|
|
|
5011
6100
|
};
|
|
5012
6101
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5013
6102
|
const onFormSubmit = async (data) => {
|
|
6103
|
+
// Validate data using AJV before submission
|
|
6104
|
+
const validationResult = validateFormData(data);
|
|
6105
|
+
if (!validationResult.isValid) {
|
|
6106
|
+
// Set validation errors
|
|
6107
|
+
const validationErrorMessage = {
|
|
6108
|
+
type: "validation",
|
|
6109
|
+
errors: validationResult.errors,
|
|
6110
|
+
message: translate.t("validation_error"),
|
|
6111
|
+
};
|
|
6112
|
+
onSubmitError(validationErrorMessage);
|
|
6113
|
+
return;
|
|
6114
|
+
}
|
|
5014
6115
|
if (onSubmit === undefined) {
|
|
5015
6116
|
await defaultOnSubmit(defaultSubmitPromise(data));
|
|
5016
6117
|
return;
|
|
5017
6118
|
}
|
|
5018
6119
|
await defaultOnSubmit(onSubmit(data));
|
|
5019
6120
|
};
|
|
6121
|
+
// Custom error renderer for validation errors with i18n support
|
|
6122
|
+
const renderValidationErrors = (validationErrors) => {
|
|
6123
|
+
return (jsxRuntime.jsx(react.Flex, { flexFlow: "column", gap: "2", children: validationErrors.map((err, index) => (jsxRuntime.jsxs(react.Alert.Root, { status: "error", display: "flex", alignItems: "center", children: [jsxRuntime.jsx(react.Alert.Indicator, {}), jsxRuntime.jsx(react.Alert.Content, { children: jsxRuntime.jsx(react.Alert.Description, { children: err.message }) })] }, index))) }));
|
|
6124
|
+
};
|
|
5020
6125
|
const renderColumns = ({ order, keys, ignore, include, }) => {
|
|
5021
6126
|
const included = include.length > 0 ? include : keys;
|
|
5022
6127
|
const not_exist = included.filter((columnA) => !order.some((columnB) => columnA === columnB));
|
|
@@ -5031,7 +6136,7 @@ const FormBody = () => {
|
|
|
5031
6136
|
include,
|
|
5032
6137
|
});
|
|
5033
6138
|
if (isSuccess) {
|
|
5034
|
-
return (jsxRuntime.jsxs(react.Flex, { flexFlow: "column", gap: "2", children: [jsxRuntime.jsxs(react.Alert.Root, { status: "success", children: [jsxRuntime.jsx(react.Alert.Indicator, {}), jsxRuntime.jsx(react.Alert.Title, { children: translate.t("
|
|
6139
|
+
return (jsxRuntime.jsxs(react.Flex, { flexFlow: "column", gap: "2", children: [jsxRuntime.jsxs(react.Alert.Root, { status: "success", children: [jsxRuntime.jsx(react.Alert.Indicator, {}), jsxRuntime.jsx(react.Alert.Content, { children: jsxRuntime.jsx(react.Alert.Title, { children: translate.t("submit_success") }) })] }), jsxRuntime.jsx(react.Flex, { justifyContent: "end", children: jsxRuntime.jsx(react.Button, { onClick: async () => {
|
|
5035
6140
|
setIsError(false);
|
|
5036
6141
|
setIsSubmiting(false);
|
|
5037
6142
|
setIsSuccess(false);
|
|
@@ -5039,10 +6144,10 @@ const FormBody = () => {
|
|
|
5039
6144
|
setValidatedData(undefined);
|
|
5040
6145
|
const data = await getUpdatedData();
|
|
5041
6146
|
methods.reset(data);
|
|
5042
|
-
}, formNoValidate: true, children: translate.t("
|
|
6147
|
+
}, formNoValidate: true, children: translate.t("submit_again") }) })] }));
|
|
5043
6148
|
}
|
|
5044
6149
|
if (isConfirming) {
|
|
5045
|
-
return (jsxRuntime.jsxs(react.Flex, { flexFlow: "column", gap: "2", children: [jsxRuntime.jsx(react.Grid, { gap: 4, gridTemplateColumns: "repeat(12, 1fr)", gridTemplateRows:
|
|
6150
|
+
return (jsxRuntime.jsxs(react.Flex, { flexFlow: "column", gap: "2", children: [jsxRuntime.jsx(react.Grid, { gap: 4, gridTemplateColumns: "repeat(12, 1fr)", gridTemplateRows: "repeat(12, max-content)", autoFlow: "row", children: ordered.map((column) => {
|
|
5046
6151
|
return (jsxRuntime.jsx(ColumnViewer
|
|
5047
6152
|
// @ts-expect-error find suitable types
|
|
5048
6153
|
, {
|
|
@@ -5052,17 +6157,19 @@ const FormBody = () => {
|
|
|
5052
6157
|
setIsConfirming(false);
|
|
5053
6158
|
}, variant: "subtle", children: translate.t("cancel") }), jsxRuntime.jsx(react.Button, { onClick: () => {
|
|
5054
6159
|
onFormSubmit(validatedData);
|
|
5055
|
-
}, children: translate.t("confirm") })] }), isSubmiting && (jsxRuntime.jsx(react.Box, { pos: "absolute", inset: "0", bg: "bg/80", children: jsxRuntime.jsx(react.Center, { h: "full", children: jsxRuntime.jsx(react.Spinner, { color: "teal.500" }) }) })), isError && (jsxRuntime.jsx(jsxRuntime.Fragment, { children:
|
|
6160
|
+
}, children: translate.t("confirm") })] }), isSubmiting && (jsxRuntime.jsx(react.Box, { pos: "absolute", inset: "0", bg: "bg/80", children: jsxRuntime.jsx(react.Center, { h: "full", children: jsxRuntime.jsx(react.Spinner, { color: "teal.500" }) }) })), isError && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: customErrorRenderer ? (customErrorRenderer(error)) : (jsxRuntime.jsx(jsxRuntime.Fragment, { children: error?.type === "validation" &&
|
|
6161
|
+
error?.errors ? (renderValidationErrors(error.errors)) : (jsxRuntime.jsxs(react.Alert.Root, { status: "error", children: [jsxRuntime.jsx(react.Alert.Indicator, {}), jsxRuntime.jsxs(react.Alert.Content, { children: [jsxRuntime.jsx(react.Alert.Title, { children: "Error" }), jsxRuntime.jsx(react.Alert.Description, { children: jsxRuntime.jsx(AccordionRoot, { collapsible: true, defaultValue: [], children: jsxRuntime.jsxs(AccordionItem, { value: "b", children: [jsxRuntime.jsx(AccordionItemTrigger, { children: `${error}` }), jsxRuntime.jsx(AccordionItemContent, { children: `${JSON.stringify(error)}` })] }) }) })] })] })) })) }))] }));
|
|
5056
6162
|
}
|
|
5057
|
-
return (jsxRuntime.jsxs(react.Flex, { flexFlow: "column", gap: "2", children: [jsxRuntime.jsx(react.Grid, { gap: "4", gridTemplateColumns: "repeat(12, 1fr)",
|
|
6163
|
+
return (jsxRuntime.jsxs(react.Flex, { flexFlow: "column", gap: "2", children: [jsxRuntime.jsx(react.Grid, { gap: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: ordered.map((column) => {
|
|
5058
6164
|
return (jsxRuntime.jsx(ColumnRenderer
|
|
5059
6165
|
// @ts-expect-error find suitable types
|
|
5060
6166
|
, {
|
|
5061
6167
|
// @ts-expect-error find suitable types
|
|
5062
6168
|
properties: properties, prefix: ``, column }, `form-input-${column}`));
|
|
5063
|
-
}) }), jsxRuntime.jsxs(react.Flex, { justifyContent: "end", gap: "2", children: [jsxRuntime.jsx(react.Button, { onClick: () => {
|
|
6169
|
+
}) }), jsxRuntime.jsxs(react.Flex, { justifyContent: "end", gap: "2", children: [showResetButton && (jsxRuntime.jsx(react.Button, { onClick: () => {
|
|
5064
6170
|
methods.reset();
|
|
5065
|
-
}, variant: "subtle", children: translate.t("reset") }), jsxRuntime.jsx(SubmitButton, {})] })
|
|
6171
|
+
}, variant: "subtle", children: translate.t("reset") })), showSubmitButton && jsxRuntime.jsx(SubmitButton, {})] }), isError && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: customErrorRenderer ? (customErrorRenderer(error)) : (jsxRuntime.jsx(jsxRuntime.Fragment, { children: error?.type === "validation" &&
|
|
6172
|
+
error?.errors ? (renderValidationErrors(error.errors)) : (jsxRuntime.jsxs(react.Alert.Root, { status: "error", children: [jsxRuntime.jsx(react.Alert.Indicator, {}), jsxRuntime.jsxs(react.Alert.Content, { children: [jsxRuntime.jsx(react.Alert.Title, { children: "Error" }), jsxRuntime.jsx(react.Alert.Description, { children: jsxRuntime.jsx(AccordionRoot, { collapsible: true, defaultValue: [], children: jsxRuntime.jsxs(AccordionItem, { value: "b", children: [jsxRuntime.jsx(AccordionItemTrigger, { children: `${error}` }), jsxRuntime.jsx(AccordionItemContent, { children: `${JSON.stringify(error)}` })] }) }) })] })] })) })) }))] }));
|
|
5066
6173
|
};
|
|
5067
6174
|
|
|
5068
6175
|
const FormTitle = () => {
|
|
@@ -5071,7 +6178,8 @@ const FormTitle = () => {
|
|
|
5071
6178
|
};
|
|
5072
6179
|
|
|
5073
6180
|
const DefaultForm = ({ formConfig, }) => {
|
|
5074
|
-
|
|
6181
|
+
const { showTitle } = formConfig.displayConfig ?? {};
|
|
6182
|
+
return (jsxRuntime.jsx(FormRoot, { ...formConfig, children: jsxRuntime.jsxs(react.Grid, { gap: "2", children: [showTitle && jsxRuntime.jsx(FormTitle, {}), jsxRuntime.jsx(FormBody, {})] }) }));
|
|
5075
6183
|
};
|
|
5076
6184
|
|
|
5077
6185
|
const useForm = ({ preLoadedValues, keyPrefix }) => {
|
|
@@ -5116,7 +6224,6 @@ exports.EditSortingButton = EditSortingButton;
|
|
|
5116
6224
|
exports.EmptyState = EmptyState$1;
|
|
5117
6225
|
exports.ErrorAlert = ErrorAlert;
|
|
5118
6226
|
exports.FilterDialog = FilterDialog;
|
|
5119
|
-
exports.FilterOptions = FilterOptions;
|
|
5120
6227
|
exports.FormBody = FormBody;
|
|
5121
6228
|
exports.FormRoot = FormRoot;
|
|
5122
6229
|
exports.FormTitle = FormTitle;
|
|
@@ -5135,6 +6242,7 @@ exports.TableCardContainer = TableCardContainer;
|
|
|
5135
6242
|
exports.TableCards = TableCards;
|
|
5136
6243
|
exports.TableComponent = TableComponent;
|
|
5137
6244
|
exports.TableControls = TableControls;
|
|
6245
|
+
exports.TableDataDisplay = TableDataDisplay;
|
|
5138
6246
|
exports.TableFilter = TableFilter;
|
|
5139
6247
|
exports.TableFilterTags = TableFilterTags;
|
|
5140
6248
|
exports.TableFooter = TableFooter;
|