@dxos/plugin-deck 0.8.2-main.f11618f → 0.8.2-staging.42af850
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/{app-graph-builder-VYZ4IWI3.mjs → app-graph-builder-M5BT34YG.mjs} +17 -16
- package/dist/lib/browser/app-graph-builder-M5BT34YG.mjs.map +7 -0
- package/dist/lib/browser/{check-app-scheme-O7JPE4TM.mjs → check-app-scheme-7AXGR6UT.mjs} +2 -2
- package/dist/lib/browser/check-app-scheme-7AXGR6UT.mjs.map +7 -0
- package/dist/lib/browser/{state-Z6UY2Z3M.mjs → chunk-FX44YX3G.mjs} +7 -5
- package/dist/lib/browser/chunk-FX44YX3G.mjs.map +7 -0
- package/dist/lib/browser/chunk-JE2ARGEB.mjs +1487 -0
- package/dist/lib/browser/chunk-JE2ARGEB.mjs.map +7 -0
- package/dist/lib/browser/{chunk-XMCG42ID.mjs → chunk-KLN73CM3.mjs} +2 -2
- package/dist/lib/browser/{chunk-XMCG42ID.mjs.map → chunk-KLN73CM3.mjs.map} +1 -1
- package/dist/lib/browser/chunk-SLQNOATN.mjs +127 -0
- package/dist/lib/browser/chunk-SLQNOATN.mjs.map +7 -0
- package/dist/lib/browser/chunk-TRFYUEBA.mjs +145 -0
- package/dist/lib/browser/chunk-TRFYUEBA.mjs.map +7 -0
- package/dist/lib/browser/chunk-YN5OZEGS.mjs +162 -0
- package/dist/lib/browser/chunk-YN5OZEGS.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +6 -8
- package/dist/lib/browser/index.mjs.map +2 -2
- package/dist/lib/browser/{intent-resolver-JKWXWUV6.mjs → intent-resolver-3GAC57UA.mjs} +84 -66
- package/dist/lib/browser/intent-resolver-3GAC57UA.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{react-root-S6ZAKNZA.mjs → react-root-ISFFOJZX.mjs} +7 -7
- package/dist/lib/browser/{react-surface-I7WZBOGM.mjs → react-surface-A63RQB5N.mjs} +7 -7
- package/dist/lib/browser/{settings-6NU7CF2B.mjs → settings-X7GDEXU3.mjs} +4 -4
- package/dist/lib/browser/{settings-6NU7CF2B.mjs.map → settings-X7GDEXU3.mjs.map} +3 -3
- package/dist/lib/browser/state-VJ6E3ADY.mjs +10 -0
- package/dist/lib/browser/state-VJ6E3ADY.mjs.map +7 -0
- package/dist/lib/browser/{tools-VDVQTJMD.mjs → tools-N57NQ2LH.mjs} +28 -18
- package/dist/lib/browser/tools-N57NQ2LH.mjs.map +7 -0
- package/dist/lib/browser/types.mjs +1 -1
- package/dist/lib/browser/{url-handler-3CARFXQK.mjs → url-handler-BUGI6XRE.mjs} +5 -5
- package/dist/lib/browser/url-handler-BUGI6XRE.mjs.map +7 -0
- package/dist/types/src/capabilities/app-graph-builder.d.ts +2 -179
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/capabilities/capabilities.d.ts +10 -2
- package/dist/types/src/capabilities/capabilities.d.ts.map +1 -1
- package/dist/types/src/capabilities/check-app-scheme.d.ts +2 -2
- package/dist/types/src/capabilities/check-app-scheme.d.ts.map +1 -1
- package/dist/types/src/capabilities/index.d.ts +6 -181
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/intent-resolver.d.ts +2 -2
- package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
- package/dist/types/src/capabilities/state.d.ts +7 -3
- package/dist/types/src/capabilities/state.d.ts.map +1 -1
- package/dist/types/src/capabilities/tools.d.ts +1 -1
- package/dist/types/src/capabilities/tools.d.ts.map +1 -1
- package/dist/types/src/capabilities/url-handler.d.ts +2 -2
- package/dist/types/src/capabilities/url-handler.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/Banner.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/ContentEmpty.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/DeckLayout.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/Popover.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/StatusBar.d.ts.map +1 -1
- package/dist/types/src/components/DeckLayout/Toast.d.ts.map +1 -1
- package/dist/types/src/components/DeckSettings/DeckSettings.d.ts.map +1 -1
- package/dist/types/src/components/Plank/Plank.d.ts +18 -5
- package/dist/types/src/components/Plank/Plank.d.ts.map +1 -1
- package/dist/types/src/components/Plank/Plank.stories.d.ts +3 -3
- package/dist/types/src/components/Plank/Plank.stories.d.ts.map +1 -1
- package/dist/types/src/components/Plank/PlankControls.d.ts +1 -0
- package/dist/types/src/components/Plank/PlankControls.d.ts.map +1 -1
- package/dist/types/src/components/Plank/PlankError.d.ts.map +1 -1
- package/dist/types/src/components/Plank/PlankHeading.d.ts.map +1 -1
- package/dist/types/src/components/Sidebar/ComplementarySidebar.d.ts.map +1 -1
- package/dist/types/src/components/Sidebar/Sidebar.d.ts.map +1 -1
- package/dist/types/src/components/Sidebar/SidebarButton.d.ts +2 -1
- package/dist/types/src/components/Sidebar/SidebarButton.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +5 -1
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useBreakpoints.d.ts.map +1 -0
- package/dist/types/src/hooks/useCompanions.d.ts.map +1 -0
- package/dist/types/src/hooks/useDeckCompanions.d.ts +13 -0
- package/dist/types/src/hooks/useDeckCompanions.d.ts.map +1 -0
- package/dist/types/src/hooks/useHoistStatusbar.d.ts.map +1 -0
- package/dist/types/src/hooks/useNodeActionExpander.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/layout.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +0 -1
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +106 -104
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/src/util/index.d.ts +1 -4
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/src/util/layoutAppliesTopbar.d.ts.map +1 -1
- package/dist/types/src/util/overscroll.d.ts.map +1 -1
- package/dist/types/src/util/set-active.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +38 -30
- package/src/capabilities/app-graph-builder.ts +120 -92
- package/src/capabilities/check-app-scheme.ts +3 -5
- package/src/capabilities/index.ts +1 -0
- package/src/capabilities/intent-resolver.ts +100 -78
- package/src/capabilities/settings.ts +2 -2
- package/src/capabilities/state.ts +4 -2
- package/src/capabilities/tools.ts +15 -12
- package/src/capabilities/url-handler.ts +4 -4
- package/src/components/DeckLayout/ContentEmpty.tsx +3 -2
- package/src/components/DeckLayout/DeckLayout.tsx +12 -10
- package/src/components/DeckLayout/Dialog.tsx +2 -2
- package/src/components/Plank/Plank.stories.tsx +20 -8
- package/src/components/Plank/Plank.tsx +101 -68
- package/src/components/Plank/PlankControls.tsx +15 -25
- package/src/components/Plank/PlankHeading.tsx +22 -10
- package/src/components/Sidebar/ComplementarySidebar.tsx +7 -38
- package/src/components/Sidebar/Sidebar.tsx +2 -1
- package/src/components/Sidebar/SidebarButton.tsx +26 -7
- package/src/components/fragments.ts +1 -1
- package/src/hooks/index.ts +5 -1
- package/src/{util → hooks}/useCompanions.ts +3 -3
- package/src/hooks/useDeckCompanions.ts +33 -0
- package/src/hooks/useNodeActionExpander.ts +3 -8
- package/src/index.ts +1 -1
- package/src/translations.ts +0 -1
- package/src/types.ts +74 -71
- package/src/util/index.ts +1 -4
- package/dist/lib/browser/app-graph-builder-VYZ4IWI3.mjs.map +0 -7
- package/dist/lib/browser/check-app-scheme-O7JPE4TM.mjs.map +0 -7
- package/dist/lib/browser/chunk-6HJZL3WT.mjs +0 -118
- package/dist/lib/browser/chunk-6HJZL3WT.mjs.map +0 -7
- package/dist/lib/browser/chunk-FLOVGNYB.mjs +0 -81
- package/dist/lib/browser/chunk-FLOVGNYB.mjs.map +0 -7
- package/dist/lib/browser/chunk-RBJ6DLAC.mjs +0 -24
- package/dist/lib/browser/chunk-RBJ6DLAC.mjs.map +0 -7
- package/dist/lib/browser/chunk-RDFJGGGX.mjs +0 -1334
- package/dist/lib/browser/chunk-RDFJGGGX.mjs.map +0 -7
- package/dist/lib/browser/chunk-ZMJMCN7O.mjs +0 -157
- package/dist/lib/browser/chunk-ZMJMCN7O.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-JKWXWUV6.mjs.map +0 -7
- package/dist/lib/browser/state-Z6UY2Z3M.mjs.map +0 -7
- package/dist/lib/browser/tools-VDVQTJMD.mjs.map +0 -7
- package/dist/lib/browser/url-handler-3CARFXQK.mjs.map +0 -7
- package/dist/types/src/util/useBreakpoints.d.ts.map +0 -1
- package/dist/types/src/util/useCompanions.d.ts.map +0 -1
- package/dist/types/src/util/useHoistStatusbar.d.ts.map +0 -1
- /package/dist/lib/browser/{react-root-S6ZAKNZA.mjs.map → react-root-ISFFOJZX.mjs.map} +0 -0
- /package/dist/lib/browser/{react-surface-I7WZBOGM.mjs.map → react-surface-A63RQB5N.mjs.map} +0 -0
- /package/dist/types/src/{util → hooks}/useBreakpoints.d.ts +0 -0
- /package/dist/types/src/{util → hooks}/useCompanions.d.ts +0 -0
- /package/dist/types/src/{util → hooks}/useHoistStatusbar.d.ts +0 -0
- /package/src/{util → hooks}/useBreakpoints.ts +0 -0
- /package/src/{util → hooks}/useHoistStatusbar.ts +0 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { batch } from '@preact/signals-core';
|
|
6
|
-
import { Effect, pipe } from 'effect';
|
|
6
|
+
import { Schema, Effect, pipe, Option } from 'effect';
|
|
7
7
|
|
|
8
8
|
import {
|
|
9
9
|
Capabilities,
|
|
@@ -11,16 +11,16 @@ import {
|
|
|
11
11
|
contributes,
|
|
12
12
|
IntentAction,
|
|
13
13
|
LayoutAction,
|
|
14
|
-
type
|
|
14
|
+
type PluginContext,
|
|
15
15
|
createIntent,
|
|
16
16
|
chain,
|
|
17
17
|
} from '@dxos/app-framework';
|
|
18
|
-
import { getTypename
|
|
18
|
+
import { getTypename } from '@dxos/echo-schema';
|
|
19
19
|
import { invariant } from '@dxos/invariant';
|
|
20
20
|
import { isLiveObject } from '@dxos/live-object';
|
|
21
21
|
import { log } from '@dxos/log';
|
|
22
22
|
import { AttentionCapabilities } from '@dxos/plugin-attention';
|
|
23
|
-
import {
|
|
23
|
+
import { isActionLike } from '@dxos/plugin-graph';
|
|
24
24
|
import { ObservabilityAction } from '@dxos/plugin-observability/types';
|
|
25
25
|
import { byPosition, isNonNullable } from '@dxos/util';
|
|
26
26
|
|
|
@@ -38,13 +38,13 @@ import {
|
|
|
38
38
|
} from '../types';
|
|
39
39
|
import { setActive } from '../util';
|
|
40
40
|
|
|
41
|
-
export default (context:
|
|
41
|
+
export default (context: PluginContext) =>
|
|
42
42
|
contributes(Capabilities.IntentResolver, [
|
|
43
43
|
createResolver({
|
|
44
44
|
intent: IntentAction.ShowUndo,
|
|
45
45
|
resolve: (data) => {
|
|
46
|
-
const layout = context.
|
|
47
|
-
const { undoPromise: undo } = context.
|
|
46
|
+
const layout = context.getCapability(DeckCapabilities.MutableDeckState);
|
|
47
|
+
const { undoPromise: undo } = context.getCapability(Capabilities.IntentDispatcher);
|
|
48
48
|
|
|
49
49
|
// TODO(wittjosiah): Support undoing further back than the last action.
|
|
50
50
|
if (layout.currentUndoId) {
|
|
@@ -67,12 +67,12 @@ export default (context: PluginsContext) =>
|
|
|
67
67
|
}),
|
|
68
68
|
createResolver({
|
|
69
69
|
intent: LayoutAction.UpdateLayout,
|
|
70
|
-
// TODO(wittjosiah): This should be able to just be `
|
|
70
|
+
// TODO(wittjosiah): This should be able to just be `Schema.is(LayoutAction.UpdateSidebar.fields.input)`
|
|
71
71
|
// but the filter is not being applied correctly.
|
|
72
|
-
filter: (data): data is
|
|
73
|
-
|
|
72
|
+
filter: (data): data is Schema.Schema.Type<typeof LayoutAction.UpdateSidebar.fields.input> =>
|
|
73
|
+
Schema.is(LayoutAction.UpdateSidebar.fields.input)(data),
|
|
74
74
|
resolve: ({ options }) => {
|
|
75
|
-
const layout = context.
|
|
75
|
+
const layout = context.getCapability(DeckCapabilities.MutableDeckState);
|
|
76
76
|
const next = options?.state ?? layout.sidebarState;
|
|
77
77
|
if (next !== layout.sidebarState) {
|
|
78
78
|
layout.sidebarState = next;
|
|
@@ -81,12 +81,12 @@ export default (context: PluginsContext) =>
|
|
|
81
81
|
}),
|
|
82
82
|
createResolver({
|
|
83
83
|
intent: LayoutAction.UpdateLayout,
|
|
84
|
-
// TODO(wittjosiah): This should be able to just be `
|
|
84
|
+
// TODO(wittjosiah): This should be able to just be `Schema.is(LayoutAction.UpdateComplementary.fields.input)`
|
|
85
85
|
// but the filter is not being applied correctly.
|
|
86
|
-
filter: (data): data is
|
|
87
|
-
|
|
86
|
+
filter: (data): data is Schema.Schema.Type<typeof LayoutAction.UpdateComplementary.fields.input> =>
|
|
87
|
+
Schema.is(LayoutAction.UpdateComplementary.fields.input)(data),
|
|
88
88
|
resolve: ({ subject, options }) => {
|
|
89
|
-
const layout = context.
|
|
89
|
+
const layout = context.getCapability(DeckCapabilities.MutableDeckState);
|
|
90
90
|
|
|
91
91
|
if (layout.complementarySidebarPanel !== subject) {
|
|
92
92
|
layout.complementarySidebarPanel = subject;
|
|
@@ -100,26 +100,28 @@ export default (context: PluginsContext) =>
|
|
|
100
100
|
}),
|
|
101
101
|
createResolver({
|
|
102
102
|
intent: LayoutAction.UpdateLayout,
|
|
103
|
-
// TODO(wittjosiah): This should be able to just be `
|
|
103
|
+
// TODO(wittjosiah): This should be able to just be `Schema.is(LayoutAction.UpdateDialog.fields.input)`
|
|
104
104
|
// but the filter is not being applied correctly.
|
|
105
|
-
filter: (data): data is
|
|
106
|
-
|
|
105
|
+
filter: (data): data is Schema.Schema.Type<typeof LayoutAction.UpdateDialog.fields.input> =>
|
|
106
|
+
Schema.is(LayoutAction.UpdateDialog.fields.input)(data),
|
|
107
107
|
resolve: ({ subject, options }) => {
|
|
108
|
-
const layout = context.
|
|
108
|
+
const layout = context.getCapability(DeckCapabilities.MutableDeckState);
|
|
109
109
|
layout.dialogOpen = options.state ?? Boolean(subject);
|
|
110
|
-
layout.dialogContent = subject ? { component: subject, props: options.props } : null;
|
|
111
|
-
layout.dialogBlockAlign = options.blockAlign ?? 'center';
|
|
112
110
|
layout.dialogType = options.type ?? 'default';
|
|
111
|
+
layout.dialogBlockAlign = options.blockAlign ?? 'center';
|
|
112
|
+
layout.dialogOverlayClasses = options.overlayClasses;
|
|
113
|
+
layout.dialogOverlayStyle = options.overlayStyle;
|
|
114
|
+
layout.dialogContent = subject ? { component: subject, props: options.props } : null;
|
|
113
115
|
},
|
|
114
116
|
}),
|
|
115
117
|
createResolver({
|
|
116
118
|
intent: LayoutAction.UpdateLayout,
|
|
117
|
-
// TODO(wittjosiah): This should be able to just be `
|
|
119
|
+
// TODO(wittjosiah): This should be able to just be `Schema.is(LayoutAction.UpdatePopover.fields.input)`
|
|
118
120
|
// but the filter is not being applied correctly.
|
|
119
|
-
filter: (data): data is
|
|
120
|
-
|
|
121
|
+
filter: (data): data is Schema.Schema.Type<typeof LayoutAction.UpdatePopover.fields.input> =>
|
|
122
|
+
Schema.is(LayoutAction.UpdatePopover.fields.input)(data),
|
|
121
123
|
resolve: ({ subject, options }) => {
|
|
122
|
-
const layout = context.
|
|
124
|
+
const layout = context.getCapability(DeckCapabilities.MutableDeckState);
|
|
123
125
|
layout.popoverOpen = options.state ?? Boolean(subject);
|
|
124
126
|
layout.popoverContent =
|
|
125
127
|
typeof subject === 'string' ? { component: subject, props: options.props } : subject ? { subject } : null;
|
|
@@ -133,21 +135,21 @@ export default (context: PluginsContext) =>
|
|
|
133
135
|
}),
|
|
134
136
|
createResolver({
|
|
135
137
|
intent: LayoutAction.UpdateLayout,
|
|
136
|
-
// TODO(wittjosiah): This should be able to just be `
|
|
138
|
+
// TODO(wittjosiah): This should be able to just be `Schema.is(LayoutAction.AddToast.fields.input)`
|
|
137
139
|
// but the filter is not being applied correctly.
|
|
138
|
-
filter: (data): data is
|
|
139
|
-
|
|
140
|
+
filter: (data): data is Schema.Schema.Type<typeof LayoutAction.AddToast.fields.input> =>
|
|
141
|
+
Schema.is(LayoutAction.AddToast.fields.input)(data),
|
|
140
142
|
resolve: ({ subject }) => {
|
|
141
|
-
const layout = context.
|
|
143
|
+
const layout = context.getCapability(DeckCapabilities.MutableDeckState);
|
|
142
144
|
layout.toasts.push(subject);
|
|
143
145
|
},
|
|
144
146
|
}),
|
|
145
147
|
createResolver({
|
|
146
148
|
intent: LayoutAction.UpdateLayout,
|
|
147
|
-
// TODO(wittjosiah): This should be able to just be `
|
|
149
|
+
// TODO(wittjosiah): This should be able to just be `Schema.is(LayoutAction.SetLayoutMode.fields.input)`
|
|
148
150
|
// but the filter is not being applied correctly.
|
|
149
|
-
filter: (data): data is
|
|
150
|
-
if (!
|
|
151
|
+
filter: (data): data is Schema.Schema.Type<typeof LayoutAction.SetLayoutMode.fields.input> => {
|
|
152
|
+
if (!Schema.is(LayoutAction.SetLayoutMode.fields.input)(data)) {
|
|
151
153
|
return false;
|
|
152
154
|
}
|
|
153
155
|
|
|
@@ -158,7 +160,7 @@ export default (context: PluginsContext) =>
|
|
|
158
160
|
return true;
|
|
159
161
|
},
|
|
160
162
|
resolve: ({ subject, options }) => {
|
|
161
|
-
const state = context.
|
|
163
|
+
const state = context.getCapability(DeckCapabilities.MutableDeckState);
|
|
162
164
|
|
|
163
165
|
const setMode = (mode: LayoutMode) => {
|
|
164
166
|
const deck = state.deck;
|
|
@@ -202,10 +204,11 @@ export default (context: PluginsContext) =>
|
|
|
202
204
|
}),
|
|
203
205
|
createResolver({
|
|
204
206
|
intent: LayoutAction.UpdateLayout,
|
|
205
|
-
filter: (data): data is
|
|
206
|
-
|
|
207
|
+
filter: (data): data is Schema.Schema.Type<typeof LayoutAction.SwitchWorkspace.fields.input> =>
|
|
208
|
+
Schema.is(LayoutAction.SwitchWorkspace.fields.input)(data),
|
|
207
209
|
resolve: ({ subject }) => {
|
|
208
|
-
const
|
|
210
|
+
const { graph } = context.getCapability(Capabilities.AppGraph);
|
|
211
|
+
const state = context.getCapability(DeckCapabilities.MutableDeckState);
|
|
209
212
|
batch(() => {
|
|
210
213
|
// TODO(wittjosiah): This is a hack to prevent the previous deck from being set for pinned items.
|
|
211
214
|
// Ideally this should be worked into the data model in a generic way.
|
|
@@ -223,15 +226,24 @@ export default (context: PluginsContext) =>
|
|
|
223
226
|
return {
|
|
224
227
|
intents: [createIntent(LayoutAction.ScrollIntoView, { part: 'current', subject: first })],
|
|
225
228
|
};
|
|
229
|
+
} else {
|
|
230
|
+
const [item] = graph
|
|
231
|
+
.getConnections(subject)
|
|
232
|
+
.filter((node) => !isActionLike(node) && node.properties.disposition !== 'hidden');
|
|
233
|
+
if (item) {
|
|
234
|
+
return {
|
|
235
|
+
intents: [createIntent(LayoutAction.Open, { part: 'main', subject: [item.id] })],
|
|
236
|
+
};
|
|
237
|
+
}
|
|
226
238
|
}
|
|
227
239
|
},
|
|
228
240
|
}),
|
|
229
241
|
createResolver({
|
|
230
242
|
intent: LayoutAction.UpdateLayout,
|
|
231
|
-
filter: (data): data is
|
|
232
|
-
|
|
243
|
+
filter: (data): data is Schema.Schema.Type<typeof LayoutAction.RevertWorkspace.fields.input> =>
|
|
244
|
+
Schema.is(LayoutAction.RevertWorkspace.fields.input)(data),
|
|
233
245
|
resolve: () => {
|
|
234
|
-
const state = context.
|
|
246
|
+
const state = context.getCapability(DeckCapabilities.MutableDeckState);
|
|
235
247
|
return {
|
|
236
248
|
intents: [createIntent(LayoutAction.SwitchWorkspace, { part: 'workspace', subject: state.previousDeck })],
|
|
237
249
|
};
|
|
@@ -239,19 +251,19 @@ export default (context: PluginsContext) =>
|
|
|
239
251
|
}),
|
|
240
252
|
createResolver({
|
|
241
253
|
intent: LayoutAction.UpdateLayout,
|
|
242
|
-
filter: (data): data is
|
|
243
|
-
|
|
254
|
+
filter: (data): data is Schema.Schema.Type<typeof LayoutAction.Open.fields.input> =>
|
|
255
|
+
Schema.is(LayoutAction.Open.fields.input)(data),
|
|
244
256
|
resolve: ({ subject, options }) =>
|
|
245
257
|
Effect.gen(function* () {
|
|
246
|
-
const { graph } = context.
|
|
247
|
-
const state = context.
|
|
248
|
-
const attention = context.
|
|
258
|
+
const { graph } = context.getCapability(Capabilities.AppGraph);
|
|
259
|
+
const state = context.getCapability(DeckCapabilities.MutableDeckState);
|
|
260
|
+
const attention = context.getCapability(AttentionCapabilities.Attention);
|
|
249
261
|
const settings = context
|
|
250
|
-
.
|
|
262
|
+
.getCapabilities(Capabilities.SettingsStore)[0]
|
|
251
263
|
?.getStore<DeckSettingsProps>(DECK_PLUGIN)?.value;
|
|
252
264
|
|
|
253
265
|
if (options?.workspace && state.activeDeck !== options?.workspace) {
|
|
254
|
-
const { dispatch } = context.
|
|
266
|
+
const { dispatch } = context.getCapability(Capabilities.IntentDispatcher);
|
|
255
267
|
yield* dispatch(
|
|
256
268
|
createIntent(LayoutAction.SwitchWorkspace, { part: 'workspace', subject: options.workspace }),
|
|
257
269
|
);
|
|
@@ -285,8 +297,13 @@ export default (context: PluginsContext) =>
|
|
|
285
297
|
: []),
|
|
286
298
|
createIntent(LayoutAction.Expose, { part: 'navigation', subject: newlyOpen[0] ?? subject[0] }),
|
|
287
299
|
...newlyOpen.map((subjectId) => {
|
|
288
|
-
const
|
|
289
|
-
|
|
300
|
+
const typename = Option.match(graph.getNode(subjectId), {
|
|
301
|
+
onNone: () => undefined,
|
|
302
|
+
onSome: (node) => {
|
|
303
|
+
const active = node.data;
|
|
304
|
+
return isLiveObject(active) ? getTypename(active) : undefined;
|
|
305
|
+
},
|
|
306
|
+
});
|
|
290
307
|
return createIntent(ObservabilityAction.SendEvent, {
|
|
291
308
|
name: 'navigation.activate',
|
|
292
309
|
properties: {
|
|
@@ -301,11 +318,11 @@ export default (context: PluginsContext) =>
|
|
|
301
318
|
}),
|
|
302
319
|
createResolver({
|
|
303
320
|
intent: LayoutAction.UpdateLayout,
|
|
304
|
-
filter: (data): data is
|
|
305
|
-
|
|
321
|
+
filter: (data): data is Schema.Schema.Type<typeof LayoutAction.Close.fields.input> =>
|
|
322
|
+
Schema.is(LayoutAction.Close.fields.input)(data),
|
|
306
323
|
resolve: ({ subject }) => {
|
|
307
|
-
const state = context.
|
|
308
|
-
const attention = context.
|
|
324
|
+
const state = context.getCapability(DeckCapabilities.MutableDeckState);
|
|
325
|
+
const attention = context.getCapability(AttentionCapabilities.Attention);
|
|
309
326
|
const active = state.deck.solo ? [state.deck.solo] : state.deck.active;
|
|
310
327
|
const next = subject.reduce((acc, id) => closeEntry(acc, id), active);
|
|
311
328
|
const toAttend = setActive({ next, state, attention });
|
|
@@ -324,11 +341,11 @@ export default (context: PluginsContext) =>
|
|
|
324
341
|
}),
|
|
325
342
|
createResolver({
|
|
326
343
|
intent: LayoutAction.UpdateLayout,
|
|
327
|
-
filter: (data): data is
|
|
328
|
-
|
|
344
|
+
filter: (data): data is Schema.Schema.Type<typeof LayoutAction.Set.fields.input> =>
|
|
345
|
+
Schema.is(LayoutAction.Set.fields.input)(data),
|
|
329
346
|
resolve: ({ subject }) => {
|
|
330
|
-
const state = context.
|
|
331
|
-
const attention = context.
|
|
347
|
+
const state = context.getCapability(DeckCapabilities.MutableDeckState);
|
|
348
|
+
const attention = context.getCapability(AttentionCapabilities.Attention);
|
|
332
349
|
const toAttend = setActive({ next: subject as string[], state, attention });
|
|
333
350
|
return {
|
|
334
351
|
intents: toAttend ? [createIntent(LayoutAction.ScrollIntoView, { part: 'current', subject: toAttend })] : [],
|
|
@@ -337,24 +354,24 @@ export default (context: PluginsContext) =>
|
|
|
337
354
|
}),
|
|
338
355
|
createResolver({
|
|
339
356
|
intent: LayoutAction.UpdateLayout,
|
|
340
|
-
filter: (data): data is
|
|
341
|
-
|
|
357
|
+
filter: (data): data is Schema.Schema.Type<typeof LayoutAction.ScrollIntoView.fields.input> =>
|
|
358
|
+
Schema.is(LayoutAction.ScrollIntoView.fields.input)(data),
|
|
342
359
|
resolve: ({ subject }) => {
|
|
343
|
-
const layout = context.
|
|
360
|
+
const layout = context.getCapability(DeckCapabilities.MutableDeckState);
|
|
344
361
|
layout.scrollIntoView = subject;
|
|
345
362
|
},
|
|
346
363
|
}),
|
|
347
364
|
createResolver({
|
|
348
365
|
intent: DeckAction.UpdatePlankSize,
|
|
349
366
|
resolve: (data) => {
|
|
350
|
-
const state = context.
|
|
367
|
+
const state = context.getCapability(DeckCapabilities.MutableDeckState);
|
|
351
368
|
state.deck.plankSizing[data.id] = data.size;
|
|
352
369
|
},
|
|
353
370
|
}),
|
|
354
371
|
createResolver({
|
|
355
372
|
intent: DeckAction.ChangeCompanion,
|
|
356
373
|
resolve: (data) => {
|
|
357
|
-
const state = context.
|
|
374
|
+
const state = context.getCapability(DeckCapabilities.MutableDeckState);
|
|
358
375
|
// TODO(thure): Reactivity only works when creating a lexically new `activeCompanions`… Are these not proxy objects?
|
|
359
376
|
if (data.companion === null) {
|
|
360
377
|
const { [data.primary]: _, ...nextActiveCompanions } = state.deck.activeCompanions ?? {};
|
|
@@ -371,9 +388,9 @@ export default (context: PluginsContext) =>
|
|
|
371
388
|
createResolver({
|
|
372
389
|
intent: DeckAction.Adjust,
|
|
373
390
|
resolve: (adjustment) => {
|
|
374
|
-
const state = context.
|
|
375
|
-
const attention = context.
|
|
376
|
-
const { graph } = context.
|
|
391
|
+
const state = context.getCapability(DeckCapabilities.MutableDeckState);
|
|
392
|
+
const attention = context.getCapability(AttentionCapabilities.Attention);
|
|
393
|
+
const { graph } = context.getCapability(Capabilities.AppGraph);
|
|
377
394
|
|
|
378
395
|
return batch(() => {
|
|
379
396
|
if (adjustment.type === 'increment-end' || adjustment.type === 'increment-start') {
|
|
@@ -385,20 +402,25 @@ export default (context: PluginsContext) =>
|
|
|
385
402
|
}
|
|
386
403
|
|
|
387
404
|
if (adjustment.type === 'companion') {
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
.
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
405
|
+
return pipe(
|
|
406
|
+
graph.getNode(adjustment.id),
|
|
407
|
+
Option.map((node) =>
|
|
408
|
+
graph
|
|
409
|
+
.getConnections(node.id)
|
|
410
|
+
.filter((n) => n.type === PLANK_COMPANION_TYPE)
|
|
411
|
+
.toSorted((a, b) => byPosition(a.properties, b.properties)),
|
|
412
|
+
),
|
|
413
|
+
Option.flatMap((companions) => (companions.length > 0 ? Option.some(companions[0]) : Option.none())),
|
|
414
|
+
Option.match({
|
|
415
|
+
onNone: () => ({}),
|
|
416
|
+
onSome: (companion) => ({
|
|
417
|
+
intents: [
|
|
418
|
+
// TODO(wittjosiah): This should remember the previously selected companion.
|
|
419
|
+
createIntent(DeckAction.ChangeCompanion, { primary: adjustment.id, companion: companion.id }),
|
|
420
|
+
],
|
|
421
|
+
}),
|
|
422
|
+
}),
|
|
423
|
+
);
|
|
402
424
|
}
|
|
403
425
|
|
|
404
426
|
if (adjustment.type.startsWith('solo')) {
|
|
@@ -11,9 +11,9 @@ import { DeckSettingsSchema, type DeckSettingsProps } from '../types';
|
|
|
11
11
|
export default () => {
|
|
12
12
|
const settings = live<DeckSettingsProps>({
|
|
13
13
|
showHints: false,
|
|
14
|
-
enableDeck:
|
|
15
|
-
enableNativeRedirect: false,
|
|
14
|
+
enableDeck: false,
|
|
16
15
|
enableStatusbar: false,
|
|
16
|
+
enableNativeRedirect: false,
|
|
17
17
|
newPlankPositioning: 'start',
|
|
18
18
|
overscroll: 'none',
|
|
19
19
|
});
|
|
@@ -10,7 +10,7 @@ import { type SidebarState } from '@dxos/react-ui';
|
|
|
10
10
|
|
|
11
11
|
import { DeckCapabilities } from './capabilities';
|
|
12
12
|
import { DECK_PLUGIN } from '../meta';
|
|
13
|
-
import { getMode, type
|
|
13
|
+
import { getMode, type DeckPluginState, defaultDeck, type DeckState } from '../types';
|
|
14
14
|
|
|
15
15
|
const boolean = /true|false/;
|
|
16
16
|
|
|
@@ -29,7 +29,7 @@ const migrateSidebarState = () => {
|
|
|
29
29
|
});
|
|
30
30
|
};
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
const DeckStateFactory = () => {
|
|
33
33
|
migrateSidebarState();
|
|
34
34
|
|
|
35
35
|
const state = new LocalStorageStore<DeckPluginState>(DECK_PLUGIN, {
|
|
@@ -100,3 +100,5 @@ export default () => {
|
|
|
100
100
|
contributes(Capabilities.Layout, layout),
|
|
101
101
|
];
|
|
102
102
|
};
|
|
103
|
+
|
|
104
|
+
export default DeckStateFactory;
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { Schema } from 'effect';
|
|
6
|
+
|
|
7
|
+
import { createTool, ToolResult } from '@dxos/ai';
|
|
5
8
|
import {
|
|
6
9
|
contributes,
|
|
7
10
|
createIntent,
|
|
@@ -9,8 +12,6 @@ import {
|
|
|
9
12
|
LayoutAction,
|
|
10
13
|
type PromiseIntentDispatcher,
|
|
11
14
|
} from '@dxos/app-framework';
|
|
12
|
-
import { defineTool, ToolResult } from '@dxos/artifact';
|
|
13
|
-
import { S } from '@dxos/echo-schema';
|
|
14
15
|
import { invariant } from '@dxos/invariant';
|
|
15
16
|
|
|
16
17
|
import { meta } from '../meta';
|
|
@@ -27,7 +28,7 @@ declare global {
|
|
|
27
28
|
|
|
28
29
|
export default () =>
|
|
29
30
|
contributes(Capabilities.Tools, [
|
|
30
|
-
|
|
31
|
+
createTool(meta.id, {
|
|
31
32
|
name: 'show',
|
|
32
33
|
description: `
|
|
33
34
|
Show an item as a companion to an existing plank. This will make the item appear alongside the primary content.
|
|
@@ -35,19 +36,21 @@ export default () =>
|
|
|
35
36
|
`,
|
|
36
37
|
caption: 'Showing item...',
|
|
37
38
|
// TODO(wittjosiah): Refactor Layout/Navigation/Deck actions so that they can be used directly.
|
|
38
|
-
schema:
|
|
39
|
-
id:
|
|
39
|
+
schema: Schema.Struct({
|
|
40
|
+
id: Schema.String.annotations({
|
|
40
41
|
description: 'The ID of the item to show.',
|
|
41
42
|
}),
|
|
42
43
|
}),
|
|
43
44
|
execute: async ({ id }, { extensions }) => {
|
|
44
|
-
invariant(extensions
|
|
45
|
-
|
|
45
|
+
invariant(extensions);
|
|
46
|
+
const { pivotId, dispatch, part } = extensions;
|
|
47
|
+
invariant(pivotId, 'No pivot ID');
|
|
48
|
+
invariant(dispatch, 'No intent dispatcher');
|
|
46
49
|
|
|
47
|
-
if (
|
|
48
|
-
const { data, error } = await
|
|
50
|
+
if (part === 'deck') {
|
|
51
|
+
const { data, error } = await dispatch(
|
|
49
52
|
createIntent(DeckAction.ChangeCompanion, {
|
|
50
|
-
primary:
|
|
53
|
+
primary: pivotId,
|
|
51
54
|
companion: id,
|
|
52
55
|
}),
|
|
53
56
|
);
|
|
@@ -57,12 +60,12 @@ export default () =>
|
|
|
57
60
|
|
|
58
61
|
return ToolResult.Success(data);
|
|
59
62
|
} else {
|
|
60
|
-
const { data, error } = await
|
|
63
|
+
const { data, error } = await dispatch(
|
|
61
64
|
createIntent(LayoutAction.Open, {
|
|
62
65
|
subject: [id],
|
|
63
66
|
part: 'main',
|
|
64
67
|
options: {
|
|
65
|
-
pivotId
|
|
68
|
+
pivotId,
|
|
66
69
|
positioning: 'end',
|
|
67
70
|
},
|
|
68
71
|
}),
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { Capabilities, contributes, createIntent, LayoutAction, type
|
|
5
|
+
import { Capabilities, contributes, createIntent, LayoutAction, type PluginContext } from '@dxos/app-framework';
|
|
6
6
|
import { scheduledEffect } from '@dxos/echo-signals/core';
|
|
7
7
|
|
|
8
8
|
import { DeckCapabilities } from './capabilities';
|
|
9
9
|
import { defaultDeck } from '../types';
|
|
10
10
|
|
|
11
11
|
// TODO(wittjosiah): Cleanup the url handling. May justify introducing routing capabilities.
|
|
12
|
-
export default async (context:
|
|
13
|
-
const { dispatchPromise: dispatch } = context.
|
|
14
|
-
const state = context.
|
|
12
|
+
export default async (context: PluginContext) => {
|
|
13
|
+
const { dispatchPromise: dispatch } = context.getCapability(Capabilities.IntentDispatcher);
|
|
14
|
+
const state = context.getCapability(DeckCapabilities.MutableDeckState);
|
|
15
15
|
|
|
16
16
|
const handleNavigation = async () => {
|
|
17
17
|
const pathname = window.location.pathname;
|
|
@@ -7,8 +7,9 @@ import React from 'react';
|
|
|
7
7
|
import { Surface, useCapability } from '@dxos/app-framework';
|
|
8
8
|
|
|
9
9
|
import { DeckCapabilities } from '../../capabilities';
|
|
10
|
+
import { useBreakpoints } from '../../hooks';
|
|
10
11
|
import { getMode } from '../../types';
|
|
11
|
-
import { layoutAppliesTopbar
|
|
12
|
+
import { layoutAppliesTopbar } from '../../util';
|
|
12
13
|
import { ToggleSidebarButton } from '../Sidebar';
|
|
13
14
|
import { fixedSidebarToggleStyles } from '../fragments';
|
|
14
15
|
|
|
@@ -20,7 +21,7 @@ export const ContentEmpty = () => {
|
|
|
20
21
|
return (
|
|
21
22
|
<div
|
|
22
23
|
role='none'
|
|
23
|
-
className='grid place-items-center p-8 relative bg-
|
|
24
|
+
className='grid place-items-center p-8 relative bg-deckSurface'
|
|
24
25
|
data-testid='layoutPlugin.firstRunMessage'
|
|
25
26
|
>
|
|
26
27
|
<Surface role='keyshortcuts' />
|
|
@@ -26,9 +26,10 @@ import { StatusBar } from './StatusBar';
|
|
|
26
26
|
import { Toast } from './Toast';
|
|
27
27
|
import { Topbar } from './Topbar';
|
|
28
28
|
import { DeckCapabilities } from '../../capabilities';
|
|
29
|
+
import { useBreakpoints, useHoistStatusbar } from '../../hooks';
|
|
29
30
|
import { DECK_PLUGIN } from '../../meta';
|
|
30
31
|
import { type DeckSettingsProps, getMode } from '../../types';
|
|
31
|
-
import { calculateOverscroll, layoutAppliesTopbar
|
|
32
|
+
import { calculateOverscroll, layoutAppliesTopbar } from '../../util';
|
|
32
33
|
import { Plank } from '../Plank';
|
|
33
34
|
import { ComplementarySidebar, Sidebar, ToggleComplementarySidebarButton, ToggleSidebarButton } from '../Sidebar';
|
|
34
35
|
import { fixedComplementarySidebarToggleStyles, fixedSidebarToggleStyles } from '../fragments';
|
|
@@ -38,7 +39,7 @@ export type DeckLayoutProps = {
|
|
|
38
39
|
};
|
|
39
40
|
|
|
40
41
|
const PlankSeparator = ({ order }: { order: number }) =>
|
|
41
|
-
order > 0 ? <span role='separator' className='row-span-2 bg-
|
|
42
|
+
order > 0 ? <span role='separator' className='row-span-2 bg-deckSurface is-4' style={{ gridColumn: order }} /> : null;
|
|
42
43
|
|
|
43
44
|
export const DeckLayout = ({ onDismissToast }: DeckLayoutProps) => {
|
|
44
45
|
const { dispatchPromise: dispatch } = useIntentDispatcher();
|
|
@@ -59,7 +60,7 @@ export const DeckLayout = ({ onDismissToast }: DeckLayoutProps) => {
|
|
|
59
60
|
useEffect(() => {
|
|
60
61
|
// NOTE: Not `useAttended` so that the layout component is not re-rendered when the attended list changes.
|
|
61
62
|
const attended = untracked(() => {
|
|
62
|
-
const attention = pluginManager.context.
|
|
63
|
+
const attention = pluginManager.context.getCapability(AttentionCapabilities.Attention);
|
|
63
64
|
return attention.current;
|
|
64
65
|
});
|
|
65
66
|
const firstId = solo ?? active[0];
|
|
@@ -78,7 +79,7 @@ export const DeckLayout = ({ onDismissToast }: DeckLayoutProps) => {
|
|
|
78
79
|
if (!isNotMobile && getMode(deck) === 'deck') {
|
|
79
80
|
// NOTE: Not `useAttended` so that the layout component is not re-rendered when the attended list changes.
|
|
80
81
|
const attended = untracked(() => {
|
|
81
|
-
const attention = pluginManager.context.
|
|
82
|
+
const attention = pluginManager.context.getCapability(AttentionCapabilities.Attention);
|
|
82
83
|
return attention.current;
|
|
83
84
|
});
|
|
84
85
|
|
|
@@ -91,14 +92,15 @@ export const DeckLayout = ({ onDismissToast }: DeckLayoutProps) => {
|
|
|
91
92
|
}
|
|
92
93
|
}, [isNotMobile, deck, dispatch]);
|
|
93
94
|
|
|
94
|
-
//
|
|
95
|
+
// When deck is disabled in settings, set to solo mode if the current layout mode is deck.
|
|
96
|
+
// TODO(thure): Applying this as an effect should be avoided over emitting the intent only when the setting changes.
|
|
95
97
|
useEffect(() => {
|
|
96
|
-
if (!settings.enableDeck) {
|
|
98
|
+
if (!settings.enableDeck && layoutMode === 'deck') {
|
|
97
99
|
void dispatch(
|
|
98
100
|
createIntent(LayoutAction.SetLayoutMode, { part: 'mode', subject: active[0], options: { mode: 'solo' } }),
|
|
99
101
|
);
|
|
100
102
|
}
|
|
101
|
-
}, [settings.enableDeck, dispatch, active]);
|
|
103
|
+
}, [settings.enableDeck, dispatch, active, layoutMode]);
|
|
102
104
|
|
|
103
105
|
/**
|
|
104
106
|
* Clear scroll restoration state if the window is resized
|
|
@@ -190,8 +192,8 @@ export const DeckLayout = ({ onDismissToast }: DeckLayoutProps) => {
|
|
|
190
192
|
{!isEmpty && (
|
|
191
193
|
<Main.Content
|
|
192
194
|
bounce
|
|
193
|
-
classNames={mainPosition}
|
|
194
195
|
handlesFocus
|
|
196
|
+
classNames={mainPosition}
|
|
195
197
|
style={
|
|
196
198
|
{
|
|
197
199
|
'--dx-main-sidebarWidth':
|
|
@@ -213,7 +215,7 @@ export const DeckLayout = ({ onDismissToast }: DeckLayoutProps) => {
|
|
|
213
215
|
>
|
|
214
216
|
<div
|
|
215
217
|
role='none'
|
|
216
|
-
className={!solo ? 'relative bg-
|
|
218
|
+
className={!solo ? 'relative bg-deckSurface overflow-hidden' : 'sr-only'}
|
|
217
219
|
{...(solo && { inert: '' })}
|
|
218
220
|
>
|
|
219
221
|
{!topbar && !fullscreen && <ToggleSidebarButton classNames={fixedSidebarToggleStyles} />}
|
|
@@ -247,7 +249,7 @@ export const DeckLayout = ({ onDismissToast }: DeckLayoutProps) => {
|
|
|
247
249
|
</div>
|
|
248
250
|
<div
|
|
249
251
|
role='none'
|
|
250
|
-
className={solo ? 'relative bg-
|
|
252
|
+
className={solo ? 'relative bg-deckSurface overflow-hidden' : 'sr-only'}
|
|
251
253
|
{...(!solo && { inert: '' })}
|
|
252
254
|
>
|
|
253
255
|
{!topbar && !fullscreen && <ToggleSidebarButton classNames={fixedSidebarToggleStyles} />}
|
|
@@ -12,7 +12,7 @@ import { PlankContentError } from '../Plank';
|
|
|
12
12
|
|
|
13
13
|
export const Dialog = () => {
|
|
14
14
|
const context = useCapability(DeckCapabilities.MutableDeckState);
|
|
15
|
-
const { dialogType, dialogBlockAlign,
|
|
15
|
+
const { dialogOpen, dialogType, dialogBlockAlign, dialogOverlayClasses, dialogOverlayStyle, dialogContent } = context;
|
|
16
16
|
const Root = dialogType === 'alert' ? AlertDialog.Root : NaturalDialog.Root;
|
|
17
17
|
const Overlay = dialogType === 'alert' ? AlertDialog.Overlay : NaturalDialog.Overlay;
|
|
18
18
|
|
|
@@ -27,7 +27,7 @@ export const Dialog = () => {
|
|
|
27
27
|
// TODO(burdon): Placeholder creates a suspense boundary; replace with defaults.
|
|
28
28
|
<Surface role='dialog' data={dialogContent} limit={1} fallback={PlankContentError} placeholder={<div />} />
|
|
29
29
|
) : (
|
|
30
|
-
<Overlay blockAlign={dialogBlockAlign}>
|
|
30
|
+
<Overlay blockAlign={dialogBlockAlign} classNames={dialogOverlayClasses} style={dialogOverlayStyle}>
|
|
31
31
|
<Surface role='dialog' data={dialogContent} limit={1} fallback={PlankContentError} />
|
|
32
32
|
</Overlay>
|
|
33
33
|
)}
|