@dxos/plugin-navtree 0.8.4-main.422d1c7879 → 0.8.4-main.43cb759274
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/LICENSE +102 -5
- package/PLUGIN.mdl +376 -0
- package/README.md +1 -1
- package/dist/lib/neutral/CommandsDialogContent-UBGIQ5FI.mjs +112 -0
- package/dist/lib/neutral/CommandsDialogContent-UBGIQ5FI.mjs.map +7 -0
- package/dist/lib/neutral/CommandsTrigger-BH5WLMHK.mjs +27 -0
- package/dist/lib/neutral/CommandsTrigger-BH5WLMHK.mjs.map +7 -0
- package/dist/lib/neutral/NavTreeContainer-6AR4BFDD.mjs +12 -0
- package/dist/lib/neutral/NavTreeContainer-6AR4BFDD.mjs.map +7 -0
- package/dist/lib/neutral/NavTreeDocumentTitle-H3E6ZLYE.mjs +22 -0
- package/dist/lib/neutral/NavTreeDocumentTitle-H3E6ZLYE.mjs.map +7 -0
- package/dist/lib/neutral/NavTreePlugin.mjs +68 -0
- package/dist/lib/neutral/NavTreePlugin.mjs.map +7 -0
- package/dist/lib/neutral/NavTreePlugin.node.mjs +18 -0
- package/dist/lib/neutral/NavTreePlugin.node.mjs.map +7 -0
- package/dist/lib/neutral/NavTreePlugin.workerd.mjs +16 -0
- package/dist/lib/neutral/NavTreePlugin.workerd.mjs.map +7 -0
- package/dist/lib/neutral/app-graph-builder-Z347LKSF.mjs +42 -0
- package/dist/lib/neutral/app-graph-builder-Z347LKSF.mjs.map +7 -0
- package/dist/lib/neutral/capabilities/index.mjs +17 -0
- package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
- package/dist/lib/neutral/chunk-5OPDKH6B.mjs +273 -0
- package/dist/lib/neutral/chunk-5OPDKH6B.mjs.map +7 -0
- package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
- package/dist/lib/neutral/chunk-J5LGTIGS.mjs.map +7 -0
- package/dist/lib/neutral/chunk-JOSNCOV4.mjs +79 -0
- package/dist/lib/neutral/chunk-JOSNCOV4.mjs.map +7 -0
- package/dist/lib/neutral/chunk-MDGKDQMZ.mjs +37 -0
- package/dist/lib/neutral/chunk-MDGKDQMZ.mjs.map +7 -0
- package/dist/lib/neutral/chunk-T7QS2EFI.mjs +8 -0
- package/dist/lib/neutral/chunk-T7QS2EFI.mjs.map +7 -0
- package/dist/lib/neutral/chunk-ZSWYB7JW.mjs +27 -0
- package/dist/lib/neutral/chunk-ZSWYB7JW.mjs.map +7 -0
- package/dist/lib/neutral/components/index.mjs +807 -0
- package/dist/lib/neutral/components/index.mjs.map +7 -0
- package/dist/lib/neutral/containers/index.mjs +20 -0
- package/dist/lib/neutral/containers/index.mjs.map +7 -0
- package/dist/lib/neutral/expose-26FV4W5D.mjs +38 -0
- package/dist/lib/neutral/expose-26FV4W5D.mjs.map +7 -0
- package/dist/lib/neutral/hooks/index.mjs +178 -0
- package/dist/lib/neutral/hooks/index.mjs.map +7 -0
- package/dist/lib/neutral/index.mjs +34 -0
- package/dist/lib/neutral/index.mjs.map +7 -0
- package/dist/lib/neutral/keyboard-EJ65BVTC.mjs +56 -0
- package/dist/lib/neutral/keyboard-EJ65BVTC.mjs.map +7 -0
- package/dist/lib/neutral/meta.json +1 -0
- package/dist/lib/neutral/meta.mjs +12 -0
- package/dist/lib/neutral/meta.mjs.map +7 -0
- package/dist/lib/neutral/operation-handler-ORDOJUL2.mjs +13 -0
- package/dist/lib/neutral/operation-handler-ORDOJUL2.mjs.map +7 -0
- package/dist/lib/neutral/operations/index.mjs +8 -0
- package/dist/lib/neutral/operations/index.mjs.map +7 -0
- package/dist/lib/neutral/plugin.mjs +16 -0
- package/dist/lib/neutral/plugin.mjs.map +7 -0
- package/dist/lib/neutral/react-surface-Q5XMAG7Z.mjs +50 -0
- package/dist/lib/neutral/react-surface-Q5XMAG7Z.mjs.map +7 -0
- package/dist/lib/neutral/state-VVITVXWM.mjs +127 -0
- package/dist/lib/neutral/state-VVITVXWM.mjs.map +7 -0
- package/dist/lib/neutral/testing/index.mjs +439 -0
- package/dist/lib/neutral/testing/index.mjs.map +7 -0
- package/dist/lib/neutral/translations.mjs +23 -0
- package/dist/lib/neutral/translations.mjs.map +7 -0
- package/dist/lib/neutral/types/index.mjs +10 -0
- package/dist/lib/neutral/types/index.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/NavTreePlugin.workerd.d.ts +4 -0
- package/dist/types/src/NavTreePlugin.workerd.d.ts.map +1 -0
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/capabilities/index.d.ts +2 -2
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/keyboard.d.ts.map +1 -1
- package/dist/types/src/capabilities/operation-handler.d.ts +1 -1
- package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/capabilities/state.d.ts +2 -2
- package/dist/types/src/capabilities/state.d.ts.map +1 -1
- package/dist/types/src/components/NavTree/NavTree.stories.d.ts +8 -9
- package/dist/types/src/components/NavTree/NavTree.stories.d.ts.map +1 -1
- package/dist/types/src/components/NavTreeItem/NavTreeItemAction.d.ts +2 -2
- package/dist/types/src/components/NavTreeItem/NavTreeItemAction.d.ts.map +1 -1
- package/dist/types/src/components/NavTreeItem/NavTreeItemAction.stories.d.ts +1 -1
- package/dist/types/src/components/NavTreeItem/NavTreeItemAction.stories.d.ts.map +1 -1
- package/dist/types/src/components/NavTreeItem/NavTreeItemColumns.d.ts.map +1 -1
- package/dist/types/src/components/Sidebar/L0Menu.d.ts.map +1 -1
- package/dist/types/src/components/Sidebar/L1Panel.d.ts.map +1 -1
- package/dist/types/src/components/Sidebar/L1Tabs.d.ts.map +1 -1
- package/dist/types/src/components/UserAccountAvatar/UserAccountAvatar.d.ts.map +1 -1
- package/dist/types/src/components/UserAccountAvatar/UserAccountAvatar.stories.d.ts.map +1 -1
- package/dist/types/src/components/types.d.ts +0 -1
- package/dist/types/src/components/types.d.ts.map +1 -1
- package/dist/types/src/containers/CommandsDialogContent/CommandsDialogContent.stories.d.ts +8 -9
- package/dist/types/src/containers/CommandsDialogContent/CommandsDialogContent.stories.d.ts.map +1 -1
- package/dist/types/src/containers/NavTreeContainer/NavTreeContainer.d.ts.map +1 -1
- package/dist/types/src/containers/NavTreeDocumentTitle/NavTreeDocumentTitle.d.ts.map +1 -1
- package/dist/types/src/experimental/Tree.d.ts +2 -2
- package/dist/types/src/experimental/Tree.d.ts.map +1 -1
- package/dist/types/src/experimental/Tree.stories.d.ts.map +1 -1
- package/dist/types/src/hooks/useActions.d.ts +6 -0
- package/dist/types/src/hooks/useActions.d.ts.map +1 -1
- package/dist/types/src/hooks/useLoadDescendents.d.ts.map +1 -1
- package/dist/types/src/hooks/useNavTreeModel.d.ts.map +1 -1
- package/dist/types/src/hooks/useNavTreeState.d.ts +1 -5
- package/dist/types/src/hooks/useNavTreeState.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 +3 -2
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/operations/expose.d.ts +1 -1
- package/dist/types/src/operations/expose.d.ts.map +1 -1
- package/dist/types/src/operations/index.d.ts +1 -1
- package/dist/types/src/operations/index.d.ts.map +1 -1
- package/dist/types/src/plugin.d.ts +4 -0
- package/dist/types/src/plugin.d.ts.map +1 -0
- package/dist/types/src/testing/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/testing/generator.d.ts.map +1 -1
- package/dist/types/src/testing/update-state.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +8 -10
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/NavTreeCapabilities.d.ts +13 -0
- package/dist/types/src/types/NavTreeCapabilities.d.ts.map +1 -0
- package/dist/types/src/types/NavTreeEvents.d.ts +3 -0
- package/dist/types/src/types/NavTreeEvents.d.ts.map +1 -0
- package/dist/types/src/types/index.d.ts +2 -2
- package/dist/types/src/types/index.d.ts.map +1 -1
- package/dist/types/src/types/schema.d.ts +4 -0
- package/dist/types/src/types/schema.d.ts.map +1 -1
- package/dist/types/src/util.d.ts +1 -1
- package/dist/types/src/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +108 -55
- package/src/NavTreePlugin.node.ts +17 -0
- package/src/NavTreePlugin.test.ts +27 -0
- package/src/NavTreePlugin.tsx +10 -22
- package/src/NavTreePlugin.workerd.ts +16 -0
- package/src/capabilities/app-graph-builder.ts +1 -1
- package/src/capabilities/index.ts +1 -1
- package/src/capabilities/operation-handler.ts +1 -1
- package/src/capabilities/react-surface.tsx +3 -3
- package/src/capabilities/state.ts +12 -8
- package/src/components/NavTree/NavTree.stories.tsx +8 -10
- package/src/components/NavTree/NavTree.tsx +2 -2
- package/src/components/NavTreeItem/NavTreeItemAction.stories.tsx +2 -2
- package/src/components/NavTreeItem/NavTreeItemAction.tsx +12 -12
- package/src/components/NavTreeItem/NavTreeItemColumns.tsx +17 -60
- package/src/components/Sidebar/L0Menu.tsx +17 -11
- package/src/components/Sidebar/L1Panel.tsx +87 -168
- package/src/components/types.ts +0 -1
- package/src/containers/CommandsDialogContent/CommandsDialogContent.stories.tsx +2 -1
- package/src/containers/NavTreeContainer/NavTreeContainer.tsx +0 -9
- package/src/experimental/Tree.tsx +2 -2
- package/src/hooks/useActions.ts +10 -0
- package/src/hooks/useNavTreeModel.ts +3 -1
- package/src/hooks/useNavTreeState.ts +1 -8
- package/src/index.ts +1 -2
- package/src/meta.ts +22 -7
- package/src/operations/expose.ts +1 -1
- package/src/operations/index.ts +1 -1
- package/src/plugin.ts +11 -0
- package/src/testing/app-graph-builder.ts +7 -5
- package/src/testing/generator.ts +2 -7
- package/src/translations.ts +0 -1
- package/src/types/NavTreeCapabilities.ts +21 -0
- package/src/types/{events.ts → NavTreeEvents.ts} +3 -3
- package/src/types/index.ts +3 -2
- package/src/types/schema.ts +4 -0
- package/src/util.ts +1 -1
- package/src/vite-env.d.ts +10 -0
- package/dist/lib/browser/index.mjs +0 -202
- package/dist/lib/browser/index.mjs.map +0 -7
- package/dist/lib/browser/meta.json +0 -1
- package/dist/types/src/types/capabilities.d.ts +0 -16
- package/dist/types/src/types/capabilities.d.ts.map +0 -1
- package/dist/types/src/types/events.d.ts +0 -5
- package/dist/types/src/types/events.d.ts.map +0 -1
- package/src/types/capabilities.ts +0 -21
|
@@ -4,90 +4,47 @@
|
|
|
4
4
|
|
|
5
5
|
import React, { Fragment, memo, useMemo } from 'react';
|
|
6
6
|
|
|
7
|
-
import { Node } from '@dxos/app-graph';
|
|
8
7
|
import { Popover, Treegrid, toLocalizedString, useTranslation } from '@dxos/react-ui';
|
|
9
8
|
|
|
10
|
-
import { useActions } from '#hooks';
|
|
9
|
+
import { getListActions, useActions } from '#hooks';
|
|
11
10
|
import { meta } from '#meta';
|
|
12
11
|
|
|
13
12
|
import { NAV_TREE_ITEM } from '../NavTree';
|
|
14
13
|
import { useNavTreeContext } from '../NavTreeContext';
|
|
15
14
|
import { type NavTreeItemColumnsProps } from '../types';
|
|
16
|
-
import {
|
|
15
|
+
import { NavTreeItemActionDropdownMenu, NavTreeItemMonolithicAction } from './NavTreeItemAction';
|
|
17
16
|
|
|
18
17
|
export const NavTreeItemColumns = memo(({ path, item, open }: NavTreeItemColumnsProps) => {
|
|
19
18
|
const { t } = useTranslation(meta.id);
|
|
20
19
|
const { renderItemEnd: ItemEnd, popoverAnchorId } = useNavTreeContext();
|
|
21
20
|
|
|
22
21
|
const level = path.length - 2;
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
() =>
|
|
26
|
-
actionsProp.toSorted((actionA, actionB) => {
|
|
27
|
-
const primaryA = actionA.properties?.disposition === 'list-item-primary';
|
|
28
|
-
const primaryB = actionB.properties?.disposition === 'list-item-primary';
|
|
29
|
-
if (primaryA && !primaryB) {
|
|
30
|
-
return -1;
|
|
31
|
-
}
|
|
32
|
-
if (primaryB && !primaryA) {
|
|
33
|
-
return 1;
|
|
34
|
-
}
|
|
35
|
-
return 0;
|
|
36
|
-
}),
|
|
37
|
-
[actionsProp],
|
|
38
|
-
);
|
|
39
|
-
const [primaryAction, ...secondaryActions] = sortedActions;
|
|
40
|
-
|
|
41
|
-
const actions = useMemo(
|
|
42
|
-
() =>
|
|
43
|
-
(primaryAction?.properties?.disposition === 'list-item-primary' ? secondaryActions : sortedActions)
|
|
44
|
-
.flatMap((action) => (Node.isAction(action) ? [action] : []))
|
|
45
|
-
.filter((a) => ['list-item', 'list-item-primary'].includes(a.properties?.disposition)),
|
|
46
|
-
[sortedActions, primaryAction],
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
const primaryMenuActions = useMemo(
|
|
50
|
-
() =>
|
|
51
|
-
primaryAction
|
|
52
|
-
? Node.isAction(primaryAction)
|
|
53
|
-
? [primaryAction]
|
|
54
|
-
: groupedActions[primaryAction?.id ?? '']
|
|
55
|
-
: undefined,
|
|
56
|
-
[primaryAction, groupedActions],
|
|
57
|
-
);
|
|
22
|
+
const flattenedActions = useActions(item);
|
|
23
|
+
const allActions = useMemo(() => getListActions(flattenedActions), [flattenedActions]);
|
|
58
24
|
|
|
59
25
|
const ActionRoot = popoverAnchorId === `${NAV_TREE_ITEM}:${item.id}` ? Popover.Anchor : Fragment;
|
|
60
26
|
|
|
61
27
|
return (
|
|
62
|
-
<div
|
|
63
|
-
{primaryAction?.properties?.disposition === 'list-item-primary' && !primaryAction?.properties?.disabled ? (
|
|
64
|
-
<Treegrid.Cell classNames='contents'>
|
|
65
|
-
<NavTreeItemAction
|
|
66
|
-
testId={primaryAction.properties?.testId}
|
|
67
|
-
label={toLocalizedString(primaryAction.properties?.label, t)}
|
|
68
|
-
icon={primaryAction.properties?.icon ?? 'ph--placeholder--regular'}
|
|
69
|
-
parent={item}
|
|
70
|
-
path={path}
|
|
71
|
-
monolithic={Node.isAction(primaryAction)}
|
|
72
|
-
menuActions={primaryMenuActions}
|
|
73
|
-
menuType={primaryAction.properties?.menuType}
|
|
74
|
-
caller={NAV_TREE_ITEM}
|
|
75
|
-
/>
|
|
76
|
-
</Treegrid.Cell>
|
|
77
|
-
) : (
|
|
78
|
-
<Treegrid.Cell role='none' />
|
|
79
|
-
)}
|
|
28
|
+
<div className='contents dx-app-no-drag'>
|
|
80
29
|
<ActionRoot>
|
|
81
|
-
{
|
|
30
|
+
{allActions.length === 1 ? (
|
|
31
|
+
<Treegrid.Cell classNames='contents'>
|
|
32
|
+
<NavTreeItemMonolithicAction
|
|
33
|
+
baseLabel={toLocalizedString(allActions[0].properties?.label, t)}
|
|
34
|
+
parent={item}
|
|
35
|
+
path={path}
|
|
36
|
+
{...allActions[0]}
|
|
37
|
+
/>
|
|
38
|
+
</Treegrid.Cell>
|
|
39
|
+
) : allActions.length > 1 ? (
|
|
82
40
|
<Treegrid.Cell classNames='contents'>
|
|
83
|
-
<
|
|
41
|
+
<NavTreeItemActionDropdownMenu
|
|
84
42
|
testId={`navtree.treeItem.actionsLevel${level}`}
|
|
85
43
|
label={t('tree-item-actions.label')}
|
|
86
44
|
icon='ph--dots-three-vertical--regular'
|
|
87
45
|
parent={item}
|
|
88
46
|
path={path}
|
|
89
|
-
menuActions={
|
|
90
|
-
menuType='dropdown'
|
|
47
|
+
menuActions={allActions}
|
|
91
48
|
caller={NAV_TREE_ITEM}
|
|
92
49
|
/>
|
|
93
50
|
</Treegrid.Cell>
|
|
@@ -142,9 +142,8 @@ const L0ItemRoot = memo(
|
|
|
142
142
|
|
|
143
143
|
export const L0ItemActiveTabIndicator = ({ classNames }: ThemedClassName<{}>) => (
|
|
144
144
|
<div
|
|
145
|
-
role='none'
|
|
146
145
|
className={mx(
|
|
147
|
-
'hidden group-aria-selected/l0item:block absolute start-0 h-6 w-1.5 bg-accent-
|
|
146
|
+
'hidden group-aria-selected/l0item:block absolute start-0 h-6 w-1.5 bg-accent-bg rounded-sm',
|
|
148
147
|
classNames,
|
|
149
148
|
)}
|
|
150
149
|
/>
|
|
@@ -218,14 +217,13 @@ const L0Item = memo(({ item, parent, path, pinned, onRearrange, onItemHover }: L
|
|
|
218
217
|
return (
|
|
219
218
|
<L0ItemRoot ref={itemElement} item={item} parent={parent} path={path} onMouseEnter={handleMouseEnter}>
|
|
220
219
|
<div
|
|
221
|
-
role='none'
|
|
222
220
|
data-frame={true}
|
|
223
221
|
{...(hue && { style: { background: `var(--color-${hue}-surface)` } })}
|
|
224
222
|
className={mx(
|
|
225
223
|
'flex justify-center items-center dx-focus-ring-group-indicator transition-colors rounded-sm',
|
|
226
224
|
pinned
|
|
227
|
-
? 'p-2 group-hover/l0item:bg-
|
|
228
|
-
: 'w-(--dx-l0-avatar-size) h-(--dx-l0-avatar-size) bg-
|
|
225
|
+
? 'p-2 group-hover/l0item:bg-current-surface'
|
|
226
|
+
: 'w-(--dx-l0-avatar-size) h-(--dx-l0-avatar-size) bg-current-surface',
|
|
229
227
|
)}
|
|
230
228
|
>
|
|
231
229
|
<ItemAvatar item={item} />
|
|
@@ -245,7 +243,7 @@ const ItemAvatar = ({ item }: Pick<L0ItemProps, 'item'>) => {
|
|
|
245
243
|
// Actions.
|
|
246
244
|
if (item.properties.icon) {
|
|
247
245
|
const hue = item.properties.hue ?? null;
|
|
248
|
-
const hueFgStyle = hue && { style: { color: `var(--color-${hue}-
|
|
246
|
+
const hueFgStyle = hue && { style: { color: `var(--color-${hue}-fg)` } };
|
|
249
247
|
return <Icon icon={item.properties.icon} size={6} {...hueFgStyle} />;
|
|
250
248
|
}
|
|
251
249
|
|
|
@@ -320,7 +318,7 @@ export const L0Menu = ({
|
|
|
320
318
|
classNames={[
|
|
321
319
|
'group/l0 absolute z-[1] inset-y-0 start-0 rounded-is',
|
|
322
320
|
'grid grid-cols-[var(--dx-l0-size)] grid-rows-[var(--dx-rail-size)_1fr_min-content_var(--dx-l0-size)] dx-contain-layout',
|
|
323
|
-
'w-(--dx-l0-size) bg-
|
|
321
|
+
'w-(--dx-l0-size) bg-l0-surface dx-app-drag pb-[env(safe-area-inset-bottom)]',
|
|
324
322
|
'[body[data-platform="macos"]_&]:pt-[30px]',
|
|
325
323
|
'[body[data-platform="ios"]_&]:pt-[max(env(safe-area-inset-top),0.25rem)]',
|
|
326
324
|
]}
|
|
@@ -328,8 +326,16 @@ export const L0Menu = ({
|
|
|
328
326
|
{/* TODO(wittjosiah): Use L0Item trigger. */}
|
|
329
327
|
<Menu.Root onAction={handleAction}>
|
|
330
328
|
<Menu.Trigger asChild data-testid='spacePlugin.addSpace'>
|
|
331
|
-
<div
|
|
332
|
-
<IconButton
|
|
329
|
+
<div className='grid place-items-center'>
|
|
330
|
+
<IconButton
|
|
331
|
+
density='lg'
|
|
332
|
+
variant='ghost'
|
|
333
|
+
size={5}
|
|
334
|
+
icon='ph--list--regular'
|
|
335
|
+
iconOnly
|
|
336
|
+
square
|
|
337
|
+
label={t('app-menu.label')}
|
|
338
|
+
/>
|
|
333
339
|
</div>
|
|
334
340
|
</Menu.Trigger>
|
|
335
341
|
<Menu.Content group={parent} items={menuActions} />
|
|
@@ -352,14 +358,14 @@ export const L0Menu = ({
|
|
|
352
358
|
</ScrollArea.Root>
|
|
353
359
|
|
|
354
360
|
{/* Actions. */}
|
|
355
|
-
<div
|
|
361
|
+
<div className='grid grid-cols-1 auto-rows-(--dx-rail-action) pt-2'>
|
|
356
362
|
{pinnedItems.map((item) => (
|
|
357
363
|
<L0Item key={item.id} item={item} parent={parent} path={path} pinned />
|
|
358
364
|
))}
|
|
359
365
|
</div>
|
|
360
366
|
|
|
361
367
|
{userAccountItem && (
|
|
362
|
-
<div
|
|
368
|
+
<div className='grid dx-app-no-drag'>
|
|
363
369
|
<L0ItemRoot key={userAccountItem.id} item={userAccountItem} parent={parent} path={path}>
|
|
364
370
|
<UserAccountAvatar
|
|
365
371
|
userId={userAccountItem.properties.userId}
|
|
@@ -2,27 +2,25 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import * as Effect from 'effect/Effect';
|
|
6
5
|
import * as Option from 'effect/Option';
|
|
7
6
|
import React, { memo, useCallback, useMemo } from 'react';
|
|
8
7
|
|
|
9
8
|
import { Node } from '@dxos/app-graph';
|
|
10
9
|
import { isPinnedWorkspace } from '@dxos/app-toolkit';
|
|
11
10
|
import { useAppGraph } from '@dxos/app-toolkit/ui';
|
|
12
|
-
import { Graph, useActionRunner,
|
|
11
|
+
import { Graph, useActionRunner, useEdges } from '@dxos/plugin-graph';
|
|
13
12
|
import { DensityProvider, IconButton, ScrollArea, toLocalizedString, useTranslation } from '@dxos/react-ui';
|
|
14
|
-
import { useAttended } from '@dxos/react-ui-attention';
|
|
15
13
|
import { Tree } from '@dxos/react-ui-list';
|
|
16
14
|
import { Menu, type MenuItem } from '@dxos/react-ui-menu';
|
|
17
15
|
import { Tabs } from '@dxos/react-ui-tabs';
|
|
18
16
|
import { hoverableControlItem, hoverableOpenControlItem } from '@dxos/ui-theme';
|
|
19
17
|
|
|
20
|
-
import {
|
|
18
|
+
import { getListActions, useActions, useLoadDescendents } from '#hooks';
|
|
21
19
|
import { meta } from '#meta';
|
|
22
20
|
|
|
23
21
|
import { NAV_TREE_ITEM } from '../NavTree';
|
|
24
22
|
import { useNavTreeContext } from '../NavTreeContext';
|
|
25
|
-
import {
|
|
23
|
+
import { NavTreeItemColumns } from '../NavTreeItem/NavTreeItemColumns';
|
|
26
24
|
|
|
27
25
|
export type L1PanelProps = {
|
|
28
26
|
open?: boolean;
|
|
@@ -84,49 +82,28 @@ const useIsActivatedWorkspace = (item: Node.Node): boolean => {
|
|
|
84
82
|
const L1PanelContent = ({ path, item, onBack }: Pick<L1PanelProps, 'open' | 'path' | 'item' | 'onBack'>) => {
|
|
85
83
|
const navTreeContext = useNavTreeContext();
|
|
86
84
|
|
|
87
|
-
const alternateTree = useAlternateTreeItem(item);
|
|
88
|
-
const alternatePath = useMemo(() => [...path, item.id], [item.id, path]);
|
|
89
|
-
const isAlternate = useIsAlternateTree(alternatePath, item);
|
|
90
|
-
|
|
91
85
|
return (
|
|
92
|
-
<DensityProvider density='
|
|
86
|
+
<DensityProvider density='md'>
|
|
93
87
|
<L1PanelHeader path={path} item={item} onBack={onBack} />
|
|
94
88
|
<ScrollArea.Root thin orientation='vertical'>
|
|
95
89
|
<ScrollArea.Viewport>
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
<Tree
|
|
114
|
-
model={navTreeContext.model}
|
|
115
|
-
id={item.id}
|
|
116
|
-
rootId={item.id}
|
|
117
|
-
path={path}
|
|
118
|
-
levelOffset={5}
|
|
119
|
-
gridTemplateColumns='[tree-row-start] 1fr min-content min-content min-content [tree-row-end]'
|
|
120
|
-
draggable
|
|
121
|
-
renderColumns={NavTreeItemColumns}
|
|
122
|
-
blockInstruction={navTreeContext.blockInstruction}
|
|
123
|
-
canDrop={navTreeContext.canDrop}
|
|
124
|
-
canSelect={navTreeContext.canSelect}
|
|
125
|
-
onOpenChange={navTreeContext.onOpenChange}
|
|
126
|
-
onSelect={navTreeContext.onSelect}
|
|
127
|
-
onItemHover={navTreeContext.onItemHover}
|
|
128
|
-
/>
|
|
129
|
-
)}
|
|
90
|
+
<Tree
|
|
91
|
+
classNames='pt-[2px]'
|
|
92
|
+
model={navTreeContext.model}
|
|
93
|
+
id={item.id}
|
|
94
|
+
rootId={item.id}
|
|
95
|
+
path={path}
|
|
96
|
+
levelOffset={5}
|
|
97
|
+
draggable
|
|
98
|
+
gridTemplateColumns='[tree-row-start] minmax(0, 1fr) min-content min-content [tree-row-end]'
|
|
99
|
+
renderColumns={NavTreeItemColumns}
|
|
100
|
+
blockInstruction={navTreeContext.blockInstruction}
|
|
101
|
+
canDrop={navTreeContext.canDrop}
|
|
102
|
+
canSelect={navTreeContext.canSelect}
|
|
103
|
+
onOpenChange={navTreeContext.onOpenChange}
|
|
104
|
+
onSelect={navTreeContext.onSelect}
|
|
105
|
+
onItemHover={navTreeContext.onItemHover}
|
|
106
|
+
/>
|
|
130
107
|
</ScrollArea.Viewport>
|
|
131
108
|
</ScrollArea.Root>
|
|
132
109
|
</DensityProvider>
|
|
@@ -142,169 +119,111 @@ const L1PanelHeader = ({ item, path, onBack }: Pick<L1PanelProps, 'item' | 'path
|
|
|
142
119
|
const title = toLocalizedString(item.properties.label, t);
|
|
143
120
|
const backCapableWorkspace = isPinnedWorkspace(item.id);
|
|
144
121
|
|
|
145
|
-
const {
|
|
122
|
+
const { menuActions, onAction } = useL1MenuActions({ item, path });
|
|
146
123
|
useLoadDescendents(item);
|
|
147
124
|
|
|
148
|
-
// TODO(wittjosiah): Hack to only show containsAttended when attended item is within alternate tree (e.g. settings).
|
|
149
|
-
// Since every object in the space is a descendant of the space node, we'd otherwise always show containsAttended.
|
|
150
|
-
const alternateTree = useAlternateTreeItem(item);
|
|
151
|
-
const attended = useAttended();
|
|
152
|
-
const alternateTreeOpen = useMemo(() => {
|
|
153
|
-
if (!alternateTree) {
|
|
154
|
-
return true;
|
|
155
|
-
}
|
|
156
|
-
const hasAlternateAttended = attended.some(
|
|
157
|
-
(attendedId) => attendedId === alternateTree.id || attendedId.startsWith(alternateTree.id + '/'),
|
|
158
|
-
);
|
|
159
|
-
return !hasAlternateAttended;
|
|
160
|
-
}, [alternateTree, attended]);
|
|
161
|
-
|
|
162
125
|
return (
|
|
163
126
|
<div
|
|
164
127
|
data-tauri-drag-region
|
|
165
|
-
className='
|
|
128
|
+
className='grid grid-cols-[28px_1fr_min-content_min-content] w-full items-center dx-app-drag dx-density-lg'
|
|
166
129
|
>
|
|
167
130
|
{backCapableWorkspace ? (
|
|
168
131
|
<IconButton
|
|
169
|
-
|
|
170
|
-
classNames={['shrink-0 px-2 pointer-fine:px-1', hoverableControlItem, hoverableOpenControlItem]}
|
|
132
|
+
classNames={[hoverableControlItem, hoverableOpenControlItem]}
|
|
171
133
|
variant='ghost'
|
|
172
134
|
icon='ph--caret-left--regular'
|
|
173
135
|
iconOnly
|
|
136
|
+
size={4}
|
|
174
137
|
label={t('button-back.button')}
|
|
175
138
|
data-testid='treeView.primaryTreeButton'
|
|
176
139
|
onClick={() => onBack?.()}
|
|
177
140
|
/>
|
|
178
141
|
) : (
|
|
179
|
-
<div
|
|
142
|
+
<div />
|
|
180
143
|
)}
|
|
181
144
|
<h2 data-tauri-drag-region className='flex-1 truncate min-w-0'>
|
|
182
145
|
{title}
|
|
183
146
|
</h2>
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
{
|
|
187
|
-
<NavTreeItemAction
|
|
188
|
-
testId={primaryAction.properties?.testId}
|
|
189
|
-
label={toLocalizedString(primaryAction.properties?.label, t)}
|
|
190
|
-
icon={primaryAction.properties?.icon ?? 'ph--placeholder--regular'}
|
|
191
|
-
parent={item}
|
|
192
|
-
path={path}
|
|
193
|
-
monolithic={Node.isAction(primaryAction)}
|
|
194
|
-
menuActions={Node.isAction(primaryAction) ? [primaryAction] : groupedActions[primaryAction?.id ?? '']}
|
|
195
|
-
menuType={primaryAction.properties?.menuType}
|
|
196
|
-
caller={NAV_TREE_ITEM}
|
|
197
|
-
/>
|
|
198
|
-
)}
|
|
199
|
-
{menuActions.length === 1 && (
|
|
200
|
-
<IconButton
|
|
201
|
-
density='coarse'
|
|
202
|
-
classNames={['shrink-0 px-2 pointer-fine:px-1', hoverableControlItem, hoverableOpenControlItem]}
|
|
203
|
-
variant='ghost'
|
|
204
|
-
icon={menuActions[0].properties?.icon ?? 'ph--placeholder--regular'}
|
|
205
|
-
iconOnly
|
|
206
|
-
label={toLocalizedString(menuActions[0].properties?.label, t)}
|
|
207
|
-
data-testid={menuActions[0].properties?.testId}
|
|
208
|
-
onClick={() => onAction(menuActions[0] as Node.Action)}
|
|
209
|
-
/>
|
|
210
|
-
)}
|
|
211
|
-
{menuActions.length > 1 && (
|
|
212
|
-
<Menu.Root caller={NAV_TREE_ITEM} onAction={onAction}>
|
|
213
|
-
<Menu.Trigger asChild>
|
|
214
|
-
<IconButton
|
|
215
|
-
density='coarse'
|
|
216
|
-
classNames={['shrink-0 px-2 pointer-fine:px-1', hoverableControlItem, hoverableOpenControlItem]}
|
|
217
|
-
variant='ghost'
|
|
218
|
-
icon='ph--dots-three-vertical--regular'
|
|
219
|
-
iconOnly
|
|
220
|
-
label={t('tree-item-actions.label')}
|
|
221
|
-
data-testid='navtree.treeItem.actionsLevel0'
|
|
222
|
-
/>
|
|
223
|
-
</Menu.Trigger>
|
|
224
|
-
<Menu.Content group={item} items={menuActions as MenuItem[]} />
|
|
225
|
-
</Menu.Root>
|
|
226
|
-
)}
|
|
227
|
-
{ItemEnd && <ItemEnd node={item} open={alternateTreeOpen} />}
|
|
147
|
+
<div className='contents dx-app-no-drag'>
|
|
148
|
+
<MenuActions item={item} menuActions={menuActions} onAction={onAction} />
|
|
149
|
+
{ItemEnd && <ItemEnd node={item} open />}
|
|
228
150
|
</div>
|
|
229
151
|
</div>
|
|
230
152
|
);
|
|
231
153
|
};
|
|
232
154
|
|
|
155
|
+
type L1MenuActions = {
|
|
156
|
+
menuActions: Node.Action[];
|
|
157
|
+
onAction: (action: Node.Action, params?: Node.InvokeProps) => void;
|
|
158
|
+
};
|
|
159
|
+
|
|
233
160
|
/**
|
|
234
|
-
*
|
|
161
|
+
* Header menu actions for an L1 workspace tab. Renders nothing for an empty
|
|
162
|
+
* `menuActions`, a single inline icon button for one action, and a
|
|
163
|
+
* `…`-menu trigger for multiple.
|
|
235
164
|
*/
|
|
236
|
-
const
|
|
165
|
+
const MenuActions = ({
|
|
166
|
+
item,
|
|
167
|
+
menuActions,
|
|
168
|
+
onAction,
|
|
169
|
+
}: {
|
|
170
|
+
item: Node.Node;
|
|
171
|
+
} & Pick<L1MenuActions, 'menuActions' | 'onAction'>) => {
|
|
237
172
|
const { t } = useTranslation(meta.id);
|
|
238
|
-
const { setAlternateTree } = useNavTreeContext();
|
|
239
|
-
const { graph } = useAppGraph();
|
|
240
|
-
const runAction = useActionRunner();
|
|
241
173
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
174
|
+
if (menuActions.length === 0) {
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (menuActions.length === 1) {
|
|
179
|
+
return (
|
|
180
|
+
<IconButton
|
|
181
|
+
classNames={['shrink-0 px-2 pointer-fine:px-1', hoverableControlItem, hoverableOpenControlItem]}
|
|
182
|
+
variant='ghost'
|
|
183
|
+
icon={menuActions[0].properties?.icon ?? 'ph--circle-dashed--regular'}
|
|
184
|
+
iconOnly
|
|
185
|
+
size={4}
|
|
186
|
+
label={toLocalizedString(menuActions[0].properties?.label, t)}
|
|
187
|
+
data-testid={menuActions[0].properties?.testId}
|
|
188
|
+
onClick={() => onAction(menuActions[0] as Node.Action)}
|
|
189
|
+
/>
|
|
190
|
+
);
|
|
191
|
+
}
|
|
245
192
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
193
|
+
return (
|
|
194
|
+
<Menu.Root caller={NAV_TREE_ITEM} onAction={onAction}>
|
|
195
|
+
<Menu.Trigger asChild>
|
|
196
|
+
<IconButton
|
|
197
|
+
classNames={['shrink-0 px-2 pointer-fine:px-1', hoverableControlItem, hoverableOpenControlItem]}
|
|
198
|
+
variant='ghost'
|
|
199
|
+
icon='ph--dots-three-vertical--regular'
|
|
200
|
+
iconOnly
|
|
201
|
+
size={4}
|
|
202
|
+
label={t('tree-item-actions.label')}
|
|
203
|
+
data-testid='navtree.treeItem.actionsLevel0'
|
|
204
|
+
/>
|
|
205
|
+
</Menu.Trigger>
|
|
206
|
+
<Menu.Content group={item} items={menuActions as MenuItem[]} />
|
|
207
|
+
</Menu.Root>
|
|
250
208
|
);
|
|
209
|
+
};
|
|
251
210
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
// Synthetic settings/back action.
|
|
259
|
-
const settingsActionId = `${item.id}~settings`;
|
|
260
|
-
const settingsAction = useMemo((): Node.Action | undefined => {
|
|
261
|
-
if (!alternateTree) {
|
|
262
|
-
return undefined;
|
|
263
|
-
}
|
|
264
|
-
return {
|
|
265
|
-
id: settingsActionId,
|
|
266
|
-
type: Node.ActionType,
|
|
267
|
-
data: () => Effect.void,
|
|
268
|
-
properties: {
|
|
269
|
-
label: isAlternate
|
|
270
|
-
? ['button-back.button', { ns: meta.id }]
|
|
271
|
-
: (alternateTree.properties.label ?? alternateTree.id),
|
|
272
|
-
icon: isAlternate
|
|
273
|
-
? 'ph--arrow-u-down-left--regular'
|
|
274
|
-
: (alternateTree.properties.icon ?? 'ph--placeholder--regular'),
|
|
275
|
-
disposition: 'list-item',
|
|
276
|
-
testId: isAlternate ? 'navtree.backToSpace' : 'navtree.spaceSettings',
|
|
277
|
-
},
|
|
278
|
-
} as Node.Action;
|
|
279
|
-
}, [alternateTree, isAlternate, settingsActionId, t]);
|
|
211
|
+
/**
|
|
212
|
+
* Builds the menu actions for the L1 panel header.
|
|
213
|
+
*/
|
|
214
|
+
const useL1MenuActions = ({ item, path }: Pick<L1PanelProps, 'item' | 'path'>): L1MenuActions => {
|
|
215
|
+
const runAction = useActionRunner();
|
|
280
216
|
|
|
281
|
-
const menuActions =
|
|
282
|
-
() => [...graphMenuActions, ...(settingsAction ? [settingsAction] : [])],
|
|
283
|
-
[graphMenuActions, settingsAction],
|
|
284
|
-
);
|
|
217
|
+
const menuActions = getListActions(useActions(item));
|
|
285
218
|
|
|
286
219
|
const onAction = useCallback(
|
|
287
220
|
(action: Node.Action, params?: Node.InvokeProps) => {
|
|
288
|
-
|
|
289
|
-
if (alternateTree && !isAlternate) {
|
|
290
|
-
Graph.expand(graph, alternateTree.id, 'child');
|
|
291
|
-
}
|
|
292
|
-
setAlternateTree?.(alternatePath, !isAlternate);
|
|
293
|
-
} else {
|
|
294
|
-
void runAction(action, { ...params, path });
|
|
295
|
-
}
|
|
221
|
+
void runAction(action, { ...params, path });
|
|
296
222
|
},
|
|
297
|
-
[
|
|
223
|
+
[runAction, path],
|
|
298
224
|
);
|
|
299
225
|
|
|
300
|
-
return {
|
|
301
|
-
};
|
|
302
|
-
|
|
303
|
-
/** Finds the first child with disposition 'alternate-tree' using graph connections directly. */
|
|
304
|
-
const useAlternateTreeItem = (item: Node.Node): Node.Node | undefined => {
|
|
305
|
-
const { graph } = useAppGraph();
|
|
306
|
-
const connections = useConnections(graph, item.id, 'child');
|
|
307
|
-
return connections.find((node) => node.properties.disposition === 'alternate-tree');
|
|
226
|
+
return { menuActions, onAction };
|
|
308
227
|
};
|
|
309
228
|
|
|
310
229
|
export const L1Panel = memo(L1Panel$);
|
package/src/components/types.ts
CHANGED
|
@@ -16,7 +16,6 @@ export type NavTreeContextValue = {
|
|
|
16
16
|
model: TreeModel<NavTreeItemGraphNode>;
|
|
17
17
|
popoverAnchorId?: string;
|
|
18
18
|
renderItemEnd?: FC<{ node: Node.Node; open: boolean }>;
|
|
19
|
-
setAlternateTree?: (path: string[], open: boolean) => void;
|
|
20
19
|
onTabChange?: (node: NavTreeItemGraphNode) => void;
|
|
21
20
|
} & Pick<
|
|
22
21
|
TreeProps<NavTreeItemGraphNode>,
|
|
@@ -10,8 +10,9 @@ import { StorybookPlugin, corePlugins } from '@dxos/plugin-testing';
|
|
|
10
10
|
import { Dialog } from '@dxos/react-ui';
|
|
11
11
|
import { withLayout } from '@dxos/react-ui/testing';
|
|
12
12
|
|
|
13
|
+
import { translations } from '#translations';
|
|
14
|
+
|
|
13
15
|
import { NavTreePlugin } from '../../NavTreePlugin';
|
|
14
|
-
import { translations } from '../../translations';
|
|
15
16
|
import { CommandsDialogContent } from './CommandsDialogContent';
|
|
16
17
|
|
|
17
18
|
const DefaultStory = () => (
|
|
@@ -230,13 +230,6 @@ export const NavTreeContainer$ = forwardRef<HTMLDivElement, NavTreeContainerProp
|
|
|
230
230
|
});
|
|
231
231
|
}, [graph]);
|
|
232
232
|
|
|
233
|
-
const setAlternateTree = useCallback(
|
|
234
|
-
(path: string[], open: boolean) => {
|
|
235
|
-
setItem(path, 'alternateTree', open);
|
|
236
|
-
},
|
|
237
|
-
[setItem],
|
|
238
|
-
);
|
|
239
|
-
|
|
240
233
|
const onItemHover = useCallback(({ item }: { item: Node.Node }) => Graph.expand(graph, item.id, 'child'), [graph]);
|
|
241
234
|
|
|
242
235
|
const navTreeContextValue = useMemo(
|
|
@@ -247,7 +240,6 @@ export const NavTreeContainer$ = forwardRef<HTMLDivElement, NavTreeContainerProp
|
|
|
247
240
|
blockInstruction,
|
|
248
241
|
canDrop,
|
|
249
242
|
canSelect,
|
|
250
|
-
setAlternateTree,
|
|
251
243
|
onBack: handleBack,
|
|
252
244
|
onOpenChange: handleOpenChange,
|
|
253
245
|
onSelect: handleSelect,
|
|
@@ -260,7 +252,6 @@ export const NavTreeContainer$ = forwardRef<HTMLDivElement, NavTreeContainerProp
|
|
|
260
252
|
blockInstruction,
|
|
261
253
|
canDrop,
|
|
262
254
|
canSelect,
|
|
263
|
-
setAlternateTree,
|
|
264
255
|
handleBack,
|
|
265
256
|
handleOpenChange,
|
|
266
257
|
handleSelect,
|
|
@@ -195,7 +195,7 @@ export const TreeNodeRow = (props: TreeNodeProps & { className?: string }) => {
|
|
|
195
195
|
className={mx(
|
|
196
196
|
'group w-full items-center cursor-pointer bg-hover-surface',
|
|
197
197
|
// TODO(burdon): Use data-active.
|
|
198
|
-
selected?.[id] && 'bg-
|
|
198
|
+
selected?.[id] && 'bg-current-surface',
|
|
199
199
|
className,
|
|
200
200
|
)}
|
|
201
201
|
onClick={() => selected && onChangeSelected?.(id, !selected[id])}
|
|
@@ -220,7 +220,7 @@ export const TreeNode = (props: TreeNodeProps & { ancestors?: TreeNodeData[] })
|
|
|
220
220
|
const { root, header } = getSlots?.(props.node, open?.[id] ?? false, depth, ancestors) ?? {};
|
|
221
221
|
|
|
222
222
|
return (
|
|
223
|
-
<div
|
|
223
|
+
<div className={mx('flex flex-col', root)}>
|
|
224
224
|
<TreeNodeRow {...props} className={header} />
|
|
225
225
|
{(children?.length ?? 0) > 0 && open?.[id] && <TreeChildNodes {...props} ancestors={ancestors} />}
|
|
226
226
|
</div>
|
package/src/hooks/useActions.ts
CHANGED
|
@@ -9,6 +9,16 @@ import { Graph, Node, useActions as useGraphActions } from '@dxos/plugin-graph';
|
|
|
9
9
|
|
|
10
10
|
import { type FlattenedActions } from '#types';
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Flattens grouped actions and filters to the list-item dispositions rendered as
|
|
14
|
+
* navtree item actions. Shared by row (`NavTreeItemColumns`) and header (`L1Panel`)
|
|
15
|
+
* so both apply the same normalization rule.
|
|
16
|
+
*/
|
|
17
|
+
export const getListActions = ({ actions, groupedActions }: FlattenedActions): Node.Action[] =>
|
|
18
|
+
actions
|
|
19
|
+
.flatMap((action) => (Node.isAction(action) ? [action] : (groupedActions[action.id] ?? [])))
|
|
20
|
+
.filter((action) => ['list-item', 'list-item-primary'].includes(action.properties?.disposition));
|
|
21
|
+
|
|
12
22
|
/** Returns flattened actions and grouped sub-actions for a given graph node. */
|
|
13
23
|
export const useActions = (node: Node.Node): FlattenedActions => {
|
|
14
24
|
const { graph } = useAppGraph();
|
|
@@ -7,7 +7,7 @@ import * as Option from 'effect/Option';
|
|
|
7
7
|
import { useMemo } from 'react';
|
|
8
8
|
|
|
9
9
|
import { useAppGraph } from '@dxos/app-toolkit/ui';
|
|
10
|
-
import { PLANK_COMPANION_TYPE } from '@dxos/plugin-deck
|
|
10
|
+
import { PLANK_COMPANION_TYPE } from '@dxos/plugin-deck';
|
|
11
11
|
import { type Node } from '@dxos/plugin-graph';
|
|
12
12
|
import { Path, type TreeModel } from '@dxos/react-ui-list';
|
|
13
13
|
import { mx } from '@dxos/ui-theme';
|
|
@@ -57,6 +57,8 @@ const createItemPropsFamily = (graph: ReturnType<typeof useAppGraph>['graph']) =
|
|
|
57
57
|
icon: node.properties.icon,
|
|
58
58
|
iconHue: node.properties.iconHue,
|
|
59
59
|
testId: node.properties.testId,
|
|
60
|
+
count: node.properties.count,
|
|
61
|
+
modifiedCount: node.properties.modifiedCount,
|
|
60
62
|
};
|
|
61
63
|
}).pipe(Atom.keepAlive);
|
|
62
64
|
});
|
|
@@ -12,7 +12,7 @@ import { NavTreeCapabilities } from '#types';
|
|
|
12
12
|
export type UseNavTreeStateResult = {
|
|
13
13
|
getItem: (path: string[]) => NavTreeCapabilities.NavTreeItemState;
|
|
14
14
|
getItemAtom: (path: string[]) => Atom.Atom<NavTreeCapabilities.NavTreeItemState>;
|
|
15
|
-
setItem: (path: string[], key: 'open' | 'current'
|
|
15
|
+
setItem: (path: string[], key: 'open' | 'current', next: boolean) => void;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
/**
|
|
@@ -33,10 +33,3 @@ export const useNavTreeItemState = (path: string[]): NavTreeCapabilities.NavTree
|
|
|
33
33
|
const atom = useMemo(() => getItemAtom(path), [getItemAtom, pathKey]);
|
|
34
34
|
return useAtomValue(atom);
|
|
35
35
|
};
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Hook that subscribes to the alternateTree state for a tree item.
|
|
39
|
-
*/
|
|
40
|
-
export const useIsAlternateTree = (path: string[], _item?: any): boolean => {
|
|
41
|
-
return useNavTreeItemState(path).alternateTree ?? false;
|
|
42
|
-
};
|