@dxos/react-ui-table 0.8.4-main.c1de068 → 0.8.4-main.dedc0f3
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-63UUF4IG.mjs +66 -0
- package/dist/lib/browser/chunk-63UUF4IG.mjs.map +7 -0
- package/dist/lib/browser/{chunk-5XLSHLOG.mjs → chunk-GPZSXPSA.mjs} +535 -464
- package/dist/lib/browser/chunk-GPZSXPSA.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +730 -669
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +9 -6
- 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-K734DJB7.mjs +67 -0
- package/dist/lib/node-esm/chunk-K734DJB7.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-Y66YLSTC.mjs → chunk-XUD6W42C.mjs} +535 -464
- package/dist/lib/node-esm/chunk-XUD6W42C.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +730 -669
- 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 +9 -6
- 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/CreateRefPanel.d.ts +1 -1
- package/dist/types/src/components/Table/CreateRefPanel.d.ts.map +1 -1
- package/dist/types/src/components/Table/DynamicTable.d.ts.map +1 -1
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts +50 -2
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/Relations.stories.d.ts +44 -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 +3 -2
- package/dist/types/src/components/Table/Table.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.stories.d.ts +42 -3
- 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 +7 -3
- package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +8 -15
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts +39 -3
- package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TableToolbar/TableToolbar.d.ts.map +1 -1
- package/dist/types/src/hooks/useAddRow.d.ts +2 -1
- package/dist/types/src/hooks/useAddRow.d.ts.map +1 -1
- package/dist/types/src/hooks/useTableModel.d.ts +1 -1
- package/dist/types/src/hooks/useTableModel.d.ts.map +1 -1
- 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 +9 -7
- 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 +2 -3
- package/dist/types/src/model/table-sorting.d.ts.map +1 -1
- package/dist/types/src/testing/useTestTableModel.d.ts +2 -21
- 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/index.d.ts +1 -1
- package/dist/types/src/types/index.d.ts.map +1 -1
- package/dist/types/src/types/schema.d.ts +24 -4
- package/dist/types/src/types/schema.d.ts.map +1 -1
- package/dist/types/src/util/dynamic-table.d.ts +2 -2
- 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/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 +47 -42
- package/src/components/Table/ColumnActionsMenu.tsx +1 -1
- package/src/components/Table/ColumnSettings.tsx +1 -1
- package/src/components/Table/CreateRefPanel.tsx +25 -8
- package/src/components/Table/DynamicTable.stories.tsx +7 -4
- package/src/components/Table/DynamicTable.tsx +4 -3
- package/src/components/Table/{relations.stories.tsx → Relations.stories.tsx} +40 -23
- package/src/components/Table/RowActionsMenu.tsx +3 -3
- package/src/components/Table/Table.stories.tsx +39 -28
- package/src/components/Table/Table.tsx +138 -112
- package/src/components/TableCellEditor/CellValidationMessage.tsx +1 -1
- package/src/components/TableCellEditor/FormCellEditor.tsx +143 -42
- package/src/components/TableCellEditor/TableCellEditor.stories.tsx +12 -24
- package/src/components/TableCellEditor/TableCellEditor.tsx +74 -137
- package/src/components/TableToolbar/TableToolbar.tsx +2 -2
- package/src/components/testing.ts +1 -1
- package/src/hooks/useAddRow.ts +6 -4
- package/src/hooks/useTableModel.ts +1 -1
- package/src/model/modal-controller.ts +1 -1
- package/src/model/selection-model.ts +3 -2
- package/src/model/table-model.test.ts +3 -4
- package/src/model/table-model.ts +35 -24
- package/src/model/table-presentation.test.ts +4 -4
- package/src/model/table-presentation.ts +72 -30
- package/src/model/table-sorting.ts +16 -7
- package/src/playwright/smoke.spec.ts +129 -37
- package/src/testing/useTestTableModel.ts +7 -5
- package/src/translations.ts +2 -2
- package/src/types/index.ts +1 -1
- package/src/types/schema.ts +62 -5
- package/src/util/dynamic-table.ts +8 -7
- package/src/util/index.ts +0 -1
- package/src/util/schema.ts +1 -1
- 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/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/util/table.d.ts +0 -11
- package/dist/types/src/util/table.d.ts.map +0 -1
- package/src/components/TableCellEditor/extension.ts +0 -61
- 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,
|
|
@@ -16,8 +15,8 @@ import {
|
|
|
16
15
|
touch,
|
|
17
16
|
useAddRow,
|
|
18
17
|
useTableModel
|
|
19
|
-
} from "./chunk-
|
|
20
|
-
import "./chunk-
|
|
18
|
+
} from "./chunk-GPZSXPSA.mjs";
|
|
19
|
+
import "./chunk-63UUF4IG.mjs";
|
|
21
20
|
|
|
22
21
|
// src/translations.ts
|
|
23
22
|
var translationKey = "react-ui-table";
|
|
@@ -29,8 +28,8 @@ var translations = [
|
|
|
29
28
|
"create object label": "Create table",
|
|
30
29
|
"table name placeholder": "Table name",
|
|
31
30
|
"settings title": "Table settings",
|
|
32
|
-
"table schema label": "
|
|
33
|
-
"new schema": "New
|
|
31
|
+
"table schema label": "Record type",
|
|
32
|
+
"new schema": "New record type",
|
|
34
33
|
"continue label": "Continue",
|
|
35
34
|
"create stack section label": "Create table",
|
|
36
35
|
"add row label": "Add row",
|
|
@@ -53,270 +52,37 @@ var translations = [
|
|
|
53
52
|
|
|
54
53
|
// src/components/Table/Table.tsx
|
|
55
54
|
import { useSignals as _useSignals8 } from "@preact-signals/safe-react/tracking";
|
|
56
|
-
import React8, { forwardRef, useCallback as useCallback5,
|
|
57
|
-
import { Filter } from "@dxos/echo";
|
|
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 React8, { forwardRef, useCallback as useCallback5, useEffect as useEffect3, useImperativeHandle, useMemo as useMemo5, useState as useState4 } from "react";
|
|
62
56
|
import { useAttention } from "@dxos/react-ui-attention";
|
|
63
|
-
import { closestCell,
|
|
57
|
+
import { Grid, closestCell, gridSeparatorBlockEnd, gridSeparatorInlineEnd } from "@dxos/react-ui-grid";
|
|
58
|
+
import { DxEditRequest } from "@dxos/react-ui-grid";
|
|
64
59
|
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
60
|
|
|
296
61
|
// src/components/TableCellEditor/TableCellEditor.tsx
|
|
297
|
-
import { useSignals as
|
|
298
|
-
import
|
|
62
|
+
import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
|
|
63
|
+
import { EditorView } from "@codemirror/view";
|
|
64
|
+
import React3, { useCallback as useCallback2, useMemo as useMemo2, useRef as useRef2, useState as useState2 } from "react";
|
|
65
|
+
import { debounce } from "@dxos/async";
|
|
299
66
|
import { FormatEnum, TypeEnum } from "@dxos/echo-schema";
|
|
300
67
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
301
|
-
import { useThemeContext } from "@dxos/react-ui";
|
|
302
68
|
import { createMarkdownExtensions } from "@dxos/react-ui-editor";
|
|
303
|
-
import {
|
|
304
|
-
import {
|
|
69
|
+
import { GridCellEditor, editorKeys, parseCellIndex as parseCellIndex2, useGridContext as useGridContext3 } from "@dxos/react-ui-grid";
|
|
70
|
+
import { createLinks, tagPicker } from "@dxos/react-ui-tag-picker";
|
|
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,107 @@ 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 React2, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
106
|
+
import { Filter, Obj } from "@dxos/echo";
|
|
107
|
+
import { Ref, getValue } from "@dxos/echo-schema";
|
|
341
108
|
import { invariant } from "@dxos/invariant";
|
|
342
|
-
import {
|
|
343
|
-
import {
|
|
344
|
-
import {
|
|
345
|
-
import {
|
|
109
|
+
import { getSnapshot } from "@dxos/live-object";
|
|
110
|
+
import { getSpace } from "@dxos/react-client/echo";
|
|
111
|
+
import { Popover } from "@dxos/react-ui";
|
|
112
|
+
import { Form } from "@dxos/react-ui-form";
|
|
113
|
+
import { cellQuery, parseCellIndex, useGridContext as useGridContext2 } from "@dxos/react-ui-grid";
|
|
114
|
+
import { getDeep, isNotFalsy, setDeep } from "@dxos/util";
|
|
346
115
|
var __dxlog_file = "/__w/dxos/dxos/packages/ui/react-ui-table/src/components/TableCellEditor/FormCellEditor.tsx";
|
|
347
|
-
var
|
|
348
|
-
|
|
116
|
+
var createOptionLabel = [
|
|
117
|
+
"create new object label",
|
|
118
|
+
{
|
|
119
|
+
ns: translationKey
|
|
120
|
+
}
|
|
121
|
+
];
|
|
122
|
+
var FormCellEditor = ({ fieldProjection, model, schema, onSave, client, modals, __gridScope, ...formProps }) => {
|
|
123
|
+
var _effect = _useSignals2();
|
|
349
124
|
try {
|
|
350
|
-
const { editing: contextEditing, setEditing } =
|
|
351
|
-
const [editing, setLocalEditing] =
|
|
125
|
+
const { editing: contextEditing, setEditing, id: gridId } = useGridContext2("ArrayEditor", __gridScope);
|
|
126
|
+
const [editing, setLocalEditing] = useState(false);
|
|
352
127
|
const anchorRef = useRef(null);
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
128
|
+
const getSchema = useCallback((typeAnnotation) => {
|
|
129
|
+
const space = getSpace(model.view);
|
|
130
|
+
invariant(space, void 0, {
|
|
131
|
+
F: __dxlog_file,
|
|
132
|
+
L: 53,
|
|
133
|
+
S: void 0,
|
|
134
|
+
A: [
|
|
135
|
+
"space",
|
|
136
|
+
""
|
|
137
|
+
]
|
|
138
|
+
});
|
|
139
|
+
let schema2;
|
|
140
|
+
if (client) {
|
|
141
|
+
schema2 = client.graph.schemaRegistry.getSchema(typeAnnotation.typename);
|
|
142
|
+
}
|
|
143
|
+
if (!schema2) {
|
|
144
|
+
schema2 = space.db.schemaRegistry.getSchema(typeAnnotation.typename);
|
|
360
145
|
}
|
|
146
|
+
return {
|
|
147
|
+
space,
|
|
148
|
+
schema: schema2
|
|
149
|
+
};
|
|
361
150
|
}, [
|
|
362
|
-
|
|
151
|
+
client,
|
|
152
|
+
model
|
|
363
153
|
]);
|
|
364
|
-
const
|
|
365
|
-
|
|
366
|
-
|
|
154
|
+
const handleQueryRefOptions = useCallback(async (typeAnnotation) => {
|
|
155
|
+
const { schema: schema2, space } = getSchema(typeAnnotation);
|
|
156
|
+
if (model && schema2 && space) {
|
|
157
|
+
const { objects } = await space.db.query(Filter.type(schema2)).run();
|
|
158
|
+
return objects.map((obj) => {
|
|
159
|
+
return {
|
|
160
|
+
dxn: Obj.getDXN(obj),
|
|
161
|
+
label: getValue(obj, fieldProjection.field.referencePath) || obj.id.toString()
|
|
162
|
+
};
|
|
163
|
+
}).filter(isNotFalsy);
|
|
367
164
|
}
|
|
368
|
-
return
|
|
369
|
-
fieldProjection.field.path
|
|
370
|
-
]);
|
|
165
|
+
return [];
|
|
371
166
|
}, [
|
|
372
|
-
|
|
373
|
-
|
|
167
|
+
client,
|
|
168
|
+
model
|
|
374
169
|
]);
|
|
375
|
-
const originalRow =
|
|
170
|
+
const originalRow = useMemo(() => {
|
|
376
171
|
if (model && contextEditing) {
|
|
377
172
|
const cell = parseCellIndex(contextEditing.index);
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
173
|
+
if (model.isDraftCell(cell)) {
|
|
174
|
+
const draftRow = model.draftRows.value[cell.row];
|
|
175
|
+
invariant(draftRow, void 0, {
|
|
176
|
+
F: __dxlog_file,
|
|
177
|
+
L: 94,
|
|
178
|
+
S: void 0,
|
|
179
|
+
A: [
|
|
180
|
+
"draftRow",
|
|
181
|
+
""
|
|
182
|
+
]
|
|
183
|
+
});
|
|
184
|
+
return draftRow.data;
|
|
185
|
+
} else {
|
|
186
|
+
const row = model.getRowAt(cell.row);
|
|
187
|
+
invariant(row, void 0, {
|
|
188
|
+
F: __dxlog_file,
|
|
189
|
+
L: 98,
|
|
190
|
+
S: void 0,
|
|
191
|
+
A: [
|
|
192
|
+
"row",
|
|
193
|
+
""
|
|
194
|
+
]
|
|
195
|
+
});
|
|
196
|
+
return row;
|
|
197
|
+
}
|
|
389
198
|
}
|
|
390
199
|
return void 0;
|
|
391
200
|
}, [
|
|
392
201
|
model,
|
|
393
202
|
contextEditing
|
|
394
203
|
]);
|
|
395
|
-
const
|
|
396
|
-
if (originalRow) {
|
|
397
|
-
return getSnapshot(originalRow);
|
|
398
|
-
}
|
|
399
|
-
}, [
|
|
400
|
-
originalRow
|
|
401
|
-
]);
|
|
402
|
-
const handleSave = useCallback3((values) => {
|
|
204
|
+
const handleSave = useCallback((values) => {
|
|
403
205
|
const path = fieldProjection.field.path;
|
|
404
206
|
const value = getDeep(values, [
|
|
405
207
|
path
|
|
@@ -407,14 +209,74 @@ var FormCellEditor = ({ fieldProjection, model, schema, onSave, __gridScope }) =
|
|
|
407
209
|
setDeep(originalRow, [
|
|
408
210
|
path
|
|
409
211
|
], value);
|
|
212
|
+
contextEditing?.cellElement?.focus();
|
|
410
213
|
setEditing(null);
|
|
411
214
|
setLocalEditing(false);
|
|
412
215
|
onSave?.();
|
|
413
216
|
}, [
|
|
414
217
|
fieldProjection.field.path,
|
|
218
|
+
onSave,
|
|
219
|
+
contextEditing,
|
|
220
|
+
originalRow
|
|
221
|
+
]);
|
|
222
|
+
const handleCreate = useCallback((object) => {
|
|
223
|
+
const ref = Ref.make(object);
|
|
224
|
+
const path = fieldProjection.field.path;
|
|
225
|
+
setDeep(originalRow, [
|
|
226
|
+
path
|
|
227
|
+
], ref);
|
|
228
|
+
contextEditing?.cellElement?.focus();
|
|
229
|
+
setEditing(null);
|
|
230
|
+
setLocalEditing(false);
|
|
231
|
+
onSave?.();
|
|
232
|
+
}, [
|
|
233
|
+
fieldProjection.field.path,
|
|
234
|
+
onSave,
|
|
235
|
+
contextEditing,
|
|
236
|
+
originalRow
|
|
237
|
+
]);
|
|
238
|
+
const handleCreateFromQuery = useCallback(async (typeAnnotation, query) => {
|
|
239
|
+
if (model && modals && contextEditing?.index) {
|
|
240
|
+
setLocalEditing(false);
|
|
241
|
+
modals.openCreateRef(typeAnnotation.typename, document.querySelector(cellQuery(contextEditing.index, gridId)), {
|
|
242
|
+
[fieldProjection.field.referencePath]: query
|
|
243
|
+
}, handleCreate);
|
|
244
|
+
}
|
|
245
|
+
}, [
|
|
246
|
+
model,
|
|
247
|
+
modals,
|
|
248
|
+
client,
|
|
249
|
+
contextEditing?.index,
|
|
250
|
+
gridId,
|
|
251
|
+
fieldProjection,
|
|
252
|
+
handleSave
|
|
253
|
+
]);
|
|
254
|
+
useEffect(() => {
|
|
255
|
+
if (contextEditing && contextEditing.cellElement) {
|
|
256
|
+
anchorRef.current = contextEditing.cellElement.querySelector(".dx-grid__cell__content");
|
|
257
|
+
setLocalEditing(true);
|
|
258
|
+
} else {
|
|
259
|
+
anchorRef.current = null;
|
|
260
|
+
setLocalEditing(false);
|
|
261
|
+
}
|
|
262
|
+
}, [
|
|
263
|
+
contextEditing
|
|
264
|
+
]);
|
|
265
|
+
const narrowedSchema = useMemo(() => {
|
|
266
|
+
if (!schema) {
|
|
267
|
+
return void 0;
|
|
268
|
+
}
|
|
269
|
+
return narrowSchema(schema, [
|
|
270
|
+
fieldProjection.field.path
|
|
271
|
+
]);
|
|
272
|
+
}, [
|
|
273
|
+
JSON.stringify(schema),
|
|
274
|
+
fieldProjection.field.path
|
|
275
|
+
]);
|
|
276
|
+
const formValues = useMemo(() => originalRow ? getSnapshot(originalRow) : {}, [
|
|
415
277
|
originalRow
|
|
416
278
|
]);
|
|
417
|
-
const handleOpenChange =
|
|
279
|
+
const handleOpenChange = useCallback((nextOpen) => {
|
|
418
280
|
if (nextOpen === false) {
|
|
419
281
|
setEditing(null);
|
|
420
282
|
onSave?.();
|
|
@@ -424,76 +286,38 @@ var FormCellEditor = ({ fieldProjection, model, schema, onSave, __gridScope }) =
|
|
|
424
286
|
if (!editing) {
|
|
425
287
|
return null;
|
|
426
288
|
}
|
|
427
|
-
return /* @__PURE__ */
|
|
289
|
+
return /* @__PURE__ */ React2.createElement(Popover.Root, {
|
|
428
290
|
open: editing,
|
|
429
291
|
onOpenChange: handleOpenChange
|
|
430
|
-
}, /* @__PURE__ */
|
|
292
|
+
}, /* @__PURE__ */ React2.createElement(Popover.VirtualTrigger, {
|
|
431
293
|
virtualRef: anchorRef
|
|
432
|
-
}), /* @__PURE__ */
|
|
294
|
+
}), /* @__PURE__ */ React2.createElement(Popover.Portal, null, /* @__PURE__ */ React2.createElement(Popover.Content, {
|
|
433
295
|
tabIndex: -1,
|
|
434
296
|
classNames: "popover-card-width density-fine"
|
|
435
|
-
}, /* @__PURE__ */
|
|
297
|
+
}, /* @__PURE__ */ React2.createElement(Popover.Arrow, null), /* @__PURE__ */ React2.createElement(Popover.Viewport, null, /* @__PURE__ */ React2.createElement(Form, {
|
|
298
|
+
autoFocus: true,
|
|
436
299
|
values: formValues,
|
|
437
300
|
schema: narrowedSchema,
|
|
438
|
-
onSave: handleSave
|
|
439
|
-
|
|
301
|
+
onSave: handleSave,
|
|
302
|
+
...formProps,
|
|
303
|
+
onQueryRefOptions: handleQueryRefOptions,
|
|
304
|
+
onCreateFromQuery: handleCreateFromQuery,
|
|
305
|
+
createOptionIcon: "ph--plus--regular",
|
|
306
|
+
createOptionLabel
|
|
307
|
+
})))));
|
|
440
308
|
} finally {
|
|
441
309
|
_effect.f();
|
|
442
310
|
}
|
|
443
311
|
};
|
|
444
312
|
|
|
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
313
|
// src/components/TableCellEditor/TableCellEditor.tsx
|
|
485
314
|
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();
|
|
315
|
+
var adaptValidationMessage = (message) => message ? message.endsWith("is missing") ? "Can\u2019t be blank" : message : null;
|
|
316
|
+
var TableValueEditor = ({ model, modals, schema, onFocus, onSave, client, __gridScope }) => {
|
|
317
|
+
var _effect = _useSignals3();
|
|
494
318
|
try {
|
|
495
|
-
const { editing } =
|
|
496
|
-
const fieldProjection =
|
|
319
|
+
const { editing } = useGridContext3("TableValueEditor", __gridScope);
|
|
320
|
+
const fieldProjection = useMemo2(() => {
|
|
497
321
|
if (!model || !editing) {
|
|
498
322
|
return;
|
|
499
323
|
}
|
|
@@ -502,7 +326,7 @@ var TableValueEditor = ({ model, modals, schema, onEnter, onFocus, onSave, onQue
|
|
|
502
326
|
const fieldProjection2 = model.projection.getFieldProjection(field.id);
|
|
503
327
|
invariant2(fieldProjection2, void 0, {
|
|
504
328
|
F: __dxlog_file2,
|
|
505
|
-
L:
|
|
329
|
+
L: 71,
|
|
506
330
|
S: void 0,
|
|
507
331
|
A: [
|
|
508
332
|
"fieldProjection",
|
|
@@ -514,21 +338,21 @@ var TableValueEditor = ({ model, modals, schema, onEnter, onFocus, onSave, onQue
|
|
|
514
338
|
model,
|
|
515
339
|
editing
|
|
516
340
|
]);
|
|
517
|
-
if (fieldProjection?.props.type === TypeEnum.Array || fieldProjection?.props.format === FormatEnum.SingleSelect) {
|
|
518
|
-
return /* @__PURE__ */
|
|
341
|
+
if (fieldProjection?.props.type === TypeEnum.Array || fieldProjection?.props.format === FormatEnum.SingleSelect || fieldProjection?.props.format === FormatEnum.Ref) {
|
|
342
|
+
return /* @__PURE__ */ React3.createElement(FormCellEditor, {
|
|
519
343
|
fieldProjection,
|
|
520
344
|
model,
|
|
521
345
|
schema,
|
|
522
346
|
__gridScope,
|
|
523
|
-
onSave
|
|
347
|
+
onSave,
|
|
348
|
+
client,
|
|
349
|
+
modals
|
|
524
350
|
});
|
|
525
351
|
}
|
|
526
|
-
return /* @__PURE__ */
|
|
352
|
+
return /* @__PURE__ */ React3.createElement(TableCellEditor, {
|
|
527
353
|
model,
|
|
528
354
|
modals,
|
|
529
|
-
onEnter,
|
|
530
355
|
onFocus,
|
|
531
|
-
onQuery,
|
|
532
356
|
onSave,
|
|
533
357
|
__gridScope
|
|
534
358
|
});
|
|
@@ -537,19 +361,18 @@ var TableValueEditor = ({ model, modals, schema, onEnter, onFocus, onSave, onQue
|
|
|
537
361
|
}
|
|
538
362
|
};
|
|
539
363
|
var editorSlots = {
|
|
540
|
-
|
|
364
|
+
scroll: {
|
|
541
365
|
className: "!plb-[--dx-grid-cell-editor-padding-block]"
|
|
542
366
|
}
|
|
543
367
|
};
|
|
544
|
-
var TableCellEditor = ({ model, modals,
|
|
545
|
-
var _effect =
|
|
368
|
+
var TableCellEditor = ({ model, modals, onFocus, onSave, __gridScope }) => {
|
|
369
|
+
var _effect = _useSignals3();
|
|
546
370
|
try {
|
|
547
|
-
const {
|
|
371
|
+
const { editing, setEditing } = useGridContext3("TableCellEditor", __gridScope);
|
|
548
372
|
const suppressNextBlur = useRef2(false);
|
|
549
|
-
const
|
|
550
|
-
const [
|
|
551
|
-
const
|
|
552
|
-
const fieldProjection = useMemo4(() => {
|
|
373
|
+
const [validationError, setValidationError] = useState2(null);
|
|
374
|
+
const [validationVariant, setValidationVariant] = useState2("error");
|
|
375
|
+
const fieldProjection = useMemo2(() => {
|
|
553
376
|
if (!model || !editing) {
|
|
554
377
|
return;
|
|
555
378
|
}
|
|
@@ -558,7 +381,7 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, onSave, __gri
|
|
|
558
381
|
const fieldProjection2 = model.projection.getFieldProjection(field.id);
|
|
559
382
|
invariant2(fieldProjection2, void 0, {
|
|
560
383
|
F: __dxlog_file2,
|
|
561
|
-
L:
|
|
384
|
+
L: 120,
|
|
562
385
|
S: void 0,
|
|
563
386
|
A: [
|
|
564
387
|
"fieldProjection",
|
|
@@ -570,38 +393,7 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, onSave, __gri
|
|
|
570
393
|
model,
|
|
571
394
|
editing
|
|
572
395
|
]);
|
|
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) => {
|
|
396
|
+
const handleEnter = useCallback2(async (value) => {
|
|
605
397
|
if (!model || !editing) {
|
|
606
398
|
return;
|
|
607
399
|
}
|
|
@@ -610,33 +402,39 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, onSave, __gri
|
|
|
610
402
|
if (validationResult.valid) {
|
|
611
403
|
setValidationError(null);
|
|
612
404
|
model.setCellData(cell, value);
|
|
613
|
-
onEnter?.(cell);
|
|
614
405
|
onFocus?.();
|
|
615
406
|
setEditing(null);
|
|
616
407
|
onSave?.();
|
|
617
408
|
} else {
|
|
618
|
-
setValidationError(validationResult.error);
|
|
409
|
+
setValidationError(adaptValidationMessage(validationResult.error));
|
|
619
410
|
setValidationVariant("error");
|
|
620
411
|
}
|
|
621
412
|
}, [
|
|
622
413
|
model,
|
|
623
414
|
editing,
|
|
624
|
-
onEnter,
|
|
625
415
|
onFocus,
|
|
626
416
|
setEditing
|
|
627
417
|
]);
|
|
628
|
-
const handleBlur =
|
|
629
|
-
if (!model || !editing) {
|
|
630
|
-
return;
|
|
631
|
-
}
|
|
418
|
+
const handleBlur = useCallback2(async (value) => {
|
|
632
419
|
if (suppressNextBlur.current) {
|
|
633
420
|
suppressNextBlur.current = false;
|
|
421
|
+
} else if (model && editing) {
|
|
422
|
+
const cell = parseCellIndex2(editing.index);
|
|
423
|
+
if (value !== void 0) {
|
|
424
|
+
const result = await model.validateCellData(cell, value);
|
|
425
|
+
if (result.valid) {
|
|
426
|
+
setValidationError(null);
|
|
427
|
+
model.setCellData(cell, value);
|
|
428
|
+
setEditing(null);
|
|
429
|
+
onSave?.();
|
|
430
|
+
}
|
|
431
|
+
}
|
|
634
432
|
}
|
|
635
433
|
}, [
|
|
636
434
|
model,
|
|
637
435
|
editing
|
|
638
436
|
]);
|
|
639
|
-
const handleClose =
|
|
437
|
+
const handleClose = useCallback2(async (value, event) => {
|
|
640
438
|
if (!model || !editing || !fieldProjection) {
|
|
641
439
|
return;
|
|
642
440
|
}
|
|
@@ -644,19 +442,20 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, onSave, __gri
|
|
|
644
442
|
if (value !== void 0) {
|
|
645
443
|
const result = await model.validateCellData(cell, value);
|
|
646
444
|
if (result.valid) {
|
|
445
|
+
suppressNextBlur.current = true;
|
|
647
446
|
setValidationError(null);
|
|
648
447
|
model.setCellData(cell, value);
|
|
649
448
|
setEditing(null);
|
|
650
449
|
onSave?.();
|
|
651
|
-
onEnter?.(cell);
|
|
652
450
|
if (event && onFocus) {
|
|
653
|
-
onFocus(determineNavigationAxis(event), determineNavigationDelta(event));
|
|
451
|
+
onFocus(determineNavigationAxis(event), determineNavigationDelta(event), cell);
|
|
654
452
|
}
|
|
655
453
|
} else {
|
|
656
454
|
setValidationError(result.error);
|
|
657
455
|
setValidationVariant("error");
|
|
658
456
|
}
|
|
659
457
|
} else {
|
|
458
|
+
suppressNextBlur.current = true;
|
|
660
459
|
setValidationError(null);
|
|
661
460
|
setEditing(null);
|
|
662
461
|
onSave?.();
|
|
@@ -665,182 +464,416 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, onSave, __gri
|
|
|
665
464
|
}
|
|
666
465
|
}
|
|
667
466
|
}, [
|
|
668
|
-
model,
|
|
669
|
-
editing,
|
|
670
|
-
onFocus,
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
467
|
+
model,
|
|
468
|
+
editing,
|
|
469
|
+
onFocus,
|
|
470
|
+
fieldProjection,
|
|
471
|
+
setEditing,
|
|
472
|
+
onSave
|
|
473
|
+
]);
|
|
474
|
+
const extensions = useMemo2(() => {
|
|
475
|
+
if (!fieldProjection) {
|
|
476
|
+
return [];
|
|
477
|
+
}
|
|
478
|
+
const extensions2 = [
|
|
479
|
+
editorKeys({
|
|
480
|
+
onClose: handleClose,
|
|
481
|
+
...editing?.initialContent && {
|
|
482
|
+
onNav: handleClose
|
|
483
|
+
}
|
|
484
|
+
})
|
|
485
|
+
];
|
|
486
|
+
const format = fieldProjection.props.format;
|
|
487
|
+
if (format === FormatEnum.SingleSelect || format === FormatEnum.MultiSelect) {
|
|
488
|
+
const options = fieldProjection.props.options || [];
|
|
489
|
+
const mode = format === FormatEnum.SingleSelect ? "single-select" : "multi-select";
|
|
490
|
+
extensions2.push(createMarkdownExtensions());
|
|
491
|
+
extensions2.push(tagPicker({
|
|
492
|
+
mode,
|
|
493
|
+
keymap: false,
|
|
494
|
+
onSearch: (text, selectedIds) => {
|
|
495
|
+
return options.filter((option) => selectedIds.indexOf(option.id) === -1 && (text.length === 0 || option.title.toLowerCase().includes(text.toLowerCase()))).map((option) => ({
|
|
496
|
+
id: option.id,
|
|
497
|
+
label: option.title,
|
|
498
|
+
hue: option.color
|
|
499
|
+
}));
|
|
500
|
+
},
|
|
501
|
+
onUpdate: (ids) => {
|
|
502
|
+
if (model && editing) {
|
|
503
|
+
if (ids.length === 0) {
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
if (mode === "single-select") {
|
|
507
|
+
void handleEnter(ids[0]);
|
|
508
|
+
} else {
|
|
509
|
+
void handleEnter(ids);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}));
|
|
514
|
+
}
|
|
515
|
+
if (model && editing) {
|
|
516
|
+
extensions2.push(EditorView.updateListener.of(debounce((update) => {
|
|
517
|
+
const content = update.state.doc.toString();
|
|
518
|
+
const cell = parseCellIndex2(editing.index);
|
|
519
|
+
void model.validateCellData(cell, content).then((result) => {
|
|
520
|
+
if (result.valid) {
|
|
521
|
+
setValidationError(null);
|
|
522
|
+
} else {
|
|
523
|
+
setValidationError(result.error);
|
|
524
|
+
setValidationVariant("error");
|
|
525
|
+
}
|
|
526
|
+
});
|
|
527
|
+
}, 10)));
|
|
528
|
+
}
|
|
529
|
+
return extensions2;
|
|
530
|
+
}, [
|
|
531
|
+
model,
|
|
532
|
+
modals,
|
|
533
|
+
editing,
|
|
534
|
+
fieldProjection,
|
|
535
|
+
handleClose
|
|
536
|
+
]);
|
|
537
|
+
const getCellContent = useCallback2(() => {
|
|
538
|
+
if (model && editing) {
|
|
539
|
+
const cell = parseCellIndex2(editing.index);
|
|
540
|
+
const { col } = cell;
|
|
541
|
+
const field = model.projection.fields[col];
|
|
542
|
+
const fieldProjection2 = model.projection.getFieldProjection(field.id);
|
|
543
|
+
if (fieldProjection2?.props.format === FormatEnum.SingleSelect || fieldProjection2?.props.format === FormatEnum.MultiSelect) {
|
|
544
|
+
const value2 = model.getCellData(cell);
|
|
545
|
+
if (value2 !== void 0) {
|
|
546
|
+
const options = fieldProjection2.props.options || [];
|
|
547
|
+
if (fieldProjection2.props.format === FormatEnum.MultiSelect) {
|
|
548
|
+
const tagItems = value2.split(",").map((id) => {
|
|
549
|
+
const option = options.find((o) => o.id === id);
|
|
550
|
+
if (option) {
|
|
551
|
+
return {
|
|
552
|
+
id,
|
|
553
|
+
label: option.title,
|
|
554
|
+
hue: option.color
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
return void 0;
|
|
558
|
+
}).filter((item) => item !== void 0);
|
|
559
|
+
return createLinks(tagItems);
|
|
560
|
+
} else {
|
|
561
|
+
const option = options.find((o) => o.id === value2);
|
|
562
|
+
if (option) {
|
|
563
|
+
const tagItem = {
|
|
564
|
+
id: value2,
|
|
565
|
+
label: option.title,
|
|
566
|
+
hue: option.color
|
|
567
|
+
};
|
|
568
|
+
return createLinks([
|
|
569
|
+
tagItem
|
|
570
|
+
]);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
return "";
|
|
575
|
+
}
|
|
576
|
+
const value = model.getCellData(cell);
|
|
577
|
+
return value !== void 0 ? String(value) : "";
|
|
578
|
+
}
|
|
579
|
+
}, [
|
|
580
|
+
model,
|
|
581
|
+
editing
|
|
582
|
+
]);
|
|
583
|
+
return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(CellValidationMessage, {
|
|
584
|
+
validationError,
|
|
585
|
+
variant: validationVariant,
|
|
586
|
+
__gridScope
|
|
587
|
+
}), /* @__PURE__ */ React3.createElement(GridCellEditor, {
|
|
588
|
+
extensions,
|
|
589
|
+
getCellContent,
|
|
590
|
+
onBlur: handleBlur,
|
|
591
|
+
slots: editorSlots
|
|
592
|
+
}));
|
|
593
|
+
} finally {
|
|
594
|
+
_effect.f();
|
|
595
|
+
}
|
|
596
|
+
};
|
|
597
|
+
var determineNavigationAxis = ({ key }) => {
|
|
598
|
+
switch (key) {
|
|
599
|
+
case "ArrowUp":
|
|
600
|
+
case "ArrowDown":
|
|
601
|
+
case "Enter": {
|
|
602
|
+
return "row";
|
|
603
|
+
}
|
|
604
|
+
case "ArrowLeft":
|
|
605
|
+
case "ArrowRight":
|
|
606
|
+
case "Tab":
|
|
607
|
+
return "col";
|
|
608
|
+
}
|
|
609
|
+
};
|
|
610
|
+
var determineNavigationDelta = ({ key, shift }) => {
|
|
611
|
+
switch (key) {
|
|
612
|
+
case "ArrowUp":
|
|
613
|
+
case "ArrowLeft":
|
|
614
|
+
return -1;
|
|
615
|
+
case "ArrowDown":
|
|
616
|
+
case "ArrowRight":
|
|
617
|
+
return 1;
|
|
618
|
+
}
|
|
619
|
+
return shift ? -1 : 1;
|
|
620
|
+
};
|
|
621
|
+
|
|
622
|
+
// src/components/Table/ColumnActionsMenu.tsx
|
|
623
|
+
import { useSignals as _useSignals4 } from "@preact-signals/safe-react/tracking";
|
|
624
|
+
import React4 from "react";
|
|
625
|
+
import { DropdownMenu, useTranslation } from "@dxos/react-ui";
|
|
626
|
+
var ColumnActionsMenu = ({ model, modals }) => {
|
|
627
|
+
var _effect = _useSignals4();
|
|
628
|
+
try {
|
|
629
|
+
const { t } = useTranslation(translationKey);
|
|
630
|
+
const state = modals.state.value;
|
|
631
|
+
if (state?.type !== "column") {
|
|
632
|
+
return null;
|
|
633
|
+
}
|
|
634
|
+
const currentSort = model.sorting?.sorting;
|
|
635
|
+
const isCurrentColumnSorted = currentSort?.fieldId === state.fieldId;
|
|
636
|
+
return /* @__PURE__ */ React4.createElement(DropdownMenu.Root, {
|
|
637
|
+
modal: false,
|
|
638
|
+
open: true,
|
|
639
|
+
onOpenChange: modals.close
|
|
640
|
+
}, /* @__PURE__ */ React4.createElement(DropdownMenu.VirtualTrigger, {
|
|
641
|
+
virtualRef: modals.trigger
|
|
642
|
+
}), /* @__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, {
|
|
643
|
+
"data-testid": "column-sort-descending",
|
|
644
|
+
onClick: () => model.sorting?.setSort(state.fieldId, "desc")
|
|
645
|
+
}, t("column action sort descending")), (!isCurrentColumnSorted || currentSort?.direction === "desc") && /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
|
|
646
|
+
"data-testid": "column-sort-ascending",
|
|
647
|
+
onClick: () => model.sorting?.setSort(state.fieldId, "asc")
|
|
648
|
+
}, t("column action sort ascending")), isCurrentColumnSorted && /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
|
|
649
|
+
"data-testid": "column-clear-sort",
|
|
650
|
+
onClick: () => model.sorting?.clearSort()
|
|
651
|
+
}, t("column action clear sorting")), model.getColumnCount() > 1 && model.features.schemaEditable && /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
|
|
652
|
+
"data-testid": "column-delete",
|
|
653
|
+
onClick: () => model.deleteColumn(state.fieldId)
|
|
654
|
+
}, t("column action delete")), model.features.schemaEditable && /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
|
|
655
|
+
"data-testid": "column-settings",
|
|
656
|
+
onClick: () => modals.openColumnSettings()
|
|
657
|
+
}, t("column action settings"))), /* @__PURE__ */ React4.createElement(DropdownMenu.Arrow, null))));
|
|
658
|
+
} finally {
|
|
659
|
+
_effect.f();
|
|
660
|
+
}
|
|
661
|
+
};
|
|
662
|
+
|
|
663
|
+
// src/components/Table/ColumnSettings.tsx
|
|
664
|
+
import { useSignals as _useSignals5 } from "@preact-signals/safe-react/tracking";
|
|
665
|
+
import React5, { useCallback as useCallback3, useEffect as useEffect2, useMemo as useMemo3, useState as useState3 } from "react";
|
|
666
|
+
import { Popover as Popover2 } from "@dxos/react-ui";
|
|
667
|
+
import { FieldEditor } from "@dxos/react-ui-form";
|
|
668
|
+
var ColumnSettings = ({ registry, model, modals, onNewColumn }) => {
|
|
669
|
+
var _effect = _useSignals5();
|
|
670
|
+
try {
|
|
671
|
+
const [newField, setNewField] = useState3();
|
|
672
|
+
const state = modals.state.value;
|
|
673
|
+
useEffect2(() => {
|
|
674
|
+
if (state?.type === "columnSettings" && state.mode.type === "create" && model?.projection) {
|
|
675
|
+
setNewField(model.projection.createFieldProjection());
|
|
676
|
+
requestAnimationFrame(() => {
|
|
677
|
+
onNewColumn();
|
|
678
|
+
});
|
|
679
|
+
} else {
|
|
680
|
+
setNewField(void 0);
|
|
681
|
+
}
|
|
682
|
+
}, [
|
|
683
|
+
model?.projection,
|
|
684
|
+
state
|
|
685
|
+
]);
|
|
686
|
+
const existingField = useMemo3(() => {
|
|
687
|
+
if (state?.type === "columnSettings") {
|
|
688
|
+
const { mode } = state;
|
|
689
|
+
if (mode.type === "edit") {
|
|
690
|
+
return model?.projection?.fields.find((f) => f.id === mode.fieldId);
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
return void 0;
|
|
694
|
+
}, [
|
|
695
|
+
model?.projection?.fields,
|
|
696
|
+
state
|
|
697
|
+
]);
|
|
698
|
+
const field = existingField ?? newField;
|
|
699
|
+
const handleSave = useCallback3(() => {
|
|
700
|
+
modals.close();
|
|
701
|
+
}, [
|
|
702
|
+
modals
|
|
703
|
+
]);
|
|
704
|
+
const handleCancel = useCallback3(() => {
|
|
705
|
+
if (state?.type === "columnSettings" && state.mode.type === "create" && newField) {
|
|
706
|
+
model?.projection.deleteFieldProjection(newField.id);
|
|
707
|
+
}
|
|
708
|
+
}, [
|
|
709
|
+
model?.projection,
|
|
710
|
+
state,
|
|
711
|
+
newField
|
|
712
|
+
]);
|
|
713
|
+
if (!model?.projection || !field) {
|
|
714
|
+
return null;
|
|
715
|
+
}
|
|
716
|
+
return /* @__PURE__ */ React5.createElement(Popover2.Root, {
|
|
717
|
+
modal: false,
|
|
718
|
+
open: state?.type === "columnSettings"
|
|
719
|
+
}, /* @__PURE__ */ React5.createElement(Popover2.VirtualTrigger, {
|
|
720
|
+
virtualRef: modals.trigger
|
|
721
|
+
}), /* @__PURE__ */ React5.createElement(Popover2.Portal, null, /* @__PURE__ */ React5.createElement(Popover2.Content, {
|
|
722
|
+
classNames: "md:is-64"
|
|
723
|
+
}, /* @__PURE__ */ React5.createElement(Popover2.Viewport, null, /* @__PURE__ */ React5.createElement(FieldEditor, {
|
|
724
|
+
projection: model.projection,
|
|
725
|
+
field,
|
|
726
|
+
registry,
|
|
727
|
+
onSave: handleSave,
|
|
728
|
+
onCancel: handleCancel
|
|
729
|
+
})), /* @__PURE__ */ React5.createElement(Popover2.Arrow, null))));
|
|
730
|
+
} finally {
|
|
731
|
+
_effect.f();
|
|
732
|
+
}
|
|
733
|
+
};
|
|
734
|
+
|
|
735
|
+
// src/components/Table/CreateRefPanel.tsx
|
|
736
|
+
import { useSignals as _useSignals6 } from "@preact-signals/safe-react/tracking";
|
|
737
|
+
import { Schema } from "effect";
|
|
738
|
+
import React6, { useCallback as useCallback4, useMemo as useMemo4 } from "react";
|
|
739
|
+
import { Type } from "@dxos/echo";
|
|
740
|
+
import { live } from "@dxos/live-object";
|
|
741
|
+
import { useClient } from "@dxos/react-client";
|
|
742
|
+
import { getSpace as getSpace2 } from "@dxos/react-client/echo";
|
|
743
|
+
import { Popover as Popover3 } from "@dxos/react-ui";
|
|
744
|
+
import { Form as Form2 } from "@dxos/react-ui-form";
|
|
745
|
+
import { useGridContext as useGridContext4 } from "@dxos/react-ui-grid";
|
|
746
|
+
var CreateRefPanel = ({ model, modals, __gridScope }) => {
|
|
747
|
+
var _effect = _useSignals6();
|
|
748
|
+
try {
|
|
749
|
+
const { id: gridId } = useGridContext4("TableCellEditor", __gridScope);
|
|
750
|
+
const client = useClient();
|
|
751
|
+
const space = model && getSpace2(model?.view);
|
|
752
|
+
const state = modals.state.value;
|
|
753
|
+
const getSchema = useCallback4(() => {
|
|
754
|
+
if (!space || state?.type !== "createRefPanel") {
|
|
755
|
+
return;
|
|
756
|
+
}
|
|
757
|
+
const staticSchema = client.graph.schemaRegistry.schemas.find((schema3) => Type.getTypename(schema3) === state.typename);
|
|
758
|
+
if (staticSchema) {
|
|
759
|
+
return staticSchema;
|
|
760
|
+
}
|
|
761
|
+
const [schema2] = space.db.schemaRegistry.query({
|
|
762
|
+
typename: state.typename
|
|
763
|
+
}).runSync();
|
|
764
|
+
return schema2;
|
|
765
|
+
}, [
|
|
766
|
+
space,
|
|
767
|
+
state
|
|
768
|
+
]);
|
|
769
|
+
const schema = useMemo4(() => {
|
|
770
|
+
const schema2 = getSchema();
|
|
771
|
+
if (!schema2) {
|
|
772
|
+
return;
|
|
773
|
+
}
|
|
774
|
+
const omit = Schema.omit("id");
|
|
775
|
+
return omit(schema2);
|
|
776
|
+
}, [
|
|
777
|
+
getSchema
|
|
675
778
|
]);
|
|
676
|
-
const
|
|
677
|
-
if (!
|
|
678
|
-
return
|
|
679
|
-
}
|
|
680
|
-
const extension2 = [
|
|
681
|
-
editorKeys({
|
|
682
|
-
onClose: handleClose,
|
|
683
|
-
...editing?.initialContent && {
|
|
684
|
-
onNav: handleClose
|
|
685
|
-
}
|
|
686
|
-
})
|
|
687
|
-
];
|
|
688
|
-
const format = fieldProjection.props.format;
|
|
689
|
-
if (format === FormatEnum.SingleSelect || format === FormatEnum.MultiSelect) {
|
|
690
|
-
extension2.push(createMarkdownExtensions({
|
|
691
|
-
themeMode
|
|
692
|
-
}));
|
|
693
|
-
const options = fieldProjection.props.options || [];
|
|
694
|
-
const mode = format === FormatEnum.SingleSelect ? "single-select" : "multi-select";
|
|
695
|
-
extension2.push(tagPicker({
|
|
696
|
-
mode,
|
|
697
|
-
keymap: false,
|
|
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
|
-
}
|
|
715
|
-
}
|
|
716
|
-
}
|
|
717
|
-
}));
|
|
779
|
+
const handleSave = useCallback4((values) => {
|
|
780
|
+
if (!model || !space || state?.type !== "createRefPanel") {
|
|
781
|
+
return;
|
|
718
782
|
}
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
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
|
-
}
|
|
783
|
+
const schema2 = getSchema();
|
|
784
|
+
if (schema2) {
|
|
785
|
+
const obj = space.db.add(live(schema2, values));
|
|
786
|
+
state.onCreate?.(obj);
|
|
747
787
|
}
|
|
748
|
-
|
|
788
|
+
void modals.close();
|
|
749
789
|
}, [
|
|
750
790
|
model,
|
|
751
791
|
modals,
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
handleClose,
|
|
755
|
-
themeMode
|
|
792
|
+
space,
|
|
793
|
+
state
|
|
756
794
|
]);
|
|
757
|
-
const
|
|
758
|
-
if (model
|
|
759
|
-
|
|
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
|
-
const value = model.getCellData(cell);
|
|
797
|
-
return value !== void 0 ? String(value) : "";
|
|
795
|
+
const handleCancel = useCallback4(() => {
|
|
796
|
+
if (model) {
|
|
797
|
+
modals.close();
|
|
798
798
|
}
|
|
799
799
|
}, [
|
|
800
|
-
|
|
801
|
-
editing
|
|
800
|
+
modals
|
|
802
801
|
]);
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
802
|
+
if (!model?.projection) {
|
|
803
|
+
return null;
|
|
804
|
+
}
|
|
805
|
+
return /* @__PURE__ */ React6.createElement(Popover3.Root, {
|
|
806
|
+
modal: false,
|
|
807
|
+
open: state?.type === "createRefPanel" && !!schema,
|
|
808
|
+
onOpenChange: (nextOpen) => {
|
|
809
|
+
if (model && !nextOpen) {
|
|
810
|
+
return modals.close();
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
}, /* @__PURE__ */ React6.createElement(Popover3.VirtualTrigger, {
|
|
814
|
+
virtualRef: modals.trigger
|
|
815
|
+
}), /* @__PURE__ */ React6.createElement(Popover3.Portal, null, /* @__PURE__ */ React6.createElement(Popover3.Content, {
|
|
816
|
+
classNames: "md:is-64",
|
|
817
|
+
"data-grid": gridId
|
|
818
|
+
}, /* @__PURE__ */ React6.createElement(Popover3.Viewport, null, state?.type === "createRefPanel" && schema && /* @__PURE__ */ React6.createElement(Form2, {
|
|
819
|
+
schema,
|
|
820
|
+
values: state.initialValues ?? {},
|
|
821
|
+
onSave: handleSave,
|
|
822
|
+
onCancel: handleCancel
|
|
823
|
+
})), /* @__PURE__ */ React6.createElement(Popover3.Arrow, null))));
|
|
813
824
|
} finally {
|
|
814
825
|
_effect.f();
|
|
815
826
|
}
|
|
816
827
|
};
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
828
|
+
|
|
829
|
+
// src/components/Table/RowActionsMenu.tsx
|
|
830
|
+
import { useSignals as _useSignals7 } from "@preact-signals/safe-react/tracking";
|
|
831
|
+
import React7 from "react";
|
|
832
|
+
import { DropdownMenu as DropdownMenu2, toLocalizedString, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
833
|
+
var RowActionsMenu = ({ model, modals }) => {
|
|
834
|
+
var _effect = _useSignals7();
|
|
835
|
+
try {
|
|
836
|
+
const { t } = useTranslation2(translationKey);
|
|
837
|
+
const hasSelection = model.selection.hasSelection.value;
|
|
838
|
+
const state = modals.state.value;
|
|
839
|
+
if (state?.type !== "row") {
|
|
840
|
+
return null;
|
|
823
841
|
}
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
842
|
+
return /* @__PURE__ */ React7.createElement(DropdownMenu2.Root, {
|
|
843
|
+
modal: false,
|
|
844
|
+
open: true,
|
|
845
|
+
onOpenChange: modals.close
|
|
846
|
+
}, /* @__PURE__ */ React7.createElement(DropdownMenu2.VirtualTrigger, {
|
|
847
|
+
virtualRef: modals.trigger
|
|
848
|
+
}), /* @__PURE__ */ React7.createElement(DropdownMenu2.Content, null, /* @__PURE__ */ React7.createElement(DropdownMenu2.Viewport, null, model.features.dataEditable !== false && /* @__PURE__ */ React7.createElement(DropdownMenu2.Item, {
|
|
849
|
+
"data-testid": "row-menu-delete",
|
|
850
|
+
onClick: () => model.deleteRow(state.rowIndex)
|
|
851
|
+
}, t(hasSelection ? "bulk delete row label" : "delete row label")), model.rowActions?.map((action) => /* @__PURE__ */ React7.createElement(DropdownMenu2.Item, {
|
|
852
|
+
key: action.id,
|
|
853
|
+
"data-testid": `row-action-${action.id}`,
|
|
854
|
+
onClick: () => {
|
|
855
|
+
modals.close();
|
|
856
|
+
model.handleRowAction(action.id, state.rowIndex);
|
|
857
|
+
}
|
|
858
|
+
}, toLocalizedString(action.label, t)))), /* @__PURE__ */ React7.createElement(DropdownMenu2.Arrow, null)));
|
|
859
|
+
} finally {
|
|
860
|
+
_effect.f();
|
|
838
861
|
}
|
|
839
|
-
return shift ? -1 : 1;
|
|
840
862
|
};
|
|
841
863
|
|
|
842
864
|
// src/components/Table/Table.tsx
|
|
843
|
-
var
|
|
865
|
+
var columnDefault = {
|
|
866
|
+
grid: {
|
|
867
|
+
minSize: 80,
|
|
868
|
+
maxSize: 640
|
|
869
|
+
}
|
|
870
|
+
};
|
|
871
|
+
var rowDefault = {
|
|
872
|
+
frozenRowsStart: {
|
|
873
|
+
readonly: true,
|
|
874
|
+
focusUnfurl: false
|
|
875
|
+
}
|
|
876
|
+
};
|
|
844
877
|
var TableRoot = ({ children, role = "article" }) => {
|
|
845
878
|
var _effect = _useSignals8();
|
|
846
879
|
try {
|
|
@@ -864,14 +897,19 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
864
897
|
try {
|
|
865
898
|
const [dxGrid, setDxGrid] = useState4(null);
|
|
866
899
|
const { hasAttention } = useAttention(model?.id ?? "table");
|
|
867
|
-
const { t } = useTranslation3(translationKey);
|
|
868
900
|
const modals = useMemo5(() => new ModalController(), []);
|
|
869
901
|
const draftRowCount = model?.getDraftRowCount() ?? 0;
|
|
902
|
+
const handleSave = useCallback5(() => {
|
|
903
|
+
dxGrid?.updateCells(true);
|
|
904
|
+
dxGrid?.requestUpdate();
|
|
905
|
+
}, [
|
|
906
|
+
dxGrid
|
|
907
|
+
]);
|
|
870
908
|
const frozen = useMemo5(() => {
|
|
871
909
|
const noActionColumn = model?.features.dataEditable === false && model?.features.schemaEditable === false && model.rowActions.length === 0;
|
|
872
910
|
return {
|
|
873
911
|
frozenRowsStart: 1,
|
|
874
|
-
frozenRowsEnd: draftRowCount,
|
|
912
|
+
frozenRowsEnd: Math.max(1, draftRowCount),
|
|
875
913
|
frozenColsStart: model?.features.selection.enabled ? 1 : 0,
|
|
876
914
|
frozenColsEnd: noActionColumn ? 0 : 1
|
|
877
915
|
};
|
|
@@ -882,7 +920,7 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
882
920
|
const getCells = useCallback5((range, plane) => presentation?.getCells(range, plane) ?? {}, [
|
|
883
921
|
presentation
|
|
884
922
|
]);
|
|
885
|
-
|
|
923
|
+
useEffect3(() => {
|
|
886
924
|
if (!presentation || !dxGrid) {
|
|
887
925
|
return;
|
|
888
926
|
}
|
|
@@ -892,6 +930,30 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
892
930
|
dxGrid,
|
|
893
931
|
getCells
|
|
894
932
|
]);
|
|
933
|
+
const handleInsertRowResult = useCallback5((insertResult) => {
|
|
934
|
+
if (insertResult === "draft") {
|
|
935
|
+
requestAnimationFrame(() => {
|
|
936
|
+
dxGrid?.setFocus({
|
|
937
|
+
plane: "frozenRowsEnd",
|
|
938
|
+
col: 0,
|
|
939
|
+
row: 0
|
|
940
|
+
});
|
|
941
|
+
dxGrid?.refocus();
|
|
942
|
+
});
|
|
943
|
+
} else {
|
|
944
|
+
requestAnimationFrame(() => {
|
|
945
|
+
dxGrid?.setFocus({
|
|
946
|
+
plane: "grid",
|
|
947
|
+
col: 0,
|
|
948
|
+
row: model ? model.getRowCount() - 1 : 0
|
|
949
|
+
});
|
|
950
|
+
dxGrid?.refocus();
|
|
951
|
+
});
|
|
952
|
+
}
|
|
953
|
+
}, [
|
|
954
|
+
model,
|
|
955
|
+
dxGrid
|
|
956
|
+
]);
|
|
895
957
|
useImperativeHandle(forwardedRef, () => {
|
|
896
958
|
if (!presentation || !dxGrid) {
|
|
897
959
|
return {};
|
|
@@ -904,18 +966,38 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
904
966
|
dxGrid.updateCells(true);
|
|
905
967
|
dxGrid.requestUpdate();
|
|
906
968
|
}
|
|
907
|
-
}
|
|
969
|
+
},
|
|
970
|
+
handleInsertRowResult
|
|
908
971
|
};
|
|
909
972
|
}, [
|
|
910
973
|
presentation,
|
|
974
|
+
dxGrid,
|
|
975
|
+
model
|
|
976
|
+
]);
|
|
977
|
+
const handleSaveDraftRow = useCallback5((rowIndex = 0) => {
|
|
978
|
+
if (model && dxGrid) {
|
|
979
|
+
const didCommitSuccessfully = model.commitDraftRow(rowIndex);
|
|
980
|
+
if (didCommitSuccessfully) {
|
|
981
|
+
requestAnimationFrame(() => {
|
|
982
|
+
dxGrid.scrollToEndRow();
|
|
983
|
+
});
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
}, [
|
|
987
|
+
model,
|
|
911
988
|
dxGrid
|
|
912
989
|
]);
|
|
913
990
|
const handleGridClick = useCallback5((event) => {
|
|
914
|
-
const
|
|
915
|
-
if (
|
|
991
|
+
const cell = closestCell(event.target);
|
|
992
|
+
if (cell) {
|
|
993
|
+
const { row: rowIndex, plane } = cell;
|
|
916
994
|
if (onRowClick) {
|
|
917
|
-
|
|
918
|
-
|
|
995
|
+
if (plane === "grid") {
|
|
996
|
+
const row = model?.getRowAt(rowIndex);
|
|
997
|
+
row && onRowClick(row);
|
|
998
|
+
} else {
|
|
999
|
+
onRowClick(cell);
|
|
1000
|
+
}
|
|
919
1001
|
}
|
|
920
1002
|
if (model?.features.selection.enabled && model?.selection.selectionMode === "single") {
|
|
921
1003
|
model.selection.toggleSelectionForRowIndex(rowIndex);
|
|
@@ -951,14 +1033,7 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
951
1033
|
break;
|
|
952
1034
|
}
|
|
953
1035
|
case "saveDraftRow": {
|
|
954
|
-
|
|
955
|
-
const didCommitSuccessfully = model.commitDraftRow(data.rowIndex);
|
|
956
|
-
if (dxGrid && didCommitSuccessfully) {
|
|
957
|
-
requestAnimationFrame(() => {
|
|
958
|
-
dxGrid.scrollToEndRow();
|
|
959
|
-
});
|
|
960
|
-
}
|
|
961
|
-
}
|
|
1036
|
+
handleSaveDraftRow();
|
|
962
1037
|
break;
|
|
963
1038
|
}
|
|
964
1039
|
}
|
|
@@ -997,29 +1072,20 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
997
1072
|
modals,
|
|
998
1073
|
dxGrid
|
|
999
1074
|
]);
|
|
1000
|
-
const handleFocus = useCallback5((increment, delta) => {
|
|
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
|
-
});
|
|
1075
|
+
const handleFocus = useCallback5((increment, delta, cell) => {
|
|
1076
|
+
if (dxGrid && model) {
|
|
1077
|
+
if (cell?.plane === "grid" && cell?.row >= model.getRowCount() - 1) {
|
|
1078
|
+
handleInsertRowResult(draftRowCount < 1 ? model.insertRow() : "final");
|
|
1079
|
+
} else if (cell?.plane === "frozenRowsEnd" && increment === "row") {
|
|
1080
|
+
handleSaveDraftRow(cell.row);
|
|
1081
|
+
handleInsertRowResult(model.insertRow());
|
|
1082
|
+
} else {
|
|
1083
|
+
dxGrid.refocus(increment, delta);
|
|
1018
1084
|
}
|
|
1019
1085
|
}
|
|
1020
1086
|
}, [
|
|
1021
|
-
|
|
1022
|
-
|
|
1087
|
+
dxGrid,
|
|
1088
|
+
model
|
|
1023
1089
|
]);
|
|
1024
1090
|
const handleKeyDown = useCallback5((event) => {
|
|
1025
1091
|
if (!model?.features.dataEditable) {
|
|
@@ -1029,15 +1095,63 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
1029
1095
|
if (!model || !cell) {
|
|
1030
1096
|
return;
|
|
1031
1097
|
}
|
|
1098
|
+
if (event.metaKey || event.ctrlKey) {
|
|
1099
|
+
switch (event.key) {
|
|
1100
|
+
case "c": {
|
|
1101
|
+
try {
|
|
1102
|
+
const cellData = model.getCellData(cell);
|
|
1103
|
+
const textContent = cellData?.toString() ?? "";
|
|
1104
|
+
void navigator.clipboard.writeText(textContent);
|
|
1105
|
+
event.preventDefault();
|
|
1106
|
+
} catch (error) {
|
|
1107
|
+
console.warn("Failed to copy cell content:", error);
|
|
1108
|
+
}
|
|
1109
|
+
break;
|
|
1110
|
+
}
|
|
1111
|
+
case "v": {
|
|
1112
|
+
event.preventDefault();
|
|
1113
|
+
void navigator.clipboard.readText().then((clipboardText) => {
|
|
1114
|
+
try {
|
|
1115
|
+
model.setCellData(cell, clipboardText);
|
|
1116
|
+
handleSave();
|
|
1117
|
+
} catch {
|
|
1118
|
+
const cellElement = event.target.closest('[data-dx-grid-action="cell"]');
|
|
1119
|
+
if (cellElement) {
|
|
1120
|
+
const rect = cellElement.getBoundingClientRect();
|
|
1121
|
+
const editRequest = new DxEditRequest({
|
|
1122
|
+
cellIndex: `${cell.plane},${cell.col},${cell.row}`,
|
|
1123
|
+
cellBox: {
|
|
1124
|
+
insetInlineStart: rect.left,
|
|
1125
|
+
insetBlockStart: rect.top,
|
|
1126
|
+
inlineSize: rect.width,
|
|
1127
|
+
blockSize: rect.height
|
|
1128
|
+
},
|
|
1129
|
+
cellElement,
|
|
1130
|
+
initialContent: clipboardText
|
|
1131
|
+
});
|
|
1132
|
+
cellElement.dispatchEvent(editRequest);
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
});
|
|
1136
|
+
break;
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1032
1140
|
switch (event.key) {
|
|
1033
1141
|
case "Backspace":
|
|
1034
1142
|
case "Delete": {
|
|
1035
|
-
|
|
1143
|
+
try {
|
|
1144
|
+
model.setCellData(cell, void 0);
|
|
1145
|
+
event.preventDefault();
|
|
1146
|
+
} catch {
|
|
1147
|
+
}
|
|
1036
1148
|
break;
|
|
1037
1149
|
}
|
|
1038
1150
|
}
|
|
1039
1151
|
}, [
|
|
1040
|
-
model
|
|
1152
|
+
model,
|
|
1153
|
+
dxGrid,
|
|
1154
|
+
handleSave
|
|
1041
1155
|
]);
|
|
1042
1156
|
const handleAxisResize = useCallback5((event) => {
|
|
1043
1157
|
if (event.axis === "col") {
|
|
@@ -1064,59 +1178,6 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
1064
1178
|
model,
|
|
1065
1179
|
dxGrid
|
|
1066
1180
|
]);
|
|
1067
|
-
const handleQuery = useCallback5(async ({ field, props }, text) => {
|
|
1068
|
-
if (model && props.referenceSchema && field.referencePath) {
|
|
1069
|
-
const space = getSpace2(model.view);
|
|
1070
|
-
invariant3(space, void 0, {
|
|
1071
|
-
F: __dxlog_file3,
|
|
1072
|
-
L: 325,
|
|
1073
|
-
S: void 0,
|
|
1074
|
-
A: [
|
|
1075
|
-
"space",
|
|
1076
|
-
""
|
|
1077
|
-
]
|
|
1078
|
-
});
|
|
1079
|
-
let schema2;
|
|
1080
|
-
if (client) {
|
|
1081
|
-
schema2 = client.graph.schemaRegistry.getSchema(props.referenceSchema);
|
|
1082
|
-
}
|
|
1083
|
-
if (!schema2) {
|
|
1084
|
-
schema2 = space.db.schemaRegistry.getSchema(props.referenceSchema);
|
|
1085
|
-
}
|
|
1086
|
-
if (schema2) {
|
|
1087
|
-
const { objects } = await space.db.query(Filter.type(schema2)).run();
|
|
1088
|
-
const options = objects.map((obj) => {
|
|
1089
|
-
const value = getValue(obj, field.referencePath);
|
|
1090
|
-
if (!value || typeof value !== "string") {
|
|
1091
|
-
return void 0;
|
|
1092
|
-
}
|
|
1093
|
-
return {
|
|
1094
|
-
label: value,
|
|
1095
|
-
data: obj
|
|
1096
|
-
};
|
|
1097
|
-
}).filter(isNotFalsy);
|
|
1098
|
-
return [
|
|
1099
|
-
...options,
|
|
1100
|
-
{
|
|
1101
|
-
label: t("create new object label", {
|
|
1102
|
-
text
|
|
1103
|
-
}),
|
|
1104
|
-
data: createOption(text)
|
|
1105
|
-
}
|
|
1106
|
-
];
|
|
1107
|
-
}
|
|
1108
|
-
}
|
|
1109
|
-
return [];
|
|
1110
|
-
}, [
|
|
1111
|
-
model,
|
|
1112
|
-
client,
|
|
1113
|
-
t
|
|
1114
|
-
]);
|
|
1115
|
-
const handleSave = useCallback5(() => {
|
|
1116
|
-
dxGrid?.updateCells(true);
|
|
1117
|
-
}, [
|
|
1118
|
-
dxGrid
|
|
1119
|
-
]);
|
|
1120
1181
|
if (!model || !modals) {
|
|
1121
1182
|
return /* @__PURE__ */ React8.createElement("span", {
|
|
1122
1183
|
role: "none",
|
|
@@ -1129,20 +1190,21 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
1129
1190
|
model,
|
|
1130
1191
|
modals,
|
|
1131
1192
|
schema,
|
|
1132
|
-
onEnter: handleEnter,
|
|
1133
1193
|
onFocus: handleFocus,
|
|
1134
|
-
|
|
1135
|
-
|
|
1194
|
+
onSave: handleSave,
|
|
1195
|
+
client
|
|
1136
1196
|
}), /* @__PURE__ */ React8.createElement(Grid.Content, {
|
|
1137
1197
|
className: mx("[--dx-grid-base:var(--baseSurface)]", gridSeparatorInlineEnd, gridSeparatorBlockEnd),
|
|
1138
1198
|
frozen,
|
|
1139
1199
|
columns: model.columnMeta.value,
|
|
1200
|
+
columnDefault,
|
|
1201
|
+
rowDefault,
|
|
1140
1202
|
limitRows: model.getRowCount() ?? 0,
|
|
1141
1203
|
limitColumns: model.projection.fields.length,
|
|
1142
1204
|
overscroll: "trap",
|
|
1143
1205
|
onAxisResize: handleAxisResize,
|
|
1144
1206
|
onClick: handleGridClick,
|
|
1145
|
-
|
|
1207
|
+
onKeyDownCapture: handleKeyDown,
|
|
1146
1208
|
onWheelCapture: handleWheel,
|
|
1147
1209
|
ref: setDxGrid
|
|
1148
1210
|
}), /* @__PURE__ */ React8.createElement(RowActionsMenu, {
|
|
@@ -1170,7 +1232,7 @@ var Table = {
|
|
|
1170
1232
|
|
|
1171
1233
|
// src/components/Table/DynamicTable.tsx
|
|
1172
1234
|
import { useSignals as _useSignals9 } from "@preact-signals/safe-react/tracking";
|
|
1173
|
-
import React9, {
|
|
1235
|
+
import React9, { useCallback as useCallback6, useMemo as useMemo6, useRef as useRef3 } from "react";
|
|
1174
1236
|
import { useDefaultValue } from "@dxos/react-ui";
|
|
1175
1237
|
import { mx as mx2 } from "@dxos/react-ui-theme";
|
|
1176
1238
|
var DynamicTable = ({ classNames, name = "example.com/dynamic-table", rows, properties, jsonSchema: _jsonSchema, schema, rowActions, onRowClick, onRowAction, ...props }) => {
|
|
@@ -1250,7 +1312,7 @@ import { useSignals as _useSignals10 } from "@preact-signals/safe-react/tracking
|
|
|
1250
1312
|
import { Rx } from "@effect-rx/rx-react";
|
|
1251
1313
|
import React10, { useMemo as useMemo7 } from "react";
|
|
1252
1314
|
import { live as live2 } from "@dxos/live-object";
|
|
1253
|
-
import {
|
|
1315
|
+
import { MenuProvider, ToolbarMenu, createGapSeparator, createMenuAction, useMenuActions } from "@dxos/react-ui-menu";
|
|
1254
1316
|
import { rxFromSignal } from "@dxos/react-ui-menu";
|
|
1255
1317
|
var createTableToolbarActions = ({ state, onAdd, onSave, customActions }) => Rx.make((get) => {
|
|
1256
1318
|
const add = createMenuAction("add-row", onAdd, {
|
|
@@ -1337,7 +1399,6 @@ export {
|
|
|
1337
1399
|
TablePresentation,
|
|
1338
1400
|
TableToolbar,
|
|
1339
1401
|
cellClassesForRowSelection,
|
|
1340
|
-
createTable,
|
|
1341
1402
|
getBaseSchema,
|
|
1342
1403
|
makeDynamicTable,
|
|
1343
1404
|
narrowSchema,
|