@dxos/plugin-navtree 0.7.4 → 0.7.5-feature-compute.4d9d99a
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-OF4MMBLH.mjs +42 -0
- package/dist/lib/browser/app-graph-builder-OF4MMBLH.mjs.map +7 -0
- package/dist/lib/browser/chunk-IMGT2LAL.mjs +658 -0
- package/dist/lib/browser/chunk-IMGT2LAL.mjs.map +7 -0
- package/dist/lib/browser/{chunk-PSVCPL4T.mjs → chunk-KOXMEAOS.mjs} +5 -3
- package/dist/lib/browser/chunk-KOXMEAOS.mjs.map +7 -0
- package/dist/lib/browser/chunk-OI7AAA6Q.mjs +15 -0
- package/dist/lib/browser/chunk-OI7AAA6Q.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +106 -1212
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/intent-resolver-74JPWYBP.mjs +42 -0
- package/dist/lib/browser/intent-resolver-74JPWYBP.mjs.map +7 -0
- package/dist/lib/browser/keyboard-MUBRTPI5.mjs +46 -0
- package/dist/lib/browser/keyboard-MUBRTPI5.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/react-surface-6QWXI53A.mjs +189 -0
- package/dist/lib/browser/react-surface-6QWXI53A.mjs.map +7 -0
- package/dist/lib/browser/state-HT65TAYL.mjs +111 -0
- package/dist/lib/browser/state-HT65TAYL.mjs.map +7 -0
- package/dist/types/src/NavTreePlugin.d.ts +1 -3
- package/dist/types/src/NavTreePlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/app-graph-builder.d.ts +181 -0
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
- package/dist/types/src/capabilities/capabilities.d.ts +17 -0
- package/dist/types/src/capabilities/capabilities.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +195 -0
- package/dist/types/src/capabilities/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/intent-resolver.d.ts +4 -0
- package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -0
- package/dist/types/src/capabilities/keyboard.d.ts +4 -0
- package/dist/types/src/capabilities/keyboard.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-surface.d.ts +4 -0
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
- package/dist/types/src/capabilities/state.d.ts +17 -0
- package/dist/types/src/capabilities/state.d.ts.map +1 -0
- package/dist/types/src/components/CommandsTrigger.d.ts.map +1 -1
- package/dist/types/src/components/NavTree.d.ts +2 -2
- package/dist/types/src/components/NavTree.d.ts.map +1 -1
- package/dist/types/src/components/NavTreeContainer.d.ts.map +1 -1
- package/dist/types/src/components/NavTreeFooter.d.ts.map +1 -1
- package/dist/types/src/components/NavTreeItemAction.d.ts +4 -8
- package/dist/types/src/components/NavTreeItemAction.d.ts.map +1 -1
- package/dist/types/src/components/NavTreeItemAction.stories.d.ts +0 -5
- package/dist/types/src/components/NavTreeItemAction.stories.d.ts.map +1 -1
- package/dist/types/src/components/NotchStart.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +1 -0
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/events.d.ts +4 -0
- package/dist/types/src/events.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +3 -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/translations.d.ts +0 -1
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +1 -1
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -0
- package/package.json +31 -38
- package/src/NavTreePlugin.tsx +70 -287
- package/src/capabilities/app-graph-builder.ts +40 -0
- package/src/capabilities/capabilities.ts +18 -0
- package/src/capabilities/index.ts +13 -0
- package/src/capabilities/intent-resolver.ts +30 -0
- package/src/capabilities/keyboard.ts +54 -0
- package/src/capabilities/react-surface.tsx +82 -0
- package/src/capabilities/state.ts +100 -0
- package/src/components/CommandsDialog.tsx +3 -3
- package/src/components/CommandsTrigger.tsx +11 -8
- package/src/components/NavTree.tsx +6 -11
- package/src/components/NavTreeContainer.tsx +22 -56
- package/src/components/NavTreeFooter.tsx +21 -18
- package/src/components/NavTreeItemAction.stories.tsx +0 -2
- package/src/components/NavTreeItemAction.tsx +51 -317
- package/src/components/NotchStart.tsx +8 -7
- package/src/components/index.ts +1 -0
- package/src/events.ts +11 -0
- package/src/index.ts +3 -4
- package/src/meta.ts +3 -1
- package/src/translations.ts +0 -1
- package/src/types.ts +1 -1
- package/dist/lib/browser/chunk-PSVCPL4T.mjs.map +0 -7
- package/dist/lib/browser/meta.mjs +0 -11
- package/dist/lib/browser/meta.mjs.map +0 -7
|
@@ -0,0 +1,658 @@
|
|
|
1
|
+
import {
|
|
2
|
+
COMMANDS_DIALOG,
|
|
3
|
+
KEY_BINDING,
|
|
4
|
+
NAVTREE_PLUGIN
|
|
5
|
+
} from "./chunk-KOXMEAOS.mjs";
|
|
6
|
+
|
|
7
|
+
// packages/plugins/plugin-navtree/src/components/CommandsDialog.tsx
|
|
8
|
+
import React, { useMemo, useState } from "react";
|
|
9
|
+
import { useIntentDispatcher, LayoutAction, createIntent } from "@dxos/app-framework";
|
|
10
|
+
import { isActionGroup, isAction } from "@dxos/app-graph";
|
|
11
|
+
import { Keyboard, keySymbols } from "@dxos/keyboard";
|
|
12
|
+
import { useGraph } from "@dxos/plugin-graph";
|
|
13
|
+
import { Button, Dialog, Icon, useTranslation, toLocalizedString } from "@dxos/react-ui";
|
|
14
|
+
import { SearchList } from "@dxos/react-ui-searchlist";
|
|
15
|
+
import { descriptionText, mx } from "@dxos/react-ui-theme";
|
|
16
|
+
import { getHostPlatform } from "@dxos/util";
|
|
17
|
+
var CommandsDialogContent = ({ selected: initial }) => {
|
|
18
|
+
const { t } = useTranslation(NAVTREE_PLUGIN);
|
|
19
|
+
const [selected, setSelected] = useState(initial);
|
|
20
|
+
const { dispatchPromise: dispatch } = useIntentDispatcher();
|
|
21
|
+
const { graph } = useGraph();
|
|
22
|
+
const allActions = useMemo(() => {
|
|
23
|
+
const current = Keyboard.singleton.getCurrentContext();
|
|
24
|
+
const actionMap = /* @__PURE__ */ new Set();
|
|
25
|
+
const actions2 = [];
|
|
26
|
+
graph?.traverse({
|
|
27
|
+
visitor: (node, path) => {
|
|
28
|
+
if ((isAction(node) || isActionGroup(node)) && !actionMap.has(node.id) && current.startsWith(path.slice(0, -1).join("/"))) {
|
|
29
|
+
actionMap.add(node.id);
|
|
30
|
+
actions2.push(node);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
actions2.sort((a, b) => {
|
|
35
|
+
return toLocalizedString(a.properties.label, t)?.toLowerCase().localeCompare(toLocalizedString(b.properties.label, t)?.toLowerCase());
|
|
36
|
+
});
|
|
37
|
+
return actions2;
|
|
38
|
+
}, [
|
|
39
|
+
graph
|
|
40
|
+
]);
|
|
41
|
+
const group = allActions.find(({ id }) => id === selected);
|
|
42
|
+
const actions = isActionGroup(group) ? graph.actions(group) : allActions;
|
|
43
|
+
return /* @__PURE__ */ React.createElement(Dialog.Content, {
|
|
44
|
+
classNames: [
|
|
45
|
+
"md:max-is-[30rem] overflow-hidden mbs-12"
|
|
46
|
+
]
|
|
47
|
+
}, /* @__PURE__ */ React.createElement(Dialog.Title, null, t("commands dialog title", {
|
|
48
|
+
ns: NAVTREE_PLUGIN
|
|
49
|
+
})), /* @__PURE__ */ React.createElement(SearchList.Root, {
|
|
50
|
+
label: t("command list input placeholder"),
|
|
51
|
+
classNames: "flex flex-col grow overflow-hidden my-2"
|
|
52
|
+
}, /* @__PURE__ */ React.createElement(SearchList.Input, {
|
|
53
|
+
placeholder: t("command list input placeholder"),
|
|
54
|
+
classNames: "px-1 my-2"
|
|
55
|
+
}), /* @__PURE__ */ React.createElement(SearchList.Content, {
|
|
56
|
+
classNames: "max-bs-[24rem] overflow-auto"
|
|
57
|
+
}, actions?.map((action) => {
|
|
58
|
+
const label = toLocalizedString(action.properties.label, t);
|
|
59
|
+
const shortcut = typeof action.properties.keyBinding === "string" ? action.properties.keyBinding : action.properties.keyBinding?.[getHostPlatform()];
|
|
60
|
+
return /* @__PURE__ */ React.createElement(SearchList.Item, {
|
|
61
|
+
value: label,
|
|
62
|
+
key: action.id,
|
|
63
|
+
onSelect: () => {
|
|
64
|
+
if (action.properties.disabled) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (isActionGroup(action)) {
|
|
68
|
+
setSelected(action.id);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
void dispatch(createIntent(LayoutAction.SetLayout, {
|
|
72
|
+
element: "dialog",
|
|
73
|
+
state: false
|
|
74
|
+
}));
|
|
75
|
+
setTimeout(() => {
|
|
76
|
+
const node = graph.nodes(group ?? action, {
|
|
77
|
+
relation: "inbound"
|
|
78
|
+
})[0];
|
|
79
|
+
void (node && isAction(action) && action.data({
|
|
80
|
+
node,
|
|
81
|
+
caller: KEY_BINDING
|
|
82
|
+
}));
|
|
83
|
+
});
|
|
84
|
+
},
|
|
85
|
+
classNames: "flex items-center gap-2",
|
|
86
|
+
disabled: action.properties.disabled,
|
|
87
|
+
...action.properties?.testId && {
|
|
88
|
+
"data-testid": action.properties.testId
|
|
89
|
+
}
|
|
90
|
+
}, /* @__PURE__ */ React.createElement(Icon, {
|
|
91
|
+
icon: action.properties.icon,
|
|
92
|
+
size: 4
|
|
93
|
+
}), /* @__PURE__ */ React.createElement("span", {
|
|
94
|
+
className: "grow truncate"
|
|
95
|
+
}, label), shortcut && /* @__PURE__ */ React.createElement("span", {
|
|
96
|
+
className: mx("shrink-0", descriptionText)
|
|
97
|
+
}, keySymbols(shortcut).join("")));
|
|
98
|
+
}))), /* @__PURE__ */ React.createElement(Dialog.Close, {
|
|
99
|
+
asChild: true
|
|
100
|
+
}, /* @__PURE__ */ React.createElement(Button, {
|
|
101
|
+
variant: "primary",
|
|
102
|
+
classNames: "mbs-2"
|
|
103
|
+
}, t("close label", {
|
|
104
|
+
ns: "os"
|
|
105
|
+
}))));
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
// packages/plugins/plugin-navtree/src/components/CommandsTrigger.tsx
|
|
109
|
+
import { MagnifyingGlass } from "@phosphor-icons/react";
|
|
110
|
+
import React2 from "react";
|
|
111
|
+
import { createIntent as createIntent2, LayoutAction as LayoutAction2, useIntentDispatcher as useIntentDispatcher2 } from "@dxos/app-framework";
|
|
112
|
+
import { Button as Button2, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
113
|
+
import { getSize } from "@dxos/react-ui-theme";
|
|
114
|
+
var CommandsTrigger = () => {
|
|
115
|
+
const { dispatchPromise: dispatch } = useIntentDispatcher2();
|
|
116
|
+
const { t } = useTranslation2(NAVTREE_PLUGIN);
|
|
117
|
+
return /* @__PURE__ */ React2.createElement(Button2, {
|
|
118
|
+
classNames: "m-1 !pli-1 lg:!pli-2",
|
|
119
|
+
onClick: () => dispatch(createIntent2(LayoutAction2.SetLayout, {
|
|
120
|
+
element: "dialog",
|
|
121
|
+
component: COMMANDS_DIALOG,
|
|
122
|
+
dialogBlockAlign: "start"
|
|
123
|
+
}))
|
|
124
|
+
}, /* @__PURE__ */ React2.createElement("span", {
|
|
125
|
+
className: "text-description font-normal grow text-start"
|
|
126
|
+
}, t("command list input placeholder")), /* @__PURE__ */ React2.createElement(MagnifyingGlass, {
|
|
127
|
+
className: getSize(5)
|
|
128
|
+
}));
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
// packages/plugins/plugin-navtree/src/util.ts
|
|
132
|
+
import { ACTION_TYPE, ACTION_GROUP_TYPE, isAction as isAction2 } from "@dxos/app-graph";
|
|
133
|
+
import { nonNullable } from "@dxos/util";
|
|
134
|
+
var getParent = (graph, node, path) => {
|
|
135
|
+
const parentId = path[path.length - 2];
|
|
136
|
+
return graph.nodes(node, {
|
|
137
|
+
relation: "inbound"
|
|
138
|
+
}).find((n) => n.id === parentId);
|
|
139
|
+
};
|
|
140
|
+
var getPersistenceParent = (graph, node, path, persistenceClass) => {
|
|
141
|
+
if (node.properties.acceptPersistenceClass?.has(persistenceClass)) {
|
|
142
|
+
return node;
|
|
143
|
+
} else {
|
|
144
|
+
const parent = getParent(graph, node, path);
|
|
145
|
+
return parent ? getPersistenceParent(graph, parent, path.slice(0, path.length - 1), persistenceClass) : null;
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
var resolveMigrationOperation = (graph, activeNode, destinationPath, destinationRelatedNode) => {
|
|
149
|
+
const activeClass = activeNode.properties.persistenceClass;
|
|
150
|
+
if (destinationRelatedNode && activeClass) {
|
|
151
|
+
const persistenceParent = getPersistenceParent(graph, destinationRelatedNode, destinationPath, activeClass);
|
|
152
|
+
if (persistenceParent) {
|
|
153
|
+
const activeKey = activeNode.properties.persistenceKey;
|
|
154
|
+
if (activeKey && persistenceParent?.properties.acceptPersistenceKey) {
|
|
155
|
+
return persistenceParent.properties.acceptPersistenceKey.has(activeKey) && persistenceParent.properties.onTransferStart ? "transfer" : persistenceParent.properties.onCopy ? "copy" : "reject";
|
|
156
|
+
} else {
|
|
157
|
+
return "reject";
|
|
158
|
+
}
|
|
159
|
+
} else {
|
|
160
|
+
return "reject";
|
|
161
|
+
}
|
|
162
|
+
} else {
|
|
163
|
+
return "reject";
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
var sortActions = (actions) => actions.sort((a, b) => {
|
|
167
|
+
if (a.properties.disposition === b.properties.disposition) {
|
|
168
|
+
return 0;
|
|
169
|
+
}
|
|
170
|
+
if (a.properties.disposition === "toolbar") {
|
|
171
|
+
return -1;
|
|
172
|
+
}
|
|
173
|
+
return 1;
|
|
174
|
+
});
|
|
175
|
+
var getChildren = (graph, node, filter, path = []) => {
|
|
176
|
+
return graph.nodes(node, {
|
|
177
|
+
relation: "outbound",
|
|
178
|
+
filter
|
|
179
|
+
}).map((n) => {
|
|
180
|
+
const nextPath = [
|
|
181
|
+
...path,
|
|
182
|
+
node.id
|
|
183
|
+
];
|
|
184
|
+
return nextPath.includes(n.id) ? void 0 : n;
|
|
185
|
+
}).filter(nonNullable);
|
|
186
|
+
};
|
|
187
|
+
var getActions = (graph, node) => {
|
|
188
|
+
return graph.actions(node).reduce((acc, arg) => {
|
|
189
|
+
if (arg.properties.disposition === "item") {
|
|
190
|
+
return acc;
|
|
191
|
+
}
|
|
192
|
+
acc.actions.push(arg);
|
|
193
|
+
if (!isAction2(arg)) {
|
|
194
|
+
const actionGroup = graph.actions(arg);
|
|
195
|
+
acc.groupedActions[arg.id] = actionGroup;
|
|
196
|
+
}
|
|
197
|
+
return acc;
|
|
198
|
+
}, {
|
|
199
|
+
actions: [],
|
|
200
|
+
groupedActions: {}
|
|
201
|
+
});
|
|
202
|
+
};
|
|
203
|
+
var expandChildrenAndActions = (graph, node) => {
|
|
204
|
+
return Promise.all([
|
|
205
|
+
expandChildren(graph, node),
|
|
206
|
+
expandActions(graph, node)
|
|
207
|
+
]);
|
|
208
|
+
};
|
|
209
|
+
var expandChildren = (graph, node) => {
|
|
210
|
+
return graph.expand(node, "outbound");
|
|
211
|
+
};
|
|
212
|
+
var expandActions = (graph, node) => {
|
|
213
|
+
return Promise.all([
|
|
214
|
+
graph.expand(node, "outbound", ACTION_TYPE),
|
|
215
|
+
graph.expand(node, "outbound", ACTION_GROUP_TYPE)
|
|
216
|
+
]);
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
// packages/plugins/plugin-navtree/src/components/NavTreeContainer.tsx
|
|
220
|
+
import { monitorForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
|
|
221
|
+
import { extractInstruction } from "@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item";
|
|
222
|
+
import { untracked } from "@preact/signals-core";
|
|
223
|
+
import React5, { memo, useCallback as useCallback2, useEffect as useEffect2 } from "react";
|
|
224
|
+
import { createIntent as createIntent3, LayoutAction as LayoutAction3, NavigationAction, useIntentDispatcher as useIntentDispatcher3, Surface } from "@dxos/app-framework";
|
|
225
|
+
import { isAction as isAction4, isActionLike } from "@dxos/app-graph";
|
|
226
|
+
import { useGraph as useGraph2 } from "@dxos/plugin-graph";
|
|
227
|
+
import { isEchoObject, isSpace } from "@dxos/react-client/echo";
|
|
228
|
+
import { useMediaQuery, useSidebars } from "@dxos/react-ui";
|
|
229
|
+
import { isTreeData } from "@dxos/react-ui-list";
|
|
230
|
+
import { mx as mx3 } from "@dxos/react-ui-theme";
|
|
231
|
+
import { arrayMove } from "@dxos/util";
|
|
232
|
+
|
|
233
|
+
// packages/plugins/plugin-navtree/src/components/NavTree.tsx
|
|
234
|
+
import React4, { Fragment, useCallback, useEffect } from "react";
|
|
235
|
+
import { isAction as isAction3 } from "@dxos/app-graph";
|
|
236
|
+
import { Popover, toLocalizedString as toLocalizedString3, Treegrid, useTranslation as useTranslation4 } from "@dxos/react-ui";
|
|
237
|
+
import { Tree } from "@dxos/react-ui-list";
|
|
238
|
+
|
|
239
|
+
// packages/plugins/plugin-navtree/src/components/NavTreeItemAction.tsx
|
|
240
|
+
import React3, { useRef } from "react";
|
|
241
|
+
import { useTranslation as useTranslation3, toLocalizedString as toLocalizedString2, IconButton } from "@dxos/react-ui";
|
|
242
|
+
import { DropdownMenu, MenuProvider } from "@dxos/react-ui-menu";
|
|
243
|
+
import { hoverableControlItem, hoverableOpenControlItem, mx as mx2 } from "@dxos/react-ui-theme";
|
|
244
|
+
var fallbackIcon = "ph--placeholder--regular";
|
|
245
|
+
var actionButtonProps = {
|
|
246
|
+
iconOnly: true,
|
|
247
|
+
size: 4,
|
|
248
|
+
variant: "ghost",
|
|
249
|
+
density: "fine",
|
|
250
|
+
classNames: mx2("shrink-0 !pli-2 pointer-fine:!pli-1", hoverableControlItem, hoverableOpenControlItem)
|
|
251
|
+
};
|
|
252
|
+
var NavTreeItemActionDropdownMenu = ({ label, icon, testId, menuActions, onAction }) => {
|
|
253
|
+
const { t } = useTranslation3(NAVTREE_PLUGIN);
|
|
254
|
+
const suppressNextTooltip = useRef(false);
|
|
255
|
+
return /* @__PURE__ */ React3.createElement(MenuProvider, {
|
|
256
|
+
onAction
|
|
257
|
+
}, /* @__PURE__ */ React3.createElement(DropdownMenu.Root, {
|
|
258
|
+
items: menuActions,
|
|
259
|
+
suppressNextTooltip
|
|
260
|
+
}, /* @__PURE__ */ React3.createElement(DropdownMenu.Trigger, {
|
|
261
|
+
asChild: true
|
|
262
|
+
}, /* @__PURE__ */ React3.createElement(IconButton, {
|
|
263
|
+
...actionButtonProps,
|
|
264
|
+
icon: icon ?? fallbackIcon,
|
|
265
|
+
label: toLocalizedString2(label, t),
|
|
266
|
+
"data-testid": testId,
|
|
267
|
+
suppressNextTooltip
|
|
268
|
+
}))));
|
|
269
|
+
};
|
|
270
|
+
var NavTreeItemMonolithicAction = ({ parent, properties: { disabled, caller, testId, icon } = {
|
|
271
|
+
label: "never"
|
|
272
|
+
}, data: invoke, baseLabel }) => {
|
|
273
|
+
return /* @__PURE__ */ React3.createElement(IconButton, {
|
|
274
|
+
...actionButtonProps,
|
|
275
|
+
icon: icon ?? fallbackIcon,
|
|
276
|
+
label: baseLabel,
|
|
277
|
+
disabled,
|
|
278
|
+
onClick: (event) => {
|
|
279
|
+
if (disabled) {
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
event.stopPropagation();
|
|
283
|
+
void invoke?.(caller ? {
|
|
284
|
+
node: parent,
|
|
285
|
+
caller
|
|
286
|
+
} : {
|
|
287
|
+
node: parent
|
|
288
|
+
});
|
|
289
|
+
},
|
|
290
|
+
"data-testid": testId
|
|
291
|
+
});
|
|
292
|
+
};
|
|
293
|
+
var NavTreeItemAction = ({ monolithic, menuActions, parent: node, ...props }) => {
|
|
294
|
+
const { t } = useTranslation3(NAVTREE_PLUGIN);
|
|
295
|
+
const monolithicAction = menuActions?.length === 1 && menuActions[0];
|
|
296
|
+
const baseLabel = toLocalizedString2(monolithicAction ? monolithicAction.properties.label : props.label, t);
|
|
297
|
+
return monolithic && menuActions?.length === 1 ? /* @__PURE__ */ React3.createElement(NavTreeItemMonolithicAction, {
|
|
298
|
+
baseLabel,
|
|
299
|
+
parent: node,
|
|
300
|
+
...menuActions[0]
|
|
301
|
+
}) : /* @__PURE__ */ React3.createElement(NavTreeItemActionDropdownMenu, {
|
|
302
|
+
...props,
|
|
303
|
+
label: baseLabel,
|
|
304
|
+
parent: node,
|
|
305
|
+
menuActions,
|
|
306
|
+
onAction: (action) => action.data?.(props.caller ? {
|
|
307
|
+
node,
|
|
308
|
+
caller: props.caller
|
|
309
|
+
} : {
|
|
310
|
+
node
|
|
311
|
+
})
|
|
312
|
+
});
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
// packages/plugins/plugin-navtree/src/components/NavTree.tsx
|
|
316
|
+
var NAV_TREE_ITEM = "NavTreeItem";
|
|
317
|
+
var NavTree = ({ getActions: getActions2, loadDescendents, renderItemEnd: renderItemEnd2, popoverAnchorId, ...props }) => {
|
|
318
|
+
const renderColumns = useCallback(({ item, path, open }) => {
|
|
319
|
+
return /* @__PURE__ */ React4.createElement(NavTreeColumns, {
|
|
320
|
+
path,
|
|
321
|
+
node: item,
|
|
322
|
+
getActions: getActions2,
|
|
323
|
+
open,
|
|
324
|
+
loadDescendents,
|
|
325
|
+
renderItemEnd: renderItemEnd2,
|
|
326
|
+
popoverAnchorId
|
|
327
|
+
});
|
|
328
|
+
}, [
|
|
329
|
+
renderItemEnd2,
|
|
330
|
+
popoverAnchorId,
|
|
331
|
+
loadDescendents
|
|
332
|
+
]);
|
|
333
|
+
return /* @__PURE__ */ React4.createElement(Tree, {
|
|
334
|
+
...props,
|
|
335
|
+
draggable: true,
|
|
336
|
+
gridTemplateColumns: "[tree-row-start] 1fr min-content min-content min-content [tree-row-end]",
|
|
337
|
+
renderColumns
|
|
338
|
+
});
|
|
339
|
+
};
|
|
340
|
+
var NavTreeColumns = ({ path, node, getActions: getActions2, open, loadDescendents, renderItemEnd: ItemEnd, popoverAnchorId }) => {
|
|
341
|
+
const { t } = useTranslation4(NAVTREE_PLUGIN);
|
|
342
|
+
const level = path.length - 2;
|
|
343
|
+
const { actions: _actions, groupedActions } = getActions2(node);
|
|
344
|
+
const [primaryAction, ...secondaryActions] = _actions.toSorted((a, b) => a.properties?.disposition === "toolbar" ? -1 : 1);
|
|
345
|
+
const actions = (primaryAction?.properties?.disposition === "toolbar" ? secondaryActions : _actions).flatMap((action) => isAction3(action) ? [
|
|
346
|
+
action
|
|
347
|
+
] : []).filter((action) => !action.properties?.hidden);
|
|
348
|
+
const ActionRoot = popoverAnchorId === `dxos.org/ui/${NAV_TREE_ITEM}/${node.id}` ? Popover.Anchor : Fragment;
|
|
349
|
+
useEffect(() => {
|
|
350
|
+
const frame = requestAnimationFrame(() => {
|
|
351
|
+
void loadDescendents?.(node);
|
|
352
|
+
if (primaryAction && !isAction3(primaryAction)) {
|
|
353
|
+
void loadDescendents?.(primaryAction);
|
|
354
|
+
}
|
|
355
|
+
});
|
|
356
|
+
return () => cancelAnimationFrame(frame);
|
|
357
|
+
}, [
|
|
358
|
+
primaryAction
|
|
359
|
+
]);
|
|
360
|
+
return /* @__PURE__ */ React4.createElement(React4.Fragment, null, primaryAction?.properties?.disposition === "toolbar" ? /* @__PURE__ */ React4.createElement(NavTreeItemAction, {
|
|
361
|
+
testId: primaryAction.properties?.testId,
|
|
362
|
+
label: toLocalizedString3(primaryAction.properties?.label, t),
|
|
363
|
+
icon: primaryAction.properties?.icon ?? "ph--placeholder--regular",
|
|
364
|
+
parent: node,
|
|
365
|
+
monolithic: isAction3(primaryAction),
|
|
366
|
+
menuActions: isAction3(primaryAction) ? [
|
|
367
|
+
primaryAction
|
|
368
|
+
] : groupedActions[primaryAction.id],
|
|
369
|
+
menuType: primaryAction.properties?.menuType,
|
|
370
|
+
caller: NAV_TREE_ITEM
|
|
371
|
+
}) : /* @__PURE__ */ React4.createElement(Treegrid.Cell, null), /* @__PURE__ */ React4.createElement(ActionRoot, null, actions.length > 0 ? /* @__PURE__ */ React4.createElement(NavTreeItemAction, {
|
|
372
|
+
testId: `navtree.treeItem.actionsLevel${level}`,
|
|
373
|
+
label: t("tree item actions label"),
|
|
374
|
+
icon: "ph--dots-three-vertical--regular",
|
|
375
|
+
parent: node,
|
|
376
|
+
menuActions: actions,
|
|
377
|
+
menuType: "dropdown",
|
|
378
|
+
caller: NAV_TREE_ITEM
|
|
379
|
+
}) : /* @__PURE__ */ React4.createElement(Treegrid.Cell, null)), ItemEnd && /* @__PURE__ */ React4.createElement(ItemEnd, {
|
|
380
|
+
node,
|
|
381
|
+
open
|
|
382
|
+
}));
|
|
383
|
+
};
|
|
384
|
+
|
|
385
|
+
// packages/plugins/plugin-navtree/src/components/NavTreeContainer.tsx
|
|
386
|
+
var NODE_TYPE = "dxos/app-graph/node";
|
|
387
|
+
var renderItemEnd = ({ node, open }) => /* @__PURE__ */ React5.createElement(Surface, {
|
|
388
|
+
role: "navtree-item-end",
|
|
389
|
+
data: {
|
|
390
|
+
id: node.id,
|
|
391
|
+
subject: node.data,
|
|
392
|
+
open
|
|
393
|
+
},
|
|
394
|
+
limit: 1
|
|
395
|
+
});
|
|
396
|
+
var NavTreeContainer = /* @__PURE__ */ memo(({ isCurrent, popoverAnchorId, ...props }) => {
|
|
397
|
+
const { closeNavigationSidebar } = useSidebars(NAVTREE_PLUGIN);
|
|
398
|
+
const [isLg] = useMediaQuery("lg", {
|
|
399
|
+
ssr: false
|
|
400
|
+
});
|
|
401
|
+
const { dispatchPromise: dispatch } = useIntentDispatcher3();
|
|
402
|
+
const { graph } = useGraph2();
|
|
403
|
+
const getActions2 = useCallback2((node) => getActions(graph, node), [
|
|
404
|
+
graph
|
|
405
|
+
]);
|
|
406
|
+
const getItems = useCallback2((node) => {
|
|
407
|
+
return graph.nodes(node ?? graph.root, {
|
|
408
|
+
filter: (node2) => {
|
|
409
|
+
return untracked(() => {
|
|
410
|
+
const action = isActionLike(node2);
|
|
411
|
+
const disposition = node2.properties.disposition;
|
|
412
|
+
return !action || action && disposition === "item";
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
});
|
|
416
|
+
}, [
|
|
417
|
+
graph
|
|
418
|
+
]);
|
|
419
|
+
const getProps = useCallback2((node, path) => {
|
|
420
|
+
const children = getChildren(graph, node, void 0, path);
|
|
421
|
+
const parentOf = children.length > 0 ? children.map(({ id }) => id) : node.properties.role === "branch" ? [] : void 0;
|
|
422
|
+
return {
|
|
423
|
+
id: node.id,
|
|
424
|
+
label: node.properties.label ?? node.id,
|
|
425
|
+
parentOf,
|
|
426
|
+
icon: node.properties.icon,
|
|
427
|
+
disabled: node.properties.disabled,
|
|
428
|
+
className: mx3(node.properties.modified && "italic", node.properties.className),
|
|
429
|
+
headingClassName: node.properties.headingClassName,
|
|
430
|
+
testId: node.properties.testId
|
|
431
|
+
};
|
|
432
|
+
}, [
|
|
433
|
+
graph
|
|
434
|
+
]);
|
|
435
|
+
const loadDescendents = useCallback2((node) => {
|
|
436
|
+
void expandActions(graph, node);
|
|
437
|
+
if (!isActionLike(node)) {
|
|
438
|
+
void expandChildren(graph, node).then(() => (
|
|
439
|
+
// Load one level deeper, which resolves some juddering observed on open/close.
|
|
440
|
+
Promise.all(getChildren(graph, node).flatMap((child) => [
|
|
441
|
+
expandActions(graph, child),
|
|
442
|
+
expandChildren(graph, child)
|
|
443
|
+
]))
|
|
444
|
+
));
|
|
445
|
+
}
|
|
446
|
+
}, [
|
|
447
|
+
graph
|
|
448
|
+
]);
|
|
449
|
+
const canDrop = useCallback2((source, target) => {
|
|
450
|
+
const sourceNode = source.item;
|
|
451
|
+
const targetNode = target.item;
|
|
452
|
+
if (isSpace(targetNode.data)) {
|
|
453
|
+
return isEchoObject(sourceNode.data) || isSpace(sourceNode.data);
|
|
454
|
+
} else if (isEchoObject(targetNode.data)) {
|
|
455
|
+
return isEchoObject(sourceNode.data);
|
|
456
|
+
} else {
|
|
457
|
+
return false;
|
|
458
|
+
}
|
|
459
|
+
}, []);
|
|
460
|
+
const handleSelect = useCallback2(({ item: node, path, option }) => {
|
|
461
|
+
if (!node.data) {
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
if (isAction4(node)) {
|
|
465
|
+
const [parent] = graph.nodes(node, {
|
|
466
|
+
relation: "inbound"
|
|
467
|
+
});
|
|
468
|
+
void (parent && node.data({
|
|
469
|
+
node: parent,
|
|
470
|
+
caller: NAV_TREE_ITEM
|
|
471
|
+
}));
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
const current = isCurrent(path, node);
|
|
475
|
+
if (!current) {
|
|
476
|
+
void dispatch(createIntent3(NavigationAction.Open, {
|
|
477
|
+
activeParts: {
|
|
478
|
+
main: [
|
|
479
|
+
node.id
|
|
480
|
+
]
|
|
481
|
+
}
|
|
482
|
+
}));
|
|
483
|
+
} else if (option) {
|
|
484
|
+
void dispatch(createIntent3(NavigationAction.Close, {
|
|
485
|
+
activeParts: {
|
|
486
|
+
main: [
|
|
487
|
+
node.id
|
|
488
|
+
]
|
|
489
|
+
}
|
|
490
|
+
}));
|
|
491
|
+
} else {
|
|
492
|
+
void dispatch(createIntent3(LayoutAction3.ScrollIntoView, {
|
|
493
|
+
id: node.id
|
|
494
|
+
}));
|
|
495
|
+
}
|
|
496
|
+
const defaultAction = graph.actions(node).find((action) => action.properties?.disposition === "default");
|
|
497
|
+
if (isAction4(defaultAction)) {
|
|
498
|
+
void defaultAction.data();
|
|
499
|
+
}
|
|
500
|
+
if (!isLg) {
|
|
501
|
+
closeNavigationSidebar();
|
|
502
|
+
}
|
|
503
|
+
}, [
|
|
504
|
+
graph,
|
|
505
|
+
dispatch,
|
|
506
|
+
isCurrent,
|
|
507
|
+
isLg,
|
|
508
|
+
closeNavigationSidebar
|
|
509
|
+
]);
|
|
510
|
+
useEffect2(() => {
|
|
511
|
+
return monitorForElements({
|
|
512
|
+
canMonitor: ({ source }) => isTreeData(source.data),
|
|
513
|
+
onDrop: ({ location, source }) => {
|
|
514
|
+
if (!location.current.dropTargets.length) {
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
const target = location.current.dropTargets[0];
|
|
518
|
+
const instruction = extractInstruction(target.data);
|
|
519
|
+
if (instruction !== null && instruction.type !== "instruction-blocked") {
|
|
520
|
+
const sourceNode = source.data.item;
|
|
521
|
+
const targetNode = target.data.item;
|
|
522
|
+
const sourcePath = source.data.path;
|
|
523
|
+
const targetPath = target.data.path;
|
|
524
|
+
const operation = sourcePath.slice(0, -1).join() === targetPath.slice(0, -1).join() && instruction.type !== "make-child" ? "rearrange" : resolveMigrationOperation(graph, sourceNode, targetPath, targetNode);
|
|
525
|
+
const sourceParent = getParent(graph, sourceNode, sourcePath);
|
|
526
|
+
const targetParent = getParent(graph, targetNode, targetPath);
|
|
527
|
+
const sourceItems = getItems(sourceParent);
|
|
528
|
+
const targetItems = getItems(targetParent);
|
|
529
|
+
const sourceIndex = sourceItems.findIndex(({ id }) => id === sourceNode.id);
|
|
530
|
+
const targetIndex = targetItems.findIndex(({ id }) => id === targetNode.id);
|
|
531
|
+
const migrationIndex = instruction.type === "make-child" ? void 0 : instruction.type === "reorder-below" ? targetIndex + 1 : targetIndex;
|
|
532
|
+
switch (operation) {
|
|
533
|
+
case "rearrange": {
|
|
534
|
+
const nextItems = sourceItems.map(({ data }) => data);
|
|
535
|
+
arrayMove(nextItems, sourceIndex, targetIndex);
|
|
536
|
+
void sourceParent?.properties.onRearrangeChildren?.(nextItems);
|
|
537
|
+
break;
|
|
538
|
+
}
|
|
539
|
+
case "copy": {
|
|
540
|
+
const target2 = instruction.type === "make-child" ? targetNode : targetParent;
|
|
541
|
+
void target2?.properties.onCopy?.(sourceNode, migrationIndex);
|
|
542
|
+
break;
|
|
543
|
+
}
|
|
544
|
+
case "transfer": {
|
|
545
|
+
const target2 = instruction.type === "make-child" ? targetNode : targetParent;
|
|
546
|
+
if (!target2?.properties.onTransferStart || !sourceParent?.properties.onTransferEnd) {
|
|
547
|
+
break;
|
|
548
|
+
}
|
|
549
|
+
void target2?.properties.onTransferStart(sourceNode, migrationIndex);
|
|
550
|
+
void sourceParent?.properties.onTransferEnd?.(sourceNode, target2);
|
|
551
|
+
break;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
});
|
|
557
|
+
}, [
|
|
558
|
+
graph
|
|
559
|
+
]);
|
|
560
|
+
return /* @__PURE__ */ React5.createElement(NavTree, {
|
|
561
|
+
id: graph.root.id,
|
|
562
|
+
getActions: getActions2,
|
|
563
|
+
getItems,
|
|
564
|
+
getProps,
|
|
565
|
+
isCurrent,
|
|
566
|
+
loadDescendents,
|
|
567
|
+
renderItemEnd,
|
|
568
|
+
popoverAnchorId,
|
|
569
|
+
canDrop,
|
|
570
|
+
onSelect: handleSelect,
|
|
571
|
+
...props
|
|
572
|
+
});
|
|
573
|
+
});
|
|
574
|
+
|
|
575
|
+
// packages/plugins/plugin-navtree/src/components/NavTreeDocumentTitle.tsx
|
|
576
|
+
import { useEffect as useEffect3 } from "react";
|
|
577
|
+
import { toLocalizedString as toLocalizedString4, useTranslation as useTranslation5 } from "@dxos/react-ui";
|
|
578
|
+
var NavTreeDocumentTitle = ({ node }) => {
|
|
579
|
+
const { t } = useTranslation5(NAVTREE_PLUGIN);
|
|
580
|
+
useEffect3(() => {
|
|
581
|
+
document.title = node ? toLocalizedString4(node.properties.label, t) : t("current app name", {
|
|
582
|
+
ns: "appkit"
|
|
583
|
+
});
|
|
584
|
+
}, [
|
|
585
|
+
node?.properties?.label
|
|
586
|
+
]);
|
|
587
|
+
return null;
|
|
588
|
+
};
|
|
589
|
+
|
|
590
|
+
// packages/plugins/plugin-navtree/src/components/NotchStart.tsx
|
|
591
|
+
import React7 from "react";
|
|
592
|
+
import { createIntent as createIntent4, useIntentDispatcher as useIntentDispatcher4, useCapabilities } from "@dxos/app-framework";
|
|
593
|
+
import { ClientAction } from "@dxos/plugin-client/types";
|
|
594
|
+
import { ObservabilityCapabilities } from "@dxos/plugin-observability";
|
|
595
|
+
import { useIdentity } from "@dxos/react-client/halo";
|
|
596
|
+
|
|
597
|
+
// packages/plugins/plugin-navtree/src/components/HaloButton.tsx
|
|
598
|
+
import React6 from "react";
|
|
599
|
+
import { ConnectionState, useNetworkStatus } from "@dxos/react-client/mesh";
|
|
600
|
+
import { Avatar } from "@dxos/react-ui";
|
|
601
|
+
import { focusRing, mx as mx4 } from "@dxos/react-ui-theme";
|
|
602
|
+
import { hexToFallback } from "@dxos/util";
|
|
603
|
+
var INTERNAL = "https://avatars.githubusercontent.com/u/57182821";
|
|
604
|
+
var HaloButton = (props) => {
|
|
605
|
+
const { onClick, identityKey, internal, size = 8 } = props;
|
|
606
|
+
const fallbackValue = hexToFallback(identityKey ?? "0");
|
|
607
|
+
const { swarm: connectionState } = useNetworkStatus();
|
|
608
|
+
return /* @__PURE__ */ React6.createElement("button", {
|
|
609
|
+
className: mx4(focusRing, "rounded grid place-items-center"),
|
|
610
|
+
onClick
|
|
611
|
+
}, /* @__PURE__ */ React6.createElement(Avatar.Root, {
|
|
612
|
+
size,
|
|
613
|
+
variant: "circle",
|
|
614
|
+
status: connectionState === ConnectionState.OFFLINE ? "error" : internal ? "internal" : "active",
|
|
615
|
+
hue: props.hue || fallbackValue.hue
|
|
616
|
+
}, /* @__PURE__ */ React6.createElement(Avatar.Frame, {
|
|
617
|
+
"data-testid": "treeView.haloButton",
|
|
618
|
+
"data-joyride": "welcome/halo"
|
|
619
|
+
}, internal ? /* @__PURE__ */ React6.createElement(Avatar.Image, {
|
|
620
|
+
href: INTERNAL
|
|
621
|
+
}) : /* @__PURE__ */ React6.createElement(Avatar.Fallback, {
|
|
622
|
+
text: props.emoji || fallbackValue.emoji
|
|
623
|
+
}))));
|
|
624
|
+
};
|
|
625
|
+
|
|
626
|
+
// packages/plugins/plugin-navtree/src/components/NotchStart.tsx
|
|
627
|
+
var NotchStart = () => {
|
|
628
|
+
const identity = useIdentity();
|
|
629
|
+
const [observability] = useCapabilities(ObservabilityCapabilities.Observability);
|
|
630
|
+
const { dispatchPromise: dispatch } = useIntentDispatcher4();
|
|
631
|
+
return /* @__PURE__ */ React7.createElement(HaloButton, {
|
|
632
|
+
size: 8,
|
|
633
|
+
identityKey: identity?.identityKey.toHex(),
|
|
634
|
+
hue: identity?.profile?.data?.hue,
|
|
635
|
+
emoji: identity?.profile?.data?.emoji,
|
|
636
|
+
internal: observability?.group === "dxos",
|
|
637
|
+
onClick: () => dispatch(createIntent4(ClientAction.ShareIdentity))
|
|
638
|
+
});
|
|
639
|
+
};
|
|
640
|
+
|
|
641
|
+
export {
|
|
642
|
+
CommandsDialogContent,
|
|
643
|
+
CommandsTrigger,
|
|
644
|
+
getParent,
|
|
645
|
+
getPersistenceParent,
|
|
646
|
+
resolveMigrationOperation,
|
|
647
|
+
sortActions,
|
|
648
|
+
getChildren,
|
|
649
|
+
getActions,
|
|
650
|
+
expandChildrenAndActions,
|
|
651
|
+
expandChildren,
|
|
652
|
+
expandActions,
|
|
653
|
+
NODE_TYPE,
|
|
654
|
+
NavTreeContainer,
|
|
655
|
+
NavTreeDocumentTitle,
|
|
656
|
+
NotchStart
|
|
657
|
+
};
|
|
658
|
+
//# sourceMappingURL=chunk-IMGT2LAL.mjs.map
|