Files
platform/src/apps/officer-web/Screens/Dashboard/Plugins/defaultLayout.ts
T
pastilhasandClaude Opus 5 d58f58813c the marketplace is browsed by tag, not scrolled
/marketplace was a list of every plugin on the left and a preview on the right.
that is a fine control panel and a poor shop: twenty-one rows sorted by nothing
anybody cares about, where "something for my calendar" means reading all of them.

now: tags down the left with counts, cards in a grid on the right, and clicking
a card takes over the panel with a back link. three things about the shape.

BOTH the filter and the selection are in the URL — ?tag= and ?selected=. a
filter in component state is lost on Back, so filtering, opening a plugin and
pressing Back would drop you in an unfiltered grid having lost your place.
browser Back works for free for the same reason. selecting a tag also CLEARS the
selection, because a detail for a plugin outside the new filter is a page the
grid you are now looking at cannot return to.

the detail REPLACES the grid rather than sitting beside it. a grid needs the
width and a detail beside one gets half of it; neither reads well. the back link
drops ?selected= and keeps ?tag=, which is the entire point of putting the
filter there.

the panel KEYS are unchanged though both components were replaced. a stored
layout names them, and renaming would drop everyone back to the default
arrangement for nothing — the key identifies a slot, not an implementation.

two things found on the way. PluginItem and AvailablePlugin had no tags, so the
api now carries them on both branches — from the manifest for a plugin that is
here, from the catalogue for one that is not, same field either way. and the
screen used useDashboardState, which persists the whole tree: the panels this
ships would never have reached anyone who had opened it before. useAuthoredLayout
takes the structure from source and persists only sizes, which is what an
authored screen wants.

21/22 -> 22/78 as well: the left panel holds seven tags now, not twenty-one
rows, and the width is worth more to the grid.

verified: bundle contains the new panels, api returns tags for all 21 with none
missing the field.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Officer-Session: 656f5c85-e49a-4f1f-b9f3-042a04b4d043
2026-08-27 07:32:05 +00:00

17 lines
846 B
TypeScript

import type { LayoutNode } from 'officerdev';
// List left, detail right — a master list with a live preview, which is why the selection is `?selected=`
// rather than a `/plugins/:appName` route: linking rows to the detail route would make it the whole page
// and destroy the side-by-side. See docs/navigation-audit.md.
export const defaultLayout: LayoutNode = {
type: 'group',
id: 'plugins-root',
direction: 'horizontal',
children: [
// 22/78, not 32/68. The left panel was a list of every plugin and needed the room; it is a list of
// seven tags now, and the grid on the right is what benefits from the width — one more card per row.
{ node: { type: 'panel', id: 'plugins-list', appType: 'plugins-list' }, size: 22 },
{ node: { type: 'panel', id: 'plugin-detail', appType: 'plugin-detail' }, size: 78 },
],
};