@dxos/react-ui-table 0.8.4-main.2c6827d → 0.8.4-main.3c1ae3b
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-CJQ6T4LL.mjs +77 -0
- package/dist/lib/browser/chunk-CJQ6T4LL.mjs.map +7 -0
- package/dist/lib/browser/{chunk-GS2UNGJK.mjs → chunk-V7A7ZA5E.mjs} +119 -111
- package/dist/lib/browser/chunk-V7A7ZA5E.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +162 -147
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +15 -31
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/browser/types/index.mjs +3 -3
- package/dist/lib/node-esm/{chunk-TRR3C5NX.mjs → chunk-P73ALX3N.mjs} +119 -111
- package/dist/lib/node-esm/chunk-P73ALX3N.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-T6PXZQ6W.mjs +78 -0
- package/dist/lib/node-esm/chunk-T6PXZQ6W.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +162 -147
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +15 -31
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/types/index.mjs +3 -3
- package/dist/types/src/components/Table/ColumnActionsMenu.d.ts +1 -2
- package/dist/types/src/components/Table/ColumnActionsMenu.d.ts.map +1 -1
- package/dist/types/src/components/Table/ColumnSettings.d.ts +2 -2
- package/dist/types/src/components/Table/ColumnSettings.d.ts.map +1 -1
- package/dist/types/src/components/Table/DynamicTable.d.ts +4 -5
- package/dist/types/src/components/Table/DynamicTable.d.ts.map +1 -1
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts +3 -17
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/Relations.stories.d.ts +10 -6
- package/dist/types/src/components/Table/Relations.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.d.ts +8 -8
- package/dist/types/src/components/Table/Table.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.stories.d.ts +70 -4
- package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/CellValidationMessage.d.ts +1 -1
- package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts +10 -11
- package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +5 -7
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts +3 -3
- package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/testing.d.ts +0 -2
- package/dist/types/src/components/testing.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +2 -1
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useProjectionModel.d.ts +5 -0
- package/dist/types/src/hooks/useProjectionModel.d.ts.map +1 -0
- package/dist/types/src/hooks/useTableModel.d.ts +4 -5
- package/dist/types/src/hooks/useTableModel.d.ts.map +1 -1
- package/dist/types/src/model/table-model.d.ts +6 -8
- package/dist/types/src/model/table-model.d.ts.map +1 -1
- package/dist/types/src/model/table-sorting.d.ts +7 -3
- package/dist/types/src/model/table-sorting.d.ts.map +1 -1
- package/dist/types/src/playwright/TableManager.d.ts +1 -1
- package/dist/types/src/playwright/TableManager.d.ts.map +1 -1
- package/dist/types/src/testing/useTestTableModel.d.ts +19 -15
- package/dist/types/src/testing/useTestTableModel.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +2 -2
- package/dist/types/src/types/Table.d.ts +28 -0
- package/dist/types/src/types/Table.d.ts.map +1 -0
- package/dist/types/src/types/index.d.ts +1 -1
- package/dist/types/src/types/index.d.ts.map +1 -1
- package/dist/types/src/util/dynamic-table.d.ts +9 -9
- package/dist/types/src/util/dynamic-table.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +38 -38
- package/src/components/Table/ColumnActionsMenu.tsx +4 -1
- package/src/components/Table/ColumnSettings.tsx +2 -3
- package/src/components/Table/DynamicTable.stories.tsx +7 -9
- package/src/components/Table/DynamicTable.tsx +18 -10
- package/src/components/Table/Relations.stories.tsx +9 -18
- package/src/components/Table/Table.stories.tsx +52 -59
- package/src/components/Table/Table.tsx +317 -304
- package/src/components/TableCellEditor/CellValidationMessage.tsx +1 -1
- package/src/components/TableCellEditor/FormCellEditor.tsx +101 -108
- package/src/components/TableCellEditor/TableCellEditor.stories.tsx +11 -8
- package/src/components/TableCellEditor/TableCellEditor.tsx +29 -29
- package/src/components/TableToolbar/TableToolbar.tsx +1 -1
- package/src/components/testing.ts +3 -3
- package/src/hooks/index.ts +2 -1
- package/src/hooks/useProjectionModel.ts +19 -0
- package/src/hooks/useTableModel.ts +11 -13
- package/src/model/table-model.test.ts +4 -4
- package/src/model/table-model.ts +29 -38
- package/src/model/table-presentation.test.ts +4 -4
- package/src/model/table-presentation.ts +9 -9
- package/src/model/table-sorting.ts +21 -12
- package/src/playwright/TableManager.ts +5 -5
- package/src/playwright/smoke.spec.ts +1 -1
- package/src/testing/useTestTableModel.ts +31 -27
- package/src/translations.ts +2 -2
- package/src/types/Table.ts +90 -0
- package/src/types/index.ts +1 -1
- package/src/util/dynamic-table.ts +11 -16
- package/dist/lib/browser/chunk-2PFAPQL4.mjs +0 -66
- package/dist/lib/browser/chunk-2PFAPQL4.mjs.map +0 -7
- package/dist/lib/browser/chunk-GS2UNGJK.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-6POOFFYF.mjs +0 -67
- package/dist/lib/node-esm/chunk-6POOFFYF.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-TRR3C5NX.mjs.map +0 -7
- package/dist/types/src/types/schema.d.ts +0 -28
- package/dist/types/src/types/schema.d.ts.map +0 -1
- package/src/types/schema.ts +0 -73
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.3c1ae3b",
|
|
4
4
|
"description": "A table component.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -65,33 +65,33 @@
|
|
|
65
65
|
"@radix-ui/react-use-controllable-state": "1.1.0",
|
|
66
66
|
"date-fns": "^3.3.1",
|
|
67
67
|
"lodash.orderby": "^4.6.0",
|
|
68
|
-
"@dxos/async": "0.8.4-main.
|
|
69
|
-
"@dxos/
|
|
70
|
-
"@dxos/
|
|
71
|
-
"@dxos/
|
|
72
|
-
"@dxos/
|
|
73
|
-
"@dxos/
|
|
74
|
-
"@dxos/
|
|
75
|
-
"@dxos/
|
|
76
|
-
"@dxos/
|
|
77
|
-
"@dxos/log": "0.8.4-main.
|
|
78
|
-
"@dxos/
|
|
79
|
-
"@dxos/random": "0.8.4-main.
|
|
80
|
-
"@dxos/
|
|
81
|
-
"@dxos/react-
|
|
82
|
-
"@dxos/react-ui-
|
|
83
|
-
"@dxos/
|
|
84
|
-
"@dxos/react-ui-
|
|
85
|
-
"@dxos/react-ui-
|
|
86
|
-
"@dxos/react-ui-grid": "0.8.4-main.
|
|
87
|
-
"@dxos/react-ui-
|
|
88
|
-
"@dxos/react-ui-
|
|
89
|
-
"@dxos/react-ui-
|
|
90
|
-
"@dxos/react-ui-syntax-highlighter": "0.8.4-main.
|
|
91
|
-
"@dxos/types": "0.8.4-main.
|
|
92
|
-
"@dxos/schema": "0.8.4-main.
|
|
93
|
-
"@dxos/
|
|
94
|
-
"@dxos/util": "0.8.4-main.
|
|
68
|
+
"@dxos/async": "0.8.4-main.3c1ae3b",
|
|
69
|
+
"@dxos/context": "0.8.4-main.3c1ae3b",
|
|
70
|
+
"@dxos/debug": "0.8.4-main.3c1ae3b",
|
|
71
|
+
"@dxos/echo": "0.8.4-main.3c1ae3b",
|
|
72
|
+
"@dxos/echo-db": "0.8.4-main.3c1ae3b",
|
|
73
|
+
"@dxos/effect": "0.8.4-main.3c1ae3b",
|
|
74
|
+
"@dxos/invariant": "0.8.4-main.3c1ae3b",
|
|
75
|
+
"@dxos/keys": "0.8.4-main.3c1ae3b",
|
|
76
|
+
"@dxos/lit-grid": "0.8.4-main.3c1ae3b",
|
|
77
|
+
"@dxos/log": "0.8.4-main.3c1ae3b",
|
|
78
|
+
"@dxos/live-object": "0.8.4-main.3c1ae3b",
|
|
79
|
+
"@dxos/random": "0.8.4-main.3c1ae3b",
|
|
80
|
+
"@dxos/plugin-search": "0.8.4-main.3c1ae3b",
|
|
81
|
+
"@dxos/react-client": "0.8.4-main.3c1ae3b",
|
|
82
|
+
"@dxos/react-ui-attention": "0.8.4-main.3c1ae3b",
|
|
83
|
+
"@dxos/react-ui-components": "0.8.4-main.3c1ae3b",
|
|
84
|
+
"@dxos/react-ui-editor": "0.8.4-main.3c1ae3b",
|
|
85
|
+
"@dxos/react-ui-form": "0.8.4-main.3c1ae3b",
|
|
86
|
+
"@dxos/react-ui-grid": "0.8.4-main.3c1ae3b",
|
|
87
|
+
"@dxos/react-ui-menu": "0.8.4-main.3c1ae3b",
|
|
88
|
+
"@dxos/react-ui-searchlist": "0.8.4-main.3c1ae3b",
|
|
89
|
+
"@dxos/react-ui-stack": "0.8.4-main.3c1ae3b",
|
|
90
|
+
"@dxos/react-ui-syntax-highlighter": "0.8.4-main.3c1ae3b",
|
|
91
|
+
"@dxos/react-ui-types": "0.8.4-main.3c1ae3b",
|
|
92
|
+
"@dxos/schema": "0.8.4-main.3c1ae3b",
|
|
93
|
+
"@dxos/types": "0.8.4-main.3c1ae3b",
|
|
94
|
+
"@dxos/util": "0.8.4-main.3c1ae3b"
|
|
95
95
|
},
|
|
96
96
|
"devDependencies": {
|
|
97
97
|
"@effect-atom/atom-react": "^0.3.4",
|
|
@@ -104,14 +104,14 @@
|
|
|
104
104
|
"react": "~19.2.0",
|
|
105
105
|
"react-dom": "~19.2.0",
|
|
106
106
|
"vite": "7.1.9",
|
|
107
|
-
"@dxos/echo-signals": "0.8.4-main.
|
|
108
|
-
"@dxos/lit-ui": "0.8.4-main.
|
|
109
|
-
"@dxos/
|
|
110
|
-
"@dxos/
|
|
111
|
-
"@dxos/
|
|
112
|
-
"@dxos/react-ui-theme": "0.8.4-main.
|
|
113
|
-
"@dxos/
|
|
114
|
-
"@dxos/
|
|
107
|
+
"@dxos/echo-signals": "0.8.4-main.3c1ae3b",
|
|
108
|
+
"@dxos/lit-ui": "0.8.4-main.3c1ae3b",
|
|
109
|
+
"@dxos/plugin-search": "0.8.4-main.3c1ae3b",
|
|
110
|
+
"@dxos/react-ui": "0.8.4-main.3c1ae3b",
|
|
111
|
+
"@dxos/random": "0.8.4-main.3c1ae3b",
|
|
112
|
+
"@dxos/react-ui-theme": "0.8.4-main.3c1ae3b",
|
|
113
|
+
"@dxos/storybook-utils": "0.8.4-main.3c1ae3b",
|
|
114
|
+
"@dxos/test-utils": "0.8.4-main.3c1ae3b"
|
|
115
115
|
},
|
|
116
116
|
"peerDependencies": {
|
|
117
117
|
"@effect-atom/atom-react": "^0.3.4",
|
|
@@ -119,8 +119,8 @@
|
|
|
119
119
|
"effect": "^3.13.3",
|
|
120
120
|
"react": "^19.0.0",
|
|
121
121
|
"react-dom": "^19.0.0",
|
|
122
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
123
|
-
"@dxos/react-ui-theme": "0.8.4-main.
|
|
122
|
+
"@dxos/react-ui": "0.8.4-main.3c1ae3b",
|
|
123
|
+
"@dxos/react-ui-theme": "0.8.4-main.3c1ae3b"
|
|
124
124
|
},
|
|
125
125
|
"publishConfig": {
|
|
126
126
|
"access": "public"
|
|
@@ -9,7 +9,10 @@ import { DropdownMenu, useTranslation } from '@dxos/react-ui';
|
|
|
9
9
|
import { type ModalController, type TableModel } from '../../model';
|
|
10
10
|
import { translationKey } from '../../translations';
|
|
11
11
|
|
|
12
|
-
type ColumnActionsMenuProps = {
|
|
12
|
+
export type ColumnActionsMenuProps = {
|
|
13
|
+
model: TableModel;
|
|
14
|
+
modals: ModalController;
|
|
15
|
+
};
|
|
13
16
|
|
|
14
17
|
export const ColumnActionsMenu = ({ model, modals }: ColumnActionsMenuProps) => {
|
|
15
18
|
const { t } = useTranslation(translationKey);
|
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
import { type SchemaRegistry } from '@dxos/echo-db';
|
|
7
|
+
import { type SchemaRegistry } from '@dxos/echo';
|
|
9
8
|
import { Popover } from '@dxos/react-ui';
|
|
10
9
|
import { FieldEditor } from '@dxos/react-ui-form';
|
|
11
10
|
import { type FieldType } from '@dxos/schema';
|
|
@@ -13,7 +12,7 @@ import { type FieldType } from '@dxos/schema';
|
|
|
13
12
|
import { type ModalController, type TableModel } from '../../model';
|
|
14
13
|
|
|
15
14
|
type ColumnSettingsProps = {
|
|
16
|
-
registry?: SchemaRegistry;
|
|
15
|
+
registry?: SchemaRegistry.SchemaRegistry;
|
|
17
16
|
model?: TableModel;
|
|
18
17
|
modals: ModalController;
|
|
19
18
|
onNewColumn: () => void;
|
|
@@ -6,14 +6,13 @@ import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
|
6
6
|
import React, { useMemo, useState } from 'react';
|
|
7
7
|
|
|
8
8
|
import { Obj } from '@dxos/echo';
|
|
9
|
-
import {
|
|
9
|
+
import { Format, type JsonSchemaType } from '@dxos/echo/internal';
|
|
10
10
|
import { faker } from '@dxos/random';
|
|
11
|
-
import { useClient } from '@dxos/react-client';
|
|
12
11
|
import { Filter, useQuery, useSchema } from '@dxos/react-client/echo';
|
|
13
12
|
import { useClientProvider, withClientProvider } from '@dxos/react-client/testing';
|
|
14
13
|
import { withTheme } from '@dxos/react-ui/testing';
|
|
15
14
|
import { type SchemaPropertyDefinition } from '@dxos/schema';
|
|
16
|
-
import {
|
|
15
|
+
import { TestSchema } from '@dxos/schema/testing';
|
|
17
16
|
|
|
18
17
|
import { type TableFeatures } from '../../model';
|
|
19
18
|
import { translations } from '../../translations';
|
|
@@ -25,8 +24,8 @@ faker.seed(0);
|
|
|
25
24
|
const useTestPropertiesAndObjects = () => {
|
|
26
25
|
const properties = useMemo<SchemaPropertyDefinition[]>(
|
|
27
26
|
() => [
|
|
28
|
-
{ name: 'name', format:
|
|
29
|
-
{ name: 'age', format:
|
|
27
|
+
{ name: 'name', format: Format.TypeFormat.String },
|
|
28
|
+
{ name: 'age', format: Format.TypeFormat.Number },
|
|
30
29
|
],
|
|
31
30
|
[],
|
|
32
31
|
);
|
|
@@ -130,9 +129,8 @@ export const WithJsonSchema: StoryObj = {
|
|
|
130
129
|
|
|
131
130
|
export const WithEchoSchema: StoryObj = {
|
|
132
131
|
render: () => {
|
|
133
|
-
const client = useClient();
|
|
134
132
|
const { space } = useClientProvider();
|
|
135
|
-
const schema = useSchema(
|
|
133
|
+
const schema = useSchema(space, TestSchema.Person.typename);
|
|
136
134
|
const objects = useQuery(space, schema ? Filter.type(schema) : Filter.nothing());
|
|
137
135
|
if (!schema) {
|
|
138
136
|
return <div>Loading schema...</div>;
|
|
@@ -142,13 +140,13 @@ export const WithEchoSchema: StoryObj = {
|
|
|
142
140
|
},
|
|
143
141
|
decorators: [
|
|
144
142
|
withClientProvider({
|
|
145
|
-
types: [
|
|
143
|
+
types: [TestSchema.Person],
|
|
146
144
|
createIdentity: true,
|
|
147
145
|
createSpace: true,
|
|
148
146
|
onCreateSpace: async ({ space }) => {
|
|
149
147
|
Array.from({ length: 10 }).forEach(() => {
|
|
150
148
|
space.db.add(
|
|
151
|
-
Obj.make(
|
|
149
|
+
Obj.make(TestSchema.Person, {
|
|
152
150
|
name: faker.person.fullName(),
|
|
153
151
|
email: faker.internet.email(),
|
|
154
152
|
}),
|
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import type * as Schema from 'effect/Schema';
|
|
6
5
|
import React, { useCallback, useMemo, useRef } from 'react';
|
|
7
6
|
|
|
7
|
+
import { type Type } from '@dxos/echo';
|
|
8
8
|
import { type JsonSchemaType } from '@dxos/echo/internal';
|
|
9
9
|
import { type ThemedClassName, useDefaultValue } from '@dxos/react-ui';
|
|
10
10
|
import { mx } from '@dxos/react-ui-theme';
|
|
11
|
+
import { ProjectionModel } from '@dxos/schema';
|
|
11
12
|
|
|
12
13
|
import { useTableModel } from '../../hooks';
|
|
13
14
|
import { type TableFeatures, TablePresentation, type TableRowAction } from '../../model';
|
|
@@ -15,12 +16,12 @@ import { type TablePropertyDefinition, getBaseSchema, makeDynamicTable } from '.
|
|
|
15
16
|
|
|
16
17
|
import { Table, type TableController } from './Table';
|
|
17
18
|
|
|
18
|
-
type DynamicTableProps = ThemedClassName<{
|
|
19
|
+
export type DynamicTableProps<T extends Type.Entity.Any = Type.Entity.Any> = ThemedClassName<{
|
|
20
|
+
schema?: T;
|
|
19
21
|
name?: string; // TODO(burdon): Remove?
|
|
20
22
|
rows: any[];
|
|
21
23
|
properties?: TablePropertyDefinition[];
|
|
22
24
|
jsonSchema?: JsonSchemaType;
|
|
23
|
-
schema?: Schema.Schema.AnyNoContext;
|
|
24
25
|
features?: Partial<TableFeatures>;
|
|
25
26
|
rowActions?: TableRowAction[];
|
|
26
27
|
onRowClick?: (row: any) => void;
|
|
@@ -32,25 +33,25 @@ type DynamicTableProps = ThemedClassName<{
|
|
|
32
33
|
*/
|
|
33
34
|
// TODO(burdon): Instead of creating component variants, create helpers/hooks that normalize the props.
|
|
34
35
|
// TODO(burdon): Warning: Cannot update a component (`DynamicTable`) while rendering a different component (`DynamicTable`).
|
|
35
|
-
export const DynamicTable = ({
|
|
36
|
+
export const DynamicTable = <T extends Type.Entity.Any = Type.Entity.Any>({
|
|
36
37
|
classNames,
|
|
38
|
+
schema,
|
|
37
39
|
name = 'example.com/dynamic-table', // Rmove default or make random; this will lead to type collisions.
|
|
38
40
|
rows,
|
|
39
41
|
properties,
|
|
40
42
|
jsonSchema: _jsonSchema,
|
|
41
|
-
schema,
|
|
42
43
|
rowActions,
|
|
43
44
|
onRowClick,
|
|
44
45
|
onRowAction,
|
|
45
46
|
...props
|
|
46
|
-
}: DynamicTableProps) => {
|
|
47
|
+
}: DynamicTableProps<T>) => {
|
|
47
48
|
// TODO(burdon): Remove variance from the props (should be normalized externally; possibly via hooks).
|
|
48
49
|
const { jsonSchema } = useMemo(
|
|
49
50
|
() => getBaseSchema({ typename: name, properties, jsonSchema: _jsonSchema, schema }),
|
|
50
51
|
[name, properties, _jsonSchema, schema],
|
|
51
52
|
);
|
|
52
53
|
|
|
53
|
-
const {
|
|
54
|
+
const { object, projection } = useMemo(() => makeDynamicTable({ jsonSchema, properties }), [jsonSchema, properties]);
|
|
54
55
|
|
|
55
56
|
const tableRef = useRef<TableController>(null);
|
|
56
57
|
const handleCellUpdate = useCallback((cell: any) => {
|
|
@@ -70,11 +71,18 @@ export const DynamicTable = ({
|
|
|
70
71
|
}) as const,
|
|
71
72
|
);
|
|
72
73
|
|
|
74
|
+
const projectionModel = useMemo(() => {
|
|
75
|
+
if (jsonSchema && projection) {
|
|
76
|
+
const model = new ProjectionModel(jsonSchema, projection);
|
|
77
|
+
model.normalizeView();
|
|
78
|
+
return model;
|
|
79
|
+
}
|
|
80
|
+
}, [jsonSchema, projection]);
|
|
81
|
+
|
|
73
82
|
const model = useTableModel({
|
|
74
83
|
rows,
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
projection,
|
|
84
|
+
object,
|
|
85
|
+
projection: projectionModel,
|
|
78
86
|
features,
|
|
79
87
|
rowActions,
|
|
80
88
|
onCellUpdate: handleCellUpdate,
|
|
@@ -8,7 +8,6 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
|
8
8
|
import { expect, userEvent, within } from 'storybook/test';
|
|
9
9
|
|
|
10
10
|
import { Obj, Type } from '@dxos/echo';
|
|
11
|
-
import { type JsonSchemaType } from '@dxos/echo/internal';
|
|
12
11
|
import { type DxGrid } from '@dxos/lit-grid';
|
|
13
12
|
import '@dxos/lit-ui/dx-tag-picker.pcss';
|
|
14
13
|
import { faker } from '@dxos/random';
|
|
@@ -21,7 +20,7 @@ import { View } from '@dxos/schema';
|
|
|
21
20
|
import { type ValueGenerator, createAsyncGenerator } from '@dxos/schema/testing';
|
|
22
21
|
import { Organization, Person } from '@dxos/types';
|
|
23
22
|
|
|
24
|
-
import { useTableModel } from '../../hooks';
|
|
23
|
+
import { useProjectionModel, useTableModel } from '../../hooks';
|
|
25
24
|
import { type TableFeatures, TablePresentation, type TableRow } from '../../model';
|
|
26
25
|
import { translations } from '../../translations';
|
|
27
26
|
import { Table } from '../../types';
|
|
@@ -36,10 +35,8 @@ const generator: ValueGenerator = faker as any;
|
|
|
36
35
|
// TODO(burdon): Reconcile schemas types and utils (see API PR).
|
|
37
36
|
// TODO(burdon): Base type for T (with id); see ECHO API PR?
|
|
38
37
|
const useTestModel = <S extends Type.Obj.Any>(schema: S, count: number) => {
|
|
39
|
-
const client = useClient();
|
|
40
38
|
const { space } = useClientProvider();
|
|
41
|
-
const [
|
|
42
|
-
const [jsonSchema, setJsonSchema] = useState<JsonSchemaType>();
|
|
39
|
+
const [object, setObject] = useState<Table.Table>();
|
|
43
40
|
|
|
44
41
|
const features = useMemo<TableFeatures>(
|
|
45
42
|
() => ({ schemaEditable: false, dataEditable: true, selection: { enabled: false } }),
|
|
@@ -51,18 +48,14 @@ const useTestModel = <S extends Type.Obj.Any>(schema: S, count: number) => {
|
|
|
51
48
|
return;
|
|
52
49
|
}
|
|
53
50
|
|
|
54
|
-
const {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
setJsonSchema(jsonSchema);
|
|
60
|
-
setView(view);
|
|
61
|
-
space.db.add(view);
|
|
62
|
-
await space.db.schemaRegistry.register([effectSchema]);
|
|
63
|
-
}, [client, space, schema]);
|
|
51
|
+
const { view, jsonSchema } = await View.makeFromSpace({ space, typename: Type.getTypename(schema) });
|
|
52
|
+
const object = Table.make({ view, jsonSchema });
|
|
53
|
+
setObject(object);
|
|
54
|
+
space.db.add(object);
|
|
55
|
+
}, [space, schema]);
|
|
64
56
|
|
|
65
|
-
const
|
|
57
|
+
const projection = useProjectionModel(schema, object);
|
|
58
|
+
const model = useTableModel<TableRow>({ object, projection, features });
|
|
66
59
|
|
|
67
60
|
useEffect(() => {
|
|
68
61
|
if (!model || !space) {
|
|
@@ -107,7 +100,6 @@ const DefaultStory = () => {
|
|
|
107
100
|
schema={Organization.Organization}
|
|
108
101
|
presentation={orgPresentation}
|
|
109
102
|
onCreate={handleCreate}
|
|
110
|
-
client={client}
|
|
111
103
|
ignoreAttention
|
|
112
104
|
testId='relations-0'
|
|
113
105
|
/>
|
|
@@ -118,7 +110,6 @@ const DefaultStory = () => {
|
|
|
118
110
|
schema={Person.Person}
|
|
119
111
|
presentation={contactPresentation}
|
|
120
112
|
onCreate={handleCreate}
|
|
121
|
-
client={client}
|
|
122
113
|
ignoreAttention
|
|
123
114
|
testId='relations-1'
|
|
124
115
|
/>
|
|
@@ -6,26 +6,18 @@ import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
|
6
6
|
import * as Schema from 'effect/Schema';
|
|
7
7
|
import React, { useCallback } from 'react';
|
|
8
8
|
|
|
9
|
-
import { Obj, type QueryAST, Type } from '@dxos/echo';
|
|
10
|
-
import {
|
|
11
|
-
EchoObject,
|
|
12
|
-
FormatAnnotation,
|
|
13
|
-
FormatEnum,
|
|
14
|
-
GeneratorAnnotation,
|
|
15
|
-
LabelAnnotation,
|
|
16
|
-
PropertyMetaAnnotationId,
|
|
17
|
-
} from '@dxos/echo/internal';
|
|
18
|
-
import { live } from '@dxos/echo/internal';
|
|
9
|
+
import { Annotation, Format, Obj, type QueryAST, Type } from '@dxos/echo';
|
|
10
|
+
import { PropertyMetaAnnotationId } from '@dxos/echo/internal';
|
|
19
11
|
import { invariant } from '@dxos/invariant';
|
|
20
12
|
import { faker } from '@dxos/random';
|
|
21
13
|
import { PublicKey } from '@dxos/react-client';
|
|
22
14
|
import { type Space } from '@dxos/react-client/echo';
|
|
23
15
|
import { withClientProvider } from '@dxos/react-client/testing';
|
|
24
16
|
import { withTheme } from '@dxos/react-ui/testing';
|
|
25
|
-
import { ViewEditor } from '@dxos/react-ui-form';
|
|
17
|
+
import { ViewEditor, translations as formTranslations } from '@dxos/react-ui-form';
|
|
26
18
|
import { SyntaxHighlighter } from '@dxos/react-ui-syntax-highlighter';
|
|
27
19
|
import { View, getSchemaFromPropertyDefinitions, getTypenameFromQuery } from '@dxos/schema';
|
|
28
|
-
import {
|
|
20
|
+
import { TestSchema, createObjectFactory } from '@dxos/schema/testing';
|
|
29
21
|
|
|
30
22
|
import { useTestTableModel } from '../../testing';
|
|
31
23
|
import { translations } from '../../translations';
|
|
@@ -34,13 +26,13 @@ import { TableToolbar } from '../TableToolbar';
|
|
|
34
26
|
|
|
35
27
|
import { Table as TableComponent } from './Table';
|
|
36
28
|
|
|
37
|
-
const
|
|
29
|
+
const Example = Schema.Struct({
|
|
38
30
|
// TODO(wittjosiah): Should be title. Currently name to work with default label.
|
|
39
31
|
name: Schema.optional(Schema.String).annotations({ title: 'Title' }),
|
|
40
32
|
urgent: Schema.optional(Schema.Boolean).annotations({ title: 'Urgent' }),
|
|
41
33
|
status: Schema.optional(
|
|
42
34
|
Schema.Literal('todo', 'in-progress', 'done')
|
|
43
|
-
.pipe(FormatAnnotation.set(
|
|
35
|
+
.pipe(Format.FormatAnnotation.set(Format.TypeFormat.SingleSelect))
|
|
44
36
|
.annotations({
|
|
45
37
|
title: 'Status',
|
|
46
38
|
[PropertyMetaAnnotationId]: {
|
|
@@ -55,14 +47,14 @@ const TestSchema = Schema.Struct({
|
|
|
55
47
|
}),
|
|
56
48
|
),
|
|
57
49
|
description: Schema.optional(Schema.String).annotations({ title: 'Description' }),
|
|
58
|
-
parent: Schema.optional(Schema.suspend((): Type.Ref<
|
|
50
|
+
parent: Schema.optional(Schema.suspend((): Type.Ref<Example> => Type.Ref(Example))).annotations({
|
|
59
51
|
title: 'Parent',
|
|
60
52
|
}),
|
|
61
53
|
}).pipe(
|
|
62
54
|
Type.Obj({ typename: `example.com/type/${PublicKey.random().truncate()}`, version: '0.1.0' }),
|
|
63
|
-
LabelAnnotation.set(['name']),
|
|
55
|
+
Annotation.LabelAnnotation.set(['name']),
|
|
64
56
|
);
|
|
65
|
-
interface
|
|
57
|
+
interface Example extends Schema.Schema.Type<typeof Example> {}
|
|
66
58
|
|
|
67
59
|
const StoryViewEditor = ({
|
|
68
60
|
view,
|
|
@@ -106,20 +98,10 @@ const StoryViewEditor = ({
|
|
|
106
98
|
//
|
|
107
99
|
|
|
108
100
|
const DefaultStory = () => {
|
|
109
|
-
const {
|
|
110
|
-
|
|
111
|
-
schema,
|
|
112
|
-
view,
|
|
113
|
-
tableRef,
|
|
114
|
-
model,
|
|
115
|
-
presentation,
|
|
116
|
-
client,
|
|
117
|
-
handleInsertRow,
|
|
118
|
-
handleSaveView,
|
|
119
|
-
handleDeleteColumn,
|
|
120
|
-
} = useTestTableModel();
|
|
101
|
+
const { space, schema, table, tableRef, model, presentation, handleInsertRow, handleSaveView, handleDeleteColumn } =
|
|
102
|
+
useTestTableModel();
|
|
121
103
|
|
|
122
|
-
if (!schema || !view) {
|
|
104
|
+
if (!schema || !table?.view.target) {
|
|
123
105
|
return <div />;
|
|
124
106
|
}
|
|
125
107
|
|
|
@@ -130,18 +112,22 @@ const DefaultStory = () => {
|
|
|
130
112
|
<TableComponent.Root>
|
|
131
113
|
<TableComponent.Main
|
|
132
114
|
ref={tableRef}
|
|
115
|
+
schema={schema}
|
|
133
116
|
model={model}
|
|
134
117
|
presentation={presentation}
|
|
135
|
-
schema={schema}
|
|
136
|
-
client={client}
|
|
137
118
|
ignoreAttention
|
|
138
119
|
/>
|
|
139
120
|
</TableComponent.Root>
|
|
140
121
|
</div>
|
|
141
122
|
<div className='flex flex-col bs-full border-l border-separator overflow-y-auto'>
|
|
142
|
-
<StoryViewEditor
|
|
123
|
+
<StoryViewEditor
|
|
124
|
+
view={table.view.target}
|
|
125
|
+
schema={schema}
|
|
126
|
+
space={space}
|
|
127
|
+
handleDeleteColumn={handleDeleteColumn}
|
|
128
|
+
/>
|
|
143
129
|
<SyntaxHighlighter language='json' className='text-xs'>
|
|
144
|
-
{JSON.stringify({ view, schema }, null, 2)}
|
|
130
|
+
{JSON.stringify({ view: table.view.target, schema }, null, 2)}
|
|
145
131
|
</SyntaxHighlighter>
|
|
146
132
|
</div>
|
|
147
133
|
</div>
|
|
@@ -165,15 +151,16 @@ const meta = {
|
|
|
165
151
|
types: [View.View, Table.Table],
|
|
166
152
|
createIdentity: true,
|
|
167
153
|
createSpace: true,
|
|
168
|
-
onCreateSpace: async ({
|
|
169
|
-
const [schema] = await space.db.schemaRegistry.register([
|
|
170
|
-
const { view } = await
|
|
154
|
+
onCreateSpace: async ({ space }) => {
|
|
155
|
+
const [schema] = await space.db.schemaRegistry.register([Example]);
|
|
156
|
+
const { view, jsonSchema } = await View.makeFromSpace({ space, typename: schema.typename });
|
|
157
|
+
const table = Table.make({ view, jsonSchema });
|
|
171
158
|
view.projection.fields = [
|
|
172
159
|
view.projection.fields.find((field: any) => field.path === 'name')!,
|
|
173
160
|
...view.projection.fields.filter((field: any) => field.path !== 'name'),
|
|
174
161
|
];
|
|
175
162
|
|
|
176
|
-
space.db.add(
|
|
163
|
+
space.db.add(table);
|
|
177
164
|
|
|
178
165
|
Array.from({ length: 10 }).map(() => {
|
|
179
166
|
return space.db.add(
|
|
@@ -192,7 +179,7 @@ const meta = {
|
|
|
192
179
|
controls: {
|
|
193
180
|
disable: true,
|
|
194
181
|
},
|
|
195
|
-
translations,
|
|
182
|
+
translations: [...translations, ...formTranslations],
|
|
196
183
|
},
|
|
197
184
|
} satisfies Meta<typeof TableComponent>;
|
|
198
185
|
|
|
@@ -209,26 +196,27 @@ export const StaticSchema: StoryObj = {
|
|
|
209
196
|
types: [View.View, Table.Table],
|
|
210
197
|
createIdentity: true,
|
|
211
198
|
createSpace: true,
|
|
212
|
-
onCreateSpace: async ({
|
|
213
|
-
const { view } = await
|
|
214
|
-
|
|
199
|
+
onCreateSpace: async ({ space }) => {
|
|
200
|
+
const { view, jsonSchema } = await View.makeFromSpace({ space, typename: TestSchema.Person.typename });
|
|
201
|
+
const table = Table.make({ view, jsonSchema });
|
|
202
|
+
space.db.add(table);
|
|
215
203
|
|
|
216
204
|
const factory = createObjectFactory(space.db, faker as any);
|
|
217
205
|
await factory([
|
|
218
|
-
{ type:
|
|
219
|
-
// { type:
|
|
206
|
+
{ type: TestSchema.Person, count: 10 },
|
|
207
|
+
// { type: TestSchema.Organization, count: 1 },
|
|
220
208
|
]);
|
|
221
209
|
},
|
|
222
210
|
}),
|
|
223
211
|
],
|
|
224
212
|
parameters: {
|
|
225
213
|
layout: 'fullscreen',
|
|
226
|
-
translations,
|
|
214
|
+
translations: [...translations, ...formTranslations],
|
|
227
215
|
},
|
|
228
216
|
};
|
|
229
217
|
|
|
230
218
|
const ContactWithArrayOfEmails = Schema.Struct({
|
|
231
|
-
name: Schema.String.pipe(GeneratorAnnotation.set('person.fullName')),
|
|
219
|
+
name: Schema.String.pipe(Annotation.GeneratorAnnotation.set('person.fullName')),
|
|
232
220
|
emails: Schema.optional(
|
|
233
221
|
Schema.Array(
|
|
234
222
|
Schema.Struct({
|
|
@@ -238,7 +226,7 @@ const ContactWithArrayOfEmails = Schema.Struct({
|
|
|
238
226
|
),
|
|
239
227
|
),
|
|
240
228
|
}).pipe(
|
|
241
|
-
|
|
229
|
+
Type.Obj({
|
|
242
230
|
typename: 'dxos.org/type/ContactWithArrayOfEmails',
|
|
243
231
|
version: '0.1.0',
|
|
244
232
|
}),
|
|
@@ -248,17 +236,21 @@ export const ArrayOfObjects: StoryObj = {
|
|
|
248
236
|
render: DefaultStory,
|
|
249
237
|
decorators: [
|
|
250
238
|
withClientProvider({
|
|
251
|
-
types: [View.View, Table.Table,
|
|
239
|
+
types: [View.View, Table.Table, TestSchema.Person, TestSchema.Organization, ContactWithArrayOfEmails],
|
|
252
240
|
createIdentity: true,
|
|
253
241
|
createSpace: true,
|
|
254
|
-
onCreateSpace: async ({
|
|
255
|
-
const { view } = await
|
|
256
|
-
|
|
242
|
+
onCreateSpace: async ({ space }) => {
|
|
243
|
+
const { view, jsonSchema } = await View.makeFromSpace({
|
|
244
|
+
space,
|
|
245
|
+
typename: ContactWithArrayOfEmails.typename,
|
|
246
|
+
});
|
|
247
|
+
const table = Table.make({ view, jsonSchema });
|
|
248
|
+
space.db.add(table);
|
|
257
249
|
|
|
258
250
|
const factory = createObjectFactory(space.db, faker as any);
|
|
259
251
|
await factory([
|
|
260
|
-
// { type:
|
|
261
|
-
// { type:
|
|
252
|
+
// { type: TestSchema.Person, count: 10 },
|
|
253
|
+
// { type: TestSchema.Organization, count: 1 },
|
|
262
254
|
{ type: ContactWithArrayOfEmails, count: 10 },
|
|
263
255
|
]);
|
|
264
256
|
},
|
|
@@ -278,7 +270,7 @@ export const Tags: Meta<StoryProps> = {
|
|
|
278
270
|
types: [View.View, Table.Table],
|
|
279
271
|
createIdentity: true,
|
|
280
272
|
createSpace: true,
|
|
281
|
-
onCreateSpace: async ({
|
|
273
|
+
onCreateSpace: async ({ space }) => {
|
|
282
274
|
// Configure schema.
|
|
283
275
|
const typename = 'example.com/SingleSelect';
|
|
284
276
|
const selectOptions = [
|
|
@@ -294,25 +286,26 @@ export const Tags: Meta<StoryProps> = {
|
|
|
294
286
|
const schema = getSchemaFromPropertyDefinitions(typename, [
|
|
295
287
|
{
|
|
296
288
|
name: 'single',
|
|
297
|
-
format:
|
|
289
|
+
format: Format.TypeFormat.SingleSelect,
|
|
298
290
|
config: { options: selectOptions },
|
|
299
291
|
},
|
|
300
292
|
{
|
|
301
293
|
name: 'multiple',
|
|
302
|
-
format:
|
|
294
|
+
format: Format.TypeFormat.MultiSelect,
|
|
303
295
|
config: { options: selectOptions },
|
|
304
296
|
},
|
|
305
297
|
]);
|
|
306
298
|
const [storedSchema] = await space.db.schemaRegistry.register([schema]);
|
|
307
299
|
|
|
308
300
|
// Initialize table.
|
|
309
|
-
const { view } = await
|
|
310
|
-
|
|
301
|
+
const { view, jsonSchema } = await View.makeFromSpace({ space, typename });
|
|
302
|
+
const table = Table.make({ view, jsonSchema });
|
|
303
|
+
space.db.add(table);
|
|
311
304
|
|
|
312
305
|
// Populate.
|
|
313
306
|
Array.from({ length: 10 }).map(() => {
|
|
314
307
|
return space.db.add(
|
|
315
|
-
|
|
308
|
+
Obj.make(storedSchema, {
|
|
316
309
|
single: faker.helpers.arrayElement([...selectOptionIds, undefined]),
|
|
317
310
|
multiple: faker.helpers.randomSubset(selectOptionIds),
|
|
318
311
|
}),
|