@dxos/plugin-space 0.7.5-main.9d26e3a → 0.7.5-main.b19bfc8

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 (258) hide show
  1. package/dist/lib/browser/app-graph-builder-MGK5HWPZ.mjs +288 -0
  2. package/dist/lib/browser/app-graph-builder-MGK5HWPZ.mjs.map +7 -0
  3. package/dist/lib/browser/app-graph-serializer-FOWFLYGU.mjs +80 -0
  4. package/dist/lib/browser/app-graph-serializer-FOWFLYGU.mjs.map +7 -0
  5. package/dist/lib/browser/chunk-23RVI5FZ.mjs +539 -0
  6. package/dist/lib/browser/chunk-23RVI5FZ.mjs.map +7 -0
  7. package/dist/lib/browser/chunk-NU7WDVGN.mjs +23 -0
  8. package/dist/lib/browser/chunk-NU7WDVGN.mjs.map +7 -0
  9. package/dist/lib/browser/chunk-PQXZCNAU.mjs +13 -0
  10. package/dist/lib/browser/chunk-PQXZCNAU.mjs.map +7 -0
  11. package/dist/lib/browser/chunk-S6B7627U.mjs +1809 -0
  12. package/dist/lib/browser/chunk-S6B7627U.mjs.map +7 -0
  13. package/dist/lib/browser/chunk-UDWHTKB5.mjs +136 -0
  14. package/dist/lib/browser/chunk-UDWHTKB5.mjs.map +7 -0
  15. package/dist/lib/browser/{chunk-54VE4GTA.mjs → chunk-ULA2UQJ4.mjs} +25 -15
  16. package/dist/lib/browser/chunk-ULA2UQJ4.mjs.map +7 -0
  17. package/dist/lib/browser/identity-created-FYGS6TBH.mjs +28 -0
  18. package/dist/lib/browser/identity-created-FYGS6TBH.mjs.map +7 -0
  19. package/dist/lib/browser/index.mjs +219 -3480
  20. package/dist/lib/browser/index.mjs.map +4 -4
  21. package/dist/lib/browser/intent-resolver-QVR4MSJV.mjs +555 -0
  22. package/dist/lib/browser/intent-resolver-QVR4MSJV.mjs.map +7 -0
  23. package/dist/lib/browser/meta.json +1 -1
  24. package/dist/lib/browser/react-root-IP2ZB245.mjs +28 -0
  25. package/dist/lib/browser/react-root-IP2ZB245.mjs.map +7 -0
  26. package/dist/lib/browser/react-surface-BT3EHB6V.mjs +225 -0
  27. package/dist/lib/browser/react-surface-BT3EHB6V.mjs.map +7 -0
  28. package/dist/lib/browser/schema-5W3DSY2E.mjs +24 -0
  29. package/dist/lib/browser/schema-5W3DSY2E.mjs.map +7 -0
  30. package/dist/lib/browser/settings-PHPCXX33.mjs +24 -0
  31. package/dist/lib/browser/settings-PHPCXX33.mjs.map +7 -0
  32. package/dist/lib/browser/spaces-ready-K47RR7N2.mjs +199 -0
  33. package/dist/lib/browser/spaces-ready-K47RR7N2.mjs.map +7 -0
  34. package/dist/lib/browser/state-INJ63O57.mjs +47 -0
  35. package/dist/lib/browser/state-INJ63O57.mjs.map +7 -0
  36. package/dist/lib/browser/types/index.mjs +6 -4
  37. package/dist/lib/node/app-graph-builder-ZIUBXRPA.cjs +291 -0
  38. package/dist/lib/node/app-graph-builder-ZIUBXRPA.cjs.map +7 -0
  39. package/dist/lib/node/app-graph-serializer-VQOGHKXL.cjs +88 -0
  40. package/dist/lib/node/app-graph-serializer-VQOGHKXL.cjs.map +7 -0
  41. package/dist/lib/node/chunk-N2FS7PRA.cjs +1807 -0
  42. package/dist/lib/node/chunk-N2FS7PRA.cjs.map +7 -0
  43. package/dist/lib/node/chunk-OVGKWJOC.cjs +567 -0
  44. package/dist/lib/node/chunk-OVGKWJOC.cjs.map +7 -0
  45. package/dist/lib/node/chunk-U6DYXAR3.cjs +153 -0
  46. package/dist/lib/node/chunk-U6DYXAR3.cjs.map +7 -0
  47. package/dist/lib/node/{chunk-YF2AQ7KP.cjs → chunk-WAJKBO3J.cjs} +31 -20
  48. package/dist/lib/node/chunk-WAJKBO3J.cjs.map +7 -0
  49. package/dist/lib/node/{chunk-46S3JOES.cjs → chunk-WZR6OAN3.cjs} +9 -12
  50. package/dist/lib/node/chunk-WZR6OAN3.cjs.map +7 -0
  51. package/dist/lib/node/chunk-YZKNRFHU.cjs +43 -0
  52. package/dist/lib/node/chunk-YZKNRFHU.cjs.map +7 -0
  53. package/dist/lib/node/identity-created-AXI64BLE.cjs +44 -0
  54. package/dist/lib/node/identity-created-AXI64BLE.cjs.map +7 -0
  55. package/dist/lib/node/index.cjs +203 -3468
  56. package/dist/lib/node/index.cjs.map +4 -4
  57. package/dist/lib/node/intent-resolver-MLENGECT.cjs +553 -0
  58. package/dist/lib/node/intent-resolver-MLENGECT.cjs.map +7 -0
  59. package/dist/lib/node/meta.json +1 -1
  60. package/dist/lib/node/react-root-3OX5Z5CX.cjs +50 -0
  61. package/dist/lib/node/react-root-3OX5Z5CX.cjs.map +7 -0
  62. package/dist/lib/node/react-surface-5NYCMXSM.cjs +221 -0
  63. package/dist/lib/node/react-surface-5NYCMXSM.cjs.map +7 -0
  64. package/dist/lib/node/schema-YN7WVFRX.cjs +40 -0
  65. package/dist/lib/node/schema-YN7WVFRX.cjs.map +7 -0
  66. package/dist/lib/node/{meta.cjs → settings-5QYFWNH7.cjs} +19 -13
  67. package/dist/lib/node/settings-5QYFWNH7.cjs.map +7 -0
  68. package/dist/lib/node/spaces-ready-FQNAKR7G.cjs +210 -0
  69. package/dist/lib/node/spaces-ready-FQNAKR7G.cjs.map +7 -0
  70. package/dist/lib/node/state-57UE3DYE.cjs +61 -0
  71. package/dist/lib/node/state-57UE3DYE.cjs.map +7 -0
  72. package/dist/lib/node/types/index.cjs +19 -17
  73. package/dist/lib/node/types/index.cjs.map +2 -2
  74. package/dist/lib/node-esm/app-graph-builder-TERVM2SL.mjs +289 -0
  75. package/dist/lib/node-esm/app-graph-builder-TERVM2SL.mjs.map +7 -0
  76. package/dist/lib/node-esm/app-graph-serializer-GZRSWHEN.mjs +81 -0
  77. package/dist/lib/node-esm/app-graph-serializer-GZRSWHEN.mjs.map +7 -0
  78. package/dist/lib/node-esm/chunk-2TQ2AJEZ.mjs +137 -0
  79. package/dist/lib/node-esm/chunk-2TQ2AJEZ.mjs.map +7 -0
  80. package/dist/lib/node-esm/chunk-6RSVVEPS.mjs +24 -0
  81. package/dist/lib/node-esm/chunk-6RSVVEPS.mjs.map +7 -0
  82. package/dist/lib/node-esm/chunk-DIKRH2IK.mjs +1810 -0
  83. package/dist/lib/node-esm/chunk-DIKRH2IK.mjs.map +7 -0
  84. package/dist/lib/node-esm/{chunk-2MNFEB23.mjs → chunk-ICCM4YRJ.mjs} +5 -7
  85. package/dist/lib/node-esm/chunk-ICCM4YRJ.mjs.map +7 -0
  86. package/dist/lib/node-esm/chunk-PGH5L7MV.mjs +540 -0
  87. package/dist/lib/node-esm/chunk-PGH5L7MV.mjs.map +7 -0
  88. package/dist/lib/node-esm/{chunk-CDZETPO7.mjs → chunk-TRNZQEEN.mjs} +25 -15
  89. package/dist/lib/node-esm/chunk-TRNZQEEN.mjs.map +7 -0
  90. package/dist/lib/node-esm/identity-created-3CGEXNPO.mjs +29 -0
  91. package/dist/lib/node-esm/identity-created-3CGEXNPO.mjs.map +7 -0
  92. package/dist/lib/node-esm/index.mjs +219 -3480
  93. package/dist/lib/node-esm/index.mjs.map +4 -4
  94. package/dist/lib/node-esm/intent-resolver-BLW4RM6X.mjs +556 -0
  95. package/dist/lib/node-esm/intent-resolver-BLW4RM6X.mjs.map +7 -0
  96. package/dist/lib/node-esm/meta.json +1 -1
  97. package/dist/lib/node-esm/react-root-7XXGP56B.mjs +29 -0
  98. package/dist/lib/node-esm/react-root-7XXGP56B.mjs.map +7 -0
  99. package/dist/lib/node-esm/react-surface-R2ECJSFB.mjs +226 -0
  100. package/dist/lib/node-esm/react-surface-R2ECJSFB.mjs.map +7 -0
  101. package/dist/lib/node-esm/schema-LOR2EVGY.mjs +25 -0
  102. package/dist/lib/node-esm/schema-LOR2EVGY.mjs.map +7 -0
  103. package/dist/lib/node-esm/settings-H6MXTEQM.mjs +25 -0
  104. package/dist/lib/node-esm/settings-H6MXTEQM.mjs.map +7 -0
  105. package/dist/lib/node-esm/spaces-ready-HKAQG5SA.mjs +200 -0
  106. package/dist/lib/node-esm/spaces-ready-HKAQG5SA.mjs.map +7 -0
  107. package/dist/lib/node-esm/state-VYA6OFHD.mjs +48 -0
  108. package/dist/lib/node-esm/state-VYA6OFHD.mjs.map +7 -0
  109. package/dist/lib/node-esm/types/index.mjs +6 -4
  110. package/dist/types/src/SpacePlugin.d.ts +3 -22
  111. package/dist/types/src/SpacePlugin.d.ts.map +1 -1
  112. package/dist/types/src/capabilities/app-graph-builder.d.ts +181 -0
  113. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
  114. package/dist/types/src/capabilities/app-graph-serializer.d.ts +4 -0
  115. package/dist/types/src/capabilities/app-graph-serializer.d.ts.map +1 -0
  116. package/dist/types/src/capabilities/capabilities.d.ts +22 -0
  117. package/dist/types/src/capabilities/capabilities.d.ts.map +1 -0
  118. package/dist/types/src/capabilities/identity-created.d.ts +4 -0
  119. package/dist/types/src/capabilities/identity-created.d.ts.map +1 -0
  120. package/dist/types/src/capabilities/index.d.ts +197 -0
  121. package/dist/types/src/capabilities/index.d.ts.map +1 -0
  122. package/dist/types/src/capabilities/intent-resolver.d.ts +9 -0
  123. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -0
  124. package/dist/types/src/capabilities/react-root.d.ts +7 -0
  125. package/dist/types/src/capabilities/react-root.d.ts.map +1 -0
  126. package/dist/types/src/capabilities/react-surface.d.ts +7 -0
  127. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
  128. package/dist/types/src/capabilities/schema.d.ts +4 -0
  129. package/dist/types/src/capabilities/schema.d.ts.map +1 -0
  130. package/dist/types/src/capabilities/settings.d.ts +4 -0
  131. package/dist/types/src/capabilities/settings.d.ts.map +1 -0
  132. package/dist/types/src/capabilities/spaces-ready.d.ts +4 -0
  133. package/dist/types/src/capabilities/spaces-ready.d.ts.map +1 -0
  134. package/dist/types/src/capabilities/state.d.ts +5 -0
  135. package/dist/types/src/capabilities/state.d.ts.map +1 -0
  136. package/dist/types/src/components/AdvancedObjectSettings/AdvancedObjectSettings.d.ts +6 -0
  137. package/dist/types/src/components/AdvancedObjectSettings/AdvancedObjectSettings.d.ts.map +1 -0
  138. package/dist/types/src/components/AdvancedObjectSettings/ForeignKeys.d.ts +7 -0
  139. package/dist/types/src/components/AdvancedObjectSettings/ForeignKeys.d.ts.map +1 -0
  140. package/dist/types/src/components/AdvancedObjectSettings/index.d.ts +2 -0
  141. package/dist/types/src/components/AdvancedObjectSettings/index.d.ts.map +1 -0
  142. package/dist/types/src/components/AwaitingObject.d.ts +1 -2
  143. package/dist/types/src/components/AwaitingObject.d.ts.map +1 -1
  144. package/dist/types/src/components/BaseObjectSettings.d.ts +6 -0
  145. package/dist/types/src/components/BaseObjectSettings.d.ts.map +1 -0
  146. package/dist/types/src/components/CollectionMain.d.ts +1 -2
  147. package/dist/types/src/components/CollectionMain.d.ts.map +1 -1
  148. package/dist/types/src/components/CollectionSection.d.ts +1 -2
  149. package/dist/types/src/components/CollectionSection.d.ts.map +1 -1
  150. package/dist/types/src/components/CreateDialog/CreateObjectDialog.d.ts +2 -5
  151. package/dist/types/src/components/CreateDialog/CreateObjectDialog.d.ts.map +1 -1
  152. package/dist/types/src/components/CreateDialog/CreateObjectDialog.stories.d.ts.map +1 -1
  153. package/dist/types/src/components/CreateDialog/CreateObjectPanel.d.ts +9 -11
  154. package/dist/types/src/components/CreateDialog/CreateObjectPanel.d.ts.map +1 -1
  155. package/dist/types/src/components/CreateDialog/CreateSpaceDialog.d.ts +1 -2
  156. package/dist/types/src/components/CreateDialog/CreateSpaceDialog.d.ts.map +1 -1
  157. package/dist/types/src/components/JoinDialog.d.ts +1 -2
  158. package/dist/types/src/components/JoinDialog.d.ts.map +1 -1
  159. package/dist/types/src/components/MenuFooter.d.ts +1 -2
  160. package/dist/types/src/components/MenuFooter.d.ts.map +1 -1
  161. package/dist/types/src/components/PersistenceStatus.d.ts +1 -2
  162. package/dist/types/src/components/PersistenceStatus.d.ts.map +1 -1
  163. package/dist/types/src/components/PopoverAddSpace.d.ts +3 -0
  164. package/dist/types/src/components/PopoverAddSpace.d.ts.map +1 -0
  165. package/dist/types/src/components/PopoverRenameObject.d.ts +1 -2
  166. package/dist/types/src/components/PopoverRenameObject.d.ts.map +1 -1
  167. package/dist/types/src/components/PopoverRenameSpace.d.ts +1 -2
  168. package/dist/types/src/components/PopoverRenameSpace.d.ts.map +1 -1
  169. package/dist/types/src/components/ShareSpaceButton.d.ts +2 -3
  170. package/dist/types/src/components/ShareSpaceButton.d.ts.map +1 -1
  171. package/dist/types/src/components/SpacePluginSettings.d.ts +1 -2
  172. package/dist/types/src/components/SpacePluginSettings.d.ts.map +1 -1
  173. package/dist/types/src/components/SpacePresence.d.ts +4 -5
  174. package/dist/types/src/components/SpacePresence.d.ts.map +1 -1
  175. package/dist/types/src/components/SpacePresence.stories.d.ts +2 -3
  176. package/dist/types/src/components/SpacePresence.stories.d.ts.map +1 -1
  177. package/dist/types/src/components/SpaceSettings/SpaceSettingsDialog.d.ts +1 -2
  178. package/dist/types/src/components/SpaceSettings/SpaceSettingsDialog.d.ts.map +1 -1
  179. package/dist/types/src/components/SpaceSettings/SpaceSettingsPanel.d.ts +3 -5
  180. package/dist/types/src/components/SpaceSettings/SpaceSettingsPanel.d.ts.map +1 -1
  181. package/dist/types/src/components/SpaceSettings/SpaceSettingsPanel.stories.d.ts.map +1 -1
  182. package/dist/types/src/components/SyncStatus/InlineSyncStatus.d.ts +1 -2
  183. package/dist/types/src/components/SyncStatus/InlineSyncStatus.d.ts.map +1 -1
  184. package/dist/types/src/components/SyncStatus/Space.d.ts +2 -3
  185. package/dist/types/src/components/SyncStatus/Space.d.ts.map +1 -1
  186. package/dist/types/src/components/SyncStatus/SyncStatus.d.ts +3 -4
  187. package/dist/types/src/components/SyncStatus/SyncStatus.d.ts.map +1 -1
  188. package/dist/types/src/components/index.d.ts +3 -1
  189. package/dist/types/src/components/index.d.ts.map +1 -1
  190. package/dist/types/src/events.d.ts +9 -0
  191. package/dist/types/src/events.d.ts.map +1 -0
  192. package/dist/types/src/index.d.ts +3 -5
  193. package/dist/types/src/index.d.ts.map +1 -1
  194. package/dist/types/src/meta.d.ts +2 -4
  195. package/dist/types/src/meta.d.ts.map +1 -1
  196. package/dist/types/src/translations.d.ts +21 -0
  197. package/dist/types/src/translations.d.ts.map +1 -1
  198. package/dist/types/src/types/collection.d.ts +2 -2
  199. package/dist/types/src/types/thread.d.ts +34 -34
  200. package/dist/types/src/types/types.d.ts +41 -37
  201. package/dist/types/src/types/types.d.ts.map +1 -1
  202. package/dist/types/src/util.d.ts +10 -8
  203. package/dist/types/src/util.d.ts.map +1 -1
  204. package/dist/types/tsconfig.tsbuildinfo +1 -1
  205. package/package.json +41 -47
  206. package/src/SpacePlugin.tsx +141 -1410
  207. package/src/capabilities/app-graph-builder.ts +319 -0
  208. package/src/capabilities/app-graph-serializer.ts +73 -0
  209. package/src/capabilities/capabilities.ts +28 -0
  210. package/src/capabilities/identity-created.ts +26 -0
  211. package/src/capabilities/index.ts +18 -0
  212. package/src/capabilities/intent-resolver.ts +536 -0
  213. package/src/capabilities/react-root.tsx +20 -0
  214. package/src/capabilities/react-surface.tsx +210 -0
  215. package/src/capabilities/schema.ts +27 -0
  216. package/src/capabilities/settings.ts +17 -0
  217. package/src/capabilities/spaces-ready.ts +230 -0
  218. package/src/capabilities/state.ts +45 -0
  219. package/src/components/AdvancedObjectSettings/AdvancedObjectSettings.tsx +72 -0
  220. package/src/components/AdvancedObjectSettings/ForeignKeys.tsx +51 -0
  221. package/src/components/AdvancedObjectSettings/index.ts +5 -0
  222. package/src/components/AwaitingObject.tsx +5 -11
  223. package/src/components/{DefaultObjectSettings.tsx → BaseObjectSettings.tsx} +9 -2
  224. package/src/components/CreateDialog/CreateObjectDialog.stories.tsx +1 -3
  225. package/src/components/CreateDialog/CreateObjectDialog.tsx +43 -35
  226. package/src/components/CreateDialog/CreateObjectPanel.tsx +139 -105
  227. package/src/components/CreateDialog/CreateSpaceDialog.tsx +18 -9
  228. package/src/components/JoinDialog.tsx +27 -19
  229. package/src/components/PopoverAddSpace.tsx +46 -0
  230. package/src/components/SpacePluginSettings.tsx +5 -10
  231. package/src/components/SpacePresence.stories.tsx +2 -2
  232. package/src/components/SpacePresence.tsx +7 -7
  233. package/src/components/SpaceSettings/SpaceSettingsDialog.tsx +16 -1
  234. package/src/components/SpaceSettings/SpaceSettingsPanel.stories.tsx +5 -1
  235. package/src/components/SpaceSettings/SpaceSettingsPanel.tsx +30 -8
  236. package/src/components/SyncStatus/InlineSyncStatus.tsx +2 -2
  237. package/src/components/SyncStatus/SyncStatus.tsx +2 -1
  238. package/src/components/index.ts +3 -1
  239. package/src/events.ts +18 -0
  240. package/src/index.ts +3 -7
  241. package/src/meta.ts +2 -3
  242. package/src/translations.ts +7 -0
  243. package/src/types/types.ts +32 -51
  244. package/src/util.tsx +45 -29
  245. package/dist/lib/browser/chunk-54VE4GTA.mjs.map +0 -7
  246. package/dist/lib/browser/chunk-73BCBSLP.mjs +0 -15
  247. package/dist/lib/browser/chunk-73BCBSLP.mjs.map +0 -7
  248. package/dist/lib/browser/meta.mjs +0 -11
  249. package/dist/lib/browser/meta.mjs.map +0 -7
  250. package/dist/lib/node/chunk-46S3JOES.cjs.map +0 -7
  251. package/dist/lib/node/chunk-YF2AQ7KP.cjs.map +0 -7
  252. package/dist/lib/node/meta.cjs.map +0 -7
  253. package/dist/lib/node-esm/chunk-2MNFEB23.mjs.map +0 -7
  254. package/dist/lib/node-esm/chunk-CDZETPO7.mjs.map +0 -7
  255. package/dist/lib/node-esm/meta.mjs +0 -12
  256. package/dist/lib/node-esm/meta.mjs.map +0 -7
  257. package/dist/types/src/components/DefaultObjectSettings.d.ts +0 -7
  258. package/dist/types/src/components/DefaultObjectSettings.d.ts.map +0 -1
@@ -5,13 +5,7 @@
5
5
  import { CheckCircle, CircleDashed, CircleNotch } from '@phosphor-icons/react';
6
6
  import React, { useCallback, useEffect, useState } from 'react';
7
7
 
8
- import {
9
- useResolvePlugin,
10
- parseNavigationPlugin,
11
- NavigationAction,
12
- useIntentDispatcher,
13
- createIntent,
14
- } from '@dxos/app-framework';
8
+ import { createIntent, LayoutAction, useIntentDispatcher, useLayout } from '@dxos/app-framework';
15
9
  import { useClient } from '@dxos/react-client';
16
10
  import { Filter, fullyQualifiedId, useQuery } from '@dxos/react-client/echo';
17
11
  import { Button, Toast, useTranslation } from '@dxos/react-ui';
@@ -29,7 +23,7 @@ export const AwaitingObject = ({ id }: { id: string }) => {
29
23
  const [found, setFound] = useState(false);
30
24
  const { t } = useTranslation(SPACE_PLUGIN);
31
25
  const { dispatchPromise: dispatch } = useIntentDispatcher();
32
- const navigationPlugin = useResolvePlugin(parseNavigationPlugin);
26
+ const layout = useLayout();
33
27
 
34
28
  const client = useClient();
35
29
  const objects = useQuery(client.spaces, Filter.all());
@@ -50,11 +44,11 @@ export const AwaitingObject = ({ id }: { id: string }) => {
50
44
  if (objects.findIndex((object) => fullyQualifiedId(object) === id) > -1) {
51
45
  setFound(true);
52
46
 
53
- if (navigationPlugin?.provides.location.active.solo?.[0].id === id) {
47
+ if (layout.active.includes(id)) {
54
48
  setOpen(false);
55
49
  }
56
50
  }
57
- }, [id, objects, navigationPlugin]);
51
+ }, [id, objects, layout]);
58
52
 
59
53
  const handleClose = useCallback(
60
54
  async () => dispatch(createIntent(SpaceAction.WaitForObject, { id: undefined })),
@@ -62,7 +56,7 @@ export const AwaitingObject = ({ id }: { id: string }) => {
62
56
  );
63
57
 
64
58
  const handleNavigate = useCallback(() => {
65
- void dispatch(createIntent(NavigationAction.Open, { activeParts: { main: [id] } }));
59
+ void dispatch(createIntent(LayoutAction.Open, { part: 'main', subject: [id] }));
66
60
  void handleClose();
67
61
  }, [id, handleClose, dispatch]);
68
62
 
@@ -9,23 +9,30 @@ import { Input, useTranslation } from '@dxos/react-ui';
9
9
 
10
10
  import { SPACE_PLUGIN } from '../meta';
11
11
 
12
- export type DefaultObjectSettingsProps = {
12
+ export type BaseObjectSettingsProps = {
13
13
  object: ReactiveEchoObject<any>;
14
14
  };
15
15
 
16
- export const DefaultObjectSettings = ({ object }: DefaultObjectSettingsProps) => {
16
+ export const BaseObjectSettings = ({ object }: BaseObjectSettingsProps) => {
17
17
  const { t } = useTranslation(SPACE_PLUGIN);
18
+ const inputRef = React.useRef<HTMLInputElement>(null);
18
19
  // TODO(burdon): Standardize forms.
19
20
  return (
20
21
  <div role='form' className='flex flex-col w-full p-2 gap-1'>
21
22
  <Input.Root>
22
23
  <Input.Label>{t('name label')}</Input.Label>
23
24
  <Input.TextInput
25
+ ref={inputRef}
24
26
  placeholder={t('name placeholder')}
25
27
  value={object.name ?? ''}
26
28
  onChange={(event) => {
27
29
  object.name = event.target.value;
28
30
  }}
31
+ onKeyDown={(event) => {
32
+ if (event.key === 'Enter') {
33
+ inputRef.current?.blur();
34
+ }
35
+ }}
29
36
  />
30
37
  </Input.Root>
31
38
  </div>
@@ -40,9 +40,7 @@ const meta: Meta<typeof CreateObjectDialog> = {
40
40
  parameters: {
41
41
  translations: [...translations, osTranslations],
42
42
  },
43
- args: {
44
- schemas: [CollectionType],
45
- },
43
+ args: {},
46
44
  };
47
45
 
48
46
  export default meta;
@@ -5,58 +5,65 @@
5
5
  import { pipe } from 'effect';
6
6
  import React, { useCallback, useRef } from 'react';
7
7
 
8
- import { chain, createIntent, type MetadataResolver, NavigationAction, useIntentDispatcher } from '@dxos/app-framework';
9
- import { useClient } from '@dxos/react-client';
10
8
  import {
11
- getSpace,
12
- isReactiveObject,
13
- isSpace,
14
- type ReactiveObject,
15
- type TypedObject,
16
- useSpaces,
17
- } from '@dxos/react-client/echo';
9
+ Capabilities,
10
+ chain,
11
+ createIntent,
12
+ LayoutAction,
13
+ useCapabilities,
14
+ useIntentDispatcher,
15
+ usePluginManager,
16
+ } from '@dxos/app-framework';
17
+ import { invariant } from '@dxos/invariant';
18
+ import { useClient } from '@dxos/react-client';
19
+ import { getSpace, isReactiveObject, isSpace, type ReactiveObject, useSpaces } from '@dxos/react-client/echo';
18
20
  import { Button, Dialog, Icon, useTranslation } from '@dxos/react-ui';
19
21
 
20
22
  import { CreateObjectPanel, type CreateObjectPanelProps } from './CreateObjectPanel';
23
+ import { SpaceCapabilities } from '../../capabilities';
21
24
  import { SPACE_PLUGIN } from '../../meta';
22
- import { CollectionType, SpaceAction } from '../../types';
25
+ import { CollectionType, type ObjectForm, SpaceAction } from '../../types';
23
26
 
24
27
  export const CREATE_OBJECT_DIALOG = `${SPACE_PLUGIN}/CreateObjectDialog`;
25
28
 
26
- export type CreateObjectDialogProps = Pick<CreateObjectPanelProps, 'schemas' | 'target' | 'typename' | 'name'> & {
27
- resolve?: MetadataResolver;
29
+ export type CreateObjectDialogProps = Pick<CreateObjectPanelProps, 'target' | 'typename' | 'name'> & {
28
30
  shouldNavigate?: (object: ReactiveObject<any>) => boolean;
29
31
  };
30
32
 
31
33
  export const CreateObjectDialog = ({
32
- schemas,
33
34
  target,
34
35
  typename,
35
36
  name,
36
37
  shouldNavigate: _shouldNavigate,
37
- resolve,
38
38
  }: CreateObjectDialogProps) => {
39
39
  const closeRef = useRef<HTMLButtonElement | null>(null);
40
+ const manager = usePluginManager();
40
41
  const { t } = useTranslation(SPACE_PLUGIN);
41
42
  const client = useClient();
42
43
  const spaces = useSpaces();
43
44
  const { dispatchPromise: dispatch } = useIntentDispatcher();
45
+ const forms = useCapabilities(SpaceCapabilities.ObjectForm);
46
+
47
+ const resolve = useCallback(
48
+ (typename: string) =>
49
+ manager.context.requestCapabilities(Capabilities.Metadata).find(({ id }) => id === typename)?.metadata ?? {},
50
+ [manager],
51
+ );
44
52
 
45
53
  const handleCreateObject = useCallback(
46
54
  async ({
47
- schema,
55
+ form,
48
56
  target: _target,
49
- name,
57
+ data = {},
50
58
  }: {
51
- schema: TypedObject;
59
+ form: ObjectForm;
52
60
  target: CreateObjectPanelProps['target'];
53
- name?: string;
61
+ data?: Record<string, any>;
54
62
  }) => {
55
63
  const target = isSpace(_target)
56
64
  ? (_target.properties[CollectionType.typename]?.target as CollectionType | undefined)
57
65
  : _target;
58
- const createObjectIntent = resolve?.(schema.typename)?.createObject;
59
- if (!createObjectIntent || !target) {
66
+ if (!target) {
60
67
  // TODO(wittjosiah): UI feedback.
61
68
  return;
62
69
  }
@@ -65,13 +72,14 @@ export const CreateObjectDialog = ({
65
72
  closeRef.current?.click();
66
73
 
67
74
  const space = isSpace(target) ? target : getSpace(target);
68
- const result = await dispatch(createObjectIntent({ name, space }));
75
+ invariant(space, 'Missing space');
76
+ const result = await dispatch(form.getIntent(data, { space }));
69
77
  const object = result.data?.object;
70
78
  if (isReactiveObject(object)) {
71
79
  const addObjectIntent = createIntent(SpaceAction.AddObject, { target, object });
72
80
  const shouldNavigate = _shouldNavigate ?? (() => true);
73
81
  if (shouldNavigate(object)) {
74
- await dispatch(pipe(addObjectIntent, chain(NavigationAction.Open, {})));
82
+ await dispatch(pipe(addObjectIntent, chain(LayoutAction.Open, { part: 'main' })));
75
83
  } else {
76
84
  await dispatch(addObjectIntent);
77
85
  }
@@ -83,7 +91,7 @@ export const CreateObjectDialog = ({
83
91
  return (
84
92
  // TODO(wittjosiah): The tablist dialog pattern is copied from @dxos/plugin-manager.
85
93
  // Consider factoring it out to the tabs package.
86
- <Dialog.Content classNames='p-0 bs-content min-bs-[15rem] max-bs-full md:max-is-[40rem] overflow-hidden'>
94
+ <Dialog.Content classNames='p-0 bs-content max-bs-full md:max-is-[40rem] overflow-hidden'>
87
95
  <div role='none' className='flex justify-between pbs-2 pis-2 pie-2 @md:pbs-4 @md:pis-4 @md:pie-4'>
88
96
  <Dialog.Title>{t('create object dialog title')}</Dialog.Title>
89
97
  <Dialog.Close asChild>
@@ -92,18 +100,18 @@ export const CreateObjectDialog = ({
92
100
  </Button>
93
101
  </Dialog.Close>
94
102
  </div>
95
- <div className='p-4'>
96
- <CreateObjectPanel
97
- schemas={schemas}
98
- spaces={spaces}
99
- target={target}
100
- typename={typename}
101
- name={name}
102
- defaultSpaceId={client.spaces.default.id}
103
- resolve={resolve}
104
- onCreateObject={handleCreateObject}
105
- />
106
- </div>
103
+
104
+ <CreateObjectPanel
105
+ classNames='p-4'
106
+ forms={forms}
107
+ spaces={spaces}
108
+ target={target}
109
+ typename={typename}
110
+ name={name}
111
+ defaultSpaceId={client.spaces.default.id}
112
+ resolve={resolve}
113
+ onCreateObject={handleCreateObject}
114
+ />
107
115
  </Dialog.Content>
108
116
  );
109
117
  };
@@ -4,35 +4,60 @@
4
4
 
5
5
  import React, { useCallback, useState } from 'react';
6
6
 
7
- import { type MetadataResolver } from '@dxos/app-framework';
8
- import { type TypedObject, getObjectAnnotation, S } from '@dxos/echo-schema';
9
- import { type SpaceId, type Space, isSpace } from '@dxos/react-client/echo';
10
- import { Icon, IconButton, Input, toLocalizedString, useTranslation } from '@dxos/react-ui';
11
- import { Form, InputHeader } from '@dxos/react-ui-form';
7
+ import { Surface, isSurfaceAvailable, usePluginManager } from '@dxos/app-framework';
8
+ import { getObjectAnnotation, type ObjectAnnotation, type S } from '@dxos/echo-schema';
9
+ import { invariant } from '@dxos/invariant';
10
+ import { type SpaceId, type Space } from '@dxos/react-client/echo';
11
+ import { Icon, type ThemedClassName, toLocalizedString, useTranslation } from '@dxos/react-ui';
12
+ import { Form, type InputProps } from '@dxos/react-ui-form';
12
13
  import { SearchList } from '@dxos/react-ui-searchlist';
13
- import { nonNullable, type MaybePromise } from '@dxos/util';
14
+ import { mx } from '@dxos/react-ui-theme';
15
+ import { isNonNullable, type MaybePromise } from '@dxos/util';
14
16
 
15
17
  import { SPACE_PLUGIN } from '../../meta';
16
- import { type CollectionType } from '../../types';
18
+ import { type ObjectForm, type CollectionType } from '../../types';
17
19
  import { getSpaceDisplayName } from '../../util';
18
20
 
19
- export type CreateObjectPanelProps = {
20
- schemas: TypedObject[];
21
+ // TODO(ZaymonFC): Move this if you find yourself needing it elsewhere.
22
+ /**
23
+ * Creates a surface input component based on plugin context.
24
+ * @param baseData Additional data that will be merged with form data and passed to the surface.
25
+ * This allows providing more context to the surface than what's available from the form itself.
26
+ */
27
+ const useInputSurfaceLookup = (baseData?: Record<string, any>) => {
28
+ const pluginManager = usePluginManager();
29
+
30
+ return useCallback(
31
+ ({ prop, schema, inputProps }: { prop: string; schema: S.Schema<any>; inputProps: InputProps }) => {
32
+ const composedData = { prop, schema, ...baseData };
33
+ if (!isSurfaceAvailable(pluginManager.context, { role: 'form-input', data: composedData })) {
34
+ return undefined;
35
+ }
36
+
37
+ return <Surface role='form-input' data={composedData} {...inputProps} />;
38
+ },
39
+ [pluginManager, baseData],
40
+ );
41
+ };
42
+
43
+ export type CreateObjectPanelProps = ThemedClassName<{
44
+ forms: ObjectForm[];
21
45
  spaces: Space[];
22
46
  typename?: string;
23
47
  target?: Space | CollectionType;
24
48
  name?: string;
25
49
  defaultSpaceId?: SpaceId;
26
- resolve?: MetadataResolver;
50
+ resolve?: (typename: string) => Record<string, any>;
27
51
  onCreateObject?: (params: {
28
- schema: TypedObject;
52
+ form: ObjectForm;
29
53
  target: Space | CollectionType;
30
- name?: string;
54
+ data?: Record<string, any>;
31
55
  }) => MaybePromise<void>;
32
- };
56
+ }>;
33
57
 
34
58
  export const CreateObjectPanel = ({
35
- schemas,
59
+ classNames,
60
+ forms,
36
61
  spaces,
37
62
  typename: initialTypename,
38
63
  target: initialTarget,
@@ -44,126 +69,135 @@ export const CreateObjectPanel = ({
44
69
  const { t } = useTranslation(SPACE_PLUGIN);
45
70
  const [typename, setTypename] = useState<string | undefined>(initialTypename);
46
71
  const [target, setTarget] = useState<Space | CollectionType | undefined>(initialTarget);
47
- const schema = schemas.find((schema) => getObjectAnnotation(schema)?.typename === typename);
48
- const options = schemas.map(getObjectAnnotation).filter(nonNullable);
49
-
50
- const handleClearSchema = useCallback(() => setTypename(undefined), []);
51
- const handleClearTarget = useCallback(() => setTarget(undefined), []);
72
+ const form = forms.find((form) => getObjectAnnotation(form.objectSchema)?.typename === typename);
73
+ const options: ObjectAnnotation[] = forms
74
+ .map((form) => getObjectAnnotation(form.objectSchema))
75
+ .filter(isNonNullable)
76
+ .sort((a, b) => {
77
+ const nameA = t('typename label', { ns: a.typename, defaultValue: a.typename });
78
+ const nameB = t('typename label', { ns: b.typename, defaultValue: b.typename });
79
+ return nameA.localeCompare(nameB);
80
+ });
52
81
 
53
82
  const handleCreateObject = useCallback(
54
- async ({ name }: { name?: string }) => {
55
- if (!schema || !target) {
83
+ async (props: Record<string, any>) => {
84
+ if (!form || !target) {
56
85
  return;
57
86
  }
87
+ await onCreateObject?.({ form, target, data: props });
88
+ },
89
+ [onCreateObject, form, target],
90
+ );
58
91
 
59
- await onCreateObject?.({ schema, target, name });
92
+ const handleSetTypename = useCallback(
93
+ async (typename: string) => {
94
+ invariant(target, 'target is required');
95
+ const form = forms.find((form) => getObjectAnnotation(form.objectSchema)?.typename === typename);
96
+ if (form && !form.formSchema) {
97
+ await onCreateObject?.({ form, target });
98
+ } else {
99
+ setTypename(typename);
100
+ }
60
101
  },
61
- [onCreateObject, schema, target],
102
+ [forms, onCreateObject, target],
62
103
  );
63
104
 
64
- // TODO(wittjosiah): All of these inputs should be rolled into a `Form` once it supports the necessary variants.
65
- const schemaInput = (
66
- <SearchList.Root label={t('schema input label')} classNames='flex flex-col grow overflow-hidden'>
105
+ const inputSurfaceLookup = useInputSurfaceLookup({ target });
106
+
107
+ // TODO(wittjosiah): These inputs should be rolled into a `Form` once it supports the necessary variants.
108
+ return (
109
+ <div role='form' className={mx('flex flex-col gap-2', classNames)}>
110
+ {!form ? (
111
+ <SelectSchema options={options} resolve={resolve} onChange={handleSetTypename} />
112
+ ) : !target ? (
113
+ <SelectSpace spaces={spaces} defaultSpaceId={defaultSpaceId} onChange={setTarget} />
114
+ ) : form.formSchema ? (
115
+ <Form
116
+ classNames='!p-0'
117
+ autoFocus
118
+ values={{ name: initialName }}
119
+ schema={form.formSchema}
120
+ testId='create-object-form'
121
+ onSave={handleCreateObject}
122
+ lookupComponent={inputSurfaceLookup}
123
+ />
124
+ ) : undefined}
125
+ </div>
126
+ );
127
+ };
128
+
129
+ const SelectSpace = ({
130
+ spaces,
131
+ defaultSpaceId,
132
+ onChange,
133
+ }: { onChange: (space: Space) => void } & Pick<CreateObjectPanelProps, 'spaces' | 'defaultSpaceId'>) => {
134
+ const { t } = useTranslation(SPACE_PLUGIN);
135
+
136
+ return (
137
+ <SearchList.Root label={t('space input label')} classNames='flex flex-col grow overflow-hidden'>
67
138
  <SearchList.Input
68
139
  autoFocus
69
- data-testid='create-object-form.schema-input'
70
- placeholder={t('schema input placeholder')}
140
+ data-testid='create-object-form.space-input'
141
+ placeholder={t('space input placeholder')}
71
142
  classNames='px-1 my-2'
72
143
  />
73
144
  <SearchList.Content classNames='max-bs-[24rem] overflow-auto'>
74
- {options.map((option) => (
75
- <SearchList.Item
76
- key={option.typename}
77
- value={t('typename label', { ns: option.typename, defaultValue: option.typename })}
78
- onSelect={() => setTypename(option.typename)}
79
- classNames='flex items-center gap-2'
80
- >
81
- <span className='flex gap-2 items-center grow truncate'>
82
- <Icon icon={resolve?.(option.typename).icon ?? 'ph--placeholder--regular'} size={5} />
83
- {t('typename label', { ns: option.typename, defaultValue: option.typename })}
84
- </span>
85
- </SearchList.Item>
86
- ))}
145
+ {spaces
146
+ .sort((a, b) => {
147
+ const aName = toLocalizedString(getSpaceDisplayName(a, { personal: a.id === defaultSpaceId }), t);
148
+ const bName = toLocalizedString(getSpaceDisplayName(b, { personal: b.id === defaultSpaceId }), t);
149
+ return aName.localeCompare(bName);
150
+ })
151
+ .map((space) => (
152
+ <SearchList.Item
153
+ key={space.id}
154
+ value={toLocalizedString(getSpaceDisplayName(space, { personal: space.id === defaultSpaceId }), t)}
155
+ onSelect={() => onChange(space)}
156
+ classNames='flex items-center gap-2'
157
+ >
158
+ <span className='grow truncate'>
159
+ {toLocalizedString(getSpaceDisplayName(space, { personal: space.id === defaultSpaceId }), t)}
160
+ </span>
161
+ </SearchList.Item>
162
+ ))}
87
163
  </SearchList.Content>
88
164
  </SearchList.Root>
89
165
  );
166
+ };
90
167
 
91
- const spaceInput = (
92
- <SearchList.Root label={t('space input label')} classNames='flex flex-col grow overflow-hidden'>
168
+ const SelectSchema = ({
169
+ options,
170
+ resolve,
171
+ onChange,
172
+ }: {
173
+ options: ObjectAnnotation[];
174
+ onChange: (type: string) => void;
175
+ } & Pick<CreateObjectPanelProps, 'resolve'>) => {
176
+ const { t } = useTranslation(SPACE_PLUGIN);
177
+
178
+ return (
179
+ <SearchList.Root label={t('schema input label')} classNames='flex flex-col grow overflow-hidden'>
93
180
  <SearchList.Input
94
181
  autoFocus
95
- data-testid='create-object-form.space-input'
96
- placeholder={t('space input placeholder')}
182
+ data-testid='create-object-form.schema-input'
183
+ placeholder={t('schema input placeholder')}
97
184
  classNames='px-1 my-2'
98
185
  />
99
186
  <SearchList.Content classNames='max-bs-[24rem] overflow-auto'>
100
- {spaces.map((space) => (
187
+ {options.map((option) => (
101
188
  <SearchList.Item
102
- key={space.id}
103
- value={toLocalizedString(getSpaceDisplayName(space, { personal: space.id === defaultSpaceId }), t)}
104
- onSelect={() => setTarget(space)}
189
+ key={option.typename}
190
+ value={t('typename label', { ns: option.typename, defaultValue: option.typename })}
191
+ onSelect={() => onChange(option.typename)}
105
192
  classNames='flex items-center gap-2'
106
193
  >
107
- <span className='grow truncate'>
108
- {toLocalizedString(getSpaceDisplayName(space, { personal: space.id === defaultSpaceId }), t)}
194
+ <span className='flex gap-2 items-center grow truncate'>
195
+ <Icon icon={resolve?.(option.typename).icon ?? 'ph--placeholder--regular'} size={5} />
196
+ {t('typename label', { ns: option.typename, defaultValue: option.typename })}
109
197
  </span>
110
198
  </SearchList.Item>
111
199
  ))}
112
200
  </SearchList.Content>
113
201
  </SearchList.Root>
114
202
  );
115
-
116
- const form = (
117
- <Form
118
- autoFocus
119
- values={{ name: initialName }}
120
- schema={S.Struct({ name: S.optional(S.String) })}
121
- testId='create-object-form'
122
- onSave={handleCreateObject}
123
- />
124
- );
125
-
126
- return (
127
- <div role='form' className='flex flex-col gap-2'>
128
- {target && (
129
- <div role='none'>
130
- <Input.Root>
131
- <InputHeader>
132
- <Input.Label>
133
- {t(isSpace(target) ? 'creating in space label' : 'creating in collection label')}
134
- </Input.Label>
135
- </InputHeader>
136
- <div role='none' className='flex gap-2'>
137
- <Input.TextInput
138
- disabled
139
- value={
140
- isSpace(target)
141
- ? toLocalizedString(getSpaceDisplayName(target, { personal: target.id === defaultSpaceId }), t)
142
- : target.name || t('unnamed collection label')
143
- }
144
- />
145
- <IconButton iconOnly icon='ph--x--regular' label={t('clear input label')} onClick={handleClearTarget} />
146
- </div>
147
- </Input.Root>
148
- </div>
149
- )}
150
- {schema && (
151
- <div role='none'>
152
- <Input.Root>
153
- <InputHeader>
154
- <Input.Label>{t('creating object type label')}</Input.Label>
155
- </InputHeader>
156
- <div role='none' className='flex gap-2'>
157
- <Input.TextInput
158
- disabled
159
- value={t('typename label', { ns: schema.typename, defaultValue: schema.typename })}
160
- />
161
- <IconButton iconOnly icon='ph--x--regular' label={t('clear input label')} onClick={handleClearSchema} />
162
- </div>
163
- </Input.Root>
164
- </div>
165
- )}
166
- {!schema ? schemaInput : !target ? spaceInput : form}
167
- </div>
168
- );
169
203
  };
@@ -2,9 +2,10 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
+ import { Effect } from 'effect';
5
6
  import React, { useCallback, useRef } from 'react';
6
7
 
7
- import { createIntent, useIntentDispatcher } from '@dxos/app-framework';
8
+ import { createIntent, LayoutAction, useIntentDispatcher } from '@dxos/app-framework';
8
9
  import { type S } from '@dxos/echo-schema';
9
10
  import { Button, Dialog, Icon, useTranslation } from '@dxos/react-ui';
10
11
  import { Form } from '@dxos/react-ui-form';
@@ -20,15 +21,16 @@ const initialValues: FormValues = { edgeReplication: true };
20
21
  export const CreateSpaceDialog = () => {
21
22
  const closeRef = useRef<HTMLButtonElement | null>(null);
22
23
  const { t } = useTranslation(SPACE_PLUGIN);
23
- const { dispatchPromise: dispatch } = useIntentDispatcher();
24
+ const { dispatch } = useIntentDispatcher();
24
25
 
25
26
  const handleCreateSpace = useCallback(
26
27
  async (data: FormValues) => {
27
- const result = await dispatch(createIntent(SpaceAction.Create, data));
28
- const target = result.data?.space;
29
- if (target) {
30
- await dispatch(createIntent(SpaceAction.OpenCreateObject, { target }));
31
- }
28
+ const program = Effect.gen(function* () {
29
+ const { space } = yield* dispatch(createIntent(SpaceAction.Create, data));
30
+ yield* dispatch(createIntent(LayoutAction.SwitchWorkspace, { part: 'workspace', subject: space.id }));
31
+ yield* dispatch(createIntent(SpaceAction.OpenCreateObject, { target: space }));
32
+ });
33
+ await Effect.runPromise(program);
32
34
  },
33
35
  [dispatch],
34
36
  );
@@ -36,7 +38,7 @@ export const CreateSpaceDialog = () => {
36
38
  return (
37
39
  // TODO(wittjosiah): The tablist dialog pattern is copied from @dxos/plugin-manager.
38
40
  // Consider factoring it out to the tabs package.
39
- <Dialog.Content classNames='p-0 bs-content min-bs-[15rem] max-bs-full md:max-is-[40rem] overflow-hidden'>
41
+ <Dialog.Content classNames='p-0 bs-content min-bs-[16rem] max-bs-full md:max-is-[32rem] overflow-hidden'>
40
42
  <div role='none' className='flex justify-between pbs-2 pis-2 pie-2 @md:pbs-4 @md:pis-4 @md:pie-4'>
41
43
  <Dialog.Title>{t('create space dialog title')}</Dialog.Title>
42
44
  <Dialog.Close asChild>
@@ -46,7 +48,14 @@ export const CreateSpaceDialog = () => {
46
48
  </Dialog.Close>
47
49
  </div>
48
50
  <div className='p-4'>
49
- <Form testId='create-space-form' values={initialValues} schema={SpaceForm} onSave={handleCreateSpace} />
51
+ <Form
52
+ testId='create-space-form'
53
+ classNames='!p-0'
54
+ autoFocus
55
+ values={initialValues}
56
+ schema={SpaceForm}
57
+ onSave={handleCreateSpace}
58
+ />
50
59
  </div>
51
60
  </Dialog.Content>
52
61
  );