@dxos/plugin-navtree 0.8.4-main.1068cf700f → 0.8.4-main.1c7ec43d41
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/NavTreePlugin-3KLPENH6.mjs +54 -0
- package/dist/lib/browser/NavTreePlugin-3KLPENH6.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +98 -114
- 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/NavTreePlugin.d.ts +1 -0
- package/dist/types/src/NavTreePlugin.d.ts.map +1 -1
- package/dist/types/src/NavTreePlugin.node.d.ts +4 -0
- package/dist/types/src/NavTreePlugin.node.d.ts.map +1 -0
- package/dist/types/src/NavTreePlugin.test.d.ts +2 -0
- package/dist/types/src/NavTreePlugin.test.d.ts.map +1 -0
- package/dist/types/src/capabilities/app-graph-builder.d.ts +6 -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 +5 -0
- 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 +5 -0
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
- package/dist/types/src/capabilities/state.d.ts +6 -0
- package/dist/types/src/capabilities/state.d.ts.map +1 -0
- package/dist/types/src/components/NavTree/NavTree.d.ts +10 -32
- package/dist/types/src/components/NavTree/NavTree.d.ts.map +1 -1
- package/dist/types/src/components/NavTree/NavTree.stories.d.ts +10 -15
- 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 +4 -1
- package/dist/types/src/components/Sidebar/L0Menu.d.ts.map +1 -1
- package/dist/types/src/components/Sidebar/L1Panel.d.ts +2 -5
- package/dist/types/src/components/Sidebar/L1Panel.d.ts.map +1 -1
- package/dist/types/src/components/Sidebar/L1Tabs.d.ts +3 -2
- 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/index.d.ts +0 -3
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/components/types.d.ts +5 -14
- package/dist/types/src/components/types.d.ts.map +1 -1
- package/dist/types/src/{components/CommandsDialog/CommandsDialog.d.ts → containers/CommandsDialogContent/CommandsDialogContent.d.ts} +1 -1
- package/dist/types/src/containers/CommandsDialogContent/CommandsDialogContent.d.ts.map +1 -0
- 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 +2 -0
- package/dist/types/src/containers/CommandsDialogContent/index.d.ts.map +1 -0
- package/dist/types/src/containers/CommandsTrigger/CommandsTrigger.d.ts.map +1 -0
- package/dist/types/src/containers/CommandsTrigger/index.d.ts +2 -0
- package/dist/types/src/containers/CommandsTrigger/index.d.ts.map +1 -0
- package/dist/types/src/containers/NavTreeContainer/NavTreeContainer.d.ts +9 -0
- package/dist/types/src/containers/NavTreeContainer/NavTreeContainer.d.ts.map +1 -0
- package/dist/types/src/containers/NavTreeContainer/index.d.ts +3 -0
- package/dist/types/src/containers/NavTreeContainer/index.d.ts.map +1 -0
- package/dist/types/src/containers/NavTreeDocumentTitle/NavTreeDocumentTitle.d.ts.map +1 -0
- package/dist/types/src/containers/NavTreeDocumentTitle/index.d.ts +2 -0
- package/dist/types/src/containers/NavTreeDocumentTitle/index.d.ts.map +1 -0
- package/dist/types/src/containers/index.d.ts +7 -0
- package/dist/types/src/containers/index.d.ts.map +1 -0
- 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/index.d.ts +5 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -0
- package/dist/types/src/hooks/useActions.d.ts +5 -0
- package/dist/types/src/hooks/useActions.d.ts.map +1 -0
- package/dist/types/src/hooks/useLoadDescendents.d.ts +6 -0
- package/dist/types/src/hooks/useLoadDescendents.d.ts.map +1 -0
- package/dist/types/src/hooks/useNavTreeModel.d.ts +7 -0
- package/dist/types/src/hooks/useNavTreeModel.d.ts.map +1 -0
- package/dist/types/src/hooks/useNavTreeState.d.ts +18 -0
- package/dist/types/src/hooks/useNavTreeState.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.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 +3 -3
- 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 +7 -3
- package/dist/types/src/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +62 -43
- package/src/NavTreePlugin.node.ts +17 -0
- package/src/NavTreePlugin.test.ts +27 -0
- package/src/NavTreePlugin.tsx +8 -25
- 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} +9 -11
- package/src/capabilities/{state/state.ts → state.ts} +41 -14
- package/src/components/NavTree/NavTree.stories.tsx +26 -24
- package/src/components/NavTree/NavTree.tsx +64 -22
- 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 +7 -9
- package/src/components/NavTreeItem/NavTreeItemAction.tsx +56 -40
- package/src/components/NavTreeItem/NavTreeItemColumns.tsx +43 -17
- package/src/components/Sidebar/L0Menu.tsx +104 -110
- package/src/components/Sidebar/L1Panel.tsx +163 -142
- package/src/components/Sidebar/L1Tabs.tsx +13 -4
- package/src/components/UserAccountAvatar/UserAccountAvatar.stories.tsx +1 -2
- package/src/components/UserAccountAvatar/UserAccountAvatar.tsx +1 -1
- package/src/components/index.ts +0 -3
- package/src/components/types.ts +11 -17
- package/src/containers/CommandsDialogContent/CommandsDialogContent.stories.tsx +46 -0
- package/src/{components/CommandsDialog/CommandsDialog.tsx → containers/CommandsDialogContent/CommandsDialogContent.tsx} +52 -53
- package/src/containers/CommandsDialogContent/index.ts +5 -0
- package/src/{components/CommandsDialog → containers/CommandsTrigger}/CommandsTrigger.tsx +8 -6
- package/src/containers/CommandsTrigger/index.ts +5 -0
- package/src/{components → containers/NavTreeContainer}/NavTreeContainer.tsx +78 -145
- package/src/containers/NavTreeContainer/index.ts +6 -0
- package/src/{components → containers/NavTreeDocumentTitle}/NavTreeDocumentTitle.tsx +2 -2
- package/src/containers/NavTreeDocumentTitle/index.ts +5 -0
- package/src/containers/index.ts +12 -0
- package/src/experimental/Tree.stories.tsx +64 -61
- package/src/experimental/Tree.tsx +3 -3
- package/src/hooks/index.ts +8 -0
- package/src/hooks/useActions.ts +34 -0
- package/src/hooks/useLoadDescendents.ts +23 -0
- package/src/hooks/useNavTreeModel.ts +118 -0
- package/src/hooks/useNavTreeState.ts +35 -0
- package/src/index.ts +8 -2
- package/src/meta.ts +3 -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 +25 -25
- package/src/translations.ts +8 -10
- package/src/types/capabilities.ts +4 -4
- package/src/types/events.ts +2 -2
- package/src/util.ts +19 -5
- 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-63YLDLLE.mjs +0 -1373
- package/dist/lib/browser/chunk-63YLDLLE.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-46XQHY2O.mjs +0 -53
- package/dist/lib/browser/keyboard-46XQHY2O.mjs.map +0 -7
- package/dist/lib/browser/operation-resolver-NNNDII45.mjs +0 -53
- package/dist/lib/browser/operation-resolver-NNNDII45.mjs.map +0 -7
- package/dist/lib/browser/react-surface-APSEG23H.mjs +0 -59
- package/dist/lib/browser/react-surface-APSEG23H.mjs.map +0 -7
- package/dist/lib/browser/state-M5YUCIQU.mjs +0 -121
- package/dist/lib/browser/state-M5YUCIQU.mjs.map +0 -7
- package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts +0 -6
- 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 +0 -5
- 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 +0 -5
- 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 +0 -6
- package/dist/types/src/capabilities/state/state.d.ts.map +0 -1
- package/dist/types/src/components/CommandsDialog/CommandsDialog.d.ts.map +0 -1
- package/dist/types/src/components/CommandsDialog/CommandsTrigger.d.ts.map +0 -1
- package/dist/types/src/components/CommandsDialog/index.d.ts +0 -3
- package/dist/types/src/components/CommandsDialog/index.d.ts.map +0 -1
- package/dist/types/src/components/NavTreeContainer.d.ts +0 -16
- package/dist/types/src/components/NavTreeContainer.d.ts.map +0 -1
- package/dist/types/src/components/NavTreeContext.d.ts.map +0 -1
- package/dist/types/src/components/NavTreeDocumentTitle.d.ts.map +0 -1
- package/dist/types/src/hooks.d.ts +0 -34
- package/dist/types/src/hooks.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 -42
- package/src/capabilities/react-surface/index.ts +0 -7
- package/src/capabilities/state/index.ts +0 -7
- package/src/components/CommandsDialog/index.ts +0 -6
- package/src/hooks.ts +0 -73
- /package/dist/types/src/{components/CommandsDialog → containers/CommandsTrigger}/CommandsTrigger.d.ts +0 -0
- /package/dist/types/src/{components → containers/NavTreeDocumentTitle}/NavTreeDocumentTitle.d.ts +0 -0
|
@@ -11,11 +11,11 @@ import { Keyboard, keySymbols } from '@dxos/keyboard';
|
|
|
11
11
|
import { Graph, Node, useActionRunner } from '@dxos/plugin-graph';
|
|
12
12
|
import { useActions } from '@dxos/plugin-graph';
|
|
13
13
|
import { Button, Dialog, toLocalizedString, useTranslation } from '@dxos/react-ui';
|
|
14
|
-
import { SearchList, useSearchListResults } from '@dxos/react-ui-
|
|
14
|
+
import { SearchList, useSearchListResults } from '@dxos/react-ui-search';
|
|
15
15
|
import { osTranslations } from '@dxos/ui-theme';
|
|
16
16
|
import { getHostPlatform } from '@dxos/util';
|
|
17
17
|
|
|
18
|
-
import { KEY_BINDING, meta } from '
|
|
18
|
+
import { KEY_BINDING, meta } from '#meta';
|
|
19
19
|
|
|
20
20
|
export type CommandsDialogContentProps = {
|
|
21
21
|
selected?: string;
|
|
@@ -25,7 +25,7 @@ export type CommandsDialogContentProps = {
|
|
|
25
25
|
export const CommandsDialogContent = forwardRef<HTMLDivElement, CommandsDialogContentProps>(
|
|
26
26
|
({ selected: initial }, forwardedRef) => {
|
|
27
27
|
const { t } = useTranslation(meta.id);
|
|
28
|
-
const {
|
|
28
|
+
const { invokePromise } = useOperationInvoker();
|
|
29
29
|
const runAction = useActionRunner();
|
|
30
30
|
const { graph } = useAppGraph();
|
|
31
31
|
const [selected, setSelected] = useState<string | undefined>(initial);
|
|
@@ -38,12 +38,12 @@ export const CommandsDialogContent = forwardRef<HTMLDivElement, CommandsDialogCo
|
|
|
38
38
|
const actionMap = new Set<string>();
|
|
39
39
|
const actions: Node.ActionLike[] = [];
|
|
40
40
|
Graph.traverse(graph, {
|
|
41
|
+
relation: ['child', 'action'],
|
|
41
42
|
visitor: (node, path) => {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
) {
|
|
43
|
+
const isActionLike = Node.isAction(node) || Node.isActionGroup(node);
|
|
44
|
+
const parentId = path.at(-2) ?? '';
|
|
45
|
+
const matches = current === parentId || current.startsWith(parentId + '/');
|
|
46
|
+
if (isActionLike && !actionMap.has(node.id) && matches) {
|
|
47
47
|
actionMap.add(node.id);
|
|
48
48
|
actions.push(node);
|
|
49
49
|
}
|
|
@@ -70,58 +70,57 @@ export const CommandsDialogContent = forwardRef<HTMLDivElement, CommandsDialogCo
|
|
|
70
70
|
|
|
71
71
|
return (
|
|
72
72
|
<Dialog.Content ref={forwardedRef}>
|
|
73
|
-
<Dialog.Title>{t('commands
|
|
73
|
+
<Dialog.Title srOnly>{t('commands-dialog.title', { ns: meta.id })}</Dialog.Title>
|
|
74
74
|
<SearchList.Root onSearch={handleSearch}>
|
|
75
|
-
<SearchList.
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
: action.properties.keyBinding?.[getHostPlatform()];
|
|
75
|
+
<SearchList.Input placeholder={t('command-list-input.placeholder')} />
|
|
76
|
+
<SearchList.Viewport>
|
|
77
|
+
{results.map((action) => {
|
|
78
|
+
const shortcut =
|
|
79
|
+
typeof action.properties.keyBinding === 'string'
|
|
80
|
+
? action.properties.keyBinding
|
|
81
|
+
: action.properties.keyBinding?.[getHostPlatform()];
|
|
83
82
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
83
|
+
return (
|
|
84
|
+
<SearchList.Item
|
|
85
|
+
value={action.id}
|
|
86
|
+
key={action.id}
|
|
87
|
+
label={toLocalizedString(action.properties.label, t)}
|
|
88
|
+
icon={action.properties.icon}
|
|
89
|
+
suffix={shortcut ? keySymbols(shortcut).join('') : undefined}
|
|
90
|
+
onSelect={() => {
|
|
91
|
+
if (action.properties.disabled) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
95
94
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
95
|
+
if (Node.isActionGroup(action)) {
|
|
96
|
+
setSelected(action.id);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
100
99
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
</SearchList.
|
|
100
|
+
void invokePromise(LayoutOperation.UpdateDialog, { state: false });
|
|
101
|
+
setTimeout(() => {
|
|
102
|
+
const lookupId = group?.id ?? action.id;
|
|
103
|
+
const node = Graph.getConnections(graph, lookupId, Node.actionRelation('inbound'))[0];
|
|
104
|
+
if (node && Node.isAction(action)) {
|
|
105
|
+
void runAction(action, { parent: node, caller: KEY_BINDING });
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}}
|
|
109
|
+
classNames='flex items-center gap-2'
|
|
110
|
+
disabled={action.properties.disabled}
|
|
111
|
+
{...(action.properties?.testId && {
|
|
112
|
+
'data-testid': action.properties.testId,
|
|
113
|
+
})}
|
|
114
|
+
/>
|
|
115
|
+
);
|
|
116
|
+
})}
|
|
117
|
+
</SearchList.Viewport>
|
|
119
118
|
</SearchList.Root>
|
|
120
|
-
<
|
|
119
|
+
<Dialog.ActionBar>
|
|
121
120
|
<Dialog.Close asChild>
|
|
122
|
-
<Button classNames='
|
|
121
|
+
<Button classNames='w-full'>{t('close.label', { ns: osTranslations })}</Button>
|
|
123
122
|
</Dialog.Close>
|
|
124
|
-
</
|
|
123
|
+
</Dialog.ActionBar>
|
|
125
124
|
</Dialog.Content>
|
|
126
125
|
);
|
|
127
126
|
},
|
|
@@ -8,19 +8,21 @@ import { useOperationInvoker } from '@dxos/app-framework/ui';
|
|
|
8
8
|
import { LayoutOperation } from '@dxos/app-toolkit';
|
|
9
9
|
import { Button, Icon, useTranslation } from '@dxos/react-ui';
|
|
10
10
|
|
|
11
|
-
import { COMMANDS_DIALOG, meta } from '
|
|
11
|
+
import { COMMANDS_DIALOG, meta } from '#meta';
|
|
12
12
|
|
|
13
13
|
// TODO(thure): Refactor to be handled by a more appropriate plugin.
|
|
14
14
|
export const CommandsTrigger = () => {
|
|
15
|
-
const {
|
|
15
|
+
const { invokePromise } = useOperationInvoker();
|
|
16
16
|
const { t } = useTranslation(meta.id);
|
|
17
17
|
return (
|
|
18
18
|
<Button
|
|
19
|
-
classNames='m-1
|
|
20
|
-
onClick={() =>
|
|
19
|
+
classNames='m-1 px-1 lg:px-2'
|
|
20
|
+
onClick={() =>
|
|
21
|
+
void invokePromise(LayoutOperation.UpdateDialog, { subject: COMMANDS_DIALOG, blockAlign: 'start' })
|
|
22
|
+
}
|
|
21
23
|
>
|
|
22
|
-
<span className='text-description font-normal grow text-start'>{t('command
|
|
23
|
-
<Icon icon='ph--magnifying-glass--regular'
|
|
24
|
+
<span className='text-description font-normal grow text-start'>{t('command-list-input.placeholder')}</span>
|
|
25
|
+
<Icon icon='ph--magnifying-glass--regular' />
|
|
24
26
|
</Button>
|
|
25
27
|
);
|
|
26
28
|
};
|
|
@@ -2,168 +2,114 @@
|
|
|
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';
|
|
7
|
-
import
|
|
6
|
+
import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
|
|
7
|
+
import React, { forwardRef, memo, useCallback, useEffect, useMemo, useRef } from 'react';
|
|
8
8
|
|
|
9
9
|
import { Surface, useOperationInvoker } from '@dxos/app-framework/ui';
|
|
10
10
|
import { LayoutOperation } from '@dxos/app-toolkit';
|
|
11
11
|
import { useAppGraph, useLayout } from '@dxos/app-toolkit/ui';
|
|
12
|
-
import { PLANK_COMPANION_TYPE } from '@dxos/plugin-deck/types';
|
|
13
12
|
import { Graph, Node, useActionRunner } from '@dxos/plugin-graph';
|
|
14
|
-
import { useConnections, useActions as useGraphActions } from '@dxos/plugin-graph';
|
|
15
13
|
import { useMediaQuery, useSidebars } from '@dxos/react-ui';
|
|
16
|
-
import { type TreeData,
|
|
17
|
-
import {
|
|
18
|
-
import { arrayMove, byPosition } from '@dxos/util';
|
|
14
|
+
import { type TreeData, isTreeData } from '@dxos/react-ui-list';
|
|
15
|
+
import { arrayMove } from '@dxos/util';
|
|
19
16
|
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
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';
|
|
24
21
|
|
|
25
|
-
import {
|
|
26
|
-
import { NavTreeContext } from './NavTreeContext';
|
|
27
|
-
import { type NavTreeContextValue } from './types';
|
|
22
|
+
import { filterItems, getParent, resolveMigrationOperation } from '../../util';
|
|
28
23
|
|
|
29
24
|
// TODO(thure): Is NavTree truly authoritative in this regard?
|
|
30
25
|
export const NODE_TYPE = 'dxos/app-graph/node';
|
|
31
26
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
);
|
|
35
|
-
|
|
36
|
-
const getChildrenFilter = (node: Node.Node): node is Node.Node =>
|
|
37
|
-
!Node.isActionLike(node) && node.type !== PLANK_COMPANION_TYPE && node.properties.disposition !== 'hidden';
|
|
38
|
-
|
|
39
|
-
const filterItems = (node: Node.Node, disposition?: string) => {
|
|
40
|
-
if (!disposition && (node.properties.disposition === 'hidden' || node.properties.disposition === 'alternate-tree')) {
|
|
41
|
-
return false;
|
|
42
|
-
} else if (!disposition) {
|
|
43
|
-
const action = Node.isAction(node);
|
|
44
|
-
return !action || node.properties.disposition === 'item';
|
|
45
|
-
} else {
|
|
46
|
-
return node.properties.disposition === disposition;
|
|
47
|
-
}
|
|
27
|
+
// TODO(wittjosiah): Avoid using Surface within the navtree, prefer declarative data flow.
|
|
28
|
+
const NavTreeItemEnd = ({ node, open }: { node: Node.Node; open: boolean }) => {
|
|
29
|
+
const data = useMemo(() => ({ id: node.id, subject: node.data, open }), [node.id, node.data, open]);
|
|
30
|
+
return <Surface.Surface role='navtree-item-end' data={data} limit={1} />;
|
|
48
31
|
};
|
|
49
32
|
|
|
50
33
|
const getItems = (graph: Graph.ReadableGraph, node?: Node.Node, disposition?: string) => {
|
|
51
|
-
return Graph.getConnections(graph, node?.id ?? Node.RootId, '
|
|
52
|
-
filterItems(node, disposition),
|
|
53
|
-
);
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
const useItems = (node?: Node.Node, options?: { disposition?: string; sort?: boolean }) => {
|
|
57
|
-
const { graph } = useAppGraph();
|
|
58
|
-
const connections = useConnections(graph, node?.id ?? Node.RootId);
|
|
59
|
-
const filtered = connections.filter((node) => filterItems(node, options?.disposition));
|
|
60
|
-
return options?.sort ? filtered.toSorted((a, b) => byPosition(a.properties, b.properties)) : filtered;
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
const useActions = (node: Node.Node): FlattenedActions => {
|
|
64
|
-
const { graph } = useAppGraph();
|
|
65
|
-
const actions = useGraphActions(graph, node.id);
|
|
66
|
-
|
|
67
|
-
return useMemo(
|
|
68
|
-
() =>
|
|
69
|
-
actions.reduce(
|
|
70
|
-
(acc: FlattenedActions, arg) => {
|
|
71
|
-
if (arg.properties.disposition === 'item') {
|
|
72
|
-
return acc;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
acc.actions.push(arg);
|
|
76
|
-
if (!Node.isAction(arg)) {
|
|
77
|
-
const actionGroup = Graph.getActions(graph, arg.id);
|
|
78
|
-
acc.groupedActions[arg.id] = actionGroup;
|
|
79
|
-
}
|
|
80
|
-
return acc;
|
|
81
|
-
},
|
|
82
|
-
{ actions: [], groupedActions: {} },
|
|
83
|
-
),
|
|
84
|
-
[actions],
|
|
85
|
-
);
|
|
34
|
+
return Graph.getConnections(graph, node?.id ?? Node.RootId, 'child').filter((node) => filterItems(node, disposition));
|
|
86
35
|
};
|
|
87
36
|
|
|
88
37
|
export type NavTreeContainerProps = {
|
|
89
38
|
popoverAnchorId?: string;
|
|
90
|
-
|
|
91
|
-
}
|
|
39
|
+
tab: string;
|
|
40
|
+
};
|
|
92
41
|
|
|
93
42
|
export const NavTreeContainer$ = forwardRef<HTMLDivElement, NavTreeContainerProps>(
|
|
94
|
-
({ tab, popoverAnchorId
|
|
43
|
+
({ tab, popoverAnchorId }, forwardedRef) => {
|
|
95
44
|
const [isLg] = useMediaQuery('lg');
|
|
96
|
-
const {
|
|
45
|
+
const { invokePromise } = useOperationInvoker();
|
|
97
46
|
const runAction = useActionRunner();
|
|
98
47
|
const { graph } = useAppGraph();
|
|
99
48
|
const { getItem, setItem } = useNavTreeState();
|
|
100
49
|
const layout = useLayout();
|
|
50
|
+
const model = useNavTreeModel(Node.RootId);
|
|
101
51
|
const { navigationSidebarState } = useSidebars(meta.id);
|
|
52
|
+
const latestRef = useRef({
|
|
53
|
+
tab,
|
|
54
|
+
activeItems: layout.active,
|
|
55
|
+
navigationSidebarState,
|
|
56
|
+
isLg,
|
|
57
|
+
});
|
|
102
58
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
disabled: node.properties.disabled,
|
|
112
|
-
label: node.properties.label ?? node.id,
|
|
113
|
-
className: mx(node.properties.className, node.properties.modified && 'italic'), // TODO(burdon): Italic?
|
|
114
|
-
headingClassName: node.properties.headingClassName,
|
|
115
|
-
icon: node.properties.icon,
|
|
116
|
-
iconHue: node.properties.iconHue,
|
|
117
|
-
testId: node.properties.testId,
|
|
118
|
-
};
|
|
119
|
-
},
|
|
120
|
-
[graph],
|
|
121
|
-
);
|
|
122
|
-
|
|
123
|
-
const loadDescendents = useCallback(
|
|
124
|
-
(node: Node.Node) => {
|
|
125
|
-
Graph.expand(graph, node.id, 'outbound');
|
|
126
|
-
// Load one level deeper, which resolves some juddering observed on open/close.
|
|
127
|
-
Graph.getConnections(graph, node.id, 'outbound').forEach((child) => {
|
|
128
|
-
Graph.expand(graph, child.id, 'outbound');
|
|
129
|
-
});
|
|
130
|
-
},
|
|
131
|
-
[graph],
|
|
132
|
-
);
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
latestRef.current = {
|
|
61
|
+
tab,
|
|
62
|
+
activeItems: layout.active,
|
|
63
|
+
navigationSidebarState,
|
|
64
|
+
isLg,
|
|
65
|
+
};
|
|
66
|
+
}, [tab, layout.active, navigationSidebarState, isLg]);
|
|
133
67
|
|
|
134
68
|
const handleOpenChange = useCallback(
|
|
135
69
|
({ item: { id }, path, open }: { item: Node.Node; path: string[]; open: boolean }) => {
|
|
136
70
|
// TODO(thure): This might become a localstorage leak; openItemIds that no longer exist should be removed from this map.
|
|
137
71
|
setItem(path, 'open', open);
|
|
138
|
-
Graph.expand(graph, id, '
|
|
72
|
+
Graph.expand(graph, id, 'child');
|
|
139
73
|
},
|
|
140
|
-
[graph],
|
|
74
|
+
[graph, setItem],
|
|
141
75
|
);
|
|
142
76
|
|
|
143
77
|
const handleTabChange = useCallback(
|
|
144
78
|
(node: NavTreeItemGraphNode) => {
|
|
145
|
-
|
|
79
|
+
Graph.expand(graph, node.id, 'child');
|
|
80
|
+
|
|
81
|
+
const {
|
|
82
|
+
tab: activeTab,
|
|
83
|
+
activeItems,
|
|
84
|
+
navigationSidebarState: currentSidebarState,
|
|
85
|
+
isLg: latestIsLg,
|
|
86
|
+
} = latestRef.current;
|
|
87
|
+
void invokePromise(LayoutOperation.UpdateSidebar, {
|
|
146
88
|
state:
|
|
147
|
-
node.id ===
|
|
148
|
-
?
|
|
149
|
-
?
|
|
89
|
+
node.id === activeTab
|
|
90
|
+
? currentSidebarState === 'expanded'
|
|
91
|
+
? latestIsLg
|
|
150
92
|
? 'collapsed'
|
|
151
93
|
: 'closed'
|
|
152
94
|
: 'expanded'
|
|
153
95
|
: 'expanded',
|
|
154
96
|
});
|
|
155
97
|
|
|
156
|
-
|
|
98
|
+
void invokePromise(LayoutOperation.SwitchWorkspace, { subject: node.id });
|
|
157
99
|
|
|
158
100
|
// Open the first item if the workspace is empty.
|
|
159
|
-
if (
|
|
101
|
+
if (activeItems.length === 0) {
|
|
160
102
|
const [item] = getItems(graph, node).filter((node) => !Node.isActionLike(node));
|
|
161
103
|
if (item && item.data) {
|
|
162
|
-
|
|
104
|
+
if (layout.mode === 'multi') {
|
|
105
|
+
void invokePromise(LayoutOperation.Set, { subject: [item.id] });
|
|
106
|
+
} else {
|
|
107
|
+
void invokePromise(LayoutOperation.Open, { subject: [item.id] });
|
|
108
|
+
}
|
|
163
109
|
}
|
|
164
110
|
}
|
|
165
111
|
},
|
|
166
|
-
[
|
|
112
|
+
[invokePromise, graph, layout.mode],
|
|
167
113
|
);
|
|
168
114
|
|
|
169
115
|
const blockInstruction = useCallback(
|
|
@@ -188,18 +134,22 @@ export const NavTreeContainer$ = forwardRef<HTMLDivElement, NavTreeContainerProp
|
|
|
188
134
|
}
|
|
189
135
|
|
|
190
136
|
if (Node.isAction(node)) {
|
|
191
|
-
const [parent] = Graph.getConnections(graph, node.id, 'inbound');
|
|
137
|
+
const [parent] = Graph.getConnections(graph, node.id, Node.childRelation('inbound'));
|
|
192
138
|
if (parent) {
|
|
193
|
-
void runAction(node, { parent, caller: NAV_TREE_ITEM });
|
|
139
|
+
void runAction(node, { parent, path, caller: NAV_TREE_ITEM });
|
|
194
140
|
}
|
|
195
141
|
return;
|
|
196
142
|
}
|
|
197
143
|
|
|
198
144
|
const current = getItem(path).current;
|
|
199
145
|
if (!current) {
|
|
200
|
-
|
|
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
|
+
}
|
|
201
151
|
} else if (option) {
|
|
202
|
-
|
|
152
|
+
void invokePromise(LayoutOperation.Close, { subject: [node.id] });
|
|
203
153
|
} else {
|
|
204
154
|
void invokePromise(LayoutOperation.ScrollIntoView, { subject: node.id });
|
|
205
155
|
}
|
|
@@ -212,13 +162,13 @@ export const NavTreeContainer$ = forwardRef<HTMLDivElement, NavTreeContainerProp
|
|
|
212
162
|
}
|
|
213
163
|
|
|
214
164
|
if (!isLg) {
|
|
215
|
-
|
|
165
|
+
void invokePromise(LayoutOperation.UpdateSidebar, { state: 'closed' });
|
|
216
166
|
}
|
|
217
167
|
},
|
|
218
|
-
[graph,
|
|
168
|
+
[graph, invokePromise, getItem, runAction, isLg, layout.mode],
|
|
219
169
|
);
|
|
220
170
|
|
|
221
|
-
const handleBack = useCallback(() =>
|
|
171
|
+
const handleBack = useCallback(() => void invokePromise(LayoutOperation.RevertWorkspace), [invokePromise]);
|
|
222
172
|
|
|
223
173
|
// TODO(wittjosiah): Factor out hook.
|
|
224
174
|
useEffect(() => {
|
|
@@ -236,8 +186,9 @@ export const NavTreeContainer$ = forwardRef<HTMLDivElement, NavTreeContainerProp
|
|
|
236
186
|
const targetNode = target.data.item as NavTreeItemGraphNode;
|
|
237
187
|
const sourcePath = source.data.path as string[];
|
|
238
188
|
const targetPath = target.data.path as string[];
|
|
189
|
+
const sameParent = sourcePath.slice(0, -1).join() === targetPath.slice(0, -1).join();
|
|
239
190
|
const operation =
|
|
240
|
-
|
|
191
|
+
sameParent && instruction.type !== 'make-child'
|
|
241
192
|
? 'rearrange'
|
|
242
193
|
: resolveMigrationOperation(graph, sourceNode, targetPath, targetNode);
|
|
243
194
|
const sourceParent = getParent(graph, sourceNode, sourcePath);
|
|
@@ -266,7 +217,7 @@ export const NavTreeContainer$ = forwardRef<HTMLDivElement, NavTreeContainerProp
|
|
|
266
217
|
}
|
|
267
218
|
case 'transfer': {
|
|
268
219
|
const target = instruction.type === 'make-child' ? targetNode : targetParent;
|
|
269
|
-
if (!target?.properties.onTransferStart ||
|
|
220
|
+
if (!target?.properties.onTransferStart || target?.id === sourceParent?.id) {
|
|
270
221
|
break;
|
|
271
222
|
}
|
|
272
223
|
void target?.properties.onTransferStart(sourceNode, migrationIndex);
|
|
@@ -279,57 +230,39 @@ export const NavTreeContainer$ = forwardRef<HTMLDivElement, NavTreeContainerProp
|
|
|
279
230
|
});
|
|
280
231
|
}, [graph]);
|
|
281
232
|
|
|
282
|
-
const
|
|
283
|
-
(path: string[], open: boolean) => {
|
|
284
|
-
setItem(path, 'alternateTree', open);
|
|
285
|
-
},
|
|
286
|
-
[setItem],
|
|
287
|
-
);
|
|
233
|
+
const onItemHover = useCallback(({ item }: { item: Node.Node }) => Graph.expand(graph, item.id, 'child'), [graph]);
|
|
288
234
|
|
|
289
235
|
const navTreeContextValue = useMemo(
|
|
290
236
|
() => ({
|
|
237
|
+
model,
|
|
238
|
+
popoverAnchorId,
|
|
239
|
+
renderItemEnd: NavTreeItemEnd,
|
|
291
240
|
blockInstruction,
|
|
292
241
|
canDrop,
|
|
293
242
|
canSelect,
|
|
294
|
-
getProps,
|
|
295
|
-
useIsAlternateTree,
|
|
296
|
-
useIsCurrent,
|
|
297
|
-
useIsOpen,
|
|
298
|
-
loadDescendents,
|
|
299
243
|
onBack: handleBack,
|
|
300
244
|
onOpenChange: handleOpenChange,
|
|
301
245
|
onSelect: handleSelect,
|
|
302
246
|
onTabChange: handleTabChange,
|
|
303
|
-
|
|
304
|
-
renderItemEnd,
|
|
305
|
-
setAlternateTree,
|
|
306
|
-
tab,
|
|
307
|
-
topbar,
|
|
308
|
-
useActions,
|
|
309
|
-
useItems,
|
|
247
|
+
onItemHover,
|
|
310
248
|
}),
|
|
311
249
|
[
|
|
250
|
+
model,
|
|
251
|
+
popoverAnchorId,
|
|
312
252
|
blockInstruction,
|
|
313
253
|
canDrop,
|
|
314
254
|
canSelect,
|
|
315
|
-
getProps,
|
|
316
255
|
handleBack,
|
|
317
256
|
handleOpenChange,
|
|
318
257
|
handleSelect,
|
|
319
258
|
handleTabChange,
|
|
320
|
-
|
|
321
|
-
popoverAnchorId,
|
|
322
|
-
renderItemEnd,
|
|
323
|
-
setAlternateTree,
|
|
324
|
-
tab,
|
|
325
|
-
topbar,
|
|
326
|
-
useActions,
|
|
259
|
+
onItemHover,
|
|
327
260
|
],
|
|
328
261
|
);
|
|
329
262
|
|
|
330
263
|
return (
|
|
331
264
|
<NavTreeContext.Provider value={navTreeContextValue}>
|
|
332
|
-
<NavTree id={Node.RootId} root={Graph.getRoot(graph)} open={layout.sidebarOpen} ref={forwardedRef} />
|
|
265
|
+
<NavTree id={Node.RootId} root={Graph.getRoot(graph)} tab={tab} open={layout.sidebarOpen} ref={forwardedRef} />
|
|
333
266
|
</NavTreeContext.Provider>
|
|
334
267
|
);
|
|
335
268
|
},
|
|
@@ -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
|
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type ComponentType, lazy } from 'react';
|
|
6
|
+
|
|
7
|
+
export { NODE_TYPE } from './NavTreeContainer';
|
|
8
|
+
|
|
9
|
+
export const CommandsDialogContent: ComponentType<any> = lazy(() => import('./CommandsDialogContent'));
|
|
10
|
+
export const CommandsTrigger: ComponentType<any> = lazy(() => import('./CommandsTrigger'));
|
|
11
|
+
export const NavTreeContainer: ComponentType<any> = lazy(() => import('./NavTreeContainer'));
|
|
12
|
+
export const NavTreeDocumentTitle: ComponentType<any> = lazy(() => import('./NavTreeDocumentTitle'));
|