/app-store, built to the platform's own conventions: a locked WorkspaceView with two panels, the selection in `?selected=` rather than a channel, and rows that are real links so cmd-click and a pasted URL both work. `?selected=` and not a /app-store/:id detail route, per docs/navigation-audit.md: this is a master list with a live preview, and linking rows to a detail route would make the detail the whole page and destroy the side-by-side. Both panels read the URL independently — the list and the detail cannot disagree if neither is telling the other anything. The install form is generated from the catalogue's fields rather than written per service, which is what lets a sidecar shipping from its own repository present a form nobody here wrote. `existing` is first in `modes` by catalogue rule, so the default selection is "I already have one" — the answer that avoids starting a second copy of something already running. States are distinguished rather than flattened. Blocked is amber and titled "Needs you", not an error: everything worked and it is waiting for a token only a person can mint. Installed-and-enabled but with a dead process shows a warning rather than a tick that lies. And the disable/uninstall copy says plainly that data, configuration and tables are kept either way, because that is the question anyone hesitates over before clicking. The dock tile is CORE, not plugin-derived: the store is how every other feature arrives, so it must never be one of the things that disappears. Verified through the API the screen uses — 14 items, email reporting installed/enabled with its process online, and /app-store present in the capability routes so the tile renders. NOT verified in a browser: no page has been opened, so the rendering itself is reasoned rather than seen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
15 lines
653 B
TypeScript
15 lines
653 B
TypeScript
import type { LayoutNode } from 'officerdev';
|
|
|
|
// List on the left, detail on the right — a master list with a live preview, which is why the selection
|
|
// is `?selected=` rather than a detail route: linking rows to /app-store/:id would make the detail the
|
|
// whole page and destroy the side-by-side. See docs/navigation-audit.md.
|
|
export const defaultLayout: LayoutNode = {
|
|
type: 'group',
|
|
id: 'app-store-root',
|
|
direction: 'horizontal',
|
|
children: [
|
|
{ node: { type: 'panel', id: 'app-store-list', appType: 'app-store-list' }, size: 30 },
|
|
{ node: { type: 'panel', id: 'app-store-detail', appType: 'app-store-detail' }, size: 70 },
|
|
],
|
|
};
|