@bsol-oss/react-datatable5 12.0.0-beta.7 → 12.0.0-beta.71
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 +282 -83
- package/dist/index.js +1637 -475
- package/dist/index.mjs +1645 -483
- 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/useFormI18n.d.ts +53 -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 +18 -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 12", 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,144 @@ const PopoverRoot = react.Popover.Root;
|
|
|
3741
3963
|
const PopoverBody = react.Popover.Body;
|
|
3742
3964
|
const PopoverTrigger = react.Popover.Trigger;
|
|
3743
3965
|
|
|
3966
|
+
/**
|
|
3967
|
+
* Custom hook to simplify i18n translation for form fields.
|
|
3968
|
+
* Automatically handles colLabel construction and removeIndex logic.
|
|
3969
|
+
*
|
|
3970
|
+
* @param column - The column name
|
|
3971
|
+
* @param prefix - The prefix for the field (usually empty string or parent path)
|
|
3972
|
+
* @returns Object with translation helper functions
|
|
3973
|
+
*
|
|
3974
|
+
* @example
|
|
3975
|
+
* ```tsx
|
|
3976
|
+
* const formI18n = useFormI18n(column, prefix);
|
|
3977
|
+
*
|
|
3978
|
+
* // Get field label
|
|
3979
|
+
* <Field label={formI18n.label()} />
|
|
3980
|
+
*
|
|
3981
|
+
* // Get error message
|
|
3982
|
+
* <Text>{formI18n.required()}</Text>
|
|
3983
|
+
*
|
|
3984
|
+
* // Get custom translation key
|
|
3985
|
+
* <Text>{formI18n.t('add_more')}</Text>
|
|
3986
|
+
*
|
|
3987
|
+
* // Access the raw colLabel
|
|
3988
|
+
* const colLabel = formI18n.colLabel;
|
|
3989
|
+
* ```
|
|
3990
|
+
*/
|
|
3991
|
+
const useFormI18n = (column, prefix = "") => {
|
|
3992
|
+
const { translate } = useSchemaContext();
|
|
3993
|
+
const colLabel = `${prefix}${column}`;
|
|
3994
|
+
return {
|
|
3995
|
+
/**
|
|
3996
|
+
* The constructed column label (prefix + column)
|
|
3997
|
+
*/
|
|
3998
|
+
colLabel,
|
|
3999
|
+
/**
|
|
4000
|
+
* Get the field label translation
|
|
4001
|
+
* Equivalent to: translate.t(removeIndex(`${colLabel}.field_label`))
|
|
4002
|
+
*/
|
|
4003
|
+
label: (options) => {
|
|
4004
|
+
return translate.t(removeIndex(`${colLabel}.field_label`), options);
|
|
4005
|
+
},
|
|
4006
|
+
/**
|
|
4007
|
+
* Get the required error message translation
|
|
4008
|
+
* Equivalent to: translate.t(removeIndex(`${colLabel}.field_required`))
|
|
4009
|
+
*/
|
|
4010
|
+
required: (options) => {
|
|
4011
|
+
return translate.t(removeIndex(`${colLabel}.field_required`), options);
|
|
4012
|
+
},
|
|
4013
|
+
/**
|
|
4014
|
+
* Get a translation for any custom key relative to the field
|
|
4015
|
+
* Equivalent to: translate.t(removeIndex(`${colLabel}.${key}`))
|
|
4016
|
+
*
|
|
4017
|
+
* @param key - The translation key suffix (e.g., 'add_more', 'total', etc.)
|
|
4018
|
+
* @param options - Optional translation options (e.g., defaultValue, interpolation variables)
|
|
4019
|
+
*/
|
|
4020
|
+
t: (key, options) => {
|
|
4021
|
+
return translate.t(removeIndex(`${colLabel}.${key}`), options);
|
|
4022
|
+
},
|
|
4023
|
+
/**
|
|
4024
|
+
* Access to the original translate object for edge cases
|
|
4025
|
+
*/
|
|
4026
|
+
translate,
|
|
4027
|
+
};
|
|
4028
|
+
};
|
|
4029
|
+
|
|
4030
|
+
dayjs.extend(utc);
|
|
4031
|
+
dayjs.extend(timezone);
|
|
3744
4032
|
const DatePicker = ({ column, schema, prefix }) => {
|
|
3745
4033
|
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
3746
|
-
const {
|
|
3747
|
-
const
|
|
4034
|
+
const { timezone } = useSchemaContext();
|
|
4035
|
+
const formI18n = useFormI18n(column, prefix);
|
|
4036
|
+
const { required, gridColumn = "span 12", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD", dateFormat = "YYYY-MM-DD", } = schema;
|
|
3748
4037
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
3749
|
-
const colLabel =
|
|
4038
|
+
const colLabel = formI18n.colLabel;
|
|
3750
4039
|
const [open, setOpen] = React.useState(false);
|
|
3751
4040
|
const selectedDate = watch(colLabel);
|
|
3752
|
-
const
|
|
3753
|
-
|
|
3754
|
-
|
|
4041
|
+
const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
|
|
4042
|
+
React.useEffect(() => {
|
|
4043
|
+
try {
|
|
4044
|
+
if (selectedDate) {
|
|
4045
|
+
// Parse the selectedDate as UTC or in a specific timezone to avoid +8 hour shift
|
|
4046
|
+
// For example, parse as UTC:
|
|
4047
|
+
const parsedDate = dayjs(selectedDate).tz(timezone);
|
|
4048
|
+
if (!parsedDate.isValid())
|
|
4049
|
+
return;
|
|
4050
|
+
// Format according to dateFormat from schema
|
|
4051
|
+
const formatted = parsedDate.format(dateFormat);
|
|
4052
|
+
// Update the form value only if different to avoid loops
|
|
4053
|
+
if (formatted !== selectedDate) {
|
|
4054
|
+
setValue(colLabel, formatted, {
|
|
4055
|
+
shouldValidate: true,
|
|
4056
|
+
shouldDirty: true,
|
|
4057
|
+
});
|
|
4058
|
+
}
|
|
4059
|
+
}
|
|
4060
|
+
}
|
|
4061
|
+
catch (e) {
|
|
4062
|
+
console.error(e);
|
|
4063
|
+
}
|
|
4064
|
+
}, [selectedDate, dateFormat, colLabel, setValue]);
|
|
4065
|
+
return (jsxRuntime.jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: "stretch", gridColumn,
|
|
4066
|
+
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
4067
|
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"));
|
|
4068
|
+
}, 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 }) => {
|
|
4069
|
+
setValue(colLabel, dayjs(date).format(dateFormat));
|
|
3764
4070
|
setOpen(false);
|
|
3765
|
-
}
|
|
4071
|
+
}, labels: {
|
|
4072
|
+
monthNamesShort: [
|
|
4073
|
+
formI18n.translate.t(`common.month_1`, { defaultValue: "January" }),
|
|
4074
|
+
formI18n.translate.t(`common.month_2`, { defaultValue: "February" }),
|
|
4075
|
+
formI18n.translate.t(`common.month_3`, { defaultValue: "March" }),
|
|
4076
|
+
formI18n.translate.t(`common.month_4`, { defaultValue: "April" }),
|
|
4077
|
+
formI18n.translate.t(`common.month_5`, { defaultValue: "May" }),
|
|
4078
|
+
formI18n.translate.t(`common.month_6`, { defaultValue: "June" }),
|
|
4079
|
+
formI18n.translate.t(`common.month_7`, { defaultValue: "July" }),
|
|
4080
|
+
formI18n.translate.t(`common.month_8`, { defaultValue: "August" }),
|
|
4081
|
+
formI18n.translate.t(`common.month_9`, { defaultValue: "September" }),
|
|
4082
|
+
formI18n.translate.t(`common.month_10`, { defaultValue: "October" }),
|
|
4083
|
+
formI18n.translate.t(`common.month_11`, { defaultValue: "November" }),
|
|
4084
|
+
formI18n.translate.t(`common.month_12`, { defaultValue: "December" }),
|
|
4085
|
+
],
|
|
4086
|
+
weekdayNamesShort: [
|
|
4087
|
+
formI18n.translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
|
|
4088
|
+
formI18n.translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
|
|
4089
|
+
formI18n.translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
|
|
4090
|
+
formI18n.translate.t(`common.weekday_4`, {
|
|
4091
|
+
defaultValue: "Wed",
|
|
4092
|
+
}),
|
|
4093
|
+
formI18n.translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
|
|
4094
|
+
formI18n.translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
|
|
4095
|
+
formI18n.translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
|
|
4096
|
+
],
|
|
4097
|
+
backButtonLabel: formI18n.translate.t(`common.back_button`, {
|
|
4098
|
+
defaultValue: "Back",
|
|
4099
|
+
}),
|
|
4100
|
+
forwardButtonLabel: formI18n.translate.t(`common.forward_button`, {
|
|
4101
|
+
defaultValue: "Forward",
|
|
4102
|
+
}),
|
|
4103
|
+
} })] }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: formI18n.required() }))] }));
|
|
3766
4104
|
};
|
|
3767
4105
|
|
|
3768
4106
|
function filterArray(array, searchTerm) {
|
|
@@ -3775,12 +4113,12 @@ function filterArray(array, searchTerm) {
|
|
|
3775
4113
|
});
|
|
3776
4114
|
}
|
|
3777
4115
|
|
|
3778
|
-
const EnumPicker = ({ column, isMultiple = false, schema, prefix, }) => {
|
|
4116
|
+
const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLimit = false, }) => {
|
|
3779
4117
|
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
3780
4118
|
const { translate } = useSchemaContext();
|
|
3781
|
-
const { required } = schema;
|
|
4119
|
+
const { required, variant } = schema;
|
|
3782
4120
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
3783
|
-
const { gridColumn, gridRow, renderDisplay } = schema;
|
|
4121
|
+
const { gridColumn = "span 12", gridRow = "span 1", renderDisplay } = schema;
|
|
3784
4122
|
const [searchText, setSearchText] = React.useState();
|
|
3785
4123
|
const [limit, setLimit] = React.useState(10);
|
|
3786
4124
|
const [openSearchResult, setOpenSearchResult] = React.useState();
|
|
@@ -3795,28 +4133,61 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, }) => {
|
|
|
3795
4133
|
setSearchText(event.target.value);
|
|
3796
4134
|
setLimit(10);
|
|
3797
4135
|
};
|
|
3798
|
-
|
|
4136
|
+
if (variant === "radio") {
|
|
4137
|
+
return (jsxRuntime.jsx(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
4138
|
+
gridRow, children: jsxRuntime.jsx(react.RadioGroup.Root, { defaultValue: "1", children: jsxRuntime.jsx(react.HStack, { gap: "6", children: filterArray(dataList, searchText ?? "").map((item) => {
|
|
4139
|
+
return (jsxRuntime.jsxs(react.RadioGroup.Item, { onClick: () => {
|
|
4140
|
+
if (!isMultiple) {
|
|
4141
|
+
setOpenSearchResult(false);
|
|
4142
|
+
setValue(colLabel, item);
|
|
4143
|
+
return;
|
|
4144
|
+
}
|
|
4145
|
+
const newSet = new Set([...(watchEnums ?? []), item]);
|
|
4146
|
+
setValue(colLabel, [...newSet]);
|
|
4147
|
+
}, value: item, children: [jsxRuntime.jsx(react.RadioGroup.ItemHiddenInput, {}), jsxRuntime.jsx(react.RadioGroup.ItemIndicator, {}), jsxRuntime.jsx(react.RadioGroup.ItemText, { children: !!renderDisplay === true
|
|
4148
|
+
? renderDisplay(item)
|
|
4149
|
+
: translate.t(removeIndex(`${colLabel}.${item}`)) })] }, `${colLabel}-${item}`));
|
|
4150
|
+
}) }) }) }));
|
|
4151
|
+
}
|
|
4152
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
3799
4153
|
gridRow, children: [isMultiple && (jsxRuntime.jsxs(react.Flex, { flexFlow: "wrap", gap: 1, children: [watchEnums.map((enumValue) => {
|
|
3800
4154
|
const item = enumValue;
|
|
3801
|
-
if (item ===
|
|
3802
|
-
return jsxRuntime.jsx(jsxRuntime.Fragment, {
|
|
4155
|
+
if (!!item === false) {
|
|
4156
|
+
return jsxRuntime.jsx(jsxRuntime.Fragment, {});
|
|
3803
4157
|
}
|
|
3804
|
-
return (jsxRuntime.jsx(Tag, { closable: true, onClick: () => {
|
|
3805
|
-
// setSelectedEnums((state) => state.filter((id) => id != item));
|
|
4158
|
+
return (jsxRuntime.jsx(Tag, { size: "lg", closable: true, onClick: () => {
|
|
3806
4159
|
setValue(column, watchEnums.filter((id) => id != item));
|
|
3807
4160
|
}, children: !!renderDisplay === true
|
|
3808
4161
|
? renderDisplay(item)
|
|
3809
|
-
: translate.t(removeIndex(`${colLabel}.${item}`)) }));
|
|
3810
|
-
}), jsxRuntime.jsx(Tag, { cursor: "pointer", onClick: () => {
|
|
4162
|
+
: translate.t(removeIndex(`${colLabel}.${item}`)) }, item));
|
|
4163
|
+
}), jsxRuntime.jsx(Tag, { size: "lg", cursor: "pointer", onClick: () => {
|
|
3811
4164
|
setOpenSearchResult(true);
|
|
3812
|
-
}, children: translate.t(removeIndex(`${colLabel}.
|
|
4165
|
+
}, children: translate.t(removeIndex(`${colLabel}.add_more`)) }, `${colLabel}-add-more-tag`)] })), !isMultiple && (jsxRuntime.jsx(Button, { variant: "outline", onClick: () => {
|
|
3813
4166
|
setOpenSearchResult(true);
|
|
3814
|
-
}, children: watchEnum ===
|
|
4167
|
+
}, justifyContent: "start", children: !!watchEnum === false
|
|
3815
4168
|
? ""
|
|
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(`${
|
|
4169
|
+
: 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
4170
|
onSearchChange(event);
|
|
3818
4171
|
setOpenSearchResult(true);
|
|
3819
|
-
}, autoComplete: "off", ref: ref }), jsxRuntime.jsx(PopoverTitle, {}), jsxRuntime.jsx(react.Text, { children: `${translate.t(`${
|
|
4172
|
+
}, 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
|
|
4173
|
+
.filter((item) => {
|
|
4174
|
+
const searchTerm = (searchText || "").toLowerCase();
|
|
4175
|
+
if (!searchTerm)
|
|
4176
|
+
return true;
|
|
4177
|
+
// Check if the original enum value contains the search text
|
|
4178
|
+
const enumValueMatch = item
|
|
4179
|
+
.toLowerCase()
|
|
4180
|
+
.includes(searchTerm);
|
|
4181
|
+
// Check if the display value (translation) contains the search text
|
|
4182
|
+
const displayValue = !!renderDisplay === true
|
|
4183
|
+
? renderDisplay(item)
|
|
4184
|
+
: translate.t(removeIndex(`${colLabel}.${item}`));
|
|
4185
|
+
// Convert to string and check if it includes the search term
|
|
4186
|
+
const displayValueString = String(displayValue).toLowerCase();
|
|
4187
|
+
const displayValueMatch = displayValueString.includes(searchTerm);
|
|
4188
|
+
return enumValueMatch || displayValueMatch;
|
|
4189
|
+
})
|
|
4190
|
+
.map((item) => {
|
|
3820
4191
|
const selected = isMultiple
|
|
3821
4192
|
? watchEnums.some((enumValue) => item === enumValue)
|
|
3822
4193
|
: watchEnum == item;
|
|
@@ -3828,10 +4199,10 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, }) => {
|
|
|
3828
4199
|
}
|
|
3829
4200
|
const newSet = new Set([...(watchEnums ?? []), item]);
|
|
3830
4201
|
setValue(colLabel, [...newSet]);
|
|
3831
|
-
}, ...(selected ? { color: "
|
|
4202
|
+
}, ...(selected ? { color: "colorPalette.400/50" } : {}), children: !!renderDisplay === true
|
|
3832
4203
|
? renderDisplay(item)
|
|
3833
4204
|
: 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}.
|
|
4205
|
+
}) }), 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
4206
|
};
|
|
3836
4207
|
|
|
3837
4208
|
function isEnteringWindow(_ref) {
|
|
@@ -4183,17 +4554,17 @@ const FileDropzone = ({ children = undefined, gridProps = {}, onDrop = () => { }
|
|
|
4183
4554
|
const filesArray = [...event.target.files];
|
|
4184
4555
|
onDrop({ files: filesArray });
|
|
4185
4556
|
};
|
|
4186
|
-
return (jsxRuntime.jsxs(react.Grid, { ...getColor(isDraggedOver), ref: ref, cursor: "pointer", onClick: handleClick, borderStyle: "dashed", borderColor: "
|
|
4557
|
+
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
4558
|
};
|
|
4188
4559
|
|
|
4189
4560
|
const FilePicker = ({ column, schema, prefix }) => {
|
|
4190
4561
|
const { setValue, formState: { errors }, watch, } = reactHookForm.useFormContext();
|
|
4191
4562
|
const { translate } = useSchemaContext();
|
|
4192
|
-
const { required, gridColumn, gridRow } = schema;
|
|
4563
|
+
const { required, gridColumn = "span 12", gridRow = "span 1", } = schema;
|
|
4193
4564
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4194
4565
|
const currentFiles = (watch(column) ?? []);
|
|
4195
4566
|
const colLabel = `${prefix}${column}`;
|
|
4196
|
-
return (jsxRuntime.jsxs(Field, { label: `${translate.t(`${colLabel}.
|
|
4567
|
+
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
4568
|
const newFiles = files.filter(({ name }) => !currentFiles.some((cur) => cur.name === name));
|
|
4198
4569
|
setValue(colLabel, [...currentFiles, ...newFiles]);
|
|
4199
4570
|
}, placeholder: translate.t(removeIndex(`${colLabel}.fileDropzone`)) }), jsxRuntime.jsx(react.Flex, { flexFlow: "column", gap: 1, children: currentFiles.map((file) => {
|
|
@@ -4201,10 +4572,19 @@ const FilePicker = ({ column, schema, prefix }) => {
|
|
|
4201
4572
|
setValue(column, currentFiles.filter(({ name }) => {
|
|
4202
4573
|
return name !== file.name;
|
|
4203
4574
|
}));
|
|
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}.
|
|
4575
|
+
}, 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));
|
|
4576
|
+
}) }), errors[`${colLabel}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4206
4577
|
};
|
|
4207
4578
|
|
|
4579
|
+
const ToggleTip = React__namespace.forwardRef(function ToggleTip(props, ref) {
|
|
4580
|
+
const { showArrow, children, portalled = true, content, portalRef, ...rest } = props;
|
|
4581
|
+
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] }) }) })] }));
|
|
4582
|
+
});
|
|
4583
|
+
const InfoTip = React__namespace.forwardRef(function InfoTip(props, ref) {
|
|
4584
|
+
const { children, ...rest } = props;
|
|
4585
|
+
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, {}) }) }));
|
|
4586
|
+
});
|
|
4587
|
+
|
|
4208
4588
|
const getTableData = async ({ serverUrl, in_table, searching = "", where = [], limit = 10, offset = 0, }) => {
|
|
4209
4589
|
if (serverUrl === undefined || serverUrl.length == 0) {
|
|
4210
4590
|
throw new Error("The serverUrl is missing");
|
|
@@ -4235,25 +4615,40 @@ const getTableData = async ({ serverUrl, in_table, searching = "", where = [], l
|
|
|
4235
4615
|
|
|
4236
4616
|
const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
4237
4617
|
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
4238
|
-
const { serverUrl, idMap, setIdMap,
|
|
4239
|
-
const
|
|
4618
|
+
const { serverUrl, idMap, setIdMap, schema: parentSchema, } = useSchemaContext();
|
|
4619
|
+
const formI18n = useFormI18n(column, prefix);
|
|
4620
|
+
const { required, gridColumn = "span 12", gridRow = "span 1", renderDisplay, foreign_key, } = schema;
|
|
4240
4621
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4241
|
-
const { table, column: column_ref, display_column, } = foreign_key;
|
|
4242
|
-
const [searchText, setSearchText] = React.useState();
|
|
4622
|
+
const { table, column: column_ref, display_column, customQueryFn, } = foreign_key;
|
|
4623
|
+
const [searchText, setSearchText] = React.useState("");
|
|
4243
4624
|
const [limit, setLimit] = React.useState(10);
|
|
4244
4625
|
const [openSearchResult, setOpenSearchResult] = React.useState();
|
|
4245
4626
|
const [page, setPage] = React.useState(0);
|
|
4246
4627
|
const ref = React.useRef(null);
|
|
4247
|
-
const colLabel =
|
|
4628
|
+
const colLabel = formI18n.colLabel;
|
|
4629
|
+
const watchId = watch(colLabel);
|
|
4630
|
+
const watchIds = isMultiple ? (watch(colLabel) ?? []) : [];
|
|
4631
|
+
// Query for search results
|
|
4248
4632
|
const query = reactQuery.useQuery({
|
|
4249
4633
|
queryKey: [`idpicker`, { column, searchText, limit, page }],
|
|
4250
4634
|
queryFn: async () => {
|
|
4635
|
+
if (customQueryFn) {
|
|
4636
|
+
const { data, idMap } = await customQueryFn({
|
|
4637
|
+
searching: searchText ?? "",
|
|
4638
|
+
limit: limit,
|
|
4639
|
+
offset: page * limit,
|
|
4640
|
+
});
|
|
4641
|
+
setIdMap((state) => {
|
|
4642
|
+
return { ...state, ...idMap };
|
|
4643
|
+
});
|
|
4644
|
+
return data;
|
|
4645
|
+
}
|
|
4251
4646
|
const data = await getTableData({
|
|
4252
4647
|
serverUrl,
|
|
4253
4648
|
searching: searchText ?? "",
|
|
4254
4649
|
in_table: table,
|
|
4255
4650
|
limit: limit,
|
|
4256
|
-
offset: page *
|
|
4651
|
+
offset: page * limit,
|
|
4257
4652
|
});
|
|
4258
4653
|
const newMap = Object.fromEntries((data ?? { data: [] }).data.map((item) => {
|
|
4259
4654
|
return [
|
|
@@ -4268,27 +4663,38 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4268
4663
|
});
|
|
4269
4664
|
return data;
|
|
4270
4665
|
},
|
|
4271
|
-
enabled:
|
|
4666
|
+
enabled: openSearchResult === true,
|
|
4272
4667
|
staleTime: 300000,
|
|
4273
4668
|
});
|
|
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({
|
|
4669
|
+
// Query for currently selected items (to display them properly)
|
|
4670
|
+
const queryDefault = reactQuery.useQuery({
|
|
4281
4671
|
queryKey: [
|
|
4282
|
-
`idpicker`,
|
|
4283
|
-
{ form: parentSchema.title, column,
|
|
4672
|
+
`idpicker-default`,
|
|
4673
|
+
{ form: parentSchema.title, column, id: isMultiple ? watchIds : watchId },
|
|
4284
4674
|
],
|
|
4285
4675
|
queryFn: async () => {
|
|
4676
|
+
if (customQueryFn) {
|
|
4677
|
+
const { data, idMap } = await customQueryFn({
|
|
4678
|
+
searching: watchIds.join(","),
|
|
4679
|
+
limit: isMultiple ? watchIds.length : 1,
|
|
4680
|
+
offset: 0,
|
|
4681
|
+
});
|
|
4682
|
+
setIdMap((state) => {
|
|
4683
|
+
return { ...state, ...idMap };
|
|
4684
|
+
});
|
|
4685
|
+
return data;
|
|
4686
|
+
}
|
|
4687
|
+
if (!watchId && (!watchIds || watchIds.length === 0)) {
|
|
4688
|
+
return { data: [] };
|
|
4689
|
+
}
|
|
4690
|
+
const searchValue = isMultiple ? watchIds.join(",") : watchId;
|
|
4286
4691
|
const data = await getTableData({
|
|
4287
4692
|
serverUrl,
|
|
4288
|
-
searching:
|
|
4693
|
+
searching: searchValue,
|
|
4289
4694
|
in_table: table,
|
|
4290
|
-
|
|
4291
|
-
|
|
4695
|
+
where: [{ id: column_ref, value: isMultiple ? watchIds : watchId }],
|
|
4696
|
+
limit: isMultiple ? watchIds.length : 1,
|
|
4697
|
+
offset: 0,
|
|
4292
4698
|
});
|
|
4293
4699
|
const newMap = Object.fromEntries((data ?? { data: [] }).data.map((item) => {
|
|
4294
4700
|
return [
|
|
@@ -4303,12 +4709,45 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4303
4709
|
});
|
|
4304
4710
|
return data;
|
|
4305
4711
|
},
|
|
4712
|
+
enabled: isMultiple
|
|
4713
|
+
? Array.isArray(watchIds) && watchIds.length > 0
|
|
4714
|
+
: !!watchId,
|
|
4306
4715
|
});
|
|
4716
|
+
// Effect to load selected values when component mounts
|
|
4717
|
+
React.useEffect(() => {
|
|
4718
|
+
if (isMultiple ? watchIds.length > 0 : !!watchId) {
|
|
4719
|
+
queryDefault.refetch();
|
|
4720
|
+
}
|
|
4721
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4722
|
+
}, []);
|
|
4723
|
+
// Effect to trigger initial data fetch when popover opens
|
|
4724
|
+
React.useEffect(() => {
|
|
4725
|
+
if (openSearchResult) {
|
|
4726
|
+
// Reset search text when opening the popover
|
|
4727
|
+
setSearchText("");
|
|
4728
|
+
// Reset page to first page
|
|
4729
|
+
setPage(0);
|
|
4730
|
+
// Fetch initial data
|
|
4731
|
+
query.refetch();
|
|
4732
|
+
}
|
|
4733
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4734
|
+
}, [openSearchResult]);
|
|
4307
4735
|
const onSearchChange = async (event) => {
|
|
4308
4736
|
setSearchText(event.target.value);
|
|
4309
4737
|
setPage(0);
|
|
4310
|
-
|
|
4738
|
+
query.refetch();
|
|
4739
|
+
};
|
|
4740
|
+
const handleLimitChange = (event) => {
|
|
4741
|
+
const newLimit = Number(event.target.value);
|
|
4742
|
+
setLimit(newLimit);
|
|
4743
|
+
// Reset to first page when changing limit
|
|
4744
|
+
setPage(0);
|
|
4745
|
+
// Trigger a new search with the updated limit
|
|
4746
|
+
query.refetch();
|
|
4311
4747
|
};
|
|
4748
|
+
const { isLoading, isFetching, data, isPending, isError } = query;
|
|
4749
|
+
const dataList = data?.data ?? [];
|
|
4750
|
+
const count = data?.count ?? 0;
|
|
4312
4751
|
const getPickedValue = () => {
|
|
4313
4752
|
if (Object.keys(idMap).length <= 0) {
|
|
4314
4753
|
return "";
|
|
@@ -4317,52 +4756,67 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4317
4756
|
if (record === undefined) {
|
|
4318
4757
|
return "";
|
|
4319
4758
|
}
|
|
4759
|
+
if (!!renderDisplay === true) {
|
|
4760
|
+
return renderDisplay(record);
|
|
4761
|
+
}
|
|
4320
4762
|
return record[display_column];
|
|
4321
4763
|
};
|
|
4322
|
-
return (jsxRuntime.jsxs(Field, { label:
|
|
4764
|
+
return (jsxRuntime.jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: "stretch", gridColumn,
|
|
4323
4765
|
gridRow, children: [isMultiple && (jsxRuntime.jsxs(react.Flex, { flexFlow: "wrap", gap: 1, children: [watchIds.map((id) => {
|
|
4324
4766
|
const item = idMap[id];
|
|
4325
4767
|
if (item === undefined) {
|
|
4326
|
-
return (jsxRuntime.jsx(react.Text, { children:
|
|
4768
|
+
return (jsxRuntime.jsx(react.Text, { children: formI18n.t('undefined') }, id));
|
|
4327
4769
|
}
|
|
4328
4770
|
return (jsxRuntime.jsx(Tag, { closable: true, onClick: () => {
|
|
4329
|
-
setValue(
|
|
4771
|
+
setValue(colLabel, watchIds.filter((itemId) => itemId !== item[column_ref]));
|
|
4330
4772
|
}, children: !!renderDisplay === true
|
|
4331
4773
|
? renderDisplay(item)
|
|
4332
4774
|
: item[display_column] }, id));
|
|
4333
4775
|
}), jsxRuntime.jsx(Tag, { cursor: "pointer", onClick: () => {
|
|
4334
4776
|
setOpenSearchResult(true);
|
|
4335
|
-
}, children:
|
|
4777
|
+
}, children: formI18n.t('add_more') })] })), !isMultiple && (jsxRuntime.jsx(Button, { variant: "outline", onClick: () => {
|
|
4336
4778
|
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:
|
|
4338
|
-
|
|
4339
|
-
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
|
|
4355
|
-
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
|
|
4779
|
+
}, 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: formI18n.t('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: `${formI18n.t('total')} ${count}, ${formI18n.t('showing')} ${limit} ${formI18n.t('per_page', { defaultValue: '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
|
|
4780
|
+
? `${page * limit + 1}-${Math.min((page + 1) * limit, count)}`
|
|
4781
|
+
: "0"] })] })] }), jsxRuntime.jsx(react.Box, { children: jsxRuntime.jsxs("select", { value: limit, onChange: handleLimitChange, style: {
|
|
4782
|
+
padding: "4px 8px",
|
|
4783
|
+
borderRadius: "4px",
|
|
4784
|
+
border: "1px solid #ccc",
|
|
4785
|
+
fontSize: "14px",
|
|
4786
|
+
}, 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) => {
|
|
4787
|
+
const selected = isMultiple
|
|
4788
|
+
? watchIds.some((id) => item[column_ref] === id)
|
|
4789
|
+
: watchId === item[column_ref];
|
|
4790
|
+
return (jsxRuntime.jsx(react.Box, { cursor: "pointer", onClick: () => {
|
|
4791
|
+
if (!isMultiple) {
|
|
4792
|
+
setOpenSearchResult(false);
|
|
4793
|
+
setValue(colLabel, item[column_ref]);
|
|
4794
|
+
return;
|
|
4795
|
+
}
|
|
4796
|
+
// For multiple selection, don't add if already selected
|
|
4797
|
+
if (selected)
|
|
4798
|
+
return;
|
|
4799
|
+
const newSet = new Set([
|
|
4800
|
+
...(watchIds ?? []),
|
|
4801
|
+
item[column_ref],
|
|
4802
|
+
]);
|
|
4803
|
+
setValue(colLabel, [...newSet]);
|
|
4804
|
+
}, opacity: 0.7, _hover: { opacity: 1 }, ...(selected
|
|
4805
|
+
? {
|
|
4806
|
+
color: "colorPalette.400/50",
|
|
4807
|
+
fontWeight: "bold",
|
|
4808
|
+
}
|
|
4809
|
+
: {}), children: !!renderDisplay === true
|
|
4810
|
+
? renderDisplay(item)
|
|
4811
|
+
: item[display_column] }, item[column_ref]));
|
|
4812
|
+
}) })) : (jsxRuntime.jsx(react.Text, { children: searchText
|
|
4813
|
+
? formI18n.t('empty_search_result')
|
|
4814
|
+
: formI18n.t('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: formI18n.required() }))] }));
|
|
4361
4815
|
};
|
|
4362
4816
|
|
|
4363
4817
|
const NumberInputRoot = React__namespace.forwardRef(function NumberInput(props, ref) {
|
|
4364
4818
|
const { children, ...rest } = props;
|
|
4365
|
-
return (jsxRuntime.
|
|
4819
|
+
return (jsxRuntime.jsx(react.NumberInput.Root, { ref: ref, variant: "outline", ...rest, children: children }));
|
|
4366
4820
|
});
|
|
4367
4821
|
const NumberInputField$1 = react.NumberInput.Input;
|
|
4368
4822
|
react.NumberInput.Scrubber;
|
|
@@ -4371,17 +4825,17 @@ react.NumberInput.Label;
|
|
|
4371
4825
|
const NumberInputField = ({ schema, column, prefix, }) => {
|
|
4372
4826
|
const { setValue, formState: { errors }, watch, } = reactHookForm.useFormContext();
|
|
4373
4827
|
const { translate } = useSchemaContext();
|
|
4374
|
-
const { required, gridColumn, gridRow } = schema;
|
|
4828
|
+
const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
|
|
4375
4829
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4376
4830
|
const colLabel = `${prefix}${column}`;
|
|
4377
4831
|
const value = watch(`${colLabel}`);
|
|
4378
|
-
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.
|
|
4832
|
+
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
4833
|
setValue(`${colLabel}`, Number(event.target.value));
|
|
4380
|
-
} }) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.
|
|
4834
|
+
} }) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4381
4835
|
};
|
|
4382
4836
|
|
|
4383
4837
|
const ObjectInput = ({ schema, column, prefix }) => {
|
|
4384
|
-
const { properties,
|
|
4838
|
+
const { properties, gridColumn = "span 12", gridRow = "span 1", required, showLabel = true, } = schema;
|
|
4385
4839
|
const { translate } = useSchemaContext();
|
|
4386
4840
|
const colLabel = `${prefix}${column}`;
|
|
4387
4841
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
@@ -4389,25 +4843,28 @@ const ObjectInput = ({ schema, column, prefix }) => {
|
|
|
4389
4843
|
if (properties === undefined) {
|
|
4390
4844
|
throw new Error(`properties is undefined when using ObjectInput`);
|
|
4391
4845
|
}
|
|
4392
|
-
return (jsxRuntime.jsxs(react.Box, { gridRow, gridColumn, children: [jsxRuntime.jsxs(react.Box, { as: "label",
|
|
4846
|
+
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: {
|
|
4847
|
+
base: "colorPalette.200",
|
|
4848
|
+
_dark: "colorPalette.800",
|
|
4849
|
+
}, gap: "4", padding: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: Object.keys(properties ?? {}).map((key) => {
|
|
4393
4850
|
return (
|
|
4394
4851
|
// @ts-expect-error find suitable types
|
|
4395
4852
|
jsxRuntime.jsx(ColumnRenderer, { column: `${key}`,
|
|
4396
4853
|
prefix: `${prefix}${column}.`,
|
|
4397
4854
|
properties }, `form-${colLabel}-${key}`));
|
|
4398
|
-
}) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.
|
|
4855
|
+
}) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4399
4856
|
};
|
|
4400
4857
|
|
|
4401
4858
|
const RecordInput$1 = ({ column, schema, prefix }) => {
|
|
4402
4859
|
const { formState: { errors }, setValue, getValues, } = reactHookForm.useFormContext();
|
|
4403
4860
|
const { translate } = useSchemaContext();
|
|
4404
|
-
const { required, gridColumn, gridRow } = schema;
|
|
4861
|
+
const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
|
|
4405
4862
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4406
4863
|
const entries = Object.entries(getValues(column) ?? {});
|
|
4407
4864
|
const [showNewEntries, setShowNewEntries] = React.useState(false);
|
|
4408
4865
|
const [newKey, setNewKey] = React.useState();
|
|
4409
4866
|
const [newValue, setNewValue] = React.useState();
|
|
4410
|
-
return (jsxRuntime.jsxs(Field, { label: `${translate.t(`${column}.
|
|
4867
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(`${column}.field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn, gridRow, children: [entries.map(([key, value]) => {
|
|
4411
4868
|
return (jsxRuntime.jsxs(react.Grid, { templateColumns: "1fr 1fr auto", gap: 1, children: [jsxRuntime.jsx(react.Input, { value: key, onChange: (e) => {
|
|
4412
4869
|
const filtered = entries.filter(([target]) => {
|
|
4413
4870
|
return target !== key;
|
|
@@ -4447,16 +4904,16 @@ const RecordInput$1 = ({ column, schema, prefix }) => {
|
|
|
4447
4904
|
setShowNewEntries(true);
|
|
4448
4905
|
setNewKey(undefined);
|
|
4449
4906
|
setNewValue(undefined);
|
|
4450
|
-
}, children: translate.t(`${column}.addNew`) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(`${column}.
|
|
4907
|
+
}, children: translate.t(`${column}.addNew`) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
|
|
4451
4908
|
};
|
|
4452
4909
|
|
|
4453
4910
|
const StringInputField = ({ column, schema, prefix, }) => {
|
|
4454
4911
|
const { register, formState: { errors }, } = reactHookForm.useFormContext();
|
|
4455
4912
|
const { translate } = useSchemaContext();
|
|
4456
|
-
const { required, gridColumn, gridRow } = schema;
|
|
4913
|
+
const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
|
|
4457
4914
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4458
4915
|
const colLabel = `${prefix}${column}`;
|
|
4459
|
-
return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.
|
|
4916
|
+
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
4917
|
};
|
|
4461
4918
|
|
|
4462
4919
|
const RadioCardItem = React__namespace.forwardRef(function RadioCardItem(props, ref) {
|
|
@@ -4554,9 +5011,574 @@ const TagPicker = ({ column, schema, prefix }) => {
|
|
|
4554
5011
|
}), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: (errors[`${column}`]?.message ?? "No error message") }))] }));
|
|
4555
5012
|
};
|
|
4556
5013
|
|
|
5014
|
+
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) => {
|
|
5015
|
+
const contentEditableRef = React.useRef(null);
|
|
5016
|
+
const isControlled = value !== undefined;
|
|
5017
|
+
// Handle input changes
|
|
5018
|
+
const handleInput = (e) => {
|
|
5019
|
+
const text = e.currentTarget.textContent || "";
|
|
5020
|
+
// Check maxLength if specified
|
|
5021
|
+
if (maxLength && text.length > maxLength) {
|
|
5022
|
+
e.currentTarget.textContent = text.slice(0, maxLength);
|
|
5023
|
+
// Move cursor to end
|
|
5024
|
+
const selection = window.getSelection();
|
|
5025
|
+
if (selection) {
|
|
5026
|
+
selection.selectAllChildren(e.currentTarget);
|
|
5027
|
+
selection.collapseToEnd();
|
|
5028
|
+
}
|
|
5029
|
+
return;
|
|
5030
|
+
}
|
|
5031
|
+
onChange?.(text);
|
|
5032
|
+
};
|
|
5033
|
+
// Handle paste events to strip formatting and respect maxLength
|
|
5034
|
+
const handlePaste = (e) => {
|
|
5035
|
+
e.preventDefault();
|
|
5036
|
+
const text = e.clipboardData.getData('text/plain');
|
|
5037
|
+
const currentText = e.currentTarget.textContent || "";
|
|
5038
|
+
let pasteText = text;
|
|
5039
|
+
if (maxLength) {
|
|
5040
|
+
const remainingLength = maxLength - currentText.length;
|
|
5041
|
+
pasteText = text.slice(0, remainingLength);
|
|
5042
|
+
}
|
|
5043
|
+
document.execCommand('insertText', false, pasteText);
|
|
5044
|
+
};
|
|
5045
|
+
// Set initial content
|
|
5046
|
+
React.useEffect(() => {
|
|
5047
|
+
if (contentEditableRef.current && !isControlled) {
|
|
5048
|
+
const initialValue = defaultValue || "";
|
|
5049
|
+
if (contentEditableRef.current.textContent !== initialValue) {
|
|
5050
|
+
contentEditableRef.current.textContent = initialValue;
|
|
5051
|
+
}
|
|
5052
|
+
}
|
|
5053
|
+
}, [defaultValue, isControlled]);
|
|
5054
|
+
// Update content when value changes (controlled mode)
|
|
5055
|
+
React.useEffect(() => {
|
|
5056
|
+
if (contentEditableRef.current && isControlled && value !== undefined) {
|
|
5057
|
+
if (contentEditableRef.current.textContent !== value) {
|
|
5058
|
+
contentEditableRef.current.textContent = value;
|
|
5059
|
+
}
|
|
5060
|
+
}
|
|
5061
|
+
}, [value, isControlled]);
|
|
5062
|
+
// Auto focus
|
|
5063
|
+
React.useEffect(() => {
|
|
5064
|
+
if (autoFocus && contentEditableRef.current) {
|
|
5065
|
+
contentEditableRef.current.focus();
|
|
5066
|
+
}
|
|
5067
|
+
}, [autoFocus]);
|
|
5068
|
+
// Forward ref
|
|
5069
|
+
React.useEffect(() => {
|
|
5070
|
+
if (typeof ref === 'function') {
|
|
5071
|
+
ref(contentEditableRef.current);
|
|
5072
|
+
}
|
|
5073
|
+
else if (ref) {
|
|
5074
|
+
ref.current = contentEditableRef.current;
|
|
5075
|
+
}
|
|
5076
|
+
}, [ref]);
|
|
5077
|
+
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: {
|
|
5078
|
+
borderColor: invalid ? "red.500" : "blue.500",
|
|
5079
|
+
boxShadow: `0 0 0 1px ${invalid ? "red.500" : "blue.500"}`,
|
|
5080
|
+
}, _disabled: {
|
|
5081
|
+
opacity: 0.6,
|
|
5082
|
+
cursor: "not-allowed",
|
|
5083
|
+
bg: "gray.50",
|
|
5084
|
+
}, _empty: {
|
|
5085
|
+
_before: {
|
|
5086
|
+
content: placeholder ? `"${placeholder}"` : undefined,
|
|
5087
|
+
color: "gray.400",
|
|
5088
|
+
pointerEvents: "none",
|
|
5089
|
+
}
|
|
5090
|
+
}, whiteSpace: "pre-wrap", overflowWrap: "break-word", overflow: "auto", maxHeight: `${rows * 4}em`, suppressContentEditableWarning: true, ...props }));
|
|
5091
|
+
// If we have additional field props, wrap in Field component
|
|
5092
|
+
if (label || helperText || errorText || required) {
|
|
5093
|
+
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 })] }));
|
|
5094
|
+
}
|
|
5095
|
+
return textareaElement;
|
|
5096
|
+
});
|
|
5097
|
+
Textarea.displayName = "Textarea";
|
|
5098
|
+
|
|
5099
|
+
const TextAreaInput = ({ column, schema, prefix, }) => {
|
|
5100
|
+
const { register, formState: { errors }, } = reactHookForm.useFormContext();
|
|
5101
|
+
const { translate } = useSchemaContext();
|
|
5102
|
+
const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
|
|
5103
|
+
const isRequired = required?.some((columnId) => columnId === column);
|
|
5104
|
+
const colLabel = `${prefix}${column}`;
|
|
5105
|
+
const form = reactHookForm.useFormContext();
|
|
5106
|
+
const { setValue, watch } = form;
|
|
5107
|
+
const watchValue = watch(colLabel);
|
|
5108
|
+
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`)) }))] }) }));
|
|
5109
|
+
};
|
|
5110
|
+
|
|
5111
|
+
function TimePicker$1({ hour, setHour, minute, setMinute, meridiem, setMeridiem, meridiemLabel = {
|
|
5112
|
+
am: "am",
|
|
5113
|
+
pm: "pm",
|
|
5114
|
+
}, onChange = (_newValue) => { }, timezone = "Asia/Hong_Kong", }) {
|
|
5115
|
+
const handleClear = () => {
|
|
5116
|
+
setHour(null);
|
|
5117
|
+
setMinute(null);
|
|
5118
|
+
setMeridiem(null);
|
|
5119
|
+
setInputValue("");
|
|
5120
|
+
setShowInput(false);
|
|
5121
|
+
onChange({ hour: null, minute: null, meridiem: null });
|
|
5122
|
+
};
|
|
5123
|
+
const getTimeString = (hour, minute, meridiem) => {
|
|
5124
|
+
if (hour === null || minute === null || meridiem === null) {
|
|
5125
|
+
return "";
|
|
5126
|
+
}
|
|
5127
|
+
// if the hour is 24, set the hour to 0
|
|
5128
|
+
if (hour === 24) {
|
|
5129
|
+
return dayjs().tz(timezone).hour(0).minute(minute).format("HH:mmZ");
|
|
5130
|
+
}
|
|
5131
|
+
// use dayjs to format the time at current timezone
|
|
5132
|
+
// if meridiem is pm, add 12 hours
|
|
5133
|
+
let newHour = hour;
|
|
5134
|
+
if (meridiem === "pm" && hour !== 12) {
|
|
5135
|
+
newHour = hour + 12;
|
|
5136
|
+
}
|
|
5137
|
+
// if the hour is 12, set the meridiem to am, and set the hour to 0
|
|
5138
|
+
else if (meridiem === "am" && hour === 12) {
|
|
5139
|
+
newHour = 0;
|
|
5140
|
+
}
|
|
5141
|
+
return dayjs().tz(timezone).hour(newHour).minute(minute).format("HH:mmZ");
|
|
5142
|
+
};
|
|
5143
|
+
const stringTime = getTimeString(hour, minute, meridiem);
|
|
5144
|
+
const [inputValue, setInputValue] = React.useState("");
|
|
5145
|
+
const [showInput, setShowInput] = React.useState(false);
|
|
5146
|
+
const handleBlur = (text) => {
|
|
5147
|
+
// ignore all non-numeric characters
|
|
5148
|
+
if (!text) {
|
|
5149
|
+
return;
|
|
5150
|
+
}
|
|
5151
|
+
const value = text.replace(/[^0-9apm]/g, "");
|
|
5152
|
+
if (value === "") {
|
|
5153
|
+
handleClear();
|
|
5154
|
+
return;
|
|
5155
|
+
}
|
|
5156
|
+
// if the value is a valid time, parse it and set the hour, minute, and meridiem
|
|
5157
|
+
// if the value is not a valid time, set the stringTime to the value
|
|
5158
|
+
// first two characters are the hour
|
|
5159
|
+
// next two characters are the minute
|
|
5160
|
+
// final two characters are the meridiem
|
|
5161
|
+
const hour = parseInt(value.slice(0, 2));
|
|
5162
|
+
const minute = parseInt(value.slice(2, 4));
|
|
5163
|
+
const meridiem = value.slice(4, 6);
|
|
5164
|
+
// validate the hour and minute
|
|
5165
|
+
if (isNaN(hour) || isNaN(minute)) {
|
|
5166
|
+
setInputValue("");
|
|
5167
|
+
return;
|
|
5168
|
+
}
|
|
5169
|
+
// if the hour is larger than 24, set the hour to 24
|
|
5170
|
+
if (hour > 24) {
|
|
5171
|
+
setInputValue("");
|
|
5172
|
+
return;
|
|
5173
|
+
}
|
|
5174
|
+
let newHour = hour;
|
|
5175
|
+
let newMinute = minute;
|
|
5176
|
+
let newMeridiem = meridiem;
|
|
5177
|
+
// if the hour is 24, set the meridiem to am, and set the hour to 0
|
|
5178
|
+
if (hour === 24) {
|
|
5179
|
+
newMeridiem = "am";
|
|
5180
|
+
newHour = 0;
|
|
5181
|
+
}
|
|
5182
|
+
// if the hour is greater than 12, set the meridiem to pm, and subtract 12 from the hour
|
|
5183
|
+
else if (hour > 12) {
|
|
5184
|
+
newMeridiem = "pm";
|
|
5185
|
+
newHour = hour - 12;
|
|
5186
|
+
}
|
|
5187
|
+
// if the hour is 12, set the meridiem to pm, and set the hour to 12
|
|
5188
|
+
else if (hour === 12) {
|
|
5189
|
+
newMeridiem = "pm";
|
|
5190
|
+
newHour = 12;
|
|
5191
|
+
}
|
|
5192
|
+
// if the hour is 0, set the meridiem to am, and set the hour to 12
|
|
5193
|
+
else if (hour === 0) {
|
|
5194
|
+
newMeridiem = "am";
|
|
5195
|
+
newHour = 12;
|
|
5196
|
+
}
|
|
5197
|
+
else {
|
|
5198
|
+
newMeridiem = meridiem ?? "am";
|
|
5199
|
+
newHour = hour;
|
|
5200
|
+
}
|
|
5201
|
+
if (minute > 59) {
|
|
5202
|
+
newMinute = 0;
|
|
5203
|
+
}
|
|
5204
|
+
else {
|
|
5205
|
+
newMinute = minute;
|
|
5206
|
+
}
|
|
5207
|
+
onChange({
|
|
5208
|
+
hour: newHour,
|
|
5209
|
+
minute: newMinute,
|
|
5210
|
+
meridiem: newMeridiem,
|
|
5211
|
+
});
|
|
5212
|
+
setShowInput(false);
|
|
5213
|
+
};
|
|
5214
|
+
const handleKeyDown = (e) => {
|
|
5215
|
+
if (e.key === "Enter") {
|
|
5216
|
+
handleBlur(e.currentTarget.value);
|
|
5217
|
+
}
|
|
5218
|
+
};
|
|
5219
|
+
const inputRef = React.useRef(null);
|
|
5220
|
+
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) => {
|
|
5221
|
+
setInputValue(e.currentTarget.value);
|
|
5222
|
+
}, onBlur: (e) => {
|
|
5223
|
+
handleBlur(e.currentTarget.value);
|
|
5224
|
+
}, onFocus: (e) => {
|
|
5225
|
+
e.currentTarget.select();
|
|
5226
|
+
}, value: inputValue, display: showInput ? undefined : "none", ref: inputRef }), jsxRuntime.jsxs(react.Button, { onClick: () => {
|
|
5227
|
+
setShowInput(true);
|
|
5228
|
+
setInputValue(dayjs(`1970-01-01T${getTimeString(hour, minute, meridiem)}`, "hh:mmZ").format("HH:mm"));
|
|
5229
|
+
inputRef.current?.focus();
|
|
5230
|
+
}, 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
|
|
5231
|
+
? dayjs(`1970-01-01T${stringTime}`, "hh:mmZ").format("hh:mm a")
|
|
5232
|
+
: "" })] }), jsxRuntime.jsx(react.Button, { onClick: handleClear, size: "sm", variant: "ghost", children: jsxRuntime.jsx(md.MdCancel, {}) })] }));
|
|
5233
|
+
}
|
|
5234
|
+
|
|
5235
|
+
dayjs.extend(timezone);
|
|
5236
|
+
const TimePicker = ({ column, schema, prefix }) => {
|
|
5237
|
+
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
5238
|
+
const { translate, timezone } = useSchemaContext();
|
|
5239
|
+
const { required, gridColumn = "span 12", gridRow = "span 1", timeFormat = "HH:mm:ssZ", displayTimeFormat = "hh:mm A", } = schema;
|
|
5240
|
+
const isRequired = required?.some((columnId) => columnId === column);
|
|
5241
|
+
const colLabel = `${prefix}${column}`;
|
|
5242
|
+
const [open, setOpen] = React.useState(false);
|
|
5243
|
+
const value = watch(colLabel);
|
|
5244
|
+
const displayedTime = dayjs(`1970-01-01T${value}`).tz(timezone).isValid()
|
|
5245
|
+
? dayjs(`1970-01-01T${value}`).tz(timezone).format(displayTimeFormat)
|
|
5246
|
+
: "";
|
|
5247
|
+
// Parse the initial time parts from the time string (HH:mm:ssZ)
|
|
5248
|
+
const parseTime = (time) => {
|
|
5249
|
+
if (!time)
|
|
5250
|
+
return { hour: 12, minute: 0, meridiem: "am" };
|
|
5251
|
+
const parsed = dayjs(`1970-01-01T${time}`).tz(timezone);
|
|
5252
|
+
if (!parsed.isValid()) {
|
|
5253
|
+
return { hour: 12, minute: 0, meridiem: "am" };
|
|
5254
|
+
}
|
|
5255
|
+
let hour = parsed.hour();
|
|
5256
|
+
const minute = parsed.minute();
|
|
5257
|
+
const meridiem = hour >= 12 ? "pm" : "am";
|
|
5258
|
+
if (hour === 0)
|
|
5259
|
+
hour = 12;
|
|
5260
|
+
else if (hour > 12)
|
|
5261
|
+
hour -= 12;
|
|
5262
|
+
return { hour, minute, meridiem };
|
|
5263
|
+
};
|
|
5264
|
+
const initialTime = parseTime(value);
|
|
5265
|
+
const [hour, setHour] = React.useState(initialTime.hour);
|
|
5266
|
+
const [minute, setMinute] = React.useState(initialTime.minute);
|
|
5267
|
+
const [meridiem, setMeridiem] = React.useState(initialTime.meridiem);
|
|
5268
|
+
React.useEffect(() => {
|
|
5269
|
+
const { hour, minute, meridiem } = parseTime(value);
|
|
5270
|
+
setHour(hour);
|
|
5271
|
+
setMinute(minute);
|
|
5272
|
+
setMeridiem(meridiem);
|
|
5273
|
+
}, [value]);
|
|
5274
|
+
const getTimeString = (hour, minute, meridiem) => {
|
|
5275
|
+
if (hour === null || minute === null || meridiem === null)
|
|
5276
|
+
return null;
|
|
5277
|
+
let newHour = hour;
|
|
5278
|
+
if (meridiem === "pm" && hour !== 12) {
|
|
5279
|
+
newHour = hour + 12;
|
|
5280
|
+
}
|
|
5281
|
+
return dayjs().tz(timezone).hour(newHour).minute(minute).second(0).format(timeFormat);
|
|
5282
|
+
};
|
|
5283
|
+
// Handle changes to time parts
|
|
5284
|
+
const handleTimeChange = ({ hour: newHour, minute: newMinute, meridiem: newMeridiem, }) => {
|
|
5285
|
+
setHour(newHour);
|
|
5286
|
+
setMinute(newMinute);
|
|
5287
|
+
setMeridiem(newMeridiem);
|
|
5288
|
+
const timeString = getTimeString(newHour, newMinute, newMeridiem);
|
|
5289
|
+
setValue(colLabel, timeString, { shouldValidate: true, shouldDirty: true });
|
|
5290
|
+
};
|
|
5291
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
5292
|
+
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: () => {
|
|
5293
|
+
setOpen(true);
|
|
5294
|
+
}, 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: {
|
|
5295
|
+
am: translate.t(`common.am`, { defaultValue: "AM" }),
|
|
5296
|
+
pm: translate.t(`common.pm`, { defaultValue: "PM" }),
|
|
5297
|
+
} }) }) }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
5298
|
+
};
|
|
5299
|
+
|
|
5300
|
+
function IsoTimePicker({ hour, setHour, minute, setMinute, second, setSecond, onChange = (_newValue) => { }, }) {
|
|
5301
|
+
// Refs for focus management
|
|
5302
|
+
const hourInputRef = React.useRef(null);
|
|
5303
|
+
const minuteInputRef = React.useRef(null);
|
|
5304
|
+
const secondInputRef = React.useRef(null);
|
|
5305
|
+
// Centralized handler for key events, value changes, and focus management
|
|
5306
|
+
const handleKeyDown = (e, field) => {
|
|
5307
|
+
const input = e.target;
|
|
5308
|
+
const value = input.value;
|
|
5309
|
+
// Handle navigation between fields
|
|
5310
|
+
if (e.key === "Tab") {
|
|
5311
|
+
return;
|
|
5312
|
+
}
|
|
5313
|
+
if (e.key === ":" && field === "hour") {
|
|
5314
|
+
e.preventDefault();
|
|
5315
|
+
minuteInputRef.current?.focus();
|
|
5316
|
+
return;
|
|
5317
|
+
}
|
|
5318
|
+
if (e.key === ":" && field === "minute") {
|
|
5319
|
+
e.preventDefault();
|
|
5320
|
+
secondInputRef.current?.focus();
|
|
5321
|
+
return;
|
|
5322
|
+
}
|
|
5323
|
+
if (e.key === "Backspace" && value === "") {
|
|
5324
|
+
e.preventDefault();
|
|
5325
|
+
if (field === "minute") {
|
|
5326
|
+
hourInputRef.current?.focus();
|
|
5327
|
+
}
|
|
5328
|
+
else if (field === "second") {
|
|
5329
|
+
minuteInputRef.current?.focus();
|
|
5330
|
+
}
|
|
5331
|
+
return;
|
|
5332
|
+
}
|
|
5333
|
+
// Handle number inputs
|
|
5334
|
+
if (field === "hour") {
|
|
5335
|
+
if (e.key.match(/^[0-9]$/)) {
|
|
5336
|
+
const newValue = value + e.key;
|
|
5337
|
+
const numValue = parseInt(newValue, 10);
|
|
5338
|
+
if (numValue > 23) {
|
|
5339
|
+
const digitValue = parseInt(e.key, 10);
|
|
5340
|
+
setHour(digitValue);
|
|
5341
|
+
onChange({ hour: digitValue, minute, second });
|
|
5342
|
+
return;
|
|
5343
|
+
}
|
|
5344
|
+
if (numValue >= 0 && numValue <= 23) {
|
|
5345
|
+
setHour(numValue);
|
|
5346
|
+
onChange({ hour: numValue, minute, second });
|
|
5347
|
+
e.preventDefault();
|
|
5348
|
+
minuteInputRef.current?.focus();
|
|
5349
|
+
}
|
|
5350
|
+
}
|
|
5351
|
+
}
|
|
5352
|
+
else if (field === "minute") {
|
|
5353
|
+
if (e.key.match(/^[0-9]$/)) {
|
|
5354
|
+
const newValue = value + e.key;
|
|
5355
|
+
const numValue = parseInt(newValue, 10);
|
|
5356
|
+
if (numValue > 59) {
|
|
5357
|
+
const digitValue = parseInt(e.key, 10);
|
|
5358
|
+
setMinute(digitValue);
|
|
5359
|
+
onChange({ hour, minute: digitValue, second });
|
|
5360
|
+
return;
|
|
5361
|
+
}
|
|
5362
|
+
if (numValue >= 0 && numValue <= 59) {
|
|
5363
|
+
setMinute(numValue);
|
|
5364
|
+
onChange({ hour, minute: numValue, second });
|
|
5365
|
+
e.preventDefault();
|
|
5366
|
+
secondInputRef.current?.focus();
|
|
5367
|
+
}
|
|
5368
|
+
}
|
|
5369
|
+
}
|
|
5370
|
+
else if (field === "second") {
|
|
5371
|
+
if (e.key.match(/^[0-9]$/)) {
|
|
5372
|
+
const newValue = value + e.key;
|
|
5373
|
+
const numValue = parseInt(newValue, 10);
|
|
5374
|
+
if (numValue > 59) {
|
|
5375
|
+
const digitValue = parseInt(e.key, 10);
|
|
5376
|
+
setSecond(digitValue);
|
|
5377
|
+
onChange({ hour, minute, second: digitValue });
|
|
5378
|
+
return;
|
|
5379
|
+
}
|
|
5380
|
+
if (numValue >= 0 && numValue <= 59) {
|
|
5381
|
+
setSecond(numValue);
|
|
5382
|
+
onChange({ hour, minute, second: numValue });
|
|
5383
|
+
}
|
|
5384
|
+
}
|
|
5385
|
+
}
|
|
5386
|
+
};
|
|
5387
|
+
const handleClear = () => {
|
|
5388
|
+
setHour(null);
|
|
5389
|
+
setMinute(null);
|
|
5390
|
+
setSecond(null);
|
|
5391
|
+
onChange({ hour: null, minute: null, second: null });
|
|
5392
|
+
hourInputRef.current?.focus();
|
|
5393
|
+
};
|
|
5394
|
+
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, {}) })] }) }));
|
|
5395
|
+
}
|
|
5396
|
+
|
|
5397
|
+
function DateTimePicker$1({ value, onChange, format = "date-time", showSeconds = false, labels = {
|
|
5398
|
+
monthNamesShort: [
|
|
5399
|
+
"Jan",
|
|
5400
|
+
"Feb",
|
|
5401
|
+
"Mar",
|
|
5402
|
+
"Apr",
|
|
5403
|
+
"May",
|
|
5404
|
+
"Jun",
|
|
5405
|
+
"Jul",
|
|
5406
|
+
"Aug",
|
|
5407
|
+
"Sep",
|
|
5408
|
+
"Oct",
|
|
5409
|
+
"Nov",
|
|
5410
|
+
"Dec",
|
|
5411
|
+
],
|
|
5412
|
+
weekdayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
|
|
5413
|
+
backButtonLabel: "Back",
|
|
5414
|
+
forwardButtonLabel: "Next",
|
|
5415
|
+
}, timezone = "Asia/Hong_Kong", }) {
|
|
5416
|
+
const [selectedDate, setSelectedDate] = React.useState(value || "");
|
|
5417
|
+
// Time state for 12-hour format
|
|
5418
|
+
const [hour12, setHour12] = React.useState(value ? dayjs(value).hour() % 12 || 12 : null);
|
|
5419
|
+
const [minute, setMinute] = React.useState(value ? dayjs(value).minute() : null);
|
|
5420
|
+
const [meridiem, setMeridiem] = React.useState(value ? (dayjs(value).hour() >= 12 ? "pm" : "am") : null);
|
|
5421
|
+
// Time state for 24-hour format
|
|
5422
|
+
const [hour24, setHour24] = React.useState(value ? dayjs(value).hour() : null);
|
|
5423
|
+
const [second, setSecond] = React.useState(value ? dayjs(value).second() : null);
|
|
5424
|
+
const handleDateChange = (date) => {
|
|
5425
|
+
setSelectedDate(date);
|
|
5426
|
+
updateDateTime(dayjs(date).tz(timezone).toISOString());
|
|
5427
|
+
};
|
|
5428
|
+
const handleTimeChange = (timeData) => {
|
|
5429
|
+
if (format === "iso-date-time") {
|
|
5430
|
+
setHour24(timeData.hour);
|
|
5431
|
+
setMinute(timeData.minute);
|
|
5432
|
+
if (showSeconds)
|
|
5433
|
+
setSecond(timeData.second);
|
|
5434
|
+
}
|
|
5435
|
+
else {
|
|
5436
|
+
setHour12(timeData.hour);
|
|
5437
|
+
setMinute(timeData.minute);
|
|
5438
|
+
setMeridiem(timeData.meridiem);
|
|
5439
|
+
}
|
|
5440
|
+
updateDateTime(dayjs(selectedDate).tz(timezone).toISOString(), timeData);
|
|
5441
|
+
};
|
|
5442
|
+
const updateDateTime = (date, timeData) => {
|
|
5443
|
+
if (!date) {
|
|
5444
|
+
onChange?.(undefined);
|
|
5445
|
+
return;
|
|
5446
|
+
}
|
|
5447
|
+
// use dayjs to convert the date to the timezone
|
|
5448
|
+
const newDate = dayjs(date).tz(timezone).toDate();
|
|
5449
|
+
if (format === "iso-date-time") {
|
|
5450
|
+
const h = timeData?.hour ?? hour24;
|
|
5451
|
+
const m = timeData?.minute ?? minute;
|
|
5452
|
+
const s = showSeconds ? timeData?.second ?? second : 0;
|
|
5453
|
+
if (h !== null)
|
|
5454
|
+
newDate.setHours(h);
|
|
5455
|
+
if (m !== null)
|
|
5456
|
+
newDate.setMinutes(m);
|
|
5457
|
+
if (s !== null)
|
|
5458
|
+
newDate.setSeconds(s);
|
|
5459
|
+
}
|
|
5460
|
+
else {
|
|
5461
|
+
const h = timeData?.hour ?? hour12;
|
|
5462
|
+
const m = timeData?.minute ?? minute;
|
|
5463
|
+
const mer = timeData?.meridiem ?? meridiem;
|
|
5464
|
+
if (h !== null && mer !== null) {
|
|
5465
|
+
let hour24 = h;
|
|
5466
|
+
if (mer === "am" && h === 12)
|
|
5467
|
+
hour24 = 0;
|
|
5468
|
+
else if (mer === "pm" && h < 12)
|
|
5469
|
+
hour24 = h + 12;
|
|
5470
|
+
newDate.setHours(hour24);
|
|
5471
|
+
}
|
|
5472
|
+
if (m !== null)
|
|
5473
|
+
newDate.setMinutes(m);
|
|
5474
|
+
newDate.setSeconds(0);
|
|
5475
|
+
}
|
|
5476
|
+
onChange?.(dayjs(newDate).tz(timezone).toISOString());
|
|
5477
|
+
};
|
|
5478
|
+
const handleClear = () => {
|
|
5479
|
+
setSelectedDate("");
|
|
5480
|
+
setHour12(null);
|
|
5481
|
+
setHour24(null);
|
|
5482
|
+
setMinute(null);
|
|
5483
|
+
setSecond(null);
|
|
5484
|
+
setMeridiem(null);
|
|
5485
|
+
onChange?.(undefined);
|
|
5486
|
+
};
|
|
5487
|
+
const isISO = format === "iso-date-time";
|
|
5488
|
+
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
|
|
5489
|
+
? dayjs(selectedDate).tz(timezone).toDate()
|
|
5490
|
+
: 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
|
|
5491
|
+
? showSeconds
|
|
5492
|
+
? "YYYY-MM-DD HH:mm:ss"
|
|
5493
|
+
: "YYYY-MM-DD HH:mm"
|
|
5494
|
+
: "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 })] }))] }));
|
|
5495
|
+
}
|
|
5496
|
+
|
|
5497
|
+
dayjs.extend(utc);
|
|
5498
|
+
dayjs.extend(timezone);
|
|
5499
|
+
const DateTimePicker = ({ column, schema, prefix, }) => {
|
|
5500
|
+
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
5501
|
+
const { timezone } = useSchemaContext();
|
|
5502
|
+
const formI18n = useFormI18n(column, prefix);
|
|
5503
|
+
const { required, gridColumn = "span 12", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD HH:mm:ss",
|
|
5504
|
+
// with timezone
|
|
5505
|
+
dateFormat = "YYYY-MM-DD[T]HH:mm:ssZ", } = schema;
|
|
5506
|
+
const isRequired = required?.some((columnId) => columnId === column);
|
|
5507
|
+
const colLabel = formI18n.colLabel;
|
|
5508
|
+
const [open, setOpen] = React.useState(false);
|
|
5509
|
+
const selectedDate = watch(colLabel);
|
|
5510
|
+
const displayDate = dayjs(selectedDate)
|
|
5511
|
+
.tz(timezone)
|
|
5512
|
+
.format(displayDateFormat);
|
|
5513
|
+
React.useEffect(() => {
|
|
5514
|
+
try {
|
|
5515
|
+
if (selectedDate) {
|
|
5516
|
+
// Parse the selectedDate as UTC or in a specific timezone to avoid +8 hour shift
|
|
5517
|
+
// For example, parse as UTC:
|
|
5518
|
+
const parsedDate = dayjs(selectedDate).tz(timezone);
|
|
5519
|
+
if (!parsedDate.isValid())
|
|
5520
|
+
return;
|
|
5521
|
+
// Format according to dateFormat from schema
|
|
5522
|
+
const formatted = parsedDate.format(dateFormat);
|
|
5523
|
+
// Update the form value only if different to avoid loops
|
|
5524
|
+
if (formatted !== selectedDate) {
|
|
5525
|
+
setValue(colLabel, formatted, {
|
|
5526
|
+
shouldValidate: true,
|
|
5527
|
+
shouldDirty: true,
|
|
5528
|
+
});
|
|
5529
|
+
}
|
|
5530
|
+
}
|
|
5531
|
+
}
|
|
5532
|
+
catch (e) {
|
|
5533
|
+
console.error(e);
|
|
5534
|
+
}
|
|
5535
|
+
}, [selectedDate, dateFormat, colLabel, setValue]);
|
|
5536
|
+
return (jsxRuntime.jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: "stretch", gridColumn,
|
|
5537
|
+
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: () => {
|
|
5538
|
+
setOpen(true);
|
|
5539
|
+
}, 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) => {
|
|
5540
|
+
setValue(colLabel, dayjs(date).tz(timezone).format(dateFormat));
|
|
5541
|
+
}, timezone: timezone, labels: {
|
|
5542
|
+
monthNamesShort: [
|
|
5543
|
+
formI18n.translate.t(`common.month_1`, { defaultValue: "January" }),
|
|
5544
|
+
formI18n.translate.t(`common.month_2`, { defaultValue: "February" }),
|
|
5545
|
+
formI18n.translate.t(`common.month_3`, { defaultValue: "March" }),
|
|
5546
|
+
formI18n.translate.t(`common.month_4`, { defaultValue: "April" }),
|
|
5547
|
+
formI18n.translate.t(`common.month_5`, { defaultValue: "May" }),
|
|
5548
|
+
formI18n.translate.t(`common.month_6`, { defaultValue: "June" }),
|
|
5549
|
+
formI18n.translate.t(`common.month_7`, { defaultValue: "July" }),
|
|
5550
|
+
formI18n.translate.t(`common.month_8`, { defaultValue: "August" }),
|
|
5551
|
+
formI18n.translate.t(`common.month_9`, { defaultValue: "September" }),
|
|
5552
|
+
formI18n.translate.t(`common.month_10`, { defaultValue: "October" }),
|
|
5553
|
+
formI18n.translate.t(`common.month_11`, { defaultValue: "November" }),
|
|
5554
|
+
formI18n.translate.t(`common.month_12`, { defaultValue: "December" }),
|
|
5555
|
+
],
|
|
5556
|
+
weekdayNamesShort: [
|
|
5557
|
+
formI18n.translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
|
|
5558
|
+
formI18n.translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
|
|
5559
|
+
formI18n.translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
|
|
5560
|
+
formI18n.translate.t(`common.weekday_4`, {
|
|
5561
|
+
defaultValue: "Wed",
|
|
5562
|
+
}),
|
|
5563
|
+
formI18n.translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
|
|
5564
|
+
formI18n.translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
|
|
5565
|
+
formI18n.translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
|
|
5566
|
+
],
|
|
5567
|
+
backButtonLabel: formI18n.translate.t(`common.back_button`, {
|
|
5568
|
+
defaultValue: "Back",
|
|
5569
|
+
}),
|
|
5570
|
+
forwardButtonLabel: formI18n.translate.t(`common.forward_button`, {
|
|
5571
|
+
defaultValue: "Forward",
|
|
5572
|
+
}),
|
|
5573
|
+
} })] }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: formI18n.required() }))] }));
|
|
5574
|
+
};
|
|
5575
|
+
|
|
4557
5576
|
const SchemaRenderer = ({ schema, prefix, column, }) => {
|
|
4558
5577
|
const colSchema = schema;
|
|
4559
|
-
const { type, variant, properties: innerProperties, foreign_key, items, } = schema;
|
|
5578
|
+
const { type, variant, properties: innerProperties, foreign_key, format, items, } = schema;
|
|
5579
|
+
if (variant === "custom-input") {
|
|
5580
|
+
return jsxRuntime.jsx(CustomInput, { schema: colSchema, prefix, column });
|
|
5581
|
+
}
|
|
4560
5582
|
if (type === "string") {
|
|
4561
5583
|
if ((schema.enum ?? []).length > 0) {
|
|
4562
5584
|
return jsxRuntime.jsx(EnumPicker, { schema: colSchema, prefix, column });
|
|
@@ -4565,9 +5587,18 @@ const SchemaRenderer = ({ schema, prefix, column, }) => {
|
|
|
4565
5587
|
idPickerSanityCheck(column, foreign_key);
|
|
4566
5588
|
return jsxRuntime.jsx(IdPicker, { schema: colSchema, prefix, column });
|
|
4567
5589
|
}
|
|
4568
|
-
if (
|
|
5590
|
+
if (format === "date") {
|
|
4569
5591
|
return jsxRuntime.jsx(DatePicker, { schema: colSchema, prefix, column });
|
|
4570
5592
|
}
|
|
5593
|
+
if (format === "time") {
|
|
5594
|
+
return jsxRuntime.jsx(TimePicker, { schema: colSchema, prefix, column });
|
|
5595
|
+
}
|
|
5596
|
+
if (format === "date-time") {
|
|
5597
|
+
return jsxRuntime.jsx(DateTimePicker, { schema: colSchema, prefix, column });
|
|
5598
|
+
}
|
|
5599
|
+
if (variant === "text-area") {
|
|
5600
|
+
return jsxRuntime.jsx(TextAreaInput, { schema: colSchema, prefix, column });
|
|
5601
|
+
}
|
|
4571
5602
|
return jsxRuntime.jsx(StringInputField, { schema: colSchema, prefix, column });
|
|
4572
5603
|
}
|
|
4573
5604
|
if (type === "number" || type === "integer") {
|
|
@@ -4593,6 +5624,15 @@ const SchemaRenderer = ({ schema, prefix, column, }) => {
|
|
|
4593
5624
|
if (variant === "file-picker") {
|
|
4594
5625
|
return jsxRuntime.jsx(FilePicker, { schema: colSchema, prefix, column });
|
|
4595
5626
|
}
|
|
5627
|
+
if (variant === "enum-picker") {
|
|
5628
|
+
const { items } = colSchema;
|
|
5629
|
+
const { enum: enumItems } = items;
|
|
5630
|
+
const enumSchema = {
|
|
5631
|
+
type: "string",
|
|
5632
|
+
enum: enumItems,
|
|
5633
|
+
};
|
|
5634
|
+
return (jsxRuntime.jsx(EnumPicker, { isMultiple: true, schema: enumSchema, prefix, column }));
|
|
5635
|
+
}
|
|
4596
5636
|
if (items) {
|
|
4597
5637
|
return jsxRuntime.jsx(ArrayRenderer, { schema: colSchema, prefix, column });
|
|
4598
5638
|
}
|
|
@@ -4614,85 +5654,95 @@ const ColumnRenderer = ({ column, properties, prefix, }) => {
|
|
|
4614
5654
|
};
|
|
4615
5655
|
|
|
4616
5656
|
const ArrayViewer = ({ schema, column, prefix }) => {
|
|
4617
|
-
const {
|
|
5657
|
+
const { gridColumn = "span 12", gridRow = "span 1", required, items, } = schema;
|
|
4618
5658
|
const { translate } = useSchemaContext();
|
|
4619
5659
|
const colLabel = `${prefix}${column}`;
|
|
4620
5660
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4621
5661
|
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
4622
5662
|
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
|
-
|
|
5663
|
+
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: {
|
|
5664
|
+
base: "colorPalette.200",
|
|
5665
|
+
_dark: "colorPalette.800",
|
|
5666
|
+
}, children: jsxRuntime.jsx(react.Grid, { gap: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: jsxRuntime.jsx(SchemaViewer, { column: `${index}`,
|
|
5667
|
+
prefix: `${colLabel}.`,
|
|
5668
|
+
// @ts-expect-error find suitable types
|
|
5669
|
+
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
5670
|
};
|
|
4627
5671
|
|
|
4628
5672
|
const BooleanViewer = ({ schema, column, prefix, }) => {
|
|
4629
5673
|
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
4630
5674
|
const { translate } = useSchemaContext();
|
|
4631
|
-
const { required, gridColumn, gridRow } = schema;
|
|
5675
|
+
const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
|
|
4632
5676
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4633
5677
|
const colLabel = `${prefix}${column}`;
|
|
4634
5678
|
const value = watch(colLabel);
|
|
4635
|
-
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.
|
|
5679
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
4636
5680
|
gridRow, children: [jsxRuntime.jsx(react.Text, { children: value
|
|
4637
5681
|
? 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}.
|
|
5682
|
+
: translate.t(removeIndex(`${colLabel}.false`)) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
5683
|
+
};
|
|
5684
|
+
|
|
5685
|
+
const CustomViewer = ({ column, schema, prefix }) => {
|
|
5686
|
+
const formContext = reactHookForm.useFormContext();
|
|
5687
|
+
const { inputViewerRender } = schema;
|
|
5688
|
+
return (inputViewerRender &&
|
|
5689
|
+
inputViewerRender({
|
|
5690
|
+
column,
|
|
5691
|
+
schema,
|
|
5692
|
+
prefix,
|
|
5693
|
+
formContext,
|
|
5694
|
+
}));
|
|
4639
5695
|
};
|
|
4640
5696
|
|
|
4641
5697
|
const DateViewer = ({ column, schema, prefix }) => {
|
|
4642
5698
|
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
4643
|
-
const { translate } = useSchemaContext();
|
|
4644
|
-
const { required, gridColumn, gridRow } = schema;
|
|
5699
|
+
const { translate, timezone } = useSchemaContext();
|
|
5700
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD", } = schema;
|
|
4645
5701
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4646
5702
|
const colLabel = `${prefix}${column}`;
|
|
4647
5703
|
const selectedDate = watch(colLabel);
|
|
4648
|
-
|
|
4649
|
-
|
|
5704
|
+
const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
|
|
5705
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
5706
|
+
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
5707
|
};
|
|
4651
5708
|
|
|
4652
5709
|
const EnumViewer = ({ column, isMultiple = false, schema, prefix, }) => {
|
|
4653
5710
|
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
4654
|
-
const
|
|
5711
|
+
const formI18n = useFormI18n(column, prefix);
|
|
4655
5712
|
const { required } = schema;
|
|
4656
5713
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4657
|
-
const { gridColumn, gridRow, renderDisplay } = schema;
|
|
4658
|
-
const colLabel =
|
|
5714
|
+
const { gridColumn = "span 12", gridRow = "span 1", renderDisplay } = schema;
|
|
5715
|
+
const colLabel = formI18n.colLabel;
|
|
4659
5716
|
const watchEnum = watch(colLabel);
|
|
4660
5717
|
const watchEnums = (watch(colLabel) ?? []);
|
|
4661
|
-
return (jsxRuntime.jsxs(Field, { label:
|
|
5718
|
+
return (jsxRuntime.jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: "stretch", gridColumn,
|
|
4662
5719
|
gridRow, children: [isMultiple && (jsxRuntime.jsx(react.Flex, { flexFlow: "wrap", gap: 1, children: watchEnums.map((enumValue) => {
|
|
4663
5720
|
const item = enumValue;
|
|
4664
5721
|
if (item === undefined) {
|
|
4665
5722
|
return jsxRuntime.jsx(jsxRuntime.Fragment, { children: "undefined" });
|
|
4666
5723
|
}
|
|
4667
|
-
return (jsxRuntime.jsx(Tag, {
|
|
5724
|
+
return (jsxRuntime.jsx(Tag, { size: "lg", children: !!renderDisplay === true
|
|
4668
5725
|
? renderDisplay(item)
|
|
4669
|
-
:
|
|
4670
|
-
}) })), !isMultiple &&
|
|
5726
|
+
: formI18n.t(item) }, item));
|
|
5727
|
+
}) })), !isMultiple && jsxRuntime.jsx(react.Text, { children: formI18n.t(watchEnum) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: formI18n.required() }))] }));
|
|
4671
5728
|
};
|
|
4672
5729
|
|
|
4673
5730
|
const FileViewer = ({ column, schema, prefix }) => {
|
|
4674
|
-
const {
|
|
5731
|
+
const { watch } = reactHookForm.useFormContext();
|
|
4675
5732
|
const { translate } = useSchemaContext();
|
|
4676
|
-
const { required, gridColumn, gridRow } = schema;
|
|
5733
|
+
const { required, gridColumn = "span 12", gridRow = "span 1", } = schema;
|
|
4677
5734
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4678
5735
|
const currentFiles = (watch(column) ?? []);
|
|
4679
5736
|
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`)) }))] }));
|
|
5737
|
+
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) => {
|
|
5738
|
+
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));
|
|
5739
|
+
}) }) }));
|
|
4690
5740
|
};
|
|
4691
5741
|
|
|
4692
5742
|
const IdViewer = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
4693
5743
|
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
4694
5744
|
const { idMap, translate } = useSchemaContext();
|
|
4695
|
-
const { required, gridColumn, gridRow, renderDisplay, foreign_key } = schema;
|
|
5745
|
+
const { required, gridColumn = "span 12", gridRow = "span 1", renderDisplay, foreign_key, } = schema;
|
|
4696
5746
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4697
5747
|
const { display_column } = foreign_key;
|
|
4698
5748
|
const colLabel = `${prefix}${column}`;
|
|
@@ -4708,7 +5758,7 @@ const IdViewer = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4708
5758
|
}
|
|
4709
5759
|
return record[display_column];
|
|
4710
5760
|
};
|
|
4711
|
-
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${column}.
|
|
5761
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
4712
5762
|
gridRow, children: [isMultiple && (jsxRuntime.jsx(react.Flex, { flexFlow: "wrap", gap: 1, children: watchIds.map((id) => {
|
|
4713
5763
|
const item = idMap[id];
|
|
4714
5764
|
if (item === undefined) {
|
|
@@ -4717,21 +5767,21 @@ const IdViewer = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4717
5767
|
return (jsxRuntime.jsx(Tag, { closable: true, children: !!renderDisplay === true
|
|
4718
5768
|
? renderDisplay(item)
|
|
4719
5769
|
: 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}.
|
|
5770
|
+
}) })), !isMultiple && jsxRuntime.jsx(react.Text, { children: getPickedValue() }), errors[`${colLabel}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4721
5771
|
};
|
|
4722
5772
|
|
|
4723
5773
|
const NumberViewer = ({ schema, column, prefix, }) => {
|
|
4724
5774
|
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
4725
5775
|
const { translate } = useSchemaContext();
|
|
4726
|
-
const { required, gridColumn, gridRow } = schema;
|
|
5776
|
+
const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
|
|
4727
5777
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4728
5778
|
const colLabel = `${prefix}${column}`;
|
|
4729
5779
|
const value = watch(colLabel);
|
|
4730
|
-
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.
|
|
5780
|
+
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
5781
|
};
|
|
4732
5782
|
|
|
4733
5783
|
const ObjectViewer = ({ schema, column, prefix }) => {
|
|
4734
|
-
const { properties,
|
|
5784
|
+
const { properties, gridColumn = "span 12", gridRow = "span 1", required, showLabel = true, } = schema;
|
|
4735
5785
|
const { translate } = useSchemaContext();
|
|
4736
5786
|
const colLabel = `${prefix}${column}`;
|
|
4737
5787
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
@@ -4739,25 +5789,28 @@ const ObjectViewer = ({ schema, column, prefix }) => {
|
|
|
4739
5789
|
if (properties === undefined) {
|
|
4740
5790
|
throw new Error(`properties is undefined when using ObjectInput`);
|
|
4741
5791
|
}
|
|
4742
|
-
return (jsxRuntime.jsxs(react.Box, { gridRow, gridColumn, children: [jsxRuntime.jsxs(react.Box, { as: "label",
|
|
5792
|
+
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: {
|
|
5793
|
+
base: "colorPalette.200",
|
|
5794
|
+
_dark: "colorPalette.800",
|
|
5795
|
+
}, children: Object.keys(properties ?? {}).map((key) => {
|
|
4743
5796
|
return (
|
|
4744
5797
|
// @ts-expect-error find suitable types
|
|
4745
5798
|
jsxRuntime.jsx(ColumnViewer, { column: `${key}`,
|
|
4746
5799
|
prefix: `${prefix}${column}.`,
|
|
4747
5800
|
properties }, `form-objectviewer-${colLabel}-${key}`));
|
|
4748
|
-
}) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.
|
|
5801
|
+
}) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4749
5802
|
};
|
|
4750
5803
|
|
|
4751
5804
|
const RecordInput = ({ column, schema, prefix }) => {
|
|
4752
5805
|
const { formState: { errors }, setValue, getValues, } = reactHookForm.useFormContext();
|
|
4753
5806
|
const { translate } = useSchemaContext();
|
|
4754
|
-
const { required, gridColumn, gridRow } = schema;
|
|
5807
|
+
const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
|
|
4755
5808
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4756
5809
|
const entries = Object.entries(getValues(column) ?? {});
|
|
4757
5810
|
const [showNewEntries, setShowNewEntries] = React.useState(false);
|
|
4758
5811
|
const [newKey, setNewKey] = React.useState();
|
|
4759
5812
|
const [newValue, setNewValue] = React.useState();
|
|
4760
|
-
return (jsxRuntime.jsxs(Field, { label: `${translate.t(`${column}.
|
|
5813
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(`${column}.field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn, gridRow, children: [entries.map(([key, value]) => {
|
|
4761
5814
|
return (jsxRuntime.jsxs(react.Grid, { templateColumns: "1fr 1fr auto", gap: 1, children: [jsxRuntime.jsx(react.Input, { value: key, onChange: (e) => {
|
|
4762
5815
|
const filtered = entries.filter(([target]) => {
|
|
4763
5816
|
return target !== key;
|
|
@@ -4797,7 +5850,17 @@ const RecordInput = ({ column, schema, prefix }) => {
|
|
|
4797
5850
|
setShowNewEntries(true);
|
|
4798
5851
|
setNewKey(undefined);
|
|
4799
5852
|
setNewValue(undefined);
|
|
4800
|
-
}, children: translate.t(`${column}.addNew`) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(`${column}.
|
|
5853
|
+
}, children: translate.t(`${column}.addNew`) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
|
|
5854
|
+
};
|
|
5855
|
+
|
|
5856
|
+
const StringViewer = ({ column, schema, prefix, }) => {
|
|
5857
|
+
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
5858
|
+
const { translate } = useSchemaContext();
|
|
5859
|
+
const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
|
|
5860
|
+
const isRequired = required?.some((columnId) => columnId === column);
|
|
5861
|
+
const colLabel = `${prefix}${column}`;
|
|
5862
|
+
const value = watch(colLabel);
|
|
5863
|
+
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
5864
|
};
|
|
4802
5865
|
|
|
4803
5866
|
const TagViewer = ({ column, schema, prefix }) => {
|
|
@@ -4885,19 +5948,50 @@ const TagViewer = ({ column, schema, prefix }) => {
|
|
|
4885
5948
|
}), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: (errors[`${column}`]?.message ?? "No error message") }))] }));
|
|
4886
5949
|
};
|
|
4887
5950
|
|
|
4888
|
-
const
|
|
5951
|
+
const TextAreaViewer = ({ column, schema, prefix, }) => {
|
|
4889
5952
|
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
4890
5953
|
const { translate } = useSchemaContext();
|
|
4891
|
-
const { required, gridColumn, gridRow } = schema;
|
|
5954
|
+
const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
|
|
4892
5955
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4893
5956
|
const colLabel = `${prefix}${column}`;
|
|
4894
5957
|
const value = watch(colLabel);
|
|
4895
|
-
return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.
|
|
5958
|
+
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`)) }))] }) }));
|
|
5959
|
+
};
|
|
5960
|
+
|
|
5961
|
+
const TimeViewer = ({ column, schema, prefix }) => {
|
|
5962
|
+
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
5963
|
+
const { translate, timezone } = useSchemaContext();
|
|
5964
|
+
const { required, gridColumn = "span 12", gridRow = "span 1", displayTimeFormat = "hh:mm A", } = schema;
|
|
5965
|
+
const isRequired = required?.some((columnId) => columnId === column);
|
|
5966
|
+
const colLabel = `${prefix}${column}`;
|
|
5967
|
+
const selectedDate = watch(colLabel);
|
|
5968
|
+
const displayedTime = dayjs(`1970-01-01T${selectedDate}`)
|
|
5969
|
+
.tz(timezone)
|
|
5970
|
+
.isValid()
|
|
5971
|
+
? dayjs(`1970-01-01T${selectedDate}`).tz(timezone).format(displayTimeFormat)
|
|
5972
|
+
: "";
|
|
5973
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
5974
|
+
gridRow, children: [jsxRuntime.jsx(react.Text, { children: displayedTime }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
|
|
5975
|
+
};
|
|
5976
|
+
|
|
5977
|
+
const DateTimeViewer = ({ column, schema, prefix }) => {
|
|
5978
|
+
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
5979
|
+
const { translate, timezone } = useSchemaContext();
|
|
5980
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD HH:mm:ss", } = schema;
|
|
5981
|
+
const isRequired = required?.some((columnId) => columnId === column);
|
|
5982
|
+
const colLabel = `${prefix}${column}`;
|
|
5983
|
+
const selectedDate = watch(colLabel);
|
|
5984
|
+
const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
|
|
5985
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
5986
|
+
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
5987
|
};
|
|
4897
5988
|
|
|
4898
5989
|
const SchemaViewer = ({ schema, prefix, column, }) => {
|
|
4899
5990
|
const colSchema = schema;
|
|
4900
|
-
const { type, variant, properties: innerProperties, foreign_key, items, } = schema;
|
|
5991
|
+
const { type, variant, properties: innerProperties, foreign_key, items, format, } = schema;
|
|
5992
|
+
if (variant === "custom-input") {
|
|
5993
|
+
return jsxRuntime.jsx(CustomViewer, { schema: colSchema, prefix, column });
|
|
5994
|
+
}
|
|
4901
5995
|
if (type === "string") {
|
|
4902
5996
|
if ((schema.enum ?? []).length > 0) {
|
|
4903
5997
|
return jsxRuntime.jsx(EnumViewer, { schema: colSchema, prefix, column });
|
|
@@ -4906,9 +6000,18 @@ const SchemaViewer = ({ schema, prefix, column, }) => {
|
|
|
4906
6000
|
idPickerSanityCheck(column, foreign_key);
|
|
4907
6001
|
return jsxRuntime.jsx(IdViewer, { schema: colSchema, prefix, column });
|
|
4908
6002
|
}
|
|
4909
|
-
if (
|
|
6003
|
+
if (format === "time") {
|
|
6004
|
+
return jsxRuntime.jsx(TimeViewer, { schema: colSchema, prefix, column });
|
|
6005
|
+
}
|
|
6006
|
+
if (format === "date") {
|
|
4910
6007
|
return jsxRuntime.jsx(DateViewer, { schema: colSchema, prefix, column });
|
|
4911
6008
|
}
|
|
6009
|
+
if (format === "date-time") {
|
|
6010
|
+
return jsxRuntime.jsx(DateTimeViewer, { schema: colSchema, prefix, column });
|
|
6011
|
+
}
|
|
6012
|
+
if (variant === "text-area") {
|
|
6013
|
+
return jsxRuntime.jsx(TextAreaViewer, { schema: colSchema, prefix, column });
|
|
6014
|
+
}
|
|
4912
6015
|
return jsxRuntime.jsx(StringViewer, { schema: colSchema, prefix, column });
|
|
4913
6016
|
}
|
|
4914
6017
|
if (type === "number" || type === "integer") {
|
|
@@ -4934,6 +6037,15 @@ const SchemaViewer = ({ schema, prefix, column, }) => {
|
|
|
4934
6037
|
if (variant === "file-picker") {
|
|
4935
6038
|
return jsxRuntime.jsx(FileViewer, { schema: colSchema, prefix, column });
|
|
4936
6039
|
}
|
|
6040
|
+
if (variant === "enum-picker") {
|
|
6041
|
+
const { items } = schema;
|
|
6042
|
+
const { enum: enumItems } = items;
|
|
6043
|
+
const enumSchema = {
|
|
6044
|
+
type: "string",
|
|
6045
|
+
enum: enumItems,
|
|
6046
|
+
};
|
|
6047
|
+
return (jsxRuntime.jsx(EnumViewer, { isMultiple: true, schema: enumSchema, prefix, column }));
|
|
6048
|
+
}
|
|
4937
6049
|
if (items) {
|
|
4938
6050
|
return jsxRuntime.jsx(ArrayViewer, { schema: colSchema, prefix, column });
|
|
4939
6051
|
}
|
|
@@ -4957,10 +6069,20 @@ const ColumnViewer = ({ column, properties, prefix, }) => {
|
|
|
4957
6069
|
};
|
|
4958
6070
|
|
|
4959
6071
|
const SubmitButton = () => {
|
|
4960
|
-
const { translate, setValidatedData, setIsError, setIsConfirming } = useSchemaContext();
|
|
6072
|
+
const { translate, setValidatedData, setIsError, setIsConfirming, setError, schema, } = useSchemaContext();
|
|
4961
6073
|
const methods = reactHookForm.useFormContext();
|
|
4962
6074
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4963
6075
|
const onValid = (data) => {
|
|
6076
|
+
const { isValid, errors } = validateData(data, schema);
|
|
6077
|
+
if (!isValid) {
|
|
6078
|
+
setError({
|
|
6079
|
+
type: "validation",
|
|
6080
|
+
errors,
|
|
6081
|
+
});
|
|
6082
|
+
setIsError(true);
|
|
6083
|
+
return;
|
|
6084
|
+
}
|
|
6085
|
+
// If validation passes, proceed to confirmation
|
|
4964
6086
|
setValidatedData(data);
|
|
4965
6087
|
setIsError(false);
|
|
4966
6088
|
setIsConfirming(true);
|
|
@@ -4971,7 +6093,8 @@ const SubmitButton = () => {
|
|
|
4971
6093
|
};
|
|
4972
6094
|
|
|
4973
6095
|
const FormBody = () => {
|
|
4974
|
-
const { schema, requestUrl, order, ignore, include, onSubmit,
|
|
6096
|
+
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();
|
|
6097
|
+
const { showSubmitButton, showResetButton } = displayConfig;
|
|
4975
6098
|
const methods = reactHookForm.useFormContext();
|
|
4976
6099
|
const { properties } = schema;
|
|
4977
6100
|
const onBeforeSubmit = () => {
|
|
@@ -4987,6 +6110,26 @@ const FormBody = () => {
|
|
|
4987
6110
|
const onSubmitSuccess = () => {
|
|
4988
6111
|
setIsSuccess(true);
|
|
4989
6112
|
};
|
|
6113
|
+
const validateFormData = (data) => {
|
|
6114
|
+
try {
|
|
6115
|
+
const { isValid, errors } = validateData(data, schema);
|
|
6116
|
+
return {
|
|
6117
|
+
isValid,
|
|
6118
|
+
errors,
|
|
6119
|
+
};
|
|
6120
|
+
}
|
|
6121
|
+
catch (error) {
|
|
6122
|
+
return {
|
|
6123
|
+
isValid: false,
|
|
6124
|
+
errors: [
|
|
6125
|
+
{
|
|
6126
|
+
field: "validation",
|
|
6127
|
+
message: error instanceof Error ? error.message : "Unknown error",
|
|
6128
|
+
},
|
|
6129
|
+
],
|
|
6130
|
+
};
|
|
6131
|
+
}
|
|
6132
|
+
};
|
|
4990
6133
|
const defaultOnSubmit = async (promise) => {
|
|
4991
6134
|
try {
|
|
4992
6135
|
onBeforeSubmit();
|
|
@@ -5011,12 +6154,28 @@ const FormBody = () => {
|
|
|
5011
6154
|
};
|
|
5012
6155
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5013
6156
|
const onFormSubmit = async (data) => {
|
|
6157
|
+
// Validate data using AJV before submission
|
|
6158
|
+
const validationResult = validateFormData(data);
|
|
6159
|
+
if (!validationResult.isValid) {
|
|
6160
|
+
// Set validation errors
|
|
6161
|
+
const validationErrorMessage = {
|
|
6162
|
+
type: "validation",
|
|
6163
|
+
errors: validationResult.errors,
|
|
6164
|
+
message: translate.t("validation_error"),
|
|
6165
|
+
};
|
|
6166
|
+
onSubmitError(validationErrorMessage);
|
|
6167
|
+
return;
|
|
6168
|
+
}
|
|
5014
6169
|
if (onSubmit === undefined) {
|
|
5015
6170
|
await defaultOnSubmit(defaultSubmitPromise(data));
|
|
5016
6171
|
return;
|
|
5017
6172
|
}
|
|
5018
6173
|
await defaultOnSubmit(onSubmit(data));
|
|
5019
6174
|
};
|
|
6175
|
+
// Custom error renderer for validation errors with i18n support
|
|
6176
|
+
const renderValidationErrors = (validationErrors) => {
|
|
6177
|
+
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))) }));
|
|
6178
|
+
};
|
|
5020
6179
|
const renderColumns = ({ order, keys, ignore, include, }) => {
|
|
5021
6180
|
const included = include.length > 0 ? include : keys;
|
|
5022
6181
|
const not_exist = included.filter((columnA) => !order.some((columnB) => columnA === columnB));
|
|
@@ -5031,7 +6190,7 @@ const FormBody = () => {
|
|
|
5031
6190
|
include,
|
|
5032
6191
|
});
|
|
5033
6192
|
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("
|
|
6193
|
+
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
6194
|
setIsError(false);
|
|
5036
6195
|
setIsSubmiting(false);
|
|
5037
6196
|
setIsSuccess(false);
|
|
@@ -5039,10 +6198,10 @@ const FormBody = () => {
|
|
|
5039
6198
|
setValidatedData(undefined);
|
|
5040
6199
|
const data = await getUpdatedData();
|
|
5041
6200
|
methods.reset(data);
|
|
5042
|
-
}, formNoValidate: true, children: translate.t("
|
|
6201
|
+
}, formNoValidate: true, children: translate.t("submit_again") }) })] }));
|
|
5043
6202
|
}
|
|
5044
6203
|
if (isConfirming) {
|
|
5045
|
-
return (jsxRuntime.jsxs(react.Flex, { flexFlow: "column", gap: "2", children: [jsxRuntime.jsx(react.Grid, { gap: 4, gridTemplateColumns: "repeat(12, 1fr)", gridTemplateRows:
|
|
6204
|
+
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
6205
|
return (jsxRuntime.jsx(ColumnViewer
|
|
5047
6206
|
// @ts-expect-error find suitable types
|
|
5048
6207
|
, {
|
|
@@ -5052,17 +6211,19 @@ const FormBody = () => {
|
|
|
5052
6211
|
setIsConfirming(false);
|
|
5053
6212
|
}, variant: "subtle", children: translate.t("cancel") }), jsxRuntime.jsx(react.Button, { onClick: () => {
|
|
5054
6213
|
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:
|
|
6214
|
+
}, 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" &&
|
|
6215
|
+
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
6216
|
}
|
|
5057
|
-
return (jsxRuntime.jsxs(react.Flex, { flexFlow: "column", gap: "2", children: [jsxRuntime.jsx(react.Grid, { gap: "4", gridTemplateColumns: "repeat(12, 1fr)",
|
|
6217
|
+
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
6218
|
return (jsxRuntime.jsx(ColumnRenderer
|
|
5059
6219
|
// @ts-expect-error find suitable types
|
|
5060
6220
|
, {
|
|
5061
6221
|
// @ts-expect-error find suitable types
|
|
5062
6222
|
properties: properties, prefix: ``, column }, `form-input-${column}`));
|
|
5063
|
-
}) }), jsxRuntime.jsxs(react.Flex, { justifyContent: "end", gap: "2", children: [jsxRuntime.jsx(react.Button, { onClick: () => {
|
|
6223
|
+
}) }), jsxRuntime.jsxs(react.Flex, { justifyContent: "end", gap: "2", children: [showResetButton && (jsxRuntime.jsx(react.Button, { onClick: () => {
|
|
5064
6224
|
methods.reset();
|
|
5065
|
-
}, variant: "subtle", children: translate.t("reset") }), jsxRuntime.jsx(SubmitButton, {})] })
|
|
6225
|
+
}, 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" &&
|
|
6226
|
+
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
6227
|
};
|
|
5067
6228
|
|
|
5068
6229
|
const FormTitle = () => {
|
|
@@ -5071,7 +6232,8 @@ const FormTitle = () => {
|
|
|
5071
6232
|
};
|
|
5072
6233
|
|
|
5073
6234
|
const DefaultForm = ({ formConfig, }) => {
|
|
5074
|
-
|
|
6235
|
+
const { showTitle } = formConfig.displayConfig ?? {};
|
|
6236
|
+
return (jsxRuntime.jsx(FormRoot, { ...formConfig, children: jsxRuntime.jsxs(react.Grid, { gap: "2", children: [showTitle && jsxRuntime.jsx(FormTitle, {}), jsxRuntime.jsx(FormBody, {})] }) }));
|
|
5075
6237
|
};
|
|
5076
6238
|
|
|
5077
6239
|
const useForm = ({ preLoadedValues, keyPrefix }) => {
|
|
@@ -5116,7 +6278,6 @@ exports.EditSortingButton = EditSortingButton;
|
|
|
5116
6278
|
exports.EmptyState = EmptyState$1;
|
|
5117
6279
|
exports.ErrorAlert = ErrorAlert;
|
|
5118
6280
|
exports.FilterDialog = FilterDialog;
|
|
5119
|
-
exports.FilterOptions = FilterOptions;
|
|
5120
6281
|
exports.FormBody = FormBody;
|
|
5121
6282
|
exports.FormRoot = FormRoot;
|
|
5122
6283
|
exports.FormTitle = FormTitle;
|
|
@@ -5135,6 +6296,7 @@ exports.TableCardContainer = TableCardContainer;
|
|
|
5135
6296
|
exports.TableCards = TableCards;
|
|
5136
6297
|
exports.TableComponent = TableComponent;
|
|
5137
6298
|
exports.TableControls = TableControls;
|
|
6299
|
+
exports.TableDataDisplay = TableDataDisplay;
|
|
5138
6300
|
exports.TableFilter = TableFilter;
|
|
5139
6301
|
exports.TableFilterTags = TableFilterTags;
|
|
5140
6302
|
exports.TableFooter = TableFooter;
|