@vuu-ui/vuu-table-extras 4.2.5 → 4.3.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/package.json +12 -12
  2. package/src/bulk-edit-dialog/useBulkEditDialog.js +93 -0
  3. package/src/editable-table/EditableTable.css.js +41 -0
  4. package/src/editable-table/EditableTable.js +176 -0
  5. package/src/editable-table/EditableTableLayout.js +61 -0
  6. package/src/index.js +4 -0
  7. package/src/table-editor/TableEditorContext.js +9 -0
  8. package/src/table-editor/TableEditorControls.js +86 -0
  9. package/src/table-editor/TableEditorForm.js +142 -0
  10. package/src/table-editor/TableEditorLayout.css.js +16 -0
  11. package/src/table-editor/TableEditorLayout.js +30 -0
  12. package/src/table-editor/TableEditorProvider.js +434 -0
  13. package/src/table-editor/TableEditorTable.js +112 -0
  14. package/src/table-editor/index.js +5 -0
  15. package/types/bulk-edit-dialog/useBulkEditDialog.d.ts +27 -0
  16. package/types/editable-table/EditableTable.d.ts +178 -0
  17. package/types/editable-table/EditableTableLayout.d.ts +41 -0
  18. package/types/index.d.ts +4 -0
  19. package/types/inline-add-row/useInlineAddRow.d.ts +1 -0
  20. package/types/table-editor/TableEditorContext.d.ts +100 -0
  21. package/types/table-editor/TableEditorControls.d.ts +43 -0
  22. package/types/table-editor/TableEditorForm.d.ts +58 -0
  23. package/types/table-editor/TableEditorLayout.d.ts +10 -0
  24. package/types/table-editor/TableEditorProvider.d.ts +57 -0
  25. package/types/table-editor/TableEditorTable.d.ts +24 -0
  26. package/types/table-editor/index.d.ts +5 -0
  27. package/types/src/calculated-column/CalculatedColumnPanel.d.ts +0 -12
  28. package/types/src/calculated-column/useCalculatedColumnPanel.d.ts +0 -10
  29. package/types/src/calculated-column/useEditCalculatedColumn.d.ts +0 -13
  30. package/types/src/cell-edit-validators/CaseValidator.d.ts +0 -2
  31. package/types/src/cell-edit-validators/PatternValidator.d.ts +0 -2
  32. package/types/src/cell-edit-validators/index.d.ts +0 -2
  33. package/types/src/cell-renderers/background-cell/BackgroundCell.d.ts +0 -2
  34. package/types/src/cell-renderers/background-cell/BackgroundCellConfigurationEditor.d.ts +0 -2
  35. package/types/src/cell-renderers/background-cell/index.d.ts +0 -2
  36. package/types/src/cell-renderers/background-cell/useDirection.d.ts +0 -3
  37. package/types/src/cell-renderers/button-cell/IconButtonCell.d.ts +0 -6
  38. package/types/src/cell-renderers/dropdown-cell/DropdownCell.d.ts +0 -2
  39. package/types/src/cell-renderers/dropdown-cell/index.d.ts +0 -1
  40. package/types/src/cell-renderers/index.d.ts +0 -6
  41. package/types/src/cell-renderers/lookup-cell/LookupCell.d.ts +0 -2
  42. package/types/src/cell-renderers/lookup-cell/index.d.ts +0 -1
  43. package/types/src/cell-renderers/pct-progress-cell/PctProgressCell.d.ts +0 -2
  44. package/types/src/cell-renderers/pct-progress-cell/index.d.ts +0 -1
  45. package/types/src/cell-renderers/progress-cell/ProgressCell.d.ts +0 -1
  46. package/types/src/cell-renderers/progress-cell/index.d.ts +0 -1
  47. package/types/src/column-expression-input/ColumnExpressionInput.d.ts +0 -10
  48. package/types/src/column-expression-input/column-function-descriptors.d.ts +0 -15
  49. package/types/src/column-expression-input/column-language-parser/ColumnExpressionLanguage.d.ts +0 -2
  50. package/types/src/column-expression-input/column-language-parser/ColumnExpressionTreeWalker.d.ts +0 -57
  51. package/types/src/column-expression-input/column-language-parser/column-expression-parse-utils.d.ts +0 -5
  52. package/types/src/column-expression-input/column-language-parser/generated/column-parser.d.ts +0 -2
  53. package/types/src/column-expression-input/column-language-parser/generated/column-parser.terms.d.ts +0 -1
  54. package/types/src/column-expression-input/column-language-parser/index.d.ts +0 -3
  55. package/types/src/column-expression-input/column-language-parser/test.d.mts +0 -1
  56. package/types/src/column-expression-input/functionDocInfo.d.ts +0 -2
  57. package/types/src/column-expression-input/highlighting.d.ts +0 -1
  58. package/types/src/column-expression-input/index.d.ts +0 -4
  59. package/types/src/column-expression-input/theme.d.ts +0 -1
  60. package/types/src/column-expression-input/useColumnAutoComplete.d.ts +0 -6
  61. package/types/src/column-expression-input/useColumnExpressionEditor.d.ts +0 -25
  62. package/types/src/column-expression-input/useColumnExpressionSuggestionProvider.d.ts +0 -8
  63. package/types/src/column-formatting-settings/BaseNumericFormattingSettings.d.ts +0 -2
  64. package/types/src/column-formatting-settings/ColumnFormattingPanel.d.ts +0 -9
  65. package/types/src/column-formatting-settings/DateTimeFormattingSettings.d.ts +0 -3
  66. package/types/src/column-formatting-settings/LongTypeFormattingSettings.d.ts +0 -3
  67. package/types/src/column-formatting-settings/index.d.ts +0 -3
  68. package/types/src/column-menu/ColumnMenu.d.ts +0 -10
  69. package/types/src/column-menu/column-action-types.d.ts +0 -11
  70. package/types/src/column-menu/column-menu-utils.d.ts +0 -19
  71. package/types/src/column-menu/useColumnActions.d.ts +0 -16
  72. package/types/src/column-picker/ColumnModel.d.ts +0 -81
  73. package/types/src/column-picker/ColumnPicker.d.ts +0 -10
  74. package/types/src/column-picker/ColumnPickerAction.d.ts +0 -5
  75. package/types/src/column-picker/useColumnPicker.d.ts +0 -16
  76. package/types/src/column-picker/useTableColumnPicker.d.ts +0 -7
  77. package/types/src/column-picker/useTableColumnPickerDeprecated.d.ts +0 -14
  78. package/types/src/column-settings-panel/ColumnNameLabel.d.ts +0 -7
  79. package/types/src/column-settings-panel/ColumnSettingsPanel.d.ts +0 -5
  80. package/types/src/column-settings-panel/useColumnSettings.d.ts +0 -30
  81. package/types/src/csv-export/export-utils.d.ts +0 -42
  82. package/types/src/csv-export/index.d.ts +0 -2
  83. package/types/src/csv-export/useCsvExport.d.ts +0 -14
  84. package/types/src/csv-upload/CsvUpload.d.ts +0 -69
  85. package/types/src/csv-upload/data-upload-preview/DataUploadPreview.d.ts +0 -10
  86. package/types/src/csv-upload/data-upload-preview/useDataUploadPreview.d.ts +0 -17
  87. package/types/src/csv-upload/index.d.ts +0 -7
  88. package/types/src/csv-upload/parse/csv-constants.d.ts +0 -3
  89. package/types/src/csv-upload/parse/csv-errors.d.ts +0 -47
  90. package/types/src/csv-upload/parse/csv-parse.d.ts +0 -11
  91. package/types/src/csv-upload/parse/csv-schema-validation.d.ts +0 -18
  92. package/types/src/csv-upload/parse/csv-upload-utils.d.ts +0 -21
  93. package/types/src/csv-upload/parse/index.d.ts +0 -5
  94. package/types/src/csv-upload/useCsvUpload.d.ts +0 -43
  95. package/types/src/datasource-stats/DatasourceStats.d.ts +0 -17
  96. package/types/src/datasource-stats/useDatasourceStats.d.ts +0 -15
  97. package/types/src/freeze-control/FreezeControl.d.ts +0 -15
  98. package/types/src/freeze-control/FrozenBanner.d.ts +0 -6
  99. package/types/src/freeze-control/freezeControlBadge.d.ts +0 -11
  100. package/types/src/freeze-control/useFreezeControl.d.ts +0 -10
  101. package/types/src/index.d.ts +0 -26
  102. package/types/src/inline-add-row/InlineAddRow.d.ts +0 -3
  103. package/types/src/inline-add-row/index.d.ts +0 -2
  104. package/types/src/inline-add-row/useInlineAddRow.d.ts +0 -59
  105. package/types/src/tabbed-table-config-panel/TabbedTableConfigPanel.d.ts +0 -17
  106. package/types/src/tabbed-table-config-panel/TabbedTableSettingsAction.d.ts +0 -7
  107. package/types/src/tabbed-table-config-panel/useTabbedTableConfigPanel.d.ts +0 -13
  108. package/types/src/table-footer/TableFooter.d.ts +0 -10
  109. package/types/src/table-provider/TableProvider.d.ts +0 -18
  110. package/types/src/table-settings-panel/TableSettingsPanel.d.ts +0 -22
  111. package/types/src/table-settings-panel/useTableSettings.d.ts +0 -14
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "4.2.5",
2
+ "version": "4.3.0-beta.1",
3
3
  "author": "heswell",
4
4
  "main": "./src/index.js",
5
5
  "license": "Apache-2.0",
@@ -10,19 +10,19 @@
10
10
  "lezer-generate:column": "lezer-generator --output ./src/column-expression-input/column-language-parser/generated/column-parser.js ./src/column-expression-input/column-language-parser/grammar/column.grammar"
11
11
  },
12
12
  "devDependencies": {
13
- "@vuu-ui/vuu-filter-types": "4.2.5",
14
- "@vuu-ui/vuu-protocol-types": "4.2.5"
13
+ "@vuu-ui/vuu-filter-types": "4.3.0-beta.1",
14
+ "@vuu-ui/vuu-protocol-types": "4.3.0-beta.1"
15
15
  },
16
16
  "dependencies": {
17
- "@vuu-ui/vuu-codemirror": "4.2.5",
18
- "@vuu-ui/vuu-data-editing": "4.2.5",
19
- "@vuu-ui/vuu-data-react": "4.2.5",
20
- "@vuu-ui/vuu-data-types": "4.2.5",
21
- "@vuu-ui/vuu-table-types": "4.2.5",
22
- "@vuu-ui/vuu-popups": "4.2.5",
23
- "@vuu-ui/vuu-table": "4.2.5",
24
- "@vuu-ui/vuu-utils": "4.2.5",
25
- "@vuu-ui/vuu-ui-controls": "4.2.5",
17
+ "@vuu-ui/vuu-codemirror": "4.3.0-beta.1",
18
+ "@vuu-ui/vuu-data-editing": "4.3.0-beta.1",
19
+ "@vuu-ui/vuu-data-react": "4.3.0-beta.1",
20
+ "@vuu-ui/vuu-data-types": "4.3.0-beta.1",
21
+ "@vuu-ui/vuu-table-types": "4.3.0-beta.1",
22
+ "@vuu-ui/vuu-popups": "4.3.0-beta.1",
23
+ "@vuu-ui/vuu-table": "4.3.0-beta.1",
24
+ "@vuu-ui/vuu-utils": "4.3.0-beta.1",
25
+ "@vuu-ui/vuu-ui-controls": "4.3.0-beta.1",
26
26
  "@lezer/lr": "1.4.2",
27
27
  "@salt-ds/core": "1.74.0",
28
28
  "@salt-ds/styles": "0.4.2",
@@ -0,0 +1,93 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { DataEditingProvider, EditButtons, useEditableTable } from "@vuu-ui/vuu-data-editing";
3
+ import { BulkEditPanel } from "@vuu-ui/vuu-table";
4
+ import { useModal } from "@vuu-ui/vuu-ui-controls";
5
+ import { useCallback, useEffect, useRef, useState } from "react";
6
+ const NOT_EDITING = {
7
+ copyOption: "Selected",
8
+ editing: false
9
+ };
10
+ const useBulkEditDialog = ({ bulkEditPanelProps, confirmCancel, dataSource: sourceTableDataSource, deleteMode, editSessionApi, onCancelled, onError, onSaved, rowDefaults, saveLabel = "Save", title = "Edit rows" })=>{
11
+ const { closeDialog, showDialog } = useModal();
12
+ const [{ copyOption, editing }, setDialogState] = useState(NOT_EDITING);
13
+ const callbacksRef = useRef({
14
+ onCancelled,
15
+ onSaved
16
+ });
17
+ callbacksRef.current = {
18
+ onCancelled,
19
+ onSaved
20
+ };
21
+ const handleCancelled = useCallback(()=>{
22
+ setDialogState(NOT_EDITING);
23
+ callbacksRef.current.onCancelled?.();
24
+ }, []);
25
+ const handleSaved = useCallback(()=>{
26
+ setDialogState(NOT_EDITING);
27
+ callbacksRef.current.onSaved?.();
28
+ }, []);
29
+ const { editSession, onCancel, onSave, rowClassNameGenerators, sessionDataSource, sourceDataSource } = useEditableTable({
30
+ copyOption,
31
+ dataSource: sourceTableDataSource,
32
+ deleteMode,
33
+ editSessionApi,
34
+ isEditMode: editing,
35
+ onCancel: handleCancelled,
36
+ onError,
37
+ onSave: handleSaved,
38
+ rowDefaults
39
+ });
40
+ const editSelectedRows = useCallback(()=>{
41
+ setDialogState({
42
+ copyOption: "Selected",
43
+ editing: true
44
+ });
45
+ }, []);
46
+ const insertRows = useCallback(()=>{
47
+ setDialogState({
48
+ copyOption: "Empty",
49
+ editing: true
50
+ });
51
+ }, []);
52
+ useEffect(()=>{
53
+ if (editing && sessionDataSource) showDialog(/*#__PURE__*/ jsx(DataEditingProvider, {
54
+ editSession: editSession,
55
+ children: /*#__PURE__*/ jsx(BulkEditPanel, {
56
+ ...bulkEditPanelProps,
57
+ parentDs: sourceDataSource,
58
+ rowClassNameGenerators: rowClassNameGenerators,
59
+ sessionDs: sessionDataSource
60
+ })
61
+ }), title, [
62
+ /*#__PURE__*/ jsx(EditButtons, {
63
+ confirmCancel: confirmCancel,
64
+ editSession: editSession,
65
+ onCancel: onCancel,
66
+ onSave: onSave,
67
+ saveLabel: saveLabel
68
+ }, "edit-buttons")
69
+ ], true);
70
+ else closeDialog();
71
+ }, [
72
+ bulkEditPanelProps,
73
+ closeDialog,
74
+ confirmCancel,
75
+ editSession,
76
+ editing,
77
+ onCancel,
78
+ onSave,
79
+ rowClassNameGenerators,
80
+ saveLabel,
81
+ sessionDataSource,
82
+ showDialog,
83
+ sourceDataSource,
84
+ title
85
+ ]);
86
+ return {
87
+ editSelectedRows,
88
+ editSession,
89
+ insertRows,
90
+ isEditing: editing
91
+ };
92
+ };
93
+ export { useBulkEditDialog };
@@ -0,0 +1,41 @@
1
+ const css = `
2
+ .vuuEditableTable {
3
+ --vuuMeasuredContainer-flex: 1 1 1px;
4
+ flex-direction: column;
5
+ flex: auto;
6
+ min-width: 0;
7
+ height: 100%;
8
+ min-height: 0;
9
+ display: flex;
10
+ }
11
+
12
+ .vuuEditableTable-withPanel {
13
+ flex-direction: row;
14
+ }
15
+
16
+ .vuuEditableTable-main {
17
+ --vuuMeasuredContainer-flex: 1 1 1px;
18
+ flex-direction: column;
19
+ flex: auto;
20
+ min-width: 0;
21
+ min-height: 0;
22
+ display: flex;
23
+ }
24
+
25
+ .vuuEditableTable-panel {
26
+ --saltSidePanel-width: 320px;
27
+ }
28
+
29
+ .vuuEditableTable-panelHeader > :first-child {
30
+ flex: 1;
31
+ min-width: 0;
32
+ }
33
+
34
+ .vuuEditableTable-detail {
35
+ min-height: 0;
36
+ overflow: auto;
37
+ }
38
+
39
+
40
+ `;
41
+ export default css;
@@ -0,0 +1,176 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { SidePanelContent, SidePanelTitle } from "@salt-ds/core";
3
+ import { useComponentCssInjection } from "@salt-ds/styles";
4
+ import { useWindow } from "@salt-ds/window";
5
+ import clsx from "clsx";
6
+ import { TableEditorCreateForm, TableEditorEditButton, TableEditorForm, TableEditorModeToggle, TableEditorNewButton, TableEditorPlaceholder, TableEditorTable, TableEditorToolbar, useTableEditor } from "../table-editor/index.js";
7
+ import { TableEditorProvider } from "../table-editor/TableEditorProvider.js";
8
+ import EditableTable from "./EditableTable.css";
9
+ import { EditableTableFooter, EditableTableMain, EditableTablePanel, EditableTablePanelHeader } from "./EditableTableLayout.js";
10
+ const classBase = "vuuEditableTable";
11
+ const PanelTitle = ({ createTitle, formTitle })=>{
12
+ const { mode, selectedRow } = useTableEditor();
13
+ const title = "create" === mode ? createTitle : selectedRow ? "function" == typeof formTitle ? formTitle(selectedRow) : formTitle : null;
14
+ return title ? /*#__PURE__*/ jsx(SidePanelTitle, {
15
+ children: title
16
+ }) : null;
17
+ };
18
+ const InlineContent = ({ createFields, createTitle = "New", panelClassName, saveLabel, showEditModeToggle, testId, validateCreate, ...tableProps })=>{
19
+ const { createStrategy, editModel } = useTableEditor();
20
+ const hasCreateForm = "form" === createStrategy;
21
+ const showToggle = showEditModeToggle ?? "session" === editModel;
22
+ const table = /*#__PURE__*/ jsxs(Fragment, {
23
+ children: [
24
+ showToggle || hasCreateForm ? /*#__PURE__*/ jsxs(TableEditorToolbar, {
25
+ children: [
26
+ showToggle ? /*#__PURE__*/ jsx(TableEditorModeToggle, {
27
+ testId: testId
28
+ }) : null,
29
+ hasCreateForm ? /*#__PURE__*/ jsx(TableEditorNewButton, {
30
+ "data-testid": `new-button${testId}`
31
+ }) : null
32
+ ]
33
+ }) : null,
34
+ /*#__PURE__*/ jsx(TableEditorTable, {
35
+ "data-testid": `table${testId}`,
36
+ ...tableProps
37
+ }),
38
+ /*#__PURE__*/ jsx(EditableTableFooter, {
39
+ saveLabel: saveLabel
40
+ })
41
+ ]
42
+ });
43
+ return hasCreateForm ? /*#__PURE__*/ jsxs(Fragment, {
44
+ children: [
45
+ /*#__PURE__*/ jsx(EditableTableMain, {
46
+ children: table
47
+ }),
48
+ /*#__PURE__*/ jsxs(EditableTablePanel, {
49
+ className: panelClassName,
50
+ "data-testid": `edit-panel${testId}`,
51
+ children: [
52
+ /*#__PURE__*/ jsx(EditableTablePanelHeader, {
53
+ children: /*#__PURE__*/ jsx(PanelTitle, {
54
+ createTitle: createTitle
55
+ })
56
+ }),
57
+ /*#__PURE__*/ jsx(SidePanelContent, {
58
+ className: `${classBase}-detail`,
59
+ children: /*#__PURE__*/ jsx(TableEditorCreateForm, {
60
+ "data-testid": `create-form${testId}`,
61
+ fields: createFields,
62
+ validate: validateCreate
63
+ })
64
+ })
65
+ ]
66
+ })
67
+ ]
68
+ }) : table;
69
+ };
70
+ const FormContent = ({ allowCreate = true, createFields, createTitle = "New", fields, formTitle, panelClassName, placeholder = "Select a row to see its details", testId, validate, validateCreate = validate, ...tableProps })=>/*#__PURE__*/ jsxs(Fragment, {
71
+ children: [
72
+ /*#__PURE__*/ jsxs(EditableTableMain, {
73
+ children: [
74
+ /*#__PURE__*/ jsxs(TableEditorToolbar, {
75
+ children: [
76
+ /*#__PURE__*/ jsx(TableEditorEditButton, {
77
+ "data-testid": `edit-button${testId}`
78
+ }),
79
+ allowCreate ? /*#__PURE__*/ jsx(TableEditorNewButton, {
80
+ "data-testid": `new-button${testId}`
81
+ }) : null
82
+ ]
83
+ }),
84
+ /*#__PURE__*/ jsx(TableEditorTable, {
85
+ "data-testid": `table${testId}`,
86
+ ...tableProps
87
+ })
88
+ ]
89
+ }),
90
+ /*#__PURE__*/ jsxs(EditableTablePanel, {
91
+ className: panelClassName,
92
+ "data-testid": `edit-panel${testId}`,
93
+ children: [
94
+ /*#__PURE__*/ jsx(EditableTablePanelHeader, {
95
+ children: /*#__PURE__*/ jsx(PanelTitle, {
96
+ createTitle: createTitle,
97
+ formTitle: formTitle
98
+ })
99
+ }),
100
+ /*#__PURE__*/ jsxs(SidePanelContent, {
101
+ className: `${classBase}-detail`,
102
+ children: [
103
+ /*#__PURE__*/ jsx(TableEditorPlaceholder, {
104
+ children: placeholder
105
+ }),
106
+ /*#__PURE__*/ jsx(TableEditorForm, {
107
+ "data-testid": `edit-form${testId}`,
108
+ fields: fields,
109
+ validate: validate
110
+ }),
111
+ allowCreate ? /*#__PURE__*/ jsx(TableEditorCreateForm, {
112
+ "data-testid": `create-form${testId}`,
113
+ fields: createFields ?? fields,
114
+ validate: validateCreate
115
+ }) : null
116
+ ]
117
+ })
118
+ ]
119
+ })
120
+ ]
121
+ });
122
+ const Container = ({ children, className, style, testId })=>{
123
+ const targetWindow = useWindow();
124
+ useComponentCssInjection({
125
+ testId: "vuu-editable-table",
126
+ css: EditableTable,
127
+ window: targetWindow
128
+ });
129
+ const { createStrategy, editStrategy, mode, panelOpen } = useTableEditor();
130
+ return /*#__PURE__*/ jsx("div", {
131
+ className: clsx(classBase, className, `${classBase}-${mode}`, {
132
+ [`${classBase}-editing`]: "edit" === mode,
133
+ [`${classBase}-panelOpen`]: panelOpen,
134
+ [`${classBase}-withPanel`]: "form" === editStrategy || "form" === createStrategy
135
+ }),
136
+ "data-testid": `edit-table${testId}`,
137
+ style: style,
138
+ children: children
139
+ });
140
+ };
141
+ const EditableTable_EditableTable = (props)=>{
142
+ const { allowDelete = false, children, className, confirmCancel, copyOption, createStrategy, dataSource, defaultMode, deleteMode, editModel = "session", editSessionApi, editStrategy = "inline", mode, onCancelled, onError, onModeChange, onSaved, panelVisibility, rowDefaults, style, testId = "", ...contentProps } = props;
143
+ const isInlineDirect = "inline" === editStrategy && "direct" === editModel;
144
+ return /*#__PURE__*/ jsx(TableEditorProvider, {
145
+ allowDelete: allowDelete,
146
+ confirmCancel: confirmCancel,
147
+ copyOption: copyOption,
148
+ createStrategy: createStrategy,
149
+ dataSource: dataSource,
150
+ defaultMode: defaultMode ?? (isInlineDirect ? "edit" : "view"),
151
+ deleteMode: deleteMode,
152
+ editModel: editModel,
153
+ editSessionApi: editSessionApi,
154
+ editStrategy: editStrategy,
155
+ mode: mode,
156
+ onCancelled: onCancelled,
157
+ onError: onError,
158
+ onModeChange: onModeChange,
159
+ onSaved: onSaved,
160
+ panelVisibility: panelVisibility,
161
+ rowDefaults: rowDefaults,
162
+ children: /*#__PURE__*/ jsx(Container, {
163
+ className: className,
164
+ style: style,
165
+ testId: testId,
166
+ children: children ?? ("form" === editStrategy ? /*#__PURE__*/ jsx(FormContent, {
167
+ ...contentProps,
168
+ testId: testId
169
+ }) : /*#__PURE__*/ jsx(InlineContent, {
170
+ ...contentProps,
171
+ testId: testId
172
+ }))
173
+ })
174
+ });
175
+ };
176
+ export { EditableTable_EditableTable as EditableTable };
@@ -0,0 +1,61 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { SidePanel, SidePanelHeader, useForkRef } from "@salt-ds/core";
3
+ import clsx from "clsx";
4
+ import { forwardRef } from "react";
5
+ import { DataSourceStats } from "../datasource-stats/DatasourceStats.js";
6
+ import { TableEditorButtons, TableEditorPanelCloseButton } from "../table-editor/index.js";
7
+ import { useTableEditorContext } from "../table-editor/TableEditorContext.js";
8
+ import { TableFooter, TableFooterTray } from "../table-footer/TableFooter.js";
9
+ const EditableTableFooter = ({ children, saveLabel, ...htmlAttributes })=>{
10
+ const { dataSource, editableTable } = useTableEditorContext("EditableTableFooter");
11
+ return /*#__PURE__*/ jsx(TableFooter, {
12
+ ...htmlAttributes,
13
+ children: editableTable?.isEditSessionReady ? /*#__PURE__*/ jsx(TableFooterTray, {
14
+ position: "center",
15
+ children: /*#__PURE__*/ jsx(TableEditorButtons, {
16
+ saveLabel: saveLabel
17
+ })
18
+ }) : children ?? /*#__PURE__*/ jsx(DataSourceStats, {
19
+ dataSource: dataSource
20
+ })
21
+ });
22
+ };
23
+ const classBase = "vuuEditableTable";
24
+ const EditableTableLayout_EditableTableMain = /*#__PURE__*/ forwardRef(function({ className, ...htmlAttributes }, forwardedRef) {
25
+ return /*#__PURE__*/ jsx("div", {
26
+ ...htmlAttributes,
27
+ className: clsx(`${classBase}-main`, className),
28
+ ref: forwardedRef
29
+ });
30
+ });
31
+ const animationWidth = "--saltSidePanel-animation-width";
32
+ const measureAnimationWidth = (el)=>{
33
+ if (el?.classList.contains("saltSidePanel-enterAnimation") && !el.style.getPropertyValue(animationWidth)) {
34
+ const { animation } = el.style;
35
+ el.style.animation = "none";
36
+ const { width } = el.getBoundingClientRect();
37
+ el.style.animation = animation;
38
+ el.style.setProperty(animationWidth, `${width}px`);
39
+ }
40
+ };
41
+ const EditableTableLayout_EditableTablePanel = /*#__PURE__*/ forwardRef(function({ className, ...props }, forwardedRef) {
42
+ const ref = useForkRef(measureAnimationWidth, forwardedRef);
43
+ return /*#__PURE__*/ jsx(SidePanel, {
44
+ ...props,
45
+ className: clsx(`${classBase}-panel`, className),
46
+ position: "right",
47
+ ref: ref
48
+ });
49
+ });
50
+ const EditableTableLayout_EditableTablePanelHeader = /*#__PURE__*/ forwardRef(function({ canClose = true, children, className, ...props }, forwardedRef) {
51
+ return /*#__PURE__*/ jsxs(SidePanelHeader, {
52
+ ...props,
53
+ className: clsx(`${classBase}-panelHeader`, className),
54
+ ref: forwardedRef,
55
+ children: [
56
+ children,
57
+ canClose ? /*#__PURE__*/ jsx(TableEditorPanelCloseButton, {}) : null
58
+ ]
59
+ });
60
+ });
61
+ export { EditableTableFooter, EditableTableLayout_EditableTableMain as EditableTableMain, EditableTableLayout_EditableTablePanel as EditableTablePanel, EditableTableLayout_EditableTablePanelHeader as EditableTablePanelHeader };
package/src/index.js CHANGED
@@ -5,6 +5,7 @@ export * from "./cell-renderers/index.js";
5
5
  export * from "./column-expression-input/index.js";
6
6
  export * from "./column-formatting-settings/index.js";
7
7
  export * from "./inline-add-row/index.js";
8
+ export * from "./table-editor/index.js";
8
9
  export { CalculatedColumnPanel } from "./calculated-column/CalculatedColumnPanel.js";
9
10
  export { ColumnMenu } from "./column-menu/ColumnMenu.js";
10
11
  export { useColumnActions } from "./column-menu/useColumnActions.js";
@@ -22,3 +23,6 @@ export { TabbedTableSettingsAction } from "./tabbed-table-config-panel/TabbedTab
22
23
  export { TableFooter, TableFooterTray } from "./table-footer/TableFooter.js";
23
24
  export { TableProvider, useTableContext } from "./table-provider/TableProvider.js";
24
25
  export { TableSettingsPanel, defaultTableSettingsPermissions } from "./table-settings-panel/TableSettingsPanel.js";
26
+ export { useBulkEditDialog } from "./bulk-edit-dialog/useBulkEditDialog.js";
27
+ export { EditableTable } from "./editable-table/EditableTable.js";
28
+ export { EditableTableFooter, EditableTableMain, EditableTablePanel, EditableTablePanelHeader } from "./editable-table/EditableTableLayout.js";
@@ -0,0 +1,9 @@
1
+ import { createContext, useContext } from "react";
2
+ const TableEditorContext = createContext(void 0);
3
+ const useTableEditorContext = (componentName)=>{
4
+ const context = useContext(TableEditorContext);
5
+ if (void 0 === context) throw Error(`${componentName} must be used within an EditableTable`);
6
+ return context;
7
+ };
8
+ const useTableEditor = ()=>useTableEditorContext("useTableEditor");
9
+ export { TableEditorContext, useTableEditor, useTableEditorContext };
@@ -0,0 +1,86 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Button, SidePanelCloseButton, ToggleButton, ToggleButtonGroup } from "@salt-ds/core";
3
+ import { EditButtons, EditFormButtons, useEditFormContext } from "@vuu-ui/vuu-data-editing";
4
+ import { forwardRef, useCallback } from "react";
5
+ import { useTableEditorContext } from "./TableEditorContext.js";
6
+ const TableEditorButtons = ({ hideCancel, saveLabel })=>{
7
+ const { allowDelete, confirmCancel, editStrategy, editableTable } = useTableEditorContext("TableEditorButtons");
8
+ const form = useEditFormContext();
9
+ if (form || "form" === editStrategy) return form ? /*#__PURE__*/ jsx(EditFormButtons, {
10
+ confirmCancel: confirmCancel,
11
+ hideCancel: hideCancel,
12
+ saveLabel: saveLabel
13
+ }) : null;
14
+ if (editableTable) {
15
+ const { canCancel, canSave, editSession, hasSelection, onCancel, onDelete, onSave } = editableTable;
16
+ return /*#__PURE__*/ jsx(EditButtons, {
17
+ canCancel: canCancel,
18
+ canSave: canSave,
19
+ confirmCancel: confirmCancel,
20
+ editSession: editSession,
21
+ hasSelection: allowDelete ? hasSelection : void 0,
22
+ onCancel: hideCancel ? void 0 : onCancel,
23
+ onDelete: allowDelete ? onDelete : void 0,
24
+ onSave: onSave,
25
+ saveLabel: saveLabel
26
+ });
27
+ }
28
+ return null;
29
+ };
30
+ const TableEditorModeToggle = ({ "aria-label": ariaLabel = "Mode", disabled, testId = "", ...props })=>{
31
+ const { cancel, editStrategy, mode, selectedRow, startEdit } = useTableEditorContext("TableEditorModeToggle");
32
+ const handleChange = useCallback((e)=>{
33
+ if ("edit" === e.currentTarget.value) startEdit();
34
+ else cancel();
35
+ }, [
36
+ cancel,
37
+ startEdit
38
+ ]);
39
+ return /*#__PURE__*/ jsxs(ToggleButtonGroup, {
40
+ ...props,
41
+ "aria-label": ariaLabel,
42
+ disabled: disabled || "create" === mode || "form" === editStrategy && void 0 === selectedRow,
43
+ onChange: handleChange,
44
+ value: "edit" === mode ? "edit" : "view",
45
+ children: [
46
+ /*#__PURE__*/ jsx(ToggleButton, {
47
+ "data-testid": `toggle-view${testId}`,
48
+ value: "view",
49
+ children: "View"
50
+ }),
51
+ /*#__PURE__*/ jsx(ToggleButton, {
52
+ "data-testid": `toggle-edit${testId}`,
53
+ value: "edit",
54
+ children: "Edit"
55
+ })
56
+ ]
57
+ });
58
+ };
59
+ const TableEditorControls_TableEditorEditButton = /*#__PURE__*/ forwardRef(function({ children = "Edit", disabled, ...props }, ref) {
60
+ const { isEditing, selectedRow, startEdit } = useTableEditorContext("TableEditorEditButton");
61
+ return /*#__PURE__*/ jsx(Button, {
62
+ ...props,
63
+ disabled: disabled || isEditing || void 0 === selectedRow,
64
+ onClick: startEdit,
65
+ ref: ref,
66
+ children: children
67
+ });
68
+ });
69
+ const TableEditorControls_TableEditorNewButton = /*#__PURE__*/ forwardRef(function({ children = "New", disabled, ...props }, ref) {
70
+ const { canCreate, startCreate } = useTableEditorContext("TableEditorNewButton");
71
+ return /*#__PURE__*/ jsx(Button, {
72
+ ...props,
73
+ disabled: disabled || !canCreate,
74
+ onClick: startCreate,
75
+ ref: ref,
76
+ children: children
77
+ });
78
+ });
79
+ const TableEditorControls_TableEditorPanelCloseButton = /*#__PURE__*/ forwardRef(function(props, ref) {
80
+ const { canClosePanel } = useTableEditorContext("TableEditorPanelCloseButton");
81
+ return canClosePanel ? /*#__PURE__*/ jsx(SidePanelCloseButton, {
82
+ ...props,
83
+ ref: ref
84
+ }) : null;
85
+ });
86
+ export { TableEditorButtons, TableEditorControls_TableEditorEditButton as TableEditorEditButton, TableEditorControls_TableEditorNewButton as TableEditorNewButton, TableEditorControls_TableEditorPanelCloseButton as TableEditorPanelCloseButton, TableEditorModeToggle };
@@ -0,0 +1,142 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { createElement, useCallback, useLayoutEffect, useMemo, useRef } from "react";
3
+ import { CreateRowForm, EditField, EditForm, getFormFields, useEditFormContext } from "@vuu-ui/vuu-data-editing";
4
+ import { useTableEditorContext } from "./TableEditorContext.js";
5
+ const classBase = "vuuTableEditorForm";
6
+ const useFormFields = (fields, operation, enabled)=>{
7
+ const { columns, dataSource } = useTableEditorContext("TableEditorForm");
8
+ const schema = dataSource.tableSchema;
9
+ return useMemo(()=>enabled ? getFormFields({
10
+ columns,
11
+ fields,
12
+ operation,
13
+ schema
14
+ }) : [], [
15
+ columns,
16
+ enabled,
17
+ fields,
18
+ operation,
19
+ schema
20
+ ]);
21
+ };
22
+ const requiredNames = (fields)=>fields.filter(({ required })=>required).map(({ name })=>name);
23
+ const FormRegistration = ()=>{
24
+ const form = useEditFormContext();
25
+ const { formHandleRef } = useTableEditorContext("TableEditorForm");
26
+ useLayoutEffect(()=>{
27
+ formHandleRef.current = form ? {
28
+ cancel: form.cancel,
29
+ getValues: form.getValues,
30
+ isDirty: form.isDirty
31
+ } : void 0;
32
+ });
33
+ useLayoutEffect(()=>()=>{
34
+ formHandleRef.current = void 0;
35
+ }, [
36
+ formHandleRef
37
+ ]);
38
+ return null;
39
+ };
40
+ const TableEditorForm = ({ children, className, fields, onCancelled, onSaved, showButtons = void 0 === children, validate, ...formProps })=>{
41
+ const { confirmCancel, dataSource, editModel, editStrategy, formHandleRef, formSessionProps, mode, onEditCancelled, onEditSaved, selectedRow } = useTableEditorContext("TableEditorForm");
42
+ const formFields = useFormFields(fields, "update", void 0 === children);
43
+ const requiredColumns = useMemo(()=>requiredNames(formFields), [
44
+ formFields
45
+ ]);
46
+ const submittedValuesRef = useRef(void 0);
47
+ const validateEdit = useCallback((values)=>{
48
+ submittedValuesRef.current = values;
49
+ return validate?.(values);
50
+ }, [
51
+ validate
52
+ ]);
53
+ const handleCancelled = useCallback(()=>{
54
+ onCancelled?.();
55
+ onEditCancelled();
56
+ }, [
57
+ onCancelled,
58
+ onEditCancelled
59
+ ]);
60
+ const handleSaved = useCallback(()=>{
61
+ onSaved?.();
62
+ onEditSaved("direct" === editModel ? formHandleRef.current?.getValues() : submittedValuesRef.current);
63
+ }, [
64
+ editModel,
65
+ formHandleRef,
66
+ onEditSaved,
67
+ onSaved
68
+ ]);
69
+ if ("form" !== editStrategy || "create" === mode || void 0 === selectedRow) return null;
70
+ return /*#__PURE__*/ createElement(EditForm, {
71
+ ...formProps,
72
+ ...formSessionProps,
73
+ className: [
74
+ classBase,
75
+ className
76
+ ].filter(Boolean).join(" "),
77
+ confirmCancel: confirmCancel,
78
+ dataRow: selectedRow,
79
+ dataSource: dataSource,
80
+ editModel: editModel,
81
+ isEditMode: "edit" === mode,
82
+ key: selectedRow.key,
83
+ onCancelled: handleCancelled,
84
+ onSaved: handleSaved,
85
+ requiredColumns: requiredColumns,
86
+ showButtons: showButtons,
87
+ validate: validateEdit,
88
+ children: [
89
+ children ?? formFields.map((field)=>/*#__PURE__*/ jsx(EditField, {
90
+ column: field
91
+ }, field.name)),
92
+ /*#__PURE__*/ jsx(FormRegistration, {})
93
+ ]
94
+ });
95
+ };
96
+ const TableEditorCreateForm = ({ children, className, fields, onCancelled, onSaved, ...formProps })=>{
97
+ const { confirmCancel, createKey, createStrategy, dataSource, editModel, editSession, editStrategy, formSessionProps, mode, onCreateDone } = useTableEditorContext("TableEditorCreateForm");
98
+ const generatedFields = useFormFields(fields, "insert", void 0 !== fields || void 0 === children);
99
+ const formFields = useMemo(()=>fields ? generatedFields : generatedFields.map((field)=>field.required ? field : {
100
+ ...field,
101
+ required: false
102
+ }), [
103
+ fields,
104
+ generatedFields
105
+ ]);
106
+ const sharedEditSession = "inline" === editStrategy && "session" === editModel ? editSession : void 0;
107
+ const handleCancelled = useCallback(()=>{
108
+ onCancelled?.();
109
+ onCreateDone(false);
110
+ }, [
111
+ onCancelled,
112
+ onCreateDone
113
+ ]);
114
+ const handleSaved = useCallback(()=>{
115
+ onSaved?.();
116
+ onCreateDone(true);
117
+ }, [
118
+ onCreateDone,
119
+ onSaved
120
+ ]);
121
+ if ("form" !== createStrategy || "create" !== mode) return null;
122
+ return /*#__PURE__*/ createElement(CreateRowForm, {
123
+ ...formProps,
124
+ ...formSessionProps,
125
+ className: [
126
+ classBase,
127
+ className
128
+ ].filter(Boolean).join(" "),
129
+ confirmCancel: confirmCancel,
130
+ dataSource: dataSource,
131
+ editSession: sharedEditSession,
132
+ fields: formFields,
133
+ key: createKey,
134
+ onCancelled: handleCancelled,
135
+ onSaved: handleSaved,
136
+ children: [
137
+ children,
138
+ /*#__PURE__*/ jsx(FormRegistration, {})
139
+ ]
140
+ });
141
+ };
142
+ export { TableEditorCreateForm, TableEditorForm };