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