@bsol-oss/react-datatable5 12.0.0-beta.6 → 12.0.0-beta.60
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 +212 -91
- package/dist/index.js +1396 -426
- package/dist/index.mjs +1402 -432
- package/dist/types/components/DataTable/DataTable.d.ts +4 -2
- package/dist/types/components/DataTable/DataTableServer.d.ts +4 -2
- package/dist/types/components/DataTable/DefaultTable.d.ts +9 -12
- package/dist/types/components/DataTable/context/DataTableContext.d.ts +22 -3
- package/dist/types/components/DataTable/context/useDataTableContext.d.ts +2 -2
- package/dist/types/components/DataTable/controls/DensityFeature.d.ts +23 -0
- package/dist/types/components/DataTable/controls/DensityToggleButton.d.ts +6 -0
- package/dist/types/components/DataTable/controls/EditSortingButton.d.ts +7 -0
- package/dist/types/components/DataTable/controls/FilterDialog.d.ts +5 -0
- package/dist/types/components/DataTable/controls/PageSizeControl.d.ts +4 -0
- package/dist/types/components/DataTable/controls/Pagination.d.ts +1 -0
- package/dist/types/components/DataTable/controls/ReloadButton.d.ts +4 -0
- package/dist/types/components/DataTable/controls/ResetFilteringButton.d.ts +1 -0
- package/dist/types/components/DataTable/controls/ResetSelectionButton.d.ts +1 -0
- package/dist/types/components/DataTable/controls/ResetSortingButton.d.ts +1 -0
- package/dist/types/components/DataTable/controls/RowCountText.d.ts +1 -0
- package/dist/types/components/DataTable/controls/SelectAllRowsToggle.d.ts +8 -0
- package/dist/types/components/DataTable/controls/TableControls.d.ts +29 -0
- package/dist/types/components/DataTable/controls/TableFilterTags.d.ts +1 -0
- package/dist/types/components/DataTable/controls/TableFilters.d.ts +1 -0
- package/dist/types/components/DataTable/controls/TableSelector.d.ts +1 -0
- package/dist/types/components/DataTable/controls/TableSorter.d.ts +1 -0
- package/dist/types/components/DataTable/controls/TableViewer.d.ts +1 -0
- package/dist/types/components/DataTable/controls/ViewDialog.d.ts +5 -0
- package/dist/types/components/DataTable/display/CardHeader.d.ts +13 -0
- package/dist/types/components/DataTable/display/DataDisplay.d.ts +6 -0
- package/dist/types/components/DataTable/display/EmptyState.d.ts +5 -0
- package/dist/types/components/DataTable/display/ErrorAlert.d.ts +4 -0
- package/dist/types/components/DataTable/display/RecordDisplay.d.ts +9 -0
- package/dist/types/components/DataTable/display/Table.d.ts +10 -0
- package/dist/types/components/DataTable/display/TableBody.d.ts +20 -0
- package/dist/types/components/DataTable/display/TableCardContainer.d.ts +10 -0
- package/dist/types/components/DataTable/display/TableCards.d.ts +11 -0
- package/dist/types/components/DataTable/display/TableComponent.d.ts +6 -0
- package/dist/types/components/DataTable/display/TableDataDisplay.d.ts +6 -0
- package/dist/types/components/DataTable/display/TableFooter.d.ts +5 -0
- package/dist/types/components/DataTable/display/TableHeader.d.ts +51 -0
- package/dist/types/components/DataTable/display/TableLoadingComponent.d.ts +5 -0
- package/dist/types/components/DataTable/display/TextCell.d.ts +10 -0
- package/dist/types/components/DataTable/useDataTable.d.ts +1 -1
- 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 +3 -1
- package/dist/types/components/Form/components/core/DefaultForm.d.ts +2 -1
- package/dist/types/components/Form/components/core/FormRoot.d.ts +4 -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 +2 -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/validation.d.ts +104 -0
- package/dist/types/components/TimePicker/TimePicker.d.ts +20 -0
- package/dist/types/index.d.ts +48 -33
- package/package.json +9 -2
package/dist/index.js
CHANGED
|
@@ -30,7 +30,12 @@ var reactI18next = require('react-i18next');
|
|
|
30
30
|
var axios = require('axios');
|
|
31
31
|
var reactHookForm = require('react-hook-form');
|
|
32
32
|
var dayjs = require('dayjs');
|
|
33
|
+
var utc = require('dayjs/plugin/utc');
|
|
34
|
+
var timezone = require('dayjs/plugin/timezone');
|
|
33
35
|
var ti = require('react-icons/ti');
|
|
36
|
+
var Ajv = require('ajv');
|
|
37
|
+
var addFormats = require('ajv-formats');
|
|
38
|
+
var addErrors = require('ajv-errors');
|
|
34
39
|
|
|
35
40
|
function _interopNamespaceDefault(e) {
|
|
36
41
|
var n = Object.create(null);
|
|
@@ -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,6 +2912,23 @@ function DataTable({ columns, data, enableRowSelection = true, enableMultiRowSel
|
|
|
2814
2912
|
setGlobalFilter,
|
|
2815
2913
|
type: "client",
|
|
2816
2914
|
translate,
|
|
2915
|
+
columns: columns,
|
|
2916
|
+
sorting,
|
|
2917
|
+
setSorting,
|
|
2918
|
+
columnFilters,
|
|
2919
|
+
setColumnFilters,
|
|
2920
|
+
pagination,
|
|
2921
|
+
setPagination,
|
|
2922
|
+
rowSelection,
|
|
2923
|
+
setRowSelection,
|
|
2924
|
+
columnOrder,
|
|
2925
|
+
setColumnOrder,
|
|
2926
|
+
density,
|
|
2927
|
+
setDensity,
|
|
2928
|
+
columnVisibility,
|
|
2929
|
+
setColumnVisibility,
|
|
2930
|
+
data,
|
|
2931
|
+
tableLabel,
|
|
2817
2932
|
}, children: children }));
|
|
2818
2933
|
}
|
|
2819
2934
|
|
|
@@ -2828,10 +2943,26 @@ function DataTable({ columns, data, enableRowSelection = true, enableMultiRowSel
|
|
|
2828
2943
|
*
|
|
2829
2944
|
* @link https://tanstack.com/table/latest/docs/guide/column-defs
|
|
2830
2945
|
*/
|
|
2831
|
-
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
|
+
}, }) {
|
|
2832
2963
|
const table = reactTable.useReactTable({
|
|
2833
2964
|
_features: [DensityFeature],
|
|
2834
|
-
data: query.data?.data ?? [],
|
|
2965
|
+
data: (query.data?.data ?? []),
|
|
2835
2966
|
rowCount: query.data?.count ?? 0,
|
|
2836
2967
|
columns: columns,
|
|
2837
2968
|
getCoreRowModel: reactTable.getCoreRowModel(),
|
|
@@ -2877,103 +3008,31 @@ function DataTableServer({ columns, enableRowSelection = true, enableMultiRowSel
|
|
|
2877
3008
|
// for tanstack-table ts bug end
|
|
2878
3009
|
});
|
|
2879
3010
|
return (jsxRuntime.jsx(DataTableContext.Provider, { value: {
|
|
2880
|
-
table:
|
|
3011
|
+
table: table,
|
|
2881
3012
|
globalFilter,
|
|
2882
3013
|
setGlobalFilter,
|
|
2883
3014
|
type: "server",
|
|
2884
3015
|
translate,
|
|
3016
|
+
columns: columns,
|
|
3017
|
+
sorting,
|
|
3018
|
+
setSorting,
|
|
3019
|
+
columnFilters,
|
|
3020
|
+
setColumnFilters,
|
|
3021
|
+
pagination,
|
|
3022
|
+
setPagination,
|
|
3023
|
+
rowSelection,
|
|
3024
|
+
setRowSelection,
|
|
3025
|
+
columnOrder,
|
|
3026
|
+
setColumnOrder,
|
|
3027
|
+
density,
|
|
3028
|
+
setDensity,
|
|
3029
|
+
columnVisibility,
|
|
3030
|
+
setColumnVisibility,
|
|
3031
|
+
data: query.data?.data ?? [],
|
|
3032
|
+
tableLabel,
|
|
2885
3033
|
}, children: jsxRuntime.jsx(DataTableServerContext.Provider, { value: { url, query }, children: children }) }));
|
|
2886
3034
|
}
|
|
2887
3035
|
|
|
2888
|
-
const Checkbox = React__namespace.forwardRef(function Checkbox(props, ref) {
|
|
2889
|
-
const { icon, children, inputProps, rootRef, ...rest } = props;
|
|
2890
|
-
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 }))] }));
|
|
2891
|
-
});
|
|
2892
|
-
|
|
2893
|
-
const TableBody = ({ pinnedBgColor = { light: "gray.50", dark: "gray.700" }, showSelector = false, alwaysShowSelector = true, canResize = true, }) => {
|
|
2894
|
-
"use no memo";
|
|
2895
|
-
const { table } = useDataTableContext();
|
|
2896
|
-
const SELECTION_BOX_WIDTH = 20;
|
|
2897
|
-
const [hoveredRow, setHoveredRow] = React.useState(-1);
|
|
2898
|
-
const handleRowHover = (index) => {
|
|
2899
|
-
setHoveredRow(index);
|
|
2900
|
-
};
|
|
2901
|
-
const getTdProps = (cell) => {
|
|
2902
|
-
const tdProps = cell.column.getIsPinned()
|
|
2903
|
-
? {
|
|
2904
|
-
left: showSelector
|
|
2905
|
-
? `${cell.column.getStart("left") + SELECTION_BOX_WIDTH + table.getDensityValue() * 2}px`
|
|
2906
|
-
: `${cell.column.getStart("left")}px`,
|
|
2907
|
-
background: pinnedBgColor.light,
|
|
2908
|
-
position: "sticky",
|
|
2909
|
-
zIndex: -1,
|
|
2910
|
-
_dark: {
|
|
2911
|
-
backgroundColor: pinnedBgColor.dark,
|
|
2912
|
-
},
|
|
2913
|
-
}
|
|
2914
|
-
: {};
|
|
2915
|
-
return tdProps;
|
|
2916
|
-
};
|
|
2917
|
-
const getTrProps = ({ hoveredRow, index, }) => {
|
|
2918
|
-
if (hoveredRow === -1) {
|
|
2919
|
-
return {};
|
|
2920
|
-
}
|
|
2921
|
-
if (hoveredRow === index) {
|
|
2922
|
-
return {
|
|
2923
|
-
opacity: "1",
|
|
2924
|
-
};
|
|
2925
|
-
}
|
|
2926
|
-
return {
|
|
2927
|
-
opacity: "0.8",
|
|
2928
|
-
};
|
|
2929
|
-
};
|
|
2930
|
-
return (jsxRuntime.jsx(react.Table.Body, { children: table.getRowModel().rows.map((row, index) => {
|
|
2931
|
-
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) => {
|
|
2932
|
-
return (jsxRuntime.jsx(react.Table.Cell, { padding: `${table.getDensityValue()}px`,
|
|
2933
|
-
// styling resize and pinning start
|
|
2934
|
-
flex: `${canResize ? "0" : "1"} 0 ${cell.column.getSize()}px`, backgroundColor: "white", ...getTdProps(cell), _dark: {
|
|
2935
|
-
backgroundColor: "gray.950",
|
|
2936
|
-
}, children: reactTable.flexRender(cell.column.columnDef.cell, cell.getContext()) }, `chakra-table-rowcell-${cell.id}-${index}`));
|
|
2937
|
-
})] }, `chakra-table-row-${row.id}`));
|
|
2938
|
-
}) }));
|
|
2939
|
-
};
|
|
2940
|
-
const TableRowSelector = ({ index, row, hoveredRow, pinnedBgColor = { light: "gray.50", dark: "gray.700" }, alwaysShowSelector = true, }) => {
|
|
2941
|
-
const { table } = useDataTableContext();
|
|
2942
|
-
const SELECTION_BOX_WIDTH = 20;
|
|
2943
|
-
const isCheckBoxVisible = (current_index, current_row) => {
|
|
2944
|
-
if (alwaysShowSelector) {
|
|
2945
|
-
return true;
|
|
2946
|
-
}
|
|
2947
|
-
if (current_row.getIsSelected()) {
|
|
2948
|
-
return true;
|
|
2949
|
-
}
|
|
2950
|
-
if (hoveredRow == current_index) {
|
|
2951
|
-
return true;
|
|
2952
|
-
}
|
|
2953
|
-
return false;
|
|
2954
|
-
};
|
|
2955
|
-
return (jsxRuntime.jsxs(react.Table.Cell, { padding: `${table.getDensityValue()}px`, ...(table.getIsSomeColumnsPinned("left")
|
|
2956
|
-
? {
|
|
2957
|
-
left: `0px`,
|
|
2958
|
-
backgroundColor: pinnedBgColor.light,
|
|
2959
|
-
position: "sticky",
|
|
2960
|
-
zIndex: 1,
|
|
2961
|
-
_dark: { backgroundColor: pinnedBgColor.dark },
|
|
2962
|
-
}
|
|
2963
|
-
: {}),
|
|
2964
|
-
// styling resize and pinning end
|
|
2965
|
-
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(),
|
|
2966
|
-
disabled: !row.getCanSelect(),
|
|
2967
|
-
onChange: row.getToggleSelectedHandler() }) }))] }));
|
|
2968
|
-
};
|
|
2969
|
-
|
|
2970
|
-
const Tooltip = React__namespace.forwardRef(function Tooltip(props, ref) {
|
|
2971
|
-
const { showArrow, children, disabled, portalled, content, contentProps, portalRef, ...rest } = props;
|
|
2972
|
-
if (disabled)
|
|
2973
|
-
return children;
|
|
2974
|
-
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] }) }) })] }));
|
|
2975
|
-
});
|
|
2976
|
-
|
|
2977
3036
|
const InputGroup = React__namespace.forwardRef(function InputGroup(props, ref) {
|
|
2978
3037
|
const { startElement, startElementProps, endElement, endElementProps, children, startOffset = "6px", endOffset = "6px", ...rest } = props;
|
|
2979
3038
|
return (jsxRuntime.jsxs(react.Group, { ref: ref, ...rest, children: [startElement && (jsxRuntime.jsx(react.InputElement, { pointerEvents: "none", ...startElementProps, children: startElement })), React__namespace.cloneElement(children, {
|
|
@@ -2987,7 +3046,8 @@ const InputGroup = React__namespace.forwardRef(function InputGroup(props, ref) {
|
|
|
2987
3046
|
});
|
|
2988
3047
|
|
|
2989
3048
|
const GlobalFilter = () => {
|
|
2990
|
-
const { table } = useDataTableContext();
|
|
3049
|
+
const { table, tableLabel } = useDataTableContext();
|
|
3050
|
+
const { globalFilterPlaceholder } = tableLabel;
|
|
2991
3051
|
const [searchTerm, setSearchTerm] = React.useState("");
|
|
2992
3052
|
const debouncedSearchTerm = usehooks.useDebounce(searchTerm, 500);
|
|
2993
3053
|
React.useEffect(() => {
|
|
@@ -2996,42 +3056,31 @@ const GlobalFilter = () => {
|
|
|
2996
3056
|
};
|
|
2997
3057
|
searchHN();
|
|
2998
3058
|
}, [debouncedSearchTerm]);
|
|
2999
|
-
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) => {
|
|
3000
3060
|
setSearchTerm(e.target.value);
|
|
3001
3061
|
} }) }) }));
|
|
3002
3062
|
};
|
|
3003
3063
|
|
|
3004
|
-
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", }) => {
|
|
3005
3072
|
const { url } = useDataTableServerContext();
|
|
3006
3073
|
const queryClient = reactQuery.useQueryClient();
|
|
3074
|
+
const { tableLabel } = useDataTableContext();
|
|
3075
|
+
const { reloadTooltip, reloadButtonText } = tableLabel;
|
|
3007
3076
|
if (variant === "icon") {
|
|
3008
|
-
return (jsxRuntime.jsx(Tooltip, { showArrow: true, content:
|
|
3077
|
+
return (jsxRuntime.jsx(Tooltip, { showArrow: true, content: reloadTooltip, children: jsxRuntime.jsx(Button, { variant: "ghost", onClick: () => {
|
|
3009
3078
|
queryClient.invalidateQueries({ queryKey: [url] });
|
|
3010
3079
|
}, "aria-label": "refresh", children: jsxRuntime.jsx(io5.IoReload, {}) }) }));
|
|
3011
3080
|
}
|
|
3012
3081
|
return (jsxRuntime.jsxs(Button, { variant: "ghost", onClick: () => {
|
|
3013
3082
|
queryClient.invalidateQueries({ queryKey: [url] });
|
|
3014
|
-
}, children: [jsxRuntime.jsx(io5.IoReload, {}), " ",
|
|
3015
|
-
};
|
|
3016
|
-
|
|
3017
|
-
const FilterOptions = ({ column }) => {
|
|
3018
|
-
const { table } = useDataTableContext();
|
|
3019
|
-
const tableColumn = table.getColumn(column);
|
|
3020
|
-
const options = tableColumn?.columnDef.meta?.filterOptions ?? [];
|
|
3021
|
-
return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: options.map((option) => {
|
|
3022
|
-
const selected = table.getColumn(column)?.getFilterValue() === option;
|
|
3023
|
-
return (jsxRuntime.jsxs(react.Button, { size: "sm", onClick: () => {
|
|
3024
|
-
if (selected) {
|
|
3025
|
-
table.setColumnFilters((state) => {
|
|
3026
|
-
return state.filter((filter) => {
|
|
3027
|
-
return filter.id !== column;
|
|
3028
|
-
});
|
|
3029
|
-
});
|
|
3030
|
-
return;
|
|
3031
|
-
}
|
|
3032
|
-
table.getColumn(column)?.setFilterValue(option);
|
|
3033
|
-
}, variant: selected ? "solid" : "outline", display: "flex", gap: "0.25rem", children: [option, selected && jsxRuntime.jsx(md.MdClose, {})] }, option));
|
|
3034
|
-
}) }));
|
|
3083
|
+
}, children: [jsxRuntime.jsx(io5.IoReload, {}), " ", reloadButtonText] }));
|
|
3035
3084
|
};
|
|
3036
3085
|
|
|
3037
3086
|
const TableFilterTags = () => {
|
|
@@ -3045,16 +3094,99 @@ const TableFilterTags = () => {
|
|
|
3045
3094
|
}) }));
|
|
3046
3095
|
};
|
|
3047
3096
|
|
|
3048
|
-
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,
|
|
3049
|
-
const {
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
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() }) }));
|
|
3055
3187
|
};
|
|
3056
3188
|
|
|
3057
|
-
const TableFooter = ({
|
|
3189
|
+
const TableFooter = ({ showSelector = false, alwaysShowSelector = true, }) => {
|
|
3058
3190
|
const table = useDataTableContext().table;
|
|
3059
3191
|
const SELECTION_BOX_WIDTH = 20;
|
|
3060
3192
|
const [hoveredCheckBox, setHoveredCheckBox] = React.useState(false);
|
|
@@ -3073,65 +3205,62 @@ const TableFooter = ({ pinnedBgColor = { light: "gray.50", dark: "gray.700" }, s
|
|
|
3073
3205
|
}
|
|
3074
3206
|
return false;
|
|
3075
3207
|
};
|
|
3076
|
-
|
|
3077
|
-
const thProps = header.column.getIsPinned()
|
|
3078
|
-
? {
|
|
3079
|
-
left: showSelector
|
|
3080
|
-
? `${header.getStart("left") + SELECTION_BOX_WIDTH + table.getDensityValue() * 2}px`
|
|
3081
|
-
: `${header.getStart("left") + table.getDensityValue() * 2}px`,
|
|
3082
|
-
background: pinnedBgColor.light,
|
|
3083
|
-
position: "sticky",
|
|
3084
|
-
zIndex: 1,
|
|
3085
|
-
_dark: {
|
|
3086
|
-
backgroundColor: pinnedBgColor.dark,
|
|
3087
|
-
},
|
|
3088
|
-
}
|
|
3089
|
-
: {};
|
|
3090
|
-
return thProps;
|
|
3091
|
-
};
|
|
3092
|
-
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
|
|
3093
|
-
// styling resize and pinning start
|
|
3094
|
-
, {
|
|
3095
|
-
// styling resize and pinning start
|
|
3096
|
-
padding: `${table.getDensityValue()}px`, ...(table.getIsSomeColumnsPinned("left")
|
|
3097
|
-
? {
|
|
3098
|
-
left: `0px`,
|
|
3099
|
-
backgroundColor: pinnedBgColor.light,
|
|
3100
|
-
position: "sticky",
|
|
3101
|
-
zIndex: 1,
|
|
3102
|
-
_dark: { backgroundColor: pinnedBgColor.dark },
|
|
3103
|
-
}
|
|
3104
|
-
: {}),
|
|
3105
|
-
// styling resize and pinning end
|
|
3106
|
-
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(),
|
|
3107
3209
|
// indeterminate: table.getIsSomeRowsSelected(),
|
|
3108
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}`,
|
|
3109
3211
|
// styling resize and pinning start
|
|
3110
|
-
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
|
|
3111
3213
|
? null
|
|
3112
|
-
: 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 && (
|
|
3113
|
-
// <UpDownIcon />
|
|
3114
|
-
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}`))) }));
|
|
3115
3215
|
};
|
|
3116
3216
|
|
|
3117
|
-
|
|
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 = {}, }) => {
|
|
3118
3256
|
const { table } = useDataTableContext();
|
|
3119
3257
|
const SELECTION_BOX_WIDTH = 20;
|
|
3120
|
-
|
|
3121
|
-
const
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
return true;
|
|
3127
|
-
}
|
|
3128
|
-
if (table.getIsAllRowsSelected()) {
|
|
3129
|
-
return true;
|
|
3130
|
-
}
|
|
3131
|
-
if (hoveredCheckBox) {
|
|
3132
|
-
return true;
|
|
3133
|
-
}
|
|
3134
|
-
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];
|
|
3135
3264
|
};
|
|
3136
3265
|
const getThProps = (header) => {
|
|
3137
3266
|
const thProps = header.column.getIsPinned()
|
|
@@ -3139,12 +3268,8 @@ const TableHeader = ({ canResize = true, pinnedBgColor = { light: "gray.50", dar
|
|
|
3139
3268
|
left: showSelector
|
|
3140
3269
|
? `${header.getStart("left") + SELECTION_BOX_WIDTH + table.getDensityValue() * 2}px`
|
|
3141
3270
|
: `${header.getStart("left")}px`,
|
|
3142
|
-
background: pinnedBgColor.light,
|
|
3143
3271
|
position: "sticky",
|
|
3144
3272
|
zIndex: 100 + 1,
|
|
3145
|
-
_dark: {
|
|
3146
|
-
backgroundColor: pinnedBgColor.dark,
|
|
3147
|
-
},
|
|
3148
3273
|
}
|
|
3149
3274
|
: {};
|
|
3150
3275
|
return thProps;
|
|
@@ -3153,21 +3278,13 @@ const TableHeader = ({ canResize = true, pinnedBgColor = { light: "gray.50", dar
|
|
|
3153
3278
|
position: "sticky",
|
|
3154
3279
|
top: 0,
|
|
3155
3280
|
};
|
|
3156
|
-
return (jsxRuntime.jsx(react.Table.Header, { ...(isSticky ? stickyProps : {}), ...
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
zIndex: 1,
|
|
3164
|
-
_dark: { backgroundColor: pinnedBgColor.dark },
|
|
3165
|
-
}
|
|
3166
|
-
: {}),
|
|
3167
|
-
// styling resize and pinning end
|
|
3168
|
-
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(),
|
|
3169
|
-
// indeterminate: table.getIsSomeRowsSelected(),
|
|
3170
|
-
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) => {
|
|
3171
3288
|
const resizeProps = {
|
|
3172
3289
|
onMouseDown: header.getResizeHandler(),
|
|
3173
3290
|
onTouchStart: header.getResizeHandler(),
|
|
@@ -3175,18 +3292,32 @@ const TableHeader = ({ canResize = true, pinnedBgColor = { light: "gray.50", dar
|
|
|
3175
3292
|
};
|
|
3176
3293
|
return (jsxRuntime.jsxs(react.Table.ColumnHeader, { padding: 0, columnSpan: `${header.colSpan}`,
|
|
3177
3294
|
// styling resize and pinning start
|
|
3178
|
-
flex: `${canResize ? "0" : "1"} 0 ${header.column.getSize()}px`, display: "grid", gridTemplateColumns: "1fr auto", zIndex: 1500 + header.index,
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
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",
|
|
3182
3313
|
},
|
|
3183
3314
|
}, children: jsxRuntime.jsxs(react.Flex, { gap: "0.5rem", alignItems: "center", children: [header.isPlaceholder
|
|
3184
3315
|
? null
|
|
3185
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: () => {
|
|
3186
3317
|
header.column.pin("left");
|
|
3187
|
-
}, 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: () => {
|
|
3188
3319
|
header.column.pin(false);
|
|
3189
|
-
}, 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: () => {
|
|
3190
3321
|
table.setSorting((state) => {
|
|
3191
3322
|
return [
|
|
3192
3323
|
...state.filter((column) => {
|
|
@@ -3195,7 +3326,7 @@ const TableHeader = ({ canResize = true, pinnedBgColor = { light: "gray.50", dar
|
|
|
3195
3326
|
{ id: header.id, desc: false },
|
|
3196
3327
|
];
|
|
3197
3328
|
});
|
|
3198
|
-
}, 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: () => {
|
|
3199
3330
|
table.setSorting((state) => {
|
|
3200
3331
|
return [
|
|
3201
3332
|
...state.filter((column) => {
|
|
@@ -3204,42 +3335,30 @@ const TableHeader = ({ canResize = true, pinnedBgColor = { light: "gray.50", dar
|
|
|
3204
3335
|
{ id: header.id, desc: true },
|
|
3205
3336
|
];
|
|
3206
3337
|
});
|
|
3207
|
-
}, 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: () => {
|
|
3208
3339
|
header.column.clearSorting();
|
|
3209
|
-
}, 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: {
|
|
3210
3343
|
borderRightColor: header.column.getIsResizing()
|
|
3211
|
-
? "
|
|
3212
|
-
: "
|
|
3344
|
+
? "colorPalette.700"
|
|
3345
|
+
: "colorPalette.400",
|
|
3213
3346
|
}, ...resizeProps }))] }, `chakra-table-header-${header.id}`));
|
|
3214
3347
|
})] }, `chakra-table-headergroup-${headerGroup.id}`))) }));
|
|
3215
3348
|
};
|
|
3216
3349
|
|
|
3217
|
-
const
|
|
3218
|
-
const { title, description, icon, children, ...rest } = props;
|
|
3219
|
-
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] }) }));
|
|
3220
|
-
});
|
|
3221
|
-
|
|
3222
|
-
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" })] }) }));
|
|
3223
|
-
const Table = ({ children, emptyComponent = EmptyResult, canResize = true, ...props }) => {
|
|
3224
|
-
const { table } = useDataTableContext();
|
|
3225
|
-
if (table.getRowModel().rows.length <= 0) {
|
|
3226
|
-
return emptyComponent;
|
|
3227
|
-
}
|
|
3228
|
-
return (jsxRuntime.jsx(react.Table.Root, { stickyHeader: true, variant: "outline", width: canResize ? table.getCenterTotalSize() : undefined, display: "grid", alignContent: "start", overflowY: "auto", ...props, children: children }));
|
|
3229
|
-
};
|
|
3230
|
-
|
|
3231
|
-
const DefaultTable = ({ showFooter = false, tableProps = {}, tableHeaderProps = {}, tableBodyProps = {}, controlProps = {}, tableFooterProps = {}, variant = "", }) => {
|
|
3350
|
+
const DefaultTable = ({ showFooter = false, tableProps = {}, tableHeaderProps = {}, tableBodyProps = {}, tableFooterProps = {}, controlProps = {}, variant = "", }) => {
|
|
3232
3351
|
if (variant === "greedy") {
|
|
3233
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 }))] }) }));
|
|
3234
3353
|
}
|
|
3235
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 })] }) }));
|
|
3236
3355
|
};
|
|
3237
3356
|
|
|
3238
|
-
const TableCardContainer = ({ children, variant = "", ...props }) => {
|
|
3357
|
+
const TableCardContainer = ({ children, variant = "", gap = "1rem", gridTemplateColumns = "repeat(auto-fit, minmax(20rem, 1fr))", direction = "row", ...props }) => {
|
|
3239
3358
|
if (variant === "carousel") {
|
|
3240
|
-
return (jsxRuntime.jsx(react.Flex, { overflow: "
|
|
3359
|
+
return (jsxRuntime.jsx(react.Flex, { overflow: "auto", gap: gap, direction: direction, ...props, children: children }));
|
|
3241
3360
|
}
|
|
3242
|
-
return (jsxRuntime.jsx(react.Grid, { gridTemplateColumns:
|
|
3361
|
+
return (jsxRuntime.jsx(react.Grid, { gridTemplateColumns: gridTemplateColumns, gap: gap, ...props, children: children }));
|
|
3243
3362
|
};
|
|
3244
3363
|
|
|
3245
3364
|
const DefaultCardTitle = () => {
|
|
@@ -3268,8 +3387,8 @@ const TableComponent = ({ render = () => {
|
|
|
3268
3387
|
};
|
|
3269
3388
|
|
|
3270
3389
|
const TableLoadingComponent = ({ render, }) => {
|
|
3271
|
-
const {
|
|
3272
|
-
return jsxRuntime.jsx(jsxRuntime.Fragment, { children: render(
|
|
3390
|
+
const { query } = useDataTableServerContext();
|
|
3391
|
+
return jsxRuntime.jsx(jsxRuntime.Fragment, { children: render(query.isLoading) });
|
|
3273
3392
|
};
|
|
3274
3393
|
|
|
3275
3394
|
const SelectAllRowsToggle = ({ selectAllIcon = jsxRuntime.jsx(md.MdOutlineChecklist, {}), clearAllIcon = jsxRuntime.jsx(md.MdClear, {}), selectAllText = "", clearAllText = "", }) => {
|
|
@@ -3488,6 +3607,70 @@ const getColumns = ({ schema, include = [], ignore = [], width = [], meta = {},
|
|
|
3488
3607
|
return columns;
|
|
3489
3608
|
};
|
|
3490
3609
|
|
|
3610
|
+
const TableDataDisplay = ({ colorPalette, emptyComponent, }) => {
|
|
3611
|
+
const { columns, translate, data } = useDataTableContext();
|
|
3612
|
+
const columnsMap = Object.fromEntries(columns.map((def) => {
|
|
3613
|
+
const { accessorKey, id } = def;
|
|
3614
|
+
if (accessorKey) {
|
|
3615
|
+
return [accessorKey, def];
|
|
3616
|
+
}
|
|
3617
|
+
return [id, def];
|
|
3618
|
+
}));
|
|
3619
|
+
const columnHeaders = Object.keys(columnsMap);
|
|
3620
|
+
const totalWidths = columns
|
|
3621
|
+
.map(({ size }) => {
|
|
3622
|
+
if (!!size === false) {
|
|
3623
|
+
return 0;
|
|
3624
|
+
}
|
|
3625
|
+
if (typeof size === "number") {
|
|
3626
|
+
return size;
|
|
3627
|
+
}
|
|
3628
|
+
return 0;
|
|
3629
|
+
})
|
|
3630
|
+
.reduce((previous, current) => previous + current, 0);
|
|
3631
|
+
const columnWidths = columns
|
|
3632
|
+
.map(({ size }) => {
|
|
3633
|
+
if (!!size === false) {
|
|
3634
|
+
return "1fr";
|
|
3635
|
+
}
|
|
3636
|
+
return `minmax(${size}px, ${(size / totalWidths) * 100}%)`;
|
|
3637
|
+
})
|
|
3638
|
+
.join(" ");
|
|
3639
|
+
console.log({ columnWidths }, "hadfg");
|
|
3640
|
+
const cellProps = {
|
|
3641
|
+
flex: "1 0 0%",
|
|
3642
|
+
overflow: "auto",
|
|
3643
|
+
paddingX: "2",
|
|
3644
|
+
py: "1",
|
|
3645
|
+
color: { base: "colorPalette.900", _dark: "colorPalette.100" },
|
|
3646
|
+
bgColor: { base: "colorPalette.50", _dark: "colorPalette.950" },
|
|
3647
|
+
borderBottomColor: { base: "colorPalette.200", _dark: "colorPalette.800" },
|
|
3648
|
+
borderBottomWidth: "1px",
|
|
3649
|
+
...{ colorPalette },
|
|
3650
|
+
};
|
|
3651
|
+
if (data.length <= 0) {
|
|
3652
|
+
return jsxRuntime.jsx(jsxRuntime.Fragment, { children: emptyComponent });
|
|
3653
|
+
}
|
|
3654
|
+
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) => {
|
|
3655
|
+
return (jsxRuntime.jsx(react.Box, { flex: "1 0 0%", paddingX: "2", py: "1", overflow: "auto", textOverflow: "ellipsis", children: translate.t(`column_header.${header}`) }));
|
|
3656
|
+
}) }), data.map((record) => {
|
|
3657
|
+
return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: columnHeaders.map((header) => {
|
|
3658
|
+
const { cell } = columnsMap[header];
|
|
3659
|
+
const value = record[header];
|
|
3660
|
+
if (!!record === false) {
|
|
3661
|
+
return (jsxRuntime.jsx(react.Box, { ...cellProps, children: translate.t(`column_cell.placeholder`) }));
|
|
3662
|
+
}
|
|
3663
|
+
if (cell) {
|
|
3664
|
+
return (jsxRuntime.jsx(react.Box, { ...cellProps, children: cell({ row: { original: record } }) }));
|
|
3665
|
+
}
|
|
3666
|
+
if (typeof value === "object") {
|
|
3667
|
+
return (jsxRuntime.jsx(react.Box, { ...cellProps, children: jsxRuntime.jsx(RecordDisplay, { object: value }) }));
|
|
3668
|
+
}
|
|
3669
|
+
return jsxRuntime.jsx(react.Box, { ...cellProps, children: value });
|
|
3670
|
+
}) }));
|
|
3671
|
+
})] }));
|
|
3672
|
+
};
|
|
3673
|
+
|
|
3491
3674
|
const AccordionItemTrigger = React__namespace.forwardRef(function AccordionItemTrigger(props, ref) {
|
|
3492
3675
|
const { children, indicatorPlacement = "end", ...rest } = props;
|
|
3493
3676
|
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, {}) }))] }));
|
|
@@ -3509,6 +3692,7 @@ const SchemaFormContext = React.createContext({
|
|
|
3509
3692
|
onSubmit: async () => { },
|
|
3510
3693
|
rowNumber: 0,
|
|
3511
3694
|
requestOptions: {},
|
|
3695
|
+
timezone: 'Asia/Hong_Kong',
|
|
3512
3696
|
});
|
|
3513
3697
|
|
|
3514
3698
|
const useSchemaContext = () => {
|
|
@@ -3534,7 +3718,7 @@ const idPickerSanityCheck = (column, foreign_key) => {
|
|
|
3534
3718
|
throw new Error(`The key column does not exist in properties of column ${column} when using id-picker.`);
|
|
3535
3719
|
}
|
|
3536
3720
|
};
|
|
3537
|
-
const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, children, order = [], ignore = [], include = [], onSubmit = undefined, rowNumber = undefined, requestOptions = {}, getUpdatedData = () => { }, }) => {
|
|
3721
|
+
const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, children, order = [], ignore = [], include = [], onSubmit = undefined, rowNumber = undefined, requestOptions = {}, getUpdatedData = () => { }, customErrorRenderer, }) => {
|
|
3538
3722
|
const [isSuccess, setIsSuccess] = React.useState(false);
|
|
3539
3723
|
const [isError, setIsError] = React.useState(false);
|
|
3540
3724
|
const [isSubmiting, setIsSubmiting] = React.useState(false);
|
|
@@ -3567,11 +3751,12 @@ const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, childre
|
|
|
3567
3751
|
error,
|
|
3568
3752
|
setError,
|
|
3569
3753
|
getUpdatedData,
|
|
3754
|
+
customErrorRenderer,
|
|
3570
3755
|
}, children: jsxRuntime.jsx(reactHookForm.FormProvider, { ...form, children: children }) }));
|
|
3571
3756
|
};
|
|
3572
3757
|
|
|
3573
3758
|
function removeIndex(str) {
|
|
3574
|
-
return str.replace(/\.\d+\./g,
|
|
3759
|
+
return str.replace(/\.\d+\./g, ".");
|
|
3575
3760
|
}
|
|
3576
3761
|
|
|
3577
3762
|
const ArrayRenderer = ({ schema, column, prefix, }) => {
|
|
@@ -3583,13 +3768,17 @@ const ArrayRenderer = ({ schema, column, prefix, }) => {
|
|
|
3583
3768
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
3584
3769
|
const { formState: { errors }, setValue, watch, } = reactHookForm.useFormContext();
|
|
3585
3770
|
const fields = (watch(colLabel) ?? []);
|
|
3586
|
-
return (jsxRuntime.jsxs(react.
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3771
|
+
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: {
|
|
3772
|
+
base: "colorPalette.200",
|
|
3773
|
+
_dark: "colorPalette.800",
|
|
3774
|
+
}, children: [jsxRuntime.jsx(react.Grid, { gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: jsxRuntime.jsx(SchemaRenderer, { column: `${index}`,
|
|
3775
|
+
prefix: `${colLabel}.`,
|
|
3776
|
+
// @ts-expect-error find suitable types
|
|
3777
|
+
schema: { showLabel: false, ...(items ?? {}) } }) }), jsxRuntime.jsx(react.Flex, { justifyContent: "end", children: jsxRuntime.jsx(react.Button, { variant: "ghost", onClick: () => {
|
|
3778
|
+
setValue(colLabel, fields.filter((_, curIndex) => {
|
|
3779
|
+
return curIndex !== index;
|
|
3780
|
+
}));
|
|
3781
|
+
}, children: jsxRuntime.jsx(react.Icon, { children: jsxRuntime.jsx(cg.CgTrash, {}) }) }) })] }, `${colLabel}.${index}`))) }), jsxRuntime.jsx(react.Flex, { children: jsxRuntime.jsx(react.Button, { onClick: () => {
|
|
3593
3782
|
if (type === "number") {
|
|
3594
3783
|
setValue(colLabel, [...fields, 0]);
|
|
3595
3784
|
return;
|
|
@@ -3603,7 +3792,7 @@ const ArrayRenderer = ({ schema, column, prefix, }) => {
|
|
|
3603
3792
|
return;
|
|
3604
3793
|
}
|
|
3605
3794
|
setValue(colLabel, [...fields, {}]);
|
|
3606
|
-
}, children: translate.t(removeIndex(`${colLabel}.add`)) }) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.
|
|
3795
|
+
}, children: translate.t(removeIndex(`${colLabel}.add`)) }) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
3607
3796
|
};
|
|
3608
3797
|
|
|
3609
3798
|
const Field = React__namespace.forwardRef(function Field(props, ref) {
|
|
@@ -3614,37 +3803,36 @@ const Field = React__namespace.forwardRef(function Field(props, ref) {
|
|
|
3614
3803
|
const BooleanPicker = ({ schema, column, prefix }) => {
|
|
3615
3804
|
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
3616
3805
|
const { translate } = useSchemaContext();
|
|
3617
|
-
const { required, gridColumn, gridRow } = schema;
|
|
3806
|
+
const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
|
|
3618
3807
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
3619
3808
|
const colLabel = `${prefix}${column}`;
|
|
3620
3809
|
const value = watch(colLabel);
|
|
3621
|
-
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.
|
|
3810
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
3622
3811
|
gridRow, children: [jsxRuntime.jsx(CheckboxCard, { checked: value, variant: "surface", onChange: () => {
|
|
3623
3812
|
setValue(colLabel, !value);
|
|
3624
|
-
} }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.
|
|
3813
|
+
} }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
3814
|
+
};
|
|
3815
|
+
|
|
3816
|
+
const CustomInput = ({ column, schema, prefix }) => {
|
|
3817
|
+
const formContext = reactHookForm.useFormContext();
|
|
3818
|
+
const { inputRender } = schema;
|
|
3819
|
+
return (inputRender &&
|
|
3820
|
+
inputRender({
|
|
3821
|
+
column,
|
|
3822
|
+
schema,
|
|
3823
|
+
prefix,
|
|
3824
|
+
formContext,
|
|
3825
|
+
}));
|
|
3625
3826
|
};
|
|
3626
3827
|
|
|
3627
|
-
const monthNamesShort = [
|
|
3628
|
-
"Jan",
|
|
3629
|
-
"Feb",
|
|
3630
|
-
"Mar",
|
|
3631
|
-
"Apr",
|
|
3632
|
-
"May",
|
|
3633
|
-
"Jun",
|
|
3634
|
-
"Jul",
|
|
3635
|
-
"Aug",
|
|
3636
|
-
"Sep",
|
|
3637
|
-
"Oct",
|
|
3638
|
-
"Nov",
|
|
3639
|
-
"Dec",
|
|
3640
|
-
];
|
|
3641
|
-
const weekdayNamesShort = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
3642
3828
|
const Calendar = ({ calendars, getBackProps, getForwardProps, getDateProps, firstDayOfWeek = 0, }) => {
|
|
3829
|
+
const { labels } = React.useContext(DatePickerContext);
|
|
3830
|
+
const { monthNamesShort, weekdayNamesShort, backButtonLabel, forwardButtonLabel } = labels;
|
|
3643
3831
|
if (calendars.length) {
|
|
3644
3832
|
return (jsxRuntime.jsxs(react.Grid, { children: [jsxRuntime.jsxs(react.Grid, { templateColumns: "repeat(4, auto)", justifyContent: "center", children: [jsxRuntime.jsx(react.Button, { variant: "ghost", ...getBackProps({
|
|
3645
3833
|
calendars,
|
|
3646
3834
|
offset: 12,
|
|
3647
|
-
}), children: "<<" }), jsxRuntime.jsx(react.Button, { variant: "ghost", ...getBackProps({ calendars }), children:
|
|
3835
|
+
}), 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({
|
|
3648
3836
|
calendars,
|
|
3649
3837
|
offset: 12,
|
|
3650
3838
|
}), 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) => {
|
|
@@ -3687,9 +3875,52 @@ const Calendar = ({ calendars, getBackProps, getForwardProps, getDateProps, firs
|
|
|
3687
3875
|
}
|
|
3688
3876
|
return null;
|
|
3689
3877
|
};
|
|
3878
|
+
const DatePickerContext = React.createContext({
|
|
3879
|
+
labels: {
|
|
3880
|
+
monthNamesShort: [
|
|
3881
|
+
"Jan",
|
|
3882
|
+
"Feb",
|
|
3883
|
+
"Mar",
|
|
3884
|
+
"Apr",
|
|
3885
|
+
"May",
|
|
3886
|
+
"Jun",
|
|
3887
|
+
"Jul",
|
|
3888
|
+
"Aug",
|
|
3889
|
+
"Sep",
|
|
3890
|
+
"Oct",
|
|
3891
|
+
"Nov",
|
|
3892
|
+
"Dec",
|
|
3893
|
+
],
|
|
3894
|
+
weekdayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
|
|
3895
|
+
backButtonLabel: "Back",
|
|
3896
|
+
forwardButtonLabel: "Next",
|
|
3897
|
+
},
|
|
3898
|
+
});
|
|
3690
3899
|
let DatePicker$1 = class DatePicker extends React.Component {
|
|
3691
3900
|
render() {
|
|
3692
|
-
|
|
3901
|
+
const { labels = {
|
|
3902
|
+
monthNamesShort: [
|
|
3903
|
+
"Jan",
|
|
3904
|
+
"Feb",
|
|
3905
|
+
"Mar",
|
|
3906
|
+
"Apr",
|
|
3907
|
+
"May",
|
|
3908
|
+
"Jun",
|
|
3909
|
+
"Jul",
|
|
3910
|
+
"Aug",
|
|
3911
|
+
"Sep",
|
|
3912
|
+
"Oct",
|
|
3913
|
+
"Nov",
|
|
3914
|
+
"Dec",
|
|
3915
|
+
],
|
|
3916
|
+
weekdayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
|
|
3917
|
+
backButtonLabel: "Back",
|
|
3918
|
+
forwardButtonLabel: "Next",
|
|
3919
|
+
}, } = this.props;
|
|
3920
|
+
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:
|
|
3921
|
+
// @ts-expect-error - Dayzed types need to be fixed
|
|
3922
|
+
(dayzedData) => (jsxRuntime.jsx(Calendar, { ...dayzedData,
|
|
3923
|
+
firstDayOfWeek: this.props.firstDayOfWeek })) }) }));
|
|
3693
3924
|
}
|
|
3694
3925
|
};
|
|
3695
3926
|
|
|
@@ -3711,28 +3942,86 @@ const PopoverRoot = react.Popover.Root;
|
|
|
3711
3942
|
const PopoverBody = react.Popover.Body;
|
|
3712
3943
|
const PopoverTrigger = react.Popover.Trigger;
|
|
3713
3944
|
|
|
3945
|
+
function translateWrapper({ prefix, column, label, translate, }) {
|
|
3946
|
+
return translate.t(removeIndex(`${prefix}${column}.${label}`));
|
|
3947
|
+
}
|
|
3948
|
+
|
|
3949
|
+
dayjs.extend(utc);
|
|
3950
|
+
dayjs.extend(timezone);
|
|
3714
3951
|
const DatePicker = ({ column, schema, prefix }) => {
|
|
3715
3952
|
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
3716
|
-
const { translate } = useSchemaContext();
|
|
3717
|
-
const { required, gridColumn, gridRow } = schema;
|
|
3953
|
+
const { translate, timezone } = useSchemaContext();
|
|
3954
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD", dateFormat = "YYYY-MM-DD", } = schema;
|
|
3718
3955
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
3719
3956
|
const colLabel = `${prefix}${column}`;
|
|
3720
3957
|
const [open, setOpen] = React.useState(false);
|
|
3721
3958
|
const selectedDate = watch(colLabel);
|
|
3722
|
-
const
|
|
3723
|
-
|
|
3724
|
-
|
|
3959
|
+
const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
|
|
3960
|
+
React.useEffect(() => {
|
|
3961
|
+
try {
|
|
3962
|
+
if (selectedDate) {
|
|
3963
|
+
// Parse the selectedDate as UTC or in a specific timezone to avoid +8 hour shift
|
|
3964
|
+
// For example, parse as UTC:
|
|
3965
|
+
const parsedDate = dayjs(selectedDate).tz(timezone);
|
|
3966
|
+
if (!parsedDate.isValid())
|
|
3967
|
+
return;
|
|
3968
|
+
// Format according to dateFormat from schema
|
|
3969
|
+
const formatted = parsedDate.format(dateFormat);
|
|
3970
|
+
// Update the form value only if different to avoid loops
|
|
3971
|
+
if (formatted !== selectedDate) {
|
|
3972
|
+
setValue(colLabel, formatted, {
|
|
3973
|
+
shouldValidate: true,
|
|
3974
|
+
shouldDirty: true,
|
|
3975
|
+
});
|
|
3976
|
+
}
|
|
3977
|
+
}
|
|
3978
|
+
}
|
|
3979
|
+
catch (e) {
|
|
3980
|
+
console.error(e);
|
|
3981
|
+
}
|
|
3982
|
+
}, [selectedDate, dateFormat, colLabel, setValue]);
|
|
3983
|
+
const customTranslate = (label) => {
|
|
3984
|
+
return translateWrapper({ prefix, column, label, translate });
|
|
3985
|
+
};
|
|
3986
|
+
return (jsxRuntime.jsxs(Field, { label: `${customTranslate(`field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
3987
|
+
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: () => {
|
|
3725
3988
|
setOpen(true);
|
|
3726
|
-
}, children: selectedDate !== undefined ? `${
|
|
3727
|
-
|
|
3728
|
-
, {
|
|
3729
|
-
// @ts-expect-error TODO: find appropriate types
|
|
3730
|
-
selected: new Date(selectedDate),
|
|
3731
|
-
// @ts-expect-error TODO: find appropriate types
|
|
3732
|
-
onDateSelected: ({ date }) => {
|
|
3733
|
-
setValue(colLabel, dayjs(date).format("YYYY-MM-DD"));
|
|
3989
|
+
}, 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 }) => {
|
|
3990
|
+
setValue(colLabel, dayjs(date).format(dateFormat));
|
|
3734
3991
|
setOpen(false);
|
|
3735
|
-
}
|
|
3992
|
+
}, labels: {
|
|
3993
|
+
monthNamesShort: [
|
|
3994
|
+
translate.t(`common.month_1`, { defaultValue: "January" }),
|
|
3995
|
+
translate.t(`common.month_2`, { defaultValue: "February" }),
|
|
3996
|
+
translate.t(`common.month_3`, { defaultValue: "March" }),
|
|
3997
|
+
translate.t(`common.month_4`, { defaultValue: "April" }),
|
|
3998
|
+
translate.t(`common.month_5`, { defaultValue: "May" }),
|
|
3999
|
+
translate.t(`common.month_6`, { defaultValue: "June" }),
|
|
4000
|
+
translate.t(`common.month_7`, { defaultValue: "July" }),
|
|
4001
|
+
translate.t(`common.month_8`, { defaultValue: "August" }),
|
|
4002
|
+
translate.t(`common.month_9`, { defaultValue: "September" }),
|
|
4003
|
+
translate.t(`common.month_10`, { defaultValue: "October" }),
|
|
4004
|
+
translate.t(`common.month_11`, { defaultValue: "November" }),
|
|
4005
|
+
translate.t(`common.month_12`, { defaultValue: "December" }),
|
|
4006
|
+
],
|
|
4007
|
+
weekdayNamesShort: [
|
|
4008
|
+
translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
|
|
4009
|
+
translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
|
|
4010
|
+
translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
|
|
4011
|
+
translate.t(`common.weekday_4`, {
|
|
4012
|
+
defaultValue: "Wed",
|
|
4013
|
+
}),
|
|
4014
|
+
translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
|
|
4015
|
+
translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
|
|
4016
|
+
translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
|
|
4017
|
+
],
|
|
4018
|
+
backButtonLabel: translate.t(`common.back_button`, {
|
|
4019
|
+
defaultValue: "Back",
|
|
4020
|
+
}),
|
|
4021
|
+
forwardButtonLabel: translate.t(`common.forward_button`, {
|
|
4022
|
+
defaultValue: "Forward",
|
|
4023
|
+
}),
|
|
4024
|
+
} })] }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: customTranslate(`field_required`) }))] }));
|
|
3736
4025
|
};
|
|
3737
4026
|
|
|
3738
4027
|
function filterArray(array, searchTerm) {
|
|
@@ -3745,12 +4034,12 @@ function filterArray(array, searchTerm) {
|
|
|
3745
4034
|
});
|
|
3746
4035
|
}
|
|
3747
4036
|
|
|
3748
|
-
const EnumPicker = ({ column, isMultiple = false, schema, prefix, }) => {
|
|
4037
|
+
const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLimit = false, }) => {
|
|
3749
4038
|
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
3750
4039
|
const { translate } = useSchemaContext();
|
|
3751
|
-
const { required } = schema;
|
|
4040
|
+
const { required, variant } = schema;
|
|
3752
4041
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
3753
|
-
const { gridColumn, gridRow, renderDisplay } = schema;
|
|
4042
|
+
const { gridColumn = "span 4", gridRow = "span 1", renderDisplay } = schema;
|
|
3754
4043
|
const [searchText, setSearchText] = React.useState();
|
|
3755
4044
|
const [limit, setLimit] = React.useState(10);
|
|
3756
4045
|
const [openSearchResult, setOpenSearchResult] = React.useState();
|
|
@@ -3765,28 +4054,61 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, }) => {
|
|
|
3765
4054
|
setSearchText(event.target.value);
|
|
3766
4055
|
setLimit(10);
|
|
3767
4056
|
};
|
|
3768
|
-
|
|
4057
|
+
if (variant === "radio") {
|
|
4058
|
+
return (jsxRuntime.jsx(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
4059
|
+
gridRow, children: jsxRuntime.jsx(react.RadioGroup.Root, { defaultValue: "1", children: jsxRuntime.jsx(react.HStack, { gap: "6", children: filterArray(dataList, searchText ?? "").map((item) => {
|
|
4060
|
+
return (jsxRuntime.jsxs(react.RadioGroup.Item, { onClick: () => {
|
|
4061
|
+
if (!isMultiple) {
|
|
4062
|
+
setOpenSearchResult(false);
|
|
4063
|
+
setValue(colLabel, item);
|
|
4064
|
+
return;
|
|
4065
|
+
}
|
|
4066
|
+
const newSet = new Set([...(watchEnums ?? []), item]);
|
|
4067
|
+
setValue(colLabel, [...newSet]);
|
|
4068
|
+
}, value: item, children: [jsxRuntime.jsx(react.RadioGroup.ItemHiddenInput, {}), jsxRuntime.jsx(react.RadioGroup.ItemIndicator, {}), jsxRuntime.jsx(react.RadioGroup.ItemText, { children: !!renderDisplay === true
|
|
4069
|
+
? renderDisplay(item)
|
|
4070
|
+
: translate.t(removeIndex(`${colLabel}.${item}`)) })] }, `${colLabel}-${item}`));
|
|
4071
|
+
}) }) }) }));
|
|
4072
|
+
}
|
|
4073
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
3769
4074
|
gridRow, children: [isMultiple && (jsxRuntime.jsxs(react.Flex, { flexFlow: "wrap", gap: 1, children: [watchEnums.map((enumValue) => {
|
|
3770
4075
|
const item = enumValue;
|
|
3771
|
-
if (item ===
|
|
3772
|
-
return jsxRuntime.jsx(jsxRuntime.Fragment, {
|
|
4076
|
+
if (!!item === false) {
|
|
4077
|
+
return jsxRuntime.jsx(jsxRuntime.Fragment, {});
|
|
3773
4078
|
}
|
|
3774
4079
|
return (jsxRuntime.jsx(Tag, { closable: true, onClick: () => {
|
|
3775
|
-
// setSelectedEnums((state) => state.filter((id) => id != item));
|
|
3776
4080
|
setValue(column, watchEnums.filter((id) => id != item));
|
|
3777
4081
|
}, children: !!renderDisplay === true
|
|
3778
4082
|
? renderDisplay(item)
|
|
3779
4083
|
: translate.t(removeIndex(`${colLabel}.${item}`)) }));
|
|
3780
4084
|
}), jsxRuntime.jsx(Tag, { cursor: "pointer", onClick: () => {
|
|
3781
4085
|
setOpenSearchResult(true);
|
|
3782
|
-
}, children: translate.t(removeIndex(`${colLabel}.
|
|
4086
|
+
}, children: translate.t(removeIndex(`${colLabel}.add_more`)) })] })), !isMultiple && (jsxRuntime.jsx(Button, { variant: "outline", onClick: () => {
|
|
3783
4087
|
setOpenSearchResult(true);
|
|
3784
|
-
}, children: watchEnum ===
|
|
4088
|
+
}, justifyContent: "start", children: !!watchEnum === false
|
|
3785
4089
|
? ""
|
|
3786
|
-
: 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(`${
|
|
4090
|
+
: 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, { children: jsxRuntime.jsxs(PopoverBody, { display: "grid", gap: 1, children: [jsxRuntime.jsx(react.Input, { placeholder: translate.t(`${colLabel}.type_to_search`), onChange: (event) => {
|
|
3787
4091
|
onSearchChange(event);
|
|
3788
4092
|
setOpenSearchResult(true);
|
|
3789
|
-
}, autoComplete: "off", ref: ref }), jsxRuntime.jsx(PopoverTitle, {}), jsxRuntime.jsx(react.Text, { children: `${translate.t(`${
|
|
4093
|
+
}, 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
|
|
4094
|
+
.filter((item) => {
|
|
4095
|
+
const searchTerm = (searchText || "").toLowerCase();
|
|
4096
|
+
if (!searchTerm)
|
|
4097
|
+
return true;
|
|
4098
|
+
// Check if the original enum value contains the search text
|
|
4099
|
+
const enumValueMatch = item
|
|
4100
|
+
.toLowerCase()
|
|
4101
|
+
.includes(searchTerm);
|
|
4102
|
+
// Check if the display value (translation) contains the search text
|
|
4103
|
+
const displayValue = !!renderDisplay === true
|
|
4104
|
+
? renderDisplay(item)
|
|
4105
|
+
: translate.t(removeIndex(`${colLabel}.${item}`));
|
|
4106
|
+
// Convert to string and check if it includes the search term
|
|
4107
|
+
const displayValueString = String(displayValue).toLowerCase();
|
|
4108
|
+
const displayValueMatch = displayValueString.includes(searchTerm);
|
|
4109
|
+
return enumValueMatch || displayValueMatch;
|
|
4110
|
+
})
|
|
4111
|
+
.map((item) => {
|
|
3790
4112
|
const selected = isMultiple
|
|
3791
4113
|
? watchEnums.some((enumValue) => item === enumValue)
|
|
3792
4114
|
: watchEnum == item;
|
|
@@ -3798,10 +4120,10 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, }) => {
|
|
|
3798
4120
|
}
|
|
3799
4121
|
const newSet = new Set([...(watchEnums ?? []), item]);
|
|
3800
4122
|
setValue(colLabel, [...newSet]);
|
|
3801
|
-
}, ...(selected ? { color: "
|
|
4123
|
+
}, ...(selected ? { color: "colorPalette.400/50" } : {}), children: !!renderDisplay === true
|
|
3802
4124
|
? renderDisplay(item)
|
|
3803
4125
|
: translate.t(removeIndex(`${colLabel}.${item}`)) }, `${colLabel}-${item}`));
|
|
3804
|
-
}) }), isDirty && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: dataList.length <= 0 && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: translate.t(removeIndex(`${colLabel}.
|
|
4126
|
+
}) }), 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`)) }))] }));
|
|
3805
4127
|
};
|
|
3806
4128
|
|
|
3807
4129
|
function isEnteringWindow(_ref) {
|
|
@@ -4153,17 +4475,17 @@ const FileDropzone = ({ children = undefined, gridProps = {}, onDrop = () => { }
|
|
|
4153
4475
|
const filesArray = [...event.target.files];
|
|
4154
4476
|
onDrop({ files: filesArray });
|
|
4155
4477
|
};
|
|
4156
|
-
return (jsxRuntime.jsxs(react.Grid, { ...getColor(isDraggedOver), ref: ref, cursor: "pointer", onClick: handleClick, borderStyle: "dashed", borderColor: "
|
|
4478
|
+
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 })] }))] }));
|
|
4157
4479
|
};
|
|
4158
4480
|
|
|
4159
4481
|
const FilePicker = ({ column, schema, prefix }) => {
|
|
4160
4482
|
const { setValue, formState: { errors }, watch, } = reactHookForm.useFormContext();
|
|
4161
4483
|
const { translate } = useSchemaContext();
|
|
4162
|
-
const { required, gridColumn, gridRow } = schema;
|
|
4484
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", } = schema;
|
|
4163
4485
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4164
4486
|
const currentFiles = (watch(column) ?? []);
|
|
4165
4487
|
const colLabel = `${prefix}${column}`;
|
|
4166
|
-
return (jsxRuntime.jsxs(Field, { label: `${translate.t(`${colLabel}.
|
|
4488
|
+
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 }) => {
|
|
4167
4489
|
const newFiles = files.filter(({ name }) => !currentFiles.some((cur) => cur.name === name));
|
|
4168
4490
|
setValue(colLabel, [...currentFiles, ...newFiles]);
|
|
4169
4491
|
}, placeholder: translate.t(removeIndex(`${colLabel}.fileDropzone`)) }), jsxRuntime.jsx(react.Flex, { flexFlow: "column", gap: 1, children: currentFiles.map((file) => {
|
|
@@ -4171,10 +4493,19 @@ const FilePicker = ({ column, schema, prefix }) => {
|
|
|
4171
4493
|
setValue(column, currentFiles.filter(({ name }) => {
|
|
4172
4494
|
return name !== file.name;
|
|
4173
4495
|
}));
|
|
4174
|
-
}, display: "flex", flexFlow: "row", alignItems: "center", padding: "2", children: [jsxRuntime.jsx(react.Box, { children: file.name }), jsxRuntime.jsx(ti.TiDeleteOutline, {})] }) }, file.name));
|
|
4175
|
-
}) }), errors[`${colLabel}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.
|
|
4496
|
+
}, 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));
|
|
4497
|
+
}) }), errors[`${colLabel}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4176
4498
|
};
|
|
4177
4499
|
|
|
4500
|
+
const ToggleTip = React__namespace.forwardRef(function ToggleTip(props, ref) {
|
|
4501
|
+
const { showArrow, children, portalled = true, content, portalRef, ...rest } = props;
|
|
4502
|
+
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] }) }) })] }));
|
|
4503
|
+
});
|
|
4504
|
+
const InfoTip = React__namespace.forwardRef(function InfoTip(props, ref) {
|
|
4505
|
+
const { children, ...rest } = props;
|
|
4506
|
+
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, {}) }) }));
|
|
4507
|
+
});
|
|
4508
|
+
|
|
4178
4509
|
const getTableData = async ({ serverUrl, in_table, searching = "", where = [], limit = 10, offset = 0, }) => {
|
|
4179
4510
|
if (serverUrl === undefined || serverUrl.length == 0) {
|
|
4180
4511
|
throw new Error("The serverUrl is missing");
|
|
@@ -4206,15 +4537,18 @@ const getTableData = async ({ serverUrl, in_table, searching = "", where = [], l
|
|
|
4206
4537
|
const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
4207
4538
|
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
4208
4539
|
const { serverUrl, idMap, setIdMap, translate, schema: parentSchema, } = useSchemaContext();
|
|
4209
|
-
const { required, gridColumn, gridRow, renderDisplay, foreign_key } = schema;
|
|
4540
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", renderDisplay, foreign_key, } = schema;
|
|
4210
4541
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4211
4542
|
const { table, column: column_ref, display_column, } = foreign_key;
|
|
4212
|
-
const [searchText, setSearchText] = React.useState();
|
|
4543
|
+
const [searchText, setSearchText] = React.useState("");
|
|
4213
4544
|
const [limit, setLimit] = React.useState(10);
|
|
4214
4545
|
const [openSearchResult, setOpenSearchResult] = React.useState();
|
|
4215
4546
|
const [page, setPage] = React.useState(0);
|
|
4216
4547
|
const ref = React.useRef(null);
|
|
4217
4548
|
const colLabel = `${prefix}${column}`;
|
|
4549
|
+
const watchId = watch(colLabel);
|
|
4550
|
+
const watchIds = isMultiple ? (watch(colLabel) ?? []) : [];
|
|
4551
|
+
// Query for search results
|
|
4218
4552
|
const query = reactQuery.useQuery({
|
|
4219
4553
|
queryKey: [`idpicker`, { column, searchText, limit, page }],
|
|
4220
4554
|
queryFn: async () => {
|
|
@@ -4223,7 +4557,7 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4223
4557
|
searching: searchText ?? "",
|
|
4224
4558
|
in_table: table,
|
|
4225
4559
|
limit: limit,
|
|
4226
|
-
offset: page *
|
|
4560
|
+
offset: page * limit,
|
|
4227
4561
|
});
|
|
4228
4562
|
const newMap = Object.fromEntries((data ?? { data: [] }).data.map((item) => {
|
|
4229
4563
|
return [
|
|
@@ -4238,27 +4572,27 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4238
4572
|
});
|
|
4239
4573
|
return data;
|
|
4240
4574
|
},
|
|
4241
|
-
enabled:
|
|
4575
|
+
enabled: openSearchResult === true,
|
|
4242
4576
|
staleTime: 300000,
|
|
4243
4577
|
});
|
|
4244
|
-
|
|
4245
|
-
const
|
|
4246
|
-
const count = data?.count ?? 0;
|
|
4247
|
-
const isDirty = (searchText?.length ?? 0) > 0;
|
|
4248
|
-
const watchId = watch(colLabel);
|
|
4249
|
-
const watchIds = (watch(colLabel) ?? []);
|
|
4250
|
-
reactQuery.useQuery({
|
|
4578
|
+
// Query for currently selected items (to display them properly)
|
|
4579
|
+
const queryDefault = reactQuery.useQuery({
|
|
4251
4580
|
queryKey: [
|
|
4252
|
-
`idpicker`,
|
|
4253
|
-
{ form: parentSchema.title, column,
|
|
4581
|
+
`idpicker-default`,
|
|
4582
|
+
{ form: parentSchema.title, column, id: isMultiple ? watchIds : watchId },
|
|
4254
4583
|
],
|
|
4255
4584
|
queryFn: async () => {
|
|
4585
|
+
if (!watchId && (!watchIds || watchIds.length === 0)) {
|
|
4586
|
+
return { data: [] };
|
|
4587
|
+
}
|
|
4588
|
+
const searchValue = isMultiple ? watchIds.join(",") : watchId;
|
|
4256
4589
|
const data = await getTableData({
|
|
4257
4590
|
serverUrl,
|
|
4258
|
-
searching:
|
|
4591
|
+
searching: searchValue,
|
|
4259
4592
|
in_table: table,
|
|
4260
|
-
|
|
4261
|
-
|
|
4593
|
+
where: [{ id: column_ref, value: isMultiple ? watchIds : watchId }],
|
|
4594
|
+
limit: isMultiple ? watchIds.length : 1,
|
|
4595
|
+
offset: 0,
|
|
4262
4596
|
});
|
|
4263
4597
|
const newMap = Object.fromEntries((data ?? { data: [] }).data.map((item) => {
|
|
4264
4598
|
return [
|
|
@@ -4273,12 +4607,45 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4273
4607
|
});
|
|
4274
4608
|
return data;
|
|
4275
4609
|
},
|
|
4610
|
+
enabled: isMultiple
|
|
4611
|
+
? Array.isArray(watchIds) && watchIds.length > 0
|
|
4612
|
+
: !!watchId,
|
|
4276
4613
|
});
|
|
4614
|
+
// Effect to load selected values when component mounts
|
|
4615
|
+
React.useEffect(() => {
|
|
4616
|
+
if (isMultiple ? watchIds.length > 0 : !!watchId) {
|
|
4617
|
+
queryDefault.refetch();
|
|
4618
|
+
}
|
|
4619
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4620
|
+
}, []);
|
|
4621
|
+
// Effect to trigger initial data fetch when popover opens
|
|
4622
|
+
React.useEffect(() => {
|
|
4623
|
+
if (openSearchResult) {
|
|
4624
|
+
// Reset search text when opening the popover
|
|
4625
|
+
setSearchText("");
|
|
4626
|
+
// Reset page to first page
|
|
4627
|
+
setPage(0);
|
|
4628
|
+
// Fetch initial data
|
|
4629
|
+
query.refetch();
|
|
4630
|
+
}
|
|
4631
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4632
|
+
}, [openSearchResult]);
|
|
4277
4633
|
const onSearchChange = async (event) => {
|
|
4278
4634
|
setSearchText(event.target.value);
|
|
4279
4635
|
setPage(0);
|
|
4280
|
-
|
|
4636
|
+
query.refetch();
|
|
4637
|
+
};
|
|
4638
|
+
const handleLimitChange = (event) => {
|
|
4639
|
+
const newLimit = Number(event.target.value);
|
|
4640
|
+
setLimit(newLimit);
|
|
4641
|
+
// Reset to first page when changing limit
|
|
4642
|
+
setPage(0);
|
|
4643
|
+
// Trigger a new search with the updated limit
|
|
4644
|
+
query.refetch();
|
|
4281
4645
|
};
|
|
4646
|
+
const { isLoading, isFetching, data, isPending, isError } = query;
|
|
4647
|
+
const dataList = data?.data ?? [];
|
|
4648
|
+
const count = data?.count ?? 0;
|
|
4282
4649
|
const getPickedValue = () => {
|
|
4283
4650
|
if (Object.keys(idMap).length <= 0) {
|
|
4284
4651
|
return "";
|
|
@@ -4287,52 +4654,62 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4287
4654
|
if (record === undefined) {
|
|
4288
4655
|
return "";
|
|
4289
4656
|
}
|
|
4657
|
+
if (!!renderDisplay === true) {
|
|
4658
|
+
return renderDisplay(record);
|
|
4659
|
+
}
|
|
4290
4660
|
return record[display_column];
|
|
4291
4661
|
};
|
|
4292
|
-
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(removeIndex(`${column}.
|
|
4662
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(removeIndex(`${column}.field_label`)))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
4293
4663
|
gridRow, children: [isMultiple && (jsxRuntime.jsxs(react.Flex, { flexFlow: "wrap", gap: 1, children: [watchIds.map((id) => {
|
|
4294
4664
|
const item = idMap[id];
|
|
4295
4665
|
if (item === undefined) {
|
|
4296
4666
|
return (jsxRuntime.jsx(react.Text, { children: translate.t(removeIndex(`${colLabel}.undefined`)) }, id));
|
|
4297
4667
|
}
|
|
4298
4668
|
return (jsxRuntime.jsx(Tag, { closable: true, onClick: () => {
|
|
4299
|
-
setValue(
|
|
4669
|
+
setValue(colLabel, watchIds.filter((itemId) => itemId !== item[column_ref]));
|
|
4300
4670
|
}, children: !!renderDisplay === true
|
|
4301
4671
|
? renderDisplay(item)
|
|
4302
4672
|
: item[display_column] }, id));
|
|
4303
4673
|
}), jsxRuntime.jsx(Tag, { cursor: "pointer", onClick: () => {
|
|
4304
4674
|
setOpenSearchResult(true);
|
|
4305
|
-
}, children: translate.t(removeIndex(`${colLabel}.
|
|
4675
|
+
}, children: translate.t(removeIndex(`${colLabel}.add_more`)) })] })), !isMultiple && (jsxRuntime.jsx(Button, { variant: "outline", onClick: () => {
|
|
4306
4676
|
setOpenSearchResult(true);
|
|
4307
|
-
}, children: getPickedValue() })), jsxRuntime.jsxs(PopoverRoot, { open: openSearchResult, onOpenChange: (e) => setOpenSearchResult(e.open), closeOnInteractOutside: true, initialFocusEl: () => ref.current, positioning: { placement: "bottom-start", strategy: "fixed" }, children: [jsxRuntime.jsx(PopoverTrigger, {}), jsxRuntime.jsx(PopoverContent, { children: jsxRuntime.jsxs(PopoverBody, { display: "grid", gap: 1, children: [jsxRuntime.jsx(react.Input, { placeholder: translate.t(removeIndex(`${colLabel}.
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
|
|
4313
|
-
|
|
4314
|
-
|
|
4315
|
-
|
|
4316
|
-
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
|
|
4330
|
-
|
|
4677
|
+
}, 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, { children: jsxRuntime.jsxs(PopoverBody, { display: "grid", gap: 1, children: [jsxRuntime.jsx(react.Input, { placeholder: translate.t(removeIndex(`${colLabel}.type_to_search`)), onChange: onSearchChange, autoComplete: "off", ref: ref, value: searchText }), jsxRuntime.jsx(PopoverTitle, {}), openSearchResult && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [(isFetching || isLoading || isPending) && jsxRuntime.jsx(react.Spinner, {}), isError && (jsxRuntime.jsx(react.Icon, { color: "red.400", children: jsxRuntime.jsx(bi.BiError, {}) })), jsxRuntime.jsxs(react.Flex, { justifyContent: "space-between", alignItems: "center", children: [jsxRuntime.jsxs(react.Flex, { alignItems: "center", gap: "2", children: [jsxRuntime.jsx(InfoTip, { children: `${translate.t(removeIndex(`${colLabel}.total`))} ${count}, ${translate.t(removeIndex(`${colLabel}.showing`))} ${limit} ${translate.t(removeIndex(`${colLabel}.per_page`), "per page")}` }), jsxRuntime.jsxs(react.Text, { fontSize: "sm", fontWeight: "bold", children: [count, jsxRuntime.jsxs(react.Text, { as: "span", fontSize: "xs", ml: "1", color: "gray.500", children: ["/ ", count > 0 ? `${page * limit + 1}-${Math.min((page + 1) * limit, count)}` : '0'] })] })] }), jsxRuntime.jsx(react.Box, { children: jsxRuntime.jsxs("select", { value: limit, onChange: handleLimitChange, style: {
|
|
4678
|
+
padding: "4px 8px",
|
|
4679
|
+
borderRadius: "4px",
|
|
4680
|
+
border: "1px solid #ccc",
|
|
4681
|
+
fontSize: "14px",
|
|
4682
|
+
}, 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) => {
|
|
4683
|
+
const selected = isMultiple
|
|
4684
|
+
? watchIds.some((id) => item[column_ref] === id)
|
|
4685
|
+
: watchId === item[column_ref];
|
|
4686
|
+
return (jsxRuntime.jsx(react.Box, { cursor: "pointer", onClick: () => {
|
|
4687
|
+
if (!isMultiple) {
|
|
4688
|
+
setOpenSearchResult(false);
|
|
4689
|
+
setValue(colLabel, item[column_ref]);
|
|
4690
|
+
return;
|
|
4691
|
+
}
|
|
4692
|
+
// For multiple selection, don't add if already selected
|
|
4693
|
+
if (selected)
|
|
4694
|
+
return;
|
|
4695
|
+
const newSet = new Set([
|
|
4696
|
+
...(watchIds ?? []),
|
|
4697
|
+
item[column_ref],
|
|
4698
|
+
]);
|
|
4699
|
+
setValue(colLabel, [...newSet]);
|
|
4700
|
+
}, opacity: 0.7, _hover: { opacity: 1 }, ...(selected
|
|
4701
|
+
? { color: "colorPalette.400/50", fontWeight: "bold" }
|
|
4702
|
+
: {}), children: !!renderDisplay === true
|
|
4703
|
+
? renderDisplay(item)
|
|
4704
|
+
: item[display_column] }, item[column_ref]));
|
|
4705
|
+
}) })) : (jsxRuntime.jsx(react.Text, { children: searchText
|
|
4706
|
+
? translate.t(removeIndex(`${colLabel}.empty_search_result`))
|
|
4707
|
+
: translate.t(removeIndex(`${colLabel}.initial_results`)) })) }), jsxRuntime.jsx(PaginationRoot, { justifySelf: "center", count: count, pageSize: limit, defaultPage: 1, page: page + 1, onPageChange: (e) => setPage(e.page - 1), children: jsxRuntime.jsxs(react.HStack, { gap: "4", children: [jsxRuntime.jsx(PaginationPrevTrigger, {}), count > 0 && jsxRuntime.jsx(PaginationPageText, {}), jsxRuntime.jsx(PaginationNextTrigger, {})] }) })] }))] }) })] }), errors[`${colLabel}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4331
4708
|
};
|
|
4332
4709
|
|
|
4333
4710
|
const NumberInputRoot = React__namespace.forwardRef(function NumberInput(props, ref) {
|
|
4334
4711
|
const { children, ...rest } = props;
|
|
4335
|
-
return (jsxRuntime.
|
|
4712
|
+
return (jsxRuntime.jsx(react.NumberInput.Root, { ref: ref, variant: "outline", ...rest, children: children }));
|
|
4336
4713
|
});
|
|
4337
4714
|
const NumberInputField$1 = react.NumberInput.Input;
|
|
4338
4715
|
react.NumberInput.Scrubber;
|
|
@@ -4341,17 +4718,17 @@ react.NumberInput.Label;
|
|
|
4341
4718
|
const NumberInputField = ({ schema, column, prefix, }) => {
|
|
4342
4719
|
const { setValue, formState: { errors }, watch, } = reactHookForm.useFormContext();
|
|
4343
4720
|
const { translate } = useSchemaContext();
|
|
4344
|
-
const { required, gridColumn, gridRow } = schema;
|
|
4721
|
+
const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
|
|
4345
4722
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4346
4723
|
const colLabel = `${prefix}${column}`;
|
|
4347
4724
|
const value = watch(`${colLabel}`);
|
|
4348
|
-
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.
|
|
4725
|
+
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) => {
|
|
4349
4726
|
setValue(`${colLabel}`, Number(event.target.value));
|
|
4350
|
-
} }) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.
|
|
4727
|
+
} }) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4351
4728
|
};
|
|
4352
4729
|
|
|
4353
4730
|
const ObjectInput = ({ schema, column, prefix }) => {
|
|
4354
|
-
const { properties,
|
|
4731
|
+
const { properties, gridColumn = "span 12", gridRow = "span 1", required, showLabel = true, } = schema;
|
|
4355
4732
|
const { translate } = useSchemaContext();
|
|
4356
4733
|
const colLabel = `${prefix}${column}`;
|
|
4357
4734
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
@@ -4359,25 +4736,28 @@ const ObjectInput = ({ schema, column, prefix }) => {
|
|
|
4359
4736
|
if (properties === undefined) {
|
|
4360
4737
|
throw new Error(`properties is undefined when using ObjectInput`);
|
|
4361
4738
|
}
|
|
4362
|
-
return (jsxRuntime.jsxs(react.Box, { gridRow, gridColumn, children: [jsxRuntime.jsxs(react.Box, { as: "label",
|
|
4739
|
+
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: {
|
|
4740
|
+
base: "colorPalette.200",
|
|
4741
|
+
_dark: "colorPalette.800",
|
|
4742
|
+
}, gap: "4", padding: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: Object.keys(properties ?? {}).map((key) => {
|
|
4363
4743
|
return (
|
|
4364
4744
|
// @ts-expect-error find suitable types
|
|
4365
4745
|
jsxRuntime.jsx(ColumnRenderer, { column: `${key}`,
|
|
4366
4746
|
prefix: `${prefix}${column}.`,
|
|
4367
4747
|
properties }, `form-${colLabel}-${key}`));
|
|
4368
|
-
}) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.
|
|
4748
|
+
}) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4369
4749
|
};
|
|
4370
4750
|
|
|
4371
4751
|
const RecordInput$1 = ({ column, schema, prefix }) => {
|
|
4372
4752
|
const { formState: { errors }, setValue, getValues, } = reactHookForm.useFormContext();
|
|
4373
4753
|
const { translate } = useSchemaContext();
|
|
4374
|
-
const { required, gridColumn, gridRow } = schema;
|
|
4754
|
+
const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
|
|
4375
4755
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4376
4756
|
const entries = Object.entries(getValues(column) ?? {});
|
|
4377
4757
|
const [showNewEntries, setShowNewEntries] = React.useState(false);
|
|
4378
4758
|
const [newKey, setNewKey] = React.useState();
|
|
4379
4759
|
const [newValue, setNewValue] = React.useState();
|
|
4380
|
-
return (jsxRuntime.jsxs(Field, { label: `${translate.t(`${column}.
|
|
4760
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(`${column}.field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn, gridRow, children: [entries.map(([key, value]) => {
|
|
4381
4761
|
return (jsxRuntime.jsxs(react.Grid, { templateColumns: "1fr 1fr auto", gap: 1, children: [jsxRuntime.jsx(react.Input, { value: key, onChange: (e) => {
|
|
4382
4762
|
const filtered = entries.filter(([target]) => {
|
|
4383
4763
|
return target !== key;
|
|
@@ -4417,16 +4797,16 @@ const RecordInput$1 = ({ column, schema, prefix }) => {
|
|
|
4417
4797
|
setShowNewEntries(true);
|
|
4418
4798
|
setNewKey(undefined);
|
|
4419
4799
|
setNewValue(undefined);
|
|
4420
|
-
}, children: translate.t(`${column}.addNew`) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(`${column}.
|
|
4800
|
+
}, children: translate.t(`${column}.addNew`) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
|
|
4421
4801
|
};
|
|
4422
4802
|
|
|
4423
4803
|
const StringInputField = ({ column, schema, prefix, }) => {
|
|
4424
4804
|
const { register, formState: { errors }, } = reactHookForm.useFormContext();
|
|
4425
4805
|
const { translate } = useSchemaContext();
|
|
4426
|
-
const { required, gridColumn, gridRow } = schema;
|
|
4806
|
+
const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
|
|
4427
4807
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4428
4808
|
const colLabel = `${prefix}${column}`;
|
|
4429
|
-
return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.
|
|
4809
|
+
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`)) }))] }) }));
|
|
4430
4810
|
};
|
|
4431
4811
|
|
|
4432
4812
|
const RadioCardItem = React__namespace.forwardRef(function RadioCardItem(props, ref) {
|
|
@@ -4524,9 +4904,459 @@ const TagPicker = ({ column, schema, prefix }) => {
|
|
|
4524
4904
|
}), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: (errors[`${column}`]?.message ?? "No error message") }))] }));
|
|
4525
4905
|
};
|
|
4526
4906
|
|
|
4907
|
+
const TextAreaInput = ({ column, schema, prefix, }) => {
|
|
4908
|
+
const { register, formState: { errors }, } = reactHookForm.useFormContext();
|
|
4909
|
+
const { translate } = useSchemaContext();
|
|
4910
|
+
const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
|
|
4911
|
+
const isRequired = required?.some((columnId) => columnId === column);
|
|
4912
|
+
const colLabel = `${prefix}${column}`;
|
|
4913
|
+
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.Textarea, { ...register(`${colLabel}`, { required: isRequired }), autoComplete: "off" }), errors[colLabel] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }) }));
|
|
4914
|
+
};
|
|
4915
|
+
|
|
4916
|
+
function TimePicker$1({ hour, setHour, minute, setMinute, meridiem, setMeridiem, meridiemLabel = {
|
|
4917
|
+
am: "am",
|
|
4918
|
+
pm: "pm",
|
|
4919
|
+
}, onChange = (_newValue) => { }, }) {
|
|
4920
|
+
// Refs for focus management
|
|
4921
|
+
const hourInputRef = React.useRef(null);
|
|
4922
|
+
const minuteInputRef = React.useRef(null);
|
|
4923
|
+
React.useRef(null);
|
|
4924
|
+
// Centralized handler for key events, value changes, and focus management
|
|
4925
|
+
const handleKeyDown = (e, field) => {
|
|
4926
|
+
const input = e.target;
|
|
4927
|
+
const value = input.value;
|
|
4928
|
+
// Handle navigation between fields
|
|
4929
|
+
if (e.key === "Tab") {
|
|
4930
|
+
// Tab is handled by the browser, no need to override
|
|
4931
|
+
return;
|
|
4932
|
+
}
|
|
4933
|
+
if (e.key === ":" && field === "hour") {
|
|
4934
|
+
e.preventDefault();
|
|
4935
|
+
minuteInputRef.current?.focus();
|
|
4936
|
+
return;
|
|
4937
|
+
}
|
|
4938
|
+
if (e.key === "Backspace" && value === "") {
|
|
4939
|
+
e.preventDefault();
|
|
4940
|
+
if (field === "minute") {
|
|
4941
|
+
hourInputRef.current?.focus();
|
|
4942
|
+
}
|
|
4943
|
+
else if (field === "meridiem") {
|
|
4944
|
+
minuteInputRef.current?.focus();
|
|
4945
|
+
}
|
|
4946
|
+
return;
|
|
4947
|
+
}
|
|
4948
|
+
// Handle number inputs
|
|
4949
|
+
if (field === "hour") {
|
|
4950
|
+
if (e.key.match(/^[0-9]$/)) {
|
|
4951
|
+
const newValue = value + e.key;
|
|
4952
|
+
const numValue = parseInt(newValue, 10);
|
|
4953
|
+
console.log("newValue", newValue, numValue);
|
|
4954
|
+
if (numValue > 12) {
|
|
4955
|
+
const digitValue = parseInt(e.key, 10);
|
|
4956
|
+
setHour(digitValue);
|
|
4957
|
+
onChange({ hour: digitValue, minute, meridiem });
|
|
4958
|
+
return;
|
|
4959
|
+
}
|
|
4960
|
+
// Auto-advance to minutes if we have a valid hour (1-12)
|
|
4961
|
+
if (numValue >= 1 && numValue <= 12) {
|
|
4962
|
+
// Set the hour value
|
|
4963
|
+
setHour(numValue);
|
|
4964
|
+
onChange({ hour: numValue, minute, meridiem });
|
|
4965
|
+
// Move to minute input
|
|
4966
|
+
e.preventDefault();
|
|
4967
|
+
minuteInputRef.current?.focus();
|
|
4968
|
+
}
|
|
4969
|
+
}
|
|
4970
|
+
}
|
|
4971
|
+
else if (field === "minute") {
|
|
4972
|
+
if (e.key.match(/^[0-9]$/)) {
|
|
4973
|
+
const newValue = value + e.key;
|
|
4974
|
+
const numValue = parseInt(newValue, 10);
|
|
4975
|
+
console.log("newValue minute", newValue, numValue, numValue > 60, numValue >= 0 && numValue <= 59, e.key);
|
|
4976
|
+
if (numValue > 60) {
|
|
4977
|
+
const digitValue = parseInt(e.key, 10);
|
|
4978
|
+
setMinute(digitValue);
|
|
4979
|
+
onChange({ hour, minute: digitValue, meridiem });
|
|
4980
|
+
return;
|
|
4981
|
+
}
|
|
4982
|
+
// Auto-advance to meridiem if we have a valid minute (0-59)
|
|
4983
|
+
if (numValue >= 0 && numValue <= 59) {
|
|
4984
|
+
// Set the minute value
|
|
4985
|
+
setMinute(numValue);
|
|
4986
|
+
onChange({ hour, minute: numValue, meridiem });
|
|
4987
|
+
}
|
|
4988
|
+
}
|
|
4989
|
+
}
|
|
4990
|
+
};
|
|
4991
|
+
// Handle meridiem button click
|
|
4992
|
+
const handleMeridiemClick = (newMeridiem) => {
|
|
4993
|
+
setMeridiem(newMeridiem);
|
|
4994
|
+
onChange({ hour, minute, meridiem: newMeridiem });
|
|
4995
|
+
};
|
|
4996
|
+
const handleClear = () => {
|
|
4997
|
+
setHour(null);
|
|
4998
|
+
setMinute(null);
|
|
4999
|
+
setMeridiem(null);
|
|
5000
|
+
onChange({ hour: null, minute: null, meridiem: null });
|
|
5001
|
+
// Focus the hour field after clearing
|
|
5002
|
+
hourInputRef.current?.focus();
|
|
5003
|
+
};
|
|
5004
|
+
return (jsxRuntime.jsx(react.Flex, { direction: "column", gap: 3, children: jsxRuntime.jsxs(react.Grid, { justifyContent: "center", alignItems: "center", templateColumns: "60px 10px 60px 90px auto", gap: "2", width: "auto", minWidth: "250px", 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.jsxs(react.Flex, { gap: "1", children: [jsxRuntime.jsx(react.Button, { size: "sm", colorScheme: meridiem === "am" ? "blue" : "gray", variant: meridiem === "am" ? "solid" : "outline", onClick: () => handleMeridiemClick("am"), width: "40px", children: meridiemLabel.am }), jsxRuntime.jsx(react.Button, { size: "sm", colorScheme: meridiem === "pm" ? "blue" : "gray", variant: meridiem === "pm" ? "solid" : "outline", onClick: () => handleMeridiemClick("pm"), width: "40px", children: meridiemLabel.pm })] }), jsxRuntime.jsx(react.Button, { onClick: handleClear, size: "sm", variant: "ghost", children: jsxRuntime.jsx(md.MdCancel, {}) })] }) }));
|
|
5005
|
+
}
|
|
5006
|
+
|
|
5007
|
+
dayjs.extend(timezone);
|
|
5008
|
+
const TimePicker = ({ column, schema, prefix }) => {
|
|
5009
|
+
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
5010
|
+
const { translate, timezone } = useSchemaContext();
|
|
5011
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", timeFormat = "HH:mm:ssZ", displayTimeFormat = "hh:mm A", } = schema;
|
|
5012
|
+
const isRequired = required?.some((columnId) => columnId === column);
|
|
5013
|
+
const colLabel = `${prefix}${column}`;
|
|
5014
|
+
const [open, setOpen] = React.useState(false);
|
|
5015
|
+
const value = watch(colLabel);
|
|
5016
|
+
const displayedTime = dayjs(`1970-01-01T${value}`).tz(timezone).isValid()
|
|
5017
|
+
? dayjs(`1970-01-01T${value}`).tz(timezone).format(displayTimeFormat)
|
|
5018
|
+
: "";
|
|
5019
|
+
// Parse the initial time parts from the ISO time string (HH:mm:ss)
|
|
5020
|
+
const parseTime = (isoTime) => {
|
|
5021
|
+
if (!isoTime)
|
|
5022
|
+
return { hour: 12, minute: 0, meridiem: "am" };
|
|
5023
|
+
const parsed = dayjs(`1970-01-01T${isoTime}`).tz(timezone);
|
|
5024
|
+
if (!parsed.isValid())
|
|
5025
|
+
return { hour: 12, minute: 0, meridiem: "am" };
|
|
5026
|
+
let hour = parsed.hour();
|
|
5027
|
+
const minute = parsed.minute();
|
|
5028
|
+
const meridiem = hour >= 12 ? "pm" : "am";
|
|
5029
|
+
if (hour === 0)
|
|
5030
|
+
hour = 12;
|
|
5031
|
+
else if (hour > 12)
|
|
5032
|
+
hour -= 12;
|
|
5033
|
+
return { hour, minute, meridiem };
|
|
5034
|
+
};
|
|
5035
|
+
const initialTime = parseTime(value);
|
|
5036
|
+
const [hour, setHour] = React.useState(initialTime.hour);
|
|
5037
|
+
const [minute, setMinute] = React.useState(initialTime.minute);
|
|
5038
|
+
const [meridiem, setMeridiem] = React.useState(initialTime.meridiem);
|
|
5039
|
+
React.useEffect(() => {
|
|
5040
|
+
const { hour, minute, meridiem } = parseTime(value);
|
|
5041
|
+
setHour(hour);
|
|
5042
|
+
setMinute(minute);
|
|
5043
|
+
setMeridiem(meridiem);
|
|
5044
|
+
}, [value]);
|
|
5045
|
+
// Convert hour, minute, meridiem to 24-hour ISO time string
|
|
5046
|
+
const toIsoTime = (hour, minute, meridiem) => {
|
|
5047
|
+
if (hour === null || minute === null || meridiem === null)
|
|
5048
|
+
return null;
|
|
5049
|
+
let h = hour;
|
|
5050
|
+
if (meridiem === "am" && hour === 12)
|
|
5051
|
+
h = 0;
|
|
5052
|
+
else if (meridiem === "pm" && hour < 12)
|
|
5053
|
+
h = hour + 12;
|
|
5054
|
+
return dayjs(`1970-01-01T${h.toString().padStart(2, "0")}:${minute.toString().padStart(2, "0")}:00`)
|
|
5055
|
+
.tz(timezone)
|
|
5056
|
+
.format(timeFormat);
|
|
5057
|
+
};
|
|
5058
|
+
// Handle changes to time parts
|
|
5059
|
+
const handleTimeChange = ({ hour: newHour, minute: newMinute, meridiem: newMeridiem, }) => {
|
|
5060
|
+
setHour(newHour);
|
|
5061
|
+
setMinute(newMinute);
|
|
5062
|
+
setMeridiem(newMeridiem);
|
|
5063
|
+
const isoTime = toIsoTime(newHour, newMinute, newMeridiem);
|
|
5064
|
+
setValue(colLabel, isoTime, { shouldValidate: true, shouldDirty: true });
|
|
5065
|
+
};
|
|
5066
|
+
const containerRef = React.useRef(null);
|
|
5067
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
5068
|
+
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: () => {
|
|
5069
|
+
setOpen(true);
|
|
5070
|
+
}, justifyContent: "start", children: [jsxRuntime.jsx(io.IoMdClock, {}), !!value ? `${displayedTime}` : ""] }) }), jsxRuntime.jsx(react.Portal, { children: jsxRuntime.jsx(react.Popover.Positioner, { children: jsxRuntime.jsx(react.Popover.Content, { ref: containerRef, 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: {
|
|
5071
|
+
am: translate.t(`common.am`, { defaultValue: "AM" }),
|
|
5072
|
+
pm: translate.t(`common.pm`, { defaultValue: "PM" }),
|
|
5073
|
+
} }) }) }) }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
5074
|
+
};
|
|
5075
|
+
|
|
5076
|
+
function IsoTimePicker({ hour, setHour, minute, setMinute, second, setSecond, onChange = (_newValue) => { }, }) {
|
|
5077
|
+
// Refs for focus management
|
|
5078
|
+
const hourInputRef = React.useRef(null);
|
|
5079
|
+
const minuteInputRef = React.useRef(null);
|
|
5080
|
+
const secondInputRef = React.useRef(null);
|
|
5081
|
+
// Centralized handler for key events, value changes, and focus management
|
|
5082
|
+
const handleKeyDown = (e, field) => {
|
|
5083
|
+
const input = e.target;
|
|
5084
|
+
const value = input.value;
|
|
5085
|
+
// Handle navigation between fields
|
|
5086
|
+
if (e.key === "Tab") {
|
|
5087
|
+
return;
|
|
5088
|
+
}
|
|
5089
|
+
if (e.key === ":" && field === "hour") {
|
|
5090
|
+
e.preventDefault();
|
|
5091
|
+
minuteInputRef.current?.focus();
|
|
5092
|
+
return;
|
|
5093
|
+
}
|
|
5094
|
+
if (e.key === ":" && field === "minute") {
|
|
5095
|
+
e.preventDefault();
|
|
5096
|
+
secondInputRef.current?.focus();
|
|
5097
|
+
return;
|
|
5098
|
+
}
|
|
5099
|
+
if (e.key === "Backspace" && value === "") {
|
|
5100
|
+
e.preventDefault();
|
|
5101
|
+
if (field === "minute") {
|
|
5102
|
+
hourInputRef.current?.focus();
|
|
5103
|
+
}
|
|
5104
|
+
else if (field === "second") {
|
|
5105
|
+
minuteInputRef.current?.focus();
|
|
5106
|
+
}
|
|
5107
|
+
return;
|
|
5108
|
+
}
|
|
5109
|
+
// Handle number inputs
|
|
5110
|
+
if (field === "hour") {
|
|
5111
|
+
if (e.key.match(/^[0-9]$/)) {
|
|
5112
|
+
const newValue = value + e.key;
|
|
5113
|
+
const numValue = parseInt(newValue, 10);
|
|
5114
|
+
if (numValue > 23) {
|
|
5115
|
+
const digitValue = parseInt(e.key, 10);
|
|
5116
|
+
setHour(digitValue);
|
|
5117
|
+
onChange({ hour: digitValue, minute, second });
|
|
5118
|
+
return;
|
|
5119
|
+
}
|
|
5120
|
+
if (numValue >= 0 && numValue <= 23) {
|
|
5121
|
+
setHour(numValue);
|
|
5122
|
+
onChange({ hour: numValue, minute, second });
|
|
5123
|
+
e.preventDefault();
|
|
5124
|
+
minuteInputRef.current?.focus();
|
|
5125
|
+
}
|
|
5126
|
+
}
|
|
5127
|
+
}
|
|
5128
|
+
else if (field === "minute") {
|
|
5129
|
+
if (e.key.match(/^[0-9]$/)) {
|
|
5130
|
+
const newValue = value + e.key;
|
|
5131
|
+
const numValue = parseInt(newValue, 10);
|
|
5132
|
+
if (numValue > 59) {
|
|
5133
|
+
const digitValue = parseInt(e.key, 10);
|
|
5134
|
+
setMinute(digitValue);
|
|
5135
|
+
onChange({ hour, minute: digitValue, second });
|
|
5136
|
+
return;
|
|
5137
|
+
}
|
|
5138
|
+
if (numValue >= 0 && numValue <= 59) {
|
|
5139
|
+
setMinute(numValue);
|
|
5140
|
+
onChange({ hour, minute: numValue, second });
|
|
5141
|
+
e.preventDefault();
|
|
5142
|
+
secondInputRef.current?.focus();
|
|
5143
|
+
}
|
|
5144
|
+
}
|
|
5145
|
+
}
|
|
5146
|
+
else if (field === "second") {
|
|
5147
|
+
if (e.key.match(/^[0-9]$/)) {
|
|
5148
|
+
const newValue = value + e.key;
|
|
5149
|
+
const numValue = parseInt(newValue, 10);
|
|
5150
|
+
if (numValue > 59) {
|
|
5151
|
+
const digitValue = parseInt(e.key, 10);
|
|
5152
|
+
setSecond(digitValue);
|
|
5153
|
+
onChange({ hour, minute, second: digitValue });
|
|
5154
|
+
return;
|
|
5155
|
+
}
|
|
5156
|
+
if (numValue >= 0 && numValue <= 59) {
|
|
5157
|
+
setSecond(numValue);
|
|
5158
|
+
onChange({ hour, minute, second: numValue });
|
|
5159
|
+
}
|
|
5160
|
+
}
|
|
5161
|
+
}
|
|
5162
|
+
};
|
|
5163
|
+
const handleClear = () => {
|
|
5164
|
+
setHour(null);
|
|
5165
|
+
setMinute(null);
|
|
5166
|
+
setSecond(null);
|
|
5167
|
+
onChange({ hour: null, minute: null, second: null });
|
|
5168
|
+
hourInputRef.current?.focus();
|
|
5169
|
+
};
|
|
5170
|
+
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, {}) })] }) }));
|
|
5171
|
+
}
|
|
5172
|
+
|
|
5173
|
+
function DateTimePicker$1({ value, onChange, format = "date-time", showSeconds = false, labels = {
|
|
5174
|
+
monthNamesShort: [
|
|
5175
|
+
"Jan",
|
|
5176
|
+
"Feb",
|
|
5177
|
+
"Mar",
|
|
5178
|
+
"Apr",
|
|
5179
|
+
"May",
|
|
5180
|
+
"Jun",
|
|
5181
|
+
"Jul",
|
|
5182
|
+
"Aug",
|
|
5183
|
+
"Sep",
|
|
5184
|
+
"Oct",
|
|
5185
|
+
"Nov",
|
|
5186
|
+
"Dec",
|
|
5187
|
+
],
|
|
5188
|
+
weekdayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
|
|
5189
|
+
backButtonLabel: "Back",
|
|
5190
|
+
forwardButtonLabel: "Next",
|
|
5191
|
+
}, timezone = "Asia/Hong_Kong", }) {
|
|
5192
|
+
const [selectedDate, setSelectedDate] = React.useState(value || "");
|
|
5193
|
+
// Time state for 12-hour format
|
|
5194
|
+
const [hour12, setHour12] = React.useState(value ? dayjs(value).hour() % 12 || 12 : null);
|
|
5195
|
+
const [minute, setMinute] = React.useState(value ? dayjs(value).minute() : null);
|
|
5196
|
+
const [meridiem, setMeridiem] = React.useState(value ? (dayjs(value).hour() >= 12 ? "pm" : "am") : null);
|
|
5197
|
+
// Time state for 24-hour format
|
|
5198
|
+
const [hour24, setHour24] = React.useState(value ? dayjs(value).hour() : null);
|
|
5199
|
+
const [second, setSecond] = React.useState(value ? dayjs(value).second() : null);
|
|
5200
|
+
const handleDateChange = (date) => {
|
|
5201
|
+
setSelectedDate(date);
|
|
5202
|
+
updateDateTime(dayjs(date).tz(timezone).toISOString());
|
|
5203
|
+
};
|
|
5204
|
+
const handleTimeChange = (timeData) => {
|
|
5205
|
+
if (format === "iso-date-time") {
|
|
5206
|
+
setHour24(timeData.hour);
|
|
5207
|
+
setMinute(timeData.minute);
|
|
5208
|
+
if (showSeconds)
|
|
5209
|
+
setSecond(timeData.second);
|
|
5210
|
+
}
|
|
5211
|
+
else {
|
|
5212
|
+
setHour12(timeData.hour);
|
|
5213
|
+
setMinute(timeData.minute);
|
|
5214
|
+
setMeridiem(timeData.meridiem);
|
|
5215
|
+
}
|
|
5216
|
+
updateDateTime(dayjs(selectedDate).tz(timezone).toISOString(), timeData);
|
|
5217
|
+
};
|
|
5218
|
+
const updateDateTime = (date, timeData) => {
|
|
5219
|
+
if (!date) {
|
|
5220
|
+
onChange?.(undefined);
|
|
5221
|
+
return;
|
|
5222
|
+
}
|
|
5223
|
+
// use dayjs to convert the date to the timezone
|
|
5224
|
+
const newDate = dayjs(date).tz(timezone).toDate();
|
|
5225
|
+
if (format === "iso-date-time") {
|
|
5226
|
+
const h = timeData?.hour ?? hour24;
|
|
5227
|
+
const m = timeData?.minute ?? minute;
|
|
5228
|
+
const s = showSeconds ? timeData?.second ?? second : 0;
|
|
5229
|
+
if (h !== null)
|
|
5230
|
+
newDate.setHours(h);
|
|
5231
|
+
if (m !== null)
|
|
5232
|
+
newDate.setMinutes(m);
|
|
5233
|
+
if (s !== null)
|
|
5234
|
+
newDate.setSeconds(s);
|
|
5235
|
+
}
|
|
5236
|
+
else {
|
|
5237
|
+
const h = timeData?.hour ?? hour12;
|
|
5238
|
+
const m = timeData?.minute ?? minute;
|
|
5239
|
+
const mer = timeData?.meridiem ?? meridiem;
|
|
5240
|
+
if (h !== null && mer !== null) {
|
|
5241
|
+
let hour24 = h;
|
|
5242
|
+
if (mer === "am" && h === 12)
|
|
5243
|
+
hour24 = 0;
|
|
5244
|
+
else if (mer === "pm" && h < 12)
|
|
5245
|
+
hour24 = h + 12;
|
|
5246
|
+
newDate.setHours(hour24);
|
|
5247
|
+
}
|
|
5248
|
+
if (m !== null)
|
|
5249
|
+
newDate.setMinutes(m);
|
|
5250
|
+
newDate.setSeconds(0);
|
|
5251
|
+
}
|
|
5252
|
+
onChange?.(dayjs(newDate).tz(timezone).toISOString());
|
|
5253
|
+
};
|
|
5254
|
+
const handleClear = () => {
|
|
5255
|
+
setSelectedDate("");
|
|
5256
|
+
setHour12(null);
|
|
5257
|
+
setHour24(null);
|
|
5258
|
+
setMinute(null);
|
|
5259
|
+
setSecond(null);
|
|
5260
|
+
setMeridiem(null);
|
|
5261
|
+
onChange?.(undefined);
|
|
5262
|
+
};
|
|
5263
|
+
const isISO = format === "iso-date-time";
|
|
5264
|
+
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
|
|
5265
|
+
? dayjs(selectedDate).tz(timezone).toDate()
|
|
5266
|
+
: 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
|
|
5267
|
+
? showSeconds
|
|
5268
|
+
? "YYYY-MM-DD HH:mm:ss"
|
|
5269
|
+
: "YYYY-MM-DD HH:mm"
|
|
5270
|
+
: "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 })] }))] }));
|
|
5271
|
+
}
|
|
5272
|
+
|
|
5273
|
+
dayjs.extend(utc);
|
|
5274
|
+
dayjs.extend(timezone);
|
|
5275
|
+
const DateTimePicker = ({ column, schema, prefix, }) => {
|
|
5276
|
+
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
5277
|
+
const { translate, timezone } = useSchemaContext();
|
|
5278
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD HH:mm:ss",
|
|
5279
|
+
// with timezone
|
|
5280
|
+
dateFormat = "YYYY-MM-DD[T]HH:mm:ssZ", } = schema;
|
|
5281
|
+
const isRequired = required?.some((columnId) => columnId === column);
|
|
5282
|
+
const colLabel = `${prefix}${column}`;
|
|
5283
|
+
const [open, setOpen] = React.useState(false);
|
|
5284
|
+
const selectedDate = watch(colLabel);
|
|
5285
|
+
const displayDate = dayjs(selectedDate)
|
|
5286
|
+
.tz(timezone)
|
|
5287
|
+
.format(displayDateFormat);
|
|
5288
|
+
React.useEffect(() => {
|
|
5289
|
+
try {
|
|
5290
|
+
if (selectedDate) {
|
|
5291
|
+
// Parse the selectedDate as UTC or in a specific timezone to avoid +8 hour shift
|
|
5292
|
+
// For example, parse as UTC:
|
|
5293
|
+
const parsedDate = dayjs(selectedDate).tz(timezone);
|
|
5294
|
+
if (!parsedDate.isValid())
|
|
5295
|
+
return;
|
|
5296
|
+
// Format according to dateFormat from schema
|
|
5297
|
+
const formatted = parsedDate.format(dateFormat);
|
|
5298
|
+
// Update the form value only if different to avoid loops
|
|
5299
|
+
if (formatted !== selectedDate) {
|
|
5300
|
+
setValue(colLabel, formatted, {
|
|
5301
|
+
shouldValidate: true,
|
|
5302
|
+
shouldDirty: true,
|
|
5303
|
+
});
|
|
5304
|
+
}
|
|
5305
|
+
}
|
|
5306
|
+
}
|
|
5307
|
+
catch (e) {
|
|
5308
|
+
console.error(e);
|
|
5309
|
+
}
|
|
5310
|
+
}, [selectedDate, dateFormat, colLabel, setValue]);
|
|
5311
|
+
const customTranslate = (label) => {
|
|
5312
|
+
return translateWrapper({ prefix, column, label, translate });
|
|
5313
|
+
};
|
|
5314
|
+
return (jsxRuntime.jsxs(Field, { label: `${customTranslate(`field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
5315
|
+
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: () => {
|
|
5316
|
+
setOpen(true);
|
|
5317
|
+
}, 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) => {
|
|
5318
|
+
setValue(colLabel, dayjs(date).tz(timezone).format(dateFormat));
|
|
5319
|
+
}, timezone: timezone, labels: {
|
|
5320
|
+
monthNamesShort: [
|
|
5321
|
+
translate.t(`common.month_1`, { defaultValue: "January" }),
|
|
5322
|
+
translate.t(`common.month_2`, { defaultValue: "February" }),
|
|
5323
|
+
translate.t(`common.month_3`, { defaultValue: "March" }),
|
|
5324
|
+
translate.t(`common.month_4`, { defaultValue: "April" }),
|
|
5325
|
+
translate.t(`common.month_5`, { defaultValue: "May" }),
|
|
5326
|
+
translate.t(`common.month_6`, { defaultValue: "June" }),
|
|
5327
|
+
translate.t(`common.month_7`, { defaultValue: "July" }),
|
|
5328
|
+
translate.t(`common.month_8`, { defaultValue: "August" }),
|
|
5329
|
+
translate.t(`common.month_9`, { defaultValue: "September" }),
|
|
5330
|
+
translate.t(`common.month_10`, { defaultValue: "October" }),
|
|
5331
|
+
translate.t(`common.month_11`, { defaultValue: "November" }),
|
|
5332
|
+
translate.t(`common.month_12`, { defaultValue: "December" }),
|
|
5333
|
+
],
|
|
5334
|
+
weekdayNamesShort: [
|
|
5335
|
+
translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
|
|
5336
|
+
translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
|
|
5337
|
+
translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
|
|
5338
|
+
translate.t(`common.weekday_4`, {
|
|
5339
|
+
defaultValue: "Wed",
|
|
5340
|
+
}),
|
|
5341
|
+
translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
|
|
5342
|
+
translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
|
|
5343
|
+
translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
|
|
5344
|
+
],
|
|
5345
|
+
backButtonLabel: translate.t(`common.back_button`, {
|
|
5346
|
+
defaultValue: "Back",
|
|
5347
|
+
}),
|
|
5348
|
+
forwardButtonLabel: translate.t(`common.forward_button`, {
|
|
5349
|
+
defaultValue: "Forward",
|
|
5350
|
+
}),
|
|
5351
|
+
} })] }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: customTranslate(`field_required`) }))] }));
|
|
5352
|
+
};
|
|
5353
|
+
|
|
4527
5354
|
const SchemaRenderer = ({ schema, prefix, column, }) => {
|
|
4528
5355
|
const colSchema = schema;
|
|
4529
|
-
const { type, variant, properties: innerProperties, foreign_key, items, } = schema;
|
|
5356
|
+
const { type, variant, properties: innerProperties, foreign_key, format, items, } = schema;
|
|
5357
|
+
if (variant === "custom-input") {
|
|
5358
|
+
return jsxRuntime.jsx(CustomInput, { schema: colSchema, prefix, column });
|
|
5359
|
+
}
|
|
4530
5360
|
if (type === "string") {
|
|
4531
5361
|
if ((schema.enum ?? []).length > 0) {
|
|
4532
5362
|
return jsxRuntime.jsx(EnumPicker, { schema: colSchema, prefix, column });
|
|
@@ -4535,9 +5365,18 @@ const SchemaRenderer = ({ schema, prefix, column, }) => {
|
|
|
4535
5365
|
idPickerSanityCheck(column, foreign_key);
|
|
4536
5366
|
return jsxRuntime.jsx(IdPicker, { schema: colSchema, prefix, column });
|
|
4537
5367
|
}
|
|
4538
|
-
if (
|
|
5368
|
+
if (format === "date") {
|
|
4539
5369
|
return jsxRuntime.jsx(DatePicker, { schema: colSchema, prefix, column });
|
|
4540
5370
|
}
|
|
5371
|
+
if (format === "time") {
|
|
5372
|
+
return jsxRuntime.jsx(TimePicker, { schema: colSchema, prefix, column });
|
|
5373
|
+
}
|
|
5374
|
+
if (format === "date-time") {
|
|
5375
|
+
return jsxRuntime.jsx(DateTimePicker, { schema: colSchema, prefix, column });
|
|
5376
|
+
}
|
|
5377
|
+
if (variant === "text-area") {
|
|
5378
|
+
return jsxRuntime.jsx(TextAreaInput, { schema: colSchema, prefix, column });
|
|
5379
|
+
}
|
|
4541
5380
|
return jsxRuntime.jsx(StringInputField, { schema: colSchema, prefix, column });
|
|
4542
5381
|
}
|
|
4543
5382
|
if (type === "number" || type === "integer") {
|
|
@@ -4584,39 +5423,56 @@ const ColumnRenderer = ({ column, properties, prefix, }) => {
|
|
|
4584
5423
|
};
|
|
4585
5424
|
|
|
4586
5425
|
const ArrayViewer = ({ schema, column, prefix }) => {
|
|
4587
|
-
const {
|
|
5426
|
+
const { gridColumn = "span 12", gridRow = "span 1", required, items, } = schema;
|
|
4588
5427
|
const { translate } = useSchemaContext();
|
|
4589
5428
|
const colLabel = `${prefix}${column}`;
|
|
4590
5429
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4591
5430
|
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
4592
5431
|
const values = watch(colLabel) ?? [];
|
|
4593
|
-
return (jsxRuntime.jsxs(react.Box, { gridRow, gridColumn, children: [jsxRuntime.jsxs(react.Box, { as: "label", gridColumn: "1/span12", children: [`${translate.t(removeIndex(`${colLabel}.
|
|
4594
|
-
|
|
4595
|
-
|
|
5432
|
+
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: {
|
|
5433
|
+
base: "colorPalette.200",
|
|
5434
|
+
_dark: "colorPalette.800",
|
|
5435
|
+
}, children: jsxRuntime.jsx(react.Grid, { gap: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: jsxRuntime.jsx(SchemaViewer, { column: `${index}`,
|
|
5436
|
+
prefix: `${colLabel}.`,
|
|
5437
|
+
// @ts-expect-error find suitable types
|
|
5438
|
+
schema: { showLabel: false, ...(items ?? {}) } }) }) }, `form-${prefix}${column}.${index}`))) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4596
5439
|
};
|
|
4597
5440
|
|
|
4598
5441
|
const BooleanViewer = ({ schema, column, prefix, }) => {
|
|
4599
5442
|
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
4600
5443
|
const { translate } = useSchemaContext();
|
|
4601
|
-
const { required, gridColumn, gridRow } = schema;
|
|
5444
|
+
const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
|
|
4602
5445
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4603
5446
|
const colLabel = `${prefix}${column}`;
|
|
4604
5447
|
const value = watch(colLabel);
|
|
4605
|
-
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.
|
|
5448
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
4606
5449
|
gridRow, children: [jsxRuntime.jsx(react.Text, { children: value
|
|
4607
5450
|
? translate.t(removeIndex(`${colLabel}.true`))
|
|
4608
|
-
: translate.t(removeIndex(`${colLabel}.false`)) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.
|
|
5451
|
+
: translate.t(removeIndex(`${colLabel}.false`)) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
5452
|
+
};
|
|
5453
|
+
|
|
5454
|
+
const CustomViewer = ({ column, schema, prefix }) => {
|
|
5455
|
+
const formContext = reactHookForm.useFormContext();
|
|
5456
|
+
const { inputViewerRender } = schema;
|
|
5457
|
+
return (inputViewerRender &&
|
|
5458
|
+
inputViewerRender({
|
|
5459
|
+
column,
|
|
5460
|
+
schema,
|
|
5461
|
+
prefix,
|
|
5462
|
+
formContext,
|
|
5463
|
+
}));
|
|
4609
5464
|
};
|
|
4610
5465
|
|
|
4611
5466
|
const DateViewer = ({ column, schema, prefix }) => {
|
|
4612
5467
|
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
4613
|
-
const { translate } = useSchemaContext();
|
|
4614
|
-
const { required, gridColumn, gridRow } = schema;
|
|
5468
|
+
const { translate, timezone } = useSchemaContext();
|
|
5469
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD", } = schema;
|
|
4615
5470
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4616
5471
|
const colLabel = `${prefix}${column}`;
|
|
4617
5472
|
const selectedDate = watch(colLabel);
|
|
4618
|
-
|
|
4619
|
-
|
|
5473
|
+
const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
|
|
5474
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
5475
|
+
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`) }))] }));
|
|
4620
5476
|
};
|
|
4621
5477
|
|
|
4622
5478
|
const EnumViewer = ({ column, isMultiple = false, schema, prefix, }) => {
|
|
@@ -4624,45 +5480,41 @@ const EnumViewer = ({ column, isMultiple = false, schema, prefix, }) => {
|
|
|
4624
5480
|
const { translate } = useSchemaContext();
|
|
4625
5481
|
const { required } = schema;
|
|
4626
5482
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4627
|
-
const { gridColumn, gridRow, renderDisplay } = schema;
|
|
5483
|
+
const { gridColumn = "span 4", gridRow = "span 1", renderDisplay } = schema;
|
|
4628
5484
|
const colLabel = `${prefix}${column}`;
|
|
4629
5485
|
const watchEnum = watch(colLabel);
|
|
4630
5486
|
const watchEnums = (watch(colLabel) ?? []);
|
|
4631
|
-
|
|
5487
|
+
const customTranslate = (label) => {
|
|
5488
|
+
return translateWrapper({ prefix, column, label, translate });
|
|
5489
|
+
};
|
|
5490
|
+
return (jsxRuntime.jsxs(Field, { label: `${customTranslate(`field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
4632
5491
|
gridRow, children: [isMultiple && (jsxRuntime.jsx(react.Flex, { flexFlow: "wrap", gap: 1, children: watchEnums.map((enumValue) => {
|
|
4633
5492
|
const item = enumValue;
|
|
4634
5493
|
if (item === undefined) {
|
|
4635
5494
|
return jsxRuntime.jsx(jsxRuntime.Fragment, { children: "undefined" });
|
|
4636
5495
|
}
|
|
4637
|
-
return (jsxRuntime.jsx(Tag, {
|
|
5496
|
+
return (jsxRuntime.jsx(Tag, { children: !!renderDisplay === true
|
|
4638
5497
|
? renderDisplay(item)
|
|
4639
|
-
:
|
|
4640
|
-
}) })), !isMultiple &&
|
|
5498
|
+
: customTranslate(item) }));
|
|
5499
|
+
}) })), !isMultiple && jsxRuntime.jsx(react.Text, { children: customTranslate(watchEnum) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: customTranslate(`field_required`) }))] }));
|
|
4641
5500
|
};
|
|
4642
5501
|
|
|
4643
5502
|
const FileViewer = ({ column, schema, prefix }) => {
|
|
4644
|
-
const {
|
|
5503
|
+
const { watch } = reactHookForm.useFormContext();
|
|
4645
5504
|
const { translate } = useSchemaContext();
|
|
4646
|
-
const { required, gridColumn, gridRow } = schema;
|
|
5505
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", } = schema;
|
|
4647
5506
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4648
5507
|
const currentFiles = (watch(column) ?? []);
|
|
4649
5508
|
const colLabel = `${prefix}${column}`;
|
|
4650
|
-
return (jsxRuntime.
|
|
4651
|
-
|
|
4652
|
-
|
|
4653
|
-
}, placeholder: translate.t(`${colLabel}.fileDropzone`) }), jsxRuntime.jsx(react.Flex, { flexFlow: "column", gap: 1, children: currentFiles.map((file) => {
|
|
4654
|
-
return (jsxRuntime.jsx(react.Card.Root, { variant: "subtle", children: jsxRuntime.jsxs(react.Card.Body, { gap: "2", cursor: "pointer", onClick: () => {
|
|
4655
|
-
setValue(column, currentFiles.filter(({ name }) => {
|
|
4656
|
-
return name !== file.name;
|
|
4657
|
-
}));
|
|
4658
|
-
}, display: "flex", flexFlow: "row", alignItems: "center", padding: "2", children: [jsxRuntime.jsx(react.Box, { children: file.name }), jsxRuntime.jsx(ti.TiDeleteOutline, {})] }) }, file.name));
|
|
4659
|
-
}) }), errors[`${colLabel}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.fieldRequired`)) }))] }));
|
|
5509
|
+
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) => {
|
|
5510
|
+
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));
|
|
5511
|
+
}) }) }));
|
|
4660
5512
|
};
|
|
4661
5513
|
|
|
4662
5514
|
const IdViewer = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
4663
5515
|
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
4664
5516
|
const { idMap, translate } = useSchemaContext();
|
|
4665
|
-
const { required, gridColumn, gridRow, renderDisplay, foreign_key } = schema;
|
|
5517
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", renderDisplay, foreign_key, } = schema;
|
|
4666
5518
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4667
5519
|
const { display_column } = foreign_key;
|
|
4668
5520
|
const colLabel = `${prefix}${column}`;
|
|
@@ -4678,7 +5530,7 @@ const IdViewer = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4678
5530
|
}
|
|
4679
5531
|
return record[display_column];
|
|
4680
5532
|
};
|
|
4681
|
-
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${column}.
|
|
5533
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
4682
5534
|
gridRow, children: [isMultiple && (jsxRuntime.jsx(react.Flex, { flexFlow: "wrap", gap: 1, children: watchIds.map((id) => {
|
|
4683
5535
|
const item = idMap[id];
|
|
4684
5536
|
if (item === undefined) {
|
|
@@ -4687,21 +5539,21 @@ const IdViewer = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4687
5539
|
return (jsxRuntime.jsx(Tag, { closable: true, children: !!renderDisplay === true
|
|
4688
5540
|
? renderDisplay(item)
|
|
4689
5541
|
: item[display_column] }, id));
|
|
4690
|
-
}) })), !isMultiple && jsxRuntime.jsx(react.Text, { children: getPickedValue() }), errors[`${colLabel}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.
|
|
5542
|
+
}) })), !isMultiple && jsxRuntime.jsx(react.Text, { children: getPickedValue() }), errors[`${colLabel}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4691
5543
|
};
|
|
4692
5544
|
|
|
4693
5545
|
const NumberViewer = ({ schema, column, prefix, }) => {
|
|
4694
5546
|
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
4695
5547
|
const { translate } = useSchemaContext();
|
|
4696
|
-
const { required, gridColumn, gridRow } = schema;
|
|
5548
|
+
const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
|
|
4697
5549
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4698
5550
|
const colLabel = `${prefix}${column}`;
|
|
4699
5551
|
const value = watch(colLabel);
|
|
4700
|
-
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.
|
|
5552
|
+
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`)) }))] }));
|
|
4701
5553
|
};
|
|
4702
5554
|
|
|
4703
5555
|
const ObjectViewer = ({ schema, column, prefix }) => {
|
|
4704
|
-
const { properties,
|
|
5556
|
+
const { properties, gridColumn = "span 12", gridRow = "span 1", required, showLabel = true, } = schema;
|
|
4705
5557
|
const { translate } = useSchemaContext();
|
|
4706
5558
|
const colLabel = `${prefix}${column}`;
|
|
4707
5559
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
@@ -4709,25 +5561,28 @@ const ObjectViewer = ({ schema, column, prefix }) => {
|
|
|
4709
5561
|
if (properties === undefined) {
|
|
4710
5562
|
throw new Error(`properties is undefined when using ObjectInput`);
|
|
4711
5563
|
}
|
|
4712
|
-
return (jsxRuntime.jsxs(react.Box, { gridRow, gridColumn, children: [jsxRuntime.jsxs(react.Box, { as: "label",
|
|
5564
|
+
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: {
|
|
5565
|
+
base: "colorPalette.200",
|
|
5566
|
+
_dark: "colorPalette.800",
|
|
5567
|
+
}, children: Object.keys(properties ?? {}).map((key) => {
|
|
4713
5568
|
return (
|
|
4714
5569
|
// @ts-expect-error find suitable types
|
|
4715
5570
|
jsxRuntime.jsx(ColumnViewer, { column: `${key}`,
|
|
4716
5571
|
prefix: `${prefix}${column}.`,
|
|
4717
5572
|
properties }, `form-objectviewer-${colLabel}-${key}`));
|
|
4718
|
-
}) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.
|
|
5573
|
+
}) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4719
5574
|
};
|
|
4720
5575
|
|
|
4721
5576
|
const RecordInput = ({ column, schema, prefix }) => {
|
|
4722
5577
|
const { formState: { errors }, setValue, getValues, } = reactHookForm.useFormContext();
|
|
4723
5578
|
const { translate } = useSchemaContext();
|
|
4724
|
-
const { required, gridColumn, gridRow } = schema;
|
|
5579
|
+
const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
|
|
4725
5580
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4726
5581
|
const entries = Object.entries(getValues(column) ?? {});
|
|
4727
5582
|
const [showNewEntries, setShowNewEntries] = React.useState(false);
|
|
4728
5583
|
const [newKey, setNewKey] = React.useState();
|
|
4729
5584
|
const [newValue, setNewValue] = React.useState();
|
|
4730
|
-
return (jsxRuntime.jsxs(Field, { label: `${translate.t(`${column}.
|
|
5585
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(`${column}.field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn, gridRow, children: [entries.map(([key, value]) => {
|
|
4731
5586
|
return (jsxRuntime.jsxs(react.Grid, { templateColumns: "1fr 1fr auto", gap: 1, children: [jsxRuntime.jsx(react.Input, { value: key, onChange: (e) => {
|
|
4732
5587
|
const filtered = entries.filter(([target]) => {
|
|
4733
5588
|
return target !== key;
|
|
@@ -4767,7 +5622,17 @@ const RecordInput = ({ column, schema, prefix }) => {
|
|
|
4767
5622
|
setShowNewEntries(true);
|
|
4768
5623
|
setNewKey(undefined);
|
|
4769
5624
|
setNewValue(undefined);
|
|
4770
|
-
}, children: translate.t(`${column}.addNew`) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(`${column}.
|
|
5625
|
+
}, children: translate.t(`${column}.addNew`) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
|
|
5626
|
+
};
|
|
5627
|
+
|
|
5628
|
+
const StringViewer = ({ column, schema, prefix, }) => {
|
|
5629
|
+
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
5630
|
+
const { translate } = useSchemaContext();
|
|
5631
|
+
const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
|
|
5632
|
+
const isRequired = required?.some((columnId) => columnId === column);
|
|
5633
|
+
const colLabel = `${prefix}${column}`;
|
|
5634
|
+
const value = watch(colLabel);
|
|
5635
|
+
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`)) }))] }) }));
|
|
4771
5636
|
};
|
|
4772
5637
|
|
|
4773
5638
|
const TagViewer = ({ column, schema, prefix }) => {
|
|
@@ -4855,19 +5720,50 @@ const TagViewer = ({ column, schema, prefix }) => {
|
|
|
4855
5720
|
}), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: (errors[`${column}`]?.message ?? "No error message") }))] }));
|
|
4856
5721
|
};
|
|
4857
5722
|
|
|
4858
|
-
const
|
|
5723
|
+
const TextAreaViewer = ({ column, schema, prefix, }) => {
|
|
4859
5724
|
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
4860
5725
|
const { translate } = useSchemaContext();
|
|
4861
|
-
const { required, gridColumn, gridRow } = schema;
|
|
5726
|
+
const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
|
|
4862
5727
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4863
5728
|
const colLabel = `${prefix}${column}`;
|
|
4864
5729
|
const value = watch(colLabel);
|
|
4865
|
-
return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.
|
|
5730
|
+
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`)) }))] }) }));
|
|
5731
|
+
};
|
|
5732
|
+
|
|
5733
|
+
const TimeViewer = ({ column, schema, prefix }) => {
|
|
5734
|
+
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
5735
|
+
const { translate, timezone } = useSchemaContext();
|
|
5736
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", displayTimeFormat = "hh:mm A", } = schema;
|
|
5737
|
+
const isRequired = required?.some((columnId) => columnId === column);
|
|
5738
|
+
const colLabel = `${prefix}${column}`;
|
|
5739
|
+
const selectedDate = watch(colLabel);
|
|
5740
|
+
const displayedTime = dayjs(`1970-01-01T${selectedDate}`)
|
|
5741
|
+
.tz(timezone)
|
|
5742
|
+
.isValid()
|
|
5743
|
+
? dayjs(`1970-01-01T${selectedDate}`).tz(timezone).format(displayTimeFormat)
|
|
5744
|
+
: "";
|
|
5745
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
5746
|
+
gridRow, children: [jsxRuntime.jsx(react.Text, { children: displayedTime }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
|
|
5747
|
+
};
|
|
5748
|
+
|
|
5749
|
+
const DateTimeViewer = ({ column, schema, prefix }) => {
|
|
5750
|
+
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
5751
|
+
const { translate, timezone } = useSchemaContext();
|
|
5752
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD HH:mm:ss", } = schema;
|
|
5753
|
+
const isRequired = required?.some((columnId) => columnId === column);
|
|
5754
|
+
const colLabel = `${prefix}${column}`;
|
|
5755
|
+
const selectedDate = watch(colLabel);
|
|
5756
|
+
const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
|
|
5757
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
5758
|
+
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`) }))] }));
|
|
4866
5759
|
};
|
|
4867
5760
|
|
|
4868
5761
|
const SchemaViewer = ({ schema, prefix, column, }) => {
|
|
4869
5762
|
const colSchema = schema;
|
|
4870
|
-
const { type, variant, properties: innerProperties, foreign_key, items, } = schema;
|
|
5763
|
+
const { type, variant, properties: innerProperties, foreign_key, items, format, } = schema;
|
|
5764
|
+
if (variant === "custom-input") {
|
|
5765
|
+
return jsxRuntime.jsx(CustomViewer, { schema: colSchema, prefix, column });
|
|
5766
|
+
}
|
|
4871
5767
|
if (type === "string") {
|
|
4872
5768
|
if ((schema.enum ?? []).length > 0) {
|
|
4873
5769
|
return jsxRuntime.jsx(EnumViewer, { schema: colSchema, prefix, column });
|
|
@@ -4876,9 +5772,18 @@ const SchemaViewer = ({ schema, prefix, column, }) => {
|
|
|
4876
5772
|
idPickerSanityCheck(column, foreign_key);
|
|
4877
5773
|
return jsxRuntime.jsx(IdViewer, { schema: colSchema, prefix, column });
|
|
4878
5774
|
}
|
|
4879
|
-
if (
|
|
5775
|
+
if (format === "time") {
|
|
5776
|
+
return jsxRuntime.jsx(TimeViewer, { schema: colSchema, prefix, column });
|
|
5777
|
+
}
|
|
5778
|
+
if (format === "date") {
|
|
4880
5779
|
return jsxRuntime.jsx(DateViewer, { schema: colSchema, prefix, column });
|
|
4881
5780
|
}
|
|
5781
|
+
if (format === "date-time") {
|
|
5782
|
+
return jsxRuntime.jsx(DateTimeViewer, { schema: colSchema, prefix, column });
|
|
5783
|
+
}
|
|
5784
|
+
if (variant === "text-area") {
|
|
5785
|
+
return jsxRuntime.jsx(TextAreaViewer, { schema: colSchema, prefix, column });
|
|
5786
|
+
}
|
|
4882
5787
|
return jsxRuntime.jsx(StringViewer, { schema: colSchema, prefix, column });
|
|
4883
5788
|
}
|
|
4884
5789
|
if (type === "number" || type === "integer") {
|
|
@@ -4927,10 +5832,24 @@ const ColumnViewer = ({ column, properties, prefix, }) => {
|
|
|
4927
5832
|
};
|
|
4928
5833
|
|
|
4929
5834
|
const SubmitButton = () => {
|
|
4930
|
-
const { translate, setValidatedData, setIsError, setIsConfirming } = useSchemaContext();
|
|
5835
|
+
const { translate, setValidatedData, setIsError, setIsConfirming, setError, schema, } = useSchemaContext();
|
|
4931
5836
|
const methods = reactHookForm.useFormContext();
|
|
4932
5837
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4933
5838
|
const onValid = (data) => {
|
|
5839
|
+
// Validate data using AJV before proceeding to confirmation
|
|
5840
|
+
const validate = new Ajv({
|
|
5841
|
+
strict: false,
|
|
5842
|
+
allErrors: true,
|
|
5843
|
+
}).compile(schema);
|
|
5844
|
+
const validationResult = validate(data);
|
|
5845
|
+
// @ts-expect-error TODO: find appropriate type
|
|
5846
|
+
const errors = validationResult.errors;
|
|
5847
|
+
if (errors && errors.length > 0) {
|
|
5848
|
+
setError(errors);
|
|
5849
|
+
setIsError(true);
|
|
5850
|
+
return;
|
|
5851
|
+
}
|
|
5852
|
+
// If validation passes, proceed to confirmation
|
|
4934
5853
|
setValidatedData(data);
|
|
4935
5854
|
setIsError(false);
|
|
4936
5855
|
setIsConfirming(true);
|
|
@@ -4941,7 +5860,7 @@ const SubmitButton = () => {
|
|
|
4941
5860
|
};
|
|
4942
5861
|
|
|
4943
5862
|
const FormBody = () => {
|
|
4944
|
-
const { schema, requestUrl, order, ignore, include, onSubmit, rowNumber, translate, requestOptions, isSuccess, setIsSuccess, isError, setIsError, isSubmiting, setIsSubmiting, isConfirming, setIsConfirming, validatedData, setValidatedData, error, setError, getUpdatedData, } = useSchemaContext();
|
|
5863
|
+
const { schema, requestUrl, order, ignore, include, onSubmit, rowNumber, translate, requestOptions, isSuccess, setIsSuccess, isError, setIsError, isSubmiting, setIsSubmiting, isConfirming, setIsConfirming, validatedData, setValidatedData, error, setError, getUpdatedData, customErrorRenderer, } = useSchemaContext();
|
|
4945
5864
|
const methods = reactHookForm.useFormContext();
|
|
4946
5865
|
const { properties } = schema;
|
|
4947
5866
|
const onBeforeSubmit = () => {
|
|
@@ -4957,6 +5876,39 @@ const FormBody = () => {
|
|
|
4957
5876
|
const onSubmitSuccess = () => {
|
|
4958
5877
|
setIsSuccess(true);
|
|
4959
5878
|
};
|
|
5879
|
+
// Enhanced validation function using AJV with i18n support
|
|
5880
|
+
const validateFormData = (data) => {
|
|
5881
|
+
try {
|
|
5882
|
+
const ajv = new Ajv({
|
|
5883
|
+
strict: false,
|
|
5884
|
+
allErrors: true,
|
|
5885
|
+
});
|
|
5886
|
+
addFormats(ajv);
|
|
5887
|
+
addErrors(ajv);
|
|
5888
|
+
const validate = ajv.compile(schema);
|
|
5889
|
+
const validationResult = validate(data);
|
|
5890
|
+
const errors = validate.errors;
|
|
5891
|
+
console.log({
|
|
5892
|
+
isValid: validationResult,
|
|
5893
|
+
errors,
|
|
5894
|
+
}, "plkdfs");
|
|
5895
|
+
return {
|
|
5896
|
+
isValid: validationResult,
|
|
5897
|
+
errors,
|
|
5898
|
+
};
|
|
5899
|
+
}
|
|
5900
|
+
catch (error) {
|
|
5901
|
+
return {
|
|
5902
|
+
isValid: false,
|
|
5903
|
+
errors: [
|
|
5904
|
+
{
|
|
5905
|
+
field: "validation",
|
|
5906
|
+
message: error instanceof Error ? error.message : "Unknown error",
|
|
5907
|
+
},
|
|
5908
|
+
],
|
|
5909
|
+
};
|
|
5910
|
+
}
|
|
5911
|
+
};
|
|
4960
5912
|
const defaultOnSubmit = async (promise) => {
|
|
4961
5913
|
try {
|
|
4962
5914
|
onBeforeSubmit();
|
|
@@ -4981,12 +5933,28 @@ const FormBody = () => {
|
|
|
4981
5933
|
};
|
|
4982
5934
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4983
5935
|
const onFormSubmit = async (data) => {
|
|
5936
|
+
// Validate data using AJV before submission
|
|
5937
|
+
const validationResult = validateFormData(data);
|
|
5938
|
+
if (!validationResult.isValid) {
|
|
5939
|
+
// Set validation errors
|
|
5940
|
+
const validationErrorMessage = {
|
|
5941
|
+
type: "validation",
|
|
5942
|
+
errors: validationResult.errors,
|
|
5943
|
+
message: translate.t("validation_error"),
|
|
5944
|
+
};
|
|
5945
|
+
onSubmitError(validationErrorMessage);
|
|
5946
|
+
return;
|
|
5947
|
+
}
|
|
4984
5948
|
if (onSubmit === undefined) {
|
|
4985
5949
|
await defaultOnSubmit(defaultSubmitPromise(data));
|
|
4986
5950
|
return;
|
|
4987
5951
|
}
|
|
4988
5952
|
await defaultOnSubmit(onSubmit(data));
|
|
4989
5953
|
};
|
|
5954
|
+
// Custom error renderer for validation errors with i18n support
|
|
5955
|
+
const renderValidationErrors = (validationErrors) => {
|
|
5956
|
+
return (jsxRuntime.jsx(AccordionRoot, { colorPalette: "red", collapsible: true, defaultValue: [], children: jsxRuntime.jsxs(AccordionItem, { value: "validation-errors", children: [jsxRuntime.jsx(AccordionItemTrigger, { children: translate.t("validation_error") }), jsxRuntime.jsx(AccordionItemContent, { display: "flex", flexFlow: "column", gap: "2", children: validationErrors.map((err, index) => (jsxRuntime.jsxs(react.AlertRoot, { status: "error", children: [jsxRuntime.jsx(react.AlertIndicator, {}), jsxRuntime.jsxs(react.AlertContent, { children: [jsxRuntime.jsx(react.AlertTitle, { fontWeight: "bold", children: err.instancePath }), jsxRuntime.jsx(react.AlertDescription, { children: err.message }), err.params !== undefined && (jsxRuntime.jsx(react.AlertDescription, { whiteSpace: "pre-wrap", wordBreak: "break-all", children: JSON.stringify(err.data, null, 2) }))] })] }))) })] }) }));
|
|
5957
|
+
};
|
|
4990
5958
|
const renderColumns = ({ order, keys, ignore, include, }) => {
|
|
4991
5959
|
const included = include.length > 0 ? include : keys;
|
|
4992
5960
|
const not_exist = included.filter((columnA) => !order.some((columnB) => columnA === columnB));
|
|
@@ -5001,7 +5969,7 @@ const FormBody = () => {
|
|
|
5001
5969
|
include,
|
|
5002
5970
|
});
|
|
5003
5971
|
if (isSuccess) {
|
|
5004
|
-
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("
|
|
5972
|
+
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("submit_success") })] }), jsxRuntime.jsx(react.Flex, { justifyContent: "end", children: jsxRuntime.jsx(react.Button, { onClick: async () => {
|
|
5005
5973
|
setIsError(false);
|
|
5006
5974
|
setIsSubmiting(false);
|
|
5007
5975
|
setIsSuccess(false);
|
|
@@ -5009,10 +5977,10 @@ const FormBody = () => {
|
|
|
5009
5977
|
setValidatedData(undefined);
|
|
5010
5978
|
const data = await getUpdatedData();
|
|
5011
5979
|
methods.reset(data);
|
|
5012
|
-
}, formNoValidate: true, children: translate.t("
|
|
5980
|
+
}, formNoValidate: true, children: translate.t("submit_again") }) })] }));
|
|
5013
5981
|
}
|
|
5014
5982
|
if (isConfirming) {
|
|
5015
|
-
return (jsxRuntime.jsxs(react.Flex, { flexFlow: "column", gap: "2", children: [jsxRuntime.jsx(react.Grid, { gap: 4, gridTemplateColumns: "repeat(12, 1fr)", gridTemplateRows:
|
|
5983
|
+
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) => {
|
|
5016
5984
|
return (jsxRuntime.jsx(ColumnViewer
|
|
5017
5985
|
// @ts-expect-error find suitable types
|
|
5018
5986
|
, {
|
|
@@ -5022,9 +5990,10 @@ const FormBody = () => {
|
|
|
5022
5990
|
setIsConfirming(false);
|
|
5023
5991
|
}, variant: "subtle", children: translate.t("cancel") }), jsxRuntime.jsx(react.Button, { onClick: () => {
|
|
5024
5992
|
onFormSubmit(validatedData);
|
|
5025
|
-
}, 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:
|
|
5993
|
+
}, 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" &&
|
|
5994
|
+
error?.errors ? (renderValidationErrors(error.errors)) : (jsxRuntime.jsx(react.Alert.Root, { status: "error", children: jsxRuntime.jsx(react.Alert.Title, { children: jsxRuntime.jsx(AccordionRoot, { collapsible: true, defaultValue: [], children: jsxRuntime.jsxs(AccordionItem, { value: "b", children: [jsxRuntime.jsxs(AccordionItemTrigger, { children: [jsxRuntime.jsx(react.Alert.Indicator, {}), `${error}`] }), jsxRuntime.jsx(AccordionItemContent, { children: `${JSON.stringify(error)}` })] }) }) }) })) })) }))] }));
|
|
5026
5995
|
}
|
|
5027
|
-
return (jsxRuntime.jsxs(react.Flex, { flexFlow: "column", gap: "2", children: [jsxRuntime.jsx(react.Grid, { gap: "4", gridTemplateColumns: "repeat(12, 1fr)",
|
|
5996
|
+
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) => {
|
|
5028
5997
|
return (jsxRuntime.jsx(ColumnRenderer
|
|
5029
5998
|
// @ts-expect-error find suitable types
|
|
5030
5999
|
, {
|
|
@@ -5032,7 +6001,8 @@ const FormBody = () => {
|
|
|
5032
6001
|
properties: properties, prefix: ``, column }, `form-input-${column}`));
|
|
5033
6002
|
}) }), jsxRuntime.jsxs(react.Flex, { justifyContent: "end", gap: "2", children: [jsxRuntime.jsx(react.Button, { onClick: () => {
|
|
5034
6003
|
methods.reset();
|
|
5035
|
-
}, variant: "subtle", children: translate.t("reset") }), jsxRuntime.jsx(SubmitButton, {})] })
|
|
6004
|
+
}, variant: "subtle", children: translate.t("reset") }), jsxRuntime.jsx(SubmitButton, {})] }), isError && error?.type === "validation" && (jsxRuntime.jsx(react.Box, { mt: 4, children: error?.errors &&
|
|
6005
|
+
renderValidationErrors(error.errors) }))] }));
|
|
5036
6006
|
};
|
|
5037
6007
|
|
|
5038
6008
|
const FormTitle = () => {
|
|
@@ -5040,8 +6010,8 @@ const FormTitle = () => {
|
|
|
5040
6010
|
return jsxRuntime.jsx(react.Heading, { children: translate.t("title") });
|
|
5041
6011
|
};
|
|
5042
6012
|
|
|
5043
|
-
const DefaultForm = ({ formConfig, }) => {
|
|
5044
|
-
return (jsxRuntime.jsx(FormRoot, { ...formConfig, children: jsxRuntime.jsxs(react.Grid, { gap: "2", children: [jsxRuntime.jsx(FormTitle, {}), jsxRuntime.jsx(FormBody, {})] }) }));
|
|
6013
|
+
const DefaultForm = ({ formConfig, showTitle = true, }) => {
|
|
6014
|
+
return (jsxRuntime.jsx(FormRoot, { ...formConfig, children: jsxRuntime.jsxs(react.Grid, { gap: "2", children: [showTitle && jsxRuntime.jsx(FormTitle, {}), jsxRuntime.jsx(FormBody, {})] }) }));
|
|
5045
6015
|
};
|
|
5046
6016
|
|
|
5047
6017
|
const useForm = ({ preLoadedValues, keyPrefix }) => {
|
|
@@ -5086,7 +6056,6 @@ exports.EditSortingButton = EditSortingButton;
|
|
|
5086
6056
|
exports.EmptyState = EmptyState$1;
|
|
5087
6057
|
exports.ErrorAlert = ErrorAlert;
|
|
5088
6058
|
exports.FilterDialog = FilterDialog;
|
|
5089
|
-
exports.FilterOptions = FilterOptions;
|
|
5090
6059
|
exports.FormBody = FormBody;
|
|
5091
6060
|
exports.FormRoot = FormRoot;
|
|
5092
6061
|
exports.FormTitle = FormTitle;
|
|
@@ -5105,6 +6074,7 @@ exports.TableCardContainer = TableCardContainer;
|
|
|
5105
6074
|
exports.TableCards = TableCards;
|
|
5106
6075
|
exports.TableComponent = TableComponent;
|
|
5107
6076
|
exports.TableControls = TableControls;
|
|
6077
|
+
exports.TableDataDisplay = TableDataDisplay;
|
|
5108
6078
|
exports.TableFilter = TableFilter;
|
|
5109
6079
|
exports.TableFilterTags = TableFilterTags;
|
|
5110
6080
|
exports.TableFooter = TableFooter;
|