diff --git a/manifest.ts b/manifest.ts index 812148d..2e2e1e9 100644 --- a/manifest.ts +++ b/manifest.ts @@ -35,7 +35,7 @@ import type { PluginManifest } from '@@/plugins/manifest'; */ export const manifest: PluginManifest = { publisher: 'officerdev', - version: '2026.08.29.01', + version: '2026.08.29.02', platform: '>=1.0.0', label: 'Fofos', diff --git a/web/DetailPanel.tsx b/web/DetailPanel.tsx index b2e8d75..23f4ac1 100644 --- a/web/DetailPanel.tsx +++ b/web/DetailPanel.tsx @@ -1,6 +1,5 @@ import { useCallback, useEffect, useRef, useState } from 'react'; -import { Link, useSearchParams } from 'react-router'; -import { Settings } from 'lucide-react'; +import { useSearchParams } from 'react-router'; import { useClient } from 'hooks/useClient'; import { DEFAULT_SECTION, isSectionKey, sectionFor, type SectionKey } from './sections'; import { ConnectionPanel } from './ConnectionPanel'; @@ -12,15 +11,21 @@ import { useFofosChanged } from './channel'; * The right column: whichever section the nav has selected. * * It reads `?section=` from the URL rather than being handed it — the two panels are siblings in a - * workspace and neither owns the other. `?config=1` renders the connection form over the top of - * whatever is selected, so settings are addressable too. + * workspace and neither owns the other. + * + * ── There used to be a `?config=1` ── + * + * The connection form was an overlay reached from a link in this header, because it was not one of the + * sections. Now it IS one — Administration — so the overlay is gone and so is the link. A second route + * to the same screen is a second thing to keep correct, and the two disagreed the moment a section was + * selected underneath a form that covered it. * * ── The unconfigured check lives HERE, once ── * - * Every section needs a connection, so every section would otherwise have to handle its absence and - * each would word it slightly differently. Asking `/status` once and rendering the connection form - * instead of any section is one answer for all nine, and it makes "not connected yet" read as a setup - * step rather than as nine broken lists. + * Every OTHER section needs a connection, so each would otherwise have to handle its absence and each + * would word it slightly differently. Asking `/status` once and sending an unconfigured plugin to + * Administration is one answer for all of them, and it makes "not connected yet" read as a setup step + * rather than as nine broken lists. */ type Status = { configured: boolean; lastProbeOk: boolean | null }; @@ -37,13 +42,13 @@ type Status = { configured: boolean; lastProbeOk: boolean | null }; */ const PANELS: Partial React.JSX.Element>> = { messages: MessagesPanel, + administration: ConnectionPanel, }; export const DetailPanel = () => { const [params] = useSearchParams(); const raw = params.get('section'); - const section: SectionKey = isSectionKey(raw) ? raw : DEFAULT_SECTION; - const showingConfig = params.get('config') === '1'; + const selected: SectionKey = isSectionKey(raw) ? raw : DEFAULT_SECTION; const client = useClient(); const clientRef = useRef(client); @@ -72,13 +77,12 @@ export const DetailPanel = () => { return
Loading…
; } - if (showingConfig || !configured) return ; - - const current = sectionFor(section); - - // Everything but `config`, so the settings link keeps the section underneath it. - const configSearch = new URLSearchParams(params); - configSearch.set('config', '1'); + /* + Unconfigured, so Administration regardless of what the nav says. The header then NAMES it, which is + the part the overlay could not do: the form used to appear under whichever row happened to be + highlighted, so it read as that section being broken rather than as one step not done yet. + */ + const current = sectionFor(configured ? selected : 'administration'); const Panel = current.built ? PANELS[current.key] : undefined; @@ -86,14 +90,7 @@ export const DetailPanel = () => {

{current.label}

- {/* A real link, so the settings are addressable and cmd-clickable like anything else. */} - - - Connection - + {current.hint}
{Panel ? : }
diff --git a/web/NavPanel.tsx b/web/NavPanel.tsx index 6515927..d6a766c 100644 --- a/web/NavPanel.tsx +++ b/web/NavPanel.tsx @@ -37,12 +37,10 @@ export const NavPanel = () => { {SECTIONS.map((section) => { const Icon = section.icon; - // Everything else in the URL is preserved. `?config=1` is the one that matters — opening the - // settings and then clicking a section should leave the settings, not silently keep them open - // underneath. + // Everything else in the URL is preserved. This is one screen of a workspace, and the global + // query string carries state that belongs to the shell rather than to this panel. const search = new URLSearchParams(params); search.set('section', section.key); - search.delete('config'); return (