@dxos/plugin-navtree 0.8.4-main.4a85c3132b → 0.8.4-main.51f1e5ca51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/index.mjs +115 -74
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/translations.mjs +21 -0
- package/dist/lib/browser/translations.mjs.map +7 -0
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +7 -5
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/keyboard.d.ts.map +1 -0
- package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
- package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
- package/dist/types/src/capabilities/{state/state.d.ts → state.d.ts} +1 -1
- package/dist/types/src/capabilities/state.d.ts.map +1 -0
- package/dist/types/src/components/NavTree/NavTree.d.ts.map +1 -1
- package/dist/types/src/components/NavTree/NavTree.stories.d.ts +9 -11
- package/dist/types/src/components/NavTree/NavTree.stories.d.ts.map +1 -1
- package/dist/types/src/components/{NavTreeContext.d.ts → NavTreeContext/NavTreeContext.d.ts} +1 -1
- package/dist/types/src/components/NavTreeContext/NavTreeContext.d.ts.map +1 -0
- package/dist/types/src/components/NavTreeContext/index.d.ts +2 -0
- package/dist/types/src/components/NavTreeContext/index.d.ts.map +1 -0
- package/dist/types/src/components/NavTreeItem/NavTreeItemAction.d.ts +7 -3
- package/dist/types/src/components/NavTreeItem/NavTreeItemAction.d.ts.map +1 -1
- package/dist/types/src/components/NavTreeItem/NavTreeItemAction.stories.d.ts +1 -1
- package/dist/types/src/components/NavTreeItem/NavTreeItemAction.stories.d.ts.map +1 -1
- package/dist/types/src/components/NavTreeItem/NavTreeItemColumns.d.ts.map +1 -1
- package/dist/types/src/components/Sidebar/L0Menu.d.ts.map +1 -1
- package/dist/types/src/components/Sidebar/L1Panel.d.ts.map +1 -1
- package/dist/types/src/components/Sidebar/L1Tabs.d.ts.map +1 -1
- package/dist/types/src/components/UserAccountAvatar/UserAccountAvatar.d.ts.map +1 -1
- package/dist/types/src/components/UserAccountAvatar/UserAccountAvatar.stories.d.ts.map +1 -1
- package/dist/types/src/components/types.d.ts +1 -2
- package/dist/types/src/components/types.d.ts.map +1 -1
- package/dist/types/src/containers/CommandsDialogContent/CommandsDialogContent.d.ts.map +1 -1
- package/dist/types/src/containers/CommandsDialogContent/CommandsDialogContent.stories.d.ts +28 -0
- package/dist/types/src/containers/CommandsDialogContent/CommandsDialogContent.stories.d.ts.map +1 -0
- package/dist/types/src/containers/CommandsDialogContent/index.d.ts +1 -2
- package/dist/types/src/containers/CommandsDialogContent/index.d.ts.map +1 -1
- package/dist/types/src/containers/CommandsTrigger/CommandsTrigger.d.ts.map +1 -1
- package/dist/types/src/containers/CommandsTrigger/index.d.ts +1 -2
- package/dist/types/src/containers/CommandsTrigger/index.d.ts.map +1 -1
- package/dist/types/src/containers/NavTreeContainer/NavTreeContainer.d.ts.map +1 -1
- package/dist/types/src/containers/NavTreeContainer/index.d.ts +2 -2
- package/dist/types/src/containers/NavTreeContainer/index.d.ts.map +1 -1
- package/dist/types/src/containers/NavTreeDocumentTitle/NavTreeDocumentTitle.d.ts.map +1 -1
- package/dist/types/src/containers/NavTreeDocumentTitle/index.d.ts +1 -2
- package/dist/types/src/containers/NavTreeDocumentTitle/index.d.ts.map +1 -1
- package/dist/types/src/containers/index.d.ts +1 -1
- package/dist/types/src/containers/index.d.ts.map +1 -1
- package/dist/types/src/experimental/Tree.d.ts +2 -2
- package/dist/types/src/experimental/Tree.d.ts.map +1 -1
- package/dist/types/src/experimental/Tree.stories.d.ts.map +1 -1
- package/dist/types/src/hooks/useActions.d.ts +2 -4
- package/dist/types/src/hooks/useActions.d.ts.map +1 -1
- package/dist/types/src/hooks/useLoadDescendents.d.ts.map +1 -1
- package/dist/types/src/hooks/useNavTreeModel.d.ts +1 -1
- package/dist/types/src/hooks/useNavTreeModel.d.ts.map +1 -1
- package/dist/types/src/hooks/useNavTreeState.d.ts +2 -6
- package/dist/types/src/hooks/useNavTreeState.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/operations/expose.d.ts +5 -0
- package/dist/types/src/operations/expose.d.ts.map +1 -0
- package/dist/types/src/operations/index.d.ts +3 -0
- package/dist/types/src/operations/index.d.ts.map +1 -0
- package/dist/types/src/testing/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/testing/generator.d.ts.map +1 -1
- package/dist/types/src/testing/update-state.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +8 -11
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/capabilities.d.ts +1 -2
- package/dist/types/src/types/capabilities.d.ts.map +1 -1
- package/dist/types/src/types/events.d.ts.map +1 -1
- package/dist/types/src/util.d.ts +2 -2
- package/dist/types/src/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +57 -43
- package/src/NavTreePlugin.tsx +7 -7
- package/src/capabilities/{app-graph-builder/app-graph-builder.ts → app-graph-builder.ts} +7 -7
- package/src/capabilities/index.ts +11 -5
- package/src/capabilities/{keyboard/keyboard.ts → keyboard.ts} +2 -2
- package/src/capabilities/operation-handler.ts +16 -0
- package/src/capabilities/{react-surface/react-surface.tsx → react-surface.tsx} +8 -8
- package/src/capabilities/{state/state.ts → state.ts} +5 -5
- package/src/components/NavTree/NavTree.stories.tsx +17 -16
- package/src/components/NavTree/NavTree.tsx +3 -2
- package/src/components/{NavTreeContext.tsx → NavTreeContext/NavTreeContext.tsx} +1 -1
- package/src/components/NavTreeContext/index.ts +5 -0
- package/src/components/NavTreeItem/NavTreeItemAction.stories.tsx +6 -8
- package/src/components/NavTreeItem/NavTreeItemAction.tsx +62 -45
- package/src/components/NavTreeItem/NavTreeItemColumns.tsx +7 -5
- package/src/components/Sidebar/L0Menu.tsx +49 -74
- package/src/components/Sidebar/L1Panel.tsx +97 -134
- package/src/components/Sidebar/L1Tabs.tsx +0 -1
- package/src/components/types.ts +1 -2
- package/src/containers/CommandsDialogContent/CommandsDialogContent.stories.tsx +46 -0
- package/src/containers/CommandsDialogContent/CommandsDialogContent.tsx +52 -58
- package/src/containers/CommandsDialogContent/index.ts +1 -3
- package/src/containers/CommandsTrigger/CommandsTrigger.tsx +7 -5
- package/src/containers/CommandsTrigger/index.ts +1 -3
- package/src/containers/NavTreeContainer/NavTreeContainer.tsx +28 -27
- package/src/containers/NavTreeContainer/index.ts +2 -3
- package/src/containers/NavTreeDocumentTitle/NavTreeDocumentTitle.tsx +2 -2
- package/src/containers/NavTreeDocumentTitle/index.ts +1 -3
- package/src/containers/index.ts +1 -1
- package/src/experimental/Tree.stories.tsx +27 -27
- package/src/hooks/useActions.ts +18 -22
- package/src/hooks/useNavTreeModel.ts +10 -4
- package/src/hooks/useNavTreeState.ts +2 -9
- package/src/meta.ts +2 -2
- package/src/operations/expose.ts +42 -0
- package/src/operations/index.ts +7 -0
- package/src/testing/app-graph-builder.ts +40 -36
- package/src/testing/generator.ts +22 -22
- package/src/translations.ts +8 -10
- package/src/types/capabilities.ts +4 -4
- package/src/types/events.ts +1 -1
- package/src/util.ts +2 -2
- package/dist/lib/browser/CommandsDialogContent-A27AKTHH.mjs +0 -111
- package/dist/lib/browser/CommandsDialogContent-A27AKTHH.mjs.map +0 -7
- package/dist/lib/browser/CommandsTrigger-HBZYQCGV.mjs +0 -33
- package/dist/lib/browser/CommandsTrigger-HBZYQCGV.mjs.map +0 -7
- package/dist/lib/browser/NavTreeContainer-B5K4FUJS.mjs +0 -12
- package/dist/lib/browser/NavTreeContainer-B5K4FUJS.mjs.map +0 -7
- package/dist/lib/browser/NavTreeDocumentTitle-GEE3URWH.mjs +0 -26
- package/dist/lib/browser/NavTreeDocumentTitle-GEE3URWH.mjs.map +0 -7
- package/dist/lib/browser/app-graph-builder-XGA4GPGL.mjs +0 -44
- package/dist/lib/browser/app-graph-builder-XGA4GPGL.mjs.map +0 -7
- package/dist/lib/browser/chunk-DQCYMXEU.mjs +0 -1426
- package/dist/lib/browser/chunk-DQCYMXEU.mjs.map +0 -7
- package/dist/lib/browser/chunk-H3OJ4WLF.mjs +0 -14
- package/dist/lib/browser/chunk-H3OJ4WLF.mjs.map +0 -7
- package/dist/lib/browser/chunk-X2HDG62A.mjs +0 -23
- package/dist/lib/browser/chunk-X2HDG62A.mjs.map +0 -7
- package/dist/lib/browser/chunk-YKTYPINZ.mjs +0 -19
- package/dist/lib/browser/chunk-YKTYPINZ.mjs.map +0 -7
- package/dist/lib/browser/keyboard-OJZC54PK.mjs +0 -54
- package/dist/lib/browser/keyboard-OJZC54PK.mjs.map +0 -7
- package/dist/lib/browser/operation-resolver-BNAMYOHF.mjs +0 -53
- package/dist/lib/browser/operation-resolver-BNAMYOHF.mjs.map +0 -7
- package/dist/lib/browser/react-surface-AYHOAJ4I.mjs +0 -59
- package/dist/lib/browser/react-surface-AYHOAJ4I.mjs.map +0 -7
- package/dist/lib/browser/state-AC3EETN7.mjs +0 -131
- package/dist/lib/browser/state-AC3EETN7.mjs.map +0 -7
- package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts.map +0 -1
- package/dist/types/src/capabilities/app-graph-builder/index.d.ts +0 -3
- package/dist/types/src/capabilities/app-graph-builder/index.d.ts.map +0 -1
- package/dist/types/src/capabilities/keyboard/index.d.ts +0 -3
- package/dist/types/src/capabilities/keyboard/index.d.ts.map +0 -1
- package/dist/types/src/capabilities/keyboard/keyboard.d.ts.map +0 -1
- package/dist/types/src/capabilities/operation-resolver/index.d.ts +0 -3
- package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +0 -1
- package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +0 -5
- package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +0 -1
- package/dist/types/src/capabilities/react-surface/index.d.ts +0 -3
- package/dist/types/src/capabilities/react-surface/index.d.ts.map +0 -1
- package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +0 -1
- package/dist/types/src/capabilities/state/index.d.ts +0 -3
- package/dist/types/src/capabilities/state/index.d.ts.map +0 -1
- package/dist/types/src/capabilities/state/state.d.ts.map +0 -1
- package/dist/types/src/components/NavTreeContext.d.ts.map +0 -1
- package/src/capabilities/app-graph-builder/index.ts +0 -7
- package/src/capabilities/keyboard/index.ts +0 -7
- package/src/capabilities/operation-resolver/index.ts +0 -7
- package/src/capabilities/operation-resolver/operation-resolver.ts +0 -44
- package/src/capabilities/react-surface/index.ts +0 -7
- package/src/capabilities/state/index.ts +0 -7
- /package/dist/types/src/capabilities/{app-graph-builder/app-graph-builder.d.ts → app-graph-builder.d.ts} +0 -0
- /package/dist/types/src/capabilities/{keyboard/keyboard.d.ts → keyboard.d.ts} +0 -0
- /package/dist/types/src/capabilities/{react-surface/react-surface.d.ts → react-surface.d.ts} +0 -0
|
@@ -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 '
|
|
18
|
-
import { useNavTreeModel, useNavTreeState } from '
|
|
19
|
-
import { meta } from '
|
|
20
|
-
import { type NavTreeItemGraphNode } from '
|
|
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 {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
[
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
165
|
+
void invokePromise(LayoutOperation.UpdateSidebar, { state: 'closed' });
|
|
157
166
|
}
|
|
158
167
|
},
|
|
159
|
-
[graph,
|
|
168
|
+
[graph, invokePromise, getItem, runAction, isLg, layout.mode],
|
|
160
169
|
);
|
|
161
170
|
|
|
162
|
-
const handleBack = useCallback(() =>
|
|
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
|
-
|
|
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 ||
|
|
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,
|
|
@@ -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 '
|
|
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
|
|
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
|
};
|
package/src/containers/index.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { type ComponentType, lazy } from 'react';
|
|
6
6
|
|
|
7
|
-
export { NODE_TYPE } from './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 {
|
|
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
|
-
|
|
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:
|
|
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:
|
|
31
|
-
title:
|
|
30
|
+
id: random.string.uuid(),
|
|
31
|
+
title: random.commerce.productName(),
|
|
32
32
|
},
|
|
33
33
|
{
|
|
34
|
-
id:
|
|
35
|
-
title:
|
|
34
|
+
id: random.string.uuid(),
|
|
35
|
+
title: random.commerce.productName(),
|
|
36
36
|
},
|
|
37
37
|
{
|
|
38
|
-
id:
|
|
39
|
-
title:
|
|
38
|
+
id: random.string.uuid(),
|
|
39
|
+
title: random.commerce.productName(),
|
|
40
40
|
children: [
|
|
41
41
|
{
|
|
42
|
-
id:
|
|
43
|
-
title:
|
|
42
|
+
id: random.string.uuid(),
|
|
43
|
+
title: random.commerce.productName(),
|
|
44
44
|
children: [
|
|
45
45
|
{
|
|
46
|
-
id:
|
|
47
|
-
title:
|
|
46
|
+
id: random.string.uuid(),
|
|
47
|
+
title: random.commerce.productName(),
|
|
48
48
|
},
|
|
49
49
|
{
|
|
50
|
-
id:
|
|
51
|
-
title:
|
|
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:
|
|
61
|
-
title:
|
|
60
|
+
id: random.string.uuid(),
|
|
61
|
+
title: random.commerce.productName(),
|
|
62
62
|
iconName: 'ph--planet--regular',
|
|
63
63
|
children: [
|
|
64
64
|
{
|
|
65
|
-
id:
|
|
66
|
-
title:
|
|
65
|
+
id: random.string.uuid(),
|
|
66
|
+
title: random.commerce.productName(),
|
|
67
67
|
},
|
|
68
68
|
],
|
|
69
69
|
},
|
|
70
70
|
{
|
|
71
|
-
id:
|
|
72
|
-
title:
|
|
71
|
+
id: random.string.uuid(),
|
|
72
|
+
title: random.commerce.productName(),
|
|
73
73
|
iconName: 'ph--sailboat--regular',
|
|
74
74
|
},
|
|
75
75
|
{
|
|
76
|
-
id:
|
|
77
|
-
title:
|
|
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:
|
|
126
|
-
title:
|
|
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:
|
|
138
|
+
id: random.string.uuid(),
|
|
139
139
|
iconName: 'ph--planet--regular',
|
|
140
|
-
title:
|
|
140
|
+
title: random.commerce.productName(),
|
|
141
141
|
});
|
|
142
142
|
|
|
143
143
|
return { ...items };
|
package/src/hooks/useActions.ts
CHANGED
|
@@ -7,32 +7,28 @@ 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 '
|
|
10
|
+
import { type FlattenedActions } from '#types';
|
|
11
11
|
|
|
12
|
-
/**
|
|
13
|
-
* Returns flattened actions and grouped sub-actions for a given graph node.
|
|
14
|
-
*/
|
|
12
|
+
/** Returns flattened actions and grouped sub-actions for a given graph node. */
|
|
15
13
|
export const useActions = (node: Node.Node): FlattenedActions => {
|
|
16
14
|
const { graph } = useAppGraph();
|
|
17
15
|
const actions = useGraphActions(graph, node.id);
|
|
18
16
|
|
|
19
|
-
return useMemo(
|
|
20
|
-
(
|
|
21
|
-
|
|
22
|
-
(
|
|
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
|
-
}
|
|
17
|
+
return useMemo(() => {
|
|
18
|
+
return actions.reduce(
|
|
19
|
+
(acc: FlattenedActions, arg) => {
|
|
20
|
+
if (arg.properties.disposition === 'item') {
|
|
32
21
|
return acc;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
acc.actions.push(arg);
|
|
25
|
+
if (!Node.isAction(arg)) {
|
|
26
|
+
const actionGroup = Graph.getActions(graph, arg.id);
|
|
27
|
+
acc.groupedActions[arg.id] = actionGroup;
|
|
28
|
+
}
|
|
29
|
+
return acc;
|
|
30
|
+
},
|
|
31
|
+
{ actions: [], groupedActions: {} },
|
|
32
|
+
);
|
|
33
|
+
}, [actions]);
|
|
38
34
|
};
|
|
@@ -12,9 +12,9 @@ import { type Node } from '@dxos/plugin-graph';
|
|
|
12
12
|
import { Path, type TreeModel } from '@dxos/react-ui-list';
|
|
13
13
|
import { mx } from '@dxos/ui-theme';
|
|
14
14
|
|
|
15
|
-
import { type NavTreeItemGraphNode } from '
|
|
16
|
-
import { filterItems } from '../util';
|
|
15
|
+
import { type NavTreeItemGraphNode } from '#types';
|
|
17
16
|
|
|
17
|
+
import { filterItems } from '../util';
|
|
18
18
|
import { useNavTreeState } from './useNavTreeState';
|
|
19
19
|
|
|
20
20
|
// TODO(wittjosiah): Move companion/hidden nodes to their own edge categories so this filter is unnecessary.
|
|
@@ -40,10 +40,17 @@ const createItemPropsFamily = (graph: ReturnType<typeof useAppGraph>['graph']) =
|
|
|
40
40
|
: node.properties.role === 'branch'
|
|
41
41
|
? []
|
|
42
42
|
: undefined;
|
|
43
|
+
const parentId = path.length >= 2 ? path[path.length - 2] : undefined;
|
|
44
|
+
const parentNode = parentId ? Option.getOrElse(get(graph.node(parentId)), () => undefined) : undefined;
|
|
45
|
+
const droppable =
|
|
46
|
+
node.properties.droppable === false || parentNode?.properties.childrenDroppable === false ? false : undefined;
|
|
47
|
+
|
|
43
48
|
return {
|
|
44
49
|
id: node.id,
|
|
45
50
|
parentOf,
|
|
46
51
|
disabled: node.properties.disabled,
|
|
52
|
+
draggable: node.properties.draggable,
|
|
53
|
+
droppable,
|
|
47
54
|
label: node.properties.label ?? node.id,
|
|
48
55
|
className: mx(node.properties.className, node.properties.modified && 'italic'),
|
|
49
56
|
headingClassName: node.properties.headingClassName,
|
|
@@ -65,8 +72,7 @@ const createItemFamily = (graph: ReturnType<typeof useAppGraph>['graph']) =>
|
|
|
65
72
|
Atom.family((id: string) =>
|
|
66
73
|
Atom.make((get) => {
|
|
67
74
|
const node = Option.getOrElse(get(graph.node(id)), () => undefined);
|
|
68
|
-
|
|
69
|
-
return node && passed ? node : undefined;
|
|
75
|
+
return node && filterItems(node) ? node : undefined;
|
|
70
76
|
}).pipe(Atom.keepAlive),
|
|
71
77
|
);
|
|
72
78
|
|
|
@@ -7,12 +7,12 @@ import { useMemo } from 'react';
|
|
|
7
7
|
|
|
8
8
|
import { useCapability } from '@dxos/app-framework/ui';
|
|
9
9
|
|
|
10
|
-
import { NavTreeCapabilities } from '
|
|
10
|
+
import { NavTreeCapabilities } from '#types';
|
|
11
11
|
|
|
12
12
|
export type UseNavTreeStateResult = {
|
|
13
13
|
getItem: (path: string[]) => NavTreeCapabilities.NavTreeItemState;
|
|
14
14
|
getItemAtom: (path: string[]) => Atom.Atom<NavTreeCapabilities.NavTreeItemState>;
|
|
15
|
-
setItem: (path: string[], key: 'open' | 'current'
|
|
15
|
+
setItem: (path: string[], key: 'open' | 'current', next: boolean) => void;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
/**
|
|
@@ -33,10 +33,3 @@ export const useNavTreeItemState = (path: string[]): NavTreeCapabilities.NavTree
|
|
|
33
33
|
const atom = useMemo(() => getItemAtom(path), [getItemAtom, pathKey]);
|
|
34
34
|
return useAtomValue(atom);
|
|
35
35
|
};
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Hook that subscribes to the alternateTree state for a tree item.
|
|
39
|
-
*/
|
|
40
|
-
export const useIsAlternateTree = (path: string[], _item?: any): boolean => {
|
|
41
|
-
return useNavTreeItemState(path).alternateTree ?? false;
|
|
42
|
-
};
|
package/src/meta.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { type Plugin } from '@dxos/app-framework';
|
|
|
6
6
|
import { trim } from '@dxos/util';
|
|
7
7
|
|
|
8
8
|
export const meta: Plugin.Meta = {
|
|
9
|
-
id: 'dxos.
|
|
9
|
+
id: 'org.dxos.plugin.navtree',
|
|
10
10
|
name: 'Navtree',
|
|
11
11
|
description: trim`
|
|
12
12
|
Hierarchical navigation tree for browsing spaces, folders, and objects.
|
|
@@ -17,4 +17,4 @@ export const meta: Plugin.Meta = {
|
|
|
17
17
|
// TODO(wittjosiah): Factor out.
|
|
18
18
|
export const KEY_BINDING = 'KeyBinding';
|
|
19
19
|
// TODO(wittjosiah): Factor out.
|
|
20
|
-
export const COMMANDS_DIALOG = `${meta.id}
|
|
20
|
+
export const COMMANDS_DIALOG = `${meta.id}.commands-dialog`;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
import * as Option from 'effect/Option';
|
|
7
|
+
|
|
8
|
+
import { Capability } from '@dxos/app-framework';
|
|
9
|
+
import { AppCapabilities, LayoutOperation } from '@dxos/app-toolkit';
|
|
10
|
+
import { Operation } from '@dxos/compute';
|
|
11
|
+
import { log } from '@dxos/log';
|
|
12
|
+
import { Graph } from '@dxos/plugin-graph';
|
|
13
|
+
import { expandAttendableId } from '@dxos/react-ui-attention';
|
|
14
|
+
|
|
15
|
+
import { NavTreeCapabilities } from '../types';
|
|
16
|
+
|
|
17
|
+
const handler: Operation.WithHandler<typeof LayoutOperation.Expose> = LayoutOperation.Expose.pipe(
|
|
18
|
+
Operation.withHandler(
|
|
19
|
+
Effect.fnUntraced(function* ({ subject }) {
|
|
20
|
+
const { graph } = yield* Capability.get(AppCapabilities.AppGraph);
|
|
21
|
+
const { getItem, setItem } = yield* Capability.get(NavTreeCapabilities.State);
|
|
22
|
+
|
|
23
|
+
const prefixes = expandAttendableId(subject);
|
|
24
|
+
|
|
25
|
+
for (const qualifiedId of prefixes) {
|
|
26
|
+
Graph.expand(graph, qualifiedId, 'child');
|
|
27
|
+
|
|
28
|
+
const treePath = prefixes.slice(0, prefixes.indexOf(qualifiedId) + 1);
|
|
29
|
+
const state = getItem(treePath);
|
|
30
|
+
if (!state.open) {
|
|
31
|
+
setItem(treePath, 'open', true);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (Option.isNone(Graph.getNode(graph, subject))) {
|
|
36
|
+
log('Node not found after expansion', { subject });
|
|
37
|
+
}
|
|
38
|
+
}),
|
|
39
|
+
),
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
export default handler;
|