@dxos/react-ui-table 0.8.4-main.2e9d522 → 0.8.4-main.3c1ae3b
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-CJQ6T4LL.mjs +77 -0
- package/dist/lib/browser/chunk-CJQ6T4LL.mjs.map +7 -0
- package/dist/lib/browser/{chunk-5XLSHLOG.mjs → chunk-V7A7ZA5E.mjs} +576 -544
- package/dist/lib/browser/chunk-V7A7ZA5E.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +694 -760
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +16 -27
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/browser/types/index.mjs +3 -3
- package/dist/lib/node-esm/{chunk-Y66YLSTC.mjs → chunk-P73ALX3N.mjs} +576 -544
- package/dist/lib/node-esm/chunk-P73ALX3N.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-T6PXZQ6W.mjs +78 -0
- package/dist/lib/node-esm/chunk-T6PXZQ6W.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +694 -760
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +16 -27
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/types/index.mjs +3 -3
- package/dist/types/src/components/Table/ColumnActionsMenu.d.ts +2 -3
- package/dist/types/src/components/Table/ColumnActionsMenu.d.ts.map +1 -1
- package/dist/types/src/components/Table/ColumnSettings.d.ts +3 -3
- package/dist/types/src/components/Table/ColumnSettings.d.ts.map +1 -1
- package/dist/types/src/components/Table/DynamicTable.d.ts +5 -6
- package/dist/types/src/components/Table/DynamicTable.d.ts.map +1 -1
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts +37 -3
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/Relations.stories.d.ts +111 -0
- package/dist/types/src/components/Table/Relations.stories.d.ts.map +1 -0
- package/dist/types/src/components/Table/RowActionsMenu.d.ts +1 -1
- package/dist/types/src/components/Table/RowActionsMenu.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.d.ts +13 -9
- package/dist/types/src/components/Table/Table.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.stories.d.ts +108 -4
- package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/CellValidationMessage.d.ts +1 -1
- package/dist/types/src/components/TableCellEditor/CellValidationMessage.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts +14 -9
- package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +11 -18
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts +39 -4
- package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/index.d.ts +1 -0
- package/dist/types/src/components/TableCellEditor/index.d.ts.map +1 -1
- package/dist/types/src/components/TableToolbar/TableToolbar.d.ts +2 -2
- package/dist/types/src/components/TableToolbar/TableToolbar.d.ts.map +1 -1
- package/dist/types/src/components/testing.d.ts +3 -5
- package/dist/types/src/components/testing.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +2 -1
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useAddRow.d.ts +3 -2
- package/dist/types/src/hooks/useAddRow.d.ts.map +1 -1
- package/dist/types/src/hooks/useProjectionModel.d.ts +5 -0
- package/dist/types/src/hooks/useProjectionModel.d.ts.map +1 -0
- package/dist/types/src/hooks/useTableModel.d.ts +5 -6
- package/dist/types/src/hooks/useTableModel.d.ts.map +1 -1
- package/dist/types/src/model/modal-controller.d.ts +0 -7
- package/dist/types/src/model/modal-controller.d.ts.map +1 -1
- package/dist/types/src/model/selection-model.d.ts.map +1 -1
- package/dist/types/src/model/table-model.d.ts +14 -14
- package/dist/types/src/model/table-model.d.ts.map +1 -1
- package/dist/types/src/model/table-presentation.d.ts +2 -1
- package/dist/types/src/model/table-presentation.d.ts.map +1 -1
- package/dist/types/src/model/table-sorting.d.ts +9 -6
- package/dist/types/src/model/table-sorting.d.ts.map +1 -1
- package/dist/types/src/playwright/TableManager.d.ts +1 -1
- package/dist/types/src/playwright/TableManager.d.ts.map +1 -1
- package/dist/types/src/testing/useTestTableModel.d.ts +19 -34
- package/dist/types/src/testing/useTestTableModel.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +2 -2
- package/dist/types/src/types/Table.d.ts +28 -0
- package/dist/types/src/types/Table.d.ts.map +1 -0
- package/dist/types/src/types/index.d.ts +1 -1
- package/dist/types/src/types/index.d.ts.map +1 -1
- package/dist/types/src/util/dynamic-table.d.ts +10 -11
- package/dist/types/src/util/dynamic-table.d.ts.map +1 -1
- package/dist/types/src/util/index.d.ts +0 -1
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/src/util/schema.d.ts +1 -1
- package/dist/types/src/util/schema.d.ts.map +1 -1
- package/dist/types/src/util/table-buttons.d.ts.map +1 -1
- package/dist/types/src/util/table-controls.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +57 -51
- package/src/components/Table/ColumnActionsMenu.tsx +5 -2
- package/src/components/Table/ColumnSettings.tsx +3 -4
- package/src/components/Table/DynamicTable.stories.tsx +21 -19
- package/src/components/Table/DynamicTable.tsx +24 -18
- package/src/components/Table/Relations.stories.tsx +233 -0
- package/src/components/Table/RowActionsMenu.tsx +23 -15
- package/src/components/Table/Table.stories.tsx +104 -99
- package/src/components/Table/Table.tsx +338 -295
- package/src/components/TableCellEditor/CellValidationMessage.tsx +2 -2
- package/src/components/TableCellEditor/FormCellEditor.tsx +143 -39
- package/src/components/TableCellEditor/TableCellEditor.stories.tsx +30 -66
- package/src/components/TableCellEditor/TableCellEditor.tsx +86 -236
- package/src/components/TableCellEditor/index.ts +1 -0
- package/src/components/TableToolbar/TableToolbar.tsx +34 -24
- package/src/components/testing.ts +4 -4
- package/src/hooks/index.ts +2 -1
- package/src/hooks/useAddRow.ts +7 -5
- package/src/hooks/useProjectionModel.ts +19 -0
- package/src/hooks/useTableModel.ts +13 -15
- package/src/model/modal-controller.ts +1 -29
- package/src/model/selection-model.ts +3 -2
- package/src/model/table-model.test.ts +21 -12
- package/src/model/table-model.ts +64 -58
- package/src/model/table-presentation.test.ts +25 -23
- package/src/model/table-presentation.ts +82 -41
- package/src/model/table-sorting.ts +32 -14
- package/src/playwright/TableManager.ts +5 -5
- package/src/playwright/smoke.spec.ts +132 -38
- package/src/testing/useTestTableModel.ts +32 -24
- package/src/translations.ts +2 -2
- package/src/types/Table.ts +90 -0
- package/src/types/index.ts +1 -1
- package/src/util/dynamic-table.ts +21 -27
- package/src/util/index.ts +0 -1
- package/src/util/schema.ts +4 -4
- package/src/util/table-buttons.ts +4 -3
- package/src/util/table-controls.ts +4 -1
- package/dist/lib/browser/chunk-5XLSHLOG.mjs.map +0 -7
- package/dist/lib/browser/chunk-L2LSB6KV.mjs +0 -18
- package/dist/lib/browser/chunk-L2LSB6KV.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-NXZ4CJYX.mjs +0 -20
- package/dist/lib/node-esm/chunk-NXZ4CJYX.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-Y66YLSTC.mjs.map +0 -7
- package/dist/types/src/components/Table/CreateRefPanel.d.ts +0 -9
- package/dist/types/src/components/Table/CreateRefPanel.d.ts.map +0 -1
- package/dist/types/src/components/Table/relations.stories.d.ts +0 -9
- package/dist/types/src/components/Table/relations.stories.d.ts.map +0 -1
- package/dist/types/src/components/TableCellEditor/extension.d.ts +0 -13
- package/dist/types/src/components/TableCellEditor/extension.d.ts.map +0 -1
- package/dist/types/src/types/schema.d.ts +0 -8
- package/dist/types/src/types/schema.d.ts.map +0 -1
- package/dist/types/src/util/table.d.ts +0 -11
- package/dist/types/src/util/table.d.ts.map +0 -1
- package/src/components/Table/CreateRefPanel.tsx +0 -86
- package/src/components/Table/relations.stories.tsx +0 -116
- package/src/components/TableCellEditor/extension.ts +0 -61
- package/src/types/schema.ts +0 -16
- package/src/util/table.ts +0 -49
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
} from "./chunk-
|
|
3
|
+
Table_exports
|
|
4
|
+
} from "./chunk-T6PXZQ6W.mjs";
|
|
5
5
|
|
|
6
6
|
// src/util/dynamic-table.ts
|
|
7
|
-
import { Obj } from "@dxos/echo";
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
var getBaseSchema = ({ typename, properties, jsonSchema, schema }) => {
|
|
7
|
+
import { Filter, Obj, Query, Ref, Type } from "@dxos/echo";
|
|
8
|
+
import { ProjectionModel, View, getSchemaFromPropertyDefinitions } from "@dxos/schema";
|
|
9
|
+
var getBaseSchema = ({ schema, typename, properties, jsonSchema }) => {
|
|
11
10
|
if (typename && properties) {
|
|
12
11
|
const schema2 = getSchemaFromPropertyDefinitions(typename, properties);
|
|
13
12
|
return {
|
|
@@ -16,8 +15,8 @@ var getBaseSchema = ({ typename, properties, jsonSchema, schema }) => {
|
|
|
16
15
|
};
|
|
17
16
|
} else if (schema) {
|
|
18
17
|
return {
|
|
19
|
-
typename: getTypename(schema),
|
|
20
|
-
jsonSchema: toJsonSchema(schema)
|
|
18
|
+
typename: Type.getTypename(schema),
|
|
19
|
+
jsonSchema: Type.toJsonSchema(schema)
|
|
21
20
|
};
|
|
22
21
|
} else if (typename && jsonSchema) {
|
|
23
22
|
return {
|
|
@@ -28,25 +27,26 @@ var getBaseSchema = ({ typename, properties, jsonSchema, schema }) => {
|
|
|
28
27
|
throw new Error("invalid properties");
|
|
29
28
|
}
|
|
30
29
|
};
|
|
31
|
-
var makeDynamicTable = ({
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
});
|
|
35
|
-
const view = createView({
|
|
36
|
-
typename,
|
|
30
|
+
var makeDynamicTable = ({ jsonSchema, properties }) => {
|
|
31
|
+
const view = View.make({
|
|
32
|
+
query: Query.select(Filter.everything()),
|
|
37
33
|
jsonSchema,
|
|
38
|
-
presentation: table,
|
|
39
34
|
...properties && {
|
|
40
35
|
fields: properties.map((property) => property.name)
|
|
41
36
|
}
|
|
42
37
|
});
|
|
38
|
+
const object = Obj.make(Table_exports.Table, {
|
|
39
|
+
view: Ref.make(view),
|
|
40
|
+
sizes: {}
|
|
41
|
+
});
|
|
43
42
|
const projection = new ProjectionModel(jsonSchema, view.projection);
|
|
43
|
+
projection.normalizeView();
|
|
44
44
|
if (properties && projection.fields) {
|
|
45
|
-
setProperties(view, projection,
|
|
45
|
+
setProperties(view, projection, object, properties);
|
|
46
46
|
}
|
|
47
47
|
return {
|
|
48
48
|
projection,
|
|
49
|
-
|
|
49
|
+
object
|
|
50
50
|
};
|
|
51
51
|
};
|
|
52
52
|
var setProperties = (view, projection, table, properties) => {
|
|
@@ -68,7 +68,7 @@ var setProperties = (view, projection, table, properties) => {
|
|
|
68
68
|
}
|
|
69
69
|
if (property.sort) {
|
|
70
70
|
const fieldId = field.id;
|
|
71
|
-
view.
|
|
71
|
+
view.sort = [
|
|
72
72
|
{
|
|
73
73
|
fieldId,
|
|
74
74
|
direction: property.sort
|
|
@@ -82,40 +82,6 @@ var setProperties = (view, projection, table, properties) => {
|
|
|
82
82
|
// src/util/signals.ts
|
|
83
83
|
var touch = (value) => value;
|
|
84
84
|
|
|
85
|
-
// src/util/table.ts
|
|
86
|
-
import { Match } from "effect";
|
|
87
|
-
import { Obj as Obj2 } from "@dxos/echo";
|
|
88
|
-
import { toEffectSchema } from "@dxos/echo-schema";
|
|
89
|
-
import { createViewFromSpace, getSchemaProperties } from "@dxos/schema";
|
|
90
|
-
var createTable = async ({ sizes, ...props }) => {
|
|
91
|
-
const table = Obj2.make(TableView, {
|
|
92
|
-
sizes: {}
|
|
93
|
-
});
|
|
94
|
-
const { jsonSchema, view } = await createViewFromSpace({
|
|
95
|
-
...props,
|
|
96
|
-
presentation: table
|
|
97
|
-
});
|
|
98
|
-
const schema = toEffectSchema(jsonSchema);
|
|
99
|
-
const shouldIncludeId = props.fields?.find((field) => field === "id") !== void 0;
|
|
100
|
-
const properties = getSchemaProperties(schema.ast, {}, shouldIncludeId);
|
|
101
|
-
for (const property of properties) {
|
|
102
|
-
if (sizes?.[property.name]) {
|
|
103
|
-
table.sizes[property.name] = sizes[property.name];
|
|
104
|
-
continue;
|
|
105
|
-
}
|
|
106
|
-
Match.type().pipe(Match.when("boolean", () => {
|
|
107
|
-
table.sizes[property.name] = 100;
|
|
108
|
-
}), Match.when("number", () => {
|
|
109
|
-
table.sizes[property.name] = 100;
|
|
110
|
-
}), Match.orElse(() => {
|
|
111
|
-
}))(property.type);
|
|
112
|
-
}
|
|
113
|
-
return {
|
|
114
|
-
jsonSchema,
|
|
115
|
-
view
|
|
116
|
-
};
|
|
117
|
-
};
|
|
118
|
-
|
|
119
85
|
// src/util/table-buttons.ts
|
|
120
86
|
var BUTTON_IDENTIFIERS = {
|
|
121
87
|
columnSettings: "data-table-column-settings-button",
|
|
@@ -125,10 +91,9 @@ var BUTTON_IDENTIFIERS = {
|
|
|
125
91
|
saveDraftRow: "data-table-save-draft-row-button",
|
|
126
92
|
sort: "data-table-sort-button"
|
|
127
93
|
};
|
|
128
|
-
var createButton = ({ attr, data, disabled = false, icon, testId, type = "primary" }) => {
|
|
94
|
+
var createButton = ({ attr, data, disabled = false, icon, testId, type: _type = "primary" }) => {
|
|
129
95
|
const dataAttrs = Object.entries(data).map(([k, v]) => `${k}="${v}"`).join(" ");
|
|
130
|
-
|
|
131
|
-
return `<button ${attr} data-testid="${testId}" class="dx-button is-6 pli-0.5 min-bs-0 absolute inset-block-1 ${positionClass}" ${dataAttrs} ${disabled ? "disabled" : ""}><svg data-size="4"><use href="/icons.svg#${icon}"/></svg></button>`;
|
|
96
|
+
return `<button ${attr} data-testid="${testId}" class="dx-button is-6 aspect-square pli-0.5 min-bs-0" ${dataAttrs} ${disabled ? "disabled" : ""} data-dx-grid-action="accessory"><svg data-size="4"><use href="/icons.svg#${icon}"/></svg></button>`;
|
|
132
97
|
};
|
|
133
98
|
var addColumnButton = {
|
|
134
99
|
attr: BUTTON_IDENTIFIERS.newColumn,
|
|
@@ -154,7 +119,8 @@ var columnSettingsButton = {
|
|
|
154
119
|
attr: BUTTON_IDENTIFIERS.columnSettings,
|
|
155
120
|
icon: columnSettingsButton.icon,
|
|
156
121
|
data: {
|
|
157
|
-
"data-field-id": fieldId
|
|
122
|
+
"data-field-id": fieldId,
|
|
123
|
+
"data-variant": "ghost"
|
|
158
124
|
},
|
|
159
125
|
testId: "table-column-settings-button"
|
|
160
126
|
});
|
|
@@ -214,7 +180,8 @@ var saveDraftRowButton = {
|
|
|
214
180
|
icon: saveDraftRowButton.icon,
|
|
215
181
|
disabled,
|
|
216
182
|
data: {
|
|
217
|
-
"data-row-index": rowIndex.toString()
|
|
183
|
+
"data-row-index": rowIndex.toString(),
|
|
184
|
+
"data-variant": "primary"
|
|
218
185
|
},
|
|
219
186
|
testId: "table-save-draft-row-button"
|
|
220
187
|
});
|
|
@@ -233,6 +200,7 @@ var tableButtons = {
|
|
|
233
200
|
};
|
|
234
201
|
|
|
235
202
|
// src/util/table-controls.ts
|
|
203
|
+
import { accessoryHandlesPointerdownAttrs } from "@dxos/lit-grid";
|
|
236
204
|
var CONTROL_IDENTIFIERS = {
|
|
237
205
|
checkbox: "data-table-checkbox",
|
|
238
206
|
switch: "data-table-switch"
|
|
@@ -245,7 +213,7 @@ var renderAttributes = (data) => {
|
|
|
245
213
|
return Object.entries(data).map(([k, v]) => `${k}="${v}"`).join(" ");
|
|
246
214
|
};
|
|
247
215
|
var renderInput = (baseClass, attrs, checked = false, disabled = false, preventToggle = false, testId) => {
|
|
248
|
-
return `<input type="checkbox" class="${baseClass}" ${renderAttributes(attrs)} ${checked ? "checked" : ""} ${preventToggle ? 'onclick="return false"' : ""} ${disabled ? "disabled" : ""} data-testid="${testId}"/>`;
|
|
216
|
+
return `<input type="checkbox" class="${baseClass}" ${renderAttributes(attrs)} ${checked ? "checked" : ""} ${preventToggle ? 'onclick="return false"' : ""} ${disabled ? "disabled" : ""} data-testid="${testId}" data-dx-grid-action="accessory"/>`;
|
|
249
217
|
};
|
|
250
218
|
var CheckboxStory = ({ rowIndex, header = false, checked = false, disabled = false }) => {
|
|
251
219
|
const attrs = {
|
|
@@ -261,7 +229,8 @@ var SwitchStory = ({ colIndex, rowIndex, checked = false, disabled = false }) =>
|
|
|
261
229
|
const attrs = {
|
|
262
230
|
[CONTROL_IDENTIFIERS.switch]: "",
|
|
263
231
|
"data-row-index": rowIndex.toString(),
|
|
264
|
-
"data-col-index": colIndex.toString()
|
|
232
|
+
"data-col-index": colIndex.toString(),
|
|
233
|
+
...accessoryHandlesPointerdownAttrs
|
|
265
234
|
};
|
|
266
235
|
return renderInput(BASE_CLASSES.switch, attrs, checked, disabled, true, "table-switch");
|
|
267
236
|
};
|
|
@@ -287,14 +256,14 @@ var tableControls = {
|
|
|
287
256
|
};
|
|
288
257
|
|
|
289
258
|
// src/util/schema.ts
|
|
290
|
-
import
|
|
291
|
-
import
|
|
259
|
+
import * as Schema from "effect/Schema";
|
|
260
|
+
import * as SchemaAST from "effect/SchemaAST";
|
|
292
261
|
var narrowSchema = (schema, paths) => {
|
|
293
262
|
const ast = schema?.ast;
|
|
294
|
-
if (isTypeLiteral(ast)) {
|
|
263
|
+
if (SchemaAST.isTypeLiteral(ast)) {
|
|
295
264
|
const propertySignatures = ast.propertySignatures.filter((signature) => paths.includes(signature.name.toString()));
|
|
296
265
|
if (propertySignatures.length > 0) {
|
|
297
|
-
const narrowType = new TypeLiteral(propertySignatures, []);
|
|
266
|
+
const narrowType = new SchemaAST.TypeLiteral(propertySignatures, []);
|
|
298
267
|
return Schema.make(narrowType);
|
|
299
268
|
}
|
|
300
269
|
}
|
|
@@ -304,67 +273,59 @@ var narrowSchema = (schema, paths) => {
|
|
|
304
273
|
// src/model/table-model.ts
|
|
305
274
|
import { computed as computed3, effect as effect2, signal as signal3 } from "@preact/signals-core";
|
|
306
275
|
import { Resource as Resource2 } from "@dxos/context";
|
|
307
|
-
import { Obj as
|
|
308
|
-
import {
|
|
276
|
+
import { Format as Format2, Obj as Obj2, Ref as Ref2 } from "@dxos/echo";
|
|
277
|
+
import { getValue as getValue2, setValue, toEffectSchema } from "@dxos/echo/internal";
|
|
309
278
|
import { invariant } from "@dxos/invariant";
|
|
310
279
|
import { ObjectId } from "@dxos/keys";
|
|
311
|
-
import { isLiveObject } from "@dxos/live-object";
|
|
312
|
-
import { fullyQualifiedId } from "@dxos/react-client/echo";
|
|
280
|
+
import { getSnapshot, isLiveObject } from "@dxos/live-object";
|
|
313
281
|
import { formatForEditing, parseValue } from "@dxos/react-ui-form";
|
|
314
|
-
import {
|
|
282
|
+
import { validateSchema } from "@dxos/schema";
|
|
283
|
+
|
|
284
|
+
// src/util/tag.ts
|
|
285
|
+
var TAG_PATTERN_REGEX = /\[([^\]]+)\]\(([^)]+)\)/g;
|
|
286
|
+
var extractTagIds = (value) => {
|
|
287
|
+
if (typeof value !== "string") {
|
|
288
|
+
return void 0;
|
|
289
|
+
}
|
|
290
|
+
const ids = [];
|
|
291
|
+
let match;
|
|
292
|
+
while ((match = TAG_PATTERN_REGEX.exec(value)) !== null) {
|
|
293
|
+
if (match[2]) {
|
|
294
|
+
ids.push(match[2]);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return ids.length > 0 ? ids : void 0;
|
|
298
|
+
};
|
|
315
299
|
|
|
316
300
|
// src/model/selection-model.ts
|
|
317
301
|
import { computed, effect, signal } from "@preact/signals-core";
|
|
318
302
|
import { Resource } from "@dxos/context";
|
|
319
303
|
var SelectionModel = class extends Resource {
|
|
304
|
+
_rows;
|
|
305
|
+
_selectionMode;
|
|
306
|
+
_initialSelection;
|
|
307
|
+
_onSelectionChanged;
|
|
308
|
+
_selection;
|
|
309
|
+
_validSelectedIds = computed(() => {
|
|
310
|
+
const rows = this._rows.value;
|
|
311
|
+
if (!rows) {
|
|
312
|
+
return /* @__PURE__ */ new Set();
|
|
313
|
+
}
|
|
314
|
+
const validIds = new Set(rows.map((row) => row.id));
|
|
315
|
+
return new Set([
|
|
316
|
+
...this._selection.value
|
|
317
|
+
].filter((id) => validIds.has(id)));
|
|
318
|
+
});
|
|
319
|
+
_hasSelection = computed(() => this._validSelectedIds.value.size > 0);
|
|
320
|
+
_allSelected = computed(() => {
|
|
321
|
+
const rows = this._rows.value;
|
|
322
|
+
if (rows.length === 0) {
|
|
323
|
+
return false;
|
|
324
|
+
}
|
|
325
|
+
return rows.every((row) => this._selection.value.has(row.id));
|
|
326
|
+
});
|
|
320
327
|
constructor(_rows, _selectionMode, _initialSelection, _onSelectionChanged) {
|
|
321
|
-
super(), this._rows = _rows, this._selectionMode = _selectionMode, this._initialSelection = _initialSelection, this._onSelectionChanged = _onSelectionChanged
|
|
322
|
-
const rows = this._rows.value;
|
|
323
|
-
if (!rows) {
|
|
324
|
-
return /* @__PURE__ */ new Set();
|
|
325
|
-
}
|
|
326
|
-
const validIds = new Set(rows.map((row) => row.id));
|
|
327
|
-
return new Set([
|
|
328
|
-
...this._selection.value
|
|
329
|
-
].filter((id) => validIds.has(id)));
|
|
330
|
-
}), this._hasSelection = computed(() => this._validSelectedIds.value.size > 0), this._allSelected = computed(() => {
|
|
331
|
-
const rows = this._rows.value;
|
|
332
|
-
if (rows.length === 0) {
|
|
333
|
-
return false;
|
|
334
|
-
}
|
|
335
|
-
return rows.every((row) => this._selection.value.has(row.id));
|
|
336
|
-
}), this.getSelectedRows = () => {
|
|
337
|
-
const selectedIds = this._validSelectedIds.value;
|
|
338
|
-
return this._rows.value.filter((row) => selectedIds.has(row.id));
|
|
339
|
-
}, this.isRowIndexSelected = (rowIndex) => {
|
|
340
|
-
const row = this._rows.value[rowIndex];
|
|
341
|
-
return this._selection.value.has(row.id);
|
|
342
|
-
}, this.isObjectSelected = (object) => {
|
|
343
|
-
return this._selection.value.has(object.id);
|
|
344
|
-
}, this.toggleSelectionForRowIndex = (rowIndex) => {
|
|
345
|
-
const row = this._rows.value[rowIndex];
|
|
346
|
-
const newSelection = new Set(this._selection.value);
|
|
347
|
-
if (newSelection.has(row.id)) {
|
|
348
|
-
newSelection.delete(row.id);
|
|
349
|
-
} else {
|
|
350
|
-
if (this._selectionMode === "single") {
|
|
351
|
-
newSelection.clear();
|
|
352
|
-
}
|
|
353
|
-
newSelection.add(row.id);
|
|
354
|
-
}
|
|
355
|
-
this._selection.value = newSelection;
|
|
356
|
-
}, this.setSelection = (mode) => {
|
|
357
|
-
switch (mode) {
|
|
358
|
-
case "all": {
|
|
359
|
-
this._selection.value = new Set(this._rows.value.map((row) => row.id));
|
|
360
|
-
break;
|
|
361
|
-
}
|
|
362
|
-
case "none": {
|
|
363
|
-
this._selection.value = /* @__PURE__ */ new Set();
|
|
364
|
-
break;
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
};
|
|
328
|
+
super(), this._rows = _rows, this._selectionMode = _selectionMode, this._initialSelection = _initialSelection, this._onSelectionChanged = _onSelectionChanged;
|
|
368
329
|
this._selection = signal(new Set(this._initialSelection));
|
|
369
330
|
}
|
|
370
331
|
async _open() {
|
|
@@ -389,23 +350,67 @@ var SelectionModel = class extends Resource {
|
|
|
389
350
|
get selectionMode() {
|
|
390
351
|
return this._selectionMode;
|
|
391
352
|
}
|
|
353
|
+
getSelectedRows = () => {
|
|
354
|
+
const selectedIds = this._validSelectedIds.value;
|
|
355
|
+
return this._rows.value.filter((row) => selectedIds.has(row.id));
|
|
356
|
+
};
|
|
357
|
+
isRowIndexSelected = (rowIndex) => {
|
|
358
|
+
const row = this._rows.value[rowIndex];
|
|
359
|
+
return this._selection.value.has(row.id);
|
|
360
|
+
};
|
|
361
|
+
isObjectSelected = (object) => {
|
|
362
|
+
return this._selection.value.has(object.id);
|
|
363
|
+
};
|
|
364
|
+
//
|
|
365
|
+
// Manipulation
|
|
366
|
+
//
|
|
367
|
+
toggleSelectionForRowIndex = (rowIndex) => {
|
|
368
|
+
const row = this._rows.value[rowIndex];
|
|
369
|
+
const newSelection = new Set(this._selection.value);
|
|
370
|
+
if (newSelection.has(row.id)) {
|
|
371
|
+
newSelection.delete(row.id);
|
|
372
|
+
} else {
|
|
373
|
+
if (this._selectionMode === "single") {
|
|
374
|
+
newSelection.clear();
|
|
375
|
+
}
|
|
376
|
+
newSelection.add(row.id);
|
|
377
|
+
}
|
|
378
|
+
this._selection.value = newSelection;
|
|
379
|
+
};
|
|
380
|
+
setSelection = (mode) => {
|
|
381
|
+
switch (mode) {
|
|
382
|
+
case "all": {
|
|
383
|
+
this._selection.value = new Set(this._rows.value.map((row) => row.id));
|
|
384
|
+
break;
|
|
385
|
+
}
|
|
386
|
+
case "none": {
|
|
387
|
+
this._selection.value = /* @__PURE__ */ new Set();
|
|
388
|
+
break;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
};
|
|
392
392
|
};
|
|
393
393
|
|
|
394
394
|
// src/model/table-sorting.ts
|
|
395
395
|
import { computed as computed2, signal as signal2 } from "@preact/signals-core";
|
|
396
396
|
import orderBy from "lodash.orderby";
|
|
397
|
-
import {
|
|
397
|
+
import { Format, TypeEnum, getValue } from "@dxos/echo/internal";
|
|
398
398
|
import { formatForDisplay } from "@dxos/react-ui-form";
|
|
399
399
|
var TableSorting = class {
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
400
|
+
_displayToDataIndex = /* @__PURE__ */ new Map();
|
|
401
|
+
_rows;
|
|
402
|
+
_getView;
|
|
403
|
+
_projection;
|
|
404
|
+
_localSort = signal2(void 0);
|
|
405
|
+
_isDirty;
|
|
406
|
+
sortedRows;
|
|
407
|
+
constructor({ rows, projection, getView }) {
|
|
405
408
|
this._rows = rows;
|
|
409
|
+
this._getView = getView;
|
|
410
|
+
this._projection = projection;
|
|
406
411
|
this._isDirty = computed2(() => {
|
|
407
412
|
const local = this._localSort.value;
|
|
408
|
-
const viewSort = this.
|
|
413
|
+
const viewSort = this._getView().sort?.[0];
|
|
409
414
|
if (local?.type === "cleared") {
|
|
410
415
|
return viewSort !== void 0;
|
|
411
416
|
}
|
|
@@ -431,7 +436,7 @@ var TableSorting = class {
|
|
|
431
436
|
if (local?.type === "active") {
|
|
432
437
|
return local.sort;
|
|
433
438
|
}
|
|
434
|
-
return this.
|
|
439
|
+
return this._getView().sort?.[0];
|
|
435
440
|
}
|
|
436
441
|
/**
|
|
437
442
|
* @reactive
|
|
@@ -474,12 +479,13 @@ var TableSorting = class {
|
|
|
474
479
|
}
|
|
475
480
|
save() {
|
|
476
481
|
if (this._localSort.value !== void 0) {
|
|
482
|
+
const view = this._getView();
|
|
477
483
|
if (this._localSort.value.type === "active") {
|
|
478
|
-
|
|
484
|
+
view.sort = [
|
|
479
485
|
this._localSort.value.sort
|
|
480
486
|
];
|
|
481
487
|
} else {
|
|
482
|
-
|
|
488
|
+
view.sort = [];
|
|
483
489
|
}
|
|
484
490
|
this._localSort.value = void 0;
|
|
485
491
|
}
|
|
@@ -536,7 +542,7 @@ var TableSorting = class {
|
|
|
536
542
|
if (value == null) {
|
|
537
543
|
return value;
|
|
538
544
|
}
|
|
539
|
-
if (format ===
|
|
545
|
+
if (format === Format.TypeFormat.SingleSelect) {
|
|
540
546
|
const options = props.options;
|
|
541
547
|
if (!options) {
|
|
542
548
|
return void 0;
|
|
@@ -544,7 +550,7 @@ var TableSorting = class {
|
|
|
544
550
|
const option = options.find((option2) => option2.id === value);
|
|
545
551
|
return option ? options.indexOf(option) : void 0;
|
|
546
552
|
}
|
|
547
|
-
if (format ===
|
|
553
|
+
if (format === Format.TypeFormat.Ref && field.referencePath) {
|
|
548
554
|
const refValue = getValue(value.target, field.referencePath);
|
|
549
555
|
return refValue;
|
|
550
556
|
}
|
|
@@ -556,22 +562,6 @@ var TableSorting = class {
|
|
|
556
562
|
}
|
|
557
563
|
};
|
|
558
564
|
|
|
559
|
-
// src/util/tag.ts
|
|
560
|
-
var TAG_PATTERN_REGEX = /\[([^\]]+)\]\(([^)]+)\)/g;
|
|
561
|
-
var extractTagIds = (value) => {
|
|
562
|
-
if (typeof value !== "string") {
|
|
563
|
-
return void 0;
|
|
564
|
-
}
|
|
565
|
-
const ids = [];
|
|
566
|
-
let match;
|
|
567
|
-
while ((match = TAG_PATTERN_REGEX.exec(value)) !== null) {
|
|
568
|
-
if (match[2]) {
|
|
569
|
-
ids.push(match[2]);
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
return ids.length > 0 ? ids : void 0;
|
|
573
|
-
};
|
|
574
|
-
|
|
575
565
|
// src/model/table-model.ts
|
|
576
566
|
var __dxlog_file = "/__w/dxos/dxos/packages/ui/react-ui-table/src/model/table-model.ts";
|
|
577
567
|
var defaultFeatures = {
|
|
@@ -583,241 +573,61 @@ var defaultFeatures = {
|
|
|
583
573
|
schemaEditable: false
|
|
584
574
|
};
|
|
585
575
|
var TableModel = class extends Resource2 {
|
|
586
|
-
|
|
576
|
+
_object;
|
|
577
|
+
_projection;
|
|
578
|
+
_visibleRange = signal3({
|
|
579
|
+
start: {
|
|
580
|
+
row: 0,
|
|
581
|
+
col: 0
|
|
582
|
+
},
|
|
583
|
+
end: {
|
|
584
|
+
row: 0,
|
|
585
|
+
col: 0
|
|
586
|
+
}
|
|
587
|
+
});
|
|
588
|
+
_onInsertRow;
|
|
589
|
+
_onDeleteRows;
|
|
590
|
+
_onDeleteColumn;
|
|
591
|
+
_onCellUpdate;
|
|
592
|
+
_onRowOrderChange;
|
|
593
|
+
_onRowAction;
|
|
594
|
+
_rowActions;
|
|
595
|
+
_features;
|
|
596
|
+
_rows = signal3([]);
|
|
597
|
+
_draftRows = signal3([]);
|
|
598
|
+
_sorting;
|
|
599
|
+
_pinnedRows;
|
|
600
|
+
_selection;
|
|
601
|
+
_columnMeta;
|
|
602
|
+
constructor({ object, projection, features = {}, sorting = [], initialSelection = [], pinnedRows = {
|
|
587
603
|
top: [],
|
|
588
604
|
bottom: []
|
|
589
605
|
}, rowActions = [], onCellUpdate, onDeleteColumn, onDeleteRows, onInsertRow, onRowOrderChange, onRowAction }) {
|
|
590
606
|
super();
|
|
591
|
-
this.
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
col: 0
|
|
595
|
-
},
|
|
596
|
-
end: {
|
|
597
|
-
row: 0,
|
|
598
|
-
col: 0
|
|
599
|
-
}
|
|
600
|
-
});
|
|
601
|
-
this._rows = signal3([]);
|
|
602
|
-
this._draftRows = signal3([]);
|
|
603
|
-
//
|
|
604
|
-
// Data
|
|
605
|
-
//
|
|
606
|
-
this.setRows = (obj) => {
|
|
607
|
-
this._rows.value = obj;
|
|
608
|
-
};
|
|
609
|
-
this.getRowCount = () => this._rows.value.length;
|
|
610
|
-
/**
|
|
611
|
-
* @reactive
|
|
612
|
-
*/
|
|
613
|
-
this.getDraftRowCount = () => this._draftRows.value.length;
|
|
614
|
-
this.getColumnCount = () => this._projection?.fields.length ?? 0;
|
|
615
|
-
this.insertRow = () => {
|
|
616
|
-
const result = this._onInsertRow?.();
|
|
617
|
-
if (result === false && this._draftRows.value.length === 0) {
|
|
618
|
-
this.createDraftRow();
|
|
619
|
-
}
|
|
620
|
-
};
|
|
621
|
-
this.commitDraftRow = (draftRowIndex) => {
|
|
622
|
-
if (draftRowIndex < 0 || draftRowIndex >= this._draftRows.value.length) {
|
|
623
|
-
return false;
|
|
624
|
-
}
|
|
625
|
-
const draftRow = this._draftRows.value[draftRowIndex];
|
|
626
|
-
if (!draftRow.valid) {
|
|
627
|
-
return false;
|
|
628
|
-
}
|
|
629
|
-
const success = this._onInsertRow?.(draftRow.data);
|
|
630
|
-
if (success) {
|
|
631
|
-
const newDraftRows = this._draftRows.value.filter((_, index) => index !== draftRowIndex);
|
|
632
|
-
this._draftRows.value = newDraftRows;
|
|
633
|
-
}
|
|
634
|
-
return success ?? false;
|
|
635
|
-
};
|
|
636
|
-
this.deleteRow = (rowIndex) => {
|
|
637
|
-
const row = this._sorting.getDataIndex(rowIndex);
|
|
638
|
-
const obj = this._rows.value[row];
|
|
639
|
-
const objectsToDelete = [];
|
|
640
|
-
if (this.features.selection.enabled && this._selection.hasSelection.value) {
|
|
641
|
-
const selectedRows = this._selection.getSelectedRows();
|
|
642
|
-
objectsToDelete.push(...selectedRows);
|
|
643
|
-
} else {
|
|
644
|
-
objectsToDelete.push(obj);
|
|
645
|
-
}
|
|
646
|
-
this._onDeleteRows?.(row, objectsToDelete);
|
|
647
|
-
};
|
|
648
|
-
this.handleRowAction = (actionId, rowIndex) => {
|
|
649
|
-
if (!this._onRowAction) {
|
|
650
|
-
return;
|
|
651
|
-
}
|
|
652
|
-
const row = this._sorting.getDataIndex(rowIndex);
|
|
653
|
-
const data = this._rows.value[row];
|
|
654
|
-
if (data) {
|
|
655
|
-
this._onRowAction(actionId, data);
|
|
656
|
-
}
|
|
657
|
-
};
|
|
658
|
-
this.getCellData = (cell) => {
|
|
659
|
-
const { col, row, plane } = cell;
|
|
660
|
-
const fields = this._projection?.fields ?? [];
|
|
661
|
-
if (col < 0 || col >= fields.length) {
|
|
662
|
-
return void 0;
|
|
663
|
-
}
|
|
664
|
-
const field = fields[col];
|
|
665
|
-
let value;
|
|
666
|
-
if (plane === "frozenRowsEnd") {
|
|
667
|
-
if (row >= 0 && row < this._draftRows.value.length) {
|
|
668
|
-
value = getValue2(this._draftRows.value[row].data, field.path);
|
|
669
|
-
} else {
|
|
670
|
-
return void 0;
|
|
671
|
-
}
|
|
672
|
-
} else {
|
|
673
|
-
const dataIndex = this._sorting.getDataIndex(row);
|
|
674
|
-
value = getValue2(this._rows.value[dataIndex], field.path);
|
|
675
|
-
}
|
|
676
|
-
if (value == null) {
|
|
677
|
-
return "";
|
|
678
|
-
}
|
|
679
|
-
const { props } = this._projection.getFieldProjection(field.id);
|
|
680
|
-
switch (props.format) {
|
|
681
|
-
case FormatEnum2.Ref: {
|
|
682
|
-
if (!field.referencePath) {
|
|
683
|
-
return "";
|
|
684
|
-
}
|
|
685
|
-
return getValue2(value.target, field.referencePath);
|
|
686
|
-
}
|
|
687
|
-
default: {
|
|
688
|
-
return formatForEditing({
|
|
689
|
-
type: props.type,
|
|
690
|
-
format: props.format,
|
|
691
|
-
value
|
|
692
|
-
});
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
|
-
};
|
|
696
|
-
this.validateCellData = async ({ col, row, plane }, value) => {
|
|
697
|
-
const fields = this._projection?.fields ?? [];
|
|
698
|
-
if (col < 0 || col >= fields.length) {
|
|
699
|
-
return {
|
|
700
|
-
valid: false,
|
|
701
|
-
error: "Invalid column index"
|
|
702
|
-
};
|
|
703
|
-
}
|
|
704
|
-
const field = fields[col];
|
|
705
|
-
const { props } = this._projection.getFieldProjection(field.id);
|
|
706
|
-
const transformedValue = editorTextToCellValue(props, value);
|
|
707
|
-
const isDraftRow = plane === "frozenRowsEnd";
|
|
708
|
-
if (isDraftRow) {
|
|
709
|
-
const isInvalidDraftRowIndex = row < 0 || row >= this._draftRows.value.length;
|
|
710
|
-
if (isInvalidDraftRowIndex) {
|
|
711
|
-
return {
|
|
712
|
-
valid: false,
|
|
713
|
-
error: "Invalid draft row index"
|
|
714
|
-
};
|
|
715
|
-
}
|
|
716
|
-
const draftRow = this._draftRows.value[row];
|
|
717
|
-
const snapshot = {
|
|
718
|
-
...draftRow.data
|
|
719
|
-
};
|
|
720
|
-
setValue(snapshot, field.path, transformedValue);
|
|
721
|
-
const validationErrors = this.validateDraftRowData(snapshot);
|
|
722
|
-
if (validationErrors.length > 0) {
|
|
723
|
-
const error = validationErrors.find((err) => err.path === field.path);
|
|
724
|
-
if (error) {
|
|
725
|
-
return {
|
|
726
|
-
valid: false,
|
|
727
|
-
error: error.message
|
|
728
|
-
};
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
return {
|
|
732
|
-
valid: true
|
|
733
|
-
};
|
|
734
|
-
} else {
|
|
735
|
-
const rowIdx = this._sorting.getDataIndex(row);
|
|
736
|
-
const currentRow = this._rows.value[rowIdx];
|
|
737
|
-
invariant(currentRow, "Invalid row index", {
|
|
738
|
-
F: __dxlog_file,
|
|
739
|
-
L: 510,
|
|
740
|
-
S: this,
|
|
741
|
-
A: [
|
|
742
|
-
"currentRow",
|
|
743
|
-
"'Invalid row index'"
|
|
744
|
-
]
|
|
745
|
-
});
|
|
746
|
-
const snapshot = getSnapshot(currentRow);
|
|
747
|
-
setValue(snapshot, field.path, transformedValue);
|
|
748
|
-
const schema = getSchema(currentRow);
|
|
749
|
-
invariant(schema, void 0, {
|
|
750
|
-
F: __dxlog_file,
|
|
751
|
-
L: 516,
|
|
752
|
-
S: this,
|
|
753
|
-
A: [
|
|
754
|
-
"schema",
|
|
755
|
-
""
|
|
756
|
-
]
|
|
757
|
-
});
|
|
758
|
-
const validationResult = validateSchema(schema, snapshot);
|
|
759
|
-
if (validationResult && validationResult.length > 0) {
|
|
760
|
-
const error = validationResult[0];
|
|
761
|
-
invariant(error.path === field.path, void 0, {
|
|
762
|
-
F: __dxlog_file,
|
|
763
|
-
L: 521,
|
|
764
|
-
S: this,
|
|
765
|
-
A: [
|
|
766
|
-
"error.path === field.path",
|
|
767
|
-
""
|
|
768
|
-
]
|
|
769
|
-
});
|
|
770
|
-
return {
|
|
771
|
-
valid: false,
|
|
772
|
-
error: error.message
|
|
773
|
-
};
|
|
774
|
-
}
|
|
775
|
-
return {
|
|
776
|
-
valid: true
|
|
777
|
-
};
|
|
778
|
-
}
|
|
779
|
-
};
|
|
780
|
-
this.setCellData = (cell, value) => {
|
|
781
|
-
const { col, row, plane } = cell;
|
|
782
|
-
const fields = this._projection?.fields ?? [];
|
|
783
|
-
if (col < 0 || col >= fields.length) {
|
|
784
|
-
return;
|
|
785
|
-
}
|
|
786
|
-
const field = fields[col];
|
|
787
|
-
const { props } = this._projection.getFieldProjection(field.id);
|
|
788
|
-
const transformedValue = editorTextToCellValue(props, value);
|
|
789
|
-
if (props.format === FormatEnum2.Ref && !isLiveObject(value)) {
|
|
790
|
-
return;
|
|
791
|
-
}
|
|
792
|
-
if (plane === "frozenRowsEnd") {
|
|
793
|
-
if (row >= 0 && row < this._draftRows.value.length) {
|
|
794
|
-
setValue(this._draftRows.value[row].data, field.path, transformedValue);
|
|
795
|
-
this.validateDraftRow(row);
|
|
796
|
-
}
|
|
797
|
-
} else {
|
|
798
|
-
const rowIdx = this._sorting.getDataIndex(row);
|
|
799
|
-
setValue(this._rows.value[rowIdx], field.path, transformedValue);
|
|
800
|
-
}
|
|
801
|
-
};
|
|
802
|
-
this._view = view;
|
|
803
|
-
this._projection = projection ?? new ProjectionModel2(schema, view.projection);
|
|
607
|
+
this._object = object;
|
|
608
|
+
this._projection = projection;
|
|
609
|
+
this._projection.normalizeView();
|
|
804
610
|
this._features = {
|
|
805
611
|
...defaultFeatures,
|
|
806
612
|
...features
|
|
807
613
|
};
|
|
808
614
|
invariant(!(this._features.dataEditable && this._features.selection.enabled && this._features.selection.mode === "single"), "Single selection is not compatible with editable tables.", {
|
|
809
615
|
F: __dxlog_file,
|
|
810
|
-
L:
|
|
616
|
+
L: 137,
|
|
811
617
|
S: this,
|
|
812
618
|
A: [
|
|
813
619
|
"!(this._features.dataEditable && this._features.selection.enabled && this._features.selection.mode === 'single')",
|
|
814
620
|
"'Single selection is not compatible with editable tables.'"
|
|
815
621
|
]
|
|
816
622
|
});
|
|
817
|
-
this._sorting = new TableSorting(
|
|
623
|
+
this._sorting = new TableSorting({
|
|
624
|
+
rows: this._rows,
|
|
625
|
+
getView: () => this.view,
|
|
626
|
+
projection: this._projection
|
|
627
|
+
});
|
|
818
628
|
if (sorting.length > 0) {
|
|
819
|
-
const
|
|
820
|
-
this._sorting.setSort(
|
|
629
|
+
const { fieldId, direction } = sorting[0];
|
|
630
|
+
this._sorting.setSort(fieldId, direction);
|
|
821
631
|
}
|
|
822
632
|
this._selection = new SelectionModel(this._sorting.sortedRows, this._features.selection.mode ?? "multiple", initialSelection, () => this._onRowOrderChange?.());
|
|
823
633
|
this._pinnedRows = pinnedRows;
|
|
@@ -830,22 +640,23 @@ var TableModel = class extends Resource2 {
|
|
|
830
640
|
this._onRowAction = onRowAction;
|
|
831
641
|
}
|
|
832
642
|
get id() {
|
|
833
|
-
return
|
|
643
|
+
return Obj2.getDXN(this._object).toString();
|
|
834
644
|
}
|
|
835
645
|
get view() {
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
get table() {
|
|
839
|
-
invariant(this._table, "Model not initialized", {
|
|
646
|
+
const view = this._object.view.target;
|
|
647
|
+
invariant(view, "Table model not initialized", {
|
|
840
648
|
F: __dxlog_file,
|
|
841
|
-
L:
|
|
649
|
+
L: 176,
|
|
842
650
|
S: this,
|
|
843
651
|
A: [
|
|
844
|
-
"
|
|
845
|
-
"'
|
|
652
|
+
"view",
|
|
653
|
+
"'Table model not initialized'"
|
|
846
654
|
]
|
|
847
655
|
});
|
|
848
|
-
return
|
|
656
|
+
return view;
|
|
657
|
+
}
|
|
658
|
+
get table() {
|
|
659
|
+
return this._object;
|
|
849
660
|
}
|
|
850
661
|
get projection() {
|
|
851
662
|
return this._projection;
|
|
@@ -877,7 +688,7 @@ var TableModel = class extends Resource2 {
|
|
|
877
688
|
get columnMeta() {
|
|
878
689
|
invariant(this._columnMeta, void 0, {
|
|
879
690
|
F: __dxlog_file,
|
|
880
|
-
L:
|
|
691
|
+
L: 219,
|
|
881
692
|
S: this,
|
|
882
693
|
A: [
|
|
883
694
|
"this._columnMeta",
|
|
@@ -900,17 +711,7 @@ var TableModel = class extends Resource2 {
|
|
|
900
711
|
// Initialisation
|
|
901
712
|
//
|
|
902
713
|
async _open() {
|
|
903
|
-
|
|
904
|
-
invariant(Obj3.instanceOf(TableView, presentation), void 0, {
|
|
905
|
-
F: __dxlog_file,
|
|
906
|
-
L: 239,
|
|
907
|
-
S: this,
|
|
908
|
-
A: [
|
|
909
|
-
"Obj.instanceOf(TableView, presentation)",
|
|
910
|
-
""
|
|
911
|
-
]
|
|
912
|
-
});
|
|
913
|
-
this._table = presentation;
|
|
714
|
+
await this._object.view.load();
|
|
914
715
|
this.initializeColumnMeta();
|
|
915
716
|
this.initializeEffects();
|
|
916
717
|
await this._selection.open(this._ctx);
|
|
@@ -935,7 +736,7 @@ var TableModel = class extends Resource2 {
|
|
|
935
736
|
},
|
|
936
737
|
frozenColsEnd: {
|
|
937
738
|
0: {
|
|
938
|
-
size:
|
|
739
|
+
size: 32,
|
|
939
740
|
resizeable: false
|
|
940
741
|
}
|
|
941
742
|
}
|
|
@@ -971,6 +772,17 @@ var TableModel = class extends Resource2 {
|
|
|
971
772
|
});
|
|
972
773
|
this._ctx.onDispose(draftRowsWatcher);
|
|
973
774
|
}
|
|
775
|
+
//
|
|
776
|
+
// Data
|
|
777
|
+
//
|
|
778
|
+
setRows = (obj) => {
|
|
779
|
+
this._rows.value = obj;
|
|
780
|
+
};
|
|
781
|
+
getRowCount = () => this._rows.value.length;
|
|
782
|
+
/**
|
|
783
|
+
* @reactive
|
|
784
|
+
*/
|
|
785
|
+
getDraftRowCount = () => this._draftRows.value.length;
|
|
974
786
|
// TODO(ZaymonFC): Return .value instead of exposing the signal.
|
|
975
787
|
get draftRows() {
|
|
976
788
|
return this._draftRows;
|
|
@@ -989,6 +801,14 @@ var TableModel = class extends Resource2 {
|
|
|
989
801
|
const validationErrors = draftRow.validationErrors || [];
|
|
990
802
|
return validationErrors.some((error) => error.path === fieldPath);
|
|
991
803
|
}
|
|
804
|
+
getColumnCount = () => this._projection?.fields.length ?? 0;
|
|
805
|
+
insertRow = () => {
|
|
806
|
+
const result = this._onInsertRow?.();
|
|
807
|
+
if (result === "draft" && this._draftRows.value.length === 0) {
|
|
808
|
+
this.createDraftRow();
|
|
809
|
+
}
|
|
810
|
+
return result ?? "final";
|
|
811
|
+
};
|
|
992
812
|
createDraftRow() {
|
|
993
813
|
if (!this._projection) {
|
|
994
814
|
return;
|
|
@@ -1025,9 +845,190 @@ var TableModel = class extends Resource2 {
|
|
|
1025
845
|
this._draftRows.value = newDraftRows;
|
|
1026
846
|
}
|
|
1027
847
|
validateDraftRowData(data) {
|
|
1028
|
-
const schema =
|
|
848
|
+
const schema = toEffectSchema(this._projection.baseSchema);
|
|
1029
849
|
return validateSchema(schema, data) || [];
|
|
1030
850
|
}
|
|
851
|
+
commitDraftRow = (draftRowIndex) => {
|
|
852
|
+
if (draftRowIndex < 0 || draftRowIndex >= this._draftRows.value.length) {
|
|
853
|
+
return false;
|
|
854
|
+
}
|
|
855
|
+
const draftRow = this._draftRows.value[draftRowIndex];
|
|
856
|
+
if (!draftRow.valid) {
|
|
857
|
+
return false;
|
|
858
|
+
}
|
|
859
|
+
const insertRowResult = this._onInsertRow?.(draftRow.data);
|
|
860
|
+
if (insertRowResult === "final") {
|
|
861
|
+
const newDraftRows = this._draftRows.value.filter((_, index) => index !== draftRowIndex);
|
|
862
|
+
this._draftRows.value = newDraftRows;
|
|
863
|
+
}
|
|
864
|
+
return insertRowResult === "final";
|
|
865
|
+
};
|
|
866
|
+
deleteRow = (rowIndex) => {
|
|
867
|
+
const row = this._sorting.getDataIndex(rowIndex);
|
|
868
|
+
const obj = this._rows.value[row];
|
|
869
|
+
const objectsToDelete = [];
|
|
870
|
+
if (this.features.selection.enabled && this._selection.hasSelection.value) {
|
|
871
|
+
const selectedRows = this._selection.getSelectedRows();
|
|
872
|
+
objectsToDelete.push(...selectedRows);
|
|
873
|
+
} else {
|
|
874
|
+
objectsToDelete.push(obj);
|
|
875
|
+
}
|
|
876
|
+
this._onDeleteRows?.(row, objectsToDelete);
|
|
877
|
+
};
|
|
878
|
+
handleRowAction = (actionId, rowIndex) => {
|
|
879
|
+
if (!this._onRowAction) {
|
|
880
|
+
return;
|
|
881
|
+
}
|
|
882
|
+
const row = this._sorting.getDataIndex(rowIndex);
|
|
883
|
+
const data = this._rows.value[row];
|
|
884
|
+
if (data) {
|
|
885
|
+
this._onRowAction(actionId, data);
|
|
886
|
+
}
|
|
887
|
+
};
|
|
888
|
+
getCellData = (cell) => {
|
|
889
|
+
const { col, row, plane } = cell;
|
|
890
|
+
const fields = this._projection?.fields ?? [];
|
|
891
|
+
if (col < 0 || col >= fields.length) {
|
|
892
|
+
return void 0;
|
|
893
|
+
}
|
|
894
|
+
const field = fields[col];
|
|
895
|
+
let value;
|
|
896
|
+
if (plane === "frozenRowsEnd") {
|
|
897
|
+
if (row >= 0 && row < this._draftRows.value.length) {
|
|
898
|
+
value = getValue2(this._draftRows.value[row].data, field.path);
|
|
899
|
+
} else {
|
|
900
|
+
return void 0;
|
|
901
|
+
}
|
|
902
|
+
} else {
|
|
903
|
+
const dataIndex = this._sorting.getDataIndex(row);
|
|
904
|
+
value = getValue2(this._rows.value[dataIndex], field.path);
|
|
905
|
+
}
|
|
906
|
+
if (value == null) {
|
|
907
|
+
return "";
|
|
908
|
+
}
|
|
909
|
+
const { props } = this._projection.getFieldProjection(field.id);
|
|
910
|
+
switch (props.format) {
|
|
911
|
+
case Format2.TypeFormat.Ref: {
|
|
912
|
+
if (!field.referencePath) {
|
|
913
|
+
return "";
|
|
914
|
+
}
|
|
915
|
+
return getValue2(value.target, field.referencePath);
|
|
916
|
+
}
|
|
917
|
+
default: {
|
|
918
|
+
return formatForEditing({
|
|
919
|
+
type: props.type,
|
|
920
|
+
format: props.format,
|
|
921
|
+
value
|
|
922
|
+
});
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
};
|
|
926
|
+
validateCellData = async ({ col, row, plane }, value) => {
|
|
927
|
+
const fields = this._projection?.fields ?? [];
|
|
928
|
+
if (col < 0 || col >= fields.length) {
|
|
929
|
+
return {
|
|
930
|
+
valid: false,
|
|
931
|
+
error: "Invalid column index"
|
|
932
|
+
};
|
|
933
|
+
}
|
|
934
|
+
const field = fields[col];
|
|
935
|
+
const { props } = this._projection.getFieldProjection(field.id);
|
|
936
|
+
const transformedValue = editorTextToCellValue(props, value);
|
|
937
|
+
const isDraftRow = plane === "frozenRowsEnd";
|
|
938
|
+
if (isDraftRow) {
|
|
939
|
+
const isInvalidDraftRowIndex = row < 0 || row >= this._draftRows.value.length;
|
|
940
|
+
if (isInvalidDraftRowIndex) {
|
|
941
|
+
return {
|
|
942
|
+
valid: false,
|
|
943
|
+
error: "Invalid draft row index"
|
|
944
|
+
};
|
|
945
|
+
}
|
|
946
|
+
const draftRow = this._draftRows.value[row];
|
|
947
|
+
const snapshot = {
|
|
948
|
+
...draftRow.data
|
|
949
|
+
};
|
|
950
|
+
setValue(snapshot, field.path, transformedValue);
|
|
951
|
+
const validationErrors = this.validateDraftRowData(snapshot);
|
|
952
|
+
if (validationErrors.length > 0) {
|
|
953
|
+
const error = validationErrors.find((err) => err.path === field.path);
|
|
954
|
+
if (error) {
|
|
955
|
+
return {
|
|
956
|
+
valid: false,
|
|
957
|
+
error: error.message
|
|
958
|
+
};
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
return {
|
|
962
|
+
valid: true
|
|
963
|
+
};
|
|
964
|
+
} else {
|
|
965
|
+
const rowIdx = this._sorting.getDataIndex(row);
|
|
966
|
+
const currentRow = this._rows.value[rowIdx];
|
|
967
|
+
invariant(currentRow, "Invalid row index", {
|
|
968
|
+
F: __dxlog_file,
|
|
969
|
+
L: 516,
|
|
970
|
+
S: this,
|
|
971
|
+
A: [
|
|
972
|
+
"currentRow",
|
|
973
|
+
"'Invalid row index'"
|
|
974
|
+
]
|
|
975
|
+
});
|
|
976
|
+
const snapshot = getSnapshot(currentRow);
|
|
977
|
+
setValue(snapshot, field.path, transformedValue);
|
|
978
|
+
const schema = Obj2.getSchema(currentRow);
|
|
979
|
+
invariant(schema, void 0, {
|
|
980
|
+
F: __dxlog_file,
|
|
981
|
+
L: 522,
|
|
982
|
+
S: this,
|
|
983
|
+
A: [
|
|
984
|
+
"schema",
|
|
985
|
+
""
|
|
986
|
+
]
|
|
987
|
+
});
|
|
988
|
+
const validationResult = validateSchema(schema, snapshot);
|
|
989
|
+
if (validationResult && validationResult.length > 0) {
|
|
990
|
+
const error = validationResult[0];
|
|
991
|
+
invariant(error.path === field.path, void 0, {
|
|
992
|
+
F: __dxlog_file,
|
|
993
|
+
L: 527,
|
|
994
|
+
S: this,
|
|
995
|
+
A: [
|
|
996
|
+
"error.path === field.path",
|
|
997
|
+
""
|
|
998
|
+
]
|
|
999
|
+
});
|
|
1000
|
+
return {
|
|
1001
|
+
valid: false,
|
|
1002
|
+
error: error.message
|
|
1003
|
+
};
|
|
1004
|
+
}
|
|
1005
|
+
return {
|
|
1006
|
+
valid: true
|
|
1007
|
+
};
|
|
1008
|
+
}
|
|
1009
|
+
};
|
|
1010
|
+
setCellData = (cell, value) => {
|
|
1011
|
+
const { col, row, plane } = cell;
|
|
1012
|
+
const fields = this._projection?.fields ?? [];
|
|
1013
|
+
if (col < 0 || col >= fields.length) {
|
|
1014
|
+
return;
|
|
1015
|
+
}
|
|
1016
|
+
const field = fields[col];
|
|
1017
|
+
const { props } = this._projection.getFieldProjection(field.id);
|
|
1018
|
+
const transformedValue = editorTextToCellValue(props, value);
|
|
1019
|
+
if (props.format === Format2.TypeFormat.Ref && !isLiveObject(value)) {
|
|
1020
|
+
return;
|
|
1021
|
+
}
|
|
1022
|
+
if (plane === "frozenRowsEnd") {
|
|
1023
|
+
if (row >= 0 && row < this._draftRows.value.length) {
|
|
1024
|
+
setValue(this._draftRows.value[row].data, field.path, transformedValue);
|
|
1025
|
+
this.validateDraftRow(row);
|
|
1026
|
+
}
|
|
1027
|
+
} else {
|
|
1028
|
+
const rowIdx = this._sorting.getDataIndex(row);
|
|
1029
|
+
setValue(this._rows.value[rowIdx], field.path, transformedValue);
|
|
1030
|
+
}
|
|
1031
|
+
};
|
|
1031
1032
|
/**
|
|
1032
1033
|
* Updates a cell's value using a transform function.
|
|
1033
1034
|
* @param {DxGridPlanePosition} position - The position of the cell to update.
|
|
@@ -1111,14 +1112,14 @@ var TableModel = class extends Resource2 {
|
|
|
1111
1112
|
};
|
|
1112
1113
|
var editorTextToCellValue = (props, value) => {
|
|
1113
1114
|
switch (props.format) {
|
|
1114
|
-
case
|
|
1115
|
+
case Format2.TypeFormat.Ref: {
|
|
1115
1116
|
if (isLiveObject(value)) {
|
|
1116
|
-
return
|
|
1117
|
+
return Ref2.make(value);
|
|
1117
1118
|
} else {
|
|
1118
1119
|
return value;
|
|
1119
1120
|
}
|
|
1120
1121
|
}
|
|
1121
|
-
case
|
|
1122
|
+
case Format2.TypeFormat.SingleSelect: {
|
|
1122
1123
|
const ids = extractTagIds(value);
|
|
1123
1124
|
if (ids && ids.length > 0) {
|
|
1124
1125
|
return ids[0];
|
|
@@ -1126,7 +1127,7 @@ var editorTextToCellValue = (props, value) => {
|
|
|
1126
1127
|
return value;
|
|
1127
1128
|
}
|
|
1128
1129
|
}
|
|
1129
|
-
case
|
|
1130
|
+
case Format2.TypeFormat.MultiSelect: {
|
|
1130
1131
|
const ids = extractTagIds(value);
|
|
1131
1132
|
return ids || value;
|
|
1132
1133
|
}
|
|
@@ -1142,102 +1143,83 @@ var editorTextToCellValue = (props, value) => {
|
|
|
1142
1143
|
|
|
1143
1144
|
// src/model/modal-controller.ts
|
|
1144
1145
|
import { signal as signal4 } from "@preact/signals-core";
|
|
1145
|
-
import { log } from "@dxos/log";
|
|
1146
|
-
var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-table/src/model/modal-controller.ts";
|
|
1147
1146
|
var ModalController = class {
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
this.
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
this.
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
this.
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
fieldId
|
|
1168
|
-
};
|
|
1169
|
-
};
|
|
1170
|
-
this.showColumnCreator = () => {
|
|
1171
|
-
this._state.value = {
|
|
1172
|
-
type: "columnSettings",
|
|
1173
|
-
mode: {
|
|
1174
|
-
type: "create"
|
|
1175
|
-
}
|
|
1176
|
-
};
|
|
1147
|
+
_state = signal4({
|
|
1148
|
+
type: "closed"
|
|
1149
|
+
});
|
|
1150
|
+
_triggerRef = {
|
|
1151
|
+
current: null
|
|
1152
|
+
};
|
|
1153
|
+
get state() {
|
|
1154
|
+
return this._state;
|
|
1155
|
+
}
|
|
1156
|
+
get trigger() {
|
|
1157
|
+
return this._triggerRef;
|
|
1158
|
+
}
|
|
1159
|
+
setTrigger = (trigger) => {
|
|
1160
|
+
this._triggerRef.current = trigger;
|
|
1161
|
+
};
|
|
1162
|
+
showRowMenu = (rowIndex) => {
|
|
1163
|
+
this._state.value = {
|
|
1164
|
+
type: "row",
|
|
1165
|
+
rowIndex
|
|
1177
1166
|
};
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
};
|
|
1167
|
+
};
|
|
1168
|
+
showColumnMenu = (fieldId) => {
|
|
1169
|
+
this._state.value = {
|
|
1170
|
+
type: "column",
|
|
1171
|
+
fieldId
|
|
1184
1172
|
};
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
mode: {
|
|
1192
|
-
type: "edit",
|
|
1193
|
-
fieldId
|
|
1194
|
-
}
|
|
1195
|
-
};
|
|
1196
|
-
});
|
|
1173
|
+
};
|
|
1174
|
+
showColumnCreator = () => {
|
|
1175
|
+
this._state.value = {
|
|
1176
|
+
type: "columnSettings",
|
|
1177
|
+
mode: {
|
|
1178
|
+
type: "create"
|
|
1197
1179
|
}
|
|
1198
1180
|
};
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1181
|
+
};
|
|
1182
|
+
showReferencePanel = (targetId, schemaId) => {
|
|
1183
|
+
this._state.value = {
|
|
1184
|
+
type: "refPanel",
|
|
1185
|
+
targetId,
|
|
1186
|
+
typename: schemaId
|
|
1187
|
+
};
|
|
1188
|
+
};
|
|
1189
|
+
openColumnSettings = () => {
|
|
1190
|
+
if (this._state.value.type === "column") {
|
|
1191
|
+
const fieldId = this._state.value.fieldId;
|
|
1192
|
+
requestAnimationFrame(() => {
|
|
1202
1193
|
this._state.value = {
|
|
1203
|
-
type: "
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1194
|
+
type: "columnSettings",
|
|
1195
|
+
mode: {
|
|
1196
|
+
type: "edit",
|
|
1197
|
+
fieldId
|
|
1198
|
+
}
|
|
1207
1199
|
};
|
|
1208
|
-
}
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
});
|
|
1215
|
-
}
|
|
1216
|
-
};
|
|
1217
|
-
this.close = () => {
|
|
1218
|
-
this._state.value = {
|
|
1219
|
-
type: "closed"
|
|
1220
|
-
};
|
|
1200
|
+
});
|
|
1201
|
+
}
|
|
1202
|
+
};
|
|
1203
|
+
close = () => {
|
|
1204
|
+
this._state.value = {
|
|
1205
|
+
type: "closed"
|
|
1221
1206
|
};
|
|
1222
|
-
}
|
|
1223
|
-
get state() {
|
|
1224
|
-
return this._state;
|
|
1225
|
-
}
|
|
1226
|
-
get trigger() {
|
|
1227
|
-
return this._triggerRef;
|
|
1228
|
-
}
|
|
1207
|
+
};
|
|
1229
1208
|
};
|
|
1230
1209
|
|
|
1231
1210
|
// src/model/table-presentation.ts
|
|
1232
1211
|
import { signal as signal5 } from "@preact/signals-core";
|
|
1233
|
-
import
|
|
1234
|
-
import { Obj as
|
|
1235
|
-
import {
|
|
1212
|
+
import * as Predicate from "effect/Predicate";
|
|
1213
|
+
import { Obj as Obj3 } from "@dxos/echo";
|
|
1214
|
+
import { Format as Format3, TypeEnum as TypeEnum2, getValue as getValue3 } from "@dxos/echo/internal";
|
|
1236
1215
|
import { cellClassesForFieldType, formatForDisplay as formatForDisplay2 } from "@dxos/react-ui-form";
|
|
1237
1216
|
import { toPlaneCellIndex } from "@dxos/react-ui-grid";
|
|
1238
1217
|
import { mx } from "@dxos/react-ui-theme";
|
|
1239
1218
|
import { VIEW_FIELD_LIMIT } from "@dxos/schema";
|
|
1240
1219
|
var TablePresentation = class {
|
|
1220
|
+
model;
|
|
1221
|
+
_visibleRange;
|
|
1222
|
+
fieldProjectionCache = /* @__PURE__ */ new Map();
|
|
1241
1223
|
constructor(model, _visibleRange = signal5({
|
|
1242
1224
|
start: {
|
|
1243
1225
|
row: 0,
|
|
@@ -1250,7 +1232,6 @@ var TablePresentation = class {
|
|
|
1250
1232
|
})) {
|
|
1251
1233
|
this.model = model;
|
|
1252
1234
|
this._visibleRange = _visibleRange;
|
|
1253
|
-
this.fieldProjectionCache = /* @__PURE__ */ new Map();
|
|
1254
1235
|
}
|
|
1255
1236
|
getCells(range, plane) {
|
|
1256
1237
|
this.fieldProjectionCache.clear();
|
|
@@ -1278,6 +1259,9 @@ var TablePresentation = class {
|
|
|
1278
1259
|
case "frozenRowsEnd":
|
|
1279
1260
|
cells = this.getDraftRowCells(range);
|
|
1280
1261
|
break;
|
|
1262
|
+
case "fixedEndStart":
|
|
1263
|
+
cells = this.getDraftIconCells(range);
|
|
1264
|
+
break;
|
|
1281
1265
|
case "fixedEndEnd":
|
|
1282
1266
|
cells = this.getDraftActionCells(range);
|
|
1283
1267
|
break;
|
|
@@ -1314,12 +1298,12 @@ var TablePresentation = class {
|
|
|
1314
1298
|
return "";
|
|
1315
1299
|
}
|
|
1316
1300
|
switch (props.format) {
|
|
1317
|
-
case
|
|
1318
|
-
case
|
|
1319
|
-
case
|
|
1301
|
+
case Format3.TypeFormat.Boolean:
|
|
1302
|
+
case Format3.TypeFormat.SingleSelect:
|
|
1303
|
+
case Format3.TypeFormat.MultiSelect: {
|
|
1320
1304
|
return "";
|
|
1321
1305
|
}
|
|
1322
|
-
case
|
|
1306
|
+
case Format3.TypeFormat.Ref: {
|
|
1323
1307
|
if (!field.referencePath) {
|
|
1324
1308
|
return "";
|
|
1325
1309
|
}
|
|
@@ -1336,10 +1320,7 @@ var TablePresentation = class {
|
|
|
1336
1320
|
}
|
|
1337
1321
|
};
|
|
1338
1322
|
const classes = [];
|
|
1339
|
-
const formatClasses = cellClassesForFieldType(
|
|
1340
|
-
type: props.type,
|
|
1341
|
-
format: props.format
|
|
1342
|
-
});
|
|
1323
|
+
const formatClasses = cellClassesForFieldType(props);
|
|
1343
1324
|
if (formatClasses) {
|
|
1344
1325
|
classes.push(formatClasses);
|
|
1345
1326
|
}
|
|
@@ -1347,9 +1328,7 @@ var TablePresentation = class {
|
|
|
1347
1328
|
if (rowSelectionClasses) {
|
|
1348
1329
|
classes.push(rowSelectionClasses);
|
|
1349
1330
|
}
|
|
1350
|
-
|
|
1351
|
-
cell.className = mx(classes.flat());
|
|
1352
|
-
}
|
|
1331
|
+
cell.className = mx(classes);
|
|
1353
1332
|
if (props.type === TypeEnum2.Array) {
|
|
1354
1333
|
const targetArray = getValue3(obj, field.path);
|
|
1355
1334
|
if (targetArray && Array.isArray(targetArray)) {
|
|
@@ -1371,20 +1350,20 @@ var TablePresentation = class {
|
|
|
1371
1350
|
}
|
|
1372
1351
|
return "Object";
|
|
1373
1352
|
};
|
|
1374
|
-
const tags = targetArray.map(getLabel).filter(isNotNullable).map((title) => {
|
|
1353
|
+
const tags = targetArray.map(getLabel).filter(Predicate.isNotNullable).map((title) => {
|
|
1375
1354
|
return `<span class="dx-tag" data-hue="neutral">${title}</span>`;
|
|
1376
1355
|
}).join("");
|
|
1377
1356
|
cell.accessoryHtml = `<div role='none' class="flex flex-row gap-1 overflow-x-auto">${tags}</div>`;
|
|
1378
1357
|
}
|
|
1379
1358
|
}
|
|
1380
|
-
if (props.format ===
|
|
1359
|
+
if (props.format === Format3.TypeFormat.Ref && props.referenceSchema) {
|
|
1381
1360
|
const targetObj = getValue3(obj, field.path)?.target;
|
|
1382
1361
|
if (targetObj) {
|
|
1383
|
-
const dxn =
|
|
1384
|
-
cell.accessoryHtml = `<dx-
|
|
1362
|
+
const dxn = Obj3.getDXN(targetObj)?.toString();
|
|
1363
|
+
cell.accessoryHtml = `<div role="none" class="absolute inline-end-0 inset-block-0 p-[--dx-grid-cell-content-padding-block]"><dx-anchor refId=${dxn} class="dx-button is-6 aspect-square min-bs-0" data-dx-grid-action="accessory"><dx-icon icon="ph--link-simple--regular"/></dx-anchor></div>`;
|
|
1385
1364
|
}
|
|
1386
1365
|
}
|
|
1387
|
-
if (props.format ===
|
|
1366
|
+
if (props.format === Format3.TypeFormat.Boolean) {
|
|
1388
1367
|
const value = getValue3(obj, field.path);
|
|
1389
1368
|
cell.accessoryHtml = tableControls.switch.render({
|
|
1390
1369
|
colIndex,
|
|
@@ -1393,7 +1372,7 @@ var TablePresentation = class {
|
|
|
1393
1372
|
});
|
|
1394
1373
|
cell.readonly = "no-text-select";
|
|
1395
1374
|
}
|
|
1396
|
-
if (props.format ===
|
|
1375
|
+
if (props.format === Format3.TypeFormat.SingleSelect) {
|
|
1397
1376
|
const value = getValue3(obj, field.path);
|
|
1398
1377
|
const options = this.model.projection.getFieldProjection(field.id).props.options;
|
|
1399
1378
|
if (options) {
|
|
@@ -1403,7 +1382,7 @@ var TablePresentation = class {
|
|
|
1403
1382
|
}
|
|
1404
1383
|
}
|
|
1405
1384
|
}
|
|
1406
|
-
if (props.format ===
|
|
1385
|
+
if (props.format === Format3.TypeFormat.MultiSelect) {
|
|
1407
1386
|
const values = getValue3(obj, field.path);
|
|
1408
1387
|
const options = this.model.projection.getFieldProjection(field.id).props.options;
|
|
1409
1388
|
if (options && values && values.length > 0) {
|
|
@@ -1443,24 +1422,37 @@ var TablePresentation = class {
|
|
|
1443
1422
|
const cells = {};
|
|
1444
1423
|
const fields = this.model.projection?.fields ?? [];
|
|
1445
1424
|
const draftRows = this.model.draftRows.value;
|
|
1446
|
-
|
|
1447
|
-
const draftRow = draftRows[row];
|
|
1425
|
+
if (draftRows.length === 0) {
|
|
1448
1426
|
for (let col = range.start.col; col <= range.end.col && col < fields.length; col++) {
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
}
|
|
1453
|
-
|
|
1454
|
-
|
|
1427
|
+
cells[toPlaneCellIndex({
|
|
1428
|
+
col,
|
|
1429
|
+
row: 0
|
|
1430
|
+
})] = {
|
|
1431
|
+
value: "",
|
|
1432
|
+
readonly: true,
|
|
1433
|
+
className: "dx-grid__row--cta__cell"
|
|
1434
|
+
};
|
|
1435
|
+
}
|
|
1436
|
+
} else {
|
|
1437
|
+
for (let row = range.start.row; row <= range.end.row && row < draftRows.length; row++) {
|
|
1438
|
+
const draftRow = draftRows[row];
|
|
1439
|
+
for (let col = range.start.col; col <= range.end.col && col < fields.length; col++) {
|
|
1455
1440
|
const cellIndex = toPlaneCellIndex({
|
|
1456
1441
|
col,
|
|
1457
1442
|
row
|
|
1458
1443
|
});
|
|
1459
|
-
const
|
|
1460
|
-
if (
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1444
|
+
const field = fields[col];
|
|
1445
|
+
if (!field) {
|
|
1446
|
+
continue;
|
|
1447
|
+
}
|
|
1448
|
+
this.createDataCell(cells, draftRow.data, field, col, row);
|
|
1449
|
+
if (this.model.hasDraftRowValidationError(row, field.path)) {
|
|
1450
|
+
const cellValue = cells[cellIndex];
|
|
1451
|
+
if (cellValue) {
|
|
1452
|
+
const existingClasses = cellValue.className || "";
|
|
1453
|
+
const draftClasses = "dx-grid__cell--flagged";
|
|
1454
|
+
cellValue.className = existingClasses ? `${existingClasses} ${draftClasses}` : draftClasses;
|
|
1455
|
+
}
|
|
1464
1456
|
}
|
|
1465
1457
|
}
|
|
1466
1458
|
}
|
|
@@ -1479,10 +1471,10 @@ var TablePresentation = class {
|
|
|
1479
1471
|
row: 0
|
|
1480
1472
|
})] = {
|
|
1481
1473
|
// TODO(burdon): Use same logic as form for fallback title.
|
|
1482
|
-
value:
|
|
1483
|
-
readonly: true,
|
|
1474
|
+
value: "",
|
|
1484
1475
|
resizeHandle: "col",
|
|
1485
1476
|
accessoryHtml: `
|
|
1477
|
+
<span class="grow min-is-0 truncate">${props.title ?? field.path}</span>
|
|
1486
1478
|
${direction !== void 0 ? tableButtons.sort.render({
|
|
1487
1479
|
fieldId: field.id,
|
|
1488
1480
|
direction
|
|
@@ -1491,7 +1483,7 @@ var TablePresentation = class {
|
|
|
1491
1483
|
fieldId: field.id
|
|
1492
1484
|
})}
|
|
1493
1485
|
`,
|
|
1494
|
-
className: "!bg-toolbarSurface"
|
|
1486
|
+
className: "!bg-toolbarSurface !text-description [&>div]:flex [&>div]:items-stretch"
|
|
1495
1487
|
};
|
|
1496
1488
|
}
|
|
1497
1489
|
return cells;
|
|
@@ -1582,19 +1574,46 @@ var TablePresentation = class {
|
|
|
1582
1574
|
getDraftActionCells(range) {
|
|
1583
1575
|
const cells = {};
|
|
1584
1576
|
const draftRows = this.model.draftRows.value;
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1577
|
+
if (draftRows.length === 0) {
|
|
1578
|
+
cells[toPlaneCellIndex({
|
|
1579
|
+
col: 0,
|
|
1580
|
+
row: 0
|
|
1581
|
+
})] = {
|
|
1582
|
+
value: "",
|
|
1583
|
+
className: "dx-grid__row--cta__cell",
|
|
1584
|
+
readonly: true
|
|
1585
|
+
};
|
|
1586
|
+
} else {
|
|
1587
|
+
for (let row = range.start.row; row <= range.end.row && row < draftRows.length; row++) {
|
|
1588
|
+
const draftRow = draftRows[row];
|
|
1589
|
+
const disabled = !draftRow.valid;
|
|
1590
|
+
cells[toPlaneCellIndex({
|
|
1591
|
+
col: 0,
|
|
1592
|
+
row
|
|
1593
|
+
})] = {
|
|
1594
|
+
value: "",
|
|
1595
|
+
readonly: true,
|
|
1596
|
+
accessoryHtml: tableButtons.saveDraftRow.render({
|
|
1597
|
+
rowIndex: row,
|
|
1598
|
+
disabled
|
|
1599
|
+
})
|
|
1600
|
+
};
|
|
1601
|
+
}
|
|
1602
|
+
}
|
|
1603
|
+
return cells;
|
|
1604
|
+
}
|
|
1605
|
+
getDraftIconCells(range) {
|
|
1606
|
+
const cells = {};
|
|
1607
|
+
const draftRows = this.model.draftRows.value;
|
|
1608
|
+
for (let row = range.start.row; row <= range.end.row; row++) {
|
|
1588
1609
|
cells[toPlaneCellIndex({
|
|
1589
1610
|
col: 0,
|
|
1590
1611
|
row
|
|
1591
1612
|
})] = {
|
|
1592
1613
|
value: "",
|
|
1593
1614
|
readonly: true,
|
|
1594
|
-
accessoryHtml:
|
|
1595
|
-
|
|
1596
|
-
disabled
|
|
1597
|
-
})
|
|
1615
|
+
accessoryHtml: '<dx-icon icon="ph--plus--regular" class="contents"></dx-icon>',
|
|
1616
|
+
className: mx("[&>div]:grid [&>div]:place-content-center", draftRows.length < 1 && "dx-grid__row--cta__cell")
|
|
1598
1617
|
};
|
|
1599
1618
|
}
|
|
1600
1619
|
return cells;
|
|
@@ -1622,31 +1641,65 @@ var cellClassesForRowSelection = (selected, selectionMode) => {
|
|
|
1622
1641
|
}
|
|
1623
1642
|
};
|
|
1624
1643
|
|
|
1644
|
+
// src/hooks/useAddRow.ts
|
|
1645
|
+
import { useCallback } from "react";
|
|
1646
|
+
import { Obj as Obj4 } from "@dxos/echo";
|
|
1647
|
+
var useAddRow = ({ space, schema }) => {
|
|
1648
|
+
return useCallback((data) => {
|
|
1649
|
+
if (space && schema) {
|
|
1650
|
+
try {
|
|
1651
|
+
space.db.add(Obj4.make(schema, data ?? {}));
|
|
1652
|
+
return "final";
|
|
1653
|
+
} catch (error) {
|
|
1654
|
+
return "draft";
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1657
|
+
return "final";
|
|
1658
|
+
}, [
|
|
1659
|
+
space,
|
|
1660
|
+
schema
|
|
1661
|
+
]);
|
|
1662
|
+
};
|
|
1663
|
+
|
|
1664
|
+
// src/hooks/useProjectionModel.ts
|
|
1665
|
+
import { useMemo } from "react";
|
|
1666
|
+
import { Type as Type2 } from "@dxos/echo";
|
|
1667
|
+
import { ProjectionModel as ProjectionModel2 } from "@dxos/schema";
|
|
1668
|
+
var useProjectionModel = (schema, table) => useMemo(() => {
|
|
1669
|
+
if (schema && table?.view.target?.projection) {
|
|
1670
|
+
const projection = new ProjectionModel2(Type2.toJsonSchema(schema), table.view.target.projection);
|
|
1671
|
+
projection.normalizeView();
|
|
1672
|
+
return projection;
|
|
1673
|
+
}
|
|
1674
|
+
}, [
|
|
1675
|
+
schema,
|
|
1676
|
+
table?.view.target?.projection
|
|
1677
|
+
]);
|
|
1678
|
+
|
|
1625
1679
|
// src/hooks/useTableModel.ts
|
|
1626
1680
|
import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
|
|
1627
1681
|
import { effect as effect3 } from "@preact/signals-core";
|
|
1628
1682
|
import orderBy2 from "lodash.orderby";
|
|
1629
|
-
import { useEffect, useMemo, useState } from "react";
|
|
1630
|
-
import {
|
|
1683
|
+
import { useEffect, useMemo as useMemo2, useState } from "react";
|
|
1684
|
+
import { Obj as Obj5 } from "@dxos/echo";
|
|
1631
1685
|
import { useSelected, useSelectionActions } from "@dxos/react-ui-attention";
|
|
1632
1686
|
import { isNonNullable } from "@dxos/util";
|
|
1633
|
-
var useTableModel = ({
|
|
1687
|
+
var useTableModel = ({ object, projection, rows, rowActions, features, onSelectionChanged, onRowAction, ...props }) => {
|
|
1634
1688
|
var _effect = _useSignals();
|
|
1635
1689
|
try {
|
|
1636
|
-
const selected = useSelected(
|
|
1637
|
-
const initialSelection =
|
|
1638
|
-
|
|
1690
|
+
const selected = useSelected(object && Obj5.getDXN(object).toString(), "multi");
|
|
1691
|
+
const initialSelection = useMemo2(() => selected, [
|
|
1692
|
+
object
|
|
1639
1693
|
]);
|
|
1640
1694
|
const [model, setModel] = useState();
|
|
1641
1695
|
useEffect(() => {
|
|
1642
|
-
if (!
|
|
1696
|
+
if (!object || !projection) {
|
|
1643
1697
|
return;
|
|
1644
1698
|
}
|
|
1645
1699
|
let model2;
|
|
1646
1700
|
const t = setTimeout(async () => {
|
|
1647
1701
|
model2 = new TableModel({
|
|
1648
|
-
|
|
1649
|
-
schema,
|
|
1702
|
+
object,
|
|
1650
1703
|
projection,
|
|
1651
1704
|
features,
|
|
1652
1705
|
rowActions,
|
|
@@ -1662,8 +1715,7 @@ var useTableModel = ({ view, schema, projection, rows, rowActions, features, onS
|
|
|
1662
1715
|
void model2?.close();
|
|
1663
1716
|
};
|
|
1664
1717
|
}, [
|
|
1665
|
-
|
|
1666
|
-
schema,
|
|
1718
|
+
object,
|
|
1667
1719
|
projection,
|
|
1668
1720
|
features,
|
|
1669
1721
|
rowActions,
|
|
@@ -1710,31 +1762,10 @@ var useTableModel = ({ view, schema, projection, rows, rowActions, features, onS
|
|
|
1710
1762
|
}
|
|
1711
1763
|
};
|
|
1712
1764
|
|
|
1713
|
-
// src/hooks/useAddRow.ts
|
|
1714
|
-
import { useCallback } from "react";
|
|
1715
|
-
import { Obj as Obj5 } from "@dxos/echo";
|
|
1716
|
-
var useAddRow = ({ space, schema }) => {
|
|
1717
|
-
return useCallback((data) => {
|
|
1718
|
-
if (space && schema) {
|
|
1719
|
-
try {
|
|
1720
|
-
space.db.add(Obj5.make(schema, data ?? {}));
|
|
1721
|
-
return true;
|
|
1722
|
-
} catch (error) {
|
|
1723
|
-
return false;
|
|
1724
|
-
}
|
|
1725
|
-
}
|
|
1726
|
-
return false;
|
|
1727
|
-
}, [
|
|
1728
|
-
space,
|
|
1729
|
-
schema
|
|
1730
|
-
]);
|
|
1731
|
-
};
|
|
1732
|
-
|
|
1733
1765
|
export {
|
|
1734
1766
|
getBaseSchema,
|
|
1735
1767
|
makeDynamicTable,
|
|
1736
1768
|
touch,
|
|
1737
|
-
createTable,
|
|
1738
1769
|
BUTTON_IDENTIFIERS,
|
|
1739
1770
|
tableButtons,
|
|
1740
1771
|
CONTROL_IDENTIFIERS,
|
|
@@ -1746,7 +1777,8 @@ export {
|
|
|
1746
1777
|
ModalController,
|
|
1747
1778
|
TablePresentation,
|
|
1748
1779
|
cellClassesForRowSelection,
|
|
1749
|
-
|
|
1750
|
-
|
|
1780
|
+
useAddRow,
|
|
1781
|
+
useProjectionModel,
|
|
1782
|
+
useTableModel
|
|
1751
1783
|
};
|
|
1752
|
-
//# sourceMappingURL=chunk-
|
|
1784
|
+
//# sourceMappingURL=chunk-P73ALX3N.mjs.map
|