@dxos/plugin-navtree 0.8.4-main.c85a9c8dae → 0.8.4-main.d9fc60f731

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 (258) hide show
  1. package/LICENSE +102 -5
  2. package/PLUGIN.mdl +376 -0
  3. package/README.md +1 -1
  4. package/dist/lib/{browser/CommandsDialogContent-A27AKTHH.mjs → neutral/CommandsDialogContent-UBGIQ5FI.mjs} +24 -23
  5. package/dist/lib/neutral/CommandsDialogContent-UBGIQ5FI.mjs.map +7 -0
  6. package/dist/lib/{browser/CommandsTrigger-HBZYQCGV.mjs → neutral/CommandsTrigger-BH5WLMHK.mjs} +8 -14
  7. package/dist/lib/neutral/CommandsTrigger-BH5WLMHK.mjs.map +7 -0
  8. package/dist/lib/neutral/NavTreeContainer-6AR4BFDD.mjs +12 -0
  9. package/dist/lib/neutral/NavTreeContainer-6AR4BFDD.mjs.map +7 -0
  10. package/dist/lib/{browser/NavTreeDocumentTitle-GEE3URWH.mjs → neutral/NavTreeDocumentTitle-H3E6ZLYE.mjs} +5 -9
  11. package/dist/lib/neutral/NavTreeDocumentTitle-H3E6ZLYE.mjs.map +7 -0
  12. package/dist/lib/neutral/NavTreePlugin.mjs +68 -0
  13. package/dist/lib/neutral/NavTreePlugin.mjs.map +7 -0
  14. package/dist/lib/neutral/NavTreePlugin.node.mjs +18 -0
  15. package/dist/lib/neutral/NavTreePlugin.node.mjs.map +7 -0
  16. package/dist/lib/neutral/NavTreePlugin.workerd.mjs +16 -0
  17. package/dist/lib/neutral/NavTreePlugin.workerd.mjs.map +7 -0
  18. package/dist/lib/{browser/app-graph-builder-XGA4GPGL.mjs → neutral/app-graph-builder-Z347LKSF.mjs} +10 -12
  19. package/dist/lib/neutral/app-graph-builder-Z347LKSF.mjs.map +7 -0
  20. package/dist/lib/neutral/capabilities/index.mjs +17 -0
  21. package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
  22. package/dist/lib/neutral/chunk-5OPDKH6B.mjs +273 -0
  23. package/dist/lib/neutral/chunk-5OPDKH6B.mjs.map +7 -0
  24. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
  25. package/dist/lib/neutral/chunk-J5LGTIGS.mjs.map +7 -0
  26. package/dist/lib/neutral/chunk-JOSNCOV4.mjs +79 -0
  27. package/dist/lib/neutral/chunk-JOSNCOV4.mjs.map +7 -0
  28. package/dist/lib/neutral/chunk-MDGKDQMZ.mjs +37 -0
  29. package/dist/lib/neutral/chunk-MDGKDQMZ.mjs.map +7 -0
  30. package/dist/lib/neutral/chunk-T7QS2EFI.mjs +8 -0
  31. package/dist/lib/neutral/chunk-T7QS2EFI.mjs.map +7 -0
  32. package/dist/lib/neutral/chunk-ZSWYB7JW.mjs +27 -0
  33. package/dist/lib/neutral/chunk-ZSWYB7JW.mjs.map +7 -0
  34. package/dist/lib/neutral/components/index.mjs +807 -0
  35. package/dist/lib/neutral/components/index.mjs.map +7 -0
  36. package/dist/lib/neutral/containers/index.mjs +20 -0
  37. package/dist/lib/neutral/containers/index.mjs.map +7 -0
  38. package/dist/lib/neutral/expose-26FV4W5D.mjs +38 -0
  39. package/dist/lib/neutral/expose-26FV4W5D.mjs.map +7 -0
  40. package/dist/lib/neutral/hooks/index.mjs +178 -0
  41. package/dist/lib/neutral/hooks/index.mjs.map +7 -0
  42. package/dist/lib/neutral/index.mjs +34 -0
  43. package/dist/lib/neutral/index.mjs.map +7 -0
  44. package/dist/lib/{browser/keyboard-OJZC54PK.mjs → neutral/keyboard-EJ65BVTC.mjs} +8 -6
  45. package/dist/lib/neutral/keyboard-EJ65BVTC.mjs.map +7 -0
  46. package/dist/lib/neutral/meta.json +1 -0
  47. package/dist/lib/neutral/meta.mjs +12 -0
  48. package/dist/lib/neutral/meta.mjs.map +7 -0
  49. package/dist/lib/neutral/operation-handler-ORDOJUL2.mjs +13 -0
  50. package/dist/lib/neutral/operation-handler-ORDOJUL2.mjs.map +7 -0
  51. package/dist/lib/neutral/operations/index.mjs +8 -0
  52. package/dist/lib/neutral/operations/index.mjs.map +7 -0
  53. package/dist/lib/neutral/plugin.mjs +16 -0
  54. package/dist/lib/neutral/plugin.mjs.map +7 -0
  55. package/dist/lib/{browser/react-surface-AYHOAJ4I.mjs → neutral/react-surface-Q5XMAG7Z.mjs} +11 -20
  56. package/dist/lib/neutral/react-surface-Q5XMAG7Z.mjs.map +7 -0
  57. package/dist/lib/{browser/state-AC3EETN7.mjs → neutral/state-VVITVXWM.mjs} +7 -11
  58. package/dist/lib/neutral/state-VVITVXWM.mjs.map +7 -0
  59. package/dist/lib/neutral/testing/index.mjs +439 -0
  60. package/dist/lib/neutral/testing/index.mjs.map +7 -0
  61. package/dist/lib/neutral/translations.mjs +23 -0
  62. package/dist/lib/neutral/translations.mjs.map +7 -0
  63. package/dist/lib/neutral/types/index.mjs +10 -0
  64. package/dist/lib/neutral/types/index.mjs.map +7 -0
  65. package/dist/types/src/NavTreePlugin.d.ts +1 -0
  66. package/dist/types/src/NavTreePlugin.d.ts.map +1 -1
  67. package/dist/types/src/NavTreePlugin.node.d.ts +4 -0
  68. package/dist/types/src/NavTreePlugin.node.d.ts.map +1 -0
  69. package/dist/types/src/NavTreePlugin.test.d.ts +2 -0
  70. package/dist/types/src/NavTreePlugin.test.d.ts.map +1 -0
  71. package/dist/types/src/NavTreePlugin.workerd.d.ts +4 -0
  72. package/dist/types/src/NavTreePlugin.workerd.d.ts.map +1 -0
  73. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
  74. package/dist/types/src/capabilities/index.d.ts +7 -5
  75. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  76. package/dist/types/src/capabilities/keyboard.d.ts.map +1 -0
  77. package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
  78. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
  79. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
  80. package/dist/types/src/capabilities/state.d.ts +6 -0
  81. package/dist/types/src/capabilities/state.d.ts.map +1 -0
  82. package/dist/types/src/components/NavTree/NavTree.d.ts.map +1 -1
  83. package/dist/types/src/components/NavTree/NavTree.stories.d.ts +9 -11
  84. package/dist/types/src/components/NavTree/NavTree.stories.d.ts.map +1 -1
  85. package/dist/types/src/components/{NavTreeContext.d.ts → NavTreeContext/NavTreeContext.d.ts} +1 -1
  86. package/dist/types/src/components/NavTreeContext/NavTreeContext.d.ts.map +1 -0
  87. package/dist/types/src/components/NavTreeContext/index.d.ts +2 -0
  88. package/dist/types/src/components/NavTreeContext/index.d.ts.map +1 -0
  89. package/dist/types/src/components/NavTreeItem/NavTreeItemAction.d.ts +7 -3
  90. package/dist/types/src/components/NavTreeItem/NavTreeItemAction.d.ts.map +1 -1
  91. package/dist/types/src/components/NavTreeItem/NavTreeItemAction.stories.d.ts +1 -1
  92. package/dist/types/src/components/NavTreeItem/NavTreeItemAction.stories.d.ts.map +1 -1
  93. package/dist/types/src/components/NavTreeItem/NavTreeItemColumns.d.ts.map +1 -1
  94. package/dist/types/src/components/Sidebar/L0Menu.d.ts.map +1 -1
  95. package/dist/types/src/components/Sidebar/L1Panel.d.ts.map +1 -1
  96. package/dist/types/src/components/Sidebar/L1Tabs.d.ts.map +1 -1
  97. package/dist/types/src/components/UserAccountAvatar/UserAccountAvatar.d.ts.map +1 -1
  98. package/dist/types/src/components/UserAccountAvatar/UserAccountAvatar.stories.d.ts.map +1 -1
  99. package/dist/types/src/components/types.d.ts +1 -2
  100. package/dist/types/src/components/types.d.ts.map +1 -1
  101. package/dist/types/src/containers/CommandsDialogContent/CommandsDialogContent.d.ts.map +1 -1
  102. package/dist/types/src/containers/CommandsDialogContent/CommandsDialogContent.stories.d.ts +28 -0
  103. package/dist/types/src/containers/CommandsDialogContent/CommandsDialogContent.stories.d.ts.map +1 -0
  104. package/dist/types/src/containers/CommandsDialogContent/index.d.ts +1 -2
  105. package/dist/types/src/containers/CommandsDialogContent/index.d.ts.map +1 -1
  106. package/dist/types/src/containers/CommandsTrigger/CommandsTrigger.d.ts.map +1 -1
  107. package/dist/types/src/containers/CommandsTrigger/index.d.ts +1 -2
  108. package/dist/types/src/containers/CommandsTrigger/index.d.ts.map +1 -1
  109. package/dist/types/src/containers/NavTreeContainer/NavTreeContainer.d.ts.map +1 -1
  110. package/dist/types/src/containers/NavTreeContainer/index.d.ts +2 -2
  111. package/dist/types/src/containers/NavTreeContainer/index.d.ts.map +1 -1
  112. package/dist/types/src/containers/NavTreeDocumentTitle/NavTreeDocumentTitle.d.ts.map +1 -1
  113. package/dist/types/src/containers/NavTreeDocumentTitle/index.d.ts +1 -2
  114. package/dist/types/src/containers/NavTreeDocumentTitle/index.d.ts.map +1 -1
  115. package/dist/types/src/containers/index.d.ts +1 -1
  116. package/dist/types/src/containers/index.d.ts.map +1 -1
  117. package/dist/types/src/experimental/Tree.d.ts +2 -2
  118. package/dist/types/src/experimental/Tree.d.ts.map +1 -1
  119. package/dist/types/src/experimental/Tree.stories.d.ts.map +1 -1
  120. package/dist/types/src/hooks/useActions.d.ts +6 -2
  121. package/dist/types/src/hooks/useActions.d.ts.map +1 -1
  122. package/dist/types/src/hooks/useLoadDescendents.d.ts.map +1 -1
  123. package/dist/types/src/hooks/useNavTreeModel.d.ts +1 -1
  124. package/dist/types/src/hooks/useNavTreeModel.d.ts.map +1 -1
  125. package/dist/types/src/hooks/useNavTreeState.d.ts +2 -6
  126. package/dist/types/src/hooks/useNavTreeState.d.ts.map +1 -1
  127. package/dist/types/src/index.d.ts +1 -2
  128. package/dist/types/src/index.d.ts.map +1 -1
  129. package/dist/types/src/meta.d.ts +3 -2
  130. package/dist/types/src/meta.d.ts.map +1 -1
  131. package/dist/types/src/operations/expose.d.ts +5 -0
  132. package/dist/types/src/operations/expose.d.ts.map +1 -0
  133. package/dist/types/src/operations/index.d.ts +3 -0
  134. package/dist/types/src/operations/index.d.ts.map +1 -0
  135. package/dist/types/src/plugin.d.ts +4 -0
  136. package/dist/types/src/plugin.d.ts.map +1 -0
  137. package/dist/types/src/testing/app-graph-builder.d.ts.map +1 -1
  138. package/dist/types/src/testing/generator.d.ts.map +1 -1
  139. package/dist/types/src/testing/update-state.d.ts.map +1 -1
  140. package/dist/types/src/translations.d.ts +8 -11
  141. package/dist/types/src/translations.d.ts.map +1 -1
  142. package/dist/types/src/types/NavTreeCapabilities.d.ts +13 -0
  143. package/dist/types/src/types/NavTreeCapabilities.d.ts.map +1 -0
  144. package/dist/types/src/types/NavTreeEvents.d.ts +3 -0
  145. package/dist/types/src/types/NavTreeEvents.d.ts.map +1 -0
  146. package/dist/types/src/types/index.d.ts +2 -2
  147. package/dist/types/src/types/index.d.ts.map +1 -1
  148. package/dist/types/src/types/schema.d.ts +4 -0
  149. package/dist/types/src/types/schema.d.ts.map +1 -1
  150. package/dist/types/src/util.d.ts +2 -2
  151. package/dist/types/src/util.d.ts.map +1 -1
  152. package/dist/types/tsconfig.tsbuildinfo +1 -1
  153. package/package.json +110 -50
  154. package/src/NavTreePlugin.node.ts +17 -0
  155. package/src/NavTreePlugin.test.ts +27 -0
  156. package/src/NavTreePlugin.tsx +16 -27
  157. package/src/NavTreePlugin.workerd.ts +16 -0
  158. package/src/capabilities/{app-graph-builder/app-graph-builder.ts → app-graph-builder.ts} +7 -7
  159. package/src/capabilities/index.ts +11 -5
  160. package/src/capabilities/{keyboard/keyboard.ts → keyboard.ts} +2 -2
  161. package/src/capabilities/operation-handler.ts +16 -0
  162. package/src/capabilities/{react-surface/react-surface.tsx → react-surface.tsx} +9 -9
  163. package/src/capabilities/{state/state.ts → state.ts} +14 -10
  164. package/src/components/NavTree/NavTree.stories.tsx +23 -24
  165. package/src/components/NavTree/NavTree.tsx +5 -4
  166. package/src/components/{NavTreeContext.tsx → NavTreeContext/NavTreeContext.tsx} +1 -1
  167. package/src/components/NavTreeContext/index.ts +5 -0
  168. package/src/components/NavTreeItem/NavTreeItemAction.stories.tsx +8 -10
  169. package/src/components/NavTreeItem/NavTreeItemAction.tsx +66 -48
  170. package/src/components/NavTreeItem/NavTreeItemColumns.tsx +22 -63
  171. package/src/components/Sidebar/L0Menu.tsx +62 -81
  172. package/src/components/Sidebar/L1Panel.tsx +99 -158
  173. package/src/components/Sidebar/L1Tabs.tsx +0 -1
  174. package/src/components/types.ts +1 -2
  175. package/src/containers/CommandsDialogContent/CommandsDialogContent.stories.tsx +46 -0
  176. package/src/containers/CommandsDialogContent/CommandsDialogContent.tsx +52 -58
  177. package/src/containers/CommandsDialogContent/index.ts +1 -3
  178. package/src/containers/CommandsTrigger/CommandsTrigger.tsx +7 -5
  179. package/src/containers/CommandsTrigger/index.ts +1 -3
  180. package/src/containers/NavTreeContainer/NavTreeContainer.tsx +28 -27
  181. package/src/containers/NavTreeContainer/index.ts +2 -3
  182. package/src/containers/NavTreeDocumentTitle/NavTreeDocumentTitle.tsx +2 -2
  183. package/src/containers/NavTreeDocumentTitle/index.ts +1 -3
  184. package/src/containers/index.ts +1 -1
  185. package/src/experimental/Tree.stories.tsx +27 -27
  186. package/src/experimental/Tree.tsx +2 -2
  187. package/src/hooks/useActions.ts +26 -20
  188. package/src/hooks/useNavTreeModel.ts +13 -5
  189. package/src/hooks/useNavTreeState.ts +2 -9
  190. package/src/index.ts +1 -2
  191. package/src/meta.ts +22 -7
  192. package/src/operations/expose.ts +42 -0
  193. package/src/operations/index.ts +7 -0
  194. package/src/plugin.ts +11 -0
  195. package/src/testing/app-graph-builder.ts +47 -41
  196. package/src/testing/generator.ts +23 -28
  197. package/src/translations.ts +8 -10
  198. package/src/types/NavTreeCapabilities.ts +21 -0
  199. package/src/types/NavTreeEvents.ts +12 -0
  200. package/src/types/index.ts +3 -2
  201. package/src/types/schema.ts +4 -0
  202. package/src/util.ts +2 -2
  203. package/src/vite-env.d.ts +10 -0
  204. package/dist/lib/browser/CommandsDialogContent-A27AKTHH.mjs.map +0 -7
  205. package/dist/lib/browser/CommandsTrigger-HBZYQCGV.mjs.map +0 -7
  206. package/dist/lib/browser/NavTreeContainer-B5K4FUJS.mjs +0 -12
  207. package/dist/lib/browser/NavTreeContainer-B5K4FUJS.mjs.map +0 -7
  208. package/dist/lib/browser/NavTreeDocumentTitle-GEE3URWH.mjs.map +0 -7
  209. package/dist/lib/browser/app-graph-builder-XGA4GPGL.mjs.map +0 -7
  210. package/dist/lib/browser/chunk-DQCYMXEU.mjs +0 -1426
  211. package/dist/lib/browser/chunk-DQCYMXEU.mjs.map +0 -7
  212. package/dist/lib/browser/chunk-H3OJ4WLF.mjs +0 -14
  213. package/dist/lib/browser/chunk-H3OJ4WLF.mjs.map +0 -7
  214. package/dist/lib/browser/chunk-X2HDG62A.mjs +0 -23
  215. package/dist/lib/browser/chunk-X2HDG62A.mjs.map +0 -7
  216. package/dist/lib/browser/chunk-YKTYPINZ.mjs +0 -19
  217. package/dist/lib/browser/chunk-YKTYPINZ.mjs.map +0 -7
  218. package/dist/lib/browser/index.mjs +0 -141
  219. package/dist/lib/browser/index.mjs.map +0 -7
  220. package/dist/lib/browser/keyboard-OJZC54PK.mjs.map +0 -7
  221. package/dist/lib/browser/meta.json +0 -1
  222. package/dist/lib/browser/operation-resolver-BNAMYOHF.mjs +0 -53
  223. package/dist/lib/browser/operation-resolver-BNAMYOHF.mjs.map +0 -7
  224. package/dist/lib/browser/react-surface-AYHOAJ4I.mjs.map +0 -7
  225. package/dist/lib/browser/state-AC3EETN7.mjs.map +0 -7
  226. package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts.map +0 -1
  227. package/dist/types/src/capabilities/app-graph-builder/index.d.ts +0 -3
  228. package/dist/types/src/capabilities/app-graph-builder/index.d.ts.map +0 -1
  229. package/dist/types/src/capabilities/keyboard/index.d.ts +0 -3
  230. package/dist/types/src/capabilities/keyboard/index.d.ts.map +0 -1
  231. package/dist/types/src/capabilities/keyboard/keyboard.d.ts.map +0 -1
  232. package/dist/types/src/capabilities/operation-resolver/index.d.ts +0 -3
  233. package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +0 -1
  234. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +0 -5
  235. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +0 -1
  236. package/dist/types/src/capabilities/react-surface/index.d.ts +0 -3
  237. package/dist/types/src/capabilities/react-surface/index.d.ts.map +0 -1
  238. package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +0 -1
  239. package/dist/types/src/capabilities/state/index.d.ts +0 -3
  240. package/dist/types/src/capabilities/state/index.d.ts.map +0 -1
  241. package/dist/types/src/capabilities/state/state.d.ts +0 -6
  242. package/dist/types/src/capabilities/state/state.d.ts.map +0 -1
  243. package/dist/types/src/components/NavTreeContext.d.ts.map +0 -1
  244. package/dist/types/src/types/capabilities.d.ts +0 -16
  245. package/dist/types/src/types/capabilities.d.ts.map +0 -1
  246. package/dist/types/src/types/events.d.ts +0 -5
  247. package/dist/types/src/types/events.d.ts.map +0 -1
  248. package/src/capabilities/app-graph-builder/index.ts +0 -7
  249. package/src/capabilities/keyboard/index.ts +0 -7
  250. package/src/capabilities/operation-resolver/index.ts +0 -7
  251. package/src/capabilities/operation-resolver/operation-resolver.ts +0 -44
  252. package/src/capabilities/react-surface/index.ts +0 -7
  253. package/src/capabilities/state/index.ts +0 -7
  254. package/src/types/capabilities.ts +0 -21
  255. package/src/types/events.ts +0 -12
  256. /package/dist/types/src/capabilities/{app-graph-builder/app-graph-builder.d.ts → app-graph-builder.d.ts} +0 -0
  257. /package/dist/types/src/capabilities/{keyboard/keyboard.d.ts → keyboard.d.ts} +0 -0
  258. /package/dist/types/src/capabilities/{react-surface/react-surface.d.ts → react-surface.d.ts} +0 -0
@@ -0,0 +1,46 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+ import React from 'react';
7
+
8
+ import { withPluginManager } from '@dxos/app-framework/testing';
9
+ import { StorybookPlugin, corePlugins } from '@dxos/plugin-testing';
10
+ import { Dialog } from '@dxos/react-ui';
11
+ import { withLayout } from '@dxos/react-ui/testing';
12
+
13
+ import { translations } from '#translations';
14
+
15
+ import { NavTreePlugin } from '../../NavTreePlugin';
16
+ import { CommandsDialogContent } from './CommandsDialogContent';
17
+
18
+ const DefaultStory = () => (
19
+ <Dialog.Root defaultOpen>
20
+ <Dialog.Overlay>
21
+ <CommandsDialogContent />
22
+ </Dialog.Overlay>
23
+ </Dialog.Root>
24
+ );
25
+
26
+ const meta = {
27
+ title: 'plugins/plugin-navtree/containers/CommandsDialogContent',
28
+ component: CommandsDialogContent,
29
+ render: DefaultStory,
30
+ decorators: [
31
+ withLayout({ layout: 'fullscreen' }),
32
+ withPluginManager({
33
+ plugins: [...corePlugins(), StorybookPlugin({}), NavTreePlugin()],
34
+ }),
35
+ ],
36
+ parameters: {
37
+ layout: 'fullscreen',
38
+ translations,
39
+ },
40
+ } satisfies Meta<typeof CommandsDialogContent>;
41
+
42
+ export default meta;
43
+
44
+ type Story = StoryObj<typeof meta>;
45
+
46
+ export const Default: Story = {};
@@ -11,11 +11,11 @@ import { Keyboard, keySymbols } from '@dxos/keyboard';
11
11
  import { Graph, Node, useActionRunner } from '@dxos/plugin-graph';
12
12
  import { useActions } from '@dxos/plugin-graph';
13
13
  import { Button, Dialog, toLocalizedString, useTranslation } from '@dxos/react-ui';
14
- import { SearchList, useSearchListResults } from '@dxos/react-ui-searchlist';
14
+ import { SearchList, useSearchListResults } from '@dxos/react-ui-search';
15
15
  import { osTranslations } from '@dxos/ui-theme';
16
16
  import { getHostPlatform } from '@dxos/util';
17
17
 
18
- import { KEY_BINDING, meta } from '../../meta';
18
+ import { KEY_BINDING, meta } from '#meta';
19
19
 
20
20
  export type CommandsDialogContentProps = {
21
21
  selected?: string;
@@ -25,7 +25,7 @@ export type CommandsDialogContentProps = {
25
25
  export const CommandsDialogContent = forwardRef<HTMLDivElement, CommandsDialogContentProps>(
26
26
  ({ selected: initial }, forwardedRef) => {
27
27
  const { t } = useTranslation(meta.id);
28
- const { invokeSync } = useOperationInvoker();
28
+ const { invokePromise } = useOperationInvoker();
29
29
  const runAction = useActionRunner();
30
30
  const { graph } = useAppGraph();
31
31
  const [selected, setSelected] = useState<string | undefined>(initial);
@@ -38,13 +38,12 @@ export const CommandsDialogContent = forwardRef<HTMLDivElement, CommandsDialogCo
38
38
  const actionMap = new Set<string>();
39
39
  const actions: Node.ActionLike[] = [];
40
40
  Graph.traverse(graph, {
41
- relation: 'child',
41
+ relation: ['child', 'action'],
42
42
  visitor: (node, path) => {
43
- if (
44
- (Node.isAction(node) || Node.isActionGroup(node)) &&
45
- !actionMap.has(node.id) &&
46
- current.startsWith(path.slice(0, -1).join('/'))
47
- ) {
43
+ const isActionLike = Node.isAction(node) || Node.isActionGroup(node);
44
+ const parentId = path.at(-2) ?? '';
45
+ const matches = current === parentId || current.startsWith(parentId + '/');
46
+ if (isActionLike && !actionMap.has(node.id) && matches) {
48
47
  actionMap.add(node.id);
49
48
  actions.push(node);
50
49
  }
@@ -71,62 +70,57 @@ export const CommandsDialogContent = forwardRef<HTMLDivElement, CommandsDialogCo
71
70
 
72
71
  return (
73
72
  <Dialog.Content ref={forwardedRef}>
74
- <Dialog.Title>{t('commands dialog title', { ns: meta.id })}</Dialog.Title>
73
+ <Dialog.Title srOnly>{t('commands-dialog.title', { ns: meta.id })}</Dialog.Title>
75
74
  <SearchList.Root onSearch={handleSearch}>
76
- <SearchList.Content>
77
- <SearchList.Input placeholder={t('command list input placeholder')} />
78
- <SearchList.Viewport>
79
- {results.map((action) => {
80
- const shortcut =
81
- typeof action.properties.keyBinding === 'string'
82
- ? action.properties.keyBinding
83
- : action.properties.keyBinding?.[getHostPlatform()];
75
+ <SearchList.Input placeholder={t('command-list-input.placeholder')} />
76
+ <SearchList.Viewport>
77
+ {results.map((action) => {
78
+ const shortcut =
79
+ typeof action.properties.keyBinding === 'string'
80
+ ? action.properties.keyBinding
81
+ : action.properties.keyBinding?.[getHostPlatform()];
84
82
 
85
- return (
86
- <SearchList.Item
87
- value={action.id}
88
- key={action.id}
89
- label={toLocalizedString(action.properties.label, t)}
90
- icon={action.properties.icon}
91
- suffix={shortcut ? keySymbols(shortcut).join('') : undefined}
92
- onSelect={() => {
93
- if (action.properties.disabled) {
94
- return;
95
- }
83
+ return (
84
+ <SearchList.Item
85
+ value={action.id}
86
+ key={action.id}
87
+ label={toLocalizedString(action.properties.label, t)}
88
+ icon={action.properties.icon}
89
+ suffix={shortcut ? keySymbols(shortcut).join('') : undefined}
90
+ onSelect={() => {
91
+ if (action.properties.disabled) {
92
+ return;
93
+ }
96
94
 
97
- if (Node.isActionGroup(action)) {
98
- setSelected(action.id);
99
- return;
100
- }
95
+ if (Node.isActionGroup(action)) {
96
+ setSelected(action.id);
97
+ return;
98
+ }
101
99
 
102
- invokeSync(LayoutOperation.UpdateDialog, { state: false });
103
- setTimeout(() => {
104
- const node = Graph.getConnections(
105
- graph,
106
- group?.id ?? action.id,
107
- Node.childRelation('inbound'),
108
- )[0];
109
- if (node && Node.isAction(action)) {
110
- void runAction(action, { parent: node, caller: KEY_BINDING });
111
- }
112
- });
113
- }}
114
- classNames='flex items-center gap-2'
115
- disabled={action.properties.disabled}
116
- {...(action.properties?.testId && {
117
- 'data-testid': action.properties.testId,
118
- })}
119
- />
120
- );
121
- })}
122
- </SearchList.Viewport>
123
- </SearchList.Content>
100
+ void invokePromise(LayoutOperation.UpdateDialog, { state: false });
101
+ setTimeout(() => {
102
+ const lookupId = group?.id ?? action.id;
103
+ const node = Graph.getConnections(graph, lookupId, Node.actionRelation('inbound'))[0];
104
+ if (node && Node.isAction(action)) {
105
+ void runAction(action, { parent: node, caller: KEY_BINDING });
106
+ }
107
+ });
108
+ }}
109
+ classNames='flex items-center gap-2'
110
+ disabled={action.properties.disabled}
111
+ {...(action.properties?.testId && {
112
+ 'data-testid': action.properties.testId,
113
+ })}
114
+ />
115
+ );
116
+ })}
117
+ </SearchList.Viewport>
124
118
  </SearchList.Root>
125
- <div role='none' className='p-form-padding'>
119
+ <Dialog.ActionBar>
126
120
  <Dialog.Close asChild>
127
- <Button classNames='w-full'>{t('close label', { ns: osTranslations })}</Button>
121
+ <Button classNames='w-full'>{t('close.label', { ns: osTranslations })}</Button>
128
122
  </Dialog.Close>
129
- </div>
123
+ </Dialog.ActionBar>
130
124
  </Dialog.Content>
131
125
  );
132
126
  },
@@ -2,6 +2,4 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { CommandsDialogContent } from './CommandsDialogContent';
6
-
7
- export default CommandsDialogContent;
5
+ export { CommandsDialogContent as default } from './CommandsDialogContent';
@@ -8,19 +8,21 @@ import { useOperationInvoker } from '@dxos/app-framework/ui';
8
8
  import { LayoutOperation } from '@dxos/app-toolkit';
9
9
  import { Button, Icon, useTranslation } from '@dxos/react-ui';
10
10
 
11
- import { COMMANDS_DIALOG, meta } from '../../meta';
11
+ import { COMMANDS_DIALOG, meta } from '#meta';
12
12
 
13
13
  // TODO(thure): Refactor to be handled by a more appropriate plugin.
14
14
  export const CommandsTrigger = () => {
15
- const { invokeSync } = useOperationInvoker();
15
+ const { invokePromise } = useOperationInvoker();
16
16
  const { t } = useTranslation(meta.id);
17
17
  return (
18
18
  <Button
19
19
  classNames='m-1 px-1 lg:px-2'
20
- onClick={() => invokeSync(LayoutOperation.UpdateDialog, { subject: COMMANDS_DIALOG, blockAlign: 'start' })}
20
+ onClick={() =>
21
+ void invokePromise(LayoutOperation.UpdateDialog, { subject: COMMANDS_DIALOG, blockAlign: 'start' })
22
+ }
21
23
  >
22
- <span className='text-description font-normal grow text-start'>{t('command list input placeholder')}</span>
23
- <Icon icon='ph--magnifying-glass--regular' size={5} />
24
+ <span className='text-description font-normal grow text-start'>{t('command-list-input.placeholder')}</span>
25
+ <Icon icon='ph--magnifying-glass--regular' />
24
26
  </Button>
25
27
  );
26
28
  };
@@ -2,6 +2,4 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { CommandsTrigger } from './CommandsTrigger';
6
-
7
- export default CommandsTrigger;
5
+ export { CommandsTrigger as default } from './CommandsTrigger';
@@ -2,8 +2,8 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
6
5
  import { type Instruction, extractInstruction } from '@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item';
6
+ import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
7
7
  import React, { forwardRef, memo, useCallback, useEffect, useMemo, useRef } from 'react';
8
8
 
9
9
  import { Surface, useOperationInvoker } from '@dxos/app-framework/ui';
@@ -14,10 +14,11 @@ import { useMediaQuery, useSidebars } from '@dxos/react-ui';
14
14
  import { type TreeData, isTreeData } from '@dxos/react-ui-list';
15
15
  import { arrayMove } from '@dxos/util';
16
16
 
17
- import { NAV_TREE_ITEM, NavTree, NavTreeContext } from '../../components';
18
- import { useNavTreeModel, useNavTreeState } from '../../hooks';
19
- import { meta } from '../../meta';
20
- import { type NavTreeItemGraphNode } from '../../types';
17
+ import { NAV_TREE_ITEM, NavTree, NavTreeContext } from '#components';
18
+ import { useNavTreeModel, useNavTreeState } from '#hooks';
19
+ import { meta } from '#meta';
20
+ import { type NavTreeItemGraphNode } from '#types';
21
+
21
22
  import { filterItems, getParent, resolveMigrationOperation } from '../../util';
22
23
 
23
24
  // TODO(thure): Is NavTree truly authoritative in this regard?
@@ -41,7 +42,7 @@ export type NavTreeContainerProps = {
41
42
  export const NavTreeContainer$ = forwardRef<HTMLDivElement, NavTreeContainerProps>(
42
43
  ({ tab, popoverAnchorId }, forwardedRef) => {
43
44
  const [isLg] = useMediaQuery('lg');
44
- const { invokeSync, invokePromise } = useOperationInvoker();
45
+ const { invokePromise } = useOperationInvoker();
45
46
  const runAction = useActionRunner();
46
47
  const { graph } = useAppGraph();
47
48
  const { getItem, setItem } = useNavTreeState();
@@ -83,7 +84,7 @@ export const NavTreeContainer$ = forwardRef<HTMLDivElement, NavTreeContainerProp
83
84
  navigationSidebarState: currentSidebarState,
84
85
  isLg: latestIsLg,
85
86
  } = latestRef.current;
86
- invokeSync(LayoutOperation.UpdateSidebar, {
87
+ void invokePromise(LayoutOperation.UpdateSidebar, {
87
88
  state:
88
89
  node.id === activeTab
89
90
  ? currentSidebarState === 'expanded'
@@ -94,17 +95,21 @@ export const NavTreeContainer$ = forwardRef<HTMLDivElement, NavTreeContainerProp
94
95
  : 'expanded',
95
96
  });
96
97
 
97
- invokeSync(LayoutOperation.SwitchWorkspace, { subject: node.id });
98
+ void invokePromise(LayoutOperation.SwitchWorkspace, { subject: node.id });
98
99
 
99
100
  // Open the first item if the workspace is empty.
100
101
  if (activeItems.length === 0) {
101
102
  const [item] = getItems(graph, node).filter((node) => !Node.isActionLike(node));
102
103
  if (item && item.data) {
103
- invokeSync(LayoutOperation.Open, { subject: [item.id] });
104
+ if (layout.mode === 'multi') {
105
+ void invokePromise(LayoutOperation.Set, { subject: [item.id] });
106
+ } else {
107
+ void invokePromise(LayoutOperation.Open, { subject: [item.id] });
108
+ }
104
109
  }
105
110
  }
106
111
  },
107
- [invokeSync, graph],
112
+ [invokePromise, graph, layout.mode],
108
113
  );
109
114
 
110
115
  const blockInstruction = useCallback(
@@ -131,16 +136,20 @@ export const NavTreeContainer$ = forwardRef<HTMLDivElement, NavTreeContainerProp
131
136
  if (Node.isAction(node)) {
132
137
  const [parent] = Graph.getConnections(graph, node.id, Node.childRelation('inbound'));
133
138
  if (parent) {
134
- void runAction(node, { parent, caller: NAV_TREE_ITEM });
139
+ void runAction(node, { parent, path, caller: NAV_TREE_ITEM });
135
140
  }
136
141
  return;
137
142
  }
138
143
 
139
144
  const current = getItem(path).current;
140
145
  if (!current) {
141
- invokeSync(LayoutOperation.Open, { subject: [node.id], key: node.properties.key });
146
+ if (layout.mode === 'multi') {
147
+ void invokePromise(LayoutOperation.Set, { subject: [node.id] });
148
+ } else {
149
+ void invokePromise(LayoutOperation.Open, { subject: [node.id], key: node.properties.key });
150
+ }
142
151
  } else if (option) {
143
- invokeSync(LayoutOperation.Close, { subject: [node.id] });
152
+ void invokePromise(LayoutOperation.Close, { subject: [node.id] });
144
153
  } else {
145
154
  void invokePromise(LayoutOperation.ScrollIntoView, { subject: node.id });
146
155
  }
@@ -153,13 +162,13 @@ export const NavTreeContainer$ = forwardRef<HTMLDivElement, NavTreeContainerProp
153
162
  }
154
163
 
155
164
  if (!isLg) {
156
- invokeSync(LayoutOperation.UpdateSidebar, { state: 'closed' });
165
+ void invokePromise(LayoutOperation.UpdateSidebar, { state: 'closed' });
157
166
  }
158
167
  },
159
- [graph, invokeSync, invokePromise, getItem, runAction, isLg],
168
+ [graph, invokePromise, getItem, runAction, isLg, layout.mode],
160
169
  );
161
170
 
162
- const handleBack = useCallback(() => invokeSync(LayoutOperation.RevertWorkspace), [invokeSync]);
171
+ const handleBack = useCallback(() => void invokePromise(LayoutOperation.RevertWorkspace), [invokePromise]);
163
172
 
164
173
  // TODO(wittjosiah): Factor out hook.
165
174
  useEffect(() => {
@@ -177,8 +186,9 @@ export const NavTreeContainer$ = forwardRef<HTMLDivElement, NavTreeContainerProp
177
186
  const targetNode = target.data.item as NavTreeItemGraphNode;
178
187
  const sourcePath = source.data.path as string[];
179
188
  const targetPath = target.data.path as string[];
189
+ const sameParent = sourcePath.slice(0, -1).join() === targetPath.slice(0, -1).join();
180
190
  const operation =
181
- sourcePath.slice(0, -1).join() === targetPath.slice(0, -1).join() && instruction.type !== 'make-child'
191
+ sameParent && instruction.type !== 'make-child'
182
192
  ? 'rearrange'
183
193
  : resolveMigrationOperation(graph, sourceNode, targetPath, targetNode);
184
194
  const sourceParent = getParent(graph, sourceNode, sourcePath);
@@ -207,7 +217,7 @@ export const NavTreeContainer$ = forwardRef<HTMLDivElement, NavTreeContainerProp
207
217
  }
208
218
  case 'transfer': {
209
219
  const target = instruction.type === 'make-child' ? targetNode : targetParent;
210
- if (!target?.properties.onTransferStart || !sourceParent?.properties.onTransferEnd) {
220
+ if (!target?.properties.onTransferStart || target?.id === sourceParent?.id) {
211
221
  break;
212
222
  }
213
223
  void target?.properties.onTransferStart(sourceNode, migrationIndex);
@@ -220,13 +230,6 @@ export const NavTreeContainer$ = forwardRef<HTMLDivElement, NavTreeContainerProp
220
230
  });
221
231
  }, [graph]);
222
232
 
223
- const setAlternateTree = useCallback(
224
- (path: string[], open: boolean) => {
225
- setItem(path, 'alternateTree', open);
226
- },
227
- [setItem],
228
- );
229
-
230
233
  const onItemHover = useCallback(({ item }: { item: Node.Node }) => Graph.expand(graph, item.id, 'child'), [graph]);
231
234
 
232
235
  const navTreeContextValue = useMemo(
@@ -237,7 +240,6 @@ export const NavTreeContainer$ = forwardRef<HTMLDivElement, NavTreeContainerProp
237
240
  blockInstruction,
238
241
  canDrop,
239
242
  canSelect,
240
- setAlternateTree,
241
243
  onBack: handleBack,
242
244
  onOpenChange: handleOpenChange,
243
245
  onSelect: handleSelect,
@@ -250,7 +252,6 @@ export const NavTreeContainer$ = forwardRef<HTMLDivElement, NavTreeContainerProp
250
252
  blockInstruction,
251
253
  canDrop,
252
254
  canSelect,
253
- setAlternateTree,
254
255
  handleBack,
255
256
  handleOpenChange,
256
257
  handleSelect,
@@ -2,6 +2,5 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { NavTreeContainer } from './NavTreeContainer';
6
-
7
- export default NavTreeContainer;
5
+ export { NavTreeContainer, NODE_TYPE } from './NavTreeContainer';
6
+ export { NavTreeContainer as default } from './NavTreeContainer';
@@ -7,12 +7,12 @@ import { type Node } from '@dxos/app-graph';
7
7
  import { toLocalizedString, useTranslation } from '@dxos/react-ui';
8
8
  import { osTranslations } from '@dxos/ui-theme';
9
9
 
10
- import { meta } from '../../meta';
10
+ import { meta } from '#meta';
11
11
 
12
12
  export const NavTreeDocumentTitle = ({ node }: { node?: Node.Node }) => {
13
13
  const { t } = useTranslation(meta.id);
14
14
  useEffect(() => {
15
- document.title = node ? toLocalizedString(node.properties.label, t) : t('current app name', { ns: osTranslations });
15
+ document.title = node ? toLocalizedString(node.properties.label, t) : t('current-app.name', { ns: osTranslations });
16
16
  }, [node?.properties?.label]);
17
17
  return null;
18
18
  };
@@ -2,6 +2,4 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { NavTreeDocumentTitle } from './NavTreeDocumentTitle';
6
-
7
- export default NavTreeDocumentTitle;
5
+ export { NavTreeDocumentTitle as default } from './NavTreeDocumentTitle';
@@ -4,7 +4,7 @@
4
4
 
5
5
  import { type ComponentType, lazy } from 'react';
6
6
 
7
- export { NODE_TYPE } from './NavTreeContainer/NavTreeContainer';
7
+ export { NODE_TYPE } from './NavTreeContainer';
8
8
 
9
9
  export const CommandsDialogContent: ComponentType<any> = lazy(() => import('./CommandsDialogContent'));
10
10
  export const CommandsTrigger: ComponentType<any> = lazy(() => import('./CommandsTrigger'));
@@ -5,14 +5,14 @@
5
5
  import { type Meta } from '@storybook/react-vite';
6
6
  import React, { useEffect, useState } from 'react';
7
7
 
8
- import { faker } from '@dxos/random';
8
+ import { random } from '@dxos/random';
9
9
  import { Icon, IconButton, Panel, ScrollArea } from '@dxos/react-ui';
10
10
  import { withLayout, withTheme } from '@dxos/react-ui/testing';
11
11
  import { mx } from '@dxos/ui-theme';
12
12
 
13
13
  import { type ItemMap, Tree, type TreeNodeData, type TreeProps, visitNodes, visitor } from './Tree';
14
14
 
15
- faker.seed(1234);
15
+ random.seed(1234);
16
16
 
17
17
  // TODO(burdon): Generate.
18
18
  const data: TreeNodeData[] = [
@@ -21,34 +21,34 @@ const data: TreeNodeData[] = [
21
21
  title: 'plugins/Root',
22
22
  children: [
23
23
  {
24
- id: faker.string.uuid(),
24
+ id: random.string.uuid(),
25
25
  title: 'plugins/Personal Space',
26
26
  color: 'text-green-400',
27
27
  iconName: 'ph--house--regular',
28
28
  children: [
29
29
  {
30
- id: faker.string.uuid(),
31
- title: faker.commerce.productName(),
30
+ id: random.string.uuid(),
31
+ title: random.commerce.productName(),
32
32
  },
33
33
  {
34
- id: faker.string.uuid(),
35
- title: faker.commerce.productName(),
34
+ id: random.string.uuid(),
35
+ title: random.commerce.productName(),
36
36
  },
37
37
  {
38
- id: faker.string.uuid(),
39
- title: faker.commerce.productName(),
38
+ id: random.string.uuid(),
39
+ title: random.commerce.productName(),
40
40
  children: [
41
41
  {
42
- id: faker.string.uuid(),
43
- title: faker.commerce.productName(),
42
+ id: random.string.uuid(),
43
+ title: random.commerce.productName(),
44
44
  children: [
45
45
  {
46
- id: faker.string.uuid(),
47
- title: faker.commerce.productName(),
46
+ id: random.string.uuid(),
47
+ title: random.commerce.productName(),
48
48
  },
49
49
  {
50
- id: faker.string.uuid(),
51
- title: faker.commerce.productName(),
50
+ id: random.string.uuid(),
51
+ title: random.commerce.productName(),
52
52
  },
53
53
  ],
54
54
  },
@@ -57,24 +57,24 @@ const data: TreeNodeData[] = [
57
57
  ],
58
58
  },
59
59
  {
60
- id: faker.string.uuid(),
61
- title: faker.commerce.productName(),
60
+ id: random.string.uuid(),
61
+ title: random.commerce.productName(),
62
62
  iconName: 'ph--planet--regular',
63
63
  children: [
64
64
  {
65
- id: faker.string.uuid(),
66
- title: faker.commerce.productName(),
65
+ id: random.string.uuid(),
66
+ title: random.commerce.productName(),
67
67
  },
68
68
  ],
69
69
  },
70
70
  {
71
- id: faker.string.uuid(),
72
- title: faker.commerce.productName(),
71
+ id: random.string.uuid(),
72
+ title: random.commerce.productName(),
73
73
  iconName: 'ph--sailboat--regular',
74
74
  },
75
75
  {
76
- id: faker.string.uuid(),
77
- title: faker.commerce.productName(),
76
+ id: random.string.uuid(),
77
+ title: random.commerce.productName(),
78
78
  iconName: 'ph--planet--regular',
79
79
  },
80
80
  ],
@@ -122,8 +122,8 @@ const Sidebar = ({ mutate }: { mutate?: boolean }) => {
122
122
  });
123
123
 
124
124
  (parent!.children ??= []).push({
125
- id: faker.string.uuid(),
126
- title: faker.commerce.productName(),
125
+ id: random.string.uuid(),
126
+ title: random.commerce.productName(),
127
127
  });
128
128
 
129
129
  setOpenItems((open) => ({ ...open, [parent!.id]: true }));
@@ -135,9 +135,9 @@ const Sidebar = ({ mutate }: { mutate?: boolean }) => {
135
135
  const handleCreateSpace = () => {
136
136
  setItems((items) => {
137
137
  items[0].children?.push({
138
- id: faker.string.uuid(),
138
+ id: random.string.uuid(),
139
139
  iconName: 'ph--planet--regular',
140
- title: faker.commerce.productName(),
140
+ title: random.commerce.productName(),
141
141
  });
142
142
 
143
143
  return { ...items };
@@ -195,7 +195,7 @@ export const TreeNodeRow = (props: TreeNodeProps & { className?: string }) => {
195
195
  className={mx(
196
196
  'group w-full items-center cursor-pointer bg-hover-surface',
197
197
  // TODO(burdon): Use data-active.
198
- selected?.[id] && 'bg-active-surface',
198
+ selected?.[id] && 'bg-current-surface',
199
199
  className,
200
200
  )}
201
201
  onClick={() => selected && onChangeSelected?.(id, !selected[id])}
@@ -220,7 +220,7 @@ export const TreeNode = (props: TreeNodeProps & { ancestors?: TreeNodeData[] })
220
220
  const { root, header } = getSlots?.(props.node, open?.[id] ?? false, depth, ancestors) ?? {};
221
221
 
222
222
  return (
223
- <div role='none' className={mx('flex flex-col', root)}>
223
+ <div className={mx('flex flex-col', root)}>
224
224
  <TreeNodeRow {...props} className={header} />
225
225
  {(children?.length ?? 0) > 0 && open?.[id] && <TreeChildNodes {...props} ancestors={ancestors} />}
226
226
  </div>
@@ -7,32 +7,38 @@ import { useMemo } from 'react';
7
7
  import { useAppGraph } from '@dxos/app-toolkit/ui';
8
8
  import { Graph, Node, useActions as useGraphActions } from '@dxos/plugin-graph';
9
9
 
10
- import { type FlattenedActions } from '../types';
10
+ import { type FlattenedActions } from '#types';
11
11
 
12
12
  /**
13
- * Returns flattened actions and grouped sub-actions for a given graph node.
13
+ * Flattens grouped actions and filters to the list-item dispositions rendered as
14
+ * navtree item actions. Shared by row (`NavTreeItemColumns`) and header (`L1Panel`)
15
+ * so both apply the same normalization rule.
14
16
  */
17
+ export const getListActions = ({ actions, groupedActions }: FlattenedActions): Node.Action[] =>
18
+ actions
19
+ .flatMap((action) => (Node.isAction(action) ? [action] : (groupedActions[action.id] ?? [])))
20
+ .filter((action) => ['list-item', 'list-item-primary'].includes(action.properties?.disposition));
21
+
22
+ /** Returns flattened actions and grouped sub-actions for a given graph node. */
15
23
  export const useActions = (node: Node.Node): FlattenedActions => {
16
24
  const { graph } = useAppGraph();
17
25
  const actions = useGraphActions(graph, node.id);
18
26
 
19
- return useMemo(
20
- () =>
21
- actions.reduce(
22
- (acc: FlattenedActions, arg) => {
23
- if (arg.properties.disposition === 'item') {
24
- return acc;
25
- }
26
-
27
- acc.actions.push(arg);
28
- if (!Node.isAction(arg)) {
29
- const actionGroup = Graph.getActions(graph, arg.id);
30
- acc.groupedActions[arg.id] = actionGroup;
31
- }
27
+ return useMemo(() => {
28
+ return actions.reduce(
29
+ (acc: FlattenedActions, arg) => {
30
+ if (arg.properties.disposition === 'item') {
32
31
  return acc;
33
- },
34
- { actions: [], groupedActions: {} },
35
- ),
36
- [actions],
37
- );
32
+ }
33
+
34
+ acc.actions.push(arg);
35
+ if (!Node.isAction(arg)) {
36
+ const actionGroup = Graph.getActions(graph, arg.id);
37
+ acc.groupedActions[arg.id] = actionGroup;
38
+ }
39
+ return acc;
40
+ },
41
+ { actions: [], groupedActions: {} },
42
+ );
43
+ }, [actions]);
38
44
  };