@dxos/react-ui-table 0.8.1-staging.5be625a → 0.8.1-staging.97aedb1
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-5MKYB7NF.mjs → chunk-YWNRUF4J.mjs} +7 -3
- package/dist/lib/browser/{chunk-5MKYB7NF.mjs.map → chunk-YWNRUF4J.mjs.map} +3 -3
- package/dist/lib/browser/index.mjs +295 -97
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/types/index.mjs +1 -1
- package/dist/lib/node/{chunk-NRFKBRPV.cjs → chunk-TGG6OZ54.cjs} +10 -6
- package/dist/lib/node/{chunk-NRFKBRPV.cjs.map → chunk-TGG6OZ54.cjs.map} +3 -3
- package/dist/lib/node/index.cjs +293 -93
- package/dist/lib/node/index.cjs.map +3 -3
- 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-SU4D55KI.mjs → chunk-KKLP54L3.mjs} +7 -3
- package/dist/lib/node-esm/{chunk-SU4D55KI.mjs.map → chunk-KKLP54L3.mjs.map} +3 -3
- package/dist/lib/node-esm/index.mjs +295 -97
- package/dist/lib/node-esm/index.mjs.map +3 -3
- 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/DynamicTable.d.ts +15 -10
- package/dist/types/src/components/Table/DynamicTable.d.ts.map +1 -1
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts +10 -0
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts.map +1 -0
- package/dist/types/src/components/Table/Table.d.ts +1 -1
- package/dist/types/src/components/Table/Table.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.stories.d.ts +2 -3
- package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/relations.stories.d.ts +9 -0
- package/dist/types/src/components/Table/relations.stories.d.ts.map +1 -0
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/testing.d.ts.map +1 -1
- package/dist/types/src/hooks/useTableModel.d.ts +6 -10
- package/dist/types/src/hooks/useTableModel.d.ts.map +1 -1
- package/dist/types/src/model/index.d.ts +1 -0
- package/dist/types/src/model/index.d.ts.map +1 -1
- package/dist/types/src/model/selection-model.d.ts +6 -3
- package/dist/types/src/model/selection-model.d.ts.map +1 -1
- package/dist/types/src/model/table-model.d.ts +13 -14
- package/dist/types/src/model/table-model.d.ts.map +1 -1
- package/dist/types/src/model/table-presentation.d.ts +4 -4
- package/dist/types/src/model/table-presentation.d.ts.map +1 -1
- package/dist/types/src/model/table-sorting.d.ts +2 -2
- package/dist/types/src/model/table-sorting.d.ts.map +1 -1
- package/dist/types/src/types/table.d.ts +2 -1
- package/dist/types/src/types/table.d.ts.map +1 -1
- package/dist/types/src/util/dynamic-table.d.ts +21 -30
- package/dist/types/src/util/dynamic-table.d.ts.map +1 -1
- package/dist/types/src/util/table-controls.d.ts +2 -2
- package/dist/types/src/util/table-controls.d.ts.map +1 -1
- package/dist/types/src/util/table.d.ts.map +1 -1
- package/package.json +33 -32
- package/src/components/Table/DynamicTable.stories.tsx +155 -0
- package/src/components/Table/DynamicTable.tsx +46 -28
- package/src/components/Table/Table.stories.tsx +129 -125
- package/src/components/Table/Table.tsx +51 -26
- package/src/components/Table/relations.stories.tsx +113 -0
- package/src/components/TableCellEditor/TableCellEditor.stories.tsx +8 -3
- package/src/components/TableCellEditor/TableCellEditor.tsx +102 -4
- package/src/components/testing.ts +0 -1
- package/src/hooks/useTableModel.ts +11 -11
- package/src/model/index.ts +1 -0
- package/src/model/selection-model.ts +12 -2
- package/src/model/table-model.test.ts +1 -1
- package/src/model/table-model.ts +27 -18
- package/src/model/table-presentation.test.ts +1 -1
- package/src/model/table-presentation.ts +65 -11
- package/src/model/table-sorting.ts +2 -2
- package/src/playwright/smoke.spec.ts +2 -3
- package/src/types/table.ts +6 -5
- package/src/util/dynamic-table.ts +57 -25
- package/src/util/table-controls.ts +4 -4
- package/src/util/table.ts +2 -1
- package/dist/lib/browser/deprecated/index.mjs +0 -1483
- package/dist/lib/browser/deprecated/index.mjs.map +0 -7
- package/dist/lib/node/deprecated/index.cjs +0 -1511
- package/dist/lib/node/deprecated/index.cjs.map +0 -7
- package/dist/lib/node-esm/deprecated/index.mjs +0 -1485
- package/dist/lib/node-esm/deprecated/index.mjs.map +0 -7
- package/dist/types/src/deprecated/components/Cell/Cell.d.ts +0 -12
- package/dist/types/src/deprecated/components/Cell/Cell.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/Cell/CellCombobox.d.ts +0 -13
- package/dist/types/src/deprecated/components/Cell/CellCombobox.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/Cell/index.d.ts +0 -2
- package/dist/types/src/deprecated/components/Cell/index.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/ColumnMenu/ColumnMenu.d.ts +0 -23
- package/dist/types/src/deprecated/components/ColumnMenu/ColumnMenu.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/ColumnMenu/ColumnMenu.stories.d.ts +0 -36
- package/dist/types/src/deprecated/components/ColumnMenu/ColumnMenu.stories.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/ColumnMenu/ColumnSettings.d.ts +0 -15
- package/dist/types/src/deprecated/components/ColumnMenu/ColumnSettings.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/ColumnMenu/ColumnSettings.stories.d.ts +0 -84
- package/dist/types/src/deprecated/components/ColumnMenu/ColumnSettings.stories.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/ColumnMenu/index.d.ts +0 -3
- package/dist/types/src/deprecated/components/ColumnMenu/index.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/Table/Table.d.ts +0 -20
- package/dist/types/src/deprecated/components/Table/Table.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/Table/Table.stories.d.ts +0 -116
- package/dist/types/src/deprecated/components/Table/Table.stories.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/Table/TableBody.d.ts +0 -12
- package/dist/types/src/deprecated/components/Table/TableBody.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/Table/TableContext.d.ts +0 -13
- package/dist/types/src/deprecated/components/Table/TableContext.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/Table/TableHead.d.ts +0 -9
- package/dist/types/src/deprecated/components/Table/TableHead.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/Table/TableRootContext.d.ts +0 -17
- package/dist/types/src/deprecated/components/Table/TableRootContext.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/Table/index.d.ts +0 -5
- package/dist/types/src/deprecated/components/Table/index.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/Table/props.d.ts +0 -42
- package/dist/types/src/deprecated/components/Table/props.d.ts.map +0 -1
- package/dist/types/src/deprecated/components/index.d.ts +0 -4
- package/dist/types/src/deprecated/components/index.d.ts.map +0 -1
- package/dist/types/src/deprecated/helpers.d.ts +0 -91
- package/dist/types/src/deprecated/helpers.d.ts.map +0 -1
- package/dist/types/src/deprecated/hooks/index.d.ts +0 -5
- package/dist/types/src/deprecated/hooks/index.d.ts.map +0 -1
- package/dist/types/src/deprecated/hooks/useColumnSizing.d.ts +0 -12
- package/dist/types/src/deprecated/hooks/useColumnSizing.d.ts.map +0 -1
- package/dist/types/src/deprecated/hooks/useColumnSorting.d.ts +0 -15
- package/dist/types/src/deprecated/hooks/useColumnSorting.d.ts.map +0 -1
- package/dist/types/src/deprecated/hooks/usePinLastRow.d.ts +0 -3
- package/dist/types/src/deprecated/hooks/usePinLastRow.d.ts.map +0 -1
- package/dist/types/src/deprecated/hooks/useRowSelection.d.ts +0 -7
- package/dist/types/src/deprecated/hooks/useRowSelection.d.ts.map +0 -1
- package/dist/types/src/deprecated/index.d.ts +0 -8
- package/dist/types/src/deprecated/index.d.ts.map +0 -1
- package/dist/types/src/deprecated/schema/Schema.stories.d.ts +0 -11
- package/dist/types/src/deprecated/schema/Schema.stories.d.ts.map +0 -1
- package/dist/types/src/deprecated/schema/column-utils.d.ts +0 -7
- package/dist/types/src/deprecated/schema/column-utils.d.ts.map +0 -1
- package/dist/types/src/deprecated/schema/index.d.ts +0 -3
- package/dist/types/src/deprecated/schema/index.d.ts.map +0 -1
- package/dist/types/src/deprecated/schema/types.d.ts +0 -27
- package/dist/types/src/deprecated/schema/types.d.ts.map +0 -1
- package/dist/types/src/deprecated/theme.d.ts +0 -29
- package/dist/types/src/deprecated/theme.d.ts.map +0 -1
- package/dist/types/src/deprecated/translations.d.ts +0 -21
- package/dist/types/src/deprecated/translations.d.ts.map +0 -1
- package/dist/types/src/deprecated/types.d.ts +0 -26
- package/dist/types/src/deprecated/types.d.ts.map +0 -1
- package/src/deprecated/components/Cell/Cell.tsx +0 -88
- package/src/deprecated/components/Cell/CellCombobox.tsx +0 -103
- package/src/deprecated/components/Cell/index.ts +0 -5
- package/src/deprecated/components/ColumnMenu/ColumnMenu.stories.tsx +0 -129
- package/src/deprecated/components/ColumnMenu/ColumnMenu.tsx +0 -182
- package/src/deprecated/components/ColumnMenu/ColumnSettings.stories.tsx +0 -108
- package/src/deprecated/components/ColumnMenu/ColumnSettings.tsx +0 -207
- package/src/deprecated/components/ColumnMenu/index.ts +0 -6
- package/src/deprecated/components/Table/Table.stories.tsx +0 -508
- package/src/deprecated/components/Table/Table.tsx +0 -301
- package/src/deprecated/components/Table/TableBody.tsx +0 -82
- package/src/deprecated/components/Table/TableContext.tsx +0 -34
- package/src/deprecated/components/Table/TableHead.tsx +0 -78
- package/src/deprecated/components/Table/TableRootContext.ts +0 -39
- package/src/deprecated/components/Table/index.ts +0 -8
- package/src/deprecated/components/Table/props.ts +0 -60
- package/src/deprecated/components/index.ts +0 -7
- package/src/deprecated/helpers.tsx +0 -526
- package/src/deprecated/hooks/index.ts +0 -8
- package/src/deprecated/hooks/useColumnSizing.ts +0 -46
- package/src/deprecated/hooks/useColumnSorting.ts +0 -64
- package/src/deprecated/hooks/usePinLastRow.ts +0 -47
- package/src/deprecated/hooks/useRowSelection.ts +0 -40
- package/src/deprecated/index.ts +0 -12
- package/src/deprecated/schema/Schema.stories.tsx +0 -59
- package/src/deprecated/schema/column-utils.ts +0 -54
- package/src/deprecated/schema/index.ts +0 -6
- package/src/deprecated/schema/types.ts +0 -40
- package/src/deprecated/theme.ts +0 -82
- package/src/deprecated/translations.ts +0 -26
- package/src/deprecated/types.ts +0 -38
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import '@dxos-theme';
|
|
6
6
|
|
|
7
7
|
import { type StoryObj, type Meta } from '@storybook/react';
|
|
8
|
-
import React, { useCallback, useMemo, useRef
|
|
8
|
+
import React, { useCallback, useMemo, useRef } from 'react';
|
|
9
9
|
|
|
10
10
|
import { FormatEnum, ImmutableSchema } from '@dxos/echo-schema';
|
|
11
11
|
import { invariant } from '@dxos/invariant';
|
|
@@ -14,31 +14,28 @@ import { faker } from '@dxos/random';
|
|
|
14
14
|
import { useClient } from '@dxos/react-client';
|
|
15
15
|
import { Filter, useQuery, useSchema, create } from '@dxos/react-client/echo';
|
|
16
16
|
import { useClientProvider, withClientProvider } from '@dxos/react-client/testing';
|
|
17
|
-
import { useDefaultValue } from '@dxos/react-ui';
|
|
18
17
|
import { ViewEditor } from '@dxos/react-ui-form';
|
|
19
18
|
import { SyntaxHighlighter } from '@dxos/react-ui-syntax-highlighter';
|
|
20
|
-
import {
|
|
19
|
+
import { getSchemaFromPropertyDefinitions, ViewProjection, ViewType } from '@dxos/schema';
|
|
21
20
|
import { Testing, createObjectFactory } from '@dxos/schema/testing';
|
|
22
21
|
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
23
22
|
|
|
24
|
-
import { DynamicTable as DynamicTableComponent } from './DynamicTable';
|
|
25
23
|
import { Table, type TableController } from './Table';
|
|
26
|
-
import { useTableModel
|
|
24
|
+
import { useTableModel } from '../../hooks';
|
|
27
25
|
import { TablePresentation } from '../../model';
|
|
28
26
|
import translations from '../../translations';
|
|
29
27
|
import { TableType } from '../../types';
|
|
30
28
|
import { initializeTable } from '../../util';
|
|
31
29
|
import { TableToolbar } from '../TableToolbar';
|
|
32
|
-
import { createItems, createTable, type SimulatorProps, useSimulator } from '../testing';
|
|
33
30
|
|
|
34
31
|
// NOTE(ZaymonFC): We rely on this seed being 0 in the smoke tests.
|
|
35
32
|
faker.seed(0);
|
|
36
33
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const
|
|
34
|
+
/**
|
|
35
|
+
* Custom hook to create and manage a test table model for storybook demonstrations.
|
|
36
|
+
* Provides table data, schema, and handlers for table operations.
|
|
37
|
+
*/
|
|
38
|
+
const useTestTableModel = () => {
|
|
42
39
|
const client = useClient();
|
|
43
40
|
const { space } = useClientProvider();
|
|
44
41
|
|
|
@@ -49,18 +46,31 @@ const DefaultStory = () => {
|
|
|
49
46
|
|
|
50
47
|
const projection = useMemo(() => {
|
|
51
48
|
if (schema && table?.view?.target) {
|
|
52
|
-
return new ViewProjection(schema, table.view.target);
|
|
49
|
+
return new ViewProjection(schema.jsonSchema, table.view.target);
|
|
53
50
|
}
|
|
54
51
|
}, [schema, table?.view?.target]);
|
|
55
52
|
|
|
56
53
|
const features = useMemo(
|
|
57
|
-
() => ({
|
|
54
|
+
() => ({
|
|
55
|
+
selection: { enabled: true, mode: 'multiple' as const },
|
|
56
|
+
dataEditable: true,
|
|
57
|
+
schemaEditable: !(schema instanceof ImmutableSchema),
|
|
58
|
+
}),
|
|
58
59
|
[schema],
|
|
59
60
|
);
|
|
60
61
|
|
|
61
62
|
const objects = useQuery(space, schema ? Filter.schema(schema) : Filter.nothing());
|
|
62
63
|
const filteredObjects = useGlobalFilteredObjects(objects);
|
|
63
64
|
|
|
65
|
+
const tableRef = useRef<TableController>(null);
|
|
66
|
+
const handleCellUpdate = useCallback((cell: any) => {
|
|
67
|
+
tableRef.current?.update?.(cell);
|
|
68
|
+
}, []);
|
|
69
|
+
|
|
70
|
+
const handleRowOrderChange = useCallback(() => {
|
|
71
|
+
tableRef.current?.update?.();
|
|
72
|
+
}, []);
|
|
73
|
+
|
|
64
74
|
const handleInsertRow = useCallback(() => {
|
|
65
75
|
if (space && schema) {
|
|
66
76
|
space.db.add(create(schema, {}));
|
|
@@ -82,28 +92,19 @@ const DefaultStory = () => {
|
|
|
82
92
|
projection.deleteFieldProjection(fieldId);
|
|
83
93
|
}
|
|
84
94
|
},
|
|
85
|
-
[
|
|
95
|
+
[projection],
|
|
86
96
|
);
|
|
87
97
|
|
|
88
|
-
const tableRef = useRef<TableController>(null);
|
|
89
|
-
const handleCellUpdate = useCallback((cell: any) => {
|
|
90
|
-
tableRef.current?.update?.(cell);
|
|
91
|
-
}, []);
|
|
92
|
-
|
|
93
|
-
const handleRowOrderChanged = useCallback(() => {
|
|
94
|
-
tableRef.current?.update?.();
|
|
95
|
-
}, []);
|
|
96
|
-
|
|
97
98
|
const model = useTableModel({
|
|
98
99
|
table,
|
|
99
100
|
projection,
|
|
100
101
|
features,
|
|
101
|
-
|
|
102
|
+
rows: filteredObjects,
|
|
102
103
|
onInsertRow: handleInsertRow,
|
|
103
104
|
onDeleteRows: handleDeleteRows,
|
|
104
105
|
onDeleteColumn: handleDeleteColumn,
|
|
105
106
|
onCellUpdate: handleCellUpdate,
|
|
106
|
-
|
|
107
|
+
onRowOrderChange: handleRowOrderChange,
|
|
107
108
|
});
|
|
108
109
|
|
|
109
110
|
const presentation = useMemo(() => {
|
|
@@ -112,7 +113,7 @@ const DefaultStory = () => {
|
|
|
112
113
|
}
|
|
113
114
|
}, [model]);
|
|
114
115
|
|
|
115
|
-
const
|
|
116
|
+
const handleToolbarAction = useCallback(
|
|
116
117
|
(action: { type: string }) => {
|
|
117
118
|
switch (action.type) {
|
|
118
119
|
case 'on-thread-create': {
|
|
@@ -132,7 +133,23 @@ const DefaultStory = () => {
|
|
|
132
133
|
[table, model],
|
|
133
134
|
);
|
|
134
135
|
|
|
135
|
-
|
|
136
|
+
return {
|
|
137
|
+
schema,
|
|
138
|
+
table,
|
|
139
|
+
tableRef,
|
|
140
|
+
model,
|
|
141
|
+
presentation,
|
|
142
|
+
space,
|
|
143
|
+
handleToolbarAction,
|
|
144
|
+
handleDeleteRows,
|
|
145
|
+
handleDeleteColumn,
|
|
146
|
+
};
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const StoryViewEditor = () => {
|
|
150
|
+
const { table, space, schema, handleDeleteColumn } = useTestTableModel();
|
|
151
|
+
|
|
152
|
+
const handleTypenameChanged = useCallback(
|
|
136
153
|
(typename: string) => {
|
|
137
154
|
if (table?.view?.target) {
|
|
138
155
|
invariant(schema);
|
|
@@ -143,6 +160,28 @@ const DefaultStory = () => {
|
|
|
143
160
|
[schema, table?.view?.target],
|
|
144
161
|
);
|
|
145
162
|
|
|
163
|
+
if (!table || !schema || !table.view?.target) {
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return (
|
|
168
|
+
<ViewEditor
|
|
169
|
+
registry={space?.db.schemaRegistry}
|
|
170
|
+
schema={schema}
|
|
171
|
+
view={table.view.target!}
|
|
172
|
+
onTypenameChanged={handleTypenameChanged}
|
|
173
|
+
onDelete={handleDeleteColumn}
|
|
174
|
+
/>
|
|
175
|
+
);
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
//
|
|
179
|
+
// Story components.
|
|
180
|
+
//
|
|
181
|
+
|
|
182
|
+
const DefaultStory = () => {
|
|
183
|
+
const { schema, table, tableRef, model, presentation, handleToolbarAction } = useTestTableModel();
|
|
184
|
+
|
|
146
185
|
if (!schema || !table) {
|
|
147
186
|
return <div />;
|
|
148
187
|
}
|
|
@@ -150,22 +189,13 @@ const DefaultStory = () => {
|
|
|
150
189
|
return (
|
|
151
190
|
<div className='grow grid grid-cols-[1fr_350px]'>
|
|
152
191
|
<div className='grid grid-rows-[min-content_1fr] min-bs-0 overflow-hidden'>
|
|
153
|
-
<TableToolbar classNames='border-
|
|
192
|
+
<TableToolbar classNames='border-be border-separator' onAction={handleToolbarAction} />
|
|
154
193
|
<Table.Root>
|
|
155
194
|
<Table.Main ref={tableRef} model={model} presentation={presentation} ignoreAttention />
|
|
156
195
|
</Table.Root>
|
|
157
196
|
</div>
|
|
158
197
|
<div className='flex flex-col h-full border-l border-separator overflow-y-auto'>
|
|
159
|
-
|
|
160
|
-
<ViewEditor
|
|
161
|
-
registry={space?.db.schemaRegistry}
|
|
162
|
-
schema={schema}
|
|
163
|
-
view={table.view.target!}
|
|
164
|
-
onTypenameChanged={onTypenameChanged}
|
|
165
|
-
onDelete={handleDeleteColumn}
|
|
166
|
-
/>
|
|
167
|
-
)}
|
|
168
|
-
|
|
198
|
+
<StoryViewEditor />
|
|
169
199
|
<SyntaxHighlighter language='json' className='w-full text-xs'>
|
|
170
200
|
{JSON.stringify({ view: table.view?.target, schema }, null, 2)}
|
|
171
201
|
</SyntaxHighlighter>
|
|
@@ -174,76 +204,16 @@ const DefaultStory = () => {
|
|
|
174
204
|
);
|
|
175
205
|
};
|
|
176
206
|
|
|
177
|
-
|
|
178
|
-
const properties = useMemo<SchemaPropertyDefinition[]>(
|
|
179
|
-
() => [
|
|
180
|
-
{ name: 'name', format: FormatEnum.String },
|
|
181
|
-
{ name: 'age', format: FormatEnum.Number },
|
|
182
|
-
],
|
|
183
|
-
[],
|
|
184
|
-
);
|
|
185
|
-
|
|
186
|
-
const [objects, _setObjects] = useState<any[]>(
|
|
187
|
-
Array.from({ length: 100 }, () => ({
|
|
188
|
-
name: faker.person.fullName(),
|
|
189
|
-
age: faker.number.int({ min: 18, max: 80 }),
|
|
190
|
-
})),
|
|
191
|
-
);
|
|
192
|
-
|
|
193
|
-
return <DynamicTableComponent properties={properties} data={objects} />;
|
|
194
|
-
};
|
|
195
|
-
|
|
196
|
-
type StoryProps = {
|
|
197
|
-
rows?: number;
|
|
198
|
-
} & Pick<SimulatorProps, 'insertInterval' | 'updateInterval'>;
|
|
199
|
-
|
|
200
|
-
const _TablePerformanceStory = (props: StoryProps) => {
|
|
201
|
-
const getDefaultRows = useCallback(() => 10, []);
|
|
202
|
-
const rows = useDefaultValue(props.rows, getDefaultRows);
|
|
203
|
-
const table = useMemo(() => createTable(), []);
|
|
204
|
-
const items = useMemo(() => createItems(rows), [rows]);
|
|
205
|
-
const itemsRef = useRef(items);
|
|
206
|
-
const simulatorProps = useMemo(() => ({ table, items, ...props }), [table, items, props]);
|
|
207
|
-
useSimulator(simulatorProps);
|
|
208
|
-
|
|
209
|
-
const handleDeleteRows = useCallback<NonNullable<UseTableModelParams<any>['onDeleteRows']>>((row) => {
|
|
210
|
-
itemsRef.current.splice(row, 1);
|
|
211
|
-
}, []);
|
|
212
|
-
|
|
213
|
-
const handleDeleteColumn = useCallback<NonNullable<UseTableModelParams<any>['onDeleteColumn']>>(
|
|
214
|
-
(fieldId) => {
|
|
215
|
-
if (table && table.view?.target) {
|
|
216
|
-
const fieldPosition = table.view.target!.fields.findIndex((field) => field.id === fieldId);
|
|
217
|
-
table.view.target!.fields.splice(fieldPosition, 1);
|
|
218
|
-
}
|
|
219
|
-
},
|
|
220
|
-
[table],
|
|
221
|
-
);
|
|
222
|
-
|
|
223
|
-
const tableRef = useRef<TableController>(null);
|
|
224
|
-
const model = useTableModel({
|
|
225
|
-
table,
|
|
226
|
-
objects: items as any[],
|
|
227
|
-
onDeleteRows: handleDeleteRows,
|
|
228
|
-
onDeleteColumn: handleDeleteColumn,
|
|
229
|
-
onCellUpdate: (cell) => tableRef.current?.update?.(cell),
|
|
230
|
-
onRowOrderChanged: () => tableRef.current?.update?.(),
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
return (
|
|
234
|
-
<Table.Root>
|
|
235
|
-
<Table.Main ref={tableRef} model={model} />
|
|
236
|
-
</Table.Root>
|
|
237
|
-
);
|
|
238
|
-
};
|
|
207
|
+
type StoryProps = { rows?: number };
|
|
239
208
|
|
|
240
209
|
//
|
|
241
210
|
// Story definitions.
|
|
242
211
|
//
|
|
243
212
|
|
|
213
|
+
// TODO(burdon): Need super simple story.
|
|
214
|
+
|
|
244
215
|
const meta: Meta<StoryProps> = {
|
|
245
216
|
title: 'ui/react-ui-table/Table',
|
|
246
|
-
component: Table.Main as any,
|
|
247
217
|
render: DefaultStory,
|
|
248
218
|
parameters: { translations },
|
|
249
219
|
decorators: [
|
|
@@ -277,17 +247,17 @@ export const StaticSchema: StoryObj = {
|
|
|
277
247
|
parameters: { translations },
|
|
278
248
|
decorators: [
|
|
279
249
|
withClientProvider({
|
|
280
|
-
types: [TableType, ViewType, Testing.
|
|
250
|
+
types: [TableType, ViewType, Testing.Contact, Testing.Org],
|
|
281
251
|
createIdentity: true,
|
|
282
252
|
createSpace: true,
|
|
283
253
|
onSpaceCreated: async ({ client, space }) => {
|
|
284
254
|
const table = space.db.add(create(TableType, {}));
|
|
285
|
-
await initializeTable({ client, space, table, typename: Testing.
|
|
255
|
+
await initializeTable({ client, space, table, typename: Testing.Contact.typename });
|
|
286
256
|
|
|
287
257
|
const factory = createObjectFactory(space.db, faker as any);
|
|
288
258
|
await factory([
|
|
289
|
-
{ type: Testing.
|
|
290
|
-
{ type: Testing.
|
|
259
|
+
{ type: Testing.Contact, count: 10 },
|
|
260
|
+
{ type: Testing.Org, count: 1 },
|
|
291
261
|
]);
|
|
292
262
|
},
|
|
293
263
|
}),
|
|
@@ -296,24 +266,58 @@ export const StaticSchema: StoryObj = {
|
|
|
296
266
|
],
|
|
297
267
|
};
|
|
298
268
|
|
|
299
|
-
export const
|
|
300
|
-
|
|
301
|
-
|
|
269
|
+
export const Tags: Meta<StoryProps> = {
|
|
270
|
+
title: 'ui/react-ui-table/Table',
|
|
271
|
+
render: DefaultStory,
|
|
272
|
+
parameters: { translations },
|
|
273
|
+
decorators: [
|
|
274
|
+
withClientProvider({
|
|
275
|
+
types: [TableType, ViewType],
|
|
276
|
+
createIdentity: true,
|
|
277
|
+
createSpace: true,
|
|
278
|
+
onSpaceCreated: async ({ client, space }) => {
|
|
279
|
+
// Configure schema.
|
|
280
|
+
const typename = 'example.com/SingleSelect';
|
|
281
|
+
const selectOptions = [
|
|
282
|
+
{ id: 'one', title: 'One', color: 'emerald' },
|
|
283
|
+
{ id: 'two', title: 'Two', color: 'blue' },
|
|
284
|
+
{ id: 'three', title: 'Three', color: 'indigo' },
|
|
285
|
+
{ id: 'four', title: 'Four', color: 'red' },
|
|
286
|
+
{ id: 'longer_option', title: 'LONGER OPTION', color: 'amber' },
|
|
287
|
+
];
|
|
288
|
+
|
|
289
|
+
const selectOptionIds = selectOptions.map((o) => o.id);
|
|
290
|
+
|
|
291
|
+
const schema = getSchemaFromPropertyDefinitions(typename, [
|
|
292
|
+
{
|
|
293
|
+
name: 'single',
|
|
294
|
+
format: FormatEnum.SingleSelect,
|
|
295
|
+
config: { options: selectOptions },
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
name: 'multiple',
|
|
299
|
+
format: FormatEnum.MultiSelect,
|
|
300
|
+
config: { options: selectOptions },
|
|
301
|
+
},
|
|
302
|
+
]);
|
|
303
|
+
const [storedSchema] = await space.db.schemaRegistry.register([schema]);
|
|
302
304
|
|
|
303
|
-
//
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
//
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
305
|
+
// Initialize table.
|
|
306
|
+
const table = space.db.add(create(TableType, {}));
|
|
307
|
+
await initializeTable({ client, space, table, initialRow: false, typename });
|
|
308
|
+
|
|
309
|
+
// Populate.
|
|
310
|
+
Array.from({ length: 10 }).map(() => {
|
|
311
|
+
return space.db.add(
|
|
312
|
+
create(storedSchema, {
|
|
313
|
+
single: faker.helpers.arrayElement([...selectOptionIds, undefined]),
|
|
314
|
+
multiple: faker.helpers.randomSubset(selectOptionIds),
|
|
315
|
+
}),
|
|
316
|
+
);
|
|
317
|
+
});
|
|
318
|
+
},
|
|
319
|
+
}),
|
|
320
|
+
withTheme,
|
|
321
|
+
withLayout({ fullscreen: true, tooltips: true }),
|
|
322
|
+
],
|
|
323
|
+
};
|
|
@@ -3,14 +3,15 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import React, {
|
|
6
|
-
|
|
6
|
+
type MouseEvent,
|
|
7
7
|
type PropsWithChildren,
|
|
8
|
+
type WheelEvent,
|
|
9
|
+
forwardRef,
|
|
8
10
|
useCallback,
|
|
9
11
|
useImperativeHandle,
|
|
10
12
|
useState,
|
|
11
|
-
type WheelEvent,
|
|
12
|
-
type MouseEvent,
|
|
13
13
|
useMemo,
|
|
14
|
+
useEffect,
|
|
14
15
|
} from 'react';
|
|
15
16
|
|
|
16
17
|
import { getValue } from '@dxos/echo-schema';
|
|
@@ -18,7 +19,7 @@ import { invariant } from '@dxos/invariant';
|
|
|
18
19
|
import { Filter } from '@dxos/react-client/echo';
|
|
19
20
|
import { useTranslation } from '@dxos/react-ui';
|
|
20
21
|
import { useAttention } from '@dxos/react-ui-attention';
|
|
21
|
-
import { type DxGridElement,
|
|
22
|
+
import { closestCell, type DxGridElement, type DxGridPosition, type GridContentProps, Grid } from '@dxos/react-ui-grid';
|
|
22
23
|
import { mx } from '@dxos/react-ui-theme';
|
|
23
24
|
import { isNotFalsy, safeParseInt } from '@dxos/util';
|
|
24
25
|
|
|
@@ -40,7 +41,7 @@ const blockEndLine =
|
|
|
40
41
|
'[&>.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';
|
|
41
42
|
|
|
42
43
|
//
|
|
43
|
-
// Root
|
|
44
|
+
// Table.Root
|
|
44
45
|
//
|
|
45
46
|
|
|
46
47
|
export type TableRootProps = PropsWithChildren<{ role?: string }>;
|
|
@@ -50,8 +51,8 @@ const TableRoot = ({ children, role }: TableRootProps) => {
|
|
|
50
51
|
<div
|
|
51
52
|
role='none'
|
|
52
53
|
className={mx(
|
|
53
|
-
'relative
|
|
54
|
-
role === 'section'
|
|
54
|
+
'relative !border-separator',
|
|
55
|
+
role === 'section' // TODO(burdon): This leaks composer plugin concepts? Standardize for react-ui?
|
|
55
56
|
? 'attention-surface overflow-hidden [&_.dx-grid]:max-is-[--dx-grid-content-inline-size]'
|
|
56
57
|
: 'flex flex-col [&_.dx-grid]:grow [&_.dx-grid]:max-is-[--dx-grid-content-inline-size] [&_.dx-grid]:bs-0 [&_.dx-grid]:max-bs-[--dx-grid-content-block-size]',
|
|
57
58
|
)}
|
|
@@ -62,7 +63,7 @@ const TableRoot = ({ children, role }: TableRootProps) => {
|
|
|
62
63
|
};
|
|
63
64
|
|
|
64
65
|
//
|
|
65
|
-
// Main
|
|
66
|
+
// Table.Main
|
|
66
67
|
//
|
|
67
68
|
|
|
68
69
|
export type TableController = {
|
|
@@ -72,21 +73,45 @@ export type TableController = {
|
|
|
72
73
|
export type TableMainProps = {
|
|
73
74
|
model?: TableModel;
|
|
74
75
|
presentation?: TablePresentation;
|
|
76
|
+
// TODO(burdon): Rename since attention isn't a useful concept here? Standardize across other components. Pass property into useAttention.
|
|
75
77
|
ignoreAttention?: boolean;
|
|
76
|
-
|
|
78
|
+
onRowClick?: (row: any) => void;
|
|
77
79
|
};
|
|
78
80
|
|
|
79
81
|
const TableMain = forwardRef<TableController, TableMainProps>(
|
|
80
|
-
({ model, presentation, ignoreAttention,
|
|
82
|
+
({ model, presentation, ignoreAttention, onRowClick }, forwardedRef) => {
|
|
81
83
|
const [dxGrid, setDxGrid] = useState<DxGridElement | null>(null);
|
|
82
84
|
const { hasAttention } = useAttention(model?.id ?? 'table');
|
|
83
85
|
const { t } = useTranslation(translationKey);
|
|
84
86
|
const modals = useMemo(() => new ModalController(), []);
|
|
85
87
|
|
|
86
|
-
const frozen = useMemo(
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
const frozen = useMemo(() => {
|
|
89
|
+
const noActionColumn =
|
|
90
|
+
model?.features.dataEditable === false &&
|
|
91
|
+
model?.features.schemaEditable === false &&
|
|
92
|
+
model.rowActions.length === 0;
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
frozenRowsStart: 1,
|
|
96
|
+
frozenColsStart: model?.features.selection.enabled ? 1 : 0,
|
|
97
|
+
frozenColsEnd: noActionColumn ? 0 : 1,
|
|
98
|
+
};
|
|
99
|
+
}, [model]);
|
|
100
|
+
|
|
101
|
+
// TODO(burdon): Replace useEffect below.
|
|
102
|
+
// const getCells = useCallback<GridContentProps['getCells']>(
|
|
103
|
+
// (range: DxGridRange, plane: DxGridPlane) => presentation?.getCells(range, plane) ?? {},
|
|
104
|
+
// [presentation],
|
|
105
|
+
// );
|
|
106
|
+
|
|
107
|
+
useEffect(() => {
|
|
108
|
+
if (!presentation || !dxGrid) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// TODO(burdon): Pass to Grid.Content?
|
|
113
|
+
dxGrid.getCells = (range, plane) => presentation.getCells(range, plane);
|
|
114
|
+
}, [presentation, dxGrid]);
|
|
90
115
|
|
|
91
116
|
/**
|
|
92
117
|
* Provides an external controller that can be called to repaint the table.
|
|
@@ -98,7 +123,6 @@ const TableMain = forwardRef<TableController, TableMainProps>(
|
|
|
98
123
|
return {};
|
|
99
124
|
}
|
|
100
125
|
|
|
101
|
-
dxGrid.getCells = (range, plane) => presentation.getCells(range, plane);
|
|
102
126
|
return {
|
|
103
127
|
update: (cell) => {
|
|
104
128
|
if (cell) {
|
|
@@ -115,11 +139,15 @@ const TableMain = forwardRef<TableController, TableMainProps>(
|
|
|
115
139
|
|
|
116
140
|
const handleGridClick = useCallback(
|
|
117
141
|
(event: MouseEvent) => {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
if (
|
|
142
|
+
const rowIndex = safeParseInt((event.target as HTMLElement).ariaRowIndex ?? '');
|
|
143
|
+
if (rowIndex != null) {
|
|
144
|
+
if (onRowClick) {
|
|
121
145
|
const row = model?.getRowAt(rowIndex);
|
|
122
|
-
row &&
|
|
146
|
+
row && onRowClick(row);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (model?.features.selection.enabled && model?.selection.selectionMode === 'single') {
|
|
150
|
+
model.selection.toggleSelectionForRowIndex(rowIndex);
|
|
123
151
|
}
|
|
124
152
|
}
|
|
125
153
|
|
|
@@ -328,32 +356,29 @@ const TableMain = forwardRef<TableController, TableMainProps>(
|
|
|
328
356
|
onQuery={handleQuery}
|
|
329
357
|
/>
|
|
330
358
|
<Grid.Content
|
|
331
|
-
onWheelCapture={handleWheel}
|
|
332
359
|
className={mx('[--dx-grid-base:var(--surface-bg)]', inlineEndLine, blockEndLine)}
|
|
333
360
|
frozen={frozen}
|
|
361
|
+
// getCells={getCells}
|
|
334
362
|
columns={model.columnMeta.value}
|
|
335
363
|
limitRows={model.getRowCount() ?? 0}
|
|
336
364
|
limitColumns={model.view?.fields?.length ?? 0}
|
|
365
|
+
overscroll='trap'
|
|
337
366
|
onAxisResize={handleAxisResize}
|
|
338
367
|
onClick={handleGridClick}
|
|
339
368
|
onKeyDown={handleKeyDown}
|
|
340
|
-
|
|
369
|
+
onWheelCapture={handleWheel}
|
|
341
370
|
ref={setDxGrid}
|
|
342
371
|
/>
|
|
343
372
|
<RowActionsMenu model={model} modals={modals} />
|
|
344
373
|
<ColumnActionsMenu model={model} modals={modals} />
|
|
345
374
|
<ColumnSettings model={model} modals={modals} onNewColumn={handleNewColumn} />
|
|
346
|
-
<RefPanel model={model} modals={modals} />
|
|
347
375
|
<CreateRefPanel model={model} modals={modals} />
|
|
376
|
+
<RefPanel model={model} modals={modals} />
|
|
348
377
|
</Grid.Root>
|
|
349
378
|
);
|
|
350
379
|
},
|
|
351
380
|
);
|
|
352
381
|
|
|
353
|
-
//
|
|
354
|
-
// CellEditor
|
|
355
|
-
//
|
|
356
|
-
|
|
357
382
|
export const Table = {
|
|
358
383
|
Root: TableRoot,
|
|
359
384
|
Main: TableMain,
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import '@dxos-theme';
|
|
6
|
+
|
|
7
|
+
import { type StoryObj, type Meta } from '@storybook/react';
|
|
8
|
+
import React, { useEffect, useMemo } from 'react';
|
|
9
|
+
|
|
10
|
+
import { AST, type BaseObject, ImmutableSchema, type BaseSchema, type HasId } from '@dxos/echo-schema';
|
|
11
|
+
import { getAnnotation } from '@dxos/effect';
|
|
12
|
+
import { faker } from '@dxos/random';
|
|
13
|
+
import { create, makeRef, type ReactiveObject } from '@dxos/react-client/echo';
|
|
14
|
+
import { withClientProvider } from '@dxos/react-client/testing';
|
|
15
|
+
import { createView, ViewProjection, ViewType } from '@dxos/schema';
|
|
16
|
+
import { createGenerator, Testing, type ValueGenerator } from '@dxos/schema/testing';
|
|
17
|
+
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
18
|
+
|
|
19
|
+
import { Table } from './Table';
|
|
20
|
+
import { useTableModel } from '../../hooks';
|
|
21
|
+
import { TablePresentation } from '../../model';
|
|
22
|
+
import translations from '../../translations';
|
|
23
|
+
import { TableType } from '../../types';
|
|
24
|
+
|
|
25
|
+
faker.seed(1);
|
|
26
|
+
const generator: ValueGenerator = faker as any;
|
|
27
|
+
|
|
28
|
+
// TODO(burdon): Many-to-many relations.
|
|
29
|
+
// TODO(burdon): Mutable and immutable views.
|
|
30
|
+
// TODO(burdon): Reconcile schemas types and utils (see API PR).
|
|
31
|
+
// TODO(burdon): Base type for T (with id); see ECHO API PR?
|
|
32
|
+
const useTestModel = <T extends BaseObject & HasId>(schema: BaseSchema<T>, count: number) => {
|
|
33
|
+
const table = useMemo(() => {
|
|
34
|
+
// const { typename } = pipe(schema.ast, AST.getAnnotation<TypeAnnotation>(TypeAnnotationId), Option.getOrThrow);
|
|
35
|
+
const typename = schema.typename;
|
|
36
|
+
const name = getAnnotation<string>(AST.TitleAnnotationId)(schema.ast) ?? typename;
|
|
37
|
+
const view = createView({ name, typename, jsonSchema: schema.jsonSchema });
|
|
38
|
+
return create(TableType, { view: makeRef(view) });
|
|
39
|
+
}, [schema]);
|
|
40
|
+
|
|
41
|
+
const projection = useMemo(() => {
|
|
42
|
+
if (!table.view?.target) {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// TODO(burdon): Just pass in view? Reuse same jsonSchema instance? View determines if mutable, etc.
|
|
47
|
+
return new ViewProjection(schema.jsonSchema, table.view.target);
|
|
48
|
+
}, [schema, table]);
|
|
49
|
+
|
|
50
|
+
const model = useTableModel({ table, projection, rows: [] });
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
if (!model) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const objectGenerator = createGenerator(generator, schema, { optional: true });
|
|
57
|
+
const objects: ReactiveObject<T>[] = Array.from({ length: count }).map(() => objectGenerator.createObject());
|
|
58
|
+
model.setRows(objects);
|
|
59
|
+
}, [model]);
|
|
60
|
+
|
|
61
|
+
const presentation = useMemo(() => {
|
|
62
|
+
if (!model) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return new TablePresentation(model);
|
|
67
|
+
}, [model]);
|
|
68
|
+
|
|
69
|
+
return { model, presentation };
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const DefaultStory = () => {
|
|
73
|
+
// TODO(burdon): Remove need for ImmutableSchema wrapper at API-level.
|
|
74
|
+
const orgSchema = useMemo(() => new ImmutableSchema(Testing.Org), []);
|
|
75
|
+
const { model: orgModel, presentation: orgPresentation } = useTestModel<Testing.Org>(orgSchema, 50);
|
|
76
|
+
|
|
77
|
+
// TODO(burdon): Generate links with references.
|
|
78
|
+
const contactSchema = useMemo(() => new ImmutableSchema(Testing.Contact), []);
|
|
79
|
+
const { model: contactModel, presentation: contactPresentation } = useTestModel<Testing.Contact>(contactSchema, 50);
|
|
80
|
+
|
|
81
|
+
// TODO(burdon): Scrolling isn't working.
|
|
82
|
+
return (
|
|
83
|
+
<div className='grow grid grid-cols-2 divide-x divide-separator'>
|
|
84
|
+
<Table.Root>
|
|
85
|
+
<Table.Main model={orgModel} presentation={orgPresentation} />
|
|
86
|
+
</Table.Root>
|
|
87
|
+
<Table.Root>
|
|
88
|
+
<Table.Main model={contactModel} presentation={contactPresentation} />
|
|
89
|
+
</Table.Root>
|
|
90
|
+
</div>
|
|
91
|
+
);
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const meta: Meta<typeof DefaultStory> = {
|
|
95
|
+
title: 'ui/react-ui-table/relations',
|
|
96
|
+
render: DefaultStory,
|
|
97
|
+
parameters: { translations },
|
|
98
|
+
decorators: [
|
|
99
|
+
withClientProvider({
|
|
100
|
+
types: [TableType, ViewType, Testing.Org, Testing.Contact],
|
|
101
|
+
createIdentity: true,
|
|
102
|
+
createSpace: true,
|
|
103
|
+
}),
|
|
104
|
+
withTheme,
|
|
105
|
+
withLayout({ fullscreen: true, tooltips: true }),
|
|
106
|
+
],
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
export default meta;
|
|
110
|
+
|
|
111
|
+
type Story = StoryObj<typeof DefaultStory>;
|
|
112
|
+
|
|
113
|
+
export const Default: Story = {};
|
|
@@ -18,6 +18,7 @@ import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
|
18
18
|
|
|
19
19
|
import { TableCellEditor, type TableCellEditorProps } from './TableCellEditor';
|
|
20
20
|
import { useTableModel } from '../../hooks';
|
|
21
|
+
import { type TableFeatures } from '../../model';
|
|
21
22
|
import translations from '../../translations';
|
|
22
23
|
import { TableType } from '../../types';
|
|
23
24
|
import { initializeTable } from '../../util';
|
|
@@ -44,12 +45,16 @@ const DefaultStory = ({ editing }: StoryProps) => {
|
|
|
44
45
|
|
|
45
46
|
const projection = useMemo(() => {
|
|
46
47
|
if (schema && table?.view) {
|
|
47
|
-
return new ViewProjection(schema, table.view.target!);
|
|
48
|
+
return new ViewProjection(schema.jsonSchema, table.view.target!);
|
|
48
49
|
}
|
|
49
50
|
}, [schema, table?.view]);
|
|
50
51
|
|
|
51
|
-
const features = useMemo(
|
|
52
|
-
() => ({
|
|
52
|
+
const features: Partial<TableFeatures> = useMemo(
|
|
53
|
+
() => ({
|
|
54
|
+
selection: { enabled: true, mode: 'multiple' },
|
|
55
|
+
dataEditable: true,
|
|
56
|
+
schemaEditable: !(schema instanceof ImmutableSchema),
|
|
57
|
+
}),
|
|
53
58
|
[],
|
|
54
59
|
);
|
|
55
60
|
|