@dxos/react-ui-table 0.8.4-main.fd6878d → 0.8.4-staging.60fe92afc8
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/LICENSE +102 -5
- package/dist/lib/browser/chunk-4KOQTPFC.mjs +1702 -0
- package/dist/lib/browser/chunk-4KOQTPFC.mjs.map +7 -0
- package/dist/lib/browser/chunk-62PYOJPY.mjs +67 -0
- package/dist/lib/browser/chunk-62PYOJPY.mjs.map +7 -0
- package/dist/lib/browser/chunk-J5LGTIGS.mjs +10 -0
- package/dist/lib/browser/chunk-J5LGTIGS.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +1151 -1175
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +37 -45
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/browser/translations.mjs +36 -0
- package/dist/lib/browser/translations.mjs.map +7 -0
- package/dist/lib/browser/types/index.mjs +4 -3
- package/dist/lib/node-esm/chunk-7LMOZUTS.mjs +68 -0
- package/dist/lib/node-esm/chunk-7LMOZUTS.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
- package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-KOSV2J5N.mjs +1704 -0
- package/dist/lib/node-esm/chunk-KOSV2J5N.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +1151 -1175
- 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 +37 -45
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/translations.mjs +37 -0
- package/dist/lib/node-esm/translations.mjs.map +7 -0
- package/dist/lib/node-esm/types/index.mjs +4 -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 +6 -7
- package/dist/types/src/components/Table/DynamicTable.d.ts.map +1 -1
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts +36 -3
- package/dist/types/src/components/Table/DynamicTable.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/Relations.stories.d.ts +112 -5
- package/dist/types/src/components/Table/Relations.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/RowActionsMenu.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.d.ts +21 -19
- package/dist/types/src/components/Table/Table.d.ts.map +1 -1
- package/dist/types/src/components/Table/Table.stories.d.ts +115 -5
- package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
- package/dist/types/src/components/Table/TableContent.d.ts +18 -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/CellValidationMessage.d.ts +1 -1
- package/dist/types/src/components/TableCellEditor/CellValidationMessage.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts +12 -9
- package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +7 -14
- package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts +38 -5
- package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TableCellEditor/index.d.ts +1 -0
- package/dist/types/src/components/TableCellEditor/index.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/components/testing.d.ts +23 -16
- 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/useAddRow.d.ts +6 -6
- package/dist/types/src/hooks/useAddRow.d.ts.map +1 -1
- package/dist/types/src/hooks/useProjectionModel.d.ts +6 -0
- package/dist/types/src/hooks/useProjectionModel.d.ts.map +1 -0
- package/dist/types/src/hooks/useTableModel.d.ts +9 -9
- package/dist/types/src/hooks/useTableModel.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +0 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/model/modal-controller.d.ts +5 -8
- package/dist/types/src/model/modal-controller.d.ts.map +1 -1
- package/dist/types/src/model/selection-model.d.ts +18 -9
- package/dist/types/src/model/selection-model.d.ts.map +1 -1
- package/dist/types/src/model/table-model.d.ts +111 -30
- package/dist/types/src/model/table-model.d.ts.map +1 -1
- package/dist/types/src/model/table-presentation.d.ts +4 -2
- 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/playwright/playwright.config.d.ts.map +1 -1
- package/dist/types/src/testing/useTestTableModel.d.ts +18 -34
- package/dist/types/src/testing/useTestTableModel.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +21 -23
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/Table.d.ts +32 -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 +14 -12
- 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/index.d.ts +2 -1
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/src/util/query-ast.d.ts +7 -0
- package/dist/types/src/util/query-ast.d.ts.map +1 -0
- package/dist/types/src/util/schema.d.ts +1 -1
- package/dist/types/src/util/schema.d.ts.map +1 -1
- package/dist/types/src/util/signals.d.ts.map +1 -1
- package/dist/types/src/util/sort.d.ts +12 -0
- package/dist/types/src/util/sort.d.ts.map +1 -0
- package/dist/types/src/util/table-buttons.d.ts +20 -20
- package/dist/types/src/util/table-buttons.d.ts.map +1 -1
- package/dist/types/src/util/table-controls.d.ts +4 -4
- package/dist/types/src/util/table-controls.d.ts.map +1 -1
- package/dist/types/src/util/tag.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +68 -77
- package/src/components/Table/ColumnActionsMenu.tsx +17 -12
- package/src/components/Table/ColumnSettings.tsx +8 -9
- package/src/components/Table/DynamicTable.stories.tsx +41 -38
- package/src/components/Table/DynamicTable.tsx +32 -36
- package/src/components/Table/Relations.stories.tsx +219 -61
- package/src/components/Table/RowActionsMenu.tsx +27 -17
- package/src/components/Table/Table.stories.tsx +217 -141
- package/src/components/Table/Table.tsx +46 -391
- package/src/components/Table/TableContent.tsx +426 -0
- package/src/components/Table/TableToolbar.tsx +111 -0
- package/src/components/TableCellEditor/CellValidationMessage.tsx +5 -6
- package/src/components/TableCellEditor/FormCellEditor.tsx +136 -41
- package/src/components/TableCellEditor/TableCellEditor.stories.tsx +39 -73
- package/src/components/TableCellEditor/TableCellEditor.tsx +81 -223
- package/src/components/TableCellEditor/index.ts +1 -0
- package/src/components/index.ts +0 -1
- package/src/components/testing.ts +42 -21
- package/src/hooks/index.ts +2 -1
- package/src/hooks/useAddRow.ts +14 -14
- package/src/hooks/useProjectionModel.ts +38 -0
- package/src/hooks/useTableModel.ts +36 -34
- package/src/index.ts +0 -4
- package/src/model/modal-controller.ts +23 -40
- package/src/model/selection-model.ts +75 -44
- package/src/model/table-model.test.ts +86 -56
- package/src/model/table-model.ts +464 -182
- package/src/model/table-presentation.test.ts +64 -59
- package/src/model/table-presentation.ts +107 -83
- package/src/playwright/TableManager.ts +13 -6
- package/src/playwright/playwright.config.ts +1 -1
- package/src/playwright/smoke.spec.ts +92 -46
- package/src/testing/useTestTableModel.ts +51 -42
- package/src/translations.ts +20 -22
- package/src/types/Table.ts +80 -0
- package/src/types/index.ts +1 -1
- package/src/util/dynamic-table.test.ts +63 -0
- package/src/util/dynamic-table.ts +53 -39
- package/src/util/index.ts +2 -1
- package/src/util/query-ast.ts +22 -0
- package/src/util/schema.ts +4 -4
- package/src/util/sort.ts +90 -0
- package/src/util/table-buttons.ts +3 -3
- package/src/util/table-controls.ts +2 -2
- package/dist/lib/browser/chunk-L2LSB6KV.mjs +0 -18
- package/dist/lib/browser/chunk-L2LSB6KV.mjs.map +0 -7
- package/dist/lib/browser/chunk-ZAOSIG3L.mjs +0 -1814
- package/dist/lib/browser/chunk-ZAOSIG3L.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-NXZ4CJYX.mjs +0 -20
- package/dist/lib/node-esm/chunk-NXZ4CJYX.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-ZOFFI3JJ.mjs +0 -1815
- package/dist/lib/node-esm/chunk-ZOFFI3JJ.mjs.map +0 -7
- package/dist/types/src/components/Table/CreateRefPanel.d.ts +0 -9
- package/dist/types/src/components/Table/CreateRefPanel.d.ts.map +0 -1
- package/dist/types/src/components/TableCellEditor/extension.d.ts +0 -13
- package/dist/types/src/components/TableCellEditor/extension.d.ts.map +0 -1
- 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/dist/types/src/model/table-sorting.d.ts +0 -53
- package/dist/types/src/model/table-sorting.d.ts.map +0 -1
- package/dist/types/src/types/schema.d.ts +0 -8
- package/dist/types/src/types/schema.d.ts.map +0 -1
- package/dist/types/src/util/table.d.ts +0 -12
- package/dist/types/src/util/table.d.ts.map +0 -1
- package/src/components/Table/CreateRefPanel.tsx +0 -86
- package/src/components/TableCellEditor/extension.ts +0 -61
- package/src/components/TableToolbar/TableToolbar.tsx +0 -102
- package/src/components/TableToolbar/index.ts +0 -5
- package/src/model/table-sorting.ts +0 -216
- package/src/types/schema.ts +0 -16
- package/src/util/table.ts +0 -53
|
@@ -2,47 +2,39 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@dxos-theme';
|
|
6
|
-
|
|
7
5
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
8
|
-
import
|
|
6
|
+
import * as Schema from 'effect/Schema';
|
|
9
7
|
import React, { useCallback } from 'react';
|
|
8
|
+
import { expect, userEvent, waitFor, within } from 'storybook/test';
|
|
10
9
|
|
|
11
|
-
import { Obj, Type } from '@dxos/echo';
|
|
12
|
-
import {
|
|
13
|
-
EchoObject,
|
|
14
|
-
FormatAnnotation,
|
|
15
|
-
FormatEnum,
|
|
16
|
-
GeneratorAnnotation,
|
|
17
|
-
LabelAnnotation,
|
|
18
|
-
PropertyMetaAnnotationId,
|
|
19
|
-
} from '@dxos/echo-schema';
|
|
10
|
+
import { DXN, Annotation, type Database, Format, Obj, type QueryAST, Ref, Type, View } from '@dxos/echo';
|
|
11
|
+
import { type Mutable, PropertyMetaAnnotationId } from '@dxos/echo/internal';
|
|
20
12
|
import { invariant } from '@dxos/invariant';
|
|
21
|
-
import {
|
|
13
|
+
import { random } from '@dxos/random';
|
|
22
14
|
import { PublicKey } from '@dxos/react-client';
|
|
23
|
-
import { type Space, live } from '@dxos/react-client/echo';
|
|
24
15
|
import { withClientProvider } from '@dxos/react-client/testing';
|
|
16
|
+
import { Panel, ScrollArea } from '@dxos/react-ui';
|
|
25
17
|
import { ViewEditor } from '@dxos/react-ui-form';
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
18
|
+
import { translations as formTranslations } from '@dxos/react-ui-form/translations';
|
|
19
|
+
import { JsonHighlighter } from '@dxos/react-ui-syntax-highlighter';
|
|
20
|
+
import { withLayout, withTheme } from '@dxos/react-ui/testing';
|
|
21
|
+
import { ViewModel, getSchemaFromPropertyDefinitions } from '@dxos/schema';
|
|
22
|
+
import { TestSchema, createObjectFactory } from '@dxos/schema/testing';
|
|
23
|
+
import { withRegistry } from '@dxos/storybook-utils';
|
|
30
24
|
|
|
31
|
-
import {
|
|
32
|
-
import { translations } from '../../translations';
|
|
33
|
-
import { TableView } from '../../types';
|
|
34
|
-
import { createTable } from '../../util';
|
|
35
|
-
import { TableToolbar } from '../TableToolbar';
|
|
25
|
+
import { translations } from '#translations';
|
|
36
26
|
|
|
37
|
-
import {
|
|
27
|
+
import { useTestTableModel } from '../../testing';
|
|
28
|
+
import { Table } from '../../types';
|
|
29
|
+
import { Table as TableComponent } from './Table';
|
|
38
30
|
|
|
39
|
-
const
|
|
31
|
+
const Example = Schema.Struct({
|
|
40
32
|
// TODO(wittjosiah): Should be title. Currently name to work with default label.
|
|
41
33
|
name: Schema.optional(Schema.String).annotations({ title: 'Title' }),
|
|
42
34
|
urgent: Schema.optional(Schema.Boolean).annotations({ title: 'Urgent' }),
|
|
43
35
|
status: Schema.optional(
|
|
44
36
|
Schema.Literal('todo', 'in-progress', 'done')
|
|
45
|
-
.pipe(FormatAnnotation.set(
|
|
37
|
+
.pipe(Format.FormatAnnotation.set(Format.TypeFormat.SingleSelect))
|
|
46
38
|
.annotations({
|
|
47
39
|
title: 'Status',
|
|
48
40
|
[PropertyMetaAnnotationId]: {
|
|
@@ -57,33 +49,35 @@ const TestSchema = Schema.Struct({
|
|
|
57
49
|
}),
|
|
58
50
|
),
|
|
59
51
|
description: Schema.optional(Schema.String).annotations({ title: 'Description' }),
|
|
60
|
-
parent: Schema.optional(Schema.suspend(():
|
|
52
|
+
parent: Schema.optional(Schema.suspend((): Ref.RefSchema<Example> => Ref.Ref(Example))).annotations({
|
|
61
53
|
title: 'Parent',
|
|
62
54
|
}),
|
|
63
55
|
}).pipe(
|
|
64
|
-
|
|
65
|
-
|
|
56
|
+
Annotation.LabelAnnotation.set(['name']),
|
|
57
|
+
// NSID last segment must start with a letter (DXN spec), so prefix the random hex.
|
|
58
|
+
Type.makeObject(DXN.make(`com.example.type.example${PublicKey.random().truncate()}`, '0.1.0')),
|
|
66
59
|
);
|
|
67
|
-
interface
|
|
60
|
+
interface Example extends Type.InstanceType<typeof Example> {}
|
|
68
61
|
|
|
69
62
|
const StoryViewEditor = ({
|
|
70
63
|
view,
|
|
71
64
|
schema,
|
|
72
|
-
|
|
65
|
+
db,
|
|
73
66
|
handleDeleteColumn,
|
|
74
67
|
}: {
|
|
75
|
-
view?:
|
|
76
|
-
schema?:
|
|
77
|
-
|
|
68
|
+
view?: View.View;
|
|
69
|
+
schema?: Type.AnyEntity;
|
|
70
|
+
db?: Database.Database;
|
|
78
71
|
handleDeleteColumn: (fieldId: string) => void;
|
|
79
72
|
}) => {
|
|
80
|
-
const
|
|
81
|
-
(
|
|
73
|
+
const handleQueryChanged = useCallback(
|
|
74
|
+
(newQuery: QueryAST.Query) => {
|
|
82
75
|
invariant(schema);
|
|
83
|
-
invariant(Type.
|
|
84
|
-
schema.updateTypename(typename);
|
|
76
|
+
invariant(Type.getDatabase(schema) != null);
|
|
85
77
|
invariant(view);
|
|
86
|
-
view
|
|
78
|
+
Obj.update(view, (view) => {
|
|
79
|
+
view.query.ast = newQuery as Mutable<typeof newQuery>;
|
|
80
|
+
});
|
|
87
81
|
},
|
|
88
82
|
[schema, view],
|
|
89
83
|
);
|
|
@@ -94,10 +88,10 @@ const StoryViewEditor = ({
|
|
|
94
88
|
|
|
95
89
|
return (
|
|
96
90
|
<ViewEditor
|
|
97
|
-
registry={
|
|
98
|
-
|
|
91
|
+
registry={db?.graph.registry}
|
|
92
|
+
type={schema}
|
|
99
93
|
view={view}
|
|
100
|
-
|
|
94
|
+
onQueryChanged={handleQueryChanged}
|
|
101
95
|
onDelete={handleDeleteColumn}
|
|
102
96
|
/>
|
|
103
97
|
);
|
|
@@ -108,122 +102,147 @@ const StoryViewEditor = ({
|
|
|
108
102
|
//
|
|
109
103
|
|
|
110
104
|
const DefaultStory = () => {
|
|
111
|
-
const {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
if (!schema || !view) {
|
|
105
|
+
const { db, schema, table, tableRef, model, presentation, handleInsertRow, handleSaveView, handleDeleteColumn } =
|
|
106
|
+
useTestTableModel();
|
|
107
|
+
|
|
108
|
+
const handleRowClick = useCallback(
|
|
109
|
+
(row: any) => {
|
|
110
|
+
if (model?.getDraftRowCount() === 0 && ['frozenRowsEnd', 'fixedEndStart', 'fixedEndEnd'].includes(row?.plane)) {
|
|
111
|
+
handleInsertRow();
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
[model, handleInsertRow],
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
if (!schema || !table?.view.target) {
|
|
125
118
|
return <div />;
|
|
126
119
|
}
|
|
127
120
|
|
|
128
121
|
return (
|
|
129
122
|
<div className='grow grid grid-cols-[1fr_350px]'>
|
|
130
|
-
<
|
|
131
|
-
<
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
123
|
+
<TableComponent.Root ref={tableRef}>
|
|
124
|
+
<Panel.Root>
|
|
125
|
+
<Panel.Toolbar asChild>
|
|
126
|
+
<TableComponent.Toolbar
|
|
127
|
+
classNames='border-b border-subdued-separator'
|
|
128
|
+
onAdd={handleInsertRow}
|
|
129
|
+
onSave={handleSaveView}
|
|
130
|
+
/>
|
|
131
|
+
</Panel.Toolbar>
|
|
132
|
+
<Panel.Content asChild>
|
|
133
|
+
<TableComponent.Content
|
|
134
|
+
schema={schema}
|
|
135
|
+
model={model}
|
|
136
|
+
presentation={presentation}
|
|
137
|
+
onRowClick={handleRowClick}
|
|
138
|
+
ignoreAttention
|
|
139
|
+
/>
|
|
140
|
+
</Panel.Content>
|
|
141
|
+
</Panel.Root>
|
|
142
|
+
</TableComponent.Root>
|
|
143
|
+
<ScrollArea.Root orientation='vertical' classNames='border-l border-separator'>
|
|
144
|
+
<ScrollArea.Viewport>
|
|
145
|
+
<StoryViewEditor view={table.view.target} schema={schema} db={db} handleDeleteColumn={handleDeleteColumn} />
|
|
146
|
+
<JsonHighlighter data={{ view: table.view.target, schema }} classNames='text-xs' />
|
|
147
|
+
</ScrollArea.Viewport>
|
|
148
|
+
</ScrollArea.Root>
|
|
149
149
|
</div>
|
|
150
150
|
);
|
|
151
151
|
};
|
|
152
152
|
|
|
153
|
-
type
|
|
153
|
+
type DefaultStoryProps = { rows?: number };
|
|
154
154
|
|
|
155
155
|
//
|
|
156
156
|
// Story definitions.
|
|
157
157
|
//
|
|
158
158
|
|
|
159
|
-
// TODO(burdon): Need
|
|
159
|
+
// TODO(burdon): Need simpler story.
|
|
160
160
|
|
|
161
|
-
const meta
|
|
161
|
+
const meta = {
|
|
162
162
|
title: 'ui/react-ui-table/Table',
|
|
163
163
|
render: DefaultStory,
|
|
164
|
-
parameters: {
|
|
165
|
-
translations,
|
|
166
|
-
layout: 'fullscreen',
|
|
167
|
-
controls: {
|
|
168
|
-
disable: true,
|
|
169
|
-
},
|
|
170
|
-
},
|
|
171
164
|
decorators: [
|
|
172
|
-
withTheme,
|
|
173
|
-
withLayout({
|
|
165
|
+
withTheme(),
|
|
166
|
+
withLayout({ layout: 'fullscreen' }),
|
|
167
|
+
withRegistry,
|
|
174
168
|
withClientProvider({
|
|
175
|
-
types: [
|
|
169
|
+
types: [View.View, Table.Table],
|
|
176
170
|
createIdentity: true,
|
|
177
171
|
createSpace: true,
|
|
178
|
-
|
|
179
|
-
const
|
|
180
|
-
const { view } = await
|
|
181
|
-
|
|
172
|
+
onCreateSpace: async ({ space }) => {
|
|
173
|
+
const type = await space.db.addType(Example);
|
|
174
|
+
const { view, jsonSchema } = await ViewModel.makeFromDatabase({
|
|
175
|
+
db: space.db,
|
|
176
|
+
typename: Type.getTypename(type),
|
|
177
|
+
});
|
|
178
|
+
const table = Table.make({ view, jsonSchema });
|
|
179
|
+
Obj.update(view, (view) => {
|
|
180
|
+
view.projection.fields = [
|
|
181
|
+
view.projection.fields.find((field) => field.path === 'name')!,
|
|
182
|
+
...view.projection.fields.filter((field) => field.path !== 'name'),
|
|
183
|
+
];
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
space.db.add(table);
|
|
182
187
|
|
|
183
188
|
Array.from({ length: 10 }).map(() => {
|
|
184
189
|
return space.db.add(
|
|
185
|
-
Obj.make(
|
|
186
|
-
name:
|
|
187
|
-
status:
|
|
188
|
-
description:
|
|
190
|
+
Obj.make(type, {
|
|
191
|
+
name: random.lorem.sentence(),
|
|
192
|
+
status: random.helpers.arrayElement(['todo', 'in-progress', 'done'] as const),
|
|
193
|
+
description: random.lorem.paragraph(),
|
|
189
194
|
}),
|
|
190
195
|
);
|
|
191
196
|
});
|
|
192
197
|
},
|
|
193
198
|
}),
|
|
194
199
|
],
|
|
195
|
-
|
|
200
|
+
parameters: {
|
|
201
|
+
layout: 'fullscreen',
|
|
202
|
+
controls: {
|
|
203
|
+
disable: true,
|
|
204
|
+
},
|
|
205
|
+
translations: [...translations, ...formTranslations],
|
|
206
|
+
},
|
|
207
|
+
} satisfies Meta<typeof TableComponent>;
|
|
196
208
|
|
|
197
209
|
export default meta;
|
|
198
210
|
|
|
199
|
-
|
|
211
|
+
type Story = StoryObj<typeof meta>;
|
|
212
|
+
|
|
213
|
+
export const Default: Story = {};
|
|
200
214
|
|
|
201
215
|
export const StaticSchema: StoryObj = {
|
|
202
216
|
render: DefaultStory,
|
|
203
|
-
parameters: { translations },
|
|
204
217
|
decorators: [
|
|
205
218
|
withClientProvider({
|
|
206
|
-
types: [
|
|
219
|
+
types: [View.View, Table.Table],
|
|
207
220
|
createIdentity: true,
|
|
208
221
|
createSpace: true,
|
|
209
|
-
|
|
210
|
-
const { view } = await
|
|
211
|
-
|
|
222
|
+
onCreateSpace: async ({ space }) => {
|
|
223
|
+
const { view, jsonSchema } = await ViewModel.makeFromDatabase({
|
|
224
|
+
db: space.db,
|
|
225
|
+
typename: Type.getTypename(TestSchema.Person),
|
|
226
|
+
});
|
|
227
|
+
const table = Table.make({ view, jsonSchema });
|
|
228
|
+
space.db.add(table);
|
|
212
229
|
|
|
213
|
-
const factory = createObjectFactory(space.db,
|
|
230
|
+
const factory = createObjectFactory(space.db, random as any);
|
|
214
231
|
await factory([
|
|
215
|
-
{ type:
|
|
216
|
-
// { type:
|
|
232
|
+
{ type: TestSchema.Person, count: 10 },
|
|
233
|
+
// { type: TestSchema.Organization, count: 1 },
|
|
217
234
|
]);
|
|
218
235
|
},
|
|
219
236
|
}),
|
|
220
|
-
withLayout({ fullscreen: true }),
|
|
221
|
-
withTheme,
|
|
222
237
|
],
|
|
238
|
+
parameters: {
|
|
239
|
+
layout: 'fullscreen',
|
|
240
|
+
translations: [...translations, ...formTranslations],
|
|
241
|
+
},
|
|
223
242
|
};
|
|
224
243
|
|
|
225
244
|
const ContactWithArrayOfEmails = Schema.Struct({
|
|
226
|
-
name: Schema.String.pipe(GeneratorAnnotation.set('person.fullName')),
|
|
245
|
+
name: Schema.String.pipe(Annotation.GeneratorAnnotation.set('person.fullName')),
|
|
227
246
|
emails: Schema.optional(
|
|
228
247
|
Schema.Array(
|
|
229
248
|
Schema.Struct({
|
|
@@ -232,50 +251,104 @@ const ContactWithArrayOfEmails = Schema.Struct({
|
|
|
232
251
|
}),
|
|
233
252
|
),
|
|
234
253
|
),
|
|
235
|
-
}).pipe(
|
|
236
|
-
EchoObject({
|
|
237
|
-
typename: 'dxos.org/type/ContactWithArrayOfEmails',
|
|
238
|
-
version: '0.1.0',
|
|
239
|
-
}),
|
|
240
|
-
);
|
|
254
|
+
}).pipe(Type.makeObject(DXN.make('org.dxos.type.contactWithArrayOfEmails', '0.1.0')));
|
|
241
255
|
|
|
242
256
|
export const ArrayOfObjects: StoryObj = {
|
|
243
257
|
render: DefaultStory,
|
|
244
|
-
parameters: { translations },
|
|
245
258
|
decorators: [
|
|
246
259
|
withClientProvider({
|
|
247
|
-
types: [
|
|
260
|
+
types: [View.View, Table.Table, TestSchema.Person, TestSchema.Organization, ContactWithArrayOfEmails],
|
|
248
261
|
createIdentity: true,
|
|
249
262
|
createSpace: true,
|
|
250
|
-
|
|
251
|
-
const { view } = await
|
|
252
|
-
|
|
263
|
+
onCreateSpace: async ({ space }) => {
|
|
264
|
+
const { view, jsonSchema } = await ViewModel.makeFromDatabase({
|
|
265
|
+
db: space.db,
|
|
266
|
+
typename: Type.getTypename(ContactWithArrayOfEmails),
|
|
267
|
+
});
|
|
268
|
+
const table = Table.make({ view, jsonSchema });
|
|
269
|
+
space.db.add(table);
|
|
253
270
|
|
|
254
|
-
const factory = createObjectFactory(space.db,
|
|
271
|
+
const factory = createObjectFactory(space.db, random as any);
|
|
255
272
|
await factory([
|
|
256
|
-
// { type:
|
|
257
|
-
// { type:
|
|
273
|
+
// { type: TestSchema.Person, count: 10 },
|
|
274
|
+
// { type: TestSchema.Organization, count: 1 },
|
|
258
275
|
{ type: ContactWithArrayOfEmails, count: 10 },
|
|
259
276
|
]);
|
|
260
277
|
},
|
|
261
278
|
}),
|
|
262
|
-
withLayout({ fullscreen: true }),
|
|
263
|
-
withTheme,
|
|
264
279
|
],
|
|
280
|
+
parameters: {
|
|
281
|
+
layout: 'fullscreen',
|
|
282
|
+
translations,
|
|
283
|
+
},
|
|
265
284
|
};
|
|
266
285
|
|
|
267
|
-
export const
|
|
286
|
+
export const RequiredSchema: StoryObj = {
|
|
287
|
+
render: DefaultStory,
|
|
288
|
+
decorators: [
|
|
289
|
+
withClientProvider({
|
|
290
|
+
types: [View.View, Table.Table, TestSchema.Person],
|
|
291
|
+
createIdentity: true,
|
|
292
|
+
createSpace: true,
|
|
293
|
+
onCreateSpace: async ({ space }) => {
|
|
294
|
+
// TestSchema.Person has a required `name: Schema.String` field.
|
|
295
|
+
// No pre-populated rows so the add-row flow is the first interaction.
|
|
296
|
+
const { view, jsonSchema } = await ViewModel.makeFromDatabase({
|
|
297
|
+
db: space.db,
|
|
298
|
+
typename: Type.getTypename(TestSchema.Person),
|
|
299
|
+
});
|
|
300
|
+
const table = Table.make({ view, jsonSchema });
|
|
301
|
+
space.db.add(table);
|
|
302
|
+
},
|
|
303
|
+
}),
|
|
304
|
+
],
|
|
305
|
+
parameters: {
|
|
306
|
+
layout: 'fullscreen',
|
|
307
|
+
translations: [...translations, ...formTranslations],
|
|
308
|
+
},
|
|
309
|
+
play: async ({ canvasElement }) => {
|
|
310
|
+
const canvas = within(canvasElement);
|
|
311
|
+
|
|
312
|
+
// 30 s covers ECHO client + space + table creation (the only inherently slow step).
|
|
313
|
+
const addRowButton = await canvas.findByTestId('table.toolbar.add-row', undefined, { timeout: 30_000 });
|
|
314
|
+
|
|
315
|
+
// Person.name is required, so db.add throws → useAddRow returns 'draft' →
|
|
316
|
+
// a draft row appears in frozenRowsEnd and focus is set to its first cell.
|
|
317
|
+
await userEvent.click(addRowButton);
|
|
318
|
+
|
|
319
|
+
const draftCell = await canvas.findByTestId('frozenRowsEnd.0.0');
|
|
320
|
+
await userEvent.click(draftCell);
|
|
321
|
+
|
|
322
|
+
// Open the editor with Enter rather than typing to open — the latter routes the first
|
|
323
|
+
// character into dx-grid's `initialContent` and races the editor mount. The empty value
|
|
324
|
+
// fails validation; the editor must stay open so the value below can be entered.
|
|
325
|
+
await userEvent.keyboard('{Enter}');
|
|
326
|
+
await canvas.findByTestId('grid.cell-editor');
|
|
327
|
+
|
|
328
|
+
// The editor is focused (autoFocus); type the required value and commit.
|
|
329
|
+
await userEvent.keyboard('Alice');
|
|
330
|
+
await userEvent.keyboard('{Enter}');
|
|
331
|
+
|
|
332
|
+
// The draft row is committed and appears in the grid with the typed value.
|
|
333
|
+
await waitFor(async () => {
|
|
334
|
+
const cell = canvas.getByTestId('grid.0.0');
|
|
335
|
+
const text = cell.querySelector('.dx-grid__cell__content')?.textContent;
|
|
336
|
+
await expect(text).toBe('Alice');
|
|
337
|
+
});
|
|
338
|
+
},
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
export const Tags: Meta<DefaultStoryProps> = {
|
|
268
342
|
title: 'ui/react-ui-table/Table',
|
|
269
343
|
render: DefaultStory,
|
|
270
|
-
parameters: { translations },
|
|
271
344
|
decorators: [
|
|
272
345
|
withClientProvider({
|
|
273
|
-
types: [
|
|
346
|
+
types: [View.View, Table.Table],
|
|
274
347
|
createIdentity: true,
|
|
275
348
|
createSpace: true,
|
|
276
|
-
|
|
349
|
+
onCreateSpace: async ({ space }) => {
|
|
277
350
|
// Configure schema.
|
|
278
|
-
const typename = 'example.
|
|
351
|
+
const typename = 'com.example.type.singleSelect';
|
|
279
352
|
const selectOptions = [
|
|
280
353
|
{ id: 'one', title: 'One', color: 'emerald' },
|
|
281
354
|
{ id: 'two', title: 'Two', color: 'blue' },
|
|
@@ -286,36 +359,39 @@ export const Tags: Meta<StoryProps> = {
|
|
|
286
359
|
|
|
287
360
|
const selectOptionIds = selectOptions.map((o) => o.id);
|
|
288
361
|
|
|
289
|
-
const
|
|
362
|
+
const type = getSchemaFromPropertyDefinitions(typename, [
|
|
290
363
|
{
|
|
291
364
|
name: 'single',
|
|
292
|
-
format:
|
|
365
|
+
format: Format.TypeFormat.SingleSelect,
|
|
293
366
|
config: { options: selectOptions },
|
|
294
367
|
},
|
|
295
368
|
{
|
|
296
369
|
name: 'multiple',
|
|
297
|
-
format:
|
|
370
|
+
format: Format.TypeFormat.MultiSelect,
|
|
298
371
|
config: { options: selectOptions },
|
|
299
372
|
},
|
|
300
373
|
]);
|
|
301
|
-
const
|
|
374
|
+
const storedType = await space.db.addType(type);
|
|
302
375
|
|
|
303
376
|
// Initialize table.
|
|
304
|
-
const { view } = await
|
|
305
|
-
|
|
377
|
+
const { view, jsonSchema } = await ViewModel.makeFromDatabase({ db: space.db, typename });
|
|
378
|
+
const table = Table.make({ view, jsonSchema });
|
|
379
|
+
space.db.add(table);
|
|
306
380
|
|
|
307
381
|
// Populate.
|
|
308
382
|
Array.from({ length: 10 }).map(() => {
|
|
309
383
|
return space.db.add(
|
|
310
|
-
|
|
311
|
-
single:
|
|
312
|
-
multiple:
|
|
384
|
+
Obj.make(Type.assertObject(storedType), {
|
|
385
|
+
single: random.helpers.arrayElement([...selectOptionIds, undefined]),
|
|
386
|
+
multiple: random.helpers.randomSubset(selectOptionIds),
|
|
313
387
|
}),
|
|
314
388
|
);
|
|
315
389
|
});
|
|
316
390
|
},
|
|
317
391
|
}),
|
|
318
|
-
withLayout({ fullscreen: true }),
|
|
319
|
-
withTheme,
|
|
320
392
|
],
|
|
393
|
+
parameters: {
|
|
394
|
+
layout: 'fullscreen',
|
|
395
|
+
translations,
|
|
396
|
+
},
|
|
321
397
|
};
|