Files
platform/src/apps/officer-web/Screens/Dashboard/CommandHQ/defaultLayout.ts
T
pastilhasandClaude Opus 5 430f058a6d command hq: two columns, with the navigation stacked
It was 16 / 34 / 50 — a category column, a commander column, and the transcript. So half the screen was
navigation for a list holding a handful of commanders (one, on this machine) while the only thing anybody
reads got the other half.

Now the two navigation panels are stacked into one 24% column — commanders on top, categories beneath — and
the transcript takes 76%.

Categories BELOW the commanders, not above: the commanders are what you came for and the categories are how
you narrow them. Above, the filter would push the list down the screen and be read first; below, the list is
at the top where a list belongs, and the categories can grow their own scrollbar without taking room from it.

The categories panel lost seventy pixels of branding — a Radar tile, "Command HQ", "Watchers &
long-running jobs" — which made sense when it owned a column and does not now that it sits at the foot of
one. The screen's own header says Command HQ two inches above it.

`All commanders` and `Uncategorised` moved INTO the scroll box with the categories. They are the same kind of
thing, a filter over the list, and splitting them into a separate nav block above made the second look like a
different mechanism. The heading and the + button stay pinned; only the list scrolls — the same rule as the
theme dropdown.

MIGRATION, and it is the part that could have gone wrong. This key is persisted per account, so the default
alone moves nobody who has opened the screen. No appType was retired either, so `hasAppType` cannot see it
the way the /chat migration could — the test is structural instead: a horizontal root with three children is
the old shape. It terminates because the replacement has two, and replacing outright is safe on a `locked`
screen where the only user contribution is column sizes. Same reasoning, and same trap, as
ChatHistory/index.tsx.

Two of my edits silently did nothing first, because I searched for `officerdb` where the module is
`officerdev` and used replace without an assertion. Both are asserted now.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 15:38:41 +00:00

61 lines
2.7 KiB
TypeScript

import type { LayoutNode } from 'officerdev';
/*
Two columns, with the navigation stacked into the left one.
── Why it changed from three ──
It was `16 / 34 / 50`: a category column, a commander column, and the transcript. So half the screen was
navigation for a list that holds a handful of commanders — one, on the machine this was written on — while
the only thing anybody reads got the other half. A category pane of its own is a filter for a list short
enough to see whole.
Now: commanders on top, categories beneath them, transcript taking three quarters.
── Why the categories are BELOW the commanders ──
Because the commanders are the thing you came for and the categories are how you narrow them when there
are too many to scan. Above, the filter would push the list down the screen and be the first thing read;
below, the list is at the top where a list belongs and the filter is where you reach for it. It also means
the categories can grow their own scrollbar without ever taking room from the commanders.
*/
export const defaultLayout: LayoutNode = {
type: 'group',
id: 'command-hq-root',
direction: 'horizontal',
children: [
{
node: {
type: 'group',
id: 'command-hq-nav',
direction: 'vertical',
children: [
{ node: { type: 'panel', id: 'command-hq-grid', appType: 'command-hq-grid' }, size: 62 },
{ node: { type: 'panel', id: 'command-hq-categories', appType: 'command-hq-categories' }, size: 38 },
],
},
size: 24,
},
{ node: { type: 'panel', id: 'command-hq-detail', appType: 'command-hq-detail' }, size: 76 },
],
};
/**
* Is this a saved copy of the three-column layout this replaced?
*
* No appType was retired — all three panels survive and only their arrangement changed — so `hasAppType`
* cannot see this the way the /chat migration could. The test is structural instead: the old shape is a
* horizontal root with THREE children, and the new one has two.
*
* It terminates for that reason: the replacement does not satisfy the test.
*
* Replacing outright is safe because the screen is `locked` — its structure is dictated by code, and the
* only thing a person can have contributed is the column sizes, which is a cheap thing to lose once. The
* same reasoning, and the same warning, as `ChatHistory/index.tsx`: get the test backwards and a stranded
* panel collapses onto `appTypes.fallback` and is written back, which is how /offscale once rendered three
* copies of one picker.
*/
export function isLegacyThreeColumn(node: LayoutNode): boolean {
return node.type === 'group' && node.direction === 'horizontal' && node.children.length === 3;
}