@dxos/plugin-space 0.6.14-staging.54a8bab → 0.6.14-staging.7b35391
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-AVLRQF6L.mjs → chunk-DJE2HYFV.mjs} +3 -2
- package/dist/lib/browser/{chunk-AVLRQF6L.mjs.map → chunk-DJE2HYFV.mjs.map} +2 -2
- package/dist/lib/browser/{chunk-WZAM3FNP.mjs → chunk-OWZKSWMX.mjs} +1 -1
- package/dist/lib/browser/{chunk-WZAM3FNP.mjs.map → chunk-OWZKSWMX.mjs.map} +2 -2
- package/dist/lib/browser/index.mjs +586 -576
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/meta.mjs +1 -1
- package/dist/lib/browser/types/index.mjs +1 -1
- package/dist/lib/node/{chunk-HTAM5LQD.cjs → chunk-FYWGZYJB.cjs} +4 -4
- package/dist/lib/node/{chunk-HTAM5LQD.cjs.map → chunk-FYWGZYJB.cjs.map} +2 -2
- package/dist/lib/node/{chunk-P4XUXM7Y.cjs → chunk-JFDDZI4Y.cjs} +6 -5
- package/dist/lib/node/{chunk-P4XUXM7Y.cjs.map → chunk-JFDDZI4Y.cjs.map} +2 -2
- package/dist/lib/node/index.cjs +816 -805
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.cjs +5 -5
- package/dist/lib/node/meta.cjs.map +1 -1
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/types/index.cjs +11 -11
- package/dist/lib/node/types/index.cjs.map +1 -1
- package/dist/lib/node-esm/{chunk-YPQGKWHJ.mjs → chunk-DVUZ7A7G.mjs} +3 -2
- package/dist/lib/node-esm/{chunk-YPQGKWHJ.mjs.map → chunk-DVUZ7A7G.mjs.map} +2 -2
- package/dist/lib/node-esm/{chunk-TRJKV4PK.mjs → chunk-MCEAI4CV.mjs} +1 -1
- package/dist/lib/node-esm/{chunk-TRJKV4PK.mjs.map → chunk-MCEAI4CV.mjs.map} +2 -2
- package/dist/lib/node-esm/index.mjs +586 -576
- 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 +1 -1
- package/dist/lib/node-esm/types/index.mjs +1 -1
- package/dist/types/src/SpacePlugin.d.ts +9 -1
- package/dist/types/src/SpacePlugin.d.ts.map +1 -1
- package/dist/types/src/components/JoinDialog.d.ts +7 -0
- package/dist/types/src/components/JoinDialog.d.ts.map +1 -0
- package/dist/types/src/components/ShareSpaceButton.d.ts +3 -2
- package/dist/types/src/components/ShareSpaceButton.d.ts.map +1 -1
- package/dist/types/src/components/{SpaceSettings.d.ts → SpacePluginSettings.d.ts} +2 -2
- package/dist/types/src/components/SpacePluginSettings.d.ts.map +1 -0
- package/dist/types/src/components/SpaceSettings/SpaceSettingsDialog.d.ts +10 -0
- package/dist/types/src/components/SpaceSettings/SpaceSettingsDialog.d.ts.map +1 -0
- package/dist/types/src/components/SpaceSettings/SpaceSettingsDialog.stories.d.ts +7 -0
- package/dist/types/src/components/SpaceSettings/SpaceSettingsDialog.stories.d.ts.map +1 -0
- package/dist/types/src/components/SpaceSettings/SpaceSettingsPanel.d.ts.map +1 -0
- package/dist/types/src/components/SpaceSettings/SpaceSettingsPanel.stories.d.ts +7 -0
- package/dist/types/src/components/SpaceSettings/SpaceSettingsPanel.stories.d.ts.map +1 -0
- package/dist/types/src/components/SpaceSettings/index.d.ts +3 -0
- package/dist/types/src/components/SpaceSettings/index.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +2 -2
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +3 -2
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +4 -0
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/types.d.ts +5 -0
- package/dist/types/src/types/types.d.ts.map +1 -1
- package/dist/types/src/util.d.ts +8 -4
- package/dist/types/src/util.d.ts.map +1 -1
- package/package.json +35 -34
- package/src/SpacePlugin.tsx +225 -146
- package/src/components/AwaitingObject.tsx +1 -1
- package/src/components/JoinDialog.tsx +100 -0
- package/src/components/ShareSpaceButton.tsx +10 -6
- package/src/components/{SpaceSettings.tsx → SpacePluginSettings.tsx} +1 -1
- package/src/components/SpaceSettings/SpaceSettingsDialog.stories.tsx +44 -0
- package/src/components/SpaceSettings/SpaceSettingsDialog.tsx +103 -0
- package/src/components/SpaceSettings/SpaceSettingsPanel.stories.tsx +32 -0
- package/src/components/{SpaceSettingsPanel.tsx → SpaceSettings/SpaceSettingsPanel.tsx} +15 -20
- package/src/components/SpaceSettings/index.ts +6 -0
- package/src/components/index.ts +2 -2
- package/src/meta.ts +2 -1
- package/src/translations.ts +4 -0
- package/src/types/types.ts +6 -0
- package/src/util.tsx +51 -23
- package/dist/types/src/components/SpaceMain/SpaceMain.d.ts +0 -10
- package/dist/types/src/components/SpaceMain/SpaceMain.d.ts.map +0 -1
- package/dist/types/src/components/SpaceMain/SpaceMembersSection.d.ts +0 -6
- package/dist/types/src/components/SpaceMain/SpaceMembersSection.d.ts.map +0 -1
- package/dist/types/src/components/SpaceMain/index.d.ts +0 -2
- package/dist/types/src/components/SpaceMain/index.d.ts.map +0 -1
- package/dist/types/src/components/SpaceSettings.d.ts.map +0 -1
- package/dist/types/src/components/SpaceSettingsPanel.d.ts.map +0 -1
- package/src/components/SpaceMain/SpaceMain.tsx +0 -60
- package/src/components/SpaceMain/SpaceMembersSection.tsx +0 -205
- package/src/components/SpaceMain/index.ts +0 -5
- /package/dist/types/src/components/{SpaceSettingsPanel.d.ts → SpaceSettings/SpaceSettingsPanel.d.ts} +0 -0
package/src/SpacePlugin.tsx
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
type Plugin,
|
|
17
17
|
type PluginDefinition,
|
|
18
18
|
Surface,
|
|
19
|
+
findPlugin,
|
|
19
20
|
firstIdInPart,
|
|
20
21
|
openIds,
|
|
21
22
|
parseGraphPlugin,
|
|
@@ -28,6 +29,7 @@ import {
|
|
|
28
29
|
import { EventSubscriptions, type Trigger, type UnsubscribeCallback } from '@dxos/async';
|
|
29
30
|
import { type HasId, isReactiveObject } from '@dxos/echo-schema';
|
|
30
31
|
import { scheduledEffect } from '@dxos/echo-signals/core';
|
|
32
|
+
import { invariant } from '@dxos/invariant';
|
|
31
33
|
import { LocalStorageStore } from '@dxos/local-storage';
|
|
32
34
|
import { log } from '@dxos/log';
|
|
33
35
|
import { Migrations } from '@dxos/migrations';
|
|
@@ -53,8 +55,7 @@ import {
|
|
|
53
55
|
parseId,
|
|
54
56
|
FQ_ID_LENGTH,
|
|
55
57
|
} from '@dxos/react-client/echo';
|
|
56
|
-
import {
|
|
57
|
-
import { ClipboardProvider, InvitationManager, type InvitationManagerProps, osTranslations } from '@dxos/shell/react';
|
|
58
|
+
import { type JoinPanelProps, osTranslations } from '@dxos/shell/react';
|
|
58
59
|
import { ComplexMap, nonNullable, reduceGroupBy } from '@dxos/util';
|
|
59
60
|
|
|
60
61
|
import {
|
|
@@ -62,6 +63,7 @@ import {
|
|
|
62
63
|
CollectionMain,
|
|
63
64
|
CollectionSection,
|
|
64
65
|
DefaultObjectSettings,
|
|
66
|
+
JoinDialog,
|
|
65
67
|
MenuFooter,
|
|
66
68
|
PopoverRenameObject,
|
|
67
69
|
PopoverRenameSpace,
|
|
@@ -69,9 +71,11 @@ import {
|
|
|
69
71
|
SmallPresence,
|
|
70
72
|
SmallPresenceLive,
|
|
71
73
|
SpacePresence,
|
|
72
|
-
|
|
74
|
+
SpacePluginSettings,
|
|
73
75
|
SpaceSettingsPanel,
|
|
74
76
|
SyncStatus,
|
|
77
|
+
SpaceSettingsDialog,
|
|
78
|
+
type SpaceSettingsDialogProps,
|
|
75
79
|
} from './components';
|
|
76
80
|
import meta, { SPACE_PLUGIN, SpaceAction } from './meta';
|
|
77
81
|
import translations from './translations';
|
|
@@ -93,6 +97,7 @@ import {
|
|
|
93
97
|
} from './util';
|
|
94
98
|
|
|
95
99
|
const ACTIVE_NODE_BROADCAST_INTERVAL = 30_000;
|
|
100
|
+
const WAIT_FOR_OBJECT_TIMEOUT = 1000;
|
|
96
101
|
const SPACE_MAX_OBJECTS = 500;
|
|
97
102
|
// https://stackoverflow.com/a/19016910
|
|
98
103
|
const DIRECTORY_TYPE = 'text/directory';
|
|
@@ -101,6 +106,16 @@ export const parseSpacePlugin = (plugin?: Plugin) =>
|
|
|
101
106
|
Array.isArray((plugin?.provides as any).space?.enabled) ? (plugin as Plugin<SpacePluginProvides>) : undefined;
|
|
102
107
|
|
|
103
108
|
export type SpacePluginOptions = {
|
|
109
|
+
/**
|
|
110
|
+
* Base URL for the invitation link.
|
|
111
|
+
*/
|
|
112
|
+
invitationUrl?: string;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Query parameter for the invitation code.
|
|
116
|
+
*/
|
|
117
|
+
invitationParam?: string;
|
|
118
|
+
|
|
104
119
|
/**
|
|
105
120
|
* Fired when first run logic should be executed.
|
|
106
121
|
*
|
|
@@ -120,6 +135,8 @@ export type SpacePluginOptions = {
|
|
|
120
135
|
};
|
|
121
136
|
|
|
122
137
|
export const SpacePlugin = ({
|
|
138
|
+
invitationUrl = window.location.origin,
|
|
139
|
+
invitationParam = 'spaceInvitationCode',
|
|
123
140
|
firstRun,
|
|
124
141
|
onFirstRun,
|
|
125
142
|
}: SpacePluginOptions = {}): PluginDefinition<SpacePluginProvides> => {
|
|
@@ -133,6 +150,7 @@ export const SpacePlugin = ({
|
|
|
133
150
|
// TODO(wittjosiah): Stop using (Complex)Map inside reactive object.
|
|
134
151
|
viewersByIdentity: new ComplexMap(PublicKey.hash),
|
|
135
152
|
sdkMigrationRunning: {},
|
|
153
|
+
navigableCollections: false,
|
|
136
154
|
});
|
|
137
155
|
const subscriptions = new EventSubscriptions();
|
|
138
156
|
const spaceSubscriptions = new EventSubscriptions();
|
|
@@ -145,6 +163,12 @@ export const SpacePlugin = ({
|
|
|
145
163
|
let navigationPlugin: Plugin<LocationProvides> | undefined;
|
|
146
164
|
let attentionPlugin: Plugin<AttentionPluginProvides> | undefined;
|
|
147
165
|
|
|
166
|
+
const createSpaceInvitationUrl = (invitationCode: string) => {
|
|
167
|
+
const baseUrl = new URL(invitationUrl);
|
|
168
|
+
baseUrl.searchParams.set(invitationParam, invitationCode);
|
|
169
|
+
return baseUrl.toString();
|
|
170
|
+
};
|
|
171
|
+
|
|
148
172
|
const onSpaceReady = async () => {
|
|
149
173
|
if (!clientPlugin || !intentPlugin || !graphPlugin || !navigationPlugin || !layoutPlugin || !attentionPlugin) {
|
|
150
174
|
return;
|
|
@@ -186,7 +210,18 @@ export const SpacePlugin = ({
|
|
|
186
210
|
|
|
187
211
|
const node = graph.findNode(soloPart.id);
|
|
188
212
|
if (!node && soloPart.id.length === FQ_ID_LENGTH) {
|
|
189
|
-
|
|
213
|
+
const timeout = setTimeout(async () => {
|
|
214
|
+
const node = graph.findNode(soloPart.id);
|
|
215
|
+
if (!node) {
|
|
216
|
+
await dispatch({
|
|
217
|
+
plugin: SPACE_PLUGIN,
|
|
218
|
+
action: SpaceAction.WAIT_FOR_OBJECT,
|
|
219
|
+
data: { id: soloPart.id },
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
}, WAIT_FOR_OBJECT_TIMEOUT);
|
|
223
|
+
|
|
224
|
+
return () => clearTimeout(timeout);
|
|
190
225
|
}
|
|
191
226
|
},
|
|
192
227
|
),
|
|
@@ -315,6 +350,12 @@ export const SpacePlugin = ({
|
|
|
315
350
|
settings.prop({ key: 'showHidden', type: LocalStorageStore.bool({ allowUndefined: true }) });
|
|
316
351
|
state.prop({ key: 'spaceNames', type: LocalStorageStore.json<Record<string, string>>() });
|
|
317
352
|
|
|
353
|
+
// TODO(wittjosiah): Hardcoded due to circular dependency.
|
|
354
|
+
// Should be based on a provides interface.
|
|
355
|
+
if (findPlugin(plugins, 'dxos.org/plugin/stack')) {
|
|
356
|
+
state.values.navigableCollections = true;
|
|
357
|
+
}
|
|
358
|
+
|
|
318
359
|
graphPlugin = resolvePlugin(plugins, parseGraphPlugin);
|
|
319
360
|
layoutPlugin = resolvePlugin(plugins, parseLayoutPlugin);
|
|
320
361
|
navigationPlugin = resolvePlugin(plugins, parseNavigationPlugin);
|
|
@@ -412,14 +453,15 @@ export const SpacePlugin = ({
|
|
|
412
453
|
{ node: <DefaultObjectSettings object={data.subject} />, disposition: 'fallback' }
|
|
413
454
|
) : null;
|
|
414
455
|
case 'dialog':
|
|
415
|
-
if (data.component === 'dxos.org/plugin/space/
|
|
456
|
+
if (data.component === 'dxos.org/plugin/space/SpaceSettingsDialog') {
|
|
416
457
|
return (
|
|
417
|
-
<
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
</Dialog.Content>
|
|
458
|
+
<SpaceSettingsDialog
|
|
459
|
+
{...(data.subject as SpaceSettingsDialogProps)}
|
|
460
|
+
createInvitationUrl={createSpaceInvitationUrl}
|
|
461
|
+
/>
|
|
422
462
|
);
|
|
463
|
+
} else if (data.component === 'dxos.org/plugin/space/JoinDialog') {
|
|
464
|
+
return <JoinDialog {...(data.subject as JoinPanelProps)} />;
|
|
423
465
|
}
|
|
424
466
|
return null;
|
|
425
467
|
case 'popover': {
|
|
@@ -462,7 +504,7 @@ export const SpacePlugin = ({
|
|
|
462
504
|
node: (
|
|
463
505
|
<>
|
|
464
506
|
<SpacePresence object={object} />
|
|
465
|
-
{space.properties[COMPOSER_SPACE_LOCK] ? null : <ShareSpaceButton
|
|
507
|
+
{space.properties[COMPOSER_SPACE_LOCK] ? null : <ShareSpaceButton space={space} />}
|
|
466
508
|
</>
|
|
467
509
|
),
|
|
468
510
|
disposition: 'hoist',
|
|
@@ -472,7 +514,7 @@ export const SpacePlugin = ({
|
|
|
472
514
|
case 'section':
|
|
473
515
|
return data.object instanceof CollectionType ? <CollectionSection collection={data.object} /> : null;
|
|
474
516
|
case 'settings':
|
|
475
|
-
return data.plugin === meta.id ? <
|
|
517
|
+
return data.plugin === meta.id ? <SpacePluginSettings settings={settings.values} /> : null;
|
|
476
518
|
case 'menu-footer':
|
|
477
519
|
if (isEchoObject(data.object)) {
|
|
478
520
|
return <MenuFooter object={data.object} />;
|
|
@@ -533,6 +575,7 @@ export const SpacePlugin = ({
|
|
|
533
575
|
label: ['spaces label', { ns: SPACE_PLUGIN }],
|
|
534
576
|
testId: 'spacePlugin.spaces',
|
|
535
577
|
role: 'branch',
|
|
578
|
+
disabled: true,
|
|
536
579
|
childrenPersistenceClass: 'echo',
|
|
537
580
|
onRearrangeChildren: async (nextOrder: Space[]) => {
|
|
538
581
|
// NOTE: This is needed to ensure order is updated by next animation frame.
|
|
@@ -567,43 +610,32 @@ export const SpacePlugin = ({
|
|
|
567
610
|
{
|
|
568
611
|
id: SpaceAction.CREATE,
|
|
569
612
|
data: async () => {
|
|
570
|
-
await dispatch(
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
},
|
|
575
|
-
{
|
|
576
|
-
action: NavigationAction.OPEN,
|
|
577
|
-
},
|
|
578
|
-
]);
|
|
613
|
+
await dispatch({
|
|
614
|
+
plugin: SPACE_PLUGIN,
|
|
615
|
+
action: SpaceAction.CREATE,
|
|
616
|
+
});
|
|
579
617
|
},
|
|
580
618
|
properties: {
|
|
581
619
|
label: ['create space label', { ns: SPACE_PLUGIN }],
|
|
582
620
|
icon: 'ph--plus--regular',
|
|
583
621
|
disposition: 'item',
|
|
584
622
|
testId: 'spacePlugin.createSpace',
|
|
585
|
-
className: '
|
|
623
|
+
className: 'border-t border-separator',
|
|
586
624
|
},
|
|
587
625
|
},
|
|
588
626
|
{
|
|
589
627
|
id: SpaceAction.JOIN,
|
|
590
628
|
data: async () => {
|
|
591
|
-
await dispatch(
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
},
|
|
596
|
-
{
|
|
597
|
-
action: NavigationAction.OPEN,
|
|
598
|
-
},
|
|
599
|
-
]);
|
|
629
|
+
await dispatch({
|
|
630
|
+
plugin: SPACE_PLUGIN,
|
|
631
|
+
action: SpaceAction.JOIN,
|
|
632
|
+
});
|
|
600
633
|
},
|
|
601
634
|
properties: {
|
|
602
635
|
label: ['join space label', { ns: SPACE_PLUGIN }],
|
|
603
636
|
icon: 'ph--sign-in--regular',
|
|
604
637
|
disposition: 'item',
|
|
605
638
|
testId: 'spacePlugin.joinSpace',
|
|
606
|
-
className: 'pbe-4',
|
|
607
639
|
},
|
|
608
640
|
},
|
|
609
641
|
],
|
|
@@ -622,26 +654,30 @@ export const SpacePlugin = ({
|
|
|
622
654
|
return;
|
|
623
655
|
}
|
|
624
656
|
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
657
|
+
// TODO(wittjosiah): During client reset, accessing default space throws.
|
|
658
|
+
try {
|
|
659
|
+
const [spacesOrder] = memoizeQuery(client.spaces.default, Filter.schema(Expando, { key: SHARED }));
|
|
660
|
+
const order: string[] = spacesOrder?.order ?? [];
|
|
661
|
+
const orderMap = new Map(order.map((id, index) => [id, index]));
|
|
662
|
+
return [
|
|
663
|
+
...spaces
|
|
664
|
+
.filter((space) => orderMap.has(space.id))
|
|
665
|
+
.sort((a, b) => orderMap.get(a.id)! - orderMap.get(b.id)!),
|
|
666
|
+
...spaces.filter((space) => !orderMap.has(space.id)),
|
|
667
|
+
]
|
|
668
|
+
.filter((space) =>
|
|
669
|
+
settings.values.showHidden ? true : space.state.get() !== SpaceState.SPACE_INACTIVE,
|
|
670
|
+
)
|
|
671
|
+
.map((space) =>
|
|
672
|
+
constructSpaceNode({
|
|
673
|
+
space,
|
|
674
|
+
navigable: state.values.navigableCollections,
|
|
675
|
+
personal: space === client.spaces.default,
|
|
676
|
+
namesCache: state.values.spaceNames,
|
|
677
|
+
resolve,
|
|
678
|
+
}),
|
|
679
|
+
);
|
|
680
|
+
} catch {}
|
|
645
681
|
},
|
|
646
682
|
}),
|
|
647
683
|
|
|
@@ -655,12 +691,12 @@ export const SpacePlugin = ({
|
|
|
655
691
|
return;
|
|
656
692
|
}
|
|
657
693
|
|
|
658
|
-
const
|
|
694
|
+
const spaceState = toSignal(
|
|
659
695
|
(onChange) => space.state.subscribe(() => onChange()).unsubscribe,
|
|
660
696
|
() => space.state.get(),
|
|
661
697
|
space.id,
|
|
662
698
|
);
|
|
663
|
-
if (
|
|
699
|
+
if (spaceState !== SpaceState.SPACE_READY) {
|
|
664
700
|
return;
|
|
665
701
|
}
|
|
666
702
|
|
|
@@ -675,7 +711,7 @@ export const SpacePlugin = ({
|
|
|
675
711
|
return;
|
|
676
712
|
}
|
|
677
713
|
|
|
678
|
-
return createObjectNode({ object, space, resolve });
|
|
714
|
+
return createObjectNode({ object, space, resolve, navigable: state.values.navigableCollections });
|
|
679
715
|
},
|
|
680
716
|
}),
|
|
681
717
|
|
|
@@ -683,7 +719,12 @@ export const SpacePlugin = ({
|
|
|
683
719
|
createExtension({
|
|
684
720
|
id: `${SPACE_PLUGIN}/actions`,
|
|
685
721
|
filter: (node): node is Node<Space> => isSpace(node.data),
|
|
686
|
-
actionGroups: ({ node }) =>
|
|
722
|
+
actionGroups: ({ node }) =>
|
|
723
|
+
constructSpaceActionGroups({
|
|
724
|
+
space: node.data,
|
|
725
|
+
dispatch,
|
|
726
|
+
navigable: state.values.navigableCollections,
|
|
727
|
+
}),
|
|
687
728
|
actions: ({ node }) => {
|
|
688
729
|
const space = node.data;
|
|
689
730
|
return constructSpaceActions({
|
|
@@ -701,12 +742,12 @@ export const SpacePlugin = ({
|
|
|
701
742
|
filter: (node): node is Node<Space> => isSpace(node.data),
|
|
702
743
|
connector: ({ node }) => {
|
|
703
744
|
const space = node.data;
|
|
704
|
-
const
|
|
745
|
+
const spaceState = toSignal(
|
|
705
746
|
(onChange) => space.state.subscribe(() => onChange()).unsubscribe,
|
|
706
747
|
() => space.state.get(),
|
|
707
748
|
space.id,
|
|
708
749
|
);
|
|
709
|
-
if (
|
|
750
|
+
if (spaceState !== SpaceState.SPACE_READY) {
|
|
710
751
|
return;
|
|
711
752
|
}
|
|
712
753
|
|
|
@@ -717,7 +758,9 @@ export const SpacePlugin = ({
|
|
|
717
758
|
|
|
718
759
|
return collection.objects
|
|
719
760
|
.filter(nonNullable)
|
|
720
|
-
.map((object) =>
|
|
761
|
+
.map((object) =>
|
|
762
|
+
createObjectNode({ object, space, resolve, navigable: state.values.navigableCollections }),
|
|
763
|
+
)
|
|
721
764
|
.filter(nonNullable);
|
|
722
765
|
},
|
|
723
766
|
}),
|
|
@@ -726,7 +769,12 @@ export const SpacePlugin = ({
|
|
|
726
769
|
createExtension({
|
|
727
770
|
id: `${SPACE_PLUGIN}/object-actions`,
|
|
728
771
|
filter: (node): node is Node<EchoReactiveObject<any>> => isEchoObject(node.data),
|
|
729
|
-
actionGroups: ({ node }) =>
|
|
772
|
+
actionGroups: ({ node }) =>
|
|
773
|
+
constructObjectActionGroups({
|
|
774
|
+
object: node.data,
|
|
775
|
+
dispatch,
|
|
776
|
+
navigable: state.values.navigableCollections,
|
|
777
|
+
}),
|
|
730
778
|
actions: ({ node }) => constructObjectActions({ node, dispatch }),
|
|
731
779
|
}),
|
|
732
780
|
|
|
@@ -743,7 +791,9 @@ export const SpacePlugin = ({
|
|
|
743
791
|
|
|
744
792
|
return collection.objects
|
|
745
793
|
.filter(nonNullable)
|
|
746
|
-
.map((object) =>
|
|
794
|
+
.map((object) =>
|
|
795
|
+
createObjectNode({ object, space, resolve, navigable: state.values.navigableCollections }),
|
|
796
|
+
)
|
|
747
797
|
.filter(nonNullable);
|
|
748
798
|
},
|
|
749
799
|
}),
|
|
@@ -923,6 +973,7 @@ export const SpacePlugin = ({
|
|
|
923
973
|
[
|
|
924
974
|
{ action: settings.values.onSpaceCreate, data: { space } },
|
|
925
975
|
{ action: SpaceAction.ADD_OBJECT, data: { target: space } },
|
|
976
|
+
{ action: NavigationAction.OPEN },
|
|
926
977
|
{ action: NavigationAction.EXPOSE },
|
|
927
978
|
],
|
|
928
979
|
]
|
|
@@ -943,69 +994,60 @@ export const SpacePlugin = ({
|
|
|
943
994
|
}
|
|
944
995
|
|
|
945
996
|
case SpaceAction.JOIN: {
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
997
|
+
return {
|
|
998
|
+
data: true,
|
|
999
|
+
intents: [
|
|
1000
|
+
[
|
|
1001
|
+
{
|
|
1002
|
+
action: LayoutAction.SET_LAYOUT,
|
|
1003
|
+
data: {
|
|
1004
|
+
element: 'dialog',
|
|
1005
|
+
component: 'dxos.org/plugin/space/JoinDialog',
|
|
1006
|
+
dialogBlockAlign: 'start',
|
|
1007
|
+
subject: {
|
|
1008
|
+
initialInvitationCode: intent.data?.invitationCode,
|
|
1009
|
+
} satisfies Partial<JoinPanelProps>,
|
|
1010
|
+
},
|
|
954
1011
|
},
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
action: LayoutAction.SET_LAYOUT,
|
|
959
|
-
data: {
|
|
960
|
-
element: 'toast',
|
|
961
|
-
subject: {
|
|
962
|
-
id: `${SPACE_PLUGIN}/join-success`,
|
|
963
|
-
duration: 10_000,
|
|
964
|
-
title: translations[0]['en-US'][SPACE_PLUGIN]['join success label'],
|
|
965
|
-
closeLabel: translations[0]['en-US'][SPACE_PLUGIN]['dismiss label'],
|
|
966
|
-
},
|
|
967
|
-
},
|
|
968
|
-
},
|
|
969
|
-
],
|
|
970
|
-
[
|
|
971
|
-
{
|
|
972
|
-
action: ObservabilityAction.SEND_EVENT,
|
|
973
|
-
data: {
|
|
974
|
-
name: 'space.join',
|
|
975
|
-
properties: {
|
|
976
|
-
spaceId: space.id,
|
|
977
|
-
},
|
|
978
|
-
},
|
|
979
|
-
},
|
|
980
|
-
],
|
|
981
|
-
],
|
|
982
|
-
};
|
|
983
|
-
}
|
|
984
|
-
}
|
|
1012
|
+
],
|
|
1013
|
+
],
|
|
1014
|
+
};
|
|
985
1015
|
break;
|
|
986
1016
|
}
|
|
987
1017
|
|
|
988
1018
|
case SpaceAction.SHARE: {
|
|
989
|
-
const
|
|
990
|
-
if (
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
const result = await clientPlugin.provides.client.shell.shareSpace({ spaceId, target });
|
|
1019
|
+
const space = intent.data?.space;
|
|
1020
|
+
if (isSpace(space) && !space.properties[COMPOSER_SPACE_LOCK]) {
|
|
1021
|
+
const active = navigationPlugin?.provides.location.active;
|
|
1022
|
+
const mode = layoutPlugin?.provides.layout.layoutMode;
|
|
1023
|
+
const target = active ? firstIdInPart(active, mode === 'solo' ? 'solo' : 'main') : undefined;
|
|
1024
|
+
|
|
996
1025
|
return {
|
|
997
|
-
data:
|
|
1026
|
+
data: true,
|
|
998
1027
|
intents: [
|
|
1028
|
+
[
|
|
1029
|
+
{
|
|
1030
|
+
action: LayoutAction.SET_LAYOUT,
|
|
1031
|
+
data: {
|
|
1032
|
+
element: 'dialog',
|
|
1033
|
+
component: 'dxos.org/plugin/space/SpaceSettingsDialog',
|
|
1034
|
+
dialogBlockAlign: 'start',
|
|
1035
|
+
subject: {
|
|
1036
|
+
space,
|
|
1037
|
+
target,
|
|
1038
|
+
initialTab: 'members',
|
|
1039
|
+
createInvitationUrl: createSpaceInvitationUrl,
|
|
1040
|
+
} satisfies Partial<SpaceSettingsDialogProps>,
|
|
1041
|
+
},
|
|
1042
|
+
},
|
|
1043
|
+
],
|
|
999
1044
|
[
|
|
1000
1045
|
{
|
|
1001
1046
|
action: ObservabilityAction.SEND_EVENT,
|
|
1002
1047
|
data: {
|
|
1003
1048
|
name: 'space.share',
|
|
1004
1049
|
properties: {
|
|
1005
|
-
|
|
1006
|
-
members: result.members?.length,
|
|
1007
|
-
error: result.error?.message,
|
|
1008
|
-
cancelled: result.cancelled,
|
|
1050
|
+
space: space.id,
|
|
1009
1051
|
},
|
|
1010
1052
|
},
|
|
1011
1053
|
},
|
|
@@ -1086,6 +1128,33 @@ export const SpacePlugin = ({
|
|
|
1086
1128
|
break;
|
|
1087
1129
|
}
|
|
1088
1130
|
|
|
1131
|
+
case SpaceAction.OPEN_SETTINGS: {
|
|
1132
|
+
const space = intent.data?.space;
|
|
1133
|
+
if (isSpace(space)) {
|
|
1134
|
+
return {
|
|
1135
|
+
data: true,
|
|
1136
|
+
intents: [
|
|
1137
|
+
[
|
|
1138
|
+
{
|
|
1139
|
+
action: LayoutAction.SET_LAYOUT,
|
|
1140
|
+
data: {
|
|
1141
|
+
element: 'dialog',
|
|
1142
|
+
component: 'dxos.org/plugin/space/SpaceSettingsDialog',
|
|
1143
|
+
dialogBlockAlign: 'start',
|
|
1144
|
+
subject: {
|
|
1145
|
+
space,
|
|
1146
|
+
initialTab: 'settings',
|
|
1147
|
+
createInvitationUrl: createSpaceInvitationUrl,
|
|
1148
|
+
} satisfies Partial<SpaceSettingsDialogProps>,
|
|
1149
|
+
},
|
|
1150
|
+
},
|
|
1151
|
+
],
|
|
1152
|
+
],
|
|
1153
|
+
};
|
|
1154
|
+
}
|
|
1155
|
+
break;
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1089
1158
|
case SpaceAction.OPEN: {
|
|
1090
1159
|
const space = intent.data?.space;
|
|
1091
1160
|
if (isSpace(space)) {
|
|
@@ -1217,10 +1286,13 @@ export const SpacePlugin = ({
|
|
|
1217
1286
|
};
|
|
1218
1287
|
}
|
|
1219
1288
|
|
|
1220
|
-
case SpaceAction.
|
|
1221
|
-
const
|
|
1222
|
-
|
|
1223
|
-
|
|
1289
|
+
case SpaceAction.REMOVE_OBJECTS: {
|
|
1290
|
+
const objects = intent.data?.objects ?? intent.data?.result;
|
|
1291
|
+
invariant(Array.isArray(objects));
|
|
1292
|
+
|
|
1293
|
+
// All objects must be a member of the same space.
|
|
1294
|
+
const space = getSpace(objects[0]);
|
|
1295
|
+
if (!space || !objects.every((obj) => isEchoObject(obj) && getSpace(obj) === space)) {
|
|
1224
1296
|
return;
|
|
1225
1297
|
}
|
|
1226
1298
|
|
|
@@ -1229,23 +1301,22 @@ export const SpacePlugin = ({
|
|
|
1229
1301
|
const openObjectIds = new Set<string>(openIds(activeParts ?? {}));
|
|
1230
1302
|
|
|
1231
1303
|
if (!intent.undo && resolve) {
|
|
1232
|
-
// Capture the current state for undo.
|
|
1233
1304
|
const parentCollection = intent.data?.collection ?? space.properties[CollectionType.typename];
|
|
1234
|
-
const
|
|
1305
|
+
const nestedObjectsList = await Promise.all(objects.map((obj) => getNestedObjects(obj, resolve)));
|
|
1306
|
+
|
|
1235
1307
|
const deletionData = {
|
|
1236
|
-
|
|
1308
|
+
objects,
|
|
1237
1309
|
parentCollection,
|
|
1238
|
-
|
|
1239
|
-
parentCollection instanceof CollectionType
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1310
|
+
indices: objects.map((obj) =>
|
|
1311
|
+
parentCollection instanceof CollectionType ? parentCollection.objects.indexOf(obj as Expando) : -1,
|
|
1312
|
+
),
|
|
1313
|
+
nestedObjectsList,
|
|
1314
|
+
wasActive: objects
|
|
1315
|
+
.flatMap((obj, i) => [obj, ...nestedObjectsList[i]])
|
|
1244
1316
|
.map((obj) => fullyQualifiedId(obj))
|
|
1245
1317
|
.filter((id) => openObjectIds.has(id)),
|
|
1246
1318
|
};
|
|
1247
1319
|
|
|
1248
|
-
// If the item is active, navigate to "nowhere" to avoid navigating to a removed item.
|
|
1249
1320
|
if (deletionData.wasActive.length > 0) {
|
|
1250
1321
|
await intentPlugin?.provides.intent.dispatch({
|
|
1251
1322
|
action: NavigationAction.CLOSE,
|
|
@@ -1258,48 +1329,56 @@ export const SpacePlugin = ({
|
|
|
1258
1329
|
});
|
|
1259
1330
|
}
|
|
1260
1331
|
|
|
1261
|
-
if (parentCollection instanceof CollectionType) {
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1332
|
+
if (deletionData.parentCollection instanceof CollectionType) {
|
|
1333
|
+
[...deletionData.indices]
|
|
1334
|
+
.sort((a, b) => b - a)
|
|
1335
|
+
.forEach((index: number) => {
|
|
1336
|
+
if (index !== -1) {
|
|
1337
|
+
deletionData.parentCollection.objects.splice(index, 1);
|
|
1338
|
+
}
|
|
1339
|
+
});
|
|
1267
1340
|
}
|
|
1268
1341
|
|
|
1269
|
-
|
|
1270
|
-
deletionData.nestedObjects.forEach((obj) => {
|
|
1342
|
+
deletionData.nestedObjectsList.flat().forEach((obj) => {
|
|
1271
1343
|
space.db.remove(obj);
|
|
1272
1344
|
});
|
|
1273
|
-
space.db.remove(
|
|
1345
|
+
objects.forEach((obj) => space.db.remove(obj));
|
|
1274
1346
|
|
|
1275
|
-
const undoMessageKey =
|
|
1276
|
-
|
|
1347
|
+
const undoMessageKey = objects.some((obj) => obj instanceof CollectionType)
|
|
1348
|
+
? 'collection deleted label'
|
|
1349
|
+
: objects.length > 1
|
|
1350
|
+
? 'objects deleted label'
|
|
1351
|
+
: 'object deleted label';
|
|
1277
1352
|
|
|
1278
1353
|
return {
|
|
1279
1354
|
data: true,
|
|
1280
1355
|
undoable: {
|
|
1281
|
-
//
|
|
1356
|
+
// TODO(ZaymonFC): Pluralize if more than one object.
|
|
1282
1357
|
message: translations[0]['en-US'][SPACE_PLUGIN][undoMessageKey],
|
|
1283
1358
|
data: deletionData,
|
|
1284
1359
|
},
|
|
1285
1360
|
};
|
|
1286
1361
|
} else {
|
|
1287
1362
|
const undoData = intent.data;
|
|
1288
|
-
if (
|
|
1363
|
+
if (
|
|
1364
|
+
undoData?.objects?.length &&
|
|
1365
|
+
undoData.objects.every(isEchoObject) &&
|
|
1366
|
+
undoData.parentCollection instanceof CollectionType
|
|
1367
|
+
) {
|
|
1289
1368
|
// Restore the object to the space.
|
|
1290
|
-
const
|
|
1369
|
+
const restoredObjects = undoData.objects.map((obj: Expando) => space.db.add(obj));
|
|
1291
1370
|
|
|
1292
|
-
// Restore nested objects
|
|
1293
|
-
undoData.
|
|
1371
|
+
// Restore nested objects to the space.
|
|
1372
|
+
undoData.nestedObjectsList.flat().forEach((obj: Expando) => {
|
|
1294
1373
|
space.db.add(obj);
|
|
1295
1374
|
});
|
|
1296
1375
|
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1376
|
+
undoData.indices.forEach((index: number, i: number) => {
|
|
1377
|
+
if (index !== -1) {
|
|
1378
|
+
undoData.parentCollection.objects.splice(index, 0, restoredObjects[i] as Expando);
|
|
1379
|
+
}
|
|
1380
|
+
});
|
|
1301
1381
|
|
|
1302
|
-
// Restore active state if it was active before removal.
|
|
1303
1382
|
if (undoData.wasActive.length > 0) {
|
|
1304
1383
|
await intentPlugin?.provides.intent.dispatch({
|
|
1305
1384
|
action: NavigationAction.OPEN,
|
|
@@ -43,7 +43,7 @@ export const AwaitingObject = ({ id }: { id: string }) => {
|
|
|
43
43
|
if (objects.findIndex((object) => fullyQualifiedId(object) === id) > -1) {
|
|
44
44
|
setFound(true);
|
|
45
45
|
|
|
46
|
-
if (navigationPlugin?.provides.location.active === id) {
|
|
46
|
+
if (navigationPlugin?.provides.location.active.solo?.[0].id === id) {
|
|
47
47
|
setOpen(false);
|
|
48
48
|
}
|
|
49
49
|
}
|