@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.
Files changed (84) 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-WZAM3FNP.mjs → chunk-OWZKSWMX.mjs} +1 -1
  4. package/dist/lib/browser/{chunk-WZAM3FNP.mjs.map → chunk-OWZKSWMX.mjs.map} +2 -2
  5. package/dist/lib/browser/index.mjs +586 -576
  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-HTAM5LQD.cjs → chunk-FYWGZYJB.cjs} +4 -4
  11. package/dist/lib/node/{chunk-HTAM5LQD.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 +816 -805
  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-TRJKV4PK.mjs → chunk-MCEAI4CV.mjs} +1 -1
  24. package/dist/lib/node-esm/{chunk-TRJKV4PK.mjs.map → chunk-MCEAI4CV.mjs.map} +2 -2
  25. package/dist/lib/node-esm/index.mjs +586 -576
  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/index.d.ts +2 -2
  48. package/dist/types/src/components/index.d.ts.map +1 -1
  49. package/dist/types/src/meta.d.ts +3 -2
  50. package/dist/types/src/meta.d.ts.map +1 -1
  51. package/dist/types/src/translations.d.ts +4 -0
  52. package/dist/types/src/translations.d.ts.map +1 -1
  53. package/dist/types/src/types/types.d.ts +5 -0
  54. package/dist/types/src/types/types.d.ts.map +1 -1
  55. package/dist/types/src/util.d.ts +8 -4
  56. package/dist/types/src/util.d.ts.map +1 -1
  57. package/package.json +35 -34
  58. package/src/SpacePlugin.tsx +225 -146
  59. package/src/components/AwaitingObject.tsx +1 -1
  60. package/src/components/JoinDialog.tsx +100 -0
  61. package/src/components/ShareSpaceButton.tsx +10 -6
  62. package/src/components/{SpaceSettings.tsx → SpacePluginSettings.tsx} +1 -1
  63. package/src/components/SpaceSettings/SpaceSettingsDialog.stories.tsx +44 -0
  64. package/src/components/SpaceSettings/SpaceSettingsDialog.tsx +103 -0
  65. package/src/components/SpaceSettings/SpaceSettingsPanel.stories.tsx +32 -0
  66. package/src/components/{SpaceSettingsPanel.tsx → SpaceSettings/SpaceSettingsPanel.tsx} +15 -20
  67. package/src/components/SpaceSettings/index.ts +6 -0
  68. package/src/components/index.ts +2 -2
  69. package/src/meta.ts +2 -1
  70. package/src/translations.ts +4 -0
  71. package/src/types/types.ts +6 -0
  72. package/src/util.tsx +51 -23
  73. package/dist/types/src/components/SpaceMain/SpaceMain.d.ts +0 -10
  74. package/dist/types/src/components/SpaceMain/SpaceMain.d.ts.map +0 -1
  75. package/dist/types/src/components/SpaceMain/SpaceMembersSection.d.ts +0 -6
  76. package/dist/types/src/components/SpaceMain/SpaceMembersSection.d.ts.map +0 -1
  77. package/dist/types/src/components/SpaceMain/index.d.ts +0 -2
  78. package/dist/types/src/components/SpaceMain/index.d.ts.map +0 -1
  79. package/dist/types/src/components/SpaceSettings.d.ts.map +0 -1
  80. package/dist/types/src/components/SpaceSettingsPanel.d.ts.map +0 -1
  81. package/src/components/SpaceMain/SpaceMain.tsx +0 -60
  82. package/src/components/SpaceMain/SpaceMembersSection.tsx +0 -205
  83. package/src/components/SpaceMain/index.ts +0 -5
  84. /package/dist/types/src/components/{SpaceSettingsPanel.d.ts → SpaceSettings/SpaceSettingsPanel.d.ts} +0 -0
@@ -0,0 +1,100 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import React, { useCallback } from 'react';
6
+
7
+ import { LayoutAction, NavigationAction, useIntentDispatcher } from '@dxos/app-framework';
8
+ import { useGraph } from '@dxos/plugin-graph';
9
+ import { ObservabilityAction } from '@dxos/plugin-observability/meta';
10
+ import { useSpaces } from '@dxos/react-client/echo';
11
+ import { type InvitationResult } from '@dxos/react-client/invitations';
12
+ import { Dialog, useTranslation } from '@dxos/react-ui';
13
+ import { JoinPanel, type JoinPanelProps } from '@dxos/shell/react';
14
+
15
+ import { SPACE_PLUGIN } from '../meta';
16
+
17
+ export type JoinDialogProps = JoinPanelProps & {
18
+ navigableCollections?: boolean;
19
+ };
20
+
21
+ export const JoinDialog = ({ navigableCollections, ...props }: JoinDialogProps) => {
22
+ const { t } = useTranslation(SPACE_PLUGIN);
23
+ const dispatch = useIntentDispatcher();
24
+ const spaces = useSpaces();
25
+ const { graph } = useGraph();
26
+
27
+ const handleDone = useCallback(
28
+ async (result: InvitationResult | null) => {
29
+ if (result?.spaceKey) {
30
+ await Promise.all([
31
+ dispatch({
32
+ action: LayoutAction.SET_LAYOUT,
33
+ data: {
34
+ element: 'toast',
35
+ subject: {
36
+ id: `${SPACE_PLUGIN}/join-success`,
37
+ duration: 5_000,
38
+ title: t('join success label'),
39
+ closeLabel: t('dismiss label'),
40
+ },
41
+ },
42
+ }),
43
+ dispatch({
44
+ action: LayoutAction.SET_LAYOUT,
45
+ data: {
46
+ element: 'dialog',
47
+ state: false,
48
+ },
49
+ }),
50
+ ]);
51
+ }
52
+
53
+ const space = spaces.find(({ key }) => result?.spaceKey?.equals(key));
54
+ const target = result?.target || (navigableCollections ? space?.id : undefined);
55
+ if (target) {
56
+ // Wait for up to 1 second before navigating to the target node.
57
+ // If the target has not yet replicated, this will trigger a loading toast.
58
+ await graph.waitForPath({ target }).catch(() => {});
59
+ await Promise.all([
60
+ dispatch({
61
+ action: NavigationAction.OPEN,
62
+ data: {
63
+ activeParts: { main: [target] },
64
+ },
65
+ }),
66
+ dispatch({
67
+ action: NavigationAction.EXPOSE,
68
+ data: {
69
+ id: target,
70
+ },
71
+ }),
72
+ ]);
73
+ }
74
+
75
+ if (space) {
76
+ await dispatch({
77
+ action: ObservabilityAction.SEND_EVENT,
78
+ data: {
79
+ name: 'space.join',
80
+ properties: {
81
+ spaceId: space.id,
82
+ },
83
+ },
84
+ });
85
+ }
86
+ },
87
+ [dispatch, spaces],
88
+ );
89
+
90
+ return (
91
+ <Dialog.Content>
92
+ <JoinPanel
93
+ {...props}
94
+ exitActionParent={<Dialog.Close asChild />}
95
+ doneActionParent={<Dialog.Close asChild />}
96
+ onDone={handleDone}
97
+ />
98
+ </Dialog.Content>
99
+ );
100
+ };
@@ -5,14 +5,15 @@
5
5
  import React from 'react';
6
6
 
7
7
  import { useIntentDispatcher } from '@dxos/app-framework';
8
- import { Button, useTranslation } from '@dxos/react-ui';
8
+ import { type Space } from '@dxos/react-client/echo';
9
+ import { IconButton, useTranslation } from '@dxos/react-ui';
9
10
 
10
11
  import { SPACE_PLUGIN, SpaceAction } from '../meta';
11
12
 
12
- export const ShareSpaceButton = ({ spaceId }: { spaceId: string }) => {
13
+ export const ShareSpaceButton = ({ space }: { space: Space }) => {
13
14
  const dispatch = useIntentDispatcher();
14
15
 
15
- return <ShareSpaceButtonImpl onClick={() => dispatch({ action: SpaceAction.SHARE, data: { spaceId } })} />;
16
+ return <ShareSpaceButtonImpl onClick={() => dispatch({ action: SpaceAction.SHARE, data: { space } })} />;
16
17
  };
17
18
 
18
19
  // TODO(wittjosiah): Better way to name pure/impure components?
@@ -20,8 +21,11 @@ export const ShareSpaceButtonImpl = ({ onClick }: { onClick: () => void }) => {
20
21
  const { t } = useTranslation(SPACE_PLUGIN);
21
22
 
22
23
  return (
23
- <Button data-testid='spacePlugin.shareSpaceButton' onClick={onClick} classNames='mli-1'>
24
- {t('share space label')}
25
- </Button>
24
+ <IconButton
25
+ data-testid='spacePlugin.shareSpaceButton'
26
+ icon='ph--users--regular'
27
+ label={t('share space label')}
28
+ onClick={onClick}
29
+ />
26
30
  );
27
31
  };
@@ -11,7 +11,7 @@ import { DeprecatedFormInput } from '@dxos/react-ui-data';
11
11
  import { SpaceAction, SPACE_PLUGIN } from '../meta';
12
12
  import { parseSpaceInitPlugin, type SpaceSettingsProps } from '../types';
13
13
 
14
- export const SpaceSettings = ({ settings }: { settings: SpaceSettingsProps }) => {
14
+ export const SpacePluginSettings = ({ settings }: { settings: SpaceSettingsProps }) => {
15
15
  const { t } = useTranslation(SPACE_PLUGIN);
16
16
  const dispatch = useIntentDispatcher();
17
17
  const plugins = useResolvePlugins(parseSpaceInitPlugin);
@@ -0,0 +1,44 @@
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 from 'react';
9
+
10
+ import { useStoryClientData, withClientProvider } from '@dxos/react-client/testing';
11
+ import { Dialog } from '@dxos/react-ui';
12
+ import { osTranslations } from '@dxos/shell/react';
13
+ import { withLayout, withTheme } from '@dxos/storybook-utils';
14
+
15
+ import { SpaceSettingsDialog, type SpaceSettingsDialogProps } from './SpaceSettingsDialog';
16
+ import translations from '../../translations';
17
+
18
+ const Story = (args: Partial<SpaceSettingsDialogProps>) => {
19
+ const { space } = useStoryClientData();
20
+
21
+ return (
22
+ <Dialog.Root open>
23
+ <Dialog.Overlay blockAlign='start'>
24
+ <SpaceSettingsDialog {...args} space={space!} />
25
+ </Dialog.Overlay>
26
+ </Dialog.Root>
27
+ );
28
+ };
29
+
30
+ const meta: Meta = {
31
+ title: 'plugins/plugin-space/SpaceSettingsDialog',
32
+ component: SpaceSettingsDialog,
33
+ render: Story,
34
+ decorators: [
35
+ withClientProvider({ createIdentity: true, createSpace: true }),
36
+ withTheme,
37
+ withLayout({ tooltips: true }),
38
+ ],
39
+ parameters: { translations: [...translations, osTranslations] },
40
+ };
41
+
42
+ export default meta;
43
+
44
+ export const Default: StoryObj<typeof SpaceSettingsDialog> = {};
@@ -0,0 +1,103 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import React, { useState } from 'react';
6
+
7
+ import { useClient } from '@dxos/react-client';
8
+ import { Button, Dialog, Icon, toLocalizedString, useTranslation } from '@dxos/react-ui';
9
+ import { Tabs, type TabsRootProps, type TabsActivePart } from '@dxos/react-ui-tabs';
10
+ import { ClipboardProvider, SpacePanel, type SpacePanelProps } from '@dxos/shell/react';
11
+
12
+ import { SpaceSettingsPanel, type SpaceSettingsPanelProps } from './SpaceSettingsPanel';
13
+ import { SPACE_PLUGIN } from '../../meta';
14
+ import { COMPOSER_SPACE_LOCK, getSpaceDisplayName } from '../../util';
15
+
16
+ export type SpaceSettingsTab = 'members' | 'settings';
17
+
18
+ export type SpaceSettingsDialogProps = {
19
+ initialTab?: SpaceSettingsTab;
20
+ namesCache?: Record<string, string>;
21
+ } & SpaceSettingsPanelProps &
22
+ Pick<SpacePanelProps, 'createInvitationUrl' | 'target'>;
23
+
24
+ export const SpaceSettingsDialog = ({
25
+ space,
26
+ target,
27
+ createInvitationUrl,
28
+ initialTab = 'members',
29
+ namesCache,
30
+ }: SpaceSettingsDialogProps) => {
31
+ const { t } = useTranslation(SPACE_PLUGIN);
32
+ const client = useClient();
33
+ const [tabsActivePart, setTabsActivePart] = useState<TabsActivePart>('list');
34
+ const [selected, setSelected] = useState<SpaceSettingsTab>(initialTab);
35
+ const locked = space.properties[COMPOSER_SPACE_LOCK];
36
+ const name = getSpaceDisplayName(space, { personal: client.spaces.default === space, namesCache });
37
+
38
+ return (
39
+ // TODO(wittjosiah): The tablist dialog pattern is copied from @dxos/plugin-manager.
40
+ // Consider factoring it out to the tabs package.
41
+ <Dialog.Content classNames='p-0 bs-content min-bs-[15rem] max-bs-full md:max-is-[40rem] overflow-hidden'>
42
+ <div role='none' className='flex justify-between pbs-3 pis-2 pie-3 @md:pbs-4 @md:pis-4 @md:pie-5'>
43
+ <Dialog.Title
44
+ onClick={() => setTabsActivePart('list')}
45
+ aria-description={t('click to return to tablist description')}
46
+ classNames='flex cursor-pointer items-center group/title'
47
+ >
48
+ <Icon
49
+ icon='ph--caret-left--regular'
50
+ size={4}
51
+ classNames={['@md:hidden', tabsActivePart === 'list' && 'invisible']}
52
+ />
53
+ <span
54
+ className={
55
+ tabsActivePart !== 'list'
56
+ ? 'group-hover/title:underline @md:group-hover/title:no-underline underline-offset-4 decoration-1'
57
+ : ''
58
+ }
59
+ >
60
+ {toLocalizedString(name, t)}
61
+ </span>
62
+ </Dialog.Title>
63
+ <Dialog.Close asChild>
64
+ <Button density='fine' variant='ghost' autoFocus>
65
+ <Icon icon='ph--x--regular' size={3} />
66
+ </Button>
67
+ </Dialog.Close>
68
+ </div>
69
+ <Tabs.Root
70
+ orientation='vertical'
71
+ value={selected}
72
+ onValueChange={setSelected as TabsRootProps['onValueChange']}
73
+ activePart={tabsActivePart}
74
+ onActivePartChange={setTabsActivePart}
75
+ classNames='flex flex-col flex-1 mbs-2'
76
+ >
77
+ <Tabs.Viewport classNames='flex-1 min-bs-0'>
78
+ <div role='none' className='overflow-y-auto pli-3 @md:pis-2 @md:pie-0 mbe-4 border-r border-separator'>
79
+ <Tabs.Tablist classNames='flex flex-col max-bs-none min-is-[200px] gap-4 overflow-y-auto'>
80
+ <div role='none' className='flex flex-col ml-1'>
81
+ <Tabs.Tab value='settings'>{t('settings tab label')}</Tabs.Tab>
82
+ <Tabs.Tab value='members' disabled={locked}>
83
+ {t('members tab label')}
84
+ </Tabs.Tab>
85
+ </div>
86
+ </Tabs.Tablist>
87
+ </div>
88
+
89
+ <Tabs.Tabpanel value='settings' classNames='pli-3 @md:pli-5 max-bs-dvh overflow-y-auto'>
90
+ <SpaceSettingsPanel space={space} />
91
+ </Tabs.Tabpanel>
92
+
93
+ {/* TODO(wittjosiah): Weird focus ring when tabpanel is focused. */}
94
+ <Tabs.Tabpanel value='members' classNames='pli-3 @md:pli-5 max-bs-dvh overflow-y-auto'>
95
+ <ClipboardProvider>
96
+ <SpacePanel space={space} hideHeading target={target} createInvitationUrl={createInvitationUrl} />
97
+ </ClipboardProvider>
98
+ </Tabs.Tabpanel>
99
+ </Tabs.Viewport>
100
+ </Tabs.Root>
101
+ </Dialog.Content>
102
+ );
103
+ };
@@ -0,0 +1,32 @@
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 from 'react';
9
+
10
+ import { useStoryClientData, withClientProvider } from '@dxos/react-client/testing';
11
+ import { withTheme } from '@dxos/storybook-utils';
12
+
13
+ import { SpaceSettingsPanel, type SpaceSettingsPanelProps } from './SpaceSettingsPanel';
14
+ import translations from '../../translations';
15
+
16
+ const Story = (args: Partial<SpaceSettingsPanelProps>) => {
17
+ const { space } = useStoryClientData();
18
+
19
+ return <SpaceSettingsPanel {...args} space={space!} />;
20
+ };
21
+
22
+ const meta: Meta = {
23
+ title: 'plugins/plugin-space/SpaceSettingsPanel',
24
+ component: SpaceSettingsPanel,
25
+ render: Story,
26
+ decorators: [withClientProvider({ createIdentity: true, createSpace: true }), withTheme],
27
+ parameters: { translations },
28
+ };
29
+
30
+ export default meta;
31
+
32
+ export const Default: StoryObj<typeof SpaceSettingsPanel> = {};
@@ -10,8 +10,9 @@ import { useClient } from '@dxos/react-client';
10
10
  import { type Space } from '@dxos/react-client/echo';
11
11
  import { DeviceType, useDevices } from '@dxos/react-client/halo';
12
12
  import { Input, useTranslation } from '@dxos/react-ui';
13
+ import { DeprecatedFormInput } from '@dxos/react-ui-data';
13
14
 
14
- import { SPACE_PLUGIN } from '../meta';
15
+ import { SPACE_PLUGIN } from '../../meta';
15
16
 
16
17
  export type SpaceSettingsPanelProps = {
17
18
  space: Space;
@@ -43,26 +44,20 @@ export const SpaceSettingsPanel = ({ space }: SpaceSettingsPanelProps) => {
43
44
  );
44
45
 
45
46
  return (
46
- <div role='form' className='flex flex-col w-full p-2 gap-4'>
47
- <Input.Root>
48
- <div role='none' className='flex flex-col gap-1'>
49
- <Input.Label>{t('name label')}</Input.Label>
50
- <Input.TextInput
51
- placeholder={t('name placeholder')}
52
- value={space.properties.name ?? ''}
53
- onChange={(event) => {
54
- space.properties.name = event.target.value;
55
- }}
56
- />
57
- </div>
58
- </Input.Root>
47
+ <div role='form' className='flex flex-col'>
48
+ <DeprecatedFormInput label={t('name label')}>
49
+ <Input.TextInput
50
+ placeholder={t('unnamed space label')}
51
+ value={space.properties.name ?? ''}
52
+ onChange={(event) => {
53
+ space.properties.name = event.target.value;
54
+ }}
55
+ />
56
+ </DeprecatedFormInput>
59
57
  {edgeReplicationAvailable && (
60
- <Input.Root>
61
- <div role='none' className='flex justify-between'>
62
- <Input.Label>{t('edge replication label')}</Input.Label>
63
- <Input.Switch checked={edgeReplication} onCheckedChange={toggleEdgeReplication} />
64
- </div>
65
- </Input.Root>
58
+ <DeprecatedFormInput label={t('edge replication label')}>
59
+ <Input.Switch checked={edgeReplication} onCheckedChange={toggleEdgeReplication} />
60
+ </DeprecatedFormInput>
66
61
  )}
67
62
  </div>
68
63
  );
@@ -0,0 +1,6 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ export * from './SpaceSettingsDialog';
6
+ export * from './SpaceSettingsPanel';
@@ -6,13 +6,13 @@ export * from './AwaitingObject';
6
6
  export * from './CollectionMain';
7
7
  export * from './CollectionSection';
8
8
  export * from './DefaultObjectSettings';
9
+ export * from './JoinDialog';
9
10
  export * from './MenuFooter';
10
11
  export * from './PersistenceStatus';
11
12
  export * from './PopoverRenameObject';
12
13
  export * from './PopoverRenameSpace';
13
14
  export * from './ShareSpaceButton';
14
- export * from './SpaceMain';
15
15
  export * from './SpacePresence';
16
+ export * from './SpacePluginSettings';
16
17
  export * from './SpaceSettings';
17
- export * from './SpaceSettingsPanel';
18
18
  export * from './SyncStatus';
package/src/meta.ts CHANGED
@@ -25,9 +25,10 @@ export enum SpaceAction {
25
25
  CLOSE = `${SPACE_ACTION}/close`,
26
26
  MIGRATE = `${SPACE_ACTION}/migrate`,
27
27
  ADD_OBJECT = `${SPACE_ACTION}/add-object`,
28
- REMOVE_OBJECT = `${SPACE_ACTION}/remove-object`,
28
+ REMOVE_OBJECTS = `${SPACE_ACTION}/remove-objects`,
29
29
  RENAME_OBJECT = `${SPACE_ACTION}/rename-object`,
30
30
  DUPLICATE_OBJECT = `${SPACE_ACTION}/duplicate-object`,
31
31
  WAIT_FOR_OBJECT = `${SPACE_ACTION}/wait-for-object`,
32
32
  TOGGLE_HIDDEN = `${SPACE_ACTION}/toggle-hidden`,
33
+ OPEN_SETTINGS = `${SPACE_ACTION}/open-settings`,
33
34
  }
@@ -47,6 +47,7 @@ export default [
47
47
  'delete object label': 'Delete item',
48
48
  'collection deleted label': 'Collection deleted',
49
49
  'object deleted label': 'Item deleted',
50
+ 'objects deleted label': 'Items deleted',
50
51
  'go to object label': 'Open item',
51
52
  'found object label': 'Ready.',
52
53
  'found object description': 'The requested object is now available.',
@@ -100,6 +101,9 @@ export default [
100
101
  'offline persisted label': 'Saved to disk (offline)',
101
102
  'remote synced label': 'Synced with peers',
102
103
  'open settings panel label': 'Show Settings',
104
+ 'open space settings label': 'Space Settings',
105
+ 'members tab label': 'Members',
106
+ 'settings tab label': 'Settings',
103
107
  },
104
108
  },
105
109
  },
@@ -55,6 +55,12 @@ export type PluginState = {
55
55
  */
56
56
  // TODO(wittjosiah): Factor out to sdk. Migration running should probably be a space state.
57
57
  sdkMigrationRunning: Record<string, boolean>;
58
+
59
+ /**
60
+ * Whether or not the user can navigate to collections in the graph.
61
+ * Determined by whether or not there is an available plugin that can render a collection.
62
+ */
63
+ navigableCollections: boolean;
58
64
  };
59
65
 
60
66
  export type SpaceSettingsProps = {
package/src/util.tsx CHANGED
@@ -92,15 +92,18 @@ export const getSpaceDisplayName = (
92
92
  };
93
93
 
94
94
  const getCollectionGraphNodePartials = ({
95
+ navigable,
95
96
  collection,
96
97
  space,
97
98
  resolve,
98
99
  }: {
100
+ navigable: boolean;
99
101
  collection: CollectionType;
100
102
  space: Space;
101
103
  resolve: MetadataResolver;
102
104
  }) => {
103
105
  return {
106
+ disabled: !navigable,
104
107
  acceptPersistenceClass: new Set(['echo']),
105
108
  acceptPersistenceKey: new Set([space.id]),
106
109
  role: 'branch',
@@ -176,11 +179,13 @@ const checkPendingMigration = (space: Space) => {
176
179
 
177
180
  export const constructSpaceNode = ({
178
181
  space,
182
+ navigable = false,
179
183
  personal,
180
184
  namesCache,
181
185
  resolve,
182
186
  }: {
183
187
  space: Space;
188
+ navigable?: boolean;
184
189
  personal?: boolean;
185
190
  namesCache?: Record<string, string>;
186
191
  resolve: MetadataResolver;
@@ -189,7 +194,7 @@ export const constructSpaceNode = ({
189
194
  const collection = space.state.get() === SpaceState.SPACE_READY && space.properties[CollectionType.typename];
190
195
  const partials =
191
196
  space.state.get() === SpaceState.SPACE_READY && collection instanceof CollectionType
192
- ? getCollectionGraphNodePartials({ collection, space, resolve })
197
+ ? getCollectionGraphNodePartials({ collection, space, resolve, navigable })
193
198
  : {};
194
199
 
195
200
  return {
@@ -201,13 +206,21 @@ export const constructSpaceNode = ({
201
206
  label: getSpaceDisplayName(space, { personal, namesCache }),
202
207
  description: space.state.get() === SpaceState.SPACE_READY && space.properties.description,
203
208
  icon: 'ph--planet--regular',
204
- disabled: space.state.get() !== SpaceState.SPACE_READY || hasPendingMigration,
209
+ disabled: !navigable || space.state.get() !== SpaceState.SPACE_READY || hasPendingMigration,
205
210
  testId: 'spacePlugin.space',
206
211
  },
207
212
  };
208
213
  };
209
214
 
210
- export const constructSpaceActionGroups = ({ space, dispatch }: { space: Space; dispatch: IntentDispatcher }) => {
215
+ export const constructSpaceActionGroups = ({
216
+ space,
217
+ navigable,
218
+ dispatch,
219
+ }: {
220
+ space: Space;
221
+ navigable: boolean;
222
+ dispatch: IntentDispatcher;
223
+ }) => {
211
224
  const state = space.state.get();
212
225
  const hasPendingMigration = checkPendingMigration(space);
213
226
  const getId = (id: string) => `${id}/${space.id}`;
@@ -226,8 +239,6 @@ export const constructSpaceActionGroups = ({ space, dispatch }: { space: Space;
226
239
  label: ['create object in space label', { ns: SPACE_PLUGIN }],
227
240
  icon: 'ph--plus--regular',
228
241
  disposition: 'toolbar',
229
- // TODO(wittjosiah): This is currently a navtree feature. Address this with cmd+k integration.
230
- // mainAreaDisposition: 'in-flow',
231
242
  menuType: 'searchList',
232
243
  testId: 'spacePlugin.createObject',
233
244
  },
@@ -242,9 +253,13 @@ export const constructSpaceActionGroups = ({ space, dispatch }: { space: Space;
242
253
  action: SpaceAction.ADD_OBJECT,
243
254
  data: { target: collection, object: create(CollectionType, { objects: [], views: {} }) },
244
255
  },
245
- {
246
- action: NavigationAction.OPEN,
247
- },
256
+ ...(navigable
257
+ ? [
258
+ {
259
+ action: NavigationAction.OPEN,
260
+ },
261
+ ]
262
+ : []),
248
263
  ]),
249
264
  properties: {
250
265
  label: ['create collection label', { ns: SPACE_PLUGIN }],
@@ -286,7 +301,6 @@ export const constructSpaceActions = ({
286
301
  label: ['migrate space label', { ns: SPACE_PLUGIN }],
287
302
  icon: 'ph--database--regular',
288
303
  disposition: 'toolbar',
289
- mainAreaDisposition: 'in-flow',
290
304
  disabled: migrating || Migrations.running(space),
291
305
  },
292
306
  });
@@ -302,7 +316,7 @@ export const constructSpaceActions = ({
302
316
  if (locked) {
303
317
  return;
304
318
  }
305
- await dispatch({ plugin: SPACE_PLUGIN, action: SpaceAction.SHARE, data: { spaceId: space.id } });
319
+ await dispatch({ plugin: SPACE_PLUGIN, action: SpaceAction.SHARE, data: { space } });
306
320
  },
307
321
  properties: {
308
322
  label: ['share space label', { ns: SPACE_PLUGIN }],
@@ -312,7 +326,6 @@ export const constructSpaceActions = ({
312
326
  macos: 'meta+.',
313
327
  windows: 'alt+.',
314
328
  },
315
- mainAreaDisposition: 'absent',
316
329
  },
317
330
  },
318
331
  {
@@ -343,12 +356,23 @@ export const constructSpaceActions = ({
343
356
  macos: 'shift+F6',
344
357
  windows: 'shift+F6',
345
358
  },
346
- mainAreaDisposition: 'absent',
359
+ },
360
+ },
361
+ {
362
+ id: getId(SpaceAction.OPEN_SETTINGS),
363
+ type: ACTION_TYPE,
364
+ data: async () => {
365
+ await dispatch({ plugin: SPACE_PLUGIN, action: SpaceAction.OPEN_SETTINGS, data: { space } });
366
+ },
367
+ properties: {
368
+ label: ['open space settings label', { ns: SPACE_PLUGIN }],
369
+ icon: 'ph--gear--regular',
347
370
  },
348
371
  },
349
372
  );
350
373
  }
351
374
 
375
+ // TODO(wittjosiah): Consider moving close space into the space settings dialog.
352
376
  if (state !== SpaceState.SPACE_INACTIVE && !hasPendingMigration) {
353
377
  actions.push({
354
378
  id: getId(SpaceAction.CLOSE),
@@ -359,7 +383,6 @@ export const constructSpaceActions = ({
359
383
  properties: {
360
384
  label: ['close space label', { ns: SPACE_PLUGIN }],
361
385
  icon: 'ph--x--regular',
362
- mainAreaDisposition: 'menu',
363
386
  disabled: personal,
364
387
  },
365
388
  });
@@ -376,7 +399,6 @@ export const constructSpaceActions = ({
376
399
  label: ['open space label', { ns: SPACE_PLUGIN }],
377
400
  icon: 'ph--clock-counter-clockwise--regular',
378
401
  disposition: 'toolbar',
379
- mainAreaDisposition: 'in-flow',
380
402
  },
381
403
  });
382
404
  }
@@ -387,10 +409,12 @@ export const constructSpaceActions = ({
387
409
  export const createObjectNode = ({
388
410
  object,
389
411
  space,
412
+ navigable = false,
390
413
  resolve,
391
414
  }: {
392
415
  object: EchoReactiveObject<any>;
393
416
  space: Space;
417
+ navigable?: boolean;
394
418
  resolve: MetadataResolver;
395
419
  }) => {
396
420
  const type = getTypename(object);
@@ -405,7 +429,7 @@ export const createObjectNode = ({
405
429
 
406
430
  const partials =
407
431
  object instanceof CollectionType
408
- ? getCollectionGraphNodePartials({ collection: object, space, resolve })
432
+ ? getCollectionGraphNodePartials({ collection: object, space, resolve, navigable })
409
433
  : metadata.graphProps;
410
434
 
411
435
  return {
@@ -427,9 +451,11 @@ export const createObjectNode = ({
427
451
 
428
452
  export const constructObjectActionGroups = ({
429
453
  object,
454
+ navigable,
430
455
  dispatch,
431
456
  }: {
432
457
  object: EchoReactiveObject<any>;
458
+ navigable: boolean;
433
459
  dispatch: IntentDispatcher;
434
460
  }) => {
435
461
  if (!(object instanceof CollectionType)) {
@@ -447,8 +473,6 @@ export const constructObjectActionGroups = ({
447
473
  label: ['create object in collection label', { ns: SPACE_PLUGIN }],
448
474
  icon: 'ph--plus--regular',
449
475
  disposition: 'toolbar',
450
- // TODO(wittjosiah): This is currently a navtree feature. Address this with cmd+k integration.
451
- // mainAreaDisposition: 'in-flow',
452
476
  menuType: 'searchList',
453
477
  testId: 'spacePlugin.createObject',
454
478
  },
@@ -463,9 +487,13 @@ export const constructObjectActionGroups = ({
463
487
  action: SpaceAction.ADD_OBJECT,
464
488
  data: { target: collection, object: create(CollectionType, { objects: [], views: {} }) },
465
489
  },
466
- {
467
- action: NavigationAction.OPEN,
468
- },
490
+ ...(navigable
491
+ ? [
492
+ {
493
+ action: NavigationAction.OPEN,
494
+ },
495
+ ]
496
+ : []),
469
497
  ]),
470
498
  properties: {
471
499
  label: ['create collection label', { ns: SPACE_PLUGIN }],
@@ -511,7 +539,7 @@ export const constructObjectActions = ({
511
539
  },
512
540
  },
513
541
  {
514
- id: getId(SpaceAction.REMOVE_OBJECT),
542
+ id: getId(SpaceAction.REMOVE_OBJECTS),
515
543
  type: ACTION_TYPE,
516
544
  data: async () => {
517
545
  const graph = getGraph(node);
@@ -520,8 +548,8 @@ export const constructObjectActions = ({
520
548
  .find(({ data }) => data instanceof CollectionType)?.data;
521
549
  await dispatch([
522
550
  {
523
- action: SpaceAction.REMOVE_OBJECT,
524
- data: { object, collection },
551
+ action: SpaceAction.REMOVE_OBJECTS,
552
+ data: { objects: [object], collection },
525
553
  },
526
554
  ]);
527
555
  },