@bsol-oss/react-datatable5 12.0.0-beta.7 → 12.0.0-beta.70

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