@dxos/react-ui-table 0.8.0 → 0.8.1-main.81238a8
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-3FR6NHPD.mjs → chunk-5MKYB7NF.mjs} +5 -7
- package/dist/lib/browser/chunk-5MKYB7NF.mjs.map +7 -0
- package/dist/lib/browser/{_deprecated → deprecated}/index.mjs +26 -26
- package/dist/lib/{node-esm/_deprecated → browser/deprecated}/index.mjs.map +4 -4
- package/dist/lib/browser/index.mjs +289 -123
- 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-NB3SFHGA.cjs → chunk-NRFKBRPV.cjs} +7 -9
- package/dist/lib/node/chunk-NRFKBRPV.cjs.map +7 -0
- package/dist/lib/node/{_deprecated → deprecated}/index.cjs +5 -5
- package/dist/lib/node/{_deprecated → deprecated}/index.cjs.map +4 -4
- package/dist/lib/node/index.cjs +282 -120
- 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-RLVVOZW5.mjs → chunk-SU4D55KI.mjs} +5 -7
- package/dist/lib/node-esm/chunk-SU4D55KI.mjs.map +7 -0
- package/dist/lib/node-esm/{_deprecated → deprecated}/index.mjs +26 -26
- package/dist/lib/node-esm/deprecated/index.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +289 -123
- 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/ColumnActionsMenu.d.ts +2 -1
- package/dist/types/src/components/Table/ColumnActionsMenu.d.ts.map +1 -1
- package/dist/types/src/components/Table/ColumnSettings.d.ts +2 -1
- package/dist/types/src/components/Table/ColumnSettings.d.ts.map +1 -1
- package/dist/types/src/components/Table/CreateRefPanel.d.ts +2 -1
- package/dist/types/src/components/Table/CreateRefPanel.d.ts.map +1 -1
- package/dist/types/src/components/Table/DynamicTable.d.ts +19 -0
- package/dist/types/src/components/Table/DynamicTable.d.ts.map +1 -0
- package/dist/types/src/components/Table/RefPanel.d.ts +2 -1
- package/dist/types/src/components/Table/RefPanel.d.ts.map +1 -1
- package/dist/types/src/components/Table/RowActionsMenu.d.ts +2 -1
- package/dist/types/src/components/Table/RowActionsMenu.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.d.ts +6 -1
- package/dist/types/src/components/Table/Table.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.stories.d.ts +2 -1
- package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/index.d.ts +1 -0
- package/dist/types/src/components/Table/index.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +2 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
- package/dist/types/src/components/TableToolbar/TableToolbar.d.ts +2 -1
- package/dist/types/src/components/TableToolbar/TableToolbar.d.ts.map +1 -1
- package/dist/types/src/components/testing.d.ts +14 -7
- package/dist/types/src/components/testing.d.ts.map +1 -1
- package/dist/types/src/{_deprecated → deprecated}/components/Cell/Cell.d.ts +2 -2
- package/dist/types/src/deprecated/components/Cell/Cell.d.ts.map +1 -0
- package/dist/types/src/{_deprecated → deprecated}/components/Cell/CellCombobox.d.ts +2 -1
- package/dist/types/src/deprecated/components/Cell/CellCombobox.d.ts.map +1 -0
- package/dist/types/src/deprecated/components/Cell/index.d.ts.map +1 -0
- package/dist/types/src/{_deprecated → deprecated}/components/ColumnMenu/ColumnMenu.d.ts +3 -2
- package/dist/types/src/deprecated/components/ColumnMenu/ColumnMenu.d.ts.map +1 -0
- package/dist/types/src/{_deprecated → deprecated}/components/ColumnMenu/ColumnMenu.stories.d.ts +3 -2
- package/dist/types/src/deprecated/components/ColumnMenu/ColumnMenu.stories.d.ts.map +1 -0
- package/dist/types/src/{_deprecated → deprecated}/components/ColumnMenu/ColumnSettings.d.ts +2 -1
- package/dist/types/src/deprecated/components/ColumnMenu/ColumnSettings.d.ts.map +1 -0
- package/dist/types/src/{_deprecated → deprecated}/components/ColumnMenu/ColumnSettings.stories.d.ts +3 -2
- package/dist/types/src/deprecated/components/ColumnMenu/ColumnSettings.stories.d.ts.map +1 -0
- package/dist/types/src/deprecated/components/ColumnMenu/index.d.ts.map +1 -0
- package/dist/types/src/{_deprecated → deprecated}/components/Table/Table.d.ts +5 -5
- package/dist/types/src/deprecated/components/Table/Table.d.ts.map +1 -0
- package/dist/types/src/{_deprecated → deprecated}/components/Table/Table.stories.d.ts +8 -7
- package/dist/types/src/deprecated/components/Table/Table.stories.d.ts.map +1 -0
- package/dist/types/src/{_deprecated → deprecated}/components/Table/TableBody.d.ts +2 -1
- package/dist/types/src/deprecated/components/Table/TableBody.d.ts.map +1 -0
- package/dist/types/src/{_deprecated → deprecated}/components/Table/TableContext.d.ts +1 -1
- package/dist/types/src/deprecated/components/Table/TableContext.d.ts.map +1 -0
- package/dist/types/src/{_deprecated → deprecated}/components/Table/TableHead.d.ts +2 -1
- package/dist/types/src/deprecated/components/Table/TableHead.d.ts.map +1 -0
- package/dist/types/src/deprecated/components/Table/TableRootContext.d.ts.map +1 -0
- package/dist/types/src/deprecated/components/Table/index.d.ts.map +1 -0
- package/dist/types/src/deprecated/components/Table/props.d.ts.map +1 -0
- package/dist/types/src/deprecated/components/index.d.ts.map +1 -0
- package/dist/types/src/deprecated/helpers.d.ts.map +1 -0
- package/dist/types/src/deprecated/hooks/index.d.ts.map +1 -0
- package/dist/types/src/deprecated/hooks/useColumnSizing.d.ts.map +1 -0
- package/dist/types/src/deprecated/hooks/useColumnSorting.d.ts.map +1 -0
- package/dist/types/src/deprecated/hooks/usePinLastRow.d.ts.map +1 -0
- package/dist/types/src/deprecated/hooks/useRowSelection.d.ts.map +1 -0
- package/dist/types/src/deprecated/index.d.ts.map +1 -0
- package/dist/types/src/{_deprecated → deprecated}/schema/Schema.stories.d.ts +2 -1
- package/dist/types/src/deprecated/schema/Schema.stories.d.ts.map +1 -0
- package/dist/types/src/deprecated/schema/column-utils.d.ts.map +1 -0
- package/dist/types/src/deprecated/schema/index.d.ts.map +1 -0
- package/dist/types/src/deprecated/schema/types.d.ts.map +1 -0
- package/dist/types/src/deprecated/theme.d.ts.map +1 -0
- package/dist/types/src/deprecated/translations.d.ts.map +1 -0
- package/dist/types/src/deprecated/types.d.ts.map +1 -0
- package/dist/types/src/hooks/useTableModel.d.ts +5 -2
- package/dist/types/src/hooks/useTableModel.d.ts.map +1 -1
- package/dist/types/src/model/table-model.d.ts +26 -7
- package/dist/types/src/model/table-model.d.ts.map +1 -1
- package/dist/types/src/model/table-sorting.d.ts.map +1 -1
- package/dist/types/src/types/table.d.ts +16 -21
- package/dist/types/src/types/table.d.ts.map +1 -1
- package/dist/types/src/util/dynamic-table.d.ts +40 -0
- package/dist/types/src/util/dynamic-table.d.ts.map +1 -0
- package/dist/types/src/util/index.d.ts +1 -0
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/package.json +35 -35
- package/src/components/Table/ColumnSettings.tsx +5 -6
- package/src/components/Table/CreateRefPanel.tsx +3 -3
- package/src/components/Table/DynamicTable.tsx +86 -0
- package/src/components/Table/RefPanel.tsx +3 -3
- package/src/components/Table/RowActionsMenu.tsx +13 -0
- package/src/components/Table/Table.stories.tsx +27 -2
- package/src/components/Table/Table.tsx +29 -10
- package/src/components/Table/index.ts +1 -0
- package/src/components/testing.ts +1 -0
- package/src/{_deprecated → deprecated}/components/Cell/Cell.tsx +2 -2
- package/src/{_deprecated → deprecated}/components/Table/TableBody.tsx +2 -2
- package/src/{_deprecated → deprecated}/helpers.tsx +2 -2
- package/src/{_deprecated → deprecated}/schema/Schema.stories.tsx +1 -1
- package/src/hooks/useTableModel.ts +22 -6
- package/src/model/table-model.test.ts +1 -1
- package/src/model/table-model.ts +76 -21
- package/src/model/table-presentation.test.ts +1 -1
- package/src/model/table-presentation.ts +3 -3
- package/src/model/table-sorting.ts +1 -0
- package/src/types/table.ts +5 -7
- package/src/util/dynamic-table.ts +71 -0
- package/src/util/index.ts +1 -0
- package/dist/lib/browser/_deprecated/index.mjs.map +0 -7
- package/dist/lib/browser/chunk-3FR6NHPD.mjs.map +0 -7
- package/dist/lib/node/chunk-NB3SFHGA.cjs.map +0 -7
- package/dist/lib/node-esm/chunk-RLVVOZW5.mjs.map +0 -7
- package/dist/types/src/_deprecated/components/Cell/Cell.d.ts.map +0 -1
- package/dist/types/src/_deprecated/components/Cell/CellCombobox.d.ts.map +0 -1
- package/dist/types/src/_deprecated/components/Cell/index.d.ts.map +0 -1
- package/dist/types/src/_deprecated/components/ColumnMenu/ColumnMenu.d.ts.map +0 -1
- package/dist/types/src/_deprecated/components/ColumnMenu/ColumnMenu.stories.d.ts.map +0 -1
- package/dist/types/src/_deprecated/components/ColumnMenu/ColumnSettings.d.ts.map +0 -1
- package/dist/types/src/_deprecated/components/ColumnMenu/ColumnSettings.stories.d.ts.map +0 -1
- package/dist/types/src/_deprecated/components/ColumnMenu/index.d.ts.map +0 -1
- package/dist/types/src/_deprecated/components/Table/Table.d.ts.map +0 -1
- package/dist/types/src/_deprecated/components/Table/Table.stories.d.ts.map +0 -1
- package/dist/types/src/_deprecated/components/Table/TableBody.d.ts.map +0 -1
- package/dist/types/src/_deprecated/components/Table/TableContext.d.ts.map +0 -1
- package/dist/types/src/_deprecated/components/Table/TableHead.d.ts.map +0 -1
- package/dist/types/src/_deprecated/components/Table/TableRootContext.d.ts.map +0 -1
- package/dist/types/src/_deprecated/components/Table/index.d.ts.map +0 -1
- package/dist/types/src/_deprecated/components/Table/props.d.ts.map +0 -1
- package/dist/types/src/_deprecated/components/index.d.ts.map +0 -1
- package/dist/types/src/_deprecated/helpers.d.ts.map +0 -1
- package/dist/types/src/_deprecated/hooks/index.d.ts.map +0 -1
- package/dist/types/src/_deprecated/hooks/useColumnSizing.d.ts.map +0 -1
- package/dist/types/src/_deprecated/hooks/useColumnSorting.d.ts.map +0 -1
- package/dist/types/src/_deprecated/hooks/usePinLastRow.d.ts.map +0 -1
- package/dist/types/src/_deprecated/hooks/useRowSelection.d.ts.map +0 -1
- package/dist/types/src/_deprecated/index.d.ts.map +0 -1
- package/dist/types/src/_deprecated/schema/Schema.stories.d.ts.map +0 -1
- package/dist/types/src/_deprecated/schema/column-utils.d.ts.map +0 -1
- package/dist/types/src/_deprecated/schema/index.d.ts.map +0 -1
- package/dist/types/src/_deprecated/schema/types.d.ts.map +0 -1
- package/dist/types/src/_deprecated/theme.d.ts.map +0 -1
- package/dist/types/src/_deprecated/translations.d.ts.map +0 -1
- package/dist/types/src/_deprecated/types.d.ts.map +0 -1
- /package/dist/types/src/{_deprecated → deprecated}/components/Cell/index.d.ts +0 -0
- /package/dist/types/src/{_deprecated → deprecated}/components/ColumnMenu/index.d.ts +0 -0
- /package/dist/types/src/{_deprecated → deprecated}/components/Table/TableRootContext.d.ts +0 -0
- /package/dist/types/src/{_deprecated → deprecated}/components/Table/index.d.ts +0 -0
- /package/dist/types/src/{_deprecated → deprecated}/components/Table/props.d.ts +0 -0
- /package/dist/types/src/{_deprecated → deprecated}/components/index.d.ts +0 -0
- /package/dist/types/src/{_deprecated → deprecated}/helpers.d.ts +0 -0
- /package/dist/types/src/{_deprecated → deprecated}/hooks/index.d.ts +0 -0
- /package/dist/types/src/{_deprecated → deprecated}/hooks/useColumnSizing.d.ts +0 -0
- /package/dist/types/src/{_deprecated → deprecated}/hooks/useColumnSorting.d.ts +0 -0
- /package/dist/types/src/{_deprecated → deprecated}/hooks/usePinLastRow.d.ts +0 -0
- /package/dist/types/src/{_deprecated → deprecated}/hooks/useRowSelection.d.ts +0 -0
- /package/dist/types/src/{_deprecated → deprecated}/index.d.ts +0 -0
- /package/dist/types/src/{_deprecated → deprecated}/schema/column-utils.d.ts +0 -0
- /package/dist/types/src/{_deprecated → deprecated}/schema/index.d.ts +0 -0
- /package/dist/types/src/{_deprecated → deprecated}/schema/types.d.ts +0 -0
- /package/dist/types/src/{_deprecated → deprecated}/theme.d.ts +0 -0
- /package/dist/types/src/{_deprecated → deprecated}/translations.d.ts +0 -0
- /package/dist/types/src/{_deprecated → deprecated}/types.d.ts +0 -0
- /package/src/{_deprecated → deprecated}/components/Cell/CellCombobox.tsx +0 -0
- /package/src/{_deprecated → deprecated}/components/Cell/index.ts +0 -0
- /package/src/{_deprecated → deprecated}/components/ColumnMenu/ColumnMenu.stories.tsx +0 -0
- /package/src/{_deprecated → deprecated}/components/ColumnMenu/ColumnMenu.tsx +0 -0
- /package/src/{_deprecated → deprecated}/components/ColumnMenu/ColumnSettings.stories.tsx +0 -0
- /package/src/{_deprecated → deprecated}/components/ColumnMenu/ColumnSettings.tsx +0 -0
- /package/src/{_deprecated → deprecated}/components/ColumnMenu/index.ts +0 -0
- /package/src/{_deprecated → deprecated}/components/Table/Table.stories.tsx +0 -0
- /package/src/{_deprecated → deprecated}/components/Table/Table.tsx +0 -0
- /package/src/{_deprecated → deprecated}/components/Table/TableContext.tsx +0 -0
- /package/src/{_deprecated → deprecated}/components/Table/TableHead.tsx +0 -0
- /package/src/{_deprecated → deprecated}/components/Table/TableRootContext.ts +0 -0
- /package/src/{_deprecated → deprecated}/components/Table/index.ts +0 -0
- /package/src/{_deprecated → deprecated}/components/Table/props.ts +0 -0
- /package/src/{_deprecated → deprecated}/components/index.ts +0 -0
- /package/src/{_deprecated → deprecated}/hooks/index.ts +0 -0
- /package/src/{_deprecated → deprecated}/hooks/useColumnSizing.ts +0 -0
- /package/src/{_deprecated → deprecated}/hooks/useColumnSorting.ts +0 -0
- /package/src/{_deprecated → deprecated}/hooks/usePinLastRow.ts +0 -0
- /package/src/{_deprecated → deprecated}/hooks/useRowSelection.ts +0 -0
- /package/src/{_deprecated → deprecated}/index.ts +0 -0
- /package/src/{_deprecated → deprecated}/schema/column-utils.ts +0 -0
- /package/src/{_deprecated → deprecated}/schema/index.ts +0 -0
- /package/src/{_deprecated → deprecated}/schema/types.ts +0 -0
- /package/src/{_deprecated → deprecated}/theme.ts +0 -0
- /package/src/{_deprecated → deprecated}/translations.ts +0 -0
- /package/src/{_deprecated → deprecated}/types.ts +0 -0
|
@@ -5,24 +5,30 @@
|
|
|
5
5
|
import { effect } from '@preact/signals-core';
|
|
6
6
|
import { useEffect, useState } from 'react';
|
|
7
7
|
|
|
8
|
-
import { type ReactiveObject } from '@dxos/react-client/echo';
|
|
8
|
+
import { fullyQualifiedId, getSpace, type ReactiveObject } from '@dxos/react-client/echo';
|
|
9
9
|
import { useSelectionActions } from '@dxos/react-ui-attention';
|
|
10
10
|
import { type ViewProjection } from '@dxos/schema';
|
|
11
11
|
import { isNonNullable } from '@dxos/util';
|
|
12
12
|
|
|
13
|
-
import { type BaseTableRow, TableModel, type TableModelProps } from '../model';
|
|
13
|
+
import { type BaseTableRow, TableModel, type TableModelProps, type TableRowAction } from '../model';
|
|
14
14
|
import { type TableType } from '../types';
|
|
15
15
|
|
|
16
16
|
export type UseTableModelParams<T extends BaseTableRow = { id: string }> = {
|
|
17
17
|
table?: TableType;
|
|
18
18
|
projection?: ViewProjection;
|
|
19
19
|
objects?: ReactiveObject<T>[];
|
|
20
|
+
onSelectionChanged?: (selection: string[]) => void;
|
|
21
|
+
rowActions?: TableRowAction[];
|
|
22
|
+
onRowAction?: (actionId: string, data: T) => void;
|
|
20
23
|
} & Pick<TableModelProps<T>, 'onInsertRow' | 'onDeleteRows' | 'onDeleteColumn' | 'onCellUpdate' | 'onRowOrderChanged'>;
|
|
21
24
|
|
|
22
25
|
export const useTableModel = <T extends BaseTableRow = { id: string }>({
|
|
23
26
|
objects,
|
|
24
27
|
table,
|
|
25
28
|
projection,
|
|
29
|
+
onSelectionChanged,
|
|
30
|
+
rowActions,
|
|
31
|
+
onRowAction,
|
|
26
32
|
...props
|
|
27
33
|
}: UseTableModelParams<T>): TableModel<T> | undefined => {
|
|
28
34
|
const [model, setModel] = useState<TableModel<T>>();
|
|
@@ -33,7 +39,15 @@ export const useTableModel = <T extends BaseTableRow = { id: string }>({
|
|
|
33
39
|
|
|
34
40
|
let model: TableModel<T> | undefined;
|
|
35
41
|
const t = setTimeout(async () => {
|
|
36
|
-
model = new TableModel<T>({
|
|
42
|
+
model = new TableModel<T>({
|
|
43
|
+
id: fullyQualifiedId(table),
|
|
44
|
+
space: getSpace(table),
|
|
45
|
+
view: table.view?.target,
|
|
46
|
+
projection,
|
|
47
|
+
rowActions,
|
|
48
|
+
onRowAction,
|
|
49
|
+
...props,
|
|
50
|
+
});
|
|
37
51
|
await model.open();
|
|
38
52
|
setModel(model);
|
|
39
53
|
});
|
|
@@ -42,7 +56,7 @@ export const useTableModel = <T extends BaseTableRow = { id: string }>({
|
|
|
42
56
|
clearTimeout(t);
|
|
43
57
|
void model?.close();
|
|
44
58
|
};
|
|
45
|
-
}, [table, projection]); // TODO(burdon): Trigger if callbacks change?
|
|
59
|
+
}, [table, projection, table?.view?.target, rowActions]); // TODO(burdon): Trigger if callbacks change?
|
|
46
60
|
|
|
47
61
|
// Update data.
|
|
48
62
|
useEffect(() => {
|
|
@@ -59,7 +73,9 @@ export const useTableModel = <T extends BaseTableRow = { id: string }>({
|
|
|
59
73
|
}
|
|
60
74
|
|
|
61
75
|
const unsubscribe = effect(() => {
|
|
62
|
-
|
|
76
|
+
const selectedItems = [...model.selection.selection.value];
|
|
77
|
+
select(selectedItems);
|
|
78
|
+
onSelectionChanged?.(selectedItems);
|
|
63
79
|
});
|
|
64
80
|
|
|
65
81
|
// Maybe clear the selection here?
|
|
@@ -67,7 +83,7 @@ export const useTableModel = <T extends BaseTableRow = { id: string }>({
|
|
|
67
83
|
clear();
|
|
68
84
|
unsubscribe();
|
|
69
85
|
};
|
|
70
|
-
}, [model]);
|
|
86
|
+
}, [model, onSelectionChanged]);
|
|
71
87
|
|
|
72
88
|
return model;
|
|
73
89
|
};
|
|
@@ -108,5 +108,5 @@ const createTableModel = (props: Partial<TableModelProps> = {}): TableModel => {
|
|
|
108
108
|
const view = createView({ name: 'Test', typename: schema.typename, jsonSchema: schema.jsonSchema });
|
|
109
109
|
const projection = new ViewProjection(schema, view);
|
|
110
110
|
const table = create(TableType, { view: makeRef(view) });
|
|
111
|
-
return new TableModel({ table, projection, ...props });
|
|
111
|
+
return new TableModel({ id: table.id, space: undefined, view, projection, ...props });
|
|
112
112
|
};
|
package/src/model/table-model.ts
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
import { computed, effect, signal, type ReadonlySignal } from '@preact/signals-core';
|
|
6
6
|
|
|
7
|
+
import { type Space } from '@dxos/client/echo';
|
|
7
8
|
import { Resource } from '@dxos/context';
|
|
8
9
|
import { type FieldSortType, FormatEnum, getValue, setValue, type JsonProp } from '@dxos/echo-schema';
|
|
9
10
|
import { invariant } from '@dxos/invariant';
|
|
10
11
|
import { isReactiveObject, makeRef } from '@dxos/live-object';
|
|
11
|
-
import { PublicKey } from '@dxos/react-client';
|
|
12
12
|
import { formatForEditing, parseValue } from '@dxos/react-ui-form';
|
|
13
13
|
import {
|
|
14
14
|
type DxGridAxisMeta,
|
|
@@ -16,17 +16,23 @@ import {
|
|
|
16
16
|
type DxGridPlanePosition,
|
|
17
17
|
type DxGridPosition,
|
|
18
18
|
} from '@dxos/react-ui-grid';
|
|
19
|
-
import { type ViewProjection } from '@dxos/schema';
|
|
19
|
+
import { type ViewType, type ViewProjection } from '@dxos/schema';
|
|
20
20
|
|
|
21
21
|
import { SelectionModel } from './selection-model';
|
|
22
22
|
import { TableSorting } from './table-sorting';
|
|
23
|
-
import { type TableType } from '../types';
|
|
24
23
|
import { touch } from '../util';
|
|
25
24
|
|
|
26
25
|
export type BaseTableRow = Record<JsonProp, any> & { id: string };
|
|
27
26
|
|
|
27
|
+
export type TableRowAction = {
|
|
28
|
+
id: string;
|
|
29
|
+
translationKey: string;
|
|
30
|
+
};
|
|
31
|
+
|
|
28
32
|
export type TableModelProps<T extends BaseTableRow = { id: string }> = {
|
|
29
|
-
|
|
33
|
+
id?: string;
|
|
34
|
+
space?: Space;
|
|
35
|
+
view?: ViewType;
|
|
30
36
|
projection: ViewProjection;
|
|
31
37
|
sorting?: FieldSortType[];
|
|
32
38
|
pinnedRows?: { top: number[]; bottom: number[] };
|
|
@@ -35,12 +41,14 @@ export type TableModelProps<T extends BaseTableRow = { id: string }> = {
|
|
|
35
41
|
onDeleteColumn?: (fieldId: string) => void;
|
|
36
42
|
onCellUpdate?: (cell: DxGridPosition) => void;
|
|
37
43
|
onRowOrderChanged?: () => void;
|
|
44
|
+
rowActions?: TableRowAction[];
|
|
45
|
+
onRowAction?: (actionId: string, data: T) => void;
|
|
38
46
|
};
|
|
39
47
|
|
|
40
48
|
export class TableModel<T extends BaseTableRow = { id: string }> extends Resource {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
private readonly
|
|
49
|
+
private readonly _id: string | undefined;
|
|
50
|
+
private readonly _space: Space | undefined;
|
|
51
|
+
private readonly _view: ViewType | undefined;
|
|
44
52
|
private readonly _projection: ViewProjection;
|
|
45
53
|
|
|
46
54
|
private readonly _visibleRange = signal<DxGridPlaneRange>({
|
|
@@ -53,6 +61,8 @@ export class TableModel<T extends BaseTableRow = { id: string }> extends Resourc
|
|
|
53
61
|
private readonly _onDeleteColumn?: TableModelProps<T>['onDeleteColumn'];
|
|
54
62
|
private readonly _onCellUpdate?: TableModelProps<T>['onCellUpdate'];
|
|
55
63
|
private readonly _onRowOrderChanged?: TableModelProps<T>['onRowOrderChanged'];
|
|
64
|
+
private readonly _rowActions: TableRowAction[];
|
|
65
|
+
private readonly _onRowAction?: TableModelProps<T>['onRowAction'];
|
|
56
66
|
|
|
57
67
|
private readonly _rows = signal<T[]>([]);
|
|
58
68
|
private readonly _sorting: TableSorting<T>;
|
|
@@ -62,7 +72,9 @@ export class TableModel<T extends BaseTableRow = { id: string }> extends Resourc
|
|
|
62
72
|
private _columnMeta?: ReadonlySignal<DxGridAxisMeta>;
|
|
63
73
|
|
|
64
74
|
constructor({
|
|
65
|
-
|
|
75
|
+
id,
|
|
76
|
+
space,
|
|
77
|
+
view,
|
|
66
78
|
projection,
|
|
67
79
|
sorting = [],
|
|
68
80
|
pinnedRows = { top: [], bottom: [] },
|
|
@@ -71,11 +83,16 @@ export class TableModel<T extends BaseTableRow = { id: string }> extends Resourc
|
|
|
71
83
|
onDeleteRows,
|
|
72
84
|
onInsertRow,
|
|
73
85
|
onRowOrderChanged,
|
|
86
|
+
rowActions = [],
|
|
87
|
+
onRowAction,
|
|
74
88
|
}: TableModelProps<T>) {
|
|
75
89
|
super();
|
|
76
|
-
this.
|
|
90
|
+
this._id = id;
|
|
91
|
+
this._space = space;
|
|
92
|
+
this._view = view;
|
|
77
93
|
this._projection = projection;
|
|
78
|
-
|
|
94
|
+
|
|
95
|
+
this._sorting = new TableSorting(this._rows, this._view, projection);
|
|
79
96
|
|
|
80
97
|
if (sorting.length > 0) {
|
|
81
98
|
const [sort] = sorting;
|
|
@@ -88,10 +105,20 @@ export class TableModel<T extends BaseTableRow = { id: string }> extends Resourc
|
|
|
88
105
|
this._onDeleteColumn = onDeleteColumn;
|
|
89
106
|
this._onCellUpdate = onCellUpdate;
|
|
90
107
|
this._onRowOrderChanged = onRowOrderChanged;
|
|
108
|
+
this._rowActions = rowActions;
|
|
109
|
+
this._onRowAction = onRowAction;
|
|
91
110
|
}
|
|
92
111
|
|
|
93
|
-
public get
|
|
94
|
-
return this.
|
|
112
|
+
public get id() {
|
|
113
|
+
return this._id;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
public get space() {
|
|
117
|
+
return this._space;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
public get view() {
|
|
121
|
+
return this._view;
|
|
95
122
|
}
|
|
96
123
|
|
|
97
124
|
public get projection() {
|
|
@@ -109,6 +136,17 @@ export class TableModel<T extends BaseTableRow = { id: string }> extends Resourc
|
|
|
109
136
|
return this._sorting;
|
|
110
137
|
}
|
|
111
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Gets the row data at the specified display index.
|
|
141
|
+
*/
|
|
142
|
+
public getRowAt(displayIndex: number): T | undefined {
|
|
143
|
+
if (displayIndex < 0 || displayIndex >= this._sorting.sortedRows.value.length) {
|
|
144
|
+
return undefined;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return this._sorting.sortedRows.value[displayIndex];
|
|
148
|
+
}
|
|
149
|
+
|
|
112
150
|
public get pinnedRows(): NonNullable<TableModelProps<T>['pinnedRows']> {
|
|
113
151
|
return this._pinnedRows;
|
|
114
152
|
}
|
|
@@ -127,6 +165,10 @@ export class TableModel<T extends BaseTableRow = { id: string }> extends Resourc
|
|
|
127
165
|
return this._sorting.isDirty;
|
|
128
166
|
}
|
|
129
167
|
|
|
168
|
+
public get rowActions(): TableRowAction[] {
|
|
169
|
+
return this._rowActions;
|
|
170
|
+
}
|
|
171
|
+
|
|
130
172
|
//
|
|
131
173
|
// Initialisation
|
|
132
174
|
//
|
|
@@ -140,7 +182,7 @@ export class TableModel<T extends BaseTableRow = { id: string }> extends Resourc
|
|
|
140
182
|
|
|
141
183
|
private initializeColumnMeta(): void {
|
|
142
184
|
this._columnMeta = computed(() => {
|
|
143
|
-
const fields = this.
|
|
185
|
+
const fields = this._view?.fields ?? [];
|
|
144
186
|
const meta = Object.fromEntries(
|
|
145
187
|
fields.map((field, index: number) => [index, { size: field?.size ?? 256, resizeable: true }]),
|
|
146
188
|
);
|
|
@@ -172,7 +214,7 @@ export class TableModel<T extends BaseTableRow = { id: string }> extends Resourc
|
|
|
172
214
|
rowEffects.push(
|
|
173
215
|
effect(() => {
|
|
174
216
|
const obj = this._sorting.sortedRows.value[row];
|
|
175
|
-
this?.
|
|
217
|
+
this._view?.fields.forEach((field) => touch(getValue(obj, field.path)));
|
|
176
218
|
this._onCellUpdate?.({ row, col: start.col, plane: 'grid' });
|
|
177
219
|
}),
|
|
178
220
|
);
|
|
@@ -193,7 +235,7 @@ export class TableModel<T extends BaseTableRow = { id: string }> extends Resourc
|
|
|
193
235
|
|
|
194
236
|
public getRowCount = (): number => this._rows.value.length;
|
|
195
237
|
|
|
196
|
-
public getColumnCount = (): number => this.
|
|
238
|
+
public getColumnCount = (): number => this._view?.fields.length ?? 0;
|
|
197
239
|
|
|
198
240
|
public insertRow = (rowIndex?: number): void => {
|
|
199
241
|
const row = rowIndex !== undefined ? this._sorting.getDataIndex(rowIndex) : this._rows.value.length;
|
|
@@ -215,8 +257,21 @@ export class TableModel<T extends BaseTableRow = { id: string }> extends Resourc
|
|
|
215
257
|
this._onDeleteRows?.(row, objectsToDelete);
|
|
216
258
|
};
|
|
217
259
|
|
|
260
|
+
public handleRowAction = (actionId: string, rowIndex: number): void => {
|
|
261
|
+
if (!this._onRowAction) {
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const row = this._sorting.getDataIndex(rowIndex);
|
|
266
|
+
const data = this._rows.value[row];
|
|
267
|
+
|
|
268
|
+
if (data) {
|
|
269
|
+
this._onRowAction(actionId, data);
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
|
|
218
273
|
public getCellData = ({ col, row }: DxGridPlanePosition): any => {
|
|
219
|
-
const fields = this.
|
|
274
|
+
const fields = this._view?.fields ?? [];
|
|
220
275
|
if (col < 0 || col >= fields.length) {
|
|
221
276
|
return undefined;
|
|
222
277
|
}
|
|
@@ -246,7 +301,7 @@ export class TableModel<T extends BaseTableRow = { id: string }> extends Resourc
|
|
|
246
301
|
|
|
247
302
|
public setCellData = ({ col, row }: DxGridPlanePosition, value: any): void => {
|
|
248
303
|
const rowIdx = this._sorting.getDataIndex(row);
|
|
249
|
-
const fields = this.
|
|
304
|
+
const fields = this._view?.fields ?? [];
|
|
250
305
|
if (col < 0 || col >= fields.length) {
|
|
251
306
|
return;
|
|
252
307
|
}
|
|
@@ -285,7 +340,7 @@ export class TableModel<T extends BaseTableRow = { id: string }> extends Resourc
|
|
|
285
340
|
*/
|
|
286
341
|
public updateCellData({ col, row }: DxGridPlanePosition, update: (value: any) => any): void {
|
|
287
342
|
const dataRow = this._sorting.getDataIndex(row);
|
|
288
|
-
const fields = this.
|
|
343
|
+
const fields = this._view?.fields ?? [];
|
|
289
344
|
const field = fields[col];
|
|
290
345
|
|
|
291
346
|
const value = getValue(this._rows.value[dataRow], field.path);
|
|
@@ -298,11 +353,11 @@ export class TableModel<T extends BaseTableRow = { id: string }> extends Resourc
|
|
|
298
353
|
//
|
|
299
354
|
|
|
300
355
|
public deleteColumn(fieldId: string): void {
|
|
301
|
-
if (!this.
|
|
356
|
+
if (!this._view) {
|
|
302
357
|
return;
|
|
303
358
|
}
|
|
304
359
|
|
|
305
|
-
const field = this.
|
|
360
|
+
const field = this._view?.fields.find((field) => field.id === fieldId);
|
|
306
361
|
if (field && this._onDeleteColumn) {
|
|
307
362
|
this._onDeleteColumn(field.id);
|
|
308
363
|
}
|
|
@@ -313,7 +368,7 @@ export class TableModel<T extends BaseTableRow = { id: string }> extends Resourc
|
|
|
313
368
|
//
|
|
314
369
|
|
|
315
370
|
public setColumnWidth(columnIndex: number, width: number): void {
|
|
316
|
-
const fields = this.
|
|
371
|
+
const fields = this._view?.fields ?? [];
|
|
317
372
|
if (columnIndex < fields.length) {
|
|
318
373
|
const newWidth = Math.max(0, width);
|
|
319
374
|
const field = fields[columnIndex];
|
|
@@ -98,5 +98,5 @@ const createTableModel = (props: Partial<TableModelProps> = {}): TableModel => {
|
|
|
98
98
|
const view = createView({ name: 'Test', typename: schema.typename, jsonSchema: schema.jsonSchema });
|
|
99
99
|
const projection = new ViewProjection(schema, view);
|
|
100
100
|
const table = create(TableType, { view: makeRef(view) });
|
|
101
|
-
return new TableModel({ table, projection, ...props });
|
|
101
|
+
return new TableModel({ id: table.id, view, projection, ...props });
|
|
102
102
|
};
|
|
@@ -55,7 +55,7 @@ export class TablePresentation<T extends BaseTableRow = { id: string }> {
|
|
|
55
55
|
|
|
56
56
|
private getMainGridCells(range: DxGridPlaneRange): DxGridPlaneCells {
|
|
57
57
|
const cells: DxGridPlaneCells = {};
|
|
58
|
-
const fields = this.model.
|
|
58
|
+
const fields = this.model.view?.fields ?? [];
|
|
59
59
|
|
|
60
60
|
const addCell = (obj: T, field: FieldType, colIndex: number, displayIndex: number): void => {
|
|
61
61
|
const { props } = this.model.projection.getFieldProjection(field.id);
|
|
@@ -151,7 +151,7 @@ export class TablePresentation<T extends BaseTableRow = { id: string }> {
|
|
|
151
151
|
|
|
152
152
|
private getHeaderCells(range: DxGridPlaneRange): DxGridPlaneCells {
|
|
153
153
|
const cells: DxGridPlaneCells = {};
|
|
154
|
-
const fields = this.model.
|
|
154
|
+
const fields = this.model.view?.fields ?? [];
|
|
155
155
|
for (let col = range.start.col; col <= range.end.col && col < fields.length; col++) {
|
|
156
156
|
const { field, props } = this.model.projection.getFieldProjection(fields[col].id);
|
|
157
157
|
const sorting = this.model.sorting?.sorting;
|
|
@@ -224,7 +224,7 @@ export class TablePresentation<T extends BaseTableRow = { id: string }> {
|
|
|
224
224
|
return {
|
|
225
225
|
[toPlaneCellIndex({ col: 0, row: 0 })]: {
|
|
226
226
|
accessoryHtml: tableButtons.addColumn.render({
|
|
227
|
-
disabled: (this.model.
|
|
227
|
+
disabled: (this.model.view?.fields?.length ?? 0) >= VIEW_FIELD_LIMIT,
|
|
228
228
|
}),
|
|
229
229
|
className: '!bg-gridHeader',
|
|
230
230
|
readonly: true,
|
package/src/types/table.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { EchoObject, Expando, LabelAnnotationId, ObjectId, Ref, S } from '@dxos/echo-schema';
|
|
6
6
|
// import { ThreadType } from '@dxos/plugin-space/types';
|
|
7
7
|
import { ViewType } from '@dxos/schema';
|
|
8
8
|
|
|
@@ -12,11 +12,9 @@ export const TableSchema = S.Struct({
|
|
|
12
12
|
view: S.optional(Ref(ViewType)),
|
|
13
13
|
// TODO(burdon): Should not import from plugin. Either factor out type or use reverse deps when supported.
|
|
14
14
|
threads: S.optional(S.Array(Ref(Expando /* ThreadType */))), // TODO(dmaretskyi): Breaks edge because plugin-space depends on react-client.
|
|
15
|
+
}).annotations({
|
|
16
|
+
[LabelAnnotationId]: 'name',
|
|
15
17
|
});
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
export class TableType extends TypedObject({
|
|
20
|
-
typename: 'dxos.org/type/Table',
|
|
21
|
-
version: '0.1.0',
|
|
22
|
-
})(TableSchema.fields) {}
|
|
19
|
+
export const TableType = TableSchema.pipe(EchoObject('dxos.org/type/Table', '0.1.0'));
|
|
20
|
+
export type TableType = S.Schema.Type<typeof TableType>;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type SortDirectionType } from '@dxos/echo-schema';
|
|
6
|
+
import { create, makeRef } from '@dxos/live-object';
|
|
7
|
+
import {
|
|
8
|
+
createView,
|
|
9
|
+
echoSchemaFromPropertyDefinitions,
|
|
10
|
+
ViewProjection,
|
|
11
|
+
type SchemaPropertyDefinition,
|
|
12
|
+
} from '@dxos/schema';
|
|
13
|
+
|
|
14
|
+
import { TableType } from '..';
|
|
15
|
+
|
|
16
|
+
type PropertyDisplayProps = {
|
|
17
|
+
size: number;
|
|
18
|
+
title: string;
|
|
19
|
+
sort: SortDirectionType;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export type TablePropertyDefinition = SchemaPropertyDefinition & Partial<PropertyDisplayProps>;
|
|
23
|
+
|
|
24
|
+
export const makeDynamicTable = (typename: string, properties: TablePropertyDefinition[]) => {
|
|
25
|
+
const table = create(TableType, { name: 'dynamic-table' });
|
|
26
|
+
const echoSchema = echoSchemaFromPropertyDefinitions(typename, properties);
|
|
27
|
+
const propertyNames = properties.map((property) => property.name);
|
|
28
|
+
|
|
29
|
+
const view = createView({
|
|
30
|
+
name: 'dynamic-table',
|
|
31
|
+
typename: echoSchema.typename,
|
|
32
|
+
jsonSchema: echoSchema.jsonSchema,
|
|
33
|
+
fields: propertyNames,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
table.view = makeRef(view);
|
|
37
|
+
const viewProjection = new ViewProjection(echoSchema, view);
|
|
38
|
+
|
|
39
|
+
for (const property of properties) {
|
|
40
|
+
if (!view.fields) {
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const field = view.fields.find((field) => field.path === property.name);
|
|
45
|
+
if (field) {
|
|
46
|
+
if (property.size !== undefined) {
|
|
47
|
+
field.size = property.size;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (property.title !== undefined) {
|
|
51
|
+
const fieldProjection = viewProjection.getFieldProjection(field.id);
|
|
52
|
+
viewProjection.setFieldProjection({
|
|
53
|
+
...fieldProjection,
|
|
54
|
+
props: { ...fieldProjection.props, title: property.title },
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (property.sort) {
|
|
59
|
+
const fieldId = field.id;
|
|
60
|
+
view.query.sort = [{ fieldId, direction: property.sort }];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
table,
|
|
67
|
+
schema: echoSchema,
|
|
68
|
+
view,
|
|
69
|
+
viewProjection,
|
|
70
|
+
};
|
|
71
|
+
};
|