@dxos/react-ui-table 0.7.5-main.9d26e3a → 0.7.5-main.e9bb01b
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 +446 -282
- 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 +438 -268
- 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 +446 -282
- 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 +1 -4
- 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 +35 -34
- package/src/_deprecated/schema/Schema.stories.tsx +1 -1
- package/src/components/Table/ColumnActionsMenu.tsx +4 -4
- package/src/components/Table/Table.stories.tsx +52 -40
- 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 +25 -4
- package/src/model/table-sorting.ts +215 -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-controls.ts +2 -2
- 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="dx-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
|
|
@@ -469,8 +503,8 @@ var CONTROL_IDENTIFIERS = {
|
|
|
469
503
|
switch: "data-table-switch"
|
|
470
504
|
};
|
|
471
505
|
var BASE_CLASSES = {
|
|
472
|
-
checkbox: "absolute inset-block-[.375rem] inline-end-[.375rem]
|
|
473
|
-
switch: "absolute inset-block-[.25rem] inline-end-[.25rem]
|
|
506
|
+
checkbox: "absolute inset-block-[.375rem] inline-end-[.375rem] dx-checkbox",
|
|
507
|
+
switch: "absolute inset-block-[.25rem] inline-end-[.25rem] dx-checkbox--switch"
|
|
474
508
|
};
|
|
475
509
|
var renderAttributes = (data) => {
|
|
476
510
|
return Object.entries(data).map(([k, v]) => `${k}="${v}"`).join(" ");
|
|
@@ -597,8 +631,173 @@ 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.SingleSelect) {
|
|
780
|
+
const options = props.options;
|
|
781
|
+
if (!options) {
|
|
782
|
+
return void 0;
|
|
783
|
+
}
|
|
784
|
+
const option = options.find((option2) => option2.id === value);
|
|
785
|
+
return option ? options.indexOf(option) : void 0;
|
|
786
|
+
}
|
|
787
|
+
if (format === FormatEnum2.Ref && field.referencePath) {
|
|
788
|
+
const refValue = getValue(value.target, field.referencePath);
|
|
789
|
+
return refValue;
|
|
790
|
+
}
|
|
791
|
+
return formatForDisplay({
|
|
792
|
+
type,
|
|
793
|
+
format,
|
|
794
|
+
value
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
};
|
|
798
|
+
|
|
600
799
|
// packages/ui/react-ui-table/src/model/table-model.ts
|
|
601
|
-
var
|
|
800
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/model/table-model.ts";
|
|
602
801
|
var TableModel = class extends Resource2 {
|
|
603
802
|
constructor({ table, projection, sorting = [], pinnedRows = {
|
|
604
803
|
top: [],
|
|
@@ -606,7 +805,7 @@ var TableModel = class extends Resource2 {
|
|
|
606
805
|
}, onCellUpdate, onDeleteColumn, onDeleteRows, onInsertRow, onRowOrderChanged }) {
|
|
607
806
|
super();
|
|
608
807
|
this.id = `table-model-${PublicKey2.random().truncate()}`;
|
|
609
|
-
this._visibleRange =
|
|
808
|
+
this._visibleRange = signal3({
|
|
610
809
|
start: {
|
|
611
810
|
row: 0,
|
|
612
811
|
col: 0
|
|
@@ -616,14 +815,7 @@ var TableModel = class extends Resource2 {
|
|
|
616
815
|
col: 0
|
|
617
816
|
}
|
|
618
817
|
});
|
|
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([]);
|
|
818
|
+
this._rows = signal3([]);
|
|
627
819
|
//
|
|
628
820
|
// Data
|
|
629
821
|
//
|
|
@@ -633,11 +825,11 @@ var TableModel = class extends Resource2 {
|
|
|
633
825
|
this.getRowCount = () => this._rows.value.length;
|
|
634
826
|
this.getColumnCount = () => this.table.view?.target?.fields.length ?? 0;
|
|
635
827
|
this.insertRow = (rowIndex) => {
|
|
636
|
-
const row = rowIndex !== void 0 ? this.
|
|
828
|
+
const row = rowIndex !== void 0 ? this._sorting.getDataIndex(rowIndex) : this._rows.value.length;
|
|
637
829
|
this._onInsertRow?.(row);
|
|
638
830
|
};
|
|
639
831
|
this.deleteRow = (rowIndex) => {
|
|
640
|
-
const row = this.
|
|
832
|
+
const row = this._sorting.getDataIndex(rowIndex);
|
|
641
833
|
const obj = this._rows.value[row];
|
|
642
834
|
const objectsToDelete = [];
|
|
643
835
|
if (this._selection.hasSelection.value) {
|
|
@@ -654,18 +846,18 @@ var TableModel = class extends Resource2 {
|
|
|
654
846
|
return void 0;
|
|
655
847
|
}
|
|
656
848
|
const field = fields[col];
|
|
657
|
-
const dataIndex = this.
|
|
658
|
-
const value =
|
|
849
|
+
const dataIndex = this._sorting.getDataIndex(row);
|
|
850
|
+
const value = getValue2(this._rows.value[dataIndex], field.path);
|
|
659
851
|
if (value == null) {
|
|
660
852
|
return "";
|
|
661
853
|
}
|
|
662
854
|
const { props } = this._projection.getFieldProjection(field.id);
|
|
663
855
|
switch (props.format) {
|
|
664
|
-
case
|
|
856
|
+
case FormatEnum3.Ref: {
|
|
665
857
|
if (!field.referencePath) {
|
|
666
858
|
return "";
|
|
667
859
|
}
|
|
668
|
-
return
|
|
860
|
+
return getValue2(value.target, field.referencePath);
|
|
669
861
|
}
|
|
670
862
|
default: {
|
|
671
863
|
return formatForEditing({
|
|
@@ -677,7 +869,7 @@ var TableModel = class extends Resource2 {
|
|
|
677
869
|
}
|
|
678
870
|
};
|
|
679
871
|
this.setCellData = ({ col, row }, value) => {
|
|
680
|
-
const rowIdx = this.
|
|
872
|
+
const rowIdx = this._sorting.getDataIndex(row);
|
|
681
873
|
const fields = this.table.view?.target?.fields ?? [];
|
|
682
874
|
if (col < 0 || col >= fields.length) {
|
|
683
875
|
return;
|
|
@@ -685,7 +877,7 @@ var TableModel = class extends Resource2 {
|
|
|
685
877
|
const field = fields[col];
|
|
686
878
|
const { props } = this._projection.getFieldProjection(field.id);
|
|
687
879
|
switch (props.format) {
|
|
688
|
-
case
|
|
880
|
+
case FormatEnum3.Ref: {
|
|
689
881
|
if (isReactiveObject(value)) {
|
|
690
882
|
setValue(this._rows.value[rowIdx], field.path, makeRef2(value));
|
|
691
883
|
}
|
|
@@ -703,7 +895,11 @@ var TableModel = class extends Resource2 {
|
|
|
703
895
|
};
|
|
704
896
|
this._table = table;
|
|
705
897
|
this._projection = projection;
|
|
706
|
-
this._sorting
|
|
898
|
+
this._sorting = new TableSorting(this._rows, table.view?.target, projection);
|
|
899
|
+
if (sorting.length > 0) {
|
|
900
|
+
const [sort] = sorting;
|
|
901
|
+
this._sorting.setSort(sort.fieldId, sort.direction);
|
|
902
|
+
}
|
|
707
903
|
this._pinnedRows = pinnedRows;
|
|
708
904
|
this._onInsertRow = onInsertRow;
|
|
709
905
|
this._onDeleteRows = onDeleteRows;
|
|
@@ -718,14 +914,20 @@ var TableModel = class extends Resource2 {
|
|
|
718
914
|
return this._projection;
|
|
719
915
|
}
|
|
720
916
|
get rows() {
|
|
721
|
-
return this.
|
|
917
|
+
return this._sorting.sortedRows;
|
|
918
|
+
}
|
|
919
|
+
/**
|
|
920
|
+
* @reactive
|
|
921
|
+
*/
|
|
922
|
+
get sorting() {
|
|
923
|
+
return this._sorting;
|
|
722
924
|
}
|
|
723
925
|
get pinnedRows() {
|
|
724
926
|
return this._pinnedRows;
|
|
725
927
|
}
|
|
726
928
|
get columnMeta() {
|
|
727
929
|
invariant(this._columnMeta, void 0, {
|
|
728
|
-
F:
|
|
930
|
+
F: __dxlog_file,
|
|
729
931
|
L: 117,
|
|
730
932
|
S: this,
|
|
731
933
|
A: [
|
|
@@ -735,24 +937,24 @@ var TableModel = class extends Resource2 {
|
|
|
735
937
|
});
|
|
736
938
|
return this._columnMeta;
|
|
737
939
|
}
|
|
738
|
-
get sorting() {
|
|
739
|
-
return this._sorting.value;
|
|
740
|
-
}
|
|
741
940
|
get selection() {
|
|
742
941
|
return this._selection;
|
|
743
942
|
}
|
|
943
|
+
/** @reactive */
|
|
944
|
+
get isViewDirty() {
|
|
945
|
+
return this._sorting.isDirty;
|
|
946
|
+
}
|
|
744
947
|
//
|
|
745
948
|
// Initialisation
|
|
746
949
|
//
|
|
747
950
|
async _open() {
|
|
748
951
|
this.initializeColumnMeta();
|
|
749
|
-
this.initializeSorting();
|
|
750
952
|
this.initializeEffects();
|
|
751
|
-
this._selection = new SelectionModel(this.
|
|
953
|
+
this._selection = new SelectionModel(this._sorting.sortedRows, () => this._onRowOrderChanged?.());
|
|
752
954
|
await this._selection.open(this._ctx);
|
|
753
955
|
}
|
|
754
956
|
initializeColumnMeta() {
|
|
755
|
-
this._columnMeta =
|
|
957
|
+
this._columnMeta = computed3(() => {
|
|
756
958
|
const fields = this._table.view?.target?.fields ?? [];
|
|
757
959
|
const meta = Object.fromEntries(fields.map((field, index) => [
|
|
758
960
|
index,
|
|
@@ -778,60 +980,9 @@ var TableModel = class extends Resource2 {
|
|
|
778
980
|
};
|
|
779
981
|
});
|
|
780
982
|
}
|
|
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
983
|
initializeEffects() {
|
|
833
984
|
const rowOrderWatcher = effect2(() => {
|
|
834
|
-
touch(this.
|
|
985
|
+
touch(this._sorting.sortedRows.value);
|
|
835
986
|
this._onRowOrderChanged?.();
|
|
836
987
|
});
|
|
837
988
|
this._ctx.onDispose(rowOrderWatcher);
|
|
@@ -840,8 +991,8 @@ var TableModel = class extends Resource2 {
|
|
|
840
991
|
const rowEffects = [];
|
|
841
992
|
for (let row = start.row; row <= end.row; row++) {
|
|
842
993
|
rowEffects.push(effect2(() => {
|
|
843
|
-
const obj = this.
|
|
844
|
-
this?._table?.view?.target?.fields.forEach((field) => touch(
|
|
994
|
+
const obj = this._sorting.sortedRows.value[row];
|
|
995
|
+
this?._table?.view?.target?.fields.forEach((field) => touch(getValue2(obj, field.path)));
|
|
845
996
|
this._onCellUpdate?.({
|
|
846
997
|
row,
|
|
847
998
|
col: start.col,
|
|
@@ -859,10 +1010,10 @@ var TableModel = class extends Resource2 {
|
|
|
859
1010
|
* @param {(value: any) => any} update - A function that takes the current value and returns the updated value.
|
|
860
1011
|
*/
|
|
861
1012
|
updateCellData({ col, row }, update) {
|
|
862
|
-
const dataRow = this.
|
|
1013
|
+
const dataRow = this._sorting.getDataIndex(row);
|
|
863
1014
|
const fields = this.table.view?.target?.fields ?? [];
|
|
864
1015
|
const field = fields[col];
|
|
865
|
-
const value =
|
|
1016
|
+
const value = getValue2(this._rows.value[dataRow], field.path);
|
|
866
1017
|
const updatedValue = update(value);
|
|
867
1018
|
setValue(this._rows.value[dataRow], field.path, updatedValue);
|
|
868
1019
|
}
|
|
@@ -875,9 +1026,6 @@ var TableModel = class extends Resource2 {
|
|
|
875
1026
|
}
|
|
876
1027
|
const field = this.table.view.target?.fields.find((field2) => field2.id === fieldId);
|
|
877
1028
|
if (field && this._onDeleteColumn) {
|
|
878
|
-
if (this._sorting.value?.fieldId === fieldId) {
|
|
879
|
-
this.clearSort();
|
|
880
|
-
}
|
|
881
1029
|
this._onDeleteColumn(field.id);
|
|
882
1030
|
}
|
|
883
1031
|
}
|
|
@@ -895,18 +1043,6 @@ var TableModel = class extends Resource2 {
|
|
|
895
1043
|
}
|
|
896
1044
|
}
|
|
897
1045
|
//
|
|
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
1046
|
// Pinning
|
|
911
1047
|
//
|
|
912
1048
|
// TODO(burdon): Change to setPinned(on/off).
|
|
@@ -917,15 +1053,21 @@ var TableModel = class extends Resource2 {
|
|
|
917
1053
|
this._pinnedRows.top = this._pinnedRows.top.filter((index) => index !== rowIndex);
|
|
918
1054
|
this._pinnedRows.bottom = this._pinnedRows.bottom.filter((index) => index !== rowIndex);
|
|
919
1055
|
}
|
|
1056
|
+
//
|
|
1057
|
+
// View operations
|
|
1058
|
+
//
|
|
1059
|
+
saveView() {
|
|
1060
|
+
this._sorting.save();
|
|
1061
|
+
}
|
|
920
1062
|
};
|
|
921
1063
|
|
|
922
1064
|
// packages/ui/react-ui-table/src/model/modal-controller.ts
|
|
923
|
-
import { signal as
|
|
924
|
-
import { log
|
|
925
|
-
var
|
|
1065
|
+
import { signal as signal4 } from "@preact/signals-core";
|
|
1066
|
+
import { log } from "@dxos/log";
|
|
1067
|
+
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/model/modal-controller.ts";
|
|
926
1068
|
var ModalController = class {
|
|
927
1069
|
constructor() {
|
|
928
|
-
this._state =
|
|
1070
|
+
this._state = signal4({
|
|
929
1071
|
type: "closed"
|
|
930
1072
|
});
|
|
931
1073
|
this._triggerRef = {
|
|
@@ -985,8 +1127,8 @@ var ModalController = class {
|
|
|
985
1127
|
onCreate
|
|
986
1128
|
};
|
|
987
1129
|
} else {
|
|
988
|
-
|
|
989
|
-
F:
|
|
1130
|
+
log.warn("anchor cell not found while creating new ref", void 0, {
|
|
1131
|
+
F: __dxlog_file2,
|
|
990
1132
|
L: 86,
|
|
991
1133
|
S: this,
|
|
992
1134
|
C: (f, a) => f(...a)
|
|
@@ -1008,14 +1150,14 @@ var ModalController = class {
|
|
|
1008
1150
|
};
|
|
1009
1151
|
|
|
1010
1152
|
// packages/ui/react-ui-table/src/model/table-presentation.ts
|
|
1011
|
-
import { signal as
|
|
1012
|
-
import { FormatEnum as
|
|
1153
|
+
import { signal as signal5 } from "@preact/signals-core";
|
|
1154
|
+
import { FormatEnum as FormatEnum4, getValue as getValue3 } from "@dxos/echo-schema";
|
|
1013
1155
|
import { cellClassesForFieldType, cellClassesForRowSelection, formatForDisplay as formatForDisplay2 } from "@dxos/react-ui-form";
|
|
1014
1156
|
import { toPlaneCellIndex } from "@dxos/react-ui-grid";
|
|
1015
1157
|
import { mx } from "@dxos/react-ui-theme";
|
|
1016
1158
|
import { VIEW_FIELD_LIMIT } from "@dxos/schema";
|
|
1017
1159
|
var TablePresentation = class {
|
|
1018
|
-
constructor(model, _visibleRange =
|
|
1160
|
+
constructor(model, _visibleRange = signal5({
|
|
1019
1161
|
start: {
|
|
1020
1162
|
row: 0,
|
|
1021
1163
|
col: 0
|
|
@@ -1054,19 +1196,20 @@ var TablePresentation = class {
|
|
|
1054
1196
|
const { props } = this.model.projection.getFieldProjection(field.id);
|
|
1055
1197
|
const cell = {
|
|
1056
1198
|
get value() {
|
|
1057
|
-
const value =
|
|
1199
|
+
const value = getValue3(obj, field.path);
|
|
1058
1200
|
if (value == null) {
|
|
1059
1201
|
return "";
|
|
1060
1202
|
}
|
|
1061
1203
|
switch (props.format) {
|
|
1062
|
-
case
|
|
1204
|
+
case FormatEnum4.Boolean:
|
|
1205
|
+
case FormatEnum4.SingleSelect: {
|
|
1063
1206
|
return "";
|
|
1064
1207
|
}
|
|
1065
|
-
case
|
|
1208
|
+
case FormatEnum4.Ref: {
|
|
1066
1209
|
if (!field.referencePath) {
|
|
1067
1210
|
return "";
|
|
1068
1211
|
}
|
|
1069
|
-
return
|
|
1212
|
+
return getValue3(value.target, field.referencePath);
|
|
1070
1213
|
}
|
|
1071
1214
|
default: {
|
|
1072
1215
|
return formatForDisplay2({
|
|
@@ -1093,8 +1236,8 @@ var TablePresentation = class {
|
|
|
1093
1236
|
if (classes.length > 0) {
|
|
1094
1237
|
cell.className = mx(classes.flat());
|
|
1095
1238
|
}
|
|
1096
|
-
if (props.format ===
|
|
1097
|
-
const targetObj =
|
|
1239
|
+
if (props.format === FormatEnum4.Ref && props.referenceSchema) {
|
|
1240
|
+
const targetObj = getValue3(obj, field.path)?.target;
|
|
1098
1241
|
if (targetObj) {
|
|
1099
1242
|
cell.accessoryHtml = tableButtons.referencedCell.render({
|
|
1100
1243
|
targetId: targetObj.id,
|
|
@@ -1102,8 +1245,8 @@ var TablePresentation = class {
|
|
|
1102
1245
|
});
|
|
1103
1246
|
}
|
|
1104
1247
|
}
|
|
1105
|
-
if (props.format ===
|
|
1106
|
-
const value =
|
|
1248
|
+
if (props.format === FormatEnum4.Boolean) {
|
|
1249
|
+
const value = getValue3(obj, field.path);
|
|
1107
1250
|
cell.accessoryHtml = tableControls.switch.render({
|
|
1108
1251
|
colIndex,
|
|
1109
1252
|
rowIndex: displayIndex,
|
|
@@ -1111,6 +1254,16 @@ var TablePresentation = class {
|
|
|
1111
1254
|
});
|
|
1112
1255
|
cell.readonly = true;
|
|
1113
1256
|
}
|
|
1257
|
+
if (props.format === FormatEnum4.SingleSelect) {
|
|
1258
|
+
const value = getValue3(obj, field.path);
|
|
1259
|
+
const options = this.model.projection.getFieldProjection(field.id).props.options;
|
|
1260
|
+
if (options) {
|
|
1261
|
+
const option = options.find((o) => o.id === value);
|
|
1262
|
+
if (option) {
|
|
1263
|
+
cell.accessoryHtml = `<span class="dx-tag" data-hue="${option.color}">${option.title}</span>`;
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1114
1267
|
const idx = toPlaneCellIndex({
|
|
1115
1268
|
col: colIndex,
|
|
1116
1269
|
row: displayIndex
|
|
@@ -1133,6 +1286,8 @@ var TablePresentation = class {
|
|
|
1133
1286
|
const fields = this.model.table.view?.target?.fields ?? [];
|
|
1134
1287
|
for (let col = range.start.col; col <= range.end.col && col < fields.length; col++) {
|
|
1135
1288
|
const { field, props } = this.model.projection.getFieldProjection(fields[col].id);
|
|
1289
|
+
const sorting = this.model.sorting?.sorting;
|
|
1290
|
+
const direction = sorting?.fieldId === field.id ? sorting.direction : void 0;
|
|
1136
1291
|
cells[toPlaneCellIndex({
|
|
1137
1292
|
col,
|
|
1138
1293
|
row: 0
|
|
@@ -1141,9 +1296,16 @@ var TablePresentation = class {
|
|
|
1141
1296
|
value: props.title ?? field.path,
|
|
1142
1297
|
readonly: true,
|
|
1143
1298
|
resizeHandle: "col",
|
|
1144
|
-
accessoryHtml:
|
|
1299
|
+
accessoryHtml: `
|
|
1300
|
+
${direction !== void 0 ? tableButtons.sort.render({
|
|
1301
|
+
fieldId: field.id,
|
|
1302
|
+
direction
|
|
1303
|
+
}) : ""}
|
|
1304
|
+
${tableButtons.columnSettings.render({
|
|
1145
1305
|
fieldId: field.id
|
|
1146
|
-
})
|
|
1306
|
+
})}
|
|
1307
|
+
`,
|
|
1308
|
+
className: "!bg-gridHeader"
|
|
1147
1309
|
};
|
|
1148
1310
|
}
|
|
1149
1311
|
return cells;
|
|
@@ -1193,13 +1355,14 @@ var TablePresentation = class {
|
|
|
1193
1355
|
col: 0,
|
|
1194
1356
|
row: 0
|
|
1195
1357
|
})]: {
|
|
1196
|
-
value: "",
|
|
1197
1358
|
accessoryHtml: tableControls.checkbox.render({
|
|
1198
1359
|
rowIndex: 0,
|
|
1199
1360
|
header: true,
|
|
1200
1361
|
checked: this.model.selection.allRowsSeleted.value
|
|
1201
1362
|
}),
|
|
1202
|
-
|
|
1363
|
+
className: "!bg-gridHeader",
|
|
1364
|
+
readonly: true,
|
|
1365
|
+
value: ""
|
|
1203
1366
|
}
|
|
1204
1367
|
};
|
|
1205
1368
|
}
|
|
@@ -1209,11 +1372,12 @@ var TablePresentation = class {
|
|
|
1209
1372
|
col: 0,
|
|
1210
1373
|
row: 0
|
|
1211
1374
|
})]: {
|
|
1212
|
-
value: "",
|
|
1213
1375
|
accessoryHtml: tableButtons.addColumn.render({
|
|
1214
1376
|
disabled: (this.model.table.view?.target?.fields?.length ?? 0) >= VIEW_FIELD_LIMIT
|
|
1215
1377
|
}),
|
|
1216
|
-
|
|
1378
|
+
className: "!bg-gridHeader",
|
|
1379
|
+
readonly: true,
|
|
1380
|
+
value: ""
|
|
1217
1381
|
}
|
|
1218
1382
|
};
|
|
1219
1383
|
}
|
|
@@ -1221,7 +1385,7 @@ var TablePresentation = class {
|
|
|
1221
1385
|
|
|
1222
1386
|
// packages/ui/react-ui-table/src/components/TableCellEditor/TableCellEditor.tsx
|
|
1223
1387
|
import React6, { useCallback as useCallback3, useMemo as useMemo3, useRef } from "react";
|
|
1224
|
-
import { FormatEnum as
|
|
1388
|
+
import { FormatEnum as FormatEnum5 } from "@dxos/echo-schema";
|
|
1225
1389
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
1226
1390
|
import { cellQuery, editorKeys, parseCellIndex, useGridContext as useGridContext2, GridCellEditor } from "@dxos/react-ui-grid";
|
|
1227
1391
|
|
|
@@ -1265,7 +1429,7 @@ var completion = ({ debug, onQuery, onMatch }) => {
|
|
|
1265
1429
|
};
|
|
1266
1430
|
|
|
1267
1431
|
// packages/ui/react-ui-table/src/components/TableCellEditor/TableCellEditor.tsx
|
|
1268
|
-
var
|
|
1432
|
+
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/components/TableCellEditor/TableCellEditor.tsx";
|
|
1269
1433
|
var newValue = Symbol.for("newValue");
|
|
1270
1434
|
var createOption = (text) => ({
|
|
1271
1435
|
[newValue]: true,
|
|
@@ -1283,7 +1447,7 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, __gridScope }
|
|
|
1283
1447
|
const field = model.projection.view.fields[col];
|
|
1284
1448
|
const fieldProjection2 = model.projection.getFieldProjection(field.id);
|
|
1285
1449
|
invariant2(fieldProjection2, void 0, {
|
|
1286
|
-
F:
|
|
1450
|
+
F: __dxlog_file3,
|
|
1287
1451
|
L: 67,
|
|
1288
1452
|
S: void 0,
|
|
1289
1453
|
A: [
|
|
@@ -1357,7 +1521,7 @@ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, __gridScope }
|
|
|
1357
1521
|
];
|
|
1358
1522
|
if (onQuery) {
|
|
1359
1523
|
switch (fieldProjection.props.format) {
|
|
1360
|
-
case
|
|
1524
|
+
case FormatEnum5.Ref: {
|
|
1361
1525
|
extension2.push([
|
|
1362
1526
|
completion({
|
|
1363
1527
|
onQuery: (text) => onQuery(fieldProjection, text),
|
|
@@ -1433,7 +1597,7 @@ var determineNavigationDelta = ({ key, shift }) => {
|
|
|
1433
1597
|
};
|
|
1434
1598
|
|
|
1435
1599
|
// packages/ui/react-ui-table/src/components/Table/Table.tsx
|
|
1436
|
-
var
|
|
1600
|
+
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/components/Table/Table.tsx";
|
|
1437
1601
|
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";
|
|
1438
1602
|
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";
|
|
1439
1603
|
var frozen = {
|
|
@@ -1501,6 +1665,10 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
1501
1665
|
modals.showReferencePanel(data.targetId, data.schemaId);
|
|
1502
1666
|
break;
|
|
1503
1667
|
}
|
|
1668
|
+
case "sort": {
|
|
1669
|
+
model?.sorting?.toggleSort(data.fieldId);
|
|
1670
|
+
break;
|
|
1671
|
+
}
|
|
1504
1672
|
}
|
|
1505
1673
|
return;
|
|
1506
1674
|
}
|
|
@@ -1601,8 +1769,8 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
1601
1769
|
if (model && props.referenceSchema && field.referencePath) {
|
|
1602
1770
|
const space = getSpace4(model.table);
|
|
1603
1771
|
invariant3(space, void 0, {
|
|
1604
|
-
F:
|
|
1605
|
-
L:
|
|
1772
|
+
F: __dxlog_file4,
|
|
1773
|
+
L: 264,
|
|
1606
1774
|
S: void 0,
|
|
1607
1775
|
A: [
|
|
1608
1776
|
"space",
|
|
@@ -1613,7 +1781,7 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
|
|
|
1613
1781
|
if (schema) {
|
|
1614
1782
|
const { objects } = await space.db.query(Filter.schema(schema)).run();
|
|
1615
1783
|
const options = objects.map((obj) => {
|
|
1616
|
-
const value =
|
|
1784
|
+
const value = getValue4(obj, field.referencePath);
|
|
1617
1785
|
if (!value || typeof value !== "string") {
|
|
1618
1786
|
return void 0;
|
|
1619
1787
|
}
|
|
@@ -1686,79 +1854,76 @@ var Table = {
|
|
|
1686
1854
|
Main: TableMain
|
|
1687
1855
|
};
|
|
1688
1856
|
|
|
1689
|
-
// packages/ui/react-ui-table/src/components/
|
|
1690
|
-
import {
|
|
1691
|
-
import
|
|
1692
|
-
import {
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
import { Icon, Toolbar as NaturalToolbar, Tooltip } from "@dxos/react-ui";
|
|
1697
|
-
var buttonStyles = "min-bs-0 p-2";
|
|
1698
|
-
var tooltipProps = {
|
|
1699
|
-
side: "top",
|
|
1700
|
-
classNames: "z-10"
|
|
1701
|
-
};
|
|
1702
|
-
var ToolbarSeparator = () => /* @__PURE__ */ React8.createElement("div", {
|
|
1703
|
-
role: "separator",
|
|
1704
|
-
className: "grow"
|
|
1705
|
-
});
|
|
1706
|
-
var ToolbarButton = ({ icon, children, ...props }) => {
|
|
1707
|
-
return /* @__PURE__ */ React8.createElement(Tooltip.Root, null, /* @__PURE__ */ React8.createElement(Tooltip.Trigger, {
|
|
1708
|
-
asChild: true
|
|
1709
|
-
}, /* @__PURE__ */ React8.createElement(NaturalToolbar.Button, {
|
|
1710
|
-
variant: "ghost",
|
|
1711
|
-
...props,
|
|
1712
|
-
classNames: buttonStyles
|
|
1713
|
-
}, /* @__PURE__ */ React8.createElement(Icon, {
|
|
1714
|
-
icon,
|
|
1715
|
-
size: 5
|
|
1716
|
-
}), /* @__PURE__ */ React8.createElement("span", {
|
|
1717
|
-
className: "sr-only"
|
|
1718
|
-
}, children))), /* @__PURE__ */ React8.createElement(Tooltip.Portal, null, /* @__PURE__ */ React8.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React8.createElement(Tooltip.Arrow, null))));
|
|
1719
|
-
};
|
|
1720
|
-
|
|
1721
|
-
// packages/ui/react-ui-table/src/components/Toolbar/Toolbar.tsx
|
|
1722
|
-
var [ToolbarContextProvider, useToolbarContext] = createContext("Toolbar");
|
|
1723
|
-
var ToolbarRoot = ({ classNames, children, onAction }) => {
|
|
1724
|
-
return /* @__PURE__ */ React9.createElement(ToolbarContextProvider, {
|
|
1725
|
-
onAction
|
|
1726
|
-
}, /* @__PURE__ */ React9.createElement(NaturalToolbar2.Root, {
|
|
1727
|
-
classNames: [
|
|
1728
|
-
"is-full shrink-0 overflow-x-auto overflow-y-hidden p-1 attention-surface",
|
|
1729
|
-
classNames
|
|
1730
|
-
]
|
|
1731
|
-
}, children));
|
|
1732
|
-
};
|
|
1733
|
-
var Editing = () => {
|
|
1734
|
-
const { onAction } = useToolbarContext("Editing");
|
|
1735
|
-
const { t } = useTranslation4(translationKey);
|
|
1736
|
-
return /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement(ToolbarButton, {
|
|
1737
|
-
value: "add-row",
|
|
1857
|
+
// packages/ui/react-ui-table/src/components/TableToolbar/TableToolbar.tsx
|
|
1858
|
+
import React8, { useCallback as useCallback5, useMemo as useMemo5 } from "react";
|
|
1859
|
+
import { create as create3 } from "@dxos/live-object";
|
|
1860
|
+
import { createGapSeparator, createMenuAction, MenuProvider, ToolbarMenu, useMenuActions } from "@dxos/react-ui-menu";
|
|
1861
|
+
var createTableToolbarActions = (state) => {
|
|
1862
|
+
const add = createMenuAction("add-row", {
|
|
1863
|
+
type: "add-row",
|
|
1738
1864
|
icon: "ph--plus--regular",
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
const
|
|
1748
|
-
|
|
1749
|
-
|
|
1865
|
+
label: [
|
|
1866
|
+
"add row",
|
|
1867
|
+
{
|
|
1868
|
+
ns: translationKey
|
|
1869
|
+
}
|
|
1870
|
+
],
|
|
1871
|
+
testId: "table.toolbar.add-row"
|
|
1872
|
+
});
|
|
1873
|
+
const save = createMenuAction("save-view", {
|
|
1874
|
+
type: "save-view",
|
|
1875
|
+
icon: "ph--floppy-disk--regular",
|
|
1876
|
+
label: [
|
|
1877
|
+
"save view label",
|
|
1878
|
+
{
|
|
1879
|
+
ns: translationKey
|
|
1880
|
+
}
|
|
1881
|
+
],
|
|
1882
|
+
testId: "table.toolbar.save-view",
|
|
1883
|
+
iconOnly: false,
|
|
1884
|
+
hidden: !state.viewDirty
|
|
1885
|
+
});
|
|
1886
|
+
const gap = createGapSeparator();
|
|
1887
|
+
const comment = createMenuAction("comment", {
|
|
1888
|
+
type: "comment",
|
|
1750
1889
|
icon: "ph--chat-text--regular",
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1890
|
+
label: [
|
|
1891
|
+
"create comment",
|
|
1892
|
+
{
|
|
1893
|
+
ns: translationKey
|
|
1894
|
+
}
|
|
1895
|
+
],
|
|
1896
|
+
testId: "table.toolbar.comment"
|
|
1897
|
+
});
|
|
1898
|
+
const nodes = [
|
|
1899
|
+
add,
|
|
1900
|
+
save,
|
|
1901
|
+
...gap.nodes,
|
|
1902
|
+
comment
|
|
1903
|
+
];
|
|
1904
|
+
return {
|
|
1905
|
+
nodes,
|
|
1906
|
+
edges: nodes.map(({ id: target }) => ({
|
|
1907
|
+
source: "root",
|
|
1908
|
+
target
|
|
1909
|
+
}))
|
|
1910
|
+
};
|
|
1756
1911
|
};
|
|
1757
|
-
var
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1912
|
+
var TableToolbar = ({ classNames, viewDirty, attendableId, onAction }) => {
|
|
1913
|
+
const state = useMemo5(() => create3({
|
|
1914
|
+
viewDirty
|
|
1915
|
+
}), []);
|
|
1916
|
+
const actionsCreator = useCallback5(() => createTableToolbarActions(state), [
|
|
1917
|
+
state
|
|
1918
|
+
]);
|
|
1919
|
+
const menu = useMenuActions(actionsCreator);
|
|
1920
|
+
return /* @__PURE__ */ React8.createElement(MenuProvider, {
|
|
1921
|
+
...menu,
|
|
1922
|
+
attendableId,
|
|
1923
|
+
onAction
|
|
1924
|
+
}, /* @__PURE__ */ React8.createElement(ToolbarMenu, {
|
|
1925
|
+
classNames
|
|
1926
|
+
}));
|
|
1762
1927
|
};
|
|
1763
1928
|
|
|
1764
1929
|
// packages/ui/react-ui-table/src/hooks/useTableModel.ts
|
|
@@ -1805,8 +1970,8 @@ export {
|
|
|
1805
1970
|
TableModel,
|
|
1806
1971
|
TablePresentation,
|
|
1807
1972
|
TableSchema,
|
|
1973
|
+
TableToolbar,
|
|
1808
1974
|
TableType,
|
|
1809
|
-
Toolbar,
|
|
1810
1975
|
initializeTable,
|
|
1811
1976
|
renderCheckbox,
|
|
1812
1977
|
renderSwitch,
|
|
@@ -1814,7 +1979,6 @@ export {
|
|
|
1814
1979
|
tableControls,
|
|
1815
1980
|
touch,
|
|
1816
1981
|
translations_default as translations,
|
|
1817
|
-
useTableModel
|
|
1818
|
-
useToolbarContext
|
|
1982
|
+
useTableModel
|
|
1819
1983
|
};
|
|
1820
1984
|
//# sourceMappingURL=index.mjs.map
|