@dxos/plugin-space 0.7.2 → 0.7.3-staging.971cd8d
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.
- package/dist/lib/browser/{chunk-DJE2HYFV.mjs → chunk-FTKV32QZ.mjs} +9 -2
- package/dist/lib/browser/chunk-FTKV32QZ.mjs.map +7 -0
- package/dist/lib/browser/{chunk-OWZKSWMX.mjs → chunk-MWKXNS5S.mjs} +13 -3
- package/dist/lib/browser/{chunk-OWZKSWMX.mjs.map → chunk-MWKXNS5S.mjs.map} +3 -3
- package/dist/lib/browser/index.mjs +1056 -674
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/meta.mjs +3 -1
- package/dist/lib/browser/types/index.mjs +5 -3
- package/dist/lib/node/{chunk-FYWGZYJB.cjs → chunk-6SNOZF7Y.cjs} +18 -7
- package/dist/lib/node/chunk-6SNOZF7Y.cjs.map +7 -0
- package/dist/lib/node/{chunk-JFDDZI4Y.cjs → chunk-QNVEU2UD.cjs} +12 -4
- package/dist/lib/node/chunk-QNVEU2UD.cjs.map +7 -0
- package/dist/lib/node/index.cjs +1160 -789
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.cjs +7 -5
- package/dist/lib/node/meta.cjs.map +2 -2
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/types/index.cjs +14 -12
- package/dist/lib/node/types/index.cjs.map +2 -2
- package/dist/lib/node-esm/{chunk-MCEAI4CV.mjs → chunk-OHEAWSCA.mjs} +13 -3
- package/dist/lib/node-esm/{chunk-MCEAI4CV.mjs.map → chunk-OHEAWSCA.mjs.map} +3 -3
- package/dist/lib/node-esm/{chunk-DVUZ7A7G.mjs → chunk-UMV7XREB.mjs} +9 -2
- package/dist/lib/node-esm/chunk-UMV7XREB.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +1056 -674
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/meta.mjs +3 -1
- package/dist/lib/node-esm/types/index.mjs +5 -3
- package/dist/types/src/SpacePlugin.d.ts.map +1 -1
- package/dist/types/src/components/CreateDialog/CreateObjectDialog.d.ts +9 -0
- package/dist/types/src/components/CreateDialog/CreateObjectDialog.d.ts.map +1 -0
- package/dist/types/src/components/CreateDialog/CreateObjectDialog.stories.d.ts +10 -0
- package/dist/types/src/components/CreateDialog/CreateObjectDialog.stories.d.ts.map +1 -0
- package/dist/types/src/components/CreateDialog/CreateObjectPanel.d.ts +22 -0
- package/dist/types/src/components/CreateDialog/CreateObjectPanel.d.ts.map +1 -0
- package/dist/types/src/components/CreateDialog/CreateSpaceDialog.d.ts +3 -0
- package/dist/types/src/components/CreateDialog/CreateSpaceDialog.d.ts.map +1 -0
- package/dist/types/src/components/CreateDialog/index.d.ts +3 -0
- package/dist/types/src/components/CreateDialog/index.d.ts.map +1 -0
- package/dist/types/src/components/PopoverRenameObject.d.ts +1 -1
- package/dist/types/src/components/SpacePluginSettings.d.ts.map +1 -1
- package/dist/types/src/components/SpaceSettings/SpaceSettingsPanel.d.ts.map +1 -1
- package/dist/types/src/components/SyncStatus/InlineSyncStatus.d.ts +6 -0
- package/dist/types/src/components/SyncStatus/InlineSyncStatus.d.ts.map +1 -0
- package/dist/types/src/components/SyncStatus/Space.d.ts +8 -3
- package/dist/types/src/components/SyncStatus/Space.d.ts.map +1 -1
- package/dist/types/src/components/SyncStatus/SyncStatus.d.ts +3 -2
- package/dist/types/src/components/SyncStatus/SyncStatus.d.ts.map +1 -1
- package/dist/types/src/components/SyncStatus/SyncStatus.stories.d.ts +1 -2
- package/dist/types/src/components/SyncStatus/SyncStatus.stories.d.ts.map +1 -1
- package/dist/types/src/components/SyncStatus/SyncStatusDetail.stories.d.ts +8 -0
- package/dist/types/src/components/SyncStatus/SyncStatusDetail.stories.d.ts.map +1 -0
- package/dist/types/src/components/SyncStatus/index.d.ts +1 -0
- package/dist/types/src/components/SyncStatus/index.d.ts.map +1 -1
- package/dist/types/src/components/SyncStatus/sync-state.d.ts +5 -1
- package/dist/types/src/components/SyncStatus/sync-state.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +1 -0
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +5 -0
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +224 -0
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/types.d.ts +14 -14
- package/dist/types/src/types/types.d.ts.map +1 -1
- package/dist/types/src/util.d.ts +3 -13
- package/dist/types/src/util.d.ts.map +1 -1
- package/package.json +38 -35
- package/src/SpacePlugin.tsx +169 -75
- package/src/components/AwaitingObject.tsx +2 -2
- package/src/components/CreateDialog/CreateObjectDialog.stories.tsx +83 -0
- package/src/components/CreateDialog/CreateObjectDialog.tsx +97 -0
- package/src/components/CreateDialog/CreateObjectPanel.tsx +169 -0
- package/src/components/CreateDialog/CreateSpaceDialog.tsx +57 -0
- package/src/components/CreateDialog/index.ts +6 -0
- package/src/components/PopoverRenameObject.tsx +1 -1
- package/src/components/SpacePluginSettings.tsx +3 -32
- package/src/components/SpaceSettings/SpaceSettingsDialog.tsx +1 -1
- package/src/components/SpaceSettings/SpaceSettingsPanel.tsx +2 -6
- package/src/components/SyncStatus/InlineSyncStatus.tsx +45 -0
- package/src/components/SyncStatus/Space.tsx +30 -6
- package/src/components/SyncStatus/SyncStatus.stories.tsx +3 -32
- package/src/components/SyncStatus/SyncStatus.tsx +32 -14
- package/src/components/SyncStatus/SyncStatusDetail.stories.tsx +83 -0
- package/src/components/SyncStatus/index.ts +1 -0
- package/src/components/SyncStatus/sync-state.ts +24 -0
- package/src/components/index.ts +1 -0
- package/src/meta.ts +6 -0
- package/src/translations.ts +15 -0
- package/src/types/types.ts +20 -16
- package/src/util.tsx +51 -141
- package/dist/lib/browser/chunk-DJE2HYFV.mjs.map +0 -7
- package/dist/lib/node/chunk-FYWGZYJB.cjs.map +0 -7
- package/dist/lib/node/chunk-JFDDZI4Y.cjs.map +0 -7
- package/dist/lib/node-esm/chunk-DVUZ7A7G.mjs.map +0 -7
package/src/SpacePlugin.tsx
CHANGED
|
@@ -12,10 +12,12 @@ import {
|
|
|
12
12
|
LayoutAction,
|
|
13
13
|
type LayoutProvides,
|
|
14
14
|
type LocationProvides,
|
|
15
|
+
type MetadataResolverProvides,
|
|
15
16
|
NavigationAction,
|
|
16
17
|
type Plugin,
|
|
17
18
|
type PluginDefinition,
|
|
18
19
|
Surface,
|
|
20
|
+
filterPlugins,
|
|
19
21
|
findPlugin,
|
|
20
22
|
firstIdInPart,
|
|
21
23
|
openIds,
|
|
@@ -27,9 +29,10 @@ import {
|
|
|
27
29
|
resolvePlugin,
|
|
28
30
|
} from '@dxos/app-framework';
|
|
29
31
|
import { EventSubscriptions, type Trigger, type UnsubscribeCallback } from '@dxos/async';
|
|
30
|
-
import { type
|
|
32
|
+
import { S, type AbstractTypedObject, type HasId } from '@dxos/echo-schema';
|
|
31
33
|
import { scheduledEffect } from '@dxos/echo-signals/core';
|
|
32
34
|
import { invariant } from '@dxos/invariant';
|
|
35
|
+
import { create, isDeleted, isReactiveObject } from '@dxos/live-object';
|
|
33
36
|
import { LocalStorageStore } from '@dxos/local-storage';
|
|
34
37
|
import { log } from '@dxos/log';
|
|
35
38
|
import { Migrations } from '@dxos/migrations';
|
|
@@ -37,25 +40,25 @@ import { type AttentionPluginProvides, parseAttentionPlugin } from '@dxos/plugin
|
|
|
37
40
|
import { type ClientPluginProvides, parseClientPlugin } from '@dxos/plugin-client';
|
|
38
41
|
import { type Node, createExtension, memoize, toSignal } from '@dxos/plugin-graph';
|
|
39
42
|
import { ObservabilityAction } from '@dxos/plugin-observability/meta';
|
|
43
|
+
import { EdgeReplicationSetting } from '@dxos/protocols/proto/dxos/echo/metadata';
|
|
40
44
|
import { type Client, PublicKey } from '@dxos/react-client';
|
|
41
45
|
import {
|
|
42
|
-
type ReactiveEchoObject,
|
|
43
46
|
Expando,
|
|
47
|
+
FQ_ID_LENGTH,
|
|
44
48
|
Filter,
|
|
45
|
-
|
|
49
|
+
OBJECT_ID_LENGTH,
|
|
50
|
+
type ReactiveEchoObject,
|
|
51
|
+
SPACE_ID_LENGTH,
|
|
46
52
|
type Space,
|
|
47
53
|
SpaceState,
|
|
48
|
-
create,
|
|
49
54
|
fullyQualifiedId,
|
|
50
55
|
getSpace,
|
|
51
56
|
getTypename,
|
|
52
57
|
isEchoObject,
|
|
53
58
|
isSpace,
|
|
54
59
|
loadObjectReferences,
|
|
60
|
+
parseFullyQualifiedId,
|
|
55
61
|
parseId,
|
|
56
|
-
FQ_ID_LENGTH,
|
|
57
|
-
SPACE_ID_LENGTH,
|
|
58
|
-
OBJECT_ID_LENGTH,
|
|
59
62
|
} from '@dxos/react-client/echo';
|
|
60
63
|
import { type JoinPanelProps, osTranslations } from '@dxos/shell/react';
|
|
61
64
|
import { ComplexMap, nonNullable, reduceGroupBy } from '@dxos/util';
|
|
@@ -64,33 +67,42 @@ import {
|
|
|
64
67
|
AwaitingObject,
|
|
65
68
|
CollectionMain,
|
|
66
69
|
CollectionSection,
|
|
70
|
+
CreateObjectDialog,
|
|
71
|
+
type CreateObjectDialogProps,
|
|
72
|
+
CreateSpaceDialog,
|
|
67
73
|
DefaultObjectSettings,
|
|
68
74
|
JoinDialog,
|
|
75
|
+
InlineSyncStatus,
|
|
69
76
|
MenuFooter,
|
|
70
77
|
PopoverRenameObject,
|
|
71
78
|
PopoverRenameSpace,
|
|
72
79
|
ShareSpaceButton,
|
|
73
80
|
SmallPresence,
|
|
74
81
|
SmallPresenceLive,
|
|
75
|
-
SpacePresence,
|
|
76
82
|
SpacePluginSettings,
|
|
83
|
+
SpacePresence,
|
|
84
|
+
SpaceSettingsDialog,
|
|
77
85
|
SpaceSettingsPanel,
|
|
78
86
|
SyncStatus,
|
|
79
|
-
SpaceSettingsDialog,
|
|
80
87
|
type SpaceSettingsDialogProps,
|
|
81
88
|
} from './components';
|
|
82
|
-
import meta, { SPACE_PLUGIN, SpaceAction } from './meta';
|
|
89
|
+
import meta, { CollectionAction, SPACE_PLUGIN, SpaceAction } from './meta';
|
|
83
90
|
import translations from './translations';
|
|
84
|
-
import {
|
|
91
|
+
import {
|
|
92
|
+
CollectionType,
|
|
93
|
+
parseSchemaPlugin,
|
|
94
|
+
SpaceForm,
|
|
95
|
+
type PluginState,
|
|
96
|
+
type SpacePluginProvides,
|
|
97
|
+
type SpaceSettingsProps,
|
|
98
|
+
} from './types';
|
|
85
99
|
import {
|
|
86
100
|
COMPOSER_SPACE_LOCK,
|
|
87
101
|
SHARED,
|
|
88
102
|
SPACES,
|
|
89
103
|
SPACE_TYPE,
|
|
90
104
|
cloneObject,
|
|
91
|
-
constructObjectActionGroups,
|
|
92
105
|
constructObjectActions,
|
|
93
|
-
constructSpaceActionGroups,
|
|
94
106
|
constructSpaceActions,
|
|
95
107
|
constructSpaceNode,
|
|
96
108
|
createObjectNode,
|
|
@@ -142,9 +154,7 @@ export const SpacePlugin = ({
|
|
|
142
154
|
firstRun,
|
|
143
155
|
onFirstRun,
|
|
144
156
|
}: SpacePluginOptions = {}): PluginDefinition<SpacePluginProvides> => {
|
|
145
|
-
const settings = new LocalStorageStore<SpaceSettingsProps>(SPACE_PLUGIN, {
|
|
146
|
-
onSpaceCreate: 'dxos.org/plugin/markdown/action/create',
|
|
147
|
-
});
|
|
157
|
+
const settings = new LocalStorageStore<SpaceSettingsProps>(SPACE_PLUGIN, {});
|
|
148
158
|
const state = new LocalStorageStore<PluginState>(SPACE_PLUGIN, {
|
|
149
159
|
awaiting: undefined,
|
|
150
160
|
spaceNames: {},
|
|
@@ -153,10 +163,12 @@ export const SpacePlugin = ({
|
|
|
153
163
|
viewersByIdentity: new ComplexMap(PublicKey.hash),
|
|
154
164
|
sdkMigrationRunning: {},
|
|
155
165
|
navigableCollections: false,
|
|
166
|
+
enabledEdgeReplication: false,
|
|
156
167
|
});
|
|
157
168
|
const subscriptions = new EventSubscriptions();
|
|
158
169
|
const spaceSubscriptions = new EventSubscriptions();
|
|
159
170
|
const graphSubscriptions = new Map<string, UnsubscribeCallback>();
|
|
171
|
+
const schemas: AbstractTypedObject[] = [];
|
|
160
172
|
|
|
161
173
|
let clientPlugin: Plugin<ClientPluginProvides> | undefined;
|
|
162
174
|
let graphPlugin: Plugin<GraphProvides> | undefined;
|
|
@@ -164,6 +176,7 @@ export const SpacePlugin = ({
|
|
|
164
176
|
let layoutPlugin: Plugin<LayoutProvides> | undefined;
|
|
165
177
|
let navigationPlugin: Plugin<LocationProvides> | undefined;
|
|
166
178
|
let attentionPlugin: Plugin<AttentionPluginProvides> | undefined;
|
|
179
|
+
let metadataPlugin: Plugin<MetadataResolverProvides> | undefined;
|
|
167
180
|
|
|
168
181
|
const createSpaceInvitationUrl = (invitationCode: string) => {
|
|
169
182
|
const baseUrl = new URL(invitationUrl);
|
|
@@ -254,18 +267,31 @@ export const SpacePlugin = ({
|
|
|
254
267
|
subscriptions.add(
|
|
255
268
|
scheduledEffect(
|
|
256
269
|
() => ({
|
|
257
|
-
|
|
258
|
-
|
|
270
|
+
open: openIds(location.active, layout.layoutMode === 'solo' ? ['solo'] : ['main']),
|
|
271
|
+
closed: [...location.closed],
|
|
259
272
|
}),
|
|
260
|
-
({
|
|
273
|
+
({ open, closed }) => {
|
|
261
274
|
const send = () => {
|
|
262
275
|
const spaces = client.spaces.get();
|
|
263
276
|
const identity = client.halo.identity.get();
|
|
264
277
|
if (identity && location.active) {
|
|
265
278
|
// Group parts by space for efficient messaging.
|
|
266
|
-
const idsBySpace = reduceGroupBy(
|
|
267
|
-
|
|
268
|
-
|
|
279
|
+
const idsBySpace = reduceGroupBy(open, (id) => {
|
|
280
|
+
try {
|
|
281
|
+
const [spaceId] = parseFullyQualifiedId(id);
|
|
282
|
+
return spaceId;
|
|
283
|
+
} catch {
|
|
284
|
+
return null;
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
const removedBySpace = reduceGroupBy(closed, (id) => {
|
|
289
|
+
try {
|
|
290
|
+
const [spaceId] = parseFullyQualifiedId(id);
|
|
291
|
+
return spaceId;
|
|
292
|
+
} catch {
|
|
293
|
+
return null;
|
|
294
|
+
}
|
|
269
295
|
});
|
|
270
296
|
|
|
271
297
|
// NOTE: Ensure all spaces are included so that we send the correct `removed` object arrays.
|
|
@@ -275,7 +301,8 @@ export const SpacePlugin = ({
|
|
|
275
301
|
}
|
|
276
302
|
}
|
|
277
303
|
|
|
278
|
-
for (const [spaceId,
|
|
304
|
+
for (const [spaceId, added] of idsBySpace) {
|
|
305
|
+
const removed = removedBySpace.get(spaceId) ?? [];
|
|
279
306
|
const space = spaces.find((space) => space.id === spaceId);
|
|
280
307
|
if (!space) {
|
|
281
308
|
continue;
|
|
@@ -285,9 +312,8 @@ export const SpacePlugin = ({
|
|
|
285
312
|
.postMessage('viewing', {
|
|
286
313
|
identityKey: identity.identityKey.toHex(),
|
|
287
314
|
attended: attention.attended ? [...attention.attended] : [],
|
|
288
|
-
added
|
|
289
|
-
|
|
290
|
-
removed: removed.filter((id) => !ids.includes(id)),
|
|
315
|
+
added,
|
|
316
|
+
removed,
|
|
291
317
|
})
|
|
292
318
|
// TODO(burdon): This seems defensive; why would this fail? Backoff interval.
|
|
293
319
|
.catch((err) => {
|
|
@@ -298,6 +324,7 @@ export const SpacePlugin = ({
|
|
|
298
324
|
};
|
|
299
325
|
|
|
300
326
|
send();
|
|
327
|
+
// Send at interval to allow peers to expire entries if they become disconnected.
|
|
301
328
|
const interval = setInterval(() => send(), ACTIVE_NODE_BROADCAST_INTERVAL);
|
|
302
329
|
return () => clearInterval(interval);
|
|
303
330
|
},
|
|
@@ -314,7 +341,13 @@ export const SpacePlugin = ({
|
|
|
314
341
|
const { added, removed, attended } = message.payload;
|
|
315
342
|
|
|
316
343
|
const identityKey = PublicKey.safeFrom(message.payload.identityKey);
|
|
317
|
-
|
|
344
|
+
const currentIdentity = client.halo.identity.get();
|
|
345
|
+
if (
|
|
346
|
+
identityKey &&
|
|
347
|
+
!currentIdentity?.identityKey.equals(identityKey) &&
|
|
348
|
+
Array.isArray(added) &&
|
|
349
|
+
Array.isArray(removed)
|
|
350
|
+
) {
|
|
318
351
|
added.forEach((id) => {
|
|
319
352
|
if (typeof id === 'string') {
|
|
320
353
|
if (!(id in state.values.viewersByObject)) {
|
|
@@ -346,11 +379,24 @@ export const SpacePlugin = ({
|
|
|
346
379
|
);
|
|
347
380
|
};
|
|
348
381
|
|
|
382
|
+
const setEdgeReplicationDefault = async (client: Client) => {
|
|
383
|
+
try {
|
|
384
|
+
await Promise.all(
|
|
385
|
+
client.spaces.get().map((space) => space.internal.setEdgeReplicationPreference(EdgeReplicationSetting.ENABLED)),
|
|
386
|
+
);
|
|
387
|
+
state.values.enabledEdgeReplication = true;
|
|
388
|
+
} catch (err) {
|
|
389
|
+
log.catch(err);
|
|
390
|
+
}
|
|
391
|
+
};
|
|
392
|
+
|
|
349
393
|
return {
|
|
350
394
|
meta,
|
|
351
395
|
ready: async (plugins) => {
|
|
352
396
|
settings.prop({ key: 'showHidden', type: LocalStorageStore.bool({ allowUndefined: true }) });
|
|
353
|
-
state
|
|
397
|
+
state
|
|
398
|
+
.prop({ key: 'spaceNames', type: LocalStorageStore.json<Record<string, string>>() })
|
|
399
|
+
.prop({ key: 'enabledEdgeReplication', type: LocalStorageStore.bool() });
|
|
354
400
|
|
|
355
401
|
// TODO(wittjosiah): Hardcoded due to circular dependency.
|
|
356
402
|
// Should be based on a provides interface.
|
|
@@ -360,6 +406,7 @@ export const SpacePlugin = ({
|
|
|
360
406
|
|
|
361
407
|
graphPlugin = resolvePlugin(plugins, parseGraphPlugin);
|
|
362
408
|
layoutPlugin = resolvePlugin(plugins, parseLayoutPlugin);
|
|
409
|
+
metadataPlugin = resolvePlugin(plugins, parseMetadataResolverPlugin);
|
|
363
410
|
navigationPlugin = resolvePlugin(plugins, parseNavigationPlugin);
|
|
364
411
|
attentionPlugin = resolvePlugin(plugins, parseAttentionPlugin);
|
|
365
412
|
clientPlugin = resolvePlugin(plugins, parseClientPlugin);
|
|
@@ -371,6 +418,21 @@ export const SpacePlugin = ({
|
|
|
371
418
|
const client = clientPlugin.provides.client;
|
|
372
419
|
const dispatch = intentPlugin.provides.intent.dispatch;
|
|
373
420
|
|
|
421
|
+
schemas.push(
|
|
422
|
+
...filterPlugins(plugins, parseSchemaPlugin)
|
|
423
|
+
.map((plugin) => plugin.provides.echo.schema)
|
|
424
|
+
.filter(nonNullable)
|
|
425
|
+
.reduce((acc, schema) => {
|
|
426
|
+
return [...acc, ...schema];
|
|
427
|
+
}),
|
|
428
|
+
);
|
|
429
|
+
client.addTypes(schemas);
|
|
430
|
+
filterPlugins(plugins, parseSchemaPlugin).forEach((plugin) => {
|
|
431
|
+
if (plugin.provides.echo.system) {
|
|
432
|
+
client.addTypes(plugin.provides.echo.system);
|
|
433
|
+
}
|
|
434
|
+
});
|
|
435
|
+
|
|
374
436
|
const handleFirstRun = async () => {
|
|
375
437
|
const defaultSpace = client.spaces.default;
|
|
376
438
|
|
|
@@ -393,6 +455,7 @@ export const SpacePlugin = ({
|
|
|
393
455
|
}
|
|
394
456
|
|
|
395
457
|
await onSpaceReady();
|
|
458
|
+
await setEdgeReplicationDefault(client);
|
|
396
459
|
}
|
|
397
460
|
}).unsubscribe,
|
|
398
461
|
);
|
|
@@ -417,6 +480,7 @@ export const SpacePlugin = ({
|
|
|
417
480
|
metadata: {
|
|
418
481
|
records: {
|
|
419
482
|
[CollectionType.typename]: {
|
|
483
|
+
createObject: CollectionAction.CREATE,
|
|
420
484
|
placeholder: ['unnamed collection label', { ns: SPACE_PLUGIN }],
|
|
421
485
|
icon: 'ph--cards-three--regular',
|
|
422
486
|
// TODO(wittjosiah): Move out of metadata.
|
|
@@ -448,6 +512,7 @@ export const SpacePlugin = ({
|
|
|
448
512
|
disposition: 'fallback',
|
|
449
513
|
}
|
|
450
514
|
) : null;
|
|
515
|
+
// TODO(burdon): Add role name syntax to minimal plugin docs.
|
|
451
516
|
case 'complementary--settings':
|
|
452
517
|
return isSpace(data.subject) ? (
|
|
453
518
|
<SpaceSettingsPanel space={data.subject} />
|
|
@@ -464,6 +529,17 @@ export const SpacePlugin = ({
|
|
|
464
529
|
);
|
|
465
530
|
} else if (data.component === 'dxos.org/plugin/space/JoinDialog') {
|
|
466
531
|
return <JoinDialog {...(data.subject as JoinPanelProps)} />;
|
|
532
|
+
} else if (data.component === 'dxos.org/plugin/space/CreateSpaceDialog') {
|
|
533
|
+
return <CreateSpaceDialog />;
|
|
534
|
+
} else if (data.component === 'dxos.org/plugin/space/CreateObjectDialog') {
|
|
535
|
+
return (
|
|
536
|
+
<CreateObjectDialog
|
|
537
|
+
{...(data.subject as CreateObjectDialogProps)}
|
|
538
|
+
schemas={schemas}
|
|
539
|
+
navigableCollections={state.values.navigableCollections}
|
|
540
|
+
resolve={metadataPlugin?.provides.metadata.resolver}
|
|
541
|
+
/>
|
|
542
|
+
);
|
|
467
543
|
}
|
|
468
544
|
return null;
|
|
469
545
|
case 'popover': {
|
|
@@ -475,20 +551,19 @@ export const SpacePlugin = ({
|
|
|
475
551
|
}
|
|
476
552
|
return null;
|
|
477
553
|
}
|
|
478
|
-
|
|
479
|
-
case 'presence--glyph': {
|
|
554
|
+
case 'navtree-item-end': {
|
|
480
555
|
return isReactiveObject(data.object) ? (
|
|
481
556
|
<SmallPresenceLive
|
|
482
557
|
id={data.id as string}
|
|
483
558
|
viewers={state.values.viewersByObject[fullyQualifiedId(data.object)]}
|
|
484
559
|
/>
|
|
560
|
+
) : isSpace(data.object) ? (
|
|
561
|
+
<InlineSyncStatus space={data.object} />
|
|
485
562
|
) : (
|
|
563
|
+
// TODO(wittjosiah): Attention glyph for non-echo items should be handled elsewhere.
|
|
486
564
|
<SmallPresence id={data.id as string} count={0} />
|
|
487
565
|
);
|
|
488
566
|
}
|
|
489
|
-
case 'navbar-start': {
|
|
490
|
-
return null;
|
|
491
|
-
}
|
|
492
567
|
case 'navbar-end': {
|
|
493
568
|
if (!isEchoObject(data.object) && !isSpace(data.object)) {
|
|
494
569
|
return null;
|
|
@@ -611,18 +686,18 @@ export const SpacePlugin = ({
|
|
|
611
686
|
filter: (node): node is Node<null> => node.id === SPACES,
|
|
612
687
|
actions: () => [
|
|
613
688
|
{
|
|
614
|
-
id: SpaceAction.
|
|
689
|
+
id: SpaceAction.OPEN_CREATE_SPACE,
|
|
615
690
|
data: async () => {
|
|
616
691
|
await dispatch({
|
|
617
692
|
plugin: SPACE_PLUGIN,
|
|
618
|
-
action: SpaceAction.
|
|
693
|
+
action: SpaceAction.OPEN_CREATE_SPACE,
|
|
619
694
|
});
|
|
620
695
|
},
|
|
621
696
|
properties: {
|
|
622
697
|
label: ['create space label', { ns: SPACE_PLUGIN }],
|
|
623
698
|
icon: 'ph--plus--regular',
|
|
624
|
-
disposition: 'item',
|
|
625
699
|
testId: 'spacePlugin.createSpace',
|
|
700
|
+
disposition: 'item',
|
|
626
701
|
className: 'border-t border-separator',
|
|
627
702
|
},
|
|
628
703
|
},
|
|
@@ -637,8 +712,8 @@ export const SpacePlugin = ({
|
|
|
637
712
|
properties: {
|
|
638
713
|
label: ['join space label', { ns: SPACE_PLUGIN }],
|
|
639
714
|
icon: 'ph--sign-in--regular',
|
|
640
|
-
disposition: 'item',
|
|
641
715
|
testId: 'spacePlugin.joinSpace',
|
|
716
|
+
disposition: 'item',
|
|
642
717
|
},
|
|
643
718
|
},
|
|
644
719
|
],
|
|
@@ -720,16 +795,10 @@ export const SpacePlugin = ({
|
|
|
720
795
|
},
|
|
721
796
|
}),
|
|
722
797
|
|
|
723
|
-
// Create space actions
|
|
798
|
+
// Create space actions.
|
|
724
799
|
createExtension({
|
|
725
800
|
id: `${SPACE_PLUGIN}/actions`,
|
|
726
801
|
filter: (node): node is Node<Space> => isSpace(node.data),
|
|
727
|
-
actionGroups: ({ node }) =>
|
|
728
|
-
constructSpaceActionGroups({
|
|
729
|
-
space: node.data,
|
|
730
|
-
dispatch,
|
|
731
|
-
navigable: state.values.navigableCollections,
|
|
732
|
-
}),
|
|
733
802
|
actions: ({ node }) => {
|
|
734
803
|
const space = node.data;
|
|
735
804
|
return constructSpaceActions({
|
|
@@ -818,7 +887,8 @@ export const SpacePlugin = ({
|
|
|
818
887
|
void space.db
|
|
819
888
|
.query({ id: objectId })
|
|
820
889
|
.first()
|
|
821
|
-
.then((o) => (store.value = o))
|
|
890
|
+
.then((o) => (store.value = o))
|
|
891
|
+
.catch((err) => log.catch(err, { objectId }));
|
|
822
892
|
}
|
|
823
893
|
}, id);
|
|
824
894
|
const object = store.value;
|
|
@@ -838,12 +908,6 @@ export const SpacePlugin = ({
|
|
|
838
908
|
createExtension({
|
|
839
909
|
id: `${SPACE_PLUGIN}/object-actions`,
|
|
840
910
|
filter: (node): node is Node<ReactiveEchoObject<any>> => isEchoObject(node.data),
|
|
841
|
-
actionGroups: ({ node }) =>
|
|
842
|
-
constructObjectActionGroups({
|
|
843
|
-
object: node.data,
|
|
844
|
-
dispatch,
|
|
845
|
-
navigable: state.values.navigableCollections,
|
|
846
|
-
}),
|
|
847
911
|
actions: ({ node }) => constructObjectActions({ node, dispatch }),
|
|
848
912
|
}),
|
|
849
913
|
|
|
@@ -889,18 +953,7 @@ export const SpacePlugin = ({
|
|
|
889
953
|
};
|
|
890
954
|
}
|
|
891
955
|
|
|
892
|
-
const object =
|
|
893
|
-
(onChange) => {
|
|
894
|
-
const timeout = setTimeout(async () => {
|
|
895
|
-
await space?.db.query({ id: objectId }).first();
|
|
896
|
-
onChange();
|
|
897
|
-
});
|
|
898
|
-
|
|
899
|
-
return () => clearTimeout(timeout);
|
|
900
|
-
},
|
|
901
|
-
() => space?.db.getObjectById(objectId),
|
|
902
|
-
subjectId,
|
|
903
|
-
);
|
|
956
|
+
const [object] = memoizeQuery(space, { id: objectId });
|
|
904
957
|
if (!object || !subjectId) {
|
|
905
958
|
return;
|
|
906
959
|
}
|
|
@@ -1002,12 +1055,34 @@ export const SpacePlugin = ({
|
|
|
1002
1055
|
return { data: true };
|
|
1003
1056
|
}
|
|
1004
1057
|
|
|
1058
|
+
case SpaceAction.OPEN_CREATE_SPACE: {
|
|
1059
|
+
return {
|
|
1060
|
+
data: true,
|
|
1061
|
+
intents: [
|
|
1062
|
+
[
|
|
1063
|
+
{
|
|
1064
|
+
action: LayoutAction.SET_LAYOUT,
|
|
1065
|
+
data: {
|
|
1066
|
+
element: 'dialog',
|
|
1067
|
+
component: 'dxos.org/plugin/space/CreateSpaceDialog',
|
|
1068
|
+
dialogBlockAlign: 'start',
|
|
1069
|
+
subject: intent.data,
|
|
1070
|
+
},
|
|
1071
|
+
},
|
|
1072
|
+
],
|
|
1073
|
+
],
|
|
1074
|
+
};
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1005
1077
|
case SpaceAction.CREATE: {
|
|
1006
|
-
if (!client) {
|
|
1078
|
+
if (!client || !S.is(SpaceForm)(intent.data)) {
|
|
1007
1079
|
return;
|
|
1008
1080
|
}
|
|
1009
1081
|
|
|
1010
|
-
const space = await client.spaces.create(intent.data
|
|
1082
|
+
const space = await client.spaces.create({ name: intent.data.name });
|
|
1083
|
+
if (intent.data.edgeReplication) {
|
|
1084
|
+
await space.internal.setEdgeReplicationPreference(EdgeReplicationSetting.ENABLED);
|
|
1085
|
+
}
|
|
1011
1086
|
await space.waitUntilReady();
|
|
1012
1087
|
const collection = create(CollectionType, { objects: [], views: {} });
|
|
1013
1088
|
space.properties[CollectionType.typename] = collection;
|
|
@@ -1023,16 +1098,6 @@ export const SpacePlugin = ({
|
|
|
1023
1098
|
activeParts: { main: [space.id] },
|
|
1024
1099
|
},
|
|
1025
1100
|
intents: [
|
|
1026
|
-
...(settings.values.onSpaceCreate
|
|
1027
|
-
? [
|
|
1028
|
-
[
|
|
1029
|
-
{ action: settings.values.onSpaceCreate, data: { space } },
|
|
1030
|
-
{ action: SpaceAction.ADD_OBJECT, data: { target: space } },
|
|
1031
|
-
{ action: NavigationAction.OPEN },
|
|
1032
|
-
{ action: NavigationAction.EXPOSE },
|
|
1033
|
-
],
|
|
1034
|
-
]
|
|
1035
|
-
: []),
|
|
1036
1101
|
[
|
|
1037
1102
|
{
|
|
1038
1103
|
action: ObservabilityAction.SEND_EVENT,
|
|
@@ -1258,6 +1323,25 @@ export const SpacePlugin = ({
|
|
|
1258
1323
|
break;
|
|
1259
1324
|
}
|
|
1260
1325
|
|
|
1326
|
+
case SpaceAction.OPEN_CREATE_OBJECT: {
|
|
1327
|
+
return {
|
|
1328
|
+
data: true,
|
|
1329
|
+
intents: [
|
|
1330
|
+
[
|
|
1331
|
+
{
|
|
1332
|
+
action: LayoutAction.SET_LAYOUT,
|
|
1333
|
+
data: {
|
|
1334
|
+
element: 'dialog',
|
|
1335
|
+
component: 'dxos.org/plugin/space/CreateObjectDialog',
|
|
1336
|
+
dialogBlockAlign: 'start',
|
|
1337
|
+
subject: intent.data,
|
|
1338
|
+
},
|
|
1339
|
+
},
|
|
1340
|
+
],
|
|
1341
|
+
],
|
|
1342
|
+
};
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1261
1345
|
case SpaceAction.ADD_OBJECT: {
|
|
1262
1346
|
const object = intent.data?.object ?? intent.data?.result;
|
|
1263
1347
|
if (!isReactiveObject(object)) {
|
|
@@ -1491,6 +1575,16 @@ export const SpacePlugin = ({
|
|
|
1491
1575
|
settings.values.showHidden = intent.data?.state ?? !settings.values.showHidden;
|
|
1492
1576
|
return { data: true };
|
|
1493
1577
|
}
|
|
1578
|
+
|
|
1579
|
+
case CollectionAction.CREATE: {
|
|
1580
|
+
const collection = create(CollectionType, {
|
|
1581
|
+
name: intent.data?.name,
|
|
1582
|
+
objects: [],
|
|
1583
|
+
views: {},
|
|
1584
|
+
});
|
|
1585
|
+
|
|
1586
|
+
return { data: collection };
|
|
1587
|
+
}
|
|
1494
1588
|
}
|
|
1495
1589
|
},
|
|
1496
1590
|
},
|
|
@@ -7,7 +7,7 @@ import React, { useEffect, useState } from 'react';
|
|
|
7
7
|
|
|
8
8
|
import { parseIntentPlugin, useResolvePlugin, parseNavigationPlugin, NavigationAction } from '@dxos/app-framework';
|
|
9
9
|
import { useClient } from '@dxos/react-client';
|
|
10
|
-
import { fullyQualifiedId, useQuery } from '@dxos/react-client/echo';
|
|
10
|
+
import { Filter, fullyQualifiedId, useQuery } from '@dxos/react-client/echo';
|
|
11
11
|
import { Button, Toast, useTranslation } from '@dxos/react-ui';
|
|
12
12
|
import { getSize, mx } from '@dxos/react-ui-theme';
|
|
13
13
|
|
|
@@ -25,7 +25,7 @@ export const AwaitingObject = ({ id }: { id: string }) => {
|
|
|
25
25
|
const navigationPlugin = useResolvePlugin(parseNavigationPlugin);
|
|
26
26
|
|
|
27
27
|
const client = useClient();
|
|
28
|
-
const objects = useQuery(client.spaces);
|
|
28
|
+
const objects = useQuery(client.spaces, Filter.all());
|
|
29
29
|
|
|
30
30
|
useEffect(() => {
|
|
31
31
|
if (!id) {
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import '@dxos-theme';
|
|
6
|
+
|
|
7
|
+
import { type Meta, type StoryObj } from '@storybook/react';
|
|
8
|
+
import React, { useEffect } from 'react';
|
|
9
|
+
|
|
10
|
+
import { create, Filter, useQuery, useSpace } from '@dxos/react-client/echo';
|
|
11
|
+
import { withClientProvider } from '@dxos/react-client/testing';
|
|
12
|
+
import { Dialog } from '@dxos/react-ui';
|
|
13
|
+
import { osTranslations } from '@dxos/shell/react';
|
|
14
|
+
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
15
|
+
|
|
16
|
+
import { CreateObjectDialog, type CreateObjectDialogProps } from './CreateObjectDialog';
|
|
17
|
+
import translations from '../../translations';
|
|
18
|
+
import { CollectionType } from '../../types';
|
|
19
|
+
|
|
20
|
+
const Story = (args: CreateObjectDialogProps) => {
|
|
21
|
+
return (
|
|
22
|
+
<Dialog.Root open>
|
|
23
|
+
<Dialog.Overlay blockAlign='start'>
|
|
24
|
+
<CreateObjectDialog {...args} />
|
|
25
|
+
</Dialog.Overlay>
|
|
26
|
+
</Dialog.Root>
|
|
27
|
+
);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// TODO(wittjosiah): Story should be for CreateObjectPanel.
|
|
31
|
+
const meta: Meta<typeof CreateObjectDialog> = {
|
|
32
|
+
title: 'plugins/plugin-space/CreateObjectDialog',
|
|
33
|
+
component: CreateObjectDialog,
|
|
34
|
+
render: Story,
|
|
35
|
+
decorators: [
|
|
36
|
+
withClientProvider({ createIdentity: true, createSpace: true, types: [CollectionType] }),
|
|
37
|
+
withTheme,
|
|
38
|
+
withLayout({ tooltips: true }),
|
|
39
|
+
],
|
|
40
|
+
parameters: { translations: [...translations, osTranslations] },
|
|
41
|
+
args: {
|
|
42
|
+
schemas: [CollectionType],
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export default meta;
|
|
47
|
+
|
|
48
|
+
export const Default: StoryObj<typeof CreateObjectDialog> = {};
|
|
49
|
+
|
|
50
|
+
export const Typename: StoryObj<typeof CreateObjectDialog> = {
|
|
51
|
+
args: { typename: CollectionType.typename },
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export const TargetSpace: StoryObj<typeof CreateObjectDialog> = {
|
|
55
|
+
render: (args) => {
|
|
56
|
+
const space = useSpace();
|
|
57
|
+
|
|
58
|
+
if (!space) {
|
|
59
|
+
return <></>;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return <Story {...args} target={space} />;
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export const TargetCollection: StoryObj<typeof CreateObjectDialog> = {
|
|
67
|
+
render: (args) => {
|
|
68
|
+
const space = useSpace();
|
|
69
|
+
const [collection] = useQuery(space, Filter.schema(CollectionType));
|
|
70
|
+
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
if (space) {
|
|
73
|
+
space.db.add(create(CollectionType, { name: 'My Collection', objects: [], views: {} }));
|
|
74
|
+
}
|
|
75
|
+
}, [space]);
|
|
76
|
+
|
|
77
|
+
if (!collection) {
|
|
78
|
+
return <></>;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return <Story {...args} target={collection} />;
|
|
82
|
+
},
|
|
83
|
+
};
|