@dxos/react-ui-table 0.8.4-main.67995b8 → 0.8.4-main.70d3990
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/dist/lib/browser/chunk-5XWSB3JP.mjs +71 -0
- package/dist/lib/browser/chunk-5XWSB3JP.mjs.map +7 -0
- package/dist/lib/browser/{chunk-5XLSHLOG.mjs → chunk-KNC7XYT6.mjs} +573 -541
- package/dist/lib/browser/chunk-KNC7XYT6.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +625 -698
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +16 -24
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/browser/types/index.mjs +3 -3
- package/dist/lib/node-esm/{chunk-Y66YLSTC.mjs → chunk-CWSGS3Y2.mjs} +573 -541
- package/dist/lib/node-esm/chunk-CWSGS3Y2.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-MKTMOY46.mjs +72 -0
- package/dist/lib/node-esm/chunk-MKTMOY46.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +625 -698
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +16 -24
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/types/index.mjs +3 -3
- package/dist/types/src/components/Table/ColumnActionsMenu.d.ts +1 -1
- package/dist/types/src/components/Table/ColumnActionsMenu.d.ts.map +1 -1
- package/dist/types/src/components/Table/ColumnSettings.d.ts +1 -1
- package/dist/types/src/components/Table/ColumnSettings.d.ts.map +1 -1
- package/dist/types/src/components/Table/DynamicTable.d.ts +2 -2
- package/dist/types/src/components/Table/DynamicTable.d.ts.map +1 -1
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts +51 -3
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/Relations.stories.d.ts +108 -0
- package/dist/types/src/components/Table/Relations.stories.d.ts.map +1 -0
- package/dist/types/src/components/Table/RowActionsMenu.d.ts +1 -1
- package/dist/types/src/components/Table/RowActionsMenu.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.d.ts +8 -4
- package/dist/types/src/components/Table/Table.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.stories.d.ts +105 -4
- package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/CellValidationMessage.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts +12 -6
- package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +12 -17
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts +39 -4
- package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/index.d.ts +1 -0
- package/dist/types/src/components/TableCellEditor/index.d.ts.map +1 -1
- package/dist/types/src/components/TableToolbar/TableToolbar.d.ts +2 -2
- package/dist/types/src/components/TableToolbar/TableToolbar.d.ts.map +1 -1
- package/dist/types/src/components/testing.d.ts +3 -5
- package/dist/types/src/components/testing.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +2 -1
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useAddRow.d.ts +3 -2
- package/dist/types/src/hooks/useAddRow.d.ts.map +1 -1
- package/dist/types/src/hooks/useProjectionModel.d.ts +5 -0
- package/dist/types/src/hooks/useProjectionModel.d.ts.map +1 -0
- package/dist/types/src/hooks/useTableModel.d.ts +5 -6
- package/dist/types/src/hooks/useTableModel.d.ts.map +1 -1
- package/dist/types/src/model/modal-controller.d.ts +0 -7
- package/dist/types/src/model/modal-controller.d.ts.map +1 -1
- package/dist/types/src/model/selection-model.d.ts.map +1 -1
- package/dist/types/src/model/table-model.d.ts +14 -14
- package/dist/types/src/model/table-model.d.ts.map +1 -1
- package/dist/types/src/model/table-presentation.d.ts +2 -1
- package/dist/types/src/model/table-presentation.d.ts.map +1 -1
- package/dist/types/src/model/table-sorting.d.ts +9 -6
- package/dist/types/src/model/table-sorting.d.ts.map +1 -1
- package/dist/types/src/playwright/TableManager.d.ts +1 -1
- package/dist/types/src/playwright/TableManager.d.ts.map +1 -1
- package/dist/types/src/testing/useTestTableModel.d.ts +21 -34
- package/dist/types/src/testing/useTestTableModel.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +2 -2
- package/dist/types/src/types/Table.d.ts +28 -0
- package/dist/types/src/types/Table.d.ts.map +1 -0
- package/dist/types/src/types/index.d.ts +1 -1
- package/dist/types/src/types/index.d.ts.map +1 -1
- package/dist/types/src/util/dynamic-table.d.ts +9 -9
- package/dist/types/src/util/dynamic-table.d.ts.map +1 -1
- package/dist/types/src/util/index.d.ts +0 -1
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/src/util/schema.d.ts +1 -1
- package/dist/types/src/util/schema.d.ts.map +1 -1
- package/dist/types/src/util/table-buttons.d.ts.map +1 -1
- package/dist/types/src/util/table-controls.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +61 -59
- package/src/components/Table/ColumnActionsMenu.tsx +1 -1
- package/src/components/Table/ColumnSettings.tsx +1 -1
- package/src/components/Table/DynamicTable.stories.tsx +21 -17
- package/src/components/Table/DynamicTable.tsx +19 -13
- package/src/components/Table/Relations.stories.tsx +237 -0
- package/src/components/Table/RowActionsMenu.tsx +23 -15
- package/src/components/Table/Table.stories.tsx +103 -86
- package/src/components/Table/Table.tsx +140 -115
- package/src/components/TableCellEditor/CellValidationMessage.tsx +1 -1
- package/src/components/TableCellEditor/FormCellEditor.tsx +153 -42
- package/src/components/TableCellEditor/TableCellEditor.stories.tsx +28 -66
- package/src/components/TableCellEditor/TableCellEditor.tsx +75 -225
- package/src/components/TableCellEditor/index.ts +1 -0
- package/src/components/TableToolbar/TableToolbar.tsx +34 -24
- package/src/components/testing.ts +4 -4
- package/src/hooks/index.ts +2 -1
- package/src/hooks/useAddRow.ts +7 -5
- package/src/hooks/useProjectionModel.ts +19 -0
- package/src/hooks/useTableModel.ts +12 -14
- package/src/model/modal-controller.ts +1 -29
- package/src/model/selection-model.ts +3 -2
- package/src/model/table-model.test.ts +21 -12
- package/src/model/table-model.ts +62 -56
- package/src/model/table-presentation.test.ts +25 -23
- package/src/model/table-presentation.ts +82 -41
- package/src/model/table-sorting.ts +32 -14
- package/src/playwright/TableManager.ts +3 -3
- package/src/playwright/smoke.spec.ts +132 -38
- package/src/testing/useTestTableModel.ts +34 -22
- package/src/translations.ts +2 -2
- package/src/types/Table.ts +89 -0
- package/src/types/index.ts +1 -1
- package/src/util/dynamic-table.ts +20 -24
- package/src/util/index.ts +0 -1
- package/src/util/schema.ts +4 -4
- package/src/util/table-buttons.ts +4 -3
- package/src/util/table-controls.ts +4 -1
- package/dist/lib/browser/chunk-5XLSHLOG.mjs.map +0 -7
- package/dist/lib/browser/chunk-L2LSB6KV.mjs +0 -18
- package/dist/lib/browser/chunk-L2LSB6KV.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-NXZ4CJYX.mjs +0 -20
- package/dist/lib/node-esm/chunk-NXZ4CJYX.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-Y66YLSTC.mjs.map +0 -7
- package/dist/types/src/components/Table/CreateRefPanel.d.ts +0 -9
- package/dist/types/src/components/Table/CreateRefPanel.d.ts.map +0 -1
- package/dist/types/src/components/Table/relations.stories.d.ts +0 -9
- package/dist/types/src/components/Table/relations.stories.d.ts.map +0 -1
- package/dist/types/src/components/TableCellEditor/extension.d.ts +0 -13
- package/dist/types/src/components/TableCellEditor/extension.d.ts.map +0 -1
- package/dist/types/src/types/schema.d.ts +0 -8
- package/dist/types/src/types/schema.d.ts.map +0 -1
- package/dist/types/src/util/table.d.ts +0 -11
- package/dist/types/src/util/table.d.ts.map +0 -1
- package/src/components/Table/CreateRefPanel.tsx +0 -86
- package/src/components/Table/relations.stories.tsx +0 -116
- package/src/components/TableCellEditor/extension.ts +0 -61
- package/src/types/schema.ts +0 -16
- package/src/util/table.ts +0 -49
|
@@ -7,7 +7,6 @@ import {
|
|
|
7
7
|
TableModel,
|
|
8
8
|
TablePresentation,
|
|
9
9
|
cellClassesForRowSelection,
|
|
10
|
-
createTable,
|
|
11
10
|
getBaseSchema,
|
|
12
11
|
makeDynamicTable,
|
|
13
12
|
narrowSchema,
|
|
@@ -15,9 +14,10 @@ import {
|
|
|
15
14
|
tableControls,
|
|
16
15
|
touch,
|
|
17
16
|
useAddRow,
|
|
17
|
+
useProjectionModel,
|
|
18
18
|
useTableModel
|
|
19
|
-
} from "./chunk-
|
|
20
|
-
import "./chunk-
|
|
19
|
+
} from "./chunk-KNC7XYT6.mjs";
|
|
20
|
+
import "./chunk-5XWSB3JP.mjs";
|
|
21
21
|
|
|
22
22
|
// src/translations.ts
|
|
23
23
|
var translationKey = "react-ui-table";
|
|
@@ -29,8 +29,8 @@ var translations = [
|
|
|
29
29
|
"create object label": "Create table",
|
|
30
30
|
"table name placeholder": "Table name",
|
|
31
31
|
"settings title": "Table settings",
|
|
32
|
-
"table schema label": "
|
|
33
|
-
"new schema": "New
|
|
32
|
+
"table schema label": "Type",
|
|
33
|
+
"new schema": "New type",
|
|
34
34
|
"continue label": "Continue",
|
|
35
35
|
"create stack section label": "Create table",
|
|
36
36
|
"add row label": "Add row",
|
|
@@ -52,271 +52,37 @@ var translations = [
|
|
|
52
52
|
];
|
|
53
53
|
|
|
54
54
|
// src/components/Table/Table.tsx
|
|
55
|
-
import { useSignals as
|
|
56
|
-
import
|
|
57
|
-
import {
|
|
58
|
-
import { getValue } from "@dxos/echo-schema";
|
|
59
|
-
import { invariant as invariant3 } from "@dxos/invariant";
|
|
60
|
-
import { getSpace as getSpace2 } from "@dxos/react-client/echo";
|
|
61
|
-
import { useTranslation as useTranslation3 } from "@dxos/react-ui";
|
|
55
|
+
import { useSignals as _useSignals7 } from "@preact-signals/safe-react/tracking";
|
|
56
|
+
import * as String2 from "effect/String";
|
|
57
|
+
import React7, { forwardRef, useCallback as useCallback4, useEffect as useEffect3, useImperativeHandle, useMemo as useMemo4, useState as useState4 } from "react";
|
|
62
58
|
import { useAttention } from "@dxos/react-ui-attention";
|
|
63
|
-
import { closestCell,
|
|
59
|
+
import { Grid, closestCell, gridSeparatorBlockEnd, gridSeparatorInlineEnd } from "@dxos/react-ui-grid";
|
|
60
|
+
import { DxEditRequest } from "@dxos/react-ui-grid";
|
|
64
61
|
import { mx } from "@dxos/react-ui-theme";
|
|
65
|
-
import { isNotFalsy, safeParseInt } from "@dxos/util";
|
|
66
|
-
|
|
67
|
-
// src/components/Table/ColumnActionsMenu.tsx
|
|
68
|
-
import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
|
|
69
|
-
import React from "react";
|
|
70
|
-
import { DropdownMenu, useTranslation } from "@dxos/react-ui";
|
|
71
|
-
var ColumnActionsMenu = ({ model, modals }) => {
|
|
72
|
-
var _effect = _useSignals();
|
|
73
|
-
try {
|
|
74
|
-
const { t } = useTranslation(translationKey);
|
|
75
|
-
const state = modals.state.value;
|
|
76
|
-
if (state?.type !== "column") {
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
79
|
-
const currentSort = model.sorting?.sorting;
|
|
80
|
-
const isCurrentColumnSorted = currentSort?.fieldId === state.fieldId;
|
|
81
|
-
return /* @__PURE__ */ React.createElement(DropdownMenu.Root, {
|
|
82
|
-
modal: false,
|
|
83
|
-
open: true,
|
|
84
|
-
onOpenChange: modals.close
|
|
85
|
-
}, /* @__PURE__ */ React.createElement(DropdownMenu.VirtualTrigger, {
|
|
86
|
-
virtualRef: modals.trigger
|
|
87
|
-
}), /* @__PURE__ */ React.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React.createElement(DropdownMenu.Content, null, /* @__PURE__ */ React.createElement(DropdownMenu.Viewport, null, (!isCurrentColumnSorted || currentSort?.direction === "asc") && /* @__PURE__ */ React.createElement(DropdownMenu.Item, {
|
|
88
|
-
"data-testid": "column-sort-descending",
|
|
89
|
-
onClick: () => model.sorting?.setSort(state.fieldId, "desc")
|
|
90
|
-
}, t("column action sort descending")), (!isCurrentColumnSorted || currentSort?.direction === "desc") && /* @__PURE__ */ React.createElement(DropdownMenu.Item, {
|
|
91
|
-
"data-testid": "column-sort-ascending",
|
|
92
|
-
onClick: () => model.sorting?.setSort(state.fieldId, "asc")
|
|
93
|
-
}, t("column action sort ascending")), isCurrentColumnSorted && /* @__PURE__ */ React.createElement(DropdownMenu.Item, {
|
|
94
|
-
"data-testid": "column-clear-sort",
|
|
95
|
-
onClick: () => model.sorting?.clearSort()
|
|
96
|
-
}, t("column action clear sorting")), model.getColumnCount() > 1 && model.features.schemaEditable && /* @__PURE__ */ React.createElement(DropdownMenu.Item, {
|
|
97
|
-
"data-testid": "column-delete",
|
|
98
|
-
onClick: () => model.deleteColumn(state.fieldId)
|
|
99
|
-
}, t("column action delete")), model.features.schemaEditable && /* @__PURE__ */ React.createElement(DropdownMenu.Item, {
|
|
100
|
-
"data-testid": "column-settings",
|
|
101
|
-
onClick: () => modals.openColumnSettings()
|
|
102
|
-
}, t("column action settings"))), /* @__PURE__ */ React.createElement(DropdownMenu.Arrow, null))));
|
|
103
|
-
} finally {
|
|
104
|
-
_effect.f();
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
// src/components/Table/ColumnSettings.tsx
|
|
109
|
-
import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
|
|
110
|
-
import React2, { useCallback, useEffect, useMemo, useState } from "react";
|
|
111
|
-
import { Popover } from "@dxos/react-ui";
|
|
112
|
-
import { FieldEditor } from "@dxos/react-ui-form";
|
|
113
|
-
var ColumnSettings = ({ registry, model, modals, onNewColumn }) => {
|
|
114
|
-
var _effect = _useSignals2();
|
|
115
|
-
try {
|
|
116
|
-
const [newField, setNewField] = useState();
|
|
117
|
-
const state = modals.state.value;
|
|
118
|
-
useEffect(() => {
|
|
119
|
-
if (state?.type === "columnSettings" && state.mode.type === "create" && model?.projection) {
|
|
120
|
-
setNewField(model.projection.createFieldProjection());
|
|
121
|
-
requestAnimationFrame(() => {
|
|
122
|
-
onNewColumn();
|
|
123
|
-
});
|
|
124
|
-
} else {
|
|
125
|
-
setNewField(void 0);
|
|
126
|
-
}
|
|
127
|
-
}, [
|
|
128
|
-
model?.projection,
|
|
129
|
-
state
|
|
130
|
-
]);
|
|
131
|
-
const existingField = useMemo(() => {
|
|
132
|
-
if (state?.type === "columnSettings") {
|
|
133
|
-
const { mode } = state;
|
|
134
|
-
if (mode.type === "edit") {
|
|
135
|
-
return model?.projection?.fields.find((f) => f.id === mode.fieldId);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
return void 0;
|
|
139
|
-
}, [
|
|
140
|
-
model?.projection?.fields,
|
|
141
|
-
state
|
|
142
|
-
]);
|
|
143
|
-
const field = existingField ?? newField;
|
|
144
|
-
const handleSave = useCallback(() => {
|
|
145
|
-
modals.close();
|
|
146
|
-
}, [
|
|
147
|
-
modals
|
|
148
|
-
]);
|
|
149
|
-
const handleCancel = useCallback(() => {
|
|
150
|
-
if (state?.type === "columnSettings" && state.mode.type === "create" && newField) {
|
|
151
|
-
model?.projection.deleteFieldProjection(newField.id);
|
|
152
|
-
}
|
|
153
|
-
}, [
|
|
154
|
-
model?.projection,
|
|
155
|
-
state,
|
|
156
|
-
newField
|
|
157
|
-
]);
|
|
158
|
-
if (!model?.projection || !field) {
|
|
159
|
-
return null;
|
|
160
|
-
}
|
|
161
|
-
return /* @__PURE__ */ React2.createElement(Popover.Root, {
|
|
162
|
-
modal: false,
|
|
163
|
-
open: state?.type === "columnSettings"
|
|
164
|
-
}, /* @__PURE__ */ React2.createElement(Popover.VirtualTrigger, {
|
|
165
|
-
virtualRef: modals.trigger
|
|
166
|
-
}), /* @__PURE__ */ React2.createElement(Popover.Portal, null, /* @__PURE__ */ React2.createElement(Popover.Content, {
|
|
167
|
-
classNames: "md:is-64"
|
|
168
|
-
}, /* @__PURE__ */ React2.createElement(Popover.Viewport, null, /* @__PURE__ */ React2.createElement(FieldEditor, {
|
|
169
|
-
projection: model.projection,
|
|
170
|
-
field,
|
|
171
|
-
registry,
|
|
172
|
-
onSave: handleSave,
|
|
173
|
-
onCancel: handleCancel
|
|
174
|
-
})), /* @__PURE__ */ React2.createElement(Popover.Arrow, null))));
|
|
175
|
-
} finally {
|
|
176
|
-
_effect.f();
|
|
177
|
-
}
|
|
178
|
-
};
|
|
179
|
-
|
|
180
|
-
// src/components/Table/CreateRefPanel.tsx
|
|
181
|
-
import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
|
|
182
|
-
import { Schema } from "effect";
|
|
183
|
-
import React3, { useCallback as useCallback2, useMemo as useMemo2 } from "react";
|
|
184
|
-
import { live } from "@dxos/live-object";
|
|
185
|
-
import { getSpace } from "@dxos/react-client/echo";
|
|
186
|
-
import { Popover as Popover2 } from "@dxos/react-ui";
|
|
187
|
-
import { Form } from "@dxos/react-ui-form";
|
|
188
|
-
import { useGridContext } from "@dxos/react-ui-grid";
|
|
189
|
-
var CreateRefPanel = ({ model, modals, __gridScope }) => {
|
|
190
|
-
var _effect = _useSignals3();
|
|
191
|
-
try {
|
|
192
|
-
const { id: gridId } = useGridContext("TableCellEditor", __gridScope);
|
|
193
|
-
const space = model && getSpace(model?.view);
|
|
194
|
-
const state = modals.state.value;
|
|
195
|
-
const schema = useMemo2(() => {
|
|
196
|
-
if (!space || state?.type !== "createRefPanel") {
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
const [schema2] = space.db.schemaRegistry.query({
|
|
200
|
-
typename: state.typename
|
|
201
|
-
}).runSync();
|
|
202
|
-
if (schema2) {
|
|
203
|
-
const omit = Schema.omit("id");
|
|
204
|
-
return omit(schema2);
|
|
205
|
-
}
|
|
206
|
-
}, [
|
|
207
|
-
space,
|
|
208
|
-
state
|
|
209
|
-
]);
|
|
210
|
-
const handleSave = useCallback2((values) => {
|
|
211
|
-
if (!model || !space || state?.type !== "createRefPanel") {
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
214
|
-
const [schema2] = space.db.schemaRegistry.query({
|
|
215
|
-
typename: state.typename
|
|
216
|
-
}).runSync();
|
|
217
|
-
if (schema2) {
|
|
218
|
-
const obj = space.db.add(live(schema2, values));
|
|
219
|
-
state.onCreate?.(obj);
|
|
220
|
-
}
|
|
221
|
-
void modals.close();
|
|
222
|
-
}, [
|
|
223
|
-
modals,
|
|
224
|
-
space,
|
|
225
|
-
state
|
|
226
|
-
]);
|
|
227
|
-
const handleCancel = useCallback2(() => {
|
|
228
|
-
if (model) {
|
|
229
|
-
modals.close();
|
|
230
|
-
}
|
|
231
|
-
}, [
|
|
232
|
-
modals
|
|
233
|
-
]);
|
|
234
|
-
if (!model?.projection) {
|
|
235
|
-
return null;
|
|
236
|
-
}
|
|
237
|
-
return /* @__PURE__ */ React3.createElement(Popover2.Root, {
|
|
238
|
-
modal: false,
|
|
239
|
-
open: state?.type === "createRefPanel" && !!schema,
|
|
240
|
-
onOpenChange: (nextOpen) => {
|
|
241
|
-
if (model && !nextOpen) {
|
|
242
|
-
return modals.close();
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
}, /* @__PURE__ */ React3.createElement(Popover2.VirtualTrigger, {
|
|
246
|
-
virtualRef: modals.trigger
|
|
247
|
-
}), /* @__PURE__ */ React3.createElement(Popover2.Portal, null, /* @__PURE__ */ React3.createElement(Popover2.Content, {
|
|
248
|
-
classNames: "md:is-64",
|
|
249
|
-
"data-grid": gridId
|
|
250
|
-
}, /* @__PURE__ */ React3.createElement(Popover2.Viewport, null, state?.type === "createRefPanel" && schema && /* @__PURE__ */ React3.createElement(Form, {
|
|
251
|
-
schema,
|
|
252
|
-
values: state.initialValues ?? {},
|
|
253
|
-
onSave: handleSave,
|
|
254
|
-
onCancel: handleCancel
|
|
255
|
-
})), /* @__PURE__ */ React3.createElement(Popover2.Arrow, null))));
|
|
256
|
-
} finally {
|
|
257
|
-
_effect.f();
|
|
258
|
-
}
|
|
259
|
-
};
|
|
260
|
-
|
|
261
|
-
// src/components/Table/RowActionsMenu.tsx
|
|
262
|
-
import { useSignals as _useSignals4 } from "@preact-signals/safe-react/tracking";
|
|
263
|
-
import React4 from "react";
|
|
264
|
-
import { DropdownMenu as DropdownMenu2, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
265
|
-
var RowActionsMenu = ({ model, modals }) => {
|
|
266
|
-
var _effect = _useSignals4();
|
|
267
|
-
try {
|
|
268
|
-
const { t } = useTranslation2(translationKey);
|
|
269
|
-
const hasSelection = model.selection.hasSelection.value;
|
|
270
|
-
const state = modals.state.value;
|
|
271
|
-
if (state?.type !== "row") {
|
|
272
|
-
return null;
|
|
273
|
-
}
|
|
274
|
-
return /* @__PURE__ */ React4.createElement(DropdownMenu2.Root, {
|
|
275
|
-
modal: false,
|
|
276
|
-
open: true,
|
|
277
|
-
onOpenChange: modals.close
|
|
278
|
-
}, /* @__PURE__ */ React4.createElement(DropdownMenu2.VirtualTrigger, {
|
|
279
|
-
virtualRef: modals.trigger
|
|
280
|
-
}), /* @__PURE__ */ React4.createElement(DropdownMenu2.Content, null, /* @__PURE__ */ React4.createElement(DropdownMenu2.Viewport, null, model.features.dataEditable !== false && /* @__PURE__ */ React4.createElement(DropdownMenu2.Item, {
|
|
281
|
-
"data-testid": "row-menu-delete",
|
|
282
|
-
onClick: () => model.deleteRow(state.rowIndex)
|
|
283
|
-
}, t(hasSelection ? "bulk delete row label" : "delete row label")), model.rowActions?.map((action) => /* @__PURE__ */ React4.createElement(DropdownMenu2.Item, {
|
|
284
|
-
key: action.id,
|
|
285
|
-
"data-testid": `row-action-${action.id}`,
|
|
286
|
-
onClick: () => {
|
|
287
|
-
modals.close();
|
|
288
|
-
model.handleRowAction(action.id, state.rowIndex);
|
|
289
|
-
}
|
|
290
|
-
}, t(action.translationKey)))), /* @__PURE__ */ React4.createElement(DropdownMenu2.Arrow, null)));
|
|
291
|
-
} finally {
|
|
292
|
-
_effect.f();
|
|
293
|
-
}
|
|
294
|
-
};
|
|
295
62
|
|
|
296
63
|
// src/components/TableCellEditor/TableCellEditor.tsx
|
|
297
|
-
import { useSignals as
|
|
298
|
-
import
|
|
299
|
-
import {
|
|
64
|
+
import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
|
|
65
|
+
import { EditorView } from "@codemirror/view";
|
|
66
|
+
import React3, { useCallback as useCallback2, useMemo as useMemo2, useRef as useRef2, useState as useState2 } from "react";
|
|
67
|
+
import { debounce } from "@dxos/async";
|
|
68
|
+
import { Format as Format2, TypeEnum } from "@dxos/echo/internal";
|
|
300
69
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
301
|
-
import {
|
|
302
|
-
import { createMarkdownExtensions } from "@dxos/react-ui-editor";
|
|
303
|
-
import { cellQuery, editorKeys, parseCellIndex as parseCellIndex2, useGridContext as useGridContext4, GridCellEditor } from "@dxos/react-ui-grid";
|
|
304
|
-
import { tagPicker, createLinks } from "@dxos/react-ui-tag-picker";
|
|
70
|
+
import { GridCellEditor, editorKeys, parseCellIndex as parseCellIndex2, useGridContext as useGridContext3 } from "@dxos/react-ui-grid";
|
|
305
71
|
|
|
306
72
|
// src/components/TableCellEditor/CellValidationMessage.tsx
|
|
307
|
-
import { useSignals as
|
|
308
|
-
import
|
|
309
|
-
import { useGridContext
|
|
73
|
+
import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
|
|
74
|
+
import React from "react";
|
|
75
|
+
import { useGridContext } from "@dxos/react-ui-grid";
|
|
310
76
|
var CellValidationMessage = ({ validationError, variant = "error", __gridScope }) => {
|
|
311
|
-
var _effect =
|
|
77
|
+
var _effect = _useSignals();
|
|
312
78
|
try {
|
|
313
|
-
const { editing, editBox: box } =
|
|
79
|
+
const { editing, editBox: box } = useGridContext("GridSheetCellEditor", __gridScope);
|
|
314
80
|
if (!editing || !validationError) {
|
|
315
81
|
return null;
|
|
316
82
|
}
|
|
317
83
|
const bgClass = variant === "error" ? "bg-errorSurface" : "bg-warningSurface";
|
|
318
84
|
const textClass = variant === "error" ? "text-errorSurfaceText" : "text-warningSurfaceText";
|
|
319
|
-
return /* @__PURE__ */
|
|
85
|
+
return /* @__PURE__ */ React.createElement("div", {
|
|
320
86
|
role: "none",
|
|
321
87
|
className: `absolute ${bgClass} ${textClass} rounded-bs-sm text-xs p-1`,
|
|
322
88
|
style: {
|
|
@@ -335,71 +101,108 @@ var CellValidationMessage = ({ validationError, variant = "error", __gridScope }
|
|
|
335
101
|
};
|
|
336
102
|
|
|
337
103
|
// src/components/TableCellEditor/FormCellEditor.tsx
|
|
338
|
-
import { useSignals as
|
|
339
|
-
import
|
|
340
|
-
import {
|
|
104
|
+
import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
|
|
105
|
+
import * as Schema from "effect/Schema";
|
|
106
|
+
import React2, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
107
|
+
import { Filter, Obj } from "@dxos/echo";
|
|
108
|
+
import { Format, Ref, getValue } from "@dxos/echo/internal";
|
|
341
109
|
import { invariant } from "@dxos/invariant";
|
|
342
|
-
import {
|
|
343
|
-
import {
|
|
344
|
-
import {
|
|
345
|
-
import {
|
|
110
|
+
import { getSnapshot } from "@dxos/live-object";
|
|
111
|
+
import { getSpace } from "@dxos/react-client/echo";
|
|
112
|
+
import { Popover } from "@dxos/react-ui";
|
|
113
|
+
import { Form } from "@dxos/react-ui-form";
|
|
114
|
+
import { parseCellIndex, useGridContext as useGridContext2 } from "@dxos/react-ui-grid";
|
|
115
|
+
import { getDeep, isTruthy, setDeep } from "@dxos/util";
|
|
346
116
|
var __dxlog_file = "/__w/dxos/dxos/packages/ui/react-ui-table/src/components/TableCellEditor/FormCellEditor.tsx";
|
|
347
|
-
var
|
|
348
|
-
|
|
117
|
+
var createOptionLabel = [
|
|
118
|
+
"create new object label",
|
|
119
|
+
{
|
|
120
|
+
ns: translationKey
|
|
121
|
+
}
|
|
122
|
+
];
|
|
123
|
+
var FormCellEditor = ({ fieldProjection, model, schema, onSave, client, modals, onCreate, __gridScope, ...formProps }) => {
|
|
124
|
+
var _effect = _useSignals2();
|
|
349
125
|
try {
|
|
350
|
-
const { editing: contextEditing, setEditing } =
|
|
351
|
-
const [editing, setLocalEditing] =
|
|
126
|
+
const { editing: contextEditing, setEditing, id: gridId } = useGridContext2("ArrayEditor", __gridScope);
|
|
127
|
+
const [editing, setLocalEditing] = useState(false);
|
|
352
128
|
const anchorRef = useRef(null);
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
129
|
+
const getSchema = useCallback((typeAnnotation) => {
|
|
130
|
+
const space = getSpace(model.view);
|
|
131
|
+
invariant(space, void 0, {
|
|
132
|
+
F: __dxlog_file,
|
|
133
|
+
L: 57,
|
|
134
|
+
S: void 0,
|
|
135
|
+
A: [
|
|
136
|
+
"space",
|
|
137
|
+
""
|
|
138
|
+
]
|
|
139
|
+
});
|
|
140
|
+
let schema2;
|
|
141
|
+
if (client) {
|
|
142
|
+
schema2 = client.graph.schemaRegistry.getSchema(typeAnnotation.typename);
|
|
143
|
+
}
|
|
144
|
+
if (!schema2) {
|
|
145
|
+
schema2 = space.db.schemaRegistry.getSchema(typeAnnotation.typename);
|
|
360
146
|
}
|
|
147
|
+
return {
|
|
148
|
+
space,
|
|
149
|
+
schema: schema2
|
|
150
|
+
};
|
|
361
151
|
}, [
|
|
362
|
-
|
|
152
|
+
client,
|
|
153
|
+
model
|
|
363
154
|
]);
|
|
364
|
-
const
|
|
365
|
-
|
|
366
|
-
|
|
155
|
+
const handleQueryRefOptions = useCallback(async (typeAnnotation) => {
|
|
156
|
+
const { schema: schema2, space } = getSchema(typeAnnotation);
|
|
157
|
+
if (model && schema2 && space) {
|
|
158
|
+
const { objects } = await space.db.query(Filter.type(schema2)).run();
|
|
159
|
+
return objects.map((obj) => {
|
|
160
|
+
return {
|
|
161
|
+
dxn: Obj.getDXN(obj),
|
|
162
|
+
label: getValue(obj, fieldProjection.field.referencePath) || obj.id.toString()
|
|
163
|
+
};
|
|
164
|
+
}).filter(isTruthy);
|
|
367
165
|
}
|
|
368
|
-
return
|
|
369
|
-
fieldProjection.field.path
|
|
370
|
-
]);
|
|
166
|
+
return [];
|
|
371
167
|
}, [
|
|
372
|
-
|
|
373
|
-
|
|
168
|
+
client,
|
|
169
|
+
model
|
|
374
170
|
]);
|
|
375
|
-
const originalRow =
|
|
171
|
+
const originalRow = useMemo(() => {
|
|
376
172
|
if (model && contextEditing) {
|
|
377
173
|
const cell = parseCellIndex(contextEditing.index);
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
174
|
+
if (model.isDraftCell(cell)) {
|
|
175
|
+
const draftRow = model.draftRows.value[cell.row];
|
|
176
|
+
invariant(draftRow, void 0, {
|
|
177
|
+
F: __dxlog_file,
|
|
178
|
+
L: 98,
|
|
179
|
+
S: void 0,
|
|
180
|
+
A: [
|
|
181
|
+
"draftRow",
|
|
182
|
+
""
|
|
183
|
+
]
|
|
184
|
+
});
|
|
185
|
+
return draftRow.data;
|
|
186
|
+
} else {
|
|
187
|
+
const row = model.getRowAt(cell.row);
|
|
188
|
+
invariant(row, void 0, {
|
|
189
|
+
F: __dxlog_file,
|
|
190
|
+
L: 102,
|
|
191
|
+
S: void 0,
|
|
192
|
+
A: [
|
|
193
|
+
"row",
|
|
194
|
+
""
|
|
195
|
+
]
|
|
196
|
+
});
|
|
197
|
+
return row;
|
|
198
|
+
}
|
|
389
199
|
}
|
|
390
200
|
return void 0;
|
|
391
201
|
}, [
|
|
392
202
|
model,
|
|
393
203
|
contextEditing
|
|
394
204
|
]);
|
|
395
|
-
const
|
|
396
|
-
if (originalRow) {
|
|
397
|
-
return getSnapshot(originalRow);
|
|
398
|
-
}
|
|
399
|
-
}, [
|
|
400
|
-
originalRow
|
|
401
|
-
]);
|
|
402
|
-
const handleSave = useCallback3((values) => {
|
|
205
|
+
const handleSave = useCallback((values) => {
|
|
403
206
|
const path = fieldProjection.field.path;
|
|
404
207
|
const value = getDeep(values, [
|
|
405
208
|
path
|
|
@@ -407,93 +210,128 @@ var FormCellEditor = ({ fieldProjection, model, schema, onSave, __gridScope }) =
|
|
|
407
210
|
setDeep(originalRow, [
|
|
408
211
|
path
|
|
409
212
|
], value);
|
|
213
|
+
contextEditing?.cellElement?.focus();
|
|
410
214
|
setEditing(null);
|
|
411
215
|
setLocalEditing(false);
|
|
412
216
|
onSave?.();
|
|
413
217
|
}, [
|
|
414
218
|
fieldProjection.field.path,
|
|
219
|
+
onSave,
|
|
220
|
+
contextEditing,
|
|
221
|
+
originalRow
|
|
222
|
+
]);
|
|
223
|
+
useEffect(() => {
|
|
224
|
+
if (contextEditing && contextEditing.cellElement) {
|
|
225
|
+
anchorRef.current = contextEditing.cellElement.querySelector(".dx-grid__cell__content");
|
|
226
|
+
setLocalEditing(true);
|
|
227
|
+
} else {
|
|
228
|
+
anchorRef.current = null;
|
|
229
|
+
setLocalEditing(false);
|
|
230
|
+
}
|
|
231
|
+
}, [
|
|
232
|
+
contextEditing
|
|
233
|
+
]);
|
|
234
|
+
const narrowedSchema = useMemo(() => {
|
|
235
|
+
if (!schema) {
|
|
236
|
+
return void 0;
|
|
237
|
+
}
|
|
238
|
+
return narrowSchema(schema, [
|
|
239
|
+
fieldProjection.field.path
|
|
240
|
+
]);
|
|
241
|
+
}, [
|
|
242
|
+
JSON.stringify(schema),
|
|
243
|
+
fieldProjection.field.path
|
|
244
|
+
]);
|
|
245
|
+
const formValues = useMemo(() => originalRow ? getSnapshot(originalRow) : {}, [
|
|
415
246
|
originalRow
|
|
416
247
|
]);
|
|
417
|
-
const handleOpenChange =
|
|
248
|
+
const handleOpenChange = useCallback((nextOpen) => {
|
|
418
249
|
if (nextOpen === false) {
|
|
419
250
|
setEditing(null);
|
|
420
251
|
onSave?.();
|
|
421
252
|
}
|
|
422
253
|
setLocalEditing(nextOpen);
|
|
423
254
|
}, []);
|
|
255
|
+
const refSchema = useMemo(() => {
|
|
256
|
+
if (fieldProjection.props.format === Format.TypeFormat.Ref && fieldProjection.props.referenceSchema) {
|
|
257
|
+
const { schema: refSchema2 } = getSchema({
|
|
258
|
+
typename: fieldProjection.props.referenceSchema
|
|
259
|
+
});
|
|
260
|
+
return refSchema2;
|
|
261
|
+
}
|
|
262
|
+
return null;
|
|
263
|
+
}, [
|
|
264
|
+
fieldProjection.props.format,
|
|
265
|
+
fieldProjection.props.referenceSchema,
|
|
266
|
+
getSchema
|
|
267
|
+
]);
|
|
268
|
+
const createSchema = useMemo(() => {
|
|
269
|
+
return refSchema ? Schema.omit("id")(refSchema) : null;
|
|
270
|
+
}, [
|
|
271
|
+
refSchema
|
|
272
|
+
]);
|
|
273
|
+
const handleCreate = useCallback((values) => {
|
|
274
|
+
if (refSchema && onCreate) {
|
|
275
|
+
const objectWithId = onCreate(refSchema, values);
|
|
276
|
+
if (objectWithId) {
|
|
277
|
+
const ref = Ref.make(objectWithId);
|
|
278
|
+
const path = fieldProjection.field.path;
|
|
279
|
+
setDeep(originalRow, [
|
|
280
|
+
path
|
|
281
|
+
], ref);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
contextEditing?.cellElement?.focus();
|
|
285
|
+
setEditing(null);
|
|
286
|
+
setLocalEditing(false);
|
|
287
|
+
onSave?.();
|
|
288
|
+
}, [
|
|
289
|
+
fieldProjection.field.path,
|
|
290
|
+
onSave,
|
|
291
|
+
contextEditing,
|
|
292
|
+
originalRow,
|
|
293
|
+
refSchema,
|
|
294
|
+
onCreate
|
|
295
|
+
]);
|
|
424
296
|
if (!editing) {
|
|
425
297
|
return null;
|
|
426
298
|
}
|
|
427
|
-
return /* @__PURE__ */
|
|
299
|
+
return /* @__PURE__ */ React2.createElement(Popover.Root, {
|
|
428
300
|
open: editing,
|
|
429
301
|
onOpenChange: handleOpenChange
|
|
430
|
-
}, /* @__PURE__ */
|
|
302
|
+
}, /* @__PURE__ */ React2.createElement(Popover.VirtualTrigger, {
|
|
431
303
|
virtualRef: anchorRef
|
|
432
|
-
}), /* @__PURE__ */
|
|
304
|
+
}), /* @__PURE__ */ React2.createElement(Popover.Portal, null, /* @__PURE__ */ React2.createElement(Popover.Content, {
|
|
433
305
|
tabIndex: -1,
|
|
434
306
|
classNames: "popover-card-width density-fine"
|
|
435
|
-
}, /* @__PURE__ */
|
|
307
|
+
}, /* @__PURE__ */ React2.createElement(Popover.Arrow, null), /* @__PURE__ */ React2.createElement(Popover.Viewport, null, /* @__PURE__ */ React2.createElement(Form, {
|
|
308
|
+
autoFocus: true,
|
|
436
309
|
values: formValues,
|
|
437
310
|
schema: narrowedSchema,
|
|
438
|
-
onSave: handleSave
|
|
439
|
-
|
|
311
|
+
onSave: handleSave,
|
|
312
|
+
...formProps,
|
|
313
|
+
onQueryRefOptions: handleQueryRefOptions,
|
|
314
|
+
...createSchema && {
|
|
315
|
+
onCreate: handleCreate,
|
|
316
|
+
createSchema,
|
|
317
|
+
createInitialValuePath: fieldProjection.field.referencePath,
|
|
318
|
+
createOptionIcon: "ph--plus--regular",
|
|
319
|
+
createOptionLabel
|
|
320
|
+
}
|
|
321
|
+
})))));
|
|
440
322
|
} finally {
|
|
441
323
|
_effect.f();
|
|
442
324
|
}
|
|
443
325
|
};
|
|
444
326
|
|
|
445
|
-
// src/components/TableCellEditor/extension.ts
|
|
446
|
-
import { autocompletion, pickedCompletion } from "@codemirror/autocomplete";
|
|
447
|
-
import { EditorView } from "@codemirror/view";
|
|
448
|
-
var completion = ({ debug, onQuery, onMatch }) => {
|
|
449
|
-
return [
|
|
450
|
-
EditorView.theme({
|
|
451
|
-
".cm-completionDialog": {
|
|
452
|
-
width: "var(--dx-gridCellWidth)"
|
|
453
|
-
}
|
|
454
|
-
}),
|
|
455
|
-
autocompletion({
|
|
456
|
-
icons: false,
|
|
457
|
-
activateOnTyping: true,
|
|
458
|
-
closeOnBlur: !debug,
|
|
459
|
-
override: [
|
|
460
|
-
async (context) => {
|
|
461
|
-
const text = context.state.doc.toString();
|
|
462
|
-
return {
|
|
463
|
-
from: 0,
|
|
464
|
-
options: await onQuery(text)
|
|
465
|
-
};
|
|
466
|
-
}
|
|
467
|
-
],
|
|
468
|
-
// TODO(burdon): Consts from grid (to line-up with grid).
|
|
469
|
-
tooltipClass: () => "cm-completionDialog !mt-[8px] !-ml-[4px] [&>ul]:!max-h-[264px]",
|
|
470
|
-
optionClass: () => "flex h-[33px] items-center"
|
|
471
|
-
}),
|
|
472
|
-
// Check for accepted completion metadata in the transaction.
|
|
473
|
-
EditorView.updateListener.of((update) => {
|
|
474
|
-
update.transactions.forEach((tr) => {
|
|
475
|
-
const completion2 = tr.annotation(pickedCompletion);
|
|
476
|
-
if (completion2) {
|
|
477
|
-
onMatch(completion2.data);
|
|
478
|
-
}
|
|
479
|
-
});
|
|
480
|
-
})
|
|
481
|
-
];
|
|
482
|
-
};
|
|
483
|
-
|
|
484
327
|
// src/components/TableCellEditor/TableCellEditor.tsx
|
|
485
328
|
var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-table/src/components/TableCellEditor/TableCellEditor.tsx";
|
|
486
|
-
var
|
|
487
|
-
var
|
|
488
|
-
|
|
489
|
-
text
|
|
490
|
-
});
|
|
491
|
-
var isCreateOption = (data) => typeof data === "object" && data[newValue];
|
|
492
|
-
var TableValueEditor = ({ model, modals, schema, onEnter, onFocus, onSave, onQuery, __gridScope }) => {
|
|
493
|
-
var _effect = _useSignals7();
|
|
329
|
+
var adaptValidationMessage = (message) => message ? message.endsWith("is missing") ? "Can\u2019t be blank" : message : null;
|
|
330
|
+
var TableValueEditor = ({ model, modals, schema, onFocus, onSave, onCreate, client, __gridScope }) => {
|
|
331
|
+
var _effect = _useSignals3();
|
|
494
332
|
try {
|
|
495
|
-
const { editing } =
|
|
496
|
-
const fieldProjection =
|
|
333
|
+
const { editing } = useGridContext3("TableValueEditor", __gridScope);
|
|
334
|
+
const fieldProjection = useMemo2(() => {
|
|
497
335
|
if (!model || !editing) {
|
|
498
336
|
return;
|
|
499
337
|
}
|
|
@@ -502,7 +340,7 @@ var TableValueEditor = ({ model, modals, schema, onEnter, onFocus, onSave, onQue
|
|
|
502
340
|
const fieldProjection2 = model.projection.getFieldProjection(field.id);
|
|
503
341
|
invariant2(fieldProjection2, void 0, {
|
|
504
342
|
F: __dxlog_file2,
|
|
505
|
-
L:
|
|
343
|
+
L: 71,
|
|
506
344
|
S: void 0,
|
|
507
345
|
A: [
|
|
508
346
|
"fieldProjection",
|
|
@@ -514,21 +352,22 @@ var TableValueEditor = ({ model, modals, schema, onEnter, onFocus, onSave, onQue
|
|
|
514
352
|
model,
|
|
515
353
|
editing
|
|
516
354
|
]);
|
|
517
|
-
if (fieldProjection?.props.type === TypeEnum.Array || fieldProjection?.props.format ===
|
|
518
|
-
return /* @__PURE__ */
|
|
355
|
+
if (fieldProjection?.props.type === TypeEnum.Array || fieldProjection?.props.format === Format2.TypeFormat.SingleSelect || fieldProjection?.props.format === Format2.TypeFormat.Ref) {
|
|
356
|
+
return /* @__PURE__ */ React3.createElement(FormCellEditor, {
|
|
519
357
|
fieldProjection,
|
|
520
358
|
model,
|
|
521
359
|
schema,
|
|
522
360
|
__gridScope,
|
|
523
|
-
onSave
|
|
361
|
+
onSave,
|
|
362
|
+
onCreate,
|
|
363
|
+
client,
|
|
364
|
+
modals
|
|
524
365
|
});
|
|
525
366
|
}
|
|
526
|
-
return /* @__PURE__ */
|
|
367
|
+
return /* @__PURE__ */ React3.createElement(TableCellEditor, {
|
|
527
368
|
model,
|
|
528
369
|
modals,
|
|
529
|
-
onEnter,
|
|
530
370
|
onFocus,
|
|
531
|
-
onQuery,
|
|
532
371
|
onSave,
|
|
533
372
|
__gridScope
|
|
534
373
|
});
|
|
@@ -537,19 +376,18 @@ var TableValueEditor = ({ model, modals, schema, onEnter, onFocus, onSave, onQue
|
|
|
537
376
|
}
|
|
538
377
|
};
|
|
539
378
|
var editorSlots = {
|
|
540
|
-
|
|
379
|
+
scroll: {
|
|
541
380
|
className: "!plb-[--dx-grid-cell-editor-padding-block]"
|
|
542
381
|
}
|
|
543
382
|
};
|
|
544
|
-
var TableCellEditor = ({ model, modals,
|
|
545
|
-
var _effect =
|
|
383
|
+
var TableCellEditor = ({ model, modals, onFocus, onSave, __gridScope }) => {
|
|
384
|
+
var _effect = _useSignals3();
|
|
546
385
|
try {
|
|
547
|
-
const {
|
|
386
|
+
const { editing, setEditing } = useGridContext3("TableCellEditor", __gridScope);
|
|
548
387
|
const suppressNextBlur = useRef2(false);
|
|
549
|
-
const
|
|
550
|
-
const [
|
|
551
|
-
const
|
|
552
|
-
const fieldProjection = useMemo4(() => {
|
|
388
|
+
const [validationError, setValidationError] = useState2(null);
|
|
389
|
+
const [validationVariant, setValidationVariant] = useState2("error");
|
|
390
|
+
const fieldProjection = useMemo2(() => {
|
|
553
391
|
if (!model || !editing) {
|
|
554
392
|
return;
|
|
555
393
|
}
|
|
@@ -558,7 +396,7 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, onSave, __gri
|
|
|
558
396
|
const fieldProjection2 = model.projection.getFieldProjection(field.id);
|
|
559
397
|
invariant2(fieldProjection2, void 0, {
|
|
560
398
|
F: __dxlog_file2,
|
|
561
|
-
L:
|
|
399
|
+
L: 121,
|
|
562
400
|
S: void 0,
|
|
563
401
|
A: [
|
|
564
402
|
"fieldProjection",
|
|
@@ -570,38 +408,7 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, onSave, __gri
|
|
|
570
408
|
model,
|
|
571
409
|
editing
|
|
572
410
|
]);
|
|
573
|
-
|
|
574
|
-
if (!model || !editing || !fieldProjection) {
|
|
575
|
-
setValidationError(null);
|
|
576
|
-
return;
|
|
577
|
-
}
|
|
578
|
-
const cell = parseCellIndex2(editing.index);
|
|
579
|
-
const { row, col } = cell;
|
|
580
|
-
if (model.isDraftCell(cell)) {
|
|
581
|
-
const field = model.projection.fields[col];
|
|
582
|
-
const hasValidationError = model.hasDraftRowValidationError(row, field.path);
|
|
583
|
-
if (hasValidationError) {
|
|
584
|
-
const draftRows = model.draftRows.value;
|
|
585
|
-
if (row >= 0 && row < draftRows.length) {
|
|
586
|
-
const draftRow = draftRows[row];
|
|
587
|
-
const validationError = draftRow.validationErrors?.find((error) => error.path === field.path);
|
|
588
|
-
if (validationError) {
|
|
589
|
-
setValidationError(validationError.message);
|
|
590
|
-
setValidationVariant("warning");
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
} else {
|
|
594
|
-
setValidationError(null);
|
|
595
|
-
}
|
|
596
|
-
} else {
|
|
597
|
-
setValidationError(null);
|
|
598
|
-
}
|
|
599
|
-
}, [
|
|
600
|
-
model,
|
|
601
|
-
editing,
|
|
602
|
-
fieldProjection
|
|
603
|
-
]);
|
|
604
|
-
const handleEnter = useCallback4(async (value) => {
|
|
411
|
+
const handleEnter = useCallback2(async (value) => {
|
|
605
412
|
if (!model || !editing) {
|
|
606
413
|
return;
|
|
607
414
|
}
|
|
@@ -610,33 +417,39 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, onSave, __gri
|
|
|
610
417
|
if (validationResult.valid) {
|
|
611
418
|
setValidationError(null);
|
|
612
419
|
model.setCellData(cell, value);
|
|
613
|
-
onEnter?.(cell);
|
|
614
420
|
onFocus?.();
|
|
615
421
|
setEditing(null);
|
|
616
422
|
onSave?.();
|
|
617
423
|
} else {
|
|
618
|
-
setValidationError(validationResult.error);
|
|
424
|
+
setValidationError(adaptValidationMessage(validationResult.error));
|
|
619
425
|
setValidationVariant("error");
|
|
620
426
|
}
|
|
621
427
|
}, [
|
|
622
428
|
model,
|
|
623
429
|
editing,
|
|
624
|
-
onEnter,
|
|
625
430
|
onFocus,
|
|
626
431
|
setEditing
|
|
627
|
-
]);
|
|
628
|
-
const handleBlur =
|
|
629
|
-
if (!model || !editing) {
|
|
630
|
-
return;
|
|
631
|
-
}
|
|
432
|
+
]);
|
|
433
|
+
const handleBlur = useCallback2(async (value) => {
|
|
632
434
|
if (suppressNextBlur.current) {
|
|
633
435
|
suppressNextBlur.current = false;
|
|
436
|
+
} else if (model && editing) {
|
|
437
|
+
const cell = parseCellIndex2(editing.index);
|
|
438
|
+
if (value !== void 0) {
|
|
439
|
+
const result = await model.validateCellData(cell, value);
|
|
440
|
+
if (result.valid) {
|
|
441
|
+
setValidationError(null);
|
|
442
|
+
model.setCellData(cell, value);
|
|
443
|
+
setEditing(null);
|
|
444
|
+
onSave?.();
|
|
445
|
+
}
|
|
446
|
+
}
|
|
634
447
|
}
|
|
635
448
|
}, [
|
|
636
449
|
model,
|
|
637
450
|
editing
|
|
638
451
|
]);
|
|
639
|
-
const handleClose =
|
|
452
|
+
const handleClose = useCallback2(async (value, event) => {
|
|
640
453
|
if (!model || !editing || !fieldProjection) {
|
|
641
454
|
return;
|
|
642
455
|
}
|
|
@@ -644,19 +457,20 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, onSave, __gri
|
|
|
644
457
|
if (value !== void 0) {
|
|
645
458
|
const result = await model.validateCellData(cell, value);
|
|
646
459
|
if (result.valid) {
|
|
460
|
+
suppressNextBlur.current = true;
|
|
647
461
|
setValidationError(null);
|
|
648
462
|
model.setCellData(cell, value);
|
|
649
463
|
setEditing(null);
|
|
650
464
|
onSave?.();
|
|
651
|
-
onEnter?.(cell);
|
|
652
465
|
if (event && onFocus) {
|
|
653
|
-
onFocus(determineNavigationAxis(event), determineNavigationDelta(event));
|
|
466
|
+
onFocus(determineNavigationAxis(event), determineNavigationDelta(event), cell);
|
|
654
467
|
}
|
|
655
468
|
} else {
|
|
656
469
|
setValidationError(result.error);
|
|
657
470
|
setValidationVariant("error");
|
|
658
471
|
}
|
|
659
472
|
} else {
|
|
473
|
+
suppressNextBlur.current = true;
|
|
660
474
|
setValidationError(null);
|
|
661
475
|
setEditing(null);
|
|
662
476
|
onSave?.();
|
|
@@ -668,16 +482,15 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, onSave, __gri
|
|
|
668
482
|
model,
|
|
669
483
|
editing,
|
|
670
484
|
onFocus,
|
|
671
|
-
onEnter,
|
|
672
485
|
fieldProjection,
|
|
673
486
|
setEditing,
|
|
674
487
|
onSave
|
|
675
488
|
]);
|
|
676
|
-
const
|
|
489
|
+
const extensions = useMemo2(() => {
|
|
677
490
|
if (!fieldProjection) {
|
|
678
491
|
return [];
|
|
679
492
|
}
|
|
680
|
-
const
|
|
493
|
+
const extensions2 = [
|
|
681
494
|
editorKeys({
|
|
682
495
|
onClose: handleClose,
|
|
683
496
|
...editing?.initialContent && {
|
|
@@ -685,114 +498,31 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, onSave, __gri
|
|
|
685
498
|
}
|
|
686
499
|
})
|
|
687
500
|
];
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
onSearch: (text, selectedIds) => {
|
|
699
|
-
return options.filter((option) => selectedIds.indexOf(option.id) === -1 && (text.length === 0 || option.title.toLowerCase().includes(text.toLowerCase()))).map((option) => ({
|
|
700
|
-
id: option.id,
|
|
701
|
-
label: option.title,
|
|
702
|
-
hue: option.color
|
|
703
|
-
}));
|
|
704
|
-
},
|
|
705
|
-
onUpdate: (ids) => {
|
|
706
|
-
if (model && editing) {
|
|
707
|
-
if (ids.length === 0) {
|
|
708
|
-
return;
|
|
709
|
-
}
|
|
710
|
-
if (mode === "single-select") {
|
|
711
|
-
void handleEnter(ids[0]);
|
|
712
|
-
} else {
|
|
713
|
-
void handleEnter(ids);
|
|
714
|
-
}
|
|
501
|
+
if (model && editing) {
|
|
502
|
+
extensions2.push(EditorView.updateListener.of(debounce((update) => {
|
|
503
|
+
const content = update.state.doc.toString();
|
|
504
|
+
const cell = parseCellIndex2(editing.index);
|
|
505
|
+
void model.validateCellData(cell, content).then((result) => {
|
|
506
|
+
if (result.valid) {
|
|
507
|
+
setValidationError(null);
|
|
508
|
+
} else {
|
|
509
|
+
setValidationError(result.error);
|
|
510
|
+
setValidationVariant("error");
|
|
715
511
|
}
|
|
716
|
-
}
|
|
717
|
-
}));
|
|
718
|
-
}
|
|
719
|
-
if (onQuery) {
|
|
720
|
-
switch (fieldProjection.props.format) {
|
|
721
|
-
case FormatEnum.Ref: {
|
|
722
|
-
extension2.push([
|
|
723
|
-
completion({
|
|
724
|
-
onQuery: (text) => onQuery(fieldProjection, text),
|
|
725
|
-
onMatch: (data) => {
|
|
726
|
-
if (model && editing && modals) {
|
|
727
|
-
if (isCreateOption(data)) {
|
|
728
|
-
const { field, props } = fieldProjection;
|
|
729
|
-
if (props.referenceSchema) {
|
|
730
|
-
suppressNextBlur.current = true;
|
|
731
|
-
modals.openCreateRef(props.referenceSchema, document.querySelector(cellQuery(editing.index, gridId)), {
|
|
732
|
-
[field.referencePath]: data.text
|
|
733
|
-
}, (data2) => {
|
|
734
|
-
void handleEnter(data2);
|
|
735
|
-
});
|
|
736
|
-
}
|
|
737
|
-
} else {
|
|
738
|
-
void handleEnter(data);
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
}
|
|
742
|
-
})
|
|
743
|
-
]);
|
|
744
|
-
break;
|
|
745
|
-
}
|
|
746
|
-
}
|
|
512
|
+
});
|
|
513
|
+
}, 10)));
|
|
747
514
|
}
|
|
748
|
-
return
|
|
515
|
+
return extensions2;
|
|
749
516
|
}, [
|
|
750
517
|
model,
|
|
751
518
|
modals,
|
|
752
519
|
editing,
|
|
753
520
|
fieldProjection,
|
|
754
|
-
handleClose
|
|
755
|
-
themeMode
|
|
521
|
+
handleClose
|
|
756
522
|
]);
|
|
757
|
-
const getCellContent =
|
|
523
|
+
const getCellContent = useCallback2(() => {
|
|
758
524
|
if (model && editing) {
|
|
759
525
|
const cell = parseCellIndex2(editing.index);
|
|
760
|
-
const { col } = cell;
|
|
761
|
-
const field = model.projection.fields[col];
|
|
762
|
-
const fieldProjection2 = model.projection.getFieldProjection(field.id);
|
|
763
|
-
if (fieldProjection2?.props.format === FormatEnum.SingleSelect || fieldProjection2?.props.format === FormatEnum.MultiSelect) {
|
|
764
|
-
const value2 = model.getCellData(cell);
|
|
765
|
-
if (value2 !== void 0) {
|
|
766
|
-
const options = fieldProjection2.props.options || [];
|
|
767
|
-
if (fieldProjection2.props.format === FormatEnum.MultiSelect) {
|
|
768
|
-
const tagItems = value2.split(",").map((id) => {
|
|
769
|
-
const option = options.find((o) => o.id === id);
|
|
770
|
-
if (option) {
|
|
771
|
-
return {
|
|
772
|
-
id,
|
|
773
|
-
label: option.title,
|
|
774
|
-
hue: option.color
|
|
775
|
-
};
|
|
776
|
-
}
|
|
777
|
-
return void 0;
|
|
778
|
-
}).filter((item) => item !== void 0);
|
|
779
|
-
return createLinks(tagItems);
|
|
780
|
-
} else {
|
|
781
|
-
const option = options.find((o) => o.id === value2);
|
|
782
|
-
if (option) {
|
|
783
|
-
const tagItem = {
|
|
784
|
-
id: value2,
|
|
785
|
-
label: option.title,
|
|
786
|
-
hue: option.color
|
|
787
|
-
};
|
|
788
|
-
return createLinks([
|
|
789
|
-
tagItem
|
|
790
|
-
]);
|
|
791
|
-
}
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
return "";
|
|
795
|
-
}
|
|
796
526
|
const value = model.getCellData(cell);
|
|
797
527
|
return value !== void 0 ? String(value) : "";
|
|
798
528
|
}
|
|
@@ -800,12 +530,12 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, onSave, __gri
|
|
|
800
530
|
model,
|
|
801
531
|
editing
|
|
802
532
|
]);
|
|
803
|
-
return /* @__PURE__ */
|
|
804
|
-
validationError
|
|
805
|
-
variant:
|
|
533
|
+
return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(CellValidationMessage, {
|
|
534
|
+
validationError,
|
|
535
|
+
variant: validationVariant,
|
|
806
536
|
__gridScope
|
|
807
|
-
}), /* @__PURE__ */
|
|
808
|
-
|
|
537
|
+
}), /* @__PURE__ */ React3.createElement(GridCellEditor, {
|
|
538
|
+
extensions,
|
|
809
539
|
getCellContent,
|
|
810
540
|
onBlur: handleBlur,
|
|
811
541
|
slots: editorSlots
|
|
@@ -839,12 +569,171 @@ var determineNavigationDelta = ({ key, shift }) => {
|
|
|
839
569
|
return shift ? -1 : 1;
|
|
840
570
|
};
|
|
841
571
|
|
|
572
|
+
// src/components/Table/ColumnActionsMenu.tsx
|
|
573
|
+
import { useSignals as _useSignals4 } from "@preact-signals/safe-react/tracking";
|
|
574
|
+
import React4 from "react";
|
|
575
|
+
import { DropdownMenu, useTranslation } from "@dxos/react-ui";
|
|
576
|
+
var ColumnActionsMenu = ({ model, modals }) => {
|
|
577
|
+
var _effect = _useSignals4();
|
|
578
|
+
try {
|
|
579
|
+
const { t } = useTranslation(translationKey);
|
|
580
|
+
const state = modals.state.value;
|
|
581
|
+
if (state?.type !== "column") {
|
|
582
|
+
return null;
|
|
583
|
+
}
|
|
584
|
+
const currentSort = model.sorting?.sorting;
|
|
585
|
+
const isCurrentColumnSorted = currentSort?.fieldId === state.fieldId;
|
|
586
|
+
return /* @__PURE__ */ React4.createElement(DropdownMenu.Root, {
|
|
587
|
+
modal: false,
|
|
588
|
+
open: true,
|
|
589
|
+
onOpenChange: modals.close
|
|
590
|
+
}, /* @__PURE__ */ React4.createElement(DropdownMenu.VirtualTrigger, {
|
|
591
|
+
virtualRef: modals.trigger
|
|
592
|
+
}), /* @__PURE__ */ React4.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React4.createElement(DropdownMenu.Content, null, /* @__PURE__ */ React4.createElement(DropdownMenu.Viewport, null, (!isCurrentColumnSorted || currentSort?.direction === "asc") && /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
|
|
593
|
+
"data-testid": "column-sort-descending",
|
|
594
|
+
onClick: () => model.sorting?.setSort(state.fieldId, "desc")
|
|
595
|
+
}, t("column action sort descending")), (!isCurrentColumnSorted || currentSort?.direction === "desc") && /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
|
|
596
|
+
"data-testid": "column-sort-ascending",
|
|
597
|
+
onClick: () => model.sorting?.setSort(state.fieldId, "asc")
|
|
598
|
+
}, t("column action sort ascending")), isCurrentColumnSorted && /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
|
|
599
|
+
"data-testid": "column-clear-sort",
|
|
600
|
+
onClick: () => model.sorting?.clearSort()
|
|
601
|
+
}, t("column action clear sorting")), model.getColumnCount() > 1 && model.features.schemaEditable && /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
|
|
602
|
+
"data-testid": "column-delete",
|
|
603
|
+
onClick: () => model.deleteColumn(state.fieldId)
|
|
604
|
+
}, t("column action delete")), model.features.schemaEditable && /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
|
|
605
|
+
"data-testid": "column-settings",
|
|
606
|
+
onClick: () => modals.openColumnSettings()
|
|
607
|
+
}, t("column action settings"))), /* @__PURE__ */ React4.createElement(DropdownMenu.Arrow, null))));
|
|
608
|
+
} finally {
|
|
609
|
+
_effect.f();
|
|
610
|
+
}
|
|
611
|
+
};
|
|
612
|
+
|
|
613
|
+
// src/components/Table/ColumnSettings.tsx
|
|
614
|
+
import { useSignals as _useSignals5 } from "@preact-signals/safe-react/tracking";
|
|
615
|
+
import React5, { useCallback as useCallback3, useEffect as useEffect2, useMemo as useMemo3, useState as useState3 } from "react";
|
|
616
|
+
import { Popover as Popover2 } from "@dxos/react-ui";
|
|
617
|
+
import { FieldEditor } from "@dxos/react-ui-form";
|
|
618
|
+
var ColumnSettings = ({ registry, model, modals, onNewColumn }) => {
|
|
619
|
+
var _effect = _useSignals5();
|
|
620
|
+
try {
|
|
621
|
+
const [newField, setNewField] = useState3();
|
|
622
|
+
const state = modals.state.value;
|
|
623
|
+
useEffect2(() => {
|
|
624
|
+
if (state?.type === "columnSettings" && state.mode.type === "create" && model?.projection) {
|
|
625
|
+
setNewField(model.projection.createFieldProjection());
|
|
626
|
+
requestAnimationFrame(() => {
|
|
627
|
+
onNewColumn();
|
|
628
|
+
});
|
|
629
|
+
} else {
|
|
630
|
+
setNewField(void 0);
|
|
631
|
+
}
|
|
632
|
+
}, [
|
|
633
|
+
model?.projection,
|
|
634
|
+
state
|
|
635
|
+
]);
|
|
636
|
+
const existingField = useMemo3(() => {
|
|
637
|
+
if (state?.type === "columnSettings") {
|
|
638
|
+
const { mode } = state;
|
|
639
|
+
if (mode.type === "edit") {
|
|
640
|
+
return model?.projection?.fields.find((f) => f.id === mode.fieldId);
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
return void 0;
|
|
644
|
+
}, [
|
|
645
|
+
model?.projection?.fields,
|
|
646
|
+
state
|
|
647
|
+
]);
|
|
648
|
+
const field = existingField ?? newField;
|
|
649
|
+
const handleSave = useCallback3(() => {
|
|
650
|
+
modals.close();
|
|
651
|
+
}, [
|
|
652
|
+
modals
|
|
653
|
+
]);
|
|
654
|
+
const handleCancel = useCallback3(() => {
|
|
655
|
+
if (state?.type === "columnSettings" && state.mode.type === "create" && newField) {
|
|
656
|
+
model?.projection.deleteFieldProjection(newField.id);
|
|
657
|
+
}
|
|
658
|
+
}, [
|
|
659
|
+
model?.projection,
|
|
660
|
+
state,
|
|
661
|
+
newField
|
|
662
|
+
]);
|
|
663
|
+
if (!model?.projection || !field) {
|
|
664
|
+
return null;
|
|
665
|
+
}
|
|
666
|
+
return /* @__PURE__ */ React5.createElement(Popover2.Root, {
|
|
667
|
+
modal: false,
|
|
668
|
+
open: state?.type === "columnSettings"
|
|
669
|
+
}, /* @__PURE__ */ React5.createElement(Popover2.VirtualTrigger, {
|
|
670
|
+
virtualRef: modals.trigger
|
|
671
|
+
}), /* @__PURE__ */ React5.createElement(Popover2.Portal, null, /* @__PURE__ */ React5.createElement(Popover2.Content, {
|
|
672
|
+
classNames: "md:is-64"
|
|
673
|
+
}, /* @__PURE__ */ React5.createElement(Popover2.Viewport, null, /* @__PURE__ */ React5.createElement(FieldEditor, {
|
|
674
|
+
projection: model.projection,
|
|
675
|
+
field,
|
|
676
|
+
registry,
|
|
677
|
+
onSave: handleSave,
|
|
678
|
+
onCancel: handleCancel
|
|
679
|
+
})), /* @__PURE__ */ React5.createElement(Popover2.Arrow, null))));
|
|
680
|
+
} finally {
|
|
681
|
+
_effect.f();
|
|
682
|
+
}
|
|
683
|
+
};
|
|
684
|
+
|
|
685
|
+
// src/components/Table/RowActionsMenu.tsx
|
|
686
|
+
import { useSignals as _useSignals6 } from "@preact-signals/safe-react/tracking";
|
|
687
|
+
import React6 from "react";
|
|
688
|
+
import { DropdownMenu as DropdownMenu2, toLocalizedString, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
689
|
+
var RowActionsMenu = ({ model, modals }) => {
|
|
690
|
+
var _effect = _useSignals6();
|
|
691
|
+
try {
|
|
692
|
+
const { t } = useTranslation2(translationKey);
|
|
693
|
+
const hasSelection = model.selection.hasSelection.value;
|
|
694
|
+
const state = modals.state.value;
|
|
695
|
+
if (state?.type !== "row") {
|
|
696
|
+
return null;
|
|
697
|
+
}
|
|
698
|
+
return /* @__PURE__ */ React6.createElement(DropdownMenu2.Root, {
|
|
699
|
+
modal: false,
|
|
700
|
+
open: true,
|
|
701
|
+
onOpenChange: modals.close
|
|
702
|
+
}, /* @__PURE__ */ React6.createElement(DropdownMenu2.VirtualTrigger, {
|
|
703
|
+
virtualRef: modals.trigger
|
|
704
|
+
}), /* @__PURE__ */ React6.createElement(DropdownMenu2.Content, null, /* @__PURE__ */ React6.createElement(DropdownMenu2.Viewport, null, model.rowActions?.length > 0 && /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(DropdownMenu2.Group, null, model.rowActions?.map((action) => /* @__PURE__ */ React6.createElement(DropdownMenu2.Item, {
|
|
705
|
+
key: action.id,
|
|
706
|
+
"data-testid": `row-action-${action.id}`,
|
|
707
|
+
onClick: () => {
|
|
708
|
+
modals.close();
|
|
709
|
+
model.handleRowAction(action.id, state.rowIndex);
|
|
710
|
+
}
|
|
711
|
+
}, toLocalizedString(action.label, t)))), /* @__PURE__ */ React6.createElement(DropdownMenu2.Separator, null)), model.features.dataEditable !== false && /* @__PURE__ */ React6.createElement(DropdownMenu2.Item, {
|
|
712
|
+
"data-testid": "row-menu-delete",
|
|
713
|
+
onClick: () => model.deleteRow(state.rowIndex)
|
|
714
|
+
}, t(hasSelection ? "bulk delete row label" : "delete row label"))), /* @__PURE__ */ React6.createElement(DropdownMenu2.Arrow, null)));
|
|
715
|
+
} finally {
|
|
716
|
+
_effect.f();
|
|
717
|
+
}
|
|
718
|
+
};
|
|
719
|
+
|
|
842
720
|
// src/components/Table/Table.tsx
|
|
843
|
-
var
|
|
721
|
+
var columnDefault = {
|
|
722
|
+
grid: {
|
|
723
|
+
minSize: 80,
|
|
724
|
+
maxSize: 640
|
|
725
|
+
}
|
|
726
|
+
};
|
|
727
|
+
var rowDefault = {
|
|
728
|
+
frozenRowsStart: {
|
|
729
|
+
readonly: true,
|
|
730
|
+
focusUnfurl: false
|
|
731
|
+
}
|
|
732
|
+
};
|
|
844
733
|
var TableRoot = ({ children, role = "article" }) => {
|
|
845
|
-
var _effect =
|
|
734
|
+
var _effect = _useSignals7();
|
|
846
735
|
try {
|
|
847
|
-
return /* @__PURE__ */
|
|
736
|
+
return /* @__PURE__ */ React7.createElement("div", {
|
|
848
737
|
role: "none",
|
|
849
738
|
className: mx("relative !border-separator [&_.dx-grid]:max-is-[--dx-grid-content-inline-size] [&_.dx-grid]:max-bs-[--dx-grid-content-block-size]", role === "card--popover" && "popover-card-height", role === "section" && "attention-surface", role === "card--intrinsic" && "[&_.dx-grid]:bs-[--dx-grid-content-block-size]", [
|
|
850
739
|
"card--popover",
|
|
@@ -859,19 +748,24 @@ var TableRoot = ({ children, role = "article" }) => {
|
|
|
859
748
|
_effect.f();
|
|
860
749
|
}
|
|
861
750
|
};
|
|
862
|
-
var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttention, schema, client, onRowClick }, forwardedRef) => {
|
|
863
|
-
var _effect =
|
|
751
|
+
var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttention, schema, client, onCreate, onRowClick, testId }, forwardedRef) => {
|
|
752
|
+
var _effect = _useSignals7();
|
|
864
753
|
try {
|
|
865
754
|
const [dxGrid, setDxGrid] = useState4(null);
|
|
866
755
|
const { hasAttention } = useAttention(model?.id ?? "table");
|
|
867
|
-
const
|
|
868
|
-
const modals = useMemo5(() => new ModalController(), []);
|
|
756
|
+
const modals = useMemo4(() => new ModalController(), []);
|
|
869
757
|
const draftRowCount = model?.getDraftRowCount() ?? 0;
|
|
870
|
-
const
|
|
758
|
+
const handleSave = useCallback4(() => {
|
|
759
|
+
dxGrid?.updateCells(true);
|
|
760
|
+
dxGrid?.requestUpdate();
|
|
761
|
+
}, [
|
|
762
|
+
dxGrid
|
|
763
|
+
]);
|
|
764
|
+
const frozen = useMemo4(() => {
|
|
871
765
|
const noActionColumn = model?.features.dataEditable === false && model?.features.schemaEditable === false && model.rowActions.length === 0;
|
|
872
766
|
return {
|
|
873
767
|
frozenRowsStart: 1,
|
|
874
|
-
frozenRowsEnd: draftRowCount,
|
|
768
|
+
frozenRowsEnd: Math.max(1, draftRowCount),
|
|
875
769
|
frozenColsStart: model?.features.selection.enabled ? 1 : 0,
|
|
876
770
|
frozenColsEnd: noActionColumn ? 0 : 1
|
|
877
771
|
};
|
|
@@ -879,10 +773,10 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
879
773
|
model,
|
|
880
774
|
draftRowCount
|
|
881
775
|
]);
|
|
882
|
-
const getCells =
|
|
776
|
+
const getCells = useCallback4((range, plane) => presentation?.getCells(range, plane) ?? {}, [
|
|
883
777
|
presentation
|
|
884
778
|
]);
|
|
885
|
-
|
|
779
|
+
useEffect3(() => {
|
|
886
780
|
if (!presentation || !dxGrid) {
|
|
887
781
|
return;
|
|
888
782
|
}
|
|
@@ -892,6 +786,30 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
892
786
|
dxGrid,
|
|
893
787
|
getCells
|
|
894
788
|
]);
|
|
789
|
+
const handleInsertRowResult = useCallback4((insertResult) => {
|
|
790
|
+
if (insertResult === "draft") {
|
|
791
|
+
requestAnimationFrame(() => {
|
|
792
|
+
dxGrid?.setFocus({
|
|
793
|
+
plane: "frozenRowsEnd",
|
|
794
|
+
col: 0,
|
|
795
|
+
row: 0
|
|
796
|
+
});
|
|
797
|
+
dxGrid?.refocus();
|
|
798
|
+
});
|
|
799
|
+
} else {
|
|
800
|
+
requestAnimationFrame(() => {
|
|
801
|
+
dxGrid?.setFocus({
|
|
802
|
+
plane: "grid",
|
|
803
|
+
col: 0,
|
|
804
|
+
row: model ? model.getRowCount() - 1 : 0
|
|
805
|
+
});
|
|
806
|
+
dxGrid?.refocus();
|
|
807
|
+
});
|
|
808
|
+
}
|
|
809
|
+
}, [
|
|
810
|
+
model,
|
|
811
|
+
dxGrid
|
|
812
|
+
]);
|
|
895
813
|
useImperativeHandle(forwardedRef, () => {
|
|
896
814
|
if (!presentation || !dxGrid) {
|
|
897
815
|
return {};
|
|
@@ -904,18 +822,38 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
904
822
|
dxGrid.updateCells(true);
|
|
905
823
|
dxGrid.requestUpdate();
|
|
906
824
|
}
|
|
907
|
-
}
|
|
825
|
+
},
|
|
826
|
+
handleInsertRowResult
|
|
908
827
|
};
|
|
909
828
|
}, [
|
|
910
829
|
presentation,
|
|
830
|
+
dxGrid,
|
|
831
|
+
model
|
|
832
|
+
]);
|
|
833
|
+
const handleSaveDraftRow = useCallback4((rowIndex = 0) => {
|
|
834
|
+
if (model && dxGrid) {
|
|
835
|
+
const didCommitSuccessfully = model.commitDraftRow(rowIndex);
|
|
836
|
+
if (didCommitSuccessfully) {
|
|
837
|
+
requestAnimationFrame(() => {
|
|
838
|
+
dxGrid.scrollToEndRow();
|
|
839
|
+
});
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
}, [
|
|
843
|
+
model,
|
|
911
844
|
dxGrid
|
|
912
845
|
]);
|
|
913
|
-
const handleGridClick =
|
|
914
|
-
const
|
|
915
|
-
if (
|
|
846
|
+
const handleGridClick = useCallback4((event) => {
|
|
847
|
+
const cell = closestCell(event.target);
|
|
848
|
+
if (cell) {
|
|
849
|
+
const { row: rowIndex, plane } = cell;
|
|
916
850
|
if (onRowClick) {
|
|
917
|
-
|
|
918
|
-
|
|
851
|
+
if (plane === "grid") {
|
|
852
|
+
const row = model?.getRowAt(rowIndex);
|
|
853
|
+
row && onRowClick(row);
|
|
854
|
+
} else {
|
|
855
|
+
onRowClick(cell);
|
|
856
|
+
}
|
|
919
857
|
}
|
|
920
858
|
if (model?.features.selection.enabled && model?.selection.selectionMode === "single") {
|
|
921
859
|
model.selection.toggleSelectionForRowIndex(rowIndex);
|
|
@@ -951,14 +889,7 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
951
889
|
break;
|
|
952
890
|
}
|
|
953
891
|
case "saveDraftRow": {
|
|
954
|
-
|
|
955
|
-
const didCommitSuccessfully = model.commitDraftRow(data.rowIndex);
|
|
956
|
-
if (dxGrid && didCommitSuccessfully) {
|
|
957
|
-
requestAnimationFrame(() => {
|
|
958
|
-
dxGrid.scrollToEndRow();
|
|
959
|
-
});
|
|
960
|
-
}
|
|
961
|
-
}
|
|
892
|
+
handleSaveDraftRow();
|
|
962
893
|
break;
|
|
963
894
|
}
|
|
964
895
|
}
|
|
@@ -997,31 +928,22 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
997
928
|
modals,
|
|
998
929
|
dxGrid
|
|
999
930
|
]);
|
|
1000
|
-
const handleFocus =
|
|
1001
|
-
if (dxGrid) {
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
return;
|
|
1010
|
-
}
|
|
1011
|
-
if (model && cell.row === model.getRowCount() - 1) {
|
|
1012
|
-
model.insertRow();
|
|
1013
|
-
if (dxGrid) {
|
|
1014
|
-
requestAnimationFrame(() => {
|
|
1015
|
-
dxGrid?.scrollToRow(cell.row + 1);
|
|
1016
|
-
dxGrid?.refocus("row", 1);
|
|
1017
|
-
});
|
|
931
|
+
const handleFocus = useCallback4((increment, delta, cell) => {
|
|
932
|
+
if (dxGrid && model) {
|
|
933
|
+
if (cell?.plane === "grid" && cell?.row >= model.getRowCount() - 1 && increment !== "col") {
|
|
934
|
+
handleInsertRowResult(draftRowCount < 1 ? model.insertRow() : "final");
|
|
935
|
+
} else if (cell?.plane === "frozenRowsEnd" && increment === "row") {
|
|
936
|
+
handleSaveDraftRow(cell.row);
|
|
937
|
+
handleInsertRowResult(model.insertRow());
|
|
938
|
+
} else {
|
|
939
|
+
dxGrid.refocus(increment, delta);
|
|
1018
940
|
}
|
|
1019
941
|
}
|
|
1020
942
|
}, [
|
|
1021
|
-
|
|
1022
|
-
|
|
943
|
+
dxGrid,
|
|
944
|
+
model
|
|
1023
945
|
]);
|
|
1024
|
-
const handleKeyDown =
|
|
946
|
+
const handleKeyDown = useCallback4((event) => {
|
|
1025
947
|
if (!model?.features.dataEditable) {
|
|
1026
948
|
return;
|
|
1027
949
|
}
|
|
@@ -1029,21 +951,66 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
1029
951
|
if (!model || !cell) {
|
|
1030
952
|
return;
|
|
1031
953
|
}
|
|
954
|
+
if (event.metaKey || event.ctrlKey) {
|
|
955
|
+
switch (event.key) {
|
|
956
|
+
case "c": {
|
|
957
|
+
try {
|
|
958
|
+
const cellData = model.getCellData(cell);
|
|
959
|
+
const textContent = cellData?.toString() ?? "";
|
|
960
|
+
void navigator.clipboard.writeText(textContent);
|
|
961
|
+
event.preventDefault();
|
|
962
|
+
} catch (error) {
|
|
963
|
+
console.warn("Failed to copy cell content:", error);
|
|
964
|
+
}
|
|
965
|
+
break;
|
|
966
|
+
}
|
|
967
|
+
case "v": {
|
|
968
|
+
event.preventDefault();
|
|
969
|
+
void navigator.clipboard.readText().then((clipboardText) => {
|
|
970
|
+
try {
|
|
971
|
+
model.setCellData(cell, String2.trim(clipboardText).replace(/[\n\r]+/, " "));
|
|
972
|
+
handleSave();
|
|
973
|
+
} catch {
|
|
974
|
+
const cellElement = event.target.closest('[data-dx-grid-action="cell"]');
|
|
975
|
+
if (cellElement) {
|
|
976
|
+
const rect = cellElement.getBoundingClientRect();
|
|
977
|
+
const editRequest = new DxEditRequest({
|
|
978
|
+
cellIndex: `${cell.plane},${cell.col},${cell.row}`,
|
|
979
|
+
cellBox: {
|
|
980
|
+
insetInlineStart: rect.left,
|
|
981
|
+
insetBlockStart: rect.top,
|
|
982
|
+
inlineSize: rect.width,
|
|
983
|
+
blockSize: rect.height
|
|
984
|
+
},
|
|
985
|
+
cellElement,
|
|
986
|
+
initialContent: clipboardText
|
|
987
|
+
});
|
|
988
|
+
cellElement.dispatchEvent(editRequest);
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
});
|
|
992
|
+
break;
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
}
|
|
1032
996
|
switch (event.key) {
|
|
1033
997
|
case "Backspace":
|
|
1034
998
|
case "Delete": {
|
|
1035
999
|
try {
|
|
1036
1000
|
model.setCellData(cell, void 0);
|
|
1037
1001
|
event.preventDefault();
|
|
1002
|
+
handleSave();
|
|
1038
1003
|
} catch {
|
|
1039
1004
|
}
|
|
1040
1005
|
break;
|
|
1041
1006
|
}
|
|
1042
1007
|
}
|
|
1043
1008
|
}, [
|
|
1044
|
-
model
|
|
1009
|
+
model,
|
|
1010
|
+
dxGrid,
|
|
1011
|
+
handleSave
|
|
1045
1012
|
]);
|
|
1046
|
-
const handleAxisResize =
|
|
1013
|
+
const handleAxisResize = useCallback4((event) => {
|
|
1047
1014
|
if (event.axis === "col") {
|
|
1048
1015
|
const columnIndex = parseInt(event.index, 10);
|
|
1049
1016
|
model?.setColumnWidth(columnIndex, event.size);
|
|
@@ -1051,7 +1018,7 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
1051
1018
|
}, [
|
|
1052
1019
|
model
|
|
1053
1020
|
]);
|
|
1054
|
-
const handleWheel =
|
|
1021
|
+
const handleWheel = useCallback4((event) => {
|
|
1055
1022
|
if (!ignoreAttention && !hasAttention) {
|
|
1056
1023
|
event.stopPropagation();
|
|
1057
1024
|
}
|
|
@@ -1059,7 +1026,7 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
1059
1026
|
hasAttention,
|
|
1060
1027
|
ignoreAttention
|
|
1061
1028
|
]);
|
|
1062
|
-
const handleNewColumn =
|
|
1029
|
+
const handleNewColumn = useCallback4(() => {
|
|
1063
1030
|
const columns = model?.getColumnCount();
|
|
1064
1031
|
if (dxGrid && columns) {
|
|
1065
1032
|
dxGrid.scrollToColumn(columns - 1);
|
|
@@ -1068,79 +1035,28 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
1068
1035
|
model,
|
|
1069
1036
|
dxGrid
|
|
1070
1037
|
]);
|
|
1071
|
-
const handleQuery = useCallback5(async ({ field, props }, text) => {
|
|
1072
|
-
if (model && props.referenceSchema && field.referencePath) {
|
|
1073
|
-
const space = getSpace2(model.view);
|
|
1074
|
-
invariant3(space, void 0, {
|
|
1075
|
-
F: __dxlog_file3,
|
|
1076
|
-
L: 330,
|
|
1077
|
-
S: void 0,
|
|
1078
|
-
A: [
|
|
1079
|
-
"space",
|
|
1080
|
-
""
|
|
1081
|
-
]
|
|
1082
|
-
});
|
|
1083
|
-
let schema2;
|
|
1084
|
-
if (client) {
|
|
1085
|
-
schema2 = client.graph.schemaRegistry.getSchema(props.referenceSchema);
|
|
1086
|
-
}
|
|
1087
|
-
if (!schema2) {
|
|
1088
|
-
schema2 = space.db.schemaRegistry.getSchema(props.referenceSchema);
|
|
1089
|
-
}
|
|
1090
|
-
if (schema2) {
|
|
1091
|
-
const { objects } = await space.db.query(Filter.type(schema2)).run();
|
|
1092
|
-
const options = objects.map((obj) => {
|
|
1093
|
-
const value = getValue(obj, field.referencePath);
|
|
1094
|
-
if (!value || typeof value !== "string") {
|
|
1095
|
-
return void 0;
|
|
1096
|
-
}
|
|
1097
|
-
return {
|
|
1098
|
-
label: value,
|
|
1099
|
-
data: obj
|
|
1100
|
-
};
|
|
1101
|
-
}).filter(isNotFalsy);
|
|
1102
|
-
return [
|
|
1103
|
-
...options,
|
|
1104
|
-
{
|
|
1105
|
-
label: t("create new object label", {
|
|
1106
|
-
text
|
|
1107
|
-
}),
|
|
1108
|
-
data: createOption(text)
|
|
1109
|
-
}
|
|
1110
|
-
];
|
|
1111
|
-
}
|
|
1112
|
-
}
|
|
1113
|
-
return [];
|
|
1114
|
-
}, [
|
|
1115
|
-
model,
|
|
1116
|
-
client,
|
|
1117
|
-
t
|
|
1118
|
-
]);
|
|
1119
|
-
const handleSave = useCallback5(() => {
|
|
1120
|
-
dxGrid?.updateCells(true);
|
|
1121
|
-
}, [
|
|
1122
|
-
dxGrid
|
|
1123
|
-
]);
|
|
1124
1038
|
if (!model || !modals) {
|
|
1125
|
-
return /* @__PURE__ */
|
|
1039
|
+
return /* @__PURE__ */ React7.createElement("span", {
|
|
1126
1040
|
role: "none",
|
|
1127
1041
|
className: "attention-surface"
|
|
1128
1042
|
});
|
|
1129
1043
|
}
|
|
1130
|
-
return /* @__PURE__ */
|
|
1044
|
+
return /* @__PURE__ */ React7.createElement(Grid.Root, {
|
|
1131
1045
|
id: model.id ?? "table-grid"
|
|
1132
|
-
}, /* @__PURE__ */
|
|
1046
|
+
}, /* @__PURE__ */ React7.createElement(TableValueEditor, {
|
|
1133
1047
|
model,
|
|
1134
1048
|
modals,
|
|
1135
1049
|
schema,
|
|
1136
|
-
onEnter: handleEnter,
|
|
1137
1050
|
onFocus: handleFocus,
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1051
|
+
onSave: handleSave,
|
|
1052
|
+
onCreate,
|
|
1053
|
+
client
|
|
1054
|
+
}), /* @__PURE__ */ React7.createElement(Grid.Content, {
|
|
1141
1055
|
className: mx("[--dx-grid-base:var(--baseSurface)]", gridSeparatorInlineEnd, gridSeparatorBlockEnd),
|
|
1142
1056
|
frozen,
|
|
1143
1057
|
columns: model.columnMeta.value,
|
|
1058
|
+
columnDefault,
|
|
1059
|
+
rowDefault,
|
|
1144
1060
|
limitRows: model.getRowCount() ?? 0,
|
|
1145
1061
|
limitColumns: model.projection.fields.length,
|
|
1146
1062
|
overscroll: "trap",
|
|
@@ -1148,20 +1064,20 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
1148
1064
|
onClick: handleGridClick,
|
|
1149
1065
|
onKeyDownCapture: handleKeyDown,
|
|
1150
1066
|
onWheelCapture: handleWheel,
|
|
1067
|
+
...testId && {
|
|
1068
|
+
"data-testid": testId
|
|
1069
|
+
},
|
|
1151
1070
|
ref: setDxGrid
|
|
1152
|
-
}), /* @__PURE__ */
|
|
1071
|
+
}), /* @__PURE__ */ React7.createElement(RowActionsMenu, {
|
|
1153
1072
|
model,
|
|
1154
1073
|
modals
|
|
1155
|
-
}), /* @__PURE__ */
|
|
1074
|
+
}), /* @__PURE__ */ React7.createElement(ColumnActionsMenu, {
|
|
1156
1075
|
model,
|
|
1157
1076
|
modals
|
|
1158
|
-
}), /* @__PURE__ */
|
|
1077
|
+
}), /* @__PURE__ */ React7.createElement(ColumnSettings, {
|
|
1159
1078
|
model,
|
|
1160
1079
|
modals,
|
|
1161
1080
|
onNewColumn: handleNewColumn
|
|
1162
|
-
}), /* @__PURE__ */ React8.createElement(CreateRefPanel, {
|
|
1163
|
-
model,
|
|
1164
|
-
modals
|
|
1165
1081
|
}));
|
|
1166
1082
|
} finally {
|
|
1167
1083
|
_effect.f();
|
|
@@ -1173,14 +1089,15 @@ var Table = {
|
|
|
1173
1089
|
};
|
|
1174
1090
|
|
|
1175
1091
|
// src/components/Table/DynamicTable.tsx
|
|
1176
|
-
import { useSignals as
|
|
1177
|
-
import
|
|
1092
|
+
import { useSignals as _useSignals8 } from "@preact-signals/safe-react/tracking";
|
|
1093
|
+
import React8, { useCallback as useCallback5, useMemo as useMemo5, useRef as useRef3 } from "react";
|
|
1178
1094
|
import { useDefaultValue } from "@dxos/react-ui";
|
|
1179
1095
|
import { mx as mx2 } from "@dxos/react-ui-theme";
|
|
1096
|
+
import { ProjectionModel } from "@dxos/schema";
|
|
1180
1097
|
var DynamicTable = ({ classNames, name = "example.com/dynamic-table", rows, properties, jsonSchema: _jsonSchema, schema, rowActions, onRowClick, onRowAction, ...props }) => {
|
|
1181
|
-
var _effect =
|
|
1098
|
+
var _effect = _useSignals8();
|
|
1182
1099
|
try {
|
|
1183
|
-
const {
|
|
1100
|
+
const { jsonSchema } = useMemo5(() => getBaseSchema({
|
|
1184
1101
|
typename: name,
|
|
1185
1102
|
properties,
|
|
1186
1103
|
jsonSchema: _jsonSchema,
|
|
@@ -1191,20 +1108,18 @@ var DynamicTable = ({ classNames, name = "example.com/dynamic-table", rows, prop
|
|
|
1191
1108
|
_jsonSchema,
|
|
1192
1109
|
schema
|
|
1193
1110
|
]);
|
|
1194
|
-
const {
|
|
1195
|
-
typename,
|
|
1111
|
+
const { object, projection } = useMemo5(() => makeDynamicTable({
|
|
1196
1112
|
jsonSchema,
|
|
1197
1113
|
properties
|
|
1198
1114
|
}), [
|
|
1199
|
-
typename,
|
|
1200
1115
|
jsonSchema,
|
|
1201
1116
|
properties
|
|
1202
1117
|
]);
|
|
1203
1118
|
const tableRef = useRef3(null);
|
|
1204
|
-
const handleCellUpdate =
|
|
1119
|
+
const handleCellUpdate = useCallback5((cell) => {
|
|
1205
1120
|
tableRef.current?.update?.(cell);
|
|
1206
1121
|
}, []);
|
|
1207
|
-
const handleRowOrderChange =
|
|
1122
|
+
const handleRowOrderChange = useCallback5(() => {
|
|
1208
1123
|
tableRef.current?.update?.();
|
|
1209
1124
|
}, []);
|
|
1210
1125
|
const features = useDefaultValue(props.features, () => ({
|
|
@@ -1213,31 +1128,40 @@ var DynamicTable = ({ classNames, name = "example.com/dynamic-table", rows, prop
|
|
|
1213
1128
|
},
|
|
1214
1129
|
dataEditable: false
|
|
1215
1130
|
}));
|
|
1131
|
+
const projectionModel = useMemo5(() => {
|
|
1132
|
+
if (jsonSchema && projection) {
|
|
1133
|
+
const model2 = new ProjectionModel(jsonSchema, projection);
|
|
1134
|
+
model2.normalizeView();
|
|
1135
|
+
return model2;
|
|
1136
|
+
}
|
|
1137
|
+
}, [
|
|
1138
|
+
jsonSchema,
|
|
1139
|
+
projection
|
|
1140
|
+
]);
|
|
1216
1141
|
const model = useTableModel({
|
|
1217
1142
|
rows,
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
projection,
|
|
1143
|
+
object,
|
|
1144
|
+
projection: projectionModel,
|
|
1221
1145
|
features,
|
|
1222
1146
|
rowActions,
|
|
1223
1147
|
onCellUpdate: handleCellUpdate,
|
|
1224
1148
|
onRowOrderChange: handleRowOrderChange,
|
|
1225
1149
|
onRowAction
|
|
1226
1150
|
});
|
|
1227
|
-
const presentation =
|
|
1151
|
+
const presentation = useMemo5(() => {
|
|
1228
1152
|
if (model) {
|
|
1229
1153
|
return new TablePresentation(model);
|
|
1230
1154
|
}
|
|
1231
1155
|
}, [
|
|
1232
1156
|
model
|
|
1233
1157
|
]);
|
|
1234
|
-
return /* @__PURE__ */
|
|
1158
|
+
return /* @__PURE__ */ React8.createElement("div", {
|
|
1235
1159
|
role: "none",
|
|
1236
1160
|
className: mx2("is-full bs-full grow grid", classNames)
|
|
1237
|
-
}, /* @__PURE__ */
|
|
1161
|
+
}, /* @__PURE__ */ React8.createElement("div", {
|
|
1238
1162
|
role: "none",
|
|
1239
1163
|
className: "grid min-bs-0 overflow-hidden"
|
|
1240
|
-
}, /* @__PURE__ */
|
|
1164
|
+
}, /* @__PURE__ */ React8.createElement(Table.Root, null, /* @__PURE__ */ React8.createElement(Table.Main, {
|
|
1241
1165
|
ref: tableRef,
|
|
1242
1166
|
model,
|
|
1243
1167
|
presentation,
|
|
@@ -1250,43 +1174,46 @@ var DynamicTable = ({ classNames, name = "example.com/dynamic-table", rows, prop
|
|
|
1250
1174
|
};
|
|
1251
1175
|
|
|
1252
1176
|
// src/components/TableToolbar/TableToolbar.tsx
|
|
1253
|
-
import { useSignals as
|
|
1254
|
-
import {
|
|
1255
|
-
import
|
|
1256
|
-
import { live
|
|
1257
|
-
import {
|
|
1258
|
-
import {
|
|
1259
|
-
var createTableToolbarActions = ({ state, onAdd, onSave, customActions }) =>
|
|
1260
|
-
const
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1177
|
+
import { useSignals as _useSignals9 } from "@preact-signals/safe-react/tracking";
|
|
1178
|
+
import { Atom } from "@effect-atom/atom-react";
|
|
1179
|
+
import React9, { useMemo as useMemo6 } from "react";
|
|
1180
|
+
import { live } from "@dxos/live-object";
|
|
1181
|
+
import { MenuProvider, ToolbarMenu, createGapSeparator, createMenuAction, useMenuActions } from "@dxos/react-ui-menu";
|
|
1182
|
+
import { atomFromSignal } from "@dxos/react-ui-menu";
|
|
1183
|
+
var createTableToolbarActions = ({ state, onAdd, onSave, customActions }) => Atom.make((get) => {
|
|
1184
|
+
const nodes = [];
|
|
1185
|
+
if (onAdd) {
|
|
1186
|
+
const add = createMenuAction("add-row", onAdd, {
|
|
1187
|
+
type: "add-row",
|
|
1188
|
+
icon: "ph--plus--regular",
|
|
1189
|
+
label: [
|
|
1190
|
+
"add row label",
|
|
1191
|
+
{
|
|
1192
|
+
ns: translationKey
|
|
1193
|
+
}
|
|
1194
|
+
],
|
|
1195
|
+
testId: "table.toolbar.add-row"
|
|
1196
|
+
});
|
|
1197
|
+
nodes.push(add);
|
|
1198
|
+
}
|
|
1199
|
+
if (onSave) {
|
|
1200
|
+
const save = createMenuAction("save-view", onSave, {
|
|
1201
|
+
type: "save-view",
|
|
1202
|
+
icon: "ph--floppy-disk--regular",
|
|
1203
|
+
label: [
|
|
1204
|
+
"save view label",
|
|
1205
|
+
{
|
|
1206
|
+
ns: translationKey
|
|
1207
|
+
}
|
|
1208
|
+
],
|
|
1209
|
+
testId: "table.toolbar.save-view",
|
|
1210
|
+
iconOnly: false,
|
|
1211
|
+
hidden: get(atomFromSignal(() => !state.viewDirty))
|
|
1212
|
+
});
|
|
1213
|
+
nodes.push(save);
|
|
1214
|
+
}
|
|
1284
1215
|
const gap = createGapSeparator();
|
|
1285
|
-
|
|
1286
|
-
add,
|
|
1287
|
-
save,
|
|
1288
|
-
...gap.nodes
|
|
1289
|
-
];
|
|
1216
|
+
nodes.push(...gap.nodes);
|
|
1290
1217
|
const edges = nodes.map(({ id: target }) => ({
|
|
1291
1218
|
source: "root",
|
|
1292
1219
|
target
|
|
@@ -1302,12 +1229,12 @@ var createTableToolbarActions = ({ state, onAdd, onSave, customActions }) => Rx.
|
|
|
1302
1229
|
};
|
|
1303
1230
|
});
|
|
1304
1231
|
var TableToolbar = ({ classNames, viewDirty, attendableId, onAdd, onSave, customActions }) => {
|
|
1305
|
-
var _effect =
|
|
1232
|
+
var _effect = _useSignals9();
|
|
1306
1233
|
try {
|
|
1307
|
-
const state =
|
|
1234
|
+
const state = useMemo6(() => live({
|
|
1308
1235
|
viewDirty
|
|
1309
1236
|
}), []);
|
|
1310
|
-
const actionsCreator =
|
|
1237
|
+
const actionsCreator = useMemo6(() => createTableToolbarActions({
|
|
1311
1238
|
state,
|
|
1312
1239
|
onAdd,
|
|
1313
1240
|
onSave,
|
|
@@ -1319,10 +1246,10 @@ var TableToolbar = ({ classNames, viewDirty, attendableId, onAdd, onSave, custom
|
|
|
1319
1246
|
customActions
|
|
1320
1247
|
]);
|
|
1321
1248
|
const menu = useMenuActions(actionsCreator);
|
|
1322
|
-
return /* @__PURE__ */
|
|
1249
|
+
return /* @__PURE__ */ React9.createElement(MenuProvider, {
|
|
1323
1250
|
...menu,
|
|
1324
1251
|
attendableId
|
|
1325
|
-
}, /* @__PURE__ */
|
|
1252
|
+
}, /* @__PURE__ */ React9.createElement(ToolbarMenu, {
|
|
1326
1253
|
classNames
|
|
1327
1254
|
}));
|
|
1328
1255
|
} finally {
|
|
@@ -1341,7 +1268,6 @@ export {
|
|
|
1341
1268
|
TablePresentation,
|
|
1342
1269
|
TableToolbar,
|
|
1343
1270
|
cellClassesForRowSelection,
|
|
1344
|
-
createTable,
|
|
1345
1271
|
getBaseSchema,
|
|
1346
1272
|
makeDynamicTable,
|
|
1347
1273
|
narrowSchema,
|
|
@@ -1350,6 +1276,7 @@ export {
|
|
|
1350
1276
|
touch,
|
|
1351
1277
|
translations,
|
|
1352
1278
|
useAddRow,
|
|
1279
|
+
useProjectionModel,
|
|
1353
1280
|
useTableModel
|
|
1354
1281
|
};
|
|
1355
1282
|
//# sourceMappingURL=index.mjs.map
|