@dxos/react-ui-table 0.8.3-staging.0fa589b → 0.8.4-main.1da679c

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 (148) hide show
  1. package/dist/lib/browser/chunk-63UUF4IG.mjs +66 -0
  2. package/dist/lib/browser/chunk-63UUF4IG.mjs.map +7 -0
  3. package/dist/lib/browser/chunk-BBXDTWCX.mjs +1822 -0
  4. package/dist/lib/browser/chunk-BBXDTWCX.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +816 -2152
  6. package/dist/lib/browser/index.mjs.map +4 -4
  7. package/dist/lib/browser/meta.json +1 -1
  8. package/dist/lib/browser/testing/index.mjs +124 -0
  9. package/dist/lib/browser/testing/index.mjs.map +7 -0
  10. package/dist/lib/browser/types/index.mjs +3 -5
  11. package/dist/lib/node-esm/chunk-K734DJB7.mjs +67 -0
  12. package/dist/lib/node-esm/chunk-K734DJB7.mjs.map +7 -0
  13. package/dist/lib/node-esm/chunk-RNQDU7IQ.mjs +1823 -0
  14. package/dist/lib/node-esm/chunk-RNQDU7IQ.mjs.map +7 -0
  15. package/dist/lib/node-esm/index.mjs +816 -2152
  16. package/dist/lib/node-esm/index.mjs.map +4 -4
  17. package/dist/lib/node-esm/meta.json +1 -1
  18. package/dist/lib/node-esm/testing/index.mjs +125 -0
  19. package/dist/lib/node-esm/testing/index.mjs.map +7 -0
  20. package/dist/lib/node-esm/types/index.mjs +3 -5
  21. package/dist/types/src/components/Table/ColumnActionsMenu.d.ts +1 -1
  22. package/dist/types/src/components/Table/ColumnActionsMenu.d.ts.map +1 -1
  23. package/dist/types/src/components/Table/ColumnSettings.d.ts +4 -2
  24. package/dist/types/src/components/Table/ColumnSettings.d.ts.map +1 -1
  25. package/dist/types/src/components/Table/CreateRefPanel.d.ts +1 -1
  26. package/dist/types/src/components/Table/CreateRefPanel.d.ts.map +1 -1
  27. package/dist/types/src/components/Table/DynamicTable.d.ts +1 -1
  28. package/dist/types/src/components/Table/DynamicTable.d.ts.map +1 -1
  29. package/dist/types/src/components/Table/DynamicTable.stories.d.ts +50 -2
  30. package/dist/types/src/components/Table/DynamicTable.stories.d.ts.map +1 -1
  31. package/dist/types/src/components/Table/Relations.stories.d.ts +44 -0
  32. package/dist/types/src/components/Table/Relations.stories.d.ts.map +1 -0
  33. package/dist/types/src/components/Table/RowActionsMenu.d.ts +1 -1
  34. package/dist/types/src/components/Table/RowActionsMenu.d.ts.map +1 -1
  35. package/dist/types/src/components/Table/Table.d.ts +3 -2
  36. package/dist/types/src/components/Table/Table.d.ts.map +1 -1
  37. package/dist/types/src/components/Table/Table.stories.d.ts +42 -3
  38. package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
  39. package/dist/types/src/components/TableCellEditor/CellValidationMessage.d.ts +2 -1
  40. package/dist/types/src/components/TableCellEditor/CellValidationMessage.d.ts.map +1 -1
  41. package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts +8 -3
  42. package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts.map +1 -1
  43. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +9 -15
  44. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
  45. package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts +39 -3
  46. package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts.map +1 -1
  47. package/dist/types/src/components/TableToolbar/TableToolbar.d.ts.map +1 -1
  48. package/dist/types/src/components/testing.d.ts +3 -40
  49. package/dist/types/src/components/testing.d.ts.map +1 -1
  50. package/dist/types/src/hooks/index.d.ts +1 -0
  51. package/dist/types/src/hooks/index.d.ts.map +1 -1
  52. package/dist/types/src/hooks/useAddRow.d.ts +14 -0
  53. package/dist/types/src/hooks/useAddRow.d.ts.map +1 -0
  54. package/dist/types/src/hooks/useTableModel.d.ts +8 -7
  55. package/dist/types/src/hooks/useTableModel.d.ts.map +1 -1
  56. package/dist/types/src/index.d.ts +1 -2
  57. package/dist/types/src/index.d.ts.map +1 -1
  58. package/dist/types/src/model/modal-controller.d.ts.map +1 -1
  59. package/dist/types/src/model/selection-model.d.ts +2 -1
  60. package/dist/types/src/model/selection-model.d.ts.map +1 -1
  61. package/dist/types/src/model/table-model.d.ts +59 -21
  62. package/dist/types/src/model/table-model.d.ts.map +1 -1
  63. package/dist/types/src/model/table-presentation.d.ts +10 -1
  64. package/dist/types/src/model/table-presentation.d.ts.map +1 -1
  65. package/dist/types/src/model/table-sorting.d.ts +3 -4
  66. package/dist/types/src/model/table-sorting.d.ts.map +1 -1
  67. package/dist/types/src/playwright/playwright.config.d.ts +3 -0
  68. package/dist/types/src/playwright/playwright.config.d.ts.map +1 -0
  69. package/dist/types/src/testing/index.d.ts +2 -0
  70. package/dist/types/src/testing/index.d.ts.map +1 -0
  71. package/dist/types/src/testing/useTestTableModel.d.ts +22 -0
  72. package/dist/types/src/testing/useTestTableModel.d.ts.map +1 -0
  73. package/dist/types/src/translations.d.ts +5 -6
  74. package/dist/types/src/translations.d.ts.map +1 -1
  75. package/dist/types/src/types/index.d.ts +1 -1
  76. package/dist/types/src/types/index.d.ts.map +1 -1
  77. package/dist/types/src/types/schema.d.ts +28 -0
  78. package/dist/types/src/types/schema.d.ts.map +1 -0
  79. package/dist/types/src/util/dynamic-table.d.ts +4 -5
  80. package/dist/types/src/util/dynamic-table.d.ts.map +1 -1
  81. package/dist/types/src/util/index.d.ts +0 -1
  82. package/dist/types/src/util/index.d.ts.map +1 -1
  83. package/dist/types/src/util/table-buttons.d.ts +15 -1
  84. package/dist/types/src/util/table-buttons.d.ts.map +1 -1
  85. package/dist/types/src/util/table-controls.d.ts.map +1 -1
  86. package/dist/types/tsconfig.tsbuildinfo +1 -1
  87. package/package.json +57 -44
  88. package/src/components/Table/ColumnActionsMenu.tsx +1 -1
  89. package/src/components/Table/ColumnSettings.tsx +15 -11
  90. package/src/components/Table/CreateRefPanel.tsx +30 -11
  91. package/src/components/Table/DynamicTable.stories.tsx +8 -5
  92. package/src/components/Table/DynamicTable.tsx +17 -10
  93. package/src/components/Table/{relations.stories.tsx → Relations.stories.tsx} +56 -47
  94. package/src/components/Table/RowActionsMenu.tsx +3 -3
  95. package/src/components/Table/Table.stories.tsx +126 -159
  96. package/src/components/Table/Table.tsx +169 -123
  97. package/src/components/TableCellEditor/CellValidationMessage.tsx +7 -2
  98. package/src/components/TableCellEditor/FormCellEditor.tsx +158 -48
  99. package/src/components/TableCellEditor/TableCellEditor.stories.tsx +31 -47
  100. package/src/components/TableCellEditor/TableCellEditor.tsx +106 -111
  101. package/src/components/TableToolbar/TableToolbar.tsx +2 -2
  102. package/src/components/testing.ts +7 -24
  103. package/src/hooks/index.ts +1 -0
  104. package/src/hooks/useAddRow.ts +38 -0
  105. package/src/hooks/useTableModel.ts +21 -17
  106. package/src/index.ts +1 -2
  107. package/src/model/modal-controller.ts +1 -1
  108. package/src/model/selection-model.ts +6 -3
  109. package/src/model/table-model.test.ts +12 -9
  110. package/src/model/table-model.ts +288 -88
  111. package/src/model/table-presentation.test.ts +12 -8
  112. package/src/model/table-presentation.ts +263 -138
  113. package/src/model/table-sorting.ts +22 -13
  114. package/src/playwright/playwright.config.ts +17 -0
  115. package/src/playwright/smoke.spec.ts +137 -44
  116. package/src/testing/index.ts +5 -0
  117. package/src/testing/useTestTableModel.ts +124 -0
  118. package/src/translations.ts +7 -5
  119. package/src/types/index.ts +2 -2
  120. package/src/types/schema.ts +73 -0
  121. package/src/util/dynamic-table.ts +24 -21
  122. package/src/util/index.ts +0 -1
  123. package/src/util/schema.ts +1 -1
  124. package/src/util/table-buttons.ts +28 -4
  125. package/src/util/table-controls.ts +4 -1
  126. package/dist/lib/browser/chunk-TL7CKQQV.mjs +0 -27
  127. package/dist/lib/browser/chunk-TL7CKQQV.mjs.map +0 -7
  128. package/dist/lib/node/chunk-O2VPBNS5.cjs +0 -50
  129. package/dist/lib/node/chunk-O2VPBNS5.cjs.map +0 -7
  130. package/dist/lib/node/index.cjs +0 -2739
  131. package/dist/lib/node/index.cjs.map +0 -7
  132. package/dist/lib/node/meta.json +0 -1
  133. package/dist/lib/node/types/index.cjs +0 -31
  134. package/dist/lib/node/types/index.cjs.map +0 -7
  135. package/dist/lib/node-esm/chunk-GBT6GD4G.mjs +0 -29
  136. package/dist/lib/node-esm/chunk-GBT6GD4G.mjs.map +0 -7
  137. package/dist/types/src/components/Table/relations.stories.d.ts +0 -9
  138. package/dist/types/src/components/Table/relations.stories.d.ts.map +0 -1
  139. package/dist/types/src/components/TableCellEditor/extension.d.ts +0 -13
  140. package/dist/types/src/components/TableCellEditor/extension.d.ts.map +0 -1
  141. package/dist/types/src/types/table.d.ts +0 -56
  142. package/dist/types/src/types/table.d.ts.map +0 -1
  143. package/dist/types/src/util/table.d.ts +0 -14
  144. package/dist/types/src/util/table.d.ts.map +0 -1
  145. package/src/components/TableCellEditor/extension.ts +0 -61
  146. package/src/playwright/playwright.config.cts +0 -18
  147. package/src/types/table.ts +0 -27
  148. package/src/util/table.ts +0 -127
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/react-ui-table",
3
- "version": "0.8.3-staging.0fa589b",
3
+ "version": "0.8.4-main.1da679c",
4
4
  "description": "A table component.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -10,16 +10,25 @@
10
10
  "type": "module",
11
11
  "exports": {
12
12
  "./deprecated": {
13
+ "source": "./src/deprecated/index.ts",
13
14
  "types": "./dist/types/src/deprecated/index.d.ts",
14
15
  "browser": "./dist/lib/browser/deprecated/index.mjs",
15
16
  "node": "./dist/lib/node-esm/deprecated/index.mjs"
16
17
  },
17
18
  ".": {
19
+ "source": "./src/index.ts",
18
20
  "types": "./dist/types/src/index.d.ts",
19
21
  "browser": "./dist/lib/browser/index.mjs",
20
22
  "node": "./dist/lib/node-esm/index.mjs"
21
23
  },
24
+ "./testing": {
25
+ "source": "./src/testing/index.ts",
26
+ "types": "./dist/types/src/testing/index.d.ts",
27
+ "browser": "./dist/lib/browser/testing/index.mjs",
28
+ "node": "./dist/lib/node-esm/testing/index.mjs"
29
+ },
22
30
  "./types": {
31
+ "source": "./src/types/index.ts",
23
32
  "types": "./dist/types/src/types/index.d.ts",
24
33
  "browser": "./dist/lib/browser/types/index.mjs",
25
34
  "node": "./dist/lib/node-esm/types/index.mjs"
@@ -31,6 +40,9 @@
31
40
  "deprecated": [
32
41
  "dist/types/src/deprecated/index.d.ts"
33
42
  ],
43
+ "testing": [
44
+ "dist/types/src/testing/index.d.ts"
45
+ ],
34
46
  "types": [
35
47
  "dist/types/src/types/index.d.ts"
36
48
  ]
@@ -41,9 +53,9 @@
41
53
  "src"
42
54
  ],
43
55
  "dependencies": {
44
- "@codemirror/autocomplete": "^6.18.1",
45
- "@codemirror/state": "^6.4.1",
46
- "@codemirror/view": "^6.34.1",
56
+ "@codemirror/autocomplete": "^6.18.7",
57
+ "@codemirror/state": "^6.5.2",
58
+ "@codemirror/view": "^6.38.2",
47
59
  "@fluentui/react-tabster": "^9.24.2",
48
60
  "@preact-signals/safe-react": "^0.9.0",
49
61
  "@preact/signals-core": "^1.9.0",
@@ -53,60 +65,61 @@
53
65
  "@radix-ui/react-use-controllable-state": "1.1.0",
54
66
  "date-fns": "^3.3.1",
55
67
  "lodash.orderby": "^4.6.0",
56
- "@dxos/context": "0.8.3-staging.0fa589b",
57
- "@dxos/debug": "0.8.3-staging.0fa589b",
58
- "@dxos/echo-schema": "0.8.3-staging.0fa589b",
59
- "@dxos/effect": "0.8.3-staging.0fa589b",
60
- "@dxos/echo": "0.8.3-staging.0fa589b",
61
- "@dxos/invariant": "0.8.3-staging.0fa589b",
62
- "@dxos/lit-grid": "0.8.3-staging.0fa589b",
63
- "@dxos/live-object": "0.8.3-staging.0fa589b",
64
- "@dxos/keys": "0.8.3-staging.0fa589b",
65
- "@dxos/log": "0.8.3-staging.0fa589b",
66
- "@dxos/plugin-search": "0.8.3-staging.0fa589b",
67
- "@dxos/plugin-space": "0.8.3-staging.0fa589b",
68
- "@dxos/react-client": "0.8.3-staging.0fa589b",
69
- "@dxos/react-ui-attention": "0.8.3-staging.0fa589b",
70
- "@dxos/react-ui-editor": "0.8.3-staging.0fa589b",
71
- "@dxos/react-ui-form": "0.8.3-staging.0fa589b",
72
- "@dxos/react-ui-menu": "0.8.3-staging.0fa589b",
73
- "@dxos/react-ui-grid": "0.8.3-staging.0fa589b",
74
- "@dxos/react-ui-searchlist": "0.8.3-staging.0fa589b",
75
- "@dxos/react-ui-stack": "0.8.3-staging.0fa589b",
76
- "@dxos/react-ui-syntax-highlighter": "0.8.3-staging.0fa589b",
77
- "@dxos/react-ui-types": "0.8.3-staging.0fa589b",
78
- "@dxos/react-ui-tag-picker": "0.8.3-staging.0fa589b",
79
- "@dxos/schema": "0.8.3-staging.0fa589b",
80
- "@dxos/util": "0.8.3-staging.0fa589b"
68
+ "@dxos/async": "0.8.4-main.1da679c",
69
+ "@dxos/context": "0.8.4-main.1da679c",
70
+ "@dxos/debug": "0.8.4-main.1da679c",
71
+ "@dxos/echo": "0.8.4-main.1da679c",
72
+ "@dxos/echo-db": "0.8.4-main.1da679c",
73
+ "@dxos/effect": "0.8.4-main.1da679c",
74
+ "@dxos/keys": "0.8.4-main.1da679c",
75
+ "@dxos/echo-schema": "0.8.4-main.1da679c",
76
+ "@dxos/lit-grid": "0.8.4-main.1da679c",
77
+ "@dxos/invariant": "0.8.4-main.1da679c",
78
+ "@dxos/live-object": "0.8.4-main.1da679c",
79
+ "@dxos/log": "0.8.4-main.1da679c",
80
+ "@dxos/random": "0.8.4-main.1da679c",
81
+ "@dxos/react-client": "0.8.4-main.1da679c",
82
+ "@dxos/react-ui-editor": "0.8.4-main.1da679c",
83
+ "@dxos/react-ui-attention": "0.8.4-main.1da679c",
84
+ "@dxos/react-ui-form": "0.8.4-main.1da679c",
85
+ "@dxos/plugin-search": "0.8.4-main.1da679c",
86
+ "@dxos/react-ui-grid": "0.8.4-main.1da679c",
87
+ "@dxos/react-ui-menu": "0.8.4-main.1da679c",
88
+ "@dxos/react-ui-searchlist": "0.8.4-main.1da679c",
89
+ "@dxos/react-ui-stack": "0.8.4-main.1da679c",
90
+ "@dxos/react-ui-syntax-highlighter": "0.8.4-main.1da679c",
91
+ "@dxos/react-ui-tag-picker": "0.8.4-main.1da679c",
92
+ "@dxos/schema": "0.8.4-main.1da679c",
93
+ "@dxos/util": "0.8.4-main.1da679c",
94
+ "@dxos/react-ui-types": "0.8.4-main.1da679c"
81
95
  },
82
96
  "devDependencies": {
83
- "@effect-rx/rx-react": "^0.34.1",
84
- "@effect/platform": "0.80.12",
85
- "@phosphor-icons/react": "^2.1.5",
97
+ "@effect-rx/rx-react": "0.38.0",
98
+ "@effect/platform": "0.90.2",
86
99
  "@types/lodash.orderby": "^4.6.9",
87
100
  "@types/react": "~18.2.0",
88
101
  "@types/react-dom": "~18.2.0",
89
- "effect": "3.14.21",
102
+ "effect": "3.17.7",
90
103
  "fast-check": "^3.19.0",
91
104
  "react": "~18.2.0",
92
105
  "react-dom": "~18.2.0",
93
- "vite": "5.4.7",
94
- "@dxos/echo-signals": "0.8.3-staging.0fa589b",
95
- "@dxos/random": "0.8.3-staging.0fa589b",
96
- "@dxos/react-ui": "0.8.3-staging.0fa589b",
97
- "@dxos/react-ui-theme": "0.8.3-staging.0fa589b",
98
- "@dxos/storybook-utils": "0.8.3-staging.0fa589b",
99
- "@dxos/test-utils": "0.8.3-staging.0fa589b"
106
+ "vite": "7.1.1",
107
+ "@dxos/echo-signals": "0.8.4-main.1da679c",
108
+ "@dxos/plugin-search": "0.8.4-main.1da679c",
109
+ "@dxos/react-ui": "0.8.4-main.1da679c",
110
+ "@dxos/random": "0.8.4-main.1da679c",
111
+ "@dxos/react-ui-theme": "0.8.4-main.1da679c",
112
+ "@dxos/storybook-utils": "0.8.4-main.1da679c",
113
+ "@dxos/test-utils": "0.8.4-main.1da679c"
100
114
  },
101
115
  "peerDependencies": {
102
116
  "@effect-rx/rx-react": "^0.34.1",
103
- "@effect/platform": "0.80.12",
104
- "@phosphor-icons/react": "^2.1.5",
117
+ "@effect/platform": "^0.80.12",
105
118
  "effect": "^3.13.3",
106
119
  "react": "~18.2.0",
107
120
  "react-dom": "~18.2.0",
108
- "@dxos/react-ui": "0.8.3-staging.0fa589b",
109
- "@dxos/react-ui-theme": "0.8.3-staging.0fa589b"
121
+ "@dxos/react-ui": "0.8.4-main.1da679c",
122
+ "@dxos/react-ui-theme": "0.8.4-main.1da679c"
110
123
  },
111
124
  "publishConfig": {
112
125
  "access": "public"
@@ -6,7 +6,7 @@ import React from 'react';
6
6
 
7
7
  import { DropdownMenu, useTranslation } from '@dxos/react-ui';
8
8
 
9
- import { type TableModel, type ModalController } from '../../model';
9
+ import { type ModalController, type TableModel } from '../../model';
10
10
  import { translationKey } from '../../translations';
11
11
 
12
12
  type ColumnActionsMenuProps = { model: TableModel; modals: ModalController };
@@ -4,20 +4,25 @@
4
4
 
5
5
  import React, { useCallback, useEffect, useMemo, useState } from 'react';
6
6
 
7
+ // TODO(burdon): Remove dependency on echo-db.
8
+ import { type SchemaRegistry } from '@dxos/echo-db';
7
9
  import { Popover } from '@dxos/react-ui';
8
10
  import { FieldEditor } from '@dxos/react-ui-form';
9
11
  import { type FieldType } from '@dxos/schema';
10
12
 
11
- import { type TableModel, type ModalController } from '../../model';
13
+ import { type ModalController, type TableModel } from '../../model';
12
14
 
13
- type ColumnSettingsProps = { model?: TableModel; modals: ModalController; onNewColumn: () => void };
15
+ type ColumnSettingsProps = {
16
+ registry?: SchemaRegistry;
17
+ model?: TableModel;
18
+ modals: ModalController;
19
+ onNewColumn: () => void;
20
+ };
14
21
 
15
- export const ColumnSettings = ({ model, modals, onNewColumn }: ColumnSettingsProps) => {
22
+ export const ColumnSettings = ({ registry, model, modals, onNewColumn }: ColumnSettingsProps) => {
16
23
  const [newField, setNewField] = useState<FieldType>();
17
24
  const state = modals.state.value;
18
25
 
19
- const space = model?.space;
20
-
21
26
  useEffect(() => {
22
27
  if (state?.type === 'columnSettings' && state.mode.type === 'create' && model?.projection) {
23
28
  setNewField(model.projection.createFieldProjection());
@@ -33,11 +38,11 @@ export const ColumnSettings = ({ model, modals, onNewColumn }: ColumnSettingsPro
33
38
  if (state?.type === 'columnSettings') {
34
39
  const { mode } = state;
35
40
  if (mode.type === 'edit') {
36
- return model?.view?.fields.find((f) => f.id === mode.fieldId);
41
+ return model?.projection?.fields.find((f) => f.id === mode.fieldId);
37
42
  }
38
43
  }
39
44
  return undefined;
40
- }, [model?.view?.fields, state]);
45
+ }, [model?.projection?.fields, state]);
41
46
 
42
47
  const field = existingField ?? newField;
43
48
 
@@ -47,11 +52,11 @@ export const ColumnSettings = ({ model, modals, onNewColumn }: ColumnSettingsPro
47
52
 
48
53
  const handleCancel = useCallback(() => {
49
54
  if (state?.type === 'columnSettings' && state.mode.type === 'create' && newField) {
50
- model?.projection?.deleteFieldProjection(newField.id);
55
+ model?.projection.deleteFieldProjection(newField.id);
51
56
  }
52
57
  }, [model?.projection, state, newField]);
53
58
 
54
- if (!model?.view || !model.projection || !field) {
59
+ if (!model?.projection || !field) {
55
60
  return null;
56
61
  }
57
62
 
@@ -62,10 +67,9 @@ export const ColumnSettings = ({ model, modals, onNewColumn }: ColumnSettingsPro
62
67
  <Popover.Content classNames='md:is-64'>
63
68
  <Popover.Viewport>
64
69
  <FieldEditor
65
- view={model.view!}
66
70
  projection={model.projection}
67
71
  field={field}
68
- registry={space?.db.schemaRegistry}
72
+ registry={registry}
69
73
  onSave={handleSave}
70
74
  onCancel={handleCancel}
71
75
  />
@@ -5,47 +5,66 @@
5
5
  import { Schema } from 'effect';
6
6
  import React, { useCallback, useMemo } from 'react';
7
7
 
8
- import { live } from '@dxos/react-client/echo';
8
+ import { Type } from '@dxos/echo';
9
+ import { live } from '@dxos/live-object';
10
+ // TODO(wittjosiah): Remove dependency on react-client.
11
+ import { useClient } from '@dxos/react-client';
12
+ import { getSpace } from '@dxos/react-client/echo';
9
13
  import { Popover } from '@dxos/react-ui';
10
14
  import { Form } from '@dxos/react-ui-form';
11
15
  import { type GridScopedProps, useGridContext } from '@dxos/react-ui-grid';
12
16
 
13
- import { type TableModel, type ModalController } from '../../model';
17
+ import { type ModalController, type TableModel } from '../../model';
14
18
 
15
19
  export type CreateRefPanelProps = { model?: TableModel; modals: ModalController };
16
20
 
17
21
  // TODO(burdon): Factor out Space dependency (to plugin?)
18
22
  export const CreateRefPanel = ({ model, modals, __gridScope }: GridScopedProps<CreateRefPanelProps>) => {
19
23
  const { id: gridId } = useGridContext('TableCellEditor', __gridScope);
20
- const space = model?.space;
24
+ const client = useClient();
25
+ const space = model && getSpace(model?.view);
21
26
  const state = modals.state.value;
22
27
 
23
- const schema = useMemo<Schema.Schema<any> | undefined>(() => {
28
+ const getSchema = useCallback(() => {
24
29
  if (!space || state?.type !== 'createRefPanel') {
25
30
  return;
26
31
  }
27
32
 
28
- const [schema] = space.db.schemaRegistry.query({ typename: state.typename }).runSync();
29
- if (schema) {
30
- const omit = Schema.omit<any, any, ['id']>('id');
31
- return omit(schema);
33
+ const staticSchema = client.graph.schemaRegistry.schemas.find(
34
+ (schema) => Type.getTypename(schema) === state.typename,
35
+ );
36
+ if (staticSchema) {
37
+ return staticSchema;
32
38
  }
39
+
40
+ const [schema] = space.db.schemaRegistry.query({ typename: state.typename }).runSync();
41
+ return schema;
33
42
  }, [space, state]);
34
43
 
44
+ const schema = useMemo<Schema.Schema<any> | undefined>(() => {
45
+ const schema = getSchema();
46
+ if (!schema) {
47
+ return;
48
+ }
49
+
50
+ const omit = Schema.omit<any, any, ['id']>('id');
51
+ return omit(schema);
52
+ }, [getSchema]);
53
+
35
54
  const handleSave = useCallback(
36
55
  (values: any) => {
37
56
  if (!model || !space || state?.type !== 'createRefPanel') {
38
57
  return;
39
58
  }
40
59
 
41
- const [schema] = space.db.schemaRegistry.query({ typename: state.typename }).runSync();
60
+ const schema = getSchema();
42
61
  if (schema) {
43
62
  const obj = space.db.add(live(schema, values));
44
63
  state.onCreate?.(obj);
45
64
  }
46
65
  void modals.close();
47
66
  },
48
- [modals, space, state],
67
+ [model, modals, space, state],
49
68
  );
50
69
 
51
70
  const handleCancel = useCallback(() => {
@@ -54,7 +73,7 @@ export const CreateRefPanel = ({ model, modals, __gridScope }: GridScopedProps<C
54
73
  }
55
74
  }, [modals]);
56
75
 
57
- if (!model?.view || !model.projection) {
76
+ if (!model?.projection) {
58
77
  return null;
59
78
  }
60
79
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  import '@dxos-theme';
6
6
 
7
- import { type StoryObj, type Meta } from '@storybook/react';
7
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
8
8
  import React, { useMemo, useState } from 'react';
9
9
 
10
10
  import { Obj } from '@dxos/echo';
@@ -17,9 +17,10 @@ import { type SchemaPropertyDefinition } from '@dxos/schema';
17
17
  import { Testing } from '@dxos/schema/testing';
18
18
  import { withLayout, withTheme } from '@dxos/storybook-utils';
19
19
 
20
- import { DynamicTable } from './DynamicTable';
21
20
  import { type TableFeatures } from '../../model';
22
- import translations from '../../translations';
21
+ import { translations } from '../../translations';
22
+
23
+ import { DynamicTable } from './DynamicTable';
23
24
 
24
25
  faker.seed(0);
25
26
 
@@ -56,15 +57,17 @@ const DynamicTableStory = () => {
56
57
  // Story definitions.
57
58
  //
58
59
 
59
- const meta: Meta = {
60
+ const meta = {
60
61
  title: 'ui/react-ui-table/DynamicTable',
61
62
  component: DynamicTable,
62
63
  parameters: { translations },
63
64
  decorators: [withLayout({ fullscreen: true }), withTheme],
64
- };
65
+ } satisfies Meta<typeof DynamicTable>;
65
66
 
66
67
  export default meta;
67
68
 
69
+ type Story = StoryObj<typeof meta>;
70
+
68
71
  export const Default: StoryObj = {
69
72
  render: DynamicTableStory,
70
73
  };
@@ -3,16 +3,17 @@
3
3
  //
4
4
 
5
5
  import { type Schema } from 'effect';
6
- import React, { useRef, useMemo, useCallback } from 'react';
6
+ import React, { useCallback, useMemo, useRef } from 'react';
7
7
 
8
8
  import { type JsonSchemaType } from '@dxos/echo-schema';
9
9
  import { type ThemedClassName, useDefaultValue } from '@dxos/react-ui';
10
10
  import { mx } from '@dxos/react-ui-theme';
11
11
 
12
- import { Table, type TableController } from './Table';
13
12
  import { useTableModel } from '../../hooks';
14
13
  import { type TableFeatures, TablePresentation, type TableRowAction } from '../../model';
15
- import { getBaseSchema, makeDynamicTable, type TablePropertyDefinition } from '../../util';
14
+ import { type TablePropertyDefinition, getBaseSchema, makeDynamicTable } from '../../util';
15
+
16
+ import { Table, type TableController } from './Table';
16
17
 
17
18
  type DynamicTableProps = ThemedClassName<{
18
19
  name?: string; // TODO(burdon): Remove?
@@ -36,18 +37,23 @@ export const DynamicTable = ({
36
37
  name = 'example.com/dynamic-table', // Rmove default or make random; this will lead to type collisions.
37
38
  rows,
38
39
  properties,
39
- jsonSchema,
40
+ jsonSchema: _jsonSchema,
40
41
  schema,
41
42
  rowActions,
42
43
  onRowClick,
43
44
  onRowAction,
44
45
  ...props
45
46
  }: DynamicTableProps) => {
46
- const { table, projection } = useMemo(() => {
47
- // TODO(burdon): Remove variance from the props (should be normalized externally; possibly via hooks).
48
- const props = getBaseSchema({ typename: name, properties, jsonSchema, schema });
49
- return makeDynamicTable({ ...props, properties });
50
- }, [name, properties, schema, jsonSchema]);
47
+ // TODO(burdon): Remove variance from the props (should be normalized externally; possibly via hooks).
48
+ const { typename, jsonSchema } = useMemo(
49
+ () => getBaseSchema({ typename: name, properties, jsonSchema: _jsonSchema, schema }),
50
+ [name, properties, _jsonSchema, schema],
51
+ );
52
+
53
+ const { projection, view } = useMemo(
54
+ () => makeDynamicTable({ typename, jsonSchema, properties }),
55
+ [typename, jsonSchema, properties],
56
+ );
51
57
 
52
58
  const tableRef = useRef<TableController>(null);
53
59
  const handleCellUpdate = useCallback((cell: any) => {
@@ -68,8 +74,9 @@ export const DynamicTable = ({
68
74
  );
69
75
 
70
76
  const model = useTableModel({
71
- table,
72
77
  rows,
78
+ view,
79
+ schema: jsonSchema,
73
80
  projection,
74
81
  features,
75
82
  rowActions,
@@ -4,27 +4,25 @@
4
4
 
5
5
  import '@dxos-theme';
6
6
 
7
- import { type StoryObj, type Meta } from '@storybook/react';
8
- import { SchemaAST } from 'effect';
9
- import React, { useEffect, useMemo } from 'react';
10
-
11
- import { Obj, type Type } from '@dxos/echo';
12
- import { getSchemaTypename, toJsonSchema } from '@dxos/echo-schema';
13
- import { getAnnotation } from '@dxos/effect';
14
- import { invariant } from '@dxos/invariant';
7
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
8
+ import React, { useEffect, useMemo, useState } from 'react';
9
+
10
+ import { Type } from '@dxos/echo';
11
+ import { type JsonSchemaType } from '@dxos/echo-schema';
15
12
  import { faker } from '@dxos/random';
16
13
  import { useClient } from '@dxos/react-client';
17
- import { makeRef } from '@dxos/react-client/echo';
18
14
  import { useClientProvider, withClientProvider } from '@dxos/react-client/testing';
19
- import { DataType, createView, ViewProjection, ViewType } from '@dxos/schema';
20
- import { createAsyncGenerator, type ValueGenerator } from '@dxos/schema/testing';
15
+ import { useAsyncEffect } from '@dxos/react-ui';
16
+ import { DataType } from '@dxos/schema';
17
+ import { type ValueGenerator, createAsyncGenerator } from '@dxos/schema/testing';
21
18
  import { withLayout, withTheme } from '@dxos/storybook-utils';
22
19
 
23
- import { Table } from './Table';
24
20
  import { useTableModel } from '../../hooks';
25
21
  import { type TableFeatures, TablePresentation, type TableRow } from '../../model';
26
- import translations from '../../translations';
27
- import { TableType } from '../../types';
22
+ import { translations } from '../../translations';
23
+ import { Table } from '../../types';
24
+
25
+ import { Table as TableComponent } from './Table';
28
26
 
29
27
  faker.seed(1);
30
28
  const generator: ValueGenerator = faker as any;
@@ -34,35 +32,34 @@ const generator: ValueGenerator = faker as any;
34
32
  // TODO(burdon): Reconcile schemas types and utils (see API PR).
35
33
  // TODO(burdon): Base type for T (with id); see ECHO API PR?
36
34
  const useTestModel = <S extends Type.Obj.Any>(schema: S, count: number) => {
35
+ const client = useClient();
37
36
  const { space } = useClientProvider();
38
-
39
- const jsonSchema = useMemo(() => toJsonSchema(schema), [schema]);
40
- const table = useMemo(() => {
41
- if (!space) {
42
- return undefined;
43
- }
44
- const typename = getSchemaTypename(schema);
45
- invariant(typename);
46
- const name = getAnnotation<string>(SchemaAST.TitleAnnotationId)(schema.ast) ?? typename;
47
- const view = createView({ name, typename, jsonSchema });
48
- return space.db.add(Obj.make(TableType, { view: makeRef(view) }));
49
- }, [schema, space, jsonSchema]);
50
-
51
- const projection = useMemo(() => {
52
- if (!table?.view?.target) {
53
- return undefined;
54
- }
55
-
56
- // TODO(burdon): Just pass in view? Reuse same jsonSchema instance? View determines if mutable, etc.
57
- return new ViewProjection(jsonSchema, table.view.target);
58
- }, [jsonSchema, table]);
37
+ const [view, setView] = useState<DataType.View>();
38
+ const [jsonSchema, setJsonSchema] = useState<JsonSchemaType>();
59
39
 
60
40
  const features = useMemo<TableFeatures>(
61
41
  () => ({ schemaEditable: false, dataEditable: true, selection: { enabled: false } }),
62
42
  [],
63
43
  );
64
44
 
65
- const model = useTableModel<TableRow>({ table, projection, rows: [], features });
45
+ useAsyncEffect(async () => {
46
+ if (!space) {
47
+ return;
48
+ }
49
+
50
+ const {
51
+ jsonSchema,
52
+ schema: effectSchema,
53
+ view,
54
+ } = await Table.makeView({ client, space, typename: Type.getTypename(schema) });
55
+ setJsonSchema(jsonSchema);
56
+ setView(view);
57
+ space.db.add(view);
58
+ await space.db.schemaRegistry.register([effectSchema]);
59
+ }, [client, space, schema]);
60
+
61
+ const model = useTableModel<TableRow>({ view, schema: jsonSchema, rows: [], features });
62
+
66
63
  useEffect(() => {
67
64
  if (!model || !space) {
68
65
  return;
@@ -92,33 +89,45 @@ const DefaultStory = () => {
92
89
 
93
90
  return (
94
91
  <div className='is-full bs-full grid grid-cols-2 divide-x divide-separator'>
95
- <Table.Root>
96
- <Table.Main model={orgModel} presentation={orgPresentation} client={client} ignoreAttention />
97
- </Table.Root>
98
- <Table.Root>
99
- <Table.Main model={contactModel} presentation={contactPresentation} client={client} ignoreAttention />
100
- </Table.Root>
92
+ <TableComponent.Root>
93
+ <TableComponent.Main
94
+ model={orgModel}
95
+ schema={DataType.Organization}
96
+ presentation={orgPresentation}
97
+ client={client}
98
+ ignoreAttention
99
+ />
100
+ </TableComponent.Root>
101
+ <TableComponent.Root>
102
+ <TableComponent.Main
103
+ model={contactModel}
104
+ schema={DataType.Person}
105
+ presentation={contactPresentation}
106
+ client={client}
107
+ ignoreAttention
108
+ />
109
+ </TableComponent.Root>
101
110
  </div>
102
111
  );
103
112
  };
104
113
 
105
- const meta: Meta<typeof DefaultStory> = {
106
- title: 'ui/react-ui-table/relations',
114
+ const meta = {
115
+ title: 'ui/react-ui-table/Relations',
107
116
  render: DefaultStory,
108
117
  parameters: { translations, controls: { disable: true } },
109
118
  decorators: [
110
119
  withClientProvider({
111
- types: [TableType, ViewType, DataType.Organization, DataType.Person],
120
+ types: [DataType.View, DataType.Organization, DataType.Person, Table.Table],
112
121
  createIdentity: true,
113
122
  createSpace: true,
114
123
  }),
115
124
  withTheme,
116
125
  withLayout({ fullscreen: true }),
117
126
  ],
118
- };
127
+ } satisfies Meta<typeof DefaultStory>;
119
128
 
120
129
  export default meta;
121
130
 
122
- type Story = StoryObj<typeof DefaultStory>;
131
+ type Story = StoryObj<typeof meta>;
123
132
 
124
133
  export const Default: Story = {};
@@ -4,9 +4,9 @@
4
4
 
5
5
  import React from 'react';
6
6
 
7
- import { DropdownMenu, useTranslation } from '@dxos/react-ui';
7
+ import { DropdownMenu, toLocalizedString, useTranslation } from '@dxos/react-ui';
8
8
 
9
- import { type TableModel, type ModalController } from '../../model';
9
+ import { type ModalController, type TableModel } from '../../model';
10
10
  import { translationKey } from '../../translations';
11
11
 
12
12
  type RowActionsMenuProps = { model: TableModel; modals: ModalController };
@@ -38,7 +38,7 @@ export const RowActionsMenu = ({ model, modals }: RowActionsMenuProps) => {
38
38
  model.handleRowAction(action.id, state.rowIndex);
39
39
  }}
40
40
  >
41
- {t(action.translationKey)}
41
+ {toLocalizedString(action.label, t)}
42
42
  </DropdownMenu.Item>
43
43
  ))}
44
44
  </DropdownMenu.Viewport>