@dxos/plugin-navtree 0.8.4-main.3c1ae3b → 0.8.4-main.3eb6e50203
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/app-graph-builder-XGA4GPGL.mjs +44 -0
- package/dist/lib/browser/app-graph-builder-XGA4GPGL.mjs.map +7 -0
- package/dist/lib/browser/chunk-63YLDLLE.mjs +1373 -0
- package/dist/lib/browser/chunk-63YLDLLE.mjs.map +7 -0
- package/dist/lib/browser/chunk-X2HDG62A.mjs +23 -0
- package/dist/lib/browser/chunk-X2HDG62A.mjs.map +7 -0
- package/dist/lib/browser/{chunk-E6MZBCU5.mjs → chunk-YKTYPINZ.mjs} +1 -1
- package/dist/lib/browser/chunk-YKTYPINZ.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +83 -91
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/{keyboard-YJEK2HTH.mjs → keyboard-46XQHY2O.mjs} +18 -14
- package/dist/lib/browser/keyboard-46XQHY2O.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/operation-resolver-NNNDII45.mjs +53 -0
- package/dist/lib/browser/operation-resolver-NNNDII45.mjs.map +7 -0
- package/dist/lib/browser/{react-surface-RPXGIV45.mjs → react-surface-APSEG23H.mjs} +16 -14
- package/dist/lib/browser/react-surface-APSEG23H.mjs.map +7 -0
- package/dist/lib/browser/state-M5YUCIQU.mjs +121 -0
- package/dist/lib/browser/state-M5YUCIQU.mjs.map +7 -0
- package/dist/types/src/NavTreePlugin.d.ts +2 -1
- package/dist/types/src/NavTreePlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts +6 -0
- package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts.map +1 -0
- package/dist/types/src/capabilities/app-graph-builder/index.d.ts +3 -0
- package/dist/types/src/capabilities/app-graph-builder/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +5 -108
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/keyboard/index.d.ts +3 -0
- package/dist/types/src/capabilities/keyboard/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/keyboard/keyboard.d.ts +5 -0
- package/dist/types/src/capabilities/keyboard/keyboard.d.ts.map +1 -0
- package/dist/types/src/capabilities/operation-resolver/index.d.ts +3 -0
- package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +5 -0
- package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-surface/index.d.ts +3 -0
- package/dist/types/src/capabilities/react-surface/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-surface/react-surface.d.ts +5 -0
- package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +1 -0
- package/dist/types/src/capabilities/state/index.d.ts +3 -0
- package/dist/types/src/capabilities/state/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/state/state.d.ts +6 -0
- package/dist/types/src/capabilities/state/state.d.ts.map +1 -0
- package/dist/types/src/components/CommandsDialog/CommandsDialog.d.ts.map +1 -1
- package/dist/types/src/components/CommandsDialog/CommandsTrigger.d.ts.map +1 -1
- package/dist/types/src/components/NavTree/NavTree.d.ts +2 -2
- package/dist/types/src/components/NavTree/NavTree.d.ts.map +1 -1
- package/dist/types/src/components/NavTree/NavTree.stories.d.ts.map +1 -1
- package/dist/types/src/components/NavTreeContainer.d.ts.map +1 -1
- package/dist/types/src/components/NavTreeDocumentTitle.d.ts +1 -1
- package/dist/types/src/components/NavTreeDocumentTitle.d.ts.map +1 -1
- package/dist/types/src/components/NavTreeItem/NavTreeItemAction.d.ts +6 -6
- package/dist/types/src/components/NavTreeItem/NavTreeItemAction.d.ts.map +1 -1
- package/dist/types/src/components/NavTreeItem/NavTreeItemAction.stories.d.ts +2 -1
- package/dist/types/src/components/NavTreeItem/NavTreeItemAction.stories.d.ts.map +1 -1
- package/dist/types/src/components/Sidebar/L0Menu.d.ts +4 -4
- package/dist/types/src/components/Sidebar/L0Menu.d.ts.map +1 -1
- package/dist/types/src/components/Sidebar/L1Panel.d.ts +2 -2
- package/dist/types/src/components/Sidebar/L1Panel.d.ts.map +1 -1
- package/dist/types/src/components/Sidebar/L1Tabs.d.ts +2 -2
- package/dist/types/src/components/Sidebar/L1Tabs.d.ts.map +1 -1
- package/dist/types/src/components/types.d.ts +7 -7
- package/dist/types/src/components/types.d.ts.map +1 -1
- package/dist/types/src/experimental/Tree.stories.d.ts +18 -4
- package/dist/types/src/experimental/Tree.stories.d.ts.map +1 -1
- package/dist/types/src/hooks.d.ts +32 -1
- package/dist/types/src/hooks.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +2 -2
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/testing/app-graph-builder.d.ts +2 -3
- package/dist/types/src/testing/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/testing/generator.d.ts +5 -6
- package/dist/types/src/testing/generator.d.ts.map +1 -1
- package/dist/types/src/testing/update-state.d.ts +2 -2
- package/dist/types/src/testing/update-state.d.ts.map +1 -1
- package/dist/types/src/types/capabilities.d.ts +16 -0
- package/dist/types/src/types/capabilities.d.ts.map +1 -0
- package/dist/types/src/types/events.d.ts +5 -0
- package/dist/types/src/types/events.d.ts.map +1 -0
- package/dist/types/src/types/index.d.ts +4 -0
- package/dist/types/src/types/index.d.ts.map +1 -0
- package/dist/types/src/{types.d.ts → types/schema.d.ts} +6 -6
- package/dist/types/src/types/schema.d.ts.map +1 -0
- package/dist/types/src/util.d.ts +7 -7
- package/dist/types/src/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +54 -52
- package/src/NavTreePlugin.tsx +53 -72
- package/src/capabilities/app-graph-builder/app-graph-builder.ts +42 -0
- package/src/capabilities/app-graph-builder/index.ts +7 -0
- package/src/capabilities/index.ts +5 -9
- package/src/capabilities/keyboard/index.ts +7 -0
- package/src/capabilities/keyboard/keyboard.ts +66 -0
- package/src/capabilities/operation-resolver/index.ts +7 -0
- package/src/capabilities/operation-resolver/operation-resolver.ts +42 -0
- package/src/capabilities/react-surface/index.ts +7 -0
- package/src/capabilities/react-surface/react-surface.tsx +55 -0
- package/src/capabilities/state/index.ts +7 -0
- package/src/capabilities/state/state.ts +122 -0
- package/src/components/CommandsDialog/CommandsDialog.tsx +62 -64
- package/src/components/CommandsDialog/CommandsTrigger.tsx +4 -14
- package/src/components/NavTree/NavTree.stories.tsx +35 -43
- package/src/components/NavTree/NavTree.tsx +1 -11
- package/src/components/NavTreeContainer.tsx +70 -114
- package/src/components/NavTreeDocumentTitle.tsx +3 -2
- package/src/components/NavTreeItem/NavTreeItemAction.stories.tsx +17 -7
- package/src/components/NavTreeItem/NavTreeItemAction.tsx +18 -12
- package/src/components/NavTreeItem/NavTreeItemColumns.tsx +5 -5
- package/src/components/Sidebar/L0Menu.tsx +67 -96
- package/src/components/Sidebar/L1Panel.tsx +151 -70
- package/src/components/Sidebar/L1Tabs.tsx +6 -31
- package/src/components/UserAccountAvatar/UserAccountAvatar.stories.tsx +1 -1
- package/src/components/types.ts +7 -7
- package/src/experimental/Tree.stories.tsx +44 -50
- package/src/experimental/Tree.tsx +1 -1
- package/src/hooks.ts +54 -2
- package/src/index.ts +1 -2
- package/src/meta.ts +2 -2
- package/src/testing/app-graph-builder.ts +158 -234
- package/src/testing/generator.ts +12 -12
- package/src/testing/update-state.ts +6 -6
- package/src/types/capabilities.ts +21 -0
- package/src/types/events.ts +12 -0
- package/src/types/index.ts +7 -0
- package/src/{types.ts → types/schema.ts} +5 -5
- package/src/util.ts +13 -16
- package/dist/lib/browser/app-graph-builder-OHSCN3GX.mjs +0 -46
- package/dist/lib/browser/app-graph-builder-OHSCN3GX.mjs.map +0 -7
- package/dist/lib/browser/chunk-5DWDYPGQ.mjs +0 -1492
- package/dist/lib/browser/chunk-5DWDYPGQ.mjs.map +0 -7
- package/dist/lib/browser/chunk-5VLWX4PK.mjs +0 -15
- package/dist/lib/browser/chunk-5VLWX4PK.mjs.map +0 -7
- package/dist/lib/browser/chunk-E6MZBCU5.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-YUVXVPHG.mjs +0 -47
- package/dist/lib/browser/intent-resolver-YUVXVPHG.mjs.map +0 -7
- package/dist/lib/browser/keyboard-YJEK2HTH.mjs.map +0 -7
- package/dist/lib/browser/react-surface-RPXGIV45.mjs.map +0 -7
- package/dist/lib/browser/state-BFD5KJCV.mjs +0 -117
- package/dist/lib/browser/state-BFD5KJCV.mjs.map +0 -7
- package/dist/types/src/capabilities/app-graph-builder.d.ts +0 -4
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +0 -1
- package/dist/types/src/capabilities/capabilities.d.ts +0 -21
- package/dist/types/src/capabilities/capabilities.d.ts.map +0 -1
- package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
- package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
- package/dist/types/src/capabilities/keyboard.d.ts +0 -4
- package/dist/types/src/capabilities/keyboard.d.ts.map +0 -1
- package/dist/types/src/capabilities/react-surface.d.ts +0 -4
- package/dist/types/src/capabilities/react-surface.d.ts.map +0 -1
- package/dist/types/src/capabilities/state.d.ts +0 -20
- package/dist/types/src/capabilities/state.d.ts.map +0 -1
- package/dist/types/src/events.d.ts +0 -4
- package/dist/types/src/events.d.ts.map +0 -1
- package/dist/types/src/types.d.ts.map +0 -1
- package/src/capabilities/app-graph-builder.ts +0 -53
- package/src/capabilities/capabilities.ts +0 -20
- package/src/capabilities/intent-resolver.ts +0 -37
- package/src/capabilities/keyboard.ts +0 -57
- package/src/capabilities/react-surface.tsx +0 -48
- package/src/capabilities/state.ts +0 -104
- package/src/events.ts +0 -11
|
@@ -4,20 +4,20 @@
|
|
|
4
4
|
|
|
5
5
|
import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
|
|
6
6
|
import { type Instruction, extractInstruction } from '@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item';
|
|
7
|
-
import { untracked } from '@preact/signals-core';
|
|
8
7
|
import React, { forwardRef, memo, useCallback, useEffect, useMemo } from 'react';
|
|
9
8
|
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
9
|
+
import { Surface, useOperationInvoker } from '@dxos/app-framework/ui';
|
|
10
|
+
import { LayoutOperation } from '@dxos/app-toolkit';
|
|
11
|
+
import { useAppGraph, useLayout } from '@dxos/app-toolkit/ui';
|
|
13
12
|
import { PLANK_COMPANION_TYPE } from '@dxos/plugin-deck/types';
|
|
13
|
+
import { Graph, Node, useActionRunner } from '@dxos/plugin-graph';
|
|
14
14
|
import { useConnections, useActions as useGraphActions } from '@dxos/plugin-graph';
|
|
15
15
|
import { useMediaQuery, useSidebars } from '@dxos/react-ui';
|
|
16
16
|
import { type TreeData, type TreeItemDataProps, isTreeData } from '@dxos/react-ui-list';
|
|
17
|
-
import { mx } from '@dxos/
|
|
17
|
+
import { mx } from '@dxos/ui-theme';
|
|
18
18
|
import { arrayMove, byPosition } from '@dxos/util';
|
|
19
19
|
|
|
20
|
-
import {
|
|
20
|
+
import { useIsAlternateTree, useIsCurrent, useIsOpen, useNavTreeState } from '../hooks';
|
|
21
21
|
import { meta } from '../meta';
|
|
22
22
|
import { type FlattenedActions, type NavTreeItemGraphNode } from '../types';
|
|
23
23
|
import { getChildren, getParent, resolveMigrationOperation } from '../util';
|
|
@@ -29,38 +29,38 @@ import { type NavTreeContextValue } from './types';
|
|
|
29
29
|
// TODO(thure): Is NavTree truly authoritative in this regard?
|
|
30
30
|
export const NODE_TYPE = 'dxos/app-graph/node';
|
|
31
31
|
|
|
32
|
-
const renderItemEnd = ({ node, open }: { node: Node; open: boolean }) => (
|
|
33
|
-
<Surface role='navtree-item-end' data={{ id: node.id, subject: node.data, open }} limit={1} />
|
|
32
|
+
const renderItemEnd = ({ node, open }: { node: Node.Node; open: boolean }) => (
|
|
33
|
+
<Surface.Surface role='navtree-item-end' data={{ id: node.id, subject: node.data, open }} limit={1} />
|
|
34
34
|
);
|
|
35
35
|
|
|
36
|
-
const getChildrenFilter = (node: Node): node is Node =>
|
|
37
|
-
|
|
38
|
-
() => !isActionLike(node) && node.type !== PLANK_COMPANION_TYPE && node.properties.disposition !== 'hidden',
|
|
39
|
-
);
|
|
36
|
+
const getChildrenFilter = (node: Node.Node): node is Node.Node =>
|
|
37
|
+
!Node.isActionLike(node) && node.type !== PLANK_COMPANION_TYPE && node.properties.disposition !== 'hidden';
|
|
40
38
|
|
|
41
|
-
const filterItems = (node: Node, disposition?: string) => {
|
|
39
|
+
const filterItems = (node: Node.Node, disposition?: string) => {
|
|
42
40
|
if (!disposition && (node.properties.disposition === 'hidden' || node.properties.disposition === 'alternate-tree')) {
|
|
43
41
|
return false;
|
|
44
42
|
} else if (!disposition) {
|
|
45
|
-
const action = isAction(node);
|
|
43
|
+
const action = Node.isAction(node);
|
|
46
44
|
return !action || node.properties.disposition === 'item';
|
|
47
45
|
} else {
|
|
48
46
|
return node.properties.disposition === disposition;
|
|
49
47
|
}
|
|
50
48
|
};
|
|
51
49
|
|
|
52
|
-
const getItems = (graph: ReadableGraph, node?: Node, disposition?: string) => {
|
|
53
|
-
return
|
|
50
|
+
const getItems = (graph: Graph.ReadableGraph, node?: Node.Node, disposition?: string) => {
|
|
51
|
+
return Graph.getConnections(graph, node?.id ?? Node.RootId, 'outbound').filter((node) =>
|
|
52
|
+
filterItems(node, disposition),
|
|
53
|
+
);
|
|
54
54
|
};
|
|
55
55
|
|
|
56
|
-
const useItems = (node?: Node, options?: { disposition?: string; sort?: boolean }) => {
|
|
56
|
+
const useItems = (node?: Node.Node, options?: { disposition?: string; sort?: boolean }) => {
|
|
57
57
|
const { graph } = useAppGraph();
|
|
58
|
-
const connections = useConnections(graph, node?.id ??
|
|
58
|
+
const connections = useConnections(graph, node?.id ?? Node.RootId);
|
|
59
59
|
const filtered = connections.filter((node) => filterItems(node, options?.disposition));
|
|
60
60
|
return options?.sort ? filtered.toSorted((a, b) => byPosition(a.properties, b.properties)) : filtered;
|
|
61
61
|
};
|
|
62
62
|
|
|
63
|
-
const useActions = (node: Node): FlattenedActions => {
|
|
63
|
+
const useActions = (node: Node.Node): FlattenedActions => {
|
|
64
64
|
const { graph } = useAppGraph();
|
|
65
65
|
const actions = useGraphActions(graph, node.id);
|
|
66
66
|
|
|
@@ -73,8 +73,8 @@ const useActions = (node: Node): FlattenedActions => {
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
acc.actions.push(arg);
|
|
76
|
-
if (!isAction(arg)) {
|
|
77
|
-
const actionGroup =
|
|
76
|
+
if (!Node.isAction(arg)) {
|
|
77
|
+
const actionGroup = Graph.getActions(graph, arg.id);
|
|
78
78
|
acc.groupedActions[arg.id] = actionGroup;
|
|
79
79
|
}
|
|
80
80
|
return acc;
|
|
@@ -93,14 +93,15 @@ export type NavTreeContainerProps = {
|
|
|
93
93
|
export const NavTreeContainer$ = forwardRef<HTMLDivElement, NavTreeContainerProps>(
|
|
94
94
|
({ tab, popoverAnchorId, topbar }, forwardedRef) => {
|
|
95
95
|
const [isLg] = useMediaQuery('lg');
|
|
96
|
-
const {
|
|
96
|
+
const { invokeSync, invokePromise } = useOperationInvoker();
|
|
97
|
+
const runAction = useActionRunner();
|
|
97
98
|
const { graph } = useAppGraph();
|
|
98
|
-
const {
|
|
99
|
+
const { getItem, setItem } = useNavTreeState();
|
|
99
100
|
const layout = useLayout();
|
|
100
101
|
const { navigationSidebarState } = useSidebars(meta.id);
|
|
101
102
|
|
|
102
103
|
const getProps = useCallback(
|
|
103
|
-
(node: Node, path: string[]): TreeItemDataProps => {
|
|
104
|
+
(node: Node.Node, path: string[]): TreeItemDataProps => {
|
|
104
105
|
const children = getChildren(graph, node, path).filter(getChildrenFilter);
|
|
105
106
|
const parentOf =
|
|
106
107
|
children.length > 0 ? children.map(({ id }) => id) : node.properties.role === 'branch' ? [] : undefined;
|
|
@@ -120,64 +121,49 @@ export const NavTreeContainer$ = forwardRef<HTMLDivElement, NavTreeContainerProp
|
|
|
120
121
|
);
|
|
121
122
|
|
|
122
123
|
const loadDescendents = useCallback(
|
|
123
|
-
(node: Node) => {
|
|
124
|
-
|
|
124
|
+
(node: Node.Node) => {
|
|
125
|
+
Graph.expand(graph, node.id, 'outbound');
|
|
125
126
|
// Load one level deeper, which resolves some juddering observed on open/close.
|
|
126
|
-
|
|
127
|
-
|
|
127
|
+
Graph.getConnections(graph, node.id, 'outbound').forEach((child) => {
|
|
128
|
+
Graph.expand(graph, child.id, 'outbound');
|
|
128
129
|
});
|
|
129
130
|
},
|
|
130
131
|
[graph],
|
|
131
132
|
);
|
|
132
133
|
|
|
133
134
|
const handleOpenChange = useCallback(
|
|
134
|
-
({ item: { id }, path, open }: { item: Node; path: string[]; open: boolean }) => {
|
|
135
|
+
({ item: { id }, path, open }: { item: Node.Node; path: string[]; open: boolean }) => {
|
|
135
136
|
// TODO(thure): This might become a localstorage leak; openItemIds that no longer exist should be removed from this map.
|
|
136
137
|
setItem(path, 'open', open);
|
|
137
|
-
|
|
138
|
+
Graph.expand(graph, id, 'outbound');
|
|
138
139
|
},
|
|
139
140
|
[graph],
|
|
140
141
|
);
|
|
141
142
|
|
|
142
143
|
const handleTabChange = useCallback(
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
: 'expanded'
|
|
155
|
-
: 'expanded',
|
|
156
|
-
},
|
|
157
|
-
}),
|
|
158
|
-
);
|
|
144
|
+
(node: NavTreeItemGraphNode) => {
|
|
145
|
+
invokeSync(LayoutOperation.UpdateSidebar, {
|
|
146
|
+
state:
|
|
147
|
+
node.id === tab
|
|
148
|
+
? navigationSidebarState === 'expanded'
|
|
149
|
+
? isLg
|
|
150
|
+
? 'collapsed'
|
|
151
|
+
: 'closed'
|
|
152
|
+
: 'expanded'
|
|
153
|
+
: 'expanded',
|
|
154
|
+
});
|
|
159
155
|
|
|
160
|
-
|
|
161
|
-
createIntent(LayoutAction.SwitchWorkspace, {
|
|
162
|
-
part: 'workspace',
|
|
163
|
-
subject: node.id,
|
|
164
|
-
}),
|
|
165
|
-
);
|
|
156
|
+
invokeSync(LayoutOperation.SwitchWorkspace, { subject: node.id });
|
|
166
157
|
|
|
167
158
|
// Open the first item if the workspace is empty.
|
|
168
159
|
if (layout.active.length === 0) {
|
|
169
|
-
const [item] = getItems(graph, node).filter((node) => !isActionLike(node));
|
|
160
|
+
const [item] = getItems(graph, node).filter((node) => !Node.isActionLike(node));
|
|
170
161
|
if (item && item.data) {
|
|
171
|
-
|
|
172
|
-
createIntent(LayoutAction.Open, {
|
|
173
|
-
part: 'main',
|
|
174
|
-
subject: [item.id],
|
|
175
|
-
}),
|
|
176
|
-
);
|
|
162
|
+
invokeSync(LayoutOperation.Open, { subject: [item.id] });
|
|
177
163
|
}
|
|
178
164
|
}
|
|
179
165
|
},
|
|
180
|
-
[
|
|
166
|
+
[invokeSync, layout.active, tab, navigationSidebarState, isLg],
|
|
181
167
|
);
|
|
182
168
|
|
|
183
169
|
const blockInstruction = useCallback(
|
|
@@ -191,75 +177,48 @@ export const NavTreeContainer$ = forwardRef<HTMLDivElement, NavTreeContainerProp
|
|
|
191
177
|
return target.item.properties.canDrop?.(source) ?? false;
|
|
192
178
|
}, []);
|
|
193
179
|
|
|
194
|
-
const canSelect = useCallback(({ item }: { item: Node }) => {
|
|
180
|
+
const canSelect = useCallback(({ item }: { item: Node.Node }) => {
|
|
195
181
|
return item.properties.selectable ?? true;
|
|
196
182
|
}, []);
|
|
197
183
|
|
|
198
184
|
const handleSelect = useCallback(
|
|
199
|
-
({ item: node, path, option }: { item: Node; path: string[]; option: boolean }) => {
|
|
185
|
+
({ item: node, path, option }: { item: Node.Node; path: string[]; option: boolean }) => {
|
|
200
186
|
if (!node.data) {
|
|
201
187
|
return;
|
|
202
188
|
}
|
|
203
189
|
|
|
204
|
-
if (isAction(node)) {
|
|
205
|
-
const [parent] =
|
|
206
|
-
|
|
190
|
+
if (Node.isAction(node)) {
|
|
191
|
+
const [parent] = Graph.getConnections(graph, node.id, 'inbound');
|
|
192
|
+
if (parent) {
|
|
193
|
+
void runAction(node, { parent, caller: NAV_TREE_ITEM });
|
|
194
|
+
}
|
|
207
195
|
return;
|
|
208
196
|
}
|
|
209
197
|
|
|
210
|
-
const current =
|
|
198
|
+
const current = getItem(path).current;
|
|
211
199
|
if (!current) {
|
|
212
|
-
|
|
213
|
-
createIntent(LayoutAction.Open, {
|
|
214
|
-
part: 'main',
|
|
215
|
-
subject: [node.id],
|
|
216
|
-
options: { key: node.properties.key },
|
|
217
|
-
}),
|
|
218
|
-
);
|
|
200
|
+
invokeSync(LayoutOperation.Open, { subject: [node.id], key: node.properties.key });
|
|
219
201
|
} else if (option) {
|
|
220
|
-
|
|
221
|
-
createIntent(LayoutAction.Close, {
|
|
222
|
-
part: 'main',
|
|
223
|
-
subject: [node.id],
|
|
224
|
-
options: { state: false },
|
|
225
|
-
}),
|
|
226
|
-
);
|
|
202
|
+
invokeSync(LayoutOperation.Close, { subject: [node.id] });
|
|
227
203
|
} else {
|
|
228
|
-
void
|
|
229
|
-
createIntent(LayoutAction.ScrollIntoView, {
|
|
230
|
-
part: 'current',
|
|
231
|
-
subject: node.id,
|
|
232
|
-
}),
|
|
233
|
-
);
|
|
204
|
+
void invokePromise(LayoutOperation.ScrollIntoView, { subject: node.id });
|
|
234
205
|
}
|
|
235
206
|
|
|
236
|
-
const defaultAction =
|
|
237
|
-
|
|
238
|
-
|
|
207
|
+
const defaultAction = Graph.getActions(graph, node.id).find(
|
|
208
|
+
(action) => action.properties?.disposition === 'default',
|
|
209
|
+
);
|
|
210
|
+
if (Node.isAction(defaultAction)) {
|
|
211
|
+
void runAction(defaultAction);
|
|
239
212
|
}
|
|
240
213
|
|
|
241
214
|
if (!isLg) {
|
|
242
|
-
|
|
243
|
-
createIntent(LayoutAction.UpdateSidebar, {
|
|
244
|
-
part: 'sidebar',
|
|
245
|
-
options: { state: 'closed' },
|
|
246
|
-
}),
|
|
247
|
-
);
|
|
215
|
+
invokeSync(LayoutOperation.UpdateSidebar, { state: 'closed' });
|
|
248
216
|
}
|
|
249
217
|
},
|
|
250
|
-
[graph,
|
|
218
|
+
[graph, invokeSync, invokePromise, getItem, isLg, runAction],
|
|
251
219
|
);
|
|
252
220
|
|
|
253
|
-
const handleBack = useCallback(
|
|
254
|
-
() =>
|
|
255
|
-
dispatch(
|
|
256
|
-
createIntent(LayoutAction.RevertWorkspace, {
|
|
257
|
-
part: 'workspace',
|
|
258
|
-
options: { revert: true },
|
|
259
|
-
}),
|
|
260
|
-
),
|
|
261
|
-
[dispatch],
|
|
262
|
-
);
|
|
221
|
+
const handleBack = useCallback(() => invokeSync(LayoutOperation.RevertWorkspace), [invokeSync]);
|
|
263
222
|
|
|
264
223
|
// TODO(wittjosiah): Factor out hook.
|
|
265
224
|
useEffect(() => {
|
|
@@ -297,7 +256,7 @@ export const NavTreeContainer$ = forwardRef<HTMLDivElement, NavTreeContainerProp
|
|
|
297
256
|
case 'rearrange': {
|
|
298
257
|
const nextItems = sourceItems.map(({ data }) => data);
|
|
299
258
|
arrayMove(nextItems, sourceIndex, targetIndex);
|
|
300
|
-
void
|
|
259
|
+
void sourceNode.properties.onRearrange?.(nextItems);
|
|
301
260
|
break;
|
|
302
261
|
}
|
|
303
262
|
case 'copy': {
|
|
@@ -333,9 +292,9 @@ export const NavTreeContainer$ = forwardRef<HTMLDivElement, NavTreeContainerProp
|
|
|
333
292
|
canDrop,
|
|
334
293
|
canSelect,
|
|
335
294
|
getProps,
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
295
|
+
useIsAlternateTree,
|
|
296
|
+
useIsCurrent,
|
|
297
|
+
useIsOpen,
|
|
339
298
|
loadDescendents,
|
|
340
299
|
onBack: handleBack,
|
|
341
300
|
onOpenChange: handleOpenChange,
|
|
@@ -358,9 +317,6 @@ export const NavTreeContainer$ = forwardRef<HTMLDivElement, NavTreeContainerProp
|
|
|
358
317
|
handleOpenChange,
|
|
359
318
|
handleSelect,
|
|
360
319
|
handleTabChange,
|
|
361
|
-
isAlternateTree,
|
|
362
|
-
isCurrent,
|
|
363
|
-
isOpen,
|
|
364
320
|
loadDescendents,
|
|
365
321
|
popoverAnchorId,
|
|
366
322
|
renderItemEnd,
|
|
@@ -373,7 +329,7 @@ export const NavTreeContainer$ = forwardRef<HTMLDivElement, NavTreeContainerProp
|
|
|
373
329
|
|
|
374
330
|
return (
|
|
375
331
|
<NavTreeContext.Provider value={navTreeContextValue}>
|
|
376
|
-
<NavTree id={
|
|
332
|
+
<NavTree id={Node.RootId} root={Graph.getRoot(graph)} open={layout.sidebarOpen} ref={forwardedRef} />
|
|
377
333
|
</NavTreeContext.Provider>
|
|
378
334
|
);
|
|
379
335
|
},
|
|
@@ -5,13 +5,14 @@ import { useEffect } from 'react';
|
|
|
5
5
|
|
|
6
6
|
import { type Node } from '@dxos/app-graph';
|
|
7
7
|
import { toLocalizedString, useTranslation } from '@dxos/react-ui';
|
|
8
|
+
import { osTranslations } from '@dxos/ui-theme';
|
|
8
9
|
|
|
9
10
|
import { meta } from '../meta';
|
|
10
11
|
|
|
11
|
-
export const NavTreeDocumentTitle = ({ node }: { node?: Node }) => {
|
|
12
|
+
export const NavTreeDocumentTitle = ({ node }: { node?: Node.Node }) => {
|
|
12
13
|
const { t } = useTranslation(meta.id);
|
|
13
14
|
useEffect(() => {
|
|
14
|
-
document.title = node ? toLocalizedString(node.properties.label, t) : t('current app name', { ns:
|
|
15
|
+
document.title = node ? toLocalizedString(node.properties.label, t) : t('current app name', { ns: osTranslations });
|
|
15
16
|
}, [node?.properties?.label]);
|
|
16
17
|
return null;
|
|
17
18
|
};
|
|
@@ -3,8 +3,12 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
6
|
+
import * as Effect from 'effect/Effect';
|
|
6
7
|
|
|
7
|
-
import {
|
|
8
|
+
import { RuntimePlugin } from '@dxos/app-framework';
|
|
9
|
+
import { withPluginManager } from '@dxos/app-framework/testing';
|
|
10
|
+
import { type Node } from '@dxos/app-graph';
|
|
11
|
+
import { corePlugins } from '@dxos/plugin-testing';
|
|
8
12
|
import { faker } from '@dxos/random';
|
|
9
13
|
import { withTheme } from '@dxos/react-ui/testing';
|
|
10
14
|
|
|
@@ -18,7 +22,7 @@ const parent = {
|
|
|
18
22
|
label: faker.lorem.words(2),
|
|
19
23
|
icon: 'ph--circle--regular',
|
|
20
24
|
},
|
|
21
|
-
} satisfies NodeArg<any>;
|
|
25
|
+
} satisfies Node.NodeArg<any>;
|
|
22
26
|
|
|
23
27
|
// TODO(burdon): Factor out across tests.
|
|
24
28
|
const menuActions = faker.helpers.multiple(
|
|
@@ -26,14 +30,15 @@ const menuActions = faker.helpers.multiple(
|
|
|
26
30
|
({
|
|
27
31
|
id: faker.string.uuid(),
|
|
28
32
|
type: 'action',
|
|
29
|
-
data: () =>
|
|
30
|
-
|
|
31
|
-
|
|
33
|
+
data: () =>
|
|
34
|
+
Effect.sync(() => {
|
|
35
|
+
console.log('invoke');
|
|
36
|
+
}),
|
|
32
37
|
properties: {
|
|
33
38
|
label: faker.lorem.words(2),
|
|
34
39
|
icon: 'ph--circle--regular',
|
|
35
40
|
},
|
|
36
|
-
}) satisfies NodeArg<any>,
|
|
41
|
+
}) satisfies Node.NodeArg<any>,
|
|
37
42
|
{ count: 20 },
|
|
38
43
|
);
|
|
39
44
|
|
|
@@ -46,7 +51,12 @@ const meta = {
|
|
|
46
51
|
menuActions,
|
|
47
52
|
label: 'Select action',
|
|
48
53
|
} satisfies Partial<NavTreeItemActionMenuProps>,
|
|
49
|
-
decorators: [
|
|
54
|
+
decorators: [
|
|
55
|
+
withTheme(),
|
|
56
|
+
withPluginManager({
|
|
57
|
+
plugins: [...corePlugins(), RuntimePlugin()],
|
|
58
|
+
}),
|
|
59
|
+
],
|
|
50
60
|
parameters: {
|
|
51
61
|
layout: 'centered',
|
|
52
62
|
},
|
|
@@ -4,19 +4,20 @@
|
|
|
4
4
|
|
|
5
5
|
import React from 'react';
|
|
6
6
|
|
|
7
|
-
import { type
|
|
7
|
+
import { type Node } from '@dxos/app-graph';
|
|
8
|
+
import { useActionRunner } from '@dxos/plugin-graph';
|
|
8
9
|
import { IconButton, toLocalizedString, useDensityContext, useTranslation } from '@dxos/react-ui';
|
|
9
10
|
import { DropdownMenu, type MenuItem, MenuProvider } from '@dxos/react-ui-menu';
|
|
10
|
-
import { hoverableControlItem, hoverableOpenControlItem } from '@dxos/
|
|
11
|
+
import { hoverableControlItem, hoverableOpenControlItem } from '@dxos/ui-theme';
|
|
11
12
|
|
|
12
13
|
import { meta } from '../../meta';
|
|
13
14
|
import { type ActionProperties } from '../../types';
|
|
14
15
|
|
|
15
16
|
export type NavTreeItemActionMenuProps = ActionProperties & {
|
|
16
|
-
parent: Node;
|
|
17
|
+
parent: Node.Node;
|
|
17
18
|
caller?: string;
|
|
18
19
|
monolithic?: boolean;
|
|
19
|
-
menuActions?: Action[];
|
|
20
|
+
menuActions?: Node.Action[];
|
|
20
21
|
};
|
|
21
22
|
|
|
22
23
|
const fallbackIcon = 'ph--placeholder--regular';
|
|
@@ -40,8 +41,10 @@ export const NavTreeItemActionDropdownMenu = ({
|
|
|
40
41
|
}: NavTreeItemActionMenuProps) => {
|
|
41
42
|
const { t } = useTranslation(meta.id);
|
|
42
43
|
const density = useDensityContext();
|
|
44
|
+
const runAction = useActionRunner();
|
|
45
|
+
|
|
43
46
|
return (
|
|
44
|
-
<MenuProvider>
|
|
47
|
+
<MenuProvider onAction={runAction}>
|
|
45
48
|
<DropdownMenu.Root group={parent} items={menuActions as MenuItem[]} caller={caller}>
|
|
46
49
|
<DropdownMenu.Trigger asChild>
|
|
47
50
|
<IconButton
|
|
@@ -59,13 +62,16 @@ export const NavTreeItemActionDropdownMenu = ({
|
|
|
59
62
|
);
|
|
60
63
|
};
|
|
61
64
|
|
|
62
|
-
export const NavTreeItemMonolithicAction = (
|
|
63
|
-
parent,
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
export const NavTreeItemMonolithicAction = (
|
|
66
|
+
props: Node.Action & { parent: Node.Node; onAction?: (action: Node.Action) => void; baseLabel: string },
|
|
67
|
+
) => {
|
|
68
|
+
const {
|
|
69
|
+
parent,
|
|
70
|
+
properties: { disabled, caller, testId, icon, variant = 'ghost', iconOnly = true } = { label: 'never' },
|
|
71
|
+
baseLabel,
|
|
72
|
+
} = props;
|
|
68
73
|
const density = useDensityContext();
|
|
74
|
+
const runAction = useActionRunner();
|
|
69
75
|
return (
|
|
70
76
|
<IconButton
|
|
71
77
|
{...(density === 'coarse' ? coarseActionButtonProps : fineActionButtonProps)}
|
|
@@ -86,7 +92,7 @@ export const NavTreeItemMonolithicAction = ({
|
|
|
86
92
|
return;
|
|
87
93
|
}
|
|
88
94
|
|
|
89
|
-
void
|
|
95
|
+
void runAction(props, caller ? { parent, caller } : { parent });
|
|
90
96
|
}}
|
|
91
97
|
data-testid={testId}
|
|
92
98
|
/>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import React, { Fragment, memo } from 'react';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { Node } from '@dxos/app-graph';
|
|
8
8
|
import { Popover, Treegrid, toLocalizedString, useTranslation } from '@dxos/react-ui';
|
|
9
9
|
|
|
10
10
|
import { useLoadDescendents } from '../../hooks';
|
|
@@ -26,11 +26,11 @@ export const NavTreeItemColumns = memo(({ path, item, open }: NavTreeItemColumns
|
|
|
26
26
|
);
|
|
27
27
|
|
|
28
28
|
const actions = (primaryAction?.properties?.disposition === 'list-item-primary' ? secondaryActions : _actions)
|
|
29
|
-
.flatMap((action) => (isAction(action) ? [action] : []))
|
|
29
|
+
.flatMap((action) => (Node.isAction(action) ? [action] : []))
|
|
30
30
|
.filter((a) => ['list-item', 'list-item-primary'].includes(a.properties?.disposition));
|
|
31
31
|
|
|
32
32
|
useLoadDescendents(item);
|
|
33
|
-
useLoadDescendents(primaryAction && !isAction(primaryAction) ? primaryAction : undefined);
|
|
33
|
+
useLoadDescendents(primaryAction && !Node.isAction(primaryAction) ? (primaryAction as Node.Node) : undefined);
|
|
34
34
|
|
|
35
35
|
const ActionRoot = popoverAnchorId === `dxos.org/ui/${NAV_TREE_ITEM}/${item.id}` ? Popover.Anchor : Fragment;
|
|
36
36
|
|
|
@@ -43,8 +43,8 @@ export const NavTreeItemColumns = memo(({ path, item, open }: NavTreeItemColumns
|
|
|
43
43
|
label={toLocalizedString(primaryAction.properties?.label, t)}
|
|
44
44
|
icon={primaryAction.properties?.icon ?? 'ph--placeholder--regular'}
|
|
45
45
|
parent={item}
|
|
46
|
-
monolithic={isAction(primaryAction)}
|
|
47
|
-
menuActions={isAction(primaryAction) ? [primaryAction] : groupedActions[primaryAction
|
|
46
|
+
monolithic={Node.isAction(primaryAction)}
|
|
47
|
+
menuActions={Node.isAction(primaryAction) ? [primaryAction] : groupedActions[primaryAction?.id ?? '']}
|
|
48
48
|
menuType={primaryAction.properties?.menuType}
|
|
49
49
|
caller={NAV_TREE_ITEM}
|
|
50
50
|
/>
|