@dxos/react-ui-table 0.7.4 → 0.7.5-main.937ce75
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-IYCSJDMB.mjs → chunk-AT7O4RAD.mjs} +4 -4
- package/dist/lib/browser/{chunk-IYCSJDMB.mjs.map → chunk-AT7O4RAD.mjs.map} +2 -2
- package/dist/lib/browser/index.mjs +1442 -1219
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/types/index.mjs +1 -1
- package/dist/lib/node/{chunk-MHBMVCFZ.cjs → chunk-YSBXNBDJ.cjs} +6 -6
- package/dist/lib/node/{chunk-MHBMVCFZ.cjs.map → chunk-YSBXNBDJ.cjs.map} +2 -2
- package/dist/lib/node/index.cjs +1351 -1111
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/types/index.cjs +3 -3
- package/dist/lib/node/types/index.cjs.map +1 -1
- package/dist/lib/node-esm/{chunk-BMWGPXPL.mjs → chunk-6OH2NHUX.mjs} +4 -4
- package/dist/lib/node-esm/{chunk-BMWGPXPL.mjs.map → chunk-6OH2NHUX.mjs.map} +2 -2
- package/dist/lib/node-esm/index.mjs +1442 -1219
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/types/index.mjs +1 -1
- package/dist/types/src/_deprecated/hooks/useColumnSorting.d.ts +1 -1
- package/dist/types/src/components/Table/ColumnActionsMenu.d.ts +4 -3
- package/dist/types/src/components/Table/ColumnActionsMenu.d.ts.map +1 -1
- package/dist/types/src/components/Table/ColumnSettings.d.ts +3 -2
- package/dist/types/src/components/Table/ColumnSettings.d.ts.map +1 -1
- package/dist/types/src/components/Table/CreateRefPanel.d.ts +3 -2
- package/dist/types/src/components/Table/CreateRefPanel.d.ts.map +1 -1
- package/dist/types/src/components/Table/RefPanel.d.ts +4 -3
- package/dist/types/src/components/Table/RefPanel.d.ts.map +1 -1
- package/dist/types/src/components/Table/RowActionsMenu.d.ts +3 -2
- package/dist/types/src/components/Table/RowActionsMenu.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.d.ts +2 -1
- package/dist/types/src/components/Table/Table.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +3 -2
- 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/testing.d.ts +55 -71
- package/dist/types/src/components/testing.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/model/index.d.ts +1 -0
- package/dist/types/src/model/index.d.ts.map +1 -1
- package/dist/types/src/model/modal-controller.d.ts +6 -2
- 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 +14 -27
- package/dist/types/src/model/table-model.d.ts.map +1 -1
- package/dist/types/src/model/table-presentation.d.ts +22 -0
- package/dist/types/src/model/table-presentation.d.ts.map +1 -0
- package/dist/types/src/model/table-presentation.test.d.ts +2 -0
- package/dist/types/src/model/table-presentation.test.d.ts.map +1 -0
- package/dist/types/src/model/table-sorting.d.ts +48 -0
- package/dist/types/src/model/table-sorting.d.ts.map +1 -0
- package/dist/types/src/playwright/TableManager.d.ts +2 -1
- package/dist/types/src/playwright/TableManager.d.ts.map +1 -1
- package/dist/types/src/types/table.d.ts +118 -154
- package/dist/types/src/types/table.d.ts.map +1 -1
- package/dist/types/src/util/index.d.ts +1 -0
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/src/util/table-buttons.d.ts +50 -20
- package/dist/types/src/util/table-buttons.d.ts.map +1 -1
- package/dist/types/src/util/table-controls.d.ts +32 -9
- package/dist/types/src/util/table-controls.d.ts.map +1 -1
- package/dist/types/src/util/table.d.ts +2 -2
- package/dist/types/src/util/table.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -0
- package/package.json +29 -29
- package/src/components/Table/ColumnActionsMenu.tsx +8 -8
- package/src/components/Table/ColumnSettings.tsx +11 -11
- package/src/components/Table/CreateRefPanel.tsx +13 -14
- package/src/components/Table/RefPanel.tsx +9 -9
- package/src/components/Table/RowActionsMenu.tsx +6 -7
- package/src/components/Table/Table.stories.tsx +40 -23
- package/src/components/Table/Table.tsx +235 -148
- package/src/components/TableCellEditor/TableCellEditor.stories.tsx +13 -12
- package/src/components/TableCellEditor/TableCellEditor.tsx +6 -4
- package/src/components/testing.ts +10 -8
- package/src/index.ts +2 -0
- package/src/model/index.ts +1 -0
- package/src/model/modal-controller.ts +15 -48
- package/src/model/selection-model.ts +12 -1
- package/src/model/table-model.test.ts +4 -71
- package/src/model/table-model.ts +61 -292
- package/src/model/table-presentation.test.ts +102 -0
- package/src/model/table-presentation.ts +217 -0
- package/src/model/table-sorting.ts +131 -0
- package/src/playwright/TableManager.ts +5 -1
- package/src/playwright/smoke.spec.ts +79 -1
- package/src/types/table.ts +3 -3
- package/src/util/index.ts +1 -0
- package/src/util/table-buttons.ts +97 -48
- package/src/util/table-controls.ts +71 -7
- package/src/util/table.ts +21 -13
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
TableSchema,
|
|
3
3
|
TableType
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-AT7O4RAD.mjs";
|
|
5
5
|
|
|
6
6
|
// packages/ui/react-ui-table/src/translations.ts
|
|
7
7
|
var translationKey = "table";
|
|
@@ -35,33 +35,33 @@ var translations_default = [
|
|
|
35
35
|
];
|
|
36
36
|
|
|
37
37
|
// packages/ui/react-ui-table/src/components/Table/Table.tsx
|
|
38
|
-
import React7, { forwardRef, useCallback as useCallback4, useImperativeHandle, useState as useState2 } from "react";
|
|
39
|
-
import { getValue } from "@dxos/echo-schema";
|
|
40
|
-
import { invariant as
|
|
38
|
+
import React7, { forwardRef, useCallback as useCallback4, useImperativeHandle, useState as useState2, useMemo as useMemo4 } from "react";
|
|
39
|
+
import { getValue as getValue4 } from "@dxos/echo-schema";
|
|
40
|
+
import { invariant as invariant3 } from "@dxos/invariant";
|
|
41
41
|
import { Filter, getSpace as getSpace4, fullyQualifiedId } from "@dxos/react-client/echo";
|
|
42
42
|
import { useTranslation as useTranslation3 } from "@dxos/react-ui";
|
|
43
43
|
import { useAttention } from "@dxos/react-ui-attention";
|
|
44
44
|
import { Grid, closestCell } from "@dxos/react-ui-grid";
|
|
45
|
-
import { mx } from "@dxos/react-ui-theme";
|
|
45
|
+
import { mx as mx2 } from "@dxos/react-ui-theme";
|
|
46
46
|
import { isNotFalsy } from "@dxos/util";
|
|
47
47
|
|
|
48
48
|
// packages/ui/react-ui-table/src/components/Table/ColumnActionsMenu.tsx
|
|
49
49
|
import React from "react";
|
|
50
50
|
import { DropdownMenu, useTranslation } from "@dxos/react-ui";
|
|
51
|
-
var ColumnActionsMenu = ({ model }) => {
|
|
51
|
+
var ColumnActionsMenu = ({ model, modals }) => {
|
|
52
52
|
const { t } = useTranslation(translationKey);
|
|
53
|
-
const state =
|
|
54
|
-
if (
|
|
53
|
+
const state = modals.state.value;
|
|
54
|
+
if (state?.type !== "column") {
|
|
55
55
|
return null;
|
|
56
56
|
}
|
|
57
57
|
const currentSort = model.sorting;
|
|
58
58
|
const isCurrentColumnSorted = currentSort?.fieldId === state.fieldId;
|
|
59
59
|
return /* @__PURE__ */ React.createElement(DropdownMenu.Root, {
|
|
60
60
|
modal: false,
|
|
61
|
-
open:
|
|
62
|
-
onOpenChange:
|
|
61
|
+
open: true,
|
|
62
|
+
onOpenChange: modals.close
|
|
63
63
|
}, /* @__PURE__ */ React.createElement(DropdownMenu.VirtualTrigger, {
|
|
64
|
-
virtualRef:
|
|
64
|
+
virtualRef: modals.trigger
|
|
65
65
|
}), /* @__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, {
|
|
66
66
|
"data-testid": "column-sort-descending",
|
|
67
67
|
onClick: () => model.setSort(state.fieldId, "desc")
|
|
@@ -76,7 +76,7 @@ var ColumnActionsMenu = ({ model }) => {
|
|
|
76
76
|
onClick: () => model.deleteColumn(state.fieldId)
|
|
77
77
|
}, t("column action delete")), /* @__PURE__ */ React.createElement(DropdownMenu.Item, {
|
|
78
78
|
"data-testid": "column-settings",
|
|
79
|
-
onClick: () =>
|
|
79
|
+
onClick: () => modals.openColumnSettings()
|
|
80
80
|
}, t("column action settings"))), /* @__PURE__ */ React.createElement(DropdownMenu.Arrow, null))));
|
|
81
81
|
};
|
|
82
82
|
|
|
@@ -85,9 +85,9 @@ import React2, { useCallback, useEffect, useMemo, useState } from "react";
|
|
|
85
85
|
import { getSpace } from "@dxos/react-client/echo";
|
|
86
86
|
import { DropdownMenu as DropdownMenu2 } from "@dxos/react-ui";
|
|
87
87
|
import { FieldEditor } from "@dxos/react-ui-form";
|
|
88
|
-
var ColumnSettings = ({ model, onNewColumn }) => {
|
|
88
|
+
var ColumnSettings = ({ model, modals, onNewColumn }) => {
|
|
89
89
|
const [newField, setNewField] = useState();
|
|
90
|
-
const state =
|
|
90
|
+
const state = modals.state.value;
|
|
91
91
|
const space = getSpace(model?.table);
|
|
92
92
|
useEffect(() => {
|
|
93
93
|
if (state?.type === "columnSettings" && state.mode.type === "create" && model?.projection) {
|
|
@@ -106,19 +106,19 @@ var ColumnSettings = ({ model, onNewColumn }) => {
|
|
|
106
106
|
if (state?.type === "columnSettings") {
|
|
107
107
|
const { mode } = state;
|
|
108
108
|
if (mode.type === "edit") {
|
|
109
|
-
return model?.table?.view?.fields.find((f) => f.id === mode.fieldId);
|
|
109
|
+
return model?.table?.view?.target?.fields.find((f) => f.id === mode.fieldId);
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
112
|
return void 0;
|
|
113
113
|
}, [
|
|
114
|
-
model?.table?.view?.fields,
|
|
114
|
+
model?.table?.view?.target?.fields,
|
|
115
115
|
state
|
|
116
116
|
]);
|
|
117
117
|
const field = existingField ?? newField;
|
|
118
118
|
const handleSave = useCallback(() => {
|
|
119
|
-
|
|
119
|
+
modals.close();
|
|
120
120
|
}, [
|
|
121
|
-
|
|
121
|
+
modals
|
|
122
122
|
]);
|
|
123
123
|
const handleCancel = useCallback(() => {
|
|
124
124
|
if (state?.type === "columnSettings" && state.mode.type === "create" && newField) {
|
|
@@ -129,18 +129,18 @@ var ColumnSettings = ({ model, onNewColumn }) => {
|
|
|
129
129
|
state,
|
|
130
130
|
newField
|
|
131
131
|
]);
|
|
132
|
-
if (!model?.table?.view || !model.projection || !field) {
|
|
132
|
+
if (!model?.table?.view?.target || !model.projection || !field) {
|
|
133
133
|
return null;
|
|
134
134
|
}
|
|
135
135
|
return /* @__PURE__ */ React2.createElement(DropdownMenu2.Root, {
|
|
136
136
|
modal: false,
|
|
137
137
|
open: state?.type === "columnSettings"
|
|
138
138
|
}, /* @__PURE__ */ React2.createElement(DropdownMenu2.VirtualTrigger, {
|
|
139
|
-
virtualRef:
|
|
139
|
+
virtualRef: modals.trigger
|
|
140
140
|
}), /* @__PURE__ */ React2.createElement(DropdownMenu2.Portal, null, /* @__PURE__ */ React2.createElement(DropdownMenu2.Content, {
|
|
141
141
|
classNames: "md:is-64"
|
|
142
142
|
}, /* @__PURE__ */ React2.createElement(DropdownMenu2.Viewport, null, /* @__PURE__ */ React2.createElement(FieldEditor, {
|
|
143
|
-
view: model.table.view,
|
|
143
|
+
view: model.table.view.target,
|
|
144
144
|
projection: model.projection,
|
|
145
145
|
field,
|
|
146
146
|
registry: space?.db.schemaRegistry,
|
|
@@ -156,15 +156,17 @@ import { create, getSpace as getSpace2 } from "@dxos/react-client/echo";
|
|
|
156
156
|
import { Popover } from "@dxos/react-ui";
|
|
157
157
|
import { Form } from "@dxos/react-ui-form";
|
|
158
158
|
import { useGridContext } from "@dxos/react-ui-grid";
|
|
159
|
-
var CreateRefPanel = ({ model, __gridScope }) => {
|
|
159
|
+
var CreateRefPanel = ({ model, modals, __gridScope }) => {
|
|
160
160
|
const { id: gridId } = useGridContext("TableCellEditor", __gridScope);
|
|
161
161
|
const space = getSpace2(model?.table);
|
|
162
|
-
const state =
|
|
162
|
+
const state = modals.state.value;
|
|
163
163
|
const schema = useMemo2(() => {
|
|
164
164
|
if (!space || state?.type !== "createRefPanel") {
|
|
165
165
|
return;
|
|
166
166
|
}
|
|
167
|
-
const schema2 = space.db.schemaRegistry.
|
|
167
|
+
const [schema2] = space.db.schemaRegistry.query({
|
|
168
|
+
typename: state.typename
|
|
169
|
+
}).runSync();
|
|
168
170
|
if (schema2) {
|
|
169
171
|
const omit = S.omit("id");
|
|
170
172
|
return omit(schema2);
|
|
@@ -177,23 +179,25 @@ var CreateRefPanel = ({ model, __gridScope }) => {
|
|
|
177
179
|
if (!model || !space || state?.type !== "createRefPanel") {
|
|
178
180
|
return;
|
|
179
181
|
}
|
|
180
|
-
const schema2 = space.db.schemaRegistry.
|
|
182
|
+
const [schema2] = space.db.schemaRegistry.query({
|
|
183
|
+
typename: state.typename
|
|
184
|
+
}).runSync();
|
|
181
185
|
if (schema2) {
|
|
182
186
|
const obj = space.db.add(create(schema2, values));
|
|
183
187
|
state.onCreate?.(obj);
|
|
184
188
|
}
|
|
185
|
-
void
|
|
189
|
+
void modals.close();
|
|
186
190
|
}, [
|
|
187
|
-
|
|
191
|
+
modals,
|
|
188
192
|
space,
|
|
189
193
|
state
|
|
190
194
|
]);
|
|
191
195
|
const handleCancel = useCallback2(() => {
|
|
192
196
|
if (model) {
|
|
193
|
-
|
|
197
|
+
modals.close();
|
|
194
198
|
}
|
|
195
199
|
}, [
|
|
196
|
-
|
|
200
|
+
modals
|
|
197
201
|
]);
|
|
198
202
|
if (!model?.table?.view || !model.projection) {
|
|
199
203
|
return null;
|
|
@@ -203,11 +207,11 @@ var CreateRefPanel = ({ model, __gridScope }) => {
|
|
|
203
207
|
open: state?.type === "createRefPanel" && !!schema,
|
|
204
208
|
onOpenChange: (nextOpen) => {
|
|
205
209
|
if (model && !nextOpen) {
|
|
206
|
-
return
|
|
210
|
+
return modals.close();
|
|
207
211
|
}
|
|
208
212
|
}
|
|
209
213
|
}, /* @__PURE__ */ React3.createElement(Popover.VirtualTrigger, {
|
|
210
|
-
virtualRef:
|
|
214
|
+
virtualRef: modals.trigger
|
|
211
215
|
}), /* @__PURE__ */ React3.createElement(Popover.Portal, null, /* @__PURE__ */ React3.createElement(Popover.Content, {
|
|
212
216
|
classNames: "md:is-64",
|
|
213
217
|
"data-grid": gridId
|
|
@@ -231,24 +235,24 @@ var getRefTargetObj = (space, id) => {
|
|
|
231
235
|
return void 0;
|
|
232
236
|
}
|
|
233
237
|
};
|
|
234
|
-
var RefPanel = ({ model }) => {
|
|
235
|
-
const state =
|
|
236
|
-
const space = getSpace3(model
|
|
238
|
+
var RefPanel = ({ model, modals }) => {
|
|
239
|
+
const state = modals.state.value;
|
|
240
|
+
const space = getSpace3(model.table);
|
|
237
241
|
const targetObj = getRefTargetObj(space, state?.type === "refPanel" ? state.targetId : void 0);
|
|
238
242
|
const schema = space && state?.type === "refPanel" ? space.db.schemaRegistry.getSchema(state.typename) : void 0;
|
|
239
|
-
if (!model
|
|
243
|
+
if (!model.table?.view || !model.projection) {
|
|
240
244
|
return null;
|
|
241
245
|
}
|
|
242
246
|
return /* @__PURE__ */ React4.createElement(Popover2.Root, {
|
|
243
247
|
modal: false,
|
|
244
248
|
open: state?.type === "refPanel" && !!targetObj && !!schema,
|
|
245
249
|
onOpenChange: (nextOpen) => {
|
|
246
|
-
if (
|
|
247
|
-
return
|
|
250
|
+
if (!nextOpen) {
|
|
251
|
+
return modals.close();
|
|
248
252
|
}
|
|
249
253
|
}
|
|
250
254
|
}, /* @__PURE__ */ React4.createElement(Popover2.VirtualTrigger, {
|
|
251
|
-
virtualRef:
|
|
255
|
+
virtualRef: modals.trigger
|
|
252
256
|
}), /* @__PURE__ */ React4.createElement(Popover2.Portal, null, /* @__PURE__ */ React4.createElement(Popover2.Content, {
|
|
253
257
|
classNames: "md:is-64"
|
|
254
258
|
}, targetObj && schema && /* @__PURE__ */ React4.createElement(Form2, {
|
|
@@ -261,691 +265,734 @@ var RefPanel = ({ model }) => {
|
|
|
261
265
|
// packages/ui/react-ui-table/src/components/Table/RowActionsMenu.tsx
|
|
262
266
|
import React5 from "react";
|
|
263
267
|
import { DropdownMenu as DropdownMenu3, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
264
|
-
var RowActionsMenu = ({ model }) => {
|
|
268
|
+
var RowActionsMenu = ({ model, modals }) => {
|
|
265
269
|
const { t } = useTranslation2(translationKey);
|
|
266
270
|
const hasSelection = model.selection.hasSelection.value;
|
|
267
|
-
const state =
|
|
271
|
+
const state = modals.state.value;
|
|
268
272
|
if (state?.type !== "row") {
|
|
269
273
|
return null;
|
|
270
274
|
}
|
|
271
275
|
return /* @__PURE__ */ React5.createElement(DropdownMenu3.Root, {
|
|
272
276
|
modal: false,
|
|
273
277
|
open: true,
|
|
274
|
-
onOpenChange:
|
|
278
|
+
onOpenChange: modals.close
|
|
275
279
|
}, /* @__PURE__ */ React5.createElement(DropdownMenu3.VirtualTrigger, {
|
|
276
|
-
virtualRef:
|
|
280
|
+
virtualRef: modals.trigger
|
|
277
281
|
}), /* @__PURE__ */ React5.createElement(DropdownMenu3.Content, null, /* @__PURE__ */ React5.createElement(DropdownMenu3.Viewport, null, /* @__PURE__ */ React5.createElement(DropdownMenu3.Item, {
|
|
278
282
|
"data-testid": "row-menu-delete",
|
|
279
283
|
onClick: () => model.deleteRow(state.rowIndex)
|
|
280
284
|
}, t(hasSelection ? "bulk delete row label" : "delete row label"))), /* @__PURE__ */ React5.createElement(DropdownMenu3.Arrow, null)));
|
|
281
285
|
};
|
|
282
286
|
|
|
283
|
-
// packages/ui/react-ui-table/src/
|
|
284
|
-
import
|
|
285
|
-
import {
|
|
287
|
+
// packages/ui/react-ui-table/src/model/table-model.ts
|
|
288
|
+
import { computed as computed3, effect as effect2, signal as signal3 } from "@preact/signals-core";
|
|
289
|
+
import { Resource as Resource2 } from "@dxos/context";
|
|
290
|
+
import { getValue as getValue2, setValue, FormatEnum as FormatEnum3 } from "@dxos/echo-schema";
|
|
286
291
|
import { invariant } from "@dxos/invariant";
|
|
287
|
-
import {
|
|
292
|
+
import { isReactiveObject, makeRef as makeRef2 } from "@dxos/live-object";
|
|
293
|
+
import { PublicKey as PublicKey2 } from "@dxos/react-client";
|
|
294
|
+
import { formatForEditing, parseValue } from "@dxos/react-ui-form";
|
|
288
295
|
|
|
289
|
-
// packages/ui/react-ui-table/src/
|
|
290
|
-
import {
|
|
291
|
-
import {
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
296
|
+
// packages/ui/react-ui-table/src/model/selection-model.ts
|
|
297
|
+
import { computed, effect, signal } from "@preact/signals-core";
|
|
298
|
+
import { Resource } from "@dxos/context";
|
|
299
|
+
|
|
300
|
+
// packages/ui/react-ui-table/src/util/signals.ts
|
|
301
|
+
var touch = (value) => value;
|
|
302
|
+
|
|
303
|
+
// packages/ui/react-ui-table/src/util/table.ts
|
|
304
|
+
import { AST, Format, FormatEnum, S as S2, TypedObject, TypeEnum } from "@dxos/echo-schema";
|
|
305
|
+
import { log } from "@dxos/log";
|
|
306
|
+
import { PublicKey } from "@dxos/react-client";
|
|
307
|
+
import { create as create2, makeRef } from "@dxos/react-client/echo";
|
|
308
|
+
import { createFieldId, createView, ViewProjection } from "@dxos/schema";
|
|
309
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/util/table.ts";
|
|
310
|
+
var initializeTable = async ({ space, table, initialRow = true }) => {
|
|
311
|
+
log("initializeTable", {
|
|
312
|
+
table
|
|
313
|
+
}, {
|
|
314
|
+
F: __dxlog_file,
|
|
315
|
+
L: 36,
|
|
316
|
+
S: void 0,
|
|
317
|
+
C: (f, a) => f(...a)
|
|
318
|
+
});
|
|
319
|
+
const ContactSchema = TypedObject({
|
|
320
|
+
typename: `example.com/type/${PublicKey.random().truncate()}`,
|
|
321
|
+
version: "0.1.0"
|
|
322
|
+
})({
|
|
323
|
+
name: S2.optional(S2.String).annotations({
|
|
324
|
+
[AST.TitleAnnotationId]: "Name"
|
|
315
325
|
}),
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
if (completion2) {
|
|
321
|
-
onMatch(completion2.data);
|
|
322
|
-
}
|
|
323
|
-
});
|
|
326
|
+
active: S2.optional(S2.Boolean),
|
|
327
|
+
email: S2.optional(Format.Email),
|
|
328
|
+
salary: S2.optional(Format.Currency()).annotations({
|
|
329
|
+
[AST.TitleAnnotationId]: "Salary"
|
|
324
330
|
})
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
// packages/ui/react-ui-table/src/components/TableCellEditor/TableCellEditor.tsx
|
|
329
|
-
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/components/TableCellEditor/TableCellEditor.tsx";
|
|
330
|
-
var newValue = Symbol.for("newValue");
|
|
331
|
-
var createOption = (text) => ({
|
|
332
|
-
[newValue]: true,
|
|
333
|
-
text
|
|
334
|
-
});
|
|
335
|
-
var isCreateOption = (data) => typeof data === "object" && data[newValue];
|
|
336
|
-
var TableCellEditor = ({ model, onEnter, onFocus, onQuery, __gridScope }) => {
|
|
337
|
-
const { id: gridId, editing, setEditing } = useGridContext2("TableCellEditor", __gridScope);
|
|
338
|
-
const suppressNextBlur = useRef(false);
|
|
339
|
-
const fieldProjection = useMemo3(() => {
|
|
340
|
-
if (!model || !editing) {
|
|
341
|
-
return;
|
|
342
|
-
}
|
|
343
|
-
const { col } = parseCellIndex(editing.index);
|
|
344
|
-
const field = model.projection.view.fields[col];
|
|
345
|
-
const fieldProjection2 = model.projection.getFieldProjection(field.id);
|
|
346
|
-
invariant(fieldProjection2, void 0, {
|
|
347
|
-
F: __dxlog_file,
|
|
348
|
-
L: 65,
|
|
349
|
-
S: void 0,
|
|
350
|
-
A: [
|
|
351
|
-
"fieldProjection",
|
|
352
|
-
""
|
|
353
|
-
]
|
|
354
|
-
});
|
|
355
|
-
return fieldProjection2;
|
|
356
|
-
}, [
|
|
357
|
-
model,
|
|
358
|
-
editing
|
|
359
|
-
]);
|
|
360
|
-
const handleEnter = useCallback3((value) => {
|
|
361
|
-
if (!model || !editing) {
|
|
362
|
-
return;
|
|
363
|
-
}
|
|
364
|
-
const cell = parseCellIndex(editing.index);
|
|
365
|
-
model.setCellData(cell, value);
|
|
366
|
-
onEnter?.(cell);
|
|
367
|
-
onFocus?.();
|
|
368
|
-
setEditing(null);
|
|
369
|
-
}, [
|
|
370
|
-
model,
|
|
371
|
-
editing
|
|
372
|
-
]);
|
|
373
|
-
const handleBlur = useCallback3((value) => {
|
|
374
|
-
if (!model || !editing) {
|
|
375
|
-
return;
|
|
376
|
-
}
|
|
377
|
-
if (suppressNextBlur.current) {
|
|
378
|
-
suppressNextBlur.current = false;
|
|
379
|
-
return;
|
|
380
|
-
}
|
|
381
|
-
const cell = parseCellIndex(editing.index);
|
|
382
|
-
if (value !== void 0) {
|
|
383
|
-
model.setCellData(cell, value);
|
|
384
|
-
}
|
|
385
|
-
}, [
|
|
386
|
-
model,
|
|
387
|
-
editing
|
|
388
|
-
]);
|
|
389
|
-
const handleClose = useCallback3((value, event) => {
|
|
390
|
-
if (!model || !editing || !fieldProjection) {
|
|
391
|
-
return;
|
|
392
|
-
}
|
|
393
|
-
const cell = parseCellIndex(editing.index);
|
|
394
|
-
onEnter?.(cell);
|
|
395
|
-
if (event && onFocus) {
|
|
396
|
-
onFocus(determineNavigationAxis(event), determineNavigationDelta(event));
|
|
397
|
-
}
|
|
398
|
-
}, [
|
|
399
|
-
model,
|
|
400
|
-
editing,
|
|
401
|
-
onFocus,
|
|
402
|
-
onEnter,
|
|
403
|
-
fieldProjection,
|
|
404
|
-
determineNavigationAxis,
|
|
405
|
-
determineNavigationDelta
|
|
406
|
-
]);
|
|
407
|
-
const extension = useMemo3(() => {
|
|
408
|
-
if (!fieldProjection) {
|
|
409
|
-
return [];
|
|
410
|
-
}
|
|
411
|
-
const extension2 = [
|
|
412
|
-
editorKeys({
|
|
413
|
-
onClose: handleClose,
|
|
414
|
-
...editing?.initialContent && {
|
|
415
|
-
onNav: handleClose
|
|
416
|
-
}
|
|
417
|
-
})
|
|
418
|
-
];
|
|
419
|
-
if (onQuery) {
|
|
420
|
-
switch (fieldProjection.props.format) {
|
|
421
|
-
case FormatEnum.Ref: {
|
|
422
|
-
extension2.push([
|
|
423
|
-
completion({
|
|
424
|
-
onQuery: (text) => onQuery(fieldProjection, text),
|
|
425
|
-
onMatch: (data) => {
|
|
426
|
-
if (model && editing) {
|
|
427
|
-
if (isCreateOption(data)) {
|
|
428
|
-
const { field, props } = fieldProjection;
|
|
429
|
-
if (props.referenceSchema) {
|
|
430
|
-
suppressNextBlur.current = true;
|
|
431
|
-
model.modalController.openCreateRef(props.referenceSchema, document.querySelector(cellQuery(editing.index, gridId)), {
|
|
432
|
-
[field.referencePath]: data.text
|
|
433
|
-
}, (data2) => {
|
|
434
|
-
handleEnter(data2);
|
|
435
|
-
});
|
|
436
|
-
}
|
|
437
|
-
} else {
|
|
438
|
-
handleEnter(data);
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
})
|
|
443
|
-
]);
|
|
444
|
-
break;
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
return extension2;
|
|
449
|
-
}, [
|
|
450
|
-
model,
|
|
451
|
-
editing,
|
|
452
|
-
fieldProjection,
|
|
453
|
-
handleClose
|
|
331
|
+
});
|
|
332
|
+
const [contactSchema] = await space.db.schemaRegistry.register([
|
|
333
|
+
ContactSchema
|
|
454
334
|
]);
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
335
|
+
table.view = makeRef(createView({
|
|
336
|
+
name: "Test",
|
|
337
|
+
typename: contactSchema.typename,
|
|
338
|
+
jsonSchema: contactSchema.jsonSchema,
|
|
339
|
+
fields: [
|
|
340
|
+
"name",
|
|
341
|
+
"active",
|
|
342
|
+
"email",
|
|
343
|
+
"salary"
|
|
344
|
+
]
|
|
345
|
+
}));
|
|
346
|
+
const projection = new ViewProjection(contactSchema, table.view.target);
|
|
347
|
+
projection.setFieldProjection({
|
|
348
|
+
field: {
|
|
349
|
+
id: table.view.target.fields.find((f) => f.path === "salary").id,
|
|
350
|
+
path: "salary",
|
|
351
|
+
size: 150
|
|
459
352
|
}
|
|
460
|
-
}, [
|
|
461
|
-
model,
|
|
462
|
-
editing
|
|
463
|
-
]);
|
|
464
|
-
return /* @__PURE__ */ React6.createElement(GridCellEditor, {
|
|
465
|
-
extension,
|
|
466
|
-
getCellContent,
|
|
467
|
-
onBlur: handleBlur
|
|
468
353
|
});
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
354
|
+
projection.setFieldProjection({
|
|
355
|
+
field: {
|
|
356
|
+
id: createFieldId(),
|
|
357
|
+
path: "manager",
|
|
358
|
+
referencePath: "name"
|
|
359
|
+
},
|
|
360
|
+
props: {
|
|
361
|
+
property: "manager",
|
|
362
|
+
type: TypeEnum.Ref,
|
|
363
|
+
format: FormatEnum.Ref,
|
|
364
|
+
referenceSchema: contactSchema.typename,
|
|
365
|
+
title: "Manager"
|
|
476
366
|
}
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
return "col";
|
|
481
|
-
}
|
|
482
|
-
};
|
|
483
|
-
var determineNavigationDelta = ({ key, shift }) => {
|
|
484
|
-
switch (key) {
|
|
485
|
-
case "ArrowUp":
|
|
486
|
-
case "ArrowLeft":
|
|
487
|
-
return -1;
|
|
488
|
-
case "ArrowDown":
|
|
489
|
-
case "ArrowRight":
|
|
490
|
-
return 1;
|
|
367
|
+
});
|
|
368
|
+
if (initialRow) {
|
|
369
|
+
space.db.add(create2(contactSchema, {}));
|
|
491
370
|
}
|
|
492
|
-
return
|
|
371
|
+
return contactSchema;
|
|
493
372
|
};
|
|
494
373
|
|
|
495
|
-
// packages/ui/react-ui-table/src/
|
|
496
|
-
var
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
frozenColsStart: 1,
|
|
502
|
-
frozenColsEnd: 1
|
|
374
|
+
// packages/ui/react-ui-table/src/util/table-buttons.ts
|
|
375
|
+
var BUTTON_IDENTIFIERS = {
|
|
376
|
+
columnSettings: "data-table-column-settings-button",
|
|
377
|
+
newColumn: "data-table-new-column-button",
|
|
378
|
+
referencedCell: "data-table-ref-cell-button",
|
|
379
|
+
rowMenu: "data-table-row-menu-button"
|
|
503
380
|
};
|
|
504
|
-
var
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
className: mx("relative border-bs !border-separator", role === "section" ? "attention-surface overflow-hidden [&_.dx-grid]:max-is-[--dx-grid-content-inline-size]" : "flex flex-col [&_.dx-grid]:grow [&_.dx-grid]:max-is-[--dx-grid-content-inline-size] [&_.dx-grid]:bs-0 [&_.dx-grid]:max-bs-[--dx-grid-content-block-size]")
|
|
508
|
-
}, children);
|
|
381
|
+
var createButton = ({ attr, data, disabled = false, icon, testId }) => {
|
|
382
|
+
const dataAttrs = Object.entries(data).map(([k, v]) => `${k}="${v}"`).join(" ");
|
|
383
|
+
return `<button ${attr} data-testid="${testId}" class="ch-button is-6 pli-0.5 min-bs-0 absolute inset-block-1 inline-end-2" ${dataAttrs} ${disabled ? "disabled" : ""}><svg><use href="/icons.svg#${icon}"/></svg></button>`;
|
|
509
384
|
};
|
|
510
|
-
var
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
385
|
+
var addColumnButton = {
|
|
386
|
+
attr: BUTTON_IDENTIFIERS.newColumn,
|
|
387
|
+
icon: "ph--plus--regular",
|
|
388
|
+
render: ({ disabled }) => {
|
|
389
|
+
return createButton({
|
|
390
|
+
attr: BUTTON_IDENTIFIERS.newColumn,
|
|
391
|
+
icon: addColumnButton.icon,
|
|
392
|
+
disabled,
|
|
393
|
+
data: {},
|
|
394
|
+
testId: "table-new-column-button"
|
|
395
|
+
});
|
|
396
|
+
},
|
|
397
|
+
getData: (_el) => ({
|
|
398
|
+
type: "newColumn"
|
|
399
|
+
})
|
|
400
|
+
};
|
|
401
|
+
var columnSettingsButton = {
|
|
402
|
+
attr: BUTTON_IDENTIFIERS.columnSettings,
|
|
403
|
+
icon: "ph--caret-down--regular",
|
|
404
|
+
render: ({ fieldId }) => {
|
|
405
|
+
return createButton({
|
|
406
|
+
attr: BUTTON_IDENTIFIERS.columnSettings,
|
|
407
|
+
icon: columnSettingsButton.icon,
|
|
408
|
+
data: {
|
|
409
|
+
"data-field-id": fieldId
|
|
410
|
+
},
|
|
411
|
+
testId: "table-column-settings-button"
|
|
412
|
+
});
|
|
413
|
+
},
|
|
414
|
+
getData: (el) => ({
|
|
415
|
+
type: "columnSettings",
|
|
416
|
+
fieldId: el.getAttribute("data-field-id")
|
|
417
|
+
})
|
|
418
|
+
};
|
|
419
|
+
var referencedCellButton = {
|
|
420
|
+
attr: BUTTON_IDENTIFIERS.referencedCell,
|
|
421
|
+
icon: "ph--link-simple-horizontal--regular",
|
|
422
|
+
render: ({ targetId, schemaId }) => {
|
|
423
|
+
return createButton({
|
|
424
|
+
attr: BUTTON_IDENTIFIERS.referencedCell,
|
|
425
|
+
icon: referencedCellButton.icon,
|
|
426
|
+
data: {
|
|
427
|
+
"data-target-id": targetId,
|
|
428
|
+
"data-schema-id": schemaId
|
|
429
|
+
},
|
|
430
|
+
testId: "table-ref-cell-button"
|
|
431
|
+
});
|
|
432
|
+
},
|
|
433
|
+
getData: (el) => ({
|
|
434
|
+
type: "referencedCell",
|
|
435
|
+
targetId: el.getAttribute("data-target-id"),
|
|
436
|
+
schemaId: el.getAttribute("data-schema-id")
|
|
437
|
+
})
|
|
438
|
+
};
|
|
439
|
+
var rowMenuButton = {
|
|
440
|
+
attr: BUTTON_IDENTIFIERS.rowMenu,
|
|
441
|
+
icon: "ph--dots-three--regular",
|
|
442
|
+
render: ({ rowIndex }) => {
|
|
443
|
+
return createButton({
|
|
444
|
+
attr: BUTTON_IDENTIFIERS.rowMenu,
|
|
445
|
+
icon: rowMenuButton.icon,
|
|
446
|
+
data: {
|
|
447
|
+
"data-row-index": rowIndex.toString()
|
|
448
|
+
},
|
|
449
|
+
testId: "table-row-menu-button"
|
|
450
|
+
});
|
|
451
|
+
},
|
|
452
|
+
getData: (el) => ({
|
|
453
|
+
type: "rowMenu",
|
|
454
|
+
rowIndex: Number(el.getAttribute("data-row-index"))
|
|
455
|
+
})
|
|
456
|
+
};
|
|
457
|
+
var tableButtons = {
|
|
458
|
+
addColumn: addColumnButton,
|
|
459
|
+
columnSettings: columnSettingsButton,
|
|
460
|
+
referencedCell: referencedCellButton,
|
|
461
|
+
rowMenu: rowMenuButton
|
|
462
|
+
};
|
|
463
|
+
|
|
464
|
+
// packages/ui/react-ui-table/src/util/table-controls.ts
|
|
465
|
+
var CONTROL_IDENTIFIERS = {
|
|
466
|
+
checkbox: "data-table-checkbox",
|
|
467
|
+
switch: "data-table-switch"
|
|
468
|
+
};
|
|
469
|
+
var BASE_CLASSES = {
|
|
470
|
+
checkbox: "absolute inset-block-[.375rem] inline-end-[.375rem] ch-checkbox",
|
|
471
|
+
switch: "absolute inset-block-[.25rem] inline-end-[.25rem] ch-checkbox--switch"
|
|
472
|
+
};
|
|
473
|
+
var renderAttributes = (data) => {
|
|
474
|
+
return Object.entries(data).map(([k, v]) => `${k}="${v}"`).join(" ");
|
|
475
|
+
};
|
|
476
|
+
var renderInput = (baseClass, attrs, checked = false, disabled = false, preventToggle = false, testId) => {
|
|
477
|
+
return `<input type="checkbox" class="${baseClass}" ${renderAttributes(attrs)} ${checked ? "checked" : ""} ${preventToggle ? 'onclick="return false"' : ""} ${disabled ? "disabled" : ""} data-testid="${testId}"/>`;
|
|
478
|
+
};
|
|
479
|
+
var renderCheckbox = ({ rowIndex, header = false, checked = false, disabled = false }) => {
|
|
480
|
+
const attrs = {
|
|
481
|
+
[CONTROL_IDENTIFIERS.checkbox]: "",
|
|
482
|
+
"data-row-index": rowIndex.toString(),
|
|
483
|
+
...header && {
|
|
484
|
+
"data-header": ""
|
|
517
485
|
}
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
486
|
+
};
|
|
487
|
+
return renderInput(BASE_CLASSES.checkbox, attrs, checked, disabled, true, "table-selection");
|
|
488
|
+
};
|
|
489
|
+
var renderSwitch = ({ colIndex, rowIndex, checked = false, disabled = false }) => {
|
|
490
|
+
const attrs = {
|
|
491
|
+
[CONTROL_IDENTIFIERS.switch]: "",
|
|
492
|
+
"data-row-index": rowIndex.toString(),
|
|
493
|
+
"data-col-index": colIndex.toString()
|
|
494
|
+
};
|
|
495
|
+
return renderInput(BASE_CLASSES.switch, attrs, checked, disabled, true, "table-switch");
|
|
496
|
+
};
|
|
497
|
+
var tableControls = {
|
|
498
|
+
checkbox: {
|
|
499
|
+
attr: CONTROL_IDENTIFIERS.checkbox,
|
|
500
|
+
render: renderCheckbox,
|
|
501
|
+
getData: (el) => ({
|
|
502
|
+
type: "checkbox",
|
|
503
|
+
rowIndex: Number(el.getAttribute("data-row-index")),
|
|
504
|
+
header: el.hasAttribute("data-header")
|
|
505
|
+
})
|
|
506
|
+
},
|
|
507
|
+
switch: {
|
|
508
|
+
attr: CONTROL_IDENTIFIERS.switch,
|
|
509
|
+
render: renderSwitch,
|
|
510
|
+
getData: (el) => ({
|
|
511
|
+
type: "switch",
|
|
512
|
+
rowIndex: Number(el.getAttribute("data-row-index")),
|
|
513
|
+
colIndex: Number(el.getAttribute("data-col-index"))
|
|
514
|
+
})
|
|
515
|
+
}
|
|
516
|
+
};
|
|
517
|
+
|
|
518
|
+
// packages/ui/react-ui-table/src/model/selection-model.ts
|
|
519
|
+
var SelectionModel = class extends Resource {
|
|
520
|
+
constructor(_rows, _onSelectionChanged) {
|
|
521
|
+
super();
|
|
522
|
+
this._rows = _rows;
|
|
523
|
+
this._onSelectionChanged = _onSelectionChanged;
|
|
524
|
+
this._selection = signal(/* @__PURE__ */ new Set());
|
|
525
|
+
this._validSelectedIds = computed(() => {
|
|
526
|
+
const rows = this._rows.value;
|
|
527
|
+
if (!rows) {
|
|
528
|
+
return /* @__PURE__ */ new Set();
|
|
529
|
+
}
|
|
530
|
+
const validIds = new Set(rows.map((row) => row.id));
|
|
531
|
+
return new Set([
|
|
532
|
+
...this._selection.value
|
|
533
|
+
].filter((id) => validIds.has(id)));
|
|
534
|
+
});
|
|
535
|
+
this._hasSelection = computed(() => this._validSelectedIds.value.size > 0);
|
|
536
|
+
this._allSelected = computed(() => {
|
|
537
|
+
const rows = this._rows.value;
|
|
538
|
+
if (rows.length === 0) {
|
|
539
|
+
return false;
|
|
540
|
+
}
|
|
541
|
+
return rows.every((row) => this._selection.value.has(row.id));
|
|
542
|
+
});
|
|
543
|
+
this.getSelectedRows = () => {
|
|
544
|
+
const selectedIds = this._validSelectedIds.value;
|
|
545
|
+
return this._rows.value.filter((row) => selectedIds.has(row.id));
|
|
546
|
+
};
|
|
547
|
+
this.isRowIndexSelected = (rowIndex) => {
|
|
548
|
+
const row = this._rows.value[rowIndex];
|
|
549
|
+
return this._selection.value.has(row.id);
|
|
550
|
+
};
|
|
551
|
+
this.isObjectSelected = (object) => {
|
|
552
|
+
return this._selection.value.has(object.id);
|
|
553
|
+
};
|
|
554
|
+
this.toggleSelectionForRowIndex = (rowIndex) => {
|
|
555
|
+
const row = this._rows.value[rowIndex];
|
|
556
|
+
const newSelection = new Set(this._selection.value);
|
|
557
|
+
if (newSelection.has(row.id)) {
|
|
558
|
+
newSelection.delete(row.id);
|
|
559
|
+
} else {
|
|
560
|
+
newSelection.add(row.id);
|
|
561
|
+
}
|
|
562
|
+
this._selection.value = newSelection;
|
|
563
|
+
};
|
|
564
|
+
this.setSelection = (mode) => {
|
|
565
|
+
switch (mode) {
|
|
566
|
+
case "all": {
|
|
567
|
+
this._selection.value = new Set(this._rows.value.map((row) => row.id));
|
|
568
|
+
break;
|
|
569
|
+
}
|
|
570
|
+
case "none": {
|
|
571
|
+
this._selection.value = /* @__PURE__ */ new Set();
|
|
572
|
+
break;
|
|
525
573
|
}
|
|
526
574
|
}
|
|
527
575
|
};
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
576
|
+
}
|
|
577
|
+
async _open() {
|
|
578
|
+
const selectionWatcher = effect(() => {
|
|
579
|
+
touch(this._selection.value);
|
|
580
|
+
this._onSelectionChanged?.();
|
|
581
|
+
});
|
|
582
|
+
this._ctx.onDispose(selectionWatcher);
|
|
583
|
+
}
|
|
584
|
+
//
|
|
585
|
+
// Getters
|
|
586
|
+
//
|
|
587
|
+
get selection() {
|
|
588
|
+
return this._selection;
|
|
589
|
+
}
|
|
590
|
+
get hasSelection() {
|
|
591
|
+
return this._hasSelection;
|
|
592
|
+
}
|
|
593
|
+
get allRowsSeleted() {
|
|
594
|
+
return this._allSelected;
|
|
595
|
+
}
|
|
596
|
+
};
|
|
597
|
+
|
|
598
|
+
// packages/ui/react-ui-table/src/model/table-sorting.ts
|
|
599
|
+
import { computed as computed2, signal as signal2 } from "@preact/signals-core";
|
|
600
|
+
import orderBy from "lodash.orderby";
|
|
601
|
+
import { getValue, FormatEnum as FormatEnum2, TypeEnum as TypeEnum2 } from "@dxos/echo-schema";
|
|
602
|
+
import { formatForDisplay } from "@dxos/react-ui-form";
|
|
603
|
+
var TableSorting = class {
|
|
604
|
+
constructor(rows, _table, _projection) {
|
|
605
|
+
this._table = _table;
|
|
606
|
+
this._projection = _projection;
|
|
607
|
+
this._displayToDataIndex = /* @__PURE__ */ new Map();
|
|
608
|
+
this._sorting = signal2(void 0);
|
|
609
|
+
this._rows = rows;
|
|
610
|
+
this.sortedRows = this.initialiseSortedRows();
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* @reactive
|
|
614
|
+
*/
|
|
615
|
+
get sorting() {
|
|
616
|
+
return this._sorting.value;
|
|
617
|
+
}
|
|
618
|
+
getDataIndex(displayIndex) {
|
|
619
|
+
return this._displayToDataIndex.get(displayIndex) ?? displayIndex;
|
|
620
|
+
}
|
|
621
|
+
setSort(fieldId, direction) {
|
|
622
|
+
this._sorting.value = {
|
|
623
|
+
fieldId,
|
|
624
|
+
direction
|
|
625
|
+
};
|
|
626
|
+
}
|
|
627
|
+
//
|
|
628
|
+
// Initialisation.
|
|
629
|
+
//
|
|
630
|
+
initialiseSortedRows() {
|
|
631
|
+
return computed2(() => {
|
|
632
|
+
this._displayToDataIndex.clear();
|
|
633
|
+
const sort = this._sorting.value;
|
|
634
|
+
if (!sort) {
|
|
635
|
+
return this._rows.value;
|
|
547
636
|
}
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
dxGrid
|
|
552
|
-
]);
|
|
553
|
-
const handleKeyDown = useCallback4((event) => {
|
|
554
|
-
const cell = closestCell(event.target);
|
|
555
|
-
if (!model || !cell) {
|
|
556
|
-
return;
|
|
557
|
-
}
|
|
558
|
-
switch (event.key) {
|
|
559
|
-
case "Backspace":
|
|
560
|
-
case "Delete": {
|
|
561
|
-
model.setCellData(cell, void 0);
|
|
562
|
-
break;
|
|
637
|
+
const field = this._table.view?.target?.fields.find((f) => f.id === sort.fieldId);
|
|
638
|
+
if (!field) {
|
|
639
|
+
return this._rows.value;
|
|
563
640
|
}
|
|
641
|
+
const { props } = this._projection.getFieldProjection(field.id);
|
|
642
|
+
const dataWithIndices = this._rows.value.map((item, index) => {
|
|
643
|
+
const sortValue = this.getSortValue(props, field, item);
|
|
644
|
+
const isEmpty = !(props.type === TypeEnum2.Boolean) && (sortValue == null || sortValue === "");
|
|
645
|
+
return {
|
|
646
|
+
item,
|
|
647
|
+
index,
|
|
648
|
+
value: sortValue,
|
|
649
|
+
isEmpty
|
|
650
|
+
};
|
|
651
|
+
});
|
|
652
|
+
const ordered = orderBy(dataWithIndices, [
|
|
653
|
+
"isEmpty",
|
|
654
|
+
"value"
|
|
655
|
+
], [
|
|
656
|
+
"asc",
|
|
657
|
+
sort.direction
|
|
658
|
+
]);
|
|
659
|
+
ordered.forEach(({ index: dataIndex }, displayIndex) => {
|
|
660
|
+
if (displayIndex !== dataIndex) {
|
|
661
|
+
this._displayToDataIndex.set(displayIndex, dataIndex);
|
|
662
|
+
}
|
|
663
|
+
});
|
|
664
|
+
return ordered.map(({ item }) => item);
|
|
665
|
+
});
|
|
666
|
+
}
|
|
667
|
+
getSortValue(props, field, item) {
|
|
668
|
+
const { type, format } = props;
|
|
669
|
+
const value = getValue(item, field.path);
|
|
670
|
+
if (type === TypeEnum2.Boolean) {
|
|
671
|
+
return !!value;
|
|
564
672
|
}
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
]);
|
|
568
|
-
const handleAxisResize = useCallback4((event) => {
|
|
569
|
-
if (event.axis === "col") {
|
|
570
|
-
const columnIndex = parseInt(event.index, 10);
|
|
571
|
-
model?.setColumnWidth(columnIndex, event.size);
|
|
673
|
+
if (type === TypeEnum2.Number) {
|
|
674
|
+
return value;
|
|
572
675
|
}
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
]);
|
|
576
|
-
const handleWheel = useCallback4((event) => {
|
|
577
|
-
if (!ignoreAttention && !hasAttention) {
|
|
578
|
-
event.stopPropagation();
|
|
676
|
+
if (value == null) {
|
|
677
|
+
return value;
|
|
579
678
|
}
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
]);
|
|
584
|
-
const handleNewColumn = useCallback4(() => {
|
|
585
|
-
const columns = model?.getColumnCount();
|
|
586
|
-
if (dxGrid && columns) {
|
|
587
|
-
dxGrid.scrollToColumn(columns - 1);
|
|
679
|
+
if (format === FormatEnum2.Ref && field.referencePath) {
|
|
680
|
+
const refValue = getValue(value.target, field.referencePath);
|
|
681
|
+
return refValue;
|
|
588
682
|
}
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
const handleQuery = useCallback4(async ({ field, props }, text) => {
|
|
594
|
-
if (model && props.referenceSchema && field.referencePath) {
|
|
595
|
-
const space = getSpace4(model.table);
|
|
596
|
-
invariant2(space, void 0, {
|
|
597
|
-
F: __dxlog_file2,
|
|
598
|
-
L: 180,
|
|
599
|
-
S: void 0,
|
|
600
|
-
A: [
|
|
601
|
-
"space",
|
|
602
|
-
""
|
|
603
|
-
]
|
|
604
|
-
});
|
|
605
|
-
const schema = space.db.schemaRegistry.getSchema(props.referenceSchema);
|
|
606
|
-
if (schema) {
|
|
607
|
-
const { objects } = await space.db.query(Filter.schema(schema)).run();
|
|
608
|
-
const options = objects.map((obj) => {
|
|
609
|
-
const value = getValue(obj, field.referencePath);
|
|
610
|
-
if (!value || typeof value !== "string") {
|
|
611
|
-
return void 0;
|
|
612
|
-
}
|
|
613
|
-
return {
|
|
614
|
-
label: value,
|
|
615
|
-
data: obj
|
|
616
|
-
};
|
|
617
|
-
}).filter(isNotFalsy);
|
|
618
|
-
return [
|
|
619
|
-
...options,
|
|
620
|
-
{
|
|
621
|
-
label: t("create new object label", {
|
|
622
|
-
text
|
|
623
|
-
}),
|
|
624
|
-
data: createOption(text)
|
|
625
|
-
}
|
|
626
|
-
];
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
return [];
|
|
630
|
-
}, [
|
|
631
|
-
model
|
|
632
|
-
]);
|
|
633
|
-
if (!model) {
|
|
634
|
-
return /* @__PURE__ */ React7.createElement("span", {
|
|
635
|
-
role: "none",
|
|
636
|
-
className: "attention-surface"
|
|
683
|
+
return formatForDisplay({
|
|
684
|
+
type,
|
|
685
|
+
format,
|
|
686
|
+
value
|
|
637
687
|
});
|
|
638
688
|
}
|
|
639
|
-
return /* @__PURE__ */ React7.createElement(Grid.Root, {
|
|
640
|
-
id: model.table.id ?? "table-grid"
|
|
641
|
-
}, /* @__PURE__ */ React7.createElement(TableCellEditor, {
|
|
642
|
-
model,
|
|
643
|
-
onEnter: handleEnter,
|
|
644
|
-
onFocus: handleFocus,
|
|
645
|
-
onQuery: handleQuery
|
|
646
|
-
}), /* @__PURE__ */ React7.createElement(Grid.Content, {
|
|
647
|
-
onWheelCapture: handleWheel,
|
|
648
|
-
className: mx("[--dx-grid-base:var(--surface-bg)]", inlineEndLine, blockEndLine),
|
|
649
|
-
frozen,
|
|
650
|
-
columns: model.columnMeta.value,
|
|
651
|
-
limitRows: model.getRowCount() ?? 0,
|
|
652
|
-
limitColumns: model.table.view?.fields?.length ?? 0,
|
|
653
|
-
onAxisResize: handleAxisResize,
|
|
654
|
-
onClick: model?.handleGridClick,
|
|
655
|
-
onKeyDown: handleKeyDown,
|
|
656
|
-
overscroll: "trap",
|
|
657
|
-
ref: setDxGrid
|
|
658
|
-
}), /* @__PURE__ */ React7.createElement(RowActionsMenu, {
|
|
659
|
-
model
|
|
660
|
-
}), /* @__PURE__ */ React7.createElement(ColumnActionsMenu, {
|
|
661
|
-
model
|
|
662
|
-
}), /* @__PURE__ */ React7.createElement(ColumnSettings, {
|
|
663
|
-
model,
|
|
664
|
-
onNewColumn: handleNewColumn
|
|
665
|
-
}), /* @__PURE__ */ React7.createElement(RefPanel, {
|
|
666
|
-
model
|
|
667
|
-
}), /* @__PURE__ */ React7.createElement(CreateRefPanel, {
|
|
668
|
-
model
|
|
669
|
-
}));
|
|
670
|
-
});
|
|
671
|
-
var Table = {
|
|
672
|
-
Root: TableRoot,
|
|
673
|
-
Main: TableMain
|
|
674
689
|
};
|
|
675
690
|
|
|
676
|
-
// packages/ui/react-ui-table/src/components/Toolbar/Toolbar.tsx
|
|
677
|
-
import { createContext } from "@radix-ui/react-context";
|
|
678
|
-
import React9 from "react";
|
|
679
|
-
import { Toolbar as NaturalToolbar2, useTranslation as useTranslation4 } from "@dxos/react-ui";
|
|
680
|
-
|
|
681
|
-
// packages/ui/react-ui-table/src/components/Toolbar/common.tsx
|
|
682
|
-
import React8 from "react";
|
|
683
|
-
import { Icon, Toolbar as NaturalToolbar, Tooltip } from "@dxos/react-ui";
|
|
684
|
-
var buttonStyles = "min-bs-0 p-2";
|
|
685
|
-
var tooltipProps = {
|
|
686
|
-
side: "top",
|
|
687
|
-
classNames: "z-10"
|
|
688
|
-
};
|
|
689
|
-
var ToolbarSeparator = () => /* @__PURE__ */ React8.createElement("div", {
|
|
690
|
-
role: "separator",
|
|
691
|
-
className: "grow"
|
|
692
|
-
});
|
|
693
|
-
var ToolbarButton = ({ icon, children, ...props }) => {
|
|
694
|
-
return /* @__PURE__ */ React8.createElement(Tooltip.Root, null, /* @__PURE__ */ React8.createElement(Tooltip.Trigger, {
|
|
695
|
-
asChild: true
|
|
696
|
-
}, /* @__PURE__ */ React8.createElement(NaturalToolbar.Button, {
|
|
697
|
-
variant: "ghost",
|
|
698
|
-
...props,
|
|
699
|
-
classNames: buttonStyles
|
|
700
|
-
}, /* @__PURE__ */ React8.createElement(Icon, {
|
|
701
|
-
icon,
|
|
702
|
-
size: 5
|
|
703
|
-
}), /* @__PURE__ */ React8.createElement("span", {
|
|
704
|
-
className: "sr-only"
|
|
705
|
-
}, children))), /* @__PURE__ */ React8.createElement(Tooltip.Portal, null, /* @__PURE__ */ React8.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React8.createElement(Tooltip.Arrow, null))));
|
|
706
|
-
};
|
|
707
|
-
|
|
708
|
-
// packages/ui/react-ui-table/src/components/Toolbar/Toolbar.tsx
|
|
709
|
-
var [ToolbarContextProvider, useToolbarContext] = createContext("Toolbar");
|
|
710
|
-
var ToolbarRoot = ({ classNames, children, onAction }) => {
|
|
711
|
-
return /* @__PURE__ */ React9.createElement(ToolbarContextProvider, {
|
|
712
|
-
onAction
|
|
713
|
-
}, /* @__PURE__ */ React9.createElement(NaturalToolbar2.Root, {
|
|
714
|
-
classNames: [
|
|
715
|
-
"is-full shrink-0 overflow-x-auto overflow-y-hidden p-1 attention-surface",
|
|
716
|
-
classNames
|
|
717
|
-
]
|
|
718
|
-
}, children));
|
|
719
|
-
};
|
|
720
|
-
var Editing = () => {
|
|
721
|
-
const { onAction } = useToolbarContext("Editing");
|
|
722
|
-
const { t } = useTranslation4(translationKey);
|
|
723
|
-
return /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement(ToolbarButton, {
|
|
724
|
-
value: "add-row",
|
|
725
|
-
icon: "ph--plus--regular",
|
|
726
|
-
"data-testid": "table.toolbar.add-row",
|
|
727
|
-
onClick: () => onAction?.({
|
|
728
|
-
type: "add-row"
|
|
729
|
-
})
|
|
730
|
-
}, t("add row")));
|
|
731
|
-
};
|
|
732
|
-
var Actions = () => {
|
|
733
|
-
const { onAction } = useToolbarContext("Actions");
|
|
734
|
-
const { t } = useTranslation4(translationKey);
|
|
735
|
-
return /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement(ToolbarButton, {
|
|
736
|
-
value: "comment",
|
|
737
|
-
icon: "ph--chat-text--regular",
|
|
738
|
-
"data-testid": "table.toolbar.comment",
|
|
739
|
-
onClick: () => onAction?.({
|
|
740
|
-
type: "comment"
|
|
741
|
-
})
|
|
742
|
-
}, t("create comment")));
|
|
743
|
-
};
|
|
744
|
-
var Toolbar = {
|
|
745
|
-
Root: ToolbarRoot,
|
|
746
|
-
Editing,
|
|
747
|
-
Actions,
|
|
748
|
-
Separator: ToolbarSeparator
|
|
749
|
-
};
|
|
750
|
-
|
|
751
|
-
// packages/ui/react-ui-table/src/hooks/useTableModel.ts
|
|
752
|
-
import { useEffect as useEffect2, useState as useState3 } from "react";
|
|
753
|
-
|
|
754
691
|
// packages/ui/react-ui-table/src/model/table-model.ts
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
692
|
+
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/model/table-model.ts";
|
|
693
|
+
var TableModel = class extends Resource2 {
|
|
694
|
+
constructor({ table, projection, sorting = [], pinnedRows = {
|
|
695
|
+
top: [],
|
|
696
|
+
bottom: []
|
|
697
|
+
}, onCellUpdate, onDeleteColumn, onDeleteRows, onInsertRow, onRowOrderChanged }) {
|
|
698
|
+
super();
|
|
699
|
+
this.id = `table-model-${PublicKey2.random().truncate()}`;
|
|
700
|
+
this._visibleRange = signal3({
|
|
701
|
+
start: {
|
|
702
|
+
row: 0,
|
|
703
|
+
col: 0
|
|
704
|
+
},
|
|
705
|
+
end: {
|
|
706
|
+
row: 0,
|
|
707
|
+
col: 0
|
|
708
|
+
}
|
|
709
|
+
});
|
|
710
|
+
this._rows = signal3([]);
|
|
711
|
+
//
|
|
712
|
+
// Data
|
|
713
|
+
//
|
|
714
|
+
this.setRows = (obj) => {
|
|
715
|
+
this._rows.value = obj;
|
|
716
|
+
};
|
|
717
|
+
this.getRowCount = () => this._rows.value.length;
|
|
718
|
+
this.getColumnCount = () => this.table.view?.target?.fields.length ?? 0;
|
|
719
|
+
this.insertRow = (rowIndex) => {
|
|
720
|
+
const row = rowIndex !== void 0 ? this._sorting.getDataIndex(rowIndex) : this._rows.value.length;
|
|
721
|
+
this._onInsertRow?.(row);
|
|
722
|
+
};
|
|
723
|
+
this.deleteRow = (rowIndex) => {
|
|
724
|
+
const row = this._sorting.getDataIndex(rowIndex);
|
|
725
|
+
const obj = this._rows.value[row];
|
|
726
|
+
const objectsToDelete = [];
|
|
727
|
+
if (this._selection.hasSelection.value) {
|
|
728
|
+
const selectedRows = this._selection.getSelectedRows();
|
|
729
|
+
objectsToDelete.push(...selectedRows);
|
|
730
|
+
} else {
|
|
731
|
+
objectsToDelete.push(obj);
|
|
732
|
+
}
|
|
733
|
+
this._onDeleteRows?.(row, objectsToDelete);
|
|
734
|
+
};
|
|
735
|
+
this.getCellData = ({ col, row }) => {
|
|
736
|
+
const fields = this.table.view?.target?.fields ?? [];
|
|
737
|
+
if (col < 0 || col >= fields.length) {
|
|
738
|
+
return void 0;
|
|
739
|
+
}
|
|
740
|
+
const field = fields[col];
|
|
741
|
+
const dataIndex = this._sorting.getDataIndex(row);
|
|
742
|
+
const value = getValue2(this._rows.value[dataIndex], field.path);
|
|
743
|
+
if (value == null) {
|
|
744
|
+
return "";
|
|
745
|
+
}
|
|
746
|
+
const { props } = this._projection.getFieldProjection(field.id);
|
|
747
|
+
switch (props.format) {
|
|
748
|
+
case FormatEnum3.Ref: {
|
|
749
|
+
if (!field.referencePath) {
|
|
750
|
+
return "";
|
|
751
|
+
}
|
|
752
|
+
return getValue2(value.target, field.referencePath);
|
|
753
|
+
}
|
|
754
|
+
default: {
|
|
755
|
+
return formatForEditing({
|
|
756
|
+
type: props.type,
|
|
757
|
+
format: props.format,
|
|
758
|
+
value
|
|
759
|
+
});
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
};
|
|
763
|
+
this.setCellData = ({ col, row }, value) => {
|
|
764
|
+
const rowIdx = this._sorting.getDataIndex(row);
|
|
765
|
+
const fields = this.table.view?.target?.fields ?? [];
|
|
766
|
+
if (col < 0 || col >= fields.length) {
|
|
767
|
+
return;
|
|
768
|
+
}
|
|
769
|
+
const field = fields[col];
|
|
770
|
+
const { props } = this._projection.getFieldProjection(field.id);
|
|
771
|
+
switch (props.format) {
|
|
772
|
+
case FormatEnum3.Ref: {
|
|
773
|
+
if (isReactiveObject(value)) {
|
|
774
|
+
setValue(this._rows.value[rowIdx], field.path, makeRef2(value));
|
|
775
|
+
}
|
|
776
|
+
break;
|
|
777
|
+
}
|
|
778
|
+
default: {
|
|
779
|
+
setValue(this._rows.value[rowIdx], field.path, parseValue({
|
|
780
|
+
type: props.type,
|
|
781
|
+
format: props.format,
|
|
782
|
+
value
|
|
783
|
+
}));
|
|
784
|
+
break;
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
};
|
|
788
|
+
this._table = table;
|
|
789
|
+
this._projection = projection;
|
|
790
|
+
this._sorting = new TableSorting(this._rows, table, projection);
|
|
791
|
+
if (sorting.length > 0) {
|
|
792
|
+
const [sort] = sorting;
|
|
793
|
+
this._sorting.setSort(sort.fieldId, sort.direction);
|
|
794
|
+
}
|
|
795
|
+
this._pinnedRows = pinnedRows;
|
|
796
|
+
this._onInsertRow = onInsertRow;
|
|
797
|
+
this._onDeleteRows = onDeleteRows;
|
|
798
|
+
this._onDeleteColumn = onDeleteColumn;
|
|
799
|
+
this._onCellUpdate = onCellUpdate;
|
|
800
|
+
this._onRowOrderChanged = onRowOrderChanged;
|
|
801
|
+
}
|
|
802
|
+
get table() {
|
|
803
|
+
return this._table;
|
|
804
|
+
}
|
|
805
|
+
get projection() {
|
|
806
|
+
return this._projection;
|
|
807
|
+
}
|
|
808
|
+
get rows() {
|
|
809
|
+
return this._sorting.sortedRows;
|
|
810
|
+
}
|
|
811
|
+
/**
|
|
812
|
+
* @reactive
|
|
813
|
+
*/
|
|
814
|
+
get sorting() {
|
|
815
|
+
return this._sorting.sorting;
|
|
816
|
+
}
|
|
817
|
+
get pinnedRows() {
|
|
818
|
+
return this._pinnedRows;
|
|
819
|
+
}
|
|
820
|
+
get columnMeta() {
|
|
821
|
+
invariant(this._columnMeta, void 0, {
|
|
822
|
+
F: __dxlog_file2,
|
|
823
|
+
L: 117,
|
|
824
|
+
S: this,
|
|
825
|
+
A: [
|
|
826
|
+
"this._columnMeta",
|
|
827
|
+
""
|
|
828
|
+
]
|
|
829
|
+
});
|
|
830
|
+
return this._columnMeta;
|
|
831
|
+
}
|
|
832
|
+
get selection() {
|
|
833
|
+
return this._selection;
|
|
834
|
+
}
|
|
835
|
+
//
|
|
836
|
+
// Initialisation
|
|
837
|
+
//
|
|
838
|
+
async _open() {
|
|
839
|
+
this.initializeColumnMeta();
|
|
840
|
+
this.initializeEffects();
|
|
841
|
+
this._selection = new SelectionModel(this._sorting.sortedRows, () => this._onRowOrderChanged?.());
|
|
842
|
+
await this._selection.open(this._ctx);
|
|
843
|
+
}
|
|
844
|
+
initializeColumnMeta() {
|
|
845
|
+
this._columnMeta = computed3(() => {
|
|
846
|
+
const fields = this._table.view?.target?.fields ?? [];
|
|
847
|
+
const meta = Object.fromEntries(fields.map((field, index) => [
|
|
848
|
+
index,
|
|
849
|
+
{
|
|
850
|
+
size: field?.size ?? 256,
|
|
851
|
+
resizeable: true
|
|
852
|
+
}
|
|
853
|
+
]));
|
|
854
|
+
return {
|
|
855
|
+
grid: meta,
|
|
856
|
+
frozenColsStart: {
|
|
857
|
+
0: {
|
|
858
|
+
size: 30,
|
|
859
|
+
resizeable: false
|
|
860
|
+
}
|
|
861
|
+
},
|
|
862
|
+
frozenColsEnd: {
|
|
863
|
+
0: {
|
|
864
|
+
size: 40,
|
|
865
|
+
resizeable: false
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
};
|
|
869
|
+
});
|
|
870
|
+
}
|
|
871
|
+
initializeEffects() {
|
|
872
|
+
const rowOrderWatcher = effect2(() => {
|
|
873
|
+
touch(this._sorting.sortedRows.value);
|
|
874
|
+
this._onRowOrderChanged?.();
|
|
875
|
+
});
|
|
876
|
+
this._ctx.onDispose(rowOrderWatcher);
|
|
877
|
+
const rowEffectManager = effect2(() => {
|
|
878
|
+
const { start, end } = touch(this._visibleRange.value);
|
|
879
|
+
const rowEffects = [];
|
|
880
|
+
for (let row = start.row; row <= end.row; row++) {
|
|
881
|
+
rowEffects.push(effect2(() => {
|
|
882
|
+
const obj = this._sorting.sortedRows.value[row];
|
|
883
|
+
this?._table?.view?.target?.fields.forEach((field) => touch(getValue2(obj, field.path)));
|
|
884
|
+
this._onCellUpdate?.({
|
|
885
|
+
row,
|
|
886
|
+
col: start.col,
|
|
887
|
+
plane: "grid"
|
|
888
|
+
});
|
|
889
|
+
}));
|
|
890
|
+
}
|
|
891
|
+
return () => rowEffects.forEach((cleanup) => cleanup());
|
|
892
|
+
});
|
|
893
|
+
this._ctx.onDispose(rowEffectManager);
|
|
894
|
+
}
|
|
895
|
+
/**
|
|
896
|
+
* Updates a cell's value using a transform function.
|
|
897
|
+
* @param {DxGridPlanePosition} position - The position of the cell to update.
|
|
898
|
+
* @param {(value: any) => any} update - A function that takes the current value and returns the updated value.
|
|
899
|
+
*/
|
|
900
|
+
updateCellData({ col, row }, update) {
|
|
901
|
+
const dataRow = this._sorting.getDataIndex(row);
|
|
902
|
+
const fields = this.table.view?.target?.fields ?? [];
|
|
903
|
+
const field = fields[col];
|
|
904
|
+
const value = getValue2(this._rows.value[dataRow], field.path);
|
|
905
|
+
const updatedValue = update(value);
|
|
906
|
+
setValue(this._rows.value[dataRow], field.path, updatedValue);
|
|
907
|
+
}
|
|
908
|
+
//
|
|
909
|
+
// Column Operations
|
|
910
|
+
//
|
|
911
|
+
deleteColumn(fieldId) {
|
|
912
|
+
if (!this.table.view) {
|
|
913
|
+
return;
|
|
818
914
|
}
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
id: createFieldId(),
|
|
823
|
-
path: "manager",
|
|
824
|
-
referencePath: "name"
|
|
825
|
-
},
|
|
826
|
-
props: {
|
|
827
|
-
property: "manager",
|
|
828
|
-
type: TypeEnum.Ref,
|
|
829
|
-
format: FormatEnum2.Ref,
|
|
830
|
-
referenceSchema: contactSchema.typename,
|
|
831
|
-
title: "Manager"
|
|
915
|
+
const field = this.table.view.target?.fields.find((field2) => field2.id === fieldId);
|
|
916
|
+
if (field && this._onDeleteColumn) {
|
|
917
|
+
this._onDeleteColumn(field.id);
|
|
832
918
|
}
|
|
833
|
-
});
|
|
834
|
-
if (initialRow) {
|
|
835
|
-
space.db.add(create2(contactSchema, {}));
|
|
836
919
|
}
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
icon: ICONS.columnSettings,
|
|
870
|
-
render: ({ fieldId }) => createButtonHtml({
|
|
871
|
-
button: "columnSettings",
|
|
872
|
-
value: fieldId,
|
|
873
|
-
testId: "table-column-settings-button"
|
|
874
|
-
})
|
|
875
|
-
},
|
|
876
|
-
rowMenu: {
|
|
877
|
-
attr: TABLE_ATTRS.rowMenu,
|
|
878
|
-
icon: ICONS.rowMenu,
|
|
879
|
-
render: ({ rowIndex }) => createButtonHtml({
|
|
880
|
-
button: "rowMenu",
|
|
881
|
-
value: rowIndex.toString(),
|
|
882
|
-
testId: "table-row-menu-button"
|
|
883
|
-
})
|
|
884
|
-
},
|
|
885
|
-
addColumn: {
|
|
886
|
-
attr: TABLE_ATTRS.newColumn,
|
|
887
|
-
icon: ICONS.newColumn,
|
|
888
|
-
render: ({ disabled } = {}) => createButtonHtml({
|
|
889
|
-
button: "newColumn",
|
|
890
|
-
disabled,
|
|
891
|
-
testId: "table-new-column-button"
|
|
892
|
-
})
|
|
920
|
+
//
|
|
921
|
+
// Resize
|
|
922
|
+
//
|
|
923
|
+
setColumnWidth(columnIndex, width) {
|
|
924
|
+
const fields = this.table.view?.target?.fields ?? [];
|
|
925
|
+
if (columnIndex < fields.length) {
|
|
926
|
+
const newWidth = Math.max(0, width);
|
|
927
|
+
const field = fields[columnIndex];
|
|
928
|
+
if (field) {
|
|
929
|
+
field.size = newWidth;
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
//
|
|
934
|
+
// Sorting
|
|
935
|
+
//
|
|
936
|
+
setSort(fieldId, direction) {
|
|
937
|
+
this._sorting.setSort(fieldId, direction);
|
|
938
|
+
}
|
|
939
|
+
clearSort() {
|
|
940
|
+
this._sorting.setSort("", "asc");
|
|
941
|
+
}
|
|
942
|
+
//
|
|
943
|
+
// Pinning
|
|
944
|
+
//
|
|
945
|
+
// TODO(burdon): Change to setPinned(on/off).
|
|
946
|
+
pinRow(rowIndex, side) {
|
|
947
|
+
this._pinnedRows[side].push(rowIndex);
|
|
948
|
+
}
|
|
949
|
+
unpinRow(rowIndex) {
|
|
950
|
+
this._pinnedRows.top = this._pinnedRows.top.filter((index) => index !== rowIndex);
|
|
951
|
+
this._pinnedRows.bottom = this._pinnedRows.bottom.filter((index) => index !== rowIndex);
|
|
893
952
|
}
|
|
894
953
|
};
|
|
895
954
|
|
|
896
955
|
// packages/ui/react-ui-table/src/model/modal-controller.ts
|
|
897
|
-
|
|
956
|
+
import { signal as signal4 } from "@preact/signals-core";
|
|
957
|
+
import { log as log2 } from "@dxos/log";
|
|
958
|
+
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/model/modal-controller.ts";
|
|
898
959
|
var ModalController = class {
|
|
899
960
|
constructor() {
|
|
900
|
-
this._state =
|
|
961
|
+
this._state = signal4({
|
|
901
962
|
type: "closed"
|
|
902
963
|
});
|
|
903
964
|
this._triggerRef = {
|
|
904
965
|
current: null
|
|
905
966
|
};
|
|
906
|
-
this.
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
};
|
|
936
|
-
return true;
|
|
937
|
-
}
|
|
938
|
-
const refButton = target.closest(`button[${tableButtons.referencedCell.attr}]`);
|
|
939
|
-
if (refButton) {
|
|
940
|
-
this._triggerRef.current = refButton;
|
|
941
|
-
const [schemaId, targetId] = refButton.getAttribute(tableButtons.referencedCell.attr).split("#");
|
|
942
|
-
this._state.value = {
|
|
943
|
-
type: "refPanel",
|
|
944
|
-
targetId,
|
|
945
|
-
typename: schemaId
|
|
946
|
-
};
|
|
947
|
-
}
|
|
948
|
-
return false;
|
|
967
|
+
this.setTrigger = (trigger) => {
|
|
968
|
+
this._triggerRef.current = trigger;
|
|
969
|
+
};
|
|
970
|
+
this.showRowMenu = (rowIndex) => {
|
|
971
|
+
this._state.value = {
|
|
972
|
+
type: "row",
|
|
973
|
+
rowIndex
|
|
974
|
+
};
|
|
975
|
+
};
|
|
976
|
+
this.showColumnMenu = (fieldId) => {
|
|
977
|
+
this._state.value = {
|
|
978
|
+
type: "column",
|
|
979
|
+
fieldId
|
|
980
|
+
};
|
|
981
|
+
};
|
|
982
|
+
this.showColumnCreator = () => {
|
|
983
|
+
this._state.value = {
|
|
984
|
+
type: "columnSettings",
|
|
985
|
+
mode: {
|
|
986
|
+
type: "create"
|
|
987
|
+
}
|
|
988
|
+
};
|
|
989
|
+
};
|
|
990
|
+
this.showReferencePanel = (targetId, schemaId) => {
|
|
991
|
+
this._state.value = {
|
|
992
|
+
type: "refPanel",
|
|
993
|
+
targetId,
|
|
994
|
+
typename: schemaId
|
|
995
|
+
};
|
|
949
996
|
};
|
|
950
997
|
this.openColumnSettings = () => {
|
|
951
998
|
if (this._state.value.type === "column") {
|
|
@@ -972,618 +1019,786 @@ var ModalController = class {
|
|
|
972
1019
|
};
|
|
973
1020
|
} else {
|
|
974
1021
|
log2.warn("anchor cell not found while creating new ref", void 0, {
|
|
975
|
-
F:
|
|
976
|
-
L:
|
|
1022
|
+
F: __dxlog_file3,
|
|
1023
|
+
L: 86,
|
|
977
1024
|
S: this,
|
|
978
1025
|
C: (f, a) => f(...a)
|
|
979
1026
|
});
|
|
980
1027
|
}
|
|
981
1028
|
};
|
|
982
1029
|
this.close = () => {
|
|
983
|
-
this._state.value = {
|
|
984
|
-
type: "closed"
|
|
985
|
-
};
|
|
986
|
-
};
|
|
987
|
-
}
|
|
988
|
-
get state() {
|
|
989
|
-
return this._state;
|
|
990
|
-
}
|
|
991
|
-
get trigger() {
|
|
992
|
-
return this._triggerRef;
|
|
993
|
-
}
|
|
994
|
-
};
|
|
995
|
-
|
|
996
|
-
// packages/ui/react-ui-table/src/model/selection-model.ts
|
|
997
|
-
import { computed, effect, signal as signal2 } from "@preact/signals-core";
|
|
998
|
-
import { Resource } from "@dxos/context";
|
|
999
|
-
var SelectionModel = class extends Resource {
|
|
1000
|
-
constructor(_rows, _onSelectionChanged) {
|
|
1001
|
-
super();
|
|
1002
|
-
this._rows = _rows;
|
|
1003
|
-
this._onSelectionChanged = _onSelectionChanged;
|
|
1004
|
-
this._selection = signal2(/* @__PURE__ */ new Set());
|
|
1005
|
-
this._validSelectedIds = computed(() => {
|
|
1006
|
-
const rows = this._rows.value;
|
|
1007
|
-
if (!rows) {
|
|
1008
|
-
return /* @__PURE__ */ new Set();
|
|
1009
|
-
}
|
|
1010
|
-
const validIds = new Set(rows.map((row) => row.id));
|
|
1011
|
-
return new Set([
|
|
1012
|
-
...this._selection.value
|
|
1013
|
-
].filter((id) => validIds.has(id)));
|
|
1014
|
-
});
|
|
1015
|
-
this._hasSelection = computed(() => this._validSelectedIds.value.size > 0);
|
|
1016
|
-
this._allSelected = computed(() => {
|
|
1017
|
-
const rows = this._rows.value;
|
|
1018
|
-
if (rows.length === 0) {
|
|
1019
|
-
return false;
|
|
1020
|
-
}
|
|
1021
|
-
return rows.every((row) => this._selection.value.has(row.id));
|
|
1022
|
-
});
|
|
1023
|
-
this.getSelectedRows = () => {
|
|
1024
|
-
const selectedIds = this._validSelectedIds.value;
|
|
1025
|
-
return this._rows.value.filter((row) => selectedIds.has(row.id));
|
|
1026
|
-
};
|
|
1027
|
-
this.isRowIndexSelected = (rowIndex) => {
|
|
1028
|
-
const row = this._rows.value[rowIndex];
|
|
1029
|
-
return this._selection.value.has(row.id);
|
|
1030
|
-
};
|
|
1031
|
-
this.isObjectSelected = (object) => {
|
|
1032
|
-
return this._selection.value.has(object.id);
|
|
1033
|
-
};
|
|
1034
|
-
this.toggleSelectionForRowIndex = (rowIndex) => {
|
|
1035
|
-
const row = this._rows.value[rowIndex];
|
|
1036
|
-
const newSelection = new Set(this._selection.value);
|
|
1037
|
-
if (newSelection.has(row.id)) {
|
|
1038
|
-
newSelection.delete(row.id);
|
|
1039
|
-
} else {
|
|
1040
|
-
newSelection.add(row.id);
|
|
1041
|
-
}
|
|
1042
|
-
this._selection.value = newSelection;
|
|
1043
|
-
};
|
|
1044
|
-
this.setSelection = (mode) => {
|
|
1045
|
-
this._selection.value = mode === "all" ? new Set(this._rows.value.map((row) => row.id)) : /* @__PURE__ */ new Set();
|
|
1046
|
-
};
|
|
1047
|
-
}
|
|
1048
|
-
async _open() {
|
|
1049
|
-
const selectionWatcher = effect(() => {
|
|
1050
|
-
touch(this._selection.value);
|
|
1051
|
-
this._onSelectionChanged?.();
|
|
1052
|
-
});
|
|
1053
|
-
this._ctx.onDispose(selectionWatcher);
|
|
1054
|
-
}
|
|
1055
|
-
//
|
|
1056
|
-
// Getters
|
|
1057
|
-
//
|
|
1058
|
-
get selection() {
|
|
1059
|
-
return this._selection;
|
|
1030
|
+
this._state.value = {
|
|
1031
|
+
type: "closed"
|
|
1032
|
+
};
|
|
1033
|
+
};
|
|
1060
1034
|
}
|
|
1061
|
-
get
|
|
1062
|
-
return this.
|
|
1035
|
+
get state() {
|
|
1036
|
+
return this._state;
|
|
1063
1037
|
}
|
|
1064
|
-
get
|
|
1065
|
-
return this.
|
|
1038
|
+
get trigger() {
|
|
1039
|
+
return this._triggerRef;
|
|
1066
1040
|
}
|
|
1067
1041
|
};
|
|
1068
1042
|
|
|
1069
|
-
// packages/ui/react-ui-table/src/
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
};
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1043
|
+
// packages/ui/react-ui-table/src/model/table-presentation.ts
|
|
1044
|
+
import { signal as signal5 } from "@preact/signals-core";
|
|
1045
|
+
import { FormatEnum as FormatEnum4, getValue as getValue3 } from "@dxos/echo-schema";
|
|
1046
|
+
import { cellClassesForFieldType, cellClassesForRowSelection, formatForDisplay as formatForDisplay2 } from "@dxos/react-ui-form";
|
|
1047
|
+
import { toPlaneCellIndex } from "@dxos/react-ui-grid";
|
|
1048
|
+
import { mx } from "@dxos/react-ui-theme";
|
|
1049
|
+
import { VIEW_FIELD_LIMIT } from "@dxos/schema";
|
|
1050
|
+
var TablePresentation = class {
|
|
1051
|
+
constructor(model, _visibleRange = signal5({
|
|
1052
|
+
start: {
|
|
1053
|
+
row: 0,
|
|
1054
|
+
col: 0
|
|
1055
|
+
},
|
|
1056
|
+
end: {
|
|
1057
|
+
row: 0,
|
|
1058
|
+
col: 0
|
|
1059
|
+
}
|
|
1060
|
+
})) {
|
|
1061
|
+
this.model = model;
|
|
1062
|
+
this._visibleRange = _visibleRange;
|
|
1083
1063
|
}
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
}
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
//
|
|
1117
|
-
this.getCells = (range, plane) => {
|
|
1118
|
-
switch (plane) {
|
|
1119
|
-
case "grid": {
|
|
1120
|
-
this._visibleRange.value = range;
|
|
1121
|
-
return this.getMainGridCells(range);
|
|
1122
|
-
}
|
|
1123
|
-
case "frozenRowsStart": {
|
|
1124
|
-
return this.getHeaderCells(range);
|
|
1125
|
-
}
|
|
1126
|
-
case "frozenColsStart": {
|
|
1127
|
-
return this.getSelectionColumnCells(range);
|
|
1128
|
-
}
|
|
1129
|
-
case "frozenColsEnd": {
|
|
1130
|
-
return this.getActionColumnCells(range);
|
|
1131
|
-
}
|
|
1132
|
-
case "fixedStartStart": {
|
|
1133
|
-
return this.getSelectAllCell();
|
|
1134
|
-
}
|
|
1135
|
-
case "fixedStartEnd": {
|
|
1136
|
-
return this.getNewColumnCell();
|
|
1137
|
-
}
|
|
1138
|
-
default: {
|
|
1139
|
-
return {};
|
|
1140
|
-
}
|
|
1141
|
-
}
|
|
1142
|
-
};
|
|
1143
|
-
this.getMainGridCells = (range) => {
|
|
1144
|
-
const cells = {};
|
|
1145
|
-
const fields = this._table.view?.fields ?? [];
|
|
1146
|
-
const addCell = (obj, field, colIndex, displayIndex) => {
|
|
1147
|
-
const { props } = this._projection.getFieldProjection(field.id);
|
|
1148
|
-
const cell = {
|
|
1149
|
-
get value() {
|
|
1150
|
-
const value = getValue2(obj, field.path);
|
|
1151
|
-
if (value == null) {
|
|
1064
|
+
getCells(range, plane) {
|
|
1065
|
+
switch (plane) {
|
|
1066
|
+
case "grid":
|
|
1067
|
+
this._visibleRange.value = range;
|
|
1068
|
+
return this.getMainGridCells(range);
|
|
1069
|
+
case "frozenRowsStart":
|
|
1070
|
+
return this.getHeaderCells(range);
|
|
1071
|
+
case "frozenColsStart":
|
|
1072
|
+
return this.getSelectionColumnCells(range);
|
|
1073
|
+
case "frozenColsEnd":
|
|
1074
|
+
return this.getActionColumnCells(range);
|
|
1075
|
+
case "fixedStartStart":
|
|
1076
|
+
return this.getSelectAllCell();
|
|
1077
|
+
case "fixedStartEnd":
|
|
1078
|
+
return this.getNewColumnCell();
|
|
1079
|
+
default:
|
|
1080
|
+
return {};
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
getMainGridCells(range) {
|
|
1084
|
+
const cells = {};
|
|
1085
|
+
const fields = this.model.table.view?.target?.fields ?? [];
|
|
1086
|
+
const addCell = (obj, field, colIndex, displayIndex) => {
|
|
1087
|
+
const { props } = this.model.projection.getFieldProjection(field.id);
|
|
1088
|
+
const cell = {
|
|
1089
|
+
get value() {
|
|
1090
|
+
const value = getValue3(obj, field.path);
|
|
1091
|
+
if (value == null) {
|
|
1092
|
+
return "";
|
|
1093
|
+
}
|
|
1094
|
+
switch (props.format) {
|
|
1095
|
+
case FormatEnum4.Boolean: {
|
|
1152
1096
|
return "";
|
|
1153
1097
|
}
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
return "";
|
|
1158
|
-
}
|
|
1159
|
-
return getValue2(value, field.referencePath);
|
|
1160
|
-
}
|
|
1161
|
-
default: {
|
|
1162
|
-
return formatForDisplay({
|
|
1163
|
-
type: props.type,
|
|
1164
|
-
format: props.format,
|
|
1165
|
-
value
|
|
1166
|
-
});
|
|
1098
|
+
case FormatEnum4.Ref: {
|
|
1099
|
+
if (!field.referencePath) {
|
|
1100
|
+
return "";
|
|
1167
1101
|
}
|
|
1102
|
+
return getValue3(value.target, field.referencePath);
|
|
1103
|
+
}
|
|
1104
|
+
default: {
|
|
1105
|
+
return formatForDisplay2({
|
|
1106
|
+
type: props.type,
|
|
1107
|
+
format: props.format,
|
|
1108
|
+
value
|
|
1109
|
+
});
|
|
1168
1110
|
}
|
|
1169
1111
|
}
|
|
1170
|
-
};
|
|
1171
|
-
const classes = [];
|
|
1172
|
-
const formatClasses = cellClassesForFieldType({
|
|
1173
|
-
type: props.type,
|
|
1174
|
-
format: props.format
|
|
1175
|
-
});
|
|
1176
|
-
if (formatClasses) {
|
|
1177
|
-
classes.push(formatClasses);
|
|
1178
|
-
}
|
|
1179
|
-
const rowSelectionClasses = cellClassesForRowSelection(this._selection.isObjectSelected(obj));
|
|
1180
|
-
if (rowSelectionClasses) {
|
|
1181
|
-
classes.push(rowSelectionClasses);
|
|
1182
1112
|
}
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1113
|
+
};
|
|
1114
|
+
const classes = [];
|
|
1115
|
+
const formatClasses = cellClassesForFieldType({
|
|
1116
|
+
type: props.type,
|
|
1117
|
+
format: props.format
|
|
1118
|
+
});
|
|
1119
|
+
if (formatClasses) {
|
|
1120
|
+
classes.push(formatClasses);
|
|
1121
|
+
}
|
|
1122
|
+
const rowSelectionClasses = cellClassesForRowSelection(this.model.selection.isObjectSelected(obj));
|
|
1123
|
+
if (rowSelectionClasses) {
|
|
1124
|
+
classes.push(rowSelectionClasses);
|
|
1125
|
+
}
|
|
1126
|
+
if (classes.length > 0) {
|
|
1127
|
+
cell.className = mx(classes.flat());
|
|
1128
|
+
}
|
|
1129
|
+
if (props.format === FormatEnum4.Ref && props.referenceSchema) {
|
|
1130
|
+
const targetObj = getValue3(obj, field.path)?.target;
|
|
1131
|
+
if (targetObj) {
|
|
1188
1132
|
cell.accessoryHtml = tableButtons.referencedCell.render({
|
|
1189
1133
|
targetId: targetObj.id,
|
|
1190
1134
|
schemaId: props.referenceSchema
|
|
1191
1135
|
});
|
|
1192
1136
|
}
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1137
|
+
}
|
|
1138
|
+
if (props.format === FormatEnum4.Boolean) {
|
|
1139
|
+
const value = getValue3(obj, field.path);
|
|
1140
|
+
cell.accessoryHtml = tableControls.switch.render({
|
|
1141
|
+
colIndex,
|
|
1142
|
+
rowIndex: displayIndex,
|
|
1143
|
+
checked: value ?? false
|
|
1196
1144
|
});
|
|
1197
|
-
|
|
1198
|
-
};
|
|
1199
|
-
for (let row = range.start.row; row <= range.end.row && row < this._sortedRows.value.length; row++) {
|
|
1200
|
-
for (let col = range.start.col; col <= range.end.col && col < fields.length; col++) {
|
|
1201
|
-
const field = fields[col];
|
|
1202
|
-
if (!field) {
|
|
1203
|
-
continue;
|
|
1204
|
-
}
|
|
1205
|
-
addCell(this._sortedRows.value[row], field, col, row);
|
|
1206
|
-
}
|
|
1145
|
+
cell.readonly = true;
|
|
1207
1146
|
}
|
|
1208
|
-
|
|
1147
|
+
const idx = toPlaneCellIndex({
|
|
1148
|
+
col: colIndex,
|
|
1149
|
+
row: displayIndex
|
|
1150
|
+
});
|
|
1151
|
+
cells[idx] = cell;
|
|
1209
1152
|
};
|
|
1210
|
-
|
|
1211
|
-
const cells = {};
|
|
1212
|
-
const fields = this.table.view?.fields ?? [];
|
|
1153
|
+
for (let row = range.start.row; row <= range.end.row && row < this.model.getRowCount(); row++) {
|
|
1213
1154
|
for (let col = range.start.col; col <= range.end.col && col < fields.length; col++) {
|
|
1214
|
-
const
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
// TODO(burdon): Use same logic as form for fallback title.
|
|
1220
|
-
value: props.title ?? field.path,
|
|
1221
|
-
readonly: true,
|
|
1222
|
-
resizeHandle: "col",
|
|
1223
|
-
accessoryHtml: tableButtons.columnSettings.render({
|
|
1224
|
-
fieldId: field.id
|
|
1225
|
-
})
|
|
1226
|
-
};
|
|
1155
|
+
const field = fields[col];
|
|
1156
|
+
if (!field) {
|
|
1157
|
+
continue;
|
|
1158
|
+
}
|
|
1159
|
+
addCell(this.model.rows.value[row], field, col, row);
|
|
1227
1160
|
}
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
}
|
|
1161
|
+
}
|
|
1162
|
+
return cells;
|
|
1163
|
+
}
|
|
1164
|
+
getHeaderCells(range) {
|
|
1165
|
+
const cells = {};
|
|
1166
|
+
const fields = this.model.table.view?.target?.fields ?? [];
|
|
1167
|
+
for (let col = range.start.col; col <= range.end.col && col < fields.length; col++) {
|
|
1168
|
+
const { field, props } = this.model.projection.getFieldProjection(fields[col].id);
|
|
1169
|
+
cells[toPlaneCellIndex({
|
|
1170
|
+
col,
|
|
1171
|
+
row: 0
|
|
1172
|
+
})] = {
|
|
1173
|
+
// TODO(burdon): Use same logic as form for fallback title.
|
|
1174
|
+
value: props.title ?? field.path,
|
|
1175
|
+
readonly: true,
|
|
1176
|
+
resizeHandle: "col",
|
|
1177
|
+
accessoryHtml: tableButtons.columnSettings.render({
|
|
1178
|
+
fieldId: field.id
|
|
1179
|
+
}),
|
|
1180
|
+
className: "!bg-gridHeader"
|
|
1181
|
+
};
|
|
1182
|
+
}
|
|
1183
|
+
return cells;
|
|
1184
|
+
}
|
|
1185
|
+
getSelectionColumnCells(range) {
|
|
1186
|
+
const cells = {};
|
|
1187
|
+
for (let row = range.start.row; row <= range.end.row && row < this.model.getRowCount(); row++) {
|
|
1188
|
+
const isSelected = this.model.selection.isRowIndexSelected(row);
|
|
1189
|
+
const classes = cellClassesForRowSelection(isSelected);
|
|
1190
|
+
cells[toPlaneCellIndex({
|
|
1191
|
+
col: 0,
|
|
1192
|
+
row
|
|
1193
|
+
})] = {
|
|
1194
|
+
value: "",
|
|
1195
|
+
readonly: true,
|
|
1196
|
+
className: classes ? mx(classes) : void 0,
|
|
1197
|
+
accessoryHtml: tableControls.checkbox.render({
|
|
1198
|
+
rowIndex: row,
|
|
1199
|
+
checked: isSelected
|
|
1200
|
+
})
|
|
1201
|
+
};
|
|
1202
|
+
}
|
|
1203
|
+
return cells;
|
|
1204
|
+
}
|
|
1205
|
+
getActionColumnCells(range) {
|
|
1206
|
+
const cells = {};
|
|
1207
|
+
for (let row = range.start.row; row <= range.end.row && row < this.model.getRowCount(); row++) {
|
|
1208
|
+
const isSelected = this.model.selection.isRowIndexSelected(row);
|
|
1209
|
+
const classes = cellClassesForRowSelection(isSelected);
|
|
1210
|
+
cells[toPlaneCellIndex({
|
|
1211
|
+
col: 0,
|
|
1212
|
+
row
|
|
1213
|
+
})] = {
|
|
1214
|
+
value: "",
|
|
1215
|
+
readonly: true,
|
|
1216
|
+
className: classes ? mx(classes) : void 0,
|
|
1217
|
+
accessoryHtml: tableButtons.rowMenu.render({
|
|
1218
|
+
rowIndex: row
|
|
1219
|
+
})
|
|
1220
|
+
};
|
|
1221
|
+
}
|
|
1222
|
+
return cells;
|
|
1223
|
+
}
|
|
1224
|
+
getSelectAllCell() {
|
|
1225
|
+
return {
|
|
1226
|
+
[toPlaneCellIndex({
|
|
1227
|
+
col: 0,
|
|
1228
|
+
row: 0
|
|
1229
|
+
})]: {
|
|
1230
|
+
accessoryHtml: tableControls.checkbox.render({
|
|
1231
|
+
rowIndex: 0,
|
|
1232
|
+
header: true,
|
|
1233
|
+
checked: this.model.selection.allRowsSeleted.value
|
|
1234
|
+
}),
|
|
1235
|
+
className: "!bg-gridHeader",
|
|
1236
|
+
readonly: true,
|
|
1237
|
+
value: ""
|
|
1247
1238
|
}
|
|
1248
|
-
return cells;
|
|
1249
1239
|
};
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
rowIndex: row
|
|
1264
|
-
})
|
|
1265
|
-
};
|
|
1240
|
+
}
|
|
1241
|
+
getNewColumnCell() {
|
|
1242
|
+
return {
|
|
1243
|
+
[toPlaneCellIndex({
|
|
1244
|
+
col: 0,
|
|
1245
|
+
row: 0
|
|
1246
|
+
})]: {
|
|
1247
|
+
accessoryHtml: tableButtons.addColumn.render({
|
|
1248
|
+
disabled: (this.model.table.view?.target?.fields?.length ?? 0) >= VIEW_FIELD_LIMIT
|
|
1249
|
+
}),
|
|
1250
|
+
className: "!bg-gridHeader",
|
|
1251
|
+
readonly: true,
|
|
1252
|
+
value: ""
|
|
1266
1253
|
}
|
|
1267
|
-
return cells;
|
|
1268
1254
|
};
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1255
|
+
}
|
|
1256
|
+
};
|
|
1257
|
+
|
|
1258
|
+
// packages/ui/react-ui-table/src/components/TableCellEditor/TableCellEditor.tsx
|
|
1259
|
+
import React6, { useCallback as useCallback3, useMemo as useMemo3, useRef } from "react";
|
|
1260
|
+
import { FormatEnum as FormatEnum5 } from "@dxos/echo-schema";
|
|
1261
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
1262
|
+
import { cellQuery, editorKeys, parseCellIndex, useGridContext as useGridContext2, GridCellEditor } from "@dxos/react-ui-grid";
|
|
1263
|
+
|
|
1264
|
+
// packages/ui/react-ui-table/src/components/TableCellEditor/extension.ts
|
|
1265
|
+
import { autocompletion, pickedCompletion } from "@codemirror/autocomplete";
|
|
1266
|
+
import { EditorView } from "@codemirror/view";
|
|
1267
|
+
var completion = ({ debug, onQuery, onMatch }) => {
|
|
1268
|
+
return [
|
|
1269
|
+
EditorView.theme({
|
|
1270
|
+
".cm-completionDialog": {
|
|
1271
|
+
width: "var(--dx-gridCellWidth)"
|
|
1272
|
+
}
|
|
1273
|
+
}),
|
|
1274
|
+
autocompletion({
|
|
1275
|
+
icons: false,
|
|
1276
|
+
activateOnTyping: true,
|
|
1277
|
+
closeOnBlur: !debug,
|
|
1278
|
+
override: [
|
|
1279
|
+
async (context) => {
|
|
1280
|
+
const text = context.state.doc.toString();
|
|
1281
|
+
return {
|
|
1282
|
+
from: 0,
|
|
1283
|
+
options: await onQuery(text)
|
|
1284
|
+
};
|
|
1282
1285
|
}
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1286
|
+
],
|
|
1287
|
+
// TODO(burdon): Consts from grid (to line-up with grid).
|
|
1288
|
+
tooltipClass: () => "cm-completionDialog !mt-[8px] !-ml-[4px] [&>ul]:!max-h-[264px]",
|
|
1289
|
+
optionClass: () => "flex h-[33px] items-center"
|
|
1290
|
+
}),
|
|
1291
|
+
// Check for accepted completion metadata in the transaction.
|
|
1292
|
+
EditorView.updateListener.of((update) => {
|
|
1293
|
+
update.transactions.forEach((tr) => {
|
|
1294
|
+
const completion2 = tr.annotation(pickedCompletion);
|
|
1295
|
+
if (completion2) {
|
|
1296
|
+
onMatch(completion2.data);
|
|
1297
|
+
}
|
|
1298
|
+
});
|
|
1299
|
+
})
|
|
1300
|
+
];
|
|
1301
|
+
};
|
|
1302
|
+
|
|
1303
|
+
// packages/ui/react-ui-table/src/components/TableCellEditor/TableCellEditor.tsx
|
|
1304
|
+
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/components/TableCellEditor/TableCellEditor.tsx";
|
|
1305
|
+
var newValue = Symbol.for("newValue");
|
|
1306
|
+
var createOption = (text) => ({
|
|
1307
|
+
[newValue]: true,
|
|
1308
|
+
text
|
|
1309
|
+
});
|
|
1310
|
+
var isCreateOption = (data) => typeof data === "object" && data[newValue];
|
|
1311
|
+
var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, __gridScope }) => {
|
|
1312
|
+
const { id: gridId, editing, setEditing } = useGridContext2("TableCellEditor", __gridScope);
|
|
1313
|
+
const suppressNextBlur = useRef(false);
|
|
1314
|
+
const fieldProjection = useMemo3(() => {
|
|
1315
|
+
if (!model || !editing) {
|
|
1316
|
+
return;
|
|
1317
|
+
}
|
|
1318
|
+
const { col } = parseCellIndex(editing.index);
|
|
1319
|
+
const field = model.projection.view.fields[col];
|
|
1320
|
+
const fieldProjection2 = model.projection.getFieldProjection(field.id);
|
|
1321
|
+
invariant2(fieldProjection2, void 0, {
|
|
1322
|
+
F: __dxlog_file4,
|
|
1323
|
+
L: 67,
|
|
1324
|
+
S: void 0,
|
|
1325
|
+
A: [
|
|
1326
|
+
"fieldProjection",
|
|
1327
|
+
""
|
|
1328
|
+
]
|
|
1329
|
+
});
|
|
1330
|
+
return fieldProjection2;
|
|
1331
|
+
}, [
|
|
1332
|
+
model,
|
|
1333
|
+
editing
|
|
1334
|
+
]);
|
|
1335
|
+
const handleEnter = useCallback3((value) => {
|
|
1336
|
+
if (!model || !editing) {
|
|
1337
|
+
return;
|
|
1338
|
+
}
|
|
1339
|
+
const cell = parseCellIndex(editing.index);
|
|
1340
|
+
model.setCellData(cell, value);
|
|
1341
|
+
onEnter?.(cell);
|
|
1342
|
+
onFocus?.();
|
|
1343
|
+
setEditing(null);
|
|
1344
|
+
}, [
|
|
1345
|
+
model,
|
|
1346
|
+
editing
|
|
1347
|
+
]);
|
|
1348
|
+
const handleBlur = useCallback3((value) => {
|
|
1349
|
+
if (!model || !editing) {
|
|
1350
|
+
return;
|
|
1351
|
+
}
|
|
1352
|
+
if (suppressNextBlur.current) {
|
|
1353
|
+
suppressNextBlur.current = false;
|
|
1354
|
+
return;
|
|
1355
|
+
}
|
|
1356
|
+
const cell = parseCellIndex(editing.index);
|
|
1357
|
+
if (value !== void 0) {
|
|
1358
|
+
model.setCellData(cell, value);
|
|
1359
|
+
}
|
|
1360
|
+
}, [
|
|
1361
|
+
model,
|
|
1362
|
+
editing
|
|
1363
|
+
]);
|
|
1364
|
+
const handleClose = useCallback3((value, event) => {
|
|
1365
|
+
if (!model || !editing || !fieldProjection) {
|
|
1366
|
+
return;
|
|
1367
|
+
}
|
|
1368
|
+
const cell = parseCellIndex(editing.index);
|
|
1369
|
+
onEnter?.(cell);
|
|
1370
|
+
if (event && onFocus) {
|
|
1371
|
+
onFocus(determineNavigationAxis(event), determineNavigationDelta(event));
|
|
1372
|
+
}
|
|
1373
|
+
}, [
|
|
1374
|
+
model,
|
|
1375
|
+
editing,
|
|
1376
|
+
onFocus,
|
|
1377
|
+
onEnter,
|
|
1378
|
+
fieldProjection,
|
|
1379
|
+
determineNavigationAxis,
|
|
1380
|
+
determineNavigationDelta
|
|
1381
|
+
]);
|
|
1382
|
+
const extension = useMemo3(() => {
|
|
1383
|
+
if (!fieldProjection) {
|
|
1384
|
+
return [];
|
|
1385
|
+
}
|
|
1386
|
+
const extension2 = [
|
|
1387
|
+
editorKeys({
|
|
1388
|
+
onClose: handleClose,
|
|
1389
|
+
...editing?.initialContent && {
|
|
1390
|
+
onNav: handleClose
|
|
1391
|
+
}
|
|
1392
|
+
})
|
|
1393
|
+
];
|
|
1394
|
+
if (onQuery) {
|
|
1395
|
+
switch (fieldProjection.props.format) {
|
|
1396
|
+
case FormatEnum5.Ref: {
|
|
1397
|
+
extension2.push([
|
|
1398
|
+
completion({
|
|
1399
|
+
onQuery: (text) => onQuery(fieldProjection, text),
|
|
1400
|
+
onMatch: (data) => {
|
|
1401
|
+
if (model && editing && modals) {
|
|
1402
|
+
if (isCreateOption(data)) {
|
|
1403
|
+
const { field, props } = fieldProjection;
|
|
1404
|
+
if (props.referenceSchema) {
|
|
1405
|
+
suppressNextBlur.current = true;
|
|
1406
|
+
modals.openCreateRef(props.referenceSchema, document.querySelector(cellQuery(editing.index, gridId)), {
|
|
1407
|
+
[field.referencePath]: data.text
|
|
1408
|
+
}, (data2) => {
|
|
1409
|
+
handleEnter(data2);
|
|
1410
|
+
});
|
|
1411
|
+
}
|
|
1412
|
+
} else {
|
|
1413
|
+
handleEnter(data);
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
})
|
|
1418
|
+
]);
|
|
1419
|
+
break;
|
|
1296
1420
|
}
|
|
1297
|
-
};
|
|
1298
|
-
};
|
|
1299
|
-
//
|
|
1300
|
-
// Data
|
|
1301
|
-
//
|
|
1302
|
-
this.setRows = (obj) => {
|
|
1303
|
-
this._rows.value = obj;
|
|
1304
|
-
};
|
|
1305
|
-
this.getRowCount = () => this._rows.value.length;
|
|
1306
|
-
this.getColumnCount = () => this.table.view?.fields.length ?? 0;
|
|
1307
|
-
this.insertRow = (rowIndex) => {
|
|
1308
|
-
const row = rowIndex !== void 0 ? this._displayToDataIndex.get(rowIndex) ?? rowIndex : this._rows.value.length;
|
|
1309
|
-
this._onInsertRow?.(row);
|
|
1310
|
-
};
|
|
1311
|
-
this.deleteRow = (rowIndex) => {
|
|
1312
|
-
const row = this._displayToDataIndex.get(rowIndex) ?? rowIndex;
|
|
1313
|
-
const obj = this._rows.value[row];
|
|
1314
|
-
const objectsToDelete = [];
|
|
1315
|
-
if (this._selection.hasSelection.value) {
|
|
1316
|
-
const selectedRows = this._selection.getSelectedRows();
|
|
1317
|
-
objectsToDelete.push(...selectedRows);
|
|
1318
|
-
} else {
|
|
1319
|
-
objectsToDelete.push(obj);
|
|
1320
|
-
}
|
|
1321
|
-
this._onDeleteRows?.(row, objectsToDelete);
|
|
1322
|
-
};
|
|
1323
|
-
this.getCellData = ({ col, row }) => {
|
|
1324
|
-
const fields = this.table.view?.fields ?? [];
|
|
1325
|
-
if (col < 0 || col >= fields.length) {
|
|
1326
|
-
return void 0;
|
|
1327
|
-
}
|
|
1328
|
-
const field = fields[col];
|
|
1329
|
-
const dataIndex = this._displayToDataIndex.get(row) ?? row;
|
|
1330
|
-
const value = getValue2(this._rows.value[dataIndex], field.path);
|
|
1331
|
-
if (value == null) {
|
|
1332
|
-
return "";
|
|
1333
1421
|
}
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1422
|
+
}
|
|
1423
|
+
return extension2;
|
|
1424
|
+
}, [
|
|
1425
|
+
model,
|
|
1426
|
+
modals,
|
|
1427
|
+
editing,
|
|
1428
|
+
fieldProjection,
|
|
1429
|
+
handleClose
|
|
1430
|
+
]);
|
|
1431
|
+
const getCellContent = useCallback3(() => {
|
|
1432
|
+
if (model && editing) {
|
|
1433
|
+
const value = model.getCellData(parseCellIndex(editing.index));
|
|
1434
|
+
return value !== void 0 ? String(value) : "";
|
|
1435
|
+
}
|
|
1436
|
+
}, [
|
|
1437
|
+
model,
|
|
1438
|
+
editing
|
|
1439
|
+
]);
|
|
1440
|
+
return /* @__PURE__ */ React6.createElement(GridCellEditor, {
|
|
1441
|
+
extension,
|
|
1442
|
+
getCellContent,
|
|
1443
|
+
onBlur: handleBlur
|
|
1444
|
+
});
|
|
1445
|
+
};
|
|
1446
|
+
var determineNavigationAxis = ({ key }) => {
|
|
1447
|
+
switch (key) {
|
|
1448
|
+
case "ArrowUp":
|
|
1449
|
+
case "ArrowDown":
|
|
1450
|
+
case "Enter": {
|
|
1451
|
+
return "row";
|
|
1452
|
+
}
|
|
1453
|
+
case "ArrowLeft":
|
|
1454
|
+
case "ArrowRight":
|
|
1455
|
+
case "Tab":
|
|
1456
|
+
return "col";
|
|
1457
|
+
}
|
|
1458
|
+
};
|
|
1459
|
+
var determineNavigationDelta = ({ key, shift }) => {
|
|
1460
|
+
switch (key) {
|
|
1461
|
+
case "ArrowUp":
|
|
1462
|
+
case "ArrowLeft":
|
|
1463
|
+
return -1;
|
|
1464
|
+
case "ArrowDown":
|
|
1465
|
+
case "ArrowRight":
|
|
1466
|
+
return 1;
|
|
1467
|
+
}
|
|
1468
|
+
return shift ? -1 : 1;
|
|
1469
|
+
};
|
|
1470
|
+
|
|
1471
|
+
// packages/ui/react-ui-table/src/components/Table/Table.tsx
|
|
1472
|
+
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/components/Table/Table.tsx";
|
|
1473
|
+
var inlineEndLine = "[&>.dx-grid]:relative [&>.dx-grid]:after:absolute [&>.dx-grid]:after:inset-block-0 [&>.dx-grid]:after:-inline-end-px [&>.dx-grid]:after:is-px [&>.dx-grid]:after:bg-separator";
|
|
1474
|
+
var blockEndLine = "[&>.dx-grid]:before:absolute [&>.dx-grid]:before:inset-inline-0 [&>.dx-grid]:before:-block-end-px [&>.dx-grid]:before:bs-px [&>.dx-grid]:before:bg-separator";
|
|
1475
|
+
var frozen = {
|
|
1476
|
+
frozenRowsStart: 1,
|
|
1477
|
+
frozenColsStart: 1,
|
|
1478
|
+
frozenColsEnd: 1
|
|
1479
|
+
};
|
|
1480
|
+
var TableRoot = ({ children, role }) => {
|
|
1481
|
+
return /* @__PURE__ */ React7.createElement("div", {
|
|
1482
|
+
role: "none",
|
|
1483
|
+
className: mx2("relative border-bs !border-separator", role === "section" ? "attention-surface overflow-hidden [&_.dx-grid]:max-is-[--dx-grid-content-inline-size]" : "flex flex-col [&_.dx-grid]:grow [&_.dx-grid]:max-is-[--dx-grid-content-inline-size] [&_.dx-grid]:bs-0 [&_.dx-grid]:max-bs-[--dx-grid-content-block-size]")
|
|
1484
|
+
}, children);
|
|
1485
|
+
};
|
|
1486
|
+
var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttention }, forwardedRef) => {
|
|
1487
|
+
const [dxGrid, setDxGrid] = useState2(null);
|
|
1488
|
+
const { hasAttention } = useAttention(model?.table ? fullyQualifiedId(model.table) : "table");
|
|
1489
|
+
const { t } = useTranslation3(translationKey);
|
|
1490
|
+
const modals = useMemo4(() => new ModalController(), []);
|
|
1491
|
+
useImperativeHandle(forwardedRef, () => {
|
|
1492
|
+
if (!presentation || !dxGrid) {
|
|
1493
|
+
return {};
|
|
1494
|
+
}
|
|
1495
|
+
dxGrid.getCells = (range, plane) => presentation.getCells(range, plane);
|
|
1496
|
+
return {
|
|
1497
|
+
update: (cell) => {
|
|
1498
|
+
if (cell) {
|
|
1499
|
+
dxGrid.updateIfWithinBounds(cell);
|
|
1500
|
+
} else {
|
|
1501
|
+
dxGrid.updateCells(true);
|
|
1502
|
+
dxGrid.requestUpdate();
|
|
1348
1503
|
}
|
|
1349
1504
|
}
|
|
1350
1505
|
};
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1506
|
+
}, [
|
|
1507
|
+
presentation,
|
|
1508
|
+
dxGrid
|
|
1509
|
+
]);
|
|
1510
|
+
const handleGridClick = useCallback4((event) => {
|
|
1511
|
+
if (!modals) {
|
|
1512
|
+
return;
|
|
1513
|
+
}
|
|
1514
|
+
const buttonSelector = Object.values(tableButtons).map((button) => `button[${button.attr}]`).join(",");
|
|
1515
|
+
const tableButtonElement = event.target.closest(buttonSelector);
|
|
1516
|
+
if (tableButtonElement) {
|
|
1517
|
+
const button = Object.values(tableButtons).find((btn) => tableButtonElement.hasAttribute(btn.attr));
|
|
1518
|
+
if (!button) {
|
|
1355
1519
|
return;
|
|
1356
1520
|
}
|
|
1357
|
-
|
|
1358
|
-
const
|
|
1359
|
-
switch (
|
|
1360
|
-
case
|
|
1361
|
-
|
|
1521
|
+
modals.setTrigger(tableButtonElement);
|
|
1522
|
+
const data = button.getData(tableButtonElement);
|
|
1523
|
+
switch (data.type) {
|
|
1524
|
+
case "rowMenu": {
|
|
1525
|
+
modals.showRowMenu(data.rowIndex);
|
|
1362
1526
|
break;
|
|
1363
1527
|
}
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
type: props.type,
|
|
1367
|
-
format: props.format,
|
|
1368
|
-
value
|
|
1369
|
-
}));
|
|
1528
|
+
case "columnSettings": {
|
|
1529
|
+
modals.showColumnMenu(data.fieldId);
|
|
1370
1530
|
break;
|
|
1371
1531
|
}
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
// Interactions
|
|
1376
|
-
//
|
|
1377
|
-
this.handleGridClick = (event) => {
|
|
1378
|
-
if (!this._modalController.handleClick(event)) {
|
|
1379
|
-
const target = event.target;
|
|
1380
|
-
const selectionCheckbox = target.closest(`input[${tableControls.checkbox.attributes.checkbox}]`);
|
|
1381
|
-
if (selectionCheckbox) {
|
|
1382
|
-
const isHeader = selectionCheckbox.hasAttribute(tableControls.checkbox.attributes.header);
|
|
1383
|
-
if (isHeader) {
|
|
1384
|
-
if (this._selection.allRowsSeleted.value) {
|
|
1385
|
-
this._selection.setSelection("none");
|
|
1386
|
-
} else {
|
|
1387
|
-
this._selection.setSelection("all");
|
|
1388
|
-
}
|
|
1389
|
-
} else {
|
|
1390
|
-
const rowIndex = Number(selectionCheckbox.getAttribute(tableControls.checkbox.attributes.checkbox));
|
|
1391
|
-
this._selection.toggleSelectionForRowIndex(rowIndex);
|
|
1392
|
-
}
|
|
1393
|
-
}
|
|
1394
|
-
}
|
|
1395
|
-
};
|
|
1396
|
-
this._table = table;
|
|
1397
|
-
this._projection = projection;
|
|
1398
|
-
this._sorting.value = sorting.at(0);
|
|
1399
|
-
this._pinnedRows = pinnedRows;
|
|
1400
|
-
this._onInsertRow = onInsertRow;
|
|
1401
|
-
this._onDeleteRows = onDeleteRows;
|
|
1402
|
-
this._onDeleteColumn = onDeleteColumn;
|
|
1403
|
-
this._onCellUpdate = onCellUpdate;
|
|
1404
|
-
this._onRowOrderChanged = onRowOrderChanged;
|
|
1405
|
-
}
|
|
1406
|
-
get table() {
|
|
1407
|
-
return this._table;
|
|
1408
|
-
}
|
|
1409
|
-
get projection() {
|
|
1410
|
-
return this._projection;
|
|
1411
|
-
}
|
|
1412
|
-
get pinnedRows() {
|
|
1413
|
-
return this._pinnedRows;
|
|
1414
|
-
}
|
|
1415
|
-
get columnMeta() {
|
|
1416
|
-
invariant3(this._columnMeta, void 0, {
|
|
1417
|
-
F: __dxlog_file5,
|
|
1418
|
-
L: 126,
|
|
1419
|
-
S: this,
|
|
1420
|
-
A: [
|
|
1421
|
-
"this._columnMeta",
|
|
1422
|
-
""
|
|
1423
|
-
]
|
|
1424
|
-
});
|
|
1425
|
-
return this._columnMeta;
|
|
1426
|
-
}
|
|
1427
|
-
get sorting() {
|
|
1428
|
-
return this._sorting.value;
|
|
1429
|
-
}
|
|
1430
|
-
get modalController() {
|
|
1431
|
-
return this._modalController;
|
|
1432
|
-
}
|
|
1433
|
-
get selection() {
|
|
1434
|
-
return this._selection;
|
|
1435
|
-
}
|
|
1436
|
-
//
|
|
1437
|
-
// Initialisation
|
|
1438
|
-
//
|
|
1439
|
-
async _open() {
|
|
1440
|
-
this.initializeColumnMeta();
|
|
1441
|
-
this.initializeSorting();
|
|
1442
|
-
this.initializeEffects();
|
|
1443
|
-
this._selection = new SelectionModel(this._sortedRows, () => this._onRowOrderChanged?.());
|
|
1444
|
-
await this._selection.open(this._ctx);
|
|
1445
|
-
}
|
|
1446
|
-
initializeColumnMeta() {
|
|
1447
|
-
this._columnMeta = computed2(() => {
|
|
1448
|
-
const fields = this._table.view?.fields ?? [];
|
|
1449
|
-
const meta = Object.fromEntries(fields.map((field, index) => [
|
|
1450
|
-
index,
|
|
1451
|
-
{
|
|
1452
|
-
size: field?.size ?? 256,
|
|
1453
|
-
resizeable: true
|
|
1532
|
+
case "newColumn": {
|
|
1533
|
+
modals.showColumnCreator();
|
|
1534
|
+
break;
|
|
1454
1535
|
}
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
frozenColsStart: {
|
|
1459
|
-
0: {
|
|
1460
|
-
size: 30,
|
|
1461
|
-
resizeable: false
|
|
1462
|
-
}
|
|
1463
|
-
},
|
|
1464
|
-
frozenColsEnd: {
|
|
1465
|
-
0: {
|
|
1466
|
-
size: 40,
|
|
1467
|
-
resizeable: false
|
|
1468
|
-
}
|
|
1536
|
+
case "referencedCell": {
|
|
1537
|
+
modals.showReferencePanel(data.targetId, data.schemaId);
|
|
1538
|
+
break;
|
|
1469
1539
|
}
|
|
1470
|
-
};
|
|
1471
|
-
});
|
|
1472
|
-
}
|
|
1473
|
-
initializeSorting() {
|
|
1474
|
-
this._sortedRows = computed2(() => {
|
|
1475
|
-
this._displayToDataIndex.clear();
|
|
1476
|
-
const sort = this._sorting.value;
|
|
1477
|
-
if (!sort) {
|
|
1478
|
-
return this._rows.value;
|
|
1479
1540
|
}
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
index,
|
|
1489
|
-
value,
|
|
1490
|
-
isEmpty: value == null || value === ""
|
|
1491
|
-
};
|
|
1492
|
-
});
|
|
1493
|
-
const sorted = orderBy(dataWithIndices, [
|
|
1494
|
-
"isEmpty",
|
|
1495
|
-
"value"
|
|
1496
|
-
], [
|
|
1497
|
-
"asc",
|
|
1498
|
-
sort.direction
|
|
1499
|
-
]);
|
|
1500
|
-
for (let displayIndex = 0; displayIndex < sorted.length; displayIndex++) {
|
|
1501
|
-
const { index: dataIndex } = sorted[displayIndex];
|
|
1502
|
-
if (displayIndex !== dataIndex) {
|
|
1503
|
-
this._displayToDataIndex.set(displayIndex, dataIndex);
|
|
1504
|
-
}
|
|
1541
|
+
return;
|
|
1542
|
+
}
|
|
1543
|
+
const controlSelector = Object.values(tableControls).map((control) => `input[${control.attr}]`).join(",");
|
|
1544
|
+
const controlElement = event.target.closest(controlSelector);
|
|
1545
|
+
if (controlElement) {
|
|
1546
|
+
const control = Object.values(tableControls).find((ctrl) => controlElement.hasAttribute(ctrl.attr));
|
|
1547
|
+
if (!control) {
|
|
1548
|
+
return;
|
|
1505
1549
|
}
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
plane: "grid"
|
|
1526
|
-
});
|
|
1527
|
-
}));
|
|
1550
|
+
const data = control.getData(controlElement);
|
|
1551
|
+
switch (data.type) {
|
|
1552
|
+
case "checkbox": {
|
|
1553
|
+
if (data.header) {
|
|
1554
|
+
model?.selection.setSelection(model.selection.allRowsSeleted.value ? "none" : "all");
|
|
1555
|
+
} else {
|
|
1556
|
+
model?.selection.toggleSelectionForRowIndex(data.rowIndex);
|
|
1557
|
+
}
|
|
1558
|
+
break;
|
|
1559
|
+
}
|
|
1560
|
+
case "switch": {
|
|
1561
|
+
if (model) {
|
|
1562
|
+
model.updateCellData({
|
|
1563
|
+
row: data.rowIndex,
|
|
1564
|
+
col: data.colIndex
|
|
1565
|
+
}, (value) => !value);
|
|
1566
|
+
}
|
|
1567
|
+
break;
|
|
1568
|
+
}
|
|
1528
1569
|
}
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1570
|
+
}
|
|
1571
|
+
}, [
|
|
1572
|
+
model,
|
|
1573
|
+
modals
|
|
1574
|
+
]);
|
|
1575
|
+
const handleFocus = useCallback4((increment, delta) => {
|
|
1576
|
+
if (dxGrid) {
|
|
1577
|
+
dxGrid.refocus(increment, delta);
|
|
1578
|
+
}
|
|
1579
|
+
}, [
|
|
1580
|
+
dxGrid
|
|
1581
|
+
]);
|
|
1582
|
+
const handleEnter = useCallback4((cell) => {
|
|
1583
|
+
if (model && cell.row === model.getRowCount() - 1) {
|
|
1584
|
+
model.insertRow(cell.row);
|
|
1585
|
+
if (dxGrid) {
|
|
1586
|
+
requestAnimationFrame(() => {
|
|
1587
|
+
dxGrid?.scrollToRow(cell.row + 1);
|
|
1588
|
+
dxGrid?.refocus("row", 1);
|
|
1589
|
+
});
|
|
1590
|
+
}
|
|
1591
|
+
}
|
|
1592
|
+
}, [
|
|
1593
|
+
model,
|
|
1594
|
+
dxGrid
|
|
1595
|
+
]);
|
|
1596
|
+
const handleKeyDown = useCallback4((event) => {
|
|
1597
|
+
const cell = closestCell(event.target);
|
|
1598
|
+
if (!model || !cell) {
|
|
1538
1599
|
return;
|
|
1539
1600
|
}
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1601
|
+
switch (event.key) {
|
|
1602
|
+
case "Backspace":
|
|
1603
|
+
case "Delete": {
|
|
1604
|
+
model.setCellData(cell, void 0);
|
|
1605
|
+
break;
|
|
1544
1606
|
}
|
|
1545
|
-
this._onDeleteColumn(field.id);
|
|
1546
1607
|
}
|
|
1547
|
-
}
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1608
|
+
}, [
|
|
1609
|
+
model
|
|
1610
|
+
]);
|
|
1611
|
+
const handleAxisResize = useCallback4((event) => {
|
|
1612
|
+
if (event.axis === "col") {
|
|
1613
|
+
const columnIndex = parseInt(event.index, 10);
|
|
1614
|
+
model?.setColumnWidth(columnIndex, event.size);
|
|
1615
|
+
}
|
|
1616
|
+
}, [
|
|
1617
|
+
model
|
|
1618
|
+
]);
|
|
1619
|
+
const handleWheel = useCallback4((event) => {
|
|
1620
|
+
if (!ignoreAttention && !hasAttention) {
|
|
1621
|
+
event.stopPropagation();
|
|
1622
|
+
}
|
|
1623
|
+
}, [
|
|
1624
|
+
hasAttention,
|
|
1625
|
+
ignoreAttention
|
|
1626
|
+
]);
|
|
1627
|
+
const handleNewColumn = useCallback4(() => {
|
|
1628
|
+
const columns = model?.getColumnCount();
|
|
1629
|
+
if (dxGrid && columns) {
|
|
1630
|
+
dxGrid.scrollToColumn(columns - 1);
|
|
1631
|
+
}
|
|
1632
|
+
}, [
|
|
1633
|
+
model,
|
|
1634
|
+
dxGrid
|
|
1635
|
+
]);
|
|
1636
|
+
const handleQuery = useCallback4(async ({ field, props }, text) => {
|
|
1637
|
+
if (model && props.referenceSchema && field.referencePath) {
|
|
1638
|
+
const space = getSpace4(model.table);
|
|
1639
|
+
invariant3(space, void 0, {
|
|
1640
|
+
F: __dxlog_file5,
|
|
1641
|
+
L: 260,
|
|
1642
|
+
S: void 0,
|
|
1643
|
+
A: [
|
|
1644
|
+
"space",
|
|
1645
|
+
""
|
|
1646
|
+
]
|
|
1647
|
+
});
|
|
1648
|
+
const schema = space.db.schemaRegistry.getSchema(props.referenceSchema);
|
|
1649
|
+
if (schema) {
|
|
1650
|
+
const { objects } = await space.db.query(Filter.schema(schema)).run();
|
|
1651
|
+
const options = objects.map((obj) => {
|
|
1652
|
+
const value = getValue4(obj, field.referencePath);
|
|
1653
|
+
if (!value || typeof value !== "string") {
|
|
1654
|
+
return void 0;
|
|
1655
|
+
}
|
|
1656
|
+
return {
|
|
1657
|
+
label: value,
|
|
1658
|
+
data: obj
|
|
1659
|
+
};
|
|
1660
|
+
}).filter(isNotFalsy);
|
|
1661
|
+
return [
|
|
1662
|
+
...options,
|
|
1663
|
+
{
|
|
1664
|
+
label: t("create new object label", {
|
|
1665
|
+
text
|
|
1666
|
+
}),
|
|
1667
|
+
data: createOption(text)
|
|
1668
|
+
}
|
|
1669
|
+
];
|
|
1558
1670
|
}
|
|
1559
1671
|
}
|
|
1672
|
+
return [];
|
|
1673
|
+
}, [
|
|
1674
|
+
model
|
|
1675
|
+
]);
|
|
1676
|
+
if (!model || !modals) {
|
|
1677
|
+
return /* @__PURE__ */ React7.createElement("span", {
|
|
1678
|
+
role: "none",
|
|
1679
|
+
className: "attention-surface"
|
|
1680
|
+
});
|
|
1560
1681
|
}
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
}
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1682
|
+
return /* @__PURE__ */ React7.createElement(Grid.Root, {
|
|
1683
|
+
id: model.table.id ?? "table-grid"
|
|
1684
|
+
}, /* @__PURE__ */ React7.createElement(TableCellEditor, {
|
|
1685
|
+
model,
|
|
1686
|
+
modals,
|
|
1687
|
+
onEnter: handleEnter,
|
|
1688
|
+
onFocus: handleFocus,
|
|
1689
|
+
onQuery: handleQuery
|
|
1690
|
+
}), /* @__PURE__ */ React7.createElement(Grid.Content, {
|
|
1691
|
+
onWheelCapture: handleWheel,
|
|
1692
|
+
className: mx2("[--dx-grid-base:var(--surface-bg)]", inlineEndLine, blockEndLine),
|
|
1693
|
+
frozen,
|
|
1694
|
+
columns: model.columnMeta.value,
|
|
1695
|
+
limitRows: model.getRowCount() ?? 0,
|
|
1696
|
+
limitColumns: model.table.view?.target?.fields?.length ?? 0,
|
|
1697
|
+
onAxisResize: handleAxisResize,
|
|
1698
|
+
onClick: handleGridClick,
|
|
1699
|
+
onKeyDown: handleKeyDown,
|
|
1700
|
+
overscroll: "trap",
|
|
1701
|
+
ref: setDxGrid
|
|
1702
|
+
}), /* @__PURE__ */ React7.createElement(RowActionsMenu, {
|
|
1703
|
+
model,
|
|
1704
|
+
modals
|
|
1705
|
+
}), /* @__PURE__ */ React7.createElement(ColumnActionsMenu, {
|
|
1706
|
+
model,
|
|
1707
|
+
modals
|
|
1708
|
+
}), /* @__PURE__ */ React7.createElement(ColumnSettings, {
|
|
1709
|
+
model,
|
|
1710
|
+
modals,
|
|
1711
|
+
onNewColumn: handleNewColumn
|
|
1712
|
+
}), /* @__PURE__ */ React7.createElement(RefPanel, {
|
|
1713
|
+
model,
|
|
1714
|
+
modals
|
|
1715
|
+
}), /* @__PURE__ */ React7.createElement(CreateRefPanel, {
|
|
1716
|
+
model,
|
|
1717
|
+
modals
|
|
1718
|
+
}));
|
|
1719
|
+
});
|
|
1720
|
+
var Table = {
|
|
1721
|
+
Root: TableRoot,
|
|
1722
|
+
Main: TableMain
|
|
1723
|
+
};
|
|
1724
|
+
|
|
1725
|
+
// packages/ui/react-ui-table/src/components/Toolbar/Toolbar.tsx
|
|
1726
|
+
import { createContext } from "@radix-ui/react-context";
|
|
1727
|
+
import React9 from "react";
|
|
1728
|
+
import { Toolbar as NaturalToolbar2, useTranslation as useTranslation4 } from "@dxos/react-ui";
|
|
1729
|
+
|
|
1730
|
+
// packages/ui/react-ui-table/src/components/Toolbar/common.tsx
|
|
1731
|
+
import React8 from "react";
|
|
1732
|
+
import { Icon, Toolbar as NaturalToolbar, Tooltip } from "@dxos/react-ui";
|
|
1733
|
+
var buttonStyles = "min-bs-0 p-2";
|
|
1734
|
+
var tooltipProps = {
|
|
1735
|
+
side: "top",
|
|
1736
|
+
classNames: "z-10"
|
|
1737
|
+
};
|
|
1738
|
+
var ToolbarSeparator = () => /* @__PURE__ */ React8.createElement("div", {
|
|
1739
|
+
role: "separator",
|
|
1740
|
+
className: "grow"
|
|
1741
|
+
});
|
|
1742
|
+
var ToolbarButton = ({ icon, children, ...props }) => {
|
|
1743
|
+
return /* @__PURE__ */ React8.createElement(Tooltip.Root, null, /* @__PURE__ */ React8.createElement(Tooltip.Trigger, {
|
|
1744
|
+
asChild: true
|
|
1745
|
+
}, /* @__PURE__ */ React8.createElement(NaturalToolbar.Button, {
|
|
1746
|
+
variant: "ghost",
|
|
1747
|
+
...props,
|
|
1748
|
+
classNames: buttonStyles
|
|
1749
|
+
}, /* @__PURE__ */ React8.createElement(Icon, {
|
|
1750
|
+
icon,
|
|
1751
|
+
size: 5
|
|
1752
|
+
}), /* @__PURE__ */ React8.createElement("span", {
|
|
1753
|
+
className: "sr-only"
|
|
1754
|
+
}, children))), /* @__PURE__ */ React8.createElement(Tooltip.Portal, null, /* @__PURE__ */ React8.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React8.createElement(Tooltip.Arrow, null))));
|
|
1755
|
+
};
|
|
1756
|
+
|
|
1757
|
+
// packages/ui/react-ui-table/src/components/Toolbar/Toolbar.tsx
|
|
1758
|
+
var [ToolbarContextProvider, useToolbarContext] = createContext("Toolbar");
|
|
1759
|
+
var ToolbarRoot = ({ classNames, children, onAction }) => {
|
|
1760
|
+
return /* @__PURE__ */ React9.createElement(ToolbarContextProvider, {
|
|
1761
|
+
onAction
|
|
1762
|
+
}, /* @__PURE__ */ React9.createElement(NaturalToolbar2.Root, {
|
|
1763
|
+
classNames: [
|
|
1764
|
+
"is-full shrink-0 overflow-x-auto overflow-y-hidden p-1 attention-surface",
|
|
1765
|
+
classNames
|
|
1766
|
+
]
|
|
1767
|
+
}, children));
|
|
1768
|
+
};
|
|
1769
|
+
var Editing = () => {
|
|
1770
|
+
const { onAction } = useToolbarContext("Editing");
|
|
1771
|
+
const { t } = useTranslation4(translationKey);
|
|
1772
|
+
return /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement(ToolbarButton, {
|
|
1773
|
+
value: "add-row",
|
|
1774
|
+
icon: "ph--plus--regular",
|
|
1775
|
+
"data-testid": "table.toolbar.add-row",
|
|
1776
|
+
onClick: () => onAction?.({
|
|
1777
|
+
type: "add-row"
|
|
1778
|
+
})
|
|
1779
|
+
}, t("add row")));
|
|
1780
|
+
};
|
|
1781
|
+
var Actions = () => {
|
|
1782
|
+
const { onAction } = useToolbarContext("Actions");
|
|
1783
|
+
const { t } = useTranslation4(translationKey);
|
|
1784
|
+
return /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement(ToolbarButton, {
|
|
1785
|
+
value: "comment",
|
|
1786
|
+
icon: "ph--chat-text--regular",
|
|
1787
|
+
"data-testid": "table.toolbar.comment",
|
|
1788
|
+
onClick: () => onAction?.({
|
|
1789
|
+
type: "comment"
|
|
1790
|
+
})
|
|
1791
|
+
}, t("create comment")));
|
|
1792
|
+
};
|
|
1793
|
+
var Toolbar = {
|
|
1794
|
+
Root: ToolbarRoot,
|
|
1795
|
+
Editing,
|
|
1796
|
+
Actions,
|
|
1797
|
+
Separator: ToolbarSeparator
|
|
1584
1798
|
};
|
|
1585
1799
|
|
|
1586
1800
|
// packages/ui/react-ui-table/src/hooks/useTableModel.ts
|
|
1801
|
+
import { useEffect as useEffect2, useState as useState3 } from "react";
|
|
1587
1802
|
var useTableModel = ({ objects, table, projection, ...props }) => {
|
|
1588
1803
|
const [model, setModel] = useState3();
|
|
1589
1804
|
useEffect2(() => {
|
|
@@ -1619,12 +1834,20 @@ var useTableModel = ({ objects, table, projection, ...props }) => {
|
|
|
1619
1834
|
return model;
|
|
1620
1835
|
};
|
|
1621
1836
|
export {
|
|
1837
|
+
BUTTON_IDENTIFIERS,
|
|
1838
|
+
CONTROL_IDENTIFIERS,
|
|
1839
|
+
ModalController,
|
|
1622
1840
|
Table,
|
|
1841
|
+
TableModel,
|
|
1842
|
+
TablePresentation,
|
|
1623
1843
|
TableSchema,
|
|
1624
1844
|
TableType,
|
|
1625
1845
|
Toolbar,
|
|
1626
1846
|
initializeTable,
|
|
1847
|
+
renderCheckbox,
|
|
1848
|
+
renderSwitch,
|
|
1627
1849
|
tableButtons,
|
|
1850
|
+
tableControls,
|
|
1628
1851
|
touch,
|
|
1629
1852
|
translations_default as translations,
|
|
1630
1853
|
useTableModel,
|