@dxos/plugin-deck 0.9.0 → 0.9.1-main.c7dcc2e112
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/neutral/{DeckLayout-DEURA3KR.mjs → DeckLayout-VX2BP4Q2.mjs} +35 -22
- package/dist/lib/neutral/DeckLayout-VX2BP4Q2.mjs.map +7 -0
- package/dist/lib/neutral/DeckPlugin.mjs +2 -2
- package/dist/lib/neutral/DeckPlugin.mjs.map +4 -4
- package/dist/lib/neutral/{DeckSettings-W5I57OXM.mjs → DeckSettings-CQQZJ2YS.mjs} +3 -3
- package/dist/lib/neutral/DeckSettings-CQQZJ2YS.mjs.map +7 -0
- package/dist/lib/neutral/{add-toast-TNB6DXWU.mjs → add-toast-APKTCLIA.mjs} +2 -2
- package/dist/lib/neutral/{adjust-HNU5CCRO.mjs → adjust-7CZI4GK3.mjs} +3 -3
- package/dist/lib/neutral/{app-graph-builder-HMLT627T.mjs → app-graph-builder-6HTXRTU2.mjs} +5 -5
- package/dist/lib/neutral/app-graph-builder-6HTXRTU2.mjs.map +7 -0
- package/dist/lib/neutral/capabilities/index.mjs +8 -8
- package/dist/lib/neutral/{check-app-scheme-INSOF72J.mjs → check-app-scheme-HSAORHHX.mjs} +2 -2
- package/dist/lib/neutral/{chunk-BS4EOYMK.mjs → chunk-CL7JIOI5.mjs} +28 -14
- package/dist/lib/neutral/chunk-CL7JIOI5.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-WAXJPQJI.mjs → chunk-DNG3L5QN.mjs} +31 -33
- package/dist/lib/neutral/chunk-DNG3L5QN.mjs.map +7 -0
- package/dist/lib/neutral/chunk-KY7LMF4D.mjs +46 -0
- package/dist/lib/neutral/chunk-KY7LMF4D.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-324PPIZB.mjs → chunk-KZFJ4PBT.mjs} +4 -4
- package/dist/lib/neutral/chunk-KZFJ4PBT.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-GBIGQKYW.mjs → chunk-NGX6RXNV.mjs} +4 -4
- package/dist/lib/neutral/chunk-NGX6RXNV.mjs.map +7 -0
- package/dist/lib/neutral/chunk-UZLAR4DR.mjs +8 -0
- package/dist/lib/neutral/{close-ASKR22A6.mjs → close-KJUCFIJ5.mjs} +3 -3
- package/dist/lib/neutral/components/index.mjs +1 -1
- package/dist/lib/neutral/containers/index.mjs +3 -3
- package/dist/lib/neutral/index.mjs +12 -2
- package/dist/lib/neutral/meta.json +1 -1
- package/dist/lib/neutral/meta.mjs +1 -1
- package/dist/lib/neutral/{notification-tracker-P36322BH.mjs → notification-tracker-CUDFRDCF.mjs} +9 -9
- package/dist/lib/neutral/{notification-tracker-P36322BH.mjs.map → notification-tracker-CUDFRDCF.mjs.map} +3 -3
- package/dist/lib/neutral/{open-5OYNO3RT.mjs → open-VU7YS3HB.mjs} +7 -7
- package/dist/lib/neutral/open-VU7YS3HB.mjs.map +7 -0
- package/dist/lib/neutral/operations/index.mjs +1 -1
- package/dist/lib/neutral/plugin.mjs +2 -2
- package/dist/lib/neutral/{react-root-HH5DEUOG.mjs → react-root-E6TAFHX6.mjs} +2 -2
- package/dist/lib/neutral/react-root-E6TAFHX6.mjs.map +7 -0
- package/dist/lib/neutral/{react-surface-3UVVCK3O.mjs → react-surface-O4POQWYL.mjs} +4 -5
- package/dist/lib/neutral/react-surface-O4POQWYL.mjs.map +7 -0
- package/dist/lib/neutral/{revert-workspace-B2QLT2C4.mjs → revert-workspace-24TKG3I7.mjs} +2 -2
- package/dist/lib/neutral/{scroll-into-view-B52C3PJO.mjs → scroll-into-view-3VXT6TWC.mjs} +2 -2
- package/dist/lib/neutral/{set-PA35ONXO.mjs → set-RFOLTI57.mjs} +3 -3
- package/dist/lib/neutral/{set-layout-mode-RPCCPQRB.mjs → set-layout-mode-AZ73W52Z.mjs} +2 -2
- package/dist/lib/neutral/{settings-EGNYUM4T.mjs → settings-6CDQEB6B.mjs} +3 -3
- package/dist/lib/neutral/settings-6CDQEB6B.mjs.map +7 -0
- package/dist/lib/neutral/{state-IIDXMQUO.mjs → state-D3YXB5NP.mjs} +3 -3
- package/dist/lib/neutral/{state-IIDXMQUO.mjs.map → state-D3YXB5NP.mjs.map} +2 -2
- package/dist/lib/neutral/{switch-workspace-LZF4KZXH.mjs → switch-workspace-TBPT23CZ.mjs} +4 -4
- package/dist/lib/neutral/switch-workspace-TBPT23CZ.mjs.map +7 -0
- package/dist/lib/neutral/translations.mjs +1 -1
- package/dist/lib/neutral/translations.mjs.map +3 -3
- package/dist/lib/neutral/types/index.mjs +11 -1
- package/dist/lib/neutral/{update-companion-YUCZZVGY.mjs → update-companion-5LCY6QME.mjs} +2 -2
- package/dist/lib/neutral/{update-complementary-7FZNB55J.mjs → update-complementary-HZ7QXZYE.mjs} +2 -2
- package/dist/lib/neutral/{update-dialog-FNQTSSAP.mjs → update-dialog-A7W3R5EI.mjs} +2 -2
- package/dist/lib/neutral/{update-plank-size-3YW4NXEY.mjs → update-plank-size-XHTYBLSD.mjs} +2 -2
- package/dist/lib/neutral/{update-popover-G2VUD7E6.mjs → update-popover-RDIHG73B.mjs} +2 -2
- package/dist/lib/neutral/{update-sidebar-KRHPUHUB.mjs → update-sidebar-GEI7USA5.mjs} +2 -2
- package/dist/lib/neutral/{url-handler-A6HLW4RB.mjs → url-handler-PUS4X33T.mjs} +10 -10
- package/dist/lib/neutral/url-handler-PUS4X33T.mjs.map +7 -0
- package/dist/types/dx.config.d.ts +28 -0
- package/dist/types/dx.config.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +8 -196
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts +2 -2
- 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/components/Matrix/Matrix.stories.d.ts.map +1 -1
- package/dist/types/src/containers/Deck/Banner.d.ts.map +1 -1
- package/dist/types/src/containers/Deck/DeckViewport.d.ts.map +1 -1
- package/dist/types/src/containers/Deck/StatusBar.d.ts.map +1 -1
- package/dist/types/src/containers/DeckLayout/DeckLayout.stories.d.ts.map +1 -1
- package/dist/types/src/containers/DeckLayout/Popover.d.ts.map +1 -1
- package/dist/types/src/containers/Plank/PlankHeading.d.ts.map +1 -1
- package/dist/types/src/containers/Sidebar/ComplementarySidebar.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +28 -2
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/operations/open.d.ts.map +1 -1
- package/dist/types/src/operations/switch-workspace.d.ts.map +1 -1
- package/dist/types/src/types/DeckCapabilities.d.ts +2 -2
- package/dist/types/src/types/DeckCapabilities.d.ts.map +1 -1
- package/dist/types/src/types/index.d.ts +1 -0
- package/dist/types/src/types/index.d.ts.map +1 -1
- package/dist/types/src/types/schema.d.ts +4 -2
- package/dist/types/src/types/schema.d.ts.map +1 -1
- package/dist/types/src/types/surface.d.ts +12 -0
- package/dist/types/src/types/surface.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/dx.config.ts +35 -0
- package/package.json +39 -39
- package/src/DeckPlugin.test.ts +1 -1
- package/src/DeckPlugin.ts +1 -1
- package/src/capabilities/app-graph-builder.ts +4 -4
- package/src/capabilities/check-app-scheme.ts +3 -3
- package/src/capabilities/notification-tracker.ts +8 -8
- package/src/capabilities/react-root.tsx +1 -1
- package/src/capabilities/react-surface.tsx +3 -4
- package/src/capabilities/settings.ts +2 -2
- package/src/capabilities/state.ts +1 -1
- package/src/capabilities/url-handler.ts +7 -15
- package/src/components/DeckSettings/DeckSettings.tsx +2 -2
- package/src/components/Matrix/Matrix.stories.tsx +2 -1
- package/src/containers/Deck/Banner.tsx +5 -4
- package/src/containers/Deck/DeckViewport.tsx +3 -4
- package/src/containers/Deck/StatusBar.tsx +4 -2
- package/src/containers/DeckLayout/DeckLayout.stories.tsx +6 -9
- package/src/containers/DeckLayout/Fallback.tsx +1 -1
- package/src/containers/DeckLayout/Popover.tsx +37 -20
- package/src/containers/DeckLayout/Toast.tsx +1 -1
- package/src/containers/Plank/Plank.stories.tsx +2 -2
- package/src/containers/Plank/PlankControls.tsx +2 -2
- package/src/containers/Plank/PlankError.tsx +1 -1
- package/src/containers/Plank/PlankHeading.tsx +5 -6
- package/src/containers/Sidebar/ComplementarySidebar.tsx +6 -5
- package/src/containers/Sidebar/Sidebar.tsx +1 -1
- package/src/containers/Sidebar/SidebarButton.tsx +3 -3
- package/src/meta.ts +2 -27
- package/src/operations/open.ts +12 -10
- package/src/operations/switch-workspace.ts +2 -2
- package/src/translations.ts +1 -1
- package/src/types/DeckCapabilities.ts +5 -3
- package/src/types/DeckEvents.ts +1 -1
- package/src/types/DeckOperation.ts +1 -1
- package/src/types/index.ts +1 -0
- package/src/types/schema.ts +16 -12
- package/src/types/surface.ts +28 -0
- package/src/util/plank-url-params.ts +3 -3
- package/dist/lib/neutral/DeckLayout-DEURA3KR.mjs.map +0 -7
- package/dist/lib/neutral/DeckSettings-W5I57OXM.mjs.map +0 -7
- package/dist/lib/neutral/app-graph-builder-HMLT627T.mjs.map +0 -7
- package/dist/lib/neutral/chunk-324PPIZB.mjs.map +0 -7
- package/dist/lib/neutral/chunk-BS4EOYMK.mjs.map +0 -7
- package/dist/lib/neutral/chunk-GBIGQKYW.mjs.map +0 -7
- package/dist/lib/neutral/chunk-PYEY5SEC.mjs +0 -37
- package/dist/lib/neutral/chunk-PYEY5SEC.mjs.map +0 -7
- package/dist/lib/neutral/chunk-Q4W6B4IB.mjs +0 -8
- package/dist/lib/neutral/chunk-WAXJPQJI.mjs.map +0 -7
- package/dist/lib/neutral/open-5OYNO3RT.mjs.map +0 -7
- package/dist/lib/neutral/react-root-HH5DEUOG.mjs.map +0 -7
- package/dist/lib/neutral/react-surface-3UVVCK3O.mjs.map +0 -7
- package/dist/lib/neutral/settings-EGNYUM4T.mjs.map +0 -7
- package/dist/lib/neutral/switch-workspace-LZF4KZXH.mjs.map +0 -7
- package/dist/lib/neutral/url-handler-A6HLW4RB.mjs.map +0 -7
- /package/dist/lib/neutral/{add-toast-TNB6DXWU.mjs.map → add-toast-APKTCLIA.mjs.map} +0 -0
- /package/dist/lib/neutral/{adjust-HNU5CCRO.mjs.map → adjust-7CZI4GK3.mjs.map} +0 -0
- /package/dist/lib/neutral/{check-app-scheme-INSOF72J.mjs.map → check-app-scheme-HSAORHHX.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-Q4W6B4IB.mjs.map → chunk-UZLAR4DR.mjs.map} +0 -0
- /package/dist/lib/neutral/{close-ASKR22A6.mjs.map → close-KJUCFIJ5.mjs.map} +0 -0
- /package/dist/lib/neutral/{revert-workspace-B2QLT2C4.mjs.map → revert-workspace-24TKG3I7.mjs.map} +0 -0
- /package/dist/lib/neutral/{scroll-into-view-B52C3PJO.mjs.map → scroll-into-view-3VXT6TWC.mjs.map} +0 -0
- /package/dist/lib/neutral/{set-PA35ONXO.mjs.map → set-RFOLTI57.mjs.map} +0 -0
- /package/dist/lib/neutral/{set-layout-mode-RPCCPQRB.mjs.map → set-layout-mode-AZ73W52Z.mjs.map} +0 -0
- /package/dist/lib/neutral/{update-companion-YUCZZVGY.mjs.map → update-companion-5LCY6QME.mjs.map} +0 -0
- /package/dist/lib/neutral/{update-complementary-7FZNB55J.mjs.map → update-complementary-HZ7QXZYE.mjs.map} +0 -0
- /package/dist/lib/neutral/{update-dialog-FNQTSSAP.mjs.map → update-dialog-A7W3R5EI.mjs.map} +0 -0
- /package/dist/lib/neutral/{update-plank-size-3YW4NXEY.mjs.map → update-plank-size-XHTYBLSD.mjs.map} +0 -0
- /package/dist/lib/neutral/{update-popover-G2VUD7E6.mjs.map → update-popover-RDIHG73B.mjs.map} +0 -0
- /package/dist/lib/neutral/{update-sidebar-KRHPUHUB.mjs.map → update-sidebar-GEI7USA5.mjs.map} +0 -0
|
@@ -10,10 +10,12 @@ import { AppSurface, useObjectMenuItems } from '@dxos/app-toolkit/ui';
|
|
|
10
10
|
import { Obj } from '@dxos/echo';
|
|
11
11
|
import {
|
|
12
12
|
Card,
|
|
13
|
+
Icon,
|
|
14
|
+
IconButton,
|
|
13
15
|
Popover,
|
|
14
16
|
type PopoverContentInteractOutsideEvent,
|
|
15
17
|
toLocalizedString,
|
|
16
|
-
|
|
18
|
+
useMediaQuery,
|
|
17
19
|
useTranslation,
|
|
18
20
|
} from '@dxos/react-ui';
|
|
19
21
|
import { Menu } from '@dxos/react-ui-menu';
|
|
@@ -54,9 +56,12 @@ export const PopoverRoot = ({ children }: PopoverRootProps) => {
|
|
|
54
56
|
}
|
|
55
57
|
}, [state.popoverOpen, state.popoverAnchorId, state.popoverAnchor, state.popoverContent]);
|
|
56
58
|
|
|
59
|
+
// The rename popover is modal so other navtree item menus are inert while it is open.
|
|
60
|
+
const modal = state.popoverKind === 'rename';
|
|
61
|
+
|
|
57
62
|
return (
|
|
58
63
|
<DeckPopoverProvider setOpen={setOpen}>
|
|
59
|
-
<Popover.Root modal={
|
|
64
|
+
<Popover.Root modal={modal} open={open}>
|
|
60
65
|
{state.popoverAnchor && <Popover.VirtualTrigger key={virtualIter} virtualRef={virtualRef} />}
|
|
61
66
|
{children}
|
|
62
67
|
</Popover.Root>
|
|
@@ -65,7 +70,7 @@ export const PopoverRoot = ({ children }: PopoverRootProps) => {
|
|
|
65
70
|
};
|
|
66
71
|
|
|
67
72
|
export const PopoverContent = () => {
|
|
68
|
-
const { t } = useTranslation(meta.
|
|
73
|
+
const { t } = useTranslation(meta.profile.key);
|
|
69
74
|
const { state, updateEphemeral } = useDeckState();
|
|
70
75
|
const { setOpen } = useDeckPopoverContext('PopoverContent');
|
|
71
76
|
const popoverSubject =
|
|
@@ -75,8 +80,14 @@ export const PopoverContent = () => {
|
|
|
75
80
|
const title = state.popoverTitle ? toLocalizedString(state.popoverTitle, t) : 'Unknown';
|
|
76
81
|
const icon = isObjectPopover ? (Obj.getIcon(popoverSubject)?.icon ?? 'ph--circle-dashed--regular') : undefined;
|
|
77
82
|
const content = state.popoverContent;
|
|
78
|
-
//
|
|
79
|
-
const
|
|
83
|
+
// Base and rename popovers render a plugin-provided component; everything else falls through to the card.
|
|
84
|
+
const isComponentPopover =
|
|
85
|
+
(state.popoverKind === 'base' || state.popoverKind === 'rename') && !!content && 'component' in content;
|
|
86
|
+
const isRename = state.popoverKind === 'rename';
|
|
87
|
+
|
|
88
|
+
// Anchor to the right of the row on wide displays; drop centered below on narrow ones.
|
|
89
|
+
const [isLg] = useMediaQuery('lg', { fallback: [true] });
|
|
90
|
+
const side = isRename ? (isLg ? 'right' : 'bottom') : state.popoverSide;
|
|
80
91
|
|
|
81
92
|
const handleClose = useCallback(() => {
|
|
82
93
|
setOpen(false);
|
|
@@ -91,15 +102,14 @@ export const PopoverContent = () => {
|
|
|
91
102
|
|
|
92
103
|
const handleInteractOutside = useCallback(
|
|
93
104
|
(event: KeyboardEvent | PopoverContentInteractOutsideEvent) => {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
) {
|
|
105
|
+
// Focus leaving the popover (clicking into the card surfaces a portaled menu, or CodeMirror
|
|
106
|
+
// re-focusing itself) must not dismiss it — only a pointer-down genuinely outside the card, or
|
|
107
|
+
// Escape, closes. (Clicks inside the card never reach here; Radix scopes them to the content.)
|
|
108
|
+
if (event.type === 'dismissableLayer.focusOutside') {
|
|
99
109
|
event.preventDefault();
|
|
100
|
-
|
|
101
|
-
handleClose();
|
|
110
|
+
return;
|
|
102
111
|
}
|
|
112
|
+
handleClose();
|
|
103
113
|
},
|
|
104
114
|
[handleClose],
|
|
105
115
|
);
|
|
@@ -107,15 +117,22 @@ export const PopoverContent = () => {
|
|
|
107
117
|
return (
|
|
108
118
|
<Popover.Portal>
|
|
109
119
|
<Popover.Content
|
|
110
|
-
side={
|
|
120
|
+
side={side}
|
|
111
121
|
sticky='always'
|
|
112
122
|
hideWhenDetached
|
|
113
|
-
|
|
123
|
+
// Rename focuses its input; other popovers keep focus where it was.
|
|
124
|
+
onOpenAutoFocus={isRename ? undefined : (event) => event.preventDefault()}
|
|
114
125
|
onInteractOutside={handleInteractOutside}
|
|
115
126
|
onEscapeKeyDown={handleInteractOutside}
|
|
127
|
+
// Reuse the dialog's enter/exit motion so the rename popover does not flicker on open.
|
|
128
|
+
classNames={
|
|
129
|
+
isRename
|
|
130
|
+
? ['data-[state=open]:animate-slide-up-and-fade', 'data-[state=closed]:animate-slide-down-and-fade']
|
|
131
|
+
: undefined
|
|
132
|
+
}
|
|
116
133
|
>
|
|
117
134
|
<Popover.Viewport>
|
|
118
|
-
{
|
|
135
|
+
{isComponentPopover && content && 'component' in content ? (
|
|
119
136
|
/* Base popover: a plugin-provided component (e.g. editor link preview). */
|
|
120
137
|
<Surface.Surface type={AppSurface.Popover} data={content} limit={1} />
|
|
121
138
|
) : (
|
|
@@ -129,12 +146,12 @@ export const PopoverContent = () => {
|
|
|
129
146
|
<Menu.Root>
|
|
130
147
|
<Card.Root border={false} classNames='dx-card-popover'>
|
|
131
148
|
<Card.Header>
|
|
132
|
-
<Card.
|
|
149
|
+
<Card.Block>{icon && <Icon icon={icon} />}</Card.Block>
|
|
133
150
|
<Card.Title>{title}</Card.Title>
|
|
134
151
|
{/* TODO(wittjosiah): Reconcile with Card.Menu. */}
|
|
135
|
-
<Card.
|
|
152
|
+
<Card.Block end>
|
|
136
153
|
<Menu.Trigger asChild disabled={!objectMenuItems.length}>
|
|
137
|
-
<
|
|
154
|
+
<IconButton
|
|
138
155
|
variant='ghost'
|
|
139
156
|
density='sm'
|
|
140
157
|
icon='ph--dots-three-vertical--regular'
|
|
@@ -143,11 +160,11 @@ export const PopoverContent = () => {
|
|
|
143
160
|
/>
|
|
144
161
|
</Menu.Trigger>
|
|
145
162
|
<Menu.Content items={objectMenuItems} />
|
|
146
|
-
</Card.
|
|
163
|
+
</Card.Block>
|
|
147
164
|
</Card.Header>
|
|
148
165
|
|
|
149
166
|
{content && 'subject' in content ? (
|
|
150
|
-
<Surface.Surface type={AppSurface.
|
|
167
|
+
<Surface.Surface type={AppSurface.CardContent} data={content} limit={1} />
|
|
151
168
|
) : (
|
|
152
169
|
<Card.Body classNames='min-bs-8'>
|
|
153
170
|
<Card.Row>
|
|
@@ -21,7 +21,7 @@ export const Toast = ({
|
|
|
21
21
|
onAction,
|
|
22
22
|
onOpenChange,
|
|
23
23
|
}: LayoutOperation.Toast & Pick<ToastRootProps, 'onOpenChange'>) => {
|
|
24
|
-
const { t } = useTranslation(meta.
|
|
24
|
+
const { t } = useTranslation(meta.profile.key);
|
|
25
25
|
|
|
26
26
|
// Control the open state so closing flips Radix's `open` (playing the exit animation) rather than
|
|
27
27
|
// unmounting abruptly. Both the close button and Radix's own timeout/swipe route through here.
|
|
@@ -9,7 +9,7 @@ import { Capabilities, Capability, Plugin } from '@dxos/app-framework';
|
|
|
9
9
|
import { withPluginManager } from '@dxos/app-framework/testing';
|
|
10
10
|
import { Surface } from '@dxos/app-framework/ui';
|
|
11
11
|
import { AppActivationEvents } from '@dxos/app-toolkit';
|
|
12
|
-
import { useAppGraph } from '@dxos/app-toolkit/ui';
|
|
12
|
+
import { AppSurface, useAppGraph } from '@dxos/app-toolkit/ui';
|
|
13
13
|
import { corePlugins } from '@dxos/plugin-testing';
|
|
14
14
|
import { random } from '@dxos/random';
|
|
15
15
|
import { Main } from '@dxos/react-ui';
|
|
@@ -43,7 +43,7 @@ const storySurfaceExtension = Capability.contributes(
|
|
|
43
43
|
Capabilities.ReactSurface,
|
|
44
44
|
Surface.create({
|
|
45
45
|
id: 'storyArticle',
|
|
46
|
-
|
|
46
|
+
filter: Surface.makeFilter(AppSurface.Article),
|
|
47
47
|
component: ({ data }) => {
|
|
48
48
|
const subject = (data as any)?.subject;
|
|
49
49
|
if (!subject) {
|
|
@@ -34,7 +34,7 @@ export type PlankCompanionControlsProps = {
|
|
|
34
34
|
|
|
35
35
|
export const PlankCompanionControls = forwardRef<HTMLDivElement, PlankCompanionControlsProps>(
|
|
36
36
|
({ primary }, forwardedRef) => {
|
|
37
|
-
const { t } = useTranslation(meta.
|
|
37
|
+
const { t } = useTranslation(meta.profile.key);
|
|
38
38
|
const { invokePromise } = useOperationInvoker();
|
|
39
39
|
const handleCloseCompanion = useCallback(() => {
|
|
40
40
|
return invokePromise(LayoutOperation.UpdateCompanion, { subject: null });
|
|
@@ -78,7 +78,7 @@ export const PlankControls = forwardRef<HTMLDivElement, PlankControlsProps>(
|
|
|
78
78
|
{ children, classNames, variant = 'default', capabilities, layoutMode, pin, close = false, onClick, ...props },
|
|
79
79
|
forwardedRef,
|
|
80
80
|
) => {
|
|
81
|
-
const { t } = useTranslation(meta.
|
|
81
|
+
const { t } = useTranslation(meta.profile.key);
|
|
82
82
|
const buttonClassNames =
|
|
83
83
|
variant === 'hide-disabled' ? `disabled:hidden ${plankControlSpacing}` : plankControlSpacing;
|
|
84
84
|
|
|
@@ -52,7 +52,7 @@ export const PlankError = ({
|
|
|
52
52
|
* User facing error fallback.
|
|
53
53
|
*/
|
|
54
54
|
export const PlankErrorFallback = ({ error }: ErrorFallbackProps) => {
|
|
55
|
-
const { t } = useTranslation(meta.
|
|
55
|
+
const { t } = useTranslation(meta.profile.key);
|
|
56
56
|
|
|
57
57
|
useEffect(() => {
|
|
58
58
|
if (error) {
|
|
@@ -7,10 +7,9 @@ import React, { Fragment, type MouseEvent, memo, useCallback, useEffect, useMemo
|
|
|
7
7
|
import { Surface } from '@dxos/app-framework/ui';
|
|
8
8
|
import { AppSurface } from '@dxos/app-toolkit/ui';
|
|
9
9
|
import { Graph, type Node, useActionRunner } from '@dxos/plugin-graph';
|
|
10
|
-
import { Icon, IconButton, Popover, toLocalizedString, useTranslation } from '@dxos/react-ui';
|
|
10
|
+
import { Icon, IconButton, Popover, TextTooltip, toLocalizedString, useTranslation } from '@dxos/react-ui';
|
|
11
11
|
import { getLinkedVariant } from '@dxos/react-ui-attention';
|
|
12
12
|
import { StackItem, type StackItemSigilAction } from '@dxos/react-ui-stack';
|
|
13
|
-
import { TextTooltip } from '@dxos/react-ui-text-tooltip';
|
|
14
13
|
import { hoverableControls, hoverableFocusedWithinControls, iconSize } from '@dxos/ui-theme';
|
|
15
14
|
|
|
16
15
|
import { useBreakpoints } from '#hooks';
|
|
@@ -57,14 +56,14 @@ export const PlankHeading = memo(
|
|
|
57
56
|
actions = [],
|
|
58
57
|
debug = false,
|
|
59
58
|
}: PlankHeadingProps) => {
|
|
60
|
-
const { t } = useTranslation(meta.
|
|
59
|
+
const { t } = useTranslation(meta.profile.key);
|
|
61
60
|
const { graph, onAdjust, onUpdateCompanion } = usePlankContext('PlankHeading');
|
|
62
61
|
const runAction = useActionRunner();
|
|
63
62
|
const breakpoint = useBreakpoints();
|
|
64
63
|
const icon = node?.properties?.icon ?? 'ph--circle-dashed--regular';
|
|
65
64
|
const label = pending
|
|
66
65
|
? t('pending.heading')
|
|
67
|
-
: toLocalizedString(node?.properties?.label ?? ['plank-heading-fallback.label', { ns: meta.
|
|
66
|
+
: toLocalizedString(node?.properties?.label ?? ['plank-heading-fallback.label', { ns: meta.profile.key }], t);
|
|
68
67
|
|
|
69
68
|
const isCompanionNode = node?.type === PLANK_COMPANION_TYPE;
|
|
70
69
|
|
|
@@ -111,7 +110,7 @@ export const PlankHeading = memo(
|
|
|
111
110
|
const handleAction = useCallback(
|
|
112
111
|
(action: StackItemSigilAction) => {
|
|
113
112
|
if (typeof action.data === 'function') {
|
|
114
|
-
void runAction(action as Node.Action, { parent: node, caller: meta.
|
|
113
|
+
void runAction(action as Node.Action, { parent: node, caller: meta.profile.key });
|
|
115
114
|
}
|
|
116
115
|
},
|
|
117
116
|
[node, runAction],
|
|
@@ -124,7 +123,7 @@ export const PlankHeading = memo(
|
|
|
124
123
|
[onAdjust, id],
|
|
125
124
|
);
|
|
126
125
|
|
|
127
|
-
const ActionRoot = node && popoverAnchorId === `${meta.
|
|
126
|
+
const ActionRoot = node && popoverAnchorId === `${meta.profile.key}:${node.id}` ? Popover.Anchor : Fragment;
|
|
128
127
|
|
|
129
128
|
const handleTabClick = useCallback(
|
|
130
129
|
(event: MouseEvent) => {
|
|
@@ -6,6 +6,7 @@ import React, { type MouseEvent, useCallback, useEffect, useMemo, useState } fro
|
|
|
6
6
|
|
|
7
7
|
import { Surface, useOperationInvoker } from '@dxos/app-framework/ui';
|
|
8
8
|
import { LayoutOperation } from '@dxos/app-toolkit';
|
|
9
|
+
import { AppSurface } from '@dxos/app-toolkit/ui';
|
|
9
10
|
import { IconButton, type Label, Main, Panel, toLocalizedString, Toolbar, useTranslation } from '@dxos/react-ui';
|
|
10
11
|
import { getLinkedVariant } from '@dxos/react-ui-attention';
|
|
11
12
|
import { Tabs } from '@dxos/react-ui-tabs';
|
|
@@ -19,7 +20,7 @@ import { layoutAppliesTopbar } from '../../util';
|
|
|
19
20
|
import { PlankErrorFallback, PlankLoading } from '../Plank';
|
|
20
21
|
import { ToggleComplementarySidebarButton } from './SidebarButton';
|
|
21
22
|
|
|
22
|
-
const label = ['complementary-sidebar.title', { ns: meta.
|
|
23
|
+
const label = ['complementary-sidebar.title', { ns: meta.profile.key }] satisfies Label;
|
|
23
24
|
|
|
24
25
|
export type ComplementarySidebarProps = {
|
|
25
26
|
current?: string;
|
|
@@ -27,7 +28,7 @@ export type ComplementarySidebarProps = {
|
|
|
27
28
|
|
|
28
29
|
export const ComplementarySidebar = ({ current }: ComplementarySidebarProps) => {
|
|
29
30
|
const { invokePromise } = useOperationInvoker();
|
|
30
|
-
const { t } = useTranslation(meta.
|
|
31
|
+
const { t } = useTranslation(meta.profile.key);
|
|
31
32
|
const { state, deck, updateState } = useDeckState();
|
|
32
33
|
const layoutMode = getMode(deck);
|
|
33
34
|
const breakpoint = useBreakpoints();
|
|
@@ -117,7 +118,7 @@ export const ComplementarySidebar = ({ current }: ComplementarySidebarProps) =>
|
|
|
117
118
|
className='grid grid-cols-1 auto-rows-(--dx-rail-item) py-0.5 gap-0.5 overflow-y-auto scrollbar-none'
|
|
118
119
|
style={iconSize(4)}
|
|
119
120
|
>
|
|
120
|
-
<Surface.Surface
|
|
121
|
+
<Surface.Surface type={AppSurface.StatusIndicator} />
|
|
121
122
|
</div>
|
|
122
123
|
<div className='hidden lg:grid grid-cols-1 auto-rows-(--dx-rail-action) p-1'>
|
|
123
124
|
<ToggleComplementarySidebarButton />
|
|
@@ -154,7 +155,7 @@ type ComplementarySidebarPanelProps = {
|
|
|
154
155
|
};
|
|
155
156
|
|
|
156
157
|
const ComplementarySidebarPanel = ({ companion, activeId, data }: ComplementarySidebarPanelProps) => {
|
|
157
|
-
const { t } = useTranslation(meta.
|
|
158
|
+
const { t } = useTranslation(meta.profile.key);
|
|
158
159
|
|
|
159
160
|
if (getLinkedVariant(companion.id) !== activeId && !data) {
|
|
160
161
|
return null;
|
|
@@ -178,7 +179,7 @@ const ComplementarySidebarPanel = ({ companion, activeId, data }: ComplementaryS
|
|
|
178
179
|
</Panel.Toolbar>
|
|
179
180
|
<Panel.Content classNames='bg-r1-surface'>
|
|
180
181
|
<Surface.Surface
|
|
181
|
-
|
|
182
|
+
type={AppSurface.deckCompanion(getLinkedVariant(companion.id))}
|
|
182
183
|
data={data}
|
|
183
184
|
fallback={PlankErrorFallback}
|
|
184
185
|
placeholder={<PlankLoading />}
|
|
@@ -14,7 +14,7 @@ import { getMode } from '#types';
|
|
|
14
14
|
|
|
15
15
|
import { layoutAppliesTopbar } from '../../util';
|
|
16
16
|
|
|
17
|
-
const label = ['sidebar.title', { ns: meta.
|
|
17
|
+
const label = ['sidebar.title', { ns: meta.profile.key }] satisfies Label;
|
|
18
18
|
|
|
19
19
|
export const Sidebar = () => {
|
|
20
20
|
const { state, deck } = useDeckState();
|
|
@@ -17,7 +17,7 @@ export const ToggleSidebarButton = ({
|
|
|
17
17
|
variant = 'ghost',
|
|
18
18
|
}: ThemedClassName<Pick<IconButtonProps, 'variant'>>) => {
|
|
19
19
|
const { updateState } = useDeckState();
|
|
20
|
-
const { t } = useTranslation(meta.
|
|
20
|
+
const { t } = useTranslation(meta.profile.key);
|
|
21
21
|
|
|
22
22
|
const handleClick = useCallback(() => {
|
|
23
23
|
updateState((state) => ({
|
|
@@ -41,7 +41,7 @@ export const ToggleSidebarButton = ({
|
|
|
41
41
|
|
|
42
42
|
export const CloseSidebarButton = () => {
|
|
43
43
|
const { updateState } = useDeckState();
|
|
44
|
-
const { t } = useTranslation(meta.
|
|
44
|
+
const { t } = useTranslation(meta.profile.key);
|
|
45
45
|
|
|
46
46
|
const handleClick = useCallback(() => {
|
|
47
47
|
updateState((state) => ({ ...state, sidebarState: 'collapsed' }));
|
|
@@ -67,7 +67,7 @@ export const ToggleComplementarySidebarButton = ({
|
|
|
67
67
|
}: ThemedClassName<{ inR0?: boolean; current?: string }>) => {
|
|
68
68
|
const { invokePromise } = useOperationInvoker();
|
|
69
69
|
const { state, updateState } = useDeckState();
|
|
70
|
-
const { t } = useTranslation(meta.
|
|
70
|
+
const { t } = useTranslation(meta.profile.key);
|
|
71
71
|
|
|
72
72
|
const companions = useDeckCompanions();
|
|
73
73
|
const handleClick = useCallback(() => {
|
package/src/meta.ts
CHANGED
|
@@ -3,32 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { Plugin } from '@dxos/app-framework';
|
|
6
|
-
import { DXN } from '@dxos/keys';
|
|
7
|
-
import { trim } from '@dxos/util';
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
key: DXN.make('org.dxos.plugin.deck'),
|
|
11
|
-
name: 'Layout',
|
|
12
|
-
author: 'DXOS',
|
|
13
|
-
spec: 'PLUGIN.mdl',
|
|
14
|
-
description: trim`
|
|
15
|
-
The Deck plugin is the core layout engine for DXOS Composer. It manages the multi-plank
|
|
16
|
-
workspace (the "deck"), sidebar panels, dialogs, popovers, and toast notifications, giving
|
|
17
|
-
users a flexible, persistent workspace they can arrange to match their workflow.
|
|
7
|
+
import config from '../dx.config';
|
|
18
8
|
|
|
19
|
-
|
|
20
|
-
navigate with stack semantics — opening from a pivot truncates planks to the right and
|
|
21
|
-
appends the new one — or switch to solo or fullscreen mode for focused, distraction-free
|
|
22
|
-
viewing.
|
|
23
|
-
|
|
24
|
-
Layout state (active planks, sidebar visibility, plank sizes, companion pane) is persisted
|
|
25
|
-
across sessions via KVS/localStorage. URL routing is handled by the plugin so that any
|
|
26
|
-
workspace configuration can be bookmarked or shared as a deep link.
|
|
27
|
-
|
|
28
|
-
All layout changes are expressed through typed LayoutOperations (Open, Close, SetLayoutMode,
|
|
29
|
-
UpdateSidebar, UpdateDialog, UpdatePopover, etc.) that any plugin in the system can dispatch,
|
|
30
|
-
keeping the layout logic centralised and easy to extend.
|
|
31
|
-
`,
|
|
32
|
-
icon: 'ph--layout--regular',
|
|
33
|
-
tags: ['system'],
|
|
34
|
-
});
|
|
9
|
+
export const meta = Plugin.getMetaFromConfig(config);
|
package/src/operations/open.ts
CHANGED
|
@@ -6,13 +6,7 @@ import * as Effect from 'effect/Effect';
|
|
|
6
6
|
import * as Option from 'effect/Option';
|
|
7
7
|
|
|
8
8
|
import { Capabilities, Capability } from '@dxos/app-framework';
|
|
9
|
-
import {
|
|
10
|
-
AppCapabilities,
|
|
11
|
-
LayoutOperation,
|
|
12
|
-
createEdgeExistenceChecker,
|
|
13
|
-
expandPath,
|
|
14
|
-
validateNavigationTarget,
|
|
15
|
-
} from '@dxos/app-toolkit';
|
|
9
|
+
import { AppCapabilities, LayoutOperation, NotFound } from '@dxos/app-toolkit';
|
|
16
10
|
import { Operation } from '@dxos/compute';
|
|
17
11
|
import { Context } from '@dxos/context';
|
|
18
12
|
import { Database, EID, Obj } from '@dxos/echo';
|
|
@@ -56,13 +50,15 @@ const handler: Operation.WithHandler<typeof LayoutOperation.Open> = LayoutOperat
|
|
|
56
50
|
}
|
|
57
51
|
: undefined;
|
|
58
52
|
const checkRemoteExistence = client
|
|
59
|
-
? createEdgeExistenceChecker((spaceId, body) =>
|
|
53
|
+
? NotFound.createEdgeExistenceChecker((spaceId, body) =>
|
|
54
|
+
client.edge.http.execQuery(new Context(), spaceId, body),
|
|
55
|
+
)
|
|
60
56
|
: undefined;
|
|
61
57
|
|
|
62
58
|
// Immediate: skip 404 / resolver checks but still expand the path (same as validate’s first step).
|
|
63
59
|
if (input.navigation === 'immediate') {
|
|
64
60
|
for (const subjectId of input.subject) {
|
|
65
|
-
expandPath(graph, subjectId);
|
|
61
|
+
NotFound.expandPath(graph, subjectId);
|
|
66
62
|
}
|
|
67
63
|
}
|
|
68
64
|
|
|
@@ -70,7 +66,13 @@ const handler: Operation.WithHandler<typeof LayoutOperation.Open> = LayoutOperat
|
|
|
70
66
|
input.subject.map((subjectId) =>
|
|
71
67
|
input.navigation === 'immediate'
|
|
72
68
|
? Effect.succeed(subjectId)
|
|
73
|
-
: validateNavigationTarget({
|
|
69
|
+
: NotFound.validateNavigationTarget({
|
|
70
|
+
graph,
|
|
71
|
+
subjectId,
|
|
72
|
+
pathResolvers,
|
|
73
|
+
checkLocalExistence,
|
|
74
|
+
checkRemoteExistence,
|
|
75
|
+
}),
|
|
74
76
|
),
|
|
75
77
|
);
|
|
76
78
|
input = { ...input, subject: validatedSubjects };
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import * as Effect from 'effect/Effect';
|
|
6
6
|
|
|
7
7
|
import { Capabilities, Capability } from '@dxos/app-framework';
|
|
8
|
-
import { AppCapabilities,
|
|
8
|
+
import { AppCapabilities, LayoutOperation, Paths } from '@dxos/app-toolkit';
|
|
9
9
|
import { Operation } from '@dxos/compute';
|
|
10
10
|
import { invariant } from '@dxos/invariant';
|
|
11
11
|
import { Graph, Node } from '@dxos/plugin-graph';
|
|
@@ -21,7 +21,7 @@ const handler: Operation.WithHandler<typeof LayoutOperation.SwitchWorkspace> = L
|
|
|
21
21
|
const state = yield* Capabilities.getAtomValue(DeckCapabilities.State);
|
|
22
22
|
// TODO(wittjosiah): This is a hack to prevent the previous deck from being set for pinned items.
|
|
23
23
|
// Ideally this should be worked into the data model in a generic way.
|
|
24
|
-
const shouldUpdatePrevious = !isPinnedWorkspace(state.activeDeck);
|
|
24
|
+
const shouldUpdatePrevious = !Paths.isPinnedWorkspace(state.activeDeck);
|
|
25
25
|
|
|
26
26
|
yield* Capabilities.updateAtomValue(DeckCapabilities.State, (state) => {
|
|
27
27
|
const newDecks = state.decks[input.subject]
|
package/src/translations.ts
CHANGED
|
@@ -14,14 +14,16 @@ import { meta } from '#meta';
|
|
|
14
14
|
|
|
15
15
|
import { type EphemeralDeckState, type DeckState, type StoredDeckState } from './schema';
|
|
16
16
|
|
|
17
|
-
export const Settings = Capability.make<Atom.Writable<import('./Settings').Settings>>(
|
|
17
|
+
export const Settings = Capability.make<Atom.Writable<import('./Settings').Settings>>(
|
|
18
|
+
`${meta.profile.key}.capability.settings`,
|
|
19
|
+
);
|
|
18
20
|
|
|
19
21
|
/** Persisted state (stored in KVS/localStorage). */
|
|
20
|
-
export const State = Capability.make<Atom.Writable<StoredDeckState>>(`${meta.
|
|
22
|
+
export const State = Capability.make<Atom.Writable<StoredDeckState>>(`${meta.profile.key}.capability.state`);
|
|
21
23
|
|
|
22
24
|
/** Transient/ephemeral state (not persisted). */
|
|
23
25
|
export const EphemeralState = Capability.make<Atom.Writable<EphemeralDeckState>>(
|
|
24
|
-
`${meta.
|
|
26
|
+
`${meta.profile.key}.capability.ephemeral-state`,
|
|
25
27
|
);
|
|
26
28
|
|
|
27
29
|
/** Get the current active deck from state. */
|
package/src/types/DeckEvents.ts
CHANGED
|
@@ -12,7 +12,7 @@ import { meta } from '#meta';
|
|
|
12
12
|
import * as DeckCapabilities from './DeckCapabilities';
|
|
13
13
|
|
|
14
14
|
export const StateReady: ActivationEvent.ActivationEvent = AppActivationEvents.createStateEvent(
|
|
15
|
-
`${meta.
|
|
15
|
+
`${meta.profile.key}.state-ready`,
|
|
16
16
|
);
|
|
17
17
|
|
|
18
18
|
/** Fired when DeckSettings capability is ready. */
|
|
@@ -12,7 +12,7 @@ import { DXN } from '@dxos/keys';
|
|
|
12
12
|
|
|
13
13
|
import { meta } from '#meta';
|
|
14
14
|
|
|
15
|
-
const makeKey = (name: string) => DXN.make(`${meta.
|
|
15
|
+
const makeKey = (name: string) => DXN.make(`${meta.profile.key}.operation.${name}`);
|
|
16
16
|
|
|
17
17
|
const PartAdjustmentSchema = Schema.Union(
|
|
18
18
|
Schema.Literal('close').annotations({ description: 'Close the plank.' }),
|
package/src/types/index.ts
CHANGED
package/src/types/schema.ts
CHANGED
|
@@ -4,12 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
import * as Schema from 'effect/Schema';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { AppNode, LayoutOperation, Translations } from '@dxos/app-toolkit';
|
|
8
8
|
import { type DeepReadonly } from '@dxos/util';
|
|
9
9
|
|
|
10
10
|
import { meta } from '#meta';
|
|
11
11
|
|
|
12
|
-
export
|
|
12
|
+
export const PLANK_COMPANION_TYPE = AppNode.PLANK_COMPANION_TYPE;
|
|
13
|
+
export const DECK_COMPANION_TYPE = AppNode.DECK_COMPANION_TYPE;
|
|
13
14
|
|
|
14
15
|
export type Part = 'solo' | 'multi' | 'complementary';
|
|
15
16
|
export type ResolvedPart = Part | 'solo-primary' | 'solo-companion';
|
|
@@ -91,8 +92,8 @@ export const EphemeralDeckState = Schema.Struct({
|
|
|
91
92
|
popoverSide: Schema.optional(Schema.Literal('top', 'right', 'bottom', 'left')),
|
|
92
93
|
popoverAnchor: Schema.optional(Schema.Any),
|
|
93
94
|
popoverAnchorId: Schema.optional(Schema.String),
|
|
94
|
-
popoverKind: Schema.optional(Schema.Literal('base', 'card')),
|
|
95
|
-
popoverTitle: Schema.optional(Label.annotations({ description: 'The title of the popover.' })),
|
|
95
|
+
popoverKind: Schema.optional(Schema.Literal('base', 'card', 'rename')),
|
|
96
|
+
popoverTitle: Schema.optional(Translations.Label.annotations({ description: 'The title of the popover.' })),
|
|
96
97
|
/** Ref of the subject to be passed to the popover Surface. */
|
|
97
98
|
popoverContentRef: Schema.optional(Schema.String),
|
|
98
99
|
/** Data to be passed to the popover Surface. */
|
|
@@ -126,16 +127,19 @@ export namespace DeckAction {
|
|
|
126
127
|
export type Adjustment = Schema.Schema.Type<typeof Adjustment>;
|
|
127
128
|
|
|
128
129
|
// An atomic transaction to apply to the deck, describing which element to move to which location.
|
|
129
|
-
export class Adjust extends Schema.TaggedClass<Adjust>()(`${meta.
|
|
130
|
+
export class Adjust extends Schema.TaggedClass<Adjust>()(`${meta.profile.key}.action.adjust`, {
|
|
130
131
|
input: Adjustment,
|
|
131
132
|
output: Schema.Void,
|
|
132
133
|
}) {}
|
|
133
134
|
|
|
134
|
-
export class UpdatePlankSize extends Schema.TaggedClass<UpdatePlankSize>()(
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
135
|
+
export class UpdatePlankSize extends Schema.TaggedClass<UpdatePlankSize>()(
|
|
136
|
+
`${meta.profile.key}.action.update-plank-size`,
|
|
137
|
+
{
|
|
138
|
+
input: Schema.Struct({
|
|
139
|
+
id: Schema.String,
|
|
140
|
+
size: Schema.Number,
|
|
141
|
+
}),
|
|
142
|
+
output: Schema.Void,
|
|
143
|
+
},
|
|
144
|
+
) {}
|
|
141
145
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { Surface } from '@dxos/app-framework/ui';
|
|
6
|
+
|
|
7
|
+
/** Slot for the main status-bar container. */
|
|
8
|
+
export const StatusBar: Surface.RoleToken<Record<string, unknown>> = Surface.makeType(
|
|
9
|
+
'org.dxos.plugin.statusBar.role.statusBar',
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
/** Slot for the status-bar footer region. */
|
|
13
|
+
export const StatusBarFooter: Surface.RoleToken<Record<string, unknown>> = Surface.makeType(
|
|
14
|
+
'org.dxos.plugin.statusBar.role.footer',
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
/** Slot for the version-info widget in the banner. */
|
|
18
|
+
export const VersionInfo: Surface.RoleToken<Record<string, unknown>> = Surface.makeType(
|
|
19
|
+
'org.dxos.plugin.statusBar.role.versionInfo',
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
/** Slot for the keyboard-shortcuts hints overlay. */
|
|
23
|
+
export const Hints: Surface.RoleToken<Record<string, unknown>> = Surface.makeType('org.dxos.plugin.support.role.hints');
|
|
24
|
+
|
|
25
|
+
/** Slot for the full keyboard-shortcuts list. */
|
|
26
|
+
export const Keyshortcuts: Surface.RoleToken<Record<string, unknown>> = Surface.makeType(
|
|
27
|
+
'org.dxos.plugin.support.role.keyshortcuts',
|
|
28
|
+
);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { Paths } from '@dxos/app-toolkit';
|
|
6
6
|
|
|
7
7
|
const PLANK_PARAM = 'plank';
|
|
8
8
|
|
|
@@ -14,7 +14,7 @@ export const serializePlanks = (active: readonly string[], existingSearch: strin
|
|
|
14
14
|
const params = new URLSearchParams(existingSearch);
|
|
15
15
|
params.delete(PLANK_PARAM);
|
|
16
16
|
for (const id of active) {
|
|
17
|
-
params.append(PLANK_PARAM, toUrlPath(id));
|
|
17
|
+
params.append(PLANK_PARAM, Paths.toUrlPath(id));
|
|
18
18
|
}
|
|
19
19
|
return params.size > 0 ? `?${params.toString()}` : '';
|
|
20
20
|
};
|
|
@@ -23,7 +23,7 @@ export const serializePlanks = (active: readonly string[], existingSearch: strin
|
|
|
23
23
|
* Deserialize plank query params from a URL back to qualified graph IDs.
|
|
24
24
|
*/
|
|
25
25
|
export const deserializePlanks = (url: URL): string[] => {
|
|
26
|
-
return url.searchParams.getAll(PLANK_PARAM).map(fromUrlPath);
|
|
26
|
+
return url.searchParams.getAll(PLANK_PARAM).map(Paths.fromUrlPath);
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
/**
|