build the inert context once instead of twice
`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.
This commit is contained in:
@@ -29,10 +29,18 @@ type WorkspaceContextValue = {
|
||||
|
||||
const noop = () => {};
|
||||
|
||||
const WorkspaceContext = createContext<WorkspaceContextValue>({
|
||||
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<WorkspaceContextValue>({
|
||||
maximizedPanelId: null,
|
||||
setMaximizedPanelId: noop,
|
||||
transitioningPanelId: null,
|
||||
} satisfies Partial<WorkspaceContextValue>;
|
||||
|
||||
const WorkspaceContext = createContext<WorkspaceContextValue>({
|
||||
workspace: null,
|
||||
cwd: '~',
|
||||
panelConfigs: {},
|
||||
...inertInteraction,
|
||||
isMobile: false,
|
||||
onMobileBack: null,
|
||||
});
|
||||
|
||||
@@ -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 (
|
||||
<WorkspaceProvider value={{ workspace: null, cwd: cwd ?? '~', panelConfigs: collectPanelConfigs(layout), setPanelConfig: noop, swapSourceId: null, setSwapSourceId: noop, onSwap: noop, dragSourceId: null, setDragSourceId: noop, onMove: noop, onSetZoom: noop, maximizedPanelId: null, setMaximizedPanelId: noop, transitioningPanelId: null, isMobile: isMobile ?? false, onMobileBack: onMobileBack ?? null }}>
|
||||
<WorkspaceProvider value={{ workspace: null, cwd: cwd ?? '~', panelConfigs: collectPanelConfigs(layout), ...inertInteraction, isMobile: isMobile ?? false, onMobileBack: onMobileBack ?? null }}>
|
||||
<WorkspaceRenderer
|
||||
layout={layout}
|
||||
registry={registry}
|
||||
|
||||
Reference in New Issue
Block a user