@dxos/plugin-navtree 0.8.4-main.67995b8 → 0.8.4-main.6fa680abb7

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 (239) hide show
  1. package/dist/lib/browser/CommandsDialogContent-2DKIOLJL.mjs +113 -0
  2. package/dist/lib/browser/CommandsDialogContent-2DKIOLJL.mjs.map +7 -0
  3. package/dist/lib/browser/CommandsTrigger-ABODVVMP.mjs +33 -0
  4. package/dist/lib/browser/CommandsTrigger-ABODVVMP.mjs.map +7 -0
  5. package/dist/lib/browser/NavTreeContainer-TLSYS4KK.mjs +12 -0
  6. package/dist/lib/browser/NavTreeContainer-TLSYS4KK.mjs.map +7 -0
  7. package/dist/lib/browser/NavTreeDocumentTitle-L6NLLWLD.mjs +26 -0
  8. package/dist/lib/browser/NavTreeDocumentTitle-L6NLLWLD.mjs.map +7 -0
  9. package/dist/lib/browser/app-graph-builder-Z43OTNI2.mjs +44 -0
  10. package/dist/lib/browser/app-graph-builder-Z43OTNI2.mjs.map +7 -0
  11. package/dist/lib/browser/chunk-A4VDCIJC.mjs +19 -0
  12. package/dist/lib/browser/chunk-A4VDCIJC.mjs.map +7 -0
  13. package/dist/lib/browser/chunk-AYF2TX65.mjs +14 -0
  14. package/dist/lib/browser/chunk-AYF2TX65.mjs.map +7 -0
  15. package/dist/lib/browser/chunk-JT37R5HS.mjs +1468 -0
  16. package/dist/lib/browser/chunk-JT37R5HS.mjs.map +7 -0
  17. package/dist/lib/browser/chunk-KF26WA4O.mjs +23 -0
  18. package/dist/lib/browser/chunk-KF26WA4O.mjs.map +7 -0
  19. package/dist/lib/browser/index.mjs +86 -95
  20. package/dist/lib/browser/index.mjs.map +4 -4
  21. package/dist/lib/browser/{keyboard-QRS6WOQH.mjs → keyboard-HYGFQO7T.mjs} +25 -19
  22. package/dist/lib/browser/keyboard-HYGFQO7T.mjs.map +7 -0
  23. package/dist/lib/browser/meta.json +1 -1
  24. package/dist/lib/browser/operation-resolver-VDWVUII5.mjs +49 -0
  25. package/dist/lib/browser/operation-resolver-VDWVUII5.mjs.map +7 -0
  26. package/dist/lib/browser/react-surface-D2RLMV4Z.mjs +59 -0
  27. package/dist/lib/browser/react-surface-D2RLMV4Z.mjs.map +7 -0
  28. package/dist/lib/browser/state-CWMNNF7K.mjs +131 -0
  29. package/dist/lib/browser/state-CWMNNF7K.mjs.map +7 -0
  30. package/dist/types/src/NavTreePlugin.d.ts +2 -1
  31. package/dist/types/src/NavTreePlugin.d.ts.map +1 -1
  32. package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts +6 -0
  33. package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts.map +1 -0
  34. package/dist/types/src/capabilities/app-graph-builder/index.d.ts +3 -0
  35. package/dist/types/src/capabilities/app-graph-builder/index.d.ts.map +1 -0
  36. package/dist/types/src/capabilities/index.d.ts +5 -105
  37. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  38. package/dist/types/src/capabilities/keyboard/index.d.ts +3 -0
  39. package/dist/types/src/capabilities/keyboard/index.d.ts.map +1 -0
  40. package/dist/types/src/capabilities/keyboard/keyboard.d.ts +5 -0
  41. package/dist/types/src/capabilities/keyboard/keyboard.d.ts.map +1 -0
  42. package/dist/types/src/capabilities/operation-resolver/index.d.ts +3 -0
  43. package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +1 -0
  44. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +5 -0
  45. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +1 -0
  46. package/dist/types/src/capabilities/react-surface/index.d.ts +3 -0
  47. package/dist/types/src/capabilities/react-surface/index.d.ts.map +1 -0
  48. package/dist/types/src/capabilities/react-surface/react-surface.d.ts +5 -0
  49. package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +1 -0
  50. package/dist/types/src/capabilities/state/index.d.ts +3 -0
  51. package/dist/types/src/capabilities/state/index.d.ts.map +1 -0
  52. package/dist/types/src/capabilities/state/state.d.ts +6 -0
  53. package/dist/types/src/capabilities/state/state.d.ts.map +1 -0
  54. package/dist/types/src/components/NavTree/NavTree.d.ts +11 -4
  55. package/dist/types/src/components/NavTree/NavTree.d.ts.map +1 -1
  56. package/dist/types/src/components/NavTree/NavTree.stories.d.ts +27 -5
  57. package/dist/types/src/components/NavTree/NavTree.stories.d.ts.map +1 -1
  58. package/dist/types/src/components/{NavTreeContext.d.ts → NavTreeContext/NavTreeContext.d.ts} +1 -1
  59. package/dist/types/src/components/NavTreeContext/NavTreeContext.d.ts.map +1 -0
  60. package/dist/types/src/components/NavTreeContext/index.d.ts +2 -0
  61. package/dist/types/src/components/NavTreeContext/index.d.ts.map +1 -0
  62. package/dist/types/src/components/NavTreeItem/NavTreeItemAction.d.ts +10 -8
  63. package/dist/types/src/components/NavTreeItem/NavTreeItemAction.d.ts.map +1 -1
  64. package/dist/types/src/components/NavTreeItem/NavTreeItemAction.stories.d.ts +33 -4
  65. package/dist/types/src/components/NavTreeItem/NavTreeItemAction.stories.d.ts.map +1 -1
  66. package/dist/types/src/components/NavTreeItem/NavTreeItemColumns.d.ts +1 -1
  67. package/dist/types/src/components/NavTreeItem/NavTreeItemColumns.d.ts.map +1 -1
  68. package/dist/types/src/components/Sidebar/L0Menu.d.ts +10 -5
  69. package/dist/types/src/components/Sidebar/L0Menu.d.ts.map +1 -1
  70. package/dist/types/src/components/Sidebar/L1Panel.d.ts +4 -7
  71. package/dist/types/src/components/Sidebar/L1Panel.d.ts.map +1 -1
  72. package/dist/types/src/components/Sidebar/L1Tabs.d.ts +5 -4
  73. package/dist/types/src/components/Sidebar/L1Tabs.d.ts.map +1 -1
  74. package/dist/types/src/components/UserAccountAvatar/UserAccountAvatar.d.ts.map +1 -1
  75. package/dist/types/src/components/UserAccountAvatar/UserAccountAvatar.stories.d.ts +8 -5
  76. package/dist/types/src/components/UserAccountAvatar/UserAccountAvatar.stories.d.ts.map +1 -1
  77. package/dist/types/src/components/index.d.ts +0 -3
  78. package/dist/types/src/components/index.d.ts.map +1 -1
  79. package/dist/types/src/components/types.d.ts +8 -16
  80. package/dist/types/src/components/types.d.ts.map +1 -1
  81. package/dist/types/src/containers/CommandsDialogContent/CommandsDialogContent.d.ts +6 -0
  82. package/dist/types/src/containers/CommandsDialogContent/CommandsDialogContent.d.ts.map +1 -0
  83. package/dist/types/src/containers/CommandsDialogContent/index.d.ts +3 -0
  84. package/dist/types/src/containers/CommandsDialogContent/index.d.ts.map +1 -0
  85. package/dist/types/src/containers/CommandsTrigger/CommandsTrigger.d.ts.map +1 -0
  86. package/dist/types/src/containers/CommandsTrigger/index.d.ts +3 -0
  87. package/dist/types/src/containers/CommandsTrigger/index.d.ts.map +1 -0
  88. package/dist/types/src/containers/NavTreeContainer/NavTreeContainer.d.ts +9 -0
  89. package/dist/types/src/containers/NavTreeContainer/NavTreeContainer.d.ts.map +1 -0
  90. package/dist/types/src/containers/NavTreeContainer/index.d.ts +3 -0
  91. package/dist/types/src/containers/NavTreeContainer/index.d.ts.map +1 -0
  92. package/dist/types/src/{components → containers/NavTreeDocumentTitle}/NavTreeDocumentTitle.d.ts +1 -1
  93. package/dist/types/src/containers/NavTreeDocumentTitle/NavTreeDocumentTitle.d.ts.map +1 -0
  94. package/dist/types/src/containers/NavTreeDocumentTitle/index.d.ts +3 -0
  95. package/dist/types/src/containers/NavTreeDocumentTitle/index.d.ts.map +1 -0
  96. package/dist/types/src/containers/index.d.ts +7 -0
  97. package/dist/types/src/containers/index.d.ts.map +1 -0
  98. package/dist/types/src/experimental/Tree.d.ts +1 -2
  99. package/dist/types/src/experimental/Tree.d.ts.map +1 -1
  100. package/dist/types/src/experimental/Tree.stories.d.ts +23 -6
  101. package/dist/types/src/experimental/Tree.stories.d.ts.map +1 -1
  102. package/dist/types/src/hooks/index.d.ts +5 -0
  103. package/dist/types/src/hooks/index.d.ts.map +1 -0
  104. package/dist/types/src/hooks/useActions.d.ts +5 -0
  105. package/dist/types/src/hooks/useActions.d.ts.map +1 -0
  106. package/dist/types/src/hooks/useLoadDescendents.d.ts +6 -0
  107. package/dist/types/src/hooks/useLoadDescendents.d.ts.map +1 -0
  108. package/dist/types/src/hooks/useNavTreeModel.d.ts +7 -0
  109. package/dist/types/src/hooks/useNavTreeModel.d.ts.map +1 -0
  110. package/dist/types/src/hooks/useNavTreeState.d.ts +22 -0
  111. package/dist/types/src/hooks/useNavTreeState.d.ts.map +1 -0
  112. package/dist/types/src/index.d.ts +1 -2
  113. package/dist/types/src/index.d.ts.map +1 -1
  114. package/dist/types/src/meta.d.ts +3 -4
  115. package/dist/types/src/meta.d.ts.map +1 -1
  116. package/dist/types/src/testing/app-graph-builder.d.ts +2 -3
  117. package/dist/types/src/testing/app-graph-builder.d.ts.map +1 -1
  118. package/dist/types/src/testing/generator.d.ts +5 -6
  119. package/dist/types/src/testing/generator.d.ts.map +1 -1
  120. package/dist/types/src/testing/update-state.d.ts +2 -2
  121. package/dist/types/src/testing/update-state.d.ts.map +1 -1
  122. package/dist/types/src/types/capabilities.d.ts +16 -0
  123. package/dist/types/src/types/capabilities.d.ts.map +1 -0
  124. package/dist/types/src/types/events.d.ts +5 -0
  125. package/dist/types/src/types/events.d.ts.map +1 -0
  126. package/dist/types/src/types/index.d.ts +4 -0
  127. package/dist/types/src/types/index.d.ts.map +1 -0
  128. package/dist/types/src/{types.d.ts → types/schema.d.ts} +10 -9
  129. package/dist/types/src/types/schema.d.ts.map +1 -0
  130. package/dist/types/src/util.d.ts +12 -9
  131. package/dist/types/src/util.d.ts.map +1 -1
  132. package/dist/types/tsconfig.tsbuildinfo +1 -1
  133. package/package.json +57 -55
  134. package/src/NavTreePlugin.tsx +64 -84
  135. package/src/capabilities/app-graph-builder/app-graph-builder.ts +42 -0
  136. package/src/capabilities/app-graph-builder/index.ts +7 -0
  137. package/src/capabilities/index.ts +5 -9
  138. package/src/capabilities/keyboard/index.ts +7 -0
  139. package/src/capabilities/keyboard/keyboard.ts +66 -0
  140. package/src/capabilities/operation-resolver/index.ts +7 -0
  141. package/src/capabilities/operation-resolver/operation-resolver.ts +45 -0
  142. package/src/capabilities/react-surface/index.ts +7 -0
  143. package/src/capabilities/react-surface/react-surface.tsx +53 -0
  144. package/src/capabilities/state/index.ts +7 -0
  145. package/src/capabilities/state/state.ts +149 -0
  146. package/src/components/NavTree/NavTree.stories.tsx +105 -98
  147. package/src/components/NavTree/NavTree.tsx +67 -32
  148. package/src/components/{NavTreeContext.tsx → NavTreeContext/NavTreeContext.tsx} +1 -1
  149. package/src/components/NavTreeContext/index.ts +5 -0
  150. package/src/components/NavTreeItem/NavTreeItemAction.stories.tsx +21 -13
  151. package/src/components/NavTreeItem/NavTreeItemAction.tsx +61 -37
  152. package/src/components/NavTreeItem/NavTreeItemColumns.tsx +68 -35
  153. package/src/components/Sidebar/L0Menu.tsx +170 -179
  154. package/src/components/Sidebar/L1Panel.tsx +252 -101
  155. package/src/components/Sidebar/L1Tabs.tsx +19 -33
  156. package/src/components/UserAccountAvatar/UserAccountAvatar.stories.tsx +9 -9
  157. package/src/components/UserAccountAvatar/UserAccountAvatar.tsx +20 -12
  158. package/src/components/index.ts +1 -3
  159. package/src/components/types.ts +15 -19
  160. package/src/containers/CommandsDialogContent/CommandsDialogContent.tsx +135 -0
  161. package/src/containers/CommandsDialogContent/index.ts +7 -0
  162. package/src/containers/CommandsTrigger/CommandsTrigger.tsx +26 -0
  163. package/src/containers/CommandsTrigger/index.ts +7 -0
  164. package/src/containers/NavTreeContainer/NavTreeContainer.tsx +271 -0
  165. package/src/containers/NavTreeContainer/index.ts +6 -0
  166. package/src/{components → containers/NavTreeDocumentTitle}/NavTreeDocumentTitle.tsx +5 -4
  167. package/src/containers/NavTreeDocumentTitle/index.ts +7 -0
  168. package/src/containers/index.ts +12 -0
  169. package/src/experimental/Tree.stories.tsx +78 -83
  170. package/src/experimental/Tree.tsx +6 -23
  171. package/src/hooks/index.ts +8 -0
  172. package/src/hooks/useActions.ts +34 -0
  173. package/src/hooks/useLoadDescendents.ts +23 -0
  174. package/src/hooks/useNavTreeModel.ts +118 -0
  175. package/src/hooks/useNavTreeState.ts +42 -0
  176. package/src/index.ts +1 -2
  177. package/src/meta.ts +11 -8
  178. package/src/testing/app-graph-builder.ts +159 -234
  179. package/src/testing/generator.ts +20 -18
  180. package/src/testing/update-state.ts +6 -6
  181. package/src/types/capabilities.ts +21 -0
  182. package/src/types/events.ts +12 -0
  183. package/src/types/index.ts +7 -0
  184. package/src/{types.ts → types/schema.ts} +9 -8
  185. package/src/util.ts +26 -33
  186. package/dist/lib/browser/app-graph-builder-5J4LRWDX.mjs +0 -45
  187. package/dist/lib/browser/app-graph-builder-5J4LRWDX.mjs.map +0 -7
  188. package/dist/lib/browser/chunk-ERDGQTH5.mjs +0 -16
  189. package/dist/lib/browser/chunk-ERDGQTH5.mjs.map +0 -7
  190. package/dist/lib/browser/chunk-WCARAZ7J.mjs +0 -15
  191. package/dist/lib/browser/chunk-WCARAZ7J.mjs.map +0 -7
  192. package/dist/lib/browser/chunk-WEMCSQI7.mjs +0 -1469
  193. package/dist/lib/browser/chunk-WEMCSQI7.mjs.map +0 -7
  194. package/dist/lib/browser/intent-resolver-3XYN2CBU.mjs +0 -47
  195. package/dist/lib/browser/intent-resolver-3XYN2CBU.mjs.map +0 -7
  196. package/dist/lib/browser/keyboard-QRS6WOQH.mjs.map +0 -7
  197. package/dist/lib/browser/react-surface-JSJ5SQX5.mjs +0 -51
  198. package/dist/lib/browser/react-surface-JSJ5SQX5.mjs.map +0 -7
  199. package/dist/lib/browser/state-54DY3DOY.mjs +0 -117
  200. package/dist/lib/browser/state-54DY3DOY.mjs.map +0 -7
  201. package/dist/types/src/capabilities/app-graph-builder.d.ts +0 -4
  202. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +0 -1
  203. package/dist/types/src/capabilities/capabilities.d.ts +0 -21
  204. package/dist/types/src/capabilities/capabilities.d.ts.map +0 -1
  205. package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
  206. package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
  207. package/dist/types/src/capabilities/keyboard.d.ts +0 -4
  208. package/dist/types/src/capabilities/keyboard.d.ts.map +0 -1
  209. package/dist/types/src/capabilities/react-surface.d.ts +0 -4
  210. package/dist/types/src/capabilities/react-surface.d.ts.map +0 -1
  211. package/dist/types/src/capabilities/state.d.ts +0 -20
  212. package/dist/types/src/capabilities/state.d.ts.map +0 -1
  213. package/dist/types/src/components/CommandsDialog/CommandsDialog.d.ts +0 -5
  214. package/dist/types/src/components/CommandsDialog/CommandsDialog.d.ts.map +0 -1
  215. package/dist/types/src/components/CommandsDialog/CommandsTrigger.d.ts.map +0 -1
  216. package/dist/types/src/components/CommandsDialog/index.d.ts +0 -3
  217. package/dist/types/src/components/CommandsDialog/index.d.ts.map +0 -1
  218. package/dist/types/src/components/NavTreeContainer.d.ts +0 -9
  219. package/dist/types/src/components/NavTreeContainer.d.ts.map +0 -1
  220. package/dist/types/src/components/NavTreeContext.d.ts.map +0 -1
  221. package/dist/types/src/components/NavTreeDocumentTitle.d.ts.map +0 -1
  222. package/dist/types/src/events.d.ts +0 -4
  223. package/dist/types/src/events.d.ts.map +0 -1
  224. package/dist/types/src/hooks.d.ts +0 -3
  225. package/dist/types/src/hooks.d.ts.map +0 -1
  226. package/dist/types/src/types.d.ts.map +0 -1
  227. package/src/capabilities/app-graph-builder.ts +0 -52
  228. package/src/capabilities/capabilities.ts +0 -20
  229. package/src/capabilities/intent-resolver.ts +0 -37
  230. package/src/capabilities/keyboard.ts +0 -59
  231. package/src/capabilities/react-surface.tsx +0 -45
  232. package/src/capabilities/state.ts +0 -104
  233. package/src/components/CommandsDialog/CommandsDialog.tsx +0 -118
  234. package/src/components/CommandsDialog/CommandsTrigger.tsx +0 -35
  235. package/src/components/CommandsDialog/index.ts +0 -6
  236. package/src/components/NavTreeContainer.tsx +0 -313
  237. package/src/events.ts +0 -11
  238. package/src/hooks.ts +0 -21
  239. /package/dist/types/src/{components/CommandsDialog → containers/CommandsTrigger}/CommandsTrigger.d.ts +0 -0
@@ -0,0 +1,1468 @@
1
+ import {
2
+ NavTreeCapabilities
3
+ } from "./chunk-KF26WA4O.mjs";
4
+ import {
5
+ meta
6
+ } from "./chunk-A4VDCIJC.mjs";
7
+
8
+ // src/containers/NavTreeContainer/NavTreeContainer.tsx
9
+ import { monitorForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
10
+ import { extractInstruction } from "@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item";
11
+ import React8, { forwardRef as forwardRef3, memo as memo4, useCallback as useCallback4, useEffect as useEffect2, useMemo as useMemo8, useRef as useRef2 } from "react";
12
+ import { Surface, useOperationInvoker } from "@dxos/app-framework/ui";
13
+ import { LayoutOperation } from "@dxos/app-toolkit";
14
+ import { useAppGraph as useAppGraph6, useLayout } from "@dxos/app-toolkit/ui";
15
+ import { Graph as Graph5, Node as Node6, useActionRunner as useActionRunner4 } from "@dxos/plugin-graph";
16
+ import { useMediaQuery as useMediaQuery2, useSidebars } from "@dxos/react-ui";
17
+ import { isTreeData } from "@dxos/react-ui-list";
18
+ import { arrayMove as arrayMove2 } from "@dxos/util";
19
+
20
+ // src/components/NavTree/NavTree.tsx
21
+ import React7, { forwardRef as forwardRef2, useMemo as useMemo7 } from "react";
22
+ import { useAppGraph as useAppGraph5 } from "@dxos/app-toolkit/ui";
23
+ import { Node as Node5, useConnections as useConnections2, useActions as useGraphActions2 } from "@dxos/plugin-graph";
24
+ import { Tabs as Tabs3 } from "@dxos/react-ui-tabs";
25
+ import { byPosition } from "@dxos/util";
26
+
27
+ // src/hooks/useActions.ts
28
+ import { useMemo } from "react";
29
+ import { useAppGraph } from "@dxos/app-toolkit/ui";
30
+ import { Graph, Node, useActions as useGraphActions } from "@dxos/plugin-graph";
31
+ var useActions = (node) => {
32
+ const { graph } = useAppGraph();
33
+ const actions = useGraphActions(graph, node.id);
34
+ return useMemo(() => {
35
+ return actions.reduce((acc, arg) => {
36
+ if (arg.properties.disposition === "item") {
37
+ return acc;
38
+ }
39
+ acc.actions.push(arg);
40
+ if (!Node.isAction(arg)) {
41
+ const actionGroup = Graph.getActions(graph, arg.id);
42
+ acc.groupedActions[arg.id] = actionGroup;
43
+ }
44
+ return acc;
45
+ }, {
46
+ actions: [],
47
+ groupedActions: {}
48
+ });
49
+ }, [
50
+ actions
51
+ ]);
52
+ };
53
+
54
+ // src/hooks/useLoadDescendents.ts
55
+ import { useEffect } from "react";
56
+ import { useAppGraph as useAppGraph2 } from "@dxos/app-toolkit/ui";
57
+ import { Graph as Graph2 } from "@dxos/plugin-graph";
58
+ var useLoadDescendents = (root) => {
59
+ const { graph } = useAppGraph2();
60
+ useEffect(() => {
61
+ if (!root) {
62
+ return;
63
+ }
64
+ Graph2.expand(graph, root.id, "child");
65
+ }, [
66
+ graph,
67
+ root
68
+ ]);
69
+ };
70
+
71
+ // src/hooks/useNavTreeModel.ts
72
+ import { Atom } from "@effect-atom/atom-react";
73
+ import * as Option from "effect/Option";
74
+ import { useMemo as useMemo3 } from "react";
75
+ import { useAppGraph as useAppGraph3 } from "@dxos/app-toolkit/ui";
76
+ import { PLANK_COMPANION_TYPE } from "@dxos/plugin-deck/types";
77
+ import { Path } from "@dxos/react-ui-list";
78
+ import { mx } from "@dxos/ui-theme";
79
+
80
+ // src/util.ts
81
+ import { Graph as Graph3, Node as Node2 } from "@dxos/plugin-graph";
82
+ import { isNonNullable } from "@dxos/util";
83
+ var getParent = (graph, node, path) => {
84
+ const parentId = path[path.length - 2];
85
+ return Graph3.getConnections(graph, node.id, Node2.childRelation("inbound")).find((n) => n.id === parentId);
86
+ };
87
+ var getPersistenceParent = (graph, node, path, persistenceClass) => {
88
+ if (node.properties.acceptPersistenceClass?.has(persistenceClass)) {
89
+ return node;
90
+ } else {
91
+ const parent = getParent(graph, node, path);
92
+ return parent ? getPersistenceParent(graph, parent, path.slice(0, path.length - 1), persistenceClass) : null;
93
+ }
94
+ };
95
+ var resolveMigrationOperation = (graph, activeNode, destinationPath, destinationRelatedNode) => {
96
+ const activeClass = activeNode.properties.persistenceClass;
97
+ if (destinationRelatedNode && activeClass) {
98
+ const persistenceParent = getPersistenceParent(graph, destinationRelatedNode, destinationPath, activeClass);
99
+ if (persistenceParent) {
100
+ const activeKey = activeNode.properties.persistenceKey;
101
+ if (activeKey && persistenceParent?.properties.acceptPersistenceKey) {
102
+ return persistenceParent.properties.acceptPersistenceKey.has(activeKey) && persistenceParent.properties.onTransferStart ? "transfer" : persistenceParent.properties.onCopy ? "copy" : "reject";
103
+ } else {
104
+ return "reject";
105
+ }
106
+ } else {
107
+ return "reject";
108
+ }
109
+ } else {
110
+ return "reject";
111
+ }
112
+ };
113
+ var sortActions = (actions) => actions.sort((a, b) => {
114
+ if (a.properties.disposition === b.properties.disposition) {
115
+ return 0;
116
+ }
117
+ if (a.properties.disposition === "list-item-primary") {
118
+ return -1;
119
+ }
120
+ return 1;
121
+ });
122
+ var getChildren = (graph, node, path = []) => {
123
+ return Graph3.getConnections(graph, node.id, "child").map((n) => {
124
+ const nextPath = [
125
+ ...path,
126
+ node.id
127
+ ];
128
+ return nextPath.includes(n.id) ? void 0 : n;
129
+ }).filter(isNonNullable);
130
+ };
131
+ var filterItems = (node, disposition) => {
132
+ if (!disposition && (node.properties.disposition === "hidden" || node.properties.disposition === "alternate-tree")) {
133
+ return false;
134
+ } else if (!disposition) {
135
+ const action = Node2.isAction(node);
136
+ return !action || node.properties.disposition === "item";
137
+ } else {
138
+ return node.properties.disposition === disposition;
139
+ }
140
+ };
141
+ var l0ItemType = (item) => {
142
+ if (Node2.isActionLike(item)) {
143
+ return "action";
144
+ } else {
145
+ return "tab";
146
+ }
147
+ };
148
+
149
+ // src/hooks/useNavTreeState.ts
150
+ import { useAtomValue } from "@effect-atom/atom-react";
151
+ import { useMemo as useMemo2 } from "react";
152
+ import { useCapability } from "@dxos/app-framework/ui";
153
+ var useNavTreeState = () => {
154
+ return useCapability(NavTreeCapabilities.State);
155
+ };
156
+ var useNavTreeItemState = (path) => {
157
+ const { getItemAtom } = useCapability(NavTreeCapabilities.State);
158
+ const pathKey = useMemo2(() => path.join("~"), [
159
+ path
160
+ ]);
161
+ const atom = useMemo2(() => getItemAtom(path), [
162
+ getItemAtom,
163
+ pathKey
164
+ ]);
165
+ return useAtomValue(atom);
166
+ };
167
+ var useIsAlternateTree = (path, _item) => {
168
+ return useNavTreeItemState(path).alternateTree ?? false;
169
+ };
170
+
171
+ // src/hooks/useNavTreeModel.ts
172
+ var isVisibleChild = (node) => node.type !== PLANK_COMPANION_TYPE && node.properties.disposition !== "hidden";
173
+ var createItemPropsFamily = (graph) => Atom.family((pathKey) => {
174
+ const path = Path.parts(pathKey);
175
+ const id = Path.last(pathKey);
176
+ return Atom.make((get) => {
177
+ const nodeOpt = get(graph.node(id));
178
+ const node = Option.getOrElse(nodeOpt, () => void 0);
179
+ if (!node) {
180
+ return {
181
+ id,
182
+ label: id
183
+ };
184
+ }
185
+ const safeChildren = get(graph.connections(node.id, "child")).filter((child) => !path.includes(child.id));
186
+ const visibleChildren = safeChildren.filter(isVisibleChild);
187
+ const parentOf = visibleChildren.length > 0 ? visibleChildren.map((child) => child.id) : node.properties.role === "branch" ? [] : void 0;
188
+ const parentId = path.length >= 2 ? path[path.length - 2] : void 0;
189
+ const parentNode = parentId ? Option.getOrElse(get(graph.node(parentId)), () => void 0) : void 0;
190
+ const droppable = node.properties.droppable === false || parentNode?.properties.childrenDroppable === false ? false : void 0;
191
+ return {
192
+ id: node.id,
193
+ parentOf,
194
+ disabled: node.properties.disabled,
195
+ draggable: node.properties.draggable,
196
+ droppable,
197
+ label: node.properties.label ?? node.id,
198
+ className: mx(node.properties.className, node.properties.modified && "italic"),
199
+ headingClassName: node.properties.headingClassName,
200
+ icon: node.properties.icon,
201
+ iconHue: node.properties.iconHue,
202
+ testId: node.properties.testId
203
+ };
204
+ }).pipe(Atom.keepAlive);
205
+ });
206
+ var createChildIdsFamily = (graph) => Atom.family((id) => Atom.make((get) => get(graph.connections(id, "child")).map((child) => child.id)).pipe(Atom.keepAlive));
207
+ var createItemFamily = (graph) => Atom.family((id) => Atom.make((get) => {
208
+ const node = Option.getOrElse(get(graph.node(id)), () => void 0);
209
+ return node && filterItems(node) ? node : void 0;
210
+ }).pipe(Atom.keepAlive));
211
+ var createItemOpenFamily = (getItemAtom) => Atom.family((pathKey) => {
212
+ const path = Path.parts(pathKey);
213
+ const stateAtom = getItemAtom(path);
214
+ return Atom.make((get) => get(stateAtom).open).pipe(Atom.keepAlive);
215
+ });
216
+ var createItemCurrentFamily = (getItemAtom) => Atom.family((pathKey) => {
217
+ const path = Path.parts(pathKey);
218
+ const stateAtom = getItemAtom(path);
219
+ return Atom.make((get) => get(stateAtom).current).pipe(Atom.keepAlive);
220
+ });
221
+ var useNavTreeModel = (rootId) => {
222
+ const { graph } = useAppGraph3();
223
+ const { getItemAtom } = useNavTreeState();
224
+ const itemPropsFamily = useMemo3(() => createItemPropsFamily(graph), [
225
+ graph
226
+ ]);
227
+ const childIdsFamily = useMemo3(() => createChildIdsFamily(graph), [
228
+ graph
229
+ ]);
230
+ const itemFamily = useMemo3(() => createItemFamily(graph), [
231
+ graph
232
+ ]);
233
+ const itemOpenFamily = useMemo3(() => createItemOpenFamily(getItemAtom), [
234
+ getItemAtom
235
+ ]);
236
+ const itemCurrentFamily = useMemo3(() => createItemCurrentFamily(getItemAtom), [
237
+ getItemAtom
238
+ ]);
239
+ return useMemo3(() => ({
240
+ item: (id) => itemFamily(id),
241
+ itemProps: (path) => itemPropsFamily(Path.create(...path)),
242
+ itemOpen: (path) => itemOpenFamily(Path.create(...path)),
243
+ itemCurrent: (path) => itemCurrentFamily(Path.create(...path)),
244
+ childIds: (parentId) => childIdsFamily(parentId ?? rootId)
245
+ }), [
246
+ itemFamily,
247
+ itemPropsFamily,
248
+ itemOpenFamily,
249
+ itemCurrentFamily,
250
+ childIdsFamily,
251
+ rootId
252
+ ]);
253
+ };
254
+
255
+ // src/components/NavTreeContext/NavTreeContext.tsx
256
+ import { createContext, useContext } from "react";
257
+ import { raise } from "@dxos/debug";
258
+ var NavTreeContext = /* @__PURE__ */ createContext(null);
259
+ var useNavTreeContext = () => useContext(NavTreeContext) ?? raise(new Error("Missing NavTreeContext"));
260
+
261
+ // src/components/Sidebar/L0Menu.tsx
262
+ import { combine } from "@atlaskit/pragmatic-drag-and-drop/combine";
263
+ import { draggable, dropTargetForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
264
+ import { preserveOffsetOnSource } from "@atlaskit/pragmatic-drag-and-drop/element/preserve-offset-on-source";
265
+ import { scrollJustEnoughIntoView } from "@atlaskit/pragmatic-drag-and-drop/element/scroll-just-enough-into-view";
266
+ import { attachClosestEdge, extractClosestEdge } from "@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge";
267
+ import { useAtomValue as useAtomValue2 } from "@effect-atom/atom-react";
268
+ import React2, { forwardRef, memo, useCallback, useLayoutEffect, useMemo as useMemo4, useRef, useState } from "react";
269
+ import { DxAvatar } from "@dxos/lit-ui/react";
270
+ import { useActionRunner } from "@dxos/plugin-graph";
271
+ import { Icon, ListItem, ScrollArea, Tooltip, toLocalizedString, useMediaQuery, useTranslation } from "@dxos/react-ui";
272
+ import { Menu } from "@dxos/react-ui-menu";
273
+ import { Tabs } from "@dxos/react-ui-tabs";
274
+ import { mx as mx2 } from "@dxos/ui-theme";
275
+ import { arrayMove } from "@dxos/util";
276
+
277
+ // src/components/UserAccountAvatar/UserAccountAvatar.tsx
278
+ import React from "react";
279
+ import { Avatar } from "@dxos/react-ui";
280
+ import { hexToFallback } from "@dxos/util";
281
+ var UserAccountAvatar = ({ size, userId, hue, emoji, status }) => {
282
+ const fallbackValue = hexToFallback(userId ?? "0");
283
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(L0ItemActiveTabIndicator, {
284
+ classNames: "inset-y-6"
285
+ }), /* @__PURE__ */ React.createElement("div", {
286
+ className: "grid place-items-center dx-focus-ring-group-indicator rounded-full",
287
+ "data-joyride": "welcome/account"
288
+ }, /* @__PURE__ */ React.createElement(Avatar.Root, null, /* @__PURE__ */ React.createElement(Avatar.Content, {
289
+ variant: "circle",
290
+ size: size ?? 12,
291
+ status: status ?? "active",
292
+ hue: hue || fallbackValue.hue,
293
+ fallback: emoji || fallbackValue.emoji,
294
+ "data-testid": "treeView.userAccount"
295
+ }))));
296
+ };
297
+
298
+ // src/components/Sidebar/L0Menu.tsx
299
+ var useL0ItemClick = ({ item, parent, path }, type) => {
300
+ const { onSelect, onTabChange } = useNavTreeContext();
301
+ const { getItem } = useNavTreeState();
302
+ const [isLg] = useMediaQuery("lg");
303
+ const runAction = useActionRunner();
304
+ return useCallback((event) => {
305
+ switch (type) {
306
+ case "action": {
307
+ const { properties: { caller } = {} } = item;
308
+ return void runAction(item, caller ? {
309
+ parent,
310
+ path,
311
+ caller
312
+ } : {
313
+ parent,
314
+ path
315
+ });
316
+ }
317
+ case "tab":
318
+ return onTabChange?.(item);
319
+ case "link":
320
+ return onSelect?.({
321
+ item,
322
+ path,
323
+ current: !getItem(path).current,
324
+ option: event.altKey
325
+ });
326
+ }
327
+ }, [
328
+ item,
329
+ parent,
330
+ type,
331
+ getItem,
332
+ onSelect,
333
+ onTabChange,
334
+ isLg,
335
+ runAction
336
+ ]);
337
+ };
338
+ var l0Breakpoints = {
339
+ lg: "hidden lg:grid"
340
+ };
341
+ var l0ItemRoot = 'group/l0item flex w-full justify-center items-center relative data[type!="collection"]:cursor-pointer dx-app-no-drag dx-focus-ring-group';
342
+ var l0ItemContent = "flex justify-center items-center dx-focus-ring-group-indicator transition-colors rounded-sm";
343
+ var L0ItemRoot = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef(({ item, parent, path, onMouseEnter, children }, forwardedRef) => {
344
+ const { model } = useNavTreeContext();
345
+ const itemPath = useMemo4(() => [
346
+ ...path,
347
+ item.id
348
+ ], [
349
+ item.id,
350
+ path
351
+ ]);
352
+ const { id, testId } = useAtomValue2(model.itemProps(itemPath));
353
+ const type = l0ItemType(item);
354
+ const { t } = useTranslation(meta.id);
355
+ const localizedString = toLocalizedString(item.properties.label, t);
356
+ const handleClick = useL0ItemClick({
357
+ item,
358
+ parent,
359
+ path: itemPath
360
+ }, type);
361
+ const rootProps = type === "tab" ? {
362
+ value: item.id,
363
+ tabIndex: 0,
364
+ onClick: handleClick,
365
+ "data-testid": testId,
366
+ "data-object-id": id
367
+ } : {
368
+ onClick: handleClick,
369
+ "data-testid": testId,
370
+ "data-object-id": id
371
+ };
372
+ return /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
373
+ asChild: true,
374
+ delayDuration: 0,
375
+ side: "right",
376
+ content: localizedString
377
+ }, /* @__PURE__ */ React2.createElement(Tabs.TabPrimitive, {
378
+ ...rootProps,
379
+ "data-type": type,
380
+ className: mx2(l0ItemRoot, l0Breakpoints[item.properties.l0Breakpoint]),
381
+ ref: forwardedRef,
382
+ onMouseEnter
383
+ }, children));
384
+ }));
385
+ var L0ItemActiveTabIndicator = ({ classNames }) => /* @__PURE__ */ React2.createElement("div", {
386
+ role: "none",
387
+ className: mx2("hidden group-aria-selected/l0item:block absolute start-0 inset-y-2 w-1 bg-accent-surface rounded-ie", classNames)
388
+ });
389
+ var L0Item = /* @__PURE__ */ memo(({ item, parent, path, pinned, onRearrange, onItemHover }) => {
390
+ const { t } = useTranslation(meta.id);
391
+ const itemElement = useRef(null);
392
+ const [closestEdge, setEdge] = useState(null);
393
+ const localizedString = toLocalizedString(item.properties.label, t);
394
+ const hue = item.properties.hue ?? null;
395
+ useLayoutEffect(() => {
396
+ if (!itemElement.current || !onRearrange) {
397
+ return;
398
+ }
399
+ return combine(draggable({
400
+ element: itemElement.current,
401
+ getInitialData: () => ({
402
+ id: item.id,
403
+ type: "l0Item"
404
+ }),
405
+ onGenerateDragPreview: ({ nativeSetDragImage, source, location }) => {
406
+ document.body.setAttribute("data-drag-preview", "true");
407
+ const element = source.element.querySelector("[data-frame]");
408
+ scrollJustEnoughIntoView({
409
+ element
410
+ });
411
+ const { x, y } = preserveOffsetOnSource({
412
+ element,
413
+ input: location.current.input
414
+ })({
415
+ container: element.offsetParent ?? document.body
416
+ });
417
+ nativeSetDragImage?.(element, x, y);
418
+ },
419
+ onDragStart: () => {
420
+ document.body.removeAttribute("data-drag-preview");
421
+ itemElement.current.closest("[data-drag-autoscroll]")?.setAttribute("data-drag-autoscroll", "active");
422
+ },
423
+ onDrop: () => {
424
+ itemElement.current.closest("[data-drag-autoscroll]")?.setAttribute("data-drag-autoscroll", "idle");
425
+ }
426
+ }), dropTargetForElements({
427
+ element: itemElement.current,
428
+ getData: ({ input, element }) => {
429
+ return attachClosestEdge({
430
+ id: item.id,
431
+ type: "l0Item"
432
+ }, {
433
+ input,
434
+ element,
435
+ allowedEdges: [
436
+ "top",
437
+ "bottom"
438
+ ]
439
+ });
440
+ },
441
+ onDragEnter: ({ self, source }) => {
442
+ if (source.data.type === self.data.type) {
443
+ setEdge(extractClosestEdge(self.data));
444
+ }
445
+ },
446
+ onDrag: ({ self, source }) => {
447
+ if (source.data.type === self.data.type) {
448
+ setEdge(extractClosestEdge(self.data));
449
+ }
450
+ },
451
+ onDragLeave: () => setEdge(null),
452
+ onDrop: ({ self, source }) => {
453
+ setEdge(null);
454
+ if (source.data.type === self.data.type) {
455
+ onRearrange(source.data, self.data, extractClosestEdge(self.data));
456
+ }
457
+ }
458
+ }));
459
+ }, [
460
+ item,
461
+ onRearrange
462
+ ]);
463
+ const handleMouseEnter = useCallback(() => onItemHover?.({
464
+ item
465
+ }), [
466
+ item,
467
+ onItemHover
468
+ ]);
469
+ return /* @__PURE__ */ React2.createElement(L0ItemRoot, {
470
+ ref: itemElement,
471
+ item,
472
+ parent,
473
+ path,
474
+ onMouseEnter: handleMouseEnter
475
+ }, /* @__PURE__ */ React2.createElement("div", {
476
+ role: "none",
477
+ "data-frame": true,
478
+ ...hue && {
479
+ style: {
480
+ background: `var(--color-${hue}-surface)`
481
+ }
482
+ },
483
+ className: mx2(l0ItemContent, pinned ? "p-2 group-hover/l0item:bg-active-surface" : "w-(--dx-l0-avatar-size) h-(--dx-l0-avatar-size) bg-active-surface")
484
+ }, /* @__PURE__ */ React2.createElement(ItemAvatar, {
485
+ item
486
+ })), /* @__PURE__ */ React2.createElement(L0ItemActiveTabIndicator, null), /* @__PURE__ */ React2.createElement("span", {
487
+ id: `${item.id}__label`,
488
+ className: "sr-only"
489
+ }, localizedString), closestEdge && /* @__PURE__ */ React2.createElement(ListItem.DropIndicator, {
490
+ edge: closestEdge
491
+ }));
492
+ });
493
+ var ItemAvatar = ({ item }) => {
494
+ const { t } = useTranslation(meta.id);
495
+ const type = l0ItemType(item);
496
+ if (item.properties.icon) {
497
+ const hue = item.properties.hue ?? null;
498
+ const hueFgStyle = hue && {
499
+ style: {
500
+ color: `var(--color-${hue}-surface-text)`
501
+ }
502
+ };
503
+ return /* @__PURE__ */ React2.createElement(Icon, {
504
+ icon: item.properties.icon,
505
+ size: 6,
506
+ ...hueFgStyle
507
+ });
508
+ }
509
+ if (type === "tab" && item.properties.disposition !== "pin-end") {
510
+ const hue = item.properties.hue ?? null;
511
+ const localizedString = toLocalizedString(item.properties.label, t);
512
+ return /* @__PURE__ */ React2.createElement(DxAvatar, {
513
+ hue,
514
+ hueVariant: "surface",
515
+ variant: "square",
516
+ size: 12,
517
+ fallback: localizedString
518
+ });
519
+ }
520
+ return null;
521
+ };
522
+ var L0Menu = ({ menuActions, topLevelItems, pinnedItems, userAccountItem, parent, path, onItemHover }) => {
523
+ const { t } = useTranslation(meta.id);
524
+ const runAction = useActionRunner();
525
+ const handleAction = useCallback((action, params) => {
526
+ void runAction(action, params);
527
+ }, [
528
+ runAction
529
+ ]);
530
+ const handleRearrange = useCallback((source, target, closestEdge) => {
531
+ const sourceItem = topLevelItems.find((i) => i.id === source.id);
532
+ if (!sourceItem?.properties.onRearrange) {
533
+ return;
534
+ }
535
+ const sourceIndex = topLevelItems.findIndex((i) => i.id === source.id);
536
+ const targetIndex = topLevelItems.findIndex((i) => i.id === target.id);
537
+ const insertIndex = source.id === target.id ? sourceIndex : targetIndex + (sourceIndex < targetIndex ? closestEdge === "top" ? -1 : 0 : closestEdge === "bottom" ? 1 : 0);
538
+ const nextOrder = arrayMove([
539
+ ...topLevelItems
540
+ ], sourceIndex, insertIndex);
541
+ return sourceItem.properties.onRearrange(nextOrder.map((item) => item.data));
542
+ }, [
543
+ topLevelItems
544
+ ]);
545
+ const hasRearrangeableItems = topLevelItems.some((item) => item.properties.onRearrange);
546
+ return /* @__PURE__ */ React2.createElement(Tabs.Tablist, {
547
+ classNames: [
548
+ "group/l0 absolute z-[1] inset-y-0 start-0 rounded-is",
549
+ "grid grid-cols-[var(--dx-l0-size)] grid-rows-[var(--dx-rail-size)_1fr_min-content_var(--dx-l0-size)] dx-contain-layout",
550
+ "!w-(--dx-l0-size) bg-toolbar-surface border-e border-subdued-separator dx-app-drag pb-[env(safe-area-inset-bottom)]"
551
+ ]
552
+ }, /* @__PURE__ */ React2.createElement(Menu.Root, {
553
+ onAction: handleAction
554
+ }, /* @__PURE__ */ React2.createElement(Menu.Trigger, {
555
+ asChild: true,
556
+ "data-testid": "spacePlugin.addSpace",
557
+ className: mx2(l0ItemRoot, "grid place-items-center dx-focus-ring-group", '[body[data-platform="macos"]_&]:mt-[30px]')
558
+ }, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
559
+ content: t("app menu label"),
560
+ side: "right",
561
+ asChild: true
562
+ }, /* @__PURE__ */ React2.createElement(Tabs.TabPrimitive, {
563
+ value: "options",
564
+ asChild: true,
565
+ role: "button"
566
+ }, /* @__PURE__ */ React2.createElement("div", {
567
+ role: "none",
568
+ className: mx2(l0ItemContent, "h-(--dx-rail-action) w-(--dx-rail-action) group-hover/l0item:bg-hover-surface")
569
+ }, /* @__PURE__ */ React2.createElement(Icon, {
570
+ icon: "ph--list--regular",
571
+ size: 5
572
+ }))))), /* @__PURE__ */ React2.createElement(Menu.Content, {
573
+ group: parent,
574
+ items: menuActions
575
+ })), /* @__PURE__ */ React2.createElement(ScrollArea.Root, {
576
+ thin: true,
577
+ orientation: "vertical"
578
+ }, /* @__PURE__ */ React2.createElement(ScrollArea.Viewport, null, /* @__PURE__ */ React2.createElement("div", {
579
+ role: "none",
580
+ className: mx2([
581
+ "flex flex-col gap-1 pt-1",
582
+ '[body[data-platform="macos"]_&]:py-[30px]',
583
+ '[body[data-platform="ios"]_&]:py-[max(env(safe-area-inset-top),0.25rem)]'
584
+ ])
585
+ }, topLevelItems.map((item) => /* @__PURE__ */ React2.createElement(L0Item, {
586
+ key: item.id,
587
+ item,
588
+ parent,
589
+ path,
590
+ onItemHover,
591
+ ...hasRearrangeableItems && {
592
+ onRearrange: handleRearrange
593
+ }
594
+ }))))), /* @__PURE__ */ React2.createElement("div", {
595
+ role: "none",
596
+ className: "grid grid-cols-1 auto-rows-(--dx-rail-action) pt-2"
597
+ }, pinnedItems.map((item) => /* @__PURE__ */ React2.createElement(L0Item, {
598
+ key: item.id,
599
+ item,
600
+ parent,
601
+ path,
602
+ pinned: true
603
+ }))), userAccountItem && /* @__PURE__ */ React2.createElement("div", {
604
+ role: "none",
605
+ className: "grid dx-app-no-drag"
606
+ }, /* @__PURE__ */ React2.createElement(L0ItemRoot, {
607
+ key: userAccountItem.id,
608
+ item: userAccountItem,
609
+ parent,
610
+ path
611
+ }, /* @__PURE__ */ React2.createElement(UserAccountAvatar, {
612
+ userId: userAccountItem.properties.userId,
613
+ hue: userAccountItem.properties.hue,
614
+ emoji: userAccountItem.properties.emoji,
615
+ status: userAccountItem.properties.status,
616
+ size: 10
617
+ }))));
618
+ };
619
+
620
+ // src/components/Sidebar/L1Panel.tsx
621
+ import * as Effect from "effect/Effect";
622
+ import * as Option2 from "effect/Option";
623
+ import React5, { memo as memo3, useCallback as useCallback3, useMemo as useMemo6 } from "react";
624
+ import { Node as Node4 } from "@dxos/app-graph";
625
+ import { isPinnedWorkspace } from "@dxos/app-toolkit";
626
+ import { useAppGraph as useAppGraph4 } from "@dxos/app-toolkit/ui";
627
+ import { Graph as Graph4, useActionRunner as useActionRunner3, useConnections, useEdges } from "@dxos/plugin-graph";
628
+ import { DensityProvider, IconButton as IconButton2, ScrollArea as ScrollArea2, toLocalizedString as toLocalizedString4, useTranslation as useTranslation4 } from "@dxos/react-ui";
629
+ import { useAttended } from "@dxos/react-ui-attention";
630
+ import { Tree } from "@dxos/react-ui-list";
631
+ import { Menu as Menu3 } from "@dxos/react-ui-menu";
632
+ import { Tabs as Tabs2 } from "@dxos/react-ui-tabs";
633
+ import { hoverableControlItem as hoverableControlItem2, hoverableOpenControlItem as hoverableOpenControlItem2 } from "@dxos/ui-theme";
634
+
635
+ // src/components/NavTreeItem/NavTreeItemAction.tsx
636
+ import React3, { useCallback as useCallback2 } from "react";
637
+ import { useActionRunner as useActionRunner2 } from "@dxos/plugin-graph";
638
+ import { IconButton, toLocalizedString as toLocalizedString2, useDensityContext, useTranslation as useTranslation2 } from "@dxos/react-ui";
639
+ import { Menu as Menu2 } from "@dxos/react-ui-menu";
640
+ import { hoverableControlItem, hoverableOpenControlItem } from "@dxos/ui-theme";
641
+ var fallbackIcon = "ph--placeholder--regular";
642
+ var fineActionButtonProps = {
643
+ size: 4,
644
+ density: "fine"
645
+ };
646
+ var coarseActionButtonProps = {
647
+ size: 5,
648
+ density: "coarse"
649
+ };
650
+ var NavTreeItemActionDropdownMenu = ({ parent, path, label, icon, testId, menuActions, caller }) => {
651
+ const { t } = useTranslation2(meta.id);
652
+ const density = useDensityContext();
653
+ const runAction = useActionRunner2();
654
+ const handleAction = useCallback2((action, params = {}) => runAction(action, {
655
+ ...params,
656
+ path
657
+ }), [
658
+ runAction,
659
+ path
660
+ ]);
661
+ return /* @__PURE__ */ React3.createElement(Menu2.Root, {
662
+ caller,
663
+ onAction: handleAction
664
+ }, /* @__PURE__ */ React3.createElement(Menu2.Trigger, {
665
+ asChild: true
666
+ }, /* @__PURE__ */ React3.createElement(IconButton, {
667
+ ...density === "coarse" ? coarseActionButtonProps : fineActionButtonProps,
668
+ classNames: [
669
+ "shrink-0 px-2 pointer-fine:px-1",
670
+ hoverableControlItem,
671
+ hoverableOpenControlItem
672
+ ],
673
+ variant: "ghost",
674
+ icon: icon ?? fallbackIcon,
675
+ iconOnly: true,
676
+ label: toLocalizedString2(label, t),
677
+ "data-testid": testId
678
+ })), /* @__PURE__ */ React3.createElement(Menu2.Content, {
679
+ group: parent,
680
+ items: menuActions
681
+ }));
682
+ };
683
+ var NavTreeItemMonolithicAction = (props) => {
684
+ const { parent, path, properties: { disabled, caller, testId, icon, variant = "ghost", iconOnly = true } = {
685
+ label: "never"
686
+ }, baseLabel } = props;
687
+ const density = useDensityContext();
688
+ const runAction = useActionRunner2();
689
+ return /* @__PURE__ */ React3.createElement(IconButton, {
690
+ ...density === "coarse" ? coarseActionButtonProps : fineActionButtonProps,
691
+ variant,
692
+ classNames: [
693
+ "shrink-0",
694
+ hoverableControlItem,
695
+ hoverableOpenControlItem,
696
+ iconOnly ? "px-2 pointer-fine:px-1" : "p-2 pointer-fine:p-2 me-1"
697
+ ],
698
+ icon: icon ?? fallbackIcon,
699
+ iconOnly,
700
+ label: baseLabel,
701
+ disabled,
702
+ onClick: (event) => {
703
+ event.stopPropagation();
704
+ if (disabled) {
705
+ return;
706
+ }
707
+ void runAction(props, caller ? {
708
+ parent,
709
+ caller,
710
+ path
711
+ } : {
712
+ parent,
713
+ path
714
+ });
715
+ },
716
+ "data-testid": testId
717
+ });
718
+ };
719
+ var NavTreeItemAction = ({ monolithic, menuActions, parent: node, path, ...props }) => {
720
+ const { t } = useTranslation2(meta.id);
721
+ const monolithicAction = menuActions?.length === 1 && menuActions[0];
722
+ const baseLabel = toLocalizedString2(monolithicAction ? monolithicAction.properties.label : props.label, t);
723
+ return monolithic && menuActions?.length === 1 ? /* @__PURE__ */ React3.createElement(NavTreeItemMonolithicAction, {
724
+ baseLabel,
725
+ parent: node,
726
+ path,
727
+ ...menuActions[0]
728
+ }) : /* @__PURE__ */ React3.createElement(NavTreeItemActionDropdownMenu, {
729
+ ...props,
730
+ label: baseLabel,
731
+ parent: node,
732
+ path,
733
+ menuActions
734
+ });
735
+ };
736
+
737
+ // src/components/NavTreeItem/NavTreeItemColumns.tsx
738
+ import React4, { Fragment, memo as memo2, useMemo as useMemo5 } from "react";
739
+ import { Node as Node3 } from "@dxos/app-graph";
740
+ import { Popover, Treegrid, toLocalizedString as toLocalizedString3, useTranslation as useTranslation3 } from "@dxos/react-ui";
741
+ var NavTreeItemColumns = /* @__PURE__ */ memo2(({ path, item, open }) => {
742
+ const { t } = useTranslation3(meta.id);
743
+ const { renderItemEnd: ItemEnd, popoverAnchorId } = useNavTreeContext();
744
+ const level = path.length - 2;
745
+ const { actions: actionsProp, groupedActions } = useActions(item);
746
+ const sortedActions = useMemo5(() => actionsProp.toSorted((actionA, actionB) => {
747
+ const primaryA = actionA.properties?.disposition === "list-item-primary";
748
+ const primaryB = actionB.properties?.disposition === "list-item-primary";
749
+ if (primaryA && !primaryB) {
750
+ return -1;
751
+ }
752
+ if (primaryB && !primaryA) {
753
+ return 1;
754
+ }
755
+ return 0;
756
+ }), [
757
+ actionsProp
758
+ ]);
759
+ const [primaryAction, ...secondaryActions] = sortedActions;
760
+ const actions = useMemo5(() => (primaryAction?.properties?.disposition === "list-item-primary" ? secondaryActions : sortedActions).flatMap((action) => Node3.isAction(action) ? [
761
+ action
762
+ ] : []).filter((a) => [
763
+ "list-item",
764
+ "list-item-primary"
765
+ ].includes(a.properties?.disposition)), [
766
+ sortedActions,
767
+ primaryAction
768
+ ]);
769
+ const primaryMenuActions = useMemo5(() => primaryAction ? Node3.isAction(primaryAction) ? [
770
+ primaryAction
771
+ ] : groupedActions[primaryAction?.id ?? ""] : void 0, [
772
+ primaryAction,
773
+ groupedActions
774
+ ]);
775
+ const ActionRoot = popoverAnchorId === `${NAV_TREE_ITEM}:${item.id}` ? Popover.Anchor : Fragment;
776
+ return /* @__PURE__ */ React4.createElement("div", {
777
+ role: "none",
778
+ className: "contents dx-app-no-drag"
779
+ }, primaryAction?.properties?.disposition === "list-item-primary" && !primaryAction?.properties?.disabled ? /* @__PURE__ */ React4.createElement(Treegrid.Cell, {
780
+ classNames: "contents"
781
+ }, /* @__PURE__ */ React4.createElement(NavTreeItemAction, {
782
+ testId: primaryAction.properties?.testId,
783
+ label: toLocalizedString3(primaryAction.properties?.label, t),
784
+ icon: primaryAction.properties?.icon ?? "ph--placeholder--regular",
785
+ parent: item,
786
+ path,
787
+ monolithic: Node3.isAction(primaryAction),
788
+ menuActions: primaryMenuActions,
789
+ menuType: primaryAction.properties?.menuType,
790
+ caller: NAV_TREE_ITEM
791
+ })) : /* @__PURE__ */ React4.createElement(Treegrid.Cell, {
792
+ role: "none"
793
+ }), /* @__PURE__ */ React4.createElement(ActionRoot, null, actions.length > 0 ? /* @__PURE__ */ React4.createElement(Treegrid.Cell, {
794
+ classNames: "contents"
795
+ }, /* @__PURE__ */ React4.createElement(NavTreeItemAction, {
796
+ testId: `navtree.treeItem.actionsLevel${level}`,
797
+ label: t("tree item actions label"),
798
+ icon: "ph--dots-three-vertical--regular",
799
+ parent: item,
800
+ path,
801
+ menuActions: actions,
802
+ menuType: "dropdown",
803
+ caller: NAV_TREE_ITEM
804
+ })) : /* @__PURE__ */ React4.createElement(Treegrid.Cell, {
805
+ role: "none"
806
+ })), ItemEnd && /* @__PURE__ */ React4.createElement(Treegrid.Cell, {
807
+ classNames: "contents"
808
+ }, /* @__PURE__ */ React4.createElement(ItemEnd, {
809
+ node: item,
810
+ open
811
+ })));
812
+ });
813
+
814
+ // src/components/Sidebar/L1Panel.tsx
815
+ var L1Panel$ = ({ open, path, item, isCurrent, onBack }) => {
816
+ const { t } = useTranslation4(meta.id);
817
+ const title = toLocalizedString4(item.properties.label, t);
818
+ const isActivated = useIsActivatedWorkspace(item);
819
+ const shouldRenderContent = isCurrent || isActivated;
820
+ return /* @__PURE__ */ React5.createElement(Tabs2.Tabpanel, {
821
+ key: item.id,
822
+ value: item.id,
823
+ classNames: [
824
+ "absolute inset-y-0 end-0",
825
+ "w-[calc(100%-var(--dx-l0-size))] lg:w-(--dx-l1-size) grid-cols-1 grid-rows-[var(--dx-rail-size)_1fr]",
826
+ "py-[env(safe-area-inset-top)]",
827
+ isCurrent && "grid"
828
+ ],
829
+ tabIndex: -1,
830
+ "aria-label": title,
831
+ ...isCurrent && {
832
+ "data-testid": "navtree.workspace.visible"
833
+ },
834
+ ...!open && {
835
+ inert: true
836
+ }
837
+ }, shouldRenderContent && /* @__PURE__ */ React5.createElement(L1PanelContent, {
838
+ open,
839
+ path,
840
+ item,
841
+ onBack
842
+ }));
843
+ };
844
+ var useIsActivatedWorkspace = (item) => {
845
+ const { graph } = useAppGraph4();
846
+ const edges = useEdges(graph, item.id);
847
+ return useMemo6(() => {
848
+ const childIds = edges[Graph4.relationKey("child")] ?? [];
849
+ return childIds.some((childId) => {
850
+ const child = Graph4.getNode(graph, childId);
851
+ if (Option2.isNone(child)) {
852
+ return false;
853
+ }
854
+ return child.value.properties.disposition === void 0;
855
+ });
856
+ }, [
857
+ edges,
858
+ graph
859
+ ]);
860
+ };
861
+ var L1PanelContent = ({ path, item, onBack }) => {
862
+ const navTreeContext = useNavTreeContext();
863
+ const alternateTree = useAlternateTreeItem(item);
864
+ const alternatePath = useMemo6(() => [
865
+ ...path,
866
+ item.id
867
+ ], [
868
+ item.id,
869
+ path
870
+ ]);
871
+ const isAlternate = useIsAlternateTree(alternatePath, item);
872
+ return /* @__PURE__ */ React5.createElement(DensityProvider, {
873
+ density: "fine"
874
+ }, /* @__PURE__ */ React5.createElement(L1PanelHeader, {
875
+ path,
876
+ item,
877
+ onBack
878
+ }), /* @__PURE__ */ React5.createElement(ScrollArea2.Root, {
879
+ thin: true,
880
+ orientation: "vertical"
881
+ }, /* @__PURE__ */ React5.createElement(ScrollArea2.Viewport, null, isAlternate && alternateTree ? /* @__PURE__ */ React5.createElement(Tree, {
882
+ model: navTreeContext.model,
883
+ id: alternateTree.id,
884
+ rootId: alternateTree.id,
885
+ path: alternatePath,
886
+ levelOffset: 5,
887
+ gridTemplateColumns: "[tree-row-start] 1fr min-content min-content min-content [tree-row-end]",
888
+ renderColumns: NavTreeItemColumns,
889
+ blockInstruction: navTreeContext.blockInstruction,
890
+ canDrop: navTreeContext.canDrop,
891
+ canSelect: navTreeContext.canSelect,
892
+ onOpenChange: navTreeContext.onOpenChange,
893
+ onSelect: navTreeContext.onSelect,
894
+ onItemHover: navTreeContext.onItemHover
895
+ }) : /* @__PURE__ */ React5.createElement(Tree, {
896
+ model: navTreeContext.model,
897
+ id: item.id,
898
+ rootId: item.id,
899
+ path,
900
+ levelOffset: 5,
901
+ gridTemplateColumns: "[tree-row-start] 1fr min-content min-content min-content [tree-row-end]",
902
+ draggable: true,
903
+ renderColumns: NavTreeItemColumns,
904
+ blockInstruction: navTreeContext.blockInstruction,
905
+ canDrop: navTreeContext.canDrop,
906
+ canSelect: navTreeContext.canSelect,
907
+ onOpenChange: navTreeContext.onOpenChange,
908
+ onSelect: navTreeContext.onSelect,
909
+ onItemHover: navTreeContext.onItemHover
910
+ }))));
911
+ };
912
+ var L1PanelHeader = ({ item, path, onBack }) => {
913
+ const { t } = useTranslation4(meta.id);
914
+ const { renderItemEnd: ItemEnd } = useNavTreeContext();
915
+ const title = toLocalizedString4(item.properties.label, t);
916
+ const backCapableWorkspace = isPinnedWorkspace(item.id);
917
+ const { primaryAction, groupedActions, menuActions, onAction } = useL1MenuActions({
918
+ item,
919
+ path
920
+ });
921
+ useLoadDescendents(item);
922
+ const alternateTree = useAlternateTreeItem(item);
923
+ const attended = useAttended();
924
+ const alternateTreeOpen = useMemo6(() => {
925
+ if (!alternateTree) {
926
+ return true;
927
+ }
928
+ const hasAlternateAttended = attended.some((attendedId) => attendedId === alternateTree.id || attendedId.startsWith(alternateTree.id + "/"));
929
+ return !hasAlternateAttended;
930
+ }, [
931
+ alternateTree,
932
+ attended
933
+ ]);
934
+ return /* @__PURE__ */ React5.createElement("div", {
935
+ className: "flex w-full items-center border-b border-subdued-separator dx-app-drag dx-density-coarse pe-1"
936
+ }, backCapableWorkspace ? /* @__PURE__ */ React5.createElement(IconButton2, {
937
+ size: 5,
938
+ density: "coarse",
939
+ classNames: [
940
+ "shrink-0 px-2 pointer-fine:px-1",
941
+ hoverableControlItem2,
942
+ hoverableOpenControlItem2
943
+ ],
944
+ variant: "ghost",
945
+ icon: "ph--caret-left--regular",
946
+ iconOnly: true,
947
+ label: t("button back"),
948
+ "data-testid": "treeView.primaryTreeButton",
949
+ onClick: () => onBack?.()
950
+ }) : /* @__PURE__ */ React5.createElement("div", {
951
+ className: "w-6"
952
+ }), /* @__PURE__ */ React5.createElement("h2", {
953
+ className: "flex-1 truncate min-w-0"
954
+ }, title), /* @__PURE__ */ React5.createElement("div", {
955
+ role: "none",
956
+ className: "contents dx-app-no-drag"
957
+ }, primaryAction?.properties?.disposition === "list-item-primary" && !primaryAction?.properties?.disabled && /* @__PURE__ */ React5.createElement(NavTreeItemAction, {
958
+ testId: primaryAction.properties?.testId,
959
+ label: toLocalizedString4(primaryAction.properties?.label, t),
960
+ icon: primaryAction.properties?.icon ?? "ph--placeholder--regular",
961
+ parent: item,
962
+ path,
963
+ monolithic: Node4.isAction(primaryAction),
964
+ menuActions: Node4.isAction(primaryAction) ? [
965
+ primaryAction
966
+ ] : groupedActions[primaryAction?.id ?? ""],
967
+ menuType: primaryAction.properties?.menuType,
968
+ caller: NAV_TREE_ITEM
969
+ }), menuActions.length === 1 && /* @__PURE__ */ React5.createElement(IconButton2, {
970
+ size: 5,
971
+ density: "coarse",
972
+ classNames: [
973
+ "shrink-0 px-2 pointer-fine:px-1",
974
+ hoverableControlItem2,
975
+ hoverableOpenControlItem2
976
+ ],
977
+ variant: "ghost",
978
+ icon: menuActions[0].properties?.icon ?? "ph--placeholder--regular",
979
+ iconOnly: true,
980
+ label: toLocalizedString4(menuActions[0].properties?.label, t),
981
+ "data-testid": menuActions[0].properties?.testId,
982
+ onClick: () => onAction(menuActions[0])
983
+ }), menuActions.length > 1 && /* @__PURE__ */ React5.createElement(Menu3.Root, {
984
+ caller: NAV_TREE_ITEM,
985
+ onAction
986
+ }, /* @__PURE__ */ React5.createElement(Menu3.Trigger, {
987
+ asChild: true
988
+ }, /* @__PURE__ */ React5.createElement(IconButton2, {
989
+ size: 5,
990
+ density: "coarse",
991
+ classNames: [
992
+ "shrink-0 px-2 pointer-fine:px-1",
993
+ hoverableControlItem2,
994
+ hoverableOpenControlItem2
995
+ ],
996
+ variant: "ghost",
997
+ icon: "ph--dots-three-vertical--regular",
998
+ iconOnly: true,
999
+ label: t("tree item actions label"),
1000
+ "data-testid": "navtree.treeItem.actionsLevel0"
1001
+ })), /* @__PURE__ */ React5.createElement(Menu3.Content, {
1002
+ group: item,
1003
+ items: menuActions
1004
+ })), ItemEnd && /* @__PURE__ */ React5.createElement(ItemEnd, {
1005
+ node: item,
1006
+ open: alternateTreeOpen
1007
+ })));
1008
+ };
1009
+ var useL1MenuActions = ({ item, path }) => {
1010
+ const { t } = useTranslation4(meta.id);
1011
+ const { setAlternateTree } = useNavTreeContext();
1012
+ const { graph } = useAppGraph4();
1013
+ const runAction = useActionRunner3();
1014
+ const alternateTree = useAlternateTreeItem(item);
1015
+ const alternatePath = useMemo6(() => [
1016
+ ...path,
1017
+ item.id
1018
+ ], [
1019
+ item.id,
1020
+ path
1021
+ ]);
1022
+ const isAlternate = useIsAlternateTree(alternatePath, item);
1023
+ const { actions: actionsProp, groupedActions } = useActions(item);
1024
+ const [primaryAction, ...secondaryActions] = actionsProp.toSorted((a, _b) => a.properties?.disposition === "list-item-primary" ? -1 : 1);
1025
+ const graphMenuActions = (primaryAction?.properties?.disposition === "list-item-primary" ? secondaryActions : actionsProp).flatMap((action) => Node4.isAction(action) ? [
1026
+ action
1027
+ ] : []).filter((a) => [
1028
+ "list-item",
1029
+ "list-item-primary"
1030
+ ].includes(a.properties?.disposition));
1031
+ const settingsActionId = `${item.id}~settings`;
1032
+ const settingsAction = useMemo6(() => {
1033
+ if (!alternateTree) {
1034
+ return void 0;
1035
+ }
1036
+ return {
1037
+ id: settingsActionId,
1038
+ type: Node4.ActionType,
1039
+ data: () => Effect.void,
1040
+ properties: {
1041
+ label: isAlternate ? [
1042
+ "button back",
1043
+ {
1044
+ ns: meta.id
1045
+ }
1046
+ ] : alternateTree.properties.label ?? alternateTree.id,
1047
+ icon: isAlternate ? "ph--arrow-u-down-left--regular" : alternateTree.properties.icon ?? "ph--placeholder--regular",
1048
+ disposition: "list-item",
1049
+ testId: isAlternate ? "navtree.backToSpace" : "navtree.spaceSettings"
1050
+ }
1051
+ };
1052
+ }, [
1053
+ alternateTree,
1054
+ isAlternate,
1055
+ settingsActionId,
1056
+ t
1057
+ ]);
1058
+ const menuActions = useMemo6(() => [
1059
+ ...graphMenuActions,
1060
+ ...settingsAction ? [
1061
+ settingsAction
1062
+ ] : []
1063
+ ], [
1064
+ graphMenuActions,
1065
+ settingsAction
1066
+ ]);
1067
+ const onAction = useCallback3((action, params) => {
1068
+ if (action.id === settingsActionId) {
1069
+ if (alternateTree && !isAlternate) {
1070
+ Graph4.expand(graph, alternateTree.id, "child");
1071
+ }
1072
+ setAlternateTree?.(alternatePath, !isAlternate);
1073
+ } else {
1074
+ void runAction(action, {
1075
+ ...params,
1076
+ path
1077
+ });
1078
+ }
1079
+ }, [
1080
+ settingsActionId,
1081
+ setAlternateTree,
1082
+ alternatePath,
1083
+ isAlternate,
1084
+ runAction,
1085
+ graph,
1086
+ alternateTree,
1087
+ path
1088
+ ]);
1089
+ return {
1090
+ primaryAction,
1091
+ groupedActions,
1092
+ menuActions,
1093
+ onAction
1094
+ };
1095
+ };
1096
+ var useAlternateTreeItem = (item) => {
1097
+ const { graph } = useAppGraph4();
1098
+ const connections = useConnections(graph, item.id, "child");
1099
+ return connections.find((node) => node.properties.disposition === "alternate-tree");
1100
+ };
1101
+ var L1Panel = /* @__PURE__ */ memo3(L1Panel$);
1102
+
1103
+ // src/components/Sidebar/L1Tabs.tsx
1104
+ import React6 from "react";
1105
+ var L1Tabs = ({ topLevelItems, currentItemId, onBack, open, path }) => {
1106
+ return /* @__PURE__ */ React6.createElement(React6.Fragment, null, topLevelItems.map((item) => {
1107
+ const type = l0ItemType(item);
1108
+ if (type === "tab") {
1109
+ return /* @__PURE__ */ React6.createElement(L1Panel, {
1110
+ key: item.id,
1111
+ item,
1112
+ path,
1113
+ open,
1114
+ onBack,
1115
+ isCurrent: item.id === currentItemId
1116
+ });
1117
+ }
1118
+ return null;
1119
+ }));
1120
+ };
1121
+
1122
+ // src/components/NavTree/NavTree.tsx
1123
+ var NAV_TREE_ITEM = "NavTreeItem";
1124
+ var NavTree = /* @__PURE__ */ forwardRef2(({ id, root, tab, ...props }, forwardedRef) => {
1125
+ const { onBack, onItemHover } = useNavTreeContext();
1126
+ const { topLevelActions, l0Items, pinnedItems, userAccountItem, topLevelItems } = useTopLevelNavItems(root);
1127
+ useLoadDescendents(root);
1128
+ const path = useMemo7(() => [
1129
+ id
1130
+ ], [
1131
+ id
1132
+ ]);
1133
+ return (
1134
+ // TODO(thure): `Tabs.Root` forces all items that should be able to receive focus to use `Tabs.Tab(Primitive)` since
1135
+ // it uses RovingFocus and doesn't support moving focus to an item that is not a tab. Assess whether this situation
1136
+ // should change including whether it should motivate a change in the design/taxonomy, or if this means this should
1137
+ // not use `react-ui-tabs` at all.
1138
+ /* @__PURE__ */ React7.createElement(Tabs3.Root, {
1139
+ value: tab,
1140
+ orientation: "vertical",
1141
+ verticalVariant: "stateless",
1142
+ classNames: "relative",
1143
+ ref: forwardedRef
1144
+ }, /* @__PURE__ */ React7.createElement(L0Menu, {
1145
+ menuActions: topLevelActions,
1146
+ topLevelItems: l0Items,
1147
+ pinnedItems,
1148
+ userAccountItem,
1149
+ path,
1150
+ parent: root,
1151
+ onItemHover
1152
+ }), /* @__PURE__ */ React7.createElement(L1Tabs, {
1153
+ topLevelItems,
1154
+ path,
1155
+ currentItemId: tab,
1156
+ onBack,
1157
+ ...props
1158
+ }))
1159
+ );
1160
+ });
1161
+ var useTopLevelNavItems = (root) => {
1162
+ const { graph } = useAppGraph5();
1163
+ const rootId = root?.id ?? Node5.RootId;
1164
+ const rootOutboundItems = useConnections2(graph, rootId, "child");
1165
+ const rootActions = useGraphActions2(graph, rootId);
1166
+ const { topLevelActions, l0Items, pinnedItems, userAccountItem } = useMemo7(() => {
1167
+ const topLevelWorkspaces = [];
1168
+ const outboundPinnedItems = [];
1169
+ let userAccountItem2;
1170
+ for (const node of rootOutboundItems) {
1171
+ switch (node.properties.disposition) {
1172
+ case "workspace":
1173
+ topLevelWorkspaces.push(node);
1174
+ break;
1175
+ case "pin-end":
1176
+ outboundPinnedItems.push(node);
1177
+ break;
1178
+ case "user-account":
1179
+ userAccountItem2 ??= node;
1180
+ break;
1181
+ }
1182
+ }
1183
+ const topLevelActions2 = rootActions.filter((action) => action.properties.disposition === "menu").toSorted((a, b) => byPosition(a.properties, b.properties));
1184
+ const pinnedItems2 = [
1185
+ ...outboundPinnedItems,
1186
+ ...rootActions.filter((action) => action.properties.disposition === "pin-end")
1187
+ ].toSorted((a, b) => byPosition(a.properties, b.properties));
1188
+ return {
1189
+ topLevelActions: topLevelActions2,
1190
+ l0Items: topLevelWorkspaces,
1191
+ pinnedItems: pinnedItems2,
1192
+ userAccountItem: userAccountItem2
1193
+ };
1194
+ }, [
1195
+ rootActions,
1196
+ rootOutboundItems
1197
+ ]);
1198
+ const topLevelItems = useMemo7(() => [
1199
+ ...l0Items,
1200
+ ...pinnedItems,
1201
+ ...userAccountItem ? [
1202
+ userAccountItem
1203
+ ] : []
1204
+ ], [
1205
+ l0Items,
1206
+ pinnedItems,
1207
+ userAccountItem
1208
+ ]);
1209
+ return {
1210
+ topLevelActions,
1211
+ l0Items,
1212
+ pinnedItems,
1213
+ userAccountItem,
1214
+ topLevelItems
1215
+ };
1216
+ };
1217
+
1218
+ // src/containers/NavTreeContainer/NavTreeContainer.tsx
1219
+ var NODE_TYPE = "dxos/app-graph/node";
1220
+ var NavTreeItemEnd = ({ node, open }) => {
1221
+ const data = useMemo8(() => ({
1222
+ id: node.id,
1223
+ subject: node.data,
1224
+ open
1225
+ }), [
1226
+ node.id,
1227
+ node.data,
1228
+ open
1229
+ ]);
1230
+ return /* @__PURE__ */ React8.createElement(Surface.Surface, {
1231
+ role: "navtree-item-end",
1232
+ data,
1233
+ limit: 1
1234
+ });
1235
+ };
1236
+ var getItems = (graph, node, disposition) => {
1237
+ return Graph5.getConnections(graph, node?.id ?? Node6.RootId, "child").filter((node2) => filterItems(node2, disposition));
1238
+ };
1239
+ var NavTreeContainer$ = /* @__PURE__ */ forwardRef3(({ tab, popoverAnchorId }, forwardedRef) => {
1240
+ const [isLg] = useMediaQuery2("lg");
1241
+ const { invokeSync, invokePromise } = useOperationInvoker();
1242
+ const runAction = useActionRunner4();
1243
+ const { graph } = useAppGraph6();
1244
+ const { getItem, setItem } = useNavTreeState();
1245
+ const layout = useLayout();
1246
+ const model = useNavTreeModel(Node6.RootId);
1247
+ const { navigationSidebarState } = useSidebars(meta.id);
1248
+ const latestRef = useRef2({
1249
+ tab,
1250
+ activeItems: layout.active,
1251
+ navigationSidebarState,
1252
+ isLg
1253
+ });
1254
+ useEffect2(() => {
1255
+ latestRef.current = {
1256
+ tab,
1257
+ activeItems: layout.active,
1258
+ navigationSidebarState,
1259
+ isLg
1260
+ };
1261
+ }, [
1262
+ tab,
1263
+ layout.active,
1264
+ navigationSidebarState,
1265
+ isLg
1266
+ ]);
1267
+ const handleOpenChange = useCallback4(({ item: { id }, path, open }) => {
1268
+ setItem(path, "open", open);
1269
+ Graph5.expand(graph, id, "child");
1270
+ }, [
1271
+ graph,
1272
+ setItem
1273
+ ]);
1274
+ const handleTabChange = useCallback4((node) => {
1275
+ Graph5.expand(graph, node.id, "child");
1276
+ const { tab: activeTab, activeItems, navigationSidebarState: currentSidebarState, isLg: latestIsLg } = latestRef.current;
1277
+ invokeSync(LayoutOperation.UpdateSidebar, {
1278
+ state: node.id === activeTab ? currentSidebarState === "expanded" ? latestIsLg ? "collapsed" : "closed" : "expanded" : "expanded"
1279
+ });
1280
+ invokeSync(LayoutOperation.SwitchWorkspace, {
1281
+ subject: node.id
1282
+ });
1283
+ if (activeItems.length === 0) {
1284
+ const [item] = getItems(graph, node).filter((node2) => !Node6.isActionLike(node2));
1285
+ if (item && item.data) {
1286
+ invokeSync(LayoutOperation.Open, {
1287
+ subject: [
1288
+ item.id
1289
+ ]
1290
+ });
1291
+ }
1292
+ }
1293
+ }, [
1294
+ invokeSync,
1295
+ graph
1296
+ ]);
1297
+ const blockInstruction = useCallback4(({ instruction, source, target }) => {
1298
+ return target.item.properties.blockInstruction?.(source, instruction) ?? false;
1299
+ }, []);
1300
+ const canDrop = useCallback4(({ source, target }) => {
1301
+ return target.item.properties.canDrop?.(source) ?? false;
1302
+ }, []);
1303
+ const canSelect = useCallback4(({ item }) => {
1304
+ return item.properties.selectable ?? true;
1305
+ }, []);
1306
+ const handleSelect = useCallback4(({ item: node, path, option }) => {
1307
+ if (!node.data) {
1308
+ return;
1309
+ }
1310
+ if (Node6.isAction(node)) {
1311
+ const [parent] = Graph5.getConnections(graph, node.id, Node6.childRelation("inbound"));
1312
+ if (parent) {
1313
+ void runAction(node, {
1314
+ parent,
1315
+ path,
1316
+ caller: NAV_TREE_ITEM
1317
+ });
1318
+ }
1319
+ return;
1320
+ }
1321
+ const current = getItem(path).current;
1322
+ if (!current) {
1323
+ invokeSync(LayoutOperation.Open, {
1324
+ subject: [
1325
+ node.id
1326
+ ],
1327
+ key: node.properties.key
1328
+ });
1329
+ } else if (option) {
1330
+ invokeSync(LayoutOperation.Close, {
1331
+ subject: [
1332
+ node.id
1333
+ ]
1334
+ });
1335
+ } else {
1336
+ void invokePromise(LayoutOperation.ScrollIntoView, {
1337
+ subject: node.id
1338
+ });
1339
+ }
1340
+ const defaultAction = Graph5.getActions(graph, node.id).find((action) => action.properties?.disposition === "default");
1341
+ if (Node6.isAction(defaultAction)) {
1342
+ void runAction(defaultAction);
1343
+ }
1344
+ if (!isLg) {
1345
+ invokeSync(LayoutOperation.UpdateSidebar, {
1346
+ state: "closed"
1347
+ });
1348
+ }
1349
+ }, [
1350
+ graph,
1351
+ invokeSync,
1352
+ invokePromise,
1353
+ getItem,
1354
+ runAction,
1355
+ isLg
1356
+ ]);
1357
+ const handleBack = useCallback4(() => invokeSync(LayoutOperation.RevertWorkspace), [
1358
+ invokeSync
1359
+ ]);
1360
+ useEffect2(() => {
1361
+ return monitorForElements({
1362
+ canMonitor: ({ source }) => isTreeData(source.data),
1363
+ onDrop: ({ location, source }) => {
1364
+ if (!location.current.dropTargets.length) {
1365
+ return;
1366
+ }
1367
+ const target = location.current.dropTargets[0];
1368
+ const instruction = extractInstruction(target.data);
1369
+ if (instruction !== null && instruction.type !== "instruction-blocked") {
1370
+ const sourceNode = source.data.item;
1371
+ const targetNode = target.data.item;
1372
+ const sourcePath = source.data.path;
1373
+ const targetPath = target.data.path;
1374
+ const sameParent = sourcePath.slice(0, -1).join() === targetPath.slice(0, -1).join();
1375
+ const operation = sameParent && instruction.type !== "make-child" ? "rearrange" : resolveMigrationOperation(graph, sourceNode, targetPath, targetNode);
1376
+ const sourceParent = getParent(graph, sourceNode, sourcePath);
1377
+ const targetParent = getParent(graph, targetNode, targetPath);
1378
+ const sourceItems = getItems(graph, sourceParent);
1379
+ const targetItems = getItems(graph, targetParent);
1380
+ const sourceIndex = sourceItems.findIndex(({ id }) => id === sourceNode.id);
1381
+ const targetIndex = targetItems.findIndex(({ id }) => id === targetNode.id);
1382
+ const migrationIndex = instruction.type === "make-child" ? void 0 : instruction.type === "reorder-below" ? targetIndex + 1 : targetIndex;
1383
+ switch (operation) {
1384
+ case "rearrange": {
1385
+ const nextItems = sourceItems.map(({ data }) => data);
1386
+ arrayMove2(nextItems, sourceIndex, targetIndex);
1387
+ void sourceNode.properties.onRearrange?.(nextItems);
1388
+ break;
1389
+ }
1390
+ case "copy": {
1391
+ const target2 = instruction.type === "make-child" ? targetNode : targetParent;
1392
+ void target2?.properties.onCopy?.(sourceNode, migrationIndex);
1393
+ break;
1394
+ }
1395
+ case "transfer": {
1396
+ const target2 = instruction.type === "make-child" ? targetNode : targetParent;
1397
+ if (!target2?.properties.onTransferStart || target2?.id === sourceParent?.id) {
1398
+ break;
1399
+ }
1400
+ void target2?.properties.onTransferStart(sourceNode, migrationIndex);
1401
+ void sourceParent?.properties.onTransferEnd?.(sourceNode, target2);
1402
+ break;
1403
+ }
1404
+ }
1405
+ }
1406
+ }
1407
+ });
1408
+ }, [
1409
+ graph
1410
+ ]);
1411
+ const setAlternateTree = useCallback4((path, open) => {
1412
+ setItem(path, "alternateTree", open);
1413
+ }, [
1414
+ setItem
1415
+ ]);
1416
+ const onItemHover = useCallback4(({ item }) => Graph5.expand(graph, item.id, "child"), [
1417
+ graph
1418
+ ]);
1419
+ const navTreeContextValue = useMemo8(() => ({
1420
+ model,
1421
+ popoverAnchorId,
1422
+ renderItemEnd: NavTreeItemEnd,
1423
+ blockInstruction,
1424
+ canDrop,
1425
+ canSelect,
1426
+ setAlternateTree,
1427
+ onBack: handleBack,
1428
+ onOpenChange: handleOpenChange,
1429
+ onSelect: handleSelect,
1430
+ onTabChange: handleTabChange,
1431
+ onItemHover
1432
+ }), [
1433
+ model,
1434
+ popoverAnchorId,
1435
+ blockInstruction,
1436
+ canDrop,
1437
+ canSelect,
1438
+ setAlternateTree,
1439
+ handleBack,
1440
+ handleOpenChange,
1441
+ handleSelect,
1442
+ handleTabChange,
1443
+ onItemHover
1444
+ ]);
1445
+ return /* @__PURE__ */ React8.createElement(NavTreeContext.Provider, {
1446
+ value: navTreeContextValue
1447
+ }, /* @__PURE__ */ React8.createElement(NavTree, {
1448
+ id: Node6.RootId,
1449
+ root: Graph5.getRoot(graph),
1450
+ tab,
1451
+ open: layout.sidebarOpen,
1452
+ ref: forwardedRef
1453
+ }));
1454
+ });
1455
+ var NavTreeContainer = /* @__PURE__ */ memo4(NavTreeContainer$);
1456
+
1457
+ export {
1458
+ getParent,
1459
+ getPersistenceParent,
1460
+ resolveMigrationOperation,
1461
+ sortActions,
1462
+ getChildren,
1463
+ filterItems,
1464
+ l0ItemType,
1465
+ NODE_TYPE,
1466
+ NavTreeContainer
1467
+ };
1468
+ //# sourceMappingURL=chunk-JT37R5HS.mjs.map