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