@dxos/plugin-space 0.8.4-main.a4bbb77 → 0.8.4-main.ae835ea

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 (224) hide show
  1. package/dist/lib/browser/{CollectionMain-AX7KKXWP.mjs → CollectionMain-HTKSZCRR.mjs} +2 -2
  2. package/dist/lib/browser/ObjectDetailsPanel-5B45G744.mjs +145 -0
  3. package/dist/lib/browser/ObjectDetailsPanel-5B45G744.mjs.map +7 -0
  4. package/dist/lib/browser/ObjectSettings-UFTKBP7B.mjs +146 -0
  5. package/dist/lib/browser/ObjectSettings-UFTKBP7B.mjs.map +7 -0
  6. package/dist/lib/browser/RecordMain-BCSXTSEB.mjs +99 -0
  7. package/dist/lib/browser/RecordMain-BCSXTSEB.mjs.map +7 -0
  8. package/dist/lib/browser/{app-graph-builder-W7RVDAUA.mjs → app-graph-builder-QJFO4ANM.mjs} +37 -34
  9. package/dist/lib/browser/app-graph-builder-QJFO4ANM.mjs.map +7 -0
  10. package/dist/lib/browser/{app-graph-serializer-VLHVTDX4.mjs → app-graph-serializer-3R5NVV7U.mjs} +5 -5
  11. package/dist/lib/browser/{chunk-E2I747A7.mjs → chunk-2NS3VPSY.mjs} +2 -2
  12. package/dist/lib/browser/chunk-2NS3VPSY.mjs.map +7 -0
  13. package/dist/lib/browser/{chunk-ZIZ2JLW6.mjs → chunk-4V4JNJ33.mjs} +12 -4
  14. package/dist/lib/browser/chunk-4V4JNJ33.mjs.map +7 -0
  15. package/dist/lib/browser/{chunk-2BFVC5K6.mjs → chunk-ENBBJSNE.mjs} +230 -254
  16. package/dist/lib/browser/chunk-ENBBJSNE.mjs.map +7 -0
  17. package/dist/lib/browser/chunk-HS2VD6DN.mjs +166 -0
  18. package/dist/lib/browser/chunk-HS2VD6DN.mjs.map +7 -0
  19. package/dist/lib/browser/{chunk-PN27K4I7.mjs → chunk-OWNBEI5J.mjs} +23 -14
  20. package/dist/lib/browser/chunk-OWNBEI5J.mjs.map +7 -0
  21. package/dist/lib/browser/{chunk-JCHSUOPF.mjs → chunk-SLDQWMQ2.mjs} +12 -7
  22. package/dist/lib/browser/chunk-SLDQWMQ2.mjs.map +7 -0
  23. package/dist/lib/browser/chunk-VZBIIYFM.mjs +16 -0
  24. package/dist/lib/browser/chunk-VZBIIYFM.mjs.map +7 -0
  25. package/dist/lib/browser/{chunk-EIXZABXD.mjs → chunk-WJXU4GKV.mjs} +2 -2
  26. package/dist/lib/browser/index.mjs +31 -31
  27. package/dist/lib/browser/index.mjs.map +3 -3
  28. package/dist/lib/browser/{intent-resolver-HA7DPAUE.mjs → intent-resolver-MBVOLXFQ.mjs} +30 -23
  29. package/dist/lib/browser/intent-resolver-MBVOLXFQ.mjs.map +7 -0
  30. package/dist/lib/browser/meta.json +1 -1
  31. package/dist/lib/browser/{react-root-YQUJU64P.mjs → react-root-NKEKCEYM.mjs} +7 -7
  32. package/dist/lib/browser/{react-surface-HTXYMRSW.mjs → react-surface-PYSN2MBY.mjs} +15 -46
  33. package/dist/lib/browser/react-surface-PYSN2MBY.mjs.map +7 -0
  34. package/dist/lib/browser/{schema-defs-R56ZDBZ7.mjs → schema-defs-DWYK7TYW.mjs} +3 -3
  35. package/dist/lib/browser/{settings-5XPQMSPO.mjs → settings-ZUCC3ZLB.mjs} +3 -3
  36. package/dist/lib/browser/{spaces-ready-YY77ANIF.mjs → spaces-ready-HTWWJHLR.mjs} +6 -6
  37. package/dist/lib/browser/spaces-ready-HTWWJHLR.mjs.map +7 -0
  38. package/dist/lib/browser/{state-Y4RVCG4A.mjs → state-ISVAKMO7.mjs} +3 -3
  39. package/dist/lib/browser/types/index.mjs +2 -2
  40. package/dist/lib/node-esm/{CollectionMain-EU57SRYK.mjs → CollectionMain-OUHGG6OC.mjs} +2 -2
  41. package/dist/lib/node-esm/ObjectDetailsPanel-4SDHQVQU.mjs +146 -0
  42. package/dist/lib/node-esm/ObjectDetailsPanel-4SDHQVQU.mjs.map +7 -0
  43. package/dist/lib/node-esm/ObjectSettings-EU6F43RP.mjs +147 -0
  44. package/dist/lib/node-esm/ObjectSettings-EU6F43RP.mjs.map +7 -0
  45. package/dist/lib/node-esm/RecordMain-SD76DGOR.mjs +100 -0
  46. package/dist/lib/node-esm/RecordMain-SD76DGOR.mjs.map +7 -0
  47. package/dist/lib/node-esm/{app-graph-builder-5ZJJUMQI.mjs → app-graph-builder-B23W62HY.mjs} +37 -34
  48. package/dist/lib/node-esm/app-graph-builder-B23W62HY.mjs.map +7 -0
  49. package/dist/lib/node-esm/{app-graph-serializer-EZJSGJUT.mjs → app-graph-serializer-3Z3EXEEF.mjs} +5 -5
  50. package/dist/lib/node-esm/chunk-BDEFTL6K.mjs +18 -0
  51. package/dist/lib/node-esm/chunk-BDEFTL6K.mjs.map +7 -0
  52. package/dist/lib/node-esm/{chunk-5XRYHWL7.mjs → chunk-G4PDWB7G.mjs} +12 -4
  53. package/dist/lib/node-esm/chunk-G4PDWB7G.mjs.map +7 -0
  54. package/dist/lib/node-esm/{chunk-SVFKU7EW.mjs → chunk-H4JILUJK.mjs} +2 -2
  55. package/dist/lib/node-esm/{chunk-BLPXWPLB.mjs → chunk-KKPCCA5O.mjs} +230 -254
  56. package/dist/lib/node-esm/chunk-KKPCCA5O.mjs.map +7 -0
  57. package/dist/lib/node-esm/chunk-PM4ZIGKC.mjs +167 -0
  58. package/dist/lib/node-esm/chunk-PM4ZIGKC.mjs.map +7 -0
  59. package/dist/lib/node-esm/{chunk-XDQXUZMK.mjs → chunk-XEVIWD3O.mjs} +23 -14
  60. package/dist/lib/node-esm/chunk-XEVIWD3O.mjs.map +7 -0
  61. package/dist/lib/node-esm/{chunk-6WNZW6KT.mjs → chunk-YFQXFQGT.mjs} +12 -7
  62. package/dist/lib/node-esm/chunk-YFQXFQGT.mjs.map +7 -0
  63. package/dist/lib/node-esm/{chunk-IJVBBVCL.mjs → chunk-ZLMFLI7G.mjs} +2 -2
  64. package/dist/lib/node-esm/chunk-ZLMFLI7G.mjs.map +7 -0
  65. package/dist/lib/node-esm/index.mjs +31 -31
  66. package/dist/lib/node-esm/index.mjs.map +3 -3
  67. package/dist/lib/node-esm/{intent-resolver-LQNHMPIX.mjs → intent-resolver-IWI47NTW.mjs} +30 -23
  68. package/dist/lib/node-esm/intent-resolver-IWI47NTW.mjs.map +7 -0
  69. package/dist/lib/node-esm/meta.json +1 -1
  70. package/dist/lib/node-esm/{react-root-UTLJEIKE.mjs → react-root-LX7SIG6M.mjs} +7 -7
  71. package/dist/lib/node-esm/{react-surface-LYDYON3U.mjs → react-surface-6SVGOZNJ.mjs} +15 -46
  72. package/dist/lib/node-esm/react-surface-6SVGOZNJ.mjs.map +7 -0
  73. package/dist/lib/node-esm/{schema-defs-7IMJPIWS.mjs → schema-defs-EOG2UPJU.mjs} +3 -3
  74. package/dist/lib/node-esm/{settings-XBSK5KHH.mjs → settings-ZDJNLFGW.mjs} +3 -3
  75. package/dist/lib/node-esm/{spaces-ready-YX4IHT4P.mjs → spaces-ready-VUGYPF4L.mjs} +6 -6
  76. package/dist/lib/node-esm/spaces-ready-VUGYPF4L.mjs.map +7 -0
  77. package/dist/lib/node-esm/{state-HOHAVPUO.mjs → state-QZ4Q6ZRL.mjs} +3 -3
  78. package/dist/lib/node-esm/types/index.mjs +2 -2
  79. package/dist/types/src/SpacePlugin.d.ts.map +1 -1
  80. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  81. package/dist/types/src/capabilities/capabilities.d.ts +2 -1
  82. package/dist/types/src/capabilities/capabilities.d.ts.map +1 -1
  83. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
  84. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  85. package/dist/types/src/components/CreateDialog/CreateObjectDialog.d.ts.map +1 -1
  86. package/dist/types/src/components/CreateDialog/CreateObjectDialog.stories.d.ts +80 -0
  87. package/dist/types/src/components/CreateDialog/CreateObjectDialog.stories.d.ts.map +1 -1
  88. package/dist/types/src/components/CreateDialog/CreateObjectPanel.d.ts +1 -1
  89. package/dist/types/src/components/CreateDialog/CreateObjectPanel.d.ts.map +1 -1
  90. package/dist/types/src/components/CreateDialog/CreateSpaceDialog.d.ts.map +1 -1
  91. package/dist/types/src/components/MembersContainer.stories.d.ts +80 -0
  92. package/dist/types/src/components/MembersContainer.stories.d.ts.map +1 -1
  93. package/dist/types/src/components/ObjectDetailsPanel/ObjectDetailsPanel.d.ts +9 -0
  94. package/dist/types/src/components/ObjectDetailsPanel/ObjectDetailsPanel.d.ts.map +1 -0
  95. package/dist/types/src/components/ObjectDetailsPanel/ObjectForm.d.ts +10 -0
  96. package/dist/types/src/components/ObjectDetailsPanel/ObjectForm.d.ts.map +1 -0
  97. package/dist/types/src/components/ObjectDetailsPanel/index.d.ts +3 -0
  98. package/dist/types/src/components/ObjectDetailsPanel/index.d.ts.map +1 -0
  99. package/dist/types/src/components/ObjectSettings/BaseObjectSettings.d.ts +2 -2
  100. package/dist/types/src/components/ObjectSettings/BaseObjectSettings.d.ts.map +1 -1
  101. package/dist/types/src/components/ObjectSettings/BaseObjectSettings.stories.d.ts +1500 -0
  102. package/dist/types/src/components/ObjectSettings/BaseObjectSettings.stories.d.ts.map +1 -0
  103. package/dist/types/src/components/ObjectSettings/ForeignKeys.d.ts +1 -1
  104. package/dist/types/src/components/ObjectSettings/ForeignKeys.d.ts.map +1 -1
  105. package/dist/types/src/components/ObjectSettings/index.d.ts +2 -1
  106. package/dist/types/src/components/ObjectSettings/index.d.ts.map +1 -1
  107. package/dist/types/src/components/RecordMain.d.ts +4 -3
  108. package/dist/types/src/components/RecordMain.d.ts.map +1 -1
  109. package/dist/types/src/components/RecordMain.stories.d.ts +1667 -0
  110. package/dist/types/src/components/RecordMain.stories.d.ts.map +1 -0
  111. package/dist/types/src/components/SpacePresence.stories.d.ts +80 -0
  112. package/dist/types/src/components/SpacePresence.stories.d.ts.map +1 -1
  113. package/dist/types/src/components/SpaceSettings/SpaceSettingsContainer.d.ts.map +1 -1
  114. package/dist/types/src/components/SpaceSettings/SpaceSettingsContainer.stories.d.ts +80 -0
  115. package/dist/types/src/components/SpaceSettings/SpaceSettingsContainer.stories.d.ts.map +1 -1
  116. package/dist/types/src/components/SyncStatus/SyncStatus.d.ts.map +1 -1
  117. package/dist/types/src/components/SyncStatus/SyncStatus.stories.d.ts +81 -1
  118. package/dist/types/src/components/SyncStatus/SyncStatus.stories.d.ts.map +1 -1
  119. package/dist/types/src/components/ViewEditor.d.ts.map +1 -1
  120. package/dist/types/src/components/index.d.ts +4 -6
  121. package/dist/types/src/components/index.d.ts.map +1 -1
  122. package/dist/types/src/hooks/index.d.ts +1 -0
  123. package/dist/types/src/hooks/index.d.ts.map +1 -1
  124. package/dist/types/src/hooks/useInputSurfaceLookup.d.ts +1 -1
  125. package/dist/types/src/hooks/useInputSurfaceLookup.d.ts.map +1 -1
  126. package/dist/types/src/hooks/usePath.d.ts +1 -1
  127. package/dist/types/src/hooks/usePath.d.ts.map +1 -1
  128. package/dist/types/src/hooks/useTypeOptions.d.ts +10 -0
  129. package/dist/types/src/hooks/useTypeOptions.d.ts.map +1 -0
  130. package/dist/types/src/meta.d.ts.map +1 -1
  131. package/dist/types/src/translations.d.ts +80 -0
  132. package/dist/types/src/translations.d.ts.map +1 -1
  133. package/dist/types/src/types/types.d.ts +6 -4
  134. package/dist/types/src/types/types.d.ts.map +1 -1
  135. package/dist/types/src/util.d.ts +4 -1
  136. package/dist/types/src/util.d.ts.map +1 -1
  137. package/dist/types/tsconfig.tsbuildinfo +1 -1
  138. package/package.json +50 -48
  139. package/src/SpacePlugin.ts +7 -13
  140. package/src/capabilities/app-graph-builder.ts +29 -24
  141. package/src/capabilities/capabilities.ts +7 -2
  142. package/src/capabilities/intent-resolver.ts +13 -8
  143. package/src/capabilities/react-surface.tsx +6 -77
  144. package/src/capabilities/spaces-ready.ts +1 -1
  145. package/src/components/CreateDialog/CreateObjectDialog.tsx +5 -4
  146. package/src/components/CreateDialog/CreateObjectPanel.tsx +2 -2
  147. package/src/components/CreateDialog/CreateSpaceDialog.tsx +2 -1
  148. package/src/components/MembersContainer.tsx +1 -1
  149. package/src/components/{ObjectDetailsPanel.tsx → ObjectDetailsPanel/ObjectDetailsPanel.tsx} +8 -35
  150. package/src/components/ObjectDetailsPanel/ObjectForm.tsx +75 -0
  151. package/src/components/ObjectDetailsPanel/index.ts +7 -0
  152. package/src/components/ObjectSettings/AdvancedObjectSettings.tsx +1 -1
  153. package/src/components/ObjectSettings/BaseObjectSettings.stories.tsx +63 -0
  154. package/src/components/ObjectSettings/BaseObjectSettings.tsx +86 -26
  155. package/src/components/ObjectSettings/ForeignKeys.tsx +1 -1
  156. package/src/components/ObjectSettings/index.ts +3 -1
  157. package/src/components/RecordMain.stories.tsx +116 -0
  158. package/src/components/RecordMain.tsx +69 -29
  159. package/src/components/SchemaContainer.tsx +1 -1
  160. package/src/components/SpacePresence.tsx +1 -1
  161. package/src/components/SpaceSettings/SpaceSettingsContainer.tsx +4 -3
  162. package/src/components/SyncStatus/InlineSyncStatus.tsx +5 -5
  163. package/src/components/SyncStatus/SyncStatus.stories.tsx +3 -2
  164. package/src/components/SyncStatus/SyncStatus.tsx +93 -3
  165. package/src/components/ViewEditor.tsx +6 -7
  166. package/src/components/index.ts +1 -1
  167. package/src/hooks/index.ts +1 -0
  168. package/src/hooks/useInputSurfaceLookup.tsx +1 -1
  169. package/src/hooks/usePath.ts +1 -1
  170. package/src/hooks/useTypeOptions.ts +59 -0
  171. package/src/meta.ts +5 -0
  172. package/src/translations.ts +10 -1
  173. package/src/types/types.ts +9 -5
  174. package/src/util.tsx +22 -8
  175. package/dist/lib/browser/ObjectDetailsPanel-ETI5YBTH.mjs +0 -90
  176. package/dist/lib/browser/ObjectDetailsPanel-ETI5YBTH.mjs.map +0 -7
  177. package/dist/lib/browser/RecordMain-TEBGAVSL.mjs +0 -68
  178. package/dist/lib/browser/RecordMain-TEBGAVSL.mjs.map +0 -7
  179. package/dist/lib/browser/app-graph-builder-W7RVDAUA.mjs.map +0 -7
  180. package/dist/lib/browser/chunk-2BFVC5K6.mjs.map +0 -7
  181. package/dist/lib/browser/chunk-E2I747A7.mjs.map +0 -7
  182. package/dist/lib/browser/chunk-ELJDGQTO.mjs +0 -94
  183. package/dist/lib/browser/chunk-ELJDGQTO.mjs.map +0 -7
  184. package/dist/lib/browser/chunk-IRKDREHY.mjs +0 -11
  185. package/dist/lib/browser/chunk-IRKDREHY.mjs.map +0 -7
  186. package/dist/lib/browser/chunk-JCHSUOPF.mjs.map +0 -7
  187. package/dist/lib/browser/chunk-PN27K4I7.mjs.map +0 -7
  188. package/dist/lib/browser/chunk-ZIZ2JLW6.mjs.map +0 -7
  189. package/dist/lib/browser/intent-resolver-HA7DPAUE.mjs.map +0 -7
  190. package/dist/lib/browser/react-surface-HTXYMRSW.mjs.map +0 -7
  191. package/dist/lib/browser/spaces-ready-YY77ANIF.mjs.map +0 -7
  192. package/dist/lib/node-esm/ObjectDetailsPanel-TQ5GN4QJ.mjs +0 -91
  193. package/dist/lib/node-esm/ObjectDetailsPanel-TQ5GN4QJ.mjs.map +0 -7
  194. package/dist/lib/node-esm/RecordMain-WLYJMYER.mjs +0 -70
  195. package/dist/lib/node-esm/RecordMain-WLYJMYER.mjs.map +0 -7
  196. package/dist/lib/node-esm/app-graph-builder-5ZJJUMQI.mjs.map +0 -7
  197. package/dist/lib/node-esm/chunk-5XRYHWL7.mjs.map +0 -7
  198. package/dist/lib/node-esm/chunk-6WNZW6KT.mjs.map +0 -7
  199. package/dist/lib/node-esm/chunk-BLPXWPLB.mjs.map +0 -7
  200. package/dist/lib/node-esm/chunk-IJVBBVCL.mjs.map +0 -7
  201. package/dist/lib/node-esm/chunk-MWNATOXL.mjs +0 -13
  202. package/dist/lib/node-esm/chunk-MWNATOXL.mjs.map +0 -7
  203. package/dist/lib/node-esm/chunk-Q6AAQLQG.mjs +0 -96
  204. package/dist/lib/node-esm/chunk-Q6AAQLQG.mjs.map +0 -7
  205. package/dist/lib/node-esm/chunk-XDQXUZMK.mjs.map +0 -7
  206. package/dist/lib/node-esm/intent-resolver-LQNHMPIX.mjs.map +0 -7
  207. package/dist/lib/node-esm/react-surface-LYDYON3U.mjs.map +0 -7
  208. package/dist/lib/node-esm/spaces-ready-YX4IHT4P.mjs.map +0 -7
  209. package/dist/types/src/components/ObjectDetailsPanel.d.ts +0 -9
  210. package/dist/types/src/components/ObjectDetailsPanel.d.ts.map +0 -1
  211. /package/dist/lib/browser/{CollectionMain-AX7KKXWP.mjs.map → CollectionMain-HTKSZCRR.mjs.map} +0 -0
  212. /package/dist/lib/browser/{app-graph-serializer-VLHVTDX4.mjs.map → app-graph-serializer-3R5NVV7U.mjs.map} +0 -0
  213. /package/dist/lib/browser/{chunk-EIXZABXD.mjs.map → chunk-WJXU4GKV.mjs.map} +0 -0
  214. /package/dist/lib/browser/{react-root-YQUJU64P.mjs.map → react-root-NKEKCEYM.mjs.map} +0 -0
  215. /package/dist/lib/browser/{schema-defs-R56ZDBZ7.mjs.map → schema-defs-DWYK7TYW.mjs.map} +0 -0
  216. /package/dist/lib/browser/{settings-5XPQMSPO.mjs.map → settings-ZUCC3ZLB.mjs.map} +0 -0
  217. /package/dist/lib/browser/{state-Y4RVCG4A.mjs.map → state-ISVAKMO7.mjs.map} +0 -0
  218. /package/dist/lib/node-esm/{CollectionMain-EU57SRYK.mjs.map → CollectionMain-OUHGG6OC.mjs.map} +0 -0
  219. /package/dist/lib/node-esm/{app-graph-serializer-EZJSGJUT.mjs.map → app-graph-serializer-3Z3EXEEF.mjs.map} +0 -0
  220. /package/dist/lib/node-esm/{chunk-SVFKU7EW.mjs.map → chunk-H4JILUJK.mjs.map} +0 -0
  221. /package/dist/lib/node-esm/{react-root-UTLJEIKE.mjs.map → react-root-LX7SIG6M.mjs.map} +0 -0
  222. /package/dist/lib/node-esm/{schema-defs-7IMJPIWS.mjs.map → schema-defs-EOG2UPJU.mjs.map} +0 -0
  223. /package/dist/lib/node-esm/{settings-XBSK5KHH.mjs.map → settings-ZDJNLFGW.mjs.map} +0 -0
  224. /package/dist/lib/node-esm/{state-HOHAVPUO.mjs.map → state-QZ4Q6ZRL.mjs.map} +0 -0
@@ -2,7 +2,8 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { Effect, pipe } from 'effect';
5
+ import * as Effect from 'effect/Effect';
6
+ import * as Function from 'effect/Function';
6
7
  import React, { useCallback, useRef, useState } from 'react';
7
8
 
8
9
  import {
@@ -20,7 +21,7 @@ import { useClient } from '@dxos/react-client';
20
21
  import { type Space, getSpace, isLiveObject, isSpace, useQuery, useSpaces } from '@dxos/react-client/echo';
21
22
  import { Button, Dialog, Icon, useTranslation } from '@dxos/react-ui';
22
23
  import { cardDialogContent, cardDialogHeader } from '@dxos/react-ui-stack';
23
- import { DataType, typenameFromQuery } from '@dxos/schema';
24
+ import { DataType, getTypenameFromQuery } from '@dxos/schema';
24
25
  import { isNonNullable } from '@dxos/util';
25
26
 
26
27
  import { SpaceCapabilities } from '../../capabilities';
@@ -59,7 +60,7 @@ export const CreateObjectDialog = ({
59
60
  const space = isSpace(target) ? target : getSpace(target);
60
61
  const queryCollections = useQuery(space, Query.type(DataType.QueryCollection));
61
62
  const hiddenTypenames = queryCollections
62
- .map((collection) => typenameFromQuery(collection.query))
63
+ .map((collection) => getTypenameFromQuery(collection.query))
63
64
  .filter(isNonNullable);
64
65
 
65
66
  const resolve = useCallback<NonNullable<CreateObjectPanelProps['resolve']>>(
@@ -88,7 +89,7 @@ export const CreateObjectDialog = ({
88
89
  const addObjectIntent = createIntent(SpaceAction.AddObject, { target, object, hidden });
89
90
  const shouldNavigate = _shouldNavigate ?? (() => true);
90
91
  if (shouldNavigate(object)) {
91
- yield* dispatch(pipe(addObjectIntent, chain(LayoutAction.Open, { part: 'main' })));
92
+ yield* dispatch(Function.pipe(addObjectIntent, chain(LayoutAction.Open, { part: 'main' })));
92
93
  } else {
93
94
  yield* dispatch(addObjectIntent);
94
95
  }
@@ -2,11 +2,11 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { Option } from 'effect';
5
+ import * as Option from 'effect/Option';
6
6
  import React, { useCallback } from 'react';
7
7
 
8
8
  import { Type } from '@dxos/echo';
9
- import { type BaseObject, type TypeAnnotation, ViewAnnotation, getTypeAnnotation } from '@dxos/echo-schema';
9
+ import { type BaseObject, type TypeAnnotation, ViewAnnotation, getTypeAnnotation } from '@dxos/echo/internal';
10
10
  import { type Space, type SpaceId } from '@dxos/react-client/echo';
11
11
  import { Icon, toLocalizedString, useDefaultValue, useTranslation } from '@dxos/react-ui';
12
12
  import { Form } from '@dxos/react-ui-form';
@@ -2,7 +2,8 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { Effect, type Schema } from 'effect';
5
+ import * as Effect from 'effect/Effect';
6
+ import type * as Schema from 'effect/Schema';
6
7
  import React, { useCallback, useRef } from 'react';
7
8
 
8
9
  import { LayoutAction, createIntent, useIntentDispatcher } from '@dxos/app-framework';
@@ -130,7 +130,7 @@ export const MembersContainer = ({ space, createInvitationUrl }: MembersContaine
130
130
 
131
131
  return (
132
132
  <Clipboard.Provider>
133
- <StackItem.Content classNames='block overflow-y-auto'>
133
+ <StackItem.Content scrollable>
134
134
  <ControlPage>
135
135
  <ControlSection title={t('members verbose label')} description={t('members description')}>
136
136
  <ControlFrame>
@@ -2,52 +2,33 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import React, { useCallback } from 'react';
5
+ import React from 'react';
6
6
 
7
- import { type JsonPath, setValue } from '@dxos/echo-schema';
8
- import { invariant } from '@dxos/invariant';
9
7
  import { useClient } from '@dxos/react-client';
10
8
  import { Filter, getSpace, useQuery, useSchema } from '@dxos/react-client/echo';
11
9
  import { Callout, useTranslation } from '@dxos/react-ui';
12
10
  import { useSelected } from '@dxos/react-ui-attention';
13
- import { Form, useRefQueryLookupHandler } from '@dxos/react-ui-form';
14
11
  import { type DataType } from '@dxos/schema';
15
- import { typenameFromQuery } from '@dxos/schema';
12
+ import { getTypenameFromQuery } from '@dxos/schema';
16
13
  import { isNonNullable } from '@dxos/util';
17
14
 
18
- import { meta } from '../meta';
15
+ import { meta } from '../../meta';
16
+
17
+ import { ObjectForm } from './ObjectForm';
19
18
 
20
19
  type RowDetailsPanelProps = { objectId: string; view: DataType.View };
21
20
 
22
- const ObjectDetailsPanel = ({ objectId, view }: RowDetailsPanelProps) => {
21
+ export const ObjectDetailsPanel = ({ objectId, view }: RowDetailsPanelProps) => {
23
22
  const { t } = useTranslation(meta.id);
24
23
  const client = useClient();
25
24
  const space = getSpace(view);
26
- const typename = view.query ? typenameFromQuery(view.query.ast) : undefined;
25
+ const typename = view.query ? getTypenameFromQuery(view.query.ast) : undefined;
27
26
  const schema = useSchema(client, space, typename);
28
27
 
29
28
  const queriedObjects = useQuery(space, schema ? Filter.type(schema) : Filter.nothing());
30
29
  const selectedRows = useSelected(objectId, 'multi');
31
30
  const selectedObjects = selectedRows.map((id) => queriedObjects.find((obj) => obj.id === id)).filter(isNonNullable);
32
31
 
33
- const handleRefQueryLookup = useRefQueryLookupHandler({ space });
34
-
35
- const handleSave = useCallback(
36
- (values: any, { changed }: { changed: Record<JsonPath, boolean> }) => {
37
- const id = values.id;
38
- invariant(typeof id === 'string');
39
- const object = queriedObjects.find((obj) => obj.id === id);
40
- invariant(object);
41
-
42
- const changedPaths = Object.keys(changed).filter((path) => changed[path as JsonPath]) as JsonPath[];
43
- for (const path of changedPaths) {
44
- const value = values[path];
45
- setValue(object, path, value);
46
- }
47
- },
48
- [queriedObjects],
49
- );
50
-
51
32
  if (selectedObjects.length === 0) {
52
33
  return (
53
34
  <div role='none' className='plb-cardSpacingBlock pli-cardSpacingInline'>
@@ -63,17 +44,9 @@ const ObjectDetailsPanel = ({ objectId, view }: RowDetailsPanelProps) => {
63
44
  {schema &&
64
45
  selectedObjects.map((object) => (
65
46
  <div key={object.id} className='border border-separator rounded'>
66
- <Form
67
- autoSave
68
- schema={schema}
69
- values={object}
70
- onSave={handleSave}
71
- onQueryRefOptions={handleRefQueryLookup}
72
- />
47
+ <ObjectForm object={object} schema={schema} />
73
48
  </div>
74
49
  ))}
75
50
  </div>
76
51
  );
77
52
  };
78
-
79
- export default ObjectDetailsPanel;
@@ -0,0 +1,75 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Schema from 'effect/Schema';
6
+ import React, { useCallback, useMemo } from 'react';
7
+
8
+ import { DXN, Obj, Tag, Type } from '@dxos/echo';
9
+ import { type JsonPath, setValue } from '@dxos/echo/internal';
10
+ import { invariant } from '@dxos/invariant';
11
+ import { getSpace } from '@dxos/react-client/echo';
12
+ import { Form, useRefQueryLookupHandler } from '@dxos/react-ui-form';
13
+
14
+ import { meta as pluginMeta } from '../../meta';
15
+
16
+ const TagSchema = Tag.Tag.pipe(Schema.omit('id'));
17
+
18
+ type ObjectFormProps = { object: Obj.Any; schema: Schema.Schema.AnyNoContext };
19
+
20
+ export const ObjectForm = ({ object, schema }: ObjectFormProps) => {
21
+ const space = getSpace(object);
22
+ const handleRefQueryLookup = useRefQueryLookupHandler({ space });
23
+
24
+ const formSchema = useMemo(
25
+ () => Schema.Struct({ tag: Type.Ref(Tag.Tag).pipe(Schema.optional) }).pipe(Schema.extend(schema)),
26
+ [schema],
27
+ );
28
+
29
+ const meta = Obj.getMeta(object);
30
+ const tag = meta.tags?.[0] ? space?.db.ref(DXN.parse(meta.tags?.[0])) : undefined;
31
+ const values = useMemo(() => ({ tag, ...object }), [object, tag]);
32
+
33
+ const handleCreateTag = useCallback((values: Schema.Schema.Type<typeof TagSchema>) => {
34
+ invariant(space);
35
+ const tag = space.db.add(Tag.make(values));
36
+ const meta = Obj.getMeta(object);
37
+ meta.tags = [Obj.getDXN(tag).toString()];
38
+ }, []);
39
+
40
+ const handleSave = useCallback(
41
+ (values: any, { changed }: { changed: Record<JsonPath, boolean> }) => {
42
+ const changedPaths = Object.keys(changed).filter((path) => changed[path as JsonPath]) as JsonPath[];
43
+ for (const path of changedPaths) {
44
+ if (path === 'tag') {
45
+ const tag = values[path];
46
+ const meta = Obj.getMeta(object);
47
+ const currentTag = meta.tags?.[0];
48
+ if (currentTag !== tag?.dxn.toString()) {
49
+ meta.tags = tag ? [tag.dxn.toString()] : [];
50
+ }
51
+ continue;
52
+ }
53
+
54
+ const value = values[path];
55
+ setValue(object, path, value);
56
+ }
57
+ },
58
+ [object],
59
+ );
60
+
61
+ return (
62
+ <Form
63
+ autoSave
64
+ schema={formSchema}
65
+ values={values}
66
+ createSchema={TagSchema}
67
+ createOptionIcon='ph--plus--regular'
68
+ createOptionLabel={['add tag label', { ns: pluginMeta.id }]}
69
+ createInitialValuePath='label'
70
+ onCreate={handleCreateTag}
71
+ onSave={handleSave}
72
+ onQueryRefOptions={handleRefQueryLookup}
73
+ />
74
+ );
75
+ };
@@ -0,0 +1,7 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { ObjectDetailsPanel } from './ObjectDetailsPanel';
6
+
7
+ export default ObjectDetailsPanel;
@@ -5,7 +5,7 @@
5
5
  import React, { useCallback, useState } from 'react';
6
6
 
7
7
  import { Obj } from '@dxos/echo';
8
- import { ForeignKey } from '@dxos/echo-schema';
8
+ import { ForeignKey } from '@dxos/echo/internal';
9
9
  import { IconButton, useTranslation } from '@dxos/react-ui';
10
10
  import { Form } from '@dxos/react-ui-form';
11
11
 
@@ -0,0 +1,63 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+ import React, { useEffect, useState } from 'react';
7
+
8
+ import { type Obj, Tag } from '@dxos/echo';
9
+ import { useClientProvider, withClientProvider } from '@dxos/react-client/testing';
10
+ import { withTheme } from '@dxos/react-ui/testing';
11
+ import { DataType } from '@dxos/schema';
12
+ import { render } from '@dxos/storybook-utils';
13
+
14
+ import { translations } from '../../translations';
15
+
16
+ import { BaseObjectSettings } from './BaseObjectSettings';
17
+
18
+ const DefaultStory = () => {
19
+ const { space } = useClientProvider();
20
+ const [object, setObject] = useState<Obj.Any>();
21
+
22
+ useEffect(() => {
23
+ if (space && !object) {
24
+ const object = space.db.add(DataType.makeProject());
25
+ setObject(object as Obj.Any);
26
+ }
27
+ }, [space, object]);
28
+
29
+ if (!object) {
30
+ return null;
31
+ }
32
+
33
+ return <BaseObjectSettings object={object} classNames='is-[20rem]' />;
34
+ };
35
+
36
+ const meta = {
37
+ title: 'plugins/plugin-space/BaseObjectSettings',
38
+ component: BaseObjectSettings as any,
39
+ render: render(DefaultStory),
40
+ decorators: [
41
+ withTheme,
42
+ withClientProvider({
43
+ createIdentity: true,
44
+ createSpace: true,
45
+ types: [DataType.Project, Tag.Tag],
46
+ onCreateSpace: async ({ space }) => {
47
+ space.db.add(Tag.make({ label: 'Tag 1' }));
48
+ space.db.add(Tag.make({ label: 'Tag 2' }));
49
+ space.db.add(Tag.make({ label: 'Tag 3' }));
50
+ },
51
+ }),
52
+ ],
53
+ parameters: {
54
+ layout: 'centered',
55
+ translations,
56
+ },
57
+ } satisfies Meta<typeof DefaultStory>;
58
+
59
+ export default meta;
60
+
61
+ type Story = StoryObj<typeof meta>;
62
+
63
+ export const Default: Story = {};
@@ -2,12 +2,28 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import React, { type PropsWithChildren, useRef } from 'react';
5
+ import { batch } from '@preact/signals-core';
6
+ import * as Function from 'effect/Function';
7
+ import * as Option from 'effect/Option';
8
+ import * as Schema from 'effect/Schema';
9
+ import React, { type PropsWithChildren, useCallback, useMemo } from 'react';
6
10
 
7
- import { type Obj } from '@dxos/echo';
8
- import { Input, type ThemedClassName, useTranslation } from '@dxos/react-ui';
11
+ import { DXN, Obj, Tag, Type } from '@dxos/echo';
12
+ import { invariant } from '@dxos/invariant';
13
+ import { getSpace } from '@dxos/react-client/echo';
14
+ import { type ThemedClassName } from '@dxos/react-ui';
15
+ import { Form, useRefQueryLookupHandler } from '@dxos/react-ui-form';
9
16
 
10
- import { meta } from '../../meta';
17
+ import { meta as pluginMeta } from '../../meta';
18
+
19
+ // TODO(wittjosiah): Would be nice to control order when extending so this isn't always first/last.
20
+ const BaseSchema = Schema.Struct({
21
+ // TODO(wittjosiah): Support multiple tags.
22
+ tag: Type.Ref(Tag.Tag).pipe(Schema.optional),
23
+ });
24
+
25
+ // TODO(wittjosiah): Better way to support validation of object schemas?
26
+ const TagSchema = Tag.Tag.pipe(Schema.omit('id'));
11
27
 
12
28
  export type BaseObjectSettingsProps = ThemedClassName<
13
29
  PropsWithChildren<{
@@ -15,32 +31,76 @@ export type BaseObjectSettingsProps = ThemedClassName<
15
31
  }>
16
32
  >;
17
33
 
34
+ // TODO(wittjosiah): Reconcile w/ ObjectDetailsPanel.
18
35
  export const BaseObjectSettings = ({ classNames, children, object }: BaseObjectSettingsProps) => {
19
- const { t } = useTranslation(meta.id);
20
- const inputRef = useRef<HTMLInputElement>(null);
36
+ const space = getSpace(object);
37
+ const handleRefQueryLookup = useRefQueryLookupHandler({ space });
38
+
39
+ const formSchema = useMemo(() => {
40
+ return Function.pipe(
41
+ Obj.getSchema(object),
42
+ Option.fromNullable,
43
+ Option.map((schema) => BaseSchema.pipe(Schema.extend(schema))),
44
+ Option.getOrUndefined,
45
+ );
46
+ }, [object]);
47
+
48
+ const meta = Obj.getMeta(object);
49
+ const tag = meta.tags?.[0] ? space?.db.ref(DXN.parse(meta.tags?.[0])) : undefined;
50
+ const values = useMemo(
51
+ () => ({
52
+ tag,
53
+ ...object,
54
+ }),
55
+ [object, tag],
56
+ );
57
+
58
+ const handleCreateTag = useCallback((values: Schema.Schema.Type<typeof TagSchema>) => {
59
+ invariant(space);
60
+ const tag = space.db.add(Tag.make(values));
61
+ const meta = Obj.getMeta(object);
62
+ meta.tags = [Obj.getDXN(tag).toString()];
63
+ }, []);
64
+
65
+ const handleSave = useCallback(
66
+ ({ tag, ...values }: Schema.Schema.Type<typeof formSchema>) => {
67
+ batch(() => {
68
+ const meta = Obj.getMeta(object);
69
+ const currentTag = meta.tags?.[0];
70
+ if (tag !== undefined && currentTag !== tag?.dxn.toString()) {
71
+ meta.tags = [tag.dxn.toString()];
72
+ }
73
+
74
+ Object.entries(values).forEach(([key, value]) => {
75
+ if (value !== undefined && value !== object[key as keyof Obj.Any]) {
76
+ Object.defineProperty(object, key, { value });
77
+ }
78
+ });
79
+ });
80
+ },
81
+ [object],
82
+ );
83
+
84
+ if (!formSchema) {
85
+ return null;
86
+ }
21
87
 
22
- // TODO(wittjosiah): This should be a form based on the schema of the object.
23
- // The form should only include fields with a specific settings annotation.
24
- // Perhaps also including the field of the title annotation as well.
25
88
  return (
26
89
  <>
27
- <Input.Root>
28
- <Input.Label>{t('name label')}</Input.Label>
29
- <Input.TextInput
30
- ref={inputRef}
31
- placeholder={t('name placeholder')}
32
- // TODO(burdon): Use annotation to get the name field.
33
- value={(object as any).name ?? ''}
34
- onChange={(event) => {
35
- (object as any).name = event.target.value;
36
- }}
37
- onKeyDown={(event) => {
38
- if (event.key === 'Enter') {
39
- inputRef.current?.blur();
40
- }
41
- }}
42
- />
43
- </Input.Root>
90
+ <Form
91
+ classNames={classNames}
92
+ outerSpacing={false}
93
+ autoSave
94
+ schema={formSchema}
95
+ values={values}
96
+ createSchema={TagSchema}
97
+ createOptionIcon='ph--plus--regular'
98
+ createOptionLabel={['add tag label', { ns: pluginMeta.id }]}
99
+ createInitialValuePath='label'
100
+ onCreate={handleCreateTag}
101
+ onSave={handleSave}
102
+ onQueryRefOptions={handleRefQueryLookup}
103
+ />
44
104
  {children}
45
105
  </>
46
106
  );
@@ -4,7 +4,7 @@
4
4
 
5
5
  import React, { useCallback } from 'react';
6
6
 
7
- import { type ForeignKey } from '@dxos/echo-schema';
7
+ import { type ForeignKey } from '@dxos/echo/internal';
8
8
  import { IconButton, List, ListItem, useTranslation } from '@dxos/react-ui';
9
9
 
10
10
  import { meta } from '../../meta';
@@ -2,4 +2,6 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- export * from './ObjectSettingsContainer';
5
+ import { ObjectSettingsContainer } from './ObjectSettingsContainer';
6
+
7
+ export default ObjectSettingsContainer;
@@ -0,0 +1,116 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+ import React from 'react';
7
+
8
+ import { Capabilities, contributes, createSurface } from '@dxos/app-framework';
9
+ import { withPluginManager } from '@dxos/app-framework/testing';
10
+ import { Filter, Obj, Ref, Relation, type Type } from '@dxos/echo';
11
+ import { faker } from '@dxos/random';
12
+ import { useQuery } from '@dxos/react-client/echo';
13
+ import { useClientProvider, withClientProvider } from '@dxos/react-client/testing';
14
+ import { withTheme } from '@dxos/react-ui/testing';
15
+ import { Card } from '@dxos/react-ui-stack';
16
+ import { DataType } from '@dxos/schema';
17
+ import { type ValueGenerator, createAsyncGenerator } from '@dxos/schema/testing';
18
+ import { translations as shellTranslations } from '@dxos/shell/react';
19
+ import { render } from '@dxos/storybook-utils';
20
+
21
+ import { translations } from '../translations';
22
+
23
+ import { RecordMain } from './RecordMain';
24
+
25
+ faker.seed(1);
26
+ const generator: ValueGenerator = faker as any;
27
+
28
+ const DefaultStory = () => {
29
+ const { space } = useClientProvider();
30
+ const [org] = useQuery(space, Filter.type(DataType.Organization));
31
+ if (!org) {
32
+ return null;
33
+ }
34
+
35
+ return <RecordMain record={org} />;
36
+ };
37
+
38
+ const meta = {
39
+ title: 'plugins/plugin-space/RecordMain',
40
+ component: RecordMain as any,
41
+ render: render(DefaultStory),
42
+ decorators: [
43
+ withTheme, // TODO(wittjosiah): Try to write story which does not depend on plugin manager.
44
+ withPluginManager({
45
+ capabilities: [
46
+ contributes(Capabilities.ReactSurface, [
47
+ createSurface({
48
+ id: 'section',
49
+ role: 'section',
50
+ component: ({ data }) => (
51
+ <div role='none' className='flex justify-center'>
52
+ <div role='none' className='card-max-width'>
53
+ <Card.SurfaceRoot classNames='p-2'>
54
+ <pre className='overflow-x-auto'>{JSON.stringify(data, null, 2)}</pre>
55
+ </Card.SurfaceRoot>
56
+ </div>
57
+ </div>
58
+ ),
59
+ }),
60
+ createSurface({
61
+ id: 'card',
62
+ role: 'card',
63
+ component: ({ data }) => (
64
+ <Card.SurfaceRoot classNames='p-2'>
65
+ <pre className='overflow-x-auto'>{JSON.stringify(data, null, 2)}</pre>
66
+ </Card.SurfaceRoot>
67
+ ),
68
+ }),
69
+ ]),
70
+ ],
71
+ }),
72
+ withClientProvider({
73
+ createIdentity: true,
74
+ createSpace: true,
75
+ types: [DataType.Organization, DataType.Person, DataType.Task, DataType.HasSubject],
76
+ onCreateSpace: async ({ space }) => {
77
+ const org = space.db.add(
78
+ Obj.make(DataType.Organization, {
79
+ name: 'ACME Corp',
80
+ }),
81
+ );
82
+ const task = space.db.add(
83
+ Obj.make(DataType.Task, {
84
+ title: 'Task',
85
+ }),
86
+ );
87
+ space.db.add(
88
+ Relation.make(DataType.HasSubject, {
89
+ [Relation.Source]: task,
90
+ [Relation.Target]: org,
91
+ completedAt: new Date().toISOString(),
92
+ }),
93
+ );
94
+ const objectGenerator = createAsyncGenerator(generator, DataType.Person as Type.Obj.Any, {
95
+ db: space?.db,
96
+ force: true,
97
+ });
98
+ await objectGenerator.createObjects(3).then((objects) => {
99
+ objects.forEach((object) => {
100
+ object.organization = Ref.make(org);
101
+ });
102
+ });
103
+ },
104
+ }),
105
+ ],
106
+ parameters: {
107
+ layout: 'fullscreen',
108
+ translations: [...translations, ...shellTranslations],
109
+ },
110
+ } satisfies Meta<typeof DefaultStory>;
111
+
112
+ export default meta;
113
+
114
+ type Story = StoryObj<typeof meta>;
115
+
116
+ export const Default: Story = {};