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