@dxos/plugin-space 0.7.5-main.9d2a38b → 0.7.5-main.e94eead

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 (251) hide show
  1. package/dist/lib/browser/{app-graph-builder-F6XSETHX.mjs → app-graph-builder-MGK5HWPZ.mjs} +26 -103
  2. package/dist/lib/browser/app-graph-builder-MGK5HWPZ.mjs.map +7 -0
  3. package/dist/lib/browser/{app-graph-serializer-FYJE23GN.mjs → app-graph-serializer-FOWFLYGU.mjs} +5 -5
  4. package/dist/lib/browser/{chunk-IZ7QKQ2E.mjs → chunk-23RVI5FZ.mjs} +27 -11
  5. package/dist/lib/browser/chunk-23RVI5FZ.mjs.map +7 -0
  6. package/dist/lib/browser/{chunk-UH5P4UL3.mjs → chunk-NU7WDVGN.mjs} +4 -2
  7. package/dist/lib/browser/chunk-NU7WDVGN.mjs.map +7 -0
  8. package/dist/lib/browser/{chunk-SOXNANA6.mjs → chunk-PQXZCNAU.mjs} +3 -2
  9. package/dist/lib/browser/{chunk-SOXNANA6.mjs.map → chunk-PQXZCNAU.mjs.map} +3 -3
  10. package/dist/lib/browser/{chunk-XXD33C4E.mjs → chunk-S6B7627U.mjs} +486 -349
  11. package/dist/lib/browser/chunk-S6B7627U.mjs.map +7 -0
  12. package/dist/lib/browser/{chunk-T36CIHPG.mjs → chunk-UDWHTKB5.mjs} +7 -4
  13. package/dist/lib/browser/chunk-UDWHTKB5.mjs.map +7 -0
  14. package/dist/lib/browser/{chunk-SSJ772GK.mjs → chunk-ULA2UQJ4.mjs} +18 -5
  15. package/dist/lib/browser/chunk-ULA2UQJ4.mjs.map +7 -0
  16. package/dist/lib/browser/{identity-created-4Q4PFIC5.mjs → identity-created-FYGS6TBH.mjs} +3 -3
  17. package/dist/lib/browser/index.mjs +59 -24
  18. package/dist/lib/browser/index.mjs.map +3 -3
  19. package/dist/lib/browser/intent-resolver-QVR4MSJV.mjs +555 -0
  20. package/dist/lib/browser/intent-resolver-QVR4MSJV.mjs.map +7 -0
  21. package/dist/lib/browser/meta.json +1 -1
  22. package/dist/lib/browser/{react-root-BDOPFJGJ.mjs → react-root-IP2ZB245.mjs} +6 -6
  23. package/dist/lib/browser/{react-surface-EGOL2JBL.mjs → react-surface-BT3EHB6V.mjs} +36 -49
  24. package/dist/lib/browser/react-surface-BT3EHB6V.mjs.map +7 -0
  25. package/dist/lib/browser/schema-5W3DSY2E.mjs +24 -0
  26. package/dist/lib/browser/schema-5W3DSY2E.mjs.map +7 -0
  27. package/dist/lib/browser/{settings-WF67QZSD.mjs → settings-PHPCXX33.mjs} +3 -3
  28. package/dist/lib/browser/{spaces-ready-WVU7US3C.mjs → spaces-ready-K47RR7N2.mjs} +31 -32
  29. package/dist/lib/browser/spaces-ready-K47RR7N2.mjs.map +7 -0
  30. package/dist/lib/browser/{state-MS4KYJWI.mjs → state-INJ63O57.mjs} +3 -3
  31. package/dist/lib/browser/types/index.mjs +6 -4
  32. package/dist/lib/node/{app-graph-builder-GKLVZ4PM.cjs → app-graph-builder-ZIUBXRPA.cjs} +59 -136
  33. package/dist/lib/node/app-graph-builder-ZIUBXRPA.cjs.map +7 -0
  34. package/dist/lib/node/{app-graph-serializer-RMTU5YSC.cjs → app-graph-serializer-VQOGHKXL.cjs} +21 -21
  35. package/dist/lib/node/{chunk-AJRP7AD6.cjs → chunk-N2FS7PRA.cjs} +552 -414
  36. package/dist/lib/node/chunk-N2FS7PRA.cjs.map +7 -0
  37. package/dist/lib/node/{chunk-5D4RWKTV.cjs → chunk-OVGKWJOC.cjs} +78 -62
  38. package/dist/lib/node/chunk-OVGKWJOC.cjs.map +7 -0
  39. package/dist/lib/node/{chunk-UENH2YBM.cjs → chunk-U6DYXAR3.cjs} +12 -9
  40. package/dist/lib/node/chunk-U6DYXAR3.cjs.map +7 -0
  41. package/dist/lib/node/{chunk-YCBBGTFD.cjs → chunk-WAJKBO3J.cjs} +25 -11
  42. package/dist/lib/node/chunk-WAJKBO3J.cjs.map +7 -0
  43. package/dist/lib/node/{chunk-AO4EW2RX.cjs → chunk-WZR6OAN3.cjs} +6 -5
  44. package/dist/lib/node/{chunk-AO4EW2RX.cjs.map → chunk-WZR6OAN3.cjs.map} +3 -3
  45. package/dist/lib/node/{chunk-56NGXG2A.cjs → chunk-YZKNRFHU.cjs} +10 -8
  46. package/dist/lib/node/chunk-YZKNRFHU.cjs.map +7 -0
  47. package/dist/lib/node/{identity-created-QQWX7WX3.cjs → identity-created-AXI64BLE.cjs} +7 -7
  48. package/dist/lib/node/index.cjs +132 -98
  49. package/dist/lib/node/index.cjs.map +3 -3
  50. package/dist/lib/node/intent-resolver-MLENGECT.cjs +553 -0
  51. package/dist/lib/node/intent-resolver-MLENGECT.cjs.map +7 -0
  52. package/dist/lib/node/meta.json +1 -1
  53. package/dist/lib/node/{react-root-ZTR2J2I3.cjs → react-root-3OX5Z5CX.cjs} +12 -12
  54. package/dist/lib/node/{react-surface-75KRPQYT.cjs → react-surface-5NYCMXSM.cjs} +77 -89
  55. package/dist/lib/node/react-surface-5NYCMXSM.cjs.map +7 -0
  56. package/dist/lib/node/schema-YN7WVFRX.cjs +40 -0
  57. package/dist/lib/node/schema-YN7WVFRX.cjs.map +7 -0
  58. package/dist/lib/node/{settings-KOVSPA3S.cjs → settings-5QYFWNH7.cjs} +8 -8
  59. package/dist/lib/node/{spaces-ready-ILVGUHJH.cjs → spaces-ready-FQNAKR7G.cjs} +39 -40
  60. package/dist/lib/node/spaces-ready-FQNAKR7G.cjs.map +7 -0
  61. package/dist/lib/node/{state-4UIOUKLJ.cjs → state-57UE3DYE.cjs} +8 -8
  62. package/dist/lib/node/types/index.cjs +19 -17
  63. package/dist/lib/node/types/index.cjs.map +2 -2
  64. package/dist/lib/node-esm/{app-graph-builder-NEHQ5Z63.mjs → app-graph-builder-TERVM2SL.mjs} +26 -103
  65. package/dist/lib/node-esm/app-graph-builder-TERVM2SL.mjs.map +7 -0
  66. package/dist/lib/node-esm/{app-graph-serializer-UWWS5OVC.mjs → app-graph-serializer-GZRSWHEN.mjs} +5 -5
  67. package/dist/lib/node-esm/{chunk-E5DWIQ3N.mjs → chunk-2TQ2AJEZ.mjs} +7 -4
  68. package/dist/lib/node-esm/chunk-2TQ2AJEZ.mjs.map +7 -0
  69. package/dist/lib/node-esm/{chunk-375RB3CZ.mjs → chunk-6RSVVEPS.mjs} +4 -2
  70. package/dist/lib/node-esm/chunk-6RSVVEPS.mjs.map +7 -0
  71. package/dist/lib/node-esm/{chunk-GVOPDPS2.mjs → chunk-DIKRH2IK.mjs} +486 -349
  72. package/dist/lib/node-esm/chunk-DIKRH2IK.mjs.map +7 -0
  73. package/dist/lib/node-esm/{chunk-7FUVU45N.mjs → chunk-ICCM4YRJ.mjs} +3 -2
  74. package/dist/lib/node-esm/{chunk-7FUVU45N.mjs.map → chunk-ICCM4YRJ.mjs.map} +3 -3
  75. package/dist/lib/node-esm/{chunk-5QMAPAZD.mjs → chunk-PGH5L7MV.mjs} +27 -11
  76. package/dist/lib/node-esm/chunk-PGH5L7MV.mjs.map +7 -0
  77. package/dist/lib/node-esm/{chunk-HTBGWQEU.mjs → chunk-TRNZQEEN.mjs} +18 -5
  78. package/dist/lib/node-esm/chunk-TRNZQEEN.mjs.map +7 -0
  79. package/dist/lib/node-esm/{identity-created-HMNY2MPB.mjs → identity-created-3CGEXNPO.mjs} +3 -3
  80. package/dist/lib/node-esm/index.mjs +59 -24
  81. package/dist/lib/node-esm/index.mjs.map +3 -3
  82. package/dist/lib/node-esm/intent-resolver-BLW4RM6X.mjs +556 -0
  83. package/dist/lib/node-esm/intent-resolver-BLW4RM6X.mjs.map +7 -0
  84. package/dist/lib/node-esm/meta.json +1 -1
  85. package/dist/lib/node-esm/{react-root-OUPJA4RY.mjs → react-root-7XXGP56B.mjs} +6 -6
  86. package/dist/lib/node-esm/{react-surface-7EVWCKIP.mjs → react-surface-R2ECJSFB.mjs} +36 -49
  87. package/dist/lib/node-esm/react-surface-R2ECJSFB.mjs.map +7 -0
  88. package/dist/lib/node-esm/schema-LOR2EVGY.mjs +25 -0
  89. package/dist/lib/node-esm/schema-LOR2EVGY.mjs.map +7 -0
  90. package/dist/lib/node-esm/{settings-EDK6WI3V.mjs → settings-H6MXTEQM.mjs} +3 -3
  91. package/dist/lib/node-esm/{spaces-ready-CH3W7OGN.mjs → spaces-ready-HKAQG5SA.mjs} +31 -32
  92. package/dist/lib/node-esm/spaces-ready-HKAQG5SA.mjs.map +7 -0
  93. package/dist/lib/node-esm/{state-BMISGQ2O.mjs → state-VYA6OFHD.mjs} +3 -3
  94. package/dist/lib/node-esm/types/index.mjs +6 -4
  95. package/dist/types/src/SpacePlugin.d.ts +5 -1
  96. package/dist/types/src/SpacePlugin.d.ts.map +1 -1
  97. package/dist/types/src/capabilities/app-graph-builder.d.ts +110 -110
  98. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  99. package/dist/types/src/capabilities/capabilities.d.ts +8 -1
  100. package/dist/types/src/capabilities/capabilities.d.ts.map +1 -1
  101. package/dist/types/src/capabilities/index.d.ts +123 -121
  102. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  103. package/dist/types/src/capabilities/intent-resolver.d.ts +2 -1
  104. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
  105. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  106. package/dist/types/src/capabilities/schema.d.ts +4 -0
  107. package/dist/types/src/capabilities/schema.d.ts.map +1 -0
  108. package/dist/types/src/capabilities/spaces-ready.d.ts.map +1 -1
  109. package/dist/types/src/components/AdvancedObjectSettings/AdvancedObjectSettings.d.ts +1 -2
  110. package/dist/types/src/components/AdvancedObjectSettings/AdvancedObjectSettings.d.ts.map +1 -1
  111. package/dist/types/src/components/AdvancedObjectSettings/ForeignKeys.d.ts +1 -2
  112. package/dist/types/src/components/AdvancedObjectSettings/ForeignKeys.d.ts.map +1 -1
  113. package/dist/types/src/components/AwaitingObject.d.ts +1 -2
  114. package/dist/types/src/components/AwaitingObject.d.ts.map +1 -1
  115. package/dist/types/src/components/BaseObjectSettings.d.ts +1 -2
  116. package/dist/types/src/components/BaseObjectSettings.d.ts.map +1 -1
  117. package/dist/types/src/components/CollectionMain.d.ts +1 -2
  118. package/dist/types/src/components/CollectionMain.d.ts.map +1 -1
  119. package/dist/types/src/components/CollectionSection.d.ts +1 -2
  120. package/dist/types/src/components/CollectionSection.d.ts.map +1 -1
  121. package/dist/types/src/components/CreateDialog/CreateObjectDialog.d.ts +2 -4
  122. package/dist/types/src/components/CreateDialog/CreateObjectDialog.d.ts.map +1 -1
  123. package/dist/types/src/components/CreateDialog/CreateObjectDialog.stories.d.ts.map +1 -1
  124. package/dist/types/src/components/CreateDialog/CreateObjectPanel.d.ts +8 -9
  125. package/dist/types/src/components/CreateDialog/CreateObjectPanel.d.ts.map +1 -1
  126. package/dist/types/src/components/CreateDialog/CreateSpaceDialog.d.ts +1 -2
  127. package/dist/types/src/components/CreateDialog/CreateSpaceDialog.d.ts.map +1 -1
  128. package/dist/types/src/components/JoinDialog.d.ts +1 -2
  129. package/dist/types/src/components/JoinDialog.d.ts.map +1 -1
  130. package/dist/types/src/components/MenuFooter.d.ts +1 -2
  131. package/dist/types/src/components/MenuFooter.d.ts.map +1 -1
  132. package/dist/types/src/components/PersistenceStatus.d.ts +1 -2
  133. package/dist/types/src/components/PersistenceStatus.d.ts.map +1 -1
  134. package/dist/types/src/components/PopoverAddSpace.d.ts +3 -0
  135. package/dist/types/src/components/PopoverAddSpace.d.ts.map +1 -0
  136. package/dist/types/src/components/PopoverRenameObject.d.ts +1 -2
  137. package/dist/types/src/components/PopoverRenameObject.d.ts.map +1 -1
  138. package/dist/types/src/components/PopoverRenameSpace.d.ts +1 -2
  139. package/dist/types/src/components/PopoverRenameSpace.d.ts.map +1 -1
  140. package/dist/types/src/components/ShareSpaceButton.d.ts +2 -3
  141. package/dist/types/src/components/ShareSpaceButton.d.ts.map +1 -1
  142. package/dist/types/src/components/SpacePluginSettings.d.ts +1 -2
  143. package/dist/types/src/components/SpacePluginSettings.d.ts.map +1 -1
  144. package/dist/types/src/components/SpacePresence.d.ts +4 -5
  145. package/dist/types/src/components/SpacePresence.d.ts.map +1 -1
  146. package/dist/types/src/components/SpacePresence.stories.d.ts +2 -3
  147. package/dist/types/src/components/SpacePresence.stories.d.ts.map +1 -1
  148. package/dist/types/src/components/SpaceSettings/SpaceSettingsDialog.d.ts +1 -2
  149. package/dist/types/src/components/SpaceSettings/SpaceSettingsDialog.d.ts.map +1 -1
  150. package/dist/types/src/components/SpaceSettings/SpaceSettingsPanel.d.ts +3 -5
  151. package/dist/types/src/components/SpaceSettings/SpaceSettingsPanel.d.ts.map +1 -1
  152. package/dist/types/src/components/SpaceSettings/SpaceSettingsPanel.stories.d.ts.map +1 -1
  153. package/dist/types/src/components/SyncStatus/InlineSyncStatus.d.ts +1 -2
  154. package/dist/types/src/components/SyncStatus/InlineSyncStatus.d.ts.map +1 -1
  155. package/dist/types/src/components/SyncStatus/Space.d.ts +2 -3
  156. package/dist/types/src/components/SyncStatus/Space.d.ts.map +1 -1
  157. package/dist/types/src/components/SyncStatus/SyncStatus.d.ts +3 -4
  158. package/dist/types/src/components/SyncStatus/SyncStatus.d.ts.map +1 -1
  159. package/dist/types/src/components/index.d.ts +1 -0
  160. package/dist/types/src/components/index.d.ts.map +1 -1
  161. package/dist/types/src/events.d.ts +4 -0
  162. package/dist/types/src/events.d.ts.map +1 -1
  163. package/dist/types/src/index.d.ts +1 -1
  164. package/dist/types/src/index.d.ts.map +1 -1
  165. package/dist/types/src/meta.d.ts +1 -0
  166. package/dist/types/src/meta.d.ts.map +1 -1
  167. package/dist/types/src/translations.d.ts +9 -0
  168. package/dist/types/src/translations.d.ts.map +1 -1
  169. package/dist/types/src/types/collection.d.ts +2 -2
  170. package/dist/types/src/types/thread.d.ts +34 -34
  171. package/dist/types/src/types/types.d.ts +37 -12
  172. package/dist/types/src/types/types.d.ts.map +1 -1
  173. package/dist/types/src/util.d.ts +3 -2
  174. package/dist/types/src/util.d.ts.map +1 -1
  175. package/package.json +41 -38
  176. package/src/SpacePlugin.tsx +44 -15
  177. package/src/capabilities/app-graph-builder.ts +19 -92
  178. package/src/capabilities/capabilities.ts +7 -2
  179. package/src/capabilities/index.ts +1 -0
  180. package/src/capabilities/intent-resolver.ts +428 -312
  181. package/src/capabilities/react-surface.tsx +32 -56
  182. package/src/capabilities/schema.ts +27 -0
  183. package/src/capabilities/spaces-ready.ts +20 -21
  184. package/src/components/AwaitingObject.tsx +5 -5
  185. package/src/components/BaseObjectSettings.tsx +7 -0
  186. package/src/components/CreateDialog/CreateObjectDialog.stories.tsx +1 -3
  187. package/src/components/CreateDialog/CreateObjectDialog.tsx +42 -34
  188. package/src/components/CreateDialog/CreateObjectPanel.tsx +126 -129
  189. package/src/components/CreateDialog/CreateSpaceDialog.tsx +18 -9
  190. package/src/components/JoinDialog.tsx +27 -19
  191. package/src/components/PopoverAddSpace.tsx +46 -0
  192. package/src/components/SpacePluginSettings.tsx +3 -3
  193. package/src/components/SpacePresence.stories.tsx +2 -2
  194. package/src/components/SpacePresence.tsx +2 -3
  195. package/src/components/SpaceSettings/SpaceSettingsDialog.tsx +16 -1
  196. package/src/components/SpaceSettings/SpaceSettingsPanel.stories.tsx +5 -1
  197. package/src/components/SpaceSettings/SpaceSettingsPanel.tsx +30 -8
  198. package/src/components/SyncStatus/InlineSyncStatus.tsx +2 -2
  199. package/src/components/SyncStatus/SyncStatus.tsx +2 -1
  200. package/src/components/index.ts +1 -0
  201. package/src/events.ts +6 -0
  202. package/src/index.ts +1 -1
  203. package/src/meta.ts +1 -0
  204. package/src/translations.ts +3 -0
  205. package/src/types/types.ts +23 -4
  206. package/src/util.tsx +16 -6
  207. package/dist/lib/browser/app-graph-builder-F6XSETHX.mjs.map +0 -7
  208. package/dist/lib/browser/chunk-IZ7QKQ2E.mjs.map +0 -7
  209. package/dist/lib/browser/chunk-SSJ772GK.mjs.map +0 -7
  210. package/dist/lib/browser/chunk-T36CIHPG.mjs.map +0 -7
  211. package/dist/lib/browser/chunk-UH5P4UL3.mjs.map +0 -7
  212. package/dist/lib/browser/chunk-XXD33C4E.mjs.map +0 -7
  213. package/dist/lib/browser/intent-resolver-XRZYCXXX.mjs +0 -459
  214. package/dist/lib/browser/intent-resolver-XRZYCXXX.mjs.map +0 -7
  215. package/dist/lib/browser/react-surface-EGOL2JBL.mjs.map +0 -7
  216. package/dist/lib/browser/spaces-ready-WVU7US3C.mjs.map +0 -7
  217. package/dist/lib/node/app-graph-builder-GKLVZ4PM.cjs.map +0 -7
  218. package/dist/lib/node/chunk-56NGXG2A.cjs.map +0 -7
  219. package/dist/lib/node/chunk-5D4RWKTV.cjs.map +0 -7
  220. package/dist/lib/node/chunk-AJRP7AD6.cjs.map +0 -7
  221. package/dist/lib/node/chunk-UENH2YBM.cjs.map +0 -7
  222. package/dist/lib/node/chunk-YCBBGTFD.cjs.map +0 -7
  223. package/dist/lib/node/intent-resolver-3NI6AUAI.cjs +0 -458
  224. package/dist/lib/node/intent-resolver-3NI6AUAI.cjs.map +0 -7
  225. package/dist/lib/node/react-surface-75KRPQYT.cjs.map +0 -7
  226. package/dist/lib/node/spaces-ready-ILVGUHJH.cjs.map +0 -7
  227. package/dist/lib/node-esm/app-graph-builder-NEHQ5Z63.mjs.map +0 -7
  228. package/dist/lib/node-esm/chunk-375RB3CZ.mjs.map +0 -7
  229. package/dist/lib/node-esm/chunk-5QMAPAZD.mjs.map +0 -7
  230. package/dist/lib/node-esm/chunk-E5DWIQ3N.mjs.map +0 -7
  231. package/dist/lib/node-esm/chunk-GVOPDPS2.mjs.map +0 -7
  232. package/dist/lib/node-esm/chunk-HTBGWQEU.mjs.map +0 -7
  233. package/dist/lib/node-esm/intent-resolver-P5EVBOGP.mjs +0 -460
  234. package/dist/lib/node-esm/intent-resolver-P5EVBOGP.mjs.map +0 -7
  235. package/dist/lib/node-esm/react-surface-7EVWCKIP.mjs.map +0 -7
  236. package/dist/lib/node-esm/spaces-ready-CH3W7OGN.mjs.map +0 -7
  237. /package/dist/lib/browser/{app-graph-serializer-FYJE23GN.mjs.map → app-graph-serializer-FOWFLYGU.mjs.map} +0 -0
  238. /package/dist/lib/browser/{identity-created-4Q4PFIC5.mjs.map → identity-created-FYGS6TBH.mjs.map} +0 -0
  239. /package/dist/lib/browser/{react-root-BDOPFJGJ.mjs.map → react-root-IP2ZB245.mjs.map} +0 -0
  240. /package/dist/lib/browser/{settings-WF67QZSD.mjs.map → settings-PHPCXX33.mjs.map} +0 -0
  241. /package/dist/lib/browser/{state-MS4KYJWI.mjs.map → state-INJ63O57.mjs.map} +0 -0
  242. /package/dist/lib/node/{app-graph-serializer-RMTU5YSC.cjs.map → app-graph-serializer-VQOGHKXL.cjs.map} +0 -0
  243. /package/dist/lib/node/{identity-created-QQWX7WX3.cjs.map → identity-created-AXI64BLE.cjs.map} +0 -0
  244. /package/dist/lib/node/{react-root-ZTR2J2I3.cjs.map → react-root-3OX5Z5CX.cjs.map} +0 -0
  245. /package/dist/lib/node/{settings-KOVSPA3S.cjs.map → settings-5QYFWNH7.cjs.map} +0 -0
  246. /package/dist/lib/node/{state-4UIOUKLJ.cjs.map → state-57UE3DYE.cjs.map} +0 -0
  247. /package/dist/lib/node-esm/{app-graph-serializer-UWWS5OVC.mjs.map → app-graph-serializer-GZRSWHEN.mjs.map} +0 -0
  248. /package/dist/lib/node-esm/{identity-created-HMNY2MPB.mjs.map → identity-created-3CGEXNPO.mjs.map} +0 -0
  249. /package/dist/lib/node-esm/{react-root-OUPJA4RY.mjs.map → react-root-7XXGP56B.mjs.map} +0 -0
  250. /package/dist/lib/node-esm/{settings-EDK6WI3V.mjs.map → settings-H6MXTEQM.mjs.map} +0 -0
  251. /package/dist/lib/node-esm/{state-BMISGQ2O.mjs.map → state-VYA6OFHD.mjs.map} +0 -0
@@ -2,35 +2,22 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import React, { useCallback, useMemo, useState } from 'react';
5
+ import React, { useCallback, useState } from 'react';
6
6
 
7
7
  import { Surface, isSurfaceAvailable, usePluginManager } 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, type InputProps } from '@dxos/react-ui-form';
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
- spaces: Space[];
22
- typename?: string;
23
- target?: Space | CollectionType;
24
- name?: string;
25
- defaultSpaceId?: SpaceId;
26
- resolve?: (typename: string) => Record<string, any>;
27
- onCreateObject?: (params: {
28
- schema: TypedObject;
29
- target: Space | CollectionType;
30
- data: Record<string, any>;
31
- }) => MaybePromise<void>;
32
- };
33
-
34
21
  // TODO(ZaymonFC): Move this if you find yourself needing it elsewhere.
35
22
  /**
36
23
  * Creates a surface input component based on plugin context.
@@ -41,9 +28,8 @@ const useInputSurfaceLookup = (baseData?: Record<string, any>) => {
41
28
  const pluginManager = usePluginManager();
42
29
 
43
30
  return useCallback(
44
- ({ prop, schema, inputProps }: { prop: string; schema: S.Schema<any>; inputProps: InputProps<any> }) => {
31
+ ({ prop, schema, inputProps }: { prop: string; schema: S.Schema<any>; inputProps: InputProps }) => {
45
32
  const composedData = { prop, schema, ...baseData };
46
-
47
33
  if (!isSurfaceAvailable(pluginManager.context, { role: 'form-input', data: composedData })) {
48
34
  return undefined;
49
35
  }
@@ -54,8 +40,24 @@ const useInputSurfaceLookup = (baseData?: Record<string, any>) => {
54
40
  );
55
41
  };
56
42
 
43
+ export type CreateObjectPanelProps = ThemedClassName<{
44
+ forms: ObjectForm[];
45
+ spaces: Space[];
46
+ typename?: string;
47
+ target?: Space | CollectionType;
48
+ name?: string;
49
+ defaultSpaceId?: SpaceId;
50
+ resolve?: (typename: string) => Record<string, any>;
51
+ onCreateObject?: (params: {
52
+ form: ObjectForm;
53
+ target: Space | CollectionType;
54
+ data?: Record<string, any>;
55
+ }) => MaybePromise<void>;
56
+ }>;
57
+
57
58
  export const CreateObjectPanel = ({
58
- schemas,
59
+ classNames,
60
+ forms,
59
61
  spaces,
60
62
  typename: initialTypename,
61
63
  target: initialTarget,
@@ -67,140 +69,135 @@ export const CreateObjectPanel = ({
67
69
  const { t } = useTranslation(SPACE_PLUGIN);
68
70
  const [typename, setTypename] = useState<string | undefined>(initialTypename);
69
71
  const [target, setTarget] = useState<Space | CollectionType | undefined>(initialTarget);
70
- const schema = schemas.find((schema) => getObjectAnnotation(schema)?.typename === typename);
71
- const options = schemas.map(getObjectAnnotation).filter(nonNullable);
72
-
73
- const handleClearSchema = useCallback(() => setTypename(undefined), []);
74
- 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
+ });
75
81
 
76
82
  const handleCreateObject = useCallback(
77
83
  async (props: Record<string, any>) => {
78
- if (!schema || !target) {
84
+ if (!form || !target) {
79
85
  return;
80
86
  }
81
- await onCreateObject?.({ schema, target, data: props });
87
+ await onCreateObject?.({ form, target, data: props });
82
88
  },
83
- [onCreateObject, schema, target],
89
+ [onCreateObject, form, target],
84
90
  );
85
91
 
86
- const metadata = useMemo(() => {
87
- if (!typename) {
88
- return;
89
- }
90
- return resolve?.(typename);
91
- }, [resolve, typename]);
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
+ }
101
+ },
102
+ [forms, onCreateObject, target],
103
+ );
92
104
 
93
- // TODO(wittjosiah): All of these inputs should be rolled into a `Form` once it supports the necessary variants.
94
- const schemaInput = (
95
- <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'>
96
138
  <SearchList.Input
97
139
  autoFocus
98
- data-testid='create-object-form.schema-input'
99
- placeholder={t('schema input placeholder')}
140
+ data-testid='create-object-form.space-input'
141
+ placeholder={t('space input placeholder')}
100
142
  classNames='px-1 my-2'
101
143
  />
102
144
  <SearchList.Content classNames='max-bs-[24rem] overflow-auto'>
103
- {options.map((option) => (
104
- <SearchList.Item
105
- key={option.typename}
106
- value={t('typename label', { ns: option.typename, defaultValue: option.typename })}
107
- onSelect={() => setTypename(option.typename)}
108
- classNames='flex items-center gap-2'
109
- >
110
- <span className='flex gap-2 items-center grow truncate'>
111
- <Icon icon={resolve?.(option.typename).icon ?? 'ph--placeholder--regular'} size={5} />
112
- {t('typename label', { ns: option.typename, defaultValue: option.typename })}
113
- </span>
114
- </SearchList.Item>
115
- ))}
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
+ ))}
116
163
  </SearchList.Content>
117
164
  </SearchList.Root>
118
165
  );
166
+ };
119
167
 
120
- const spaceInput = (
121
- <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'>
122
180
  <SearchList.Input
123
181
  autoFocus
124
- data-testid='create-object-form.space-input'
125
- placeholder={t('space input placeholder')}
182
+ data-testid='create-object-form.schema-input'
183
+ placeholder={t('schema input placeholder')}
126
184
  classNames='px-1 my-2'
127
185
  />
128
186
  <SearchList.Content classNames='max-bs-[24rem] overflow-auto'>
129
- {spaces.map((space) => (
187
+ {options.map((option) => (
130
188
  <SearchList.Item
131
- key={space.id}
132
- value={toLocalizedString(getSpaceDisplayName(space, { personal: space.id === defaultSpaceId }), t)}
133
- onSelect={() => setTarget(space)}
189
+ key={option.typename}
190
+ value={t('typename label', { ns: option.typename, defaultValue: option.typename })}
191
+ onSelect={() => onChange(option.typename)}
134
192
  classNames='flex items-center gap-2'
135
193
  >
136
- <span className='grow truncate'>
137
- {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 })}
138
197
  </span>
139
198
  </SearchList.Item>
140
199
  ))}
141
200
  </SearchList.Content>
142
201
  </SearchList.Root>
143
202
  );
144
-
145
- const inputSurfaceLookup = useInputSurfaceLookup({ target });
146
-
147
- const form = useMemo(() => {
148
- // TODO(ZaymonFC): Move this default object creation schema somewhere?
149
- const schema = (metadata?.creationSchema ?? S.Struct({ name: S.optional(S.String) })) as S.Schema<any>;
150
-
151
- return (
152
- <Form
153
- autoFocus
154
- values={{ name: initialName }}
155
- schema={schema}
156
- testId='create-object-form'
157
- onSave={handleCreateObject}
158
- lookupComponent={inputSurfaceLookup}
159
- />
160
- );
161
- }, [initialName, handleCreateObject, metadata]);
162
-
163
- return (
164
- <div role='form' className='flex flex-col gap-2'>
165
- {target && (
166
- <div role='none'>
167
- <Input.Root>
168
- <InputHeader>
169
- <Input.Label>
170
- {t(isSpace(target) ? 'creating in space label' : 'creating in collection label')}
171
- </Input.Label>
172
- </InputHeader>
173
- <div role='none' className='flex gap-2'>
174
- <Input.TextInput
175
- disabled
176
- value={
177
- isSpace(target)
178
- ? toLocalizedString(getSpaceDisplayName(target, { personal: target.id === defaultSpaceId }), t)
179
- : target.name || t('unnamed collection label')
180
- }
181
- />
182
- <IconButton iconOnly icon='ph--x--regular' label={t('clear input label')} onClick={handleClearTarget} />
183
- </div>
184
- </Input.Root>
185
- </div>
186
- )}
187
- {schema && (
188
- <div role='none'>
189
- <Input.Root>
190
- <InputHeader>
191
- <Input.Label>{t('creating object type label')}</Input.Label>
192
- </InputHeader>
193
- <div role='none' className='flex gap-2'>
194
- <Input.TextInput
195
- disabled
196
- value={t('typename label', { ns: schema.typename, defaultValue: schema.typename })}
197
- />
198
- <IconButton iconOnly icon='ph--x--regular' label={t('clear input label')} onClick={handleClearSchema} />
199
- </div>
200
- </Input.Root>
201
- </div>
202
- )}
203
- {!schema ? schemaInput : !target ? spaceInput : form}
204
- </div>
205
- );
206
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
  );
@@ -4,12 +4,12 @@
4
4
 
5
5
  import React, { useCallback } from 'react';
6
6
 
7
- import { createIntent, LayoutAction, NavigationAction, useIntentDispatcher } from '@dxos/app-framework';
8
- import { useGraph } from '@dxos/plugin-graph';
7
+ import { createIntent, LayoutAction, useAppGraph, useIntentDispatcher } from '@dxos/app-framework';
8
+ import { log } from '@dxos/log';
9
9
  import { ObservabilityAction } from '@dxos/plugin-observability/types';
10
- import { useSpaces } from '@dxos/react-client/echo';
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';
@@ -21,47 +21,55 @@ export type JoinDialogProps = JoinPanelProps & {
21
21
  };
22
22
 
23
23
  export const JoinDialog = ({ navigableCollections, onDone, ...props }: JoinDialogProps) => {
24
- const { t } = useTranslation(SPACE_PLUGIN);
25
24
  const { dispatchPromise: dispatch } = useIntentDispatcher();
26
- const spaces = useSpaces();
27
- const { graph } = useGraph();
25
+ const client = useClient();
26
+ const { graph } = useAppGraph();
28
27
 
29
28
  const handleDone = useCallback(
30
29
  async (result: InvitationResult | null) => {
31
30
  if (result?.spaceKey) {
32
31
  await Promise.all([
33
32
  dispatch(
34
- createIntent(LayoutAction.SetLayout, {
35
- element: 'toast',
33
+ createIntent(LayoutAction.AddToast, {
34
+ part: 'toast',
36
35
  subject: {
37
36
  id: `${SPACE_PLUGIN}/join-success`,
38
37
  duration: 5_000,
39
- title: t('join success label'),
40
- closeLabel: t('dismiss label'),
38
+ title: ['join success label', { ns: SPACE_PLUGIN }],
39
+ closeLabel: ['dismiss label', { ns: SPACE_PLUGIN }],
41
40
  },
42
41
  }),
43
42
  ),
44
43
  dispatch(
45
- createIntent(LayoutAction.SetLayout, {
46
- element: 'dialog',
47
- state: false,
44
+ createIntent(LayoutAction.UpdateDialog, {
45
+ part: 'dialog',
46
+ options: {
47
+ state: false,
48
+ },
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(createIntent(NavigationAction.Open, { activeParts: { main: [target] } })),
64
- dispatch(createIntent(NavigationAction.Expose, { id: target })),
71
+ dispatch(createIntent(LayoutAction.Open, { part: 'main', subject: [target] })),
72
+ dispatch(createIntent(LayoutAction.Expose, { part: 'navigation', subject: target })),
65
73
  ]);
66
74
  }
67
75
 
@@ -73,7 +81,7 @@ export const JoinDialog = ({ navigableCollections, onDone, ...props }: JoinDialo
73
81
  );
74
82
  }
75
83
  },
76
- [dispatch, spaces],
84
+ [dispatch, client, graph],
77
85
  );
78
86
 
79
87
  return (
@@ -0,0 +1,46 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import React from 'react';
6
+
7
+ import { createIntent, LayoutAction, useIntentDispatcher } from '@dxos/app-framework';
8
+ import { IconButton, useTranslation } from '@dxos/react-ui';
9
+
10
+ import { SPACE_PLUGIN } from '../meta';
11
+ import { SpaceAction } from '../types';
12
+
13
+ export const POPOVER_ADD_SPACE = `${SPACE_PLUGIN}/PopoverRenameSpace`;
14
+
15
+ export const PopoverAddSpace = () => {
16
+ const { t } = useTranslation(SPACE_PLUGIN);
17
+ const { dispatchPromise: dispatch } = useIntentDispatcher();
18
+ return (
19
+ <div role='none' className='grid grid-cols-1 gap-1 [&>button]:justify-start'>
20
+ <IconButton
21
+ variant='ghost'
22
+ label={t('create space label')}
23
+ icon='ph--plus--regular'
24
+ onClick={() => {
25
+ void dispatch(createIntent(SpaceAction.OpenCreateSpace));
26
+ void dispatch(
27
+ createIntent(LayoutAction.UpdatePopover, { part: 'popover', options: { anchorId: '', state: false } }),
28
+ );
29
+ }}
30
+ data-testid='spacePlugin.createSpace'
31
+ />
32
+ <IconButton
33
+ variant='ghost'
34
+ label={t('join space label')}
35
+ icon='ph--sign-in--regular'
36
+ onClick={() => {
37
+ void dispatch(createIntent(SpaceAction.Join));
38
+ void dispatch(
39
+ createIntent(LayoutAction.UpdatePopover, { part: 'popover', options: { anchorId: '', state: false } }),
40
+ );
41
+ }}
42
+ data-testid='spacePlugin.joinSpace'
43
+ />
44
+ </div>
45
+ );
46
+ };
@@ -5,7 +5,7 @@
5
5
  import React from 'react';
6
6
 
7
7
  import { Input, useTranslation } from '@dxos/react-ui';
8
- import { DeprecatedFormInput } from '@dxos/react-ui-form';
8
+ import { DeprecatedFormContainer, DeprecatedFormInput } from '@dxos/react-ui-form';
9
9
 
10
10
  import { SPACE_PLUGIN } from '../meta';
11
11
  import { type SpaceSettingsProps } from '../types';
@@ -14,10 +14,10 @@ export const SpacePluginSettings = ({ settings }: { settings: SpaceSettingsProps
14
14
  const { t } = useTranslation(SPACE_PLUGIN);
15
15
 
16
16
  return (
17
- <>
17
+ <DeprecatedFormContainer>
18
18
  <DeprecatedFormInput label={t('show hidden spaces label')}>
19
19
  <Input.Switch checked={settings.showHidden} onCheckedChange={(checked) => (settings.showHidden = !!checked)} />
20
20
  </DeprecatedFormInput>
21
- </>
21
+ </DeprecatedFormContainer>
22
22
  );
23
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,
@@ -4,10 +4,9 @@
4
4
 
5
5
  import React, { useCallback, useEffect, useState } from 'react';
6
6
 
7
- import { useCapability } 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
- import { useGraph } from '@dxos/plugin-graph';
11
10
  import { PublicKey, useClient } from '@dxos/react-client';
12
11
  import { getSpace, useMembers, type SpaceMember, fullyQualifiedId } from '@dxos/react-client/echo';
13
12
  import { type Identity, useIdentity } from '@dxos/react-client/halo';
@@ -210,7 +209,7 @@ export const SmallPresenceLive = ({ id, open, viewers }: SmallPresenceLiveProps)
210
209
  // TODO(wittjosiah): If the attended node is deep in the graph and the graph is not fully loaded
211
210
  // this will result in an empty path until the graph is connected.
212
211
  // TODO(wittjosiah): Consider using this indicator for all open nodes instead of just attended.
213
- const { graph } = useGraph();
212
+ const { graph } = useAppGraph();
214
213
  const attended = useAttended();
215
214
  const startOfAttention = attended.at(-1);
216
215
  const path = usePath(graph, startOfAttention);
@@ -2,14 +2,16 @@
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
 
@@ -36,6 +38,8 @@ export const SpaceSettingsDialog = ({
36
38
  const [selected, setSelected] = useState<SpaceSettingsTab>(initialTab);
37
39
  const locked = space.properties[COMPOSER_SPACE_LOCK];
38
40
  const name = getSpaceDisplayName(space, { personal: client.spaces.default === space, namesCache });
41
+ const panels = useCapabilities(SpaceCapabilities.SettingsPanel);
42
+ const data = useMemo(() => ({ subject: space }), [space]);
39
43
 
40
44
  return (
41
45
  // TODO(wittjosiah): The tablist dialog pattern is copied from @dxos/plugin-manager.
@@ -84,6 +88,11 @@ export const SpaceSettingsDialog = ({
84
88
  <Tabs.Tab value='members' disabled={locked}>
85
89
  {t('members tab label')}
86
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
+ ))}
87
96
  </div>
88
97
  </Tabs.Tablist>
89
98
  </div>
@@ -98,6 +107,12 @@ export const SpaceSettingsDialog = ({
98
107
  <SpacePanel space={space} hideHeading target={target} createInvitationUrl={createInvitationUrl} />
99
108
  </Clipboard.Provider>
100
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
+ ))}
101
116
  </Tabs.Viewport>
102
117
  </Tabs.Root>
103
118
  </Dialog.Content>
@@ -15,7 +15,11 @@ import translations from '../../translations';
15
15
 
16
16
  const Story = (args: Partial<SpaceSettingsPanelProps>) => {
17
17
  const { space } = useClientProvider();
18
- return <SpaceSettingsPanel {...args} space={space!} classNames='p-2 border border-primary-500 rounded' />;
18
+ return (
19
+ <div role='none' className='p-2 border border-primary-500 rounded'>
20
+ <SpaceSettingsPanel {...args} space={space!} />
21
+ </div>
22
+ );
19
23
  };
20
24
 
21
25
  const meta: Meta = {