@bsol-oss/react-datatable5 12.0.0-beta.6 → 12.0.0-beta.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +192 -0
- package/dist/index.d.ts +212 -91
- package/dist/index.js +1396 -426
- package/dist/index.mjs +1402 -432
- package/dist/types/components/DataTable/DataTable.d.ts +4 -2
- package/dist/types/components/DataTable/DataTableServer.d.ts +4 -2
- package/dist/types/components/DataTable/DefaultTable.d.ts +9 -12
- package/dist/types/components/DataTable/context/DataTableContext.d.ts +22 -3
- package/dist/types/components/DataTable/context/useDataTableContext.d.ts +2 -2
- package/dist/types/components/DataTable/controls/DensityFeature.d.ts +23 -0
- package/dist/types/components/DataTable/controls/DensityToggleButton.d.ts +6 -0
- package/dist/types/components/DataTable/controls/EditSortingButton.d.ts +7 -0
- package/dist/types/components/DataTable/controls/FilterDialog.d.ts +5 -0
- package/dist/types/components/DataTable/controls/PageSizeControl.d.ts +4 -0
- package/dist/types/components/DataTable/controls/Pagination.d.ts +1 -0
- package/dist/types/components/DataTable/controls/ReloadButton.d.ts +4 -0
- package/dist/types/components/DataTable/controls/ResetFilteringButton.d.ts +1 -0
- package/dist/types/components/DataTable/controls/ResetSelectionButton.d.ts +1 -0
- package/dist/types/components/DataTable/controls/ResetSortingButton.d.ts +1 -0
- package/dist/types/components/DataTable/controls/RowCountText.d.ts +1 -0
- package/dist/types/components/DataTable/controls/SelectAllRowsToggle.d.ts +8 -0
- package/dist/types/components/DataTable/controls/TableControls.d.ts +29 -0
- package/dist/types/components/DataTable/controls/TableFilterTags.d.ts +1 -0
- package/dist/types/components/DataTable/controls/TableFilters.d.ts +1 -0
- package/dist/types/components/DataTable/controls/TableSelector.d.ts +1 -0
- package/dist/types/components/DataTable/controls/TableSorter.d.ts +1 -0
- package/dist/types/components/DataTable/controls/TableViewer.d.ts +1 -0
- package/dist/types/components/DataTable/controls/ViewDialog.d.ts +5 -0
- package/dist/types/components/DataTable/display/CardHeader.d.ts +13 -0
- package/dist/types/components/DataTable/display/DataDisplay.d.ts +6 -0
- package/dist/types/components/DataTable/display/EmptyState.d.ts +5 -0
- package/dist/types/components/DataTable/display/ErrorAlert.d.ts +4 -0
- package/dist/types/components/DataTable/display/RecordDisplay.d.ts +9 -0
- package/dist/types/components/DataTable/display/Table.d.ts +10 -0
- package/dist/types/components/DataTable/display/TableBody.d.ts +20 -0
- package/dist/types/components/DataTable/display/TableCardContainer.d.ts +10 -0
- package/dist/types/components/DataTable/display/TableCards.d.ts +11 -0
- package/dist/types/components/DataTable/display/TableComponent.d.ts +6 -0
- package/dist/types/components/DataTable/display/TableDataDisplay.d.ts +6 -0
- package/dist/types/components/DataTable/display/TableFooter.d.ts +5 -0
- package/dist/types/components/DataTable/display/TableHeader.d.ts +51 -0
- package/dist/types/components/DataTable/display/TableLoadingComponent.d.ts +5 -0
- package/dist/types/components/DataTable/display/TextCell.d.ts +10 -0
- package/dist/types/components/DataTable/useDataTable.d.ts +1 -1
- package/dist/types/components/DatePicker/DatePicker.d.ts +23 -0
- package/dist/types/components/DatePicker/DateTimePicker.d.ts +11 -0
- package/dist/types/components/DatePicker/DurationPicker.d.ts +12 -0
- package/dist/types/components/DatePicker/IsoTimePicker.d.ts +16 -0
- package/dist/types/components/DatePicker/PickerDemo.d.ts +1 -0
- package/dist/types/components/DatePicker/UniversalPicker.d.ts +9 -0
- package/dist/types/components/DatePicker/index.d.ts +7 -0
- package/dist/types/components/Filter/TagFilter.d.ts +5 -1
- package/dist/types/components/Form/SchemaFormContext.d.ts +3 -1
- package/dist/types/components/Form/components/core/DefaultForm.d.ts +2 -1
- package/dist/types/components/Form/components/core/FormRoot.d.ts +4 -2
- package/dist/types/components/Form/components/fields/CustomInput.d.ts +8 -0
- package/dist/types/components/Form/components/fields/DatePicker.d.ts +2 -7
- package/dist/types/components/Form/components/fields/DateTimePicker.d.ts +2 -0
- package/dist/types/components/Form/components/fields/EnumPicker.d.ts +2 -1
- package/dist/types/components/Form/components/fields/FilePicker.d.ts +2 -5
- package/dist/types/components/Form/components/fields/StringInputField.d.ts +2 -5
- package/dist/types/components/Form/components/fields/TextAreaInput.d.ts +12 -0
- package/dist/types/components/Form/components/fields/TimePicker.d.ts +7 -0
- package/dist/types/components/Form/components/fields/types.d.ts +6 -0
- package/dist/types/components/Form/components/types/CustomJSONSchema7.d.ts +19 -1
- package/dist/types/components/Form/components/viewers/CustomViewer.d.ts +8 -0
- package/dist/types/components/Form/components/viewers/DateTimeViewer.d.ts +7 -0
- package/dist/types/components/Form/components/viewers/TextAreaViewer.d.ts +12 -0
- package/dist/types/components/Form/components/viewers/TimeViewer.d.ts +7 -0
- package/dist/types/components/Form/utils/translateWrapper.d.ts +6 -0
- package/dist/types/components/Form/utils/validation.d.ts +104 -0
- package/dist/types/components/TimePicker/TimePicker.d.ts +20 -0
- package/dist/types/index.d.ts +48 -33
- package/package.json +9 -2
package/dist/index.mjs
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
-
import { Button as Button$1, AbsoluteCenter, Spinner, Span, IconButton, Portal, Dialog, Flex, Text, useDisclosure, DialogBackdrop, RadioGroup as RadioGroup$1, Grid, Box, Slider as Slider$1, HStack, For, Tag as Tag$1, Input, Menu, createRecipeContext, createContext as createContext$1, Pagination as Pagination$1, usePaginationContext, CheckboxCard as CheckboxCard$1, Image, EmptyState as EmptyState$2, VStack, Alert, Card,
|
|
2
|
+
import { Button as Button$1, AbsoluteCenter, Spinner, Span, IconButton, Portal, Dialog, Flex, Text, useDisclosure, DialogBackdrop, RadioGroup as RadioGroup$1, Grid, Box, Slider as Slider$1, HStack, For, Tag as Tag$1, Input, Menu, createRecipeContext, createContext as createContext$1, Pagination as Pagination$1, usePaginationContext, CheckboxCard as CheckboxCard$1, Image, EmptyState as EmptyState$2, VStack, Alert, Card, Group, InputElement, Tooltip as Tooltip$1, Icon, List, Table as Table$1, Checkbox as Checkbox$1, MenuRoot as MenuRoot$1, MenuTrigger as MenuTrigger$1, Accordion, Field as Field$1, Popover, NumberInput, Show, RadioCard, CheckboxGroup, Textarea, Center, AlertRoot, AlertIndicator, AlertContent, AlertTitle, AlertDescription, Heading } from '@chakra-ui/react';
|
|
3
3
|
import { AiOutlineColumnWidth } from 'react-icons/ai';
|
|
4
4
|
import * as React from 'react';
|
|
5
5
|
import React__default, { createContext, useContext, useState, useEffect, useRef } from 'react';
|
|
6
6
|
import { LuX, LuCheck, LuChevronRight, LuChevronDown } from 'react-icons/lu';
|
|
7
|
-
import { MdOutlineSort, MdFilterAlt, MdSearch,
|
|
8
|
-
import { FaUpDown, FaGripLinesVertical } from 'react-icons/fa6';
|
|
7
|
+
import { MdOutlineSort, MdFilterAlt, MdSearch, MdOutlineViewColumn, MdFilterListAlt, MdPushPin, MdCancel, MdClear, MdOutlineChecklist, MdDateRange } from 'react-icons/md';
|
|
8
|
+
import { FaUpDown, FaGripLinesVertical, FaTrash } from 'react-icons/fa6';
|
|
9
9
|
import { BiDownArrow, BiUpArrow, BiError } from 'react-icons/bi';
|
|
10
|
-
import { CgClose } from 'react-icons/cg';
|
|
10
|
+
import { CgClose, CgTrash } from 'react-icons/cg';
|
|
11
11
|
import Dayzed from '@bsol-oss/dayzed-react19';
|
|
12
12
|
import { HiMiniEllipsisHorizontal, HiChevronLeft, HiChevronRight } from 'react-icons/hi2';
|
|
13
|
-
import { IoMdEye, IoMdCheckbox } from 'react-icons/io';
|
|
13
|
+
import { IoMdEye, IoMdCheckbox, IoMdClock } from 'react-icons/io';
|
|
14
14
|
import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
|
|
15
15
|
import { bind, bindAll } from 'bind-event-listener';
|
|
16
16
|
import _defineProperty from '@babel/runtime/helpers/defineProperty';
|
|
17
17
|
import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
|
|
18
18
|
import rafSchd from 'raf-schd';
|
|
19
19
|
import invariant from 'tiny-invariant';
|
|
20
|
-
import { HiColorSwatch } from 'react-icons/hi';
|
|
20
|
+
import { HiColorSwatch, HiOutlineInformationCircle } from 'react-icons/hi';
|
|
21
21
|
import { flexRender, makeStateUpdater, functionalUpdate, useReactTable, getCoreRowModel, getFilteredRowModel, getSortedRowModel, getPaginationRowModel, createColumnHelper } from '@tanstack/react-table';
|
|
22
22
|
import { rankItem } from '@tanstack/match-sorter-utils';
|
|
23
23
|
import { BsExclamationCircleFill } from 'react-icons/bs';
|
|
@@ -29,7 +29,12 @@ import { useTranslation } from 'react-i18next';
|
|
|
29
29
|
import axios from 'axios';
|
|
30
30
|
import { FormProvider, useFormContext, useForm as useForm$1 } from 'react-hook-form';
|
|
31
31
|
import dayjs from 'dayjs';
|
|
32
|
+
import utc from 'dayjs/plugin/utc';
|
|
33
|
+
import timezone from 'dayjs/plugin/timezone';
|
|
32
34
|
import { TiDeleteOutline } from 'react-icons/ti';
|
|
35
|
+
import Ajv from 'ajv';
|
|
36
|
+
import addFormats from 'ajv-formats';
|
|
37
|
+
import addErrors from 'ajv-errors';
|
|
33
38
|
|
|
34
39
|
const DataTableContext = createContext({
|
|
35
40
|
table: {},
|
|
@@ -37,6 +42,56 @@ const DataTableContext = createContext({
|
|
|
37
42
|
setGlobalFilter: () => { },
|
|
38
43
|
type: "client",
|
|
39
44
|
translate: {},
|
|
45
|
+
data: [],
|
|
46
|
+
columns: [],
|
|
47
|
+
columnOrder: [],
|
|
48
|
+
columnFilters: [],
|
|
49
|
+
density: "sm",
|
|
50
|
+
sorting: [],
|
|
51
|
+
setPagination: function () {
|
|
52
|
+
throw new Error("Function not implemented.");
|
|
53
|
+
},
|
|
54
|
+
setSorting: function () {
|
|
55
|
+
throw new Error("Function not implemented.");
|
|
56
|
+
},
|
|
57
|
+
setColumnFilters: function () {
|
|
58
|
+
throw new Error("Function not implemented.");
|
|
59
|
+
},
|
|
60
|
+
setRowSelection: function () {
|
|
61
|
+
throw new Error("Function not implemented.");
|
|
62
|
+
},
|
|
63
|
+
setColumnOrder: function () {
|
|
64
|
+
throw new Error("Function not implemented.");
|
|
65
|
+
},
|
|
66
|
+
setDensity: function () {
|
|
67
|
+
throw new Error("Function not implemented.");
|
|
68
|
+
},
|
|
69
|
+
setColumnVisibility: function () {
|
|
70
|
+
throw new Error("Function not implemented.");
|
|
71
|
+
},
|
|
72
|
+
pagination: {
|
|
73
|
+
pageIndex: 0,
|
|
74
|
+
pageSize: 10,
|
|
75
|
+
},
|
|
76
|
+
rowSelection: {},
|
|
77
|
+
columnVisibility: {},
|
|
78
|
+
tableLabel: {
|
|
79
|
+
view: "View",
|
|
80
|
+
edit: "Edit",
|
|
81
|
+
filterButtonText: "Filter",
|
|
82
|
+
filterTitle: "Filter",
|
|
83
|
+
filterReset: "Reset",
|
|
84
|
+
filterClose: "Close",
|
|
85
|
+
reloadTooltip: "Reload",
|
|
86
|
+
reloadButtonText: "Reload",
|
|
87
|
+
resetSelection: "Reset Selection",
|
|
88
|
+
resetSorting: "Reset Sorting",
|
|
89
|
+
rowCountText: "Row Count",
|
|
90
|
+
hasErrorText: "Has Error",
|
|
91
|
+
globalFilterPlaceholder: "Search",
|
|
92
|
+
trueLabel: "True",
|
|
93
|
+
falseLabel: "False",
|
|
94
|
+
},
|
|
40
95
|
});
|
|
41
96
|
|
|
42
97
|
const useDataTableContext = () => {
|
|
@@ -92,11 +147,13 @@ const TableSorter = () => {
|
|
|
92
147
|
}) }))) }));
|
|
93
148
|
};
|
|
94
149
|
|
|
95
|
-
const ResetSortingButton = (
|
|
150
|
+
const ResetSortingButton = () => {
|
|
96
151
|
const { table } = useDataTableContext();
|
|
152
|
+
const { tableLabel } = useDataTableContext();
|
|
153
|
+
const { resetSorting } = tableLabel;
|
|
97
154
|
return (jsx(Button$1, { onClick: () => {
|
|
98
155
|
table.resetSorting();
|
|
99
|
-
}, children:
|
|
156
|
+
}, children: resetSorting }));
|
|
100
157
|
};
|
|
101
158
|
|
|
102
159
|
const EditSortingButton = ({ text, icon = jsx(MdOutlineSort, {}), title = "Edit Sorting", }) => {
|
|
@@ -124,7 +181,7 @@ const monthNamesFull = [
|
|
|
124
181
|
"November",
|
|
125
182
|
"December",
|
|
126
183
|
];
|
|
127
|
-
const weekdayNamesShort
|
|
184
|
+
const weekdayNamesShort = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
128
185
|
function Calendar$1({ calendars, getBackProps, getForwardProps, getDateProps, selected = [], firstDayOfWeek = 0, }) {
|
|
129
186
|
const [hoveredDate, setHoveredDate] = useState();
|
|
130
187
|
const onMouseLeave = () => {
|
|
@@ -159,7 +216,7 @@ function Calendar$1({ calendars, getBackProps, getForwardProps, getDateProps, se
|
|
|
159
216
|
offset: 12,
|
|
160
217
|
}), children: ">>" })] }), jsx(Grid, { templateColumns: "repeat(2, auto)", justifyContent: "center", gap: 4, children: calendars.map((calendar) => (jsxs(Grid, { gap: 4, children: [jsxs(Grid, { justifyContent: "center", children: [monthNamesFull[calendar.month], " ", calendar.year] }), jsx(Grid, { templateColumns: "repeat(7, auto)", justifyContent: "center", children: [0, 1, 2, 3, 4, 5, 6].map((weekdayNum) => {
|
|
161
218
|
const weekday = (weekdayNum + firstDayOfWeek) % 7;
|
|
162
|
-
return (jsx(Box, { minWidth: "48px", textAlign: "center", children: weekdayNamesShort
|
|
219
|
+
return (jsx(Box, { minWidth: "48px", textAlign: "center", children: weekdayNamesShort[weekday] }, `${calendar.month}${calendar.year}${weekday}`));
|
|
163
220
|
}) }), jsx(Grid, { templateColumns: "repeat(7, auto)", justifyContent: "center", children: calendar.weeks.map((week, windex) => week.map((dateObj, index) => {
|
|
164
221
|
const key = `${calendar.month}${calendar.year}${windex}${index}`;
|
|
165
222
|
if (!dateObj) {
|
|
@@ -280,8 +337,17 @@ const Tag = React.forwardRef(function Tag(props, ref) {
|
|
|
280
337
|
return (jsxs(Tag$1.Root, { ref: ref, ...rest, children: [startElement && (jsx(Tag$1.StartElement, { children: startElement })), jsx(Tag$1.Label, { children: children }), endElement && (jsx(Tag$1.EndElement, { children: endElement })), closable && (jsx(Tag$1.EndElement, { children: jsx(Tag$1.CloseTrigger, { onClick: onClose }) }))] }));
|
|
281
338
|
});
|
|
282
339
|
|
|
283
|
-
const TagFilter = ({ availableTags, selectedTags, onTagChange, }) => {
|
|
340
|
+
const TagFilter = ({ availableTags, selectedTags, onTagChange, selectOne = false, }) => {
|
|
284
341
|
const toggleTag = (tag) => {
|
|
342
|
+
if (selectOne) {
|
|
343
|
+
if (selectedTags.includes(tag)) {
|
|
344
|
+
onTagChange([]);
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
onTagChange([tag]);
|
|
348
|
+
}
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
285
351
|
if (selectedTags.includes(tag)) {
|
|
286
352
|
onTagChange(selectedTags.filter((t) => t !== tag));
|
|
287
353
|
}
|
|
@@ -289,10 +355,14 @@ const TagFilter = ({ availableTags, selectedTags, onTagChange, }) => {
|
|
|
289
355
|
onTagChange([...selectedTags, tag]);
|
|
290
356
|
}
|
|
291
357
|
};
|
|
292
|
-
return (jsx(Flex, { flexFlow: "wrap", p: "0.5rem", gap: "0.5rem", children: availableTags.map((tag) =>
|
|
358
|
+
return (jsx(Flex, { flexFlow: "wrap", p: "0.5rem", gap: "0.5rem", children: availableTags.map((tag) => {
|
|
359
|
+
const { label, value } = tag;
|
|
360
|
+
return (jsx(Tag, { variant: selectedTags.includes(value) ? "solid" : "outline", cursor: "pointer", closable: selectedTags.includes(value) ? true : undefined, onClick: () => toggleTag(value), children: label ?? value }));
|
|
361
|
+
}) }));
|
|
293
362
|
};
|
|
294
363
|
|
|
295
364
|
const Filter = ({ column }) => {
|
|
365
|
+
const { tableLabel } = useDataTableContext();
|
|
296
366
|
const { filterVariant } = column.columnDef.meta ?? {};
|
|
297
367
|
const displayName = column.columnDef.meta?.displayName ?? column.id;
|
|
298
368
|
const filterOptions = column.columnDef.meta?.filterOptions ?? [];
|
|
@@ -307,10 +377,14 @@ const Filter = ({ column }) => {
|
|
|
307
377
|
if (filterVariant === "select") {
|
|
308
378
|
return (jsxs(Flex, { flexFlow: "column", gap: "0.25rem", children: [jsx(Text, { children: displayName }), jsx(RadioGroup, { value: column.getFilterValue() ? String(column.getFilterValue()) : "", onValueChange: (details) => {
|
|
309
379
|
column.setFilterValue(details.value);
|
|
310
|
-
}, children:
|
|
380
|
+
}, children: jsxs(Flex, { flexFlow: "wrap", gap: "0.5rem", children: [filterOptions.length === 0 && jsx(Text, { children: "No filter options" }), filterOptions.length > 0 &&
|
|
381
|
+
filterOptions.map((item) => (jsx(Radio, { value: item.value, children: item.label }, item.value)))] }) })] }, column.id));
|
|
311
382
|
}
|
|
312
383
|
if (filterVariant === "tag") {
|
|
313
|
-
return (jsxs(Flex, { flexFlow: "column", gap: "0.25rem", children: [jsx(Text, { children: displayName }), jsx(TagFilter, { availableTags: filterOptions
|
|
384
|
+
return (jsxs(Flex, { flexFlow: "column", gap: "0.25rem", children: [jsx(Text, { children: displayName }), jsx(TagFilter, { availableTags: filterOptions.map((item) => ({
|
|
385
|
+
label: item.label,
|
|
386
|
+
value: item.value,
|
|
387
|
+
})), selectedTags: (column.getFilterValue() ?? []), onTagChange: (tags) => {
|
|
314
388
|
if (tags.length === 0) {
|
|
315
389
|
return column.setFilterValue(undefined);
|
|
316
390
|
}
|
|
@@ -318,7 +392,11 @@ const Filter = ({ column }) => {
|
|
|
318
392
|
} })] }, column.id));
|
|
319
393
|
}
|
|
320
394
|
if (filterVariant === "boolean") {
|
|
321
|
-
|
|
395
|
+
const { trueLabel, falseLabel } = tableLabel;
|
|
396
|
+
return (jsxs(Flex, { flexFlow: "column", gap: "0.25rem", children: [jsx(Text, { children: displayName }), jsx(TagFilter, { availableTags: [
|
|
397
|
+
{ label: trueLabel, value: "true" },
|
|
398
|
+
{ label: falseLabel, value: "false" },
|
|
399
|
+
], selectedTags: (column.getFilterValue() ?? []), onTagChange: (tags) => {
|
|
322
400
|
if (tags.length === 0) {
|
|
323
401
|
return column.setFilterValue(undefined);
|
|
324
402
|
}
|
|
@@ -373,17 +451,20 @@ const TableFilter = () => {
|
|
|
373
451
|
}) }));
|
|
374
452
|
};
|
|
375
453
|
|
|
376
|
-
const ResetFilteringButton = (
|
|
454
|
+
const ResetFilteringButton = () => {
|
|
377
455
|
const { table } = useDataTableContext();
|
|
456
|
+
const { tableLabel } = useDataTableContext();
|
|
457
|
+
const { filterReset } = tableLabel;
|
|
378
458
|
return (jsx(Button$1, { onClick: () => {
|
|
379
459
|
table.resetColumnFilters();
|
|
380
|
-
}, children:
|
|
460
|
+
}, children: filterReset }));
|
|
381
461
|
};
|
|
382
462
|
|
|
383
463
|
const FilterDialog = ({ icon = jsx(MdFilterAlt, {}), }) => {
|
|
384
464
|
const filterModal = useDisclosure();
|
|
385
|
-
const {
|
|
386
|
-
|
|
465
|
+
const { tableLabel } = useDataTableContext();
|
|
466
|
+
const { filterButtonText, filterTitle, filterClose } = tableLabel;
|
|
467
|
+
return (jsxs(DialogRoot, { size: ["full", "full", "md", "md"], open: filterModal.open, children: [jsx(DialogTrigger, { asChild: true, children: jsxs(Button$1, { as: Box, variant: "ghost", onClick: filterModal.onOpen, children: [icon, " ", filterButtonText] }) }), jsxs(DialogContent, { children: [jsx(DialogHeader, { children: jsx(DialogTitle, { children: filterTitle }) }), jsx(DialogBody, { display: "flex", flexFlow: "column", children: jsx(TableFilter, {}) }), jsxs(DialogFooter, { children: [jsx(ResetFilteringButton, {}), jsx(Button$1, { onClick: filterModal.onClose, variant: "subtle", children: filterClose })] }), jsx(DialogCloseTrigger, { onClick: filterModal.onClose })] })] }));
|
|
387
468
|
};
|
|
388
469
|
|
|
389
470
|
const MenuContent = React.forwardRef(function MenuContent(props, ref) {
|
|
@@ -502,11 +583,13 @@ const Pagination = () => {
|
|
|
502
583
|
}, children: jsxs(HStack, { children: [jsx(PaginationPrevTrigger, {}), jsx(PaginationItems, {}), jsx(PaginationNextTrigger, {})] }) }));
|
|
503
584
|
};
|
|
504
585
|
|
|
505
|
-
const ResetSelectionButton = (
|
|
586
|
+
const ResetSelectionButton = () => {
|
|
506
587
|
const { table } = useDataTableContext();
|
|
588
|
+
const { tableLabel } = useDataTableContext();
|
|
589
|
+
const { resetSelection } = tableLabel;
|
|
507
590
|
return (jsx(Button$1, { onClick: () => {
|
|
508
591
|
table.resetRowSelection();
|
|
509
|
-
}, children:
|
|
592
|
+
}, children: resetSelection }));
|
|
510
593
|
};
|
|
511
594
|
|
|
512
595
|
const RowCountText = () => {
|
|
@@ -2421,8 +2504,8 @@ CheckboxCard$1.Indicator;
|
|
|
2421
2504
|
function ColumnCard({ columnId }) {
|
|
2422
2505
|
const ref = useRef(null);
|
|
2423
2506
|
const [dragging, setDragging] = useState(false); // NEW
|
|
2424
|
-
const { table } = useDataTableContext();
|
|
2425
|
-
const displayName = columnId;
|
|
2507
|
+
const { table, translate } = useDataTableContext();
|
|
2508
|
+
const displayName = translate.t(columnId);
|
|
2426
2509
|
const column = table.getColumn(columnId);
|
|
2427
2510
|
invariant(column);
|
|
2428
2511
|
useEffect(() => {
|
|
@@ -2437,7 +2520,7 @@ function ColumnCard({ columnId }) {
|
|
|
2437
2520
|
onDrop: () => setDragging(false), // NEW
|
|
2438
2521
|
});
|
|
2439
2522
|
}, [columnId, table]);
|
|
2440
|
-
return (jsxs(Grid, { ref: ref, templateColumns: "auto 1fr", gap: "0.5rem", alignItems: "center", style: dragging ? { opacity: 0.4 } : {}, children: [jsx(Flex, { alignItems: "center", padding: "0", cursor: "grab", children: jsx(FaGripLinesVertical, { color: "
|
|
2523
|
+
return (jsxs(Grid, { ref: ref, templateColumns: "auto 1fr", gap: "0.5rem", alignItems: "center", style: dragging ? { opacity: 0.4 } : {}, children: [jsx(Flex, { alignItems: "center", padding: "0", cursor: "grab", children: jsx(FaGripLinesVertical, { color: "colorPalette.400" }) }), jsx(Flex, { justifyContent: "space-between", alignItems: "center", children: jsx(CheckboxCard, { variant: "surface", label: displayName, checked: column.getIsVisible(), onChange: column.getToggleVisibilityHandler() }) })] }));
|
|
2441
2524
|
}
|
|
2442
2525
|
function CardContainer({ location, children }) {
|
|
2443
2526
|
const ref = useRef(null);
|
|
@@ -2456,7 +2539,6 @@ function CardContainer({ location, children }) {
|
|
|
2456
2539
|
onDrop: () => setIsDraggedOver(false),
|
|
2457
2540
|
});
|
|
2458
2541
|
}, [location]);
|
|
2459
|
-
// const isDark = (location + location) % 2 === 1;
|
|
2460
2542
|
function getColor(isDraggedOver) {
|
|
2461
2543
|
if (isDraggedOver) {
|
|
2462
2544
|
return {
|
|
@@ -2466,7 +2548,6 @@ function CardContainer({ location, children }) {
|
|
|
2466
2548
|
},
|
|
2467
2549
|
};
|
|
2468
2550
|
}
|
|
2469
|
-
// return isDark ? "lightgrey" : "white";
|
|
2470
2551
|
return {
|
|
2471
2552
|
backgroundColor: undefined,
|
|
2472
2553
|
_dark: {
|
|
@@ -2517,8 +2598,9 @@ const TableViewer = () => {
|
|
|
2517
2598
|
|
|
2518
2599
|
const ViewDialog = ({ icon = jsx(IoMdEye, {}) }) => {
|
|
2519
2600
|
const viewModel = useDisclosure();
|
|
2520
|
-
const {
|
|
2521
|
-
|
|
2601
|
+
const { tableLabel } = useDataTableContext();
|
|
2602
|
+
const { view } = tableLabel;
|
|
2603
|
+
return (jsxs(DialogRoot, { children: [jsx(DialogBackdrop, {}), jsx(DialogTrigger, { asChild: true, children: jsxs(Button$1, { as: Box, variant: "ghost", onClick: viewModel.onOpen, children: [icon, " ", view] }) }), jsxs(DialogContent, { children: [jsx(DialogCloseTrigger, {}), jsx(DialogHeader, { children: jsx(DialogTitle, { children: view }) }), jsx(DialogBody, { children: jsx(TableViewer, {}) }), jsx(DialogFooter, {})] })] }));
|
|
2522
2604
|
};
|
|
2523
2605
|
|
|
2524
2606
|
const CardHeader = ({ row, imageColumnId = undefined, titleColumnId = undefined, tagColumnId = undefined, tagIcon = undefined, showTag = true, imageProps = {}, }) => {
|
|
@@ -2569,7 +2651,7 @@ const RecordDisplay = ({ object, boxProps, translate, prefix = "", }) => {
|
|
|
2569
2651
|
return jsx(Fragment, { children: "null" });
|
|
2570
2652
|
}
|
|
2571
2653
|
return (jsx(Grid, { rowGap: 1, padding: 1, overflow: "auto", ...boxProps, children: Object.entries(object).map(([field, value]) => {
|
|
2572
|
-
return (jsxs(Grid, { columnGap: 2, gridTemplateColumns: "auto 1fr", children: [jsx(Text, { color: "
|
|
2654
|
+
return (jsxs(Grid, { columnGap: 2, gridTemplateColumns: "auto 1fr", children: [jsx(Text, { color: "colorPalette.400", children: getColumn({ field }) }), typeof value === "object" ? (jsx(RecordDisplay, { object: value, prefix: `${prefix}${field}.`, translate: translate })) : (jsx(Text, { children: JSON.stringify(value) }))] }, field));
|
|
2573
2655
|
}) }));
|
|
2574
2656
|
};
|
|
2575
2657
|
|
|
@@ -2619,7 +2701,7 @@ const CellRenderer = ({ cell }) => {
|
|
|
2619
2701
|
paddingY: 2,
|
|
2620
2702
|
}, object: value })] }, cell.id));
|
|
2621
2703
|
}
|
|
2622
|
-
return (jsxs(Box, { gridColumn, gridRow, children: [jsx(Box, { color:
|
|
2704
|
+
return (jsxs(Box, { gridColumn, gridRow, children: [jsx(Box, { color: "colorPalette.400", children: getLabel({ columnId: cell.column.id }) }), jsx(Box, { wordBreak: "break-word", textOverflow: "ellipsis", overflow: "hidden", children: `${formatValue(cell.getValue())}` })] }, cell.id));
|
|
2623
2705
|
};
|
|
2624
2706
|
const DataDisplay = ({ variant = "" }) => {
|
|
2625
2707
|
const { table, translate } = useDataTableContext();
|
|
@@ -2741,7 +2823,23 @@ const fuzzyFilter = (row, columnId, value, addMeta) => {
|
|
|
2741
2823
|
*
|
|
2742
2824
|
* @link https://tanstack.com/table/latest/docs/guide/column-defs
|
|
2743
2825
|
*/
|
|
2744
|
-
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,
|
|
2826
|
+
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 = {
|
|
2827
|
+
view: "View",
|
|
2828
|
+
edit: "Edit",
|
|
2829
|
+
filterButtonText: "Filter",
|
|
2830
|
+
filterTitle: "Filter",
|
|
2831
|
+
filterReset: "Reset",
|
|
2832
|
+
filterClose: "Close",
|
|
2833
|
+
reloadTooltip: "Reload",
|
|
2834
|
+
reloadButtonText: "Reload",
|
|
2835
|
+
resetSelection: "Reset Selection",
|
|
2836
|
+
resetSorting: "Reset Sorting",
|
|
2837
|
+
rowCountText: "Row Count",
|
|
2838
|
+
hasErrorText: "Has Error",
|
|
2839
|
+
globalFilterPlaceholder: "Search",
|
|
2840
|
+
trueLabel: "True",
|
|
2841
|
+
falseLabel: "False",
|
|
2842
|
+
}, }) {
|
|
2745
2843
|
const table = useReactTable({
|
|
2746
2844
|
_features: [DensityFeature],
|
|
2747
2845
|
data: data,
|
|
@@ -2794,6 +2892,23 @@ function DataTable({ columns, data, enableRowSelection = true, enableMultiRowSel
|
|
|
2794
2892
|
setGlobalFilter,
|
|
2795
2893
|
type: "client",
|
|
2796
2894
|
translate,
|
|
2895
|
+
columns: columns,
|
|
2896
|
+
sorting,
|
|
2897
|
+
setSorting,
|
|
2898
|
+
columnFilters,
|
|
2899
|
+
setColumnFilters,
|
|
2900
|
+
pagination,
|
|
2901
|
+
setPagination,
|
|
2902
|
+
rowSelection,
|
|
2903
|
+
setRowSelection,
|
|
2904
|
+
columnOrder,
|
|
2905
|
+
setColumnOrder,
|
|
2906
|
+
density,
|
|
2907
|
+
setDensity,
|
|
2908
|
+
columnVisibility,
|
|
2909
|
+
setColumnVisibility,
|
|
2910
|
+
data,
|
|
2911
|
+
tableLabel,
|
|
2797
2912
|
}, children: children }));
|
|
2798
2913
|
}
|
|
2799
2914
|
|
|
@@ -2808,10 +2923,26 @@ function DataTable({ columns, data, enableRowSelection = true, enableMultiRowSel
|
|
|
2808
2923
|
*
|
|
2809
2924
|
* @link https://tanstack.com/table/latest/docs/guide/column-defs
|
|
2810
2925
|
*/
|
|
2811
|
-
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,
|
|
2926
|
+
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 = {
|
|
2927
|
+
view: "View",
|
|
2928
|
+
edit: "Edit",
|
|
2929
|
+
filterButtonText: "Filter",
|
|
2930
|
+
filterTitle: "Filter",
|
|
2931
|
+
filterReset: "Reset",
|
|
2932
|
+
filterClose: "Close",
|
|
2933
|
+
reloadTooltip: "Reload",
|
|
2934
|
+
reloadButtonText: "Reload",
|
|
2935
|
+
resetSelection: "Reset Selection",
|
|
2936
|
+
resetSorting: "Reset Sorting",
|
|
2937
|
+
rowCountText: "Row Count",
|
|
2938
|
+
hasErrorText: "Has Error",
|
|
2939
|
+
globalFilterPlaceholder: "Search",
|
|
2940
|
+
trueLabel: "True",
|
|
2941
|
+
falseLabel: "False",
|
|
2942
|
+
}, }) {
|
|
2812
2943
|
const table = useReactTable({
|
|
2813
2944
|
_features: [DensityFeature],
|
|
2814
|
-
data: query.data?.data ?? [],
|
|
2945
|
+
data: (query.data?.data ?? []),
|
|
2815
2946
|
rowCount: query.data?.count ?? 0,
|
|
2816
2947
|
columns: columns,
|
|
2817
2948
|
getCoreRowModel: getCoreRowModel(),
|
|
@@ -2857,103 +2988,31 @@ function DataTableServer({ columns, enableRowSelection = true, enableMultiRowSel
|
|
|
2857
2988
|
// for tanstack-table ts bug end
|
|
2858
2989
|
});
|
|
2859
2990
|
return (jsx(DataTableContext.Provider, { value: {
|
|
2860
|
-
table:
|
|
2991
|
+
table: table,
|
|
2861
2992
|
globalFilter,
|
|
2862
2993
|
setGlobalFilter,
|
|
2863
2994
|
type: "server",
|
|
2864
2995
|
translate,
|
|
2996
|
+
columns: columns,
|
|
2997
|
+
sorting,
|
|
2998
|
+
setSorting,
|
|
2999
|
+
columnFilters,
|
|
3000
|
+
setColumnFilters,
|
|
3001
|
+
pagination,
|
|
3002
|
+
setPagination,
|
|
3003
|
+
rowSelection,
|
|
3004
|
+
setRowSelection,
|
|
3005
|
+
columnOrder,
|
|
3006
|
+
setColumnOrder,
|
|
3007
|
+
density,
|
|
3008
|
+
setDensity,
|
|
3009
|
+
columnVisibility,
|
|
3010
|
+
setColumnVisibility,
|
|
3011
|
+
data: query.data?.data ?? [],
|
|
3012
|
+
tableLabel,
|
|
2865
3013
|
}, children: jsx(DataTableServerContext.Provider, { value: { url, query }, children: children }) }));
|
|
2866
3014
|
}
|
|
2867
3015
|
|
|
2868
|
-
const Checkbox = React.forwardRef(function Checkbox(props, ref) {
|
|
2869
|
-
const { icon, children, inputProps, rootRef, ...rest } = props;
|
|
2870
|
-
return (jsxs(Checkbox$1.Root, { ref: rootRef, ...rest, children: [jsx(Checkbox$1.HiddenInput, { ref: ref, ...inputProps }), jsx(Checkbox$1.Control, { children: icon || jsx(Checkbox$1.Indicator, {}) }), children != null && (jsx(Checkbox$1.Label, { children: children }))] }));
|
|
2871
|
-
});
|
|
2872
|
-
|
|
2873
|
-
const TableBody = ({ pinnedBgColor = { light: "gray.50", dark: "gray.700" }, showSelector = false, alwaysShowSelector = true, canResize = true, }) => {
|
|
2874
|
-
"use no memo";
|
|
2875
|
-
const { table } = useDataTableContext();
|
|
2876
|
-
const SELECTION_BOX_WIDTH = 20;
|
|
2877
|
-
const [hoveredRow, setHoveredRow] = useState(-1);
|
|
2878
|
-
const handleRowHover = (index) => {
|
|
2879
|
-
setHoveredRow(index);
|
|
2880
|
-
};
|
|
2881
|
-
const getTdProps = (cell) => {
|
|
2882
|
-
const tdProps = cell.column.getIsPinned()
|
|
2883
|
-
? {
|
|
2884
|
-
left: showSelector
|
|
2885
|
-
? `${cell.column.getStart("left") + SELECTION_BOX_WIDTH + table.getDensityValue() * 2}px`
|
|
2886
|
-
: `${cell.column.getStart("left")}px`,
|
|
2887
|
-
background: pinnedBgColor.light,
|
|
2888
|
-
position: "sticky",
|
|
2889
|
-
zIndex: -1,
|
|
2890
|
-
_dark: {
|
|
2891
|
-
backgroundColor: pinnedBgColor.dark,
|
|
2892
|
-
},
|
|
2893
|
-
}
|
|
2894
|
-
: {};
|
|
2895
|
-
return tdProps;
|
|
2896
|
-
};
|
|
2897
|
-
const getTrProps = ({ hoveredRow, index, }) => {
|
|
2898
|
-
if (hoveredRow === -1) {
|
|
2899
|
-
return {};
|
|
2900
|
-
}
|
|
2901
|
-
if (hoveredRow === index) {
|
|
2902
|
-
return {
|
|
2903
|
-
opacity: "1",
|
|
2904
|
-
};
|
|
2905
|
-
}
|
|
2906
|
-
return {
|
|
2907
|
-
opacity: "0.8",
|
|
2908
|
-
};
|
|
2909
|
-
};
|
|
2910
|
-
return (jsx(Table$1.Body, { children: table.getRowModel().rows.map((row, index) => {
|
|
2911
|
-
return (jsxs(Table$1.Row, { display: "flex", zIndex: 1, onMouseEnter: () => handleRowHover(index), onMouseLeave: () => handleRowHover(-1), ...getTrProps({ hoveredRow, index }), children: [showSelector && (jsx(TableRowSelector, { index: index, row: row, hoveredRow: hoveredRow, alwaysShowSelector: alwaysShowSelector })), row.getVisibleCells().map((cell, index) => {
|
|
2912
|
-
return (jsx(Table$1.Cell, { padding: `${table.getDensityValue()}px`,
|
|
2913
|
-
// styling resize and pinning start
|
|
2914
|
-
flex: `${canResize ? "0" : "1"} 0 ${cell.column.getSize()}px`, backgroundColor: "white", ...getTdProps(cell), _dark: {
|
|
2915
|
-
backgroundColor: "gray.950",
|
|
2916
|
-
}, children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, `chakra-table-rowcell-${cell.id}-${index}`));
|
|
2917
|
-
})] }, `chakra-table-row-${row.id}`));
|
|
2918
|
-
}) }));
|
|
2919
|
-
};
|
|
2920
|
-
const TableRowSelector = ({ index, row, hoveredRow, pinnedBgColor = { light: "gray.50", dark: "gray.700" }, alwaysShowSelector = true, }) => {
|
|
2921
|
-
const { table } = useDataTableContext();
|
|
2922
|
-
const SELECTION_BOX_WIDTH = 20;
|
|
2923
|
-
const isCheckBoxVisible = (current_index, current_row) => {
|
|
2924
|
-
if (alwaysShowSelector) {
|
|
2925
|
-
return true;
|
|
2926
|
-
}
|
|
2927
|
-
if (current_row.getIsSelected()) {
|
|
2928
|
-
return true;
|
|
2929
|
-
}
|
|
2930
|
-
if (hoveredRow == current_index) {
|
|
2931
|
-
return true;
|
|
2932
|
-
}
|
|
2933
|
-
return false;
|
|
2934
|
-
};
|
|
2935
|
-
return (jsxs(Table$1.Cell, { padding: `${table.getDensityValue()}px`, ...(table.getIsSomeColumnsPinned("left")
|
|
2936
|
-
? {
|
|
2937
|
-
left: `0px`,
|
|
2938
|
-
backgroundColor: pinnedBgColor.light,
|
|
2939
|
-
position: "sticky",
|
|
2940
|
-
zIndex: 1,
|
|
2941
|
-
_dark: { backgroundColor: pinnedBgColor.dark },
|
|
2942
|
-
}
|
|
2943
|
-
: {}),
|
|
2944
|
-
// styling resize and pinning end
|
|
2945
|
-
display: "grid", children: [!isCheckBoxVisible(index, row) && (jsx(Box, { as: "span", margin: "0rem", display: "grid", justifyItems: "center", alignItems: "center", width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px` })), isCheckBoxVisible(index, row) && (jsx(Box, { margin: "0rem", display: "grid", justifyItems: "center", alignItems: "center", children: jsx(Checkbox, { width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px`, isChecked: row.getIsSelected(),
|
|
2946
|
-
disabled: !row.getCanSelect(),
|
|
2947
|
-
onChange: row.getToggleSelectedHandler() }) }))] }));
|
|
2948
|
-
};
|
|
2949
|
-
|
|
2950
|
-
const Tooltip = React.forwardRef(function Tooltip(props, ref) {
|
|
2951
|
-
const { showArrow, children, disabled, portalled, content, contentProps, portalRef, ...rest } = props;
|
|
2952
|
-
if (disabled)
|
|
2953
|
-
return children;
|
|
2954
|
-
return (jsxs(Tooltip$1.Root, { ...rest, children: [jsx(Tooltip$1.Trigger, { asChild: true, children: children }), jsx(Portal, { disabled: !portalled, container: portalRef, children: jsx(Tooltip$1.Positioner, { children: jsxs(Tooltip$1.Content, { ref: ref, ...contentProps, children: [showArrow && (jsx(Tooltip$1.Arrow, { children: jsx(Tooltip$1.ArrowTip, {}) })), content] }) }) })] }));
|
|
2955
|
-
});
|
|
2956
|
-
|
|
2957
3016
|
const InputGroup = React.forwardRef(function InputGroup(props, ref) {
|
|
2958
3017
|
const { startElement, startElementProps, endElement, endElementProps, children, startOffset = "6px", endOffset = "6px", ...rest } = props;
|
|
2959
3018
|
return (jsxs(Group, { ref: ref, ...rest, children: [startElement && (jsx(InputElement, { pointerEvents: "none", ...startElementProps, children: startElement })), React.cloneElement(children, {
|
|
@@ -2967,7 +3026,8 @@ const InputGroup = React.forwardRef(function InputGroup(props, ref) {
|
|
|
2967
3026
|
});
|
|
2968
3027
|
|
|
2969
3028
|
const GlobalFilter = () => {
|
|
2970
|
-
const { table } = useDataTableContext();
|
|
3029
|
+
const { table, tableLabel } = useDataTableContext();
|
|
3030
|
+
const { globalFilterPlaceholder } = tableLabel;
|
|
2971
3031
|
const [searchTerm, setSearchTerm] = useState("");
|
|
2972
3032
|
const debouncedSearchTerm = useDebounce(searchTerm, 500);
|
|
2973
3033
|
useEffect(() => {
|
|
@@ -2976,42 +3036,31 @@ const GlobalFilter = () => {
|
|
|
2976
3036
|
};
|
|
2977
3037
|
searchHN();
|
|
2978
3038
|
}, [debouncedSearchTerm]);
|
|
2979
|
-
return (jsx(Fragment, { children: jsx(InputGroup, { flex: "1", startElement: jsx(MdSearch, {}), children: jsx(Input, { placeholder:
|
|
3039
|
+
return (jsx(Fragment, { children: jsx(InputGroup, { flex: "1", startElement: jsx(MdSearch, {}), children: jsx(Input, { placeholder: globalFilterPlaceholder, variant: "outline", onChange: (e) => {
|
|
2980
3040
|
setSearchTerm(e.target.value);
|
|
2981
3041
|
} }) }) }));
|
|
2982
3042
|
};
|
|
2983
3043
|
|
|
2984
|
-
const
|
|
3044
|
+
const Tooltip = React.forwardRef(function Tooltip(props, ref) {
|
|
3045
|
+
const { showArrow, children, disabled, portalled, content, contentProps, portalRef, ...rest } = props;
|
|
3046
|
+
if (disabled)
|
|
3047
|
+
return children;
|
|
3048
|
+
return (jsxs(Tooltip$1.Root, { ...rest, children: [jsx(Tooltip$1.Trigger, { asChild: true, children: children }), jsx(Portal, { disabled: !portalled, container: portalRef, children: jsx(Tooltip$1.Positioner, { children: jsxs(Tooltip$1.Content, { ref: ref, ...contentProps, children: [showArrow && (jsx(Tooltip$1.Arrow, { children: jsx(Tooltip$1.ArrowTip, {}) })), content] }) }) })] }));
|
|
3049
|
+
});
|
|
3050
|
+
|
|
3051
|
+
const ReloadButton = ({ variant = "icon", }) => {
|
|
2985
3052
|
const { url } = useDataTableServerContext();
|
|
2986
3053
|
const queryClient = useQueryClient();
|
|
3054
|
+
const { tableLabel } = useDataTableContext();
|
|
3055
|
+
const { reloadTooltip, reloadButtonText } = tableLabel;
|
|
2987
3056
|
if (variant === "icon") {
|
|
2988
|
-
return (jsx(Tooltip, { showArrow: true, content:
|
|
3057
|
+
return (jsx(Tooltip, { showArrow: true, content: reloadTooltip, children: jsx(Button, { variant: "ghost", onClick: () => {
|
|
2989
3058
|
queryClient.invalidateQueries({ queryKey: [url] });
|
|
2990
3059
|
}, "aria-label": "refresh", children: jsx(IoReload, {}) }) }));
|
|
2991
3060
|
}
|
|
2992
3061
|
return (jsxs(Button, { variant: "ghost", onClick: () => {
|
|
2993
3062
|
queryClient.invalidateQueries({ queryKey: [url] });
|
|
2994
|
-
}, children: [jsx(IoReload, {}), " ",
|
|
2995
|
-
};
|
|
2996
|
-
|
|
2997
|
-
const FilterOptions = ({ column }) => {
|
|
2998
|
-
const { table } = useDataTableContext();
|
|
2999
|
-
const tableColumn = table.getColumn(column);
|
|
3000
|
-
const options = tableColumn?.columnDef.meta?.filterOptions ?? [];
|
|
3001
|
-
return (jsx(Fragment, { children: options.map((option) => {
|
|
3002
|
-
const selected = table.getColumn(column)?.getFilterValue() === option;
|
|
3003
|
-
return (jsxs(Button$1, { size: "sm", onClick: () => {
|
|
3004
|
-
if (selected) {
|
|
3005
|
-
table.setColumnFilters((state) => {
|
|
3006
|
-
return state.filter((filter) => {
|
|
3007
|
-
return filter.id !== column;
|
|
3008
|
-
});
|
|
3009
|
-
});
|
|
3010
|
-
return;
|
|
3011
|
-
}
|
|
3012
|
-
table.getColumn(column)?.setFilterValue(option);
|
|
3013
|
-
}, variant: selected ? "solid" : "outline", display: "flex", gap: "0.25rem", children: [option, selected && jsx(MdClose, {})] }, option));
|
|
3014
|
-
}) }));
|
|
3063
|
+
}, children: [jsx(IoReload, {}), " ", reloadButtonText] }));
|
|
3015
3064
|
};
|
|
3016
3065
|
|
|
3017
3066
|
const TableFilterTags = () => {
|
|
@@ -3025,16 +3074,99 @@ const TableFilterTags = () => {
|
|
|
3025
3074
|
}) }));
|
|
3026
3075
|
};
|
|
3027
3076
|
|
|
3028
|
-
const TableControls = ({ fitTableWidth = false, fitTableHeight = false, children = jsx(Fragment, {}), showGlobalFilter = false, showFilter = false, showFilterName = false, showFilterTags = false, showReload = false, showPagination = true, showPageSizeControl = true, showPageCountText = true, showView = true,
|
|
3029
|
-
const {
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3077
|
+
const TableControls = ({ fitTableWidth = false, fitTableHeight = false, children = jsx(Fragment, {}), showGlobalFilter = false, showFilter = false, showFilterName = false, showFilterTags = false, showReload = false, showPagination = true, showPageSizeControl = true, showPageCountText = true, showView = true, filterTagsOptions = [], extraItems = jsx(Fragment, {}), loading = false, hasError = false, gridProps = {}, }) => {
|
|
3078
|
+
const { tableLabel, table } = useDataTableContext();
|
|
3079
|
+
const { rowCountText, hasErrorText } = tableLabel;
|
|
3080
|
+
return (jsxs(Grid, { templateRows: "auto 1fr", width: fitTableWidth ? "fit-content" : "100%", height: fitTableHeight ? "fit-content" : "100%", gap: "0.5rem", ...gridProps, children: [jsxs(Flex, { flexFlow: "column", gap: 2, children: [jsxs(Flex, { justifyContent: "space-between", children: [jsx(Box, { children: showView && jsx(ViewDialog, { icon: jsx(MdOutlineViewColumn, {}) }) }), jsxs(Flex, { gap: "0.5rem", alignItems: "center", justifySelf: "end", children: [loading && jsx(Spinner, { size: "sm" }), hasError && (jsx(Tooltip, { content: hasErrorText, children: jsx(Icon, { as: BsExclamationCircleFill, color: "red.400" }) })), showGlobalFilter && jsx(GlobalFilter, {}), showFilter && jsx(FilterDialog, {}), showReload && jsx(ReloadButton, {}), extraItems] })] }), filterTagsOptions.length > 0 && (jsx(Flex, { flexFlow: "column", gap: "0.5rem", children: filterTagsOptions.map((option) => {
|
|
3081
|
+
const { column, options } = option;
|
|
3082
|
+
const tableColumn = table.getColumn(column);
|
|
3083
|
+
return (jsxs(Flex, { alignItems: "center", flexFlow: "wrap", gap: "0.5rem", children: [tableColumn?.columnDef.meta?.displayName && (jsx(Text, { children: tableColumn?.columnDef.meta?.displayName })), jsx(TagFilter, { availableTags: options, selectedTags: tableColumn?.getFilterValue() ?? [], selectOne: true, onTagChange: (tags) => {
|
|
3084
|
+
if (tags.length === 0) {
|
|
3085
|
+
return tableColumn?.setFilterValue(undefined);
|
|
3086
|
+
}
|
|
3087
|
+
tableColumn?.setFilterValue(tags);
|
|
3088
|
+
} })] }, column));
|
|
3089
|
+
}) })), showFilterTags && (jsx(Flex, { children: jsx(TableFilterTags, {}) }))] }), jsx(Grid, { overflow: "auto", bg: { base: "colorPalette.50", _dark: "colorPalette.950" }, children: children }), (showPageSizeControl || showPageCountText || showPagination) && (jsxs(Flex, { justifyContent: "space-between", children: [jsxs(Flex, { gap: "1rem", alignItems: "center", children: [showPageSizeControl && jsx(PageSizeControl, {}), showPageCountText && (jsxs(Flex, { children: [jsx(Text, { paddingRight: "0.5rem", children: rowCountText }), jsx(RowCountText, {})] }))] }), jsx(Box, { justifySelf: "end", children: showPagination && jsx(Pagination, {}) })] }))] }));
|
|
3090
|
+
};
|
|
3091
|
+
|
|
3092
|
+
const EmptyState = React.forwardRef(function EmptyState(props, ref) {
|
|
3093
|
+
const { title, description, icon, children, ...rest } = props;
|
|
3094
|
+
return (jsx(EmptyState$2.Root, { ref: ref, ...rest, children: jsxs(EmptyState$2.Content, { children: [icon && (jsx(EmptyState$2.Indicator, { children: icon })), description ? (jsxs(VStack, { textAlign: "center", children: [jsx(EmptyState$2.Title, { children: title }), jsx(EmptyState$2.Description, { children: description })] })) : (jsx(EmptyState$2.Title, { children: title })), children] }) }));
|
|
3095
|
+
});
|
|
3096
|
+
|
|
3097
|
+
const EmptyResult = (jsx(EmptyState, { icon: jsx(HiColorSwatch, {}), title: "No results found", description: "Try adjusting your search", children: jsxs(List.Root, { variant: "marker", children: [jsx(List.Item, { children: "Try removing filters" }), jsx(List.Item, { children: "Try different keywords" })] }) }));
|
|
3098
|
+
const Table = ({ children, emptyComponent = EmptyResult, canResize = true, ...props }) => {
|
|
3099
|
+
const { table } = useDataTableContext();
|
|
3100
|
+
if (table.getRowModel().rows.length <= 0) {
|
|
3101
|
+
return emptyComponent;
|
|
3102
|
+
}
|
|
3103
|
+
return (jsx(Table$1.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 }));
|
|
3104
|
+
};
|
|
3105
|
+
|
|
3106
|
+
const Checkbox = React.forwardRef(function Checkbox(props, ref) {
|
|
3107
|
+
const { icon, children, inputProps, rootRef, ...rest } = props;
|
|
3108
|
+
return (jsxs(Checkbox$1.Root, { ref: rootRef, ...rest, children: [jsx(Checkbox$1.HiddenInput, { ref: ref, ...inputProps }), jsx(Checkbox$1.Control, { children: icon || jsx(Checkbox$1.Indicator, {}) }), children != null && (jsx(Checkbox$1.Label, { children: children }))] }));
|
|
3109
|
+
});
|
|
3110
|
+
|
|
3111
|
+
const TableBody = ({ showSelector = false, canResize = true, }) => {
|
|
3112
|
+
"use no memo";
|
|
3113
|
+
const { table } = useDataTableContext();
|
|
3114
|
+
const SELECTION_BOX_WIDTH = 20;
|
|
3115
|
+
const [hoveredRow, setHoveredRow] = useState(-1);
|
|
3116
|
+
const handleRowHover = (index) => {
|
|
3117
|
+
setHoveredRow(index);
|
|
3118
|
+
};
|
|
3119
|
+
const getTdProps = (cell) => {
|
|
3120
|
+
const tdProps = cell.column.getIsPinned()
|
|
3121
|
+
? {
|
|
3122
|
+
left: showSelector
|
|
3123
|
+
? `${cell.column.getStart("left") + SELECTION_BOX_WIDTH + table.getDensityValue() * 2}px`
|
|
3124
|
+
: `${cell.column.getStart("left")}px`,
|
|
3125
|
+
position: "relative",
|
|
3126
|
+
}
|
|
3127
|
+
: {};
|
|
3128
|
+
return tdProps;
|
|
3129
|
+
};
|
|
3130
|
+
const getTrProps = ({ hoveredRow, index, }) => {
|
|
3131
|
+
if (hoveredRow === -1) {
|
|
3132
|
+
return {};
|
|
3133
|
+
}
|
|
3134
|
+
if (hoveredRow === index) {
|
|
3135
|
+
return {
|
|
3136
|
+
opacity: "1",
|
|
3137
|
+
};
|
|
3138
|
+
}
|
|
3139
|
+
return {
|
|
3140
|
+
opacity: "0.8",
|
|
3141
|
+
};
|
|
3142
|
+
};
|
|
3143
|
+
return (jsx(Table$1.Body, { children: table.getRowModel().rows.map((row, index) => {
|
|
3144
|
+
return (jsxs(Table$1.Row, { display: "flex", zIndex: 1, onMouseEnter: () => handleRowHover(index), onMouseLeave: () => handleRowHover(-1), ...getTrProps({ hoveredRow, index }), children: [showSelector && (jsx(TableRowSelector, { index: index, row: row, hoveredRow: hoveredRow })), row.getVisibleCells().map((cell, index) => {
|
|
3145
|
+
return (jsx(Table$1.Cell, { padding: `${table.getDensityValue()}px`,
|
|
3146
|
+
// styling resize and pinning start
|
|
3147
|
+
flex: `${canResize ? "0" : "1"} 0 ${cell.column.getSize()}px`,
|
|
3148
|
+
// this is to avoid the cell from being too wide
|
|
3149
|
+
minWidth: `0`, color: {
|
|
3150
|
+
base: "colorPalette.900",
|
|
3151
|
+
_dark: "colorPalette.100",
|
|
3152
|
+
},
|
|
3153
|
+
bg: { base: "colorPalette.50", _dark: "colorPalette.950" }, ...getTdProps(cell), children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, `chakra-table-rowcell-${cell.id}-${index}`));
|
|
3154
|
+
})] }, `chakra-table-row-${row.id}`));
|
|
3155
|
+
}) }));
|
|
3156
|
+
};
|
|
3157
|
+
const TableRowSelector = ({ row, }) => {
|
|
3158
|
+
const { table } = useDataTableContext();
|
|
3159
|
+
const SELECTION_BOX_WIDTH = 20;
|
|
3160
|
+
return (jsx(Table$1.Cell, { padding: `${table.getDensityValue()}px`, display: "grid", color: {
|
|
3161
|
+
base: "colorPalette.900",
|
|
3162
|
+
_dark: "colorPalette.100",
|
|
3163
|
+
},
|
|
3164
|
+
bg: { base: "colorPalette.50", _dark: "colorPalette.950" }, justifyItems: "center", alignItems: "center", children: jsx(Checkbox, { width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px`, checked: row.getIsSelected(),
|
|
3165
|
+
disabled: !row.getCanSelect(),
|
|
3166
|
+
onCheckedChange: row.getToggleSelectedHandler() }) }));
|
|
3035
3167
|
};
|
|
3036
3168
|
|
|
3037
|
-
const TableFooter = ({
|
|
3169
|
+
const TableFooter = ({ showSelector = false, alwaysShowSelector = true, }) => {
|
|
3038
3170
|
const table = useDataTableContext().table;
|
|
3039
3171
|
const SELECTION_BOX_WIDTH = 20;
|
|
3040
3172
|
const [hoveredCheckBox, setHoveredCheckBox] = useState(false);
|
|
@@ -3053,65 +3185,62 @@ const TableFooter = ({ pinnedBgColor = { light: "gray.50", dark: "gray.700" }, s
|
|
|
3053
3185
|
}
|
|
3054
3186
|
return false;
|
|
3055
3187
|
};
|
|
3056
|
-
|
|
3057
|
-
const thProps = header.column.getIsPinned()
|
|
3058
|
-
? {
|
|
3059
|
-
left: showSelector
|
|
3060
|
-
? `${header.getStart("left") + SELECTION_BOX_WIDTH + table.getDensityValue() * 2}px`
|
|
3061
|
-
: `${header.getStart("left") + table.getDensityValue() * 2}px`,
|
|
3062
|
-
background: pinnedBgColor.light,
|
|
3063
|
-
position: "sticky",
|
|
3064
|
-
zIndex: 1,
|
|
3065
|
-
_dark: {
|
|
3066
|
-
backgroundColor: pinnedBgColor.dark,
|
|
3067
|
-
},
|
|
3068
|
-
}
|
|
3069
|
-
: {};
|
|
3070
|
-
return thProps;
|
|
3071
|
-
};
|
|
3072
|
-
return (jsx(Table$1.Footer, { children: table.getFooterGroups().map((footerGroup) => (jsxs(Table$1.Row, { display: "flex", children: [showSelector && (jsxs(Table$1.Header
|
|
3073
|
-
// styling resize and pinning start
|
|
3074
|
-
, {
|
|
3075
|
-
// styling resize and pinning start
|
|
3076
|
-
padding: `${table.getDensityValue()}px`, ...(table.getIsSomeColumnsPinned("left")
|
|
3077
|
-
? {
|
|
3078
|
-
left: `0px`,
|
|
3079
|
-
backgroundColor: pinnedBgColor.light,
|
|
3080
|
-
position: "sticky",
|
|
3081
|
-
zIndex: 1,
|
|
3082
|
-
_dark: { backgroundColor: pinnedBgColor.dark },
|
|
3083
|
-
}
|
|
3084
|
-
: {}),
|
|
3085
|
-
// styling resize and pinning end
|
|
3086
|
-
onMouseEnter: () => handleRowHover(true), onMouseLeave: () => handleRowHover(false), display: "grid", children: [isCheckBoxVisible() && (jsx(Box, { margin: "0rem", display: "grid", justifyItems: "center", alignItems: "center", children: jsx(Checkbox, { width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px`, isChecked: table.getIsAllRowsSelected(),
|
|
3188
|
+
return (jsx(Table$1.Footer, { children: table.getFooterGroups().map((footerGroup) => (jsxs(Table$1.Row, { display: "flex", children: [showSelector && (jsxs(Table$1.Header, { padding: `${table.getDensityValue()}px`, onMouseEnter: () => handleRowHover(true), onMouseLeave: () => handleRowHover(false), display: "grid", children: [isCheckBoxVisible() && (jsx(Box, { margin: "0rem", display: "grid", justifyItems: "center", alignItems: "center", children: jsx(Checkbox, { width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px`, isChecked: table.getIsAllRowsSelected(),
|
|
3087
3189
|
// indeterminate: table.getIsSomeRowsSelected(),
|
|
3088
3190
|
onChange: table.getToggleAllRowsSelectedHandler() }) })), !isCheckBoxVisible() && (jsx(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) => (jsx(Table$1.Cell, { padding: "0", columnSpan: `${header.colSpan}`,
|
|
3089
3191
|
// styling resize and pinning start
|
|
3090
|
-
maxWidth: `${header.getSize()}px`, width: `${header.getSize()}px`, display: "grid",
|
|
3192
|
+
maxWidth: `${header.getSize()}px`, width: `${header.getSize()}px`, display: "grid", children: jsx(MenuRoot$1, { children: jsx(MenuTrigger$1, { asChild: true, children: jsx(Box, { padding: `${table.getDensityValue()}px`, display: "flex", alignItems: "center", justifyContent: "start", borderRadius: "0rem", children: jsxs(Flex, { gap: "0.5rem", alignItems: "center", children: [header.isPlaceholder
|
|
3091
3193
|
? null
|
|
3092
|
-
: flexRender(header.column.columnDef.footer, header.getContext()), jsx(Box, { children: header.column.getCanSort() && (jsxs(Fragment, { children: [header.column.getIsSorted() === false && (
|
|
3093
|
-
// <UpDownIcon />
|
|
3094
|
-
jsx(Fragment, {})), header.column.getIsSorted() === "asc" && (jsx(BiUpArrow, {})), header.column.getIsSorted() === "desc" && (jsx(BiDownArrow, {}))] })) })] }) }) }) }) }, `chakra-table-footer-${header.column.id}-${footerGroup.id}`)))] }, `chakra-table-footergroup-${footerGroup.id}`))) }));
|
|
3194
|
+
: flexRender(header.column.columnDef.footer, header.getContext()), jsx(Box, { children: header.column.getCanSort() && (jsxs(Fragment, { children: [header.column.getIsSorted() === false && jsx(Fragment, {}), header.column.getIsSorted() === "asc" && (jsx(BiUpArrow, {})), header.column.getIsSorted() === "desc" && (jsx(BiDownArrow, {}))] })) })] }) }) }) }) }, `chakra-table-footer-${header.column.id}-${footerGroup.id}`)))] }, `chakra-table-footergroup-${footerGroup.id}`))) }));
|
|
3095
3195
|
};
|
|
3096
3196
|
|
|
3097
|
-
|
|
3197
|
+
// Default text values
|
|
3198
|
+
const DEFAULT_HEADER_TEXTS = {
|
|
3199
|
+
pinColumn: "Pin Column",
|
|
3200
|
+
cancelPin: "Cancel Pin",
|
|
3201
|
+
sortAscending: "Sort Ascending",
|
|
3202
|
+
sortDescending: "Sort Descending",
|
|
3203
|
+
clearSorting: "Clear Sorting",
|
|
3204
|
+
};
|
|
3205
|
+
/**
|
|
3206
|
+
* TableHeader component with configurable text strings.
|
|
3207
|
+
*
|
|
3208
|
+
* @example
|
|
3209
|
+
* // Using default texts
|
|
3210
|
+
* <TableHeader />
|
|
3211
|
+
*
|
|
3212
|
+
* @example
|
|
3213
|
+
* // Customizing default texts for all columns
|
|
3214
|
+
* <TableHeader
|
|
3215
|
+
* defaultTexts={{
|
|
3216
|
+
* pinColumn: "Pin This Column",
|
|
3217
|
+
* sortAscending: "Sort A-Z"
|
|
3218
|
+
* }}
|
|
3219
|
+
* />
|
|
3220
|
+
*
|
|
3221
|
+
* @example
|
|
3222
|
+
* // Customizing texts per column via meta
|
|
3223
|
+
* const columns = [
|
|
3224
|
+
* columnHelper.accessor("name", {
|
|
3225
|
+
* header: "Name",
|
|
3226
|
+
* meta: {
|
|
3227
|
+
* headerTexts: {
|
|
3228
|
+
* pinColumn: "Pin Name Column",
|
|
3229
|
+
* sortAscending: "Sort Names A-Z"
|
|
3230
|
+
* }
|
|
3231
|
+
* }
|
|
3232
|
+
* })
|
|
3233
|
+
* ];
|
|
3234
|
+
*/
|
|
3235
|
+
const TableHeader = ({ canResize = true, showSelector = false, isSticky = true, tableHeaderProps = {}, tableRowProps = {}, defaultTexts = {}, }) => {
|
|
3098
3236
|
const { table } = useDataTableContext();
|
|
3099
3237
|
const SELECTION_BOX_WIDTH = 20;
|
|
3100
|
-
|
|
3101
|
-
const
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
return true;
|
|
3107
|
-
}
|
|
3108
|
-
if (table.getIsAllRowsSelected()) {
|
|
3109
|
-
return true;
|
|
3110
|
-
}
|
|
3111
|
-
if (hoveredCheckBox) {
|
|
3112
|
-
return true;
|
|
3113
|
-
}
|
|
3114
|
-
return false;
|
|
3238
|
+
// Merge default texts with provided defaults
|
|
3239
|
+
const mergedDefaultTexts = { ...DEFAULT_HEADER_TEXTS, ...defaultTexts };
|
|
3240
|
+
// Helper function to get text for a specific header
|
|
3241
|
+
const getHeaderText = (header, key) => {
|
|
3242
|
+
const columnMeta = header.column.columnDef.meta;
|
|
3243
|
+
return columnMeta?.headerTexts?.[key] || mergedDefaultTexts[key];
|
|
3115
3244
|
};
|
|
3116
3245
|
const getThProps = (header) => {
|
|
3117
3246
|
const thProps = header.column.getIsPinned()
|
|
@@ -3119,12 +3248,8 @@ const TableHeader = ({ canResize = true, pinnedBgColor = { light: "gray.50", dar
|
|
|
3119
3248
|
left: showSelector
|
|
3120
3249
|
? `${header.getStart("left") + SELECTION_BOX_WIDTH + table.getDensityValue() * 2}px`
|
|
3121
3250
|
: `${header.getStart("left")}px`,
|
|
3122
|
-
background: pinnedBgColor.light,
|
|
3123
3251
|
position: "sticky",
|
|
3124
3252
|
zIndex: 100 + 1,
|
|
3125
|
-
_dark: {
|
|
3126
|
-
backgroundColor: pinnedBgColor.dark,
|
|
3127
|
-
},
|
|
3128
3253
|
}
|
|
3129
3254
|
: {};
|
|
3130
3255
|
return thProps;
|
|
@@ -3133,21 +3258,13 @@ const TableHeader = ({ canResize = true, pinnedBgColor = { light: "gray.50", dar
|
|
|
3133
3258
|
position: "sticky",
|
|
3134
3259
|
top: 0,
|
|
3135
3260
|
};
|
|
3136
|
-
return (jsx(Table$1.Header, { ...(isSticky ? stickyProps : {}), ...
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
zIndex: 1,
|
|
3144
|
-
_dark: { backgroundColor: pinnedBgColor.dark },
|
|
3145
|
-
}
|
|
3146
|
-
: {}),
|
|
3147
|
-
// styling resize and pinning end
|
|
3148
|
-
padding: `${table.getDensityValue()}px`, onMouseEnter: () => handleRowHover(true), onMouseLeave: () => handleRowHover(false), display: "grid", children: [isCheckBoxVisible() && (jsx(Box, { margin: "0rem", display: "grid", justifyItems: "center", alignItems: "center", children: jsx(Checkbox, { width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px`, isChecked: table.getIsAllRowsSelected(),
|
|
3149
|
-
// indeterminate: table.getIsSomeRowsSelected(),
|
|
3150
|
-
onChange: table.getToggleAllRowsSelectedHandler() }) })), !isCheckBoxVisible() && (jsx(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) => {
|
|
3261
|
+
return (jsx(Table$1.Header, { ...(isSticky ? stickyProps : {}), bgColor: "transparent", ...tableHeaderProps, children: table.getHeaderGroups().map((headerGroup) => (jsxs(Table$1.Row, { display: "flex", bgColor: "transparent", ...tableRowProps, children: [showSelector && (jsx(Table$1.ColumnHeader, { padding: `${table.getDensityValue()}px`, display: "grid", color: {
|
|
3262
|
+
base: "colorPalette.900",
|
|
3263
|
+
_dark: "colorPalette.100",
|
|
3264
|
+
},
|
|
3265
|
+
bg: { base: "colorPalette.50", _dark: "colorPalette.950" }, justifyItems: "center", alignItems: "center", children: jsx(Checkbox, { width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px`, checked: table.getIsAllRowsSelected(),
|
|
3266
|
+
// indeterminate: table.getIsSomeRowsSelected(),
|
|
3267
|
+
onChange: table.getToggleAllRowsSelectedHandler() }) })), headerGroup.headers.map((header) => {
|
|
3151
3268
|
const resizeProps = {
|
|
3152
3269
|
onMouseDown: header.getResizeHandler(),
|
|
3153
3270
|
onTouchStart: header.getResizeHandler(),
|
|
@@ -3155,18 +3272,32 @@ const TableHeader = ({ canResize = true, pinnedBgColor = { light: "gray.50", dar
|
|
|
3155
3272
|
};
|
|
3156
3273
|
return (jsxs(Table$1.ColumnHeader, { padding: 0, columnSpan: `${header.colSpan}`,
|
|
3157
3274
|
// styling resize and pinning start
|
|
3158
|
-
flex: `${canResize ? "0" : "1"} 0 ${header.column.getSize()}px`, display: "grid", gridTemplateColumns: "1fr auto", zIndex: 1500 + header.index,
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3275
|
+
flex: `${canResize ? "0" : "1"} 0 ${header.column.getSize()}px`, display: "grid", gridTemplateColumns: "1fr auto", zIndex: 1500 + header.index, color: {
|
|
3276
|
+
base: "colorPalette.800",
|
|
3277
|
+
_dark: "colorPalette.200",
|
|
3278
|
+
},
|
|
3279
|
+
bg: { base: "colorPalette.100", _dark: "colorPalette.900" }, ...getThProps(header), children: [jsxs(MenuRoot, { children: [jsx(MenuTrigger, { asChild: true, children: jsx(Flex, { padding: `${table.getDensityValue()}px`, alignItems: "center", justifyContent: "start", borderRadius: "0rem", overflow: "auto", color: {
|
|
3280
|
+
base: "colorPalette.800",
|
|
3281
|
+
_dark: "colorPalette.200",
|
|
3282
|
+
_hover: {
|
|
3283
|
+
base: "colorPalette.700",
|
|
3284
|
+
_dark: "colorPalette.300",
|
|
3285
|
+
},
|
|
3286
|
+
},
|
|
3287
|
+
bg: {
|
|
3288
|
+
base: "colorPalette.100",
|
|
3289
|
+
_dark: "colorPalette.900",
|
|
3290
|
+
_hover: {
|
|
3291
|
+
base: "colorPalette.200",
|
|
3292
|
+
_dark: "colorPalette.800",
|
|
3162
3293
|
},
|
|
3163
3294
|
}, children: jsxs(Flex, { gap: "0.5rem", alignItems: "center", children: [header.isPlaceholder
|
|
3164
3295
|
? null
|
|
3165
3296
|
: flexRender(header.column.columnDef.header, header.getContext()), jsx(Box, { children: header.column.getCanSort() && (jsxs(Fragment, { children: [header.column.getIsSorted() === false && jsx(Fragment, {}), header.column.getIsSorted() === "asc" && (jsx(BiUpArrow, {})), header.column.getIsSorted() === "desc" && (jsx(BiDownArrow, {}))] })) }), jsx(Box, { children: header.column.getIsFiltered() && jsx(MdFilterListAlt, {}) })] }) }) }), jsxs(MenuContent, { children: [!header.column.getIsPinned() && (jsx(MenuItem, { asChild: true, value: "pin-column", children: jsxs(Button, { variant: "ghost", onClick: () => {
|
|
3166
3297
|
header.column.pin("left");
|
|
3167
|
-
}, children: [jsx(MdPushPin, {}),
|
|
3298
|
+
}, children: [jsx(MdPushPin, {}), getHeaderText(header, "pinColumn")] }) })), header.column.getIsPinned() && (jsx(MenuItem, { asChild: true, value: "cancel-pin", children: jsxs(Button, { variant: "ghost", onClick: () => {
|
|
3168
3299
|
header.column.pin(false);
|
|
3169
|
-
}, children: [jsx(MdCancel, {}),
|
|
3300
|
+
}, children: [jsx(MdCancel, {}), getHeaderText(header, "cancelPin")] }) })), header.column.getCanSort() && (jsxs(Fragment, { children: [jsx(MenuItem, { asChild: true, value: "sort-ascend", children: jsxs(Button, { variant: "ghost", onClick: () => {
|
|
3170
3301
|
table.setSorting((state) => {
|
|
3171
3302
|
return [
|
|
3172
3303
|
...state.filter((column) => {
|
|
@@ -3175,7 +3306,7 @@ const TableHeader = ({ canResize = true, pinnedBgColor = { light: "gray.50", dar
|
|
|
3175
3306
|
{ id: header.id, desc: false },
|
|
3176
3307
|
];
|
|
3177
3308
|
});
|
|
3178
|
-
}, children: [jsx(GrAscend, {}),
|
|
3309
|
+
}, children: [jsx(GrAscend, {}), getHeaderText(header, "sortAscending")] }) }), jsx(MenuItem, { asChild: true, value: "sort-descend", children: jsxs(Button, { variant: "ghost", onClick: () => {
|
|
3179
3310
|
table.setSorting((state) => {
|
|
3180
3311
|
return [
|
|
3181
3312
|
...state.filter((column) => {
|
|
@@ -3184,42 +3315,30 @@ const TableHeader = ({ canResize = true, pinnedBgColor = { light: "gray.50", dar
|
|
|
3184
3315
|
{ id: header.id, desc: true },
|
|
3185
3316
|
];
|
|
3186
3317
|
});
|
|
3187
|
-
}, children: [jsx(GrDescend, {}),
|
|
3318
|
+
}, children: [jsx(GrDescend, {}), getHeaderText(header, "sortDescending")] }) }), header.column.getIsSorted() && (jsx(MenuItem, { asChild: true, value: "clear-sorting", children: jsxs(Button, { variant: "ghost", onClick: () => {
|
|
3188
3319
|
header.column.clearSorting();
|
|
3189
|
-
}, children: [jsx(MdClear, {}),
|
|
3320
|
+
}, children: [jsx(MdClear, {}), getHeaderText(header, "clearSorting")] }) }))] }))] })] }), canResize && (jsx(Box, { borderRight: "0.2rem solid", borderRightColor: header.column.getIsResizing()
|
|
3321
|
+
? "colorPalette.700"
|
|
3322
|
+
: "transparent", position: "relative", right: "0.1rem", width: "2px", height: "100%", userSelect: "none", style: { touchAction: "none" }, _hover: {
|
|
3190
3323
|
borderRightColor: header.column.getIsResizing()
|
|
3191
|
-
? "
|
|
3192
|
-
: "
|
|
3324
|
+
? "colorPalette.700"
|
|
3325
|
+
: "colorPalette.400",
|
|
3193
3326
|
}, ...resizeProps }))] }, `chakra-table-header-${header.id}`));
|
|
3194
3327
|
})] }, `chakra-table-headergroup-${headerGroup.id}`))) }));
|
|
3195
3328
|
};
|
|
3196
3329
|
|
|
3197
|
-
const
|
|
3198
|
-
const { title, description, icon, children, ...rest } = props;
|
|
3199
|
-
return (jsx(EmptyState$2.Root, { ref: ref, ...rest, children: jsxs(EmptyState$2.Content, { children: [icon && (jsx(EmptyState$2.Indicator, { children: icon })), description ? (jsxs(VStack, { textAlign: "center", children: [jsx(EmptyState$2.Title, { children: title }), jsx(EmptyState$2.Description, { children: description })] })) : (jsx(EmptyState$2.Title, { children: title })), children] }) }));
|
|
3200
|
-
});
|
|
3201
|
-
|
|
3202
|
-
const EmptyResult = (jsx(EmptyState, { icon: jsx(HiColorSwatch, {}), title: "No results found", description: "Try adjusting your search", children: jsxs(List.Root, { variant: "marker", children: [jsx(List.Item, { children: "Try removing filters" }), jsx(List.Item, { children: "Try different keywords" })] }) }));
|
|
3203
|
-
const Table = ({ children, emptyComponent = EmptyResult, canResize = true, ...props }) => {
|
|
3204
|
-
const { table } = useDataTableContext();
|
|
3205
|
-
if (table.getRowModel().rows.length <= 0) {
|
|
3206
|
-
return emptyComponent;
|
|
3207
|
-
}
|
|
3208
|
-
return (jsx(Table$1.Root, { stickyHeader: true, variant: "outline", width: canResize ? table.getCenterTotalSize() : undefined, display: "grid", alignContent: "start", overflowY: "auto", ...props, children: children }));
|
|
3209
|
-
};
|
|
3210
|
-
|
|
3211
|
-
const DefaultTable = ({ showFooter = false, tableProps = {}, tableHeaderProps = {}, tableBodyProps = {}, controlProps = {}, tableFooterProps = {}, variant = "", }) => {
|
|
3330
|
+
const DefaultTable = ({ showFooter = false, tableProps = {}, tableHeaderProps = {}, tableBodyProps = {}, tableFooterProps = {}, controlProps = {}, variant = "", }) => {
|
|
3212
3331
|
if (variant === "greedy") {
|
|
3213
3332
|
return (jsx(TableControls, { ...controlProps, children: jsxs(Table, { canResize: false, ...{ ...tableProps }, children: [jsx(TableHeader, { canResize: false, ...tableHeaderProps }), jsx(TableBody, { canResize: false, ...tableBodyProps }), showFooter && (jsx(TableFooter, { canResize: false, ...tableFooterProps }))] }) }));
|
|
3214
3333
|
}
|
|
3215
3334
|
return (jsx(TableControls, { ...controlProps, children: jsxs(Table, { ...tableProps, children: [jsx(TableHeader, { ...tableHeaderProps }), jsx(TableBody, { ...tableBodyProps }), showFooter && jsx(TableFooter, { ...tableFooterProps })] }) }));
|
|
3216
3335
|
};
|
|
3217
3336
|
|
|
3218
|
-
const TableCardContainer = ({ children, variant = "", ...props }) => {
|
|
3337
|
+
const TableCardContainer = ({ children, variant = "", gap = "1rem", gridTemplateColumns = "repeat(auto-fit, minmax(20rem, 1fr))", direction = "row", ...props }) => {
|
|
3219
3338
|
if (variant === "carousel") {
|
|
3220
|
-
return (jsx(Flex, { overflow: "
|
|
3339
|
+
return (jsx(Flex, { overflow: "auto", gap: gap, direction: direction, ...props, children: children }));
|
|
3221
3340
|
}
|
|
3222
|
-
return (jsx(Grid, { gridTemplateColumns:
|
|
3341
|
+
return (jsx(Grid, { gridTemplateColumns: gridTemplateColumns, gap: gap, ...props, children: children }));
|
|
3223
3342
|
};
|
|
3224
3343
|
|
|
3225
3344
|
const DefaultCardTitle = () => {
|
|
@@ -3248,8 +3367,8 @@ const TableComponent = ({ render = () => {
|
|
|
3248
3367
|
};
|
|
3249
3368
|
|
|
3250
3369
|
const TableLoadingComponent = ({ render, }) => {
|
|
3251
|
-
const {
|
|
3252
|
-
return jsx(Fragment, { children: render(
|
|
3370
|
+
const { query } = useDataTableServerContext();
|
|
3371
|
+
return jsx(Fragment, { children: render(query.isLoading) });
|
|
3253
3372
|
};
|
|
3254
3373
|
|
|
3255
3374
|
const SelectAllRowsToggle = ({ selectAllIcon = jsx(MdOutlineChecklist, {}), clearAllIcon = jsx(MdClear, {}), selectAllText = "", clearAllText = "", }) => {
|
|
@@ -3468,6 +3587,70 @@ const getColumns = ({ schema, include = [], ignore = [], width = [], meta = {},
|
|
|
3468
3587
|
return columns;
|
|
3469
3588
|
};
|
|
3470
3589
|
|
|
3590
|
+
const TableDataDisplay = ({ colorPalette, emptyComponent, }) => {
|
|
3591
|
+
const { columns, translate, data } = useDataTableContext();
|
|
3592
|
+
const columnsMap = Object.fromEntries(columns.map((def) => {
|
|
3593
|
+
const { accessorKey, id } = def;
|
|
3594
|
+
if (accessorKey) {
|
|
3595
|
+
return [accessorKey, def];
|
|
3596
|
+
}
|
|
3597
|
+
return [id, def];
|
|
3598
|
+
}));
|
|
3599
|
+
const columnHeaders = Object.keys(columnsMap);
|
|
3600
|
+
const totalWidths = columns
|
|
3601
|
+
.map(({ size }) => {
|
|
3602
|
+
if (!!size === false) {
|
|
3603
|
+
return 0;
|
|
3604
|
+
}
|
|
3605
|
+
if (typeof size === "number") {
|
|
3606
|
+
return size;
|
|
3607
|
+
}
|
|
3608
|
+
return 0;
|
|
3609
|
+
})
|
|
3610
|
+
.reduce((previous, current) => previous + current, 0);
|
|
3611
|
+
const columnWidths = columns
|
|
3612
|
+
.map(({ size }) => {
|
|
3613
|
+
if (!!size === false) {
|
|
3614
|
+
return "1fr";
|
|
3615
|
+
}
|
|
3616
|
+
return `minmax(${size}px, ${(size / totalWidths) * 100}%)`;
|
|
3617
|
+
})
|
|
3618
|
+
.join(" ");
|
|
3619
|
+
console.log({ columnWidths }, "hadfg");
|
|
3620
|
+
const cellProps = {
|
|
3621
|
+
flex: "1 0 0%",
|
|
3622
|
+
overflow: "auto",
|
|
3623
|
+
paddingX: "2",
|
|
3624
|
+
py: "1",
|
|
3625
|
+
color: { base: "colorPalette.900", _dark: "colorPalette.100" },
|
|
3626
|
+
bgColor: { base: "colorPalette.50", _dark: "colorPalette.950" },
|
|
3627
|
+
borderBottomColor: { base: "colorPalette.200", _dark: "colorPalette.800" },
|
|
3628
|
+
borderBottomWidth: "1px",
|
|
3629
|
+
...{ colorPalette },
|
|
3630
|
+
};
|
|
3631
|
+
if (data.length <= 0) {
|
|
3632
|
+
return jsx(Fragment, { children: emptyComponent });
|
|
3633
|
+
}
|
|
3634
|
+
return (jsxs(Grid, { templateColumns: `${columnWidths}`, overflow: "auto", borderWidth: "1px", color: { base: "colorPalette.900", _dark: "colorPalette.100" }, borderColor: { base: "colorPalette.200", _dark: "colorPalette.800" }, colorPalette, children: [jsx(Grid, { templateColumns: `${columnWidths}`, column: `1/span ${columns.length}`, bg: { base: "colorPalette.200", _dark: "colorPalette.800" }, colorPalette, children: columnHeaders.map((header) => {
|
|
3635
|
+
return (jsx(Box, { flex: "1 0 0%", paddingX: "2", py: "1", overflow: "auto", textOverflow: "ellipsis", children: translate.t(`column_header.${header}`) }));
|
|
3636
|
+
}) }), data.map((record) => {
|
|
3637
|
+
return (jsx(Fragment, { children: columnHeaders.map((header) => {
|
|
3638
|
+
const { cell } = columnsMap[header];
|
|
3639
|
+
const value = record[header];
|
|
3640
|
+
if (!!record === false) {
|
|
3641
|
+
return (jsx(Box, { ...cellProps, children: translate.t(`column_cell.placeholder`) }));
|
|
3642
|
+
}
|
|
3643
|
+
if (cell) {
|
|
3644
|
+
return (jsx(Box, { ...cellProps, children: cell({ row: { original: record } }) }));
|
|
3645
|
+
}
|
|
3646
|
+
if (typeof value === "object") {
|
|
3647
|
+
return (jsx(Box, { ...cellProps, children: jsx(RecordDisplay, { object: value }) }));
|
|
3648
|
+
}
|
|
3649
|
+
return jsx(Box, { ...cellProps, children: value });
|
|
3650
|
+
}) }));
|
|
3651
|
+
})] }));
|
|
3652
|
+
};
|
|
3653
|
+
|
|
3471
3654
|
const AccordionItemTrigger = React.forwardRef(function AccordionItemTrigger(props, ref) {
|
|
3472
3655
|
const { children, indicatorPlacement = "end", ...rest } = props;
|
|
3473
3656
|
return (jsxs(Accordion.ItemTrigger, { ...rest, ref: ref, children: [indicatorPlacement === "start" && (jsx(Accordion.ItemIndicator, { rotate: { base: "-90deg", _open: "0deg" }, children: jsx(LuChevronDown, {}) })), jsx(HStack, { gap: "4", flex: "1", textAlign: "start", width: "full", children: children }), indicatorPlacement === "end" && (jsx(Accordion.ItemIndicator, { children: jsx(LuChevronDown, {}) }))] }));
|
|
@@ -3489,6 +3672,7 @@ const SchemaFormContext = createContext({
|
|
|
3489
3672
|
onSubmit: async () => { },
|
|
3490
3673
|
rowNumber: 0,
|
|
3491
3674
|
requestOptions: {},
|
|
3675
|
+
timezone: 'Asia/Hong_Kong',
|
|
3492
3676
|
});
|
|
3493
3677
|
|
|
3494
3678
|
const useSchemaContext = () => {
|
|
@@ -3514,7 +3698,7 @@ const idPickerSanityCheck = (column, foreign_key) => {
|
|
|
3514
3698
|
throw new Error(`The key column does not exist in properties of column ${column} when using id-picker.`);
|
|
3515
3699
|
}
|
|
3516
3700
|
};
|
|
3517
|
-
const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, children, order = [], ignore = [], include = [], onSubmit = undefined, rowNumber = undefined, requestOptions = {}, getUpdatedData = () => { }, }) => {
|
|
3701
|
+
const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, children, order = [], ignore = [], include = [], onSubmit = undefined, rowNumber = undefined, requestOptions = {}, getUpdatedData = () => { }, customErrorRenderer, }) => {
|
|
3518
3702
|
const [isSuccess, setIsSuccess] = useState(false);
|
|
3519
3703
|
const [isError, setIsError] = useState(false);
|
|
3520
3704
|
const [isSubmiting, setIsSubmiting] = useState(false);
|
|
@@ -3547,11 +3731,12 @@ const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, childre
|
|
|
3547
3731
|
error,
|
|
3548
3732
|
setError,
|
|
3549
3733
|
getUpdatedData,
|
|
3734
|
+
customErrorRenderer,
|
|
3550
3735
|
}, children: jsx(FormProvider, { ...form, children: children }) }));
|
|
3551
3736
|
};
|
|
3552
3737
|
|
|
3553
3738
|
function removeIndex(str) {
|
|
3554
|
-
return str.replace(/\.\d+\./g,
|
|
3739
|
+
return str.replace(/\.\d+\./g, ".");
|
|
3555
3740
|
}
|
|
3556
3741
|
|
|
3557
3742
|
const ArrayRenderer = ({ schema, column, prefix, }) => {
|
|
@@ -3563,13 +3748,17 @@ const ArrayRenderer = ({ schema, column, prefix, }) => {
|
|
|
3563
3748
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
3564
3749
|
const { formState: { errors }, setValue, watch, } = useFormContext();
|
|
3565
3750
|
const fields = (watch(colLabel) ?? []);
|
|
3566
|
-
return (jsxs(
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3751
|
+
return (jsxs(Flex, { gridRow, gridColumn, flexFlow: "column", gap: 2, children: [jsxs(Box, { as: "label", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsx("span", { children: "*" })] }), jsx(Flex, { flexFlow: "column", gap: 2, children: fields.map((field, index) => (jsxs(Grid, { gridTemplateColumns: '1fr auto', gap: 2, bgColor: { base: "colorPalette.100", _dark: "colorPalette.900" }, p: 2, borderRadius: 4, borderWidth: 1, borderColor: {
|
|
3752
|
+
base: "colorPalette.200",
|
|
3753
|
+
_dark: "colorPalette.800",
|
|
3754
|
+
}, children: [jsx(Grid, { gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: jsx(SchemaRenderer, { column: `${index}`,
|
|
3755
|
+
prefix: `${colLabel}.`,
|
|
3756
|
+
// @ts-expect-error find suitable types
|
|
3757
|
+
schema: { showLabel: false, ...(items ?? {}) } }) }), jsx(Flex, { justifyContent: "end", children: jsx(Button$1, { variant: "ghost", onClick: () => {
|
|
3758
|
+
setValue(colLabel, fields.filter((_, curIndex) => {
|
|
3759
|
+
return curIndex !== index;
|
|
3760
|
+
}));
|
|
3761
|
+
}, children: jsx(Icon, { children: jsx(CgTrash, {}) }) }) })] }, `${colLabel}.${index}`))) }), jsx(Flex, { children: jsx(Button$1, { onClick: () => {
|
|
3573
3762
|
if (type === "number") {
|
|
3574
3763
|
setValue(colLabel, [...fields, 0]);
|
|
3575
3764
|
return;
|
|
@@ -3583,7 +3772,7 @@ const ArrayRenderer = ({ schema, column, prefix, }) => {
|
|
|
3583
3772
|
return;
|
|
3584
3773
|
}
|
|
3585
3774
|
setValue(colLabel, [...fields, {}]);
|
|
3586
|
-
}, children: translate.t(removeIndex(`${colLabel}.add`)) }) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.
|
|
3775
|
+
}, children: translate.t(removeIndex(`${colLabel}.add`)) }) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
3587
3776
|
};
|
|
3588
3777
|
|
|
3589
3778
|
const Field = React.forwardRef(function Field(props, ref) {
|
|
@@ -3594,37 +3783,36 @@ const Field = React.forwardRef(function Field(props, ref) {
|
|
|
3594
3783
|
const BooleanPicker = ({ schema, column, prefix }) => {
|
|
3595
3784
|
const { watch, formState: { errors }, setValue, } = useFormContext();
|
|
3596
3785
|
const { translate } = useSchemaContext();
|
|
3597
|
-
const { required, gridColumn, gridRow } = schema;
|
|
3786
|
+
const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
|
|
3598
3787
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
3599
3788
|
const colLabel = `${prefix}${column}`;
|
|
3600
3789
|
const value = watch(colLabel);
|
|
3601
|
-
return (jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.
|
|
3790
|
+
return (jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
3602
3791
|
gridRow, children: [jsx(CheckboxCard, { checked: value, variant: "surface", onChange: () => {
|
|
3603
3792
|
setValue(colLabel, !value);
|
|
3604
|
-
} }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.
|
|
3793
|
+
} }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
3794
|
+
};
|
|
3795
|
+
|
|
3796
|
+
const CustomInput = ({ column, schema, prefix }) => {
|
|
3797
|
+
const formContext = useFormContext();
|
|
3798
|
+
const { inputRender } = schema;
|
|
3799
|
+
return (inputRender &&
|
|
3800
|
+
inputRender({
|
|
3801
|
+
column,
|
|
3802
|
+
schema,
|
|
3803
|
+
prefix,
|
|
3804
|
+
formContext,
|
|
3805
|
+
}));
|
|
3605
3806
|
};
|
|
3606
3807
|
|
|
3607
|
-
const monthNamesShort = [
|
|
3608
|
-
"Jan",
|
|
3609
|
-
"Feb",
|
|
3610
|
-
"Mar",
|
|
3611
|
-
"Apr",
|
|
3612
|
-
"May",
|
|
3613
|
-
"Jun",
|
|
3614
|
-
"Jul",
|
|
3615
|
-
"Aug",
|
|
3616
|
-
"Sep",
|
|
3617
|
-
"Oct",
|
|
3618
|
-
"Nov",
|
|
3619
|
-
"Dec",
|
|
3620
|
-
];
|
|
3621
|
-
const weekdayNamesShort = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
3622
3808
|
const Calendar = ({ calendars, getBackProps, getForwardProps, getDateProps, firstDayOfWeek = 0, }) => {
|
|
3809
|
+
const { labels } = useContext(DatePickerContext);
|
|
3810
|
+
const { monthNamesShort, weekdayNamesShort, backButtonLabel, forwardButtonLabel } = labels;
|
|
3623
3811
|
if (calendars.length) {
|
|
3624
3812
|
return (jsxs(Grid, { children: [jsxs(Grid, { templateColumns: "repeat(4, auto)", justifyContent: "center", children: [jsx(Button$1, { variant: "ghost", ...getBackProps({
|
|
3625
3813
|
calendars,
|
|
3626
3814
|
offset: 12,
|
|
3627
|
-
}), children: "<<" }), jsx(Button$1, { variant: "ghost", ...getBackProps({ calendars }), children:
|
|
3815
|
+
}), children: "<<" }), jsx(Button$1, { variant: "ghost", ...getBackProps({ calendars }), children: backButtonLabel }), jsx(Button$1, { variant: "ghost", ...getForwardProps({ calendars }), children: forwardButtonLabel }), jsx(Button$1, { variant: "ghost", ...getForwardProps({
|
|
3628
3816
|
calendars,
|
|
3629
3817
|
offset: 12,
|
|
3630
3818
|
}), children: ">>" })] }), jsx(Grid, { templateColumns: "repeat(2, auto)", justifyContent: "center", children: calendars.map((calendar) => (jsxs(Grid, { gap: 4, children: [jsxs(Grid, { justifyContent: "center", children: [monthNamesShort[calendar.month], " ", calendar.year] }), jsxs(Grid, { templateColumns: "repeat(7, auto)", justifyContent: "center", children: [[0, 1, 2, 3, 4, 5, 6].map((weekdayNum) => {
|
|
@@ -3667,9 +3855,52 @@ const Calendar = ({ calendars, getBackProps, getForwardProps, getDateProps, firs
|
|
|
3667
3855
|
}
|
|
3668
3856
|
return null;
|
|
3669
3857
|
};
|
|
3858
|
+
const DatePickerContext = createContext({
|
|
3859
|
+
labels: {
|
|
3860
|
+
monthNamesShort: [
|
|
3861
|
+
"Jan",
|
|
3862
|
+
"Feb",
|
|
3863
|
+
"Mar",
|
|
3864
|
+
"Apr",
|
|
3865
|
+
"May",
|
|
3866
|
+
"Jun",
|
|
3867
|
+
"Jul",
|
|
3868
|
+
"Aug",
|
|
3869
|
+
"Sep",
|
|
3870
|
+
"Oct",
|
|
3871
|
+
"Nov",
|
|
3872
|
+
"Dec",
|
|
3873
|
+
],
|
|
3874
|
+
weekdayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
|
|
3875
|
+
backButtonLabel: "Back",
|
|
3876
|
+
forwardButtonLabel: "Next",
|
|
3877
|
+
},
|
|
3878
|
+
});
|
|
3670
3879
|
let DatePicker$1 = class DatePicker extends React__default.Component {
|
|
3671
3880
|
render() {
|
|
3672
|
-
|
|
3881
|
+
const { labels = {
|
|
3882
|
+
monthNamesShort: [
|
|
3883
|
+
"Jan",
|
|
3884
|
+
"Feb",
|
|
3885
|
+
"Mar",
|
|
3886
|
+
"Apr",
|
|
3887
|
+
"May",
|
|
3888
|
+
"Jun",
|
|
3889
|
+
"Jul",
|
|
3890
|
+
"Aug",
|
|
3891
|
+
"Sep",
|
|
3892
|
+
"Oct",
|
|
3893
|
+
"Nov",
|
|
3894
|
+
"Dec",
|
|
3895
|
+
],
|
|
3896
|
+
weekdayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
|
|
3897
|
+
backButtonLabel: "Back",
|
|
3898
|
+
forwardButtonLabel: "Next",
|
|
3899
|
+
}, } = this.props;
|
|
3900
|
+
return (jsx(DatePickerContext.Provider, { value: { labels }, children: jsx(Dayzed, { onDateSelected: this.props.onDateSelected, selected: this.props.selected, firstDayOfWeek: this.props.firstDayOfWeek, showOutsideDays: this.props.showOutsideDays, date: this.props.date, minDate: this.props.minDate, maxDate: this.props.maxDate, monthsToDisplay: this.props.monthsToDisplay, render:
|
|
3901
|
+
// @ts-expect-error - Dayzed types need to be fixed
|
|
3902
|
+
(dayzedData) => (jsx(Calendar, { ...dayzedData,
|
|
3903
|
+
firstDayOfWeek: this.props.firstDayOfWeek })) }) }));
|
|
3673
3904
|
}
|
|
3674
3905
|
};
|
|
3675
3906
|
|
|
@@ -3691,28 +3922,86 @@ const PopoverRoot = Popover.Root;
|
|
|
3691
3922
|
const PopoverBody = Popover.Body;
|
|
3692
3923
|
const PopoverTrigger = Popover.Trigger;
|
|
3693
3924
|
|
|
3925
|
+
function translateWrapper({ prefix, column, label, translate, }) {
|
|
3926
|
+
return translate.t(removeIndex(`${prefix}${column}.${label}`));
|
|
3927
|
+
}
|
|
3928
|
+
|
|
3929
|
+
dayjs.extend(utc);
|
|
3930
|
+
dayjs.extend(timezone);
|
|
3694
3931
|
const DatePicker = ({ column, schema, prefix }) => {
|
|
3695
3932
|
const { watch, formState: { errors }, setValue, } = useFormContext();
|
|
3696
|
-
const { translate } = useSchemaContext();
|
|
3697
|
-
const { required, gridColumn, gridRow } = schema;
|
|
3933
|
+
const { translate, timezone } = useSchemaContext();
|
|
3934
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD", dateFormat = "YYYY-MM-DD", } = schema;
|
|
3698
3935
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
3699
3936
|
const colLabel = `${prefix}${column}`;
|
|
3700
3937
|
const [open, setOpen] = useState(false);
|
|
3701
3938
|
const selectedDate = watch(colLabel);
|
|
3702
|
-
const
|
|
3703
|
-
|
|
3704
|
-
|
|
3939
|
+
const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
|
|
3940
|
+
useEffect(() => {
|
|
3941
|
+
try {
|
|
3942
|
+
if (selectedDate) {
|
|
3943
|
+
// Parse the selectedDate as UTC or in a specific timezone to avoid +8 hour shift
|
|
3944
|
+
// For example, parse as UTC:
|
|
3945
|
+
const parsedDate = dayjs(selectedDate).tz(timezone);
|
|
3946
|
+
if (!parsedDate.isValid())
|
|
3947
|
+
return;
|
|
3948
|
+
// Format according to dateFormat from schema
|
|
3949
|
+
const formatted = parsedDate.format(dateFormat);
|
|
3950
|
+
// Update the form value only if different to avoid loops
|
|
3951
|
+
if (formatted !== selectedDate) {
|
|
3952
|
+
setValue(colLabel, formatted, {
|
|
3953
|
+
shouldValidate: true,
|
|
3954
|
+
shouldDirty: true,
|
|
3955
|
+
});
|
|
3956
|
+
}
|
|
3957
|
+
}
|
|
3958
|
+
}
|
|
3959
|
+
catch (e) {
|
|
3960
|
+
console.error(e);
|
|
3961
|
+
}
|
|
3962
|
+
}, [selectedDate, dateFormat, colLabel, setValue]);
|
|
3963
|
+
const customTranslate = (label) => {
|
|
3964
|
+
return translateWrapper({ prefix, column, label, translate });
|
|
3965
|
+
};
|
|
3966
|
+
return (jsxs(Field, { label: `${customTranslate(`field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
3967
|
+
gridRow, children: [jsxs(PopoverRoot, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsx(PopoverTrigger, { asChild: true, children: jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
|
|
3705
3968
|
setOpen(true);
|
|
3706
|
-
}, children: selectedDate !== undefined ? `${
|
|
3707
|
-
|
|
3708
|
-
, {
|
|
3709
|
-
// @ts-expect-error TODO: find appropriate types
|
|
3710
|
-
selected: new Date(selectedDate),
|
|
3711
|
-
// @ts-expect-error TODO: find appropriate types
|
|
3712
|
-
onDateSelected: ({ date }) => {
|
|
3713
|
-
setValue(colLabel, dayjs(date).format("YYYY-MM-DD"));
|
|
3969
|
+
}, justifyContent: "start", children: [jsx(MdDateRange, {}), selectedDate !== undefined ? `${displayDate}` : ""] }) }), jsx(PopoverContent, { children: jsxs(PopoverBody, { children: [jsx(PopoverTitle, {}), jsx(DatePicker$1, { selected: new Date(selectedDate), onDateSelected: ({ date }) => {
|
|
3970
|
+
setValue(colLabel, dayjs(date).format(dateFormat));
|
|
3714
3971
|
setOpen(false);
|
|
3715
|
-
}
|
|
3972
|
+
}, labels: {
|
|
3973
|
+
monthNamesShort: [
|
|
3974
|
+
translate.t(`common.month_1`, { defaultValue: "January" }),
|
|
3975
|
+
translate.t(`common.month_2`, { defaultValue: "February" }),
|
|
3976
|
+
translate.t(`common.month_3`, { defaultValue: "March" }),
|
|
3977
|
+
translate.t(`common.month_4`, { defaultValue: "April" }),
|
|
3978
|
+
translate.t(`common.month_5`, { defaultValue: "May" }),
|
|
3979
|
+
translate.t(`common.month_6`, { defaultValue: "June" }),
|
|
3980
|
+
translate.t(`common.month_7`, { defaultValue: "July" }),
|
|
3981
|
+
translate.t(`common.month_8`, { defaultValue: "August" }),
|
|
3982
|
+
translate.t(`common.month_9`, { defaultValue: "September" }),
|
|
3983
|
+
translate.t(`common.month_10`, { defaultValue: "October" }),
|
|
3984
|
+
translate.t(`common.month_11`, { defaultValue: "November" }),
|
|
3985
|
+
translate.t(`common.month_12`, { defaultValue: "December" }),
|
|
3986
|
+
],
|
|
3987
|
+
weekdayNamesShort: [
|
|
3988
|
+
translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
|
|
3989
|
+
translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
|
|
3990
|
+
translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
|
|
3991
|
+
translate.t(`common.weekday_4`, {
|
|
3992
|
+
defaultValue: "Wed",
|
|
3993
|
+
}),
|
|
3994
|
+
translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
|
|
3995
|
+
translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
|
|
3996
|
+
translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
|
|
3997
|
+
],
|
|
3998
|
+
backButtonLabel: translate.t(`common.back_button`, {
|
|
3999
|
+
defaultValue: "Back",
|
|
4000
|
+
}),
|
|
4001
|
+
forwardButtonLabel: translate.t(`common.forward_button`, {
|
|
4002
|
+
defaultValue: "Forward",
|
|
4003
|
+
}),
|
|
4004
|
+
} })] }) })] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: customTranslate(`field_required`) }))] }));
|
|
3716
4005
|
};
|
|
3717
4006
|
|
|
3718
4007
|
function filterArray(array, searchTerm) {
|
|
@@ -3725,12 +4014,12 @@ function filterArray(array, searchTerm) {
|
|
|
3725
4014
|
});
|
|
3726
4015
|
}
|
|
3727
4016
|
|
|
3728
|
-
const EnumPicker = ({ column, isMultiple = false, schema, prefix, }) => {
|
|
4017
|
+
const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLimit = false, }) => {
|
|
3729
4018
|
const { watch, formState: { errors }, setValue, } = useFormContext();
|
|
3730
4019
|
const { translate } = useSchemaContext();
|
|
3731
|
-
const { required } = schema;
|
|
4020
|
+
const { required, variant } = schema;
|
|
3732
4021
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
3733
|
-
const { gridColumn, gridRow, renderDisplay } = schema;
|
|
4022
|
+
const { gridColumn = "span 4", gridRow = "span 1", renderDisplay } = schema;
|
|
3734
4023
|
const [searchText, setSearchText] = useState();
|
|
3735
4024
|
const [limit, setLimit] = useState(10);
|
|
3736
4025
|
const [openSearchResult, setOpenSearchResult] = useState();
|
|
@@ -3745,28 +4034,61 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, }) => {
|
|
|
3745
4034
|
setSearchText(event.target.value);
|
|
3746
4035
|
setLimit(10);
|
|
3747
4036
|
};
|
|
3748
|
-
|
|
4037
|
+
if (variant === "radio") {
|
|
4038
|
+
return (jsx(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
4039
|
+
gridRow, children: jsx(RadioGroup$1.Root, { defaultValue: "1", children: jsx(HStack, { gap: "6", children: filterArray(dataList, searchText ?? "").map((item) => {
|
|
4040
|
+
return (jsxs(RadioGroup$1.Item, { onClick: () => {
|
|
4041
|
+
if (!isMultiple) {
|
|
4042
|
+
setOpenSearchResult(false);
|
|
4043
|
+
setValue(colLabel, item);
|
|
4044
|
+
return;
|
|
4045
|
+
}
|
|
4046
|
+
const newSet = new Set([...(watchEnums ?? []), item]);
|
|
4047
|
+
setValue(colLabel, [...newSet]);
|
|
4048
|
+
}, value: item, children: [jsx(RadioGroup$1.ItemHiddenInput, {}), jsx(RadioGroup$1.ItemIndicator, {}), jsx(RadioGroup$1.ItemText, { children: !!renderDisplay === true
|
|
4049
|
+
? renderDisplay(item)
|
|
4050
|
+
: translate.t(removeIndex(`${colLabel}.${item}`)) })] }, `${colLabel}-${item}`));
|
|
4051
|
+
}) }) }) }));
|
|
4052
|
+
}
|
|
4053
|
+
return (jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
3749
4054
|
gridRow, children: [isMultiple && (jsxs(Flex, { flexFlow: "wrap", gap: 1, children: [watchEnums.map((enumValue) => {
|
|
3750
4055
|
const item = enumValue;
|
|
3751
|
-
if (item ===
|
|
3752
|
-
return jsx(Fragment, {
|
|
4056
|
+
if (!!item === false) {
|
|
4057
|
+
return jsx(Fragment, {});
|
|
3753
4058
|
}
|
|
3754
4059
|
return (jsx(Tag, { closable: true, onClick: () => {
|
|
3755
|
-
// setSelectedEnums((state) => state.filter((id) => id != item));
|
|
3756
4060
|
setValue(column, watchEnums.filter((id) => id != item));
|
|
3757
4061
|
}, children: !!renderDisplay === true
|
|
3758
4062
|
? renderDisplay(item)
|
|
3759
4063
|
: translate.t(removeIndex(`${colLabel}.${item}`)) }));
|
|
3760
4064
|
}), jsx(Tag, { cursor: "pointer", onClick: () => {
|
|
3761
4065
|
setOpenSearchResult(true);
|
|
3762
|
-
}, children: translate.t(removeIndex(`${colLabel}.
|
|
4066
|
+
}, children: translate.t(removeIndex(`${colLabel}.add_more`)) })] })), !isMultiple && (jsx(Button, { variant: "outline", onClick: () => {
|
|
3763
4067
|
setOpenSearchResult(true);
|
|
3764
|
-
}, children: watchEnum ===
|
|
4068
|
+
}, justifyContent: "start", children: !!watchEnum === false
|
|
3765
4069
|
? ""
|
|
3766
|
-
: translate.t(removeIndex(`${colLabel}.${watchEnum}`)) })), jsxs(PopoverRoot, { open: openSearchResult, onOpenChange: (e) => setOpenSearchResult(e.open), closeOnInteractOutside: true, initialFocusEl: () => ref.current, positioning: { placement: "bottom-start" }, children: [jsx(PopoverTrigger, {}), jsx(PopoverContent, { children: jsxs(PopoverBody, { display: "grid", gap: 1, children: [jsx(Input, { placeholder: translate.t(`${
|
|
4070
|
+
: translate.t(removeIndex(`${colLabel}.${watchEnum ?? "null"}`)) })), jsxs(PopoverRoot, { open: openSearchResult, onOpenChange: (e) => setOpenSearchResult(e.open), closeOnInteractOutside: true, initialFocusEl: () => ref.current, positioning: { placement: "bottom-start" }, children: [jsx(PopoverTrigger, {}), jsx(PopoverContent, { children: jsxs(PopoverBody, { display: "grid", gap: 1, children: [jsx(Input, { placeholder: translate.t(`${colLabel}.type_to_search`), onChange: (event) => {
|
|
3767
4071
|
onSearchChange(event);
|
|
3768
4072
|
setOpenSearchResult(true);
|
|
3769
|
-
}, autoComplete: "off", ref: ref }), jsx(PopoverTitle, {}), jsx(Text, { children: `${translate.t(`${
|
|
4073
|
+
}, autoComplete: "off", ref: ref }), jsx(PopoverTitle, {}), showTotalAndLimit && (jsx(Text, { children: `${translate.t(removeIndex(`${colLabel}.total`))}: ${count}, ${translate.t(removeIndex(`${colLabel}.showing`))} ${limit}` })), jsxs(Grid, { overflow: "auto", maxHeight: "20rem", children: [jsx(Flex, { flexFlow: "column wrap", children: dataList
|
|
4074
|
+
.filter((item) => {
|
|
4075
|
+
const searchTerm = (searchText || "").toLowerCase();
|
|
4076
|
+
if (!searchTerm)
|
|
4077
|
+
return true;
|
|
4078
|
+
// Check if the original enum value contains the search text
|
|
4079
|
+
const enumValueMatch = item
|
|
4080
|
+
.toLowerCase()
|
|
4081
|
+
.includes(searchTerm);
|
|
4082
|
+
// Check if the display value (translation) contains the search text
|
|
4083
|
+
const displayValue = !!renderDisplay === true
|
|
4084
|
+
? renderDisplay(item)
|
|
4085
|
+
: translate.t(removeIndex(`${colLabel}.${item}`));
|
|
4086
|
+
// Convert to string and check if it includes the search term
|
|
4087
|
+
const displayValueString = String(displayValue).toLowerCase();
|
|
4088
|
+
const displayValueMatch = displayValueString.includes(searchTerm);
|
|
4089
|
+
return enumValueMatch || displayValueMatch;
|
|
4090
|
+
})
|
|
4091
|
+
.map((item) => {
|
|
3770
4092
|
const selected = isMultiple
|
|
3771
4093
|
? watchEnums.some((enumValue) => item === enumValue)
|
|
3772
4094
|
: watchEnum == item;
|
|
@@ -3778,10 +4100,10 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, }) => {
|
|
|
3778
4100
|
}
|
|
3779
4101
|
const newSet = new Set([...(watchEnums ?? []), item]);
|
|
3780
4102
|
setValue(colLabel, [...newSet]);
|
|
3781
|
-
}, ...(selected ? { color: "
|
|
4103
|
+
}, ...(selected ? { color: "colorPalette.400/50" } : {}), children: !!renderDisplay === true
|
|
3782
4104
|
? renderDisplay(item)
|
|
3783
4105
|
: translate.t(removeIndex(`${colLabel}.${item}`)) }, `${colLabel}-${item}`));
|
|
3784
|
-
}) }), isDirty && (jsx(Fragment, { children: dataList.length <= 0 && (jsx(Fragment, { children: translate.t(removeIndex(`${colLabel}.
|
|
4106
|
+
}) }), isDirty && (jsx(Fragment, { children: dataList.length <= 0 && (jsx(Fragment, { children: translate.t(removeIndex(`${colLabel}.empty_search_result`)) })) }))] })] }) })] }), errors[`${colLabel}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
3785
4107
|
};
|
|
3786
4108
|
|
|
3787
4109
|
function isEnteringWindow(_ref) {
|
|
@@ -4133,17 +4455,17 @@ const FileDropzone = ({ children = undefined, gridProps = {}, onDrop = () => { }
|
|
|
4133
4455
|
const filesArray = [...event.target.files];
|
|
4134
4456
|
onDrop({ files: filesArray });
|
|
4135
4457
|
};
|
|
4136
|
-
return (jsxs(Grid, { ...getColor(isDraggedOver), ref: ref, cursor: "pointer", onClick: handleClick, borderStyle: "dashed", borderColor: "
|
|
4458
|
+
return (jsxs(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 && (jsxs(Fragment, { children: [jsx(Flex, { children: placeholder }), jsx(Input, { type: "file", multiple: true, style: { display: "none" }, ref: fileInput, onChange: handleChange })] }))] }));
|
|
4137
4459
|
};
|
|
4138
4460
|
|
|
4139
4461
|
const FilePicker = ({ column, schema, prefix }) => {
|
|
4140
4462
|
const { setValue, formState: { errors }, watch, } = useFormContext();
|
|
4141
4463
|
const { translate } = useSchemaContext();
|
|
4142
|
-
const { required, gridColumn, gridRow } = schema;
|
|
4464
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", } = schema;
|
|
4143
4465
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4144
4466
|
const currentFiles = (watch(column) ?? []);
|
|
4145
4467
|
const colLabel = `${prefix}${column}`;
|
|
4146
|
-
return (jsxs(Field, { label: `${translate.t(`${colLabel}.
|
|
4468
|
+
return (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: [jsx(FileDropzone, { onDrop: ({ files }) => {
|
|
4147
4469
|
const newFiles = files.filter(({ name }) => !currentFiles.some((cur) => cur.name === name));
|
|
4148
4470
|
setValue(colLabel, [...currentFiles, ...newFiles]);
|
|
4149
4471
|
}, placeholder: translate.t(removeIndex(`${colLabel}.fileDropzone`)) }), jsx(Flex, { flexFlow: "column", gap: 1, children: currentFiles.map((file) => {
|
|
@@ -4151,10 +4473,19 @@ const FilePicker = ({ column, schema, prefix }) => {
|
|
|
4151
4473
|
setValue(column, currentFiles.filter(({ name }) => {
|
|
4152
4474
|
return name !== file.name;
|
|
4153
4475
|
}));
|
|
4154
|
-
}, display: "flex", flexFlow: "row", alignItems: "center", padding: "2", children: [jsx(Box, { children: file.name }), jsx(TiDeleteOutline, {})] }) }, file.name));
|
|
4155
|
-
}) }), errors[`${colLabel}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.
|
|
4476
|
+
}, display: "flex", flexFlow: "row", alignItems: "center", padding: "2", children: [file.type.startsWith("image/") && (jsx(Image, { src: URL.createObjectURL(file), alt: file.name, boxSize: "50px", objectFit: "cover", borderRadius: "md", marginRight: "2" })), jsx(Box, { children: file.name }), jsx(TiDeleteOutline, {})] }) }, file.name));
|
|
4477
|
+
}) }), errors[`${colLabel}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4156
4478
|
};
|
|
4157
4479
|
|
|
4480
|
+
const ToggleTip = React.forwardRef(function ToggleTip(props, ref) {
|
|
4481
|
+
const { showArrow, children, portalled = true, content, portalRef, ...rest } = props;
|
|
4482
|
+
return (jsxs(Popover.Root, { ...rest, positioning: { ...rest.positioning, gutter: 4 }, children: [jsx(Popover.Trigger, { asChild: true, children: children }), jsx(Portal, { disabled: !portalled, container: portalRef, children: jsx(Popover.Positioner, { children: jsxs(Popover.Content, { width: "auto", px: "2", py: "1", textStyle: "xs", rounded: "sm", ref: ref, children: [showArrow && (jsx(Popover.Arrow, { children: jsx(Popover.ArrowTip, {}) })), content] }) }) })] }));
|
|
4483
|
+
});
|
|
4484
|
+
const InfoTip = React.forwardRef(function InfoTip(props, ref) {
|
|
4485
|
+
const { children, ...rest } = props;
|
|
4486
|
+
return (jsx(ToggleTip, { content: children, ...rest, ref: ref, children: jsx(IconButton, { variant: "ghost", "aria-label": "info", size: "2xs", colorPalette: "colorPalette", children: jsx(HiOutlineInformationCircle, {}) }) }));
|
|
4487
|
+
});
|
|
4488
|
+
|
|
4158
4489
|
const getTableData = async ({ serverUrl, in_table, searching = "", where = [], limit = 10, offset = 0, }) => {
|
|
4159
4490
|
if (serverUrl === undefined || serverUrl.length == 0) {
|
|
4160
4491
|
throw new Error("The serverUrl is missing");
|
|
@@ -4186,15 +4517,18 @@ const getTableData = async ({ serverUrl, in_table, searching = "", where = [], l
|
|
|
4186
4517
|
const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
4187
4518
|
const { watch, formState: { errors }, setValue, } = useFormContext();
|
|
4188
4519
|
const { serverUrl, idMap, setIdMap, translate, schema: parentSchema, } = useSchemaContext();
|
|
4189
|
-
const { required, gridColumn, gridRow, renderDisplay, foreign_key } = schema;
|
|
4520
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", renderDisplay, foreign_key, } = schema;
|
|
4190
4521
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4191
4522
|
const { table, column: column_ref, display_column, } = foreign_key;
|
|
4192
|
-
const [searchText, setSearchText] = useState();
|
|
4523
|
+
const [searchText, setSearchText] = useState("");
|
|
4193
4524
|
const [limit, setLimit] = useState(10);
|
|
4194
4525
|
const [openSearchResult, setOpenSearchResult] = useState();
|
|
4195
4526
|
const [page, setPage] = useState(0);
|
|
4196
4527
|
const ref = useRef(null);
|
|
4197
4528
|
const colLabel = `${prefix}${column}`;
|
|
4529
|
+
const watchId = watch(colLabel);
|
|
4530
|
+
const watchIds = isMultiple ? (watch(colLabel) ?? []) : [];
|
|
4531
|
+
// Query for search results
|
|
4198
4532
|
const query = useQuery({
|
|
4199
4533
|
queryKey: [`idpicker`, { column, searchText, limit, page }],
|
|
4200
4534
|
queryFn: async () => {
|
|
@@ -4203,7 +4537,7 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4203
4537
|
searching: searchText ?? "",
|
|
4204
4538
|
in_table: table,
|
|
4205
4539
|
limit: limit,
|
|
4206
|
-
offset: page *
|
|
4540
|
+
offset: page * limit,
|
|
4207
4541
|
});
|
|
4208
4542
|
const newMap = Object.fromEntries((data ?? { data: [] }).data.map((item) => {
|
|
4209
4543
|
return [
|
|
@@ -4218,27 +4552,27 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4218
4552
|
});
|
|
4219
4553
|
return data;
|
|
4220
4554
|
},
|
|
4221
|
-
enabled:
|
|
4555
|
+
enabled: openSearchResult === true,
|
|
4222
4556
|
staleTime: 300000,
|
|
4223
4557
|
});
|
|
4224
|
-
|
|
4225
|
-
const
|
|
4226
|
-
const count = data?.count ?? 0;
|
|
4227
|
-
const isDirty = (searchText?.length ?? 0) > 0;
|
|
4228
|
-
const watchId = watch(colLabel);
|
|
4229
|
-
const watchIds = (watch(colLabel) ?? []);
|
|
4230
|
-
useQuery({
|
|
4558
|
+
// Query for currently selected items (to display them properly)
|
|
4559
|
+
const queryDefault = useQuery({
|
|
4231
4560
|
queryKey: [
|
|
4232
|
-
`idpicker`,
|
|
4233
|
-
{ form: parentSchema.title, column,
|
|
4561
|
+
`idpicker-default`,
|
|
4562
|
+
{ form: parentSchema.title, column, id: isMultiple ? watchIds : watchId },
|
|
4234
4563
|
],
|
|
4235
4564
|
queryFn: async () => {
|
|
4565
|
+
if (!watchId && (!watchIds || watchIds.length === 0)) {
|
|
4566
|
+
return { data: [] };
|
|
4567
|
+
}
|
|
4568
|
+
const searchValue = isMultiple ? watchIds.join(",") : watchId;
|
|
4236
4569
|
const data = await getTableData({
|
|
4237
4570
|
serverUrl,
|
|
4238
|
-
searching:
|
|
4571
|
+
searching: searchValue,
|
|
4239
4572
|
in_table: table,
|
|
4240
|
-
|
|
4241
|
-
|
|
4573
|
+
where: [{ id: column_ref, value: isMultiple ? watchIds : watchId }],
|
|
4574
|
+
limit: isMultiple ? watchIds.length : 1,
|
|
4575
|
+
offset: 0,
|
|
4242
4576
|
});
|
|
4243
4577
|
const newMap = Object.fromEntries((data ?? { data: [] }).data.map((item) => {
|
|
4244
4578
|
return [
|
|
@@ -4253,12 +4587,45 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4253
4587
|
});
|
|
4254
4588
|
return data;
|
|
4255
4589
|
},
|
|
4590
|
+
enabled: isMultiple
|
|
4591
|
+
? Array.isArray(watchIds) && watchIds.length > 0
|
|
4592
|
+
: !!watchId,
|
|
4256
4593
|
});
|
|
4594
|
+
// Effect to load selected values when component mounts
|
|
4595
|
+
useEffect(() => {
|
|
4596
|
+
if (isMultiple ? watchIds.length > 0 : !!watchId) {
|
|
4597
|
+
queryDefault.refetch();
|
|
4598
|
+
}
|
|
4599
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4600
|
+
}, []);
|
|
4601
|
+
// Effect to trigger initial data fetch when popover opens
|
|
4602
|
+
useEffect(() => {
|
|
4603
|
+
if (openSearchResult) {
|
|
4604
|
+
// Reset search text when opening the popover
|
|
4605
|
+
setSearchText("");
|
|
4606
|
+
// Reset page to first page
|
|
4607
|
+
setPage(0);
|
|
4608
|
+
// Fetch initial data
|
|
4609
|
+
query.refetch();
|
|
4610
|
+
}
|
|
4611
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4612
|
+
}, [openSearchResult]);
|
|
4257
4613
|
const onSearchChange = async (event) => {
|
|
4258
4614
|
setSearchText(event.target.value);
|
|
4259
4615
|
setPage(0);
|
|
4260
|
-
|
|
4616
|
+
query.refetch();
|
|
4617
|
+
};
|
|
4618
|
+
const handleLimitChange = (event) => {
|
|
4619
|
+
const newLimit = Number(event.target.value);
|
|
4620
|
+
setLimit(newLimit);
|
|
4621
|
+
// Reset to first page when changing limit
|
|
4622
|
+
setPage(0);
|
|
4623
|
+
// Trigger a new search with the updated limit
|
|
4624
|
+
query.refetch();
|
|
4261
4625
|
};
|
|
4626
|
+
const { isLoading, isFetching, data, isPending, isError } = query;
|
|
4627
|
+
const dataList = data?.data ?? [];
|
|
4628
|
+
const count = data?.count ?? 0;
|
|
4262
4629
|
const getPickedValue = () => {
|
|
4263
4630
|
if (Object.keys(idMap).length <= 0) {
|
|
4264
4631
|
return "";
|
|
@@ -4267,52 +4634,62 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4267
4634
|
if (record === undefined) {
|
|
4268
4635
|
return "";
|
|
4269
4636
|
}
|
|
4637
|
+
if (!!renderDisplay === true) {
|
|
4638
|
+
return renderDisplay(record);
|
|
4639
|
+
}
|
|
4270
4640
|
return record[display_column];
|
|
4271
4641
|
};
|
|
4272
|
-
return (jsxs(Field, { label: `${translate.t(removeIndex(removeIndex(`${column}.
|
|
4642
|
+
return (jsxs(Field, { label: `${translate.t(removeIndex(removeIndex(`${column}.field_label`)))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
4273
4643
|
gridRow, children: [isMultiple && (jsxs(Flex, { flexFlow: "wrap", gap: 1, children: [watchIds.map((id) => {
|
|
4274
4644
|
const item = idMap[id];
|
|
4275
4645
|
if (item === undefined) {
|
|
4276
4646
|
return (jsx(Text, { children: translate.t(removeIndex(`${colLabel}.undefined`)) }, id));
|
|
4277
4647
|
}
|
|
4278
4648
|
return (jsx(Tag, { closable: true, onClick: () => {
|
|
4279
|
-
setValue(
|
|
4649
|
+
setValue(colLabel, watchIds.filter((itemId) => itemId !== item[column_ref]));
|
|
4280
4650
|
}, children: !!renderDisplay === true
|
|
4281
4651
|
? renderDisplay(item)
|
|
4282
4652
|
: item[display_column] }, id));
|
|
4283
4653
|
}), jsx(Tag, { cursor: "pointer", onClick: () => {
|
|
4284
4654
|
setOpenSearchResult(true);
|
|
4285
|
-
}, children: translate.t(removeIndex(`${colLabel}.
|
|
4655
|
+
}, children: translate.t(removeIndex(`${colLabel}.add_more`)) })] })), !isMultiple && (jsx(Button, { variant: "outline", onClick: () => {
|
|
4286
4656
|
setOpenSearchResult(true);
|
|
4287
|
-
}, children: getPickedValue() })), jsxs(PopoverRoot, { open: openSearchResult, onOpenChange: (e) => setOpenSearchResult(e.open), closeOnInteractOutside: true, initialFocusEl: () => ref.current, positioning: { placement: "bottom-start", strategy: "fixed" }, children: [jsx(PopoverTrigger, {}), jsx(PopoverContent, { children: jsxs(PopoverBody, { display: "grid", gap: 1, children: [jsx(Input, { placeholder: translate.t(removeIndex(`${colLabel}.
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
|
|
4293
|
-
|
|
4294
|
-
|
|
4295
|
-
|
|
4296
|
-
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4657
|
+
}, justifyContent: "start", children: queryDefault.isLoading ? jsx(Spinner, { size: "sm" }) : getPickedValue() })), jsxs(PopoverRoot, { open: openSearchResult, onOpenChange: (e) => setOpenSearchResult(e.open), closeOnInteractOutside: true, initialFocusEl: () => ref.current, positioning: { placement: "bottom-start", strategy: "fixed" }, children: [jsx(PopoverTrigger, {}), jsx(PopoverContent, { children: jsxs(PopoverBody, { display: "grid", gap: 1, children: [jsx(Input, { placeholder: translate.t(removeIndex(`${colLabel}.type_to_search`)), onChange: onSearchChange, autoComplete: "off", ref: ref, value: searchText }), jsx(PopoverTitle, {}), openSearchResult && (jsxs(Fragment, { children: [(isFetching || isLoading || isPending) && jsx(Spinner, {}), isError && (jsx(Icon, { color: "red.400", children: jsx(BiError, {}) })), jsxs(Flex, { justifyContent: "space-between", alignItems: "center", children: [jsxs(Flex, { alignItems: "center", gap: "2", children: [jsx(InfoTip, { children: `${translate.t(removeIndex(`${colLabel}.total`))} ${count}, ${translate.t(removeIndex(`${colLabel}.showing`))} ${limit} ${translate.t(removeIndex(`${colLabel}.per_page`), "per page")}` }), jsxs(Text, { fontSize: "sm", fontWeight: "bold", children: [count, jsxs(Text, { as: "span", fontSize: "xs", ml: "1", color: "gray.500", children: ["/ ", count > 0 ? `${page * limit + 1}-${Math.min((page + 1) * limit, count)}` : '0'] })] })] }), jsx(Box, { children: jsxs("select", { value: limit, onChange: handleLimitChange, style: {
|
|
4658
|
+
padding: "4px 8px",
|
|
4659
|
+
borderRadius: "4px",
|
|
4660
|
+
border: "1px solid #ccc",
|
|
4661
|
+
fontSize: "14px",
|
|
4662
|
+
}, children: [jsx("option", { value: "5", children: "5" }), jsx("option", { value: "10", children: "10" }), jsx("option", { value: "20", children: "20" }), jsx("option", { value: "30", children: "30" })] }) })] }), jsx(Grid, { overflowY: "auto", children: dataList.length > 0 ? (jsx(Flex, { flexFlow: "column wrap", gap: 1, children: dataList.map((item) => {
|
|
4663
|
+
const selected = isMultiple
|
|
4664
|
+
? watchIds.some((id) => item[column_ref] === id)
|
|
4665
|
+
: watchId === item[column_ref];
|
|
4666
|
+
return (jsx(Box, { cursor: "pointer", onClick: () => {
|
|
4667
|
+
if (!isMultiple) {
|
|
4668
|
+
setOpenSearchResult(false);
|
|
4669
|
+
setValue(colLabel, item[column_ref]);
|
|
4670
|
+
return;
|
|
4671
|
+
}
|
|
4672
|
+
// For multiple selection, don't add if already selected
|
|
4673
|
+
if (selected)
|
|
4674
|
+
return;
|
|
4675
|
+
const newSet = new Set([
|
|
4676
|
+
...(watchIds ?? []),
|
|
4677
|
+
item[column_ref],
|
|
4678
|
+
]);
|
|
4679
|
+
setValue(colLabel, [...newSet]);
|
|
4680
|
+
}, opacity: 0.7, _hover: { opacity: 1 }, ...(selected
|
|
4681
|
+
? { color: "colorPalette.400/50", fontWeight: "bold" }
|
|
4682
|
+
: {}), children: !!renderDisplay === true
|
|
4683
|
+
? renderDisplay(item)
|
|
4684
|
+
: item[display_column] }, item[column_ref]));
|
|
4685
|
+
}) })) : (jsx(Text, { children: searchText
|
|
4686
|
+
? translate.t(removeIndex(`${colLabel}.empty_search_result`))
|
|
4687
|
+
: translate.t(removeIndex(`${colLabel}.initial_results`)) })) }), jsx(PaginationRoot, { justifySelf: "center", count: count, pageSize: limit, defaultPage: 1, page: page + 1, onPageChange: (e) => setPage(e.page - 1), children: jsxs(HStack, { gap: "4", children: [jsx(PaginationPrevTrigger, {}), count > 0 && jsx(PaginationPageText, {}), jsx(PaginationNextTrigger, {})] }) })] }))] }) })] }), errors[`${colLabel}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4311
4688
|
};
|
|
4312
4689
|
|
|
4313
4690
|
const NumberInputRoot = React.forwardRef(function NumberInput$1(props, ref) {
|
|
4314
4691
|
const { children, ...rest } = props;
|
|
4315
|
-
return (
|
|
4692
|
+
return (jsx(NumberInput.Root, { ref: ref, variant: "outline", ...rest, children: children }));
|
|
4316
4693
|
});
|
|
4317
4694
|
const NumberInputField$1 = NumberInput.Input;
|
|
4318
4695
|
NumberInput.Scrubber;
|
|
@@ -4321,17 +4698,17 @@ NumberInput.Label;
|
|
|
4321
4698
|
const NumberInputField = ({ schema, column, prefix, }) => {
|
|
4322
4699
|
const { setValue, formState: { errors }, watch, } = useFormContext();
|
|
4323
4700
|
const { translate } = useSchemaContext();
|
|
4324
|
-
const { required, gridColumn, gridRow } = schema;
|
|
4701
|
+
const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
|
|
4325
4702
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4326
4703
|
const colLabel = `${prefix}${column}`;
|
|
4327
4704
|
const value = watch(`${colLabel}`);
|
|
4328
|
-
return (jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.
|
|
4705
|
+
return (jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn, gridRow, children: [jsx(NumberInputRoot, { children: jsx(NumberInputField$1, { required: isRequired, value: value, onChange: (event) => {
|
|
4329
4706
|
setValue(`${colLabel}`, Number(event.target.value));
|
|
4330
|
-
} }) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.
|
|
4707
|
+
} }) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4331
4708
|
};
|
|
4332
4709
|
|
|
4333
4710
|
const ObjectInput = ({ schema, column, prefix }) => {
|
|
4334
|
-
const { properties,
|
|
4711
|
+
const { properties, gridColumn = "span 12", gridRow = "span 1", required, showLabel = true, } = schema;
|
|
4335
4712
|
const { translate } = useSchemaContext();
|
|
4336
4713
|
const colLabel = `${prefix}${column}`;
|
|
4337
4714
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
@@ -4339,25 +4716,28 @@ const ObjectInput = ({ schema, column, prefix }) => {
|
|
|
4339
4716
|
if (properties === undefined) {
|
|
4340
4717
|
throw new Error(`properties is undefined when using ObjectInput`);
|
|
4341
4718
|
}
|
|
4342
|
-
return (jsxs(Box, { gridRow, gridColumn, children: [jsxs(Box, { as: "label",
|
|
4719
|
+
return (jsxs(Box, { gridRow, gridColumn, children: [showLabel && (jsxs(Box, { as: "label", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsx("span", { children: "*" })] })), jsx(Grid, { bgColor: { base: "colorPalette.100", _dark: "colorPalette.900" }, p: 2, borderRadius: 4, borderWidth: 1, borderColor: {
|
|
4720
|
+
base: "colorPalette.200",
|
|
4721
|
+
_dark: "colorPalette.800",
|
|
4722
|
+
}, gap: "4", padding: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: Object.keys(properties ?? {}).map((key) => {
|
|
4343
4723
|
return (
|
|
4344
4724
|
// @ts-expect-error find suitable types
|
|
4345
4725
|
jsx(ColumnRenderer, { column: `${key}`,
|
|
4346
4726
|
prefix: `${prefix}${column}.`,
|
|
4347
4727
|
properties }, `form-${colLabel}-${key}`));
|
|
4348
|
-
}) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.
|
|
4728
|
+
}) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4349
4729
|
};
|
|
4350
4730
|
|
|
4351
4731
|
const RecordInput$1 = ({ column, schema, prefix }) => {
|
|
4352
4732
|
const { formState: { errors }, setValue, getValues, } = useFormContext();
|
|
4353
4733
|
const { translate } = useSchemaContext();
|
|
4354
|
-
const { required, gridColumn, gridRow } = schema;
|
|
4734
|
+
const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
|
|
4355
4735
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4356
4736
|
const entries = Object.entries(getValues(column) ?? {});
|
|
4357
4737
|
const [showNewEntries, setShowNewEntries] = useState(false);
|
|
4358
4738
|
const [newKey, setNewKey] = useState();
|
|
4359
4739
|
const [newValue, setNewValue] = useState();
|
|
4360
|
-
return (jsxs(Field, { label: `${translate.t(`${column}.
|
|
4740
|
+
return (jsxs(Field, { label: `${translate.t(`${column}.field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn, gridRow, children: [entries.map(([key, value]) => {
|
|
4361
4741
|
return (jsxs(Grid, { templateColumns: "1fr 1fr auto", gap: 1, children: [jsx(Input, { value: key, onChange: (e) => {
|
|
4362
4742
|
const filtered = entries.filter(([target]) => {
|
|
4363
4743
|
return target !== key;
|
|
@@ -4397,16 +4777,16 @@ const RecordInput$1 = ({ column, schema, prefix }) => {
|
|
|
4397
4777
|
setShowNewEntries(true);
|
|
4398
4778
|
setNewKey(undefined);
|
|
4399
4779
|
setNewValue(undefined);
|
|
4400
|
-
}, children: translate.t(`${column}.addNew`) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(`${column}.
|
|
4780
|
+
}, children: translate.t(`${column}.addNew`) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
|
|
4401
4781
|
};
|
|
4402
4782
|
|
|
4403
4783
|
const StringInputField = ({ column, schema, prefix, }) => {
|
|
4404
4784
|
const { register, formState: { errors }, } = useFormContext();
|
|
4405
4785
|
const { translate } = useSchemaContext();
|
|
4406
|
-
const { required, gridColumn, gridRow } = schema;
|
|
4786
|
+
const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
|
|
4407
4787
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4408
4788
|
const colLabel = `${prefix}${column}`;
|
|
4409
|
-
return (jsx(Fragment, { children: jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.
|
|
4789
|
+
return (jsx(Fragment, { children: jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn: gridColumn, gridRow: gridRow, children: [jsx(Input, { ...register(`${colLabel}`, { required: isRequired }), autoComplete: "off" }), errors[colLabel] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }) }));
|
|
4410
4790
|
};
|
|
4411
4791
|
|
|
4412
4792
|
const RadioCardItem = React.forwardRef(function RadioCardItem(props, ref) {
|
|
@@ -4504,9 +4884,459 @@ const TagPicker = ({ column, schema, prefix }) => {
|
|
|
4504
4884
|
}), errors[`${column}`] && (jsx(Text, { color: "red.400", children: (errors[`${column}`]?.message ?? "No error message") }))] }));
|
|
4505
4885
|
};
|
|
4506
4886
|
|
|
4887
|
+
const TextAreaInput = ({ column, schema, prefix, }) => {
|
|
4888
|
+
const { register, formState: { errors }, } = useFormContext();
|
|
4889
|
+
const { translate } = useSchemaContext();
|
|
4890
|
+
const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
|
|
4891
|
+
const isRequired = required?.some((columnId) => columnId === column);
|
|
4892
|
+
const colLabel = `${prefix}${column}`;
|
|
4893
|
+
return (jsx(Fragment, { children: jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn: gridColumn ?? "span 4", gridRow: gridRow ?? "span 1", children: [jsx(Textarea, { ...register(`${colLabel}`, { required: isRequired }), autoComplete: "off" }), errors[colLabel] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }) }));
|
|
4894
|
+
};
|
|
4895
|
+
|
|
4896
|
+
function TimePicker$1({ hour, setHour, minute, setMinute, meridiem, setMeridiem, meridiemLabel = {
|
|
4897
|
+
am: "am",
|
|
4898
|
+
pm: "pm",
|
|
4899
|
+
}, onChange = (_newValue) => { }, }) {
|
|
4900
|
+
// Refs for focus management
|
|
4901
|
+
const hourInputRef = useRef(null);
|
|
4902
|
+
const minuteInputRef = useRef(null);
|
|
4903
|
+
useRef(null);
|
|
4904
|
+
// Centralized handler for key events, value changes, and focus management
|
|
4905
|
+
const handleKeyDown = (e, field) => {
|
|
4906
|
+
const input = e.target;
|
|
4907
|
+
const value = input.value;
|
|
4908
|
+
// Handle navigation between fields
|
|
4909
|
+
if (e.key === "Tab") {
|
|
4910
|
+
// Tab is handled by the browser, no need to override
|
|
4911
|
+
return;
|
|
4912
|
+
}
|
|
4913
|
+
if (e.key === ":" && field === "hour") {
|
|
4914
|
+
e.preventDefault();
|
|
4915
|
+
minuteInputRef.current?.focus();
|
|
4916
|
+
return;
|
|
4917
|
+
}
|
|
4918
|
+
if (e.key === "Backspace" && value === "") {
|
|
4919
|
+
e.preventDefault();
|
|
4920
|
+
if (field === "minute") {
|
|
4921
|
+
hourInputRef.current?.focus();
|
|
4922
|
+
}
|
|
4923
|
+
else if (field === "meridiem") {
|
|
4924
|
+
minuteInputRef.current?.focus();
|
|
4925
|
+
}
|
|
4926
|
+
return;
|
|
4927
|
+
}
|
|
4928
|
+
// Handle number inputs
|
|
4929
|
+
if (field === "hour") {
|
|
4930
|
+
if (e.key.match(/^[0-9]$/)) {
|
|
4931
|
+
const newValue = value + e.key;
|
|
4932
|
+
const numValue = parseInt(newValue, 10);
|
|
4933
|
+
console.log("newValue", newValue, numValue);
|
|
4934
|
+
if (numValue > 12) {
|
|
4935
|
+
const digitValue = parseInt(e.key, 10);
|
|
4936
|
+
setHour(digitValue);
|
|
4937
|
+
onChange({ hour: digitValue, minute, meridiem });
|
|
4938
|
+
return;
|
|
4939
|
+
}
|
|
4940
|
+
// Auto-advance to minutes if we have a valid hour (1-12)
|
|
4941
|
+
if (numValue >= 1 && numValue <= 12) {
|
|
4942
|
+
// Set the hour value
|
|
4943
|
+
setHour(numValue);
|
|
4944
|
+
onChange({ hour: numValue, minute, meridiem });
|
|
4945
|
+
// Move to minute input
|
|
4946
|
+
e.preventDefault();
|
|
4947
|
+
minuteInputRef.current?.focus();
|
|
4948
|
+
}
|
|
4949
|
+
}
|
|
4950
|
+
}
|
|
4951
|
+
else if (field === "minute") {
|
|
4952
|
+
if (e.key.match(/^[0-9]$/)) {
|
|
4953
|
+
const newValue = value + e.key;
|
|
4954
|
+
const numValue = parseInt(newValue, 10);
|
|
4955
|
+
console.log("newValue minute", newValue, numValue, numValue > 60, numValue >= 0 && numValue <= 59, e.key);
|
|
4956
|
+
if (numValue > 60) {
|
|
4957
|
+
const digitValue = parseInt(e.key, 10);
|
|
4958
|
+
setMinute(digitValue);
|
|
4959
|
+
onChange({ hour, minute: digitValue, meridiem });
|
|
4960
|
+
return;
|
|
4961
|
+
}
|
|
4962
|
+
// Auto-advance to meridiem if we have a valid minute (0-59)
|
|
4963
|
+
if (numValue >= 0 && numValue <= 59) {
|
|
4964
|
+
// Set the minute value
|
|
4965
|
+
setMinute(numValue);
|
|
4966
|
+
onChange({ hour, minute: numValue, meridiem });
|
|
4967
|
+
}
|
|
4968
|
+
}
|
|
4969
|
+
}
|
|
4970
|
+
};
|
|
4971
|
+
// Handle meridiem button click
|
|
4972
|
+
const handleMeridiemClick = (newMeridiem) => {
|
|
4973
|
+
setMeridiem(newMeridiem);
|
|
4974
|
+
onChange({ hour, minute, meridiem: newMeridiem });
|
|
4975
|
+
};
|
|
4976
|
+
const handleClear = () => {
|
|
4977
|
+
setHour(null);
|
|
4978
|
+
setMinute(null);
|
|
4979
|
+
setMeridiem(null);
|
|
4980
|
+
onChange({ hour: null, minute: null, meridiem: null });
|
|
4981
|
+
// Focus the hour field after clearing
|
|
4982
|
+
hourInputRef.current?.focus();
|
|
4983
|
+
};
|
|
4984
|
+
return (jsx(Flex, { direction: "column", gap: 3, children: jsxs(Grid, { justifyContent: "center", alignItems: "center", templateColumns: "60px 10px 60px 90px auto", gap: "2", width: "auto", minWidth: "250px", children: [jsx(Input, { ref: hourInputRef, type: "text", value: hour === null ? "" : hour.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "hour"), placeholder: "HH", maxLength: 2, textAlign: "center" }), jsx(Text, { children: ":" }), jsx(Input, { ref: minuteInputRef, type: "text", value: minute === null ? "" : minute.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "minute"), placeholder: "MM", maxLength: 2, textAlign: "center" }), jsxs(Flex, { gap: "1", children: [jsx(Button$1, { size: "sm", colorScheme: meridiem === "am" ? "blue" : "gray", variant: meridiem === "am" ? "solid" : "outline", onClick: () => handleMeridiemClick("am"), width: "40px", children: meridiemLabel.am }), jsx(Button$1, { size: "sm", colorScheme: meridiem === "pm" ? "blue" : "gray", variant: meridiem === "pm" ? "solid" : "outline", onClick: () => handleMeridiemClick("pm"), width: "40px", children: meridiemLabel.pm })] }), jsx(Button$1, { onClick: handleClear, size: "sm", variant: "ghost", children: jsx(MdCancel, {}) })] }) }));
|
|
4985
|
+
}
|
|
4986
|
+
|
|
4987
|
+
dayjs.extend(timezone);
|
|
4988
|
+
const TimePicker = ({ column, schema, prefix }) => {
|
|
4989
|
+
const { watch, formState: { errors }, setValue, } = useFormContext();
|
|
4990
|
+
const { translate, timezone } = useSchemaContext();
|
|
4991
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", timeFormat = "HH:mm:ssZ", displayTimeFormat = "hh:mm A", } = schema;
|
|
4992
|
+
const isRequired = required?.some((columnId) => columnId === column);
|
|
4993
|
+
const colLabel = `${prefix}${column}`;
|
|
4994
|
+
const [open, setOpen] = useState(false);
|
|
4995
|
+
const value = watch(colLabel);
|
|
4996
|
+
const displayedTime = dayjs(`1970-01-01T${value}`).tz(timezone).isValid()
|
|
4997
|
+
? dayjs(`1970-01-01T${value}`).tz(timezone).format(displayTimeFormat)
|
|
4998
|
+
: "";
|
|
4999
|
+
// Parse the initial time parts from the ISO time string (HH:mm:ss)
|
|
5000
|
+
const parseTime = (isoTime) => {
|
|
5001
|
+
if (!isoTime)
|
|
5002
|
+
return { hour: 12, minute: 0, meridiem: "am" };
|
|
5003
|
+
const parsed = dayjs(`1970-01-01T${isoTime}`).tz(timezone);
|
|
5004
|
+
if (!parsed.isValid())
|
|
5005
|
+
return { hour: 12, minute: 0, meridiem: "am" };
|
|
5006
|
+
let hour = parsed.hour();
|
|
5007
|
+
const minute = parsed.minute();
|
|
5008
|
+
const meridiem = hour >= 12 ? "pm" : "am";
|
|
5009
|
+
if (hour === 0)
|
|
5010
|
+
hour = 12;
|
|
5011
|
+
else if (hour > 12)
|
|
5012
|
+
hour -= 12;
|
|
5013
|
+
return { hour, minute, meridiem };
|
|
5014
|
+
};
|
|
5015
|
+
const initialTime = parseTime(value);
|
|
5016
|
+
const [hour, setHour] = useState(initialTime.hour);
|
|
5017
|
+
const [minute, setMinute] = useState(initialTime.minute);
|
|
5018
|
+
const [meridiem, setMeridiem] = useState(initialTime.meridiem);
|
|
5019
|
+
useEffect(() => {
|
|
5020
|
+
const { hour, minute, meridiem } = parseTime(value);
|
|
5021
|
+
setHour(hour);
|
|
5022
|
+
setMinute(minute);
|
|
5023
|
+
setMeridiem(meridiem);
|
|
5024
|
+
}, [value]);
|
|
5025
|
+
// Convert hour, minute, meridiem to 24-hour ISO time string
|
|
5026
|
+
const toIsoTime = (hour, minute, meridiem) => {
|
|
5027
|
+
if (hour === null || minute === null || meridiem === null)
|
|
5028
|
+
return null;
|
|
5029
|
+
let h = hour;
|
|
5030
|
+
if (meridiem === "am" && hour === 12)
|
|
5031
|
+
h = 0;
|
|
5032
|
+
else if (meridiem === "pm" && hour < 12)
|
|
5033
|
+
h = hour + 12;
|
|
5034
|
+
return dayjs(`1970-01-01T${h.toString().padStart(2, "0")}:${minute.toString().padStart(2, "0")}:00`)
|
|
5035
|
+
.tz(timezone)
|
|
5036
|
+
.format(timeFormat);
|
|
5037
|
+
};
|
|
5038
|
+
// Handle changes to time parts
|
|
5039
|
+
const handleTimeChange = ({ hour: newHour, minute: newMinute, meridiem: newMeridiem, }) => {
|
|
5040
|
+
setHour(newHour);
|
|
5041
|
+
setMinute(newMinute);
|
|
5042
|
+
setMeridiem(newMeridiem);
|
|
5043
|
+
const isoTime = toIsoTime(newHour, newMinute, newMeridiem);
|
|
5044
|
+
setValue(colLabel, isoTime, { shouldValidate: true, shouldDirty: true });
|
|
5045
|
+
};
|
|
5046
|
+
const containerRef = useRef(null);
|
|
5047
|
+
return (jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
5048
|
+
gridRow, children: [jsxs(Popover.Root, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsx(Popover.Trigger, { asChild: true, children: jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
|
|
5049
|
+
setOpen(true);
|
|
5050
|
+
}, justifyContent: "start", children: [jsx(IoMdClock, {}), !!value ? `${displayedTime}` : ""] }) }), jsx(Portal, { children: jsx(Popover.Positioner, { children: jsx(Popover.Content, { ref: containerRef, children: jsx(Popover.Body, { children: jsx(TimePicker$1, { hour: hour, setHour: setHour, minute: minute, setMinute: setMinute, meridiem: meridiem, setMeridiem: setMeridiem, onChange: handleTimeChange, meridiemLabel: {
|
|
5051
|
+
am: translate.t(`common.am`, { defaultValue: "AM" }),
|
|
5052
|
+
pm: translate.t(`common.pm`, { defaultValue: "PM" }),
|
|
5053
|
+
} }) }) }) }) })] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
5054
|
+
};
|
|
5055
|
+
|
|
5056
|
+
function IsoTimePicker({ hour, setHour, minute, setMinute, second, setSecond, onChange = (_newValue) => { }, }) {
|
|
5057
|
+
// Refs for focus management
|
|
5058
|
+
const hourInputRef = useRef(null);
|
|
5059
|
+
const minuteInputRef = useRef(null);
|
|
5060
|
+
const secondInputRef = useRef(null);
|
|
5061
|
+
// Centralized handler for key events, value changes, and focus management
|
|
5062
|
+
const handleKeyDown = (e, field) => {
|
|
5063
|
+
const input = e.target;
|
|
5064
|
+
const value = input.value;
|
|
5065
|
+
// Handle navigation between fields
|
|
5066
|
+
if (e.key === "Tab") {
|
|
5067
|
+
return;
|
|
5068
|
+
}
|
|
5069
|
+
if (e.key === ":" && field === "hour") {
|
|
5070
|
+
e.preventDefault();
|
|
5071
|
+
minuteInputRef.current?.focus();
|
|
5072
|
+
return;
|
|
5073
|
+
}
|
|
5074
|
+
if (e.key === ":" && field === "minute") {
|
|
5075
|
+
e.preventDefault();
|
|
5076
|
+
secondInputRef.current?.focus();
|
|
5077
|
+
return;
|
|
5078
|
+
}
|
|
5079
|
+
if (e.key === "Backspace" && value === "") {
|
|
5080
|
+
e.preventDefault();
|
|
5081
|
+
if (field === "minute") {
|
|
5082
|
+
hourInputRef.current?.focus();
|
|
5083
|
+
}
|
|
5084
|
+
else if (field === "second") {
|
|
5085
|
+
minuteInputRef.current?.focus();
|
|
5086
|
+
}
|
|
5087
|
+
return;
|
|
5088
|
+
}
|
|
5089
|
+
// Handle number inputs
|
|
5090
|
+
if (field === "hour") {
|
|
5091
|
+
if (e.key.match(/^[0-9]$/)) {
|
|
5092
|
+
const newValue = value + e.key;
|
|
5093
|
+
const numValue = parseInt(newValue, 10);
|
|
5094
|
+
if (numValue > 23) {
|
|
5095
|
+
const digitValue = parseInt(e.key, 10);
|
|
5096
|
+
setHour(digitValue);
|
|
5097
|
+
onChange({ hour: digitValue, minute, second });
|
|
5098
|
+
return;
|
|
5099
|
+
}
|
|
5100
|
+
if (numValue >= 0 && numValue <= 23) {
|
|
5101
|
+
setHour(numValue);
|
|
5102
|
+
onChange({ hour: numValue, minute, second });
|
|
5103
|
+
e.preventDefault();
|
|
5104
|
+
minuteInputRef.current?.focus();
|
|
5105
|
+
}
|
|
5106
|
+
}
|
|
5107
|
+
}
|
|
5108
|
+
else if (field === "minute") {
|
|
5109
|
+
if (e.key.match(/^[0-9]$/)) {
|
|
5110
|
+
const newValue = value + e.key;
|
|
5111
|
+
const numValue = parseInt(newValue, 10);
|
|
5112
|
+
if (numValue > 59) {
|
|
5113
|
+
const digitValue = parseInt(e.key, 10);
|
|
5114
|
+
setMinute(digitValue);
|
|
5115
|
+
onChange({ hour, minute: digitValue, second });
|
|
5116
|
+
return;
|
|
5117
|
+
}
|
|
5118
|
+
if (numValue >= 0 && numValue <= 59) {
|
|
5119
|
+
setMinute(numValue);
|
|
5120
|
+
onChange({ hour, minute: numValue, second });
|
|
5121
|
+
e.preventDefault();
|
|
5122
|
+
secondInputRef.current?.focus();
|
|
5123
|
+
}
|
|
5124
|
+
}
|
|
5125
|
+
}
|
|
5126
|
+
else if (field === "second") {
|
|
5127
|
+
if (e.key.match(/^[0-9]$/)) {
|
|
5128
|
+
const newValue = value + e.key;
|
|
5129
|
+
const numValue = parseInt(newValue, 10);
|
|
5130
|
+
if (numValue > 59) {
|
|
5131
|
+
const digitValue = parseInt(e.key, 10);
|
|
5132
|
+
setSecond(digitValue);
|
|
5133
|
+
onChange({ hour, minute, second: digitValue });
|
|
5134
|
+
return;
|
|
5135
|
+
}
|
|
5136
|
+
if (numValue >= 0 && numValue <= 59) {
|
|
5137
|
+
setSecond(numValue);
|
|
5138
|
+
onChange({ hour, minute, second: numValue });
|
|
5139
|
+
}
|
|
5140
|
+
}
|
|
5141
|
+
}
|
|
5142
|
+
};
|
|
5143
|
+
const handleClear = () => {
|
|
5144
|
+
setHour(null);
|
|
5145
|
+
setMinute(null);
|
|
5146
|
+
setSecond(null);
|
|
5147
|
+
onChange({ hour: null, minute: null, second: null });
|
|
5148
|
+
hourInputRef.current?.focus();
|
|
5149
|
+
};
|
|
5150
|
+
return (jsx(Flex, { direction: "column", gap: 3, children: jsxs(Grid, { justifyContent: "center", alignItems: "center", templateColumns: "60px 10px 60px 10px 60px auto", gap: "2", width: "auto", minWidth: "300px", children: [jsx(Input, { ref: hourInputRef, type: "text", value: hour === null ? "" : hour.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "hour"), placeholder: "HH", maxLength: 2, textAlign: "center" }), jsx(Text, { children: ":" }), jsx(Input, { ref: minuteInputRef, type: "text", value: minute === null ? "" : minute.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "minute"), placeholder: "MM", maxLength: 2, textAlign: "center" }), jsx(Text, { children: ":" }), jsx(Input, { ref: secondInputRef, type: "text", value: second === null ? "" : second.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "second"), placeholder: "SS", maxLength: 2, textAlign: "center" }), jsx(Button$1, { onClick: handleClear, size: "sm", variant: "ghost", children: jsx(MdCancel, {}) })] }) }));
|
|
5151
|
+
}
|
|
5152
|
+
|
|
5153
|
+
function DateTimePicker$1({ value, onChange, format = "date-time", showSeconds = false, labels = {
|
|
5154
|
+
monthNamesShort: [
|
|
5155
|
+
"Jan",
|
|
5156
|
+
"Feb",
|
|
5157
|
+
"Mar",
|
|
5158
|
+
"Apr",
|
|
5159
|
+
"May",
|
|
5160
|
+
"Jun",
|
|
5161
|
+
"Jul",
|
|
5162
|
+
"Aug",
|
|
5163
|
+
"Sep",
|
|
5164
|
+
"Oct",
|
|
5165
|
+
"Nov",
|
|
5166
|
+
"Dec",
|
|
5167
|
+
],
|
|
5168
|
+
weekdayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
|
|
5169
|
+
backButtonLabel: "Back",
|
|
5170
|
+
forwardButtonLabel: "Next",
|
|
5171
|
+
}, timezone = "Asia/Hong_Kong", }) {
|
|
5172
|
+
const [selectedDate, setSelectedDate] = useState(value || "");
|
|
5173
|
+
// Time state for 12-hour format
|
|
5174
|
+
const [hour12, setHour12] = useState(value ? dayjs(value).hour() % 12 || 12 : null);
|
|
5175
|
+
const [minute, setMinute] = useState(value ? dayjs(value).minute() : null);
|
|
5176
|
+
const [meridiem, setMeridiem] = useState(value ? (dayjs(value).hour() >= 12 ? "pm" : "am") : null);
|
|
5177
|
+
// Time state for 24-hour format
|
|
5178
|
+
const [hour24, setHour24] = useState(value ? dayjs(value).hour() : null);
|
|
5179
|
+
const [second, setSecond] = useState(value ? dayjs(value).second() : null);
|
|
5180
|
+
const handleDateChange = (date) => {
|
|
5181
|
+
setSelectedDate(date);
|
|
5182
|
+
updateDateTime(dayjs(date).tz(timezone).toISOString());
|
|
5183
|
+
};
|
|
5184
|
+
const handleTimeChange = (timeData) => {
|
|
5185
|
+
if (format === "iso-date-time") {
|
|
5186
|
+
setHour24(timeData.hour);
|
|
5187
|
+
setMinute(timeData.minute);
|
|
5188
|
+
if (showSeconds)
|
|
5189
|
+
setSecond(timeData.second);
|
|
5190
|
+
}
|
|
5191
|
+
else {
|
|
5192
|
+
setHour12(timeData.hour);
|
|
5193
|
+
setMinute(timeData.minute);
|
|
5194
|
+
setMeridiem(timeData.meridiem);
|
|
5195
|
+
}
|
|
5196
|
+
updateDateTime(dayjs(selectedDate).tz(timezone).toISOString(), timeData);
|
|
5197
|
+
};
|
|
5198
|
+
const updateDateTime = (date, timeData) => {
|
|
5199
|
+
if (!date) {
|
|
5200
|
+
onChange?.(undefined);
|
|
5201
|
+
return;
|
|
5202
|
+
}
|
|
5203
|
+
// use dayjs to convert the date to the timezone
|
|
5204
|
+
const newDate = dayjs(date).tz(timezone).toDate();
|
|
5205
|
+
if (format === "iso-date-time") {
|
|
5206
|
+
const h = timeData?.hour ?? hour24;
|
|
5207
|
+
const m = timeData?.minute ?? minute;
|
|
5208
|
+
const s = showSeconds ? timeData?.second ?? second : 0;
|
|
5209
|
+
if (h !== null)
|
|
5210
|
+
newDate.setHours(h);
|
|
5211
|
+
if (m !== null)
|
|
5212
|
+
newDate.setMinutes(m);
|
|
5213
|
+
if (s !== null)
|
|
5214
|
+
newDate.setSeconds(s);
|
|
5215
|
+
}
|
|
5216
|
+
else {
|
|
5217
|
+
const h = timeData?.hour ?? hour12;
|
|
5218
|
+
const m = timeData?.minute ?? minute;
|
|
5219
|
+
const mer = timeData?.meridiem ?? meridiem;
|
|
5220
|
+
if (h !== null && mer !== null) {
|
|
5221
|
+
let hour24 = h;
|
|
5222
|
+
if (mer === "am" && h === 12)
|
|
5223
|
+
hour24 = 0;
|
|
5224
|
+
else if (mer === "pm" && h < 12)
|
|
5225
|
+
hour24 = h + 12;
|
|
5226
|
+
newDate.setHours(hour24);
|
|
5227
|
+
}
|
|
5228
|
+
if (m !== null)
|
|
5229
|
+
newDate.setMinutes(m);
|
|
5230
|
+
newDate.setSeconds(0);
|
|
5231
|
+
}
|
|
5232
|
+
onChange?.(dayjs(newDate).tz(timezone).toISOString());
|
|
5233
|
+
};
|
|
5234
|
+
const handleClear = () => {
|
|
5235
|
+
setSelectedDate("");
|
|
5236
|
+
setHour12(null);
|
|
5237
|
+
setHour24(null);
|
|
5238
|
+
setMinute(null);
|
|
5239
|
+
setSecond(null);
|
|
5240
|
+
setMeridiem(null);
|
|
5241
|
+
onChange?.(undefined);
|
|
5242
|
+
};
|
|
5243
|
+
const isISO = format === "iso-date-time";
|
|
5244
|
+
return (jsxs(Flex, { direction: "column", gap: 4, p: 4, border: "1px solid", borderColor: "gray.200", borderRadius: "md", children: [jsx(DatePicker$1, { selected: selectedDate
|
|
5245
|
+
? dayjs(selectedDate).tz(timezone).toDate()
|
|
5246
|
+
: new Date(), onDateSelected: ({ date }) => handleDateChange(dayjs(date).tz(timezone).toISOString()), monthsToDisplay: 1, labels: labels }), jsxs(Grid, { templateColumns: "1fr auto", alignItems: "center", gap: 4, children: [isISO ? (jsx(IsoTimePicker, { hour: hour24, setHour: setHour24, minute: minute, setMinute: setMinute, second: second, setSecond: setSecond, onChange: handleTimeChange })) : (jsx(TimePicker$1, { hour: hour12, setHour: setHour12, minute: minute, setMinute: setMinute, meridiem: meridiem, setMeridiem: setMeridiem, onChange: handleTimeChange })), jsx(Button$1, { onClick: handleClear, size: "sm", variant: "outline", colorScheme: "red", children: jsx(Icon, { as: FaTrash }) })] }), selectedDate && (jsxs(Flex, { gap: 2, children: [jsx(Text, { fontSize: "sm", color: { base: "gray.600", _dark: "gray.600" }, children: dayjs(value).format(isISO
|
|
5247
|
+
? showSeconds
|
|
5248
|
+
? "YYYY-MM-DD HH:mm:ss"
|
|
5249
|
+
: "YYYY-MM-DD HH:mm"
|
|
5250
|
+
: "YYYY-MM-DD hh:mm A ") }), jsx(Text, { fontSize: "sm", color: { base: "gray.600", _dark: "gray.600" }, children: dayjs(value).tz(timezone).format("Z") }), jsx(Text, { fontSize: "sm", color: { base: "gray.600", _dark: "gray.600" }, children: timezone })] }))] }));
|
|
5251
|
+
}
|
|
5252
|
+
|
|
5253
|
+
dayjs.extend(utc);
|
|
5254
|
+
dayjs.extend(timezone);
|
|
5255
|
+
const DateTimePicker = ({ column, schema, prefix, }) => {
|
|
5256
|
+
const { watch, formState: { errors }, setValue, } = useFormContext();
|
|
5257
|
+
const { translate, timezone } = useSchemaContext();
|
|
5258
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD HH:mm:ss",
|
|
5259
|
+
// with timezone
|
|
5260
|
+
dateFormat = "YYYY-MM-DD[T]HH:mm:ssZ", } = schema;
|
|
5261
|
+
const isRequired = required?.some((columnId) => columnId === column);
|
|
5262
|
+
const colLabel = `${prefix}${column}`;
|
|
5263
|
+
const [open, setOpen] = useState(false);
|
|
5264
|
+
const selectedDate = watch(colLabel);
|
|
5265
|
+
const displayDate = dayjs(selectedDate)
|
|
5266
|
+
.tz(timezone)
|
|
5267
|
+
.format(displayDateFormat);
|
|
5268
|
+
useEffect(() => {
|
|
5269
|
+
try {
|
|
5270
|
+
if (selectedDate) {
|
|
5271
|
+
// Parse the selectedDate as UTC or in a specific timezone to avoid +8 hour shift
|
|
5272
|
+
// For example, parse as UTC:
|
|
5273
|
+
const parsedDate = dayjs(selectedDate).tz(timezone);
|
|
5274
|
+
if (!parsedDate.isValid())
|
|
5275
|
+
return;
|
|
5276
|
+
// Format according to dateFormat from schema
|
|
5277
|
+
const formatted = parsedDate.format(dateFormat);
|
|
5278
|
+
// Update the form value only if different to avoid loops
|
|
5279
|
+
if (formatted !== selectedDate) {
|
|
5280
|
+
setValue(colLabel, formatted, {
|
|
5281
|
+
shouldValidate: true,
|
|
5282
|
+
shouldDirty: true,
|
|
5283
|
+
});
|
|
5284
|
+
}
|
|
5285
|
+
}
|
|
5286
|
+
}
|
|
5287
|
+
catch (e) {
|
|
5288
|
+
console.error(e);
|
|
5289
|
+
}
|
|
5290
|
+
}, [selectedDate, dateFormat, colLabel, setValue]);
|
|
5291
|
+
const customTranslate = (label) => {
|
|
5292
|
+
return translateWrapper({ prefix, column, label, translate });
|
|
5293
|
+
};
|
|
5294
|
+
return (jsxs(Field, { label: `${customTranslate(`field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
5295
|
+
gridRow, children: [jsxs(PopoverRoot, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsx(PopoverTrigger, { asChild: true, children: jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
|
|
5296
|
+
setOpen(true);
|
|
5297
|
+
}, justifyContent: "start", children: [jsx(MdDateRange, {}), selectedDate !== undefined ? `${displayDate}` : ""] }) }), jsx(PopoverContent, { minW: "450px", children: jsxs(PopoverBody, { children: [jsx(PopoverTitle, {}), jsx(DateTimePicker$1, { value: selectedDate, onChange: (date) => {
|
|
5298
|
+
setValue(colLabel, dayjs(date).tz(timezone).format(dateFormat));
|
|
5299
|
+
}, timezone: timezone, labels: {
|
|
5300
|
+
monthNamesShort: [
|
|
5301
|
+
translate.t(`common.month_1`, { defaultValue: "January" }),
|
|
5302
|
+
translate.t(`common.month_2`, { defaultValue: "February" }),
|
|
5303
|
+
translate.t(`common.month_3`, { defaultValue: "March" }),
|
|
5304
|
+
translate.t(`common.month_4`, { defaultValue: "April" }),
|
|
5305
|
+
translate.t(`common.month_5`, { defaultValue: "May" }),
|
|
5306
|
+
translate.t(`common.month_6`, { defaultValue: "June" }),
|
|
5307
|
+
translate.t(`common.month_7`, { defaultValue: "July" }),
|
|
5308
|
+
translate.t(`common.month_8`, { defaultValue: "August" }),
|
|
5309
|
+
translate.t(`common.month_9`, { defaultValue: "September" }),
|
|
5310
|
+
translate.t(`common.month_10`, { defaultValue: "October" }),
|
|
5311
|
+
translate.t(`common.month_11`, { defaultValue: "November" }),
|
|
5312
|
+
translate.t(`common.month_12`, { defaultValue: "December" }),
|
|
5313
|
+
],
|
|
5314
|
+
weekdayNamesShort: [
|
|
5315
|
+
translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
|
|
5316
|
+
translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
|
|
5317
|
+
translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
|
|
5318
|
+
translate.t(`common.weekday_4`, {
|
|
5319
|
+
defaultValue: "Wed",
|
|
5320
|
+
}),
|
|
5321
|
+
translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
|
|
5322
|
+
translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
|
|
5323
|
+
translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
|
|
5324
|
+
],
|
|
5325
|
+
backButtonLabel: translate.t(`common.back_button`, {
|
|
5326
|
+
defaultValue: "Back",
|
|
5327
|
+
}),
|
|
5328
|
+
forwardButtonLabel: translate.t(`common.forward_button`, {
|
|
5329
|
+
defaultValue: "Forward",
|
|
5330
|
+
}),
|
|
5331
|
+
} })] }) })] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: customTranslate(`field_required`) }))] }));
|
|
5332
|
+
};
|
|
5333
|
+
|
|
4507
5334
|
const SchemaRenderer = ({ schema, prefix, column, }) => {
|
|
4508
5335
|
const colSchema = schema;
|
|
4509
|
-
const { type, variant, properties: innerProperties, foreign_key, items, } = schema;
|
|
5336
|
+
const { type, variant, properties: innerProperties, foreign_key, format, items, } = schema;
|
|
5337
|
+
if (variant === "custom-input") {
|
|
5338
|
+
return jsx(CustomInput, { schema: colSchema, prefix, column });
|
|
5339
|
+
}
|
|
4510
5340
|
if (type === "string") {
|
|
4511
5341
|
if ((schema.enum ?? []).length > 0) {
|
|
4512
5342
|
return jsx(EnumPicker, { schema: colSchema, prefix, column });
|
|
@@ -4515,9 +5345,18 @@ const SchemaRenderer = ({ schema, prefix, column, }) => {
|
|
|
4515
5345
|
idPickerSanityCheck(column, foreign_key);
|
|
4516
5346
|
return jsx(IdPicker, { schema: colSchema, prefix, column });
|
|
4517
5347
|
}
|
|
4518
|
-
if (
|
|
5348
|
+
if (format === "date") {
|
|
4519
5349
|
return jsx(DatePicker, { schema: colSchema, prefix, column });
|
|
4520
5350
|
}
|
|
5351
|
+
if (format === "time") {
|
|
5352
|
+
return jsx(TimePicker, { schema: colSchema, prefix, column });
|
|
5353
|
+
}
|
|
5354
|
+
if (format === "date-time") {
|
|
5355
|
+
return jsx(DateTimePicker, { schema: colSchema, prefix, column });
|
|
5356
|
+
}
|
|
5357
|
+
if (variant === "text-area") {
|
|
5358
|
+
return jsx(TextAreaInput, { schema: colSchema, prefix, column });
|
|
5359
|
+
}
|
|
4521
5360
|
return jsx(StringInputField, { schema: colSchema, prefix, column });
|
|
4522
5361
|
}
|
|
4523
5362
|
if (type === "number" || type === "integer") {
|
|
@@ -4564,39 +5403,56 @@ const ColumnRenderer = ({ column, properties, prefix, }) => {
|
|
|
4564
5403
|
};
|
|
4565
5404
|
|
|
4566
5405
|
const ArrayViewer = ({ schema, column, prefix }) => {
|
|
4567
|
-
const {
|
|
5406
|
+
const { gridColumn = "span 12", gridRow = "span 1", required, items, } = schema;
|
|
4568
5407
|
const { translate } = useSchemaContext();
|
|
4569
5408
|
const colLabel = `${prefix}${column}`;
|
|
4570
5409
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4571
5410
|
const { watch, formState: { errors }, } = useFormContext();
|
|
4572
5411
|
const values = watch(colLabel) ?? [];
|
|
4573
|
-
return (jsxs(Box, { gridRow, gridColumn, children: [jsxs(Box, { as: "label", gridColumn: "1/span12", children: [`${translate.t(removeIndex(`${colLabel}.
|
|
4574
|
-
|
|
4575
|
-
|
|
5412
|
+
return (jsxs(Box, { gridRow, gridColumn, children: [jsxs(Box, { as: "label", gridColumn: "1/span12", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsx("span", { children: "*" })] }), jsx(Flex, { flexFlow: "column", gap: 1, children: values.map((field, index) => (jsx(Flex, { flexFlow: "column", bgColor: { base: "colorPalette.100", _dark: "colorPalette.900" }, p: "2", borderRadius: "md", borderWidth: "thin", borderColor: {
|
|
5413
|
+
base: "colorPalette.200",
|
|
5414
|
+
_dark: "colorPalette.800",
|
|
5415
|
+
}, children: jsx(Grid, { gap: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: jsx(SchemaViewer, { column: `${index}`,
|
|
5416
|
+
prefix: `${colLabel}.`,
|
|
5417
|
+
// @ts-expect-error find suitable types
|
|
5418
|
+
schema: { showLabel: false, ...(items ?? {}) } }) }) }, `form-${prefix}${column}.${index}`))) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4576
5419
|
};
|
|
4577
5420
|
|
|
4578
5421
|
const BooleanViewer = ({ schema, column, prefix, }) => {
|
|
4579
5422
|
const { watch, formState: { errors }, } = useFormContext();
|
|
4580
5423
|
const { translate } = useSchemaContext();
|
|
4581
|
-
const { required, gridColumn, gridRow } = schema;
|
|
5424
|
+
const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
|
|
4582
5425
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4583
5426
|
const colLabel = `${prefix}${column}`;
|
|
4584
5427
|
const value = watch(colLabel);
|
|
4585
|
-
return (jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.
|
|
5428
|
+
return (jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
4586
5429
|
gridRow, children: [jsx(Text, { children: value
|
|
4587
5430
|
? translate.t(removeIndex(`${colLabel}.true`))
|
|
4588
|
-
: translate.t(removeIndex(`${colLabel}.false`)) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.
|
|
5431
|
+
: translate.t(removeIndex(`${colLabel}.false`)) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
5432
|
+
};
|
|
5433
|
+
|
|
5434
|
+
const CustomViewer = ({ column, schema, prefix }) => {
|
|
5435
|
+
const formContext = useFormContext();
|
|
5436
|
+
const { inputViewerRender } = schema;
|
|
5437
|
+
return (inputViewerRender &&
|
|
5438
|
+
inputViewerRender({
|
|
5439
|
+
column,
|
|
5440
|
+
schema,
|
|
5441
|
+
prefix,
|
|
5442
|
+
formContext,
|
|
5443
|
+
}));
|
|
4589
5444
|
};
|
|
4590
5445
|
|
|
4591
5446
|
const DateViewer = ({ column, schema, prefix }) => {
|
|
4592
5447
|
const { watch, formState: { errors }, } = useFormContext();
|
|
4593
|
-
const { translate } = useSchemaContext();
|
|
4594
|
-
const { required, gridColumn, gridRow } = schema;
|
|
5448
|
+
const { translate, timezone } = useSchemaContext();
|
|
5449
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD", } = schema;
|
|
4595
5450
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4596
5451
|
const colLabel = `${prefix}${column}`;
|
|
4597
5452
|
const selectedDate = watch(colLabel);
|
|
4598
|
-
|
|
4599
|
-
|
|
5453
|
+
const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
|
|
5454
|
+
return (jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
5455
|
+
gridRow, children: [jsxs(Text, { children: [" ", selectedDate !== undefined ? displayDate : ""] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
|
|
4600
5456
|
};
|
|
4601
5457
|
|
|
4602
5458
|
const EnumViewer = ({ column, isMultiple = false, schema, prefix, }) => {
|
|
@@ -4604,45 +5460,41 @@ const EnumViewer = ({ column, isMultiple = false, schema, prefix, }) => {
|
|
|
4604
5460
|
const { translate } = useSchemaContext();
|
|
4605
5461
|
const { required } = schema;
|
|
4606
5462
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4607
|
-
const { gridColumn, gridRow, renderDisplay } = schema;
|
|
5463
|
+
const { gridColumn = "span 4", gridRow = "span 1", renderDisplay } = schema;
|
|
4608
5464
|
const colLabel = `${prefix}${column}`;
|
|
4609
5465
|
const watchEnum = watch(colLabel);
|
|
4610
5466
|
const watchEnums = (watch(colLabel) ?? []);
|
|
4611
|
-
|
|
5467
|
+
const customTranslate = (label) => {
|
|
5468
|
+
return translateWrapper({ prefix, column, label, translate });
|
|
5469
|
+
};
|
|
5470
|
+
return (jsxs(Field, { label: `${customTranslate(`field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
4612
5471
|
gridRow, children: [isMultiple && (jsx(Flex, { flexFlow: "wrap", gap: 1, children: watchEnums.map((enumValue) => {
|
|
4613
5472
|
const item = enumValue;
|
|
4614
5473
|
if (item === undefined) {
|
|
4615
5474
|
return jsx(Fragment, { children: "undefined" });
|
|
4616
5475
|
}
|
|
4617
|
-
return (jsx(Tag, {
|
|
5476
|
+
return (jsx(Tag, { children: !!renderDisplay === true
|
|
4618
5477
|
? renderDisplay(item)
|
|
4619
|
-
:
|
|
4620
|
-
}) })), !isMultiple &&
|
|
5478
|
+
: customTranslate(item) }));
|
|
5479
|
+
}) })), !isMultiple && jsx(Text, { children: customTranslate(watchEnum) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: customTranslate(`field_required`) }))] }));
|
|
4621
5480
|
};
|
|
4622
5481
|
|
|
4623
5482
|
const FileViewer = ({ column, schema, prefix }) => {
|
|
4624
|
-
const {
|
|
5483
|
+
const { watch } = useFormContext();
|
|
4625
5484
|
const { translate } = useSchemaContext();
|
|
4626
|
-
const { required, gridColumn, gridRow } = schema;
|
|
5485
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", } = schema;
|
|
4627
5486
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4628
5487
|
const currentFiles = (watch(column) ?? []);
|
|
4629
5488
|
const colLabel = `${prefix}${column}`;
|
|
4630
|
-
return (
|
|
4631
|
-
|
|
4632
|
-
|
|
4633
|
-
}, placeholder: translate.t(`${colLabel}.fileDropzone`) }), jsx(Flex, { flexFlow: "column", gap: 1, children: currentFiles.map((file) => {
|
|
4634
|
-
return (jsx(Card.Root, { variant: "subtle", children: jsxs(Card.Body, { gap: "2", cursor: "pointer", onClick: () => {
|
|
4635
|
-
setValue(column, currentFiles.filter(({ name }) => {
|
|
4636
|
-
return name !== file.name;
|
|
4637
|
-
}));
|
|
4638
|
-
}, display: "flex", flexFlow: "row", alignItems: "center", padding: "2", children: [jsx(Box, { children: file.name }), jsx(TiDeleteOutline, {})] }) }, file.name));
|
|
4639
|
-
}) }), errors[`${colLabel}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.fieldRequired`)) }))] }));
|
|
5489
|
+
return (jsx(Field, { label: `${translate.t(`${colLabel}.field_label`)}`, required: isRequired, gridColumn: gridColumn, gridRow: gridRow, display: "grid", gridTemplateRows: "auto 1fr auto", alignItems: "stretch", children: jsx(Flex, { flexFlow: "column", gap: 1, children: currentFiles.map((file) => {
|
|
5490
|
+
return (jsx(Card.Root, { variant: "subtle", children: jsxs(Card.Body, { gap: "2", display: "flex", flexFlow: "row", alignItems: "center", padding: "2", children: [file.type.startsWith("image/") && (jsx(Image, { src: URL.createObjectURL(file), alt: file.name, boxSize: "50px", objectFit: "cover", borderRadius: "md", marginRight: "2" })), jsx(Box, { children: file.name })] }) }, file.name));
|
|
5491
|
+
}) }) }));
|
|
4640
5492
|
};
|
|
4641
5493
|
|
|
4642
5494
|
const IdViewer = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
4643
5495
|
const { watch, formState: { errors }, } = useFormContext();
|
|
4644
5496
|
const { idMap, translate } = useSchemaContext();
|
|
4645
|
-
const { required, gridColumn, gridRow, renderDisplay, foreign_key } = schema;
|
|
5497
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", renderDisplay, foreign_key, } = schema;
|
|
4646
5498
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4647
5499
|
const { display_column } = foreign_key;
|
|
4648
5500
|
const colLabel = `${prefix}${column}`;
|
|
@@ -4658,7 +5510,7 @@ const IdViewer = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4658
5510
|
}
|
|
4659
5511
|
return record[display_column];
|
|
4660
5512
|
};
|
|
4661
|
-
return (jsxs(Field, { label: `${translate.t(removeIndex(`${column}.
|
|
5513
|
+
return (jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
4662
5514
|
gridRow, children: [isMultiple && (jsx(Flex, { flexFlow: "wrap", gap: 1, children: watchIds.map((id) => {
|
|
4663
5515
|
const item = idMap[id];
|
|
4664
5516
|
if (item === undefined) {
|
|
@@ -4667,21 +5519,21 @@ const IdViewer = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4667
5519
|
return (jsx(Tag, { closable: true, children: !!renderDisplay === true
|
|
4668
5520
|
? renderDisplay(item)
|
|
4669
5521
|
: item[display_column] }, id));
|
|
4670
|
-
}) })), !isMultiple && jsx(Text, { children: getPickedValue() }), errors[`${colLabel}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.
|
|
5522
|
+
}) })), !isMultiple && jsx(Text, { children: getPickedValue() }), errors[`${colLabel}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4671
5523
|
};
|
|
4672
5524
|
|
|
4673
5525
|
const NumberViewer = ({ schema, column, prefix, }) => {
|
|
4674
5526
|
const { watch, formState: { errors }, } = useFormContext();
|
|
4675
5527
|
const { translate } = useSchemaContext();
|
|
4676
|
-
const { required, gridColumn, gridRow } = schema;
|
|
5528
|
+
const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
|
|
4677
5529
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4678
5530
|
const colLabel = `${prefix}${column}`;
|
|
4679
5531
|
const value = watch(colLabel);
|
|
4680
|
-
return (jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.
|
|
5532
|
+
return (jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn, gridRow, children: [jsx(Text, { children: value }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4681
5533
|
};
|
|
4682
5534
|
|
|
4683
5535
|
const ObjectViewer = ({ schema, column, prefix }) => {
|
|
4684
|
-
const { properties,
|
|
5536
|
+
const { properties, gridColumn = "span 12", gridRow = "span 1", required, showLabel = true, } = schema;
|
|
4685
5537
|
const { translate } = useSchemaContext();
|
|
4686
5538
|
const colLabel = `${prefix}${column}`;
|
|
4687
5539
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
@@ -4689,25 +5541,28 @@ const ObjectViewer = ({ schema, column, prefix }) => {
|
|
|
4689
5541
|
if (properties === undefined) {
|
|
4690
5542
|
throw new Error(`properties is undefined when using ObjectInput`);
|
|
4691
5543
|
}
|
|
4692
|
-
return (jsxs(Box, { gridRow, gridColumn, children: [jsxs(Box, { as: "label",
|
|
5544
|
+
return (jsxs(Box, { gridRow, gridColumn, children: [showLabel && (jsxs(Box, { as: "label", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsx("span", { children: "*" })] })), jsx(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: {
|
|
5545
|
+
base: "colorPalette.200",
|
|
5546
|
+
_dark: "colorPalette.800",
|
|
5547
|
+
}, children: Object.keys(properties ?? {}).map((key) => {
|
|
4693
5548
|
return (
|
|
4694
5549
|
// @ts-expect-error find suitable types
|
|
4695
5550
|
jsx(ColumnViewer, { column: `${key}`,
|
|
4696
5551
|
prefix: `${prefix}${column}.`,
|
|
4697
5552
|
properties }, `form-objectviewer-${colLabel}-${key}`));
|
|
4698
|
-
}) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.
|
|
5553
|
+
}) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4699
5554
|
};
|
|
4700
5555
|
|
|
4701
5556
|
const RecordInput = ({ column, schema, prefix }) => {
|
|
4702
5557
|
const { formState: { errors }, setValue, getValues, } = useFormContext();
|
|
4703
5558
|
const { translate } = useSchemaContext();
|
|
4704
|
-
const { required, gridColumn, gridRow } = schema;
|
|
5559
|
+
const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
|
|
4705
5560
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4706
5561
|
const entries = Object.entries(getValues(column) ?? {});
|
|
4707
5562
|
const [showNewEntries, setShowNewEntries] = useState(false);
|
|
4708
5563
|
const [newKey, setNewKey] = useState();
|
|
4709
5564
|
const [newValue, setNewValue] = useState();
|
|
4710
|
-
return (jsxs(Field, { label: `${translate.t(`${column}.
|
|
5565
|
+
return (jsxs(Field, { label: `${translate.t(`${column}.field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn, gridRow, children: [entries.map(([key, value]) => {
|
|
4711
5566
|
return (jsxs(Grid, { templateColumns: "1fr 1fr auto", gap: 1, children: [jsx(Input, { value: key, onChange: (e) => {
|
|
4712
5567
|
const filtered = entries.filter(([target]) => {
|
|
4713
5568
|
return target !== key;
|
|
@@ -4747,7 +5602,17 @@ const RecordInput = ({ column, schema, prefix }) => {
|
|
|
4747
5602
|
setShowNewEntries(true);
|
|
4748
5603
|
setNewKey(undefined);
|
|
4749
5604
|
setNewValue(undefined);
|
|
4750
|
-
}, children: translate.t(`${column}.addNew`) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(`${column}.
|
|
5605
|
+
}, children: translate.t(`${column}.addNew`) }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
|
|
5606
|
+
};
|
|
5607
|
+
|
|
5608
|
+
const StringViewer = ({ column, schema, prefix, }) => {
|
|
5609
|
+
const { watch, formState: { errors }, } = useFormContext();
|
|
5610
|
+
const { translate } = useSchemaContext();
|
|
5611
|
+
const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
|
|
5612
|
+
const isRequired = required?.some((columnId) => columnId === column);
|
|
5613
|
+
const colLabel = `${prefix}${column}`;
|
|
5614
|
+
const value = watch(colLabel);
|
|
5615
|
+
return (jsx(Fragment, { children: jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn: gridColumn ?? "span 4", gridRow: gridRow ?? "span 1", children: [jsx(Text, { children: value }), errors[colLabel] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }) }));
|
|
4751
5616
|
};
|
|
4752
5617
|
|
|
4753
5618
|
const TagViewer = ({ column, schema, prefix }) => {
|
|
@@ -4835,19 +5700,50 @@ const TagViewer = ({ column, schema, prefix }) => {
|
|
|
4835
5700
|
}), errors[`${column}`] && (jsx(Text, { color: "red.400", children: (errors[`${column}`]?.message ?? "No error message") }))] }));
|
|
4836
5701
|
};
|
|
4837
5702
|
|
|
4838
|
-
const
|
|
5703
|
+
const TextAreaViewer = ({ column, schema, prefix, }) => {
|
|
4839
5704
|
const { watch, formState: { errors }, } = useFormContext();
|
|
4840
5705
|
const { translate } = useSchemaContext();
|
|
4841
|
-
const { required, gridColumn, gridRow } = schema;
|
|
5706
|
+
const { required, gridColumn = "span 4", gridRow = "span 1" } = schema;
|
|
4842
5707
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4843
5708
|
const colLabel = `${prefix}${column}`;
|
|
4844
5709
|
const value = watch(colLabel);
|
|
4845
|
-
return (jsx(Fragment, { children: jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.
|
|
5710
|
+
return (jsx(Fragment, { children: jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn: gridColumn, gridRow: gridRow, children: [jsx(Text, { whiteSpace: "pre-wrap", children: value }), " ", errors[colLabel] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }) }));
|
|
5711
|
+
};
|
|
5712
|
+
|
|
5713
|
+
const TimeViewer = ({ column, schema, prefix }) => {
|
|
5714
|
+
const { watch, formState: { errors }, } = useFormContext();
|
|
5715
|
+
const { translate, timezone } = useSchemaContext();
|
|
5716
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", displayTimeFormat = "hh:mm A", } = schema;
|
|
5717
|
+
const isRequired = required?.some((columnId) => columnId === column);
|
|
5718
|
+
const colLabel = `${prefix}${column}`;
|
|
5719
|
+
const selectedDate = watch(colLabel);
|
|
5720
|
+
const displayedTime = dayjs(`1970-01-01T${selectedDate}`)
|
|
5721
|
+
.tz(timezone)
|
|
5722
|
+
.isValid()
|
|
5723
|
+
? dayjs(`1970-01-01T${selectedDate}`).tz(timezone).format(displayTimeFormat)
|
|
5724
|
+
: "";
|
|
5725
|
+
return (jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
5726
|
+
gridRow, children: [jsx(Text, { children: displayedTime }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
|
|
5727
|
+
};
|
|
5728
|
+
|
|
5729
|
+
const DateTimeViewer = ({ column, schema, prefix }) => {
|
|
5730
|
+
const { watch, formState: { errors }, } = useFormContext();
|
|
5731
|
+
const { translate, timezone } = useSchemaContext();
|
|
5732
|
+
const { required, gridColumn = "span 4", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD HH:mm:ss", } = schema;
|
|
5733
|
+
const isRequired = required?.some((columnId) => columnId === column);
|
|
5734
|
+
const colLabel = `${prefix}${column}`;
|
|
5735
|
+
const selectedDate = watch(colLabel);
|
|
5736
|
+
const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
|
|
5737
|
+
return (jsxs(Field, { label: `${translate.t(removeIndex(`${column}.field_label`))}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
5738
|
+
gridRow, children: [jsxs(Text, { children: [" ", selectedDate !== undefined ? displayDate : ""] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(`${column}.field_required`) }))] }));
|
|
4846
5739
|
};
|
|
4847
5740
|
|
|
4848
5741
|
const SchemaViewer = ({ schema, prefix, column, }) => {
|
|
4849
5742
|
const colSchema = schema;
|
|
4850
|
-
const { type, variant, properties: innerProperties, foreign_key, items, } = schema;
|
|
5743
|
+
const { type, variant, properties: innerProperties, foreign_key, items, format, } = schema;
|
|
5744
|
+
if (variant === "custom-input") {
|
|
5745
|
+
return jsx(CustomViewer, { schema: colSchema, prefix, column });
|
|
5746
|
+
}
|
|
4851
5747
|
if (type === "string") {
|
|
4852
5748
|
if ((schema.enum ?? []).length > 0) {
|
|
4853
5749
|
return jsx(EnumViewer, { schema: colSchema, prefix, column });
|
|
@@ -4856,9 +5752,18 @@ const SchemaViewer = ({ schema, prefix, column, }) => {
|
|
|
4856
5752
|
idPickerSanityCheck(column, foreign_key);
|
|
4857
5753
|
return jsx(IdViewer, { schema: colSchema, prefix, column });
|
|
4858
5754
|
}
|
|
4859
|
-
if (
|
|
5755
|
+
if (format === "time") {
|
|
5756
|
+
return jsx(TimeViewer, { schema: colSchema, prefix, column });
|
|
5757
|
+
}
|
|
5758
|
+
if (format === "date") {
|
|
4860
5759
|
return jsx(DateViewer, { schema: colSchema, prefix, column });
|
|
4861
5760
|
}
|
|
5761
|
+
if (format === "date-time") {
|
|
5762
|
+
return jsx(DateTimeViewer, { schema: colSchema, prefix, column });
|
|
5763
|
+
}
|
|
5764
|
+
if (variant === "text-area") {
|
|
5765
|
+
return jsx(TextAreaViewer, { schema: colSchema, prefix, column });
|
|
5766
|
+
}
|
|
4862
5767
|
return jsx(StringViewer, { schema: colSchema, prefix, column });
|
|
4863
5768
|
}
|
|
4864
5769
|
if (type === "number" || type === "integer") {
|
|
@@ -4907,10 +5812,24 @@ const ColumnViewer = ({ column, properties, prefix, }) => {
|
|
|
4907
5812
|
};
|
|
4908
5813
|
|
|
4909
5814
|
const SubmitButton = () => {
|
|
4910
|
-
const { translate, setValidatedData, setIsError, setIsConfirming } = useSchemaContext();
|
|
5815
|
+
const { translate, setValidatedData, setIsError, setIsConfirming, setError, schema, } = useSchemaContext();
|
|
4911
5816
|
const methods = useFormContext();
|
|
4912
5817
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4913
5818
|
const onValid = (data) => {
|
|
5819
|
+
// Validate data using AJV before proceeding to confirmation
|
|
5820
|
+
const validate = new Ajv({
|
|
5821
|
+
strict: false,
|
|
5822
|
+
allErrors: true,
|
|
5823
|
+
}).compile(schema);
|
|
5824
|
+
const validationResult = validate(data);
|
|
5825
|
+
// @ts-expect-error TODO: find appropriate type
|
|
5826
|
+
const errors = validationResult.errors;
|
|
5827
|
+
if (errors && errors.length > 0) {
|
|
5828
|
+
setError(errors);
|
|
5829
|
+
setIsError(true);
|
|
5830
|
+
return;
|
|
5831
|
+
}
|
|
5832
|
+
// If validation passes, proceed to confirmation
|
|
4914
5833
|
setValidatedData(data);
|
|
4915
5834
|
setIsError(false);
|
|
4916
5835
|
setIsConfirming(true);
|
|
@@ -4921,7 +5840,7 @@ const SubmitButton = () => {
|
|
|
4921
5840
|
};
|
|
4922
5841
|
|
|
4923
5842
|
const FormBody = () => {
|
|
4924
|
-
const { schema, requestUrl, order, ignore, include, onSubmit, rowNumber, translate, requestOptions, isSuccess, setIsSuccess, isError, setIsError, isSubmiting, setIsSubmiting, isConfirming, setIsConfirming, validatedData, setValidatedData, error, setError, getUpdatedData, } = useSchemaContext();
|
|
5843
|
+
const { schema, requestUrl, order, ignore, include, onSubmit, rowNumber, translate, requestOptions, isSuccess, setIsSuccess, isError, setIsError, isSubmiting, setIsSubmiting, isConfirming, setIsConfirming, validatedData, setValidatedData, error, setError, getUpdatedData, customErrorRenderer, } = useSchemaContext();
|
|
4925
5844
|
const methods = useFormContext();
|
|
4926
5845
|
const { properties } = schema;
|
|
4927
5846
|
const onBeforeSubmit = () => {
|
|
@@ -4937,6 +5856,39 @@ const FormBody = () => {
|
|
|
4937
5856
|
const onSubmitSuccess = () => {
|
|
4938
5857
|
setIsSuccess(true);
|
|
4939
5858
|
};
|
|
5859
|
+
// Enhanced validation function using AJV with i18n support
|
|
5860
|
+
const validateFormData = (data) => {
|
|
5861
|
+
try {
|
|
5862
|
+
const ajv = new Ajv({
|
|
5863
|
+
strict: false,
|
|
5864
|
+
allErrors: true,
|
|
5865
|
+
});
|
|
5866
|
+
addFormats(ajv);
|
|
5867
|
+
addErrors(ajv);
|
|
5868
|
+
const validate = ajv.compile(schema);
|
|
5869
|
+
const validationResult = validate(data);
|
|
5870
|
+
const errors = validate.errors;
|
|
5871
|
+
console.log({
|
|
5872
|
+
isValid: validationResult,
|
|
5873
|
+
errors,
|
|
5874
|
+
}, "plkdfs");
|
|
5875
|
+
return {
|
|
5876
|
+
isValid: validationResult,
|
|
5877
|
+
errors,
|
|
5878
|
+
};
|
|
5879
|
+
}
|
|
5880
|
+
catch (error) {
|
|
5881
|
+
return {
|
|
5882
|
+
isValid: false,
|
|
5883
|
+
errors: [
|
|
5884
|
+
{
|
|
5885
|
+
field: "validation",
|
|
5886
|
+
message: error instanceof Error ? error.message : "Unknown error",
|
|
5887
|
+
},
|
|
5888
|
+
],
|
|
5889
|
+
};
|
|
5890
|
+
}
|
|
5891
|
+
};
|
|
4940
5892
|
const defaultOnSubmit = async (promise) => {
|
|
4941
5893
|
try {
|
|
4942
5894
|
onBeforeSubmit();
|
|
@@ -4961,12 +5913,28 @@ const FormBody = () => {
|
|
|
4961
5913
|
};
|
|
4962
5914
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4963
5915
|
const onFormSubmit = async (data) => {
|
|
5916
|
+
// Validate data using AJV before submission
|
|
5917
|
+
const validationResult = validateFormData(data);
|
|
5918
|
+
if (!validationResult.isValid) {
|
|
5919
|
+
// Set validation errors
|
|
5920
|
+
const validationErrorMessage = {
|
|
5921
|
+
type: "validation",
|
|
5922
|
+
errors: validationResult.errors,
|
|
5923
|
+
message: translate.t("validation_error"),
|
|
5924
|
+
};
|
|
5925
|
+
onSubmitError(validationErrorMessage);
|
|
5926
|
+
return;
|
|
5927
|
+
}
|
|
4964
5928
|
if (onSubmit === undefined) {
|
|
4965
5929
|
await defaultOnSubmit(defaultSubmitPromise(data));
|
|
4966
5930
|
return;
|
|
4967
5931
|
}
|
|
4968
5932
|
await defaultOnSubmit(onSubmit(data));
|
|
4969
5933
|
};
|
|
5934
|
+
// Custom error renderer for validation errors with i18n support
|
|
5935
|
+
const renderValidationErrors = (validationErrors) => {
|
|
5936
|
+
return (jsx(AccordionRoot, { colorPalette: "red", collapsible: true, defaultValue: [], children: jsxs(AccordionItem, { value: "validation-errors", children: [jsx(AccordionItemTrigger, { children: translate.t("validation_error") }), jsx(AccordionItemContent, { display: "flex", flexFlow: "column", gap: "2", children: validationErrors.map((err, index) => (jsxs(AlertRoot, { status: "error", children: [jsx(AlertIndicator, {}), jsxs(AlertContent, { children: [jsx(AlertTitle, { fontWeight: "bold", children: err.instancePath }), jsx(AlertDescription, { children: err.message }), err.params !== undefined && (jsx(AlertDescription, { whiteSpace: "pre-wrap", wordBreak: "break-all", children: JSON.stringify(err.data, null, 2) }))] })] }))) })] }) }));
|
|
5937
|
+
};
|
|
4970
5938
|
const renderColumns = ({ order, keys, ignore, include, }) => {
|
|
4971
5939
|
const included = include.length > 0 ? include : keys;
|
|
4972
5940
|
const not_exist = included.filter((columnA) => !order.some((columnB) => columnA === columnB));
|
|
@@ -4981,7 +5949,7 @@ const FormBody = () => {
|
|
|
4981
5949
|
include,
|
|
4982
5950
|
});
|
|
4983
5951
|
if (isSuccess) {
|
|
4984
|
-
return (jsxs(Flex, { flexFlow: "column", gap: "2", children: [jsxs(Alert.Root, { status: "success", children: [jsx(Alert.Indicator, {}), jsx(Alert.Title, { children: translate.t("
|
|
5952
|
+
return (jsxs(Flex, { flexFlow: "column", gap: "2", children: [jsxs(Alert.Root, { status: "success", children: [jsx(Alert.Indicator, {}), jsx(Alert.Title, { children: translate.t("submit_success") })] }), jsx(Flex, { justifyContent: "end", children: jsx(Button$1, { onClick: async () => {
|
|
4985
5953
|
setIsError(false);
|
|
4986
5954
|
setIsSubmiting(false);
|
|
4987
5955
|
setIsSuccess(false);
|
|
@@ -4989,10 +5957,10 @@ const FormBody = () => {
|
|
|
4989
5957
|
setValidatedData(undefined);
|
|
4990
5958
|
const data = await getUpdatedData();
|
|
4991
5959
|
methods.reset(data);
|
|
4992
|
-
}, formNoValidate: true, children: translate.t("
|
|
5960
|
+
}, formNoValidate: true, children: translate.t("submit_again") }) })] }));
|
|
4993
5961
|
}
|
|
4994
5962
|
if (isConfirming) {
|
|
4995
|
-
return (jsxs(Flex, { flexFlow: "column", gap: "2", children: [jsx(Grid, { gap: 4, gridTemplateColumns: "repeat(12, 1fr)", gridTemplateRows:
|
|
5963
|
+
return (jsxs(Flex, { flexFlow: "column", gap: "2", children: [jsx(Grid, { gap: 4, gridTemplateColumns: "repeat(12, 1fr)", gridTemplateRows: "repeat(12, max-content)", autoFlow: "row", children: ordered.map((column) => {
|
|
4996
5964
|
return (jsx(ColumnViewer
|
|
4997
5965
|
// @ts-expect-error find suitable types
|
|
4998
5966
|
, {
|
|
@@ -5002,9 +5970,10 @@ const FormBody = () => {
|
|
|
5002
5970
|
setIsConfirming(false);
|
|
5003
5971
|
}, variant: "subtle", children: translate.t("cancel") }), jsx(Button$1, { onClick: () => {
|
|
5004
5972
|
onFormSubmit(validatedData);
|
|
5005
|
-
}, children: translate.t("confirm") })] }), isSubmiting && (jsx(Box, { pos: "absolute", inset: "0", bg: "bg/80", children: jsx(Center, { h: "full", children: jsx(Spinner, { color: "teal.500" }) }) })), isError && (jsx(Fragment, { children:
|
|
5973
|
+
}, children: translate.t("confirm") })] }), isSubmiting && (jsx(Box, { pos: "absolute", inset: "0", bg: "bg/80", children: jsx(Center, { h: "full", children: jsx(Spinner, { color: "teal.500" }) }) })), isError && (jsx(Fragment, { children: customErrorRenderer ? (customErrorRenderer(error)) : (jsx(Fragment, { children: error?.type === "validation" &&
|
|
5974
|
+
error?.errors ? (renderValidationErrors(error.errors)) : (jsx(Alert.Root, { status: "error", children: jsx(Alert.Title, { children: jsx(AccordionRoot, { collapsible: true, defaultValue: [], children: jsxs(AccordionItem, { value: "b", children: [jsxs(AccordionItemTrigger, { children: [jsx(Alert.Indicator, {}), `${error}`] }), jsx(AccordionItemContent, { children: `${JSON.stringify(error)}` })] }) }) }) })) })) }))] }));
|
|
5006
5975
|
}
|
|
5007
|
-
return (jsxs(Flex, { flexFlow: "column", gap: "2", children: [jsx(Grid, { gap: "4", gridTemplateColumns: "repeat(12, 1fr)",
|
|
5976
|
+
return (jsxs(Flex, { flexFlow: "column", gap: "2", children: [jsx(Grid, { gap: "4", gridTemplateColumns: "repeat(12, 1fr)", autoFlow: "row", children: ordered.map((column) => {
|
|
5008
5977
|
return (jsx(ColumnRenderer
|
|
5009
5978
|
// @ts-expect-error find suitable types
|
|
5010
5979
|
, {
|
|
@@ -5012,7 +5981,8 @@ const FormBody = () => {
|
|
|
5012
5981
|
properties: properties, prefix: ``, column }, `form-input-${column}`));
|
|
5013
5982
|
}) }), jsxs(Flex, { justifyContent: "end", gap: "2", children: [jsx(Button$1, { onClick: () => {
|
|
5014
5983
|
methods.reset();
|
|
5015
|
-
}, variant: "subtle", children: translate.t("reset") }), jsx(SubmitButton, {})] })
|
|
5984
|
+
}, variant: "subtle", children: translate.t("reset") }), jsx(SubmitButton, {})] }), isError && error?.type === "validation" && (jsx(Box, { mt: 4, children: error?.errors &&
|
|
5985
|
+
renderValidationErrors(error.errors) }))] }));
|
|
5016
5986
|
};
|
|
5017
5987
|
|
|
5018
5988
|
const FormTitle = () => {
|
|
@@ -5020,8 +5990,8 @@ const FormTitle = () => {
|
|
|
5020
5990
|
return jsx(Heading, { children: translate.t("title") });
|
|
5021
5991
|
};
|
|
5022
5992
|
|
|
5023
|
-
const DefaultForm = ({ formConfig, }) => {
|
|
5024
|
-
return (jsx(FormRoot, { ...formConfig, children: jsxs(Grid, { gap: "2", children: [jsx(FormTitle, {}), jsx(FormBody, {})] }) }));
|
|
5993
|
+
const DefaultForm = ({ formConfig, showTitle = true, }) => {
|
|
5994
|
+
return (jsx(FormRoot, { ...formConfig, children: jsxs(Grid, { gap: "2", children: [showTitle && jsx(FormTitle, {}), jsx(FormBody, {})] }) }));
|
|
5025
5995
|
};
|
|
5026
5996
|
|
|
5027
5997
|
const useForm = ({ preLoadedValues, keyPrefix }) => {
|
|
@@ -5054,4 +6024,4 @@ const getMultiDates = ({ selected, selectedDate, selectedDates, selectable, }) =
|
|
|
5054
6024
|
}
|
|
5055
6025
|
};
|
|
5056
6026
|
|
|
5057
|
-
export { CardHeader, DataDisplay, DataTable, DataTableServer, DefaultCardTitle, DefaultForm, DefaultTable, DensityToggleButton, EditSortingButton, EmptyState$1 as EmptyState, ErrorAlert, FilterDialog,
|
|
6027
|
+
export { CardHeader, DataDisplay, DataTable, DataTableServer, DefaultCardTitle, DefaultForm, DefaultTable, DensityToggleButton, EditSortingButton, EmptyState$1 as EmptyState, ErrorAlert, FilterDialog, FormBody, FormRoot, FormTitle, GlobalFilter, PageSizeControl, Pagination, RecordDisplay, ReloadButton, ResetFilteringButton, ResetSelectionButton, ResetSortingButton, RowCountText, Table, TableBody, TableCardContainer, TableCards, TableComponent, TableControls, TableDataDisplay, TableFilter, TableFilterTags, TableFooter, TableHeader, TableLoadingComponent, TableSelector, TableSorter, TableViewer, TextCell, ViewDialog, getColumns, getMultiDates, getRangeDates, idPickerSanityCheck, useDataTable, useDataTableContext, useDataTableServer, useForm, widthSanityCheck };
|