@dxos/react-ui-table 0.8.4-main.67995b8 → 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 +399 -380
- 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 +399 -380
- 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 +46 -46
- 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 +49 -43
- 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
|
|
@@ -412,74 +222,35 @@ var FormCellEditor = ({ fieldProjection, model, schema, onSave, __gridScope }) =
|
|
|
412
222
|
setLocalEditing(false);
|
|
413
223
|
onSave?.();
|
|
414
224
|
}, [
|
|
415
|
-
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
|
-
];
|
|
225
|
+
fieldProjection.field.path,
|
|
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
|
-
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);
|
|
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
|
|
1018
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
|
|
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) {
|
|
@@ -1074,7 +1093,7 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
1074
1093
|
const space = getSpace2(model.view);
|
|
1075
1094
|
invariant3(space, void 0, {
|
|
1076
1095
|
F: __dxlog_file3,
|
|
1077
|
-
L:
|
|
1096
|
+
L: 336,
|
|
1078
1097
|
S: void 0,
|
|
1079
1098
|
A: [
|
|
1080
1099
|
"space",
|
|
@@ -1119,6 +1138,7 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
1119
1138
|
]);
|
|
1120
1139
|
const handleSave = useCallback5(() => {
|
|
1121
1140
|
dxGrid?.updateCells(true);
|
|
1141
|
+
dxGrid?.requestUpdate();
|
|
1122
1142
|
}, [
|
|
1123
1143
|
dxGrid
|
|
1124
1144
|
]);
|
|
@@ -1134,7 +1154,6 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
1134
1154
|
model,
|
|
1135
1155
|
modals,
|
|
1136
1156
|
schema,
|
|
1137
|
-
onEnter: handleEnter,
|
|
1138
1157
|
onFocus: handleFocus,
|
|
1139
1158
|
onQuery: handleQuery,
|
|
1140
1159
|
onSave: handleSave
|
|
@@ -1175,7 +1194,7 @@ var Table = {
|
|
|
1175
1194
|
|
|
1176
1195
|
// src/components/Table/DynamicTable.tsx
|
|
1177
1196
|
import { useSignals as _useSignals9 } from "@preact-signals/safe-react/tracking";
|
|
1178
|
-
import React9, {
|
|
1197
|
+
import React9, { useCallback as useCallback6, useMemo as useMemo6, useRef as useRef3 } from "react";
|
|
1179
1198
|
import { useDefaultValue } from "@dxos/react-ui";
|
|
1180
1199
|
import { mx as mx2 } from "@dxos/react-ui-theme";
|
|
1181
1200
|
var DynamicTable = ({ classNames, name = "example.com/dynamic-table", rows, properties, jsonSchema: _jsonSchema, schema, rowActions, onRowClick, onRowAction, ...props }) => {
|
|
@@ -1255,7 +1274,7 @@ import { useSignals as _useSignals10 } from "@preact-signals/safe-react/tracking
|
|
|
1255
1274
|
import { Rx } from "@effect-rx/rx-react";
|
|
1256
1275
|
import React10, { useMemo as useMemo7 } from "react";
|
|
1257
1276
|
import { live as live2 } from "@dxos/live-object";
|
|
1258
|
-
import {
|
|
1277
|
+
import { MenuProvider, ToolbarMenu, createGapSeparator, createMenuAction, useMenuActions } from "@dxos/react-ui-menu";
|
|
1259
1278
|
import { rxFromSignal } from "@dxos/react-ui-menu";
|
|
1260
1279
|
var createTableToolbarActions = ({ state, onAdd, onSave, customActions }) => Rx.make((get) => {
|
|
1261
1280
|
const add = createMenuAction("add-row", onAdd, {
|