@simplysm/solid 13.0.76 → 13.0.77
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 +9 -10
- package/dist/components/data/kanban/Kanban.d.ts +31 -38
- package/dist/components/data/kanban/Kanban.d.ts.map +1 -1
- package/dist/components/data/kanban/Kanban.js.map +1 -1
- package/dist/components/data/list/List.d.ts +7 -28
- package/dist/components/data/list/List.d.ts.map +1 -1
- package/dist/components/data/list/List.js +3 -2
- package/dist/components/data/list/List.js.map +2 -2
- package/dist/components/data/sheet/DataSheet.d.ts +3 -8
- package/dist/components/data/sheet/DataSheet.d.ts.map +1 -1
- package/dist/components/data/sheet/DataSheet.js +305 -418
- package/dist/components/data/sheet/DataSheet.js.map +2 -2
- package/dist/components/data/sheet/{types.d.ts → DataSheet.types.d.ts} +9 -3
- package/dist/components/data/sheet/DataSheet.types.d.ts.map +1 -0
- package/dist/components/data/sheet/DataSheet.types.js +1 -0
- package/dist/components/data/sheet/{sheetUtils.d.ts → DataSheet.utils.d.ts} +2 -2
- package/dist/components/data/sheet/DataSheet.utils.d.ts.map +1 -0
- package/dist/components/data/sheet/{sheetUtils.js → DataSheet.utils.js} +3 -3
- package/dist/components/data/sheet/DataSheet.utils.js.map +6 -0
- package/dist/components/data/sheet/DataSheetColumn.d.ts +1 -1
- package/dist/components/data/sheet/DataSheetColumn.d.ts.map +1 -1
- package/dist/components/data/sheet/DataSheetConfigDialog.d.ts +1 -1
- package/dist/components/data/sheet/DataSheetConfigDialog.d.ts.map +1 -1
- package/dist/components/data/sheet/hooks/useDataSheetExpansion.d.ts +1 -1
- package/dist/components/data/sheet/hooks/useDataSheetExpansion.d.ts.map +1 -1
- package/dist/components/data/sheet/hooks/useDataSheetExpansion.js +1 -1
- package/dist/components/data/sheet/hooks/useDataSheetFixedColumns.d.ts +2 -2
- package/dist/components/data/sheet/hooks/useDataSheetFixedColumns.d.ts.map +1 -1
- package/dist/components/data/sheet/hooks/useDataSheetHeaderCell.d.ts +27 -0
- package/dist/components/data/sheet/hooks/useDataSheetHeaderCell.d.ts.map +1 -0
- package/dist/components/data/sheet/hooks/useDataSheetHeaderCell.js +173 -0
- package/dist/components/data/sheet/hooks/useDataSheetHeaderCell.js.map +6 -0
- package/dist/components/data/sheet/hooks/useDataSheetReorder.d.ts +1 -2
- package/dist/components/data/sheet/hooks/useDataSheetReorder.d.ts.map +1 -1
- package/dist/components/data/sheet/hooks/useDataSheetReorder.js.map +1 -1
- package/dist/components/data/sheet/hooks/useDataSheetSelection.d.ts +2 -2
- package/dist/components/data/sheet/hooks/useDataSheetSelection.d.ts.map +1 -1
- package/dist/components/data/sheet/hooks/useDataSheetSelection.js +2 -2
- package/dist/components/data/sheet/hooks/useDataSheetSelection.js.map +1 -1
- package/dist/components/data/sheet/hooks/useDataSheetSorting.d.ts +1 -1
- package/dist/components/data/sheet/hooks/useDataSheetSorting.d.ts.map +1 -1
- package/dist/components/data/sheet/hooks/useDataSheetSorting.js +1 -1
- package/dist/components/disclosure/Dialog.d.ts +6 -10
- package/dist/components/disclosure/Dialog.d.ts.map +1 -1
- package/dist/components/disclosure/Dialog.js +11 -14
- package/dist/components/disclosure/Dialog.js.map +2 -2
- package/dist/components/disclosure/Dropdown.d.ts +8 -12
- package/dist/components/disclosure/Dropdown.d.ts.map +1 -1
- package/dist/components/disclosure/Dropdown.js.map +1 -1
- package/dist/components/disclosure/Tabs.d.ts +3 -5
- package/dist/components/disclosure/Tabs.d.ts.map +1 -1
- package/dist/components/disclosure/Tabs.js.map +1 -1
- package/dist/components/display/Barcode.d.ts +1 -1
- package/dist/components/display/Barcode.d.ts.map +1 -1
- package/dist/components/display/Barcode.js +2 -1
- package/dist/components/display/Barcode.js.map +2 -2
- package/dist/components/display/Barcode.types.d.ts +2 -0
- package/dist/components/display/Barcode.types.d.ts.map +1 -0
- package/dist/components/display/Barcode.types.js +1 -0
- package/dist/components/display/Echarts.d.ts +2 -2
- package/dist/components/display/Echarts.d.ts.map +1 -1
- package/dist/components/display/Echarts.js +7 -8
- package/dist/components/display/Echarts.js.map +2 -2
- package/dist/components/features/address/AddressSearch.d.ts.map +1 -1
- package/dist/components/features/address/AddressSearch.js +4 -1
- package/dist/components/features/address/AddressSearch.js.map +2 -2
- package/dist/components/features/crud-detail/CrudDetail.d.ts +12 -13
- package/dist/components/features/crud-detail/CrudDetail.d.ts.map +1 -1
- package/dist/components/features/crud-detail/CrudDetail.js +18 -15
- package/dist/components/features/crud-detail/CrudDetail.js.map +2 -2
- package/dist/components/features/crud-detail/{types.d.ts → CrudDetail.types.d.ts} +1 -1
- package/dist/components/features/crud-detail/CrudDetail.types.d.ts.map +1 -0
- package/dist/components/features/crud-detail/CrudDetail.types.js +1 -0
- package/dist/components/features/crud-sheet/CrudSheet.d.ts +3 -13
- package/dist/components/features/crud-sheet/CrudSheet.d.ts.map +1 -1
- package/dist/components/features/crud-sheet/CrudSheet.js +62 -73
- package/dist/components/features/crud-sheet/CrudSheet.js.map +2 -2
- package/dist/components/features/crud-sheet/{types.d.ts → CrudSheet.types.d.ts} +10 -10
- package/dist/components/features/crud-sheet/CrudSheet.types.d.ts.map +1 -0
- package/dist/components/features/crud-sheet/CrudSheet.types.js +1 -0
- package/dist/components/features/crud-sheet/CrudSheet.types.js.map +6 -0
- package/dist/components/features/crud-sheet/CrudSheetColumn.d.ts +1 -1
- package/dist/components/features/crud-sheet/CrudSheetColumn.d.ts.map +1 -1
- package/dist/components/features/crud-sheet/CrudSheetTools.d.ts +1 -1
- package/dist/components/features/crud-sheet/CrudSheetTools.d.ts.map +1 -1
- package/dist/components/features/data-select-button/DataSelectButton.d.ts +2 -2
- package/dist/components/features/data-select-button/DataSelectButton.d.ts.map +1 -1
- package/dist/components/features/data-select-button/DataSelectButton.js +3 -3
- package/dist/components/features/data-select-button/DataSelectButton.js.map +2 -2
- package/dist/components/features/shared-data/SharedDataSelect.d.ts +7 -11
- package/dist/components/features/shared-data/SharedDataSelect.d.ts.map +1 -1
- package/dist/components/features/shared-data/SharedDataSelect.js +5 -4
- package/dist/components/features/shared-data/SharedDataSelect.js.map +2 -2
- package/dist/components/features/shared-data/SharedDataSelectButton.d.ts.map +1 -1
- package/dist/components/features/shared-data/SharedDataSelectButton.js.map +1 -1
- package/dist/components/features/shared-data/SharedDataSelectList.d.ts +8 -15
- package/dist/components/features/shared-data/SharedDataSelectList.d.ts.map +1 -1
- package/dist/components/features/shared-data/SharedDataSelectList.js +5 -3
- package/dist/components/features/shared-data/SharedDataSelectList.js.map +2 -2
- package/dist/components/feedback/notification/NotificationProvider.d.ts.map +1 -1
- package/dist/components/feedback/notification/NotificationProvider.js +9 -1
- package/dist/components/feedback/notification/NotificationProvider.js.map +2 -2
- package/dist/components/feedback/print/Print.d.ts +4 -6
- package/dist/components/feedback/print/Print.d.ts.map +1 -1
- package/dist/components/feedback/print/Print.js +3 -2
- package/dist/components/feedback/print/Print.js.map +2 -2
- package/dist/components/feedback/print/PrintProvider.d.ts.map +1 -1
- package/dist/components/feedback/print/PrintProvider.js +1 -0
- package/dist/components/feedback/print/PrintProvider.js.map +1 -1
- package/dist/components/form-control/Invalid.d.ts +1 -1
- package/dist/components/form-control/Invalid.d.ts.map +1 -1
- package/dist/components/form-control/Invalid.js +27 -26
- package/dist/components/form-control/Invalid.js.map +2 -2
- package/dist/components/form-control/checkbox/Checkbox.d.ts +1 -1
- package/dist/components/form-control/checkbox/Checkbox.d.ts.map +1 -1
- package/dist/components/form-control/checkbox/CheckboxGroup.d.ts +10 -10
- package/dist/components/form-control/checkbox/CheckboxGroup.d.ts.map +1 -1
- package/dist/components/form-control/checkbox/CheckboxGroup.js +2 -2
- package/dist/components/form-control/checkbox/CheckboxGroup.js.map +2 -2
- package/dist/components/form-control/checkbox/Radio.d.ts +1 -1
- package/dist/components/form-control/checkbox/Radio.d.ts.map +1 -1
- package/dist/components/form-control/checkbox/RadioGroup.d.ts +10 -10
- package/dist/components/form-control/checkbox/RadioGroup.d.ts.map +1 -1
- package/dist/components/form-control/checkbox/RadioGroup.js +2 -2
- package/dist/components/form-control/checkbox/RadioGroup.js.map +2 -2
- package/dist/components/form-control/checkbox/SelectableBase.d.ts +1 -1
- package/dist/components/form-control/checkbox/SelectableBase.d.ts.map +1 -1
- package/dist/components/form-control/checkbox/SelectableBase.js +3 -3
- package/dist/components/form-control/checkbox/SelectableBase.js.map +2 -2
- package/dist/components/form-control/checkbox/SelectionGroupBase.d.ts +1 -1
- package/dist/components/form-control/checkbox/SelectionGroupBase.d.ts.map +1 -1
- package/dist/components/form-control/checkbox/SelectionGroupBase.js +3 -3
- package/dist/components/form-control/checkbox/SelectionGroupBase.js.map +2 -2
- package/dist/components/form-control/color-picker/ColorPicker.d.ts +2 -2
- package/dist/components/form-control/color-picker/ColorPicker.d.ts.map +1 -1
- package/dist/components/form-control/color-picker/ColorPicker.js +3 -3
- package/dist/components/form-control/color-picker/ColorPicker.js.map +2 -2
- package/dist/components/form-control/combobox/Combobox.d.ts +3 -3
- package/dist/components/form-control/combobox/Combobox.d.ts.map +1 -1
- package/dist/components/form-control/combobox/Combobox.js +10 -5
- package/dist/components/form-control/combobox/Combobox.js.map +2 -2
- package/dist/components/form-control/date-range-picker/DateRangePicker.js +4 -4
- package/dist/components/form-control/date-range-picker/DateRangePicker.js.map +2 -2
- package/dist/components/form-control/editor/EditorToolbar.d.ts.map +1 -1
- package/dist/components/form-control/editor/EditorToolbar.js +176 -312
- package/dist/components/form-control/editor/EditorToolbar.js.map +2 -2
- package/dist/components/form-control/field/DatePicker.d.ts +2 -2
- package/dist/components/form-control/field/DatePicker.d.ts.map +1 -1
- package/dist/components/form-control/field/DatePicker.js +3 -3
- package/dist/components/form-control/field/DatePicker.js.map +2 -2
- package/dist/components/form-control/field/DateTimePicker.d.ts +2 -2
- package/dist/components/form-control/field/DateTimePicker.d.ts.map +1 -1
- package/dist/components/form-control/field/DateTimePicker.js +3 -3
- package/dist/components/form-control/field/DateTimePicker.js.map +2 -2
- package/dist/components/form-control/field/FieldShell.d.ts +1 -1
- package/dist/components/form-control/field/FieldShell.d.ts.map +1 -1
- package/dist/components/form-control/field/FieldShell.js +2 -2
- package/dist/components/form-control/field/FieldShell.js.map +2 -2
- package/dist/components/form-control/field/NumberInput.d.ts +7 -28
- package/dist/components/form-control/field/NumberInput.d.ts.map +1 -1
- package/dist/components/form-control/field/NumberInput.js +7 -5
- package/dist/components/form-control/field/NumberInput.js.map +2 -2
- package/dist/components/form-control/field/TextInput.d.ts +7 -23
- package/dist/components/form-control/field/TextInput.d.ts.map +1 -1
- package/dist/components/form-control/field/TextInput.js +6 -5
- package/dist/components/form-control/field/TextInput.js.map +2 -2
- package/dist/components/form-control/field/Textarea.d.ts +2 -2
- package/dist/components/form-control/field/Textarea.d.ts.map +1 -1
- package/dist/components/form-control/field/Textarea.js +3 -3
- package/dist/components/form-control/field/Textarea.js.map +2 -2
- package/dist/components/form-control/field/TimePicker.d.ts +2 -2
- package/dist/components/form-control/field/TimePicker.d.ts.map +1 -1
- package/dist/components/form-control/field/TimePicker.js +3 -3
- package/dist/components/form-control/field/TimePicker.js.map +2 -2
- package/dist/components/form-control/select/Select.d.ts +22 -44
- package/dist/components/form-control/select/Select.d.ts.map +1 -1
- package/dist/components/form-control/select/Select.js +8 -6
- package/dist/components/form-control/select/Select.js.map +2 -2
- package/dist/components/form-control/state-preset/StatePreset.js +5 -5
- package/dist/components/form-control/state-preset/StatePreset.js.map +2 -2
- package/dist/components/layout/sidebar/Sidebar.d.ts +5 -102
- package/dist/components/layout/sidebar/Sidebar.d.ts.map +1 -1
- package/dist/components/layout/sidebar/Sidebar.js.map +1 -1
- package/dist/components/layout/topbar/Topbar.d.ts +1 -1
- package/dist/components/layout/topbar/Topbar.d.ts.map +1 -1
- package/dist/components/layout/topbar/Topbar.js +3 -3
- package/dist/components/layout/topbar/Topbar.js.map +2 -2
- package/dist/helpers/createAppStructure.d.ts.map +1 -1
- package/dist/helpers/createAppStructure.js.map +1 -1
- package/dist/hooks/createControllableStore.js +5 -5
- package/dist/hooks/createControllableStore.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/providers/ServiceClientProvider.d.ts +2 -2
- package/dist/providers/ServiceClientProvider.d.ts.map +1 -1
- package/dist/providers/ServiceClientProvider.js.map +1 -1
- package/dist/providers/shared-data/SharedDataProvider.d.ts +1 -1
- package/dist/providers/shared-data/SharedDataProvider.d.ts.map +1 -1
- package/dist/providers/shared-data/SharedDataProvider.js +98 -86
- package/dist/providers/shared-data/SharedDataProvider.js.map +2 -2
- package/package.json +5 -5
- package/src/components/data/kanban/Kanban.tsx +37 -32
- package/src/components/data/list/List.tsx +3 -6
- package/src/components/data/sheet/DataSheet.tsx +224 -334
- package/src/components/data/sheet/{types.ts → DataSheet.types.ts} +8 -2
- package/src/components/data/sheet/{sheetUtils.ts → DataSheet.utils.ts} +3 -3
- package/src/components/data/sheet/DataSheetColumn.tsx +1 -1
- package/src/components/data/sheet/DataSheetConfigDialog.tsx +1 -1
- package/src/components/data/sheet/hooks/useDataSheetExpansion.ts +2 -2
- package/src/components/data/sheet/hooks/useDataSheetFixedColumns.ts +2 -2
- package/src/components/data/sheet/hooks/useDataSheetHeaderCell.tsx +168 -0
- package/src/components/data/sheet/hooks/useDataSheetReorder.ts +1 -2
- package/src/components/data/sheet/hooks/useDataSheetSelection.ts +4 -4
- package/src/components/data/sheet/hooks/useDataSheetSorting.ts +2 -2
- package/src/components/disclosure/Dialog.tsx +21 -27
- package/src/components/disclosure/Dropdown.tsx +1 -6
- package/src/components/disclosure/Tabs.tsx +1 -6
- package/src/components/display/Barcode.tsx +4 -113
- package/src/components/display/Barcode.types.ts +111 -0
- package/src/components/display/Echarts.tsx +10 -11
- package/src/components/features/address/AddressSearch.tsx +21 -3
- package/src/components/features/crud-detail/CrudDetail.tsx +21 -38
- package/src/components/features/crud-sheet/CrudSheet.tsx +77 -93
- package/src/components/features/crud-sheet/{types.ts → CrudSheet.types.ts} +9 -9
- package/src/components/features/crud-sheet/CrudSheetColumn.tsx +1 -1
- package/src/components/features/crud-sheet/CrudSheetTools.tsx +1 -1
- package/src/components/features/data-select-button/DataSelectButton.tsx +8 -8
- package/src/components/features/shared-data/SharedDataSelect.tsx +23 -34
- package/src/components/features/shared-data/SharedDataSelectButton.tsx +1 -4
- package/src/components/features/shared-data/SharedDataSelectList.tsx +6 -10
- package/src/components/feedback/notification/NotificationProvider.tsx +9 -1
- package/src/components/feedback/print/Print.tsx +4 -8
- package/src/components/feedback/print/PrintProvider.tsx +2 -1
- package/src/components/form-control/Invalid.tsx +33 -29
- package/src/components/form-control/checkbox/Checkbox.tsx +1 -1
- package/src/components/form-control/checkbox/CheckboxGroup.tsx +3 -12
- package/src/components/form-control/checkbox/Radio.tsx +1 -1
- package/src/components/form-control/checkbox/RadioGroup.tsx +3 -12
- package/src/components/form-control/checkbox/SelectableBase.tsx +3 -3
- package/src/components/form-control/checkbox/SelectionGroupBase.tsx +3 -3
- package/src/components/form-control/color-picker/ColorPicker.tsx +4 -4
- package/src/components/form-control/combobox/Combobox.tsx +23 -18
- package/src/components/form-control/date-range-picker/DateRangePicker.tsx +5 -5
- package/src/components/form-control/editor/EditorToolbar.tsx +82 -202
- package/src/components/form-control/field/DatePicker.tsx +4 -4
- package/src/components/form-control/field/DateTimePicker.tsx +4 -4
- package/src/components/form-control/field/FieldShell.tsx +2 -2
- package/src/components/form-control/field/NumberInput.tsx +8 -11
- package/src/components/form-control/field/TextInput.tsx +7 -11
- package/src/components/form-control/field/Textarea.tsx +4 -4
- package/src/components/form-control/field/TimePicker.tsx +4 -4
- package/src/components/form-control/select/Select.tsx +33 -42
- package/src/components/form-control/state-preset/StatePreset.tsx +5 -5
- package/src/components/layout/sidebar/Sidebar.tsx +1 -7
- package/src/components/layout/topbar/Topbar.tsx +3 -3
- package/src/helpers/createAppStructure.ts +16 -0
- package/src/hooks/createControllableStore.ts +5 -5
- package/src/index.ts +4 -3
- package/src/providers/ServiceClientProvider.tsx +4 -4
- package/src/providers/shared-data/SharedDataProvider.tsx +136 -113
- package/tests/components/data/sheet/DataSheet.spec.tsx +2 -2
- package/tests/components/data/sheet/hooks/useDataSheetFixedColumns.spec.ts +1 -1
- package/tests/components/data/sheet/hooks/useDataSheetSelection.spec.ts +34 -17
- package/tests/components/data/sheet/hooks/useDataSheetSorting.spec.ts +1 -1
- package/tests/components/disclosure/Dialog.spec.tsx +7 -7
- package/tests/components/display/Barcode.spec.tsx +15 -1
- package/tests/components/features/crud-sheet/CrudSheet.spec.tsx +6 -6
- package/tests/components/form-control/Invalid.spec.tsx +5 -5
- package/tests/components/form-control/combobox/Combobox.spec.tsx +24 -1
- package/tests/components/layout/topbar/TopbarActions.spec.tsx +4 -4
- package/tests/components/layout/topbar/{createTopbarActions.spec.tsx → useTopbarActions.spec.tsx} +4 -4
- package/tests/providers/shared-data/SharedDataProvider.spec.tsx +130 -8
- package/dist/components/data/sheet/sheetUtils.d.ts.map +0 -1
- package/dist/components/data/sheet/sheetUtils.js.map +0 -6
- package/dist/components/data/sheet/types.d.ts.map +0 -1
- package/dist/components/data/sheet/types.js +0 -1
- package/dist/components/features/crud-detail/types.d.ts.map +0 -1
- package/dist/components/features/crud-detail/types.js +0 -1
- package/dist/components/features/crud-sheet/types.d.ts.map +0 -1
- package/dist/components/features/crud-sheet/types.js +0 -1
- package/dist/components/feedback/notification/index.d.ts +0 -4
- package/dist/components/feedback/notification/index.d.ts.map +0 -1
- package/dist/components/feedback/notification/index.js +0 -4
- package/dist/components/feedback/notification/index.js.map +0 -6
- package/src/components/feedback/notification/index.ts +0 -3
- /package/dist/components/data/sheet/{types.js.map → DataSheet.types.js.map} +0 -0
- /package/dist/components/{features/crud-detail/types.js.map → display/Barcode.types.js.map} +0 -0
- /package/dist/components/features/{crud-sheet/types.js.map → crud-detail/CrudDetail.types.js.map} +0 -0
- /package/src/components/features/crud-detail/{types.ts → CrudDetail.types.ts} +0 -0
|
@@ -3,7 +3,6 @@ import {
|
|
|
3
3
|
createSignal,
|
|
4
4
|
createUniqueId,
|
|
5
5
|
For,
|
|
6
|
-
type JSX,
|
|
7
6
|
onCleanup,
|
|
8
7
|
Show,
|
|
9
8
|
splitProps,
|
|
@@ -12,19 +11,20 @@ import {
|
|
|
12
11
|
import { createStore, produce, reconcile } from "solid-js/store";
|
|
13
12
|
import { createControllableStore } from "../../../hooks/createControllableStore";
|
|
14
13
|
import type { DateTime } from "@simplysm/core-common";
|
|
15
|
-
import {
|
|
14
|
+
import { obj } from "@simplysm/core-common";
|
|
16
15
|
import "@simplysm/core-common"; // register extensions
|
|
17
|
-
import
|
|
16
|
+
import { openFileDialog } from "@simplysm/core-browser";
|
|
17
|
+
import type { SortingDef } from "../../data/sheet/DataSheet.types";
|
|
18
18
|
import { DataSheet } from "../../data/sheet/DataSheet";
|
|
19
19
|
import { DataSheetColumn } from "../../data/sheet/DataSheetColumn";
|
|
20
|
-
import { normalizeHeader } from "../../data/sheet/
|
|
20
|
+
import { normalizeHeader } from "../../data/sheet/DataSheet.utils";
|
|
21
21
|
import { BusyContainer } from "../../feedback/busy/BusyContainer";
|
|
22
22
|
import { useNotification } from "../../feedback/notification/NotificationProvider";
|
|
23
23
|
import { useI18n } from "../../../providers/i18n/I18nProvider";
|
|
24
24
|
import { Button } from "../../form-control/Button";
|
|
25
25
|
import { Icon } from "../../display/Icon";
|
|
26
26
|
import { FormGroup } from "../../layout/FormGroup";
|
|
27
|
-
import {
|
|
27
|
+
import { useTopbarActions, TopbarContext } from "../../layout/topbar/Topbar";
|
|
28
28
|
import { Dialog } from "../../disclosure/Dialog";
|
|
29
29
|
import { Link } from "../../display/Link";
|
|
30
30
|
import { createEventListener } from "@solid-primitives/event-listener";
|
|
@@ -53,17 +53,9 @@ import type {
|
|
|
53
53
|
CrudSheetContext,
|
|
54
54
|
CrudSheetProps,
|
|
55
55
|
SearchResult,
|
|
56
|
-
} from "./types";
|
|
56
|
+
} from "./CrudSheet.types";
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
<TItem, TFilter extends Record<string, any>>(props: CrudSheetProps<TItem, TFilter>): JSX.Element;
|
|
60
|
-
Column: typeof CrudSheetColumn;
|
|
61
|
-
Filter: typeof CrudSheetFilter;
|
|
62
|
-
Tools: typeof CrudSheetTools;
|
|
63
|
-
Header: typeof CrudSheetHeader;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const CrudSheetBase = <TItem, TFilter extends Record<string, any>>(
|
|
58
|
+
const CrudSheetBase = <TItem, TFilter extends Record<string, unknown>>(
|
|
67
59
|
props: CrudSheetProps<TItem, TFilter>,
|
|
68
60
|
) => {
|
|
69
61
|
const [local] = splitProps(props, [
|
|
@@ -71,10 +63,10 @@ const CrudSheetBase = <TItem, TFilter extends Record<string, any>>(
|
|
|
71
63
|
"getItemKey",
|
|
72
64
|
"storageKey",
|
|
73
65
|
"editable",
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
"
|
|
77
|
-
"
|
|
66
|
+
"isItemEditable",
|
|
67
|
+
"isItemDeletable",
|
|
68
|
+
"isItemDeleted",
|
|
69
|
+
"isItemSelectable",
|
|
78
70
|
"lastModifiedAtProp",
|
|
79
71
|
"lastModifiedByProp",
|
|
80
72
|
"onSubmitComplete",
|
|
@@ -113,13 +105,26 @@ const CrudSheetBase = <TItem, TFilter extends Record<string, any>>(
|
|
|
113
105
|
let originalItems: TItem[] = [];
|
|
114
106
|
|
|
115
107
|
const [filter, setFilter] = createStore<TFilter>((local.filterInitial ?? {}) as TFilter);
|
|
116
|
-
const [lastFilter, setLastFilter] = createSignal<TFilter>(
|
|
108
|
+
const [lastFilter, setLastFilter] = createSignal<TFilter>(obj.clone(filter));
|
|
117
109
|
|
|
118
110
|
const [page, setPage] = createSignal(1);
|
|
119
111
|
const [totalPageCount, setTotalPageCount] = createSignal(0);
|
|
120
112
|
const [sorts, setSorts] = createSignal<SortingDef[]>([]);
|
|
121
113
|
|
|
122
114
|
const [busyCount, setBusyCount] = createSignal(0);
|
|
115
|
+
|
|
116
|
+
async function withBusy<T>(fn: () => Promise<T>, errorMessage?: string): Promise<T | undefined> {
|
|
117
|
+
setBusyCount((c) => c + 1);
|
|
118
|
+
try {
|
|
119
|
+
return await fn();
|
|
120
|
+
} catch (err) {
|
|
121
|
+
noti.error(err, errorMessage);
|
|
122
|
+
return undefined;
|
|
123
|
+
} finally {
|
|
124
|
+
setBusyCount((c) => c - 1);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
123
128
|
const [ready, setReady] = createSignal(false);
|
|
124
129
|
|
|
125
130
|
const [selection, setSelection] = createSignal<TItem[]>([]);
|
|
@@ -132,13 +137,15 @@ const CrudSheetBase = <TItem, TFilter extends Record<string, any>>(
|
|
|
132
137
|
createEventListener(() => formRef, "pointerdown", () => activateCrud(crudId));
|
|
133
138
|
createEventListener(() => formRef, "focusin", () => activateCrud(crudId));
|
|
134
139
|
|
|
140
|
+
let refreshVersion = 0;
|
|
141
|
+
|
|
135
142
|
createEffect(() => {
|
|
136
143
|
void doRefresh();
|
|
137
144
|
});
|
|
138
145
|
|
|
139
146
|
// -- Key-based selection: restore selection when items change --
|
|
140
147
|
createEffect(() => {
|
|
141
|
-
const currentItems = items
|
|
148
|
+
const currentItems = items;
|
|
142
149
|
const keys = selectedKeys();
|
|
143
150
|
if (keys.size === 0) {
|
|
144
151
|
if (selection().length > 0) {
|
|
@@ -154,20 +161,24 @@ const CrudSheetBase = <TItem, TFilter extends Record<string, any>>(
|
|
|
154
161
|
});
|
|
155
162
|
|
|
156
163
|
async function doRefresh() {
|
|
164
|
+
const version = ++refreshVersion;
|
|
157
165
|
setBusyCount((c) => c + 1);
|
|
158
166
|
try {
|
|
159
167
|
await refresh();
|
|
168
|
+
if (version !== refreshVersion) return;
|
|
169
|
+
setReady(true);
|
|
160
170
|
} catch (err) {
|
|
171
|
+
if (version !== refreshVersion) return;
|
|
161
172
|
noti.error(err, i18n.t("crudSheet.lookupFailed"));
|
|
173
|
+
} finally {
|
|
174
|
+
setBusyCount((c) => c - 1);
|
|
162
175
|
}
|
|
163
|
-
setBusyCount((c) => c - 1);
|
|
164
|
-
setReady(true);
|
|
165
176
|
}
|
|
166
177
|
|
|
167
178
|
async function refresh() {
|
|
168
179
|
const result: SearchResult<TItem> = await local.search(lastFilter(), page(), sorts());
|
|
169
180
|
setItems(reconcile(result.items));
|
|
170
|
-
originalItems =
|
|
181
|
+
originalItems = obj.clone(result.items);
|
|
171
182
|
setTotalPageCount(result.pageCount ?? 0);
|
|
172
183
|
}
|
|
173
184
|
|
|
@@ -188,7 +199,7 @@ const CrudSheetBase = <TItem, TFilter extends Record<string, any>>(
|
|
|
188
199
|
e.preventDefault();
|
|
189
200
|
if (!checkIgnoreChanges()) return;
|
|
190
201
|
setPage(1);
|
|
191
|
-
setLastFilter(() =>
|
|
202
|
+
setLastFilter(() => obj.clone(filter));
|
|
192
203
|
}
|
|
193
204
|
|
|
194
205
|
async function handleRefresh() {
|
|
@@ -207,7 +218,7 @@ const CrudSheetBase = <TItem, TFilter extends Record<string, any>>(
|
|
|
207
218
|
}
|
|
208
219
|
|
|
209
220
|
function handleToggleDelete(item: TItem, index: number) {
|
|
210
|
-
if (!(local.
|
|
221
|
+
if (!(local.isItemDeletable?.(item) ?? true)) return;
|
|
211
222
|
if (local.inlineEdit?.deleteProp == null) return;
|
|
212
223
|
const dp = local.inlineEdit.deleteProp;
|
|
213
224
|
|
|
@@ -220,7 +231,11 @@ const CrudSheetBase = <TItem, TFilter extends Record<string, any>>(
|
|
|
220
231
|
return;
|
|
221
232
|
}
|
|
222
233
|
|
|
223
|
-
setItems(
|
|
234
|
+
setItems(
|
|
235
|
+
produce((draft) => {
|
|
236
|
+
(draft[index] as Record<string, unknown>)[dp] = !(item[dp] as boolean);
|
|
237
|
+
}),
|
|
238
|
+
);
|
|
224
239
|
}
|
|
225
240
|
|
|
226
241
|
async function handleSave() {
|
|
@@ -235,16 +250,12 @@ const CrudSheetBase = <TItem, TFilter extends Record<string, any>>(
|
|
|
235
250
|
return;
|
|
236
251
|
}
|
|
237
252
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
await local.inlineEdit.submit(diffs);
|
|
253
|
+
await withBusy(async () => {
|
|
254
|
+
await local.inlineEdit!.submit(diffs);
|
|
241
255
|
noti.success(i18n.t("crudSheet.saveCompleted"), i18n.t("crudSheet.saveSuccess"));
|
|
242
256
|
await refresh();
|
|
243
257
|
local.onSubmitComplete?.();
|
|
244
|
-
}
|
|
245
|
-
noti.error(err, i18n.t("crudSheet.saveFailed"));
|
|
246
|
-
}
|
|
247
|
-
setBusyCount((c) => c - 1);
|
|
258
|
+
}, i18n.t("crudSheet.saveFailed"));
|
|
248
259
|
}
|
|
249
260
|
|
|
250
261
|
async function handleFormSubmit(e: Event) {
|
|
@@ -258,13 +269,7 @@ const CrudSheetBase = <TItem, TFilter extends Record<string, any>>(
|
|
|
258
269
|
const result = await local.dialogEdit.editItem(item);
|
|
259
270
|
if (!result) return;
|
|
260
271
|
|
|
261
|
-
|
|
262
|
-
try {
|
|
263
|
-
await refresh();
|
|
264
|
-
} catch (err) {
|
|
265
|
-
noti.error(err, i18n.t("crudSheet.lookupFailed"));
|
|
266
|
-
}
|
|
267
|
-
setBusyCount((c) => c - 1);
|
|
272
|
+
await withBusy(() => refresh(), i18n.t("crudSheet.lookupFailed"));
|
|
268
273
|
}
|
|
269
274
|
|
|
270
275
|
async function handleDeleteItems() {
|
|
@@ -272,14 +277,10 @@ const CrudSheetBase = <TItem, TFilter extends Record<string, any>>(
|
|
|
272
277
|
const result = await local.dialogEdit.deleteItems(selection());
|
|
273
278
|
if (!result) return;
|
|
274
279
|
|
|
275
|
-
|
|
276
|
-
try {
|
|
280
|
+
await withBusy(async () => {
|
|
277
281
|
await refresh();
|
|
278
282
|
noti.success(i18n.t("crudSheet.deleteCompleted"), i18n.t("crudSheet.deleteSuccess"));
|
|
279
|
-
}
|
|
280
|
-
noti.error(err, i18n.t("crudSheet.deleteFailed"));
|
|
281
|
-
}
|
|
282
|
-
setBusyCount((c) => c - 1);
|
|
283
|
+
}, i18n.t("crudSheet.deleteFailed"));
|
|
283
284
|
}
|
|
284
285
|
|
|
285
286
|
async function handleRestoreItems() {
|
|
@@ -287,57 +288,40 @@ const CrudSheetBase = <TItem, TFilter extends Record<string, any>>(
|
|
|
287
288
|
const result = await local.dialogEdit.restoreItems(selection());
|
|
288
289
|
if (!result) return;
|
|
289
290
|
|
|
290
|
-
|
|
291
|
-
try {
|
|
291
|
+
await withBusy(async () => {
|
|
292
292
|
await refresh();
|
|
293
293
|
noti.success(i18n.t("crudSheet.restoreCompleted"), i18n.t("crudSheet.restoreSuccess"));
|
|
294
|
-
}
|
|
295
|
-
noti.error(err, i18n.t("crudSheet.restoreFailed"));
|
|
296
|
-
}
|
|
297
|
-
setBusyCount((c) => c - 1);
|
|
294
|
+
}, i18n.t("crudSheet.restoreFailed"));
|
|
298
295
|
}
|
|
299
296
|
|
|
300
297
|
// -- Excel --
|
|
301
298
|
async function handleExcelDownload() {
|
|
302
299
|
if (!local.excel) return;
|
|
303
300
|
|
|
304
|
-
|
|
305
|
-
try {
|
|
301
|
+
await withBusy(async () => {
|
|
306
302
|
const result = await local.search(lastFilter(), undefined, sorts());
|
|
307
|
-
await local.excel
|
|
308
|
-
}
|
|
309
|
-
noti.error(err, i18n.t("crudSheet.excelDownloadFailed"));
|
|
310
|
-
}
|
|
311
|
-
setBusyCount((c) => c - 1);
|
|
303
|
+
await local.excel!.download(result.items);
|
|
304
|
+
}, i18n.t("crudSheet.excelDownloadFailed"));
|
|
312
305
|
}
|
|
313
306
|
|
|
314
|
-
function handleExcelUpload() {
|
|
307
|
+
async function handleExcelUpload() {
|
|
315
308
|
if (!local.excel?.upload) return;
|
|
316
309
|
|
|
317
|
-
const
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
await local.excel!.upload!(file);
|
|
327
|
-
noti.success(i18n.t("crudSheet.excelCompleted"), i18n.t("crudSheet.excelUploadSuccess"));
|
|
328
|
-
await refresh();
|
|
329
|
-
} catch (err) {
|
|
330
|
-
noti.error(err, i18n.t("crudSheet.excelUploadFailed"));
|
|
331
|
-
}
|
|
332
|
-
setBusyCount((c) => c - 1);
|
|
333
|
-
};
|
|
334
|
-
input.click();
|
|
310
|
+
const files = await openFileDialog({ accept: ".xlsx" });
|
|
311
|
+
const file = files?.[0];
|
|
312
|
+
if (file == null) return;
|
|
313
|
+
|
|
314
|
+
await withBusy(async () => {
|
|
315
|
+
await local.excel!.upload!(file);
|
|
316
|
+
noti.success(i18n.t("crudSheet.excelCompleted"), i18n.t("crudSheet.excelUploadSuccess"));
|
|
317
|
+
await refresh();
|
|
318
|
+
}, i18n.t("crudSheet.excelUploadFailed"));
|
|
335
319
|
}
|
|
336
320
|
|
|
337
321
|
// -- Select Mode --
|
|
338
322
|
function handleSelectionChange(newSelection: TItem[]) {
|
|
339
323
|
// Current page items key Set
|
|
340
|
-
const currentItems = items
|
|
324
|
+
const currentItems = items;
|
|
341
325
|
const currentKeys = new Set<string | number>();
|
|
342
326
|
for (const item of currentItems) {
|
|
343
327
|
const key = local.getItemKey(item);
|
|
@@ -414,7 +398,7 @@ const CrudSheetBase = <TItem, TFilter extends Record<string, any>>(
|
|
|
414
398
|
|
|
415
399
|
// -- Topbar Actions --
|
|
416
400
|
if (topbarCtx) {
|
|
417
|
-
|
|
401
|
+
useTopbarActions(() => (
|
|
418
402
|
<>
|
|
419
403
|
<Show when={canEdit() && local.inlineEdit}>
|
|
420
404
|
<Button
|
|
@@ -437,7 +421,7 @@ const CrudSheetBase = <TItem, TFilter extends Record<string, any>>(
|
|
|
437
421
|
|
|
438
422
|
// -- Context for Tools --
|
|
439
423
|
const ctx: CrudSheetContext<TItem> = {
|
|
440
|
-
items: () => items
|
|
424
|
+
items: () => items,
|
|
441
425
|
selection,
|
|
442
426
|
page,
|
|
443
427
|
sorts,
|
|
@@ -458,7 +442,7 @@ const CrudSheetBase = <TItem, TFilter extends Record<string, any>>(
|
|
|
458
442
|
|
|
459
443
|
// -- Render --
|
|
460
444
|
const deleteProp = () => local.inlineEdit?.deleteProp;
|
|
461
|
-
const isItemDeleted = (item: TItem) => local.
|
|
445
|
+
const isItemDeleted = (item: TItem) => local.isItemDeleted?.(item) ?? false;
|
|
462
446
|
|
|
463
447
|
return (
|
|
464
448
|
<>
|
|
@@ -561,8 +545,8 @@ const CrudSheetBase = <TItem, TFilter extends Record<string, any>>(
|
|
|
561
545
|
selection().length === 0 ||
|
|
562
546
|
!selection().some(
|
|
563
547
|
(item) =>
|
|
564
|
-
(local.
|
|
565
|
-
!(local.
|
|
548
|
+
(local.isItemDeletable?.(item) ?? true) &&
|
|
549
|
+
!(local.isItemDeleted?.(item) ?? false),
|
|
566
550
|
)
|
|
567
551
|
}
|
|
568
552
|
>
|
|
@@ -578,7 +562,7 @@ const CrudSheetBase = <TItem, TFilter extends Record<string, any>>(
|
|
|
578
562
|
onClick={handleRestoreItems}
|
|
579
563
|
disabled={
|
|
580
564
|
selection().length === 0 ||
|
|
581
|
-
!selection().some((item) => local.
|
|
565
|
+
!selection().some((item) => local.isItemDeleted?.(item) ?? false)
|
|
582
566
|
}
|
|
583
567
|
>
|
|
584
568
|
<Icon icon={IconTrashOff} class="mr-1" />
|
|
@@ -617,7 +601,7 @@ const CrudSheetBase = <TItem, TFilter extends Record<string, any>>(
|
|
|
617
601
|
totalPageCount={totalPageCount()}
|
|
618
602
|
sorts={sorts()}
|
|
619
603
|
onSortsChange={setSorts}
|
|
620
|
-
|
|
604
|
+
isItemSelectable={local.isItemSelectable}
|
|
621
605
|
selectionMode={
|
|
622
606
|
isSelectMode()
|
|
623
607
|
? local.selectionMode
|
|
@@ -627,7 +611,7 @@ const CrudSheetBase = <TItem, TFilter extends Record<string, any>>(
|
|
|
627
611
|
}
|
|
628
612
|
selection={selection()}
|
|
629
613
|
onSelectionChange={handleSelectionChange}
|
|
630
|
-
autoSelect={isSelectMode() && local.selectionMode === "single" ?
|
|
614
|
+
autoSelect={isSelectMode() && local.selectionMode === "single" ? true : undefined}
|
|
631
615
|
cellClass={(item) => {
|
|
632
616
|
if (isItemDeleted(item)) {
|
|
633
617
|
return "line-through";
|
|
@@ -648,7 +632,7 @@ const CrudSheetBase = <TItem, TFilter extends Record<string, any>>(
|
|
|
648
632
|
<div class="flex items-center justify-center px-1 py-0.5">
|
|
649
633
|
<Link
|
|
650
634
|
theme="danger"
|
|
651
|
-
disabled={!(local.
|
|
635
|
+
disabled={!(local.isItemDeletable?.(dsCtx.item) ?? true)}
|
|
652
636
|
onClick={() => handleToggleDelete(dsCtx.item, dsCtx.index)}
|
|
653
637
|
>
|
|
654
638
|
<Icon icon={isItemDeleted(dsCtx.item) ? IconTrashOff : IconTrash} />
|
|
@@ -689,7 +673,7 @@ const CrudSheetBase = <TItem, TFilter extends Record<string, any>>(
|
|
|
689
673
|
local.dialogEdit &&
|
|
690
674
|
(col.editTrigger ?? false) &&
|
|
691
675
|
canEdit() &&
|
|
692
|
-
(local.
|
|
676
|
+
(local.isItemEditable?.(dsCtx.item) ?? true)
|
|
693
677
|
) {
|
|
694
678
|
return (
|
|
695
679
|
<Link
|
|
@@ -720,7 +704,7 @@ const CrudSheetBase = <TItem, TFilter extends Record<string, any>>(
|
|
|
720
704
|
{(dsCtx) => (
|
|
721
705
|
<div class={clsx(pad.default, "text-center")}>
|
|
722
706
|
{(
|
|
723
|
-
|
|
707
|
+
obj.getChainValue(dsCtx.item, local.lastModifiedAtProp!, true) as
|
|
724
708
|
| DateTime
|
|
725
709
|
| undefined
|
|
726
710
|
)?.toFormatString("yyyy-MM-dd HH:mm")}
|
|
@@ -733,7 +717,7 @@ const CrudSheetBase = <TItem, TFilter extends Record<string, any>>(
|
|
|
733
717
|
<DataSheetColumn<TItem> key={local.lastModifiedByProp!} header={i18n.t("crudSheet.modifiedBy")} hidden>
|
|
734
718
|
{(dsCtx) => (
|
|
735
719
|
<div class={clsx(pad.default, "text-center")}>
|
|
736
|
-
{
|
|
720
|
+
{obj.getChainValue(dsCtx.item, local.lastModifiedByProp!, true) as string}
|
|
737
721
|
</div>
|
|
738
722
|
)}
|
|
739
723
|
</DataSheetColumn>
|
|
@@ -763,7 +747,7 @@ const CrudSheetBase = <TItem, TFilter extends Record<string, any>>(
|
|
|
763
747
|
};
|
|
764
748
|
|
|
765
749
|
//#region Export
|
|
766
|
-
export const CrudSheet = Object.assign(CrudSheetBase
|
|
750
|
+
export const CrudSheet = Object.assign(CrudSheetBase, {
|
|
767
751
|
Column: CrudSheetColumn,
|
|
768
752
|
Filter: CrudSheetFilter,
|
|
769
753
|
Tools: CrudSheetTools,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { JSX } from "solid-js";
|
|
2
|
-
import type {
|
|
3
|
-
import type { DataSheetColumnProps, SortingDef } from "../../data/sheet/types";
|
|
2
|
+
import type { ArrayOneWayDiffResult } from "@simplysm/core-common";
|
|
3
|
+
import type { DataSheetColumnProps, SortingDef } from "../../data/sheet/DataSheet.types";
|
|
4
4
|
|
|
5
5
|
// ── Search ──
|
|
6
6
|
|
|
@@ -12,7 +12,7 @@ export interface SearchResult<TItem> {
|
|
|
12
12
|
// ── Feature Configs ──
|
|
13
13
|
|
|
14
14
|
export interface InlineEditConfig<TItem> {
|
|
15
|
-
submit: (diffs:
|
|
15
|
+
submit: (diffs: ArrayOneWayDiffResult<TItem>[]) => Promise<void>;
|
|
16
16
|
newItem: () => TItem;
|
|
17
17
|
deleteProp?: keyof TItem & string;
|
|
18
18
|
diffsExcludes?: string[];
|
|
@@ -64,7 +64,7 @@ export interface CrudSheetContext<TItem> {
|
|
|
64
64
|
|
|
65
65
|
// ── Props ──
|
|
66
66
|
|
|
67
|
-
export type CrudSheetProps<TItem, TFilter extends Record<string,
|
|
67
|
+
export type CrudSheetProps<TItem, TFilter extends Record<string, unknown>> = CrudSheetBaseProps<
|
|
68
68
|
TItem,
|
|
69
69
|
TFilter
|
|
70
70
|
> &
|
|
@@ -74,7 +74,7 @@ export type CrudSheetProps<TItem, TFilter extends Record<string, any>> = CrudShe
|
|
|
74
74
|
| { inlineEdit?: never; dialogEdit?: never }
|
|
75
75
|
);
|
|
76
76
|
|
|
77
|
-
interface CrudSheetBaseProps<TItem, TFilter extends Record<string,
|
|
77
|
+
interface CrudSheetBaseProps<TItem, TFilter extends Record<string, unknown>> {
|
|
78
78
|
search: (
|
|
79
79
|
filter: TFilter,
|
|
80
80
|
page: number | undefined,
|
|
@@ -83,10 +83,10 @@ interface CrudSheetBaseProps<TItem, TFilter extends Record<string, any>> {
|
|
|
83
83
|
getItemKey: (item: TItem) => string | number | undefined;
|
|
84
84
|
storageKey?: string;
|
|
85
85
|
editable?: boolean;
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
86
|
+
isItemEditable?: (item: TItem) => boolean;
|
|
87
|
+
isItemDeletable?: (item: TItem) => boolean;
|
|
88
|
+
isItemDeleted?: (item: TItem) => boolean;
|
|
89
|
+
isItemSelectable?: (item: TItem) => boolean | string;
|
|
90
90
|
lastModifiedAtProp?: string;
|
|
91
91
|
lastModifiedByProp?: string;
|
|
92
92
|
filterInitial?: TFilter;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { JSX } from "solid-js";
|
|
2
2
|
import { createSlots } from "../../../helpers/createSlots";
|
|
3
|
-
import type { CrudSheetColumnProps } from "./types";
|
|
3
|
+
import type { CrudSheetColumnProps } from "./CrudSheet.types";
|
|
4
4
|
|
|
5
5
|
const [SlotComponent, createCrudSheetColumnSlotsAccessor] = createSlots<CrudSheetColumnProps<any>>();
|
|
6
6
|
|
|
@@ -79,8 +79,8 @@ export type DataSelectButtonProps<
|
|
|
79
79
|
inset?: boolean;
|
|
80
80
|
/** Custom validation function */
|
|
81
81
|
validate?: (value: unknown) => string | undefined;
|
|
82
|
-
/**
|
|
83
|
-
|
|
82
|
+
/** lazyValidation: show error only after focus is lost */
|
|
83
|
+
lazyValidation?: boolean;
|
|
84
84
|
} & DialogPropsField<TDialogProps, TKey>;
|
|
85
85
|
|
|
86
86
|
const actionButtonClass = clsx(
|
|
@@ -113,7 +113,7 @@ export function DataSelectButton<
|
|
|
113
113
|
TKey = string | number,
|
|
114
114
|
TDialogProps extends SelectDialogBaseProps<TKey> = SelectDialogBaseProps<TKey>,
|
|
115
115
|
>(props: DataSelectButtonProps<TItem, TKey, TDialogProps>): JSX.Element {
|
|
116
|
-
const [local] = splitProps(props
|
|
116
|
+
const [local] = splitProps(props, [
|
|
117
117
|
"value",
|
|
118
118
|
"onValueChange",
|
|
119
119
|
"load",
|
|
@@ -127,8 +127,8 @@ export function DataSelectButton<
|
|
|
127
127
|
"size",
|
|
128
128
|
"inset",
|
|
129
129
|
"validate",
|
|
130
|
-
"
|
|
131
|
-
])
|
|
130
|
+
"lazyValidation",
|
|
131
|
+
]);
|
|
132
132
|
|
|
133
133
|
const i18n = useI18n();
|
|
134
134
|
const dialog = useDialog();
|
|
@@ -204,7 +204,7 @@ export function DataSelectButton<
|
|
|
204
204
|
if (local.multiple) {
|
|
205
205
|
setValue(newKeys);
|
|
206
206
|
} else {
|
|
207
|
-
setValue(
|
|
207
|
+
setValue(newKeys.length > 0 ? newKeys[0] : undefined);
|
|
208
208
|
}
|
|
209
209
|
}
|
|
210
210
|
};
|
|
@@ -213,7 +213,7 @@ export function DataSelectButton<
|
|
|
213
213
|
const handleClear = (e: MouseEvent) => {
|
|
214
214
|
e.stopPropagation();
|
|
215
215
|
if (local.multiple) {
|
|
216
|
-
setValue([] as
|
|
216
|
+
setValue([] as TKey[]);
|
|
217
217
|
} else {
|
|
218
218
|
setValue(undefined);
|
|
219
219
|
}
|
|
@@ -250,7 +250,7 @@ export function DataSelectButton<
|
|
|
250
250
|
});
|
|
251
251
|
|
|
252
252
|
return (
|
|
253
|
-
<Invalid message={errorMsg()} variant="border"
|
|
253
|
+
<Invalid message={errorMsg()} variant="border" lazyValidation={local.lazyValidation}>
|
|
254
254
|
<div data-data-select-button class="group inline-flex items-center">
|
|
255
255
|
<div
|
|
256
256
|
role="combobox"
|
|
@@ -40,14 +40,15 @@ const Action: Component<ActionProps> = (props) => {
|
|
|
40
40
|
/** SharedDataSelect Props */
|
|
41
41
|
export type SharedDataSelectProps<
|
|
42
42
|
TItem,
|
|
43
|
+
TKey extends string | number = string | number,
|
|
43
44
|
TDialogProps extends SelectDialogBaseProps = SelectDialogBaseProps,
|
|
44
45
|
> = {
|
|
45
46
|
/** Shared data accessor */
|
|
46
47
|
data: SharedDataAccessor<TItem>;
|
|
47
48
|
/** Currently selected key value (translated to item internally) */
|
|
48
|
-
value?:
|
|
49
|
+
value?: TKey | TKey[];
|
|
49
50
|
/** Value change callback (receives key, not item) */
|
|
50
|
-
onValueChange?: (value:
|
|
51
|
+
onValueChange?: (value: TKey | TKey[] | undefined) => void;
|
|
51
52
|
/** Multiple selection mode */
|
|
52
53
|
multiple?: boolean;
|
|
53
54
|
/** Required input */
|
|
@@ -68,34 +69,21 @@ export type SharedDataSelectProps<
|
|
|
68
69
|
children: JSX.Element;
|
|
69
70
|
} & DialogPropsField<TDialogProps>;
|
|
70
71
|
|
|
71
|
-
interface SharedDataSelectComponent {
|
|
72
|
-
<TItem, TDialogProps extends SelectDialogBaseProps = SelectDialogBaseProps>(
|
|
73
|
-
props: SharedDataSelectProps<TItem, TDialogProps>,
|
|
74
|
-
): JSX.Element;
|
|
75
|
-
ItemTemplate: typeof ItemTemplate;
|
|
76
|
-
Action: typeof Action;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
72
|
const SharedDataSelectBase = <
|
|
80
73
|
TItem,
|
|
74
|
+
TKey extends string | number = string | number,
|
|
81
75
|
TDialogProps extends SelectDialogBaseProps = SelectDialogBaseProps,
|
|
82
76
|
>(
|
|
83
|
-
props: SharedDataSelectProps<TItem, TDialogProps>,
|
|
77
|
+
props: SharedDataSelectProps<TItem, TKey, TDialogProps>,
|
|
84
78
|
): JSX.Element => {
|
|
85
|
-
const [local, rest] = splitProps(props
|
|
79
|
+
const [local, rest] = splitProps(props, [
|
|
86
80
|
"data",
|
|
87
81
|
"filterFn",
|
|
88
82
|
"dialog",
|
|
89
83
|
"dialogProps",
|
|
90
84
|
"dialogOptions",
|
|
91
85
|
"children",
|
|
92
|
-
])
|
|
93
|
-
typeof props,
|
|
94
|
-
Omit<
|
|
95
|
-
typeof props,
|
|
96
|
-
"data" | "filterFn" | "dialog" | "dialogProps" | "dialogOptions" | "children"
|
|
97
|
-
>,
|
|
98
|
-
];
|
|
86
|
+
]);
|
|
99
87
|
|
|
100
88
|
const i18n = useI18n();
|
|
101
89
|
const dialog = useDialog();
|
|
@@ -112,33 +100,33 @@ const SharedDataSelectBase = <
|
|
|
112
100
|
});
|
|
113
101
|
|
|
114
102
|
// Normalize value to keys array
|
|
115
|
-
const normalizeKeys = (value:
|
|
103
|
+
const normalizeKeys = (value: TKey | TKey[] | undefined | null): TKey[] => {
|
|
116
104
|
if (value === undefined || value === null) return [];
|
|
117
105
|
if (Array.isArray(value)) return value;
|
|
118
|
-
return [value
|
|
106
|
+
return [value];
|
|
119
107
|
};
|
|
120
108
|
|
|
121
109
|
// Translate key(s) to item(s) for Select's value prop
|
|
122
|
-
const keyToItem = (key:
|
|
110
|
+
const keyToItem = (key: TKey): TItem | undefined => {
|
|
123
111
|
return local.data.get(key);
|
|
124
112
|
};
|
|
125
113
|
|
|
126
114
|
const valueAsItem = createMemo((): TItem | TItem[] | undefined => {
|
|
127
|
-
const key = rest.value;
|
|
128
|
-
if (key === undefined
|
|
115
|
+
const key = rest.value as TKey | TKey[] | undefined;
|
|
116
|
+
if (key === undefined) return undefined;
|
|
129
117
|
if (Array.isArray(key)) {
|
|
130
118
|
return key
|
|
131
|
-
.map((k) => keyToItem(k
|
|
119
|
+
.map((k) => keyToItem(k))
|
|
132
120
|
.filter((v): v is TItem => v !== undefined);
|
|
133
121
|
}
|
|
134
|
-
return keyToItem(key
|
|
122
|
+
return keyToItem(key);
|
|
135
123
|
});
|
|
136
124
|
|
|
137
125
|
// Translate item back to key for onValueChange callback
|
|
138
|
-
const itemToKey = (item: TItem | TItem[] | undefined):
|
|
126
|
+
const itemToKey = (item: TItem | TItem[] | undefined): TKey | TKey[] | undefined => {
|
|
139
127
|
if (item === undefined || item === null) return undefined;
|
|
140
|
-
if (Array.isArray(item)) return item.map((i) => local.data.getKey(i));
|
|
141
|
-
return local.data.getKey(item);
|
|
128
|
+
if (Array.isArray(item)) return item.map((i) => local.data.getKey(i) as TKey);
|
|
129
|
+
return local.data.getKey(item) as TKey;
|
|
142
130
|
};
|
|
143
131
|
|
|
144
132
|
// Open dialog and handle selection result
|
|
@@ -153,7 +141,7 @@ const SharedDataSelectBase = <
|
|
|
153
141
|
selectedKeys: normalizeKeys(rest.value),
|
|
154
142
|
},
|
|
155
143
|
local.dialogOptions,
|
|
156
|
-
)) as { selectedKeys:
|
|
144
|
+
)) as { selectedKeys: TKey[] } | undefined;
|
|
157
145
|
|
|
158
146
|
if (result) {
|
|
159
147
|
const newKeys = result.selectedKeys;
|
|
@@ -191,7 +179,7 @@ const SharedDataSelectBase = <
|
|
|
191
179
|
get isItemHidden() {
|
|
192
180
|
return local.data.isItemHidden;
|
|
193
181
|
},
|
|
194
|
-
}) as
|
|
182
|
+
}) as SelectProps<TItem>;
|
|
195
183
|
|
|
196
184
|
return (
|
|
197
185
|
<ItemTemplateProvider>
|
|
@@ -218,6 +206,7 @@ const SharedDataSelectBase = <
|
|
|
218
206
|
);
|
|
219
207
|
};
|
|
220
208
|
|
|
221
|
-
export const SharedDataSelect
|
|
222
|
-
|
|
223
|
-
|
|
209
|
+
export const SharedDataSelect = Object.assign(SharedDataSelectBase, {
|
|
210
|
+
ItemTemplate,
|
|
211
|
+
Action,
|
|
212
|
+
});
|
|
@@ -44,10 +44,7 @@ export function SharedDataSelectButton<
|
|
|
44
44
|
>(
|
|
45
45
|
props: SharedDataSelectButtonProps<TItem, TDialogProps>,
|
|
46
46
|
): JSX.Element {
|
|
47
|
-
const [local, rest] = splitProps(props
|
|
48
|
-
Pick<typeof props, "data" | "children">,
|
|
49
|
-
Omit<typeof props, "data" | "children">,
|
|
50
|
-
];
|
|
47
|
+
const [local, rest] = splitProps(props, ["data", "children"]);
|
|
51
48
|
|
|
52
49
|
return (
|
|
53
50
|
<DataSelectButton
|