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