@dxos/react-ui-table 0.7.5-main.9cb18ac → 0.7.5-main.9d2a38b
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-AT7O4RAD.mjs → chunk-T7CTRLHA.mjs} +2 -2
- package/dist/lib/browser/{chunk-AT7O4RAD.mjs.map → chunk-T7CTRLHA.mjs.map} +1 -1
- package/dist/lib/browser/index.mjs +418 -276
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/types/index.mjs +1 -1
- package/dist/lib/node/{chunk-YSBXNBDJ.cjs → chunk-XQRKYO7Q.cjs} +6 -6
- package/dist/lib/node/chunk-XQRKYO7Q.cjs.map +7 -0
- package/dist/lib/node/index.cjs +410 -262
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/types/index.cjs +3 -3
- package/dist/lib/node/types/index.cjs.map +1 -1
- package/dist/lib/node-esm/{chunk-6OH2NHUX.mjs → chunk-6HE6MLBK.mjs} +2 -2
- package/dist/lib/node-esm/{chunk-6OH2NHUX.mjs.map → chunk-6HE6MLBK.mjs.map} +1 -1
- package/dist/lib/node-esm/index.mjs +418 -276
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/types/index.mjs +1 -1
- package/dist/types/src/components/Table/Table.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
- package/dist/types/src/components/TableToolbar/TableToolbar.d.ts +18 -0
- package/dist/types/src/components/TableToolbar/TableToolbar.d.ts.map +1 -0
- package/dist/types/src/components/TableToolbar/index.d.ts +2 -0
- package/dist/types/src/components/TableToolbar/index.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +1 -1
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/components/testing.d.ts +1 -1
- package/dist/types/src/model/table-model.d.ts +11 -19
- package/dist/types/src/model/table-model.d.ts.map +1 -1
- package/dist/types/src/model/table-presentation.d.ts.map +1 -1
- package/dist/types/src/model/table-sorting.d.ts +53 -0
- package/dist/types/src/model/table-sorting.d.ts.map +1 -0
- package/dist/types/src/translations.d.ts +2 -1
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/table.d.ts +3 -3
- package/dist/types/src/types/table.d.ts.map +1 -1
- package/dist/types/src/util/table-buttons.d.ts +15 -1
- package/dist/types/src/util/table-buttons.d.ts.map +1 -1
- package/dist/types/src/util/table.d.ts +2 -1
- package/dist/types/src/util/table.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +30 -29
- package/src/components/Table/ColumnActionsMenu.tsx +4 -4
- package/src/components/Table/Table.stories.tsx +33 -21
- package/src/components/Table/Table.tsx +4 -0
- package/src/components/TableToolbar/TableToolbar.tsx +72 -0
- package/src/components/{Toolbar → TableToolbar}/index.ts +1 -1
- package/src/components/index.ts +1 -1
- package/src/model/table-model.test.ts +0 -5
- package/src/model/table-model.ts +40 -98
- package/src/model/table-presentation.ts +7 -1
- package/src/model/table-sorting.ts +201 -0
- package/src/playwright/smoke.spec.ts +18 -11
- package/src/translations.ts +2 -1
- package/src/types/table.ts +1 -1
- package/src/util/table-buttons.ts +33 -3
- package/src/util/table.ts +78 -52
- package/dist/lib/node/chunk-YSBXNBDJ.cjs.map +0 -7
- package/dist/types/src/components/Toolbar/Toolbar.d.ts +0 -21
- package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +0 -1
- package/dist/types/src/components/Toolbar/common.d.ts +0 -14
- package/dist/types/src/components/Toolbar/common.d.ts.map +0 -1
- package/dist/types/src/components/Toolbar/index.d.ts +0 -2
- package/dist/types/src/components/Toolbar/index.d.ts.map +0 -1
- package/src/components/Toolbar/Toolbar.tsx +0 -87
- package/src/components/Toolbar/common.tsx +0 -71
|
@@ -2,7 +2,7 @@ import { createRequire } from 'node:module';const require = createRequire(import
|
|
|
2
2
|
import {
|
|
3
3
|
TableSchema,
|
|
4
4
|
TableType
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-6HE6MLBK.mjs";
|
|
6
6
|
|
|
7
7
|
// packages/ui/react-ui-table/src/translations.ts
|
|
8
8
|
var translationKey = "table";
|
|
@@ -18,7 +18,7 @@ var translations_default = [
|
|
|
18
18
|
"new schema": "New schema",
|
|
19
19
|
"continue label": "Continue",
|
|
20
20
|
"create stack section label": "Create table",
|
|
21
|
-
"add row": "Add row",
|
|
21
|
+
"add row label": "Add row",
|
|
22
22
|
"create comment": "Create thread",
|
|
23
23
|
"column action sort descending": "Sort Descending",
|
|
24
24
|
"column action sort ascending": "Sort Ascending",
|
|
@@ -29,7 +29,8 @@ var translations_default = [
|
|
|
29
29
|
"bulk delete row label": "Delete selected rows",
|
|
30
30
|
"column deleted label": "Column deleted",
|
|
31
31
|
"new column button label": "Create column",
|
|
32
|
-
"create new object label": "Create new object \u201C{{text}}\u201D"
|
|
32
|
+
"create new object label": "Create new object \u201C{{text}}\u201D",
|
|
33
|
+
"save view label": "Save changes to view"
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
36
|
}
|
|
@@ -37,7 +38,7 @@ var translations_default = [
|
|
|
37
38
|
|
|
38
39
|
// packages/ui/react-ui-table/src/components/Table/Table.tsx
|
|
39
40
|
import React7, { forwardRef, useCallback as useCallback4, useImperativeHandle, useState as useState2, useMemo as useMemo4 } from "react";
|
|
40
|
-
import { getValue as
|
|
41
|
+
import { getValue as getValue4 } from "@dxos/echo-schema";
|
|
41
42
|
import { invariant as invariant3 } from "@dxos/invariant";
|
|
42
43
|
import { Filter, getSpace as getSpace4, fullyQualifiedId } from "@dxos/react-client/echo";
|
|
43
44
|
import { useTranslation as useTranslation3 } from "@dxos/react-ui";
|
|
@@ -55,7 +56,7 @@ var ColumnActionsMenu = ({ model, modals }) => {
|
|
|
55
56
|
if (state?.type !== "column") {
|
|
56
57
|
return null;
|
|
57
58
|
}
|
|
58
|
-
const currentSort = model.sorting;
|
|
59
|
+
const currentSort = model.sorting?.sorting;
|
|
59
60
|
const isCurrentColumnSorted = currentSort?.fieldId === state.fieldId;
|
|
60
61
|
return /* @__PURE__ */ React.createElement(DropdownMenu.Root, {
|
|
61
62
|
modal: false,
|
|
@@ -65,13 +66,13 @@ var ColumnActionsMenu = ({ model, modals }) => {
|
|
|
65
66
|
virtualRef: modals.trigger
|
|
66
67
|
}), /* @__PURE__ */ React.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React.createElement(DropdownMenu.Content, null, /* @__PURE__ */ React.createElement(DropdownMenu.Viewport, null, (!isCurrentColumnSorted || currentSort?.direction === "asc") && /* @__PURE__ */ React.createElement(DropdownMenu.Item, {
|
|
67
68
|
"data-testid": "column-sort-descending",
|
|
68
|
-
onClick: () => model.setSort(state.fieldId, "desc")
|
|
69
|
+
onClick: () => model.sorting?.setSort(state.fieldId, "desc")
|
|
69
70
|
}, t("column action sort descending")), (!isCurrentColumnSorted || currentSort?.direction === "desc") && /* @__PURE__ */ React.createElement(DropdownMenu.Item, {
|
|
70
71
|
"data-testid": "column-sort-ascending",
|
|
71
|
-
onClick: () => model.setSort(state.fieldId, "asc")
|
|
72
|
+
onClick: () => model.sorting?.setSort(state.fieldId, "asc")
|
|
72
73
|
}, t("column action sort ascending")), isCurrentColumnSorted && /* @__PURE__ */ React.createElement(DropdownMenu.Item, {
|
|
73
74
|
"data-testid": "column-clear-sort",
|
|
74
|
-
onClick: () => model.clearSort()
|
|
75
|
+
onClick: () => model.sorting?.clearSort()
|
|
75
76
|
}, t("column action clear sorting")), model.getColumnCount() > 1 && /* @__PURE__ */ React.createElement(DropdownMenu.Item, {
|
|
76
77
|
"data-testid": "column-delete",
|
|
77
78
|
onClick: () => model.deleteColumn(state.fieldId)
|
|
@@ -286,14 +287,13 @@ var RowActionsMenu = ({ model, modals }) => {
|
|
|
286
287
|
};
|
|
287
288
|
|
|
288
289
|
// packages/ui/react-ui-table/src/model/table-model.ts
|
|
289
|
-
import { computed as
|
|
290
|
-
import orderBy from "lodash.orderby";
|
|
290
|
+
import { computed as computed3, effect as effect2, signal as signal3 } from "@preact/signals-core";
|
|
291
291
|
import { Resource as Resource2 } from "@dxos/context";
|
|
292
|
-
import {
|
|
292
|
+
import { FormatEnum as FormatEnum3, getValue as getValue2, setValue } from "@dxos/echo-schema";
|
|
293
293
|
import { invariant } from "@dxos/invariant";
|
|
294
294
|
import { isReactiveObject, makeRef as makeRef2 } from "@dxos/live-object";
|
|
295
295
|
import { PublicKey as PublicKey2 } from "@dxos/react-client";
|
|
296
|
-
import {
|
|
296
|
+
import { formatForEditing, parseValue } from "@dxos/react-ui-form";
|
|
297
297
|
|
|
298
298
|
// packages/ui/react-ui-table/src/model/selection-model.ts
|
|
299
299
|
import { computed, effect, signal } from "@preact/signals-core";
|
|
@@ -304,73 +304,81 @@ var touch = (value) => value;
|
|
|
304
304
|
|
|
305
305
|
// packages/ui/react-ui-table/src/util/table.ts
|
|
306
306
|
import { AST, Format, FormatEnum, S as S2, TypedObject, TypeEnum } from "@dxos/echo-schema";
|
|
307
|
-
import { log } from "@dxos/log";
|
|
308
307
|
import { PublicKey } from "@dxos/react-client";
|
|
309
308
|
import { create as create2, makeRef } from "@dxos/react-client/echo";
|
|
310
|
-
import { createFieldId, createView, ViewProjection } from "@dxos/schema";
|
|
311
|
-
var
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
S: void 0,
|
|
319
|
-
C: (f, a) => f(...a)
|
|
320
|
-
});
|
|
321
|
-
const ContactSchema = TypedObject({
|
|
322
|
-
typename: `example.com/type/${PublicKey.random().truncate()}`,
|
|
323
|
-
version: "0.1.0"
|
|
324
|
-
})({
|
|
325
|
-
name: S2.optional(S2.String).annotations({
|
|
326
|
-
[AST.TitleAnnotationId]: "Name"
|
|
327
|
-
}),
|
|
328
|
-
active: S2.optional(S2.Boolean),
|
|
329
|
-
email: S2.optional(Format.Email),
|
|
330
|
-
salary: S2.optional(Format.Currency()).annotations({
|
|
331
|
-
[AST.TitleAnnotationId]: "Salary"
|
|
332
|
-
})
|
|
333
|
-
});
|
|
334
|
-
const [contactSchema] = await space.db.schemaRegistry.register([
|
|
335
|
-
ContactSchema
|
|
336
|
-
]);
|
|
337
|
-
table.view = makeRef(createView({
|
|
338
|
-
name: "Test",
|
|
339
|
-
typename: contactSchema.typename,
|
|
340
|
-
jsonSchema: contactSchema.jsonSchema,
|
|
341
|
-
fields: [
|
|
342
|
-
"name",
|
|
343
|
-
"active",
|
|
344
|
-
"email",
|
|
345
|
-
"salary"
|
|
346
|
-
]
|
|
347
|
-
}));
|
|
348
|
-
const projection = new ViewProjection(contactSchema, table.view.target);
|
|
349
|
-
projection.setFieldProjection({
|
|
350
|
-
field: {
|
|
351
|
-
id: table.view.target.fields.find((f) => f.path === "salary").id,
|
|
352
|
-
path: "salary",
|
|
353
|
-
size: 150
|
|
309
|
+
import { createFieldId, createView, getSchemaProperties, ViewProjection } from "@dxos/schema";
|
|
310
|
+
var initializeTable = async ({ space, table, initialRow = true, initialSchema }) => {
|
|
311
|
+
if (initialSchema) {
|
|
312
|
+
const schema = await space.db.schemaRegistry.query({
|
|
313
|
+
typename: initialSchema
|
|
314
|
+
}).firstOrUndefined();
|
|
315
|
+
if (!schema) {
|
|
316
|
+
throw new Error(`Schema not found: ${initialSchema}`);
|
|
354
317
|
}
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
318
|
+
const fields = getSchemaProperties(schema.ast).filter((prop) => prop.type !== "object" || prop.format === FormatEnum.Ref).map((prop) => prop.name);
|
|
319
|
+
table.view = makeRef(createView({
|
|
320
|
+
// TODO(ZaymonFC): Don't hardcode name?
|
|
321
|
+
name: "View",
|
|
322
|
+
typename: schema.typename,
|
|
323
|
+
jsonSchema: schema.jsonSchema,
|
|
324
|
+
fields
|
|
325
|
+
}));
|
|
326
|
+
return schema;
|
|
327
|
+
} else {
|
|
328
|
+
const ContactSchema = TypedObject({
|
|
329
|
+
typename: `example.com/type/${PublicKey.random().truncate()}`,
|
|
330
|
+
version: "0.1.0"
|
|
331
|
+
})({
|
|
332
|
+
name: S2.optional(S2.String).annotations({
|
|
333
|
+
[AST.TitleAnnotationId]: "Name"
|
|
334
|
+
}),
|
|
335
|
+
active: S2.optional(S2.Boolean),
|
|
336
|
+
email: S2.optional(Format.Email),
|
|
337
|
+
salary: S2.optional(Format.Currency()).annotations({
|
|
338
|
+
[AST.TitleAnnotationId]: "Salary"
|
|
339
|
+
})
|
|
340
|
+
});
|
|
341
|
+
const [contactSchema] = await space.db.schemaRegistry.register([
|
|
342
|
+
ContactSchema
|
|
343
|
+
]);
|
|
344
|
+
table.view = makeRef(createView({
|
|
345
|
+
name: "View",
|
|
346
|
+
typename: contactSchema.typename,
|
|
347
|
+
jsonSchema: contactSchema.jsonSchema,
|
|
348
|
+
fields: [
|
|
349
|
+
"name",
|
|
350
|
+
"active",
|
|
351
|
+
"email",
|
|
352
|
+
"salary"
|
|
353
|
+
]
|
|
354
|
+
}));
|
|
355
|
+
const projection = new ViewProjection(contactSchema, table.view.target);
|
|
356
|
+
projection.setFieldProjection({
|
|
357
|
+
field: {
|
|
358
|
+
id: table.view.target.fields.find((f) => f.path === "salary").id,
|
|
359
|
+
path: "salary",
|
|
360
|
+
size: 150
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
projection.setFieldProjection({
|
|
364
|
+
field: {
|
|
365
|
+
id: createFieldId(),
|
|
366
|
+
path: "manager",
|
|
367
|
+
referencePath: "name"
|
|
368
|
+
},
|
|
369
|
+
props: {
|
|
370
|
+
property: "manager",
|
|
371
|
+
type: TypeEnum.Ref,
|
|
372
|
+
format: FormatEnum.Ref,
|
|
373
|
+
referenceSchema: contactSchema.typename,
|
|
374
|
+
title: "Manager"
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
if (initialRow) {
|
|
378
|
+
space.db.add(create2(contactSchema, {}));
|
|
368
379
|
}
|
|
369
|
-
|
|
370
|
-
if (initialRow) {
|
|
371
|
-
space.db.add(create2(contactSchema, {}));
|
|
380
|
+
return contactSchema;
|
|
372
381
|
}
|
|
373
|
-
return contactSchema;
|
|
374
382
|
};
|
|
375
383
|
|
|
376
384
|
// packages/ui/react-ui-table/src/util/table-buttons.ts
|
|
@@ -378,11 +386,13 @@ var BUTTON_IDENTIFIERS = {
|
|
|
378
386
|
columnSettings: "data-table-column-settings-button",
|
|
379
387
|
newColumn: "data-table-new-column-button",
|
|
380
388
|
referencedCell: "data-table-ref-cell-button",
|
|
381
|
-
rowMenu: "data-table-row-menu-button"
|
|
389
|
+
rowMenu: "data-table-row-menu-button",
|
|
390
|
+
sort: "data-table-sort-button"
|
|
382
391
|
};
|
|
383
|
-
var createButton = ({ attr, data, disabled = false, icon, testId }) => {
|
|
392
|
+
var createButton = ({ attr, data, disabled = false, icon, testId, type = "primary" }) => {
|
|
384
393
|
const dataAttrs = Object.entries(data).map(([k, v]) => `${k}="${v}"`).join(" ");
|
|
385
|
-
|
|
394
|
+
const positionClass = type === "primary" ? "inline-end-2" : "inline-end-9";
|
|
395
|
+
return `<button ${attr} data-testid="${testId}" class="ch-button is-6 pli-0.5 min-bs-0 absolute inset-block-1 ${positionClass}" ${dataAttrs} ${disabled ? "disabled" : ""}><svg><use href="/icons.svg#${icon}"/></svg></button>`;
|
|
386
396
|
};
|
|
387
397
|
var addColumnButton = {
|
|
388
398
|
attr: BUTTON_IDENTIFIERS.newColumn,
|
|
@@ -456,11 +466,35 @@ var rowMenuButton = {
|
|
|
456
466
|
rowIndex: Number(el.getAttribute("data-row-index"))
|
|
457
467
|
})
|
|
458
468
|
};
|
|
469
|
+
var sortButton = {
|
|
470
|
+
attr: BUTTON_IDENTIFIERS.sort,
|
|
471
|
+
icon: "ph--sort-ascending--regular",
|
|
472
|
+
render: ({ fieldId, direction }) => {
|
|
473
|
+
return createButton({
|
|
474
|
+
attr: BUTTON_IDENTIFIERS.sort,
|
|
475
|
+
icon: direction === "desc" ? "ph--sort-descending--regular" : "ph--sort-ascending--regular",
|
|
476
|
+
data: {
|
|
477
|
+
"data-field-id": fieldId,
|
|
478
|
+
"data-direction": direction ?? ""
|
|
479
|
+
},
|
|
480
|
+
testId: "table-sort-button",
|
|
481
|
+
// TODO(ZaymonFC): All buttons should be rendered into an absolutely positioned flex container.
|
|
482
|
+
// This is a bit hacky.
|
|
483
|
+
type: "secondary"
|
|
484
|
+
});
|
|
485
|
+
},
|
|
486
|
+
getData: (el) => ({
|
|
487
|
+
type: "sort",
|
|
488
|
+
fieldId: el.getAttribute("data-field-id"),
|
|
489
|
+
direction: el.getAttribute("data-direction")
|
|
490
|
+
})
|
|
491
|
+
};
|
|
459
492
|
var tableButtons = {
|
|
460
493
|
addColumn: addColumnButton,
|
|
461
494
|
columnSettings: columnSettingsButton,
|
|
462
495
|
referencedCell: referencedCellButton,
|
|
463
|
-
rowMenu: rowMenuButton
|
|
496
|
+
rowMenu: rowMenuButton,
|
|
497
|
+
sort: sortButton
|
|
464
498
|
};
|
|
465
499
|
|
|
466
500
|
// packages/ui/react-ui-table/src/util/table-controls.ts
|
|
@@ -597,8 +631,165 @@ var SelectionModel = class extends Resource {
|
|
|
597
631
|
}
|
|
598
632
|
};
|
|
599
633
|
|
|
634
|
+
// packages/ui/react-ui-table/src/model/table-sorting.ts
|
|
635
|
+
import { computed as computed2, signal as signal2 } from "@preact/signals-core";
|
|
636
|
+
import orderBy from "lodash.orderby";
|
|
637
|
+
import { getValue, FormatEnum as FormatEnum2, TypeEnum as TypeEnum2 } from "@dxos/echo-schema";
|
|
638
|
+
import { formatForDisplay } from "@dxos/react-ui-form";
|
|
639
|
+
var TableSorting = class {
|
|
640
|
+
constructor(rows, _view, _projection) {
|
|
641
|
+
this._view = _view;
|
|
642
|
+
this._projection = _projection;
|
|
643
|
+
this._displayToDataIndex = /* @__PURE__ */ new Map();
|
|
644
|
+
this._localSort = signal2(void 0);
|
|
645
|
+
this._rows = rows;
|
|
646
|
+
this._isDirty = computed2(() => {
|
|
647
|
+
const local = this._localSort.value;
|
|
648
|
+
const viewSort = this._view?.query.sort?.[0];
|
|
649
|
+
if (local?.type === "cleared") {
|
|
650
|
+
return viewSort !== void 0;
|
|
651
|
+
}
|
|
652
|
+
if (local?.type === "active") {
|
|
653
|
+
if (!viewSort) {
|
|
654
|
+
return true;
|
|
655
|
+
}
|
|
656
|
+
return local.sort.fieldId !== viewSort.fieldId || local.sort.direction !== viewSort.direction;
|
|
657
|
+
}
|
|
658
|
+
return false;
|
|
659
|
+
});
|
|
660
|
+
this.sortedRows = this.initialiseSortedRows();
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* @reactive
|
|
664
|
+
* @returns Local sort if present, falls back to view sort.
|
|
665
|
+
*/
|
|
666
|
+
get sorting() {
|
|
667
|
+
const local = this._localSort.value;
|
|
668
|
+
if (local?.type === "cleared") {
|
|
669
|
+
return void 0;
|
|
670
|
+
}
|
|
671
|
+
if (local?.type === "active") {
|
|
672
|
+
return local.sort;
|
|
673
|
+
}
|
|
674
|
+
return this._view?.query.sort?.[0];
|
|
675
|
+
}
|
|
676
|
+
/**
|
|
677
|
+
* @reactive
|
|
678
|
+
* @returns Whether local sort differs from view sort.
|
|
679
|
+
*/
|
|
680
|
+
get isDirty() {
|
|
681
|
+
return this._isDirty.value;
|
|
682
|
+
}
|
|
683
|
+
getDataIndex(displayIndex) {
|
|
684
|
+
return this._displayToDataIndex.get(displayIndex) ?? displayIndex;
|
|
685
|
+
}
|
|
686
|
+
setSort(fieldId, direction) {
|
|
687
|
+
this._localSort.value = {
|
|
688
|
+
type: "active",
|
|
689
|
+
sort: {
|
|
690
|
+
fieldId,
|
|
691
|
+
direction
|
|
692
|
+
}
|
|
693
|
+
};
|
|
694
|
+
}
|
|
695
|
+
toggleSort(fieldId) {
|
|
696
|
+
if (!this._view || !this.sorting || this.sorting.fieldId !== fieldId) {
|
|
697
|
+
return;
|
|
698
|
+
}
|
|
699
|
+
switch (this.sorting.direction) {
|
|
700
|
+
case "asc": {
|
|
701
|
+
this.setSort(fieldId, "desc");
|
|
702
|
+
break;
|
|
703
|
+
}
|
|
704
|
+
case "desc": {
|
|
705
|
+
this.setSort(fieldId, "asc");
|
|
706
|
+
break;
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
clearSort() {
|
|
711
|
+
this._localSort.value = {
|
|
712
|
+
type: "cleared"
|
|
713
|
+
};
|
|
714
|
+
}
|
|
715
|
+
save() {
|
|
716
|
+
if (this._view && this._localSort.value !== void 0) {
|
|
717
|
+
if (this._localSort.value.type === "active") {
|
|
718
|
+
this._view.query.sort = [
|
|
719
|
+
this._localSort.value.sort
|
|
720
|
+
];
|
|
721
|
+
} else {
|
|
722
|
+
this._view.query.sort = [];
|
|
723
|
+
}
|
|
724
|
+
this._localSort.value = void 0;
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
//
|
|
728
|
+
// Initialisation.
|
|
729
|
+
//
|
|
730
|
+
initialiseSortedRows() {
|
|
731
|
+
return computed2(() => {
|
|
732
|
+
this._displayToDataIndex.clear();
|
|
733
|
+
const sort = this.sorting;
|
|
734
|
+
if (!sort || !this._view) {
|
|
735
|
+
return this._rows.value;
|
|
736
|
+
}
|
|
737
|
+
const field = this._view.fields.find((f) => f.id === sort.fieldId);
|
|
738
|
+
if (!field) {
|
|
739
|
+
return this._rows.value;
|
|
740
|
+
}
|
|
741
|
+
const { props } = this._projection.getFieldProjection(field.id);
|
|
742
|
+
const dataWithIndices = this._rows.value.map((item, index) => {
|
|
743
|
+
const sortValue = this.getSortValue(props, field, item);
|
|
744
|
+
const isEmpty = !(props.type === TypeEnum2.Boolean) && (sortValue == null || sortValue === "");
|
|
745
|
+
return {
|
|
746
|
+
item,
|
|
747
|
+
index,
|
|
748
|
+
value: sortValue,
|
|
749
|
+
isEmpty
|
|
750
|
+
};
|
|
751
|
+
});
|
|
752
|
+
const ordered = orderBy(dataWithIndices, [
|
|
753
|
+
"isEmpty",
|
|
754
|
+
"value"
|
|
755
|
+
], [
|
|
756
|
+
"asc",
|
|
757
|
+
sort.direction
|
|
758
|
+
]);
|
|
759
|
+
ordered.forEach(({ index: dataIndex }, displayIndex) => {
|
|
760
|
+
if (displayIndex !== dataIndex) {
|
|
761
|
+
this._displayToDataIndex.set(displayIndex, dataIndex);
|
|
762
|
+
}
|
|
763
|
+
});
|
|
764
|
+
return ordered.map(({ item }) => item);
|
|
765
|
+
});
|
|
766
|
+
}
|
|
767
|
+
getSortValue(props, field, item) {
|
|
768
|
+
const { type, format } = props;
|
|
769
|
+
const value = getValue(item, field.path);
|
|
770
|
+
if (type === TypeEnum2.Boolean) {
|
|
771
|
+
return !!value;
|
|
772
|
+
}
|
|
773
|
+
if (type === TypeEnum2.Number) {
|
|
774
|
+
return value;
|
|
775
|
+
}
|
|
776
|
+
if (value == null) {
|
|
777
|
+
return value;
|
|
778
|
+
}
|
|
779
|
+
if (format === FormatEnum2.Ref && field.referencePath) {
|
|
780
|
+
const refValue = getValue(value.target, field.referencePath);
|
|
781
|
+
return refValue;
|
|
782
|
+
}
|
|
783
|
+
return formatForDisplay({
|
|
784
|
+
type,
|
|
785
|
+
format,
|
|
786
|
+
value
|
|
787
|
+
});
|
|
788
|
+
}
|
|
789
|
+
};
|
|
790
|
+
|
|
600
791
|
// packages/ui/react-ui-table/src/model/table-model.ts
|
|
601
|
-
var
|
|
792
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/model/table-model.ts";
|
|
602
793
|
var TableModel = class extends Resource2 {
|
|
603
794
|
constructor({ table, projection, sorting = [], pinnedRows = {
|
|
604
795
|
top: [],
|
|
@@ -606,7 +797,7 @@ var TableModel = class extends Resource2 {
|
|
|
606
797
|
}, onCellUpdate, onDeleteColumn, onDeleteRows, onInsertRow, onRowOrderChanged }) {
|
|
607
798
|
super();
|
|
608
799
|
this.id = `table-model-${PublicKey2.random().truncate()}`;
|
|
609
|
-
this._visibleRange =
|
|
800
|
+
this._visibleRange = signal3({
|
|
610
801
|
start: {
|
|
611
802
|
row: 0,
|
|
612
803
|
col: 0
|
|
@@ -616,14 +807,7 @@ var TableModel = class extends Resource2 {
|
|
|
616
807
|
col: 0
|
|
617
808
|
}
|
|
618
809
|
});
|
|
619
|
-
|
|
620
|
-
* Maps display indices to data indices.
|
|
621
|
-
* Used for translating between sorted/displayed order and original data order.
|
|
622
|
-
* Keys are display indices, values are corresponding data indices.
|
|
623
|
-
*/
|
|
624
|
-
this._displayToDataIndex = /* @__PURE__ */ new Map();
|
|
625
|
-
this._sorting = signal2(void 0);
|
|
626
|
-
this._rows = signal2([]);
|
|
810
|
+
this._rows = signal3([]);
|
|
627
811
|
//
|
|
628
812
|
// Data
|
|
629
813
|
//
|
|
@@ -633,11 +817,11 @@ var TableModel = class extends Resource2 {
|
|
|
633
817
|
this.getRowCount = () => this._rows.value.length;
|
|
634
818
|
this.getColumnCount = () => this.table.view?.target?.fields.length ?? 0;
|
|
635
819
|
this.insertRow = (rowIndex) => {
|
|
636
|
-
const row = rowIndex !== void 0 ? this.
|
|
820
|
+
const row = rowIndex !== void 0 ? this._sorting.getDataIndex(rowIndex) : this._rows.value.length;
|
|
637
821
|
this._onInsertRow?.(row);
|
|
638
822
|
};
|
|
639
823
|
this.deleteRow = (rowIndex) => {
|
|
640
|
-
const row = this.
|
|
824
|
+
const row = this._sorting.getDataIndex(rowIndex);
|
|
641
825
|
const obj = this._rows.value[row];
|
|
642
826
|
const objectsToDelete = [];
|
|
643
827
|
if (this._selection.hasSelection.value) {
|
|
@@ -654,18 +838,18 @@ var TableModel = class extends Resource2 {
|
|
|
654
838
|
return void 0;
|
|
655
839
|
}
|
|
656
840
|
const field = fields[col];
|
|
657
|
-
const dataIndex = this.
|
|
658
|
-
const value =
|
|
841
|
+
const dataIndex = this._sorting.getDataIndex(row);
|
|
842
|
+
const value = getValue2(this._rows.value[dataIndex], field.path);
|
|
659
843
|
if (value == null) {
|
|
660
844
|
return "";
|
|
661
845
|
}
|
|
662
846
|
const { props } = this._projection.getFieldProjection(field.id);
|
|
663
847
|
switch (props.format) {
|
|
664
|
-
case
|
|
848
|
+
case FormatEnum3.Ref: {
|
|
665
849
|
if (!field.referencePath) {
|
|
666
850
|
return "";
|
|
667
851
|
}
|
|
668
|
-
return
|
|
852
|
+
return getValue2(value.target, field.referencePath);
|
|
669
853
|
}
|
|
670
854
|
default: {
|
|
671
855
|
return formatForEditing({
|
|
@@ -677,7 +861,7 @@ var TableModel = class extends Resource2 {
|
|
|
677
861
|
}
|
|
678
862
|
};
|
|
679
863
|
this.setCellData = ({ col, row }, value) => {
|
|
680
|
-
const rowIdx = this.
|
|
864
|
+
const rowIdx = this._sorting.getDataIndex(row);
|
|
681
865
|
const fields = this.table.view?.target?.fields ?? [];
|
|
682
866
|
if (col < 0 || col >= fields.length) {
|
|
683
867
|
return;
|
|
@@ -685,7 +869,7 @@ var TableModel = class extends Resource2 {
|
|
|
685
869
|
const field = fields[col];
|
|
686
870
|
const { props } = this._projection.getFieldProjection(field.id);
|
|
687
871
|
switch (props.format) {
|
|
688
|
-
case
|
|
872
|
+
case FormatEnum3.Ref: {
|
|
689
873
|
if (isReactiveObject(value)) {
|
|
690
874
|
setValue(this._rows.value[rowIdx], field.path, makeRef2(value));
|
|
691
875
|
}
|
|
@@ -703,7 +887,11 @@ var TableModel = class extends Resource2 {
|
|
|
703
887
|
};
|
|
704
888
|
this._table = table;
|
|
705
889
|
this._projection = projection;
|
|
706
|
-
this._sorting
|
|
890
|
+
this._sorting = new TableSorting(this._rows, table.view?.target, projection);
|
|
891
|
+
if (sorting.length > 0) {
|
|
892
|
+
const [sort] = sorting;
|
|
893
|
+
this._sorting.setSort(sort.fieldId, sort.direction);
|
|
894
|
+
}
|
|
707
895
|
this._pinnedRows = pinnedRows;
|
|
708
896
|
this._onInsertRow = onInsertRow;
|
|
709
897
|
this._onDeleteRows = onDeleteRows;
|
|
@@ -718,14 +906,20 @@ var TableModel = class extends Resource2 {
|
|
|
718
906
|
return this._projection;
|
|
719
907
|
}
|
|
720
908
|
get rows() {
|
|
721
|
-
return this.
|
|
909
|
+
return this._sorting.sortedRows;
|
|
910
|
+
}
|
|
911
|
+
/**
|
|
912
|
+
* @reactive
|
|
913
|
+
*/
|
|
914
|
+
get sorting() {
|
|
915
|
+
return this._sorting;
|
|
722
916
|
}
|
|
723
917
|
get pinnedRows() {
|
|
724
918
|
return this._pinnedRows;
|
|
725
919
|
}
|
|
726
920
|
get columnMeta() {
|
|
727
921
|
invariant(this._columnMeta, void 0, {
|
|
728
|
-
F:
|
|
922
|
+
F: __dxlog_file,
|
|
729
923
|
L: 117,
|
|
730
924
|
S: this,
|
|
731
925
|
A: [
|
|
@@ -735,24 +929,24 @@ var TableModel = class extends Resource2 {
|
|
|
735
929
|
});
|
|
736
930
|
return this._columnMeta;
|
|
737
931
|
}
|
|
738
|
-
get sorting() {
|
|
739
|
-
return this._sorting.value;
|
|
740
|
-
}
|
|
741
932
|
get selection() {
|
|
742
933
|
return this._selection;
|
|
743
934
|
}
|
|
935
|
+
/** @reactive */
|
|
936
|
+
get isViewDirty() {
|
|
937
|
+
return this._sorting.isDirty;
|
|
938
|
+
}
|
|
744
939
|
//
|
|
745
940
|
// Initialisation
|
|
746
941
|
//
|
|
747
942
|
async _open() {
|
|
748
943
|
this.initializeColumnMeta();
|
|
749
|
-
this.initializeSorting();
|
|
750
944
|
this.initializeEffects();
|
|
751
|
-
this._selection = new SelectionModel(this.
|
|
945
|
+
this._selection = new SelectionModel(this._sorting.sortedRows, () => this._onRowOrderChanged?.());
|
|
752
946
|
await this._selection.open(this._ctx);
|
|
753
947
|
}
|
|
754
948
|
initializeColumnMeta() {
|
|
755
|
-
this._columnMeta =
|
|
949
|
+
this._columnMeta = computed3(() => {
|
|
756
950
|
const fields = this._table.view?.target?.fields ?? [];
|
|
757
951
|
const meta = Object.fromEntries(fields.map((field, index) => [
|
|
758
952
|
index,
|
|
@@ -778,60 +972,9 @@ var TableModel = class extends Resource2 {
|
|
|
778
972
|
};
|
|
779
973
|
});
|
|
780
974
|
}
|
|
781
|
-
initializeSorting() {
|
|
782
|
-
this._sortedRows = computed2(() => {
|
|
783
|
-
this._displayToDataIndex.clear();
|
|
784
|
-
const sort = this._sorting.value;
|
|
785
|
-
if (!sort) {
|
|
786
|
-
return this._rows.value;
|
|
787
|
-
}
|
|
788
|
-
const field = this._table.view?.target?.fields.find((field2) => field2.id === sort.fieldId);
|
|
789
|
-
if (!field) {
|
|
790
|
-
return this._rows.value;
|
|
791
|
-
}
|
|
792
|
-
const { props } = this._projection.getFieldProjection(field.id);
|
|
793
|
-
const dataWithIndices = this._rows.value.map((item, index) => {
|
|
794
|
-
const rawValue = getValue(item, field.path);
|
|
795
|
-
let sortValue = rawValue;
|
|
796
|
-
if (props.type.startsWith("boolean")) {
|
|
797
|
-
sortValue = !!rawValue;
|
|
798
|
-
} else if (rawValue != null) {
|
|
799
|
-
if (props.format === FormatEnum2.Ref && field.referencePath) {
|
|
800
|
-
sortValue = getValue(rawValue, field.referencePath);
|
|
801
|
-
} else {
|
|
802
|
-
sortValue = formatForDisplay({
|
|
803
|
-
type: props.type,
|
|
804
|
-
format: props.format,
|
|
805
|
-
value: rawValue
|
|
806
|
-
});
|
|
807
|
-
}
|
|
808
|
-
}
|
|
809
|
-
return {
|
|
810
|
-
item,
|
|
811
|
-
index,
|
|
812
|
-
value: sortValue,
|
|
813
|
-
isEmpty: !props.type.startsWith("boolean") && (sortValue == null || sortValue === "")
|
|
814
|
-
};
|
|
815
|
-
});
|
|
816
|
-
const sorted = orderBy(dataWithIndices, [
|
|
817
|
-
"isEmpty",
|
|
818
|
-
"value"
|
|
819
|
-
], [
|
|
820
|
-
"asc",
|
|
821
|
-
sort.direction
|
|
822
|
-
]);
|
|
823
|
-
for (let displayIndex = 0; displayIndex < sorted.length; displayIndex++) {
|
|
824
|
-
const { index: dataIndex } = sorted[displayIndex];
|
|
825
|
-
if (displayIndex !== dataIndex) {
|
|
826
|
-
this._displayToDataIndex.set(displayIndex, dataIndex);
|
|
827
|
-
}
|
|
828
|
-
}
|
|
829
|
-
return sorted.map(({ item }) => item);
|
|
830
|
-
});
|
|
831
|
-
}
|
|
832
975
|
initializeEffects() {
|
|
833
976
|
const rowOrderWatcher = effect2(() => {
|
|
834
|
-
touch(this.
|
|
977
|
+
touch(this._sorting.sortedRows.value);
|
|
835
978
|
this._onRowOrderChanged?.();
|
|
836
979
|
});
|
|
837
980
|
this._ctx.onDispose(rowOrderWatcher);
|
|
@@ -840,8 +983,8 @@ var TableModel = class extends Resource2 {
|
|
|
840
983
|
const rowEffects = [];
|
|
841
984
|
for (let row = start.row; row <= end.row; row++) {
|
|
842
985
|
rowEffects.push(effect2(() => {
|
|
843
|
-
const obj = this.
|
|
844
|
-
this?._table?.view?.target?.fields.forEach((field) => touch(
|
|
986
|
+
const obj = this._sorting.sortedRows.value[row];
|
|
987
|
+
this?._table?.view?.target?.fields.forEach((field) => touch(getValue2(obj, field.path)));
|
|
845
988
|
this._onCellUpdate?.({
|
|
846
989
|
row,
|
|
847
990
|
col: start.col,
|
|
@@ -859,10 +1002,10 @@ var TableModel = class extends Resource2 {
|
|
|
859
1002
|
* @param {(value: any) => any} update - A function that takes the current value and returns the updated value.
|
|
860
1003
|
*/
|
|
861
1004
|
updateCellData({ col, row }, update) {
|
|
862
|
-
const dataRow = this.
|
|
1005
|
+
const dataRow = this._sorting.getDataIndex(row);
|
|
863
1006
|
const fields = this.table.view?.target?.fields ?? [];
|
|
864
1007
|
const field = fields[col];
|
|
865
|
-
const value =
|
|
1008
|
+
const value = getValue2(this._rows.value[dataRow], field.path);
|
|
866
1009
|
const updatedValue = update(value);
|
|
867
1010
|
setValue(this._rows.value[dataRow], field.path, updatedValue);
|
|
868
1011
|
}
|
|
@@ -875,9 +1018,6 @@ var TableModel = class extends Resource2 {
|
|
|
875
1018
|
}
|
|
876
1019
|
const field = this.table.view.target?.fields.find((field2) => field2.id === fieldId);
|
|
877
1020
|
if (field && this._onDeleteColumn) {
|
|
878
|
-
if (this._sorting.value?.fieldId === fieldId) {
|
|
879
|
-
this.clearSort();
|
|
880
|
-
}
|
|
881
1021
|
this._onDeleteColumn(field.id);
|
|
882
1022
|
}
|
|
883
1023
|
}
|
|
@@ -895,18 +1035,6 @@ var TableModel = class extends Resource2 {
|
|
|
895
1035
|
}
|
|
896
1036
|
}
|
|
897
1037
|
//
|
|
898
|
-
// Sorting
|
|
899
|
-
//
|
|
900
|
-
setSort(fieldId, direction) {
|
|
901
|
-
this._sorting.value = {
|
|
902
|
-
fieldId,
|
|
903
|
-
direction
|
|
904
|
-
};
|
|
905
|
-
}
|
|
906
|
-
clearSort() {
|
|
907
|
-
this._sorting.value = void 0;
|
|
908
|
-
}
|
|
909
|
-
//
|
|
910
1038
|
// Pinning
|
|
911
1039
|
//
|
|
912
1040
|
// TODO(burdon): Change to setPinned(on/off).
|
|
@@ -917,15 +1045,21 @@ var TableModel = class extends Resource2 {
|
|
|
917
1045
|
this._pinnedRows.top = this._pinnedRows.top.filter((index) => index !== rowIndex);
|
|
918
1046
|
this._pinnedRows.bottom = this._pinnedRows.bottom.filter((index) => index !== rowIndex);
|
|
919
1047
|
}
|
|
1048
|
+
//
|
|
1049
|
+
// View operations
|
|
1050
|
+
//
|
|
1051
|
+
saveView() {
|
|
1052
|
+
this._sorting.save();
|
|
1053
|
+
}
|
|
920
1054
|
};
|
|
921
1055
|
|
|
922
1056
|
// packages/ui/react-ui-table/src/model/modal-controller.ts
|
|
923
|
-
import { signal as
|
|
924
|
-
import { log
|
|
925
|
-
var
|
|
1057
|
+
import { signal as signal4 } from "@preact/signals-core";
|
|
1058
|
+
import { log } from "@dxos/log";
|
|
1059
|
+
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/model/modal-controller.ts";
|
|
926
1060
|
var ModalController = class {
|
|
927
1061
|
constructor() {
|
|
928
|
-
this._state =
|
|
1062
|
+
this._state = signal4({
|
|
929
1063
|
type: "closed"
|
|
930
1064
|
});
|
|
931
1065
|
this._triggerRef = {
|
|
@@ -985,8 +1119,8 @@ var ModalController = class {
|
|
|
985
1119
|
onCreate
|
|
986
1120
|
};
|
|
987
1121
|
} else {
|
|
988
|
-
|
|
989
|
-
F:
|
|
1122
|
+
log.warn("anchor cell not found while creating new ref", void 0, {
|
|
1123
|
+
F: __dxlog_file2,
|
|
990
1124
|
L: 86,
|
|
991
1125
|
S: this,
|
|
992
1126
|
C: (f, a) => f(...a)
|
|
@@ -1008,14 +1142,14 @@ var ModalController = class {
|
|
|
1008
1142
|
};
|
|
1009
1143
|
|
|
1010
1144
|
// packages/ui/react-ui-table/src/model/table-presentation.ts
|
|
1011
|
-
import { signal as
|
|
1012
|
-
import { FormatEnum as
|
|
1145
|
+
import { signal as signal5 } from "@preact/signals-core";
|
|
1146
|
+
import { FormatEnum as FormatEnum4, getValue as getValue3 } from "@dxos/echo-schema";
|
|
1013
1147
|
import { cellClassesForFieldType, cellClassesForRowSelection, formatForDisplay as formatForDisplay2 } from "@dxos/react-ui-form";
|
|
1014
1148
|
import { toPlaneCellIndex } from "@dxos/react-ui-grid";
|
|
1015
1149
|
import { mx } from "@dxos/react-ui-theme";
|
|
1016
1150
|
import { VIEW_FIELD_LIMIT } from "@dxos/schema";
|
|
1017
1151
|
var TablePresentation = class {
|
|
1018
|
-
constructor(model, _visibleRange =
|
|
1152
|
+
constructor(model, _visibleRange = signal5({
|
|
1019
1153
|
start: {
|
|
1020
1154
|
row: 0,
|
|
1021
1155
|
col: 0
|
|
@@ -1054,19 +1188,19 @@ var TablePresentation = class {
|
|
|
1054
1188
|
const { props } = this.model.projection.getFieldProjection(field.id);
|
|
1055
1189
|
const cell = {
|
|
1056
1190
|
get value() {
|
|
1057
|
-
const value =
|
|
1191
|
+
const value = getValue3(obj, field.path);
|
|
1058
1192
|
if (value == null) {
|
|
1059
1193
|
return "";
|
|
1060
1194
|
}
|
|
1061
1195
|
switch (props.format) {
|
|
1062
|
-
case
|
|
1196
|
+
case FormatEnum4.Boolean: {
|
|
1063
1197
|
return "";
|
|
1064
1198
|
}
|
|
1065
|
-
case
|
|
1199
|
+
case FormatEnum4.Ref: {
|
|
1066
1200
|
if (!field.referencePath) {
|
|
1067
1201
|
return "";
|
|
1068
1202
|
}
|
|
1069
|
-
return
|
|
1203
|
+
return getValue3(value.target, field.referencePath);
|
|
1070
1204
|
}
|
|
1071
1205
|
default: {
|
|
1072
1206
|
return formatForDisplay2({
|
|
@@ -1093,8 +1227,8 @@ var TablePresentation = class {
|
|
|
1093
1227
|
if (classes.length > 0) {
|
|
1094
1228
|
cell.className = mx(classes.flat());
|
|
1095
1229
|
}
|
|
1096
|
-
if (props.format ===
|
|
1097
|
-
const targetObj =
|
|
1230
|
+
if (props.format === FormatEnum4.Ref && props.referenceSchema) {
|
|
1231
|
+
const targetObj = getValue3(obj, field.path)?.target;
|
|
1098
1232
|
if (targetObj) {
|
|
1099
1233
|
cell.accessoryHtml = tableButtons.referencedCell.render({
|
|
1100
1234
|
targetId: targetObj.id,
|
|
@@ -1102,8 +1236,8 @@ var TablePresentation = class {
|
|
|
1102
1236
|
});
|
|
1103
1237
|
}
|
|
1104
1238
|
}
|
|
1105
|
-
if (props.format ===
|
|
1106
|
-
const value =
|
|
1239
|
+
if (props.format === FormatEnum4.Boolean) {
|
|
1240
|
+
const value = getValue3(obj, field.path);
|
|
1107
1241
|
cell.accessoryHtml = tableControls.switch.render({
|
|
1108
1242
|
colIndex,
|
|
1109
1243
|
rowIndex: displayIndex,
|
|
@@ -1133,6 +1267,8 @@ var TablePresentation = class {
|
|
|
1133
1267
|
const fields = this.model.table.view?.target?.fields ?? [];
|
|
1134
1268
|
for (let col = range.start.col; col <= range.end.col && col < fields.length; col++) {
|
|
1135
1269
|
const { field, props } = this.model.projection.getFieldProjection(fields[col].id);
|
|
1270
|
+
const sorting = this.model.sorting?.sorting;
|
|
1271
|
+
const direction = sorting?.fieldId === field.id ? sorting.direction : void 0;
|
|
1136
1272
|
cells[toPlaneCellIndex({
|
|
1137
1273
|
col,
|
|
1138
1274
|
row: 0
|
|
@@ -1141,9 +1277,15 @@ var TablePresentation = class {
|
|
|
1141
1277
|
value: props.title ?? field.path,
|
|
1142
1278
|
readonly: true,
|
|
1143
1279
|
resizeHandle: "col",
|
|
1144
|
-
accessoryHtml:
|
|
1280
|
+
accessoryHtml: `
|
|
1281
|
+
${direction !== void 0 ? tableButtons.sort.render({
|
|
1282
|
+
fieldId: field.id,
|
|
1283
|
+
direction
|
|
1284
|
+
}) : ""}
|
|
1285
|
+
${tableButtons.columnSettings.render({
|
|
1145
1286
|
fieldId: field.id
|
|
1146
|
-
})
|
|
1287
|
+
})}
|
|
1288
|
+
`,
|
|
1147
1289
|
className: "!bg-gridHeader"
|
|
1148
1290
|
};
|
|
1149
1291
|
}
|
|
@@ -1224,7 +1366,7 @@ var TablePresentation = class {
|
|
|
1224
1366
|
|
|
1225
1367
|
// packages/ui/react-ui-table/src/components/TableCellEditor/TableCellEditor.tsx
|
|
1226
1368
|
import React6, { useCallback as useCallback3, useMemo as useMemo3, useRef } from "react";
|
|
1227
|
-
import { FormatEnum as
|
|
1369
|
+
import { FormatEnum as FormatEnum5 } from "@dxos/echo-schema";
|
|
1228
1370
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
1229
1371
|
import { cellQuery, editorKeys, parseCellIndex, useGridContext as useGridContext2, GridCellEditor } from "@dxos/react-ui-grid";
|
|
1230
1372
|
|
|
@@ -1268,7 +1410,7 @@ var completion = ({ debug, onQuery, onMatch }) => {
|
|
|
1268
1410
|
};
|
|
1269
1411
|
|
|
1270
1412
|
// packages/ui/react-ui-table/src/components/TableCellEditor/TableCellEditor.tsx
|
|
1271
|
-
var
|
|
1413
|
+
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/components/TableCellEditor/TableCellEditor.tsx";
|
|
1272
1414
|
var newValue = Symbol.for("newValue");
|
|
1273
1415
|
var createOption = (text) => ({
|
|
1274
1416
|
[newValue]: true,
|
|
@@ -1286,7 +1428,7 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, __gridScope }
|
|
|
1286
1428
|
const field = model.projection.view.fields[col];
|
|
1287
1429
|
const fieldProjection2 = model.projection.getFieldProjection(field.id);
|
|
1288
1430
|
invariant2(fieldProjection2, void 0, {
|
|
1289
|
-
F:
|
|
1431
|
+
F: __dxlog_file3,
|
|
1290
1432
|
L: 67,
|
|
1291
1433
|
S: void 0,
|
|
1292
1434
|
A: [
|
|
@@ -1360,7 +1502,7 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, __gridScope }
|
|
|
1360
1502
|
];
|
|
1361
1503
|
if (onQuery) {
|
|
1362
1504
|
switch (fieldProjection.props.format) {
|
|
1363
|
-
case
|
|
1505
|
+
case FormatEnum5.Ref: {
|
|
1364
1506
|
extension2.push([
|
|
1365
1507
|
completion({
|
|
1366
1508
|
onQuery: (text) => onQuery(fieldProjection, text),
|
|
@@ -1436,7 +1578,7 @@ var determineNavigationDelta = ({ key, shift }) => {
|
|
|
1436
1578
|
};
|
|
1437
1579
|
|
|
1438
1580
|
// packages/ui/react-ui-table/src/components/Table/Table.tsx
|
|
1439
|
-
var
|
|
1581
|
+
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/components/Table/Table.tsx";
|
|
1440
1582
|
var inlineEndLine = "[&>.dx-grid]:relative [&>.dx-grid]:after:absolute [&>.dx-grid]:after:inset-block-0 [&>.dx-grid]:after:-inline-end-px [&>.dx-grid]:after:is-px [&>.dx-grid]:after:bg-separator";
|
|
1441
1583
|
var blockEndLine = "[&>.dx-grid]:before:absolute [&>.dx-grid]:before:inset-inline-0 [&>.dx-grid]:before:-block-end-px [&>.dx-grid]:before:bs-px [&>.dx-grid]:before:bg-separator";
|
|
1442
1584
|
var frozen = {
|
|
@@ -1504,6 +1646,10 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
1504
1646
|
modals.showReferencePanel(data.targetId, data.schemaId);
|
|
1505
1647
|
break;
|
|
1506
1648
|
}
|
|
1649
|
+
case "sort": {
|
|
1650
|
+
model?.sorting?.toggleSort(data.fieldId);
|
|
1651
|
+
break;
|
|
1652
|
+
}
|
|
1507
1653
|
}
|
|
1508
1654
|
return;
|
|
1509
1655
|
}
|
|
@@ -1604,8 +1750,8 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
1604
1750
|
if (model && props.referenceSchema && field.referencePath) {
|
|
1605
1751
|
const space = getSpace4(model.table);
|
|
1606
1752
|
invariant3(space, void 0, {
|
|
1607
|
-
F:
|
|
1608
|
-
L:
|
|
1753
|
+
F: __dxlog_file4,
|
|
1754
|
+
L: 264,
|
|
1609
1755
|
S: void 0,
|
|
1610
1756
|
A: [
|
|
1611
1757
|
"space",
|
|
@@ -1616,7 +1762,7 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
1616
1762
|
if (schema) {
|
|
1617
1763
|
const { objects } = await space.db.query(Filter.schema(schema)).run();
|
|
1618
1764
|
const options = objects.map((obj) => {
|
|
1619
|
-
const value =
|
|
1765
|
+
const value = getValue4(obj, field.referencePath);
|
|
1620
1766
|
if (!value || typeof value !== "string") {
|
|
1621
1767
|
return void 0;
|
|
1622
1768
|
}
|
|
@@ -1689,79 +1835,76 @@ var Table = {
|
|
|
1689
1835
|
Main: TableMain
|
|
1690
1836
|
};
|
|
1691
1837
|
|
|
1692
|
-
// packages/ui/react-ui-table/src/components/
|
|
1693
|
-
import {
|
|
1694
|
-
import
|
|
1695
|
-
import {
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
import { Icon, Toolbar as NaturalToolbar, Tooltip } from "@dxos/react-ui";
|
|
1700
|
-
var buttonStyles = "min-bs-0 p-2";
|
|
1701
|
-
var tooltipProps = {
|
|
1702
|
-
side: "top",
|
|
1703
|
-
classNames: "z-10"
|
|
1704
|
-
};
|
|
1705
|
-
var ToolbarSeparator = () => /* @__PURE__ */ React8.createElement("div", {
|
|
1706
|
-
role: "separator",
|
|
1707
|
-
className: "grow"
|
|
1708
|
-
});
|
|
1709
|
-
var ToolbarButton = ({ icon, children, ...props }) => {
|
|
1710
|
-
return /* @__PURE__ */ React8.createElement(Tooltip.Root, null, /* @__PURE__ */ React8.createElement(Tooltip.Trigger, {
|
|
1711
|
-
asChild: true
|
|
1712
|
-
}, /* @__PURE__ */ React8.createElement(NaturalToolbar.Button, {
|
|
1713
|
-
variant: "ghost",
|
|
1714
|
-
...props,
|
|
1715
|
-
classNames: buttonStyles
|
|
1716
|
-
}, /* @__PURE__ */ React8.createElement(Icon, {
|
|
1717
|
-
icon,
|
|
1718
|
-
size: 5
|
|
1719
|
-
}), /* @__PURE__ */ React8.createElement("span", {
|
|
1720
|
-
className: "sr-only"
|
|
1721
|
-
}, children))), /* @__PURE__ */ React8.createElement(Tooltip.Portal, null, /* @__PURE__ */ React8.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React8.createElement(Tooltip.Arrow, null))));
|
|
1722
|
-
};
|
|
1723
|
-
|
|
1724
|
-
// packages/ui/react-ui-table/src/components/Toolbar/Toolbar.tsx
|
|
1725
|
-
var [ToolbarContextProvider, useToolbarContext] = createContext("Toolbar");
|
|
1726
|
-
var ToolbarRoot = ({ classNames, children, onAction }) => {
|
|
1727
|
-
return /* @__PURE__ */ React9.createElement(ToolbarContextProvider, {
|
|
1728
|
-
onAction
|
|
1729
|
-
}, /* @__PURE__ */ React9.createElement(NaturalToolbar2.Root, {
|
|
1730
|
-
classNames: [
|
|
1731
|
-
"is-full shrink-0 overflow-x-auto overflow-y-hidden p-1 attention-surface",
|
|
1732
|
-
classNames
|
|
1733
|
-
]
|
|
1734
|
-
}, children));
|
|
1735
|
-
};
|
|
1736
|
-
var Editing = () => {
|
|
1737
|
-
const { onAction } = useToolbarContext("Editing");
|
|
1738
|
-
const { t } = useTranslation4(translationKey);
|
|
1739
|
-
return /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement(ToolbarButton, {
|
|
1740
|
-
value: "add-row",
|
|
1838
|
+
// packages/ui/react-ui-table/src/components/TableToolbar/TableToolbar.tsx
|
|
1839
|
+
import React8, { useCallback as useCallback5, useMemo as useMemo5 } from "react";
|
|
1840
|
+
import { create as create3 } from "@dxos/live-object";
|
|
1841
|
+
import { createGapSeparator, createMenuAction, MenuProvider, ToolbarMenu, useMenuActions } from "@dxos/react-ui-menu";
|
|
1842
|
+
var createTableToolbarActions = (state) => {
|
|
1843
|
+
const add = createMenuAction("add-row", {
|
|
1844
|
+
type: "add-row",
|
|
1741
1845
|
icon: "ph--plus--regular",
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
const
|
|
1751
|
-
|
|
1752
|
-
|
|
1846
|
+
label: [
|
|
1847
|
+
"add row",
|
|
1848
|
+
{
|
|
1849
|
+
ns: translationKey
|
|
1850
|
+
}
|
|
1851
|
+
],
|
|
1852
|
+
testId: "table.toolbar.add-row"
|
|
1853
|
+
});
|
|
1854
|
+
const save = createMenuAction("save-view", {
|
|
1855
|
+
type: "save-view",
|
|
1856
|
+
icon: "ph--floppy-disk--regular",
|
|
1857
|
+
label: [
|
|
1858
|
+
"save view label",
|
|
1859
|
+
{
|
|
1860
|
+
ns: translationKey
|
|
1861
|
+
}
|
|
1862
|
+
],
|
|
1863
|
+
testId: "table.toolbar.save-view",
|
|
1864
|
+
iconOnly: false,
|
|
1865
|
+
hidden: !state.viewDirty
|
|
1866
|
+
});
|
|
1867
|
+
const gap = createGapSeparator();
|
|
1868
|
+
const comment = createMenuAction("comment", {
|
|
1869
|
+
type: "comment",
|
|
1753
1870
|
icon: "ph--chat-text--regular",
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1871
|
+
label: [
|
|
1872
|
+
"create comment",
|
|
1873
|
+
{
|
|
1874
|
+
ns: translationKey
|
|
1875
|
+
}
|
|
1876
|
+
],
|
|
1877
|
+
testId: "table.toolbar.comment"
|
|
1878
|
+
});
|
|
1879
|
+
const nodes = [
|
|
1880
|
+
add,
|
|
1881
|
+
save,
|
|
1882
|
+
...gap.nodes,
|
|
1883
|
+
comment
|
|
1884
|
+
];
|
|
1885
|
+
return {
|
|
1886
|
+
nodes,
|
|
1887
|
+
edges: nodes.map(({ id: target }) => ({
|
|
1888
|
+
source: "root",
|
|
1889
|
+
target
|
|
1890
|
+
}))
|
|
1891
|
+
};
|
|
1759
1892
|
};
|
|
1760
|
-
var
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1893
|
+
var TableToolbar = ({ classNames, viewDirty, attendableId, onAction }) => {
|
|
1894
|
+
const state = useMemo5(() => create3({
|
|
1895
|
+
viewDirty
|
|
1896
|
+
}), []);
|
|
1897
|
+
const actionsCreator = useCallback5(() => createTableToolbarActions(state), [
|
|
1898
|
+
state
|
|
1899
|
+
]);
|
|
1900
|
+
const menu = useMenuActions(actionsCreator);
|
|
1901
|
+
return /* @__PURE__ */ React8.createElement(MenuProvider, {
|
|
1902
|
+
...menu,
|
|
1903
|
+
attendableId,
|
|
1904
|
+
onAction
|
|
1905
|
+
}, /* @__PURE__ */ React8.createElement(ToolbarMenu, {
|
|
1906
|
+
classNames
|
|
1907
|
+
}));
|
|
1765
1908
|
};
|
|
1766
1909
|
|
|
1767
1910
|
// packages/ui/react-ui-table/src/hooks/useTableModel.ts
|
|
@@ -1808,8 +1951,8 @@ export {
|
|
|
1808
1951
|
TableModel,
|
|
1809
1952
|
TablePresentation,
|
|
1810
1953
|
TableSchema,
|
|
1954
|
+
TableToolbar,
|
|
1811
1955
|
TableType,
|
|
1812
|
-
Toolbar,
|
|
1813
1956
|
initializeTable,
|
|
1814
1957
|
renderCheckbox,
|
|
1815
1958
|
renderSwitch,
|
|
@@ -1817,7 +1960,6 @@ export {
|
|
|
1817
1960
|
tableControls,
|
|
1818
1961
|
touch,
|
|
1819
1962
|
translations_default as translations,
|
|
1820
|
-
useTableModel
|
|
1821
|
-
useToolbarContext
|
|
1963
|
+
useTableModel
|
|
1822
1964
|
};
|
|
1823
1965
|
//# sourceMappingURL=index.mjs.map
|