@dxos/react-ui-table 0.8.4-main.d05539e30a → 0.8.4-main.d9fc60f731
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-YDXPC7HA.mjs → chunk-X7A7G6RR.mjs} +15 -14
- package/dist/lib/browser/chunk-X7A7G6RR.mjs.map +7 -0
- package/dist/lib/browser/{chunk-4URYOFDL.mjs → chunk-YURROGGF.mjs} +6 -8
- package/dist/lib/browser/chunk-YURROGGF.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +30 -38
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +6 -7
- 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-B2SZYAEC.mjs → chunk-DLAGRBKD.mjs} +6 -8
- package/dist/lib/node-esm/chunk-DLAGRBKD.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-2AN3QQ3D.mjs → chunk-Q4HSBRJJ.mjs} +15 -14
- package/dist/lib/node-esm/chunk-Q4HSBRJJ.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +30 -38
- 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 +6 -7
- 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 +2 -2
- package/dist/types/src/components/Table/ColumnSettings.d.ts.map +1 -1
- package/dist/types/src/components/Table/DynamicTable.d.ts +2 -2
- package/dist/types/src/components/Table/DynamicTable.d.ts.map +1 -1
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts +2 -1
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/Relations.stories.d.ts +2 -1
- package/dist/types/src/components/Table/Relations.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.stories.d.ts +2 -1
- package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/TableContent.d.ts.map +1 -1
- package/dist/types/src/components/Table/TableToolbar.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts +1 -1
- package/dist/types/src/components/TableCellEditor/FormCellEditor.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/useProjectionModel.d.ts.map +1 -1
- package/dist/types/src/model/table-model.d.ts.map +1 -1
- package/dist/types/src/testing/useTestTableModel.d.ts +1 -1
- package/dist/types/src/testing/useTestTableModel.d.ts.map +1 -1
- package/dist/types/src/types/Table.d.ts +11 -4
- package/dist/types/src/types/Table.d.ts.map +1 -1
- package/dist/types/src/util/dynamic-table.d.ts +6 -6
- package/dist/types/src/util/dynamic-table.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +44 -44
- package/src/components/Table/ColumnSettings.tsx +2 -2
- package/src/components/Table/DynamicTable.stories.tsx +6 -6
- package/src/components/Table/DynamicTable.tsx +7 -7
- package/src/components/Table/Relations.stories.tsx +4 -2
- package/src/components/Table/Table.stories.tsx +22 -24
- package/src/components/Table/TableContent.tsx +2 -1
- package/src/components/Table/TableToolbar.tsx +1 -1
- package/src/components/TableCellEditor/CellValidationMessage.tsx +1 -1
- package/src/components/TableCellEditor/FormCellEditor.tsx +4 -4
- package/src/components/TableCellEditor/TableCellEditor.stories.tsx +5 -2
- package/src/components/testing.ts +2 -7
- package/src/hooks/useProjectionModel.ts +5 -6
- package/src/hooks/useTableModel.ts +1 -1
- package/src/model/table-model.test.ts +4 -9
- package/src/model/table-model.ts +7 -6
- package/src/model/table-presentation.test.ts +4 -9
- package/src/model/table-presentation.ts +2 -2
- package/src/testing/useTestTableModel.ts +4 -5
- package/src/types/Table.ts +11 -11
- package/src/util/dynamic-table.test.ts +12 -19
- package/src/util/dynamic-table.ts +17 -15
- package/dist/lib/browser/chunk-4URYOFDL.mjs.map +0 -7
- package/dist/lib/browser/chunk-YDXPC7HA.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-2AN3QQ3D.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-B2SZYAEC.mjs.map +0 -7
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.d9fc60f731",
|
|
4
4
|
"description": "A table component.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -47,9 +47,9 @@
|
|
|
47
47
|
"src"
|
|
48
48
|
],
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@codemirror/autocomplete": "^6.
|
|
51
|
-
"@codemirror/state": "^6.
|
|
52
|
-
"@codemirror/view": "^6.
|
|
50
|
+
"@codemirror/autocomplete": "^6.20.2",
|
|
51
|
+
"@codemirror/state": "^6.6.0",
|
|
52
|
+
"@codemirror/view": "^6.43.0",
|
|
53
53
|
"@effect-atom/atom-react": "^0.5.0",
|
|
54
54
|
"@fluentui/react-tabster": "9.26.11",
|
|
55
55
|
"@radix-ui/react-context": "1.1.1",
|
|
@@ -58,59 +58,59 @@
|
|
|
58
58
|
"@radix-ui/react-use-controllable-state": "1.1.0",
|
|
59
59
|
"date-fns": "^3.6.0",
|
|
60
60
|
"lodash.orderby": "^4.6.0",
|
|
61
|
-
"@dxos/
|
|
62
|
-
"@dxos/
|
|
63
|
-
"@dxos/
|
|
64
|
-
"@dxos/
|
|
65
|
-
"@dxos/echo
|
|
66
|
-
"@dxos/effect": "0.8.4-main.
|
|
67
|
-
"@dxos/invariant": "0.8.4-main.
|
|
68
|
-
"@dxos/
|
|
69
|
-
"@dxos/
|
|
70
|
-
"@dxos/
|
|
71
|
-
"@dxos/
|
|
72
|
-
"@dxos/react-
|
|
73
|
-
"@dxos/react-ui-attention": "0.8.4-main.
|
|
74
|
-
"@dxos/react-ui-
|
|
75
|
-
"@dxos/react-ui-
|
|
76
|
-
"@dxos/react-ui-
|
|
77
|
-
"@dxos/react-ui-
|
|
78
|
-
"@dxos/react-ui-menu": "0.8.4-main.
|
|
79
|
-
"@dxos/react-ui-
|
|
80
|
-
"@dxos/react-ui-
|
|
81
|
-
"@dxos/schema": "0.8.4-main.
|
|
82
|
-
"@dxos/
|
|
83
|
-
"@dxos/
|
|
84
|
-
"@dxos/
|
|
85
|
-
"@dxos/
|
|
86
|
-
"@dxos/react-ui-grid": "0.8.4-main.
|
|
61
|
+
"@dxos/debug": "0.8.4-main.d9fc60f731",
|
|
62
|
+
"@dxos/async": "0.8.4-main.d9fc60f731",
|
|
63
|
+
"@dxos/context": "0.8.4-main.d9fc60f731",
|
|
64
|
+
"@dxos/echo-atom": "0.8.4-main.d9fc60f731",
|
|
65
|
+
"@dxos/echo": "0.8.4-main.d9fc60f731",
|
|
66
|
+
"@dxos/effect": "0.8.4-main.d9fc60f731",
|
|
67
|
+
"@dxos/invariant": "0.8.4-main.d9fc60f731",
|
|
68
|
+
"@dxos/lit-grid": "0.8.4-main.d9fc60f731",
|
|
69
|
+
"@dxos/log": "0.8.4-main.d9fc60f731",
|
|
70
|
+
"@dxos/keys": "0.8.4-main.d9fc60f731",
|
|
71
|
+
"@dxos/react-client": "0.8.4-main.d9fc60f731",
|
|
72
|
+
"@dxos/react-ui-components": "0.8.4-main.d9fc60f731",
|
|
73
|
+
"@dxos/react-ui-attention": "0.8.4-main.d9fc60f731",
|
|
74
|
+
"@dxos/react-ui-editor": "0.8.4-main.d9fc60f731",
|
|
75
|
+
"@dxos/react-ui-form": "0.8.4-main.d9fc60f731",
|
|
76
|
+
"@dxos/react-ui-list": "0.8.4-main.d9fc60f731",
|
|
77
|
+
"@dxos/react-ui-search": "0.8.4-main.d9fc60f731",
|
|
78
|
+
"@dxos/react-ui-menu": "0.8.4-main.d9fc60f731",
|
|
79
|
+
"@dxos/react-ui-stack": "0.8.4-main.d9fc60f731",
|
|
80
|
+
"@dxos/react-ui-syntax-highlighter": "0.8.4-main.d9fc60f731",
|
|
81
|
+
"@dxos/schema": "0.8.4-main.d9fc60f731",
|
|
82
|
+
"@dxos/ui-types": "0.8.4-main.d9fc60f731",
|
|
83
|
+
"@dxos/util": "0.8.4-main.d9fc60f731",
|
|
84
|
+
"@dxos/types": "0.8.4-main.d9fc60f731",
|
|
85
|
+
"@dxos/random": "0.8.4-main.d9fc60f731",
|
|
86
|
+
"@dxos/react-ui-grid": "0.8.4-main.d9fc60f731"
|
|
87
87
|
},
|
|
88
88
|
"devDependencies": {
|
|
89
|
-
"@effect/platform": "0.
|
|
89
|
+
"@effect/platform": "0.96.1",
|
|
90
90
|
"@types/lodash.orderby": "^4.6.9",
|
|
91
91
|
"@types/react": "~19.2.7",
|
|
92
92
|
"@types/react-dom": "~19.2.3",
|
|
93
|
-
"effect": "3.
|
|
93
|
+
"effect": "3.21.2",
|
|
94
94
|
"fast-check": "^3.19.0",
|
|
95
95
|
"react": "~19.2.3",
|
|
96
96
|
"react-dom": "~19.2.3",
|
|
97
|
-
"vite": "^8.0.
|
|
98
|
-
"@dxos/
|
|
99
|
-
"@dxos/
|
|
100
|
-
"@dxos/
|
|
101
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
102
|
-
"@dxos/
|
|
103
|
-
"@dxos/test-utils": "0.8.4-main.
|
|
104
|
-
"@dxos/ui-theme": "0.8.4-main.
|
|
97
|
+
"vite": "^8.0.14",
|
|
98
|
+
"@dxos/random": "0.8.4-main.d9fc60f731",
|
|
99
|
+
"@dxos/lit-ui": "0.8.4-main.d9fc60f731",
|
|
100
|
+
"@dxos/storybook-utils": "0.8.4-main.d9fc60f731",
|
|
101
|
+
"@dxos/react-ui": "0.8.4-main.d9fc60f731",
|
|
102
|
+
"@dxos/react-client": "0.8.4-main.d9fc60f731",
|
|
103
|
+
"@dxos/test-utils": "0.8.4-main.d9fc60f731",
|
|
104
|
+
"@dxos/ui-theme": "0.8.4-main.d9fc60f731"
|
|
105
105
|
},
|
|
106
106
|
"peerDependencies": {
|
|
107
107
|
"@effect-atom/atom-react": "^0.5.0",
|
|
108
|
-
"@effect/platform": "0.
|
|
109
|
-
"effect": "3.
|
|
108
|
+
"@effect/platform": "0.96.1",
|
|
109
|
+
"effect": "3.21.2",
|
|
110
110
|
"react": "~19.2.3",
|
|
111
111
|
"react-dom": "~19.2.3",
|
|
112
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
113
|
-
"@dxos/ui-theme": "0.8.4-main.
|
|
112
|
+
"@dxos/react-ui": "0.8.4-main.d9fc60f731",
|
|
113
|
+
"@dxos/ui-theme": "0.8.4-main.d9fc60f731"
|
|
114
114
|
},
|
|
115
115
|
"publishConfig": {
|
|
116
116
|
"access": "public"
|
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
import { useAtomValue } from '@effect-atom/atom-react';
|
|
6
6
|
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
7
7
|
|
|
8
|
-
import { type
|
|
8
|
+
import { type Registry, type View } from '@dxos/echo';
|
|
9
9
|
import { Popover } from '@dxos/react-ui';
|
|
10
10
|
import { FieldEditor } from '@dxos/react-ui-form';
|
|
11
11
|
|
|
12
12
|
import { type ModalController, type TableModel } from '../../model';
|
|
13
13
|
|
|
14
14
|
type ColumnSettingsProps = {
|
|
15
|
-
registry?:
|
|
15
|
+
registry?: Registry.Registry;
|
|
16
16
|
model?: TableModel;
|
|
17
17
|
modals: ModalController;
|
|
18
18
|
onNewColumn: () => void;
|
|
@@ -6,10 +6,10 @@ import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
|
6
6
|
import type * as Types from 'effect/Types';
|
|
7
7
|
import React, { useMemo, useState } from 'react';
|
|
8
8
|
|
|
9
|
-
import { Filter, type JsonSchema, Obj } from '@dxos/echo';
|
|
9
|
+
import { Filter, type JsonSchema, Obj, Type } from '@dxos/echo';
|
|
10
10
|
import { Format } from '@dxos/echo/internal';
|
|
11
11
|
import { random } from '@dxos/random';
|
|
12
|
-
import { useQuery,
|
|
12
|
+
import { useQuery, useType } from '@dxos/react-client/echo';
|
|
13
13
|
import { useClientStory, withClientProvider } from '@dxos/react-client/testing';
|
|
14
14
|
import { withLayout, withTheme } from '@dxos/react-ui/testing';
|
|
15
15
|
import { type SchemaPropertyDefinition } from '@dxos/schema';
|
|
@@ -132,13 +132,13 @@ export const WithJsonSchema: StoryObj = {
|
|
|
132
132
|
export const WithEchoSchema: StoryObj = {
|
|
133
133
|
render: () => {
|
|
134
134
|
const { space } = useClientStory();
|
|
135
|
-
const
|
|
136
|
-
const objects = useQuery(space?.db,
|
|
137
|
-
if (!
|
|
135
|
+
const type = useType(space?.db, Type.getTypename(TestSchema.Person));
|
|
136
|
+
const objects = useQuery(space?.db, type ? Filter.type(type) : Filter.nothing());
|
|
137
|
+
if (!type) {
|
|
138
138
|
return <div>Loading schema...</div>;
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
return <DynamicTable
|
|
141
|
+
return <DynamicTable type={type} rows={objects} />;
|
|
142
142
|
},
|
|
143
143
|
decorators: [
|
|
144
144
|
withClientProvider({
|
|
@@ -18,7 +18,7 @@ import { type TablePropertyDefinition, getBaseSchema, makeDynamicTable } from '.
|
|
|
18
18
|
import { Table, type TableController } from './Table';
|
|
19
19
|
|
|
20
20
|
export type DynamicTableProps<T extends Type.AnyEntity = Type.AnyEntity> = ThemedClassName<{
|
|
21
|
-
|
|
21
|
+
type?: T;
|
|
22
22
|
name?: string; // TODO(burdon): Remove?
|
|
23
23
|
rows: any[];
|
|
24
24
|
properties?: TablePropertyDefinition[];
|
|
@@ -36,7 +36,7 @@ export type DynamicTableProps<T extends Type.AnyEntity = Type.AnyEntity> = Theme
|
|
|
36
36
|
// TODO(burdon): Warning: Cannot update a component (`DynamicTable`) while rendering a different component (`DynamicTable`).
|
|
37
37
|
export const DynamicTable = <T extends Type.AnyEntity = Type.AnyEntity>({
|
|
38
38
|
classNames,
|
|
39
|
-
|
|
39
|
+
type: typeProp,
|
|
40
40
|
name = 'com.example.dynamicTable', // Remove default or make random; this will lead to type collisions.
|
|
41
41
|
rows,
|
|
42
42
|
properties,
|
|
@@ -50,14 +50,14 @@ export const DynamicTable = <T extends Type.AnyEntity = Type.AnyEntity>({
|
|
|
50
50
|
const [dynamicTable, setDynamicTable] = useState<{ object: TableType.Table; projection: ProjectionModel }>();
|
|
51
51
|
|
|
52
52
|
// TODO(burdon): Remove variance from the props (should be normalized externally; possibly via hooks).
|
|
53
|
-
const {
|
|
54
|
-
() => getBaseSchema({ typename: name, properties, jsonSchema: jsonSchemaProp,
|
|
55
|
-
[name, properties, jsonSchemaProp,
|
|
53
|
+
const { type } = useMemo(
|
|
54
|
+
() => getBaseSchema({ typename: name, properties, jsonSchema: jsonSchemaProp, type: typeProp }),
|
|
55
|
+
[name, properties, jsonSchemaProp, typeProp],
|
|
56
56
|
);
|
|
57
57
|
|
|
58
58
|
useEffect(() => {
|
|
59
|
-
setDynamicTable(makeDynamicTable({ registry,
|
|
60
|
-
}, [registry,
|
|
59
|
+
setDynamicTable(makeDynamicTable({ registry, type, properties }));
|
|
60
|
+
}, [registry, type, properties]);
|
|
61
61
|
|
|
62
62
|
const tableRef = useRef<TableController>(null);
|
|
63
63
|
const handleCellUpdate = useCallback((cell: any) => {
|
|
@@ -66,7 +66,9 @@ const useTestModel = <S extends Type.AnyObj>(schema: S, count: number) => {
|
|
|
66
66
|
|
|
67
67
|
const objectGenerator = createAsyncGenerator(generator, schema, { db: space?.db, force: true });
|
|
68
68
|
void objectGenerator.createObjects(count).then((objects) => {
|
|
69
|
-
|
|
69
|
+
// TODO(wittjosiah): Remove cast. Type.InstanceType is now strict (no index signature),
|
|
70
|
+
// so it isn't assignable to TableRow (Record<JsonProp, any>); reconcile the row model type.
|
|
71
|
+
model.setRows(objects as unknown as TableRow[]);
|
|
70
72
|
});
|
|
71
73
|
}, [model, space]);
|
|
72
74
|
|
|
@@ -88,7 +90,7 @@ const DefaultStory = () => {
|
|
|
88
90
|
|
|
89
91
|
const handleCreate = useCallback(
|
|
90
92
|
(schema: Type.AnyEntity, values: any) => {
|
|
91
|
-
invariant(Type.
|
|
93
|
+
invariant(Type.isObject(schema));
|
|
92
94
|
invariant(space);
|
|
93
95
|
return space.db.add(Obj.make(schema, values));
|
|
94
96
|
},
|
|
@@ -6,7 +6,7 @@ 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 { Annotation, type Database, Format, Obj, type QueryAST, Ref, Type, View } from '@dxos/echo';
|
|
9
|
+
import { DXN, Annotation, type Database, Format, Obj, type QueryAST, Ref, Type, View } from '@dxos/echo';
|
|
10
10
|
import { type Mutable, PropertyMetaAnnotationId } from '@dxos/echo/internal';
|
|
11
11
|
import { invariant } from '@dxos/invariant';
|
|
12
12
|
import { random } from '@dxos/random';
|
|
@@ -17,7 +17,7 @@ import { ViewEditor } from '@dxos/react-ui-form';
|
|
|
17
17
|
import { translations as formTranslations } from '@dxos/react-ui-form/translations';
|
|
18
18
|
import { JsonHighlighter } from '@dxos/react-ui-syntax-highlighter';
|
|
19
19
|
import { withLayout, withTheme } from '@dxos/react-ui/testing';
|
|
20
|
-
import { ViewModel, getSchemaFromPropertyDefinitions
|
|
20
|
+
import { ViewModel, getSchemaFromPropertyDefinitions } from '@dxos/schema';
|
|
21
21
|
import { TestSchema, createObjectFactory } from '@dxos/schema/testing';
|
|
22
22
|
import { withRegistry } from '@dxos/storybook-utils';
|
|
23
23
|
|
|
@@ -52,10 +52,11 @@ const Example = Schema.Struct({
|
|
|
52
52
|
title: 'Parent',
|
|
53
53
|
}),
|
|
54
54
|
}).pipe(
|
|
55
|
-
Type.object({ typename: `com.example.type.${PublicKey.random().truncate()}`, version: '0.1.0' }),
|
|
56
55
|
Annotation.LabelAnnotation.set(['name']),
|
|
56
|
+
// NSID last segment must start with a letter (DXN spec), so prefix the random hex.
|
|
57
|
+
Type.makeObject(DXN.make(`com.example.type.example${PublicKey.random().truncate()}`, '0.1.0')),
|
|
57
58
|
);
|
|
58
|
-
interface Example extends
|
|
59
|
+
interface Example extends Type.InstanceType<typeof Example> {}
|
|
59
60
|
|
|
60
61
|
const StoryViewEditor = ({
|
|
61
62
|
view,
|
|
@@ -64,15 +65,14 @@ const StoryViewEditor = ({
|
|
|
64
65
|
handleDeleteColumn,
|
|
65
66
|
}: {
|
|
66
67
|
view?: View.View;
|
|
67
|
-
schema?:
|
|
68
|
+
schema?: Type.AnyEntity;
|
|
68
69
|
db?: Database.Database;
|
|
69
70
|
handleDeleteColumn: (fieldId: string) => void;
|
|
70
71
|
}) => {
|
|
71
72
|
const handleQueryChanged = useCallback(
|
|
72
73
|
(newQuery: QueryAST.Query) => {
|
|
73
74
|
invariant(schema);
|
|
74
|
-
invariant(Type.
|
|
75
|
-
schema.updateTypename(getTypenameFromQuery(newQuery));
|
|
75
|
+
invariant(Type.getDatabase(schema) != null);
|
|
76
76
|
invariant(view);
|
|
77
77
|
Obj.update(view, (view) => {
|
|
78
78
|
view.query.ast = newQuery as Mutable<typeof newQuery>;
|
|
@@ -87,8 +87,8 @@ const StoryViewEditor = ({
|
|
|
87
87
|
|
|
88
88
|
return (
|
|
89
89
|
<ViewEditor
|
|
90
|
-
registry={db?.
|
|
91
|
-
|
|
90
|
+
registry={db?.graph.registry}
|
|
91
|
+
type={schema}
|
|
92
92
|
view={view}
|
|
93
93
|
onQueryChanged={handleQueryChanged}
|
|
94
94
|
onDelete={handleDeleteColumn}
|
|
@@ -169,8 +169,11 @@ const meta = {
|
|
|
169
169
|
createIdentity: true,
|
|
170
170
|
createSpace: true,
|
|
171
171
|
onCreateSpace: async ({ space }) => {
|
|
172
|
-
const
|
|
173
|
-
const { view, jsonSchema } = await ViewModel.makeFromDatabase({
|
|
172
|
+
const type = await space.db.addType(Example);
|
|
173
|
+
const { view, jsonSchema } = await ViewModel.makeFromDatabase({
|
|
174
|
+
db: space.db,
|
|
175
|
+
typename: Type.getTypename(type),
|
|
176
|
+
});
|
|
174
177
|
const table = Table.make({ view, jsonSchema });
|
|
175
178
|
Obj.update(view, (view) => {
|
|
176
179
|
view.projection.fields = [
|
|
@@ -183,7 +186,7 @@ const meta = {
|
|
|
183
186
|
|
|
184
187
|
Array.from({ length: 10 }).map(() => {
|
|
185
188
|
return space.db.add(
|
|
186
|
-
Obj.make(
|
|
189
|
+
Obj.make(type, {
|
|
187
190
|
name: random.lorem.sentence(),
|
|
188
191
|
status: random.helpers.arrayElement(['todo', 'in-progress', 'done'] as const),
|
|
189
192
|
description: random.lorem.paragraph(),
|
|
@@ -218,7 +221,7 @@ export const StaticSchema: StoryObj = {
|
|
|
218
221
|
onCreateSpace: async ({ space }) => {
|
|
219
222
|
const { view, jsonSchema } = await ViewModel.makeFromDatabase({
|
|
220
223
|
db: space.db,
|
|
221
|
-
typename: TestSchema.Person
|
|
224
|
+
typename: Type.getTypename(TestSchema.Person),
|
|
222
225
|
});
|
|
223
226
|
const table = Table.make({ view, jsonSchema });
|
|
224
227
|
space.db.add(table);
|
|
@@ -247,12 +250,7 @@ const ContactWithArrayOfEmails = Schema.Struct({
|
|
|
247
250
|
}),
|
|
248
251
|
),
|
|
249
252
|
),
|
|
250
|
-
}).pipe(
|
|
251
|
-
Type.object({
|
|
252
|
-
typename: 'org.dxos.type.contactWithArrayOfEmails',
|
|
253
|
-
version: '0.1.0',
|
|
254
|
-
}),
|
|
255
|
-
);
|
|
253
|
+
}).pipe(Type.makeObject(DXN.make('org.dxos.type.contactWithArrayOfEmails', '0.1.0')));
|
|
256
254
|
|
|
257
255
|
export const ArrayOfObjects: StoryObj = {
|
|
258
256
|
render: DefaultStory,
|
|
@@ -264,7 +262,7 @@ export const ArrayOfObjects: StoryObj = {
|
|
|
264
262
|
onCreateSpace: async ({ space }) => {
|
|
265
263
|
const { view, jsonSchema } = await ViewModel.makeFromDatabase({
|
|
266
264
|
db: space.db,
|
|
267
|
-
typename: ContactWithArrayOfEmails
|
|
265
|
+
typename: Type.getTypename(ContactWithArrayOfEmails),
|
|
268
266
|
});
|
|
269
267
|
const table = Table.make({ view, jsonSchema });
|
|
270
268
|
space.db.add(table);
|
|
@@ -294,7 +292,7 @@ export const Tags: Meta<DefaultStoryProps> = {
|
|
|
294
292
|
createSpace: true,
|
|
295
293
|
onCreateSpace: async ({ space }) => {
|
|
296
294
|
// Configure schema.
|
|
297
|
-
const typename = 'com.example.type.
|
|
295
|
+
const typename = 'com.example.type.singleSelect';
|
|
298
296
|
const selectOptions = [
|
|
299
297
|
{ id: 'one', title: 'One', color: 'emerald' },
|
|
300
298
|
{ id: 'two', title: 'Two', color: 'blue' },
|
|
@@ -305,7 +303,7 @@ export const Tags: Meta<DefaultStoryProps> = {
|
|
|
305
303
|
|
|
306
304
|
const selectOptionIds = selectOptions.map((o) => o.id);
|
|
307
305
|
|
|
308
|
-
const
|
|
306
|
+
const type = getSchemaFromPropertyDefinitions(typename, [
|
|
309
307
|
{
|
|
310
308
|
name: 'single',
|
|
311
309
|
format: Format.TypeFormat.SingleSelect,
|
|
@@ -317,7 +315,7 @@ export const Tags: Meta<DefaultStoryProps> = {
|
|
|
317
315
|
config: { options: selectOptions },
|
|
318
316
|
},
|
|
319
317
|
]);
|
|
320
|
-
const
|
|
318
|
+
const storedType = await space.db.addType(type);
|
|
321
319
|
|
|
322
320
|
// Initialize table.
|
|
323
321
|
const { view, jsonSchema } = await ViewModel.makeFromDatabase({ db: space.db, typename });
|
|
@@ -327,7 +325,7 @@ export const Tags: Meta<DefaultStoryProps> = {
|
|
|
327
325
|
// Populate.
|
|
328
326
|
Array.from({ length: 10 }).map(() => {
|
|
329
327
|
return space.db.add(
|
|
330
|
-
Obj.make(
|
|
328
|
+
Obj.make(Type.assertObject(storedType), {
|
|
331
329
|
single: random.helpers.arrayElement([...selectOptionIds, undefined]),
|
|
332
330
|
multiple: random.helpers.randomSubset(selectOptionIds),
|
|
333
331
|
}),
|
|
@@ -8,6 +8,7 @@ import React, { type MouseEvent, type WheelEvent, useCallback, useContext, useEf
|
|
|
8
8
|
|
|
9
9
|
import { type Type } from '@dxos/echo';
|
|
10
10
|
import { log } from '@dxos/log';
|
|
11
|
+
import { composable, composableProps } from '@dxos/react-ui';
|
|
11
12
|
import { useAttention } from '@dxos/react-ui-attention';
|
|
12
13
|
import {
|
|
13
14
|
type DxGridAxisMeta,
|
|
@@ -21,7 +22,7 @@ import {
|
|
|
21
22
|
gridSeparatorInlineEnd,
|
|
22
23
|
} from '@dxos/react-ui-grid';
|
|
23
24
|
import { DxEditRequest } from '@dxos/react-ui-grid';
|
|
24
|
-
import {
|
|
25
|
+
import { mx } from '@dxos/ui-theme';
|
|
25
26
|
|
|
26
27
|
import { type InsertRowResult, ModalController, type TableModel, type TablePresentation } from '../../model';
|
|
27
28
|
import { tableButtons, tableControls } from '../../util';
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { Atom, RegistryContext } from '@effect-atom/atom-react';
|
|
6
6
|
import React, { useContext, useEffect, useMemo } from 'react';
|
|
7
7
|
|
|
8
|
+
import { composable, composableProps } from '@dxos/react-ui';
|
|
8
9
|
import {
|
|
9
10
|
type ActionGraphEdges,
|
|
10
11
|
type ActionGraphNodes,
|
|
@@ -16,7 +17,6 @@ import {
|
|
|
16
17
|
createMenuAction,
|
|
17
18
|
useMenuActions,
|
|
18
19
|
} from '@dxos/react-ui-menu';
|
|
19
|
-
import { composable, composableProps } from '@dxos/ui-theme';
|
|
20
20
|
|
|
21
21
|
import { translationKey } from '#translations';
|
|
22
22
|
|
|
@@ -23,7 +23,7 @@ export const CellValidationMessage = ({
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
const bgClass = variant === 'error' ? 'bg-error-surface' : 'bg-warning-surface';
|
|
26
|
-
const textClass = variant === 'error' ? 'text-error-
|
|
26
|
+
const textClass = variant === 'error' ? 'text-error-fg' : 'text-warning-fg';
|
|
27
27
|
|
|
28
28
|
return (
|
|
29
29
|
<div
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import type * as Schema from 'effect/Schema';
|
|
6
6
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
7
7
|
|
|
8
|
-
import { Entity,
|
|
8
|
+
import { Entity, Type } from '@dxos/echo';
|
|
9
9
|
import { Ref, getValue } from '@dxos/echo/internal';
|
|
10
10
|
import { invariant } from '@dxos/invariant';
|
|
11
11
|
import { type Label, Popover } from '@dxos/react-ui';
|
|
@@ -63,7 +63,7 @@ export const FormCellEditor = <T extends Type.AnyEntity = Type.AnyEntity>({
|
|
|
63
63
|
return undefined;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
return narrowSchema(schema, [fieldProjection.field.path]);
|
|
66
|
+
return narrowSchema(Type.getSchema(schema), [fieldProjection.field.path]);
|
|
67
67
|
}, [JSON.stringify(schema), fieldProjection.field.path]); // TODO(burdon): Avoid stringify.
|
|
68
68
|
|
|
69
69
|
const originalRow = useMemo<TableRow | undefined>(() => {
|
|
@@ -151,7 +151,7 @@ export const FormCellEditor = <T extends Type.AnyEntity = Type.AnyEntity>({
|
|
|
151
151
|
results
|
|
152
152
|
.map((obj) => {
|
|
153
153
|
return {
|
|
154
|
-
id: Entity.
|
|
154
|
+
id: Entity.getURI(obj),
|
|
155
155
|
label: getValue(obj, fieldProjection.field.referencePath!) || obj.id.toString(),
|
|
156
156
|
};
|
|
157
157
|
})
|
|
@@ -167,7 +167,7 @@ export const FormCellEditor = <T extends Type.AnyEntity = Type.AnyEntity>({
|
|
|
167
167
|
<Popover.Root open={editing} onOpenChange={handleOpenChange}>
|
|
168
168
|
<Popover.VirtualTrigger virtualRef={anchorRef} />
|
|
169
169
|
<Popover.Portal>
|
|
170
|
-
<Popover.Content tabIndex={-1} classNames='dx-card-popover-width dx-density-
|
|
170
|
+
<Popover.Content tabIndex={-1} classNames='dx-card-popover-width dx-density-md'>
|
|
171
171
|
<Popover.Arrow />
|
|
172
172
|
<Popover.Viewport>
|
|
173
173
|
<Form.Root
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
6
6
|
import React from 'react';
|
|
7
7
|
|
|
8
|
-
import { Obj, View } from '@dxos/echo';
|
|
8
|
+
import { Obj, Type, View } from '@dxos/echo';
|
|
9
9
|
import { random } from '@dxos/random';
|
|
10
10
|
import { withClientProvider } from '@dxos/react-client/testing';
|
|
11
11
|
import { Grid, type GridEditing, defaultRowSize } from '@dxos/react-ui-grid';
|
|
@@ -52,7 +52,10 @@ const meta = {
|
|
|
52
52
|
createIdentity: true,
|
|
53
53
|
createSpace: true,
|
|
54
54
|
onCreateSpace: async ({ space }) => {
|
|
55
|
-
const { view, jsonSchema } = await ViewModel.makeFromDatabase({
|
|
55
|
+
const { view, jsonSchema } = await ViewModel.makeFromDatabase({
|
|
56
|
+
db: space.db,
|
|
57
|
+
typename: Type.getTypename(Task.Task),
|
|
58
|
+
});
|
|
56
59
|
const table = Table.make({ view, jsonSchema });
|
|
57
60
|
space.db.add(table);
|
|
58
61
|
Array.from({ length: 10 }).forEach(() => {
|
|
@@ -6,7 +6,7 @@ import { Atom } from '@effect-atom/atom-react';
|
|
|
6
6
|
import * as Schema from 'effect/Schema';
|
|
7
7
|
import { useEffect } from 'react';
|
|
8
8
|
|
|
9
|
-
import { Format, Type } from '@dxos/echo';
|
|
9
|
+
import { DXN, Format, Type } from '@dxos/echo';
|
|
10
10
|
import { TypeEnum } from '@dxos/echo/internal';
|
|
11
11
|
import { setValue } from '@dxos/effect';
|
|
12
12
|
import { random } from '@dxos/random';
|
|
@@ -17,12 +17,7 @@ export const TestSchema = Schema.Struct({
|
|
|
17
17
|
age: Schema.optional(Schema.Number),
|
|
18
18
|
active: Schema.optional(Schema.Boolean),
|
|
19
19
|
netWorth: Schema.optional(Schema.Number),
|
|
20
|
-
}).pipe(
|
|
21
|
-
Type.object({
|
|
22
|
-
typename: 'com.example.type.test',
|
|
23
|
-
version: '0.1.0',
|
|
24
|
-
}),
|
|
25
|
-
);
|
|
20
|
+
}).pipe(Type.makeObject(DXN.make('com.example.type.test', '0.1.0')));
|
|
26
21
|
|
|
27
22
|
export type TestItem = {
|
|
28
23
|
name: string;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { type Registry } from '@effect-atom/atom-react';
|
|
6
6
|
import { useState } from 'react';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { Type } from '@dxos/echo';
|
|
9
9
|
import { useAsyncEffect } from '@dxos/react-ui';
|
|
10
10
|
import { ProjectionModel, createEchoChangeCallback } from '@dxos/schema';
|
|
11
11
|
|
|
@@ -21,13 +21,12 @@ export const useProjectionModel = <S extends Type.AnyEntity>(
|
|
|
21
21
|
useAsyncEffect(async () => {
|
|
22
22
|
if (schema && table) {
|
|
23
23
|
const view = await table.view.load();
|
|
24
|
-
//
|
|
25
|
-
|
|
26
|
-
const jsonSchema = Type.isMutable(schema) ? schema.jsonSchema : JsonSchema.toJsonSchema(schema);
|
|
24
|
+
// Use the live jsonSchema reference for reactivity.
|
|
25
|
+
const jsonSchema = schema.jsonSchema;
|
|
27
26
|
|
|
28
27
|
// Always use createEchoChangeCallback since the view is ECHO-backed.
|
|
29
|
-
// Pass
|
|
30
|
-
const change = createEchoChangeCallback(view, Type.
|
|
28
|
+
// Pass the type entity only when stored, to allow schema mutations.
|
|
29
|
+
const change = createEchoChangeCallback(view, Type.getDatabase(schema) != null ? schema : undefined);
|
|
31
30
|
|
|
32
31
|
const projection = new ProjectionModel({ registry, view, baseSchema: jsonSchema, change });
|
|
33
32
|
projection.normalizeView();
|
|
@@ -44,7 +44,7 @@ export const useTableModel = <T extends TableRow = TableRow>({
|
|
|
44
44
|
...props
|
|
45
45
|
}: UseTableModelProps<T>): TableModel<T> | undefined => {
|
|
46
46
|
const registry = useContext(RegistryContext);
|
|
47
|
-
const selected = useSelected(object && Obj.
|
|
47
|
+
const selected = useSelected(object && Obj.getURI(object), 'multi');
|
|
48
48
|
const initialSelection = useMemo(() => selected, [object]);
|
|
49
49
|
|
|
50
50
|
const [model, setModel] = useState<TableModel<T>>();
|
|
@@ -6,7 +6,7 @@ import { Registry } from '@effect-atom/atom-react';
|
|
|
6
6
|
import * as Schema from 'effect/Schema';
|
|
7
7
|
import { afterEach, beforeEach, describe, expect, test } from 'vitest';
|
|
8
8
|
|
|
9
|
-
import { Filter, JsonSchema, Query, Type } from '@dxos/echo';
|
|
9
|
+
import { DXN, Filter, JsonSchema, Query, Type } from '@dxos/echo';
|
|
10
10
|
import { createEchoSchema } from '@dxos/echo/testing';
|
|
11
11
|
import { ProjectionModel, ViewModel, createDirectChangeCallback } from '@dxos/schema';
|
|
12
12
|
|
|
@@ -118,15 +118,10 @@ describe('TableModel', () => {
|
|
|
118
118
|
const Test = Schema.Struct({
|
|
119
119
|
title: Schema.String,
|
|
120
120
|
completed: Schema.Boolean,
|
|
121
|
-
}).pipe(
|
|
122
|
-
Type.object({
|
|
123
|
-
typename: 'com.example.type.test',
|
|
124
|
-
version: '0.1.0',
|
|
125
|
-
}),
|
|
126
|
-
);
|
|
121
|
+
}).pipe(Type.makeObject(DXN.make('com.example.type.test', '0.1.0')));
|
|
127
122
|
|
|
128
123
|
const createTableModel = (registry: Registry.Registry, props: Partial<TableModelProps> = {}): TableModel => {
|
|
129
|
-
const schema = createEchoSchema(Test);
|
|
124
|
+
const schema = createEchoSchema(Type.getSchema(Test));
|
|
130
125
|
const view = ViewModel.make({
|
|
131
126
|
query: Query.select(Filter.type(schema)),
|
|
132
127
|
jsonSchema: schema.jsonSchema,
|
|
@@ -136,7 +131,7 @@ const createTableModel = (registry: Registry.Registry, props: Partial<TableModel
|
|
|
136
131
|
registry,
|
|
137
132
|
view,
|
|
138
133
|
baseSchema: schema.jsonSchema,
|
|
139
|
-
change: createDirectChangeCallback(view.projection, JsonSchema.toJsonSchema(schema)),
|
|
134
|
+
change: createDirectChangeCallback(view.projection, JsonSchema.toJsonSchema(Type.getSchema(schema))),
|
|
140
135
|
});
|
|
141
136
|
projection.normalizeView();
|
|
142
137
|
return new TableModel({
|
package/src/model/table-model.ts
CHANGED
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
import { Atom, type Registry } from '@effect-atom/atom-react';
|
|
6
6
|
|
|
7
7
|
import { Resource } from '@dxos/context';
|
|
8
|
-
import { type Database, Format, Obj, Order, Query, type QueryAST, Ref, type View } from '@dxos/echo';
|
|
8
|
+
import { type Database, Format, Obj, Order, Query, type QueryAST, Ref, Type, type View } from '@dxos/echo';
|
|
9
9
|
import { type JsonProp, type JsonSchemaType, type Mutable, toEffectSchema } from '@dxos/echo/internal';
|
|
10
10
|
import { getSnapshot } from '@dxos/echo/internal';
|
|
11
11
|
import { getValue, setValue } from '@dxos/effect';
|
|
12
12
|
import { invariant } from '@dxos/invariant';
|
|
13
|
-
import {
|
|
13
|
+
import { EntityId } from '@dxos/keys';
|
|
14
14
|
import { type Label } from '@dxos/react-ui';
|
|
15
15
|
import { formatForEditing, parseValue } from '@dxos/react-ui-form';
|
|
16
16
|
import {
|
|
@@ -299,7 +299,7 @@ export class TableModel<T extends TableRow = TableRow> extends Resource {
|
|
|
299
299
|
}
|
|
300
300
|
|
|
301
301
|
public get id(): string {
|
|
302
|
-
return Obj.
|
|
302
|
+
return Obj.getURI(this._object);
|
|
303
303
|
}
|
|
304
304
|
|
|
305
305
|
public get view(): View.View {
|
|
@@ -523,7 +523,7 @@ export class TableModel<T extends TableRow = TableRow> extends Resource {
|
|
|
523
523
|
}
|
|
524
524
|
|
|
525
525
|
// NOTE(ZaymonFC): This is initialized with id because it's required in all schemata?
|
|
526
|
-
const draftData = { id:
|
|
526
|
+
const draftData = { id: EntityId.random() } as any as T;
|
|
527
527
|
const validationErrors = this.validateDraftRowData(draftData);
|
|
528
528
|
|
|
529
529
|
const draftRow: DraftRow<T> = {
|
|
@@ -694,8 +694,9 @@ export class TableModel<T extends TableRow = TableRow> extends Resource {
|
|
|
694
694
|
const snapshot = { ...getSnapshot(currentRow) };
|
|
695
695
|
setValue(snapshot, field.path, transformedValue);
|
|
696
696
|
|
|
697
|
-
const
|
|
698
|
-
invariant(
|
|
697
|
+
const type = Obj.getType(currentRow as unknown as Obj.Unknown);
|
|
698
|
+
invariant(type);
|
|
699
|
+
const schema = Type.getSchema(type);
|
|
699
700
|
|
|
700
701
|
const validationResult = validateSchema(schema, snapshot);
|
|
701
702
|
if (validationResult && validationResult.length > 0) {
|