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