From ca046a3876a59455c04ffc9941fd7c33355146fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Padez?= Date: Fri, 7 Aug 2026 09:42:25 +0000 Subject: [PATCH] build the inert context once instead of twice MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `WorkspaceLayout` and the `createContext` default each spelled out the same eleven fields — every interaction a panel can start, switched off. Two hand-written copies of one list is a list you fall behind: adding a field to the context type only errors at the call site if it is required, and both copies have to be found. Named it. `inertInteraction` is what "this tree cannot be rearranged" means, and both places spread it. `cwd` and `root` stay out of it deliberately — they say where the workspace is rather than what can be done to it, and the inert renderer has no answer for `root`: its consumers only read it when `cwd` is scoped, which no caller makes it. --- .../components/Workspace/WorkspaceContext.ts | 23 +++++++++++++++---- .../components/Workspace/WorkspaceLayout.tsx | 4 ++-- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/workspaces/officerdev/src/components/Workspace/WorkspaceContext.ts b/src/workspaces/officerdev/src/components/Workspace/WorkspaceContext.ts index 86de39ca..93de7ac8 100644 --- a/src/workspaces/officerdev/src/components/Workspace/WorkspaceContext.ts +++ b/src/workspaces/officerdev/src/components/Workspace/WorkspaceContext.ts @@ -29,10 +29,18 @@ type WorkspaceContextValue = { const noop = () => {}; -const WorkspaceContext = createContext({ - workspace: null, - cwd: '~', - panelConfigs: {}, +/** + * The interaction half of the context, switched off — every field a panel uses to rearrange the + * workspace, plus the state those interactions run on. `WorkspaceLayout` renders a tree nobody can + * rearrange (job detail panes, settings, dashboard previews), and it used to say so by repeating + * eleven fields at the call site, which is a list you can silently fall behind: add a field to the + * context and only one of the two providers gets it. + * + * `root` and `cwd` are deliberately not in here. They are facts about where the workspace *is*, not + * interactions, and the inert renderer has no answer for them — its consumers only read `root` when + * `cwd` is scoped, which it never is there. + */ +export const inertInteraction = { setPanelConfig: noop, swapSourceId: null, setSwapSourceId: noop, @@ -44,6 +52,13 @@ const WorkspaceContext = createContext({ maximizedPanelId: null, setMaximizedPanelId: noop, transitioningPanelId: null, +} satisfies Partial; + +const WorkspaceContext = createContext({ + workspace: null, + cwd: '~', + panelConfigs: {}, + ...inertInteraction, isMobile: false, onMobileBack: null, }); diff --git a/src/workspaces/officerdev/src/components/Workspace/WorkspaceLayout.tsx b/src/workspaces/officerdev/src/components/Workspace/WorkspaceLayout.tsx index 4ed3980d..58e6c5d8 100644 --- a/src/workspaces/officerdev/src/components/Workspace/WorkspaceLayout.tsx +++ b/src/workspaces/officerdev/src/components/Workspace/WorkspaceLayout.tsx @@ -1,7 +1,7 @@ import { useCallback } from 'react'; import type { LayoutNode, AppRegistryMap, PanelComponents } from './types'; import { updateSizes, collectPanelConfigs } from './layout-utils'; -import { WorkspaceProvider } from './WorkspaceContext'; +import { WorkspaceProvider, inertInteraction } from './WorkspaceContext'; import { WorkspaceRenderer } from './WorkspaceRenderer'; import { useAppRegistry } from '../../AppRegistry/useAppRegistry'; @@ -36,7 +36,7 @@ export const WorkspaceLayout = ({ layout, onLayoutChange, registry: registryProp // dashboard previews. It is not a dashboard and not a screen, and a panel that asks should be told so // rather than handed something that parses. return ( - +