@dxos/plugin-space 0.7.4 → 0.7.5-main.9cb18ac

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 (120) hide show
  1. package/dist/lib/browser/chunk-54VE4GTA.mjs +315 -0
  2. package/dist/lib/browser/chunk-54VE4GTA.mjs.map +7 -0
  3. package/dist/lib/browser/chunk-73BCBSLP.mjs +15 -0
  4. package/dist/lib/browser/chunk-73BCBSLP.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +928 -962
  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 -5
  9. package/dist/lib/browser/types/index.mjs +8 -1
  10. package/dist/lib/node/chunk-46S3JOES.cjs +39 -0
  11. package/dist/lib/node/chunk-46S3JOES.cjs.map +7 -0
  12. package/dist/lib/node/chunk-YF2AQ7KP.cjs +343 -0
  13. package/dist/lib/node/chunk-YF2AQ7KP.cjs.map +7 -0
  14. package/dist/lib/node/index.cjs +1053 -1086
  15. package/dist/lib/node/index.cjs.map +4 -4
  16. package/dist/lib/node/meta.cjs +5 -9
  17. package/dist/lib/node/meta.cjs.map +2 -2
  18. package/dist/lib/node/meta.json +1 -1
  19. package/dist/lib/node/types/index.cjs +19 -12
  20. package/dist/lib/node/types/index.cjs.map +2 -2
  21. package/dist/lib/node-esm/chunk-2MNFEB23.mjs +17 -0
  22. package/dist/lib/node-esm/chunk-2MNFEB23.mjs.map +7 -0
  23. package/dist/lib/node-esm/chunk-CDZETPO7.mjs +316 -0
  24. package/dist/lib/node-esm/chunk-CDZETPO7.mjs.map +7 -0
  25. package/dist/lib/node-esm/index.mjs +928 -962
  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 -5
  29. package/dist/lib/node-esm/types/index.mjs +8 -1
  30. package/dist/types/src/SpacePlugin.d.ts +2 -2
  31. package/dist/types/src/SpacePlugin.d.ts.map +1 -1
  32. package/dist/types/src/components/AwaitingObject.d.ts.map +1 -1
  33. package/dist/types/src/components/CreateDialog/CreateObjectDialog.d.ts +4 -2
  34. package/dist/types/src/components/CreateDialog/CreateObjectDialog.d.ts.map +1 -1
  35. package/dist/types/src/components/CreateDialog/CreateObjectPanel.d.ts +3 -3
  36. package/dist/types/src/components/CreateDialog/CreateObjectPanel.d.ts.map +1 -1
  37. package/dist/types/src/components/CreateDialog/CreateSpaceDialog.d.ts +1 -0
  38. package/dist/types/src/components/CreateDialog/CreateSpaceDialog.d.ts.map +1 -1
  39. package/dist/types/src/components/JoinDialog.d.ts +1 -0
  40. package/dist/types/src/components/JoinDialog.d.ts.map +1 -1
  41. package/dist/types/src/components/PopoverRenameObject.d.ts +1 -0
  42. package/dist/types/src/components/PopoverRenameObject.d.ts.map +1 -1
  43. package/dist/types/src/components/PopoverRenameSpace.d.ts +1 -0
  44. package/dist/types/src/components/PopoverRenameSpace.d.ts.map +1 -1
  45. package/dist/types/src/components/ShareSpaceButton.d.ts.map +1 -1
  46. package/dist/types/src/components/SpacePluginSettings.d.ts.map +1 -1
  47. package/dist/types/src/components/SpacePresence.d.ts +9 -6
  48. package/dist/types/src/components/SpacePresence.d.ts.map +1 -1
  49. package/dist/types/src/components/SpacePresence.stories.d.ts +1 -1
  50. package/dist/types/src/components/SpacePresence.stories.d.ts.map +1 -1
  51. package/dist/types/src/components/SpaceSettings/SpaceSettingsDialog.d.ts +1 -0
  52. package/dist/types/src/components/SpaceSettings/SpaceSettingsDialog.d.ts.map +1 -1
  53. package/dist/types/src/components/SpaceSettings/SpaceSettingsDialog.stories.d.ts.map +1 -1
  54. package/dist/types/src/components/SpaceSettings/SpaceSettingsPanel.d.ts +4 -3
  55. package/dist/types/src/components/SpaceSettings/SpaceSettingsPanel.d.ts.map +1 -1
  56. package/dist/types/src/components/SpaceSettings/SpaceSettingsPanel.stories.d.ts.map +1 -1
  57. package/dist/types/src/components/SyncStatus/InlineSyncStatus.d.ts +3 -3
  58. package/dist/types/src/components/SyncStatus/InlineSyncStatus.d.ts.map +1 -1
  59. package/dist/types/src/components/SyncStatus/SyncStatusDetail.stories.d.ts +2 -2
  60. package/dist/types/src/components/SyncStatus/SyncStatusDetail.stories.d.ts.map +1 -1
  61. package/dist/types/src/hooks/index.d.ts +2 -0
  62. package/dist/types/src/hooks/index.d.ts.map +1 -0
  63. package/dist/types/src/hooks/usePath.d.ts +11 -0
  64. package/dist/types/src/hooks/usePath.d.ts.map +1 -0
  65. package/dist/types/src/meta.d.ts +0 -23
  66. package/dist/types/src/meta.d.ts.map +1 -1
  67. package/dist/types/src/translations.d.ts +6 -3
  68. package/dist/types/src/translations.d.ts.map +1 -1
  69. package/dist/types/src/types/collection.d.ts +8 -12
  70. package/dist/types/src/types/collection.d.ts.map +1 -1
  71. package/dist/types/src/types/thread.d.ts +180 -186
  72. package/dist/types/src/types/thread.d.ts.map +1 -1
  73. package/dist/types/src/types/types.d.ts +234 -4
  74. package/dist/types/src/types/types.d.ts.map +1 -1
  75. package/dist/types/src/util.d.ts +3 -3
  76. package/dist/types/src/util.d.ts.map +1 -1
  77. package/dist/types/tsconfig.tsbuildinfo +1 -0
  78. package/package.json +39 -38
  79. package/src/SpacePlugin.tsx +477 -602
  80. package/src/components/AwaitingObject.tsx +19 -17
  81. package/src/components/CreateDialog/CreateObjectDialog.tsx +33 -22
  82. package/src/components/CreateDialog/CreateObjectPanel.tsx +7 -7
  83. package/src/components/CreateDialog/CreateSpaceDialog.tsx +10 -14
  84. package/src/components/JoinDialog.tsx +18 -34
  85. package/src/components/PersistenceStatus.tsx +1 -1
  86. package/src/components/PopoverRenameObject.tsx +2 -0
  87. package/src/components/PopoverRenameSpace.tsx +2 -0
  88. package/src/components/ShareSpaceButton.tsx +5 -4
  89. package/src/components/SpacePluginSettings.tsx +5 -11
  90. package/src/components/SpacePresence.stories.tsx +25 -17
  91. package/src/components/SpacePresence.tsx +36 -16
  92. package/src/components/SpaceSettings/SpaceSettingsDialog.stories.tsx +2 -3
  93. package/src/components/SpaceSettings/SpaceSettingsDialog.tsx +3 -1
  94. package/src/components/SpaceSettings/SpaceSettingsPanel.stories.tsx +7 -5
  95. package/src/components/SpaceSettings/SpaceSettingsPanel.tsx +6 -5
  96. package/src/components/SyncStatus/InlineSyncStatus.tsx +37 -27
  97. package/src/components/SyncStatus/SyncStatusDetail.stories.tsx +55 -51
  98. package/src/hooks/index.ts +5 -0
  99. package/src/hooks/usePath.ts +44 -0
  100. package/src/meta.ts +0 -26
  101. package/src/translations.ts +3 -2
  102. package/src/types/collection.ts +3 -3
  103. package/src/types/thread.ts +6 -6
  104. package/src/types/types.ts +182 -13
  105. package/src/util.tsx +59 -52
  106. package/dist/lib/browser/chunk-FTKV32QZ.mjs +0 -43
  107. package/dist/lib/browser/chunk-FTKV32QZ.mjs.map +0 -7
  108. package/dist/lib/browser/chunk-MWKXNS5S.mjs +0 -124
  109. package/dist/lib/browser/chunk-MWKXNS5S.mjs.map +0 -7
  110. package/dist/lib/node/chunk-6SNOZF7Y.cjs +0 -152
  111. package/dist/lib/node/chunk-6SNOZF7Y.cjs.map +0 -7
  112. package/dist/lib/node/chunk-QNVEU2UD.cjs +0 -69
  113. package/dist/lib/node/chunk-QNVEU2UD.cjs.map +0 -7
  114. package/dist/lib/node-esm/chunk-OHEAWSCA.mjs +0 -126
  115. package/dist/lib/node-esm/chunk-OHEAWSCA.mjs.map +0 -7
  116. package/dist/lib/node-esm/chunk-UMV7XREB.mjs +0 -45
  117. package/dist/lib/node-esm/chunk-UMV7XREB.mjs.map +0 -7
  118. package/dist/types/src/components/SyncStatus/InlineSyncStatus.stories.d.ts +0 -6
  119. package/dist/types/src/components/SyncStatus/InlineSyncStatus.stories.d.ts.map +0 -1
  120. package/src/components/SyncStatus/InlineSyncStatus.stories.tsx +0 -57
@@ -13,6 +13,8 @@ import { SpaceSettingsPanel, type SpaceSettingsPanelProps } from './SpaceSetting
13
13
  import { SPACE_PLUGIN } from '../../meta';
14
14
  import { COMPOSER_SPACE_LOCK, getSpaceDisplayName } from '../../util';
15
15
 
16
+ export const SPACE_SETTINGS_DIALOG = `${SPACE_PLUGIN}/SpaceSettingsDialog`;
17
+
16
18
  export type SpaceSettingsTab = 'members' | 'settings';
17
19
 
18
20
  export type SpaceSettingsDialogProps = {
@@ -39,7 +41,7 @@ export const SpaceSettingsDialog = ({
39
41
  // TODO(wittjosiah): The tablist dialog pattern is copied from @dxos/plugin-manager.
40
42
  // Consider factoring it out to the tabs package.
41
43
  <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'>
44
+ <div role='none' className='flex justify-between pbs-2 pis-2 pie-2 @md:pbs-4 @md:pis-4 @md:pie-4'>
43
45
  <Dialog.Title
44
46
  onClick={() => setTabsActivePart('list')}
45
47
  aria-description={t('click to return to tablist description')}
@@ -7,16 +7,15 @@ import '@dxos-theme';
7
7
  import { type Meta, type StoryObj } from '@storybook/react';
8
8
  import React from 'react';
9
9
 
10
- import { useStoryClientData, withClientProvider } from '@dxos/react-client/testing';
10
+ import { useClientProvider, withClientProvider } from '@dxos/react-client/testing';
11
11
  import { withTheme } from '@dxos/storybook-utils';
12
12
 
13
13
  import { SpaceSettingsPanel, type SpaceSettingsPanelProps } from './SpaceSettingsPanel';
14
14
  import translations from '../../translations';
15
15
 
16
16
  const Story = (args: Partial<SpaceSettingsPanelProps>) => {
17
- const { space } = useStoryClientData();
18
-
19
- return <SpaceSettingsPanel {...args} space={space!} />;
17
+ const { space } = useClientProvider();
18
+ return <SpaceSettingsPanel {...args} space={space!} classNames='p-2 border border-primary-500 rounded' />;
20
19
  };
21
20
 
22
21
  const meta: Meta = {
@@ -24,7 +23,10 @@ const meta: Meta = {
24
23
  component: SpaceSettingsPanel,
25
24
  render: Story,
26
25
  decorators: [withClientProvider({ createIdentity: true, createSpace: true }), withTheme],
27
- parameters: { translations },
26
+ parameters: {
27
+ translations,
28
+ layout: 'centered',
29
+ },
28
30
  };
29
31
 
30
32
  export default meta;
@@ -8,16 +8,17 @@ import { log } from '@dxos/log';
8
8
  import { EdgeReplicationSetting } from '@dxos/protocols/proto/dxos/echo/metadata';
9
9
  import { useClient } from '@dxos/react-client';
10
10
  import { type Space } from '@dxos/react-client/echo';
11
- import { Input, useTranslation } from '@dxos/react-ui';
11
+ import { type ThemedClassName, Input, useTranslation } from '@dxos/react-ui';
12
12
  import { DeprecatedFormInput } from '@dxos/react-ui-form';
13
+ import { mx } from '@dxos/react-ui-theme';
13
14
 
14
15
  import { SPACE_PLUGIN } from '../../meta';
15
16
 
16
- export type SpaceSettingsPanelProps = {
17
+ export type SpaceSettingsPanelProps = ThemedClassName<{
17
18
  space: Space;
18
- };
19
+ }>;
19
20
 
20
- export const SpaceSettingsPanel = ({ space }: SpaceSettingsPanelProps) => {
21
+ export const SpaceSettingsPanel = ({ classNames, space }: SpaceSettingsPanelProps) => {
21
22
  const { t } = useTranslation(SPACE_PLUGIN);
22
23
 
23
24
  const client = useClient();
@@ -40,7 +41,7 @@ export const SpaceSettingsPanel = ({ space }: SpaceSettingsPanelProps) => {
40
41
  );
41
42
 
42
43
  return (
43
- <div role='form' className='flex flex-col'>
44
+ <div role='form' className={mx('flex flex-col', classNames)}>
44
45
  <DeprecatedFormInput label={t('name label')}>
45
46
  <Input.TextInput
46
47
  placeholder={t('unnamed space label')}
@@ -2,15 +2,18 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import React, { type CSSProperties, useEffect, useMemo, useState } from 'react';
5
+ import React, { useEffect, useState } from 'react';
6
6
 
7
+ import { useGraph } from '@dxos/plugin-graph';
7
8
  import { QueryEdgeStatusResponse } from '@dxos/protocols/proto/dxos/client/services';
8
9
  import { EdgeReplicationSetting } from '@dxos/protocols/proto/dxos/echo/metadata';
9
10
  import { useClient } from '@dxos/react-client';
10
11
  import { type Space } from '@dxos/react-client/echo';
11
- import { Icon, useTranslation } from '@dxos/react-ui';
12
+ import { Tooltip, useTranslation } from '@dxos/react-ui';
13
+ import { AttentionGlyph, useAttended, useAttention } from '@dxos/react-ui-attention';
12
14
 
13
15
  import { useSpaceSyncState } from './sync-state';
16
+ import { usePath } from '../../hooks';
14
17
  import { SPACE_PLUGIN } from '../../meta';
15
18
 
16
19
  const useEdgeStatus = (): QueryEdgeStatusResponse.EdgeStatus => {
@@ -26,36 +29,43 @@ const useEdgeStatus = (): QueryEdgeStatusResponse.EdgeStatus => {
26
29
  return status;
27
30
  };
28
31
 
29
- export const InlineSyncStatus = ({ space }: { space: Space }) => {
32
+ export const InlineSyncStatus = ({ space, open }: { space: Space; open?: boolean }) => {
33
+ const { t } = useTranslation(SPACE_PLUGIN);
34
+ const id = space.id;
35
+ const { hasAttention, isAncestor, isRelated } = useAttention(id);
36
+ const isAttended = hasAttention || isAncestor || isRelated;
37
+
38
+ // TODO(wittjosiah): If the attended node is deep in the graph and the graph is not fully loaded
39
+ // this will result in an empty path until the graph is connected.
40
+ // TODO(wittjosiah): Consider using this indicator for all open nodes instead of just attended.
41
+ const { graph } = useGraph();
42
+ const attended = useAttended();
43
+ const startOfAttention = attended.at(-1);
44
+ const path = usePath(graph, startOfAttention);
45
+ const containsAttended = !open && !isAttended && id && path ? path.includes(id) : false;
46
+
30
47
  const connectedToEdge = useEdgeStatus() === QueryEdgeStatusResponse.EdgeStatus.CONNECTED;
31
48
  // TODO(wittjosiah): This is not reactive.
32
49
  const edgeSyncEnabled = space.internal.data.edgeReplication === EdgeReplicationSetting.ENABLED;
33
50
  const syncState = useSpaceSyncState(space);
34
- if (!connectedToEdge || !edgeSyncEnabled || !syncState || syncState.missingOnLocal === 0) {
35
- return null;
36
- }
37
-
38
- return <InlineSyncStatusIndicator />;
39
- };
40
-
41
- export const InlineSyncStatusIndicator = () => {
42
- const { t } = useTranslation(SPACE_PLUGIN);
43
- const animationProps = useMemo<CSSProperties>(
44
- () => ({
45
- // Synchronize animations.
46
- animationDelay: `-${Date.now() % 2_000}ms`,
47
- }),
48
- [],
49
- );
51
+ const syncing = connectedToEdge && edgeSyncEnabled && syncState && syncState.missingOnLocal > 0;
50
52
 
51
53
  return (
52
- <div role='status' aria-label={t('syncing message')} className='flex items-center'>
53
- <Icon
54
- icon='ph--circle-notch--regular'
55
- size={3}
56
- style={animationProps}
57
- classNames='text-subdued animate-[spin_2s_linear_infinite]'
58
- />
59
- </div>
54
+ <Tooltip.Root>
55
+ <Tooltip.Trigger asChild>
56
+ <AttentionGlyph
57
+ syncing={syncing}
58
+ attended={isAttended}
59
+ containsAttended={containsAttended}
60
+ classNames='self-center mie-1'
61
+ />
62
+ </Tooltip.Trigger>
63
+ <Tooltip.Portal>
64
+ <Tooltip.Content side='bottom' classNames='z-[70]'>
65
+ <span>{t('syncing label')}</span>
66
+ <Tooltip.Arrow />
67
+ </Tooltip.Content>
68
+ </Tooltip.Portal>
69
+ </Tooltip.Root>
60
70
  );
61
71
  };
@@ -5,10 +5,13 @@
5
5
  import '@dxos-theme';
6
6
 
7
7
  import { type Meta, type StoryObj } from '@storybook/react';
8
- import React from 'react';
8
+ import React, { useState } from 'react';
9
9
 
10
+ import { type Client } from '@dxos/client';
10
11
  import { faker } from '@dxos/random';
11
- import { useStoryClientData, withClientProvider } from '@dxos/react-client/testing';
12
+ import { useClient } from '@dxos/react-client';
13
+ import { withClientProvider } from '@dxos/react-client/testing';
14
+ import { useAsyncEffect } from '@dxos/react-ui';
12
15
  import { withTheme, withLayout } from '@dxos/storybook-utils';
13
16
 
14
17
  import { SyncStatusDetail } from './SyncStatus';
@@ -17,56 +20,47 @@ import translations from '../../translations';
17
20
 
18
21
  const random = ({ min, max }: { min: number; max: number }) => min + Math.floor(Math.random() * (max - min));
19
22
 
20
- const meta: Meta = {
21
- title: 'plugins/plugin-space/SyncStatusDetail',
22
- component: SyncStatusDetail,
23
- render: (args) => {
24
- const { state } = useStoryClientData<{ state: SpaceSyncStateMap }>();
23
+ const createSpaceSyncStateMap = async (client: Client): Promise<SpaceSyncStateMap> => {
24
+ const spaces = await Promise.all(
25
+ Array.from({ length: 10 }).map(() => client.spaces.create({ name: faker.company.name() })),
26
+ );
25
27
 
26
- return <SyncStatusDetail {...args} state={state} summary={getSyncSummary(state)} />;
27
- },
28
- decorators: [
29
- withTheme,
30
- withLayout({ fullscreen: true }),
31
- withClientProvider({
32
- createIdentity: true,
33
- onIdentityCreated: async ({ client }) => {
34
- const spaces = await Promise.all(
35
- Array.from({ length: 10 }).map(() => client.spaces.create({ name: faker.company.name() })),
36
- );
28
+ return spaces.reduce<SpaceSyncStateMap>((map, space, i) => {
29
+ if (i > 4) {
30
+ const total = random({ min: 10, max: 500 });
31
+ map[space.id] = {
32
+ localDocumentCount: total,
33
+ remoteDocumentCount: total,
34
+ missingOnLocal: 0,
35
+ missingOnRemote: 0,
36
+ differentDocuments: 0,
37
+ };
38
+ return map;
39
+ }
37
40
 
38
- const state: SpaceSyncStateMap = spaces.reduce<SpaceSyncStateMap>((map, space, i) => {
39
- if (i > 4) {
40
- const total = random({ min: 10, max: 500 });
41
- map[space.id] = {
42
- localDocumentCount: total,
43
- remoteDocumentCount: total,
44
- missingOnLocal: 0,
45
- missingOnRemote: 0,
46
- differentDocuments: 0,
47
- };
48
- return map;
49
- }
41
+ const total = random({ min: 10, max: 500 });
42
+ const haveLocal = random({ min: 0, max: total });
43
+ const haveRemote = random({ min: 0, max: total });
44
+ map[space.id] = {
45
+ localDocumentCount: haveLocal,
46
+ remoteDocumentCount: haveRemote,
47
+ missingOnLocal: total - haveLocal,
48
+ missingOnRemote: total - haveRemote,
49
+ differentDocuments: 0,
50
+ };
50
51
 
51
- const total = random({ min: 10, max: 500 });
52
- const haveLocal = random({ min: 0, max: total });
53
- const haveRemote = random({ min: 0, max: total });
54
- map[space.id] = {
55
- localDocumentCount: haveLocal,
56
- remoteDocumentCount: haveRemote,
57
- missingOnLocal: total - haveLocal,
58
- missingOnRemote: total - haveRemote,
59
- differentDocuments: 0,
60
- };
61
-
62
- return map;
63
- }, {});
52
+ return map;
53
+ }, {});
54
+ };
64
55
 
65
- return { state };
66
- },
67
- }),
68
- ],
69
- parameters: { translations },
56
+ const meta: Meta<typeof SyncStatusDetail> = {
57
+ title: 'plugins/plugin-space/SyncStatusDetail',
58
+ component: SyncStatusDetail,
59
+ decorators: [withTheme, withLayout(), withClientProvider({ createIdentity: true })],
60
+ parameters: {
61
+ translations,
62
+ layout: 'centered',
63
+ },
70
64
  args: {
71
65
  classNames: 'm-2 border border-separator rounded-md',
72
66
  },
@@ -76,10 +70,20 @@ export default meta;
76
70
 
77
71
  type Story = StoryObj<typeof SyncStatusDetail>;
78
72
 
79
- export const Default: Story = {};
80
-
81
- export const Empty: Story = {
73
+ export const Default: Story = {
82
74
  render: (args) => {
83
75
  return <SyncStatusDetail {...args} state={{}} />;
84
76
  },
85
77
  };
78
+
79
+ export const Sync: Story = {
80
+ render: (args) => {
81
+ const client = useClient();
82
+ const [state, setState] = useState<SpaceSyncStateMap>({});
83
+ useAsyncEffect(async () => {
84
+ setState(await createSpaceSyncStateMap(client));
85
+ });
86
+
87
+ return <SyncStatusDetail {...args} state={state} summary={getSyncSummary(state)} />;
88
+ },
89
+ };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ export * from './usePath';
@@ -0,0 +1,44 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { useEffect, useState } from 'react';
6
+
7
+ import { type Graph } from '@dxos/plugin-graph';
8
+
9
+ /**
10
+ * React hook to get a path from the graph.
11
+ *
12
+ * @param graph Graph to find the node in.
13
+ * @param id Id of the node to find a path to.
14
+ * @param timeout Optional timeout in milliseconds to wait for the node to be found.
15
+ * @returns Path if found, undefined otherwise.
16
+ */
17
+ // TODO(wittjosiah): Factor out.
18
+ export const usePath = (graph: Graph, id?: string, timeout?: number): string[] | undefined => {
19
+ const [pathState, setPathState] = useState<string[] | undefined>(id ? graph.getPath({ target: id }) : undefined);
20
+
21
+ useEffect(() => {
22
+ if (!id && pathState) {
23
+ setPathState(undefined);
24
+ }
25
+
26
+ if (pathState?.at(-1) === id || !id) {
27
+ return;
28
+ }
29
+
30
+ // Set timeout did not seem to effectively not block the UI thread.
31
+ const frame = requestAnimationFrame(async () => {
32
+ try {
33
+ const path = await graph.waitForPath({ target: id }, { timeout });
34
+ if (path) {
35
+ setPathState(path);
36
+ }
37
+ } catch {}
38
+ });
39
+
40
+ return () => cancelAnimationFrame(frame);
41
+ }, [graph, id, timeout, pathState]);
42
+
43
+ return pathState;
44
+ };
package/src/meta.ts CHANGED
@@ -12,29 +12,3 @@ export default {
12
12
  shortId: SPACE_PLUGIN_SHORT_ID,
13
13
  name: 'Spaces',
14
14
  } satisfies PluginMeta;
15
-
16
- const SPACE_ACTION = `${SPACE_PLUGIN}/action`;
17
- export enum SpaceAction {
18
- OPEN_CREATE_SPACE = `${SPACE_ACTION}/open-create-space`,
19
- CREATE = `${SPACE_ACTION}/create`,
20
- JOIN = `${SPACE_ACTION}/join`,
21
- SHARE = `${SPACE_ACTION}/share`,
22
- LOCK = `${SPACE_ACTION}/lock`,
23
- UNLOCK = `${SPACE_ACTION}/unlock`,
24
- RENAME = `${SPACE_ACTION}/rename`,
25
- OPEN = `${SPACE_ACTION}/open`,
26
- CLOSE = `${SPACE_ACTION}/close`,
27
- MIGRATE = `${SPACE_ACTION}/migrate`,
28
- OPEN_CREATE_OBJECT = `${SPACE_ACTION}/open-create-object`,
29
- ADD_OBJECT = `${SPACE_ACTION}/add-object`,
30
- REMOVE_OBJECTS = `${SPACE_ACTION}/remove-objects`,
31
- RENAME_OBJECT = `${SPACE_ACTION}/rename-object`,
32
- DUPLICATE_OBJECT = `${SPACE_ACTION}/duplicate-object`,
33
- WAIT_FOR_OBJECT = `${SPACE_ACTION}/wait-for-object`,
34
- TOGGLE_HIDDEN = `${SPACE_ACTION}/toggle-hidden`,
35
- OPEN_SETTINGS = `${SPACE_ACTION}/open-settings`,
36
- }
37
-
38
- export enum CollectionAction {
39
- CREATE = 'dxos.org/plugin/collection/action/create',
40
- }
@@ -108,7 +108,7 @@ export default [
108
108
  'open space settings label': 'Space Settings',
109
109
  'members tab label': 'Members',
110
110
  'settings tab label': 'Settings',
111
- 'syncing message': 'Space syncing',
111
+ 'syncing label': 'Space syncing',
112
112
  'show all label': 'Show all',
113
113
  'no sync status label': 'No space with missing objects.',
114
114
  'create space dialog title': 'Create Space',
@@ -116,9 +116,10 @@ export default [
116
116
  'space input placeholder': 'Select space',
117
117
  'schema input placeholder': 'Select object type',
118
118
  'creating object type label': 'Type',
119
- 'creating in space label': 'In Space',
119
+ 'creating in space label': 'Location',
120
120
  'creating in collection label': 'In Collection',
121
121
  'clear input label': 'Clear',
122
+ 'expose object label': 'Expose in navtree',
122
123
  },
123
124
  },
124
125
  },
@@ -2,15 +2,15 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { Expando, ref, S, TypedObject } from '@dxos/echo-schema';
5
+ import { Expando, Ref, S, TypedObject } from '@dxos/echo-schema';
6
6
 
7
7
  export class CollectionType extends TypedObject({ typename: 'dxos.org/type/Collection', version: '0.1.0' })({
8
8
  name: S.optional(S.String),
9
- objects: S.mutable(S.Array(ref(Expando))),
9
+ objects: S.mutable(S.Array(Ref(Expando))),
10
10
  // Key is schema typename and value is reference to a view object of the associated schema.
11
11
  // Having collection reference the views rather than vice versa ensures that the state converges to a single view per key (i.e. type).
12
12
  // This also leaves open a future where this key could be changed to allow for multiple stack views per section.
13
13
  // TODO(wittjosiah): Any way to make this more type safe?
14
14
  // TODO(wittjosiah): Should the views be separate objects or just be schemas for view data in this record?
15
- views: S.mutable(S.Record({ key: S.String, value: ref(Expando) })),
15
+ views: S.mutable(S.Record({ key: S.String, value: Ref(Expando) })),
16
16
  }) {}
@@ -2,7 +2,7 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { Expando, ref, S, TypedObject } from '@dxos/echo-schema';
5
+ import { Expando, Ref, S, TypedObject } from '@dxos/echo-schema';
6
6
 
7
7
  // TODO(wittjosiah): These types were placed here rather than in @dxos/plugin-thread
8
8
  // in order to avoid a circular dependency between threads and other objects that use threads.
@@ -22,7 +22,7 @@ export class ContactType extends TypedObject({ typename: 'dxos.org/type/Contact'
22
22
 
23
23
  export const ActorSchema = S.mutable(
24
24
  S.Struct({
25
- contact: S.optional(ref(ContactType)),
25
+ contact: S.optional(Ref(ContactType)),
26
26
  // TODO(wittjosiah): Should the below fields just be the contact schema?
27
27
  // i.e. it should either be a reference to an existing contact or an inline contact schema.
28
28
  identityKey: S.optional(S.String),
@@ -51,7 +51,7 @@ export class MessageType extends TypedObject({ typename: 'dxos.org/type/Message'
51
51
  /** Text content of the message. */
52
52
  text: S.String,
53
53
  /** Non-text content sent with a message (e.g., files, polls, etc.) */
54
- parts: S.optional(S.mutable(S.Array(ref(Expando)))),
54
+ parts: S.optional(S.mutable(S.Array(Ref(Expando)))),
55
55
  /** Custom properties for specific message types (e.g. email subject or cc fields). */
56
56
  properties: S.optional(S.mutable(S.Record({ key: S.String, value: S.Any }))),
57
57
  // TODO(wittjosiah): Add read status:
@@ -59,7 +59,7 @@ export class MessageType extends TypedObject({ typename: 'dxos.org/type/Message'
59
59
  // - Read receipts don't need to be added to schema until they being implemented.
60
60
  /** Context of the application when message was created. */
61
61
  // TODO(burdon): Evolve "attention object" to be current UX state? E.g., of Deck?
62
- context: S.optional(ref(Expando)),
62
+ context: S.optional(Ref(Expando)),
63
63
  }) {}
64
64
 
65
65
  export const ThreadStatus = S.Union(S.Literal('staged'), S.Literal('active'), S.Literal('resolved'));
@@ -69,10 +69,10 @@ export class ThreadType extends TypedObject({ typename: 'dxos.org/type/Thread',
69
69
  /** AM cursor-range: 'from:to'. */
70
70
  anchor: S.optional(S.String),
71
71
  status: S.optional(ThreadStatus),
72
- messages: S.mutable(S.Array(ref(MessageType))),
72
+ messages: S.mutable(S.Array(Ref(MessageType))),
73
73
  }) {}
74
74
 
75
75
  export class ChannelType extends TypedObject({ typename: 'dxos.org/type/Channel', version: '0.1.0' })({
76
76
  name: S.optional(S.String),
77
- threads: S.mutable(S.Array(ref(ThreadType))),
77
+ threads: S.mutable(S.Array(Ref(ThreadType))),
78
78
  }) {}