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