diff --git a/src/apps/officer-web/App.tsx b/src/apps/officer-web/App.tsx index 3c0bd7cf..364ee675 100644 --- a/src/apps/officer-web/App.tsx +++ b/src/apps/officer-web/App.tsx @@ -101,24 +101,31 @@ export function App() { {/* One route per SCREEN, not per plugin — `screenId` is the key, because a plugin with two screens (caldav: Calendar and Contacts) contributes two entries sharing one `appName`. */} {/* - A SPLAT, so the whole subtree is the plugin's. + Three routes, and the third is the only new one. - It was a pair — the bare route and `/:section` — which gave a plugin exactly one segment and - made the platform the author of what it meant. Anything deeper had to go in the query - string, and `/fofos-admin/layout/header` was not expressible at all. + `/` and `//:section` are what every plugin has always had, and fifteen of + them read `useParams().section`. A splat ALONE replaced that for a day and took the + parameter away from all of them at once — the screens still mounted and every one of them + lost its selection, which is a worse failure than a 404 because nothing says so. - A splat matches zero segments too, so this is one route where there were two, and the - plugin reads its own position off the location. Routing inside a plugin is the plugin's, - which is the same line `mountPrefix` already draws around its API: the platform owns where - a plugin STARTS and nothing after it. + The splat is added for depth rather than instead of them: `/fofos-admin/layout/header` was + not expressible before, and a plugin that wants its own subtree reads the location. + React-router ranks a static or dynamic segment above a splat, so a plugin with one segment + still gets `section` and only deeper paths fall through. */} - {installedPlugins.map((plugin) => ( + {installedPlugins.flatMap((plugin) => [ + } />, } + />, + } - /> - ))} + />, + ])} } /> } /> {/* TEMPORARY / EXPERIMENTAL — offline file transfer over animated QR codes */}