@dxos/plugin-space 0.6.13-main.548ca8d → 0.6.13-staging.1e988a3

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 (91) hide show
  1. package/dist/lib/browser/{chunk-QK5I2EPF.mjs → chunk-DTVUOG2C.mjs} +4 -23
  2. package/dist/lib/browser/chunk-DTVUOG2C.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-AVLRQF6L.mjs → chunk-LZEGRS7H.mjs} +1 -1
  4. package/dist/lib/browser/chunk-LZEGRS7H.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +246 -592
  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 +3 -7
  10. package/dist/lib/node/{chunk-P4XUXM7Y.cjs → chunk-6CNYF6YU.cjs} +4 -4
  11. package/dist/lib/node/chunk-6CNYF6YU.cjs.map +7 -0
  12. package/dist/lib/node/{chunk-HE2GHO6Z.cjs → chunk-CVZPI2P3.cjs} +8 -29
  13. package/dist/lib/node/chunk-CVZPI2P3.cjs.map +7 -0
  14. package/dist/lib/node/index.cjs +469 -812
  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 +10 -14
  20. package/dist/lib/node/types/index.cjs.map +2 -2
  21. package/dist/types/src/SpacePlugin.d.ts.map +1 -1
  22. package/dist/types/src/components/EmptySpace.d.ts +3 -0
  23. package/dist/types/src/components/EmptySpace.d.ts.map +1 -0
  24. package/dist/types/src/components/EmptyTree.d.ts +3 -0
  25. package/dist/types/src/components/EmptyTree.d.ts.map +1 -0
  26. package/dist/types/src/components/MenuFooter.d.ts.map +1 -1
  27. package/dist/types/src/components/ShareSpaceButton.stories.d.ts +0 -4
  28. package/dist/types/src/components/ShareSpaceButton.stories.d.ts.map +1 -1
  29. package/dist/types/src/components/SpaceMain/SpaceMain.d.ts.map +1 -1
  30. package/dist/types/src/components/SpacePresence.stories.d.ts +0 -4
  31. package/dist/types/src/components/SpacePresence.stories.d.ts.map +1 -1
  32. package/dist/types/src/components/SpaceSettings.d.ts.map +1 -1
  33. package/dist/types/src/components/index.d.ts +2 -3
  34. package/dist/types/src/components/index.d.ts.map +1 -1
  35. package/dist/types/src/meta.d.ts.map +1 -1
  36. package/dist/types/src/translations.d.ts +0 -4
  37. package/dist/types/src/translations.d.ts.map +1 -1
  38. package/dist/types/src/types/thread.d.ts +0 -14
  39. package/dist/types/src/types/thread.d.ts.map +1 -1
  40. package/dist/types/src/types/types.d.ts +1 -18
  41. package/dist/types/src/types/types.d.ts.map +1 -1
  42. package/dist/types/src/util.d.ts +4 -1
  43. package/dist/types/src/util.d.ts.map +1 -1
  44. package/package.json +36 -44
  45. package/src/SpacePlugin.tsx +83 -145
  46. package/src/components/EmptySpace.tsx +25 -0
  47. package/src/components/EmptyTree.tsx +25 -0
  48. package/src/components/MenuFooter.tsx +0 -1
  49. package/src/components/SpaceMain/SpaceMain.tsx +22 -1
  50. package/src/components/SpacePresence.tsx +1 -1
  51. package/src/components/SpaceSettings.tsx +3 -32
  52. package/src/components/index.ts +2 -3
  53. package/src/meta.ts +1 -3
  54. package/src/translations.ts +0 -4
  55. package/src/types/collection.ts +1 -1
  56. package/src/types/thread.ts +1 -11
  57. package/src/types/types.ts +1 -25
  58. package/src/util.tsx +50 -15
  59. package/dist/lib/browser/chunk-AVLRQF6L.mjs.map +0 -7
  60. package/dist/lib/browser/chunk-QK5I2EPF.mjs.map +0 -7
  61. package/dist/lib/node/chunk-HE2GHO6Z.cjs.map +0 -7
  62. package/dist/lib/node/chunk-P4XUXM7Y.cjs.map +0 -7
  63. package/dist/lib/node-esm/chunk-2TR4WD6U.mjs +0 -116
  64. package/dist/lib/node-esm/chunk-2TR4WD6U.mjs.map +0 -7
  65. package/dist/lib/node-esm/chunk-YPQGKWHJ.mjs +0 -37
  66. package/dist/lib/node-esm/chunk-YPQGKWHJ.mjs.map +0 -7
  67. package/dist/lib/node-esm/index.mjs +0 -2987
  68. package/dist/lib/node-esm/index.mjs.map +0 -7
  69. package/dist/lib/node-esm/meta.json +0 -1
  70. package/dist/lib/node-esm/meta.mjs +0 -14
  71. package/dist/lib/node-esm/meta.mjs.map +0 -7
  72. package/dist/lib/node-esm/types/index.mjs +0 -26
  73. package/dist/lib/node-esm/types/index.mjs.map +0 -7
  74. package/dist/types/src/components/FallbackSettings.d.ts +0 -8
  75. package/dist/types/src/components/FallbackSettings.d.ts.map +0 -1
  76. package/dist/types/src/components/SaveStatus.d.ts +0 -3
  77. package/dist/types/src/components/SaveStatus.d.ts.map +0 -1
  78. package/dist/types/src/components/SyncStatus/SyncStatus.d.ts +0 -13
  79. package/dist/types/src/components/SyncStatus/SyncStatus.d.ts.map +0 -1
  80. package/dist/types/src/components/SyncStatus/SyncStatus.stories.d.ts +0 -117
  81. package/dist/types/src/components/SyncStatus/SyncStatus.stories.d.ts.map +0 -1
  82. package/dist/types/src/components/SyncStatus/index.d.ts +0 -2
  83. package/dist/types/src/components/SyncStatus/index.d.ts.map +0 -1
  84. package/dist/types/src/components/SyncStatus/types.d.ts +0 -14
  85. package/dist/types/src/components/SyncStatus/types.d.ts.map +0 -1
  86. package/src/components/FallbackSettings.tsx +0 -35
  87. package/src/components/SaveStatus.tsx +0 -95
  88. package/src/components/SyncStatus/SyncStatus.stories.tsx +0 -62
  89. package/src/components/SyncStatus/SyncStatus.tsx +0 -188
  90. package/src/components/SyncStatus/index.ts +0 -5
  91. package/src/components/SyncStatus/types.ts +0 -77
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/plugin-space",
3
- "version": "0.6.13-main.548ca8d",
3
+ "version": "0.6.13-staging.1e988a3",
4
4
  "description": "DXOS Surface plugin for DXOS ECHO Spaces",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -10,24 +10,21 @@
10
10
  ".": {
11
11
  "browser": "./dist/lib/browser/index.mjs",
12
12
  "node": {
13
- "require": "./dist/lib/node/index.cjs",
14
- "default": "./dist/lib/node-esm/index.mjs"
13
+ "default": "./dist/lib/node/index.cjs"
15
14
  },
16
15
  "types": "./dist/types/src/index.d.ts"
17
16
  },
18
17
  "./meta": {
19
18
  "browser": "./dist/lib/browser/meta.mjs",
20
19
  "node": {
21
- "require": "./dist/lib/node/meta.cjs",
22
- "default": "./dist/lib/node-esm/meta.mjs"
20
+ "default": "./dist/lib/node/meta.cjs"
23
21
  },
24
22
  "types": "./dist/types/src/meta.d.ts"
25
23
  },
26
24
  "./types": {
27
25
  "browser": "./dist/lib/browser/types/index.mjs",
28
26
  "node": {
29
- "require": "./dist/lib/node/types/index.cjs",
30
- "default": "./dist/lib/node-esm/types/index.mjs"
27
+ "default": "./dist/lib/node/types/index.cjs"
31
28
  },
32
29
  "types": "./dist/types/src/types/index.d.ts"
33
30
  }
@@ -48,40 +45,34 @@
48
45
  "src"
49
46
  ],
50
47
  "dependencies": {
51
- "@effect/schema": "^0.75.1",
52
48
  "@preact/signals-core": "^1.6.0",
53
49
  "jszip": "^3.10.1",
54
50
  "localforage": "^1.10.0",
55
51
  "lodash.get": "^4.4.2",
56
52
  "react-drag-drop-files": "^2.3.8",
57
53
  "react-is": "~18.2.0",
58
- "@dxos/app-framework": "0.6.13-main.548ca8d",
59
- "@dxos/async": "0.6.13-main.548ca8d",
60
- "@dxos/client": "0.6.13-main.548ca8d",
61
- "@dxos/automerge": "0.6.13-main.548ca8d",
62
- "@dxos/context": "0.6.13-main.548ca8d",
63
- "@dxos/display-name": "0.6.13-main.548ca8d",
64
- "@dxos/invariant": "0.6.13-main.548ca8d",
65
- "@dxos/echo-schema": "0.6.13-main.548ca8d",
66
- "@dxos/echo-signals": "0.6.13-main.548ca8d",
67
- "@dxos/local-storage": "0.6.13-main.548ca8d",
68
- "@dxos/keys": "0.6.13-main.548ca8d",
69
- "@dxos/migrations": "0.6.13-main.548ca8d",
70
- "@dxos/log": "0.6.13-main.548ca8d",
71
- "@dxos/plugin-attention": "0.6.13-main.548ca8d",
72
- "@dxos/plugin-client": "0.6.13-main.548ca8d",
73
- "@dxos/plugin-metadata": "0.6.13-main.548ca8d",
74
- "@dxos/plugin-observability": "0.6.13-main.548ca8d",
75
- "@dxos/plugin-graph": "0.6.13-main.548ca8d",
76
- "@dxos/plugin-status-bar": "0.6.13-main.548ca8d",
77
- "@dxos/plugin-settings": "0.6.13-main.548ca8d",
78
- "@dxos/react-client": "0.6.13-main.548ca8d",
79
- "@dxos/protocols": "0.6.13-main.548ca8d",
80
- "@dxos/react-ui-attention": "0.6.13-main.548ca8d",
81
- "@dxos/react-ui-syntax-highlighter": "0.6.13-main.548ca8d",
82
- "@dxos/react-ui-editor": "0.6.13-main.548ca8d",
83
- "@dxos/shell": "0.6.13-main.548ca8d",
84
- "@dxos/util": "0.6.13-main.548ca8d"
54
+ "@dxos/app-framework": "0.6.13-staging.1e988a3",
55
+ "@dxos/async": "0.6.13-staging.1e988a3",
56
+ "@dxos/automerge": "0.6.13-staging.1e988a3",
57
+ "@dxos/client": "0.6.13-staging.1e988a3",
58
+ "@dxos/display-name": "0.6.13-staging.1e988a3",
59
+ "@dxos/echo-schema": "0.6.13-staging.1e988a3",
60
+ "@dxos/keys": "0.6.13-staging.1e988a3",
61
+ "@dxos/invariant": "0.6.13-staging.1e988a3",
62
+ "@dxos/local-storage": "0.6.13-staging.1e988a3",
63
+ "@dxos/log": "0.6.13-staging.1e988a3",
64
+ "@dxos/migrations": "0.6.13-staging.1e988a3",
65
+ "@dxos/plugin-attention": "0.6.13-staging.1e988a3",
66
+ "@dxos/plugin-graph": "0.6.13-staging.1e988a3",
67
+ "@dxos/plugin-client": "0.6.13-staging.1e988a3",
68
+ "@dxos/plugin-metadata": "0.6.13-staging.1e988a3",
69
+ "@dxos/plugin-observability": "0.6.13-staging.1e988a3",
70
+ "@dxos/plugin-settings": "0.6.13-staging.1e988a3",
71
+ "@dxos/react-client": "0.6.13-staging.1e988a3",
72
+ "@dxos/react-ui-attention": "0.6.13-staging.1e988a3",
73
+ "@dxos/react-ui-editor": "0.6.13-staging.1e988a3",
74
+ "@dxos/shell": "0.6.13-staging.1e988a3",
75
+ "@dxos/util": "0.6.13-staging.1e988a3"
85
76
  },
86
77
  "devDependencies": {
87
78
  "@babel/core": "^7.18.13",
@@ -91,17 +82,18 @@
91
82
  "@types/react-dom": "~18.2.0",
92
83
  "react": "~18.2.0",
93
84
  "react-dom": "~18.2.0",
94
- "vite": "5.4.7",
95
- "@dxos/react-ui-theme": "0.6.13-main.548ca8d",
96
- "@dxos/react-ui": "0.6.13-main.548ca8d",
97
- "@dxos/storybook-utils": "0.6.13-main.548ca8d"
85
+ "vite": "^5.3.4",
86
+ "@dxos/react-ui": "0.6.13-staging.1e988a3",
87
+ "@dxos/react-ui-theme": "0.6.13-staging.1e988a3",
88
+ "@dxos/storybook-utils": "0.6.13-staging.1e988a3"
98
89
  },
99
- "peerDependencies": {
90
+ "optionalDependencies": {
91
+ "@babel/core": "^7.18.13",
100
92
  "@phosphor-icons/react": "^2.1.5",
101
- "react": "~18.2.0",
102
- "react-dom": "~18.2.0",
103
- "@dxos/react-ui": "0.6.13-main.548ca8d",
104
- "@dxos/react-ui-theme": "0.6.13-main.548ca8d"
93
+ "react": "^18.0.0",
94
+ "react-dom": "^18.0.0",
95
+ "@dxos/react-ui-theme": "0.6.13-staging.1e988a3",
96
+ "@dxos/react-ui": "0.6.13-staging.1e988a3"
105
97
  },
106
98
  "publishConfig": {
107
99
  "access": "public"
@@ -2,76 +2,74 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { signal } from '@preact/signals-core';
5
+ import { type IconProps, Plus, SignIn, CardsThree, Warning } from '@phosphor-icons/react';
6
+ import { effect, signal } from '@preact/signals-core';
6
7
  import React from 'react';
7
8
 
8
9
  import {
9
10
  type IntentDispatcher,
10
11
  type IntentPluginProvides,
11
12
  LayoutAction,
13
+ Surface,
12
14
  type LocationProvides,
13
15
  NavigationAction,
14
16
  type Plugin,
15
17
  type PluginDefinition,
16
- Surface,
17
- firstIdInPart,
18
18
  openIds,
19
- parseGraphPlugin,
19
+ firstIdInPart,
20
20
  parseIntentPlugin,
21
- parseMetadataResolverPlugin,
22
21
  parseNavigationPlugin,
22
+ parseMetadataResolverPlugin,
23
23
  resolvePlugin,
24
+ parseGraphPlugin,
24
25
  } from '@dxos/app-framework';
25
26
  import { EventSubscriptions, type Trigger, type UnsubscribeCallback } from '@dxos/async';
26
- import { type EchoReactiveObject, type Identifiable, isReactiveObject } from '@dxos/echo-schema';
27
- import { scheduledEffect } from '@dxos/echo-signals/core';
27
+ import { type Identifiable, isReactiveObject, type EchoReactiveObject } from '@dxos/echo-schema';
28
28
  import { LocalStorageStore } from '@dxos/local-storage';
29
29
  import { log } from '@dxos/log';
30
30
  import { Migrations } from '@dxos/migrations';
31
31
  import { type AttentionPluginProvides, parseAttentionPlugin } from '@dxos/plugin-attention';
32
32
  import { type ClientPluginProvides, parseClientPlugin } from '@dxos/plugin-client';
33
- import { type Node, createExtension, memoize, toSignal } from '@dxos/plugin-graph';
33
+ import { createExtension, isGraphNode, memoize, type Node, toSignal } from '@dxos/plugin-graph';
34
34
  import { ObservabilityAction } from '@dxos/plugin-observability/meta';
35
35
  import { type Client, PublicKey } from '@dxos/react-client';
36
36
  import {
37
- Expando,
38
- Filter,
39
37
  type PropertiesTypeProps,
40
38
  type Space,
41
- SpaceState,
42
39
  create,
40
+ Expando,
41
+ Filter,
43
42
  fullyQualifiedId,
44
43
  getSpace,
45
44
  getTypename,
46
45
  isEchoObject,
47
46
  isSpace,
48
47
  loadObjectReferences,
49
- parseFullyQualifiedId,
48
+ SpaceState,
50
49
  } from '@dxos/react-client/echo';
51
50
  import { Dialog } from '@dxos/react-ui';
52
- import { ClipboardProvider, InvitationManager, type InvitationManagerProps, osTranslations } from '@dxos/shell/react';
51
+ import { InvitationManager, type InvitationManagerProps, osTranslations, ClipboardProvider } from '@dxos/shell/react';
53
52
  import { ComplexMap, nonNullable, reduceGroupBy } from '@dxos/util';
54
53
 
55
54
  import {
56
55
  AwaitingObject,
57
56
  CollectionMain,
58
57
  CollectionSection,
59
- FallbackSettings,
58
+ EmptySpace,
59
+ EmptyTree,
60
60
  MenuFooter,
61
61
  MissingObject,
62
62
  PopoverRenameObject,
63
63
  PopoverRenameSpace,
64
- SaveStatus,
65
64
  ShareSpaceButton,
66
65
  SmallPresence,
67
66
  SmallPresenceLive,
68
67
  SpacePresence,
69
68
  SpaceSettings,
70
- SyncStatus,
71
69
  } from './components';
72
70
  import meta, { SPACE_PLUGIN, SpaceAction } from './meta';
73
71
  import translations from './translations';
74
- import { CollectionType, type PluginState, type SpacePluginProvides, type SpaceSettingsProps } from './types';
72
+ import { CollectionType, type SpacePluginProvides, type SpaceSettingsProps, type PluginState } from './types';
75
73
  import {
76
74
  COMPOSER_SPACE_LOCK,
77
75
  SHARED,
@@ -120,9 +118,7 @@ export const SpacePlugin = ({
120
118
  firstRun,
121
119
  onFirstRun,
122
120
  }: SpacePluginOptions = {}): PluginDefinition<SpacePluginProvides> => {
123
- const settings = new LocalStorageStore<SpaceSettingsProps>(SPACE_PLUGIN, {
124
- onSpaceCreate: 'dxos.org/plugin/markdown/action/create',
125
- });
121
+ const settings = new LocalStorageStore<SpaceSettingsProps>(SPACE_PLUGIN);
126
122
  const state = new LocalStorageStore<PluginState>(SPACE_PLUGIN, {
127
123
  awaiting: undefined,
128
124
  spaceNames: {},
@@ -175,10 +171,9 @@ export const SpacePlugin = ({
175
171
  .filter((space) => space.state.get() === SpaceState.SPACE_READY)
176
172
  .forEach((space) => {
177
173
  subscriptions.add(
178
- scheduledEffect(
179
- () => ({ name: space.properties.name }),
180
- ({ name }) => (state.values.spaceNames[space.id] = name),
181
- ),
174
+ effect(() => {
175
+ state.values.spaceNames[space.id] = space.properties.name;
176
+ }),
182
177
  );
183
178
  });
184
179
  }).unsubscribe,
@@ -186,56 +181,54 @@ export const SpacePlugin = ({
186
181
 
187
182
  // Broadcast active node to other peers in the space.
188
183
  subscriptions.add(
189
- scheduledEffect(
190
- () => ({
191
- ids: openIds(location.active),
192
- removed: location.closed ? [location.closed].flat() : [],
193
- }),
194
- ({ ids, removed }) => {
195
- const send = () => {
196
- const spaces = client.spaces.get();
197
- const identity = client.halo.identity.get();
198
- if (identity && location.active) {
199
- // Group parts by space for efficient messaging.
200
- const idsBySpace = reduceGroupBy(ids, (id) => {
201
- const [spaceId] = id.split(':'); // TODO(burdon): Factor out.
202
- return spaceId;
203
- });
204
-
205
- // NOTE: Ensure all spaces are included so that we send the correct `removed` object arrays.
206
- for (const space of spaces) {
207
- if (!idsBySpace.has(space.id)) {
208
- idsBySpace.set(space.id, []);
209
- }
184
+ effect(() => {
185
+ const send = () => {
186
+ const spaces = client.spaces.get();
187
+ const identity = client.halo.identity.get();
188
+ if (identity && location.active) {
189
+ const ids = openIds(location.active);
190
+
191
+ // Group parts by space for efficient messaging.
192
+ const idsBySpace = reduceGroupBy(ids, (id) => {
193
+ const [spaceId] = id.split(':'); // TODO(burdon): Factor out.
194
+ return spaceId;
195
+ });
196
+
197
+ // NOTE: Ensure all spaces are included so that we send the correct `removed` object arrays.
198
+ for (const space of spaces) {
199
+ if (!idsBySpace.has(space.id)) {
200
+ idsBySpace.set(space.id, []);
210
201
  }
202
+ }
211
203
 
212
- for (const [spaceId, ids] of idsBySpace) {
213
- const space = spaces.find((space) => space.id === spaceId);
214
- if (!space) {
215
- continue;
216
- }
217
-
218
- void space
219
- .postMessage('viewing', {
220
- identityKey: identity.identityKey.toHex(),
221
- attended: attention.attended ? [...attention.attended] : [],
222
- added: ids,
223
- // TODO(Zan): When we re-open a part, we should remove it from the removed list in the navigation plugin.
224
- removed: removed.filter((id) => !ids.includes(id)),
225
- })
226
- // TODO(burdon): This seems defensive; why would this fail? Backoff interval.
227
- .catch((err) => {
228
- log.warn('Failed to broadcast active node for presence.', { err: err.message });
229
- });
204
+ for (const [spaceId, ids] of idsBySpace) {
205
+ const space = spaces.find((space) => space.id === spaceId);
206
+ if (!space) {
207
+ continue;
230
208
  }
209
+
210
+ const removed = location.closed ? [location.closed].flat() : [];
211
+
212
+ void space
213
+ .postMessage('viewing', {
214
+ identityKey: identity.identityKey.toHex(),
215
+ attended: attention.attended ? [...attention.attended] : [],
216
+ added: ids,
217
+ // TODO(Zan): When we re-open a part, we should remove it from the removed list in the navigation plugin.
218
+ removed: removed.filter((id) => !ids.includes(id)),
219
+ })
220
+ // TODO(burdon): This seems defensive; why would this fail? Backoff interval.
221
+ .catch((err) => {
222
+ log.warn('Failed to broadcast active node for presence.', { err: err.message });
223
+ });
231
224
  }
232
- };
225
+ }
226
+ };
233
227
 
234
- send();
235
- const interval = setInterval(() => send(), ACTIVE_NODE_BROADCAST_INTERVAL);
236
- return () => clearInterval(interval);
237
- },
238
- ),
228
+ send();
229
+ const interval = setInterval(() => send(), ACTIVE_NODE_BROADCAST_INTERVAL);
230
+ return () => clearInterval(interval);
231
+ }),
239
232
  );
240
233
 
241
234
  // Listen for active nodes from other peers in the space.
@@ -347,7 +340,8 @@ export const SpacePlugin = ({
347
340
  records: {
348
341
  [CollectionType.typename]: {
349
342
  placeholder: ['unnamed collection label', { ns: SPACE_PLUGIN }],
350
- icon: 'ph--cards-three--regular',
343
+ icon: (props: IconProps) => <CardsThree {...props} />,
344
+ iconSymbol: 'ph--cards-three--regular',
351
345
  // TODO(wittjosiah): Move out of metadata.
352
346
  loadReferences: (collection: CollectionType) =>
353
347
  loadObjectReferences(collection, (collection) => [
@@ -368,18 +362,22 @@ export const SpacePlugin = ({
368
362
  case 'main':
369
363
  // TODO(wittjosiah): Need to avoid shotgun parsing space state everywhere.
370
364
  return isSpace(primary) && primary.state.get() === SpaceState.SPACE_READY ? (
371
- <Surface
372
- data={{ active: primary.properties[CollectionType.typename], id: primary.id }}
373
- role={role}
374
- {...rest}
375
- />
365
+ <Surface data={{ active: primary.properties[CollectionType.typename] }} role={role} {...rest} />
376
366
  ) : primary instanceof CollectionType ? (
377
367
  { node: <CollectionMain collection={primary} />, disposition: 'fallback' }
378
368
  ) : typeof primary === 'string' && primary.length === OBJECT_ID_LENGTH ? (
379
369
  <MissingObject id={primary} />
380
370
  ) : null;
381
- case 'complementary--settings':
382
- return isEchoObject(data.subject) ? <FallbackSettings object={data.subject} /> : null;
371
+ // TODO(burdon): Add role name syntax to minimal plugin docs.
372
+ case 'tree--empty':
373
+ switch (true) {
374
+ case data.plugin === SPACE_PLUGIN:
375
+ return <EmptyTree />;
376
+ case isGraphNode(data.activeNode) && isSpace(data.activeNode.data):
377
+ return <EmptySpace />;
378
+ default:
379
+ return null;
380
+ }
383
381
  case 'dialog':
384
382
  if (data.component === 'dxos.org/plugin/space/InvitationManagerDialog') {
385
383
  return (
@@ -400,7 +398,6 @@ export const SpacePlugin = ({
400
398
  return <PopoverRenameObject object={data.subject} />;
401
399
  }
402
400
  return null;
403
- // TODO(burdon): Add role name syntax to minimal plugin docs.
404
401
  case 'presence--glyph': {
405
402
  return isReactiveObject(data.object) ? (
406
403
  <SmallPresenceLive viewers={state.values.viewersByObject[fullyQualifiedId(data.object)]} />
@@ -444,14 +441,6 @@ export const SpacePlugin = ({
444
441
  } else {
445
442
  return <MenuFooter object={data.object} />;
446
443
  }
447
- case 'status': {
448
- return (
449
- <>
450
- <SyncStatus />
451
- <SaveStatus />
452
- </>
453
- );
454
- }
455
444
  default:
456
445
  return null;
457
446
  }
@@ -551,7 +540,8 @@ export const SpacePlugin = ({
551
540
  },
552
541
  properties: {
553
542
  label: ['create space label', { ns: SPACE_PLUGIN }],
554
- icon: 'ph--plus--regular',
543
+ icon: (props: IconProps) => <Plus {...props} />,
544
+ iconSymbol: 'ph--plus--regular',
555
545
  disposition: 'toolbar',
556
546
  testId: 'spacePlugin.createSpace',
557
547
  },
@@ -571,7 +561,8 @@ export const SpacePlugin = ({
571
561
  },
572
562
  properties: {
573
563
  label: ['join space label', { ns: SPACE_PLUGIN }],
574
- icon: 'ph--sign-in--regular',
564
+ icon: (props: IconProps) => <SignIn {...props} />,
565
+ iconSymbol: 'ph--sign-in--regular',
575
566
  testId: 'spacePlugin.joinSpace',
576
567
  },
577
568
  },
@@ -716,52 +707,6 @@ export const SpacePlugin = ({
716
707
  .filter(nonNullable);
717
708
  },
718
709
  }),
719
-
720
- // Create nodes for object settings.
721
- createExtension({
722
- id: `${SPACE_PLUGIN}/settings-for-subject`,
723
- resolver: ({ id }) => {
724
- // TODO(Zan): Find util (or make one).
725
- if (!id.endsWith('~settings')) {
726
- return;
727
- }
728
-
729
- const [subjectId] = id.split('~');
730
- const [spaceId, objectId] = parseFullyQualifiedId(subjectId);
731
- const space = client.spaces.get().find((space) => space.id === spaceId);
732
- const object = toSignal(
733
- (onChange) => {
734
- const timeout = setTimeout(async () => {
735
- await space?.db.loadObjectById(objectId);
736
- onChange();
737
- });
738
-
739
- return () => clearTimeout(timeout);
740
- },
741
- () => space?.db.getObjectById(objectId),
742
- subjectId,
743
- );
744
- if (!object || !subjectId) {
745
- return;
746
- }
747
-
748
- const meta = resolve(getTypename(object) ?? '');
749
- const label = meta.label?.(object) ||
750
- object.name ||
751
- meta.placeholder || ['unnamed object settings label', { ns: SPACE_PLUGIN }];
752
-
753
- return {
754
- id,
755
- type: 'orphan-settings-for-subject',
756
- data: null,
757
- properties: {
758
- icon: 'ph--gear--regular',
759
- label,
760
- object,
761
- },
762
- };
763
- },
764
- }),
765
710
  ];
766
711
  },
767
712
  serializer: (plugins) => {
@@ -860,15 +805,6 @@ export const SpacePlugin = ({
860
805
  data: { space, id: space.id, activeParts: { main: [space.id] } },
861
806
 
862
807
  intents: [
863
- ...(settings.values.onSpaceCreate
864
- ? [
865
- [
866
- { action: settings.values.onSpaceCreate, data: { space } },
867
- { action: SpaceAction.ADD_OBJECT, data: { target: space } },
868
- { action: NavigationAction.EXPOSE },
869
- ],
870
- ]
871
- : []),
872
808
  [
873
809
  {
874
810
  action: ObservabilityAction.SEND_EVENT,
@@ -1084,7 +1020,8 @@ export const SpacePlugin = ({
1084
1020
  title: translations[0]['en-US'][SPACE_PLUGIN]['space limit label'],
1085
1021
  description: translations[0]['en-US'][SPACE_PLUGIN]['space limit description'],
1086
1022
  duration: 5_000,
1087
- icon: 'ph--warning--regular',
1023
+ icon: (props: IconProps) => <Warning {...props} />,
1024
+ iconSymbol: 'ph--warning--regular',
1088
1025
  actionLabel: translations[0]['en-US'][SPACE_PLUGIN]['remove deleted objects label'],
1089
1026
  actionAlt: translations[0]['en-US'][SPACE_PLUGIN]['remove deleted objects alt'],
1090
1027
  // TODO(wittjosiah): Use OS namespace.
@@ -1123,7 +1060,7 @@ export const SpacePlugin = ({
1123
1060
  }
1124
1061
 
1125
1062
  return {
1126
- data: { id: fullyQualifiedId(object), object, activeParts: { main: [fullyQualifiedId(object)] } },
1063
+ data: { id: object.id, object, activeParts: { main: [fullyQualifiedId(object)] } },
1127
1064
  intents: [
1128
1065
  [
1129
1066
  {
@@ -1178,6 +1115,7 @@ export const SpacePlugin = ({
1178
1115
  activeParts: {
1179
1116
  main: deletionData.wasActive,
1180
1117
  sidebar: deletionData.wasActive,
1118
+ complementary: deletionData.wasActive,
1181
1119
  },
1182
1120
  },
1183
1121
  });
@@ -0,0 +1,25 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import React from 'react';
6
+
7
+ import { useTranslation } from '@dxos/react-ui';
8
+ import { descriptionText, mx } from '@dxos/react-ui-theme';
9
+
10
+ import { SPACE_PLUGIN } from '../meta';
11
+
12
+ export const EmptySpace = () => {
13
+ const { t } = useTranslation(SPACE_PLUGIN);
14
+ return (
15
+ <div
16
+ role='none'
17
+ className={mx(
18
+ 'p-2 mli-2 mbe-2 text-center border border-dashed border-neutral-400/50 rounded-lg',
19
+ descriptionText,
20
+ )}
21
+ >
22
+ {t('empty space message')}
23
+ </div>
24
+ );
25
+ };
@@ -0,0 +1,25 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import React from 'react';
6
+
7
+ import { useTranslation } from '@dxos/react-ui';
8
+ import { descriptionText, mx } from '@dxos/react-ui-theme';
9
+
10
+ import { SPACE_PLUGIN } from '../meta';
11
+
12
+ export const EmptyTree = () => {
13
+ const { t } = useTranslation(SPACE_PLUGIN);
14
+ return (
15
+ <div
16
+ role='none'
17
+ className={mx(
18
+ 'p-2 mli-2 mbe-2 text-center border border-dashed border-neutral-400/50 rounded-lg',
19
+ descriptionText,
20
+ )}
21
+ >
22
+ {t('empty tree message')}
23
+ </div>
24
+ );
25
+ };
@@ -1,7 +1,6 @@
1
1
  //
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
-
5
4
  import { Planet } from '@phosphor-icons/react';
6
5
  import React from 'react';
7
6
 
@@ -6,14 +6,35 @@ import { Command } from '@phosphor-icons/react';
6
6
  import React from 'react';
7
7
 
8
8
  import { Surface } from '@dxos/app-framework';
9
+ import { type Action } from '@dxos/plugin-graph';
9
10
  import { SpaceState, type Space } from '@dxos/react-client/echo';
10
- import { Main, useTranslation } from '@dxos/react-ui';
11
+ import { Button, Main, useTranslation, toLocalizedString } from '@dxos/react-ui';
11
12
  import { getSize, mx, topbarBlockPaddingStart } from '@dxos/react-ui-theme';
12
13
  import { ClipboardProvider } from '@dxos/shell/react';
13
14
 
14
15
  import { SpaceMembersSection } from './SpaceMembersSection';
15
16
  import { SPACE_PLUGIN } from '../../meta';
16
17
 
18
+ const _InFlowSpaceActions = ({ actionsMap }: { actionsMap: Record<string, Action> }) => {
19
+ const { t } = useTranslation(SPACE_PLUGIN);
20
+ return (
21
+ <section className='mbe-4 col-start-2 col-end-4 md:col-end-7 grid gap-2 auto-rows-min grid-cols-[repeat(auto-fill,minmax(8rem,1fr))]'>
22
+ {Object.entries(actionsMap)
23
+ .filter(([_, { properties }]) => properties?.mainAreaDisposition === 'in-flow')
24
+ .map(([actionId, { data: invoke, properties }]) => {
25
+ const Icon = properties?.icon;
26
+ const label = properties?.label;
27
+ return (
28
+ <Button key={actionId} classNames='block text-center plb-2 font-normal'>
29
+ {Icon && <Icon size={5} className='mli-auto' />}
30
+ <p>{toLocalizedString(label, t)}</p>
31
+ </Button>
32
+ );
33
+ })}
34
+ </section>
35
+ );
36
+ };
37
+
17
38
  const KeyShortcuts = () => {
18
39
  const { t } = useTranslation(SPACE_PLUGIN);
19
40
  return (
@@ -110,7 +110,7 @@ export type MemberPresenceProps = ThemedClassName<{
110
110
 
111
111
  export const FullPresence = (props: MemberPresenceProps) => {
112
112
  const { size = 9, onMemberClick } = props;
113
- const members = useDefaultValue(props.members, () => []);
113
+ const members = useDefaultValue(props.members, []);
114
114
 
115
115
  if (members.length === 0) {
116
116
  return null;