@dxos/plugin-space 0.6.14-main.8b352a0 → 0.6.14-staging.3e2eaca

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 (108) hide show
  1. package/dist/lib/browser/{chunk-AVLRQF6L.mjs → chunk-DJE2HYFV.mjs} +3 -2
  2. package/dist/lib/browser/{chunk-AVLRQF6L.mjs.map → chunk-DJE2HYFV.mjs.map} +2 -2
  3. package/dist/lib/browser/{chunk-FOI7DAUV.mjs → chunk-OWZKSWMX.mjs} +1 -1
  4. package/dist/lib/browser/{chunk-FOI7DAUV.mjs.map → chunk-OWZKSWMX.mjs.map} +2 -2
  5. package/dist/lib/browser/index.mjs +817 -762
  6. package/dist/lib/browser/index.mjs.map +4 -4
  7. package/dist/lib/browser/meta.json +1 -1
  8. package/dist/lib/browser/meta.mjs +1 -1
  9. package/dist/lib/browser/types/index.mjs +1 -1
  10. package/dist/lib/node/{chunk-OTDRTHT4.cjs → chunk-FYWGZYJB.cjs} +4 -4
  11. package/dist/lib/node/{chunk-OTDRTHT4.cjs.map → chunk-FYWGZYJB.cjs.map} +2 -2
  12. package/dist/lib/node/{chunk-P4XUXM7Y.cjs → chunk-JFDDZI4Y.cjs} +6 -5
  13. package/dist/lib/node/{chunk-P4XUXM7Y.cjs.map → chunk-JFDDZI4Y.cjs.map} +2 -2
  14. package/dist/lib/node/index.cjs +1009 -957
  15. package/dist/lib/node/index.cjs.map +4 -4
  16. package/dist/lib/node/meta.cjs +5 -5
  17. package/dist/lib/node/meta.cjs.map +1 -1
  18. package/dist/lib/node/meta.json +1 -1
  19. package/dist/lib/node/types/index.cjs +11 -11
  20. package/dist/lib/node/types/index.cjs.map +1 -1
  21. package/dist/lib/node-esm/{chunk-YPQGKWHJ.mjs → chunk-DVUZ7A7G.mjs} +3 -2
  22. package/dist/lib/node-esm/{chunk-YPQGKWHJ.mjs.map → chunk-DVUZ7A7G.mjs.map} +2 -2
  23. package/dist/lib/node-esm/{chunk-FYDGMPSC.mjs → chunk-MCEAI4CV.mjs} +1 -1
  24. package/dist/lib/node-esm/{chunk-FYDGMPSC.mjs.map → chunk-MCEAI4CV.mjs.map} +2 -2
  25. package/dist/lib/node-esm/index.mjs +817 -762
  26. package/dist/lib/node-esm/index.mjs.map +4 -4
  27. package/dist/lib/node-esm/meta.json +1 -1
  28. package/dist/lib/node-esm/meta.mjs +1 -1
  29. package/dist/lib/node-esm/types/index.mjs +1 -1
  30. package/dist/types/src/SpacePlugin.d.ts +9 -1
  31. package/dist/types/src/SpacePlugin.d.ts.map +1 -1
  32. package/dist/types/src/components/JoinDialog.d.ts +7 -0
  33. package/dist/types/src/components/JoinDialog.d.ts.map +1 -0
  34. package/dist/types/src/components/ShareSpaceButton.d.ts +3 -2
  35. package/dist/types/src/components/ShareSpaceButton.d.ts.map +1 -1
  36. package/dist/types/src/components/{SpaceSettings.d.ts → SpacePluginSettings.d.ts} +2 -2
  37. package/dist/types/src/components/SpacePluginSettings.d.ts.map +1 -0
  38. package/dist/types/src/components/SpaceSettings/SpaceSettingsDialog.d.ts +10 -0
  39. package/dist/types/src/components/SpaceSettings/SpaceSettingsDialog.d.ts.map +1 -0
  40. package/dist/types/src/components/SpaceSettings/SpaceSettingsDialog.stories.d.ts +7 -0
  41. package/dist/types/src/components/SpaceSettings/SpaceSettingsDialog.stories.d.ts.map +1 -0
  42. package/dist/types/src/components/SpaceSettings/SpaceSettingsPanel.d.ts.map +1 -0
  43. package/dist/types/src/components/SpaceSettings/SpaceSettingsPanel.stories.d.ts +7 -0
  44. package/dist/types/src/components/SpaceSettings/SpaceSettingsPanel.stories.d.ts.map +1 -0
  45. package/dist/types/src/components/SpaceSettings/index.d.ts +3 -0
  46. package/dist/types/src/components/SpaceSettings/index.d.ts.map +1 -0
  47. package/dist/types/src/components/SyncStatus/Space.d.ts +8 -0
  48. package/dist/types/src/components/SyncStatus/Space.d.ts.map +1 -0
  49. package/dist/types/src/components/SyncStatus/SyncStatus.d.ts +3 -2
  50. package/dist/types/src/components/SyncStatus/SyncStatus.d.ts.map +1 -1
  51. package/dist/types/src/components/SyncStatus/SyncStatus.stories.d.ts +5 -20
  52. package/dist/types/src/components/SyncStatus/SyncStatus.stories.d.ts.map +1 -1
  53. package/dist/types/src/components/SyncStatus/save-tracker.d.ts +3 -0
  54. package/dist/types/src/components/SyncStatus/save-tracker.d.ts.map +1 -0
  55. package/dist/types/src/components/SyncStatus/status.d.ts +9 -0
  56. package/dist/types/src/components/SyncStatus/status.d.ts.map +1 -0
  57. package/dist/types/src/components/SyncStatus/{types.d.ts → sync-state.d.ts} +1 -1
  58. package/dist/types/src/components/SyncStatus/sync-state.d.ts.map +1 -0
  59. package/dist/types/src/components/index.d.ts +2 -4
  60. package/dist/types/src/components/index.d.ts.map +1 -1
  61. package/dist/types/src/meta.d.ts +3 -2
  62. package/dist/types/src/meta.d.ts.map +1 -1
  63. package/dist/types/src/translations.d.ts +10 -0
  64. package/dist/types/src/translations.d.ts.map +1 -1
  65. package/dist/types/src/types/types.d.ts +7 -1
  66. package/dist/types/src/types/types.d.ts.map +1 -1
  67. package/dist/types/src/util.d.ts +8 -4
  68. package/dist/types/src/util.d.ts.map +1 -1
  69. package/package.json +35 -33
  70. package/src/SpacePlugin.tsx +279 -175
  71. package/src/components/AwaitingObject.tsx +1 -1
  72. package/src/components/JoinDialog.tsx +100 -0
  73. package/src/components/ShareSpaceButton.tsx +10 -6
  74. package/src/components/{SpaceSettings.tsx → SpacePluginSettings.tsx} +6 -6
  75. package/src/components/SpaceSettings/SpaceSettingsDialog.stories.tsx +44 -0
  76. package/src/components/SpaceSettings/SpaceSettingsDialog.tsx +103 -0
  77. package/src/components/SpaceSettings/SpaceSettingsPanel.stories.tsx +32 -0
  78. package/src/components/{SpaceSettingsPanel.tsx → SpaceSettings/SpaceSettingsPanel.tsx} +25 -20
  79. package/src/components/SpaceSettings/index.ts +6 -0
  80. package/src/components/SyncStatus/Space.tsx +109 -0
  81. package/src/components/SyncStatus/SyncStatus.stories.tsx +13 -4
  82. package/src/components/SyncStatus/SyncStatus.tsx +43 -129
  83. package/src/components/{SaveStatus.tsx → SyncStatus/save-tracker.ts} +1 -25
  84. package/src/components/SyncStatus/status.ts +44 -0
  85. package/src/components/index.ts +2 -4
  86. package/src/meta.ts +2 -1
  87. package/src/translations.ts +10 -0
  88. package/src/types/types.ts +9 -1
  89. package/src/util.tsx +51 -23
  90. package/dist/types/src/components/MissingObject.d.ts +0 -5
  91. package/dist/types/src/components/MissingObject.d.ts.map +0 -1
  92. package/dist/types/src/components/SaveStatus.d.ts +0 -3
  93. package/dist/types/src/components/SaveStatus.d.ts.map +0 -1
  94. package/dist/types/src/components/SpaceMain/SpaceMain.d.ts +0 -10
  95. package/dist/types/src/components/SpaceMain/SpaceMain.d.ts.map +0 -1
  96. package/dist/types/src/components/SpaceMain/SpaceMembersSection.d.ts +0 -6
  97. package/dist/types/src/components/SpaceMain/SpaceMembersSection.d.ts.map +0 -1
  98. package/dist/types/src/components/SpaceMain/index.d.ts +0 -2
  99. package/dist/types/src/components/SpaceMain/index.d.ts.map +0 -1
  100. package/dist/types/src/components/SpaceSettings.d.ts.map +0 -1
  101. package/dist/types/src/components/SpaceSettingsPanel.d.ts.map +0 -1
  102. package/dist/types/src/components/SyncStatus/types.d.ts.map +0 -1
  103. package/src/components/MissingObject.tsx +0 -54
  104. package/src/components/SpaceMain/SpaceMain.tsx +0 -60
  105. package/src/components/SpaceMain/SpaceMembersSection.tsx +0 -205
  106. package/src/components/SpaceMain/index.ts +0 -5
  107. /package/dist/types/src/components/{SpaceSettingsPanel.d.ts → SpaceSettings/SpaceSettingsPanel.d.ts} +0 -0
  108. /package/src/components/SyncStatus/{types.ts → sync-state.ts} +0 -0
@@ -3,7 +3,7 @@ import {
3
3
  SPACE_PLUGIN_SHORT_ID,
4
4
  SpaceAction,
5
5
  meta_default
6
- } from "./chunk-AVLRQF6L.mjs";
6
+ } from "./chunk-DJE2HYFV.mjs";
7
7
  import {
8
8
  ActorSchema,
9
9
  ChannelType,
@@ -15,26 +15,26 @@ import {
15
15
  ThreadStatus,
16
16
  ThreadType,
17
17
  parseSpaceInitPlugin
18
- } from "./chunk-FOI7DAUV.mjs";
18
+ } from "./chunk-OWZKSWMX.mjs";
19
19
 
20
20
  // packages/plugins/plugin-space/src/SpacePlugin.tsx
21
21
  import { signal } from "@preact/signals-core";
22
- import React18 from "react";
23
- import { LayoutAction as LayoutAction2, NavigationAction as NavigationAction3, Surface as Surface2, firstIdInPart, openIds, parseGraphPlugin, parseIntentPlugin as parseIntentPlugin3, parseMetadataResolverPlugin, parseNavigationPlugin as parseNavigationPlugin2, resolvePlugin } from "@dxos/app-framework";
22
+ import React17 from "react";
23
+ import { LayoutAction as LayoutAction2, NavigationAction as NavigationAction4, Surface, findPlugin, firstIdInPart, openIds, parseGraphPlugin, parseIntentPlugin as parseIntentPlugin2, parseLayoutPlugin, parseMetadataResolverPlugin, parseNavigationPlugin as parseNavigationPlugin2, resolvePlugin } from "@dxos/app-framework";
24
24
  import { EventSubscriptions } from "@dxos/async";
25
25
  import { isReactiveObject as isReactiveObject2 } from "@dxos/echo-schema";
26
26
  import { scheduledEffect } from "@dxos/echo-signals/core";
27
+ import { invariant as invariant2 } from "@dxos/invariant";
27
28
  import { LocalStorageStore } from "@dxos/local-storage";
28
29
  import { log as log3 } from "@dxos/log";
29
30
  import { Migrations as Migrations2 } from "@dxos/migrations";
30
31
  import { parseAttentionPlugin } from "@dxos/plugin-attention";
31
32
  import { parseClientPlugin } from "@dxos/plugin-client";
32
33
  import { createExtension, memoize as memoize2, toSignal } from "@dxos/plugin-graph";
33
- import { ObservabilityAction } from "@dxos/plugin-observability/meta";
34
+ import { ObservabilityAction as ObservabilityAction2 } from "@dxos/plugin-observability/meta";
34
35
  import { PublicKey as PublicKey2 } from "@dxos/react-client";
35
- import { Expando, Filter, SpaceState as SpaceState3, create as create2, fullyQualifiedId as fullyQualifiedId4, getSpace as getSpace4, getTypename as getTypename2, isEchoObject as isEchoObject2, isSpace as isSpace2, loadObjectReferences, parseId } from "@dxos/react-client/echo";
36
- import { Dialog } from "@dxos/react-ui";
37
- import { ClipboardProvider as ClipboardProvider2, InvitationManager, osTranslations } from "@dxos/shell/react";
36
+ import { Expando, Filter, SpaceState as SpaceState2, create as create2, fullyQualifiedId as fullyQualifiedId4, getSpace as getSpace4, getTypename as getTypename2, isEchoObject as isEchoObject2, isSpace as isSpace2, loadObjectReferences, parseId, FQ_ID_LENGTH } from "@dxos/react-client/echo";
37
+ import { osTranslations } from "@dxos/shell/react";
38
38
  import { ComplexMap as ComplexMap2, nonNullable, reduceGroupBy } from "@dxos/util";
39
39
 
40
40
  // packages/plugins/plugin-space/src/components/AwaitingObject.tsx
@@ -70,7 +70,7 @@ var AwaitingObject = ({ id }) => {
70
70
  useEffect(() => {
71
71
  if (objects.findIndex((object) => fullyQualifiedId(object) === id) > -1) {
72
72
  setFound(true);
73
- if (navigationPlugin?.provides.location.active === id) {
73
+ if (navigationPlugin?.provides.location.active.solo?.[0].id === id) {
74
74
  setOpen(false);
75
75
  }
76
76
  }
@@ -177,15 +177,105 @@ var DefaultObjectSettings = ({ object }) => {
177
177
  })));
178
178
  };
179
179
 
180
+ // packages/plugins/plugin-space/src/components/JoinDialog.tsx
181
+ import React5, { useCallback } from "react";
182
+ import { LayoutAction, NavigationAction as NavigationAction2, useIntentDispatcher } from "@dxos/app-framework";
183
+ import { useGraph } from "@dxos/plugin-graph";
184
+ import { ObservabilityAction } from "@dxos/plugin-observability/meta";
185
+ import { useSpaces } from "@dxos/react-client/echo";
186
+ import { Dialog, useTranslation as useTranslation5 } from "@dxos/react-ui";
187
+ import { JoinPanel } from "@dxos/shell/react";
188
+ var JoinDialog = ({ navigableCollections, ...props }) => {
189
+ const { t } = useTranslation5(SPACE_PLUGIN);
190
+ const dispatch = useIntentDispatcher();
191
+ const spaces = useSpaces();
192
+ const { graph } = useGraph();
193
+ const handleDone = useCallback(async (result) => {
194
+ if (result?.spaceKey) {
195
+ await Promise.all([
196
+ dispatch({
197
+ action: LayoutAction.SET_LAYOUT,
198
+ data: {
199
+ element: "toast",
200
+ subject: {
201
+ id: `${SPACE_PLUGIN}/join-success`,
202
+ duration: 5e3,
203
+ title: t("join success label"),
204
+ closeLabel: t("dismiss label")
205
+ }
206
+ }
207
+ }),
208
+ dispatch({
209
+ action: LayoutAction.SET_LAYOUT,
210
+ data: {
211
+ element: "dialog",
212
+ state: false
213
+ }
214
+ })
215
+ ]);
216
+ }
217
+ const space = spaces.find(({ key }) => result?.spaceKey?.equals(key));
218
+ const target = result?.target || (navigableCollections ? space?.id : void 0);
219
+ if (target) {
220
+ await graph.waitForPath({
221
+ target
222
+ }).catch(() => {
223
+ });
224
+ await Promise.all([
225
+ dispatch({
226
+ action: NavigationAction2.OPEN,
227
+ data: {
228
+ activeParts: {
229
+ main: [
230
+ target
231
+ ]
232
+ }
233
+ }
234
+ }),
235
+ dispatch({
236
+ action: NavigationAction2.EXPOSE,
237
+ data: {
238
+ id: target
239
+ }
240
+ })
241
+ ]);
242
+ }
243
+ if (space) {
244
+ await dispatch({
245
+ action: ObservabilityAction.SEND_EVENT,
246
+ data: {
247
+ name: "space.join",
248
+ properties: {
249
+ spaceId: space.id
250
+ }
251
+ }
252
+ });
253
+ }
254
+ }, [
255
+ dispatch,
256
+ spaces
257
+ ]);
258
+ return /* @__PURE__ */ React5.createElement(Dialog.Content, null, /* @__PURE__ */ React5.createElement(JoinPanel, {
259
+ ...props,
260
+ exitActionParent: /* @__PURE__ */ React5.createElement(Dialog.Close, {
261
+ asChild: true
262
+ }),
263
+ doneActionParent: /* @__PURE__ */ React5.createElement(Dialog.Close, {
264
+ asChild: true
265
+ }),
266
+ onDone: handleDone
267
+ }));
268
+ };
269
+
180
270
  // packages/plugins/plugin-space/src/components/MenuFooter.tsx
181
271
  import { Planet } from "@phosphor-icons/react";
182
- import React5 from "react";
272
+ import React6 from "react";
183
273
  import { getSpace as getSpace2 } from "@dxos/client/echo";
184
274
  import { useClient as useClient2 } from "@dxos/react-client";
185
- import { DropdownMenu, toLocalizedString, useTranslation as useTranslation5 } from "@dxos/react-ui";
275
+ import { DropdownMenu, toLocalizedString, useTranslation as useTranslation6 } from "@dxos/react-ui";
186
276
 
187
277
  // packages/plugins/plugin-space/src/util.tsx
188
- import { NavigationAction as NavigationAction2 } from "@dxos/app-framework";
278
+ import { NavigationAction as NavigationAction3 } from "@dxos/app-framework";
189
279
  import { create, isReactiveObject, getTypename, getSchema, getObjectAnnotation, EXPANDO_TYPENAME } from "@dxos/echo-schema";
190
280
  import { invariant } from "@dxos/invariant";
191
281
  import { Migrations } from "@dxos/migrations";
@@ -217,8 +307,9 @@ var getSpaceDisplayName = (space, { personal, namesCache = {} } = {}) => {
217
307
  }
218
308
  ];
219
309
  };
220
- var getCollectionGraphNodePartials = ({ collection, space, resolve }) => {
310
+ var getCollectionGraphNodePartials = ({ navigable, collection, space, resolve }) => {
221
311
  return {
312
+ disabled: !navigable,
222
313
  acceptPersistenceClass: /* @__PURE__ */ new Set([
223
314
  "echo"
224
315
  ]),
@@ -258,13 +349,14 @@ var getCollectionGraphNodePartials = ({ collection, space, resolve }) => {
258
349
  var checkPendingMigration = (space) => {
259
350
  return space.state.get() === SpaceState.SPACE_REQUIRES_MIGRATION || space.state.get() === SpaceState.SPACE_READY && !!Migrations.versionProperty && space.properties[Migrations.versionProperty] !== Migrations.targetVersion;
260
351
  };
261
- var constructSpaceNode = ({ space, personal, namesCache, resolve }) => {
352
+ var constructSpaceNode = ({ space, navigable = false, personal, namesCache, resolve }) => {
262
353
  const hasPendingMigration = checkPendingMigration(space);
263
354
  const collection = space.state.get() === SpaceState.SPACE_READY && space.properties[CollectionType.typename];
264
355
  const partials = space.state.get() === SpaceState.SPACE_READY && collection instanceof CollectionType ? getCollectionGraphNodePartials({
265
356
  collection,
266
357
  space,
267
- resolve
358
+ resolve,
359
+ navigable
268
360
  }) : {};
269
361
  return {
270
362
  id: space.id,
@@ -278,12 +370,12 @@ var constructSpaceNode = ({ space, personal, namesCache, resolve }) => {
278
370
  }),
279
371
  description: space.state.get() === SpaceState.SPACE_READY && space.properties.description,
280
372
  icon: "ph--planet--regular",
281
- disabled: space.state.get() !== SpaceState.SPACE_READY || hasPendingMigration,
373
+ disabled: !navigable || space.state.get() !== SpaceState.SPACE_READY || hasPendingMigration,
282
374
  testId: "spacePlugin.space"
283
375
  }
284
376
  };
285
377
  };
286
- var constructSpaceActionGroups = ({ space, dispatch }) => {
378
+ var constructSpaceActionGroups = ({ space, navigable, dispatch }) => {
287
379
  const state = space.state.get();
288
380
  const hasPendingMigration = checkPendingMigration(space);
289
381
  const getId = (id) => `${id}/${space.id}`;
@@ -305,8 +397,6 @@ var constructSpaceActionGroups = ({ space, dispatch }) => {
305
397
  ],
306
398
  icon: "ph--plus--regular",
307
399
  disposition: "toolbar",
308
- // TODO(wittjosiah): This is currently a navtree feature. Address this with cmd+k integration.
309
- // mainAreaDisposition: 'in-flow',
310
400
  menuType: "searchList",
311
401
  testId: "spacePlugin.createObject"
312
402
  },
@@ -326,9 +416,11 @@ var constructSpaceActionGroups = ({ space, dispatch }) => {
326
416
  })
327
417
  }
328
418
  },
329
- {
330
- action: NavigationAction2.OPEN
331
- }
419
+ ...navigable ? [
420
+ {
421
+ action: NavigationAction3.OPEN
422
+ }
423
+ ] : []
332
424
  ]),
333
425
  properties: {
334
426
  label: [
@@ -373,7 +465,6 @@ var constructSpaceActions = ({ space, dispatch, personal, migrating }) => {
373
465
  ],
374
466
  icon: "ph--database--regular",
375
467
  disposition: "toolbar",
376
- mainAreaDisposition: "in-flow",
377
468
  disabled: migrating || Migrations.running(space)
378
469
  }
379
470
  });
@@ -391,7 +482,7 @@ var constructSpaceActions = ({ space, dispatch, personal, migrating }) => {
391
482
  plugin: SPACE_PLUGIN,
392
483
  action: SpaceAction.SHARE,
393
484
  data: {
394
- spaceId: space.id
485
+ space
395
486
  }
396
487
  });
397
488
  },
@@ -407,8 +498,7 @@ var constructSpaceActions = ({ space, dispatch, personal, migrating }) => {
407
498
  keyBinding: {
408
499
  macos: "meta+.",
409
500
  windows: "alt+."
410
- },
411
- mainAreaDisposition: "absent"
501
+ }
412
502
  }
413
503
  }, {
414
504
  id: locked ? getId(SpaceAction.UNLOCK) : getId(SpaceAction.LOCK),
@@ -455,8 +545,28 @@ var constructSpaceActions = ({ space, dispatch, personal, migrating }) => {
455
545
  keyBinding: {
456
546
  macos: "shift+F6",
457
547
  windows: "shift+F6"
458
- },
459
- mainAreaDisposition: "absent"
548
+ }
549
+ }
550
+ }, {
551
+ id: getId(SpaceAction.OPEN_SETTINGS),
552
+ type: ACTION_TYPE,
553
+ data: async () => {
554
+ await dispatch({
555
+ plugin: SPACE_PLUGIN,
556
+ action: SpaceAction.OPEN_SETTINGS,
557
+ data: {
558
+ space
559
+ }
560
+ });
561
+ },
562
+ properties: {
563
+ label: [
564
+ "open space settings label",
565
+ {
566
+ ns: SPACE_PLUGIN
567
+ }
568
+ ],
569
+ icon: "ph--gear--regular"
460
570
  }
461
571
  });
462
572
  }
@@ -481,7 +591,6 @@ var constructSpaceActions = ({ space, dispatch, personal, migrating }) => {
481
591
  }
482
592
  ],
483
593
  icon: "ph--x--regular",
484
- mainAreaDisposition: "menu",
485
594
  disabled: personal
486
595
  }
487
596
  });
@@ -507,14 +616,13 @@ var constructSpaceActions = ({ space, dispatch, personal, migrating }) => {
507
616
  }
508
617
  ],
509
618
  icon: "ph--clock-counter-clockwise--regular",
510
- disposition: "toolbar",
511
- mainAreaDisposition: "in-flow"
619
+ disposition: "toolbar"
512
620
  }
513
621
  });
514
622
  }
515
623
  return actions;
516
624
  };
517
- var createObjectNode = ({ object, space, resolve }) => {
625
+ var createObjectNode = ({ object, space, navigable = false, resolve }) => {
518
626
  const type = getTypename(object);
519
627
  if (!type) {
520
628
  return void 0;
@@ -526,7 +634,8 @@ var createObjectNode = ({ object, space, resolve }) => {
526
634
  const partials = object instanceof CollectionType ? getCollectionGraphNodePartials({
527
635
  collection: object,
528
636
  space,
529
- resolve
637
+ resolve,
638
+ navigable
530
639
  }) : metadata.graphProps;
531
640
  return {
532
641
  id: fullyQualifiedId2(object),
@@ -547,7 +656,7 @@ var createObjectNode = ({ object, space, resolve }) => {
547
656
  }
548
657
  };
549
658
  };
550
- var constructObjectActionGroups = ({ object, dispatch }) => {
659
+ var constructObjectActionGroups = ({ object, navigable, dispatch }) => {
551
660
  if (!(object instanceof CollectionType)) {
552
661
  return [];
553
662
  }
@@ -567,8 +676,6 @@ var constructObjectActionGroups = ({ object, dispatch }) => {
567
676
  ],
568
677
  icon: "ph--plus--regular",
569
678
  disposition: "toolbar",
570
- // TODO(wittjosiah): This is currently a navtree feature. Address this with cmd+k integration.
571
- // mainAreaDisposition: 'in-flow',
572
679
  menuType: "searchList",
573
680
  testId: "spacePlugin.createObject"
574
681
  },
@@ -588,9 +695,11 @@ var constructObjectActionGroups = ({ object, dispatch }) => {
588
695
  })
589
696
  }
590
697
  },
591
- {
592
- action: NavigationAction2.OPEN
593
- }
698
+ ...navigable ? [
699
+ {
700
+ action: NavigationAction3.OPEN
701
+ }
702
+ ] : []
594
703
  ]),
595
704
  properties: {
596
705
  label: [
@@ -638,7 +747,7 @@ var constructObjectActions = ({ node, dispatch }) => {
638
747
  }
639
748
  },
640
749
  {
641
- id: getId(SpaceAction.REMOVE_OBJECT),
750
+ id: getId(SpaceAction.REMOVE_OBJECTS),
642
751
  type: ACTION_TYPE,
643
752
  data: async () => {
644
753
  const graph = getGraph(node);
@@ -647,9 +756,11 @@ var constructObjectActions = ({ node, dispatch }) => {
647
756
  }).find(({ data }) => data instanceof CollectionType)?.data;
648
757
  await dispatch([
649
758
  {
650
- action: SpaceAction.REMOVE_OBJECT,
759
+ action: SpaceAction.REMOVE_OBJECTS,
651
760
  data: {
652
- object,
761
+ objects: [
762
+ object
763
+ ],
653
764
  collection
654
765
  }
655
766
  }
@@ -722,7 +833,7 @@ var cloneObject = async (object, resolve, newSpace) => {
722
833
  const serializer = metadata.serializer;
723
834
  invariant(serializer, `No serializer for type: ${typename}`, {
724
835
  F: __dxlog_file,
725
- L: 604,
836
+ L: 632,
726
837
  S: void 0,
727
838
  A: [
728
839
  "serializer",
@@ -741,83 +852,42 @@ var cloneObject = async (object, resolve, newSpace) => {
741
852
 
742
853
  // packages/plugins/plugin-space/src/components/MenuFooter.tsx
743
854
  var MenuFooter = ({ object }) => {
744
- const { t } = useTranslation5(SPACE_PLUGIN);
855
+ const { t } = useTranslation6(SPACE_PLUGIN);
745
856
  const client = useClient2();
746
857
  const space = getSpace2(object);
747
858
  const spaceName = space ? getSpaceDisplayName(space, {
748
859
  personal: client.spaces.default === space
749
860
  }) : "";
750
- return space ? /* @__PURE__ */ React5.createElement(React5.Fragment, null, /* @__PURE__ */ React5.createElement(DropdownMenu.Separator, null), /* @__PURE__ */ React5.createElement(DropdownMenu.GroupLabel, null, t("menu footer label")), /* @__PURE__ */ React5.createElement("dl", {
861
+ return space ? /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(DropdownMenu.Separator, null), /* @__PURE__ */ React6.createElement(DropdownMenu.GroupLabel, null, t("menu footer label")), /* @__PURE__ */ React6.createElement("dl", {
751
862
  className: "pis-2 mbe-2 text-xs grid grid-cols-[max-content_1fr] gap-2"
752
- }, /* @__PURE__ */ React5.createElement("dt", {
863
+ }, /* @__PURE__ */ React6.createElement("dt", {
753
864
  className: "uppercase text-[.75em] tracking-wide font-medium mbs-px self-start"
754
- }, t("location label")), /* @__PURE__ */ React5.createElement("dd", {
865
+ }, t("location label")), /* @__PURE__ */ React6.createElement("dd", {
755
866
  className: "line-clamp-3"
756
- }, /* @__PURE__ */ React5.createElement(Planet, {
867
+ }, /* @__PURE__ */ React6.createElement(Planet, {
757
868
  className: "inline-block mie-1"
758
869
  }), toLocalizedString(spaceName, t)))) : null;
759
870
  };
760
871
 
761
- // packages/plugins/plugin-space/src/components/MissingObject.tsx
762
- import React6, { useEffect as useEffect2, useState as useState2 } from "react";
763
- import { parseIntentPlugin as parseIntentPlugin2, useResolvePlugin as useResolvePlugin2 } from "@dxos/app-framework";
764
- import { Status, useTranslation as useTranslation6 } from "@dxos/react-ui";
765
- import { baseSurface as baseSurface2, descriptionText as descriptionText2, mx as mx3 } from "@dxos/react-ui-theme";
766
- var WAIT_FOR_OBJECT_TIMEOUT2 = 1e3;
767
- var MissingObject = ({ id }) => {
768
- const { t } = useTranslation6(SPACE_PLUGIN);
769
- const [waiting, setWaiting] = useState2(false);
770
- const intentPlugin = useResolvePlugin2(parseIntentPlugin2);
771
- useEffect2(() => {
772
- if (!intentPlugin) {
773
- return;
774
- }
775
- const timeout = setTimeout(async () => {
776
- setWaiting(true);
777
- await intentPlugin.provides.intent.dispatch({
778
- plugin: SPACE_PLUGIN,
779
- action: SpaceAction.WAIT_FOR_OBJECT,
780
- data: {
781
- id
782
- }
783
- });
784
- }, WAIT_FOR_OBJECT_TIMEOUT2);
785
- return () => clearTimeout(timeout);
786
- }, [
787
- intentPlugin,
788
- id
789
- ]);
790
- return /* @__PURE__ */ React6.createElement("div", {
791
- role: "none",
792
- className: mx3(baseSurface2, "min-bs-screen is-full flex items-center justify-center p-8")
793
- }, waiting ? /* @__PURE__ */ React6.createElement("p", {
794
- role: "alert",
795
- className: mx3(descriptionText2, "border border-dashed border-neutral-400/50 rounded-lg flex items-center justify-center p-8 font-normal text-lg")
796
- }, t("missing object message")) : /* @__PURE__ */ React6.createElement(Status, {
797
- indeterminate: true,
798
- "aria-label": "Initializing"
799
- }));
800
- };
801
-
802
872
  // packages/plugins/plugin-space/src/components/PersistenceStatus.tsx
803
873
  import { ArrowsCounterClockwise, CheckCircle as CheckCircle2, Warning } from "@phosphor-icons/react";
804
- import React7, { useEffect as useEffect3, useState as useState3 } from "react";
874
+ import React7, { useEffect as useEffect2, useState as useState2 } from "react";
805
875
  import { debounce } from "@dxos/async";
806
876
  import { Tooltip, useTranslation as useTranslation7 } from "@dxos/react-ui";
807
- import { getSize as getSize2, mx as mx4, staticPlaceholderText, warningText } from "@dxos/react-ui-theme";
808
- var Status2;
809
- (function(Status3) {
810
- Status3[Status3["PERSISTED_LOCALLY"] = 0] = "PERSISTED_LOCALLY";
811
- Status3[Status3["PENDING"] = 1] = "PENDING";
812
- Status3[Status3["ERROR"] = 2] = "ERROR";
813
- })(Status2 || (Status2 = {}));
877
+ import { getSize as getSize2, mx as mx3, staticPlaceholderText, warningText } from "@dxos/react-ui-theme";
878
+ var Status;
879
+ (function(Status2) {
880
+ Status2[Status2["PERSISTED_LOCALLY"] = 0] = "PERSISTED_LOCALLY";
881
+ Status2[Status2["PENDING"] = 1] = "PENDING";
882
+ Status2[Status2["ERROR"] = 2] = "ERROR";
883
+ })(Status || (Status = {}));
814
884
  var PersistenceStatus = ({ db }) => {
815
885
  const { t } = useTranslation7(SPACE_PLUGIN);
816
- const [displayMessage, setDisplayMessage] = useState3(false);
817
- const [status, naturalSetStatus] = useState3(0);
818
- const [prevStatus, setPrevStatus] = useState3(0);
886
+ const [displayMessage, setDisplayMessage] = useState2(false);
887
+ const [status, naturalSetStatus] = useState2(0);
888
+ const [prevStatus, setPrevStatus] = useState2(0);
819
889
  const _setStatus = debounce(naturalSetStatus, 500);
820
- useEffect3(() => {
890
+ useEffect2(() => {
821
891
  setPrevStatus(status);
822
892
  if (prevStatus !== status && status === 0) {
823
893
  setDisplayMessage(true);
@@ -832,17 +902,17 @@ var PersistenceStatus = ({ db }) => {
832
902
  return /* @__PURE__ */ React7.createElement("div", {
833
903
  className: "flex items-center"
834
904
  }, /* @__PURE__ */ React7.createElement(Warning, {
835
- className: mx4(getSize2(4), "me-1")
905
+ className: mx3(getSize2(4), "me-1")
836
906
  }), /* @__PURE__ */ React7.createElement("span", {
837
- className: mx4("text-sm", warningText)
907
+ className: mx3("text-sm", warningText)
838
908
  }, t("persistence error label")));
839
909
  case 1:
840
910
  return /* @__PURE__ */ React7.createElement("div", {
841
911
  className: "flex items-center"
842
912
  }, /* @__PURE__ */ React7.createElement(ArrowsCounterClockwise, {
843
- className: mx4(getSize2(4), "me-1")
913
+ className: mx3(getSize2(4), "me-1")
844
914
  }), /* @__PURE__ */ React7.createElement("span", {
845
- className: mx4("text-sm", staticPlaceholderText)
915
+ className: mx3("text-sm", staticPlaceholderText)
846
916
  }, t("persistence pending label")));
847
917
  case 0:
848
918
  default:
@@ -852,9 +922,9 @@ var PersistenceStatus = ({ db }) => {
852
922
  role: "status",
853
923
  className: "flex items-center"
854
924
  }, /* @__PURE__ */ React7.createElement(CheckCircle2, {
855
- className: mx4(getSize2(4), "me-1")
925
+ className: mx3(getSize2(4), "me-1")
856
926
  }), displayMessage && /* @__PURE__ */ React7.createElement("span", {
857
- className: mx4("text-sm", staticPlaceholderText)
927
+ className: mx3("text-sm", staticPlaceholderText)
858
928
  }, t("persisted locally label"))), /* @__PURE__ */ React7.createElement(Tooltip.Portal, null, /* @__PURE__ */ React7.createElement(Tooltip.Content, {
859
929
  classNames: "z-10"
860
930
  }, t("persisted locally message"), /* @__PURE__ */ React7.createElement(Tooltip.Arrow, null))));
@@ -862,7 +932,7 @@ var PersistenceStatus = ({ db }) => {
862
932
  };
863
933
 
864
934
  // packages/plugins/plugin-space/src/components/PopoverRenameObject.tsx
865
- import React8, { useCallback, useRef, useState as useState4 } from "react";
935
+ import React8, { useCallback as useCallback2, useRef, useState as useState3 } from "react";
866
936
  import { log } from "@dxos/log";
867
937
  import { Button as Button2, Input as Input2, Popover, useTranslation as useTranslation8 } from "@dxos/react-ui";
868
938
  var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/components/PopoverRenameObject.tsx";
@@ -870,8 +940,8 @@ var PopoverRenameObject = ({ object: obj }) => {
870
940
  const { t } = useTranslation8(SPACE_PLUGIN);
871
941
  const doneButton = useRef(null);
872
942
  const object = obj;
873
- const [name, setName] = useState4(object.name || object.title || "");
874
- const handleDone = useCallback(() => {
943
+ const [name, setName] = useState3(object.name || object.title || "");
944
+ const handleDone = useCallback2(() => {
875
945
  try {
876
946
  object.name = name;
877
947
  } catch {
@@ -918,13 +988,13 @@ var PopoverRenameObject = ({ object: obj }) => {
918
988
  };
919
989
 
920
990
  // packages/plugins/plugin-space/src/components/PopoverRenameSpace.tsx
921
- import React9, { useCallback as useCallback2, useRef as useRef2, useState as useState5 } from "react";
991
+ import React9, { useCallback as useCallback3, useRef as useRef2, useState as useState4 } from "react";
922
992
  import { Button as Button3, Input as Input3, Popover as Popover2, useTranslation as useTranslation9 } from "@dxos/react-ui";
923
993
  var PopoverRenameSpace = ({ space }) => {
924
994
  const { t } = useTranslation9(SPACE_PLUGIN);
925
995
  const doneButton = useRef2(null);
926
- const [name, setName] = useState5(space.properties.name ?? "");
927
- const handleDone = useCallback2(() => {
996
+ const [name, setName] = useState4(space.properties.name ?? "");
997
+ const handleDone = useCallback3(() => {
928
998
  space.properties.name = name;
929
999
  }, [
930
1000
  space,
@@ -958,270 +1028,37 @@ var PopoverRenameSpace = ({ space }) => {
958
1028
 
959
1029
  // packages/plugins/plugin-space/src/components/ShareSpaceButton.tsx
960
1030
  import React10 from "react";
961
- import { useIntentDispatcher } from "@dxos/app-framework";
962
- import { Button as Button4, useTranslation as useTranslation10 } from "@dxos/react-ui";
963
- var ShareSpaceButton = ({ spaceId }) => {
964
- const dispatch = useIntentDispatcher();
1031
+ import { useIntentDispatcher as useIntentDispatcher2 } from "@dxos/app-framework";
1032
+ import { IconButton, useTranslation as useTranslation10 } from "@dxos/react-ui";
1033
+ var ShareSpaceButton = ({ space }) => {
1034
+ const dispatch = useIntentDispatcher2();
965
1035
  return /* @__PURE__ */ React10.createElement(ShareSpaceButtonImpl, {
966
1036
  onClick: () => dispatch({
967
1037
  action: SpaceAction.SHARE,
968
1038
  data: {
969
- spaceId
1039
+ space
970
1040
  }
971
1041
  })
972
1042
  });
973
1043
  };
974
1044
  var ShareSpaceButtonImpl = ({ onClick }) => {
975
1045
  const { t } = useTranslation10(SPACE_PLUGIN);
976
- return /* @__PURE__ */ React10.createElement(Button4, {
1046
+ return /* @__PURE__ */ React10.createElement(IconButton, {
977
1047
  "data-testid": "spacePlugin.shareSpaceButton",
978
- onClick,
979
- classNames: "mli-1"
980
- }, t("share space label"));
981
- };
982
-
983
- // packages/plugins/plugin-space/src/components/SpaceMain/SpaceMain.tsx
984
- import { Command } from "@phosphor-icons/react";
985
- import React12 from "react";
986
- import { Surface } from "@dxos/app-framework";
987
- import { SpaceState as SpaceState2 } from "@dxos/react-client/echo";
988
- import { Main, useTranslation as useTranslation12 } from "@dxos/react-ui";
989
- import { getSize as getSize4, mx as mx6, topbarBlockPaddingStart } from "@dxos/react-ui-theme";
990
- import { ClipboardProvider } from "@dxos/shell/react";
991
-
992
- // packages/plugins/plugin-space/src/components/SpaceMain/SpaceMembersSection.tsx
993
- import { CaretDown, Check, UserPlus, UsersThree } from "@phosphor-icons/react";
994
- import React11, { useCallback as useCallback3, useState as useState6 } from "react";
995
- import { LayoutAction, useIntent } from "@dxos/app-framework";
996
- import { useMembers, SpaceMember, useSpaceInvitations } from "@dxos/react-client/echo";
997
- import { InvitationEncoder } from "@dxos/react-client/invitations";
998
- import { Invitation } from "@dxos/react-client/invitations";
999
- import { Button as Button5, ButtonGroup, DropdownMenu as DropdownMenu2, List, useTranslation as useTranslation11 } from "@dxos/react-ui";
1000
- import { descriptionText as descriptionText3, getSize as getSize3, mx as mx5 } from "@dxos/react-ui-theme";
1001
- import { InvitationListItem, IdentityListItem } from "@dxos/shell/react";
1002
- var activeActionKeyStorageKey = "dxos:react-shell/space-manager/active-action";
1003
- var Presence = SpaceMember.PresenceState;
1004
- var handleCreateInvitationUrl = (invitationCode) => `${origin}?spaceInvitationCode=${invitationCode}`;
1005
- var SpaceMemberList = ({ members }) => {
1006
- return members.length > 0 ? /* @__PURE__ */ React11.createElement(List, {
1007
- classNames: "col-start-2 col-end-5 gap-y-1 grid grid-cols-subgrid items-center"
1008
- }, members.map((member) => /* @__PURE__ */ React11.createElement(IdentityListItem, {
1009
- classNames: "contents",
1010
- key: member.identity.identityKey.toHex(),
1011
- identity: member.identity,
1012
- presence: member.presence
1013
- }))) : null;
1014
- };
1015
- var SpaceMembersSection = ({ space }) => {
1016
- const { t } = useTranslation11(SPACE_PLUGIN);
1017
- const invitations = useSpaceInvitations(space.key);
1018
- const { dispatch } = useIntent();
1019
- const handleCloseDialog = () => dispatch({
1020
- action: LayoutAction.SET_LAYOUT,
1021
- data: {
1022
- element: "dialog",
1023
- state: false
1024
- }
1048
+ icon: "ph--users--regular",
1049
+ label: t("share space label"),
1050
+ onClick
1025
1051
  });
1026
- const handleInvitationSelect = ({ invitation: invitationObservable }) => {
1027
- const invitation = invitationObservable.get();
1028
- void dispatch({
1029
- action: LayoutAction.SET_LAYOUT,
1030
- data: {
1031
- element: "dialog",
1032
- component: "dxos.org/plugin/space/InvitationManagerDialog",
1033
- subject: {
1034
- invitationUrl: handleCreateInvitationUrl(InvitationEncoder.encode(invitation)),
1035
- send: handleCloseDialog,
1036
- status: invitation.state,
1037
- type: invitation.type,
1038
- authCode: invitation.authCode,
1039
- id: invitation.invitationId
1040
- }
1041
- }
1042
- });
1043
- };
1044
- const inviteActions = {
1045
- inviteOne: {
1046
- label: t("invite one label", {
1047
- ns: "os"
1048
- }),
1049
- description: t("invite one description", {
1050
- ns: "os"
1051
- }),
1052
- icon: UserPlus,
1053
- onClick: useCallback3(() => {
1054
- space.share?.({
1055
- type: Invitation.Type.INTERACTIVE,
1056
- authMethod: Invitation.AuthMethod.SHARED_SECRET
1057
- });
1058
- }, [
1059
- space
1060
- ])
1061
- },
1062
- inviteMany: {
1063
- label: t("invite many label", {
1064
- ns: "os"
1065
- }),
1066
- description: t("invite many description", {
1067
- ns: "os"
1068
- }),
1069
- icon: UsersThree,
1070
- onClick: useCallback3(() => {
1071
- space.share?.({
1072
- type: Invitation.Type.INTERACTIVE,
1073
- authMethod: Invitation.AuthMethod.NONE,
1074
- multiUse: true
1075
- });
1076
- }, [
1077
- space
1078
- ])
1079
- }
1080
- };
1081
- const [activeActionKey, setInternalActiveActionKey] = useState6(localStorage.getItem(activeActionKeyStorageKey) ?? "inviteOne");
1082
- const setActiveActionKey = (nextKey) => {
1083
- setInternalActiveActionKey(nextKey);
1084
- localStorage.setItem(activeActionKeyStorageKey, nextKey);
1085
- };
1086
- const activeAction = inviteActions[activeActionKey] ?? {};
1087
- const members = useMembers(space.key).reduce((acc, member) => {
1088
- acc[member.presence].push(member);
1089
- return acc;
1090
- }, {
1091
- [Presence.ONLINE]: [],
1092
- [Presence.OFFLINE]: []
1093
- });
1094
- return /* @__PURE__ */ React11.createElement("section", {
1095
- className: "mbe-4 col-span-3 grid gap-y-2 grid-cols-subgrid auto-rows-min"
1096
- }, /* @__PURE__ */ React11.createElement("h2", {
1097
- className: "contents"
1098
- }, /* @__PURE__ */ React11.createElement(UsersThree, {
1099
- weight: "duotone",
1100
- className: mx5(getSize3(5), "place-self-center")
1101
- }), /* @__PURE__ */ React11.createElement("span", {
1102
- className: "text-lg col-span-2"
1103
- }, t("space members label"))), /* @__PURE__ */ React11.createElement("h3", {
1104
- className: "col-start-2 col-span-3 text-sm italic text-description"
1105
- }, t("invitations heading")), invitations.length > 0 && /* @__PURE__ */ React11.createElement(List, {
1106
- classNames: "col-start-2 col-span-2 gap-y-2 grid grid-cols-[var(--rail-size)_1fr_var(--rail-action)_var(--rail-action)]"
1107
- }, invitations.map((invitation) => /* @__PURE__ */ React11.createElement(InvitationListItem, {
1108
- reverseEffects: true,
1109
- classNames: "pis-0 pie-0 gap-0 col-span-4 grid grid-cols-subgrid",
1110
- key: invitation.get().invitationId,
1111
- invitation,
1112
- send: handleInvitationSelect,
1113
- createInvitationUrl: handleCreateInvitationUrl
1114
- }))), /* @__PURE__ */ React11.createElement(ButtonGroup, {
1115
- classNames: "col-start-2 col-end-4 grid grid-cols-[1fr_var(--rail-action)] place-self-grow gap-px"
1116
- }, /* @__PURE__ */ React11.createElement(Button5, {
1117
- classNames: "gap-2",
1118
- onClick: activeAction.onClick
1119
- }, /* @__PURE__ */ React11.createElement(activeAction.icon, {
1120
- className: getSize3(5)
1121
- }), /* @__PURE__ */ React11.createElement("span", null, t(activeAction.label, {
1122
- ns: "os"
1123
- }))), /* @__PURE__ */ React11.createElement(DropdownMenu2.Root, null, /* @__PURE__ */ React11.createElement(DropdownMenu2.Trigger, {
1124
- asChild: true
1125
- }, /* @__PURE__ */ React11.createElement(Button5, {
1126
- classNames: "pli-0"
1127
- }, /* @__PURE__ */ React11.createElement(CaretDown, {
1128
- className: getSize3(4)
1129
- }))), /* @__PURE__ */ React11.createElement(DropdownMenu2.Content, null, /* @__PURE__ */ React11.createElement(DropdownMenu2.Viewport, null, Object.entries(inviteActions).map(([id, action]) => {
1130
- return /* @__PURE__ */ React11.createElement(DropdownMenu2.CheckboxItem, {
1131
- key: id,
1132
- "aria-labelledby": `${id}__label`,
1133
- "aria-describedby": `${id}__description`,
1134
- checked: activeActionKey === id,
1135
- onCheckedChange: (checked) => checked && setActiveActionKey(id),
1136
- classNames: "gap-2"
1137
- }, action.icon && /* @__PURE__ */ React11.createElement(action.icon, {
1138
- className: getSize3(5)
1139
- }), /* @__PURE__ */ React11.createElement("div", {
1140
- role: "none",
1141
- className: "flex-1 min-is-0 space-b-1"
1142
- }, /* @__PURE__ */ React11.createElement("p", {
1143
- id: `${id}__label`
1144
- }, t(action.label, {
1145
- ns: "os"
1146
- })), action.description && /* @__PURE__ */ React11.createElement("p", {
1147
- id: `${id}__description`,
1148
- className: descriptionText3
1149
- }, t(action.description, {
1150
- ns: "os"
1151
- }))), /* @__PURE__ */ React11.createElement(DropdownMenu2.ItemIndicator, {
1152
- asChild: true
1153
- }, /* @__PURE__ */ React11.createElement(Check, {
1154
- className: getSize3(4)
1155
- })));
1156
- })), /* @__PURE__ */ React11.createElement(DropdownMenu2.Arrow, null)))), members[Presence.ONLINE].length + members[Presence.OFFLINE].length < 1 ? /* @__PURE__ */ React11.createElement("p", {
1157
- className: mx5(descriptionText3, "text-center is-full mlb-2")
1158
- }, t("empty space members message", {
1159
- ns: "os"
1160
- })) : /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement("h3", {
1161
- className: "col-start-2 col-end-5 text-sm italic text-description"
1162
- }, t("active space members heading", {
1163
- count: members[Presence.ONLINE].length
1164
- })), /* @__PURE__ */ React11.createElement(SpaceMemberList, {
1165
- members: members[Presence.ONLINE]
1166
- }), /* @__PURE__ */ React11.createElement("h3", {
1167
- className: "col-start-2 col-end-5 text-sm italic text-description"
1168
- }, t("inactive space members heading", {
1169
- count: members[Presence.OFFLINE].length
1170
- })), /* @__PURE__ */ React11.createElement(SpaceMemberList, {
1171
- members: members[Presence.OFFLINE]
1172
- })));
1173
- };
1174
-
1175
- // packages/plugins/plugin-space/src/components/SpaceMain/SpaceMain.tsx
1176
- var KeyShortcuts = () => {
1177
- const { t } = useTranslation12(SPACE_PLUGIN);
1178
- return /* @__PURE__ */ React12.createElement("section", {
1179
- className: "mbe-4 col-span-4 md:col-start-5 md:col-end-7 grid grid-cols-subgrid gap-y-2 auto-rows-min"
1180
- }, /* @__PURE__ */ React12.createElement("h2", {
1181
- className: "contents"
1182
- }, /* @__PURE__ */ React12.createElement(Command, {
1183
- weight: "duotone",
1184
- className: mx6(getSize4(5), "place-self-center")
1185
- }), /* @__PURE__ */ React12.createElement("span", {
1186
- className: "text-lg col-span-2 md:col-span-1"
1187
- }, t("keyshortcuts label"))), /* @__PURE__ */ React12.createElement("div", {
1188
- role: "none",
1189
- className: "col-start-2 col-end-4 md:col-end-5 pie-2"
1190
- }, /* @__PURE__ */ React12.createElement(Surface, {
1191
- role: "keyshortcuts"
1192
- })));
1193
- };
1194
- var spaceMainLayout = "grid gap-y-2 auto-rows-min before:bs-2 before:col-span-5 grid-cols-[var(--rail-size)_var(--rail-size)_1fr_var(--rail-size)] md:grid-cols-[var(--rail-size)_var(--rail-size)_minmax(max-content,1fr)_var(--rail-size)_var(--rail-size)_minmax(max-content,2fr)_var(--rail-size)]";
1195
- var SpaceMain = ({ space, role }) => {
1196
- const state = space.state.get();
1197
- const ready = state === SpaceState2.SPACE_READY;
1198
- const Root = role === "main" ? Main.Content : "div";
1199
- return /* @__PURE__ */ React12.createElement(ClipboardProvider, null, /* @__PURE__ */ React12.createElement(Root, {
1200
- ...role === "main" ? {
1201
- classNames: [
1202
- topbarBlockPaddingStart,
1203
- "min-bs-dvh",
1204
- spaceMainLayout
1205
- ]
1206
- } : {
1207
- role: "none",
1208
- className: mx6(topbarBlockPaddingStart, "row-span-2", spaceMainLayout)
1209
- },
1210
- "data-testid": `spacePlugin.${role}`,
1211
- "data-isready": ready ? "true" : "false"
1212
- }, ready && /* @__PURE__ */ React12.createElement(SpaceMembersSection, {
1213
- space
1214
- }), /* @__PURE__ */ React12.createElement(KeyShortcuts, null)));
1215
1052
  };
1216
1053
 
1217
1054
  // packages/plugins/plugin-space/src/components/SpacePresence.tsx
1218
- import React13, { useCallback as useCallback4, useEffect as useEffect4, useState as useState7 } from "react";
1055
+ import React11, { useCallback as useCallback4, useEffect as useEffect3, useState as useState5 } from "react";
1219
1056
  import { usePlugin } from "@dxos/app-framework";
1220
1057
  import { generateName } from "@dxos/display-name";
1221
1058
  import { PublicKey, useClient as useClient3 } from "@dxos/react-client";
1222
- import { getSpace as getSpace3, useMembers as useMembers2, fullyQualifiedId as fullyQualifiedId3 } from "@dxos/react-client/echo";
1059
+ import { getSpace as getSpace3, useMembers, fullyQualifiedId as fullyQualifiedId3 } from "@dxos/react-client/echo";
1223
1060
  import { useIdentity } from "@dxos/react-client/halo";
1224
- import { Avatar, AvatarGroup, AvatarGroupItem, Tooltip as Tooltip2, useTranslation as useTranslation13, List as List2, ListItem, useDefaultValue } from "@dxos/react-ui";
1061
+ import { Avatar, AvatarGroup, AvatarGroupItem, Tooltip as Tooltip2, useTranslation as useTranslation11, List, ListItem, useDefaultValue } from "@dxos/react-ui";
1225
1062
  import { AttentionGlyph, useAttention } from "@dxos/react-ui-attention";
1226
1063
  import { ComplexMap, keyToFallback } from "@dxos/util";
1227
1064
  var REFRESH_INTERVAL = 5e3;
@@ -1233,9 +1070,9 @@ var SpacePresence = ({ object, spaceKey }) => {
1233
1070
  const client = useClient3();
1234
1071
  const identity = useIdentity();
1235
1072
  const space = spaceKey ? client.spaces.get(spaceKey) : getSpace3(object);
1236
- const spaceMembers = useMembers2(space?.key);
1237
- const [_moment, setMoment] = useState7(Date.now());
1238
- useEffect4(() => {
1073
+ const spaceMembers = useMembers(space?.key);
1074
+ const [_moment, setMoment] = useState5(Date.now());
1075
+ useEffect3(() => {
1239
1076
  const interval = setInterval(() => setMoment(Date.now()), REFRESH_INTERVAL);
1240
1077
  return () => clearInterval(interval);
1241
1078
  }, []);
@@ -1258,7 +1095,7 @@ var SpacePresence = ({ object, spaceKey }) => {
1258
1095
  lastSeen
1259
1096
  };
1260
1097
  }).toSorted((a, b) => a.lastSeen - b.lastSeen);
1261
- return /* @__PURE__ */ React13.createElement(FullPresence, {
1098
+ return /* @__PURE__ */ React11.createElement(FullPresence, {
1262
1099
  members: membersForObject
1263
1100
  });
1264
1101
  };
@@ -1268,38 +1105,38 @@ var FullPresence = (props) => {
1268
1105
  if (members.length === 0) {
1269
1106
  return null;
1270
1107
  }
1271
- return /* @__PURE__ */ React13.createElement(AvatarGroup.Root, {
1108
+ return /* @__PURE__ */ React11.createElement(AvatarGroup.Root, {
1272
1109
  size,
1273
1110
  classNames: "mbs-2 mie-4",
1274
1111
  "data-testid": "spacePlugin.presence"
1275
- }, members.slice(0, 3).map((member, i) => /* @__PURE__ */ React13.createElement(Tooltip2.Root, {
1112
+ }, members.slice(0, 3).map((member, i) => /* @__PURE__ */ React11.createElement(Tooltip2.Root, {
1276
1113
  key: member.identity.identityKey.toHex()
1277
- }, /* @__PURE__ */ React13.createElement(Tooltip2.Trigger, null, /* @__PURE__ */ React13.createElement(PrensenceAvatar, {
1114
+ }, /* @__PURE__ */ React11.createElement(Tooltip2.Trigger, null, /* @__PURE__ */ React11.createElement(PrensenceAvatar, {
1278
1115
  identity: member.identity,
1279
1116
  group: true,
1280
1117
  match: member.currentlyAttended,
1281
1118
  index: members.length - i,
1282
1119
  onClick: () => onMemberClick?.(member)
1283
- })), /* @__PURE__ */ React13.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React13.createElement(Tooltip2.Content, {
1120
+ })), /* @__PURE__ */ React11.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React11.createElement(Tooltip2.Content, {
1284
1121
  side: "bottom"
1285
- }, /* @__PURE__ */ React13.createElement("span", null, getName(member.identity)), /* @__PURE__ */ React13.createElement(Tooltip2.Arrow, null))))), members.length > 3 && /* @__PURE__ */ React13.createElement(Tooltip2.Root, null, /* @__PURE__ */ React13.createElement(Tooltip2.Trigger, null, /* @__PURE__ */ React13.createElement(AvatarGroupItem.Root, {
1122
+ }, /* @__PURE__ */ React11.createElement("span", null, getName(member.identity)), /* @__PURE__ */ React11.createElement(Tooltip2.Arrow, null))))), members.length > 3 && /* @__PURE__ */ React11.createElement(Tooltip2.Root, null, /* @__PURE__ */ React11.createElement(Tooltip2.Trigger, null, /* @__PURE__ */ React11.createElement(AvatarGroupItem.Root, {
1286
1123
  status: "inactive"
1287
- }, /* @__PURE__ */ React13.createElement(Avatar.Frame, {
1124
+ }, /* @__PURE__ */ React11.createElement(Avatar.Frame, {
1288
1125
  style: {
1289
1126
  zIndex: members.length - 4
1290
1127
  }
1291
- }, /* @__PURE__ */ React13.createElement(Avatar.Fallback, {
1128
+ }, /* @__PURE__ */ React11.createElement(Avatar.Fallback, {
1292
1129
  text: `+${members.length - 3}`
1293
- })))), /* @__PURE__ */ React13.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React13.createElement(Tooltip2.Content, {
1130
+ })))), /* @__PURE__ */ React11.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React11.createElement(Tooltip2.Content, {
1294
1131
  side: "bottom"
1295
- }, /* @__PURE__ */ React13.createElement(Tooltip2.Arrow, null), /* @__PURE__ */ React13.createElement(List2, {
1132
+ }, /* @__PURE__ */ React11.createElement(Tooltip2.Arrow, null), /* @__PURE__ */ React11.createElement(List, {
1296
1133
  classNames: "max-h-56 overflow-y-auto"
1297
- }, members.map((member) => /* @__PURE__ */ React13.createElement(ListItem.Root, {
1134
+ }, members.map((member) => /* @__PURE__ */ React11.createElement(ListItem.Root, {
1298
1135
  key: member.identity.identityKey.toHex(),
1299
1136
  classNames: "flex gap-2 items-center cursor-pointer mbe-2",
1300
1137
  onClick: () => onMemberClick?.(member),
1301
1138
  "data-testid": "identity-list-item"
1302
- }, /* @__PURE__ */ React13.createElement(PrensenceAvatar, {
1139
+ }, /* @__PURE__ */ React11.createElement(PrensenceAvatar, {
1303
1140
  identity: member.identity,
1304
1141
  showName: true,
1305
1142
  match: member.currentlyAttended
@@ -1309,10 +1146,10 @@ var PrensenceAvatar = ({ identity, showName, match, group, index, onClick }) =>
1309
1146
  const Root = group ? AvatarGroupItem.Root : Avatar.Root;
1310
1147
  const status = match ? "current" : "active";
1311
1148
  const fallbackValue = keyToFallback(identity.identityKey);
1312
- return /* @__PURE__ */ React13.createElement(Root, {
1149
+ return /* @__PURE__ */ React11.createElement(Root, {
1313
1150
  status,
1314
1151
  hue: identity.profile?.data?.hue || fallbackValue.hue
1315
- }, /* @__PURE__ */ React13.createElement(Avatar.Frame, {
1152
+ }, /* @__PURE__ */ React11.createElement(Avatar.Frame, {
1316
1153
  "data-testid": "spacePlugin.presence.member",
1317
1154
  "data-status": status,
1318
1155
  ...index ? {
@@ -1321,9 +1158,9 @@ var PrensenceAvatar = ({ identity, showName, match, group, index, onClick }) =>
1321
1158
  }
1322
1159
  } : {},
1323
1160
  onClick: () => onClick?.()
1324
- }, /* @__PURE__ */ React13.createElement(Avatar.Fallback, {
1161
+ }, /* @__PURE__ */ React11.createElement(Avatar.Fallback, {
1325
1162
  text: identity.profile?.data?.emoji || fallbackValue.emoji
1326
- })), showName && /* @__PURE__ */ React13.createElement(Avatar.Label, {
1163
+ })), showName && /* @__PURE__ */ React11.createElement(Avatar.Label, {
1327
1164
  classNames: "text-sm truncate pli-2"
1328
1165
  }, getName(identity)));
1329
1166
  };
@@ -1332,8 +1169,8 @@ var SmallPresenceLive = ({ id, viewers }) => {
1332
1169
  const moment = Date.now();
1333
1170
  return Array.from(viewers2.values()).filter(({ lastSeen }) => moment - lastSeen < ACTIVITY_DURATION);
1334
1171
  };
1335
- const [activeViewers, setActiveViewers] = useState7(viewers ? getActiveViewers(viewers) : []);
1336
- useEffect4(() => {
1172
+ const [activeViewers, setActiveViewers] = useState5(viewers ? getActiveViewers(viewers) : []);
1173
+ useEffect3(() => {
1337
1174
  if (viewers) {
1338
1175
  setActiveViewers(getActiveViewers(viewers));
1339
1176
  const interval = setInterval(() => {
@@ -1344,44 +1181,44 @@ var SmallPresenceLive = ({ id, viewers }) => {
1344
1181
  }, [
1345
1182
  viewers
1346
1183
  ]);
1347
- return /* @__PURE__ */ React13.createElement(SmallPresence, {
1184
+ return /* @__PURE__ */ React11.createElement(SmallPresence, {
1348
1185
  id,
1349
1186
  count: activeViewers.length
1350
1187
  });
1351
1188
  };
1352
1189
  var SmallPresence = ({ id, count }) => {
1353
- const { t } = useTranslation13(SPACE_PLUGIN);
1190
+ const { t } = useTranslation11(SPACE_PLUGIN);
1354
1191
  const { hasAttention, isAncestor, isRelated } = useAttention(id);
1355
1192
  const attention = hasAttention || isAncestor || isRelated;
1356
- return /* @__PURE__ */ React13.createElement(Tooltip2.Root, null, /* @__PURE__ */ React13.createElement(Tooltip2.Trigger, {
1193
+ return /* @__PURE__ */ React11.createElement(Tooltip2.Root, null, /* @__PURE__ */ React11.createElement(Tooltip2.Trigger, {
1357
1194
  asChild: true
1358
- }, /* @__PURE__ */ React13.createElement("div", {
1195
+ }, /* @__PURE__ */ React11.createElement("div", {
1359
1196
  role: "none",
1360
1197
  className: "flex",
1361
1198
  "data-attention": attention
1362
- }, /* @__PURE__ */ React13.createElement(AttentionGlyph, {
1199
+ }, /* @__PURE__ */ React11.createElement(AttentionGlyph, {
1363
1200
  presence: count > 1 ? "many" : count === 1 ? "one" : "none",
1364
1201
  classNames: "self-center mie-1"
1365
- }))), /* @__PURE__ */ React13.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React13.createElement(Tooltip2.Content, {
1202
+ }))), /* @__PURE__ */ React11.createElement(Tooltip2.Portal, null, /* @__PURE__ */ React11.createElement(Tooltip2.Content, {
1366
1203
  side: "bottom",
1367
1204
  classNames: "z-[70]"
1368
- }, /* @__PURE__ */ React13.createElement("span", null, t("presence label", {
1205
+ }, /* @__PURE__ */ React11.createElement("span", null, t("presence label", {
1369
1206
  count
1370
- })), /* @__PURE__ */ React13.createElement(Tooltip2.Arrow, null))));
1207
+ })), /* @__PURE__ */ React11.createElement(Tooltip2.Arrow, null))));
1371
1208
  };
1372
1209
 
1373
- // packages/plugins/plugin-space/src/components/SpaceSettings.tsx
1374
- import React14 from "react";
1375
- import { useIntentDispatcher as useIntentDispatcher2, useResolvePlugins } from "@dxos/app-framework";
1376
- import { Input as Input4, Select, toLocalizedString as toLocalizedString2, useTranslation as useTranslation14 } from "@dxos/react-ui";
1377
- import { FormInput } from "@dxos/react-ui-data";
1378
- var SpaceSettings = ({ settings }) => {
1379
- const { t } = useTranslation14(SPACE_PLUGIN);
1380
- const dispatch = useIntentDispatcher2();
1210
+ // packages/plugins/plugin-space/src/components/SpacePluginSettings.tsx
1211
+ import React12 from "react";
1212
+ import { useIntentDispatcher as useIntentDispatcher3, useResolvePlugins } from "@dxos/app-framework";
1213
+ import { Input as Input4, Select, toLocalizedString as toLocalizedString2, useTranslation as useTranslation12 } from "@dxos/react-ui";
1214
+ import { DeprecatedFormInput } from "@dxos/react-ui-data";
1215
+ var SpacePluginSettings = ({ settings }) => {
1216
+ const { t } = useTranslation12(SPACE_PLUGIN);
1217
+ const dispatch = useIntentDispatcher3();
1381
1218
  const plugins = useResolvePlugins(parseSpaceInitPlugin);
1382
- return /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(FormInput, {
1219
+ return /* @__PURE__ */ React12.createElement(React12.Fragment, null, /* @__PURE__ */ React12.createElement(DeprecatedFormInput, {
1383
1220
  label: t("show hidden spaces label")
1384
- }, /* @__PURE__ */ React14.createElement(Input4.Switch, {
1221
+ }, /* @__PURE__ */ React12.createElement(Input4.Switch, {
1385
1222
  checked: settings.showHidden,
1386
1223
  onCheckedChange: (checked) => dispatch({
1387
1224
  plugin: SPACE_PLUGIN,
@@ -1390,34 +1227,49 @@ var SpaceSettings = ({ settings }) => {
1390
1227
  state: !!checked
1391
1228
  }
1392
1229
  })
1393
- })), /* @__PURE__ */ React14.createElement(FormInput, {
1230
+ })), /* @__PURE__ */ React12.createElement(DeprecatedFormInput, {
1394
1231
  label: t("default on space create label")
1395
- }, /* @__PURE__ */ React14.createElement(Select.Root, {
1232
+ }, /* @__PURE__ */ React12.createElement(Select.Root, {
1396
1233
  value: settings.onSpaceCreate,
1397
1234
  onValueChange: (value) => {
1398
1235
  settings.onSpaceCreate = value;
1399
1236
  }
1400
- }, /* @__PURE__ */ React14.createElement(Select.TriggerButton, null), /* @__PURE__ */ React14.createElement(Select.Portal, null, /* @__PURE__ */ React14.createElement(Select.Content, null, /* @__PURE__ */ React14.createElement(Select.Viewport, null, plugins.map(({ provides: { space: { onSpaceCreate } } }) => /* @__PURE__ */ React14.createElement(Select.Option, {
1237
+ }, /* @__PURE__ */ React12.createElement(Select.TriggerButton, null), /* @__PURE__ */ React12.createElement(Select.Portal, null, /* @__PURE__ */ React12.createElement(Select.Content, null, /* @__PURE__ */ React12.createElement(Select.Viewport, null, plugins.map(({ provides: { space: { onSpaceCreate } } }) => /* @__PURE__ */ React12.createElement(Select.Option, {
1401
1238
  key: onSpaceCreate.action,
1402
1239
  value: onSpaceCreate.action
1403
1240
  }, toLocalizedString2(onSpaceCreate.label, t)))))))));
1404
1241
  };
1405
1242
 
1406
- // packages/plugins/plugin-space/src/components/SpaceSettingsPanel.tsx
1407
- import React15, { useCallback as useCallback5, useState as useState8 } from "react";
1243
+ // packages/plugins/plugin-space/src/components/SpaceSettings/SpaceSettingsDialog.tsx
1244
+ import React14, { useState as useState7 } from "react";
1245
+ import { useClient as useClient5 } from "@dxos/react-client";
1246
+ import { Button as Button4, Dialog as Dialog2, Icon, toLocalizedString as toLocalizedString3, useTranslation as useTranslation14 } from "@dxos/react-ui";
1247
+ import { Tabs } from "@dxos/react-ui-tabs";
1248
+ import { ClipboardProvider, SpacePanel } from "@dxos/shell/react";
1249
+
1250
+ // packages/plugins/plugin-space/src/components/SpaceSettings/SpaceSettingsPanel.tsx
1251
+ import React13, { useCallback as useCallback5, useState as useState6 } from "react";
1408
1252
  import { log as log2 } from "@dxos/log";
1409
1253
  import { EdgeReplicationSetting } from "@dxos/protocols/proto/dxos/echo/metadata";
1410
- import { Input as Input5, useTranslation as useTranslation15 } from "@dxos/react-ui";
1411
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/components/SpaceSettingsPanel.tsx";
1254
+ import { useClient as useClient4 } from "@dxos/react-client";
1255
+ import { DeviceType, useDevices } from "@dxos/react-client/halo";
1256
+ import { Input as Input5, useTranslation as useTranslation13 } from "@dxos/react-ui";
1257
+ import { DeprecatedFormInput as DeprecatedFormInput2 } from "@dxos/react-ui-data";
1258
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/components/SpaceSettings/SpaceSettingsPanel.tsx";
1412
1259
  var SpaceSettingsPanel = ({ space }) => {
1413
- const { t } = useTranslation15(SPACE_PLUGIN);
1414
- const [edgeReplication, setEdgeReplication] = useState8(space.internal.data.edgeReplication === EdgeReplicationSetting.ENABLED);
1260
+ const { t } = useTranslation13(SPACE_PLUGIN);
1261
+ const client = useClient4();
1262
+ const devices = useDevices();
1263
+ const managedDeviceAvailable = devices.find((device) => device.profile?.type === DeviceType.AGENT_MANAGED);
1264
+ const edgeAgents = Boolean(client.config.values.runtime?.client?.edgeFeatures?.agents);
1265
+ const edgeReplicationAvailable = edgeAgents && managedDeviceAvailable;
1266
+ const [edgeReplication, setEdgeReplication] = useState6(space.internal.data.edgeReplication === EdgeReplicationSetting.ENABLED);
1415
1267
  const toggleEdgeReplication = useCallback5(async (next) => {
1416
1268
  setEdgeReplication(next);
1417
1269
  await space?.internal.setEdgeReplicationPreference(next ? EdgeReplicationSetting.ENABLED : EdgeReplicationSetting.DISABLED).catch((err) => {
1418
1270
  log2.catch(err, void 0, {
1419
1271
  F: __dxlog_file3,
1420
- L: 30,
1272
+ L: 39,
1421
1273
  S: void 0,
1422
1274
  C: (f, a) => f(...a)
1423
1275
  });
@@ -1426,50 +1278,207 @@ var SpaceSettingsPanel = ({ space }) => {
1426
1278
  }, [
1427
1279
  space
1428
1280
  ]);
1429
- return /* @__PURE__ */ React15.createElement("div", {
1281
+ return /* @__PURE__ */ React13.createElement("div", {
1430
1282
  role: "form",
1431
- className: "flex flex-col w-full p-2 gap-4"
1432
- }, /* @__PURE__ */ React15.createElement(Input5.Root, null, /* @__PURE__ */ React15.createElement("div", {
1433
- role: "none",
1434
- className: "flex flex-col gap-1"
1435
- }, /* @__PURE__ */ React15.createElement(Input5.Label, null, t("name label")), /* @__PURE__ */ React15.createElement(Input5.TextInput, {
1436
- placeholder: t("name placeholder"),
1437
- value: space.properties.name,
1283
+ className: "flex flex-col"
1284
+ }, /* @__PURE__ */ React13.createElement(DeprecatedFormInput2, {
1285
+ label: t("name label")
1286
+ }, /* @__PURE__ */ React13.createElement(Input5.TextInput, {
1287
+ placeholder: t("unnamed space label"),
1288
+ value: space.properties.name ?? "",
1438
1289
  onChange: (event) => {
1439
1290
  space.properties.name = event.target.value;
1440
1291
  }
1441
- }))), /* @__PURE__ */ React15.createElement(Input5.Root, null, /* @__PURE__ */ React15.createElement("div", {
1442
- role: "none",
1443
- className: "flex justify-between"
1444
- }, /* @__PURE__ */ React15.createElement(Input5.Label, null, t("edge replication label")), /* @__PURE__ */ React15.createElement(Input5.Switch, {
1292
+ })), edgeReplicationAvailable && /* @__PURE__ */ React13.createElement(DeprecatedFormInput2, {
1293
+ label: t("edge replication label")
1294
+ }, /* @__PURE__ */ React13.createElement(Input5.Switch, {
1445
1295
  checked: edgeReplication,
1446
1296
  onCheckedChange: toggleEdgeReplication
1447
- }))));
1297
+ })));
1448
1298
  };
1449
1299
 
1450
- // packages/plugins/plugin-space/src/components/SaveStatus.tsx
1451
- import React16, { useEffect as useEffect5, useState as useState9 } from "react";
1452
- import { Context } from "@dxos/context";
1300
+ // packages/plugins/plugin-space/src/components/SpaceSettings/SpaceSettingsDialog.tsx
1301
+ var SpaceSettingsDialog = ({ space, target, createInvitationUrl, initialTab = "members", namesCache }) => {
1302
+ const { t } = useTranslation14(SPACE_PLUGIN);
1303
+ const client = useClient5();
1304
+ const [tabsActivePart, setTabsActivePart] = useState7("list");
1305
+ const [selected, setSelected] = useState7(initialTab);
1306
+ const locked = space.properties[COMPOSER_SPACE_LOCK];
1307
+ const name = getSpaceDisplayName(space, {
1308
+ personal: client.spaces.default === space,
1309
+ namesCache
1310
+ });
1311
+ return (
1312
+ // TODO(wittjosiah): The tablist dialog pattern is copied from @dxos/plugin-manager.
1313
+ // Consider factoring it out to the tabs package.
1314
+ /* @__PURE__ */ React14.createElement(Dialog2.Content, {
1315
+ classNames: "p-0 bs-content min-bs-[15rem] max-bs-full md:max-is-[40rem] overflow-hidden"
1316
+ }, /* @__PURE__ */ React14.createElement("div", {
1317
+ role: "none",
1318
+ className: "flex justify-between pbs-3 pis-2 pie-3 @md:pbs-4 @md:pis-4 @md:pie-5"
1319
+ }, /* @__PURE__ */ React14.createElement(Dialog2.Title, {
1320
+ onClick: () => setTabsActivePart("list"),
1321
+ "aria-description": t("click to return to tablist description"),
1322
+ classNames: "flex cursor-pointer items-center group/title"
1323
+ }, /* @__PURE__ */ React14.createElement(Icon, {
1324
+ icon: "ph--caret-left--regular",
1325
+ size: 4,
1326
+ classNames: [
1327
+ "@md:hidden",
1328
+ tabsActivePart === "list" && "invisible"
1329
+ ]
1330
+ }), /* @__PURE__ */ React14.createElement("span", {
1331
+ className: tabsActivePart !== "list" ? "group-hover/title:underline @md:group-hover/title:no-underline underline-offset-4 decoration-1" : ""
1332
+ }, toLocalizedString3(name, t))), /* @__PURE__ */ React14.createElement(Dialog2.Close, {
1333
+ asChild: true
1334
+ }, /* @__PURE__ */ React14.createElement(Button4, {
1335
+ density: "fine",
1336
+ variant: "ghost",
1337
+ autoFocus: true
1338
+ }, /* @__PURE__ */ React14.createElement(Icon, {
1339
+ icon: "ph--x--regular",
1340
+ size: 3
1341
+ })))), /* @__PURE__ */ React14.createElement(Tabs.Root, {
1342
+ orientation: "vertical",
1343
+ value: selected,
1344
+ onValueChange: setSelected,
1345
+ activePart: tabsActivePart,
1346
+ onActivePartChange: setTabsActivePart,
1347
+ classNames: "flex flex-col flex-1 mbs-2"
1348
+ }, /* @__PURE__ */ React14.createElement(Tabs.Viewport, {
1349
+ classNames: "flex-1 min-bs-0"
1350
+ }, /* @__PURE__ */ React14.createElement("div", {
1351
+ role: "none",
1352
+ className: "overflow-y-auto pli-3 @md:pis-2 @md:pie-0 mbe-4 border-r border-separator"
1353
+ }, /* @__PURE__ */ React14.createElement(Tabs.Tablist, {
1354
+ classNames: "flex flex-col max-bs-none min-is-[200px] gap-4 overflow-y-auto"
1355
+ }, /* @__PURE__ */ React14.createElement("div", {
1356
+ role: "none",
1357
+ className: "flex flex-col ml-1"
1358
+ }, /* @__PURE__ */ React14.createElement(Tabs.Tab, {
1359
+ value: "settings"
1360
+ }, t("settings tab label")), /* @__PURE__ */ React14.createElement(Tabs.Tab, {
1361
+ value: "members",
1362
+ disabled: locked
1363
+ }, t("members tab label"))))), /* @__PURE__ */ React14.createElement(Tabs.Tabpanel, {
1364
+ value: "settings",
1365
+ classNames: "pli-3 @md:pli-5 max-bs-dvh overflow-y-auto"
1366
+ }, /* @__PURE__ */ React14.createElement(SpaceSettingsPanel, {
1367
+ space
1368
+ })), /* @__PURE__ */ React14.createElement(Tabs.Tabpanel, {
1369
+ value: "members",
1370
+ classNames: "pli-3 @md:pli-5 max-bs-dvh overflow-y-auto"
1371
+ }, /* @__PURE__ */ React14.createElement(ClipboardProvider, null, /* @__PURE__ */ React14.createElement(SpacePanel, {
1372
+ space,
1373
+ hideHeading: true,
1374
+ target,
1375
+ createInvitationUrl
1376
+ }))))))
1377
+ );
1378
+ };
1379
+
1380
+ // packages/plugins/plugin-space/src/components/SyncStatus/SyncStatus.tsx
1381
+ import React16, { useEffect as useEffect6, useState as useState10 } from "react";
1453
1382
  import { StatusBar } from "@dxos/plugin-status-bar";
1454
- import { useClient as useClient4 } from "@dxos/react-client";
1455
- import { Icon, useTranslation as useTranslation16 } from "@dxos/react-ui";
1456
- var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/components/SaveStatus.tsx";
1457
- var SaveStatus = () => {
1458
- const { t } = useTranslation16(SPACE_PLUGIN);
1459
- const client = useClient4();
1460
- const [state, setState] = useState9("saved");
1461
- useEffect5(() => {
1462
- return createClientSaveTracker(client, (state2) => {
1463
- setState(state2);
1464
- });
1465
- }, []);
1466
- return /* @__PURE__ */ React16.createElement(StatusBar.Item, {
1467
- title: state === "saving" ? t("saving label") : t("saved label")
1468
- }, /* @__PURE__ */ React16.createElement(Icon, {
1469
- icon: state === "saving" ? "ph--arrows-clockwise--regular" : "ph--check-circle--regular",
1470
- size: 4
1383
+ import { useClient as useClient7 } from "@dxos/react-client";
1384
+ import { Icon as Icon3, Popover as Popover3, useTranslation as useTranslation15 } from "@dxos/react-ui";
1385
+ import { SyntaxHighlighter } from "@dxos/react-ui-syntax-highlighter";
1386
+ import { mx as mx5 } from "@dxos/react-ui-theme";
1387
+
1388
+ // packages/plugins/plugin-space/src/components/SyncStatus/Space.tsx
1389
+ import React15, { useEffect as useEffect4, useState as useState8 } from "react";
1390
+ import { Icon as Icon2 } from "@dxos/react-ui";
1391
+ import { mx as mx4 } from "@dxos/react-ui-theme";
1392
+ var SYNC_STALLED_TIMEOUT = 5e3;
1393
+ var styles = {
1394
+ barBg: "bg-neutral-50 dark:bg-green-900 text-black",
1395
+ barFg: "bg-neutral-100 bg-green-500",
1396
+ barHover: "dark:hover:bg-green-500"
1397
+ };
1398
+ var useActive = (count) => {
1399
+ const [current, setCurrent] = useState8(count);
1400
+ const [active, setActive] = useState8(false);
1401
+ useEffect4(() => {
1402
+ let t;
1403
+ if (count !== current) {
1404
+ setActive(true);
1405
+ setCurrent(count);
1406
+ t && clearTimeout(t);
1407
+ t = setTimeout(() => {
1408
+ setActive(false);
1409
+ }, SYNC_STALLED_TIMEOUT);
1410
+ }
1411
+ return () => {
1412
+ setActive(false);
1413
+ clearTimeout(t);
1414
+ };
1415
+ }, [
1416
+ count,
1417
+ current
1418
+ ]);
1419
+ return active;
1420
+ };
1421
+ var SpaceRow = ({ spaceId, state: { localDocumentCount, remoteDocumentCount, missingOnLocal, missingOnRemote } }) => {
1422
+ const downActive = useActive(localDocumentCount);
1423
+ const upActive = useActive(remoteDocumentCount);
1424
+ return /* @__PURE__ */ React15.createElement("div", {
1425
+ className: mx4("flex items-center mx-[2px] gap-[2px] cursor-pointer", styles.barHover),
1426
+ title: spaceId,
1427
+ onClick: () => {
1428
+ void navigator.clipboard.writeText(spaceId);
1429
+ }
1430
+ }, /* @__PURE__ */ React15.createElement(Icon2, {
1431
+ icon: "ph--arrow-fat-line-left--regular",
1432
+ size: 3,
1433
+ classNames: mx4(downActive && "animate-[pulse_1s_infinite]")
1434
+ }), /* @__PURE__ */ React15.createElement(Candle, {
1435
+ up: {
1436
+ count: remoteDocumentCount,
1437
+ total: remoteDocumentCount + missingOnRemote
1438
+ },
1439
+ down: {
1440
+ count: localDocumentCount,
1441
+ total: localDocumentCount + missingOnLocal
1442
+ },
1443
+ title: spaceId
1444
+ }), /* @__PURE__ */ React15.createElement(Icon2, {
1445
+ icon: "ph--arrow-fat-line-right--regular",
1446
+ size: 3,
1447
+ classNames: mx4(upActive && "animate-[pulse_1s_step-start_infinite]")
1471
1448
  }));
1472
1449
  };
1450
+ var Candle = ({ classNames, up, down }) => {
1451
+ return /* @__PURE__ */ React15.createElement("div", {
1452
+ className: mx4("grid grid-cols-[1fr_2rem_1fr] w-full h-3", classNames)
1453
+ }, /* @__PURE__ */ React15.createElement(Bar, {
1454
+ classNames: "justify-end",
1455
+ ...up
1456
+ }), /* @__PURE__ */ React15.createElement("div", {
1457
+ className: "relative"
1458
+ }, /* @__PURE__ */ React15.createElement("div", {
1459
+ className: mx4("absolute inset-0 flex items-center justify-center text-xs", styles.barBg)
1460
+ }, up.total)), /* @__PURE__ */ React15.createElement(Bar, down));
1461
+ };
1462
+ var Bar = ({ classNames, count, total }) => {
1463
+ let p = count / total * 100;
1464
+ if (count < total) {
1465
+ p = Math.min(p, 95);
1466
+ }
1467
+ return /* @__PURE__ */ React15.createElement("div", {
1468
+ className: mx4("relative flex w-full", styles.barBg, classNames)
1469
+ }, /* @__PURE__ */ React15.createElement("div", {
1470
+ className: mx4("shrink-0", styles.barFg),
1471
+ style: {
1472
+ width: `${p}%`
1473
+ }
1474
+ }), count !== total && /* @__PURE__ */ React15.createElement("div", {
1475
+ className: "absolute top-0 bottom-0 flex items-center mx-0.5 text-black text-xs"
1476
+ }, count));
1477
+ };
1478
+
1479
+ // packages/plugins/plugin-space/src/components/SyncStatus/save-tracker.ts
1480
+ import { Context } from "@dxos/context";
1481
+ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/components/SyncStatus/save-tracker.ts";
1473
1482
  var createClientSaveTracker = (client, cb) => {
1474
1483
  const unsubscribeCallbacks = {};
1475
1484
  const state = {};
@@ -1498,7 +1507,7 @@ var createClientSaveTracker = (client, cb) => {
1498
1507
  var createSpaceSaveTracker = (space, cb) => {
1499
1508
  const ctx = new Context(void 0, {
1500
1509
  F: __dxlog_file4,
1501
- L: 64
1510
+ L: 40
1502
1511
  });
1503
1512
  void space.waitUntilReady().then(() => {
1504
1513
  if (ctx.disposed) {
@@ -1529,19 +1538,41 @@ var createSpaceSaveTracker = (space, cb) => {
1529
1538
  };
1530
1539
  };
1531
1540
 
1532
- // packages/plugins/plugin-space/src/components/SyncStatus/SyncStatus.tsx
1533
- import React17, { useEffect as useEffect7, useState as useState11 } from "react";
1534
- import { StatusBar as StatusBar2 } from "@dxos/plugin-status-bar";
1535
- import { Icon as Icon2, Popover as Popover3, useTranslation as useTranslation17 } from "@dxos/react-ui";
1536
- import { SyntaxHighlighter } from "@dxos/react-ui-syntax-highlighter";
1537
- import { mx as mx7 } from "@dxos/react-ui-theme";
1541
+ // packages/plugins/plugin-space/src/components/SyncStatus/status.ts
1542
+ var getStatus = ({ offline, saved, needsToUpload, needsToDownload }) => {
1543
+ if (!saved) {
1544
+ return "saving locally";
1545
+ } else if (!offline && needsToDownload) {
1546
+ return "downloading";
1547
+ } else if (!offline && needsToUpload) {
1548
+ return "uploading";
1549
+ } else if (offline && !needsToUpload && !needsToDownload) {
1550
+ return "offline persisted";
1551
+ } else {
1552
+ return "remote synced";
1553
+ }
1554
+ };
1555
+ var getIcon = (status) => {
1556
+ switch (status) {
1557
+ case "saving locally":
1558
+ return "ph--download--regular";
1559
+ case "downloading":
1560
+ return "ph--cloud-arrow-down--regular";
1561
+ case "uploading":
1562
+ return "ph--cloud-arrow-up--regular";
1563
+ case "offline persisted":
1564
+ return "ph--check-circle--regular";
1565
+ case "remote synced":
1566
+ return "ph--cloud-check--regular";
1567
+ }
1568
+ };
1538
1569
 
1539
- // packages/plugins/plugin-space/src/components/SyncStatus/types.ts
1540
- import { useEffect as useEffect6, useState as useState10 } from "react";
1570
+ // packages/plugins/plugin-space/src/components/SyncStatus/sync-state.ts
1571
+ import { useEffect as useEffect5, useState as useState9 } from "react";
1541
1572
  import { Context as Context2 } from "@dxos/context";
1542
1573
  import { EdgeService } from "@dxos/protocols";
1543
- import { useClient as useClient5 } from "@dxos/react-client";
1544
- var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/components/SyncStatus/types.ts";
1574
+ import { useClient as useClient6 } from "@dxos/react-client";
1575
+ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/components/SyncStatus/sync-state.ts";
1545
1576
  var createEmptyEdgeSyncState = () => ({
1546
1577
  missingOnLocal: 0,
1547
1578
  missingOnRemote: 0,
@@ -1561,9 +1592,9 @@ var getSyncSummary = (syncMap) => {
1561
1592
  };
1562
1593
  var isEdgePeerId = (peerId, spaceId) => peerId.startsWith(`${EdgeService.AUTOMERGE_REPLICATOR}:${spaceId}`);
1563
1594
  var useSyncState = () => {
1564
- const client = useClient5();
1565
- const [spaceState, setSpaceState] = useState10({});
1566
- useEffect6(() => {
1595
+ const client = useClient6();
1596
+ const [spaceState, setSpaceState] = useState9({});
1597
+ useEffect5(() => {
1567
1598
  const ctx = new Context2(void 0, {
1568
1599
  F: __dxlog_file5,
1569
1600
  L: 48
@@ -1598,146 +1629,86 @@ var useSyncState = () => {
1598
1629
  };
1599
1630
 
1600
1631
  // packages/plugins/plugin-space/src/components/SyncStatus/SyncStatus.tsx
1601
- var SYNC_STALLED_TIMEOUT = 5e3;
1602
- var styles = {
1603
- barBg: "bg-neutral-50 dark:bg-green-900 text-black",
1604
- barFg: "bg-neutral-100 bg-green-500",
1605
- barHover: "dark:hover:bg-green-500"
1606
- };
1607
1632
  var SyncStatus = () => {
1633
+ const client = useClient7();
1608
1634
  const state = useSyncState();
1609
- return /* @__PURE__ */ React17.createElement(SyncStatusIndicator, {
1610
- state
1635
+ const [saved, setSaved] = useState10(true);
1636
+ useEffect6(() => {
1637
+ return createClientSaveTracker(client, (state2) => {
1638
+ setSaved(state2 === "saved");
1639
+ });
1640
+ }, []);
1641
+ return /* @__PURE__ */ React16.createElement(SyncStatusIndicator, {
1642
+ state,
1643
+ saved
1611
1644
  });
1612
1645
  };
1613
- var SyncStatusIndicator = ({ state }) => {
1646
+ var SyncStatusIndicator = ({ state, saved }) => {
1647
+ const { t } = useTranslation15(SPACE_PLUGIN);
1614
1648
  const summary = getSyncSummary(state);
1615
- const offline = false;
1649
+ const offline = Object.values(state).length === 0;
1616
1650
  const needsToUpload = summary.differentDocuments > 0 || summary.missingOnRemote > 0;
1617
1651
  const needsToDownload = summary.differentDocuments > 0 || summary.missingOnLocal > 0;
1618
- const [classNames, setClassNames] = useState11();
1619
- useEffect7(() => {
1652
+ const status = getStatus({
1653
+ offline,
1654
+ saved,
1655
+ needsToUpload,
1656
+ needsToDownload
1657
+ });
1658
+ const [classNames, setClassNames] = useState10();
1659
+ useEffect6(() => {
1620
1660
  setClassNames(void 0);
1621
- if (!needsToUpload && !needsToDownload) {
1661
+ if (offline || !needsToUpload && !needsToDownload) {
1622
1662
  return;
1623
1663
  }
1624
- const t = setTimeout(() => {
1664
+ const t2 = setTimeout(() => {
1625
1665
  setClassNames("text-orange-500");
1626
1666
  }, SYNC_STALLED_TIMEOUT);
1627
- return () => clearTimeout(t);
1667
+ return () => clearTimeout(t2);
1628
1668
  }, [
1669
+ offline,
1629
1670
  needsToUpload,
1630
1671
  needsToDownload
1631
1672
  ]);
1632
- return /* @__PURE__ */ React17.createElement(StatusBar2.Item, null, /* @__PURE__ */ React17.createElement(Popover3.Root, null, /* @__PURE__ */ React17.createElement(Popover3.Trigger, null, /* @__PURE__ */ React17.createElement(Icon2, {
1633
- icon: offline ? "ph--cloud-x--regular" : needsToUpload ? "ph--cloud-arrow-up--regular" : needsToDownload ? "ph--cloud-arrow-down--regular" : "ph--cloud-check--regular",
1673
+ const title = t(`${status} label`);
1674
+ const icon = /* @__PURE__ */ React16.createElement(Icon3, {
1675
+ icon: getIcon(status),
1634
1676
  size: 4,
1635
1677
  classNames
1636
- })), /* @__PURE__ */ React17.createElement(Popover3.Content, {
1637
- sideOffset: 16
1638
- }, /* @__PURE__ */ React17.createElement(SyncStatusDetail, {
1639
- state,
1640
- summary,
1641
- debug: false
1642
- }))));
1678
+ });
1679
+ if (offline) {
1680
+ return /* @__PURE__ */ React16.createElement(StatusBar.Item, {
1681
+ title
1682
+ }, icon);
1683
+ } else {
1684
+ return /* @__PURE__ */ React16.createElement(Popover3.Root, null, /* @__PURE__ */ React16.createElement(Popover3.Trigger, {
1685
+ asChild: true
1686
+ }, /* @__PURE__ */ React16.createElement(StatusBar.Button, {
1687
+ title
1688
+ }, icon)), /* @__PURE__ */ React16.createElement(Popover3.Portal, null, /* @__PURE__ */ React16.createElement(Popover3.Content, {
1689
+ sideOffset: 16
1690
+ }, /* @__PURE__ */ React16.createElement(SyncStatusDetail, {
1691
+ state,
1692
+ summary,
1693
+ debug: false
1694
+ }))));
1695
+ }
1643
1696
  };
1644
1697
  var SyncStatusDetail = ({ classNames, state, summary, debug }) => {
1645
- const { t } = useTranslation17(SPACE_PLUGIN);
1698
+ const { t } = useTranslation15(SPACE_PLUGIN);
1646
1699
  const entries = Object.entries(state).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
1647
- return /* @__PURE__ */ React17.createElement("div", {
1648
- className: mx7("flex flex-col text-xs min-w-[16rem]", classNames)
1649
- }, /* @__PURE__ */ React17.createElement("h1", {
1650
- className: "p-2"
1651
- }, t("sync status title")), /* @__PURE__ */ React17.createElement("div", {
1652
- className: "flex flex-col gap-[2px] my-[2px]"
1653
- }, entries.map(([spaceId, state2]) => /* @__PURE__ */ React17.createElement(SpaceRow, {
1700
+ return /* @__PURE__ */ React16.createElement("div", {
1701
+ className: mx5("flex flex-col gap-3 p-2 text-xs min-w-[16rem]", classNames)
1702
+ }, /* @__PURE__ */ React16.createElement("h1", null, t("sync status title")), /* @__PURE__ */ React16.createElement("div", {
1703
+ className: "flex flex-col gap-2"
1704
+ }, entries.map(([spaceId, state2]) => /* @__PURE__ */ React16.createElement(SpaceRow, {
1654
1705
  key: spaceId,
1655
1706
  spaceId,
1656
1707
  state: state2
1657
- }))), debug && /* @__PURE__ */ React17.createElement(SyntaxHighlighter, {
1708
+ }))), debug && /* @__PURE__ */ React16.createElement(SyntaxHighlighter, {
1658
1709
  language: "json"
1659
1710
  }, JSON.stringify(summary, null, 2)));
1660
1711
  };
1661
- var useActive = (count) => {
1662
- const [current, setCurrent] = useState11(count);
1663
- const [active, setActive] = useState11(false);
1664
- useEffect7(() => {
1665
- let t;
1666
- if (count !== current) {
1667
- setActive(true);
1668
- setCurrent(count);
1669
- t && clearTimeout(t);
1670
- t = setTimeout(() => {
1671
- setActive(false);
1672
- }, SYNC_STALLED_TIMEOUT);
1673
- }
1674
- return () => {
1675
- setActive(false);
1676
- clearTimeout(t);
1677
- };
1678
- }, [
1679
- count,
1680
- current
1681
- ]);
1682
- return active;
1683
- };
1684
- var SpaceRow = ({ spaceId, state: { localDocumentCount, remoteDocumentCount, missingOnLocal, missingOnRemote } }) => {
1685
- const downActive = useActive(localDocumentCount);
1686
- const upActive = useActive(remoteDocumentCount);
1687
- return /* @__PURE__ */ React17.createElement("div", {
1688
- className: mx7("flex items-center mx-[2px] gap-[2px] cursor-pointer", styles.barHover),
1689
- title: spaceId,
1690
- onClick: () => {
1691
- void navigator.clipboard.writeText(spaceId);
1692
- }
1693
- }, /* @__PURE__ */ React17.createElement(Icon2, {
1694
- icon: "ph--arrow-fat-line-left--regular",
1695
- size: 3,
1696
- classNames: mx7(downActive && "animate-[pulse_1s_infinite]")
1697
- }), /* @__PURE__ */ React17.createElement(Candle, {
1698
- up: {
1699
- count: remoteDocumentCount,
1700
- total: remoteDocumentCount + missingOnRemote
1701
- },
1702
- down: {
1703
- count: localDocumentCount,
1704
- total: localDocumentCount + missingOnLocal
1705
- },
1706
- title: spaceId
1707
- }), /* @__PURE__ */ React17.createElement(Icon2, {
1708
- icon: "ph--arrow-fat-line-right--regular",
1709
- size: 3,
1710
- classNames: mx7(upActive && "animate-[pulse_1s_step-start_infinite]")
1711
- }));
1712
- };
1713
- var Candle = ({ classNames, up, down }) => {
1714
- return /* @__PURE__ */ React17.createElement("div", {
1715
- className: mx7("grid grid-cols-[1fr_2rem_1fr] w-full h-3", classNames)
1716
- }, /* @__PURE__ */ React17.createElement(Bar, {
1717
- classNames: "justify-end",
1718
- ...up
1719
- }), /* @__PURE__ */ React17.createElement("div", {
1720
- className: "relative"
1721
- }, /* @__PURE__ */ React17.createElement("div", {
1722
- className: mx7("absolute inset-0 flex items-center justify-center text-xs", styles.barBg)
1723
- }, up.total)), /* @__PURE__ */ React17.createElement(Bar, down));
1724
- };
1725
- var Bar = ({ classNames, count, total }) => {
1726
- let p = count / total * 100;
1727
- if (count < total) {
1728
- p = Math.min(p, 95);
1729
- }
1730
- return /* @__PURE__ */ React17.createElement("div", {
1731
- className: mx7("relative flex w-full", styles.barBg, classNames)
1732
- }, /* @__PURE__ */ React17.createElement("div", {
1733
- className: mx7("shrink-0", styles.barFg),
1734
- style: {
1735
- width: `${p}%`
1736
- }
1737
- }), count !== total && /* @__PURE__ */ React17.createElement("div", {
1738
- className: "absolute top-0 bottom-0 flex items-center mx-0.5 text-black text-xs"
1739
- }, count));
1740
- };
1741
1712
 
1742
1713
  // packages/plugins/plugin-space/src/translations.ts
1743
1714
  var translations_default = [
@@ -1783,6 +1754,7 @@ var translations_default = [
1783
1754
  "delete object label": "Delete item",
1784
1755
  "collection deleted label": "Collection deleted",
1785
1756
  "object deleted label": "Item deleted",
1757
+ "objects deleted label": "Items deleted",
1786
1758
  "go to object label": "Open item",
1787
1759
  "found object label": "Ready.",
1788
1760
  "found object description": "The requested object is now available.",
@@ -1826,7 +1798,16 @@ var translations_default = [
1826
1798
  "name label": "Name",
1827
1799
  "name placeholder": "Name",
1828
1800
  "unnamed object settings label": "Settings",
1829
- "edge replication label": "Enable EDGE Replication"
1801
+ "edge replication label": "Enable EDGE Replication",
1802
+ "saving locally label": "Writing to disk",
1803
+ "downloading label": "Replicating from peers",
1804
+ "uploading label": "Replicating to peers",
1805
+ "offline persisted label": "Saved to disk (offline)",
1806
+ "remote synced label": "Synced with peers",
1807
+ "open settings panel label": "Show Settings",
1808
+ "open space settings label": "Space Settings",
1809
+ "members tab label": "Members",
1810
+ "settings tab label": "Settings"
1830
1811
  }
1831
1812
  }
1832
1813
  }
@@ -1835,11 +1816,11 @@ var translations_default = [
1835
1816
  // packages/plugins/plugin-space/src/SpacePlugin.tsx
1836
1817
  var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-space/src/SpacePlugin.tsx";
1837
1818
  var ACTIVE_NODE_BROADCAST_INTERVAL = 3e4;
1838
- var OBJECT_ID_LENGTH = 60;
1819
+ var WAIT_FOR_OBJECT_TIMEOUT2 = 1e3;
1839
1820
  var SPACE_MAX_OBJECTS = 500;
1840
1821
  var DIRECTORY_TYPE = "text/directory";
1841
1822
  var parseSpacePlugin = (plugin) => Array.isArray(plugin?.provides.space?.enabled) ? plugin : void 0;
1842
- var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
1823
+ var SpacePlugin = ({ invitationUrl = window.location.origin, invitationParam = "spaceInvitationCode", firstRun, onFirstRun } = {}) => {
1843
1824
  const settings = new LocalStorageStore(SPACE_PLUGIN, {
1844
1825
  onSpaceCreate: "dxos.org/plugin/markdown/action/create"
1845
1826
  });
@@ -1849,21 +1830,32 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
1849
1830
  viewersByObject: {},
1850
1831
  // TODO(wittjosiah): Stop using (Complex)Map inside reactive object.
1851
1832
  viewersByIdentity: new ComplexMap2(PublicKey2.hash),
1852
- sdkMigrationRunning: {}
1833
+ sdkMigrationRunning: {},
1834
+ navigableCollections: false
1853
1835
  });
1854
1836
  const subscriptions = new EventSubscriptions();
1855
1837
  const spaceSubscriptions = new EventSubscriptions();
1856
1838
  const graphSubscriptions = /* @__PURE__ */ new Map();
1857
1839
  let clientPlugin;
1840
+ let graphPlugin;
1858
1841
  let intentPlugin;
1842
+ let layoutPlugin;
1859
1843
  let navigationPlugin;
1860
1844
  let attentionPlugin;
1845
+ const createSpaceInvitationUrl = (invitationCode) => {
1846
+ const baseUrl = new URL(invitationUrl);
1847
+ baseUrl.searchParams.set(invitationParam, invitationCode);
1848
+ return baseUrl.toString();
1849
+ };
1861
1850
  const onSpaceReady = async () => {
1862
- if (!clientPlugin || !navigationPlugin || !attentionPlugin) {
1851
+ if (!clientPlugin || !intentPlugin || !graphPlugin || !navigationPlugin || !layoutPlugin || !attentionPlugin) {
1863
1852
  return;
1864
1853
  }
1865
1854
  const client = clientPlugin.provides.client;
1855
+ const dispatch = intentPlugin.provides.intent.dispatch;
1856
+ const graph = graphPlugin.provides.graph;
1866
1857
  const location = navigationPlugin.provides.location;
1858
+ const layout = layoutPlugin.provides.layout;
1867
1859
  const attention = attentionPlugin.provides.attention;
1868
1860
  const defaultSpace = client.spaces.default;
1869
1861
  if (typeof defaultSpace.properties[COMPOSER_SPACE_LOCK] !== "boolean") {
@@ -1878,11 +1870,35 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
1878
1870
  order: []
1879
1871
  }));
1880
1872
  }
1873
+ subscriptions.add(scheduledEffect(() => ({
1874
+ layoutMode: layout.layoutMode,
1875
+ soloPart: location.active.solo?.[0]
1876
+ }), ({ layoutMode, soloPart }) => {
1877
+ if (layoutMode !== "solo" || !soloPart) {
1878
+ return;
1879
+ }
1880
+ const node = graph.findNode(soloPart.id);
1881
+ if (!node && soloPart.id.length === FQ_ID_LENGTH) {
1882
+ const timeout = setTimeout(async () => {
1883
+ const node2 = graph.findNode(soloPart.id);
1884
+ if (!node2) {
1885
+ await dispatch({
1886
+ plugin: SPACE_PLUGIN,
1887
+ action: SpaceAction.WAIT_FOR_OBJECT,
1888
+ data: {
1889
+ id: soloPart.id
1890
+ }
1891
+ });
1892
+ }
1893
+ }, WAIT_FOR_OBJECT_TIMEOUT2);
1894
+ return () => clearTimeout(timeout);
1895
+ }
1896
+ }));
1881
1897
  subscriptions.add(client.spaces.subscribe(async (spaces) => {
1882
- if (defaultSpace.state.get() === SpaceState3.SPACE_REQUIRES_MIGRATION) {
1898
+ if (defaultSpace.state.get() === SpaceState2.SPACE_REQUIRES_MIGRATION) {
1883
1899
  await defaultSpace.internal.migrate();
1884
1900
  }
1885
- spaces.filter((space) => space.state.get() === SpaceState3.SPACE_READY).forEach((space) => {
1901
+ spaces.filter((space) => space.state.get() === SpaceState2.SPACE_READY).forEach((space) => {
1886
1902
  subscriptions.add(scheduledEffect(() => ({
1887
1903
  name: space.properties.name
1888
1904
  }), ({ name }) => state.values.spaceNames[space.id] = name));
@@ -1925,7 +1941,7 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
1925
1941
  err: err.message
1926
1942
  }, {
1927
1943
  F: __dxlog_file6,
1928
- L: 231,
1944
+ L: 292,
1929
1945
  S: void 0,
1930
1946
  C: (f, a) => f(...a)
1931
1947
  });
@@ -1983,10 +1999,15 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
1983
1999
  key: "spaceNames",
1984
2000
  type: LocalStorageStore.json()
1985
2001
  });
2002
+ if (findPlugin(plugins, "dxos.org/plugin/stack")) {
2003
+ state.values.navigableCollections = true;
2004
+ }
2005
+ graphPlugin = resolvePlugin(plugins, parseGraphPlugin);
2006
+ layoutPlugin = resolvePlugin(plugins, parseLayoutPlugin);
1986
2007
  navigationPlugin = resolvePlugin(plugins, parseNavigationPlugin2);
1987
2008
  attentionPlugin = resolvePlugin(plugins, parseAttentionPlugin);
1988
2009
  clientPlugin = resolvePlugin(plugins, parseClientPlugin);
1989
- intentPlugin = resolvePlugin(plugins, parseIntentPlugin3);
2010
+ intentPlugin = resolvePlugin(plugins, parseIntentPlugin2);
1990
2011
  if (!clientPlugin || !intentPlugin) {
1991
2012
  return;
1992
2013
  }
@@ -2006,7 +2027,7 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2006
2027
  dispatch
2007
2028
  });
2008
2029
  };
2009
- client.spaces.isReady.subscribe(async (ready) => {
2030
+ subscriptions.add(client.spaces.isReady.subscribe(async (ready) => {
2010
2031
  if (ready) {
2011
2032
  await clientPlugin?.provides.client.spaces.default.waitUntilReady();
2012
2033
  if (firstRun) {
@@ -2016,7 +2037,7 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2016
2037
  }
2017
2038
  await onSpaceReady();
2018
2039
  }
2019
- });
2040
+ }).unsubscribe);
2020
2041
  },
2021
2042
  unload: async () => {
2022
2043
  settings.close();
@@ -2032,7 +2053,21 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2032
2053
  ...translations_default,
2033
2054
  osTranslations
2034
2055
  ],
2035
- root: () => state.values.awaiting ? /* @__PURE__ */ React18.createElement(AwaitingObject, {
2056
+ complementary: {
2057
+ panels: [
2058
+ {
2059
+ id: "settings",
2060
+ label: [
2061
+ "open settings panel label",
2062
+ {
2063
+ ns: SPACE_PLUGIN
2064
+ }
2065
+ ],
2066
+ icon: "ph--gear--regular"
2067
+ }
2068
+ ]
2069
+ },
2070
+ root: () => state.values.awaiting ? /* @__PURE__ */ React17.createElement(AwaitingObject, {
2036
2071
  id: state.values.awaiting
2037
2072
  }) : null,
2038
2073
  metadata: {
@@ -2060,50 +2095,48 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2060
2095
  },
2061
2096
  surface: {
2062
2097
  component: ({ data, role, ...rest }) => {
2063
- const primary = data.active ?? data.object;
2064
2098
  switch (role) {
2065
2099
  case "article":
2066
- case "main":
2067
- return isSpace2(primary) && primary.state.get() === SpaceState3.SPACE_READY ? /* @__PURE__ */ React18.createElement(Surface2, {
2100
+ return isSpace2(data.object) && data.object.state.get() === SpaceState2.SPACE_READY ? /* @__PURE__ */ React17.createElement(Surface, {
2068
2101
  data: {
2069
- active: primary.properties[CollectionType.typename],
2070
- id: primary.id
2102
+ object: data.object.properties[CollectionType.typename],
2103
+ id: data.object.id
2071
2104
  },
2072
2105
  role,
2073
2106
  ...rest
2074
- }) : primary instanceof CollectionType ? {
2075
- node: /* @__PURE__ */ React18.createElement(CollectionMain, {
2076
- collection: primary
2107
+ }) : data.object instanceof CollectionType ? {
2108
+ node: /* @__PURE__ */ React17.createElement(CollectionMain, {
2109
+ collection: data.object
2077
2110
  }),
2078
2111
  disposition: "fallback"
2079
- } : typeof primary === "string" && primary.length === OBJECT_ID_LENGTH ? /* @__PURE__ */ React18.createElement(MissingObject, {
2080
- id: primary
2081
- }) : null;
2112
+ } : null;
2082
2113
  case "complementary--settings":
2083
- return isSpace2(data.subject) ? /* @__PURE__ */ React18.createElement(SpaceSettingsPanel, {
2114
+ return isSpace2(data.subject) ? /* @__PURE__ */ React17.createElement(SpaceSettingsPanel, {
2084
2115
  space: data.subject
2085
2116
  }) : isEchoObject2(data.subject) ? {
2086
- node: /* @__PURE__ */ React18.createElement(DefaultObjectSettings, {
2117
+ node: /* @__PURE__ */ React17.createElement(DefaultObjectSettings, {
2087
2118
  object: data.subject
2088
2119
  }),
2089
2120
  disposition: "fallback"
2090
2121
  } : null;
2091
2122
  case "dialog":
2092
- if (data.component === "dxos.org/plugin/space/InvitationManagerDialog") {
2093
- return /* @__PURE__ */ React18.createElement(Dialog.Content, null, /* @__PURE__ */ React18.createElement(ClipboardProvider2, null, /* @__PURE__ */ React18.createElement(InvitationManager, {
2094
- active: true,
2095
- ...data.subject
2096
- })));
2123
+ if (data.component === "dxos.org/plugin/space/SpaceSettingsDialog") {
2124
+ return /* @__PURE__ */ React17.createElement(SpaceSettingsDialog, {
2125
+ ...data.subject,
2126
+ createInvitationUrl: createSpaceInvitationUrl
2127
+ });
2128
+ } else if (data.component === "dxos.org/plugin/space/JoinDialog") {
2129
+ return /* @__PURE__ */ React17.createElement(JoinDialog, data.subject);
2097
2130
  }
2098
2131
  return null;
2099
2132
  case "popover": {
2100
2133
  if (data.component === "dxos.org/plugin/space/RenameSpacePopover" && isSpace2(data.subject)) {
2101
- return /* @__PURE__ */ React18.createElement(PopoverRenameSpace, {
2134
+ return /* @__PURE__ */ React17.createElement(PopoverRenameSpace, {
2102
2135
  space: data.subject
2103
2136
  });
2104
2137
  }
2105
2138
  if (data.component === "dxos.org/plugin/space/RenameObjectPopover" && isReactiveObject2(data.subject)) {
2106
- return /* @__PURE__ */ React18.createElement(PopoverRenameObject, {
2139
+ return /* @__PURE__ */ React17.createElement(PopoverRenameObject, {
2107
2140
  object: data.subject
2108
2141
  });
2109
2142
  }
@@ -2111,10 +2144,10 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2111
2144
  }
2112
2145
  // TODO(burdon): Add role name syntax to minimal plugin docs.
2113
2146
  case "presence--glyph": {
2114
- return isReactiveObject2(data.object) ? /* @__PURE__ */ React18.createElement(SmallPresenceLive, {
2147
+ return isReactiveObject2(data.object) ? /* @__PURE__ */ React17.createElement(SmallPresenceLive, {
2115
2148
  id: data.id,
2116
2149
  viewers: state.values.viewersByObject[fullyQualifiedId4(data.object)]
2117
- }) : /* @__PURE__ */ React18.createElement(SmallPresence, {
2150
+ }) : /* @__PURE__ */ React17.createElement(SmallPresence, {
2118
2151
  id: data.id,
2119
2152
  count: 0
2120
2153
  });
@@ -2127,34 +2160,34 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2127
2160
  return null;
2128
2161
  }
2129
2162
  const space = isSpace2(data.object) ? data.object : getSpace4(data.object);
2130
- const object = isSpace2(data.object) ? data.object.state.get() === SpaceState3.SPACE_READY ? space?.properties[CollectionType.typename] : void 0 : data.object;
2163
+ const object = isSpace2(data.object) ? data.object.state.get() === SpaceState2.SPACE_READY ? space?.properties[CollectionType.typename] : void 0 : data.object;
2131
2164
  return space && object ? {
2132
- node: /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement(SpacePresence, {
2165
+ node: /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement(SpacePresence, {
2133
2166
  object
2134
- }), space.properties[COMPOSER_SPACE_LOCK] ? null : /* @__PURE__ */ React18.createElement(ShareSpaceButton, {
2135
- spaceId: space.id
2167
+ }), space.properties[COMPOSER_SPACE_LOCK] ? null : /* @__PURE__ */ React17.createElement(ShareSpaceButton, {
2168
+ space
2136
2169
  })),
2137
2170
  disposition: "hoist"
2138
2171
  } : null;
2139
2172
  }
2140
2173
  case "section":
2141
- return data.object instanceof CollectionType ? /* @__PURE__ */ React18.createElement(CollectionSection, {
2174
+ return data.object instanceof CollectionType ? /* @__PURE__ */ React17.createElement(CollectionSection, {
2142
2175
  collection: data.object
2143
2176
  }) : null;
2144
2177
  case "settings":
2145
- return data.plugin === meta_default.id ? /* @__PURE__ */ React18.createElement(SpaceSettings, {
2178
+ return data.plugin === meta_default.id ? /* @__PURE__ */ React17.createElement(SpacePluginSettings, {
2146
2179
  settings: settings.values
2147
2180
  }) : null;
2148
2181
  case "menu-footer":
2149
2182
  if (isEchoObject2(data.object)) {
2150
- return /* @__PURE__ */ React18.createElement(MenuFooter, {
2183
+ return /* @__PURE__ */ React17.createElement(MenuFooter, {
2151
2184
  object: data.object
2152
2185
  });
2153
2186
  } else {
2154
2187
  return null;
2155
2188
  }
2156
2189
  case "status": {
2157
- return /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement(SyncStatus, null), /* @__PURE__ */ React18.createElement(SaveStatus, null));
2190
+ return /* @__PURE__ */ React17.createElement(SyncStatus, null);
2158
2191
  }
2159
2192
  default:
2160
2193
  return null;
@@ -2165,11 +2198,11 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2165
2198
  builder: (plugins) => {
2166
2199
  const clientPlugin2 = resolvePlugin(plugins, parseClientPlugin);
2167
2200
  const metadataPlugin = resolvePlugin(plugins, parseMetadataResolverPlugin);
2168
- const graphPlugin = resolvePlugin(plugins, parseGraphPlugin);
2201
+ const graphPlugin2 = resolvePlugin(plugins, parseGraphPlugin);
2169
2202
  const client = clientPlugin2?.provides.client;
2170
2203
  const dispatch = intentPlugin?.provides.intent.dispatch;
2171
2204
  const resolve = metadataPlugin?.provides.metadata.resolver;
2172
- const graph = graphPlugin?.provides.graph;
2205
+ const graph = graphPlugin2?.provides.graph;
2173
2206
  if (!client || !dispatch || !resolve || !graph) {
2174
2207
  return [];
2175
2208
  }
@@ -2187,7 +2220,7 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2187
2220
  }
2188
2221
  });
2189
2222
  return () => defaultSpaceUnsubscribe?.();
2190
- }, () => client.spaces.isReady.get() && client.spaces.default.state.get() === SpaceState3.SPACE_READY);
2223
+ }, () => client.spaces.isReady.get() && client.spaces.default.state.get() === SpaceState2.SPACE_READY);
2191
2224
  if (!isReady) {
2192
2225
  return [];
2193
2226
  }
@@ -2204,6 +2237,7 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2204
2237
  ],
2205
2238
  testId: "spacePlugin.spaces",
2206
2239
  role: "branch",
2240
+ disabled: true,
2207
2241
  childrenPersistenceClass: "echo",
2208
2242
  onRearrangeChildren: async (nextOrder) => {
2209
2243
  graph._sortEdges(SPACES, "outbound", nextOrder.map(({ id }) => id));
@@ -2215,7 +2249,7 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2215
2249
  } else {
2216
2250
  log3.warn("spaces order object not found", void 0, {
2217
2251
  F: __dxlog_file6,
2218
- L: 528,
2252
+ L: 596,
2219
2253
  S: void 0,
2220
2254
  C: (f, a) => f(...a)
2221
2255
  });
@@ -2234,15 +2268,10 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2234
2268
  {
2235
2269
  id: SpaceAction.CREATE,
2236
2270
  data: async () => {
2237
- await dispatch([
2238
- {
2239
- plugin: SPACE_PLUGIN,
2240
- action: SpaceAction.CREATE
2241
- },
2242
- {
2243
- action: NavigationAction3.OPEN
2244
- }
2245
- ]);
2271
+ await dispatch({
2272
+ plugin: SPACE_PLUGIN,
2273
+ action: SpaceAction.CREATE
2274
+ });
2246
2275
  },
2247
2276
  properties: {
2248
2277
  label: [
@@ -2254,21 +2283,16 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2254
2283
  icon: "ph--plus--regular",
2255
2284
  disposition: "item",
2256
2285
  testId: "spacePlugin.createSpace",
2257
- className: "pbs-4"
2286
+ className: "border-t border-separator"
2258
2287
  }
2259
2288
  },
2260
2289
  {
2261
2290
  id: SpaceAction.JOIN,
2262
2291
  data: async () => {
2263
- await dispatch([
2264
- {
2265
- plugin: SPACE_PLUGIN,
2266
- action: SpaceAction.JOIN
2267
- },
2268
- {
2269
- action: NavigationAction3.OPEN
2270
- }
2271
- ]);
2292
+ await dispatch({
2293
+ plugin: SPACE_PLUGIN,
2294
+ action: SpaceAction.JOIN
2295
+ });
2272
2296
  },
2273
2297
  properties: {
2274
2298
  label: [
@@ -2279,8 +2303,7 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2279
2303
  ],
2280
2304
  icon: "ph--sign-in--regular",
2281
2305
  disposition: "item",
2282
- testId: "spacePlugin.joinSpace",
2283
- className: "pbe-4"
2306
+ testId: "spacePlugin.joinSpace"
2284
2307
  }
2285
2308
  }
2286
2309
  ],
@@ -2290,23 +2313,27 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2290
2313
  if (!spaces || !isReady) {
2291
2314
  return;
2292
2315
  }
2293
- const [spacesOrder] = memoizeQuery(client.spaces.default, Filter.schema(Expando, {
2294
- key: SHARED
2295
- }));
2296
- const order = spacesOrder?.order ?? [];
2297
- const orderMap = new Map(order.map((id, index) => [
2298
- id,
2299
- index
2300
- ]));
2301
- return [
2302
- ...spaces.filter((space) => orderMap.has(space.id)).sort((a, b) => orderMap.get(a.id) - orderMap.get(b.id)),
2303
- ...spaces.filter((space) => !orderMap.has(space.id))
2304
- ].filter((space) => settings.values.showHidden ? true : space.state.get() !== SpaceState3.SPACE_INACTIVE).map((space) => constructSpaceNode({
2305
- space,
2306
- personal: space === client.spaces.default,
2307
- namesCache: state.values.spaceNames,
2308
- resolve
2309
- }));
2316
+ try {
2317
+ const [spacesOrder] = memoizeQuery(client.spaces.default, Filter.schema(Expando, {
2318
+ key: SHARED
2319
+ }));
2320
+ const order = spacesOrder?.order ?? [];
2321
+ const orderMap = new Map(order.map((id, index) => [
2322
+ id,
2323
+ index
2324
+ ]));
2325
+ return [
2326
+ ...spaces.filter((space) => orderMap.has(space.id)).sort((a, b) => orderMap.get(a.id) - orderMap.get(b.id)),
2327
+ ...spaces.filter((space) => !orderMap.has(space.id))
2328
+ ].filter((space) => settings.values.showHidden ? true : space.state.get() !== SpaceState2.SPACE_INACTIVE).map((space) => constructSpaceNode({
2329
+ space,
2330
+ navigable: state.values.navigableCollections,
2331
+ personal: space === client.spaces.default,
2332
+ namesCache: state.values.spaceNames,
2333
+ resolve
2334
+ }));
2335
+ } catch {
2336
+ }
2310
2337
  }
2311
2338
  }),
2312
2339
  // Find an object by its fully qualified id.
@@ -2318,8 +2345,8 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2318
2345
  if (!space) {
2319
2346
  return;
2320
2347
  }
2321
- const state2 = toSignal((onChange) => space.state.subscribe(() => onChange()).unsubscribe, () => space.state.get(), space.id);
2322
- if (state2 !== SpaceState3.SPACE_READY) {
2348
+ const spaceState = toSignal((onChange) => space.state.subscribe(() => onChange()).unsubscribe, () => space.state.get(), space.id);
2349
+ if (spaceState !== SpaceState2.SPACE_READY) {
2323
2350
  return;
2324
2351
  }
2325
2352
  const store = memoize2(() => signal(space.db.getObjectById(objectId)), id);
@@ -2335,7 +2362,8 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2335
2362
  return createObjectNode({
2336
2363
  object,
2337
2364
  space,
2338
- resolve
2365
+ resolve,
2366
+ navigable: state.values.navigableCollections
2339
2367
  });
2340
2368
  }
2341
2369
  }),
@@ -2345,7 +2373,8 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2345
2373
  filter: (node) => isSpace2(node.data),
2346
2374
  actionGroups: ({ node }) => constructSpaceActionGroups({
2347
2375
  space: node.data,
2348
- dispatch
2376
+ dispatch,
2377
+ navigable: state.values.navigableCollections
2349
2378
  }),
2350
2379
  actions: ({ node }) => {
2351
2380
  const space = node.data;
@@ -2363,8 +2392,8 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2363
2392
  filter: (node) => isSpace2(node.data),
2364
2393
  connector: ({ node }) => {
2365
2394
  const space = node.data;
2366
- const state2 = toSignal((onChange) => space.state.subscribe(() => onChange()).unsubscribe, () => space.state.get(), space.id);
2367
- if (state2 !== SpaceState3.SPACE_READY) {
2395
+ const spaceState = toSignal((onChange) => space.state.subscribe(() => onChange()).unsubscribe, () => space.state.get(), space.id);
2396
+ if (spaceState !== SpaceState2.SPACE_READY) {
2368
2397
  return;
2369
2398
  }
2370
2399
  const collection = space.properties[CollectionType.typename];
@@ -2374,7 +2403,8 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2374
2403
  return collection.objects.filter(nonNullable).map((object) => createObjectNode({
2375
2404
  object,
2376
2405
  space,
2377
- resolve
2406
+ resolve,
2407
+ navigable: state.values.navigableCollections
2378
2408
  })).filter(nonNullable);
2379
2409
  }
2380
2410
  }),
@@ -2384,7 +2414,8 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2384
2414
  filter: (node) => isEchoObject2(node.data),
2385
2415
  actionGroups: ({ node }) => constructObjectActionGroups({
2386
2416
  object: node.data,
2387
- dispatch
2417
+ dispatch,
2418
+ navigable: state.values.navigableCollections
2388
2419
  }),
2389
2420
  actions: ({ node }) => constructObjectActions({
2390
2421
  node,
@@ -2404,7 +2435,8 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2404
2435
  return collection.objects.filter(nonNullable).map((object) => createObjectNode({
2405
2436
  object,
2406
2437
  space,
2407
- resolve
2438
+ resolve,
2439
+ navigable: state.values.navigableCollections
2408
2440
  })).filter(nonNullable);
2409
2441
  }
2410
2442
  }),
@@ -2477,7 +2509,7 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2477
2509
  ];
2478
2510
  },
2479
2511
  serializer: (plugins) => {
2480
- const dispatch = resolvePlugin(plugins, parseIntentPlugin3)?.provides.intent.dispatch;
2512
+ const dispatch = resolvePlugin(plugins, parseIntentPlugin2)?.provides.intent.dispatch;
2481
2513
  if (!dispatch) {
2482
2514
  return [];
2483
2515
  }
@@ -2595,13 +2627,16 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2595
2627
  }
2596
2628
  },
2597
2629
  {
2598
- action: NavigationAction3.EXPOSE
2630
+ action: NavigationAction4.OPEN
2631
+ },
2632
+ {
2633
+ action: NavigationAction4.EXPOSE
2599
2634
  }
2600
2635
  ]
2601
2636
  ] : [],
2602
2637
  [
2603
2638
  {
2604
- action: ObservabilityAction.SEND_EVENT,
2639
+ action: ObservabilityAction2.SEND_EVENT,
2605
2640
  data: {
2606
2641
  name: "space.create",
2607
2642
  properties: {
@@ -2614,77 +2649,58 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2614
2649
  };
2615
2650
  }
2616
2651
  case SpaceAction.JOIN: {
2617
- if (client) {
2618
- const { space } = await client.shell.joinSpace({
2619
- invitationCode: intent.data?.invitationCode
2620
- });
2621
- if (space) {
2622
- return {
2623
- data: {
2624
- space,
2625
- id: space.id,
2626
- activeParts: {
2627
- main: [
2628
- space.id
2629
- ]
2630
- }
2631
- },
2632
- intents: [
2633
- [
2634
- {
2635
- action: LayoutAction2.SET_LAYOUT,
2636
- data: {
2637
- element: "toast",
2638
- subject: {
2639
- id: `${SPACE_PLUGIN}/join-success`,
2640
- duration: 1e4,
2641
- title: translations_default[0]["en-US"][SPACE_PLUGIN]["join success label"],
2642
- closeLabel: translations_default[0]["en-US"][SPACE_PLUGIN]["dismiss label"]
2643
- }
2644
- }
2645
- }
2646
- ],
2647
- [
2648
- {
2649
- action: ObservabilityAction.SEND_EVENT,
2650
- data: {
2651
- name: "space.join",
2652
- properties: {
2653
- spaceId: space.id
2654
- }
2655
- }
2652
+ return {
2653
+ data: true,
2654
+ intents: [
2655
+ [
2656
+ {
2657
+ action: LayoutAction2.SET_LAYOUT,
2658
+ data: {
2659
+ element: "dialog",
2660
+ component: "dxos.org/plugin/space/JoinDialog",
2661
+ dialogBlockAlign: "start",
2662
+ subject: {
2663
+ initialInvitationCode: intent.data?.invitationCode
2656
2664
  }
2657
- ]
2658
- ]
2659
- };
2660
- }
2661
- }
2665
+ }
2666
+ }
2667
+ ]
2668
+ ]
2669
+ };
2662
2670
  break;
2663
2671
  }
2664
2672
  case SpaceAction.SHARE: {
2665
- const spaceId = intent.data?.spaceId;
2666
- if (clientPlugin2 && typeof spaceId === "string") {
2667
- if (!navigationPlugin?.provides.location.active) {
2668
- return;
2669
- }
2670
- const target = firstIdInPart(navigationPlugin?.provides.location.active, "main");
2671
- const result = await clientPlugin2.provides.client.shell.shareSpace({
2672
- spaceId,
2673
- target
2674
- });
2673
+ const space = intent.data?.space;
2674
+ if (isSpace2(space) && !space.properties[COMPOSER_SPACE_LOCK]) {
2675
+ const active = navigationPlugin?.provides.location.active;
2676
+ const mode = layoutPlugin?.provides.layout.layoutMode;
2677
+ const target = active ? firstIdInPart(active, mode === "solo" ? "solo" : "main") : void 0;
2675
2678
  return {
2676
- data: result,
2679
+ data: true,
2677
2680
  intents: [
2678
2681
  [
2679
2682
  {
2680
- action: ObservabilityAction.SEND_EVENT,
2683
+ action: LayoutAction2.SET_LAYOUT,
2684
+ data: {
2685
+ element: "dialog",
2686
+ component: "dxos.org/plugin/space/SpaceSettingsDialog",
2687
+ dialogBlockAlign: "start",
2688
+ subject: {
2689
+ space,
2690
+ target,
2691
+ initialTab: "members",
2692
+ createInvitationUrl: createSpaceInvitationUrl
2693
+ }
2694
+ }
2695
+ }
2696
+ ],
2697
+ [
2698
+ {
2699
+ action: ObservabilityAction2.SEND_EVENT,
2681
2700
  data: {
2682
2701
  name: "space.share",
2683
2702
  properties: {
2684
- spaceId,
2685
- members: result.members?.length,
2686
- error: result.error?.message,
2687
- cancelled: result.cancelled
2703
+ space: space.id
2688
2704
  }
2689
2705
  }
2690
2706
  }
@@ -2703,7 +2719,7 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2703
2719
  intents: [
2704
2720
  [
2705
2721
  {
2706
- action: ObservabilityAction.SEND_EVENT,
2722
+ action: ObservabilityAction2.SEND_EVENT,
2707
2723
  data: {
2708
2724
  name: "space.lock",
2709
2725
  properties: {
@@ -2726,7 +2742,7 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2726
2742
  intents: [
2727
2743
  [
2728
2744
  {
2729
- action: ObservabilityAction.SEND_EVENT,
2745
+ action: ObservabilityAction2.SEND_EVENT,
2730
2746
  data: {
2731
2747
  name: "space.unlock",
2732
2748
  properties: {
@@ -2761,6 +2777,32 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2761
2777
  }
2762
2778
  break;
2763
2779
  }
2780
+ case SpaceAction.OPEN_SETTINGS: {
2781
+ const space = intent.data?.space;
2782
+ if (isSpace2(space)) {
2783
+ return {
2784
+ data: true,
2785
+ intents: [
2786
+ [
2787
+ {
2788
+ action: LayoutAction2.SET_LAYOUT,
2789
+ data: {
2790
+ element: "dialog",
2791
+ component: "dxos.org/plugin/space/SpaceSettingsDialog",
2792
+ dialogBlockAlign: "start",
2793
+ subject: {
2794
+ space,
2795
+ initialTab: "settings",
2796
+ createInvitationUrl: createSpaceInvitationUrl
2797
+ }
2798
+ }
2799
+ }
2800
+ ]
2801
+ ]
2802
+ };
2803
+ }
2804
+ break;
2805
+ }
2764
2806
  case SpaceAction.OPEN: {
2765
2807
  const space = intent.data?.space;
2766
2808
  if (isSpace2(space)) {
@@ -2784,7 +2826,7 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2784
2826
  case SpaceAction.MIGRATE: {
2785
2827
  const space = intent.data?.space;
2786
2828
  if (isSpace2(space)) {
2787
- if (space.state.get() === SpaceState3.SPACE_REQUIRES_MIGRATION) {
2829
+ if (space.state.get() === SpaceState2.SPACE_REQUIRES_MIGRATION) {
2788
2830
  state.values.sdkMigrationRunning[space.id] = true;
2789
2831
  await space.internal.migrate();
2790
2832
  state.values.sdkMigrationRunning[space.id] = false;
@@ -2795,7 +2837,7 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2795
2837
  intents: [
2796
2838
  [
2797
2839
  {
2798
- action: ObservabilityAction.SEND_EVENT,
2840
+ action: ObservabilityAction2.SEND_EVENT,
2799
2841
  data: {
2800
2842
  name: "space.migrate",
2801
2843
  properties: {
@@ -2845,7 +2887,7 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2845
2887
  ],
2846
2888
  [
2847
2889
  {
2848
- action: ObservabilityAction.SEND_EVENT,
2890
+ action: ObservabilityAction2.SEND_EVENT,
2849
2891
  data: {
2850
2892
  name: "space.limit",
2851
2893
  properties: {
@@ -2886,7 +2928,7 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2886
2928
  intents: [
2887
2929
  [
2888
2930
  {
2889
- action: ObservabilityAction.SEND_EVENT,
2931
+ action: ObservabilityAction2.SEND_EVENT,
2890
2932
  data: {
2891
2933
  name: "space.object.add",
2892
2934
  properties: {
@@ -2900,10 +2942,19 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2900
2942
  ]
2901
2943
  };
2902
2944
  }
2903
- case SpaceAction.REMOVE_OBJECT: {
2904
- const object = intent.data?.object ?? intent.data?.result;
2905
- const space = getSpace4(object);
2906
- if (!(isEchoObject2(object) && space)) {
2945
+ case SpaceAction.REMOVE_OBJECTS: {
2946
+ const objects = intent.data?.objects ?? intent.data?.result;
2947
+ invariant2(Array.isArray(objects), void 0, {
2948
+ F: __dxlog_file6,
2949
+ L: 1291,
2950
+ S: void 0,
2951
+ A: [
2952
+ "Array.isArray(objects)",
2953
+ ""
2954
+ ]
2955
+ });
2956
+ const space = getSpace4(objects[0]);
2957
+ if (!space || !objects.every((obj) => isEchoObject2(obj) && getSpace4(obj) === space)) {
2907
2958
  return;
2908
2959
  }
2909
2960
  const resolve = resolvePlugin(plugins, parseMetadataResolverPlugin)?.provides.metadata.resolver;
@@ -2911,20 +2962,20 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2911
2962
  const openObjectIds = new Set(openIds(activeParts ?? {}));
2912
2963
  if (!intent.undo && resolve) {
2913
2964
  const parentCollection = intent.data?.collection ?? space.properties[CollectionType.typename];
2914
- const nestedObjects = await getNestedObjects(object, resolve);
2965
+ const nestedObjectsList = await Promise.all(objects.map((obj) => getNestedObjects(obj, resolve)));
2915
2966
  const deletionData = {
2916
- object,
2967
+ objects,
2917
2968
  parentCollection,
2918
- index: parentCollection instanceof CollectionType ? parentCollection.objects.indexOf(object) : -1,
2919
- nestedObjects,
2920
- wasActive: [
2921
- object,
2922
- ...nestedObjects
2923
- ].map((obj) => fullyQualifiedId4(obj)).filter((id) => openObjectIds.has(id))
2969
+ indices: objects.map((obj) => parentCollection instanceof CollectionType ? parentCollection.objects.indexOf(obj) : -1),
2970
+ nestedObjectsList,
2971
+ wasActive: objects.flatMap((obj, i) => [
2972
+ obj,
2973
+ ...nestedObjectsList[i]
2974
+ ]).map((obj) => fullyQualifiedId4(obj)).filter((id) => openObjectIds.has(id))
2924
2975
  };
2925
2976
  if (deletionData.wasActive.length > 0) {
2926
2977
  await intentPlugin?.provides.intent.dispatch({
2927
- action: NavigationAction3.CLOSE,
2978
+ action: NavigationAction4.CLOSE,
2928
2979
  data: {
2929
2980
  activeParts: {
2930
2981
  main: deletionData.wasActive,
@@ -2933,38 +2984,43 @@ var SpacePlugin = ({ firstRun, onFirstRun } = {}) => {
2933
2984
  }
2934
2985
  });
2935
2986
  }
2936
- if (parentCollection instanceof CollectionType) {
2937
- const index = parentCollection.objects.indexOf(object);
2938
- if (index !== -1) {
2939
- parentCollection.objects.splice(index, 1);
2940
- }
2987
+ if (deletionData.parentCollection instanceof CollectionType) {
2988
+ [
2989
+ ...deletionData.indices
2990
+ ].sort((a, b) => b - a).forEach((index) => {
2991
+ if (index !== -1) {
2992
+ deletionData.parentCollection.objects.splice(index, 1);
2993
+ }
2994
+ });
2941
2995
  }
2942
- deletionData.nestedObjects.forEach((obj) => {
2996
+ deletionData.nestedObjectsList.flat().forEach((obj) => {
2943
2997
  space.db.remove(obj);
2944
2998
  });
2945
- space.db.remove(object);
2946
- const undoMessageKey = object instanceof CollectionType ? "collection deleted label" : "object deleted label";
2999
+ objects.forEach((obj) => space.db.remove(obj));
3000
+ const undoMessageKey = objects.some((obj) => obj instanceof CollectionType) ? "collection deleted label" : objects.length > 1 ? "objects deleted label" : "object deleted label";
2947
3001
  return {
2948
3002
  data: true,
2949
3003
  undoable: {
2950
- // Consider using a translation key here.
3004
+ // TODO(ZaymonFC): Pluralize if more than one object.
2951
3005
  message: translations_default[0]["en-US"][SPACE_PLUGIN][undoMessageKey],
2952
3006
  data: deletionData
2953
3007
  }
2954
3008
  };
2955
3009
  } else {
2956
3010
  const undoData = intent.data;
2957
- if (undoData && isEchoObject2(undoData.object) && undoData.parentCollection instanceof CollectionType) {
2958
- const restoredObject = space.db.add(undoData.object);
2959
- undoData.nestedObjects.forEach((obj) => {
3011
+ if (undoData?.objects?.length && undoData.objects.every(isEchoObject2) && undoData.parentCollection instanceof CollectionType) {
3012
+ const restoredObjects = undoData.objects.map((obj) => space.db.add(obj));
3013
+ undoData.nestedObjectsList.flat().forEach((obj) => {
2960
3014
  space.db.add(obj);
2961
3015
  });
2962
- if (undoData.index !== -1) {
2963
- undoData.parentCollection.objects.splice(undoData.index, 0, restoredObject);
2964
- }
3016
+ undoData.indices.forEach((index, i) => {
3017
+ if (index !== -1) {
3018
+ undoData.parentCollection.objects.splice(index, 0, restoredObjects[i]);
3019
+ }
3020
+ });
2965
3021
  if (undoData.wasActive.length > 0) {
2966
3022
  await intentPlugin?.provides.intent.dispatch({
2967
- action: NavigationAction3.OPEN,
3023
+ action: NavigationAction4.OPEN,
2968
3024
  data: {
2969
3025
  activeParts: {
2970
3026
  main: undoData.wasActive
@@ -3051,10 +3107,10 @@ export {
3051
3107
  ContactType,
3052
3108
  DefaultObjectSettings,
3053
3109
  FullPresence,
3110
+ JoinDialog,
3054
3111
  MenuFooter,
3055
3112
  MessageState,
3056
3113
  MessageType,
3057
- MissingObject,
3058
3114
  PersistenceStatus,
3059
3115
  PopoverRenameObject,
3060
3116
  PopoverRenameSpace,
@@ -3064,16 +3120,15 @@ export {
3064
3120
  SPACE_PLUGIN,
3065
3121
  SPACE_PLUGIN_SHORT_ID,
3066
3122
  SPACE_TYPE,
3067
- SaveStatus,
3068
3123
  ShareSpaceButton,
3069
3124
  ShareSpaceButtonImpl,
3070
3125
  SmallPresence,
3071
3126
  SmallPresenceLive,
3072
3127
  SpaceAction,
3073
- SpaceMain,
3074
3128
  SpacePlugin,
3129
+ SpacePluginSettings,
3075
3130
  SpacePresence,
3076
- SpaceSettings,
3131
+ SpaceSettingsDialog,
3077
3132
  SpaceSettingsPanel,
3078
3133
  SyncStatus,
3079
3134
  SyncStatusDetail,