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