@dxos/react-ui-table 0.8.4-main.9735255 → 0.8.4-main.9be5663bfe
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-OZBLY7XM.mjs → chunk-BF54SSNL.mjs} +12 -18
- package/dist/lib/browser/chunk-BF54SSNL.mjs.map +7 -0
- package/dist/lib/browser/{chunk-I5IFW7UF.mjs → chunk-F7Y374KL.mjs} +39 -34
- package/dist/lib/browser/chunk-F7Y374KL.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +205 -179
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +6 -6
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/browser/types/index.mjs +1 -1
- package/dist/lib/node-esm/{chunk-DDJKYJFY.mjs → chunk-CCJ4LOVM.mjs} +39 -34
- package/dist/lib/node-esm/chunk-CCJ4LOVM.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-WNZSKIRF.mjs → chunk-SIRDIPHZ.mjs} +12 -18
- package/dist/lib/node-esm/chunk-SIRDIPHZ.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +205 -179
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +6 -6
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/types/index.mjs +1 -1
- package/dist/types/src/components/Table/ColumnSettings.d.ts.map +1 -1
- package/dist/types/src/components/Table/DynamicTable.d.ts +5 -4
- package/dist/types/src/components/Table/DynamicTable.d.ts.map +1 -1
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts +20 -22
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/Relations.stories.d.ts +81 -82
- package/dist/types/src/components/Table/Relations.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.d.ts +20 -21
- package/dist/types/src/components/Table/Table.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.stories.d.ts +83 -84
- package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/TableContent.d.ts +17 -0
- package/dist/types/src/components/Table/TableContent.d.ts.map +1 -0
- package/dist/types/src/components/Table/TableToolbar.d.ts +21 -0
- package/dist/types/src/components/Table/TableToolbar.d.ts.map +1 -0
- package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts +3 -3
- package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +2 -2
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts +22 -24
- package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +0 -1
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useAddRow.d.ts +1 -1
- package/dist/types/src/hooks/useAddRow.d.ts.map +1 -1
- package/dist/types/src/hooks/useProjectionModel.d.ts +1 -1
- package/dist/types/src/hooks/useProjectionModel.d.ts.map +1 -1
- package/dist/types/src/hooks/useTableModel.d.ts +1 -1
- package/dist/types/src/model/table-model.d.ts +5 -4
- 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/playwright/TableManager.d.ts +2 -1
- package/dist/types/src/playwright/TableManager.d.ts.map +1 -1
- package/dist/types/src/testing/useTestTableModel.d.ts +2 -2
- package/dist/types/src/testing/useTestTableModel.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +19 -21
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/Table.d.ts +1 -6
- package/dist/types/src/types/Table.d.ts.map +1 -1
- package/dist/types/src/util/dynamic-table.d.ts +6 -5
- package/dist/types/src/util/dynamic-table.d.ts.map +1 -1
- package/dist/types/src/util/dynamic-table.test.d.ts +2 -0
- package/dist/types/src/util/dynamic-table.test.d.ts.map +1 -0
- package/dist/types/src/util/query-ast.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +43 -43
- package/src/components/Table/ColumnActionsMenu.tsx +5 -5
- package/src/components/Table/ColumnSettings.tsx +3 -4
- package/src/components/Table/DynamicTable.stories.tsx +17 -17
- package/src/components/Table/DynamicTable.tsx +13 -20
- package/src/components/Table/Relations.stories.tsx +38 -30
- package/src/components/Table/Table.stories.tsx +69 -49
- package/src/components/Table/Table.tsx +41 -435
- package/src/components/Table/TableContent.tsx +421 -0
- package/src/components/{TableToolbar → Table}/TableToolbar.tsx +35 -42
- package/src/components/TableCellEditor/CellValidationMessage.tsx +4 -4
- package/src/components/TableCellEditor/FormCellEditor.tsx +12 -6
- package/src/components/TableCellEditor/TableCellEditor.stories.tsx +11 -11
- package/src/components/TableCellEditor/TableCellEditor.tsx +12 -10
- package/src/components/index.ts +0 -1
- package/src/components/testing.ts +10 -10
- package/src/hooks/useAddRow.ts +1 -1
- package/src/hooks/useProjectionModel.ts +3 -3
- package/src/hooks/useTableModel.ts +1 -1
- package/src/model/table-model.test.ts +5 -6
- package/src/model/table-model.ts +15 -14
- package/src/model/table-presentation.test.ts +5 -6
- package/src/model/table-presentation.ts +12 -12
- package/src/playwright/TableManager.ts +10 -3
- package/src/playwright/playwright.config.ts +1 -1
- package/src/playwright/smoke.spec.ts +48 -5
- package/src/testing/useTestTableModel.ts +6 -6
- package/src/translations.ts +19 -21
- package/src/types/Table.ts +11 -22
- package/src/util/dynamic-table.test.ts +70 -0
- package/src/util/dynamic-table.ts +17 -16
- package/src/util/query-ast.ts +3 -0
- package/src/util/table-buttons.ts +1 -1
- package/src/util/table-controls.ts +2 -2
- package/dist/lib/browser/chunk-I5IFW7UF.mjs.map +0 -7
- package/dist/lib/browser/chunk-OZBLY7XM.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-DDJKYJFY.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-WNZSKIRF.mjs.map +0 -7
- package/dist/types/src/components/TableToolbar/TableToolbar.d.ts +0 -21
- package/dist/types/src/components/TableToolbar/TableToolbar.d.ts.map +0 -1
- package/dist/types/src/components/TableToolbar/index.d.ts +0 -2
- package/dist/types/src/components/TableToolbar/index.d.ts.map +0 -1
- package/src/components/TableToolbar/index.ts +0 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/react-ui-table",
|
|
3
|
-
"version": "0.8.4-main.
|
|
3
|
+
"version": "0.8.4-main.9be5663bfe",
|
|
4
4
|
"description": "A table component.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -60,66 +60,66 @@
|
|
|
60
60
|
"@codemirror/autocomplete": "^6.19.0",
|
|
61
61
|
"@codemirror/state": "^6.5.2",
|
|
62
62
|
"@codemirror/view": "^6.38.4",
|
|
63
|
-
"@effect-atom/atom-react": "^0.
|
|
63
|
+
"@effect-atom/atom-react": "^0.5.0",
|
|
64
64
|
"@fluentui/react-tabster": "9.26.11",
|
|
65
65
|
"@radix-ui/react-context": "1.1.1",
|
|
66
66
|
"@radix-ui/react-primitive": "2.0.2",
|
|
67
67
|
"@radix-ui/react-slot": "1.1.2",
|
|
68
68
|
"@radix-ui/react-use-controllable-state": "1.1.0",
|
|
69
|
-
"date-fns": "^3.
|
|
69
|
+
"date-fns": "^3.6.0",
|
|
70
70
|
"lodash.orderby": "^4.6.0",
|
|
71
|
-
"@dxos/
|
|
72
|
-
"@dxos/debug": "0.8.4-main.
|
|
73
|
-
"@dxos/
|
|
74
|
-
"@dxos/
|
|
75
|
-
"@dxos/
|
|
76
|
-
"@dxos/
|
|
77
|
-
"@dxos/
|
|
78
|
-
"@dxos/
|
|
79
|
-
"@dxos/
|
|
80
|
-
"@dxos/
|
|
81
|
-
"@dxos/
|
|
82
|
-
"@dxos/react-
|
|
83
|
-
"@dxos/react-ui-
|
|
84
|
-
"@dxos/react-
|
|
85
|
-
"@dxos/react-ui-
|
|
86
|
-
"@dxos/react-ui-
|
|
87
|
-
"@dxos/react-ui-
|
|
88
|
-
"@dxos/react-ui-
|
|
89
|
-
"@dxos/react-ui-
|
|
90
|
-
"@dxos/
|
|
91
|
-
"@dxos/
|
|
92
|
-
"@dxos/
|
|
93
|
-
"@dxos/
|
|
94
|
-
"@dxos/
|
|
95
|
-
"@dxos/
|
|
71
|
+
"@dxos/async": "0.8.4-main.9be5663bfe",
|
|
72
|
+
"@dxos/debug": "0.8.4-main.9be5663bfe",
|
|
73
|
+
"@dxos/context": "0.8.4-main.9be5663bfe",
|
|
74
|
+
"@dxos/effect": "0.8.4-main.9be5663bfe",
|
|
75
|
+
"@dxos/invariant": "0.8.4-main.9be5663bfe",
|
|
76
|
+
"@dxos/keys": "0.8.4-main.9be5663bfe",
|
|
77
|
+
"@dxos/echo-atom": "0.8.4-main.9be5663bfe",
|
|
78
|
+
"@dxos/lit-grid": "0.8.4-main.9be5663bfe",
|
|
79
|
+
"@dxos/log": "0.8.4-main.9be5663bfe",
|
|
80
|
+
"@dxos/random": "0.8.4-main.9be5663bfe",
|
|
81
|
+
"@dxos/react-ui-attention": "0.8.4-main.9be5663bfe",
|
|
82
|
+
"@dxos/react-ui-components": "0.8.4-main.9be5663bfe",
|
|
83
|
+
"@dxos/react-ui-form": "0.8.4-main.9be5663bfe",
|
|
84
|
+
"@dxos/react-client": "0.8.4-main.9be5663bfe",
|
|
85
|
+
"@dxos/react-ui-grid": "0.8.4-main.9be5663bfe",
|
|
86
|
+
"@dxos/react-ui-menu": "0.8.4-main.9be5663bfe",
|
|
87
|
+
"@dxos/react-ui-editor": "0.8.4-main.9be5663bfe",
|
|
88
|
+
"@dxos/react-ui-search": "0.8.4-main.9be5663bfe",
|
|
89
|
+
"@dxos/react-ui-stack": "0.8.4-main.9be5663bfe",
|
|
90
|
+
"@dxos/react-ui-syntax-highlighter": "0.8.4-main.9be5663bfe",
|
|
91
|
+
"@dxos/schema": "0.8.4-main.9be5663bfe",
|
|
92
|
+
"@dxos/types": "0.8.4-main.9be5663bfe",
|
|
93
|
+
"@dxos/util": "0.8.4-main.9be5663bfe",
|
|
94
|
+
"@dxos/ui-types": "0.8.4-main.9be5663bfe",
|
|
95
|
+
"@dxos/echo": "0.8.4-main.9be5663bfe"
|
|
96
96
|
},
|
|
97
97
|
"devDependencies": {
|
|
98
|
-
"@effect/platform": "0.
|
|
98
|
+
"@effect/platform": "0.94.4",
|
|
99
99
|
"@types/lodash.orderby": "^4.6.9",
|
|
100
100
|
"@types/react": "~19.2.7",
|
|
101
101
|
"@types/react-dom": "~19.2.3",
|
|
102
|
-
"effect": "3.
|
|
102
|
+
"effect": "3.20.0",
|
|
103
103
|
"fast-check": "^3.19.0",
|
|
104
104
|
"react": "~19.2.3",
|
|
105
105
|
"react-dom": "~19.2.3",
|
|
106
|
-
"vite": "7.1.
|
|
107
|
-
"@dxos/lit-ui": "0.8.4-main.
|
|
108
|
-
"@dxos/random": "0.8.4-main.
|
|
109
|
-
"@dxos/react-client": "0.8.4-main.
|
|
110
|
-
"@dxos/
|
|
111
|
-
"@dxos/
|
|
112
|
-
"@dxos/ui
|
|
113
|
-
"@dxos/
|
|
106
|
+
"vite": "^7.1.11",
|
|
107
|
+
"@dxos/lit-ui": "0.8.4-main.9be5663bfe",
|
|
108
|
+
"@dxos/random": "0.8.4-main.9be5663bfe",
|
|
109
|
+
"@dxos/react-client": "0.8.4-main.9be5663bfe",
|
|
110
|
+
"@dxos/test-utils": "0.8.4-main.9be5663bfe",
|
|
111
|
+
"@dxos/storybook-utils": "0.8.4-main.9be5663bfe",
|
|
112
|
+
"@dxos/react-ui": "0.8.4-main.9be5663bfe",
|
|
113
|
+
"@dxos/ui-theme": "0.8.4-main.9be5663bfe"
|
|
114
114
|
},
|
|
115
115
|
"peerDependencies": {
|
|
116
|
-
"@effect-atom/atom-react": "^0.
|
|
117
|
-
"@effect/platform": "0.
|
|
118
|
-
"effect": "3.
|
|
116
|
+
"@effect-atom/atom-react": "^0.5.0",
|
|
117
|
+
"@effect/platform": "0.94.4",
|
|
118
|
+
"effect": "3.20.0",
|
|
119
119
|
"react": "~19.2.3",
|
|
120
120
|
"react-dom": "~19.2.3",
|
|
121
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
122
|
-
"@dxos/ui-theme": "0.8.4-main.
|
|
121
|
+
"@dxos/react-ui": "0.8.4-main.9be5663bfe",
|
|
122
|
+
"@dxos/ui-theme": "0.8.4-main.9be5663bfe"
|
|
123
123
|
},
|
|
124
124
|
"publishConfig": {
|
|
125
125
|
"access": "public"
|
|
@@ -36,7 +36,7 @@ export const ColumnActionsMenu = ({ model, modals }: ColumnActionsMenuProps) =>
|
|
|
36
36
|
data-testid='column-sort-descending'
|
|
37
37
|
onClick={() => model.setSort(state.fieldId, 'desc')}
|
|
38
38
|
>
|
|
39
|
-
{t('column
|
|
39
|
+
{t('column-action-sort-descending.menu')}
|
|
40
40
|
</DropdownMenu.Item>
|
|
41
41
|
)}
|
|
42
42
|
{(!isCurrentColumnSorted || currentSort?.direction === 'desc') && (
|
|
@@ -44,22 +44,22 @@ export const ColumnActionsMenu = ({ model, modals }: ColumnActionsMenuProps) =>
|
|
|
44
44
|
data-testid='column-sort-ascending'
|
|
45
45
|
onClick={() => model.setSort(state.fieldId, 'asc')}
|
|
46
46
|
>
|
|
47
|
-
{t('column
|
|
47
|
+
{t('column-action-sort-ascending.menu')}
|
|
48
48
|
</DropdownMenu.Item>
|
|
49
49
|
)}
|
|
50
50
|
{isCurrentColumnSorted && (
|
|
51
51
|
<DropdownMenu.Item data-testid='column-clear-sort' onClick={() => model.clearSort()}>
|
|
52
|
-
{t('column
|
|
52
|
+
{t('column-action-clear-sorting.menu')}
|
|
53
53
|
</DropdownMenu.Item>
|
|
54
54
|
)}
|
|
55
55
|
{model.getColumnCount() > 1 && model.features.schemaEditable && (
|
|
56
56
|
<DropdownMenu.Item data-testid='column-delete' onClick={() => model.deleteColumn(state.fieldId)}>
|
|
57
|
-
{t('column
|
|
57
|
+
{t('column-action-delete.menu')}
|
|
58
58
|
</DropdownMenu.Item>
|
|
59
59
|
)}
|
|
60
60
|
{model.features.schemaEditable && (
|
|
61
61
|
<DropdownMenu.Item data-testid='column-settings' onClick={() => modals.openColumnSettings()}>
|
|
62
|
-
{t('column
|
|
62
|
+
{t('column-action-settings.menu')}
|
|
63
63
|
</DropdownMenu.Item>
|
|
64
64
|
)}
|
|
65
65
|
</DropdownMenu.Viewport>
|
|
@@ -5,10 +5,9 @@
|
|
|
5
5
|
import { useAtomValue } from '@effect-atom/atom-react';
|
|
6
6
|
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
7
7
|
|
|
8
|
-
import { type SchemaRegistry } from '@dxos/echo';
|
|
8
|
+
import { type SchemaRegistry, type View } from '@dxos/echo';
|
|
9
9
|
import { Popover } from '@dxos/react-ui';
|
|
10
10
|
import { FieldEditor } from '@dxos/react-ui-form';
|
|
11
|
-
import { type FieldType } from '@dxos/schema';
|
|
12
11
|
|
|
13
12
|
import { type ModalController, type TableModel } from '../../model';
|
|
14
13
|
|
|
@@ -20,7 +19,7 @@ type ColumnSettingsProps = {
|
|
|
20
19
|
};
|
|
21
20
|
|
|
22
21
|
export const ColumnSettings = ({ registry, model, modals, onNewColumn }: ColumnSettingsProps) => {
|
|
23
|
-
const [newField, setNewField] = useState<FieldType>();
|
|
22
|
+
const [newField, setNewField] = useState<View.FieldType>();
|
|
24
23
|
const state = useAtomValue(modals.state);
|
|
25
24
|
|
|
26
25
|
useEffect(() => {
|
|
@@ -64,7 +63,7 @@ export const ColumnSettings = ({ registry, model, modals, onNewColumn }: ColumnS
|
|
|
64
63
|
<Popover.Root modal={false} open={state?.type === 'columnSettings'}>
|
|
65
64
|
<Popover.VirtualTrigger virtualRef={modals.trigger} />
|
|
66
65
|
<Popover.Portal>
|
|
67
|
-
<Popover.Content classNames='md:
|
|
66
|
+
<Popover.Content classNames='md:w-64'>
|
|
68
67
|
<Popover.Viewport>
|
|
69
68
|
<FieldEditor
|
|
70
69
|
projection={model.projection}
|
|
@@ -3,24 +3,24 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
6
|
+
import type * as Types from 'effect/Types';
|
|
6
7
|
import React, { useMemo, useState } from 'react';
|
|
7
8
|
|
|
8
|
-
import { Obj } from '@dxos/echo';
|
|
9
|
-
import { Format
|
|
10
|
-
import {
|
|
9
|
+
import { type JsonSchema, Obj } from '@dxos/echo';
|
|
10
|
+
import { Format } from '@dxos/echo/internal';
|
|
11
|
+
import { random } from '@dxos/random';
|
|
11
12
|
import { Filter, useQuery, useSchema } from '@dxos/react-client/echo';
|
|
12
13
|
import { useClientStory, withClientProvider } from '@dxos/react-client/testing';
|
|
13
|
-
import { withTheme } from '@dxos/react-ui/testing';
|
|
14
|
+
import { withLayout, withTheme } from '@dxos/react-ui/testing';
|
|
14
15
|
import { type SchemaPropertyDefinition } from '@dxos/schema';
|
|
15
16
|
import { TestSchema } from '@dxos/schema/testing';
|
|
16
17
|
import { withRegistry } from '@dxos/storybook-utils';
|
|
17
18
|
|
|
18
19
|
import { type TableFeatures } from '../../model';
|
|
19
20
|
import { translations } from '../../translations';
|
|
20
|
-
|
|
21
21
|
import { DynamicTable } from './DynamicTable';
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
random.seed(0);
|
|
24
24
|
|
|
25
25
|
const useTestPropertiesAndObjects = () => {
|
|
26
26
|
const properties = useMemo<SchemaPropertyDefinition[]>(
|
|
@@ -33,9 +33,9 @@ const useTestPropertiesAndObjects = () => {
|
|
|
33
33
|
|
|
34
34
|
const [rows] = useState<any[]>(
|
|
35
35
|
Array.from({ length: 10 }, () => ({
|
|
36
|
-
id:
|
|
37
|
-
name:
|
|
38
|
-
age:
|
|
36
|
+
id: random.string.uuid(),
|
|
37
|
+
name: random.person.fullName(),
|
|
38
|
+
age: random.number.int({ min: 18, max: 80 }),
|
|
39
39
|
})),
|
|
40
40
|
);
|
|
41
41
|
|
|
@@ -58,7 +58,7 @@ const DynamicTableStory = () => {
|
|
|
58
58
|
const meta = {
|
|
59
59
|
title: 'ui/react-ui-table/DynamicTable',
|
|
60
60
|
component: DynamicTable,
|
|
61
|
-
decorators: [withTheme, withRegistry],
|
|
61
|
+
decorators: [withTheme(), withLayout({ layout: 'fullscreen' }), withRegistry],
|
|
62
62
|
parameters: {
|
|
63
63
|
layout: 'fullscreen',
|
|
64
64
|
translations,
|
|
@@ -101,7 +101,7 @@ export const WithClickToSelect: StoryObj = {
|
|
|
101
101
|
|
|
102
102
|
export const WithJsonSchema: StoryObj = {
|
|
103
103
|
render: () => {
|
|
104
|
-
const schema = useMemo<
|
|
104
|
+
const schema = useMemo<Types.DeepMutable<JsonSchema.JsonSchema>>(
|
|
105
105
|
() => ({
|
|
106
106
|
type: 'object',
|
|
107
107
|
properties: {
|
|
@@ -117,10 +117,10 @@ export const WithJsonSchema: StoryObj = {
|
|
|
117
117
|
|
|
118
118
|
const [rows] = useState<any[]>(
|
|
119
119
|
Array.from({ length: 15 }, () => ({
|
|
120
|
-
name:
|
|
121
|
-
age:
|
|
122
|
-
email:
|
|
123
|
-
active:
|
|
120
|
+
name: random.person.fullName(),
|
|
121
|
+
age: random.number.int({ min: 18, max: 80 }),
|
|
122
|
+
email: random.internet.email(),
|
|
123
|
+
active: random.datatype.boolean(),
|
|
124
124
|
})),
|
|
125
125
|
);
|
|
126
126
|
|
|
@@ -148,8 +148,8 @@ export const WithEchoSchema: StoryObj = {
|
|
|
148
148
|
Array.from({ length: 10 }).forEach(() => {
|
|
149
149
|
space.db.add(
|
|
150
150
|
Obj.make(TestSchema.Person, {
|
|
151
|
-
name:
|
|
152
|
-
email:
|
|
151
|
+
name: random.person.fullName(),
|
|
152
|
+
email: random.internet.email(),
|
|
153
153
|
}),
|
|
154
154
|
);
|
|
155
155
|
});
|
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { RegistryContext } from '@effect-atom/atom-react';
|
|
6
|
+
import type * as Types from 'effect/Types';
|
|
6
7
|
import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
|
7
8
|
|
|
8
9
|
import { type Type } from '@dxos/echo';
|
|
9
|
-
import { type
|
|
10
|
+
import { type JsonSchema } from '@dxos/echo';
|
|
10
11
|
import { type ThemedClassName, useDefaultValue } from '@dxos/react-ui';
|
|
11
12
|
import { type ProjectionModel } from '@dxos/schema';
|
|
12
13
|
import { mx } from '@dxos/ui-theme';
|
|
@@ -15,15 +16,14 @@ import { useTableModel } from '../../hooks';
|
|
|
15
16
|
import { type TableFeatures, TablePresentation, type TableRowAction } from '../../model';
|
|
16
17
|
import { type Table as TableType } from '../../types';
|
|
17
18
|
import { type TablePropertyDefinition, getBaseSchema, makeDynamicTable } from '../../util';
|
|
18
|
-
|
|
19
19
|
import { Table, type TableController } from './Table';
|
|
20
20
|
|
|
21
|
-
export type DynamicTableProps<T extends Type.
|
|
21
|
+
export type DynamicTableProps<T extends Type.AnyEntity = Type.AnyEntity> = ThemedClassName<{
|
|
22
22
|
schema?: T;
|
|
23
23
|
name?: string; // TODO(burdon): Remove?
|
|
24
24
|
rows: any[];
|
|
25
25
|
properties?: TablePropertyDefinition[];
|
|
26
|
-
jsonSchema?:
|
|
26
|
+
jsonSchema?: Types.DeepMutable<JsonSchema.JsonSchema>;
|
|
27
27
|
features?: Partial<TableFeatures>;
|
|
28
28
|
rowActions?: TableRowAction[];
|
|
29
29
|
onRowClick?: (row: any) => void;
|
|
@@ -35,13 +35,13 @@ export type DynamicTableProps<T extends Type.Entity.Any = Type.Entity.Any> = The
|
|
|
35
35
|
*/
|
|
36
36
|
// TODO(burdon): Instead of creating component variants, create helpers/hooks that normalize the props.
|
|
37
37
|
// TODO(burdon): Warning: Cannot update a component (`DynamicTable`) while rendering a different component (`DynamicTable`).
|
|
38
|
-
export const DynamicTable = <T extends Type.
|
|
38
|
+
export const DynamicTable = <T extends Type.AnyEntity = Type.AnyEntity>({
|
|
39
39
|
classNames,
|
|
40
40
|
schema,
|
|
41
|
-
name = 'example.
|
|
41
|
+
name = 'com.example.dynamic-table', // Remove default or make random; this will lead to type collisions.
|
|
42
42
|
rows,
|
|
43
43
|
properties,
|
|
44
|
-
jsonSchema:
|
|
44
|
+
jsonSchema: jsonSchemaProp,
|
|
45
45
|
rowActions,
|
|
46
46
|
onRowClick,
|
|
47
47
|
onRowAction,
|
|
@@ -52,8 +52,8 @@ export const DynamicTable = <T extends Type.Entity.Any = Type.Entity.Any>({
|
|
|
52
52
|
|
|
53
53
|
// TODO(burdon): Remove variance from the props (should be normalized externally; possibly via hooks).
|
|
54
54
|
const { jsonSchema } = useMemo(
|
|
55
|
-
() => getBaseSchema({ typename: name, properties, jsonSchema:
|
|
56
|
-
[name, properties,
|
|
55
|
+
() => getBaseSchema({ typename: name, properties, jsonSchema: jsonSchemaProp, schema }),
|
|
56
|
+
[name, properties, jsonSchemaProp, schema],
|
|
57
57
|
);
|
|
58
58
|
|
|
59
59
|
useEffect(() => {
|
|
@@ -95,18 +95,11 @@ export const DynamicTable = <T extends Type.Entity.Any = Type.Entity.Any>({
|
|
|
95
95
|
}
|
|
96
96
|
}, [registry, model]);
|
|
97
97
|
|
|
98
|
-
// TODO(burdon): Do we need the outer divs?
|
|
99
98
|
return (
|
|
100
|
-
<div role='none' className={mx('
|
|
101
|
-
<div role='none' className='grid min-
|
|
102
|
-
<Table.Root>
|
|
103
|
-
<Table.
|
|
104
|
-
ref={tableRef}
|
|
105
|
-
model={model}
|
|
106
|
-
presentation={presentation}
|
|
107
|
-
ignoreAttention
|
|
108
|
-
onRowClick={onRowClick}
|
|
109
|
-
/>
|
|
99
|
+
<div role='none' className={mx('dx-expander grid', classNames)}>
|
|
100
|
+
<div role='none' className='grid min-h-0 overflow-hidden'>
|
|
101
|
+
<Table.Root ref={tableRef}>
|
|
102
|
+
<Table.Content model={model} presentation={presentation} ignoreAttention onRowClick={onRowClick} />
|
|
110
103
|
</Table.Root>
|
|
111
104
|
</div>
|
|
112
105
|
</div>
|
|
@@ -5,37 +5,37 @@
|
|
|
5
5
|
import { RegistryContext } from '@effect-atom/atom-react';
|
|
6
6
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
7
7
|
import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react';
|
|
8
|
-
import { expect, userEvent, within } from 'storybook/test';
|
|
8
|
+
import { expect, userEvent, waitFor, within } from 'storybook/test';
|
|
9
9
|
|
|
10
10
|
import { Obj, Type } from '@dxos/echo';
|
|
11
|
+
import { View } from '@dxos/echo';
|
|
11
12
|
import { invariant } from '@dxos/invariant';
|
|
12
13
|
import { type DxGrid } from '@dxos/lit-grid';
|
|
13
|
-
import '@dxos/
|
|
14
|
-
import { faker } from '@dxos/random';
|
|
14
|
+
import { random } from '@dxos/random';
|
|
15
15
|
import { useClientStory, withClientProvider } from '@dxos/react-client/testing';
|
|
16
16
|
import { useAsyncEffect } from '@dxos/react-ui';
|
|
17
|
-
import { withLayout, withTheme } from '@dxos/react-ui/testing';
|
|
18
17
|
import { translations as formTranslations } from '@dxos/react-ui-form';
|
|
19
|
-
import {
|
|
18
|
+
import { withLayout, withTheme } from '@dxos/react-ui/testing';
|
|
19
|
+
import { ViewModel } from '@dxos/schema';
|
|
20
20
|
import { type ValueGenerator, createAsyncGenerator } from '@dxos/schema/testing';
|
|
21
21
|
import { withRegistry } from '@dxos/storybook-utils';
|
|
22
22
|
import { Organization, Person } from '@dxos/types';
|
|
23
|
+
import '@dxos/lit-ui/dx-tag-picker.pcss';
|
|
23
24
|
|
|
24
25
|
import { useProjectionModel, useTableModel } from '../../hooks';
|
|
25
26
|
import { type TableFeatures, TablePresentation, type TableRow } from '../../model';
|
|
26
27
|
import { translations } from '../../translations';
|
|
27
28
|
import { Table } from '../../types';
|
|
28
|
-
|
|
29
29
|
import { Table as TableComponent } from './Table';
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
const generator: ValueGenerator =
|
|
31
|
+
random.seed(1);
|
|
32
|
+
const generator: ValueGenerator = random as any;
|
|
33
33
|
|
|
34
34
|
// TODO(burdon): Many-to-many relations.
|
|
35
35
|
// TODO(burdon): Mutable and immutable views.
|
|
36
36
|
// TODO(burdon): Reconcile schemas types and utils (see API PR).
|
|
37
37
|
// TODO(burdon): Base type for T (with id); see ECHO API PR?
|
|
38
|
-
const useTestModel = <S extends Type.
|
|
38
|
+
const useTestModel = <S extends Type.AnyObj>(schema: S, count: number) => {
|
|
39
39
|
const registry = useContext(RegistryContext);
|
|
40
40
|
const { space } = useClientStory();
|
|
41
41
|
const [object, setObject] = useState<Table.Table>();
|
|
@@ -50,7 +50,7 @@ const useTestModel = <S extends Type.Obj.Any>(schema: S, count: number) => {
|
|
|
50
50
|
return;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
const { view, jsonSchema } = await
|
|
53
|
+
const { view, jsonSchema } = await ViewModel.makeFromDatabase({ db: space.db, typename: Type.getTypename(schema) });
|
|
54
54
|
const object = Table.make({ view, jsonSchema });
|
|
55
55
|
setObject(object);
|
|
56
56
|
space.db.add(object);
|
|
@@ -87,7 +87,7 @@ const DefaultStory = () => {
|
|
|
87
87
|
const { space } = useClientStory();
|
|
88
88
|
|
|
89
89
|
const handleCreate = useCallback(
|
|
90
|
-
(schema: Type.
|
|
90
|
+
(schema: Type.AnyEntity, values: any) => {
|
|
91
91
|
invariant(Type.isObjectSchema(schema));
|
|
92
92
|
invariant(space);
|
|
93
93
|
return space.db.add(Obj.make(schema, values));
|
|
@@ -96,9 +96,9 @@ const DefaultStory = () => {
|
|
|
96
96
|
);
|
|
97
97
|
|
|
98
98
|
return (
|
|
99
|
-
<div className='
|
|
99
|
+
<div className='dx-expander grid grid-cols-2 divide-x divide-separator'>
|
|
100
100
|
<TableComponent.Root>
|
|
101
|
-
<TableComponent.
|
|
101
|
+
<TableComponent.Content
|
|
102
102
|
model={orgModel}
|
|
103
103
|
schema={Organization.Organization}
|
|
104
104
|
presentation={orgPresentation}
|
|
@@ -108,7 +108,7 @@ const DefaultStory = () => {
|
|
|
108
108
|
/>
|
|
109
109
|
</TableComponent.Root>
|
|
110
110
|
<TableComponent.Root>
|
|
111
|
-
<TableComponent.
|
|
111
|
+
<TableComponent.Content
|
|
112
112
|
model={contactModel}
|
|
113
113
|
schema={Person.Person}
|
|
114
114
|
presentation={contactPresentation}
|
|
@@ -125,7 +125,7 @@ const meta = {
|
|
|
125
125
|
title: 'ui/react-ui-table/Relations',
|
|
126
126
|
render: DefaultStory,
|
|
127
127
|
decorators: [
|
|
128
|
-
withTheme,
|
|
128
|
+
withTheme(),
|
|
129
129
|
withRegistry,
|
|
130
130
|
// TODO(thure): Shouldn't `layout: 'fullscreen'` below make this unnecessary?
|
|
131
131
|
withLayout({ classNames: 'fixed inset-0' }),
|
|
@@ -147,7 +147,7 @@ export default meta;
|
|
|
147
147
|
type Story = StoryObj<typeof meta>;
|
|
148
148
|
|
|
149
149
|
export const Default: Story = {
|
|
150
|
-
play: async ({ canvasElement }
|
|
150
|
+
play: async ({ canvasElement }) => {
|
|
151
151
|
const canvas = within(canvasElement);
|
|
152
152
|
const body = within(document.body);
|
|
153
153
|
|
|
@@ -195,8 +195,15 @@ export const Default: Story = {
|
|
|
195
195
|
const saveButton = await body.findByTestId('save-button');
|
|
196
196
|
await userEvent.click(saveButton);
|
|
197
197
|
|
|
198
|
-
// Verify the relation was set (cell should now contain the org name)
|
|
199
|
-
|
|
198
|
+
// Verify the relation was set (cell should now contain the org name).
|
|
199
|
+
// Wait for the grid (Lit web component) to repaint after the reactive data update.
|
|
200
|
+
await waitFor(
|
|
201
|
+
async () => {
|
|
202
|
+
const updatedCell = within(secondGrid).getByTestId('grid.4.0');
|
|
203
|
+
await expect(updatedCell).toHaveTextContent(orgName.substring(0, 4));
|
|
204
|
+
},
|
|
205
|
+
{ timeout: 5000 },
|
|
206
|
+
);
|
|
200
207
|
|
|
201
208
|
// Test object creation (new relations) - equivalent to "new relations work as expected" test
|
|
202
209
|
// Find a different cell to test object creation (second row, relations column)
|
|
@@ -215,23 +222,24 @@ export const Default: Story = {
|
|
|
215
222
|
const newSearchField = await body.findByPlaceholderText('Search…');
|
|
216
223
|
await userEvent.click(newSearchField);
|
|
217
224
|
|
|
218
|
-
// Type a new object name (this will create a new object)
|
|
225
|
+
// Type a new object name (this will create a new object).
|
|
219
226
|
const newOrgName = 'Salieri LLC';
|
|
220
227
|
await userEvent.type(newSearchField, newOrgName);
|
|
221
228
|
|
|
222
|
-
//
|
|
223
|
-
const
|
|
224
|
-
await
|
|
229
|
+
// Click the create option directly to open the create form.
|
|
230
|
+
const createOptionLabel = await body.findByText(/Create new object/, undefined, { timeout: 2000 });
|
|
231
|
+
await userEvent.click(createOptionLabel.closest('[role="option"]') as HTMLElement);
|
|
225
232
|
|
|
226
|
-
//
|
|
227
|
-
await
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
const createReferencedObjectForm = await body.findByTestId('create-referenced-object-form');
|
|
233
|
+
// Look for and click save button.
|
|
234
|
+
const createReferencedObjectForm = await body.findByTestId('create-referenced-object-form', undefined, {
|
|
235
|
+
timeout: 2000,
|
|
236
|
+
});
|
|
231
237
|
const saveObjectButton = await within(createReferencedObjectForm).findByTestId('save-button');
|
|
238
|
+
await expect(saveObjectButton).not.toBeDisabled();
|
|
232
239
|
await userEvent.click(saveObjectButton);
|
|
233
240
|
|
|
234
|
-
// Verify the
|
|
235
|
-
await
|
|
241
|
+
// Verify the relation was set by checking for the accessory link anchor in the cell.
|
|
242
|
+
const updatedNewCell = await within(secondGrid).findByTestId('grid.4.1', undefined, { timeout: 5000 });
|
|
243
|
+
await expect(updatedNewCell.querySelector('dx-anchor')).toBeTruthy();
|
|
236
244
|
},
|
|
237
|
-
}
|
|
245
|
+
};
|