@dxos/react-ui-table 0.8.4-main.c1de068 → 0.8.4-main.f5c0578
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-5XLSHLOG.mjs → chunk-ZAOSIG3L.mjs} +382 -319
- package/dist/lib/browser/chunk-ZAOSIG3L.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +404 -381
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +4 -2
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/{chunk-Y66YLSTC.mjs → chunk-ZOFFI3JJ.mjs} +382 -319
- package/dist/lib/node-esm/chunk-ZOFFI3JJ.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +404 -381
- 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 +4 -2
- package/dist/lib/node-esm/testing/index.mjs.map +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 +1 -1
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/{relations.stories.d.ts → Relations.stories.d.ts} +2 -2
- 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 +1 -0
- package/dist/types/src/components/Table/Table.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.stories.d.ts +1 -1
- 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/TableCellEditor.d.ts +5 -5
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/extension.d.ts.map +1 -1
- package/dist/types/src/components/TableToolbar/TableToolbar.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 +3 -2
- 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 -2
- package/dist/types/src/model/table-sorting.d.ts.map +1 -1
- package/dist/types/src/testing/useTestTableModel.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +2 -2
- package/dist/types/src/util/dynamic-table.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/src/util/table.d.ts +2 -1
- package/dist/types/src/util/table.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +42 -38
- package/src/components/Table/ColumnActionsMenu.tsx +1 -1
- package/src/components/Table/ColumnSettings.tsx +1 -1
- package/src/components/Table/CreateRefPanel.tsx +1 -1
- package/src/components/Table/DynamicTable.stories.tsx +3 -2
- package/src/components/Table/DynamicTable.tsx +4 -3
- package/src/components/Table/{relations.stories.tsx → Relations.stories.tsx} +12 -4
- package/src/components/Table/RowActionsMenu.tsx +3 -3
- package/src/components/Table/Table.stories.tsx +12 -7
- package/src/components/Table/Table.tsx +56 -45
- package/src/components/TableCellEditor/CellValidationMessage.tsx +1 -1
- package/src/components/TableCellEditor/TableCellEditor.stories.tsx +4 -3
- package/src/components/TableCellEditor/TableCellEditor.tsx +16 -20
- package/src/components/TableCellEditor/extension.ts +2 -2
- package/src/components/TableToolbar/TableToolbar.tsx +2 -2
- package/src/components/testing.ts +1 -1
- 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 +2 -1
- package/src/model/table-model.ts +13 -10
- package/src/model/table-presentation.test.ts +3 -2
- package/src/model/table-presentation.ts +28 -6
- package/src/model/table-sorting.ts +3 -3
- package/src/playwright/smoke.spec.ts +92 -0
- package/src/testing/useTestTableModel.ts +3 -2
- package/src/translations.ts +2 -2
- package/src/util/dynamic-table.ts +2 -2
- package/src/util/schema.ts +1 -1
- package/src/util/table-buttons.ts +2 -1
- package/src/util/table-controls.ts +4 -1
- package/src/util/table.ts +7 -3
- package/dist/lib/browser/chunk-5XLSHLOG.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.map +0 -1
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
touch,
|
|
18
18
|
useAddRow,
|
|
19
19
|
useTableModel
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-ZOFFI3JJ.mjs";
|
|
21
21
|
import "./chunk-NXZ4CJYX.mjs";
|
|
22
22
|
|
|
23
23
|
// src/translations.ts
|
|
@@ -30,8 +30,8 @@ var translations = [
|
|
|
30
30
|
"create object label": "Create table",
|
|
31
31
|
"table name placeholder": "Table name",
|
|
32
32
|
"settings title": "Table settings",
|
|
33
|
-
"table schema label": "
|
|
34
|
-
"new schema": "New
|
|
33
|
+
"table schema label": "Record type",
|
|
34
|
+
"new schema": "New record type",
|
|
35
35
|
"continue label": "Continue",
|
|
36
36
|
"create stack section label": "Create table",
|
|
37
37
|
"add row label": "Add row",
|
|
@@ -54,270 +54,41 @@ var translations = [
|
|
|
54
54
|
|
|
55
55
|
// src/components/Table/Table.tsx
|
|
56
56
|
import { useSignals as _useSignals8 } from "@preact-signals/safe-react/tracking";
|
|
57
|
-
import React8, { forwardRef, useCallback as useCallback5,
|
|
57
|
+
import React8, { forwardRef, useCallback as useCallback5, useEffect as useEffect4, useImperativeHandle, useMemo as useMemo5, useState as useState4 } from "react";
|
|
58
58
|
import { Filter } from "@dxos/echo";
|
|
59
59
|
import { getValue } from "@dxos/echo-schema";
|
|
60
60
|
import { invariant as invariant3 } from "@dxos/invariant";
|
|
61
61
|
import { getSpace as getSpace2 } from "@dxos/react-client/echo";
|
|
62
62
|
import { useTranslation as useTranslation3 } from "@dxos/react-ui";
|
|
63
63
|
import { useAttention } from "@dxos/react-ui-attention";
|
|
64
|
-
import { closestCell,
|
|
64
|
+
import { Grid, closestCell, gridSeparatorBlockEnd, gridSeparatorInlineEnd } from "@dxos/react-ui-grid";
|
|
65
65
|
import { mx } from "@dxos/react-ui-theme";
|
|
66
66
|
import { isNotFalsy, safeParseInt } from "@dxos/util";
|
|
67
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
|
-
|
|
297
68
|
// src/components/TableCellEditor/TableCellEditor.tsx
|
|
298
|
-
import { useSignals as
|
|
299
|
-
import
|
|
69
|
+
import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
|
|
70
|
+
import React3, { useCallback as useCallback2, useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2, useState as useState2 } from "react";
|
|
300
71
|
import { FormatEnum, TypeEnum } from "@dxos/echo-schema";
|
|
301
72
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
302
73
|
import { useThemeContext } from "@dxos/react-ui";
|
|
303
74
|
import { createMarkdownExtensions } from "@dxos/react-ui-editor";
|
|
304
|
-
import { cellQuery, editorKeys, parseCellIndex as parseCellIndex2, useGridContext as
|
|
305
|
-
import {
|
|
75
|
+
import { GridCellEditor, cellQuery, editorKeys, parseCellIndex as parseCellIndex2, useGridContext as useGridContext3 } from "@dxos/react-ui-grid";
|
|
76
|
+
import { createLinks, tagPicker } from "@dxos/react-ui-tag-picker";
|
|
306
77
|
|
|
307
78
|
// src/components/TableCellEditor/CellValidationMessage.tsx
|
|
308
|
-
import { useSignals as
|
|
309
|
-
import
|
|
310
|
-
import { useGridContext
|
|
79
|
+
import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
|
|
80
|
+
import React from "react";
|
|
81
|
+
import { useGridContext } from "@dxos/react-ui-grid";
|
|
311
82
|
var CellValidationMessage = ({ validationError, variant = "error", __gridScope }) => {
|
|
312
|
-
var _effect =
|
|
83
|
+
var _effect = _useSignals();
|
|
313
84
|
try {
|
|
314
|
-
const { editing, editBox: box } =
|
|
85
|
+
const { editing, editBox: box } = useGridContext("GridSheetCellEditor", __gridScope);
|
|
315
86
|
if (!editing || !validationError) {
|
|
316
87
|
return null;
|
|
317
88
|
}
|
|
318
89
|
const bgClass = variant === "error" ? "bg-errorSurface" : "bg-warningSurface";
|
|
319
90
|
const textClass = variant === "error" ? "text-errorSurfaceText" : "text-warningSurfaceText";
|
|
320
|
-
return /* @__PURE__ */
|
|
91
|
+
return /* @__PURE__ */ React.createElement("div", {
|
|
321
92
|
role: "none",
|
|
322
93
|
className: `absolute ${bgClass} ${textClass} rounded-bs-sm text-xs p-1`,
|
|
323
94
|
style: {
|
|
@@ -335,23 +106,62 @@ var CellValidationMessage = ({ validationError, variant = "error", __gridScope }
|
|
|
335
106
|
}
|
|
336
107
|
};
|
|
337
108
|
|
|
109
|
+
// src/components/TableCellEditor/extension.ts
|
|
110
|
+
import { autocompletion, pickedCompletion } from "@codemirror/autocomplete";
|
|
111
|
+
import { EditorView } from "@codemirror/view";
|
|
112
|
+
var completion = ({ debug, onQuery, onMatch }) => {
|
|
113
|
+
return [
|
|
114
|
+
EditorView.theme({
|
|
115
|
+
".cm-completionDialog": {
|
|
116
|
+
width: "var(--dx-gridCellWidth)"
|
|
117
|
+
}
|
|
118
|
+
}),
|
|
119
|
+
autocompletion({
|
|
120
|
+
icons: false,
|
|
121
|
+
activateOnTyping: true,
|
|
122
|
+
closeOnBlur: !debug,
|
|
123
|
+
override: [
|
|
124
|
+
async (context) => {
|
|
125
|
+
const text = context.state.doc.toString();
|
|
126
|
+
return {
|
|
127
|
+
from: 0,
|
|
128
|
+
options: await onQuery(text)
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
],
|
|
132
|
+
// TODO(burdon): Consts from grid (to line-up with grid).
|
|
133
|
+
tooltipClass: () => "cm-completionDialog !mt-[8px] !-ml-[4px] [&>ul]:!max-h-[264px]",
|
|
134
|
+
optionClass: () => "flex h-[33px] items-center"
|
|
135
|
+
}),
|
|
136
|
+
// Check for accepted completion metadata in the transaction.
|
|
137
|
+
EditorView.updateListener.of((update) => {
|
|
138
|
+
update.transactions.forEach((tr) => {
|
|
139
|
+
const completion2 = tr.annotation(pickedCompletion);
|
|
140
|
+
if (completion2) {
|
|
141
|
+
onMatch(completion2.data);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
})
|
|
145
|
+
];
|
|
146
|
+
};
|
|
147
|
+
|
|
338
148
|
// src/components/TableCellEditor/FormCellEditor.tsx
|
|
339
|
-
import { useSignals as
|
|
340
|
-
import
|
|
149
|
+
import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
|
|
150
|
+
import React2, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
341
151
|
import { getSnapshot } from "@dxos/echo-schema";
|
|
342
152
|
import { invariant } from "@dxos/invariant";
|
|
343
|
-
import { Popover
|
|
344
|
-
import { Form
|
|
345
|
-
import { parseCellIndex, useGridContext as
|
|
153
|
+
import { Popover } from "@dxos/react-ui";
|
|
154
|
+
import { Form } from "@dxos/react-ui-form";
|
|
155
|
+
import { parseCellIndex, useGridContext as useGridContext2 } from "@dxos/react-ui-grid";
|
|
346
156
|
import { getDeep, setDeep } from "@dxos/util";
|
|
347
157
|
var __dxlog_file = "/__w/dxos/dxos/packages/ui/react-ui-table/src/components/TableCellEditor/FormCellEditor.tsx";
|
|
348
158
|
var FormCellEditor = ({ fieldProjection, model, schema, onSave, __gridScope }) => {
|
|
349
|
-
var _effect =
|
|
159
|
+
var _effect = _useSignals2();
|
|
350
160
|
try {
|
|
351
|
-
const { editing: contextEditing, setEditing } =
|
|
352
|
-
const [editing, setLocalEditing] =
|
|
161
|
+
const { editing: contextEditing, setEditing } = useGridContext2("ArrayEditor", __gridScope);
|
|
162
|
+
const [editing, setLocalEditing] = useState(false);
|
|
353
163
|
const anchorRef = useRef(null);
|
|
354
|
-
|
|
164
|
+
useEffect(() => {
|
|
355
165
|
if (contextEditing && contextEditing.cellElement) {
|
|
356
166
|
anchorRef.current = contextEditing.cellElement.querySelector(".dx-grid__cell__content");
|
|
357
167
|
setLocalEditing(true);
|
|
@@ -362,7 +172,7 @@ var FormCellEditor = ({ fieldProjection, model, schema, onSave, __gridScope }) =
|
|
|
362
172
|
}, [
|
|
363
173
|
contextEditing
|
|
364
174
|
]);
|
|
365
|
-
const narrowedSchema =
|
|
175
|
+
const narrowedSchema = useMemo(() => {
|
|
366
176
|
if (!schema) {
|
|
367
177
|
return void 0;
|
|
368
178
|
}
|
|
@@ -373,7 +183,7 @@ var FormCellEditor = ({ fieldProjection, model, schema, onSave, __gridScope }) =
|
|
|
373
183
|
JSON.stringify(schema),
|
|
374
184
|
fieldProjection.field.path
|
|
375
185
|
]);
|
|
376
|
-
const originalRow =
|
|
186
|
+
const originalRow = useMemo(() => {
|
|
377
187
|
if (model && contextEditing) {
|
|
378
188
|
const cell = parseCellIndex(contextEditing.index);
|
|
379
189
|
const row = model.getRowAt(cell.row);
|
|
@@ -393,14 +203,14 @@ var FormCellEditor = ({ fieldProjection, model, schema, onSave, __gridScope }) =
|
|
|
393
203
|
model,
|
|
394
204
|
contextEditing
|
|
395
205
|
]);
|
|
396
|
-
const formValues =
|
|
206
|
+
const formValues = useMemo(() => {
|
|
397
207
|
if (originalRow) {
|
|
398
208
|
return getSnapshot(originalRow);
|
|
399
209
|
}
|
|
400
210
|
}, [
|
|
401
211
|
originalRow
|
|
402
212
|
]);
|
|
403
|
-
const handleSave =
|
|
213
|
+
const handleSave = useCallback((values) => {
|
|
404
214
|
const path = fieldProjection.field.path;
|
|
405
215
|
const value = getDeep(values, [
|
|
406
216
|
path
|
|
@@ -413,73 +223,34 @@ var FormCellEditor = ({ fieldProjection, model, schema, onSave, __gridScope }) =
|
|
|
413
223
|
onSave?.();
|
|
414
224
|
}, [
|
|
415
225
|
fieldProjection.field.path,
|
|
416
|
-
originalRow
|
|
417
|
-
]);
|
|
418
|
-
const handleOpenChange =
|
|
419
|
-
if (nextOpen === false) {
|
|
420
|
-
setEditing(null);
|
|
421
|
-
onSave?.();
|
|
422
|
-
}
|
|
423
|
-
setLocalEditing(nextOpen);
|
|
424
|
-
}, []);
|
|
425
|
-
if (!editing) {
|
|
426
|
-
return null;
|
|
427
|
-
}
|
|
428
|
-
return /* @__PURE__ */
|
|
429
|
-
open: editing,
|
|
430
|
-
onOpenChange: handleOpenChange
|
|
431
|
-
}, /* @__PURE__ */
|
|
432
|
-
virtualRef: anchorRef
|
|
433
|
-
}), /* @__PURE__ */
|
|
434
|
-
tabIndex: -1,
|
|
435
|
-
classNames: "popover-card-width density-fine"
|
|
436
|
-
}, /* @__PURE__ */
|
|
437
|
-
values: formValues,
|
|
438
|
-
schema: narrowedSchema,
|
|
439
|
-
onSave: handleSave
|
|
440
|
-
}))));
|
|
441
|
-
} finally {
|
|
442
|
-
_effect.f();
|
|
443
|
-
}
|
|
444
|
-
};
|
|
445
|
-
|
|
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
|
-
];
|
|
226
|
+
originalRow
|
|
227
|
+
]);
|
|
228
|
+
const handleOpenChange = useCallback((nextOpen) => {
|
|
229
|
+
if (nextOpen === false) {
|
|
230
|
+
setEditing(null);
|
|
231
|
+
onSave?.();
|
|
232
|
+
}
|
|
233
|
+
setLocalEditing(nextOpen);
|
|
234
|
+
}, []);
|
|
235
|
+
if (!editing) {
|
|
236
|
+
return null;
|
|
237
|
+
}
|
|
238
|
+
return /* @__PURE__ */ React2.createElement(Popover.Root, {
|
|
239
|
+
open: editing,
|
|
240
|
+
onOpenChange: handleOpenChange
|
|
241
|
+
}, /* @__PURE__ */ React2.createElement(Popover.VirtualTrigger, {
|
|
242
|
+
virtualRef: anchorRef
|
|
243
|
+
}), /* @__PURE__ */ React2.createElement(Popover.Content, {
|
|
244
|
+
tabIndex: -1,
|
|
245
|
+
classNames: "popover-card-width density-fine"
|
|
246
|
+
}, /* @__PURE__ */ React2.createElement(Popover.Arrow, null), /* @__PURE__ */ React2.createElement(Popover.Viewport, null, /* @__PURE__ */ React2.createElement(Form, {
|
|
247
|
+
values: formValues,
|
|
248
|
+
schema: narrowedSchema,
|
|
249
|
+
onSave: handleSave
|
|
250
|
+
}))));
|
|
251
|
+
} finally {
|
|
252
|
+
_effect.f();
|
|
253
|
+
}
|
|
483
254
|
};
|
|
484
255
|
|
|
485
256
|
// src/components/TableCellEditor/TableCellEditor.tsx
|
|
@@ -491,10 +262,10 @@ var createOption = (text) => ({
|
|
|
491
262
|
});
|
|
492
263
|
var isCreateOption = (data) => typeof data === "object" && data[newValue];
|
|
493
264
|
var TableValueEditor = ({ model, modals, schema, onEnter, onFocus, onSave, onQuery, __gridScope }) => {
|
|
494
|
-
var _effect =
|
|
265
|
+
var _effect = _useSignals3();
|
|
495
266
|
try {
|
|
496
|
-
const { editing } =
|
|
497
|
-
const fieldProjection =
|
|
267
|
+
const { editing } = useGridContext3("TableValueEditor", __gridScope);
|
|
268
|
+
const fieldProjection = useMemo2(() => {
|
|
498
269
|
if (!model || !editing) {
|
|
499
270
|
return;
|
|
500
271
|
}
|
|
@@ -516,7 +287,7 @@ var TableValueEditor = ({ model, modals, schema, onEnter, onFocus, onSave, onQue
|
|
|
516
287
|
editing
|
|
517
288
|
]);
|
|
518
289
|
if (fieldProjection?.props.type === TypeEnum.Array || fieldProjection?.props.format === FormatEnum.SingleSelect) {
|
|
519
|
-
return /* @__PURE__ */
|
|
290
|
+
return /* @__PURE__ */ React3.createElement(FormCellEditor, {
|
|
520
291
|
fieldProjection,
|
|
521
292
|
model,
|
|
522
293
|
schema,
|
|
@@ -524,7 +295,7 @@ var TableValueEditor = ({ model, modals, schema, onEnter, onFocus, onSave, onQue
|
|
|
524
295
|
onSave
|
|
525
296
|
});
|
|
526
297
|
}
|
|
527
|
-
return /* @__PURE__ */
|
|
298
|
+
return /* @__PURE__ */ React3.createElement(TableCellEditor, {
|
|
528
299
|
model,
|
|
529
300
|
modals,
|
|
530
301
|
onEnter,
|
|
@@ -543,14 +314,14 @@ var editorSlots = {
|
|
|
543
314
|
}
|
|
544
315
|
};
|
|
545
316
|
var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, onSave, __gridScope }) => {
|
|
546
|
-
var _effect =
|
|
317
|
+
var _effect = _useSignals3();
|
|
547
318
|
try {
|
|
548
|
-
const { id: gridId, editing, setEditing } =
|
|
319
|
+
const { id: gridId, editing, setEditing } = useGridContext3("TableCellEditor", __gridScope);
|
|
549
320
|
const suppressNextBlur = useRef2(false);
|
|
550
321
|
const { themeMode } = useThemeContext();
|
|
551
|
-
const [
|
|
552
|
-
const [
|
|
553
|
-
const fieldProjection =
|
|
322
|
+
const [validationError, setValidationError] = useState2(null);
|
|
323
|
+
const [validationVariant, setValidationVariant] = useState2("error");
|
|
324
|
+
const fieldProjection = useMemo2(() => {
|
|
554
325
|
if (!model || !editing) {
|
|
555
326
|
return;
|
|
556
327
|
}
|
|
@@ -571,7 +342,7 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, onSave, __gri
|
|
|
571
342
|
model,
|
|
572
343
|
editing
|
|
573
344
|
]);
|
|
574
|
-
|
|
345
|
+
useEffect2(() => {
|
|
575
346
|
if (!model || !editing || !fieldProjection) {
|
|
576
347
|
setValidationError(null);
|
|
577
348
|
return;
|
|
@@ -585,9 +356,9 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, onSave, __gri
|
|
|
585
356
|
const draftRows = model.draftRows.value;
|
|
586
357
|
if (row >= 0 && row < draftRows.length) {
|
|
587
358
|
const draftRow = draftRows[row];
|
|
588
|
-
const
|
|
589
|
-
if (
|
|
590
|
-
setValidationError(
|
|
359
|
+
const validationError2 = draftRow.validationErrors?.find((error) => error.path === field.path);
|
|
360
|
+
if (validationError2) {
|
|
361
|
+
setValidationError(validationError2.message);
|
|
591
362
|
setValidationVariant("warning");
|
|
592
363
|
}
|
|
593
364
|
}
|
|
@@ -602,7 +373,7 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, onSave, __gri
|
|
|
602
373
|
editing,
|
|
603
374
|
fieldProjection
|
|
604
375
|
]);
|
|
605
|
-
const handleEnter =
|
|
376
|
+
const handleEnter = useCallback2(async (value) => {
|
|
606
377
|
if (!model || !editing) {
|
|
607
378
|
return;
|
|
608
379
|
}
|
|
@@ -626,7 +397,7 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, onSave, __gri
|
|
|
626
397
|
onFocus,
|
|
627
398
|
setEditing
|
|
628
399
|
]);
|
|
629
|
-
const handleBlur =
|
|
400
|
+
const handleBlur = useCallback2(async (value) => {
|
|
630
401
|
if (!model || !editing) {
|
|
631
402
|
return;
|
|
632
403
|
}
|
|
@@ -637,7 +408,7 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, onSave, __gri
|
|
|
637
408
|
model,
|
|
638
409
|
editing
|
|
639
410
|
]);
|
|
640
|
-
const handleClose =
|
|
411
|
+
const handleClose = useCallback2(async (value, event) => {
|
|
641
412
|
if (!model || !editing || !fieldProjection) {
|
|
642
413
|
return;
|
|
643
414
|
}
|
|
@@ -651,7 +422,7 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, onSave, __gri
|
|
|
651
422
|
onSave?.();
|
|
652
423
|
onEnter?.(cell);
|
|
653
424
|
if (event && onFocus) {
|
|
654
|
-
onFocus(determineNavigationAxis(event), determineNavigationDelta(event));
|
|
425
|
+
onFocus(determineNavigationAxis(event), determineNavigationDelta(event), cell);
|
|
655
426
|
}
|
|
656
427
|
} else {
|
|
657
428
|
setValidationError(result.error);
|
|
@@ -674,7 +445,7 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, onSave, __gri
|
|
|
674
445
|
setEditing,
|
|
675
446
|
onSave
|
|
676
447
|
]);
|
|
677
|
-
const extension =
|
|
448
|
+
const extension = useMemo2(() => {
|
|
678
449
|
if (!fieldProjection) {
|
|
679
450
|
return [];
|
|
680
451
|
}
|
|
@@ -755,7 +526,7 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, onSave, __gri
|
|
|
755
526
|
handleClose,
|
|
756
527
|
themeMode
|
|
757
528
|
]);
|
|
758
|
-
const getCellContent =
|
|
529
|
+
const getCellContent = useCallback2(() => {
|
|
759
530
|
if (model && editing) {
|
|
760
531
|
const cell = parseCellIndex2(editing.index);
|
|
761
532
|
const { col } = cell;
|
|
@@ -801,11 +572,11 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, onSave, __gri
|
|
|
801
572
|
model,
|
|
802
573
|
editing
|
|
803
574
|
]);
|
|
804
|
-
return /* @__PURE__ */
|
|
805
|
-
validationError
|
|
806
|
-
variant:
|
|
575
|
+
return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(CellValidationMessage, {
|
|
576
|
+
validationError,
|
|
577
|
+
variant: validationVariant,
|
|
807
578
|
__gridScope
|
|
808
|
-
}), /* @__PURE__ */
|
|
579
|
+
}), /* @__PURE__ */ React3.createElement(GridCellEditor, {
|
|
809
580
|
extension,
|
|
810
581
|
getCellContent,
|
|
811
582
|
onBlur: handleBlur,
|
|
@@ -840,6 +611,235 @@ var determineNavigationDelta = ({ key, shift }) => {
|
|
|
840
611
|
return shift ? -1 : 1;
|
|
841
612
|
};
|
|
842
613
|
|
|
614
|
+
// src/components/Table/ColumnActionsMenu.tsx
|
|
615
|
+
import { useSignals as _useSignals4 } from "@preact-signals/safe-react/tracking";
|
|
616
|
+
import React4 from "react";
|
|
617
|
+
import { DropdownMenu, useTranslation } from "@dxos/react-ui";
|
|
618
|
+
var ColumnActionsMenu = ({ model, modals }) => {
|
|
619
|
+
var _effect = _useSignals4();
|
|
620
|
+
try {
|
|
621
|
+
const { t } = useTranslation(translationKey);
|
|
622
|
+
const state = modals.state.value;
|
|
623
|
+
if (state?.type !== "column") {
|
|
624
|
+
return null;
|
|
625
|
+
}
|
|
626
|
+
const currentSort = model.sorting?.sorting;
|
|
627
|
+
const isCurrentColumnSorted = currentSort?.fieldId === state.fieldId;
|
|
628
|
+
return /* @__PURE__ */ React4.createElement(DropdownMenu.Root, {
|
|
629
|
+
modal: false,
|
|
630
|
+
open: true,
|
|
631
|
+
onOpenChange: modals.close
|
|
632
|
+
}, /* @__PURE__ */ React4.createElement(DropdownMenu.VirtualTrigger, {
|
|
633
|
+
virtualRef: modals.trigger
|
|
634
|
+
}), /* @__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, {
|
|
635
|
+
"data-testid": "column-sort-descending",
|
|
636
|
+
onClick: () => model.sorting?.setSort(state.fieldId, "desc")
|
|
637
|
+
}, t("column action sort descending")), (!isCurrentColumnSorted || currentSort?.direction === "desc") && /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
|
|
638
|
+
"data-testid": "column-sort-ascending",
|
|
639
|
+
onClick: () => model.sorting?.setSort(state.fieldId, "asc")
|
|
640
|
+
}, t("column action sort ascending")), isCurrentColumnSorted && /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
|
|
641
|
+
"data-testid": "column-clear-sort",
|
|
642
|
+
onClick: () => model.sorting?.clearSort()
|
|
643
|
+
}, t("column action clear sorting")), model.getColumnCount() > 1 && model.features.schemaEditable && /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
|
|
644
|
+
"data-testid": "column-delete",
|
|
645
|
+
onClick: () => model.deleteColumn(state.fieldId)
|
|
646
|
+
}, t("column action delete")), model.features.schemaEditable && /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
|
|
647
|
+
"data-testid": "column-settings",
|
|
648
|
+
onClick: () => modals.openColumnSettings()
|
|
649
|
+
}, t("column action settings"))), /* @__PURE__ */ React4.createElement(DropdownMenu.Arrow, null))));
|
|
650
|
+
} finally {
|
|
651
|
+
_effect.f();
|
|
652
|
+
}
|
|
653
|
+
};
|
|
654
|
+
|
|
655
|
+
// src/components/Table/ColumnSettings.tsx
|
|
656
|
+
import { useSignals as _useSignals5 } from "@preact-signals/safe-react/tracking";
|
|
657
|
+
import React5, { useCallback as useCallback3, useEffect as useEffect3, useMemo as useMemo3, useState as useState3 } from "react";
|
|
658
|
+
import { Popover as Popover2 } from "@dxos/react-ui";
|
|
659
|
+
import { FieldEditor } from "@dxos/react-ui-form";
|
|
660
|
+
var ColumnSettings = ({ registry, model, modals, onNewColumn }) => {
|
|
661
|
+
var _effect = _useSignals5();
|
|
662
|
+
try {
|
|
663
|
+
const [newField, setNewField] = useState3();
|
|
664
|
+
const state = modals.state.value;
|
|
665
|
+
useEffect3(() => {
|
|
666
|
+
if (state?.type === "columnSettings" && state.mode.type === "create" && model?.projection) {
|
|
667
|
+
setNewField(model.projection.createFieldProjection());
|
|
668
|
+
requestAnimationFrame(() => {
|
|
669
|
+
onNewColumn();
|
|
670
|
+
});
|
|
671
|
+
} else {
|
|
672
|
+
setNewField(void 0);
|
|
673
|
+
}
|
|
674
|
+
}, [
|
|
675
|
+
model?.projection,
|
|
676
|
+
state
|
|
677
|
+
]);
|
|
678
|
+
const existingField = useMemo3(() => {
|
|
679
|
+
if (state?.type === "columnSettings") {
|
|
680
|
+
const { mode } = state;
|
|
681
|
+
if (mode.type === "edit") {
|
|
682
|
+
return model?.projection?.fields.find((f) => f.id === mode.fieldId);
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
return void 0;
|
|
686
|
+
}, [
|
|
687
|
+
model?.projection?.fields,
|
|
688
|
+
state
|
|
689
|
+
]);
|
|
690
|
+
const field = existingField ?? newField;
|
|
691
|
+
const handleSave = useCallback3(() => {
|
|
692
|
+
modals.close();
|
|
693
|
+
}, [
|
|
694
|
+
modals
|
|
695
|
+
]);
|
|
696
|
+
const handleCancel = useCallback3(() => {
|
|
697
|
+
if (state?.type === "columnSettings" && state.mode.type === "create" && newField) {
|
|
698
|
+
model?.projection.deleteFieldProjection(newField.id);
|
|
699
|
+
}
|
|
700
|
+
}, [
|
|
701
|
+
model?.projection,
|
|
702
|
+
state,
|
|
703
|
+
newField
|
|
704
|
+
]);
|
|
705
|
+
if (!model?.projection || !field) {
|
|
706
|
+
return null;
|
|
707
|
+
}
|
|
708
|
+
return /* @__PURE__ */ React5.createElement(Popover2.Root, {
|
|
709
|
+
modal: false,
|
|
710
|
+
open: state?.type === "columnSettings"
|
|
711
|
+
}, /* @__PURE__ */ React5.createElement(Popover2.VirtualTrigger, {
|
|
712
|
+
virtualRef: modals.trigger
|
|
713
|
+
}), /* @__PURE__ */ React5.createElement(Popover2.Portal, null, /* @__PURE__ */ React5.createElement(Popover2.Content, {
|
|
714
|
+
classNames: "md:is-64"
|
|
715
|
+
}, /* @__PURE__ */ React5.createElement(Popover2.Viewport, null, /* @__PURE__ */ React5.createElement(FieldEditor, {
|
|
716
|
+
projection: model.projection,
|
|
717
|
+
field,
|
|
718
|
+
registry,
|
|
719
|
+
onSave: handleSave,
|
|
720
|
+
onCancel: handleCancel
|
|
721
|
+
})), /* @__PURE__ */ React5.createElement(Popover2.Arrow, null))));
|
|
722
|
+
} finally {
|
|
723
|
+
_effect.f();
|
|
724
|
+
}
|
|
725
|
+
};
|
|
726
|
+
|
|
727
|
+
// src/components/Table/CreateRefPanel.tsx
|
|
728
|
+
import { useSignals as _useSignals6 } from "@preact-signals/safe-react/tracking";
|
|
729
|
+
import { Schema } from "effect";
|
|
730
|
+
import React6, { useCallback as useCallback4, useMemo as useMemo4 } from "react";
|
|
731
|
+
import { live } from "@dxos/live-object";
|
|
732
|
+
import { getSpace } from "@dxos/react-client/echo";
|
|
733
|
+
import { Popover as Popover3 } from "@dxos/react-ui";
|
|
734
|
+
import { Form as Form2 } from "@dxos/react-ui-form";
|
|
735
|
+
import { useGridContext as useGridContext4 } from "@dxos/react-ui-grid";
|
|
736
|
+
var CreateRefPanel = ({ model, modals, __gridScope }) => {
|
|
737
|
+
var _effect = _useSignals6();
|
|
738
|
+
try {
|
|
739
|
+
const { id: gridId } = useGridContext4("TableCellEditor", __gridScope);
|
|
740
|
+
const space = model && getSpace(model?.view);
|
|
741
|
+
const state = modals.state.value;
|
|
742
|
+
const schema = useMemo4(() => {
|
|
743
|
+
if (!space || state?.type !== "createRefPanel") {
|
|
744
|
+
return;
|
|
745
|
+
}
|
|
746
|
+
const [schema2] = space.db.schemaRegistry.query({
|
|
747
|
+
typename: state.typename
|
|
748
|
+
}).runSync();
|
|
749
|
+
if (schema2) {
|
|
750
|
+
const omit = Schema.omit("id");
|
|
751
|
+
return omit(schema2);
|
|
752
|
+
}
|
|
753
|
+
}, [
|
|
754
|
+
space,
|
|
755
|
+
state
|
|
756
|
+
]);
|
|
757
|
+
const handleSave = useCallback4((values) => {
|
|
758
|
+
if (!model || !space || state?.type !== "createRefPanel") {
|
|
759
|
+
return;
|
|
760
|
+
}
|
|
761
|
+
const [schema2] = space.db.schemaRegistry.query({
|
|
762
|
+
typename: state.typename
|
|
763
|
+
}).runSync();
|
|
764
|
+
if (schema2) {
|
|
765
|
+
const obj = space.db.add(live(schema2, values));
|
|
766
|
+
state.onCreate?.(obj);
|
|
767
|
+
}
|
|
768
|
+
void modals.close();
|
|
769
|
+
}, [
|
|
770
|
+
modals,
|
|
771
|
+
space,
|
|
772
|
+
state
|
|
773
|
+
]);
|
|
774
|
+
const handleCancel = useCallback4(() => {
|
|
775
|
+
if (model) {
|
|
776
|
+
modals.close();
|
|
777
|
+
}
|
|
778
|
+
}, [
|
|
779
|
+
modals
|
|
780
|
+
]);
|
|
781
|
+
if (!model?.projection) {
|
|
782
|
+
return null;
|
|
783
|
+
}
|
|
784
|
+
return /* @__PURE__ */ React6.createElement(Popover3.Root, {
|
|
785
|
+
modal: false,
|
|
786
|
+
open: state?.type === "createRefPanel" && !!schema,
|
|
787
|
+
onOpenChange: (nextOpen) => {
|
|
788
|
+
if (model && !nextOpen) {
|
|
789
|
+
return modals.close();
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
}, /* @__PURE__ */ React6.createElement(Popover3.VirtualTrigger, {
|
|
793
|
+
virtualRef: modals.trigger
|
|
794
|
+
}), /* @__PURE__ */ React6.createElement(Popover3.Portal, null, /* @__PURE__ */ React6.createElement(Popover3.Content, {
|
|
795
|
+
classNames: "md:is-64",
|
|
796
|
+
"data-grid": gridId
|
|
797
|
+
}, /* @__PURE__ */ React6.createElement(Popover3.Viewport, null, state?.type === "createRefPanel" && schema && /* @__PURE__ */ React6.createElement(Form2, {
|
|
798
|
+
schema,
|
|
799
|
+
values: state.initialValues ?? {},
|
|
800
|
+
onSave: handleSave,
|
|
801
|
+
onCancel: handleCancel
|
|
802
|
+
})), /* @__PURE__ */ React6.createElement(Popover3.Arrow, null))));
|
|
803
|
+
} finally {
|
|
804
|
+
_effect.f();
|
|
805
|
+
}
|
|
806
|
+
};
|
|
807
|
+
|
|
808
|
+
// src/components/Table/RowActionsMenu.tsx
|
|
809
|
+
import { useSignals as _useSignals7 } from "@preact-signals/safe-react/tracking";
|
|
810
|
+
import React7 from "react";
|
|
811
|
+
import { DropdownMenu as DropdownMenu2, toLocalizedString, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
812
|
+
var RowActionsMenu = ({ model, modals }) => {
|
|
813
|
+
var _effect = _useSignals7();
|
|
814
|
+
try {
|
|
815
|
+
const { t } = useTranslation2(translationKey);
|
|
816
|
+
const hasSelection = model.selection.hasSelection.value;
|
|
817
|
+
const state = modals.state.value;
|
|
818
|
+
if (state?.type !== "row") {
|
|
819
|
+
return null;
|
|
820
|
+
}
|
|
821
|
+
return /* @__PURE__ */ React7.createElement(DropdownMenu2.Root, {
|
|
822
|
+
modal: false,
|
|
823
|
+
open: true,
|
|
824
|
+
onOpenChange: modals.close
|
|
825
|
+
}, /* @__PURE__ */ React7.createElement(DropdownMenu2.VirtualTrigger, {
|
|
826
|
+
virtualRef: modals.trigger
|
|
827
|
+
}), /* @__PURE__ */ React7.createElement(DropdownMenu2.Content, null, /* @__PURE__ */ React7.createElement(DropdownMenu2.Viewport, null, model.features.dataEditable !== false && /* @__PURE__ */ React7.createElement(DropdownMenu2.Item, {
|
|
828
|
+
"data-testid": "row-menu-delete",
|
|
829
|
+
onClick: () => model.deleteRow(state.rowIndex)
|
|
830
|
+
}, t(hasSelection ? "bulk delete row label" : "delete row label")), model.rowActions?.map((action) => /* @__PURE__ */ React7.createElement(DropdownMenu2.Item, {
|
|
831
|
+
key: action.id,
|
|
832
|
+
"data-testid": `row-action-${action.id}`,
|
|
833
|
+
onClick: () => {
|
|
834
|
+
modals.close();
|
|
835
|
+
model.handleRowAction(action.id, state.rowIndex);
|
|
836
|
+
}
|
|
837
|
+
}, toLocalizedString(action.label, t)))), /* @__PURE__ */ React7.createElement(DropdownMenu2.Arrow, null)));
|
|
838
|
+
} finally {
|
|
839
|
+
_effect.f();
|
|
840
|
+
}
|
|
841
|
+
};
|
|
842
|
+
|
|
843
843
|
// src/components/Table/Table.tsx
|
|
844
844
|
var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/react-ui-table/src/components/Table/Table.tsx";
|
|
845
845
|
var TableRoot = ({ children, role = "article" }) => {
|
|
@@ -905,12 +905,35 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
905
905
|
dxGrid.updateCells(true);
|
|
906
906
|
dxGrid.requestUpdate();
|
|
907
907
|
}
|
|
908
|
+
},
|
|
909
|
+
focusDraft: () => {
|
|
910
|
+
requestAnimationFrame(() => {
|
|
911
|
+
dxGrid.setFocus({
|
|
912
|
+
plane: "frozenRowsEnd",
|
|
913
|
+
col: 0,
|
|
914
|
+
row: 0
|
|
915
|
+
});
|
|
916
|
+
dxGrid.refocus();
|
|
917
|
+
});
|
|
908
918
|
}
|
|
909
919
|
};
|
|
910
920
|
}, [
|
|
911
921
|
presentation,
|
|
912
922
|
dxGrid
|
|
913
923
|
]);
|
|
924
|
+
const handleSaveDraftRow = useCallback5((rowIndex = 0) => {
|
|
925
|
+
if (model && dxGrid) {
|
|
926
|
+
const didCommitSuccessfully = model.commitDraftRow(rowIndex);
|
|
927
|
+
if (didCommitSuccessfully) {
|
|
928
|
+
requestAnimationFrame(() => {
|
|
929
|
+
dxGrid.scrollToEndRow();
|
|
930
|
+
});
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
}, [
|
|
934
|
+
model,
|
|
935
|
+
dxGrid
|
|
936
|
+
]);
|
|
914
937
|
const handleGridClick = useCallback5((event) => {
|
|
915
938
|
const rowIndex = safeParseInt(event.target.closest("[aria-rowindex]")?.ariaRowIndex ?? "");
|
|
916
939
|
if (rowIndex != null) {
|
|
@@ -952,14 +975,7 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
952
975
|
break;
|
|
953
976
|
}
|
|
954
977
|
case "saveDraftRow": {
|
|
955
|
-
|
|
956
|
-
const didCommitSuccessfully = model.commitDraftRow(data.rowIndex);
|
|
957
|
-
if (dxGrid && didCommitSuccessfully) {
|
|
958
|
-
requestAnimationFrame(() => {
|
|
959
|
-
dxGrid.scrollToEndRow();
|
|
960
|
-
});
|
|
961
|
-
}
|
|
962
|
-
}
|
|
978
|
+
handleSaveDraftRow();
|
|
963
979
|
break;
|
|
964
980
|
}
|
|
965
981
|
}
|
|
@@ -998,29 +1014,32 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
998
1014
|
modals,
|
|
999
1015
|
dxGrid
|
|
1000
1016
|
]);
|
|
1001
|
-
const handleFocus = useCallback5((increment, delta) => {
|
|
1002
|
-
if (dxGrid) {
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1017
|
+
const handleFocus = useCallback5((increment, delta, cell) => {
|
|
1018
|
+
if (dxGrid && model) {
|
|
1019
|
+
if (cell?.plane === "grid" && cell?.row >= model.getRowCount() - 1) {
|
|
1020
|
+
if (draftRowCount < 1) {
|
|
1021
|
+
model.insertRow();
|
|
1022
|
+
}
|
|
1023
|
+
dxGrid.setFocus({
|
|
1024
|
+
plane: "frozenRowsEnd",
|
|
1025
|
+
col: 0,
|
|
1026
|
+
row: 0
|
|
1027
|
+
});
|
|
1028
|
+
} else if (cell?.plane === "frozenRowsEnd" && increment === "row") {
|
|
1029
|
+
handleSaveDraftRow(cell.row);
|
|
1030
|
+
model.insertRow();
|
|
1031
|
+
dxGrid.setFocus({
|
|
1032
|
+
plane: "frozenRowsEnd",
|
|
1033
|
+
col: 0,
|
|
1034
|
+
row: 0
|
|
1018
1035
|
});
|
|
1036
|
+
} else {
|
|
1037
|
+
dxGrid.refocus(increment, delta);
|
|
1019
1038
|
}
|
|
1020
1039
|
}
|
|
1021
1040
|
}, [
|
|
1022
|
-
|
|
1023
|
-
|
|
1041
|
+
dxGrid,
|
|
1042
|
+
model
|
|
1024
1043
|
]);
|
|
1025
1044
|
const handleKeyDown = useCallback5((event) => {
|
|
1026
1045
|
if (!model?.features.dataEditable) {
|
|
@@ -1033,7 +1052,11 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
1033
1052
|
switch (event.key) {
|
|
1034
1053
|
case "Backspace":
|
|
1035
1054
|
case "Delete": {
|
|
1036
|
-
|
|
1055
|
+
try {
|
|
1056
|
+
model.setCellData(cell, void 0);
|
|
1057
|
+
event.preventDefault();
|
|
1058
|
+
} catch {
|
|
1059
|
+
}
|
|
1037
1060
|
break;
|
|
1038
1061
|
}
|
|
1039
1062
|
}
|
|
@@ -1070,7 +1093,7 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
1070
1093
|
const space = getSpace2(model.view);
|
|
1071
1094
|
invariant3(space, void 0, {
|
|
1072
1095
|
F: __dxlog_file3,
|
|
1073
|
-
L:
|
|
1096
|
+
L: 336,
|
|
1074
1097
|
S: void 0,
|
|
1075
1098
|
A: [
|
|
1076
1099
|
"space",
|
|
@@ -1115,6 +1138,7 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
1115
1138
|
]);
|
|
1116
1139
|
const handleSave = useCallback5(() => {
|
|
1117
1140
|
dxGrid?.updateCells(true);
|
|
1141
|
+
dxGrid?.requestUpdate();
|
|
1118
1142
|
}, [
|
|
1119
1143
|
dxGrid
|
|
1120
1144
|
]);
|
|
@@ -1130,7 +1154,6 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
1130
1154
|
model,
|
|
1131
1155
|
modals,
|
|
1132
1156
|
schema,
|
|
1133
|
-
onEnter: handleEnter,
|
|
1134
1157
|
onFocus: handleFocus,
|
|
1135
1158
|
onQuery: handleQuery,
|
|
1136
1159
|
onSave: handleSave
|
|
@@ -1143,7 +1166,7 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
1143
1166
|
overscroll: "trap",
|
|
1144
1167
|
onAxisResize: handleAxisResize,
|
|
1145
1168
|
onClick: handleGridClick,
|
|
1146
|
-
|
|
1169
|
+
onKeyDownCapture: handleKeyDown,
|
|
1147
1170
|
onWheelCapture: handleWheel,
|
|
1148
1171
|
ref: setDxGrid
|
|
1149
1172
|
}), /* @__PURE__ */ React8.createElement(RowActionsMenu, {
|
|
@@ -1171,7 +1194,7 @@ var Table = {
|
|
|
1171
1194
|
|
|
1172
1195
|
// src/components/Table/DynamicTable.tsx
|
|
1173
1196
|
import { useSignals as _useSignals9 } from "@preact-signals/safe-react/tracking";
|
|
1174
|
-
import React9, {
|
|
1197
|
+
import React9, { useCallback as useCallback6, useMemo as useMemo6, useRef as useRef3 } from "react";
|
|
1175
1198
|
import { useDefaultValue } from "@dxos/react-ui";
|
|
1176
1199
|
import { mx as mx2 } from "@dxos/react-ui-theme";
|
|
1177
1200
|
var DynamicTable = ({ classNames, name = "example.com/dynamic-table", rows, properties, jsonSchema: _jsonSchema, schema, rowActions, onRowClick, onRowAction, ...props }) => {
|
|
@@ -1251,7 +1274,7 @@ import { useSignals as _useSignals10 } from "@preact-signals/safe-react/tracking
|
|
|
1251
1274
|
import { Rx } from "@effect-rx/rx-react";
|
|
1252
1275
|
import React10, { useMemo as useMemo7 } from "react";
|
|
1253
1276
|
import { live as live2 } from "@dxos/live-object";
|
|
1254
|
-
import {
|
|
1277
|
+
import { MenuProvider, ToolbarMenu, createGapSeparator, createMenuAction, useMenuActions } from "@dxos/react-ui-menu";
|
|
1255
1278
|
import { rxFromSignal } from "@dxos/react-ui-menu";
|
|
1256
1279
|
var createTableToolbarActions = ({ state, onAdd, onSave, customActions }) => Rx.make((get) => {
|
|
1257
1280
|
const add = createMenuAction("add-row", onAdd, {
|