@dxos/plugin-space 0.7.4 → 0.7.5-labs.071a3e2

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 (257) hide show
  1. package/dist/lib/browser/app-graph-builder-TTM2YZVS.mjs +367 -0
  2. package/dist/lib/browser/app-graph-builder-TTM2YZVS.mjs.map +7 -0
  3. package/dist/lib/browser/app-graph-serializer-ZGM5NDXE.mjs +80 -0
  4. package/dist/lib/browser/app-graph-serializer-ZGM5NDXE.mjs.map +7 -0
  5. package/dist/lib/browser/chunk-2NMUVDMZ.mjs +1715 -0
  6. package/dist/lib/browser/chunk-2NMUVDMZ.mjs.map +7 -0
  7. package/dist/lib/browser/chunk-ENRYFGYE.mjs +133 -0
  8. package/dist/lib/browser/chunk-ENRYFGYE.mjs.map +7 -0
  9. package/dist/lib/browser/chunk-H2AR4OLP.mjs +316 -0
  10. package/dist/lib/browser/chunk-H2AR4OLP.mjs.map +7 -0
  11. package/dist/lib/browser/chunk-PQXZCNAU.mjs +13 -0
  12. package/dist/lib/browser/chunk-PQXZCNAU.mjs.map +7 -0
  13. package/dist/lib/browser/chunk-RLZQJD47.mjs +22 -0
  14. package/dist/lib/browser/chunk-RLZQJD47.mjs.map +7 -0
  15. package/dist/lib/browser/chunk-S5IGZNXJ.mjs +528 -0
  16. package/dist/lib/browser/chunk-S5IGZNXJ.mjs.map +7 -0
  17. package/dist/lib/browser/identity-created-VICTPQX7.mjs +28 -0
  18. package/dist/lib/browser/identity-created-VICTPQX7.mjs.map +7 -0
  19. package/dist/lib/browser/index.mjs +193 -3521
  20. package/dist/lib/browser/index.mjs.map +4 -4
  21. package/dist/lib/browser/intent-resolver-A5274MUR.mjs +537 -0
  22. package/dist/lib/browser/intent-resolver-A5274MUR.mjs.map +7 -0
  23. package/dist/lib/browser/meta.json +1 -1
  24. package/dist/lib/browser/react-root-N6QTWYCV.mjs +28 -0
  25. package/dist/lib/browser/react-root-N6QTWYCV.mjs.map +7 -0
  26. package/dist/lib/browser/react-surface-STMNA7W7.mjs +231 -0
  27. package/dist/lib/browser/react-surface-STMNA7W7.mjs.map +7 -0
  28. package/dist/lib/browser/settings-HN5UIYQO.mjs +24 -0
  29. package/dist/lib/browser/settings-HN5UIYQO.mjs.map +7 -0
  30. package/dist/lib/browser/spaces-ready-F57ITJDR.mjs +199 -0
  31. package/dist/lib/browser/spaces-ready-F57ITJDR.mjs.map +7 -0
  32. package/dist/lib/browser/state-6DCY5YJP.mjs +47 -0
  33. package/dist/lib/browser/state-6DCY5YJP.mjs.map +7 -0
  34. package/dist/lib/browser/types/index.mjs +14 -5
  35. package/dist/lib/node/app-graph-builder-6N4TEVHH.cjs +370 -0
  36. package/dist/lib/node/app-graph-builder-6N4TEVHH.cjs.map +7 -0
  37. package/dist/lib/node/app-graph-serializer-AWKVTYAB.cjs +88 -0
  38. package/dist/lib/node/app-graph-serializer-AWKVTYAB.cjs.map +7 -0
  39. package/dist/lib/node/chunk-2RCJT3P2.cjs +1712 -0
  40. package/dist/lib/node/chunk-2RCJT3P2.cjs.map +7 -0
  41. package/dist/lib/node/chunk-I2LRRRMV.cjs +150 -0
  42. package/dist/lib/node/chunk-I2LRRRMV.cjs.map +7 -0
  43. package/dist/lib/node/chunk-MMXP2NHE.cjs +556 -0
  44. package/dist/lib/node/chunk-MMXP2NHE.cjs.map +7 -0
  45. package/dist/lib/node/chunk-SPCSJ2CY.cjs +345 -0
  46. package/dist/lib/node/chunk-SPCSJ2CY.cjs.map +7 -0
  47. package/dist/lib/node/chunk-UX3U4RU2.cjs +42 -0
  48. package/dist/lib/node/chunk-UX3U4RU2.cjs.map +7 -0
  49. package/dist/lib/node/{meta.cjs → chunk-WZR6OAN3.cjs} +13 -13
  50. package/dist/lib/node/chunk-WZR6OAN3.cjs.map +7 -0
  51. package/dist/lib/node/identity-created-JNDKMFKI.cjs +44 -0
  52. package/dist/lib/node/identity-created-JNDKMFKI.cjs.map +7 -0
  53. package/dist/lib/node/index.cjs +176 -3506
  54. package/dist/lib/node/index.cjs.map +4 -4
  55. package/dist/lib/node/intent-resolver-NVTAESKB.cjs +536 -0
  56. package/dist/lib/node/intent-resolver-NVTAESKB.cjs.map +7 -0
  57. package/dist/lib/node/meta.json +1 -1
  58. package/dist/lib/node/react-root-YCHSAYQE.cjs +50 -0
  59. package/dist/lib/node/react-root-YCHSAYQE.cjs.map +7 -0
  60. package/dist/lib/node/react-surface-ANSZ4FKK.cjs +229 -0
  61. package/dist/lib/node/react-surface-ANSZ4FKK.cjs.map +7 -0
  62. package/dist/lib/node/settings-RBBL22DJ.cjs +38 -0
  63. package/dist/lib/node/settings-RBBL22DJ.cjs.map +7 -0
  64. package/dist/lib/node/spaces-ready-WHU4J6E5.cjs +210 -0
  65. package/dist/lib/node/spaces-ready-WHU4J6E5.cjs.map +7 -0
  66. package/dist/lib/node/state-WPZC4JXB.cjs +61 -0
  67. package/dist/lib/node/state-WPZC4JXB.cjs.map +7 -0
  68. package/dist/lib/node/types/index.cjs +23 -14
  69. package/dist/lib/node/types/index.cjs.map +2 -2
  70. package/dist/lib/node-esm/app-graph-builder-MS6BI5EW.mjs +368 -0
  71. package/dist/lib/node-esm/app-graph-builder-MS6BI5EW.mjs.map +7 -0
  72. package/dist/lib/node-esm/app-graph-serializer-AWAWDSCM.mjs +81 -0
  73. package/dist/lib/node-esm/app-graph-serializer-AWAWDSCM.mjs.map +7 -0
  74. package/dist/lib/node-esm/chunk-4HICD7AU.mjs +1716 -0
  75. package/dist/lib/node-esm/chunk-4HICD7AU.mjs.map +7 -0
  76. package/dist/lib/node-esm/chunk-77RE7Y5J.mjs +529 -0
  77. package/dist/lib/node-esm/chunk-77RE7Y5J.mjs.map +7 -0
  78. package/dist/lib/node-esm/chunk-ESWV7ICX.mjs +134 -0
  79. package/dist/lib/node-esm/chunk-ESWV7ICX.mjs.map +7 -0
  80. package/dist/lib/node-esm/chunk-ICCM4YRJ.mjs +15 -0
  81. package/dist/lib/node-esm/chunk-ICCM4YRJ.mjs.map +7 -0
  82. package/dist/lib/node-esm/chunk-LGL4A5B5.mjs +23 -0
  83. package/dist/lib/node-esm/chunk-LGL4A5B5.mjs.map +7 -0
  84. package/dist/lib/node-esm/chunk-S6VAU6VJ.mjs +317 -0
  85. package/dist/lib/node-esm/chunk-S6VAU6VJ.mjs.map +7 -0
  86. package/dist/lib/node-esm/identity-created-3AUSSVEK.mjs +29 -0
  87. package/dist/lib/node-esm/identity-created-3AUSSVEK.mjs.map +7 -0
  88. package/dist/lib/node-esm/index.mjs +193 -3521
  89. package/dist/lib/node-esm/index.mjs.map +4 -4
  90. package/dist/lib/node-esm/intent-resolver-KJ67TU34.mjs +538 -0
  91. package/dist/lib/node-esm/intent-resolver-KJ67TU34.mjs.map +7 -0
  92. package/dist/lib/node-esm/meta.json +1 -1
  93. package/dist/lib/node-esm/react-root-NBQQKAZD.mjs +29 -0
  94. package/dist/lib/node-esm/react-root-NBQQKAZD.mjs.map +7 -0
  95. package/dist/lib/node-esm/react-surface-G2H5T2D2.mjs +232 -0
  96. package/dist/lib/node-esm/react-surface-G2H5T2D2.mjs.map +7 -0
  97. package/dist/lib/node-esm/settings-VBAUB37B.mjs +25 -0
  98. package/dist/lib/node-esm/settings-VBAUB37B.mjs.map +7 -0
  99. package/dist/lib/node-esm/spaces-ready-ABADUX2P.mjs +200 -0
  100. package/dist/lib/node-esm/spaces-ready-ABADUX2P.mjs.map +7 -0
  101. package/dist/lib/node-esm/state-5GH2D5U4.mjs +48 -0
  102. package/dist/lib/node-esm/state-5GH2D5U4.mjs.map +7 -0
  103. package/dist/lib/node-esm/types/index.mjs +14 -5
  104. package/dist/types/src/SpacePlugin.d.ts +3 -22
  105. package/dist/types/src/SpacePlugin.d.ts.map +1 -1
  106. package/dist/types/src/capabilities/app-graph-builder.d.ts +181 -0
  107. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
  108. package/dist/types/src/capabilities/app-graph-serializer.d.ts +4 -0
  109. package/dist/types/src/capabilities/app-graph-serializer.d.ts.map +1 -0
  110. package/dist/types/src/capabilities/capabilities.d.ts +21 -0
  111. package/dist/types/src/capabilities/capabilities.d.ts.map +1 -0
  112. package/dist/types/src/capabilities/identity-created.d.ts +4 -0
  113. package/dist/types/src/capabilities/identity-created.d.ts.map +1 -0
  114. package/dist/types/src/capabilities/index.d.ts +196 -0
  115. package/dist/types/src/capabilities/index.d.ts.map +1 -0
  116. package/dist/types/src/capabilities/intent-resolver.d.ts +9 -0
  117. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -0
  118. package/dist/types/src/capabilities/react-root.d.ts +7 -0
  119. package/dist/types/src/capabilities/react-root.d.ts.map +1 -0
  120. package/dist/types/src/capabilities/react-surface.d.ts +7 -0
  121. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
  122. package/dist/types/src/capabilities/settings.d.ts +4 -0
  123. package/dist/types/src/capabilities/settings.d.ts.map +1 -0
  124. package/dist/types/src/capabilities/spaces-ready.d.ts +4 -0
  125. package/dist/types/src/capabilities/spaces-ready.d.ts.map +1 -0
  126. package/dist/types/src/capabilities/state.d.ts +5 -0
  127. package/dist/types/src/capabilities/state.d.ts.map +1 -0
  128. package/dist/types/src/components/AdvancedObjectSettings/AdvancedObjectSettings.d.ts +7 -0
  129. package/dist/types/src/components/AdvancedObjectSettings/AdvancedObjectSettings.d.ts.map +1 -0
  130. package/dist/types/src/components/AdvancedObjectSettings/ForeignKeys.d.ts +8 -0
  131. package/dist/types/src/components/AdvancedObjectSettings/ForeignKeys.d.ts.map +1 -0
  132. package/dist/types/src/components/AdvancedObjectSettings/index.d.ts +2 -0
  133. package/dist/types/src/components/AdvancedObjectSettings/index.d.ts.map +1 -0
  134. package/dist/types/src/components/AwaitingObject.d.ts.map +1 -1
  135. package/dist/types/src/components/BaseObjectSettings.d.ts +7 -0
  136. package/dist/types/src/components/BaseObjectSettings.d.ts.map +1 -0
  137. package/dist/types/src/components/CreateDialog/CreateObjectDialog.d.ts +5 -4
  138. package/dist/types/src/components/CreateDialog/CreateObjectDialog.d.ts.map +1 -1
  139. package/dist/types/src/components/CreateDialog/CreateObjectPanel.d.ts +9 -9
  140. package/dist/types/src/components/CreateDialog/CreateObjectPanel.d.ts.map +1 -1
  141. package/dist/types/src/components/CreateDialog/CreateSpaceDialog.d.ts +1 -0
  142. package/dist/types/src/components/CreateDialog/CreateSpaceDialog.d.ts.map +1 -1
  143. package/dist/types/src/components/JoinDialog.d.ts +1 -0
  144. package/dist/types/src/components/JoinDialog.d.ts.map +1 -1
  145. package/dist/types/src/components/PopoverRenameObject.d.ts +1 -0
  146. package/dist/types/src/components/PopoverRenameObject.d.ts.map +1 -1
  147. package/dist/types/src/components/PopoverRenameSpace.d.ts +1 -0
  148. package/dist/types/src/components/PopoverRenameSpace.d.ts.map +1 -1
  149. package/dist/types/src/components/ShareSpaceButton.d.ts.map +1 -1
  150. package/dist/types/src/components/SpacePluginSettings.d.ts.map +1 -1
  151. package/dist/types/src/components/SpacePresence.d.ts +9 -6
  152. package/dist/types/src/components/SpacePresence.d.ts.map +1 -1
  153. package/dist/types/src/components/SpacePresence.stories.d.ts +1 -1
  154. package/dist/types/src/components/SpacePresence.stories.d.ts.map +1 -1
  155. package/dist/types/src/components/SpaceSettings/SpaceSettingsDialog.d.ts +1 -0
  156. package/dist/types/src/components/SpaceSettings/SpaceSettingsDialog.d.ts.map +1 -1
  157. package/dist/types/src/components/SpaceSettings/SpaceSettingsDialog.stories.d.ts.map +1 -1
  158. package/dist/types/src/components/SpaceSettings/SpaceSettingsPanel.d.ts +4 -3
  159. package/dist/types/src/components/SpaceSettings/SpaceSettingsPanel.d.ts.map +1 -1
  160. package/dist/types/src/components/SpaceSettings/SpaceSettingsPanel.stories.d.ts.map +1 -1
  161. package/dist/types/src/components/SyncStatus/InlineSyncStatus.d.ts +3 -3
  162. package/dist/types/src/components/SyncStatus/InlineSyncStatus.d.ts.map +1 -1
  163. package/dist/types/src/components/SyncStatus/SyncStatus.d.ts.map +1 -1
  164. package/dist/types/src/components/SyncStatus/SyncStatusDetail.stories.d.ts +2 -2
  165. package/dist/types/src/components/SyncStatus/SyncStatusDetail.stories.d.ts.map +1 -1
  166. package/dist/types/src/components/index.d.ts +2 -1
  167. package/dist/types/src/components/index.d.ts.map +1 -1
  168. package/dist/types/src/events.d.ts +5 -0
  169. package/dist/types/src/events.d.ts.map +1 -0
  170. package/dist/types/src/hooks/index.d.ts +2 -0
  171. package/dist/types/src/hooks/index.d.ts.map +1 -0
  172. package/dist/types/src/hooks/usePath.d.ts +11 -0
  173. package/dist/types/src/hooks/usePath.d.ts.map +1 -0
  174. package/dist/types/src/index.d.ts +3 -5
  175. package/dist/types/src/index.d.ts.map +1 -1
  176. package/dist/types/src/meta.d.ts +2 -27
  177. package/dist/types/src/meta.d.ts.map +1 -1
  178. package/dist/types/src/translations.d.ts +18 -3
  179. package/dist/types/src/translations.d.ts.map +1 -1
  180. package/dist/types/src/types/collection.d.ts +8 -12
  181. package/dist/types/src/types/collection.d.ts.map +1 -1
  182. package/dist/types/src/types/thread.d.ts +180 -186
  183. package/dist/types/src/types/thread.d.ts.map +1 -1
  184. package/dist/types/src/types/types.d.ts +228 -16
  185. package/dist/types/src/types/types.d.ts.map +1 -1
  186. package/dist/types/src/util.d.ts +9 -8
  187. package/dist/types/src/util.d.ts.map +1 -1
  188. package/dist/types/tsconfig.tsbuildinfo +1 -0
  189. package/package.json +39 -46
  190. package/src/SpacePlugin.tsx +121 -1538
  191. package/src/capabilities/app-graph-builder.ts +393 -0
  192. package/src/capabilities/app-graph-serializer.ts +73 -0
  193. package/src/capabilities/capabilities.ts +26 -0
  194. package/src/capabilities/identity-created.ts +26 -0
  195. package/src/capabilities/index.ts +17 -0
  196. package/src/capabilities/intent-resolver.ts +518 -0
  197. package/src/capabilities/react-root.tsx +20 -0
  198. package/src/capabilities/react-surface.tsx +226 -0
  199. package/src/capabilities/settings.ts +17 -0
  200. package/src/capabilities/spaces-ready.ts +230 -0
  201. package/src/capabilities/state.ts +45 -0
  202. package/src/components/AdvancedObjectSettings/AdvancedObjectSettings.tsx +72 -0
  203. package/src/components/AdvancedObjectSettings/ForeignKeys.tsx +51 -0
  204. package/src/components/AdvancedObjectSettings/index.ts +5 -0
  205. package/src/components/AwaitingObject.tsx +15 -19
  206. package/src/components/{DefaultObjectSettings.tsx → BaseObjectSettings.tsx} +2 -2
  207. package/src/components/CreateDialog/CreateObjectDialog.tsx +49 -38
  208. package/src/components/CreateDialog/CreateObjectPanel.tsx +137 -101
  209. package/src/components/CreateDialog/CreateSpaceDialog.tsx +22 -17
  210. package/src/components/JoinDialog.tsx +40 -48
  211. package/src/components/PersistenceStatus.tsx +1 -1
  212. package/src/components/PopoverRenameObject.tsx +2 -0
  213. package/src/components/PopoverRenameSpace.tsx +2 -0
  214. package/src/components/ShareSpaceButton.tsx +5 -4
  215. package/src/components/SpacePluginSettings.tsx +5 -16
  216. package/src/components/SpacePresence.stories.tsx +27 -19
  217. package/src/components/SpacePresence.tsx +41 -21
  218. package/src/components/SpaceSettings/SpaceSettingsDialog.stories.tsx +2 -3
  219. package/src/components/SpaceSettings/SpaceSettingsDialog.tsx +19 -2
  220. package/src/components/SpaceSettings/SpaceSettingsPanel.stories.tsx +7 -5
  221. package/src/components/SpaceSettings/SpaceSettingsPanel.tsx +7 -7
  222. package/src/components/SyncStatus/InlineSyncStatus.tsx +37 -27
  223. package/src/components/SyncStatus/SyncStatus.tsx +2 -1
  224. package/src/components/SyncStatus/SyncStatusDetail.stories.tsx +55 -51
  225. package/src/components/index.ts +2 -1
  226. package/src/events.ts +12 -0
  227. package/src/hooks/index.ts +5 -0
  228. package/src/hooks/usePath.ts +44 -0
  229. package/src/index.ts +3 -7
  230. package/src/meta.ts +2 -29
  231. package/src/translations.ts +7 -2
  232. package/src/types/collection.ts +3 -3
  233. package/src/types/thread.ts +6 -6
  234. package/src/types/types.ts +177 -42
  235. package/src/util.tsx +82 -65
  236. package/dist/lib/browser/chunk-FTKV32QZ.mjs +0 -43
  237. package/dist/lib/browser/chunk-FTKV32QZ.mjs.map +0 -7
  238. package/dist/lib/browser/chunk-MWKXNS5S.mjs +0 -124
  239. package/dist/lib/browser/chunk-MWKXNS5S.mjs.map +0 -7
  240. package/dist/lib/browser/meta.mjs +0 -15
  241. package/dist/lib/browser/meta.mjs.map +0 -7
  242. package/dist/lib/node/chunk-6SNOZF7Y.cjs +0 -152
  243. package/dist/lib/node/chunk-6SNOZF7Y.cjs.map +0 -7
  244. package/dist/lib/node/chunk-QNVEU2UD.cjs +0 -69
  245. package/dist/lib/node/chunk-QNVEU2UD.cjs.map +0 -7
  246. package/dist/lib/node/meta.cjs.map +0 -7
  247. package/dist/lib/node-esm/chunk-OHEAWSCA.mjs +0 -126
  248. package/dist/lib/node-esm/chunk-OHEAWSCA.mjs.map +0 -7
  249. package/dist/lib/node-esm/chunk-UMV7XREB.mjs +0 -45
  250. package/dist/lib/node-esm/chunk-UMV7XREB.mjs.map +0 -7
  251. package/dist/lib/node-esm/meta.mjs +0 -16
  252. package/dist/lib/node-esm/meta.mjs.map +0 -7
  253. package/dist/types/src/components/DefaultObjectSettings.d.ts +0 -7
  254. package/dist/types/src/components/DefaultObjectSettings.d.ts.map +0 -1
  255. package/dist/types/src/components/SyncStatus/InlineSyncStatus.stories.d.ts +0 -6
  256. package/dist/types/src/components/SyncStatus/InlineSyncStatus.stories.d.ts.map +0 -1
  257. package/src/components/SyncStatus/InlineSyncStatus.stories.tsx +0 -57
@@ -4,92 +4,84 @@
4
4
 
5
5
  import React, { useCallback } from 'react';
6
6
 
7
- import { LayoutAction, NavigationAction, useIntentDispatcher } from '@dxos/app-framework';
8
- import { useGraph } from '@dxos/plugin-graph';
9
- import { ObservabilityAction } from '@dxos/plugin-observability/meta';
10
- import { useSpaces } from '@dxos/react-client/echo';
7
+ import { createIntent, LayoutAction, useAppGraph, useIntentDispatcher } from '@dxos/app-framework';
8
+ import { log } from '@dxos/log';
9
+ import { ObservabilityAction } from '@dxos/plugin-observability/types';
10
+ import { useClient } from '@dxos/react-client';
11
11
  import { type InvitationResult } from '@dxos/react-client/invitations';
12
- import { Dialog, useTranslation } from '@dxos/react-ui';
12
+ import { Dialog } from '@dxos/react-ui';
13
13
  import { JoinPanel, type JoinPanelProps } from '@dxos/shell/react';
14
14
 
15
15
  import { SPACE_PLUGIN } from '../meta';
16
16
 
17
+ export const JOIN_DIALOG = `${SPACE_PLUGIN}/JoinDialog`;
18
+
17
19
  export type JoinDialogProps = JoinPanelProps & {
18
20
  navigableCollections?: boolean;
19
21
  };
20
22
 
21
23
  export const JoinDialog = ({ navigableCollections, onDone, ...props }: JoinDialogProps) => {
22
- const { t } = useTranslation(SPACE_PLUGIN);
23
- const dispatch = useIntentDispatcher();
24
- const spaces = useSpaces();
25
- const { graph } = useGraph();
24
+ const { dispatchPromise: dispatch } = useIntentDispatcher();
25
+ const client = useClient();
26
+ const { graph } = useAppGraph();
26
27
 
27
28
  const handleDone = useCallback(
28
29
  async (result: InvitationResult | null) => {
29
30
  if (result?.spaceKey) {
30
31
  await Promise.all([
31
- dispatch({
32
- action: LayoutAction.SET_LAYOUT,
33
- data: {
34
- element: 'toast',
32
+ dispatch(
33
+ createIntent(LayoutAction.AddToast, {
34
+ part: 'toast',
35
35
  subject: {
36
36
  id: `${SPACE_PLUGIN}/join-success`,
37
37
  duration: 5_000,
38
- title: t('join success label'),
39
- closeLabel: t('dismiss label'),
38
+ title: ['join success label', { ns: SPACE_PLUGIN }],
39
+ closeLabel: ['dismiss label', { ns: SPACE_PLUGIN }],
40
+ },
41
+ }),
42
+ ),
43
+ dispatch(
44
+ createIntent(LayoutAction.UpdateDialog, {
45
+ part: 'dialog',
46
+ options: {
47
+ state: false,
40
48
  },
41
- },
42
- }),
43
- dispatch({
44
- action: LayoutAction.SET_LAYOUT,
45
- data: {
46
- element: 'dialog',
47
- state: false,
48
- },
49
- }),
49
+ }),
50
+ ),
50
51
  ]);
51
52
  }
52
53
 
53
- const space = spaces.find(({ key }) => result?.spaceKey?.equals(key));
54
+ const space = result?.spaceKey ? client.spaces.get(result.spaceKey) : undefined;
55
+ if (!space) {
56
+ log.warn('Space not found', result?.spaceKey);
57
+ return;
58
+ }
59
+
60
+ await dispatch(createIntent(LayoutAction.SwitchWorkspace, { part: 'workspace', subject: space.id }));
61
+
54
62
  // TODO(wittjosiah): If navigableCollections is false and there's no target,
55
63
  // should try to navigate to the first object of the space replicates.
56
64
  // Potentially this could also be done on the inviters side to ensure there's always a target.
57
65
  const target = result?.target || (navigableCollections ? space?.id : undefined);
58
66
  if (target) {
59
- // Wait for up to 1 second before navigating to the target node.
67
+ // Wait before navigating to the target node.
60
68
  // If the target has not yet replicated, this will trigger a loading toast.
61
69
  await graph.waitForPath({ target }).catch(() => {});
62
70
  await Promise.all([
63
- dispatch({
64
- action: NavigationAction.OPEN,
65
- data: {
66
- activeParts: { main: [target] },
67
- },
68
- }),
69
- dispatch({
70
- action: NavigationAction.EXPOSE,
71
- data: {
72
- id: target,
73
- },
74
- }),
71
+ dispatch(createIntent(LayoutAction.Open, { part: 'main', subject: [target] })),
72
+ dispatch(createIntent(LayoutAction.Expose, { part: 'navigation', subject: target })),
75
73
  ]);
76
74
  }
77
75
 
78
76
  await onDone?.(result);
79
77
 
80
78
  if (space) {
81
- await dispatch({
82
- action: ObservabilityAction.SEND_EVENT,
83
- data: {
84
- name: 'space.join',
85
- properties: {
86
- spaceId: space.id,
87
- },
88
- },
89
- });
79
+ await dispatch(
80
+ createIntent(ObservabilityAction.SendEvent, { name: 'space.join', properties: { spaceId: space.id } }),
81
+ );
90
82
  }
91
83
  },
92
- [dispatch, spaces],
84
+ [dispatch, client, graph],
93
85
  );
94
86
 
95
87
  return (
@@ -76,7 +76,7 @@ export const PersistenceStatus = ({ db }: { db: EchoDatabase }) => {
76
76
  )}
77
77
  </Tooltip.Trigger>
78
78
  <Tooltip.Portal>
79
- <Tooltip.Content classNames='z-10'>
79
+ <Tooltip.Content>
80
80
  {t('persisted locally message')}
81
81
  <Tooltip.Arrow />
82
82
  </Tooltip.Content>
@@ -10,6 +10,8 @@ import { Button, Input, Popover, useTranslation } from '@dxos/react-ui';
10
10
 
11
11
  import { SPACE_PLUGIN } from '../meta';
12
12
 
13
+ export const POPOVER_RENAME_OBJECT = `${SPACE_PLUGIN}/PopoverRenameObject`;
14
+
13
15
  export const PopoverRenameObject = ({ object: obj }: { object: ReactiveObject<any> }) => {
14
16
  const { t } = useTranslation(SPACE_PLUGIN);
15
17
  const doneButton = useRef<HTMLButtonElement>(null);
@@ -9,6 +9,8 @@ import { Button, Input, Popover, useTranslation } from '@dxos/react-ui';
9
9
 
10
10
  import { SPACE_PLUGIN } from '../meta';
11
11
 
12
+ export const POPOVER_RENAME_SPACE = `${SPACE_PLUGIN}/PopoverRenameSpace`;
13
+
12
14
  export const PopoverRenameSpace = ({ space }: { space: Space }) => {
13
15
  const { t } = useTranslation(SPACE_PLUGIN);
14
16
  const doneButton = useRef<HTMLButtonElement>(null);
@@ -4,16 +4,17 @@
4
4
 
5
5
  import React from 'react';
6
6
 
7
- import { useIntentDispatcher } from '@dxos/app-framework';
7
+ import { createIntent, useIntentDispatcher } from '@dxos/app-framework';
8
8
  import { type Space } from '@dxos/react-client/echo';
9
9
  import { IconButton, useTranslation } from '@dxos/react-ui';
10
10
 
11
- import { SPACE_PLUGIN, SpaceAction } from '../meta';
11
+ import { SPACE_PLUGIN } from '../meta';
12
+ import { SpaceAction } from '../types';
12
13
 
13
14
  export const ShareSpaceButton = ({ space }: { space: Space }) => {
14
- const dispatch = useIntentDispatcher();
15
+ const { dispatchPromise: dispatch } = useIntentDispatcher();
15
16
 
16
- return <ShareSpaceButtonImpl onClick={() => dispatch({ action: SpaceAction.SHARE, data: { space } })} />;
17
+ return <ShareSpaceButtonImpl onClick={() => dispatch(createIntent(SpaceAction.Share, { space }))} />;
17
18
  };
18
19
 
19
20
  // TODO(wittjosiah): Better way to name pure/impure components?
@@ -4,31 +4,20 @@
4
4
 
5
5
  import React from 'react';
6
6
 
7
- import { useIntentDispatcher } from '@dxos/app-framework';
8
7
  import { Input, useTranslation } from '@dxos/react-ui';
9
- import { DeprecatedFormInput } from '@dxos/react-ui-form';
8
+ import { DeprecatedFormContainer, DeprecatedFormInput } from '@dxos/react-ui-form';
10
9
 
11
- import { SpaceAction, SPACE_PLUGIN } from '../meta';
10
+ import { SPACE_PLUGIN } from '../meta';
12
11
  import { type SpaceSettingsProps } from '../types';
13
12
 
14
13
  export const SpacePluginSettings = ({ settings }: { settings: SpaceSettingsProps }) => {
15
14
  const { t } = useTranslation(SPACE_PLUGIN);
16
- const dispatch = useIntentDispatcher();
17
15
 
18
16
  return (
19
- <>
17
+ <DeprecatedFormContainer>
20
18
  <DeprecatedFormInput label={t('show hidden spaces label')}>
21
- <Input.Switch
22
- checked={settings.showHidden}
23
- onCheckedChange={(checked) =>
24
- dispatch({
25
- plugin: SPACE_PLUGIN,
26
- action: SpaceAction.TOGGLE_HIDDEN,
27
- data: { state: !!checked },
28
- })
29
- }
30
- />
19
+ <Input.Switch checked={settings.showHidden} onCheckedChange={(checked) => (settings.showHidden = !!checked)} />
31
20
  </DeprecatedFormInput>
32
- </>
21
+ </DeprecatedFormContainer>
33
22
  );
34
23
  };
@@ -7,7 +7,7 @@ import '@dxos-theme';
7
7
  import { type Meta } from '@storybook/react';
8
8
  import React from 'react';
9
9
 
10
- import { PublicKey } from '@dxos/keys';
10
+ import { IdentityDid, PublicKey } from '@dxos/keys';
11
11
  import { HaloSpaceMember, SpaceMember } from '@dxos/react-client/echo';
12
12
  import { withLayout, withTheme } from '@dxos/storybook-utils';
13
13
 
@@ -17,7 +17,7 @@ import translations from '../translations';
17
17
  const nViewers = (n: number, currentlyAttended = true): Member[] =>
18
18
  Array.from({ length: n }, () => ({
19
19
  role: HaloSpaceMember.Role.ADMIN,
20
- identity: { identityKey: PublicKey.random() },
20
+ identity: { did: IdentityDid.random(), identityKey: PublicKey.random() },
21
21
  presence: SpaceMember.PresenceState.ONLINE,
22
22
  lastSeen: Date.now(),
23
23
  currentlyAttended,
@@ -61,30 +61,38 @@ export const Full = (props: MemberPresenceProps) => {
61
61
  );
62
62
  };
63
63
 
64
- export const Small = (props: MemberPresenceProps) => {
65
- const p: MemberPresenceProps = {
66
- ...props,
67
- };
68
-
64
+ export const Small = () => {
69
65
  return (
70
66
  <div className='p-4'>
71
- <div className='p-3'>
72
- <SmallPresence count={0} {...p} />
67
+ <div className='flex gap-3 p-3'>
68
+ <SmallPresence count={0} />
69
+ <SmallPresence count={0} attended />
70
+ <SmallPresence count={0} containsAttended />
73
71
  </div>
74
- <div className='p-3'>
75
- <SmallPresence count={1} {...p} />
72
+ <div className='flex gap-3 p-3'>
73
+ <SmallPresence count={1} />
74
+ <SmallPresence count={1} attended />
75
+ <SmallPresence count={1} containsAttended />
76
76
  </div>
77
- <div className='p-3'>
78
- <SmallPresence count={2} {...p} />
77
+ <div className='flex gap-3 p-3'>
78
+ <SmallPresence count={2} />
79
+ <SmallPresence count={2} attended />
80
+ <SmallPresence count={2} containsAttended />
79
81
  </div>
80
- <div className='p-3'>
81
- <SmallPresence count={3} {...p} />
82
+ <div className='flex gap-3 p-3'>
83
+ <SmallPresence count={3} />
84
+ <SmallPresence count={3} attended />
85
+ <SmallPresence count={3} containsAttended />
82
86
  </div>
83
- <div className='p-3'>
84
- <SmallPresence count={4} {...p} />
87
+ <div className='flex gap-3 p-3'>
88
+ <SmallPresence count={4} />
89
+ <SmallPresence count={4} attended />
90
+ <SmallPresence count={4} containsAttended />
85
91
  </div>
86
- <div className='p-3'>
87
- <SmallPresence count={5} {...p} />
92
+ <div className='flex gap-3 p-3'>
93
+ <SmallPresence count={5} />
94
+ <SmallPresence count={5} attended />
95
+ <SmallPresence count={5} containsAttended />
88
96
  </div>
89
97
  </div>
90
98
  );
@@ -4,7 +4,7 @@
4
4
 
5
5
  import React, { useCallback, useEffect, useState } from 'react';
6
6
 
7
- import { usePlugin } from '@dxos/app-framework';
7
+ import { useAppGraph, useCapability } from '@dxos/app-framework';
8
8
  import { generateName } from '@dxos/display-name';
9
9
  import { type Expando } from '@dxos/echo-schema';
10
10
  import { PublicKey, useClient } from '@dxos/react-client';
@@ -22,11 +22,13 @@ import {
22
22
  ListItem,
23
23
  useDefaultValue,
24
24
  } from '@dxos/react-ui';
25
- import { AttentionGlyph, useAttention } from '@dxos/react-ui-attention';
25
+ import { AttentionGlyph, useAttended, useAttention, type AttentionGlyphProps } from '@dxos/react-ui-attention';
26
26
  import { ComplexMap, keyToFallback } from '@dxos/util';
27
27
 
28
+ import { SpaceCapabilities } from '../capabilities';
29
+ import { usePath } from '../hooks';
28
30
  import { SPACE_PLUGIN } from '../meta';
29
- import type { ObjectViewerProps, SpacePluginProvides } from '../types';
31
+ import type { ObjectViewerProps } from '../types';
30
32
 
31
33
  // TODO(thure): Get/derive these values from protocol
32
34
  const REFRESH_INTERVAL = 5000;
@@ -39,7 +41,8 @@ const noViewers = new ComplexMap<PublicKey, ObjectViewerProps>(PublicKey.hash);
39
41
  const getName = (identity: Identity) => identity.profile?.displayName ?? generateName(identity.identityKey.toHex());
40
42
 
41
43
  export const SpacePresence = ({ object, spaceKey }: { object: Expando; spaceKey?: PublicKey }) => {
42
- const spacePlugin = usePlugin<SpacePluginProvides>(SPACE_PLUGIN);
44
+ // TODO(wittjosiah): Doesn't need to be mutable but readonly type messes with ComplexMap.
45
+ const spaceState = useCapability(SpaceCapabilities.MutableState);
43
46
  const client = useClient();
44
47
  const identity = useIdentity();
45
48
  const space = spaceKey ? client.spaces.get(spaceKey) : getSpace(object);
@@ -61,11 +64,10 @@ export const SpacePresence = ({ object, spaceKey }: { object: Expando; spaceKey?
61
64
 
62
65
  // TODO(thure): Could it be a smell to return early when there are interactions with `deepSignal` later, since it
63
66
  // prevents reactivity?
64
- if (!identity || !spacePlugin || !space) {
67
+ if (!identity || !spaceState || !space) {
65
68
  return null;
66
69
  }
67
70
 
68
- const spaceState = spacePlugin.provides.space;
69
71
  const currentObjectViewers = spaceState.viewersByObject[fullyQualifiedId(object)] ?? noViewers;
70
72
 
71
73
  const membersForObject = spaceMembers
@@ -194,16 +196,30 @@ const PrensenceAvatar = ({ identity, showName, match, group, index, onClick }: P
194
196
  );
195
197
  };
196
198
 
197
- export const SmallPresenceLive = ({
198
- id,
199
- viewers,
200
- }: {
199
+ export type SmallPresenceLiveProps = {
201
200
  id?: string;
201
+ open?: boolean;
202
202
  viewers?: ComplexMap<PublicKey, ObjectViewerProps>;
203
- }) => {
203
+ };
204
+
205
+ export const SmallPresenceLive = ({ id, open, viewers }: SmallPresenceLiveProps) => {
206
+ const { hasAttention, isAncestor, isRelated } = useAttention(id);
207
+ const isAttended = hasAttention || isAncestor || isRelated;
208
+
209
+ // TODO(wittjosiah): If the attended node is deep in the graph and the graph is not fully loaded
210
+ // this will result in an empty path until the graph is connected.
211
+ // TODO(wittjosiah): Consider using this indicator for all open nodes instead of just attended.
212
+ const { graph } = useAppGraph();
213
+ const attended = useAttended();
214
+ const startOfAttention = attended.at(-1);
215
+ const path = usePath(graph, startOfAttention);
216
+ const containsAttended = !open && !isAttended && id && path ? path.includes(id) : false;
217
+
204
218
  const getActiveViewers = (viewers: ComplexMap<PublicKey, ObjectViewerProps>): ObjectViewerProps[] => {
205
219
  const moment = Date.now();
206
- return Array.from(viewers.values()).filter(({ lastSeen }) => moment - lastSeen < ACTIVITY_DURATION);
220
+ return Array.from<ObjectViewerProps>(viewers.values()).filter(
221
+ (viewer) => moment - viewer.lastSeen < ACTIVITY_DURATION,
222
+ );
207
223
  };
208
224
 
209
225
  const [activeViewers, setActiveViewers] = useState(viewers ? getActiveViewers(viewers) : []);
@@ -218,24 +234,28 @@ export const SmallPresenceLive = ({
218
234
  }
219
235
  }, [viewers]);
220
236
 
221
- return <SmallPresence id={id} count={activeViewers.length} />;
237
+ return <SmallPresence count={activeViewers.length} attended={isAttended} containsAttended={containsAttended} />;
222
238
  };
223
239
 
224
- export const SmallPresence = ({ id, count }: { id?: string; count: number }) => {
240
+ export type SmallPresenceProps = {
241
+ count?: number;
242
+ } & Pick<AttentionGlyphProps, 'attended' | 'containsAttended'>;
243
+
244
+ export const SmallPresence = ({ count = 0, attended, containsAttended }: SmallPresenceProps) => {
225
245
  const { t } = useTranslation(SPACE_PLUGIN);
226
- const { hasAttention, isAncestor, isRelated } = useAttention(id);
227
- const attention = hasAttention || isAncestor || isRelated;
228
246
 
229
247
  return (
230
248
  <Tooltip.Root>
231
249
  <Tooltip.Trigger asChild>
232
- {/* TODO(wittjosiah): Don't depend on data attribute just pass prop to AttentionGlyph. */}
233
- <div role='none' className='flex' data-attention={attention}>
234
- <AttentionGlyph presence={count > 1 ? 'many' : count === 1 ? 'one' : 'none'} classNames='self-center mie-1' />
235
- </div>
250
+ <AttentionGlyph
251
+ attended={attended}
252
+ containsAttended={containsAttended}
253
+ presence={count > 1 ? 'many' : count === 1 ? 'one' : 'none'}
254
+ classNames='self-center mie-1'
255
+ />
236
256
  </Tooltip.Trigger>
237
257
  <Tooltip.Portal>
238
- <Tooltip.Content side='bottom' classNames='z-[70]'>
258
+ <Tooltip.Content side='bottom'>
239
259
  <span>{t('presence label', { count })}</span>
240
260
  <Tooltip.Arrow />
241
261
  </Tooltip.Content>
@@ -7,7 +7,7 @@ import '@dxos-theme';
7
7
  import { type Meta, type StoryObj } from '@storybook/react';
8
8
  import React from 'react';
9
9
 
10
- import { useStoryClientData, withClientProvider } from '@dxos/react-client/testing';
10
+ import { useClientProvider, withClientProvider } from '@dxos/react-client/testing';
11
11
  import { Dialog } from '@dxos/react-ui';
12
12
  import { osTranslations } from '@dxos/shell/react';
13
13
  import { withLayout, withTheme } from '@dxos/storybook-utils';
@@ -16,8 +16,7 @@ import { SpaceSettingsDialog, type SpaceSettingsDialogProps } from './SpaceSetti
16
16
  import translations from '../../translations';
17
17
 
18
18
  const Story = (args: Partial<SpaceSettingsDialogProps>) => {
19
- const { space } = useStoryClientData();
20
-
19
+ const { space } = useClientProvider();
21
20
  return (
22
21
  <Dialog.Root open>
23
22
  <Dialog.Overlay blockAlign='start'>
@@ -2,17 +2,21 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import React, { useState } from 'react';
5
+ import React, { useMemo, useState } from 'react';
6
6
 
7
+ import { Surface, useCapabilities } from '@dxos/app-framework';
7
8
  import { useClient } from '@dxos/react-client';
8
9
  import { Button, Clipboard, Dialog, Icon, toLocalizedString, useTranslation } from '@dxos/react-ui';
9
10
  import { Tabs, type TabsRootProps, type TabsActivePart } from '@dxos/react-ui-tabs';
10
11
  import { SpacePanel, type SpacePanelProps } from '@dxos/shell/react';
11
12
 
12
13
  import { SpaceSettingsPanel, type SpaceSettingsPanelProps } from './SpaceSettingsPanel';
14
+ import { SpaceCapabilities } from '../../capabilities';
13
15
  import { SPACE_PLUGIN } from '../../meta';
14
16
  import { COMPOSER_SPACE_LOCK, getSpaceDisplayName } from '../../util';
15
17
 
18
+ export const SPACE_SETTINGS_DIALOG = `${SPACE_PLUGIN}/SpaceSettingsDialog`;
19
+
16
20
  export type SpaceSettingsTab = 'members' | 'settings';
17
21
 
18
22
  export type SpaceSettingsDialogProps = {
@@ -34,12 +38,14 @@ export const SpaceSettingsDialog = ({
34
38
  const [selected, setSelected] = useState<SpaceSettingsTab>(initialTab);
35
39
  const locked = space.properties[COMPOSER_SPACE_LOCK];
36
40
  const name = getSpaceDisplayName(space, { personal: client.spaces.default === space, namesCache });
41
+ const panels = useCapabilities(SpaceCapabilities.SettingsPanel);
42
+ const data = useMemo(() => ({ subject: space }), [space]);
37
43
 
38
44
  return (
39
45
  // TODO(wittjosiah): The tablist dialog pattern is copied from @dxos/plugin-manager.
40
46
  // Consider factoring it out to the tabs package.
41
47
  <Dialog.Content classNames='p-0 bs-content min-bs-[15rem] max-bs-full md:max-is-[40rem] overflow-hidden'>
42
- <div role='none' className='flex justify-between pbs-3 pis-2 pie-3 @md:pbs-4 @md:pis-4 @md:pie-5'>
48
+ <div role='none' className='flex justify-between pbs-2 pis-2 pie-2 @md:pbs-4 @md:pis-4 @md:pie-4'>
43
49
  <Dialog.Title
44
50
  onClick={() => setTabsActivePart('list')}
45
51
  aria-description={t('click to return to tablist description')}
@@ -82,6 +88,11 @@ export const SpaceSettingsDialog = ({
82
88
  <Tabs.Tab value='members' disabled={locked}>
83
89
  {t('members tab label')}
84
90
  </Tabs.Tab>
91
+ {panels.map((panel) => (
92
+ <Tabs.Tab key={panel.id} value={panel.id}>
93
+ {toLocalizedString(panel.label, t)}
94
+ </Tabs.Tab>
95
+ ))}
85
96
  </div>
86
97
  </Tabs.Tablist>
87
98
  </div>
@@ -96,6 +107,12 @@ export const SpaceSettingsDialog = ({
96
107
  <SpacePanel space={space} hideHeading target={target} createInvitationUrl={createInvitationUrl} />
97
108
  </Clipboard.Provider>
98
109
  </Tabs.Tabpanel>
110
+
111
+ {panels.map((panel) => (
112
+ <Tabs.Tabpanel key={panel.id} value={panel.id} classNames='pli-3 @md:pli-5 max-bs-dvh overflow-y-auto'>
113
+ <Surface role={`space-settings--${panel.id}`} data={data} />
114
+ </Tabs.Tabpanel>
115
+ ))}
99
116
  </Tabs.Viewport>
100
117
  </Tabs.Root>
101
118
  </Dialog.Content>
@@ -7,16 +7,15 @@ import '@dxos-theme';
7
7
  import { type Meta, type StoryObj } from '@storybook/react';
8
8
  import React from 'react';
9
9
 
10
- import { useStoryClientData, withClientProvider } from '@dxos/react-client/testing';
10
+ import { useClientProvider, withClientProvider } from '@dxos/react-client/testing';
11
11
  import { withTheme } from '@dxos/storybook-utils';
12
12
 
13
13
  import { SpaceSettingsPanel, type SpaceSettingsPanelProps } from './SpaceSettingsPanel';
14
14
  import translations from '../../translations';
15
15
 
16
16
  const Story = (args: Partial<SpaceSettingsPanelProps>) => {
17
- const { space } = useStoryClientData();
18
-
19
- return <SpaceSettingsPanel {...args} space={space!} />;
17
+ const { space } = useClientProvider();
18
+ return <SpaceSettingsPanel {...args} space={space!} classNames='p-2 border border-primary-500 rounded' />;
20
19
  };
21
20
 
22
21
  const meta: Meta = {
@@ -24,7 +23,10 @@ const meta: Meta = {
24
23
  component: SpaceSettingsPanel,
25
24
  render: Story,
26
25
  decorators: [withClientProvider({ createIdentity: true, createSpace: true }), withTheme],
27
- parameters: { translations },
26
+ parameters: {
27
+ translations,
28
+ layout: 'centered',
29
+ },
28
30
  };
29
31
 
30
32
  export default meta;
@@ -8,16 +8,16 @@ import { log } from '@dxos/log';
8
8
  import { EdgeReplicationSetting } from '@dxos/protocols/proto/dxos/echo/metadata';
9
9
  import { useClient } from '@dxos/react-client';
10
10
  import { type Space } from '@dxos/react-client/echo';
11
- import { Input, useTranslation } from '@dxos/react-ui';
12
- import { DeprecatedFormInput } from '@dxos/react-ui-form';
11
+ import { type ThemedClassName, Input, useTranslation } from '@dxos/react-ui';
12
+ import { DeprecatedFormContainer, DeprecatedFormInput } from '@dxos/react-ui-form';
13
13
 
14
14
  import { SPACE_PLUGIN } from '../../meta';
15
15
 
16
- export type SpaceSettingsPanelProps = {
16
+ export type SpaceSettingsPanelProps = ThemedClassName<{
17
17
  space: Space;
18
- };
18
+ }>;
19
19
 
20
- export const SpaceSettingsPanel = ({ space }: SpaceSettingsPanelProps) => {
20
+ export const SpaceSettingsPanel = ({ classNames, space }: SpaceSettingsPanelProps) => {
21
21
  const { t } = useTranslation(SPACE_PLUGIN);
22
22
 
23
23
  const client = useClient();
@@ -40,7 +40,7 @@ export const SpaceSettingsPanel = ({ space }: SpaceSettingsPanelProps) => {
40
40
  );
41
41
 
42
42
  return (
43
- <div role='form' className='flex flex-col'>
43
+ <DeprecatedFormContainer>
44
44
  <DeprecatedFormInput label={t('name label')}>
45
45
  <Input.TextInput
46
46
  placeholder={t('unnamed space label')}
@@ -55,6 +55,6 @@ export const SpaceSettingsPanel = ({ space }: SpaceSettingsPanelProps) => {
55
55
  <Input.Switch checked={edgeReplication} onCheckedChange={toggleEdgeReplication} />
56
56
  </DeprecatedFormInput>
57
57
  )}
58
- </div>
58
+ </DeprecatedFormContainer>
59
59
  );
60
60
  };