diff --git a/docs/workspace-panel-todo.md b/docs/workspace-panel-todo.md index d8e11d76..7780e60a 100644 --- a/docs/workspace-panel-todo.md +++ b/docs/workspace-panel-todo.md @@ -32,8 +32,10 @@ before deciding what to pick up next. Its conclusions in one paragraph: identity, the app-config fields are deleted or moved onto the app, and the inert context is built once. **§5.1's first two items are closed too** (`04371a9`, `198dc71`, `c92b51c`) — panels have a close signal that fires on a real close and on nothing else, and the terminals use it; the chat panel - deliberately does not, which is the inversion above. Tier B is now the pty backstop (the third item of - §5.1), `normalizeLayout` (§5.4) and the mobile decision (§6). + deliberately does not, which is the inversion above. **§5.4's first item is closed** (`1de1d92`) — the + allow-list is a `WorkspaceView` prop and the fourteen copies are gone. Tier B is now the pty backstop + (the third item of §5.1), the default-layout collapse (the second item of §5.4) and the mobile + decision (§6). - **Tier C, orthogonal:** everything else — including **§5.2 (remounts) and §5.3 (drag-to-move), both large downgrades.** A panel is now a pointer to a server-side session, so a remount costs a replay, and the drag hazard is disarmed by resolving identity by name (`e588524` + `bc82086`). @@ -384,7 +386,21 @@ the whole table: ### 5.4 Make `normalizeLayout` framework, not convention -- [ ] **One `makeLayoutNormalizer(allowed, fallback)` applied inside `WorkspaceView`.** +- [x] **One normaliser applied inside `WorkspaceView`.** _(`1de1d92`)_ — it landed as a prop rather + than a factory: ``, with `normalizeLayout` in + `layout-utils.ts` and the persist-back inside `WorkspaceView`. All fourteen copies are deleted; + QrTransfer gained the persist-back it never had. Two notes for whoever reads this next. The + framework normaliser **drops `config`** when it replaces an app — the copies kept it, which left + the old app's config on a panel the new app now owns, the opposite of `setApp`. And Headscale + keeps a local `useMemo`, because its check is "is the server picker present at all", which is + about a panel being _missing_ and no allow-list can see that. + Still open from this item: deriving the allow-lists from the AppRegistry (they are still + hand-written literals, so a type still allow-listed but deleted from the registry passes and + reaches the unrecoverable empty box at `PanelSlot.tsx:311-317`), and the nine locked screens + that still pass no `appTypes` at all — now a one-line fix each rather than fifty. + The original text follows. + + **One `makeLayoutNormalizer(allowed, fallback)` applied inside `WorkspaceView`.** The guard currently exists **14 times, character-identical except for the allow-list and the fallback**, plus a matching `useMemo`/persist-back `useEffect` pair 13 times — ~150 duplicated lines. Consequences of it being convention: - **10 `WorkspaceView` consumers have no guard at all**, including `screens/HomeScreen.tsx:11`, @@ -635,6 +651,13 @@ Cheap to fix, and prerequisites for the 5.8 migration rather than alternatives t _(move items here with the commit and a one-line resolution)_ +- [x] **The appType allow-list is a prop, not a convention.** _(`1de1d92`, branch + `agent-coordination-mvp`)_ — closes the first item of §5.4. Fourteen character-identical + normalisers, each with its `useMemo` and persist-back `useEffect`, collapse to + `appTypes={{ allowed, fallback }}`. 402 lines deleted for 215 added, most of the additions being + the seven tests that pin the normaliser — including idempotence, because a normaliser that does + not normalise to itself turns the persist-back into an infinite write loop. + - [x] **Panels can carry per-panel settings, and keep them through a move.** _(`e588524`, branch `agent-coordination-mvp`)_ — `LayoutPanel.config`, opaque to the framework, exposed as `usePanelConfig(panelId)`. The substantive half is in `layout-utils.ts`: `swapPanels` and