@dxos/react-ui-table 0.8.3 → 0.8.4-main.03d5cd7b56

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.
Files changed (194) hide show
  1. package/dist/lib/browser/chunk-FBURZBPH.mjs +70 -0
  2. package/dist/lib/browser/chunk-FBURZBPH.mjs.map +7 -0
  3. package/dist/lib/browser/chunk-J5LGTIGS.mjs +10 -0
  4. package/dist/lib/browser/chunk-J5LGTIGS.mjs.map +7 -0
  5. package/dist/lib/browser/chunk-YGC7LZJN.mjs +1695 -0
  6. package/dist/lib/browser/chunk-YGC7LZJN.mjs.map +7 -0
  7. package/dist/lib/browser/index.mjs +1162 -2554
  8. package/dist/lib/browser/index.mjs.map +4 -4
  9. package/dist/lib/browser/meta.json +1 -1
  10. package/dist/lib/browser/testing/index.mjs +115 -0
  11. package/dist/lib/browser/testing/index.mjs.map +7 -0
  12. package/dist/lib/browser/translations.mjs +36 -0
  13. package/dist/lib/browser/translations.mjs.map +7 -0
  14. package/dist/lib/browser/types/index.mjs +4 -5
  15. package/dist/lib/node-esm/chunk-DKKMSVKP.mjs +71 -0
  16. package/dist/lib/node-esm/chunk-DKKMSVKP.mjs.map +7 -0
  17. package/dist/lib/node-esm/chunk-GKIWDEZ7.mjs +1697 -0
  18. package/dist/lib/node-esm/chunk-GKIWDEZ7.mjs.map +7 -0
  19. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
  20. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +7 -0
  21. package/dist/lib/node-esm/index.mjs +1162 -2554
  22. package/dist/lib/node-esm/index.mjs.map +4 -4
  23. package/dist/lib/node-esm/meta.json +1 -1
  24. package/dist/lib/node-esm/testing/index.mjs +116 -0
  25. package/dist/lib/node-esm/testing/index.mjs.map +7 -0
  26. package/dist/lib/node-esm/translations.mjs +37 -0
  27. package/dist/lib/node-esm/translations.mjs.map +7 -0
  28. package/dist/lib/node-esm/types/index.mjs +4 -5
  29. package/dist/types/src/components/Table/ColumnActionsMenu.d.ts +2 -3
  30. package/dist/types/src/components/Table/ColumnActionsMenu.d.ts.map +1 -1
  31. package/dist/types/src/components/Table/ColumnSettings.d.ts +4 -2
  32. package/dist/types/src/components/Table/ColumnSettings.d.ts.map +1 -1
  33. package/dist/types/src/components/Table/DynamicTable.d.ts +7 -7
  34. package/dist/types/src/components/Table/DynamicTable.d.ts.map +1 -1
  35. package/dist/types/src/components/Table/DynamicTable.stories.d.ts +35 -3
  36. package/dist/types/src/components/Table/DynamicTable.stories.d.ts.map +1 -1
  37. package/dist/types/src/components/Table/Relations.stories.d.ts +111 -0
  38. package/dist/types/src/components/Table/Relations.stories.d.ts.map +1 -0
  39. package/dist/types/src/components/Table/RowActionsMenu.d.ts +1 -1
  40. package/dist/types/src/components/Table/RowActionsMenu.d.ts.map +1 -1
  41. package/dist/types/src/components/Table/Table.d.ts +21 -18
  42. package/dist/types/src/components/Table/Table.d.ts.map +1 -1
  43. package/dist/types/src/components/Table/Table.stories.d.ts +110 -6
  44. package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
  45. package/dist/types/src/components/Table/TableContent.d.ts +17 -0
  46. package/dist/types/src/components/Table/TableContent.d.ts.map +1 -0
  47. package/dist/types/src/components/Table/TableToolbar.d.ts +21 -0
  48. package/dist/types/src/components/Table/TableToolbar.d.ts.map +1 -0
  49. package/dist/types/src/components/TableCellEditor/CellValidationMessage.d.ts +2 -1
  50. package/dist/types/src/components/TableCellEditor/CellValidationMessage.d.ts.map +1 -1
  51. package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts +14 -9
  52. package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts.map +1 -1
  53. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +12 -18
  54. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
  55. package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts +38 -5
  56. package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts.map +1 -1
  57. package/dist/types/src/components/TableCellEditor/index.d.ts +1 -0
  58. package/dist/types/src/components/TableCellEditor/index.d.ts.map +1 -1
  59. package/dist/types/src/components/index.d.ts +0 -1
  60. package/dist/types/src/components/index.d.ts.map +1 -1
  61. package/dist/types/src/components/testing.d.ts +26 -56
  62. package/dist/types/src/components/testing.d.ts.map +1 -1
  63. package/dist/types/src/hooks/index.d.ts +2 -0
  64. package/dist/types/src/hooks/index.d.ts.map +1 -1
  65. package/dist/types/src/hooks/useAddRow.d.ts +13 -0
  66. package/dist/types/src/hooks/useAddRow.d.ts.map +1 -0
  67. package/dist/types/src/hooks/useProjectionModel.d.ts +6 -0
  68. package/dist/types/src/hooks/useProjectionModel.d.ts.map +1 -0
  69. package/dist/types/src/hooks/useTableModel.d.ts +11 -10
  70. package/dist/types/src/hooks/useTableModel.d.ts.map +1 -1
  71. package/dist/types/src/index.d.ts +0 -3
  72. package/dist/types/src/index.d.ts.map +1 -1
  73. package/dist/types/src/model/modal-controller.d.ts +5 -8
  74. package/dist/types/src/model/modal-controller.d.ts.map +1 -1
  75. package/dist/types/src/model/selection-model.d.ts +18 -8
  76. package/dist/types/src/model/selection-model.d.ts.map +1 -1
  77. package/dist/types/src/model/table-model.d.ts +150 -32
  78. package/dist/types/src/model/table-model.d.ts.map +1 -1
  79. package/dist/types/src/model/table-presentation.d.ts +13 -2
  80. package/dist/types/src/model/table-presentation.d.ts.map +1 -1
  81. package/dist/types/src/playwright/TableManager.d.ts +2 -1
  82. package/dist/types/src/playwright/TableManager.d.ts.map +1 -1
  83. package/dist/types/src/playwright/playwright.config.d.ts +3 -0
  84. package/dist/types/src/playwright/playwright.config.d.ts.map +1 -0
  85. package/dist/types/src/testing/index.d.ts +2 -0
  86. package/dist/types/src/testing/index.d.ts.map +1 -0
  87. package/dist/types/src/testing/useTestTableModel.d.ts +25 -0
  88. package/dist/types/src/testing/useTestTableModel.d.ts.map +1 -0
  89. package/dist/types/src/translations.d.ts +22 -25
  90. package/dist/types/src/translations.d.ts.map +1 -1
  91. package/dist/types/src/types/Table.d.ts +26 -0
  92. package/dist/types/src/types/Table.d.ts.map +1 -0
  93. package/dist/types/src/types/index.d.ts +1 -1
  94. package/dist/types/src/types/index.d.ts.map +1 -1
  95. package/dist/types/src/util/dynamic-table.d.ts +15 -14
  96. package/dist/types/src/util/dynamic-table.d.ts.map +1 -1
  97. package/dist/types/src/util/dynamic-table.test.d.ts +2 -0
  98. package/dist/types/src/util/dynamic-table.test.d.ts.map +1 -0
  99. package/dist/types/src/util/index.d.ts +2 -1
  100. package/dist/types/src/util/index.d.ts.map +1 -1
  101. package/dist/types/src/util/query-ast.d.ts +7 -0
  102. package/dist/types/src/util/query-ast.d.ts.map +1 -0
  103. package/dist/types/src/util/schema.d.ts +1 -1
  104. package/dist/types/src/util/schema.d.ts.map +1 -1
  105. package/dist/types/src/util/signals.d.ts.map +1 -1
  106. package/dist/types/src/util/sort.d.ts +12 -0
  107. package/dist/types/src/util/sort.d.ts.map +1 -0
  108. package/dist/types/src/util/table-buttons.d.ts +31 -17
  109. package/dist/types/src/util/table-buttons.d.ts.map +1 -1
  110. package/dist/types/src/util/table-controls.d.ts +4 -4
  111. package/dist/types/src/util/table-controls.d.ts.map +1 -1
  112. package/dist/types/src/util/tag.d.ts.map +1 -1
  113. package/dist/types/tsconfig.tsbuildinfo +1 -1
  114. package/package.json +76 -72
  115. package/src/components/Table/ColumnActionsMenu.tsx +18 -13
  116. package/src/components/Table/ColumnSettings.tsx +18 -15
  117. package/src/components/Table/DynamicTable.stories.tsx +40 -36
  118. package/src/components/Table/DynamicTable.tsx +38 -34
  119. package/src/components/Table/Relations.stories.tsx +281 -0
  120. package/src/components/Table/RowActionsMenu.tsx +29 -19
  121. package/src/components/Table/Table.stories.tsx +198 -214
  122. package/src/components/Table/Table.tsx +47 -363
  123. package/src/components/Table/TableContent.tsx +421 -0
  124. package/src/components/Table/TableToolbar.tsx +111 -0
  125. package/src/components/TableCellEditor/CellValidationMessage.tsx +9 -5
  126. package/src/components/TableCellEditor/FormCellEditor.tsx +153 -49
  127. package/src/components/TableCellEditor/TableCellEditor.stories.tsx +40 -79
  128. package/src/components/TableCellEditor/TableCellEditor.tsx +109 -199
  129. package/src/components/TableCellEditor/index.ts +1 -0
  130. package/src/components/index.ts +0 -1
  131. package/src/components/testing.ts +46 -37
  132. package/src/hooks/index.ts +2 -0
  133. package/src/hooks/useAddRow.ts +36 -0
  134. package/src/hooks/useProjectionModel.ts +39 -0
  135. package/src/hooks/useTableModel.ts +41 -35
  136. package/src/index.ts +0 -5
  137. package/src/model/modal-controller.ts +24 -41
  138. package/src/model/selection-model.ts +75 -41
  139. package/src/model/table-model.test.ts +91 -56
  140. package/src/model/table-model.ts +629 -162
  141. package/src/model/table-presentation.test.ts +69 -59
  142. package/src/model/table-presentation.ts +283 -154
  143. package/src/playwright/TableManager.ts +13 -6
  144. package/src/playwright/playwright.config.ts +17 -0
  145. package/src/playwright/smoke.spec.ts +181 -42
  146. package/src/testing/index.ts +5 -0
  147. package/src/testing/useTestTableModel.ts +133 -0
  148. package/src/translations.ts +24 -24
  149. package/src/types/Table.ts +79 -0
  150. package/src/types/index.ts +2 -2
  151. package/src/util/dynamic-table.test.ts +70 -0
  152. package/src/util/dynamic-table.ts +51 -36
  153. package/src/util/index.ts +2 -1
  154. package/src/util/query-ast.ts +22 -0
  155. package/src/util/schema.ts +4 -4
  156. package/src/util/sort.ts +90 -0
  157. package/src/util/table-buttons.ts +28 -4
  158. package/src/util/table-controls.ts +6 -3
  159. package/dist/lib/browser/chunk-TL7CKQQV.mjs +0 -27
  160. package/dist/lib/browser/chunk-TL7CKQQV.mjs.map +0 -7
  161. package/dist/lib/node/chunk-O2VPBNS5.cjs +0 -50
  162. package/dist/lib/node/chunk-O2VPBNS5.cjs.map +0 -7
  163. package/dist/lib/node/index.cjs +0 -2739
  164. package/dist/lib/node/index.cjs.map +0 -7
  165. package/dist/lib/node/meta.json +0 -1
  166. package/dist/lib/node/types/index.cjs +0 -31
  167. package/dist/lib/node/types/index.cjs.map +0 -7
  168. package/dist/lib/node-esm/chunk-GBT6GD4G.mjs +0 -29
  169. package/dist/lib/node-esm/chunk-GBT6GD4G.mjs.map +0 -7
  170. package/dist/types/src/components/Table/CreateRefPanel.d.ts +0 -9
  171. package/dist/types/src/components/Table/CreateRefPanel.d.ts.map +0 -1
  172. package/dist/types/src/components/Table/relations.stories.d.ts +0 -9
  173. package/dist/types/src/components/Table/relations.stories.d.ts.map +0 -1
  174. package/dist/types/src/components/TableCellEditor/extension.d.ts +0 -13
  175. package/dist/types/src/components/TableCellEditor/extension.d.ts.map +0 -1
  176. package/dist/types/src/components/TableToolbar/TableToolbar.d.ts +0 -21
  177. package/dist/types/src/components/TableToolbar/TableToolbar.d.ts.map +0 -1
  178. package/dist/types/src/components/TableToolbar/index.d.ts +0 -2
  179. package/dist/types/src/components/TableToolbar/index.d.ts.map +0 -1
  180. package/dist/types/src/model/table-sorting.d.ts +0 -53
  181. package/dist/types/src/model/table-sorting.d.ts.map +0 -1
  182. package/dist/types/src/types/table.d.ts +0 -56
  183. package/dist/types/src/types/table.d.ts.map +0 -1
  184. package/dist/types/src/util/table.d.ts +0 -14
  185. package/dist/types/src/util/table.d.ts.map +0 -1
  186. package/src/components/Table/CreateRefPanel.tsx +0 -84
  187. package/src/components/Table/relations.stories.tsx +0 -124
  188. package/src/components/TableCellEditor/extension.ts +0 -61
  189. package/src/components/TableToolbar/TableToolbar.tsx +0 -102
  190. package/src/components/TableToolbar/index.ts +0 -5
  191. package/src/model/table-sorting.ts +0 -216
  192. package/src/playwright/playwright.config.cts +0 -18
  193. package/src/types/table.ts +0 -27
  194. package/src/util/table.ts +0 -127
@@ -2,161 +2,96 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+ import * as Schema from 'effect/Schema';
7
+ import React, { useCallback } from 'react';
6
8
 
7
- import { type StoryObj, type Meta } from '@storybook/react';
8
- import { Schema } from 'effect';
9
- import React, { useCallback, useMemo, useRef } from 'react';
10
-
11
- import { Obj, Type } from '@dxos/echo';
12
- import { FormatEnum, isMutable, toJsonSchema, EchoObject, GeneratorAnnotation } from '@dxos/echo-schema';
9
+ import { Annotation, type Database, Format, Obj, type QueryAST, Ref, Type } from '@dxos/echo';
10
+ import { View } from '@dxos/echo';
11
+ import { type Mutable, PropertyMetaAnnotationId } from '@dxos/echo/internal';
13
12
  import { invariant } from '@dxos/invariant';
14
- import { useGlobalFilteredObjects } from '@dxos/plugin-search';
15
- import { faker } from '@dxos/random';
16
- import { useClient } from '@dxos/react-client';
17
- import { Filter, useQuery, useSchema, live } from '@dxos/react-client/echo';
18
- import { useClientProvider, withClientProvider } from '@dxos/react-client/testing';
13
+ import { random } from '@dxos/random';
14
+ import { PublicKey } from '@dxos/react-client';
15
+ import { withClientProvider } from '@dxos/react-client/testing';
16
+ import { Panel, ScrollArea } from '@dxos/react-ui';
19
17
  import { ViewEditor } from '@dxos/react-ui-form';
20
- import { SyntaxHighlighter } from '@dxos/react-ui-syntax-highlighter';
21
- import { getSchemaFromPropertyDefinitions, ViewProjection, ViewType } from '@dxos/schema';
22
- import { Testing, createObjectFactory } from '@dxos/schema/testing';
23
- import { withLayout, withTheme } from '@dxos/storybook-utils';
24
-
25
- import { Table, type TableController } from './Table';
26
- import { useTableModel } from '../../hooks';
27
- import { TablePresentation } from '../../model';
28
- import translations from '../../translations';
29
- import { TableType } from '../../types';
30
- import { initializeTable } from '../../util';
31
- import { TableToolbar } from '../TableToolbar';
32
-
33
- faker.seed(0); // NOTE(ZaymonFC): Required for smoke tests.
34
-
35
- /**
36
- * Custom hook to create and manage a test table model for storybook demonstrations.
37
- * Provides table data, schema, and handlers for table operations.
38
- */
39
- const useTestTableModel = () => {
40
- const client = useClient();
41
- const { space } = useClientProvider();
42
-
43
- const filter = useMemo(() => Filter.type(TableType), []);
44
- const tables = useQuery(space, filter);
45
- const table = useMemo(() => tables.at(0), [tables]);
46
- const schema = useSchema(client, space, table?.view?.target?.query.typename);
47
-
48
- const projection = useMemo(() => {
49
- if (schema && table?.view?.target) {
50
- return new ViewProjection(toJsonSchema(schema), table.view.target);
51
- }
52
- }, [schema, table?.view?.target]);
53
-
54
- const features = useMemo(
55
- () => ({
56
- selection: { enabled: true, mode: 'multiple' as const },
57
- dataEditable: true,
58
- schemaEditable: schema && isMutable(schema),
59
- }),
60
- [schema],
61
- );
62
-
63
- const objects = useQuery(space, schema ? Filter.type(schema) : Filter.nothing());
64
- const filteredObjects = useGlobalFilteredObjects(objects);
65
-
66
- const tableRef = useRef<TableController>(null);
67
- const handleCellUpdate = useCallback((cell: any) => {
68
- tableRef.current?.update?.(cell);
69
- }, []);
70
-
71
- const handleRowOrderChange = useCallback(() => {
72
- tableRef.current?.update?.();
73
- }, []);
74
-
75
- const handleInsertRow = useCallback(() => {
76
- if (space && schema) {
77
- space.db.add(live(schema, {}));
78
- }
79
- }, [space, schema]);
80
-
81
- const handleDeleteRows = useCallback(
82
- (_: number, objects: any[]) => {
83
- for (const object of objects) {
84
- space?.db.remove(object);
85
- }
86
- },
87
- [space],
88
- );
89
-
90
- const handleDeleteColumn = useCallback(
91
- (fieldId: string) => {
92
- if (projection) {
93
- projection.deleteFieldProjection(fieldId);
94
- }
95
- },
96
- [projection],
97
- );
98
-
99
- const model = useTableModel({
100
- table,
101
- projection,
102
- features,
103
- rows: filteredObjects,
104
- onInsertRow: handleInsertRow,
105
- onDeleteRows: handleDeleteRows,
106
- onDeleteColumn: handleDeleteColumn,
107
- onCellUpdate: handleCellUpdate,
108
- onRowOrderChange: handleRowOrderChange,
109
- });
110
-
111
- const handleSaveView = useCallback(() => {
112
- model?.saveView();
113
- }, [model]);
114
-
115
- const presentation = useMemo(() => {
116
- if (model) {
117
- return new TablePresentation(model);
118
- }
119
- }, [model]);
120
-
121
- return {
122
- schema,
123
- table,
124
- tableRef,
125
- model,
126
- presentation,
127
- space,
128
- client,
129
- handleInsertRow,
130
- handleSaveView,
131
- handleDeleteRows,
132
- handleDeleteColumn,
133
- };
134
- };
135
-
136
- const StoryViewEditor = () => {
137
- const { table, space, schema, handleDeleteColumn } = useTestTableModel();
138
-
139
- const handleTypenameChanged = useCallback(
140
- (typename: string) => {
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, getTypenameFromQuery } from '@dxos/schema';
22
+ import { TestSchema, createObjectFactory } from '@dxos/schema/testing';
23
+ import { withRegistry } from '@dxos/storybook-utils';
24
+
25
+ import { translations } from '#translations';
26
+
27
+ import { useTestTableModel } from '../../testing';
28
+ import { Table } from '../../types';
29
+ import { Table as TableComponent } from './Table';
30
+
31
+ const Example = Schema.Struct({
32
+ // TODO(wittjosiah): Should be title. Currently name to work with default label.
33
+ name: Schema.optional(Schema.String).annotations({ title: 'Title' }),
34
+ urgent: Schema.optional(Schema.Boolean).annotations({ title: 'Urgent' }),
35
+ status: Schema.optional(
36
+ Schema.Literal('todo', 'in-progress', 'done')
37
+ .pipe(Format.FormatAnnotation.set(Format.TypeFormat.SingleSelect))
38
+ .annotations({
39
+ title: 'Status',
40
+ [PropertyMetaAnnotationId]: {
41
+ singleSelect: {
42
+ options: [
43
+ { id: 'todo', title: 'Todo', color: 'indigo' },
44
+ { id: 'in-progress', title: 'In Progress', color: 'purple' },
45
+ { id: 'done', title: 'Done', color: 'amber' },
46
+ ],
47
+ },
48
+ },
49
+ }),
50
+ ),
51
+ description: Schema.optional(Schema.String).annotations({ title: 'Description' }),
52
+ parent: Schema.optional(Schema.suspend((): Ref.RefSchema<Example> => Ref.Ref(Example))).annotations({
53
+ title: 'Parent',
54
+ }),
55
+ }).pipe(
56
+ Type.object({ typename: `com.example.type.${PublicKey.random().truncate()}`, version: '0.1.0' }),
57
+ Annotation.LabelAnnotation.set(['name']),
58
+ );
59
+ interface Example extends Schema.Schema.Type<typeof Example> {}
60
+
61
+ const StoryViewEditor = ({
62
+ view,
63
+ schema,
64
+ db,
65
+ handleDeleteColumn,
66
+ }: {
67
+ view?: View.View;
68
+ schema?: Schema.Schema.AnyNoContext;
69
+ db?: Database.Database;
70
+ handleDeleteColumn: (fieldId: string) => void;
71
+ }) => {
72
+ const handleQueryChanged = useCallback(
73
+ (newQuery: QueryAST.Query) => {
141
74
  invariant(schema);
142
75
  invariant(Type.isMutable(schema));
143
- schema.updateTypename(typename);
144
- invariant(table?.view?.target);
145
- table.view.target.query.typename = typename;
76
+ schema.updateTypename(getTypenameFromQuery(newQuery));
77
+ invariant(view);
78
+ Obj.update(view, (view) => {
79
+ view.query.ast = newQuery as Mutable<typeof newQuery>;
80
+ });
146
81
  },
147
- [schema, table?.view?.target],
82
+ [schema, view],
148
83
  );
149
84
 
150
- if (!table || !schema || !table.view?.target) {
85
+ if (!view || !schema) {
151
86
  return null;
152
87
  }
153
88
 
154
89
  return (
155
90
  <ViewEditor
156
- registry={space?.db.schemaRegistry}
91
+ registry={db?.schemaRegistry}
157
92
  schema={schema}
158
- view={table.view.target!}
159
- onTypenameChanged={handleTypenameChanged}
93
+ view={view}
94
+ onQueryChanged={handleQueryChanged}
160
95
  onDelete={handleDeleteColumn}
161
96
  />
162
97
  );
@@ -167,102 +102,144 @@ const StoryViewEditor = () => {
167
102
  //
168
103
 
169
104
  const DefaultStory = () => {
170
- const { schema, table, tableRef, model, presentation, client, handleInsertRow, handleSaveView } = useTestTableModel();
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
+ );
171
116
 
172
- if (!schema || !table) {
117
+ if (!schema || !table?.view.target) {
173
118
  return <div />;
174
119
  }
175
120
 
176
121
  return (
177
122
  <div className='grow grid grid-cols-[1fr_350px]'>
178
- <div className='grid grid-rows-[min-content_1fr] min-bs-0 overflow-hidden'>
179
- <TableToolbar classNames='border-be border-subduedSeparator' onAdd={handleInsertRow} onSave={handleSaveView} />
180
- <Table.Root>
181
- <Table.Main
182
- ref={tableRef}
183
- model={model}
184
- presentation={presentation}
185
- schema={schema}
186
- client={client}
187
- ignoreAttention
188
- />
189
- </Table.Root>
190
- </div>
191
- <div className='flex flex-col h-full border-l border-separator overflow-y-auto'>
192
- <StoryViewEditor />
193
- <SyntaxHighlighter language='json' className='w-full text-xs'>
194
- {JSON.stringify({ view: table.view?.target, schema }, null, 2)}
195
- </SyntaxHighlighter>
196
- </div>
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>
197
149
  </div>
198
150
  );
199
151
  };
200
152
 
201
- type StoryProps = { rows?: number };
153
+ type DefaultStoryProps = { rows?: number };
202
154
 
203
155
  //
204
156
  // Story definitions.
205
157
  //
206
158
 
207
- // TODO(burdon): Need super simple story.
159
+ // TODO(burdon): Need simpler story.
208
160
 
209
- const meta: Meta<StoryProps> = {
161
+ const meta = {
210
162
  title: 'ui/react-ui-table/Table',
211
163
  render: DefaultStory,
212
- parameters: { translations, controls: { disable: true } },
213
164
  decorators: [
165
+ withTheme(),
166
+ withLayout({ layout: 'fullscreen' }),
167
+ withRegistry,
214
168
  withClientProvider({
215
- types: [TableType, ViewType],
169
+ types: [View.View, Table.Table],
216
170
  createIdentity: true,
217
171
  createSpace: true,
218
- onSpaceCreated: async ({ client, space }) => {
219
- const table = space.db.add(Obj.make(TableType, {}));
220
- const schema = await initializeTable({ client, space, table, initialRow: false });
172
+ onCreateSpace: async ({ space }) => {
173
+ const [schema] = await space.db.schemaRegistry.register([Example]);
174
+ const { view, jsonSchema } = await ViewModel.makeFromDatabase({ db: space.db, typename: schema.typename });
175
+ const table = Table.make({ view, jsonSchema });
176
+ Obj.update(view, (view) => {
177
+ view.projection.fields = [
178
+ view.projection.fields.find((field) => field.path === 'name')!,
179
+ ...view.projection.fields.filter((field) => field.path !== 'name'),
180
+ ];
181
+ });
182
+
183
+ space.db.add(table);
184
+
221
185
  Array.from({ length: 10 }).map(() => {
222
186
  return space.db.add(
223
- live(schema, {
224
- name: faker.person.fullName(),
187
+ Obj.make(schema, {
188
+ name: random.lorem.sentence(),
189
+ status: random.helpers.arrayElement(['todo', 'in-progress', 'done'] as const),
190
+ description: random.lorem.paragraph(),
225
191
  }),
226
192
  );
227
193
  });
228
194
  },
229
195
  }),
230
- withLayout({ fullscreen: true }),
231
- withTheme,
232
196
  ],
233
- };
197
+ parameters: {
198
+ layout: 'fullscreen',
199
+ controls: {
200
+ disable: true,
201
+ },
202
+ translations: [...translations, ...formTranslations],
203
+ },
204
+ } satisfies Meta<typeof TableComponent>;
234
205
 
235
206
  export default meta;
236
207
 
237
- export const Default = {};
208
+ type Story = StoryObj<typeof meta>;
209
+
210
+ export const Default: Story = {};
238
211
 
239
212
  export const StaticSchema: StoryObj = {
240
213
  render: DefaultStory,
241
- parameters: { translations },
242
214
  decorators: [
243
215
  withClientProvider({
244
- types: [TableType, ViewType, Testing.Contact, Testing.Organization],
216
+ types: [View.View, Table.Table],
245
217
  createIdentity: true,
246
218
  createSpace: true,
247
- onSpaceCreated: async ({ client, space }) => {
248
- const table = space.db.add(Obj.make(TableType, {}));
249
- await initializeTable({ client, space, table, typename: Testing.Organization.typename });
219
+ onCreateSpace: async ({ space }) => {
220
+ const { view, jsonSchema } = await ViewModel.makeFromDatabase({
221
+ db: space.db,
222
+ typename: TestSchema.Person.typename,
223
+ });
224
+ const table = Table.make({ view, jsonSchema });
225
+ space.db.add(table);
250
226
 
251
- const factory = createObjectFactory(space.db, faker as any);
227
+ const factory = createObjectFactory(space.db, random as any);
252
228
  await factory([
253
- // { type: Testing.Contact, count: 10 },
254
- // { type: Testing.Organization, count: 1 },
255
- { type: ContactWithArrayOfEmails, count: 10 },
229
+ { type: TestSchema.Person, count: 10 },
230
+ // { type: TestSchema.Organization, count: 1 },
256
231
  ]);
257
232
  },
258
233
  }),
259
- withLayout({ fullscreen: true }),
260
- withTheme,
261
234
  ],
235
+ parameters: {
236
+ layout: 'fullscreen',
237
+ translations: [...translations, ...formTranslations],
238
+ },
262
239
  };
263
240
 
264
241
  const ContactWithArrayOfEmails = Schema.Struct({
265
- name: Schema.String.pipe(GeneratorAnnotation.set('person.fullName')),
242
+ name: Schema.String.pipe(Annotation.GeneratorAnnotation.set('person.fullName')),
266
243
  emails: Schema.optional(
267
244
  Schema.Array(
268
245
  Schema.Struct({
@@ -272,49 +249,53 @@ const ContactWithArrayOfEmails = Schema.Struct({
272
249
  ),
273
250
  ),
274
251
  }).pipe(
275
- EchoObject({
276
- typename: 'dxos.org/type/ContactWithArrayOfEmails',
252
+ Type.object({
253
+ typename: 'org.dxos.type.contactWithArrayOfEmails',
277
254
  version: '0.1.0',
278
255
  }),
279
256
  );
280
257
 
281
258
  export const ArrayOfObjects: StoryObj = {
282
259
  render: DefaultStory,
283
- parameters: { translations },
284
260
  decorators: [
285
261
  withClientProvider({
286
- types: [TableType, ViewType, Testing.Contact, Testing.Organization, ContactWithArrayOfEmails],
262
+ types: [View.View, Table.Table, TestSchema.Person, TestSchema.Organization, ContactWithArrayOfEmails],
287
263
  createIdentity: true,
288
264
  createSpace: true,
289
- onSpaceCreated: async ({ client, space }) => {
290
- const table = space.db.add(Obj.make(TableType, {}));
291
- await initializeTable({ client, space, table, typename: ContactWithArrayOfEmails.typename });
265
+ onCreateSpace: async ({ space }) => {
266
+ const { view, jsonSchema } = await ViewModel.makeFromDatabase({
267
+ db: space.db,
268
+ typename: ContactWithArrayOfEmails.typename,
269
+ });
270
+ const table = Table.make({ view, jsonSchema });
271
+ space.db.add(table);
292
272
 
293
- const factory = createObjectFactory(space.db, faker as any);
273
+ const factory = createObjectFactory(space.db, random as any);
294
274
  await factory([
295
- // { type: Testing.Contact, count: 10 },
296
- // { type: Testing.Organization, count: 1 },
275
+ // { type: TestSchema.Person, count: 10 },
276
+ // { type: TestSchema.Organization, count: 1 },
297
277
  { type: ContactWithArrayOfEmails, count: 10 },
298
278
  ]);
299
279
  },
300
280
  }),
301
- withLayout({ fullscreen: true }),
302
- withTheme,
303
281
  ],
282
+ parameters: {
283
+ layout: 'fullscreen',
284
+ translations,
285
+ },
304
286
  };
305
287
 
306
- export const Tags: Meta<StoryProps> = {
288
+ export const Tags: Meta<DefaultStoryProps> = {
307
289
  title: 'ui/react-ui-table/Table',
308
290
  render: DefaultStory,
309
- parameters: { translations },
310
291
  decorators: [
311
292
  withClientProvider({
312
- types: [TableType, ViewType],
293
+ types: [View.View, Table.Table],
313
294
  createIdentity: true,
314
295
  createSpace: true,
315
- onSpaceCreated: async ({ client, space }) => {
296
+ onCreateSpace: async ({ space }) => {
316
297
  // Configure schema.
317
- const typename = 'example.com/SingleSelect';
298
+ const typename = 'com.example.type.single-select';
318
299
  const selectOptions = [
319
300
  { id: 'one', title: 'One', color: 'emerald' },
320
301
  { id: 'two', title: 'Two', color: 'blue' },
@@ -328,33 +309,36 @@ export const Tags: Meta<StoryProps> = {
328
309
  const schema = getSchemaFromPropertyDefinitions(typename, [
329
310
  {
330
311
  name: 'single',
331
- format: FormatEnum.SingleSelect,
312
+ format: Format.TypeFormat.SingleSelect,
332
313
  config: { options: selectOptions },
333
314
  },
334
315
  {
335
316
  name: 'multiple',
336
- format: FormatEnum.MultiSelect,
317
+ format: Format.TypeFormat.MultiSelect,
337
318
  config: { options: selectOptions },
338
319
  },
339
320
  ]);
340
321
  const [storedSchema] = await space.db.schemaRegistry.register([schema]);
341
322
 
342
323
  // Initialize table.
343
- const table = space.db.add(Obj.make(TableType, {}));
344
- await initializeTable({ client, space, table, initialRow: false, typename });
324
+ const { view, jsonSchema } = await ViewModel.makeFromDatabase({ db: space.db, typename });
325
+ const table = Table.make({ view, jsonSchema });
326
+ space.db.add(table);
345
327
 
346
328
  // Populate.
347
329
  Array.from({ length: 10 }).map(() => {
348
330
  return space.db.add(
349
- live(storedSchema, {
350
- single: faker.helpers.arrayElement([...selectOptionIds, undefined]),
351
- multiple: faker.helpers.randomSubset(selectOptionIds),
331
+ Obj.make(storedSchema, {
332
+ single: random.helpers.arrayElement([...selectOptionIds, undefined]),
333
+ multiple: random.helpers.randomSubset(selectOptionIds),
352
334
  }),
353
335
  );
354
336
  });
355
337
  },
356
338
  }),
357
- withLayout({ fullscreen: true }),
358
- withTheme,
359
339
  ],
340
+ parameters: {
341
+ layout: 'fullscreen',
342
+ translations,
343
+ },
360
344
  };