@dxos/react-ui-table 0.8.4-main.f9ba587 → 0.8.4-main.fcc0d83b33

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 (185) 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 +1158 -2872
  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 +1158 -2872
  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 +1 -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 -1
  64. package/dist/types/src/hooks/index.d.ts.map +1 -1
  65. package/dist/types/src/hooks/useAddRow.d.ts +6 -6
  66. package/dist/types/src/hooks/useAddRow.d.ts.map +1 -1
  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 +116 -34
  78. package/dist/types/src/model/table-model.d.ts.map +1 -1
  79. package/dist/types/src/model/table-presentation.d.ts +5 -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.map +1 -1
  84. package/dist/types/src/testing/index.d.ts +2 -0
  85. package/dist/types/src/testing/index.d.ts.map +1 -0
  86. package/dist/types/src/testing/useTestTableModel.d.ts +25 -0
  87. package/dist/types/src/testing/useTestTableModel.d.ts.map +1 -0
  88. package/dist/types/src/translations.d.ts +21 -23
  89. package/dist/types/src/translations.d.ts.map +1 -1
  90. package/dist/types/src/types/Table.d.ts +26 -0
  91. package/dist/types/src/types/Table.d.ts.map +1 -0
  92. package/dist/types/src/types/index.d.ts +1 -1
  93. package/dist/types/src/types/index.d.ts.map +1 -1
  94. package/dist/types/src/util/dynamic-table.d.ts +15 -14
  95. package/dist/types/src/util/dynamic-table.d.ts.map +1 -1
  96. package/dist/types/src/util/dynamic-table.test.d.ts +2 -0
  97. package/dist/types/src/util/dynamic-table.test.d.ts.map +1 -0
  98. package/dist/types/src/util/index.d.ts +2 -1
  99. package/dist/types/src/util/index.d.ts.map +1 -1
  100. package/dist/types/src/util/query-ast.d.ts +7 -0
  101. package/dist/types/src/util/query-ast.d.ts.map +1 -0
  102. package/dist/types/src/util/schema.d.ts +1 -1
  103. package/dist/types/src/util/schema.d.ts.map +1 -1
  104. package/dist/types/src/util/signals.d.ts.map +1 -1
  105. package/dist/types/src/util/sort.d.ts +12 -0
  106. package/dist/types/src/util/sort.d.ts.map +1 -0
  107. package/dist/types/src/util/table-buttons.d.ts +20 -20
  108. package/dist/types/src/util/table-buttons.d.ts.map +1 -1
  109. package/dist/types/src/util/table-controls.d.ts +4 -4
  110. package/dist/types/src/util/table-controls.d.ts.map +1 -1
  111. package/dist/types/src/util/tag.d.ts.map +1 -1
  112. package/dist/types/tsconfig.tsbuildinfo +1 -1
  113. package/package.json +80 -69
  114. package/src/components/Table/ColumnActionsMenu.tsx +18 -13
  115. package/src/components/Table/ColumnSettings.tsx +18 -15
  116. package/src/components/Table/DynamicTable.stories.tsx +40 -36
  117. package/src/components/Table/DynamicTable.tsx +38 -34
  118. package/src/components/Table/Relations.stories.tsx +281 -0
  119. package/src/components/Table/RowActionsMenu.tsx +28 -18
  120. package/src/components/Table/Table.stories.tsx +198 -220
  121. package/src/components/Table/Table.tsx +47 -376
  122. package/src/components/Table/TableContent.tsx +421 -0
  123. package/src/components/Table/TableToolbar.tsx +111 -0
  124. package/src/components/TableCellEditor/CellValidationMessage.tsx +6 -6
  125. package/src/components/TableCellEditor/FormCellEditor.tsx +153 -49
  126. package/src/components/TableCellEditor/TableCellEditor.stories.tsx +38 -77
  127. package/src/components/TableCellEditor/TableCellEditor.tsx +104 -233
  128. package/src/components/TableCellEditor/index.ts +1 -0
  129. package/src/components/index.ts +0 -1
  130. package/src/components/testing.ts +46 -37
  131. package/src/hooks/index.ts +2 -1
  132. package/src/hooks/useAddRow.ts +14 -14
  133. package/src/hooks/useProjectionModel.ts +39 -0
  134. package/src/hooks/useTableModel.ts +41 -35
  135. package/src/index.ts +0 -5
  136. package/src/model/modal-controller.ts +24 -41
  137. package/src/model/selection-model.ts +75 -41
  138. package/src/model/table-model.test.ts +91 -56
  139. package/src/model/table-model.ts +468 -187
  140. package/src/model/table-presentation.test.ts +77 -60
  141. package/src/model/table-presentation.ts +112 -66
  142. package/src/playwright/TableManager.ts +13 -6
  143. package/src/playwright/playwright.config.ts +1 -1
  144. package/src/playwright/smoke.spec.ts +180 -43
  145. package/src/testing/index.ts +5 -0
  146. package/src/testing/useTestTableModel.ts +133 -0
  147. package/src/translations.ts +20 -22
  148. package/src/types/Table.ts +79 -0
  149. package/src/types/index.ts +2 -2
  150. package/src/util/dynamic-table.test.ts +77 -0
  151. package/src/util/dynamic-table.ts +51 -36
  152. package/src/util/index.ts +2 -1
  153. package/src/util/query-ast.ts +22 -0
  154. package/src/util/schema.ts +4 -4
  155. package/src/util/sort.ts +90 -0
  156. package/src/util/table-buttons.ts +4 -3
  157. package/src/util/table-controls.ts +6 -3
  158. package/dist/lib/browser/chunk-Q5QQXJUO.mjs +0 -27
  159. package/dist/lib/browser/chunk-Q5QQXJUO.mjs.map +0 -7
  160. package/dist/lib/node-esm/chunk-ZNOU6LHG.mjs +0 -29
  161. package/dist/lib/node-esm/chunk-ZNOU6LHG.mjs.map +0 -7
  162. package/dist/types/src/components/Table/CreateRefPanel.d.ts +0 -9
  163. package/dist/types/src/components/Table/CreateRefPanel.d.ts.map +0 -1
  164. package/dist/types/src/components/Table/relations.stories.d.ts +0 -9
  165. package/dist/types/src/components/Table/relations.stories.d.ts.map +0 -1
  166. package/dist/types/src/components/TableCellEditor/extension.d.ts +0 -13
  167. package/dist/types/src/components/TableCellEditor/extension.d.ts.map +0 -1
  168. package/dist/types/src/components/TableToolbar/TableToolbar.d.ts +0 -21
  169. package/dist/types/src/components/TableToolbar/TableToolbar.d.ts.map +0 -1
  170. package/dist/types/src/components/TableToolbar/index.d.ts +0 -2
  171. package/dist/types/src/components/TableToolbar/index.d.ts.map +0 -1
  172. package/dist/types/src/model/table-sorting.d.ts +0 -53
  173. package/dist/types/src/model/table-sorting.d.ts.map +0 -1
  174. package/dist/types/src/types/table.d.ts +0 -56
  175. package/dist/types/src/types/table.d.ts.map +0 -1
  176. package/dist/types/src/util/table.d.ts +0 -14
  177. package/dist/types/src/util/table.d.ts.map +0 -1
  178. package/src/components/Table/CreateRefPanel.tsx +0 -84
  179. package/src/components/Table/relations.stories.tsx +0 -123
  180. package/src/components/TableCellEditor/extension.ts +0 -61
  181. package/src/components/TableToolbar/TableToolbar.tsx +0 -102
  182. package/src/components/TableToolbar/index.ts +0 -5
  183. package/src/model/table-sorting.ts +0 -216
  184. package/src/types/table.ts +0 -27
  185. 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-vite';
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, useAddRow } 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 addRow = useAddRow({ space, schema });
76
-
77
- const handleDeleteRows = useCallback(
78
- (_: number, objects: any[]) => {
79
- for (const object of objects) {
80
- space?.db.remove(object);
81
- }
82
- },
83
- [space],
84
- );
85
-
86
- const handleDeleteColumn = useCallback(
87
- (fieldId: string) => {
88
- if (projection) {
89
- projection.deleteFieldProjection(fieldId);
90
- }
91
- },
92
- [projection],
93
- );
94
-
95
- const model = useTableModel({
96
- table,
97
- projection,
98
- features,
99
- rows: filteredObjects,
100
- onInsertRow: addRow,
101
- onDeleteRows: handleDeleteRows,
102
- onDeleteColumn: handleDeleteColumn,
103
- onCellUpdate: handleCellUpdate,
104
- onRowOrderChange: handleRowOrderChange,
105
- });
106
-
107
- const handleInsertRow = useCallback(() => {
108
- model?.insertRow();
109
- }, [model]);
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,108 +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();
171
107
 
172
- if (!schema || !table) {
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) {
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: {
213
- translations,
214
- layout: 'fullscreen',
215
- controls: {
216
- disable: true,
217
- },
218
- },
219
164
  decorators: [
220
- withTheme,
221
- withLayout({ fullscreen: true }),
165
+ withTheme(),
166
+ withLayout({ layout: 'fullscreen' }),
167
+ withRegistry,
222
168
  withClientProvider({
223
- types: [TableType, ViewType],
169
+ types: [View.View, Table.Table],
224
170
  createIdentity: true,
225
171
  createSpace: true,
226
- onSpaceCreated: async ({ client, space }) => {
227
- const table = space.db.add(Obj.make(TableType, {}));
228
- 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
+
229
185
  Array.from({ length: 10 }).map(() => {
230
186
  return space.db.add(
231
- live(schema, {
232
- 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(),
233
191
  }),
234
192
  );
235
193
  });
236
194
  },
237
195
  }),
238
196
  ],
239
- };
197
+ parameters: {
198
+ layout: 'fullscreen',
199
+ controls: {
200
+ disable: true,
201
+ },
202
+ translations: [...translations, ...formTranslations],
203
+ },
204
+ } satisfies Meta<typeof TableComponent>;
240
205
 
241
206
  export default meta;
242
207
 
243
- export const Default = {};
208
+ type Story = StoryObj<typeof meta>;
209
+
210
+ export const Default: Story = {};
244
211
 
245
212
  export const StaticSchema: StoryObj = {
246
213
  render: DefaultStory,
247
- parameters: { translations },
248
214
  decorators: [
249
215
  withClientProvider({
250
- types: [TableType, ViewType, Testing.Contact, Testing.Organization],
216
+ types: [View.View, Table.Table],
251
217
  createIdentity: true,
252
218
  createSpace: true,
253
- onSpaceCreated: async ({ client, space }) => {
254
- const table = space.db.add(Obj.make(TableType, {}));
255
- 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);
256
226
 
257
- const factory = createObjectFactory(space.db, faker as any);
227
+ const factory = createObjectFactory(space.db, random as any);
258
228
  await factory([
259
- // { type: Testing.Contact, count: 10 },
260
- // { type: Testing.Organization, count: 1 },
261
- { type: ContactWithArrayOfEmails, count: 10 },
229
+ { type: TestSchema.Person, count: 10 },
230
+ // { type: TestSchema.Organization, count: 1 },
262
231
  ]);
263
232
  },
264
233
  }),
265
- withLayout({ fullscreen: true }),
266
- withTheme,
267
234
  ],
235
+ parameters: {
236
+ layout: 'fullscreen',
237
+ translations: [...translations, ...formTranslations],
238
+ },
268
239
  };
269
240
 
270
241
  const ContactWithArrayOfEmails = Schema.Struct({
271
- name: Schema.String.pipe(GeneratorAnnotation.set('person.fullName')),
242
+ name: Schema.String.pipe(Annotation.GeneratorAnnotation.set('person.fullName')),
272
243
  emails: Schema.optional(
273
244
  Schema.Array(
274
245
  Schema.Struct({
@@ -278,49 +249,53 @@ const ContactWithArrayOfEmails = Schema.Struct({
278
249
  ),
279
250
  ),
280
251
  }).pipe(
281
- EchoObject({
282
- typename: 'dxos.org/type/ContactWithArrayOfEmails',
252
+ Type.object({
253
+ typename: 'org.dxos.type.contactWithArrayOfEmails',
283
254
  version: '0.1.0',
284
255
  }),
285
256
  );
286
257
 
287
258
  export const ArrayOfObjects: StoryObj = {
288
259
  render: DefaultStory,
289
- parameters: { translations },
290
260
  decorators: [
291
261
  withClientProvider({
292
- types: [TableType, ViewType, Testing.Contact, Testing.Organization, ContactWithArrayOfEmails],
262
+ types: [View.View, Table.Table, TestSchema.Person, TestSchema.Organization, ContactWithArrayOfEmails],
293
263
  createIdentity: true,
294
264
  createSpace: true,
295
- onSpaceCreated: async ({ client, space }) => {
296
- const table = space.db.add(Obj.make(TableType, {}));
297
- 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);
298
272
 
299
- const factory = createObjectFactory(space.db, faker as any);
273
+ const factory = createObjectFactory(space.db, random as any);
300
274
  await factory([
301
- // { type: Testing.Contact, count: 10 },
302
- // { type: Testing.Organization, count: 1 },
275
+ // { type: TestSchema.Person, count: 10 },
276
+ // { type: TestSchema.Organization, count: 1 },
303
277
  { type: ContactWithArrayOfEmails, count: 10 },
304
278
  ]);
305
279
  },
306
280
  }),
307
- withLayout({ fullscreen: true }),
308
- withTheme,
309
281
  ],
282
+ parameters: {
283
+ layout: 'fullscreen',
284
+ translations,
285
+ },
310
286
  };
311
287
 
312
- export const Tags: Meta<StoryProps> = {
288
+ export const Tags: Meta<DefaultStoryProps> = {
313
289
  title: 'ui/react-ui-table/Table',
314
290
  render: DefaultStory,
315
- parameters: { translations },
316
291
  decorators: [
317
292
  withClientProvider({
318
- types: [TableType, ViewType],
293
+ types: [View.View, Table.Table],
319
294
  createIdentity: true,
320
295
  createSpace: true,
321
- onSpaceCreated: async ({ client, space }) => {
296
+ onCreateSpace: async ({ space }) => {
322
297
  // Configure schema.
323
- const typename = 'example.com/SingleSelect';
298
+ const typename = 'com.example.type.single-select';
324
299
  const selectOptions = [
325
300
  { id: 'one', title: 'One', color: 'emerald' },
326
301
  { id: 'two', title: 'Two', color: 'blue' },
@@ -334,33 +309,36 @@ export const Tags: Meta<StoryProps> = {
334
309
  const schema = getSchemaFromPropertyDefinitions(typename, [
335
310
  {
336
311
  name: 'single',
337
- format: FormatEnum.SingleSelect,
312
+ format: Format.TypeFormat.SingleSelect,
338
313
  config: { options: selectOptions },
339
314
  },
340
315
  {
341
316
  name: 'multiple',
342
- format: FormatEnum.MultiSelect,
317
+ format: Format.TypeFormat.MultiSelect,
343
318
  config: { options: selectOptions },
344
319
  },
345
320
  ]);
346
321
  const [storedSchema] = await space.db.schemaRegistry.register([schema]);
347
322
 
348
323
  // Initialize table.
349
- const table = space.db.add(Obj.make(TableType, {}));
350
- 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);
351
327
 
352
328
  // Populate.
353
329
  Array.from({ length: 10 }).map(() => {
354
330
  return space.db.add(
355
- live(storedSchema, {
356
- single: faker.helpers.arrayElement([...selectOptionIds, undefined]),
357
- multiple: faker.helpers.randomSubset(selectOptionIds),
331
+ Obj.make(storedSchema, {
332
+ single: random.helpers.arrayElement([...selectOptionIds, undefined]),
333
+ multiple: random.helpers.randomSubset(selectOptionIds),
358
334
  }),
359
335
  );
360
336
  });
361
337
  },
362
338
  }),
363
- withLayout({ fullscreen: true }),
364
- withTheme,
365
339
  ],
340
+ parameters: {
341
+ layout: 'fullscreen',
342
+ translations,
343
+ },
366
344
  };