@dxos/react-ui-table 0.8.4-main.3c1ae3b → 0.8.4-main.3eb6e50203
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-V7A7ZA5E.mjs → chunk-GTGYBRJA.mjs} +606 -641
- package/dist/lib/browser/chunk-GTGYBRJA.mjs.map +7 -0
- package/dist/lib/browser/{chunk-CJQ6T4LL.mjs → chunk-OZBLY7XM.mjs} +4 -5
- package/dist/lib/browser/chunk-OZBLY7XM.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +1082 -969
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +20 -16
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/browser/types/index.mjs +1 -1
- package/dist/lib/node-esm/{chunk-P73ALX3N.mjs → chunk-DPNSZHU5.mjs} +606 -640
- package/dist/lib/node-esm/chunk-DPNSZHU5.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-T6PXZQ6W.mjs → chunk-WNZSKIRF.mjs} +4 -5
- package/dist/lib/node-esm/chunk-WNZSKIRF.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +1082 -969
- 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 +20 -16
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/types/index.mjs +1 -1
- package/dist/types/src/components/Table/ColumnActionsMenu.d.ts.map +1 -1
- package/dist/types/src/components/Table/ColumnSettings.d.ts.map +1 -1
- package/dist/types/src/components/Table/DynamicTable.d.ts +3 -2
- package/dist/types/src/components/Table/DynamicTable.d.ts.map +1 -1
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts +1 -1
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/Relations.stories.d.ts +2 -2
- package/dist/types/src/components/Table/Relations.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/RowActionsMenu.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.stories.d.ts +2 -2
- package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts +1 -2
- package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts +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 +22 -13
- package/dist/types/src/components/testing.d.ts.map +1 -1
- package/dist/types/src/hooks/useAddRow.d.ts +5 -6
- package/dist/types/src/hooks/useAddRow.d.ts.map +1 -1
- package/dist/types/src/hooks/useProjectionModel.d.ts +2 -1
- package/dist/types/src/hooks/useProjectionModel.d.ts.map +1 -1
- package/dist/types/src/hooks/useTableModel.d.ts +6 -5
- package/dist/types/src/hooks/useTableModel.d.ts.map +1 -1
- package/dist/types/src/model/modal-controller.d.ts +5 -1
- package/dist/types/src/model/modal-controller.d.ts.map +1 -1
- package/dist/types/src/model/selection-model.d.ts +17 -8
- package/dist/types/src/model/selection-model.d.ts.map +1 -1
- package/dist/types/src/model/table-model.d.ts +99 -18
- package/dist/types/src/model/table-model.d.ts.map +1 -1
- package/dist/types/src/model/table-presentation.d.ts +3 -1
- package/dist/types/src/model/table-presentation.d.ts.map +1 -1
- package/dist/types/src/playwright/TableManager.d.ts +2 -1
- package/dist/types/src/playwright/TableManager.d.ts.map +1 -1
- package/dist/types/src/testing/useTestTableModel.d.ts +4 -5
- package/dist/types/src/testing/useTestTableModel.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +2 -2
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/Table.d.ts +17 -14
- package/dist/types/src/types/Table.d.ts.map +1 -1
- package/dist/types/src/util/dynamic-table.d.ts +10 -7
- package/dist/types/src/util/dynamic-table.d.ts.map +1 -1
- package/dist/types/src/util/dynamic-table.test.d.ts +2 -0
- package/dist/types/src/util/dynamic-table.test.d.ts.map +1 -0
- package/dist/types/src/util/index.d.ts +2 -0
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/src/util/query-ast.d.ts +7 -0
- package/dist/types/src/util/query-ast.d.ts.map +1 -0
- package/dist/types/src/util/sort.d.ts +12 -0
- package/dist/types/src/util/sort.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +53 -54
- package/src/components/Table/ColumnActionsMenu.tsx +6 -5
- package/src/components/Table/ColumnSettings.tsx +4 -3
- package/src/components/Table/DynamicTable.stories.tsx +10 -8
- package/src/components/Table/DynamicTable.tsx +18 -18
- package/src/components/Table/Relations.stories.tsx +23 -19
- package/src/components/Table/RowActionsMenu.tsx +3 -2
- package/src/components/Table/Table.stories.tsx +47 -31
- package/src/components/Table/Table.tsx +34 -17
- package/src/components/TableCellEditor/FormCellEditor.tsx +49 -65
- package/src/components/TableCellEditor/TableCellEditor.stories.tsx +3 -3
- package/src/components/TableCellEditor/TableCellEditor.tsx +2 -2
- package/src/components/TableToolbar/TableToolbar.tsx +18 -12
- package/src/components/testing.ts +37 -11
- package/src/hooks/useAddRow.ts +8 -10
- package/src/hooks/useProjectionModel.ts +28 -8
- package/src/hooks/useTableModel.ts +27 -23
- package/src/model/modal-controller.ts +23 -12
- package/src/model/selection-model.ts +75 -44
- package/src/model/table-model.test.ts +80 -52
- package/src/model/table-model.ts +409 -138
- package/src/model/table-presentation.test.ts +57 -47
- package/src/model/table-presentation.ts +23 -18
- package/src/playwright/TableManager.ts +10 -3
- package/src/playwright/playwright.config.ts +1 -1
- package/src/playwright/smoke.spec.ts +48 -4
- package/src/testing/useTestTableModel.ts +23 -20
- package/src/translations.ts +1 -1
- package/src/types/Table.ts +8 -8
- package/src/util/dynamic-table.test.ts +70 -0
- package/src/util/dynamic-table.ts +31 -13
- package/src/util/index.ts +2 -0
- package/src/util/query-ast.ts +19 -0
- package/src/util/sort.ts +90 -0
- package/dist/lib/browser/chunk-CJQ6T4LL.mjs.map +0 -7
- package/dist/lib/browser/chunk-V7A7ZA5E.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-P73ALX3N.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-T6PXZQ6W.mjs.map +0 -7
- package/dist/types/src/model/table-sorting.d.ts +0 -56
- package/dist/types/src/model/table-sorting.d.ts.map +0 -1
- package/src/model/table-sorting.ts +0 -234
|
@@ -1,86 +1,64 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
|
|
2
|
-
import {
|
|
3
|
-
Table_exports
|
|
4
|
-
} from "./chunk-T6PXZQ6W.mjs";
|
|
5
2
|
|
|
6
|
-
// src/util/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
if (typename && properties) {
|
|
11
|
-
const schema2 = getSchemaFromPropertyDefinitions(typename, properties);
|
|
12
|
-
return {
|
|
13
|
-
typename: schema2.typename,
|
|
14
|
-
jsonSchema: schema2.jsonSchema
|
|
15
|
-
};
|
|
16
|
-
} else if (schema) {
|
|
17
|
-
return {
|
|
18
|
-
typename: Type.getTypename(schema),
|
|
19
|
-
jsonSchema: Type.toJsonSchema(schema)
|
|
20
|
-
};
|
|
21
|
-
} else if (typename && jsonSchema) {
|
|
22
|
-
return {
|
|
23
|
-
typename,
|
|
24
|
-
jsonSchema
|
|
25
|
-
};
|
|
26
|
-
} else {
|
|
27
|
-
throw new Error("invalid properties");
|
|
3
|
+
// src/util/query-ast.ts
|
|
4
|
+
var extractOrder = (queryAst) => {
|
|
5
|
+
if (queryAst.type === "order") {
|
|
6
|
+
return queryAst.order;
|
|
28
7
|
}
|
|
8
|
+
if (queryAst.type === "options") {
|
|
9
|
+
return extractOrder(queryAst.query);
|
|
10
|
+
}
|
|
11
|
+
return void 0;
|
|
29
12
|
};
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const projection = new ProjectionModel(jsonSchema, view.projection);
|
|
43
|
-
projection.normalizeView();
|
|
44
|
-
if (properties && projection.fields) {
|
|
45
|
-
setProperties(view, projection, object, properties);
|
|
46
|
-
}
|
|
47
|
-
return {
|
|
48
|
-
projection,
|
|
49
|
-
object
|
|
50
|
-
};
|
|
51
|
-
};
|
|
52
|
-
var setProperties = (view, projection, table, properties) => {
|
|
53
|
-
for (const property of properties) {
|
|
54
|
-
const field = projection.fields.find((field2) => field2.path === property.name);
|
|
55
|
-
if (field) {
|
|
56
|
-
if (property.size !== void 0) {
|
|
57
|
-
table.sizes[field.path] = property.size;
|
|
58
|
-
}
|
|
59
|
-
if (property.title !== void 0) {
|
|
60
|
-
const fieldProjection = projection.getFieldProjection(field.id);
|
|
61
|
-
projection.setFieldProjection({
|
|
62
|
-
...fieldProjection,
|
|
63
|
-
props: {
|
|
64
|
-
...fieldProjection.props,
|
|
65
|
-
title: property.title
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
if (property.sort) {
|
|
70
|
-
const fieldId = field.id;
|
|
71
|
-
view.sort = [
|
|
72
|
-
{
|
|
73
|
-
fieldId,
|
|
74
|
-
direction: property.sort
|
|
75
|
-
}
|
|
76
|
-
];
|
|
77
|
-
}
|
|
13
|
+
|
|
14
|
+
// src/util/sort.ts
|
|
15
|
+
import { Format } from "@dxos/echo";
|
|
16
|
+
var getSortValue = (value, format) => {
|
|
17
|
+
if (value === void 0 || value === null) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
const isDateFormat = format === Format.TypeFormat.DateTime || format === Format.TypeFormat.Date;
|
|
21
|
+
if (isDateFormat) {
|
|
22
|
+
const date = new Date(value);
|
|
23
|
+
if (!isNaN(date.getTime())) {
|
|
24
|
+
return date.getTime();
|
|
78
25
|
}
|
|
26
|
+
return String(value);
|
|
79
27
|
}
|
|
28
|
+
if (format === Format.TypeFormat.Number || format === Format.TypeFormat.Integer || format === Format.TypeFormat.Currency || format === Format.TypeFormat.Percent || format === Format.TypeFormat.Duration) {
|
|
29
|
+
const num = typeof value === "number" ? value : Number(value);
|
|
30
|
+
if (!isNaN(num)) {
|
|
31
|
+
return num;
|
|
32
|
+
}
|
|
33
|
+
return String(value);
|
|
34
|
+
}
|
|
35
|
+
if (typeof value === "string") {
|
|
36
|
+
return value;
|
|
37
|
+
}
|
|
38
|
+
if (typeof value === "number") {
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
return String(value);
|
|
42
|
+
};
|
|
43
|
+
var compareValues = (aValue, bValue, format, direction) => {
|
|
44
|
+
if (aValue === void 0 || aValue === null) {
|
|
45
|
+
return bValue === void 0 || bValue === null ? 0 : 1;
|
|
46
|
+
}
|
|
47
|
+
if (bValue === void 0 || bValue === null) {
|
|
48
|
+
return -1;
|
|
49
|
+
}
|
|
50
|
+
const aSortValue = getSortValue(aValue, format);
|
|
51
|
+
const bSortValue = getSortValue(bValue, format);
|
|
52
|
+
let comparison = 0;
|
|
53
|
+
if (typeof aSortValue === "number" && typeof bSortValue === "number") {
|
|
54
|
+
comparison = aSortValue - bSortValue;
|
|
55
|
+
} else if (typeof aSortValue === "string" && typeof bSortValue === "string") {
|
|
56
|
+
comparison = aSortValue.localeCompare(bSortValue);
|
|
57
|
+
} else {
|
|
58
|
+
comparison = String(aSortValue).localeCompare(String(bSortValue));
|
|
59
|
+
}
|
|
60
|
+
return direction === "desc" ? -comparison : comparison;
|
|
80
61
|
};
|
|
81
|
-
|
|
82
|
-
// src/util/signals.ts
|
|
83
|
-
var touch = (value) => value;
|
|
84
62
|
|
|
85
63
|
// src/util/table-buttons.ts
|
|
86
64
|
var BUTTON_IDENTIFIERS = {
|
|
@@ -255,29 +233,15 @@ var tableControls = {
|
|
|
255
233
|
}
|
|
256
234
|
};
|
|
257
235
|
|
|
258
|
-
// src/util/schema.ts
|
|
259
|
-
import * as Schema from "effect/Schema";
|
|
260
|
-
import * as SchemaAST from "effect/SchemaAST";
|
|
261
|
-
var narrowSchema = (schema, paths) => {
|
|
262
|
-
const ast = schema?.ast;
|
|
263
|
-
if (SchemaAST.isTypeLiteral(ast)) {
|
|
264
|
-
const propertySignatures = ast.propertySignatures.filter((signature) => paths.includes(signature.name.toString()));
|
|
265
|
-
if (propertySignatures.length > 0) {
|
|
266
|
-
const narrowType = new SchemaAST.TypeLiteral(propertySignatures, []);
|
|
267
|
-
return Schema.make(narrowType);
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
return void 0;
|
|
271
|
-
};
|
|
272
|
-
|
|
273
236
|
// src/model/table-model.ts
|
|
274
|
-
import {
|
|
237
|
+
import { Atom as Atom2 } from "@effect-atom/atom-react";
|
|
275
238
|
import { Resource as Resource2 } from "@dxos/context";
|
|
276
|
-
import { Format as Format2, Obj
|
|
277
|
-
import {
|
|
239
|
+
import { Format as Format2, Obj, Order, Query, Ref } from "@dxos/echo";
|
|
240
|
+
import { toEffectSchema } from "@dxos/echo/internal";
|
|
241
|
+
import { getSnapshot } from "@dxos/echo/internal";
|
|
242
|
+
import { getValue, setValue } from "@dxos/effect";
|
|
278
243
|
import { invariant } from "@dxos/invariant";
|
|
279
244
|
import { ObjectId } from "@dxos/keys";
|
|
280
|
-
import { getSnapshot, isLiveObject } from "@dxos/live-object";
|
|
281
245
|
import { formatForEditing, parseValue } from "@dxos/react-ui-form";
|
|
282
246
|
import { validateSchema } from "@dxos/schema";
|
|
283
247
|
|
|
@@ -298,75 +262,99 @@ var extractTagIds = (value) => {
|
|
|
298
262
|
};
|
|
299
263
|
|
|
300
264
|
// src/model/selection-model.ts
|
|
301
|
-
import {
|
|
265
|
+
import { Atom } from "@effect-atom/atom-react";
|
|
302
266
|
import { Resource } from "@dxos/context";
|
|
303
267
|
var SelectionModel = class extends Resource {
|
|
268
|
+
_registry;
|
|
304
269
|
_rows;
|
|
270
|
+
_selection;
|
|
271
|
+
_validSelectedIds;
|
|
272
|
+
_hasSelection;
|
|
273
|
+
_allSelected;
|
|
305
274
|
_selectionMode;
|
|
306
|
-
_initialSelection;
|
|
307
275
|
_onSelectionChanged;
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
276
|
+
constructor(registry, rows, selectionMode, initialSelection, onSelectionChanged) {
|
|
277
|
+
super();
|
|
278
|
+
this._registry = registry;
|
|
279
|
+
this._rows = rows;
|
|
280
|
+
this._selectionMode = selectionMode;
|
|
281
|
+
this._onSelectionChanged = onSelectionChanged;
|
|
282
|
+
this._selection = Atom.make(new Set(initialSelection));
|
|
283
|
+
this._validSelectedIds = Atom.make((get) => {
|
|
284
|
+
const rows2 = get(this._rows);
|
|
285
|
+
if (!rows2) {
|
|
286
|
+
return /* @__PURE__ */ new Set();
|
|
287
|
+
}
|
|
288
|
+
const validIds = new Set(rows2.map((row) => row.id));
|
|
289
|
+
const selection = get(this._selection);
|
|
290
|
+
return new Set([
|
|
291
|
+
...selection
|
|
292
|
+
].filter((id) => validIds.has(id)));
|
|
293
|
+
});
|
|
294
|
+
this._hasSelection = Atom.make((get) => get(this._validSelectedIds).size > 0);
|
|
295
|
+
this._allSelected = Atom.make((get) => {
|
|
296
|
+
const rows2 = get(this._rows);
|
|
297
|
+
if (rows2.length === 0) {
|
|
298
|
+
return false;
|
|
299
|
+
}
|
|
300
|
+
const selection = get(this._selection);
|
|
301
|
+
return rows2.every((row) => selection.has(row.id));
|
|
302
|
+
});
|
|
330
303
|
}
|
|
331
304
|
async _open() {
|
|
332
|
-
const
|
|
333
|
-
touch(this._selection.value);
|
|
305
|
+
const selectionUnsubscribe = this._registry.subscribe(this._selection, () => {
|
|
334
306
|
this._onSelectionChanged?.();
|
|
335
307
|
});
|
|
336
|
-
this._ctx.onDispose(
|
|
308
|
+
this._ctx.onDispose(selectionUnsubscribe);
|
|
337
309
|
}
|
|
338
310
|
//
|
|
339
311
|
// Getters
|
|
340
312
|
//
|
|
341
|
-
|
|
313
|
+
/** Get the selection atom for reactive access. */
|
|
314
|
+
get selectionAtom() {
|
|
342
315
|
return this._selection;
|
|
343
316
|
}
|
|
344
|
-
|
|
317
|
+
/** Get the current selection value. */
|
|
318
|
+
get selection() {
|
|
319
|
+
return this._registry.get(this._selection);
|
|
320
|
+
}
|
|
321
|
+
/** Get the hasSelection atom for reactive access. */
|
|
322
|
+
get hasSelectionAtom() {
|
|
345
323
|
return this._hasSelection;
|
|
346
324
|
}
|
|
347
|
-
|
|
325
|
+
/** Check if there is any selection. */
|
|
326
|
+
get hasSelection() {
|
|
327
|
+
return this._registry.get(this._hasSelection);
|
|
328
|
+
}
|
|
329
|
+
/** Get the allRowsSelected atom for reactive access. */
|
|
330
|
+
get allRowsSelectedAtom() {
|
|
348
331
|
return this._allSelected;
|
|
349
332
|
}
|
|
333
|
+
/** Check if all rows are selected. */
|
|
334
|
+
get allRowsSelected() {
|
|
335
|
+
return this._registry.get(this._allSelected);
|
|
336
|
+
}
|
|
350
337
|
get selectionMode() {
|
|
351
338
|
return this._selectionMode;
|
|
352
339
|
}
|
|
353
340
|
getSelectedRows = () => {
|
|
354
|
-
const selectedIds = this._validSelectedIds
|
|
355
|
-
return this._rows.
|
|
341
|
+
const selectedIds = this._registry.get(this._validSelectedIds);
|
|
342
|
+
return this._registry.get(this._rows).filter((row) => selectedIds.has(row.id));
|
|
356
343
|
};
|
|
357
344
|
isRowIndexSelected = (rowIndex) => {
|
|
358
|
-
const row = this._rows
|
|
359
|
-
return this._selection.
|
|
345
|
+
const row = this._registry.get(this._rows)[rowIndex];
|
|
346
|
+
return this._registry.get(this._selection).has(row.id);
|
|
360
347
|
};
|
|
361
348
|
isObjectSelected = (object) => {
|
|
362
|
-
return this._selection.
|
|
349
|
+
return this._registry.get(this._selection).has(object.id);
|
|
363
350
|
};
|
|
364
351
|
//
|
|
365
352
|
// Manipulation
|
|
366
353
|
//
|
|
367
354
|
toggleSelectionForRowIndex = (rowIndex) => {
|
|
368
|
-
const row = this._rows
|
|
369
|
-
const
|
|
355
|
+
const row = this._registry.get(this._rows)[rowIndex];
|
|
356
|
+
const currentSelection = this._registry.get(this._selection);
|
|
357
|
+
const newSelection = new Set(currentSelection);
|
|
370
358
|
if (newSelection.has(row.id)) {
|
|
371
359
|
newSelection.delete(row.id);
|
|
372
360
|
} else {
|
|
@@ -375,195 +363,38 @@ var SelectionModel = class extends Resource {
|
|
|
375
363
|
}
|
|
376
364
|
newSelection.add(row.id);
|
|
377
365
|
}
|
|
378
|
-
this._selection
|
|
366
|
+
this._registry.set(this._selection, newSelection);
|
|
379
367
|
};
|
|
380
368
|
setSelection = (mode) => {
|
|
381
369
|
switch (mode) {
|
|
382
370
|
case "all": {
|
|
383
|
-
this._selection
|
|
371
|
+
this._registry.set(this._selection, new Set(this._registry.get(this._rows).map((row) => row.id)));
|
|
384
372
|
break;
|
|
385
373
|
}
|
|
386
374
|
case "none": {
|
|
387
|
-
this._selection
|
|
375
|
+
this._registry.set(this._selection, /* @__PURE__ */ new Set());
|
|
388
376
|
break;
|
|
389
377
|
}
|
|
390
378
|
}
|
|
391
379
|
};
|
|
392
380
|
};
|
|
393
381
|
|
|
394
|
-
// src/model/table-sorting.ts
|
|
395
|
-
import { computed as computed2, signal as signal2 } from "@preact/signals-core";
|
|
396
|
-
import orderBy from "lodash.orderby";
|
|
397
|
-
import { Format, TypeEnum, getValue } from "@dxos/echo/internal";
|
|
398
|
-
import { formatForDisplay } from "@dxos/react-ui-form";
|
|
399
|
-
var TableSorting = class {
|
|
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 }) {
|
|
408
|
-
this._rows = rows;
|
|
409
|
-
this._getView = getView;
|
|
410
|
-
this._projection = projection;
|
|
411
|
-
this._isDirty = computed2(() => {
|
|
412
|
-
const local = this._localSort.value;
|
|
413
|
-
const viewSort = this._getView().sort?.[0];
|
|
414
|
-
if (local?.type === "cleared") {
|
|
415
|
-
return viewSort !== void 0;
|
|
416
|
-
}
|
|
417
|
-
if (local?.type === "active") {
|
|
418
|
-
if (!viewSort) {
|
|
419
|
-
return true;
|
|
420
|
-
}
|
|
421
|
-
return local.sort.fieldId !== viewSort.fieldId || local.sort.direction !== viewSort.direction;
|
|
422
|
-
}
|
|
423
|
-
return false;
|
|
424
|
-
});
|
|
425
|
-
this.sortedRows = this.initialiseSortedRows();
|
|
426
|
-
}
|
|
427
|
-
/**
|
|
428
|
-
* @reactive
|
|
429
|
-
* @returns Local sort if present, falls back to view sort.
|
|
430
|
-
*/
|
|
431
|
-
get sorting() {
|
|
432
|
-
const local = this._localSort.value;
|
|
433
|
-
if (local?.type === "cleared") {
|
|
434
|
-
return void 0;
|
|
435
|
-
}
|
|
436
|
-
if (local?.type === "active") {
|
|
437
|
-
return local.sort;
|
|
438
|
-
}
|
|
439
|
-
return this._getView().sort?.[0];
|
|
440
|
-
}
|
|
441
|
-
/**
|
|
442
|
-
* @reactive
|
|
443
|
-
* @returns Whether local sort differs from view sort.
|
|
444
|
-
*/
|
|
445
|
-
get isDirty() {
|
|
446
|
-
return this._isDirty.value;
|
|
447
|
-
}
|
|
448
|
-
getDataIndex(displayIndex) {
|
|
449
|
-
return this._displayToDataIndex.get(displayIndex) ?? displayIndex;
|
|
450
|
-
}
|
|
451
|
-
setSort(fieldId, direction) {
|
|
452
|
-
this._localSort.value = {
|
|
453
|
-
type: "active",
|
|
454
|
-
sort: {
|
|
455
|
-
fieldId,
|
|
456
|
-
direction
|
|
457
|
-
}
|
|
458
|
-
};
|
|
459
|
-
}
|
|
460
|
-
toggleSort(fieldId) {
|
|
461
|
-
if (!this.sorting || this.sorting.fieldId !== fieldId) {
|
|
462
|
-
return;
|
|
463
|
-
}
|
|
464
|
-
switch (this.sorting.direction) {
|
|
465
|
-
case "asc": {
|
|
466
|
-
this.setSort(fieldId, "desc");
|
|
467
|
-
break;
|
|
468
|
-
}
|
|
469
|
-
case "desc": {
|
|
470
|
-
this.setSort(fieldId, "asc");
|
|
471
|
-
break;
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
clearSort() {
|
|
476
|
-
this._localSort.value = {
|
|
477
|
-
type: "cleared"
|
|
478
|
-
};
|
|
479
|
-
}
|
|
480
|
-
save() {
|
|
481
|
-
if (this._localSort.value !== void 0) {
|
|
482
|
-
const view = this._getView();
|
|
483
|
-
if (this._localSort.value.type === "active") {
|
|
484
|
-
view.sort = [
|
|
485
|
-
this._localSort.value.sort
|
|
486
|
-
];
|
|
487
|
-
} else {
|
|
488
|
-
view.sort = [];
|
|
489
|
-
}
|
|
490
|
-
this._localSort.value = void 0;
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
//
|
|
494
|
-
// Initialisation.
|
|
495
|
-
//
|
|
496
|
-
initialiseSortedRows() {
|
|
497
|
-
return computed2(() => {
|
|
498
|
-
this._displayToDataIndex.clear();
|
|
499
|
-
const sort = this.sorting;
|
|
500
|
-
if (!sort) {
|
|
501
|
-
return this._rows.value;
|
|
502
|
-
}
|
|
503
|
-
const field = this._projection.fields.find((f) => f.id === sort.fieldId);
|
|
504
|
-
if (!field) {
|
|
505
|
-
return this._rows.value;
|
|
506
|
-
}
|
|
507
|
-
const { props } = this._projection.getFieldProjection(field.id);
|
|
508
|
-
const dataWithIndices = this._rows.value.map((item, index) => {
|
|
509
|
-
const sortValue = this.getSortValue(props, field, item);
|
|
510
|
-
const isEmpty = !(props.type === TypeEnum.Boolean) && (sortValue == null || sortValue === "");
|
|
511
|
-
return {
|
|
512
|
-
item,
|
|
513
|
-
index,
|
|
514
|
-
value: sortValue,
|
|
515
|
-
isEmpty
|
|
516
|
-
};
|
|
517
|
-
});
|
|
518
|
-
const ordered = orderBy(dataWithIndices, [
|
|
519
|
-
"isEmpty",
|
|
520
|
-
"value"
|
|
521
|
-
], [
|
|
522
|
-
"asc",
|
|
523
|
-
sort.direction
|
|
524
|
-
]);
|
|
525
|
-
ordered.forEach(({ index: dataIndex }, displayIndex) => {
|
|
526
|
-
if (displayIndex !== dataIndex) {
|
|
527
|
-
this._displayToDataIndex.set(displayIndex, dataIndex);
|
|
528
|
-
}
|
|
529
|
-
});
|
|
530
|
-
return ordered.map(({ item }) => item);
|
|
531
|
-
});
|
|
532
|
-
}
|
|
533
|
-
getSortValue(props, field, item) {
|
|
534
|
-
const { type, format } = props;
|
|
535
|
-
const value = getValue(item, field.path);
|
|
536
|
-
if (type === TypeEnum.Boolean) {
|
|
537
|
-
return !!value;
|
|
538
|
-
}
|
|
539
|
-
if (type === TypeEnum.Number) {
|
|
540
|
-
return value;
|
|
541
|
-
}
|
|
542
|
-
if (value == null) {
|
|
543
|
-
return value;
|
|
544
|
-
}
|
|
545
|
-
if (format === Format.TypeFormat.SingleSelect) {
|
|
546
|
-
const options = props.options;
|
|
547
|
-
if (!options) {
|
|
548
|
-
return void 0;
|
|
549
|
-
}
|
|
550
|
-
const option = options.find((option2) => option2.id === value);
|
|
551
|
-
return option ? options.indexOf(option) : void 0;
|
|
552
|
-
}
|
|
553
|
-
if (format === Format.TypeFormat.Ref && field.referencePath) {
|
|
554
|
-
const refValue = getValue(value.target, field.referencePath);
|
|
555
|
-
return refValue;
|
|
556
|
-
}
|
|
557
|
-
return formatForDisplay({
|
|
558
|
-
type,
|
|
559
|
-
format,
|
|
560
|
-
value
|
|
561
|
-
});
|
|
562
|
-
}
|
|
563
|
-
};
|
|
564
|
-
|
|
565
382
|
// src/model/table-model.ts
|
|
566
383
|
var __dxlog_file = "/__w/dxos/dxos/packages/ui/react-ui-table/src/model/table-model.ts";
|
|
384
|
+
var createEchoChangeCallback = (table) => ({
|
|
385
|
+
table: (mutate) => Obj.change(table, (mutableTable) => mutate(mutableTable)),
|
|
386
|
+
row: (row, mutate) => {
|
|
387
|
+
if (Obj.isObject(row)) {
|
|
388
|
+
Obj.change(row, (mutableRow) => mutate(mutableRow));
|
|
389
|
+
} else {
|
|
390
|
+
mutate(row);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
});
|
|
394
|
+
var createDirectChangeCallback = (table) => ({
|
|
395
|
+
table: (mutate) => mutate(table),
|
|
396
|
+
row: (row, mutate) => mutate(row)
|
|
397
|
+
});
|
|
567
398
|
var defaultFeatures = {
|
|
568
399
|
selection: {
|
|
569
400
|
enabled: true,
|
|
@@ -573,80 +404,146 @@ var defaultFeatures = {
|
|
|
573
404
|
schemaEditable: false
|
|
574
405
|
};
|
|
575
406
|
var TableModel = class extends Resource2 {
|
|
407
|
+
_registry;
|
|
576
408
|
_object;
|
|
577
409
|
_projection;
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
col: 0
|
|
582
|
-
},
|
|
583
|
-
end: {
|
|
584
|
-
row: 0,
|
|
585
|
-
col: 0
|
|
586
|
-
}
|
|
587
|
-
});
|
|
410
|
+
_db;
|
|
411
|
+
_change;
|
|
412
|
+
_visibleRange;
|
|
588
413
|
_onInsertRow;
|
|
589
414
|
_onDeleteRows;
|
|
590
|
-
|
|
415
|
+
_onColumnDelete;
|
|
591
416
|
_onCellUpdate;
|
|
592
417
|
_onRowOrderChange;
|
|
593
418
|
_onRowAction;
|
|
594
419
|
_rowActions;
|
|
595
420
|
_features;
|
|
596
|
-
_rows
|
|
597
|
-
_draftRows
|
|
421
|
+
_rows;
|
|
422
|
+
_draftRows;
|
|
423
|
+
// In-memory sort state - changes are local until saved.
|
|
424
|
+
_inMemorySort;
|
|
425
|
+
// Derived atom for persisted sort from view.query.ast.
|
|
426
|
+
_persistedSort;
|
|
427
|
+
// Derived atom for current sort (in-memory takes precedence over persisted).
|
|
598
428
|
_sorting;
|
|
429
|
+
// Derived atom for sorted rows (used by rows getter and SelectionModel).
|
|
430
|
+
_sortedRows;
|
|
431
|
+
// Derived atom for viewDirty state.
|
|
432
|
+
_viewDirty;
|
|
599
433
|
_pinnedRows;
|
|
600
434
|
_selection;
|
|
601
435
|
_columnMeta;
|
|
602
|
-
|
|
436
|
+
// Counter atom that increments when cells are updated - allows UI to react to cell changes.
|
|
437
|
+
_cellUpdateCounter;
|
|
438
|
+
constructor({ registry, object, projection, db, change, features = {}, initialSelection = [], pinnedRows = {
|
|
603
439
|
top: [],
|
|
604
440
|
bottom: []
|
|
605
|
-
}, rowActions = [], onCellUpdate,
|
|
441
|
+
}, rowActions = [], onCellUpdate, onColumnDelete, onDeleteRows, onInsertRow, onRowOrderChange, onRowAction }) {
|
|
606
442
|
super();
|
|
443
|
+
this._registry = registry;
|
|
607
444
|
this._object = object;
|
|
608
445
|
this._projection = projection;
|
|
609
446
|
this._projection.normalizeView();
|
|
447
|
+
this._db = db;
|
|
448
|
+
this._change = change ?? createEchoChangeCallback(object);
|
|
610
449
|
this._features = {
|
|
611
450
|
...defaultFeatures,
|
|
612
451
|
...features
|
|
613
452
|
};
|
|
614
453
|
invariant(!(this._features.dataEditable && this._features.selection.enabled && this._features.selection.mode === "single"), "Single selection is not compatible with editable tables.", {
|
|
615
454
|
F: __dxlog_file,
|
|
616
|
-
L:
|
|
455
|
+
L: 196,
|
|
617
456
|
S: this,
|
|
618
457
|
A: [
|
|
619
458
|
"!(this._features.dataEditable && this._features.selection.enabled && this._features.selection.mode === 'single')",
|
|
620
459
|
"'Single selection is not compatible with editable tables.'"
|
|
621
460
|
]
|
|
622
461
|
});
|
|
623
|
-
this.
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
462
|
+
this._visibleRange = Atom2.make({
|
|
463
|
+
start: {
|
|
464
|
+
row: 0,
|
|
465
|
+
col: 0
|
|
466
|
+
},
|
|
467
|
+
end: {
|
|
468
|
+
row: 0,
|
|
469
|
+
col: 0
|
|
470
|
+
}
|
|
471
|
+
});
|
|
472
|
+
this._rows = Atom2.make([]);
|
|
473
|
+
this._draftRows = Atom2.make([]);
|
|
474
|
+
this._inMemorySort = Atom2.make(void 0);
|
|
475
|
+
this._cellUpdateCounter = Atom2.make(0);
|
|
476
|
+
this._persistedSort = Atom2.make((_get) => {
|
|
477
|
+
const viewSnapshot = Obj.getSnapshot(this.view);
|
|
478
|
+
const ast = viewSnapshot.query.ast;
|
|
479
|
+
const orders = extractOrder(ast);
|
|
480
|
+
if (orders && orders.length > 0) {
|
|
481
|
+
const firstOrder = orders[0];
|
|
482
|
+
if (firstOrder.kind === "property") {
|
|
483
|
+
const field = this._projection.getFields().find((f) => f.path === firstOrder.property);
|
|
484
|
+
if (field) {
|
|
485
|
+
return {
|
|
486
|
+
fieldId: field.id,
|
|
487
|
+
direction: firstOrder.direction
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
return void 0;
|
|
493
|
+
});
|
|
494
|
+
this._sorting = Atom2.make((get) => {
|
|
495
|
+
const inMemorySort = get(this._inMemorySort);
|
|
496
|
+
return inMemorySort ?? get(this._persistedSort);
|
|
497
|
+
});
|
|
498
|
+
this._sortedRows = Atom2.make((get) => {
|
|
499
|
+
const rows = get(this._rows);
|
|
500
|
+
const sort = get(this._sorting);
|
|
501
|
+
if (!sort || rows.length === 0) {
|
|
502
|
+
return rows;
|
|
503
|
+
}
|
|
504
|
+
const field = this._projection.getFields().find((f) => f.id === sort.fieldId);
|
|
505
|
+
if (!field) {
|
|
506
|
+
return rows;
|
|
507
|
+
}
|
|
508
|
+
const fieldProjection = this._projection.getFieldProjection(field.id);
|
|
509
|
+
const sorted = [
|
|
510
|
+
...rows
|
|
511
|
+
].sort((a, b) => {
|
|
512
|
+
const aValue = getValue(a, field.path);
|
|
513
|
+
const bValue = getValue(b, field.path);
|
|
514
|
+
return compareValues(aValue, bValue, fieldProjection.props.format, sort.direction);
|
|
515
|
+
});
|
|
516
|
+
return sorted;
|
|
517
|
+
});
|
|
518
|
+
this._selection = new SelectionModel(this._registry, this._sortedRows, this._features.selection.mode ?? "multiple", initialSelection, () => this._onRowOrderChange?.());
|
|
519
|
+
this._viewDirty = Atom2.make((get) => {
|
|
520
|
+
const inMemorySort = get(this._inMemorySort);
|
|
521
|
+
if (!inMemorySort) {
|
|
522
|
+
return false;
|
|
523
|
+
}
|
|
524
|
+
const persisted = get(this._persistedSort);
|
|
525
|
+
if (!persisted) {
|
|
526
|
+
return true;
|
|
527
|
+
}
|
|
528
|
+
return inMemorySort.fieldId !== persisted.fieldId || inMemorySort.direction !== persisted.direction;
|
|
627
529
|
});
|
|
628
|
-
if (sorting.length > 0) {
|
|
629
|
-
const { fieldId, direction } = sorting[0];
|
|
630
|
-
this._sorting.setSort(fieldId, direction);
|
|
631
|
-
}
|
|
632
|
-
this._selection = new SelectionModel(this._sorting.sortedRows, this._features.selection.mode ?? "multiple", initialSelection, () => this._onRowOrderChange?.());
|
|
633
530
|
this._pinnedRows = pinnedRows;
|
|
634
531
|
this._rowActions = rowActions;
|
|
635
532
|
this._onInsertRow = onInsertRow;
|
|
636
533
|
this._onDeleteRows = onDeleteRows;
|
|
637
|
-
this.
|
|
534
|
+
this._onColumnDelete = onColumnDelete;
|
|
638
535
|
this._onCellUpdate = onCellUpdate;
|
|
639
536
|
this._onRowOrderChange = onRowOrderChange;
|
|
640
537
|
this._onRowAction = onRowAction;
|
|
641
538
|
}
|
|
642
539
|
get id() {
|
|
643
|
-
return
|
|
540
|
+
return Obj.getDXN(this._object).toString();
|
|
644
541
|
}
|
|
645
542
|
get view() {
|
|
646
543
|
const view = this._object.view.target;
|
|
647
544
|
invariant(view, "Table model not initialized", {
|
|
648
545
|
F: __dxlog_file,
|
|
649
|
-
L:
|
|
546
|
+
L: 307,
|
|
650
547
|
S: this,
|
|
651
548
|
A: [
|
|
652
549
|
"view",
|
|
@@ -661,26 +558,52 @@ var TableModel = class extends Resource2 {
|
|
|
661
558
|
get projection() {
|
|
662
559
|
return this._projection;
|
|
663
560
|
}
|
|
561
|
+
get db() {
|
|
562
|
+
return this._db;
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* Atom for reactive access to rows with in-memory sorting applied.
|
|
566
|
+
*/
|
|
664
567
|
get rows() {
|
|
665
|
-
return this.
|
|
568
|
+
return this._sortedRows;
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Gets rows with in-memory sorting applied.
|
|
572
|
+
* In-memory sort is local to this instance until saved.
|
|
573
|
+
*/
|
|
574
|
+
getRows() {
|
|
575
|
+
return this._registry.get(this._sortedRows);
|
|
576
|
+
}
|
|
577
|
+
/** Atom for reactive access to cell changes. */
|
|
578
|
+
get cellUpdate() {
|
|
579
|
+
return this._cellUpdateCounter;
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
582
|
+
* Change a row using the configured change callback.
|
|
583
|
+
* Use this instead of directly mutating to ensure consistent mutation handling.
|
|
584
|
+
*/
|
|
585
|
+
changeRow(row, mutate) {
|
|
586
|
+
this._change.row(row, mutate);
|
|
666
587
|
}
|
|
667
588
|
get features() {
|
|
668
589
|
return this._features;
|
|
669
590
|
}
|
|
670
591
|
/**
|
|
671
|
-
*
|
|
592
|
+
* Gets the current sort state.
|
|
593
|
+
* Priority: in-memory sort (local changes) > persisted sort (from query AST).
|
|
672
594
|
*/
|
|
673
|
-
|
|
674
|
-
return this._sorting;
|
|
595
|
+
getSorting() {
|
|
596
|
+
return this._registry.get(this._sorting);
|
|
675
597
|
}
|
|
676
598
|
/**
|
|
677
599
|
* Gets the row data at the specified display index.
|
|
678
600
|
*/
|
|
679
601
|
getRowAt(displayIndex) {
|
|
680
|
-
|
|
602
|
+
const sortedRows = this._registry.get(this._sortedRows);
|
|
603
|
+
if (displayIndex < 0 || displayIndex >= sortedRows.length) {
|
|
681
604
|
return void 0;
|
|
682
605
|
}
|
|
683
|
-
return
|
|
606
|
+
return sortedRows[displayIndex];
|
|
684
607
|
}
|
|
685
608
|
get pinnedRows() {
|
|
686
609
|
return this._pinnedRows;
|
|
@@ -688,7 +611,7 @@ var TableModel = class extends Resource2 {
|
|
|
688
611
|
get columnMeta() {
|
|
689
612
|
invariant(this._columnMeta, void 0, {
|
|
690
613
|
F: __dxlog_file,
|
|
691
|
-
L:
|
|
614
|
+
L: 380,
|
|
692
615
|
S: this,
|
|
693
616
|
A: [
|
|
694
617
|
"this._columnMeta",
|
|
@@ -700,10 +623,6 @@ var TableModel = class extends Resource2 {
|
|
|
700
623
|
get selection() {
|
|
701
624
|
return this._selection;
|
|
702
625
|
}
|
|
703
|
-
/** @reactive */
|
|
704
|
-
get isViewDirty() {
|
|
705
|
-
return this.sorting.isDirty;
|
|
706
|
-
}
|
|
707
626
|
get rowActions() {
|
|
708
627
|
return this._rowActions;
|
|
709
628
|
}
|
|
@@ -717,8 +636,17 @@ var TableModel = class extends Resource2 {
|
|
|
717
636
|
await this._selection.open(this._ctx);
|
|
718
637
|
}
|
|
719
638
|
initializeColumnMeta() {
|
|
720
|
-
this.
|
|
721
|
-
|
|
639
|
+
invariant(this._object.view.target, "View must be loaded before initializing column meta", {
|
|
640
|
+
F: __dxlog_file,
|
|
641
|
+
L: 404,
|
|
642
|
+
S: this,
|
|
643
|
+
A: [
|
|
644
|
+
"this._object.view.target",
|
|
645
|
+
"'View must be loaded before initializing column meta'"
|
|
646
|
+
]
|
|
647
|
+
});
|
|
648
|
+
this._columnMeta = Atom2.make((get) => {
|
|
649
|
+
const fields = get(this._projection.fields);
|
|
722
650
|
const meta = Object.fromEntries(fields.map((field, index) => [
|
|
723
651
|
index,
|
|
724
652
|
{
|
|
@@ -744,49 +672,62 @@ var TableModel = class extends Resource2 {
|
|
|
744
672
|
});
|
|
745
673
|
}
|
|
746
674
|
initializeEffects() {
|
|
747
|
-
const
|
|
748
|
-
touch(this.sorting.sortedRows.value);
|
|
675
|
+
const rowsUnsubscribe = this._registry.subscribe(this._rows, () => {
|
|
749
676
|
this._onRowOrderChange?.();
|
|
750
677
|
});
|
|
751
|
-
this._ctx.onDispose(
|
|
752
|
-
const
|
|
753
|
-
|
|
754
|
-
const
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
678
|
+
this._ctx.onDispose(rowsUnsubscribe);
|
|
679
|
+
const rowSubscriptions = /* @__PURE__ */ new Map();
|
|
680
|
+
const visibleRangeUnsubscribe = this._registry.subscribe(this._visibleRange, () => {
|
|
681
|
+
for (const [id, unsub] of rowSubscriptions) {
|
|
682
|
+
unsub();
|
|
683
|
+
rowSubscriptions.delete(id);
|
|
684
|
+
}
|
|
685
|
+
const { start, end } = this._registry.get(this._visibleRange);
|
|
686
|
+
const sortedRows = this._registry.get(this._sortedRows);
|
|
687
|
+
for (let row = start.row; row <= end.row && row < sortedRows.length; row++) {
|
|
688
|
+
const obj = sortedRows[row];
|
|
689
|
+
if (Obj.isObject(obj) && !rowSubscriptions.has(obj.id)) {
|
|
690
|
+
const unsub = Obj.subscribe(obj, () => {
|
|
691
|
+
this._registry.set(this._cellUpdateCounter, this._registry.get(this._cellUpdateCounter) + 1);
|
|
692
|
+
this._onCellUpdate?.({
|
|
693
|
+
row,
|
|
694
|
+
col: start.col,
|
|
695
|
+
plane: "grid"
|
|
696
|
+
});
|
|
763
697
|
});
|
|
764
|
-
|
|
698
|
+
rowSubscriptions.set(obj.id, unsub);
|
|
699
|
+
}
|
|
765
700
|
}
|
|
766
|
-
return () => rowEffects.forEach((cleanup) => cleanup());
|
|
767
701
|
});
|
|
768
|
-
this._ctx.onDispose(
|
|
769
|
-
|
|
770
|
-
|
|
702
|
+
this._ctx.onDispose(() => {
|
|
703
|
+
visibleRangeUnsubscribe();
|
|
704
|
+
for (const unsub of rowSubscriptions.values()) {
|
|
705
|
+
unsub();
|
|
706
|
+
}
|
|
707
|
+
});
|
|
708
|
+
const draftRowsUnsubscribe = this._registry.subscribe(this._draftRows, () => {
|
|
771
709
|
this._onRowOrderChange?.();
|
|
772
710
|
});
|
|
773
|
-
this._ctx.onDispose(
|
|
711
|
+
this._ctx.onDispose(draftRowsUnsubscribe);
|
|
774
712
|
}
|
|
775
713
|
//
|
|
776
714
|
// Data
|
|
777
715
|
//
|
|
778
716
|
setRows = (obj) => {
|
|
779
|
-
this._rows
|
|
717
|
+
this._registry.set(this._rows, obj);
|
|
780
718
|
};
|
|
781
|
-
getRowCount = () => this.
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
// TODO(ZaymonFC): Return .value instead of exposing the signal.
|
|
719
|
+
getRowCount = () => this._registry.get(this._sortedRows).length;
|
|
720
|
+
getDraftRowCount() {
|
|
721
|
+
return this._registry.get(this._draftRows).length;
|
|
722
|
+
}
|
|
723
|
+
/** Atom for reactive access to draft rows. */
|
|
787
724
|
get draftRows() {
|
|
788
725
|
return this._draftRows;
|
|
789
726
|
}
|
|
727
|
+
/** Gets the current draft rows. */
|
|
728
|
+
getDraftRows() {
|
|
729
|
+
return this._registry.get(this._draftRows);
|
|
730
|
+
}
|
|
790
731
|
/**
|
|
791
732
|
* Checks if a specific field path has validation errors for a given draft row.
|
|
792
733
|
* @param draftRowIndex - The index of the draft row to check
|
|
@@ -794,17 +735,17 @@ var TableModel = class extends Resource2 {
|
|
|
794
735
|
* @returns true if the field has validation errors, false otherwise
|
|
795
736
|
*/
|
|
796
737
|
hasDraftRowValidationError(draftRowIndex, fieldPath) {
|
|
797
|
-
if (draftRowIndex < 0 || draftRowIndex >= this._draftRows.
|
|
738
|
+
if (draftRowIndex < 0 || draftRowIndex >= this._registry.get(this._draftRows).length) {
|
|
798
739
|
return false;
|
|
799
740
|
}
|
|
800
|
-
const draftRow = this._draftRows
|
|
741
|
+
const draftRow = this._registry.get(this._draftRows)[draftRowIndex];
|
|
801
742
|
const validationErrors = draftRow.validationErrors || [];
|
|
802
743
|
return validationErrors.some((error) => error.path === fieldPath);
|
|
803
744
|
}
|
|
804
|
-
getColumnCount = () => this._projection?.
|
|
745
|
+
getColumnCount = () => this._projection?.getFields().length ?? 0;
|
|
805
746
|
insertRow = () => {
|
|
806
747
|
const result = this._onInsertRow?.();
|
|
807
|
-
if (result === "draft" && this._draftRows.
|
|
748
|
+
if (result === "draft" && this._registry.get(this._draftRows).length === 0) {
|
|
808
749
|
this.createDraftRow();
|
|
809
750
|
}
|
|
810
751
|
return result ?? "final";
|
|
@@ -822,16 +763,16 @@ var TableModel = class extends Resource2 {
|
|
|
822
763
|
valid: validationErrors.length === 0,
|
|
823
764
|
validationErrors
|
|
824
765
|
};
|
|
825
|
-
this._draftRows
|
|
826
|
-
...this._draftRows
|
|
766
|
+
this._registry.set(this._draftRows, [
|
|
767
|
+
...this._registry.get(this._draftRows),
|
|
827
768
|
draftRow
|
|
828
|
-
];
|
|
769
|
+
]);
|
|
829
770
|
}
|
|
830
771
|
validateDraftRow(draftRowIndex) {
|
|
831
|
-
if (draftRowIndex < 0 || draftRowIndex >= this._draftRows.
|
|
772
|
+
if (draftRowIndex < 0 || draftRowIndex >= this._registry.get(this._draftRows).length) {
|
|
832
773
|
return;
|
|
833
774
|
}
|
|
834
|
-
const draftRow = this._draftRows
|
|
775
|
+
const draftRow = this._registry.get(this._draftRows)[draftRowIndex];
|
|
835
776
|
const validationErrors = this.validateDraftRowData(draftRow.data);
|
|
836
777
|
const updatedDraftRow = {
|
|
837
778
|
...draftRow,
|
|
@@ -839,69 +780,71 @@ var TableModel = class extends Resource2 {
|
|
|
839
780
|
validationErrors
|
|
840
781
|
};
|
|
841
782
|
const newDraftRows = [
|
|
842
|
-
...this._draftRows
|
|
783
|
+
...this._registry.get(this._draftRows)
|
|
843
784
|
];
|
|
844
785
|
newDraftRows[draftRowIndex] = updatedDraftRow;
|
|
845
|
-
this._draftRows
|
|
786
|
+
this._registry.set(this._draftRows, newDraftRows);
|
|
846
787
|
}
|
|
847
788
|
validateDraftRowData(data) {
|
|
848
789
|
const schema = toEffectSchema(this._projection.baseSchema);
|
|
849
790
|
return validateSchema(schema, data) || [];
|
|
850
791
|
}
|
|
851
792
|
commitDraftRow = (draftRowIndex) => {
|
|
852
|
-
if (draftRowIndex < 0 || draftRowIndex >= this._draftRows.
|
|
793
|
+
if (draftRowIndex < 0 || draftRowIndex >= this._registry.get(this._draftRows).length) {
|
|
853
794
|
return false;
|
|
854
795
|
}
|
|
855
|
-
const draftRow = this._draftRows
|
|
796
|
+
const draftRow = this._registry.get(this._draftRows)[draftRowIndex];
|
|
856
797
|
if (!draftRow.valid) {
|
|
857
798
|
return false;
|
|
858
799
|
}
|
|
859
800
|
const insertRowResult = this._onInsertRow?.(draftRow.data);
|
|
860
801
|
if (insertRowResult === "final") {
|
|
861
|
-
const newDraftRows = this._draftRows.
|
|
862
|
-
this._draftRows
|
|
802
|
+
const newDraftRows = this._registry.get(this._draftRows).filter((_, index) => index !== draftRowIndex);
|
|
803
|
+
this._registry.set(this._draftRows, newDraftRows);
|
|
863
804
|
}
|
|
864
805
|
return insertRowResult === "final";
|
|
865
806
|
};
|
|
866
807
|
deleteRow = (rowIndex) => {
|
|
867
|
-
const
|
|
868
|
-
const obj =
|
|
808
|
+
const sortedRows = this._registry.get(this._sortedRows);
|
|
809
|
+
const obj = sortedRows[rowIndex];
|
|
869
810
|
const objectsToDelete = [];
|
|
870
|
-
if (this.features.selection.enabled && this._selection.hasSelection
|
|
811
|
+
if (this.features.selection.enabled && this._selection.hasSelection) {
|
|
871
812
|
const selectedRows = this._selection.getSelectedRows();
|
|
872
813
|
objectsToDelete.push(...selectedRows);
|
|
873
|
-
} else {
|
|
814
|
+
} else if (obj) {
|
|
874
815
|
objectsToDelete.push(obj);
|
|
875
816
|
}
|
|
876
|
-
|
|
817
|
+
if (objectsToDelete.length > 0) {
|
|
818
|
+
this._onDeleteRows?.(rowIndex, objectsToDelete);
|
|
819
|
+
}
|
|
877
820
|
};
|
|
878
821
|
handleRowAction = (actionId, rowIndex) => {
|
|
879
822
|
if (!this._onRowAction) {
|
|
880
823
|
return;
|
|
881
824
|
}
|
|
882
|
-
const
|
|
883
|
-
const data =
|
|
825
|
+
const sortedRows = this._registry.get(this._sortedRows);
|
|
826
|
+
const data = sortedRows[rowIndex];
|
|
884
827
|
if (data) {
|
|
885
828
|
this._onRowAction(actionId, data);
|
|
886
829
|
}
|
|
887
830
|
};
|
|
888
831
|
getCellData = (cell) => {
|
|
889
832
|
const { col, row, plane } = cell;
|
|
890
|
-
const fields = this._projection?.
|
|
833
|
+
const fields = this._projection?.getFields() ?? [];
|
|
891
834
|
if (col < 0 || col >= fields.length) {
|
|
892
835
|
return void 0;
|
|
893
836
|
}
|
|
894
837
|
const field = fields[col];
|
|
895
838
|
let value;
|
|
896
839
|
if (plane === "frozenRowsEnd") {
|
|
897
|
-
if (row >= 0 && row < this._draftRows.
|
|
898
|
-
value =
|
|
840
|
+
if (row >= 0 && row < this._registry.get(this._draftRows).length) {
|
|
841
|
+
value = getValue(this._registry.get(this._draftRows)[row].data, field.path);
|
|
899
842
|
} else {
|
|
900
843
|
return void 0;
|
|
901
844
|
}
|
|
902
845
|
} else {
|
|
903
|
-
const
|
|
904
|
-
value =
|
|
846
|
+
const sortedRows = this._registry.get(this._sortedRows);
|
|
847
|
+
value = getValue(sortedRows[row], field.path);
|
|
905
848
|
}
|
|
906
849
|
if (value == null) {
|
|
907
850
|
return "";
|
|
@@ -912,7 +855,7 @@ var TableModel = class extends Resource2 {
|
|
|
912
855
|
if (!field.referencePath) {
|
|
913
856
|
return "";
|
|
914
857
|
}
|
|
915
|
-
return
|
|
858
|
+
return getValue(value.target, field.referencePath);
|
|
916
859
|
}
|
|
917
860
|
default: {
|
|
918
861
|
return formatForEditing({
|
|
@@ -924,7 +867,7 @@ var TableModel = class extends Resource2 {
|
|
|
924
867
|
}
|
|
925
868
|
};
|
|
926
869
|
validateCellData = async ({ col, row, plane }, value) => {
|
|
927
|
-
const fields = this._projection?.
|
|
870
|
+
const fields = this._projection?.getFields() ?? [];
|
|
928
871
|
if (col < 0 || col >= fields.length) {
|
|
929
872
|
return {
|
|
930
873
|
valid: false,
|
|
@@ -936,14 +879,14 @@ var TableModel = class extends Resource2 {
|
|
|
936
879
|
const transformedValue = editorTextToCellValue(props, value);
|
|
937
880
|
const isDraftRow = plane === "frozenRowsEnd";
|
|
938
881
|
if (isDraftRow) {
|
|
939
|
-
const isInvalidDraftRowIndex = row < 0 || row >= this._draftRows.
|
|
882
|
+
const isInvalidDraftRowIndex = row < 0 || row >= this._registry.get(this._draftRows).length;
|
|
940
883
|
if (isInvalidDraftRowIndex) {
|
|
941
884
|
return {
|
|
942
885
|
valid: false,
|
|
943
886
|
error: "Invalid draft row index"
|
|
944
887
|
};
|
|
945
888
|
}
|
|
946
|
-
const draftRow = this._draftRows
|
|
889
|
+
const draftRow = this._registry.get(this._draftRows)[row];
|
|
947
890
|
const snapshot = {
|
|
948
891
|
...draftRow.data
|
|
949
892
|
};
|
|
@@ -962,23 +905,24 @@ var TableModel = class extends Resource2 {
|
|
|
962
905
|
valid: true
|
|
963
906
|
};
|
|
964
907
|
} else {
|
|
965
|
-
const
|
|
966
|
-
const currentRow = this._rows.value[rowIdx];
|
|
908
|
+
const currentRow = this._registry.get(this._rows)[row];
|
|
967
909
|
invariant(currentRow, "Invalid row index", {
|
|
968
910
|
F: __dxlog_file,
|
|
969
|
-
L:
|
|
911
|
+
L: 692,
|
|
970
912
|
S: this,
|
|
971
913
|
A: [
|
|
972
914
|
"currentRow",
|
|
973
915
|
"'Invalid row index'"
|
|
974
916
|
]
|
|
975
917
|
});
|
|
976
|
-
const snapshot =
|
|
918
|
+
const snapshot = {
|
|
919
|
+
...getSnapshot(currentRow)
|
|
920
|
+
};
|
|
977
921
|
setValue(snapshot, field.path, transformedValue);
|
|
978
|
-
const schema =
|
|
922
|
+
const schema = Obj.getSchema(currentRow);
|
|
979
923
|
invariant(schema, void 0, {
|
|
980
924
|
F: __dxlog_file,
|
|
981
|
-
L:
|
|
925
|
+
L: 698,
|
|
982
926
|
S: this,
|
|
983
927
|
A: [
|
|
984
928
|
"schema",
|
|
@@ -990,7 +934,7 @@ var TableModel = class extends Resource2 {
|
|
|
990
934
|
const error = validationResult[0];
|
|
991
935
|
invariant(error.path === field.path, void 0, {
|
|
992
936
|
F: __dxlog_file,
|
|
993
|
-
L:
|
|
937
|
+
L: 703,
|
|
994
938
|
S: this,
|
|
995
939
|
A: [
|
|
996
940
|
"error.path === field.path",
|
|
@@ -1009,24 +953,27 @@ var TableModel = class extends Resource2 {
|
|
|
1009
953
|
};
|
|
1010
954
|
setCellData = (cell, value) => {
|
|
1011
955
|
const { col, row, plane } = cell;
|
|
1012
|
-
const fields = this._projection?.
|
|
956
|
+
const fields = this._projection?.getFields() ?? [];
|
|
1013
957
|
if (col < 0 || col >= fields.length) {
|
|
1014
958
|
return;
|
|
1015
959
|
}
|
|
1016
960
|
const field = fields[col];
|
|
1017
961
|
const { props } = this._projection.getFieldProjection(field.id);
|
|
1018
962
|
const transformedValue = editorTextToCellValue(props, value);
|
|
1019
|
-
if (props.format === Format2.TypeFormat.Ref && !
|
|
963
|
+
if (props.format === Format2.TypeFormat.Ref && !Obj.isObject(value)) {
|
|
1020
964
|
return;
|
|
1021
965
|
}
|
|
1022
966
|
if (plane === "frozenRowsEnd") {
|
|
1023
|
-
if (row >= 0 && row < this._draftRows.
|
|
1024
|
-
setValue(this._draftRows
|
|
967
|
+
if (row >= 0 && row < this._registry.get(this._draftRows).length) {
|
|
968
|
+
setValue(this._registry.get(this._draftRows)[row].data, field.path, transformedValue);
|
|
1025
969
|
this.validateDraftRow(row);
|
|
1026
970
|
}
|
|
1027
971
|
} else {
|
|
1028
|
-
const
|
|
1029
|
-
|
|
972
|
+
const sortedRows = this._registry.get(this._sortedRows);
|
|
973
|
+
const rowData = sortedRows[row];
|
|
974
|
+
this._change.row(rowData, (mutableRow) => {
|
|
975
|
+
setValue(mutableRow, field.path, transformedValue);
|
|
976
|
+
});
|
|
1030
977
|
}
|
|
1031
978
|
};
|
|
1032
979
|
/**
|
|
@@ -1035,12 +982,15 @@ var TableModel = class extends Resource2 {
|
|
|
1035
982
|
* @param {(value: any) => any} update - A function that takes the current value and returns the updated value.
|
|
1036
983
|
*/
|
|
1037
984
|
updateCellData({ col, row }, update) {
|
|
1038
|
-
const
|
|
1039
|
-
const fields = this._projection?.fields ?? [];
|
|
985
|
+
const fields = this._projection?.getFields() ?? [];
|
|
1040
986
|
const field = fields[col];
|
|
1041
|
-
const
|
|
987
|
+
const sortedRows = this._registry.get(this._sortedRows);
|
|
988
|
+
const rowData = sortedRows[row];
|
|
989
|
+
const value = getValue(rowData, field.path);
|
|
1042
990
|
const updatedValue = update(value);
|
|
1043
|
-
|
|
991
|
+
this._change.row(rowData, (mutableRow) => {
|
|
992
|
+
setValue(mutableRow, field.path, updatedValue);
|
|
993
|
+
});
|
|
1044
994
|
}
|
|
1045
995
|
/**
|
|
1046
996
|
* Gets the domain-appropriate cell type for a given cell position.
|
|
@@ -1074,21 +1024,23 @@ var TableModel = class extends Resource2 {
|
|
|
1074
1024
|
if (!this._projection) {
|
|
1075
1025
|
return;
|
|
1076
1026
|
}
|
|
1077
|
-
const field = this._projection?.
|
|
1078
|
-
if (field && this.
|
|
1079
|
-
this.
|
|
1027
|
+
const field = this._projection?.getFields().find((field2) => field2.id === fieldId);
|
|
1028
|
+
if (field && this._onColumnDelete) {
|
|
1029
|
+
this._onColumnDelete(field.id);
|
|
1080
1030
|
}
|
|
1081
1031
|
}
|
|
1082
1032
|
//
|
|
1083
1033
|
// Resize
|
|
1084
1034
|
//
|
|
1085
1035
|
setColumnWidth(columnIndex, width) {
|
|
1086
|
-
const fields = this._projection?.
|
|
1036
|
+
const fields = this._projection?.getFields() ?? [];
|
|
1087
1037
|
if (columnIndex < fields.length) {
|
|
1088
1038
|
const newWidth = Math.max(0, width);
|
|
1089
1039
|
const field = fields[columnIndex];
|
|
1090
1040
|
if (field) {
|
|
1091
|
-
this.table
|
|
1041
|
+
this._change.table((mutableTable) => {
|
|
1042
|
+
mutableTable.sizes[field.path] = newWidth;
|
|
1043
|
+
});
|
|
1092
1044
|
}
|
|
1093
1045
|
}
|
|
1094
1046
|
}
|
|
@@ -1104,17 +1056,87 @@ var TableModel = class extends Resource2 {
|
|
|
1104
1056
|
this._pinnedRows.bottom = this._pinnedRows.bottom.filter((index) => index !== rowIndex);
|
|
1105
1057
|
}
|
|
1106
1058
|
//
|
|
1107
|
-
//
|
|
1059
|
+
// Sort operations
|
|
1108
1060
|
//
|
|
1061
|
+
/**
|
|
1062
|
+
* Sets the sort order for a field in-memory (local to this instance).
|
|
1063
|
+
* Use saveView() to persist the sort to the view query.
|
|
1064
|
+
*/
|
|
1065
|
+
setSort(fieldId, direction) {
|
|
1066
|
+
const field = this._projection.getFields().find((f) => f.id === fieldId);
|
|
1067
|
+
if (!field) {
|
|
1068
|
+
return;
|
|
1069
|
+
}
|
|
1070
|
+
this._registry.set(this._inMemorySort, {
|
|
1071
|
+
fieldId,
|
|
1072
|
+
direction
|
|
1073
|
+
});
|
|
1074
|
+
}
|
|
1075
|
+
/**
|
|
1076
|
+
* Toggles the sort direction for a field in-memory.
|
|
1077
|
+
*/
|
|
1078
|
+
toggleSort(fieldId) {
|
|
1079
|
+
const currentSort = this.getSorting();
|
|
1080
|
+
if (!currentSort || currentSort.fieldId !== fieldId) {
|
|
1081
|
+
this.setSort(fieldId, "asc");
|
|
1082
|
+
return;
|
|
1083
|
+
}
|
|
1084
|
+
const newDirection = currentSort.direction === "asc" ? "desc" : "asc";
|
|
1085
|
+
this.setSort(fieldId, newDirection);
|
|
1086
|
+
}
|
|
1087
|
+
/**
|
|
1088
|
+
* Clears the in-memory sort order.
|
|
1089
|
+
*/
|
|
1090
|
+
clearSort() {
|
|
1091
|
+
this._registry.set(this._inMemorySort, void 0);
|
|
1092
|
+
}
|
|
1093
|
+
/**
|
|
1094
|
+
* Saves the current in-memory sort to the view query AST.
|
|
1095
|
+
* This persists the sort so it becomes the default for all viewers.
|
|
1096
|
+
*/
|
|
1109
1097
|
saveView() {
|
|
1110
|
-
this.
|
|
1098
|
+
const view = this.view;
|
|
1099
|
+
const inMemorySort = this._registry.get(this._inMemorySort);
|
|
1100
|
+
const viewSnapshot = Obj.getSnapshot(view);
|
|
1101
|
+
const currentQuery = Query.fromAst(viewSnapshot.query.ast);
|
|
1102
|
+
const baseQuery = this._getBaseQuery(currentQuery);
|
|
1103
|
+
if (inMemorySort) {
|
|
1104
|
+
const field = this._projection.getFields().find((f) => f.id === inMemorySort.fieldId);
|
|
1105
|
+
if (field) {
|
|
1106
|
+
const newQuery = baseQuery.orderBy(Order.property(field.path, inMemorySort.direction));
|
|
1107
|
+
Obj.change(view, (v) => {
|
|
1108
|
+
v.query.ast = newQuery.ast;
|
|
1109
|
+
});
|
|
1110
|
+
}
|
|
1111
|
+
} else {
|
|
1112
|
+
Obj.change(view, (v) => {
|
|
1113
|
+
v.query.ast = baseQuery.ast;
|
|
1114
|
+
});
|
|
1115
|
+
}
|
|
1116
|
+
this._registry.set(this._inMemorySort, void 0);
|
|
1117
|
+
}
|
|
1118
|
+
/**
|
|
1119
|
+
* Extracts the base query without order clauses.
|
|
1120
|
+
*/
|
|
1121
|
+
_getBaseQuery(query) {
|
|
1122
|
+
const ast = query.ast;
|
|
1123
|
+
if (ast.type === "order") {
|
|
1124
|
+
return Query.fromAst(ast.query);
|
|
1125
|
+
}
|
|
1126
|
+
return query;
|
|
1127
|
+
}
|
|
1128
|
+
/**
|
|
1129
|
+
* Checks if the view has unsaved changes (in-memory sort differs from persisted sort).
|
|
1130
|
+
*/
|
|
1131
|
+
getViewDirty() {
|
|
1132
|
+
return this._registry.get(this._viewDirty);
|
|
1111
1133
|
}
|
|
1112
1134
|
};
|
|
1113
1135
|
var editorTextToCellValue = (props, value) => {
|
|
1114
1136
|
switch (props.format) {
|
|
1115
1137
|
case Format2.TypeFormat.Ref: {
|
|
1116
|
-
if (
|
|
1117
|
-
return
|
|
1138
|
+
if (Obj.isObject(value)) {
|
|
1139
|
+
return Ref.make(value);
|
|
1118
1140
|
} else {
|
|
1119
1141
|
return value;
|
|
1120
1142
|
}
|
|
@@ -1141,104 +1163,40 @@ var editorTextToCellValue = (props, value) => {
|
|
|
1141
1163
|
}
|
|
1142
1164
|
};
|
|
1143
1165
|
|
|
1144
|
-
// src/model/modal-controller.ts
|
|
1145
|
-
import { signal as signal4 } from "@preact/signals-core";
|
|
1146
|
-
var ModalController = class {
|
|
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
|
|
1166
|
-
};
|
|
1167
|
-
};
|
|
1168
|
-
showColumnMenu = (fieldId) => {
|
|
1169
|
-
this._state.value = {
|
|
1170
|
-
type: "column",
|
|
1171
|
-
fieldId
|
|
1172
|
-
};
|
|
1173
|
-
};
|
|
1174
|
-
showColumnCreator = () => {
|
|
1175
|
-
this._state.value = {
|
|
1176
|
-
type: "columnSettings",
|
|
1177
|
-
mode: {
|
|
1178
|
-
type: "create"
|
|
1179
|
-
}
|
|
1180
|
-
};
|
|
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(() => {
|
|
1193
|
-
this._state.value = {
|
|
1194
|
-
type: "columnSettings",
|
|
1195
|
-
mode: {
|
|
1196
|
-
type: "edit",
|
|
1197
|
-
fieldId
|
|
1198
|
-
}
|
|
1199
|
-
};
|
|
1200
|
-
});
|
|
1201
|
-
}
|
|
1202
|
-
};
|
|
1203
|
-
close = () => {
|
|
1204
|
-
this._state.value = {
|
|
1205
|
-
type: "closed"
|
|
1206
|
-
};
|
|
1207
|
-
};
|
|
1208
|
-
};
|
|
1209
|
-
|
|
1210
1166
|
// src/model/table-presentation.ts
|
|
1211
|
-
import {
|
|
1167
|
+
import { Atom as Atom3 } from "@effect-atom/atom-react";
|
|
1212
1168
|
import * as Predicate from "effect/Predicate";
|
|
1213
|
-
import { Obj as
|
|
1214
|
-
import { Format as Format3, TypeEnum
|
|
1215
|
-
import { cellClassesForFieldType, formatForDisplay
|
|
1169
|
+
import { Obj as Obj2 } from "@dxos/echo";
|
|
1170
|
+
import { Format as Format3, TypeEnum, getValue as getValue2 } from "@dxos/echo/internal";
|
|
1171
|
+
import { cellClassesForFieldType, formatForDisplay } from "@dxos/react-ui-form";
|
|
1216
1172
|
import { toPlaneCellIndex } from "@dxos/react-ui-grid";
|
|
1217
|
-
import { mx } from "@dxos/react-ui-theme";
|
|
1218
1173
|
import { VIEW_FIELD_LIMIT } from "@dxos/schema";
|
|
1174
|
+
import { mx } from "@dxos/ui-theme";
|
|
1219
1175
|
var TablePresentation = class {
|
|
1220
1176
|
model;
|
|
1177
|
+
_registry;
|
|
1221
1178
|
_visibleRange;
|
|
1222
1179
|
fieldProjectionCache = /* @__PURE__ */ new Map();
|
|
1223
|
-
constructor(
|
|
1224
|
-
start: {
|
|
1225
|
-
row: 0,
|
|
1226
|
-
col: 0
|
|
1227
|
-
},
|
|
1228
|
-
end: {
|
|
1229
|
-
row: 0,
|
|
1230
|
-
col: 0
|
|
1231
|
-
}
|
|
1232
|
-
})) {
|
|
1180
|
+
constructor(registry, model) {
|
|
1233
1181
|
this.model = model;
|
|
1234
|
-
this.
|
|
1182
|
+
this._registry = registry;
|
|
1183
|
+
this._visibleRange = Atom3.make({
|
|
1184
|
+
start: {
|
|
1185
|
+
row: 0,
|
|
1186
|
+
col: 0
|
|
1187
|
+
},
|
|
1188
|
+
end: {
|
|
1189
|
+
row: 0,
|
|
1190
|
+
col: 0
|
|
1191
|
+
}
|
|
1192
|
+
});
|
|
1235
1193
|
}
|
|
1236
1194
|
getCells(range, plane) {
|
|
1237
1195
|
this.fieldProjectionCache.clear();
|
|
1238
1196
|
let cells;
|
|
1239
1197
|
switch (plane) {
|
|
1240
1198
|
case "grid":
|
|
1241
|
-
this._visibleRange
|
|
1199
|
+
this._registry.set(this._visibleRange, range);
|
|
1242
1200
|
cells = this.getMainGridCells(range);
|
|
1243
1201
|
break;
|
|
1244
1202
|
case "frozenRowsStart":
|
|
@@ -1290,7 +1248,7 @@ var TablePresentation = class {
|
|
|
1290
1248
|
const { props } = this.getFieldProjection(field.id);
|
|
1291
1249
|
const cell = {
|
|
1292
1250
|
get value() {
|
|
1293
|
-
const value =
|
|
1251
|
+
const value = getValue2(obj, field.path);
|
|
1294
1252
|
if (value == null) {
|
|
1295
1253
|
return "";
|
|
1296
1254
|
}
|
|
@@ -1307,10 +1265,10 @@ var TablePresentation = class {
|
|
|
1307
1265
|
if (!field.referencePath) {
|
|
1308
1266
|
return "";
|
|
1309
1267
|
}
|
|
1310
|
-
return
|
|
1268
|
+
return getValue2(value.target, field.referencePath);
|
|
1311
1269
|
}
|
|
1312
1270
|
default: {
|
|
1313
|
-
return
|
|
1271
|
+
return formatForDisplay({
|
|
1314
1272
|
type: props.type,
|
|
1315
1273
|
format: props.format,
|
|
1316
1274
|
value
|
|
@@ -1329,8 +1287,8 @@ var TablePresentation = class {
|
|
|
1329
1287
|
classes.push(rowSelectionClasses);
|
|
1330
1288
|
}
|
|
1331
1289
|
cell.className = mx(classes);
|
|
1332
|
-
if (props.type ===
|
|
1333
|
-
const targetArray =
|
|
1290
|
+
if (props.type === TypeEnum.Array) {
|
|
1291
|
+
const targetArray = getValue2(obj, field.path);
|
|
1334
1292
|
if (targetArray && Array.isArray(targetArray)) {
|
|
1335
1293
|
const getLabel = (value) => {
|
|
1336
1294
|
if (!value) {
|
|
@@ -1357,14 +1315,14 @@ var TablePresentation = class {
|
|
|
1357
1315
|
}
|
|
1358
1316
|
}
|
|
1359
1317
|
if (props.format === Format3.TypeFormat.Ref && props.referenceSchema) {
|
|
1360
|
-
const targetObj =
|
|
1318
|
+
const targetObj = getValue2(obj, field.path)?.target;
|
|
1361
1319
|
if (targetObj) {
|
|
1362
|
-
const dxn =
|
|
1363
|
-
cell.accessoryHtml = `<div role="none" class="absolute inline-end-0 inset-block-0 p-[--dx-grid-cell-content-padding-block]"><dx-anchor
|
|
1320
|
+
const dxn = Obj2.getDXN(targetObj)?.toString();
|
|
1321
|
+
cell.accessoryHtml = `<div role="none" class="absolute inline-end-0 inset-block-0 p-[--dx-grid-cell-content-padding-block]"><dx-anchor dxn=${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>`;
|
|
1364
1322
|
}
|
|
1365
1323
|
}
|
|
1366
1324
|
if (props.format === Format3.TypeFormat.Boolean) {
|
|
1367
|
-
const value =
|
|
1325
|
+
const value = getValue2(obj, field.path);
|
|
1368
1326
|
cell.accessoryHtml = tableControls.switch.render({
|
|
1369
1327
|
colIndex,
|
|
1370
1328
|
rowIndex: displayIndex,
|
|
@@ -1373,7 +1331,7 @@ var TablePresentation = class {
|
|
|
1373
1331
|
cell.readonly = "no-text-select";
|
|
1374
1332
|
}
|
|
1375
1333
|
if (props.format === Format3.TypeFormat.SingleSelect) {
|
|
1376
|
-
const value =
|
|
1334
|
+
const value = getValue2(obj, field.path);
|
|
1377
1335
|
const options = this.model.projection.getFieldProjection(field.id).props.options;
|
|
1378
1336
|
if (options) {
|
|
1379
1337
|
const option = options.find((o) => o.id === value);
|
|
@@ -1383,7 +1341,7 @@ var TablePresentation = class {
|
|
|
1383
1341
|
}
|
|
1384
1342
|
}
|
|
1385
1343
|
if (props.format === Format3.TypeFormat.MultiSelect) {
|
|
1386
|
-
const values =
|
|
1344
|
+
const values = getValue2(obj, field.path);
|
|
1387
1345
|
const options = this.model.projection.getFieldProjection(field.id).props.options;
|
|
1388
1346
|
if (options && values && values.length > 0) {
|
|
1389
1347
|
const tags = values.map((value) => {
|
|
@@ -1406,22 +1364,22 @@ var TablePresentation = class {
|
|
|
1406
1364
|
}
|
|
1407
1365
|
getMainGridCells(range) {
|
|
1408
1366
|
const cells = {};
|
|
1409
|
-
const fields = this.model.projection?.
|
|
1367
|
+
const fields = this.model.projection?.getFields() ?? [];
|
|
1410
1368
|
for (let row = range.start.row; row <= range.end.row && row < this.model.getRowCount(); row++) {
|
|
1411
1369
|
for (let col = range.start.col; col <= range.end.col && col < fields.length; col++) {
|
|
1412
1370
|
const field = fields[col];
|
|
1413
1371
|
if (!field) {
|
|
1414
1372
|
continue;
|
|
1415
1373
|
}
|
|
1416
|
-
this.createDataCell(cells, this.model.
|
|
1374
|
+
this.createDataCell(cells, this.model.getRows()[row], field, col, row);
|
|
1417
1375
|
}
|
|
1418
1376
|
}
|
|
1419
1377
|
return cells;
|
|
1420
1378
|
}
|
|
1421
1379
|
getDraftRowCells(range) {
|
|
1422
1380
|
const cells = {};
|
|
1423
|
-
const fields = this.model.projection?.
|
|
1424
|
-
const draftRows = this.model.
|
|
1381
|
+
const fields = this.model.projection?.getFields() ?? [];
|
|
1382
|
+
const draftRows = this.model.getDraftRows();
|
|
1425
1383
|
if (draftRows.length === 0) {
|
|
1426
1384
|
for (let col = range.start.col; col <= range.end.col && col < fields.length; col++) {
|
|
1427
1385
|
cells[toPlaneCellIndex({
|
|
@@ -1461,11 +1419,11 @@ var TablePresentation = class {
|
|
|
1461
1419
|
}
|
|
1462
1420
|
getHeaderCells(range) {
|
|
1463
1421
|
const cells = {};
|
|
1464
|
-
const fields = this.model.projection?.
|
|
1422
|
+
const fields = this.model.projection?.getFields() ?? [];
|
|
1423
|
+
const currentSort = this.model.getSorting();
|
|
1465
1424
|
for (let col = range.start.col; col <= range.end.col && col < fields.length; col++) {
|
|
1466
1425
|
const { field, props } = this.model.projection.getFieldProjection(fields[col].id);
|
|
1467
|
-
const
|
|
1468
|
-
const direction = sorting?.fieldId === field.id ? sorting.direction : void 0;
|
|
1426
|
+
const direction = currentSort?.fieldId === field.id ? currentSort.direction : void 0;
|
|
1469
1427
|
cells[toPlaneCellIndex({
|
|
1470
1428
|
col,
|
|
1471
1429
|
row: 0
|
|
@@ -1548,7 +1506,7 @@ var TablePresentation = class {
|
|
|
1548
1506
|
accessoryHtml: tableControls.checkbox.render({
|
|
1549
1507
|
rowIndex: 0,
|
|
1550
1508
|
header: true,
|
|
1551
|
-
checked: this.model.selection.
|
|
1509
|
+
checked: this.model.selection.allRowsSelected
|
|
1552
1510
|
}),
|
|
1553
1511
|
className: "!bg-toolbarSurface",
|
|
1554
1512
|
readonly: true,
|
|
@@ -1563,7 +1521,7 @@ var TablePresentation = class {
|
|
|
1563
1521
|
row: 0
|
|
1564
1522
|
})]: {
|
|
1565
1523
|
accessoryHtml: this.model.features.schemaEditable ? tableButtons.addColumn.render({
|
|
1566
|
-
disabled: (this.model.projection?.
|
|
1524
|
+
disabled: (this.model.projection?.getFields()?.length ?? 0) >= VIEW_FIELD_LIMIT
|
|
1567
1525
|
}) : void 0,
|
|
1568
1526
|
className: "!bg-toolbarSurface",
|
|
1569
1527
|
readonly: true,
|
|
@@ -1573,7 +1531,7 @@ var TablePresentation = class {
|
|
|
1573
1531
|
}
|
|
1574
1532
|
getDraftActionCells(range) {
|
|
1575
1533
|
const cells = {};
|
|
1576
|
-
const draftRows = this.model.
|
|
1534
|
+
const draftRows = this.model.getDraftRows();
|
|
1577
1535
|
if (draftRows.length === 0) {
|
|
1578
1536
|
cells[toPlaneCellIndex({
|
|
1579
1537
|
col: 0,
|
|
@@ -1604,7 +1562,7 @@ var TablePresentation = class {
|
|
|
1604
1562
|
}
|
|
1605
1563
|
getDraftIconCells(range) {
|
|
1606
1564
|
const cells = {};
|
|
1607
|
-
const draftRows = this.model.
|
|
1565
|
+
const draftRows = this.model.getDraftRows();
|
|
1608
1566
|
for (let row = range.start.row; row <= range.end.row; row++) {
|
|
1609
1567
|
cells[toPlaneCellIndex({
|
|
1610
1568
|
col: 0,
|
|
@@ -1643,12 +1601,12 @@ var cellClassesForRowSelection = (selected, selectionMode) => {
|
|
|
1643
1601
|
|
|
1644
1602
|
// src/hooks/useAddRow.ts
|
|
1645
1603
|
import { useCallback } from "react";
|
|
1646
|
-
import { Obj as
|
|
1647
|
-
var useAddRow = ({
|
|
1604
|
+
import { Obj as Obj3 } from "@dxos/echo";
|
|
1605
|
+
var useAddRow = ({ db, schema }) => {
|
|
1648
1606
|
return useCallback((data) => {
|
|
1649
|
-
if (
|
|
1607
|
+
if (db && schema) {
|
|
1650
1608
|
try {
|
|
1651
|
-
|
|
1609
|
+
db.add(Obj3.make(schema, data ?? {}));
|
|
1652
1610
|
return "final";
|
|
1653
1611
|
} catch (error) {
|
|
1654
1612
|
return "draft";
|
|
@@ -1656,129 +1614,137 @@ var useAddRow = ({ space, schema }) => {
|
|
|
1656
1614
|
}
|
|
1657
1615
|
return "final";
|
|
1658
1616
|
}, [
|
|
1659
|
-
|
|
1617
|
+
db,
|
|
1660
1618
|
schema
|
|
1661
1619
|
]);
|
|
1662
1620
|
};
|
|
1663
1621
|
|
|
1664
1622
|
// src/hooks/useProjectionModel.ts
|
|
1665
|
-
import {
|
|
1666
|
-
import { Type
|
|
1667
|
-
import {
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1623
|
+
import { useState } from "react";
|
|
1624
|
+
import { Type } from "@dxos/echo";
|
|
1625
|
+
import { useAsyncEffect } from "@dxos/react-ui";
|
|
1626
|
+
import { ProjectionModel, createEchoChangeCallback as createEchoChangeCallback2 } from "@dxos/schema";
|
|
1627
|
+
var useProjectionModel = (schema, table, registry) => {
|
|
1628
|
+
const [projection, setProjection] = useState();
|
|
1629
|
+
useAsyncEffect(async () => {
|
|
1630
|
+
if (schema && table) {
|
|
1631
|
+
const view = await table.view.load();
|
|
1632
|
+
const jsonSchema = Type.isMutable(schema) ? schema.jsonSchema : Type.toJsonSchema(schema);
|
|
1633
|
+
const change = createEchoChangeCallback2(view, Type.isMutable(schema) ? schema : void 0);
|
|
1634
|
+
const projection2 = new ProjectionModel({
|
|
1635
|
+
registry,
|
|
1636
|
+
view,
|
|
1637
|
+
baseSchema: jsonSchema,
|
|
1638
|
+
change
|
|
1639
|
+
});
|
|
1640
|
+
projection2.normalizeView();
|
|
1641
|
+
setProjection(projection2);
|
|
1642
|
+
}
|
|
1643
|
+
}, [
|
|
1644
|
+
schema,
|
|
1645
|
+
table,
|
|
1646
|
+
registry
|
|
1647
|
+
]);
|
|
1648
|
+
return projection;
|
|
1649
|
+
};
|
|
1678
1650
|
|
|
1679
1651
|
// src/hooks/useTableModel.ts
|
|
1680
|
-
import {
|
|
1681
|
-
import {
|
|
1682
|
-
import
|
|
1683
|
-
import { useEffect, useMemo as useMemo2, useState } from "react";
|
|
1684
|
-
import { Obj as Obj5 } from "@dxos/echo";
|
|
1652
|
+
import { RegistryContext } from "@effect-atom/atom-react";
|
|
1653
|
+
import { useContext, useEffect, useMemo, useState as useState2 } from "react";
|
|
1654
|
+
import { Obj as Obj4 } from "@dxos/echo";
|
|
1685
1655
|
import { useSelected, useSelectionActions } from "@dxos/react-ui-attention";
|
|
1686
1656
|
import { isNonNullable } from "@dxos/util";
|
|
1687
|
-
var useTableModel = ({ object, projection, rows, rowActions, features, onSelectionChanged, onRowAction, ...props }) => {
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
setModel(model2);
|
|
1712
|
-
});
|
|
1713
|
-
return () => {
|
|
1714
|
-
clearTimeout(t);
|
|
1715
|
-
void model2?.close();
|
|
1716
|
-
};
|
|
1717
|
-
}, [
|
|
1718
|
-
object,
|
|
1719
|
-
projection,
|
|
1720
|
-
features,
|
|
1721
|
-
rowActions,
|
|
1722
|
-
initialSelection
|
|
1723
|
-
]);
|
|
1724
|
-
useEffect(() => {
|
|
1725
|
-
if (rows) {
|
|
1726
|
-
const sortedRows = orderBy2(rows, [
|
|
1727
|
-
(row) => String(row.id)
|
|
1728
|
-
], [
|
|
1729
|
-
"asc"
|
|
1730
|
-
]);
|
|
1731
|
-
model?.setRows(sortedRows);
|
|
1732
|
-
}
|
|
1733
|
-
}, [
|
|
1734
|
-
model,
|
|
1735
|
-
rows
|
|
1736
|
-
]);
|
|
1737
|
-
const { multiSelect, clear } = useSelectionActions([
|
|
1738
|
-
model?.id
|
|
1739
|
-
].filter(isNonNullable));
|
|
1740
|
-
useEffect(() => {
|
|
1741
|
-
if (!model) {
|
|
1742
|
-
return;
|
|
1743
|
-
}
|
|
1744
|
-
const unsubscribe = effect3(() => {
|
|
1745
|
-
const selectedItems = [
|
|
1746
|
-
...model.selection.selection.value
|
|
1747
|
-
];
|
|
1748
|
-
multiSelect(selectedItems);
|
|
1749
|
-
onSelectionChanged?.(selectedItems);
|
|
1657
|
+
var useTableModel = ({ object, projection, db, rows, rowActions, features, onSelectionChanged, onRowAction, ...props }) => {
|
|
1658
|
+
const registry = useContext(RegistryContext);
|
|
1659
|
+
const selected = useSelected(object && Obj4.getDXN(object).toString(), "multi");
|
|
1660
|
+
const initialSelection = useMemo(() => selected, [
|
|
1661
|
+
object
|
|
1662
|
+
]);
|
|
1663
|
+
const [model, setModel] = useState2();
|
|
1664
|
+
useEffect(() => {
|
|
1665
|
+
if (!object || !projection) {
|
|
1666
|
+
return;
|
|
1667
|
+
}
|
|
1668
|
+
let model2;
|
|
1669
|
+
const t = setTimeout(async () => {
|
|
1670
|
+
model2 = new TableModel({
|
|
1671
|
+
registry,
|
|
1672
|
+
object,
|
|
1673
|
+
projection,
|
|
1674
|
+
db,
|
|
1675
|
+
change: createEchoChangeCallback(object),
|
|
1676
|
+
features,
|
|
1677
|
+
rowActions,
|
|
1678
|
+
initialSelection,
|
|
1679
|
+
onRowAction,
|
|
1680
|
+
...props
|
|
1750
1681
|
});
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1682
|
+
await model2.open();
|
|
1683
|
+
setModel(model2);
|
|
1684
|
+
});
|
|
1685
|
+
return () => {
|
|
1686
|
+
clearTimeout(t);
|
|
1687
|
+
void model2?.close();
|
|
1688
|
+
};
|
|
1689
|
+
}, [
|
|
1690
|
+
registry,
|
|
1691
|
+
object,
|
|
1692
|
+
projection,
|
|
1693
|
+
features,
|
|
1694
|
+
rowActions,
|
|
1695
|
+
initialSelection
|
|
1696
|
+
]);
|
|
1697
|
+
useEffect(() => {
|
|
1698
|
+
if (rows && model) {
|
|
1699
|
+
model.setRows(rows);
|
|
1700
|
+
}
|
|
1701
|
+
}, [
|
|
1702
|
+
model,
|
|
1703
|
+
rows
|
|
1704
|
+
]);
|
|
1705
|
+
const { multiSelect, clear } = useSelectionActions([
|
|
1706
|
+
model?.id
|
|
1707
|
+
].filter(isNonNullable));
|
|
1708
|
+
useEffect(() => {
|
|
1709
|
+
if (!model) {
|
|
1710
|
+
return;
|
|
1711
|
+
}
|
|
1712
|
+
const unsubscribe = registry.subscribe(model.selection.selectionAtom, () => {
|
|
1713
|
+
const selectedItems = [
|
|
1714
|
+
...model.selection.selection
|
|
1715
|
+
];
|
|
1716
|
+
multiSelect(selectedItems);
|
|
1717
|
+
onSelectionChanged?.(selectedItems);
|
|
1718
|
+
});
|
|
1719
|
+
return () => {
|
|
1720
|
+
clear();
|
|
1721
|
+
unsubscribe();
|
|
1722
|
+
};
|
|
1723
|
+
}, [
|
|
1724
|
+
registry,
|
|
1725
|
+
model,
|
|
1726
|
+
onSelectionChanged
|
|
1727
|
+
]);
|
|
1728
|
+
return model;
|
|
1763
1729
|
};
|
|
1764
1730
|
|
|
1765
1731
|
export {
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1732
|
+
extractOrder,
|
|
1733
|
+
getSortValue,
|
|
1734
|
+
compareValues,
|
|
1769
1735
|
BUTTON_IDENTIFIERS,
|
|
1770
1736
|
tableButtons,
|
|
1771
1737
|
CONTROL_IDENTIFIERS,
|
|
1772
1738
|
CheckboxStory,
|
|
1773
1739
|
SwitchStory,
|
|
1774
1740
|
tableControls,
|
|
1775
|
-
|
|
1741
|
+
createEchoChangeCallback,
|
|
1742
|
+
createDirectChangeCallback,
|
|
1776
1743
|
TableModel,
|
|
1777
|
-
ModalController,
|
|
1778
1744
|
TablePresentation,
|
|
1779
1745
|
cellClassesForRowSelection,
|
|
1780
1746
|
useAddRow,
|
|
1781
1747
|
useProjectionModel,
|
|
1782
1748
|
useTableModel
|
|
1783
1749
|
};
|
|
1784
|
-
//# sourceMappingURL=chunk-
|
|
1750
|
+
//# sourceMappingURL=chunk-DPNSZHU5.mjs.map
|