Media moves to the foot, and each section asks its own question

TWO REPORTS, AND THE SECOND ONE WAS A DESIGN MISTAKE RATHER THAN A SETTING.

Media is pinned now, beside Administration. it sat at the end of the scrolling list,
which is the bottom of the LIST and not the bottom of the panel. it belongs in the
foot for the same reason Administration does: both are about this machine, while
everything above them is about the site's pages.

and it was LOCKED BEHIND A CONNECTION IT NEVER USES. `ready` was one global flag —
"can anything be opened" — and Media is a folder on this disk that never speaks to
fofos. so sections now declare what they need:

  'connection'  the site's pages, which read fofos
  'root'        Media, which needs a folder and nothing else
  'nothing'     Administration, because locking the door you fix things through is
                locking somebody out entirely

`sectionOpen` is one function, used by the nav to decide whether to offer a link and
by the detail panel to decide what to render — so the two cannot disagree about a
section. that was already the rule with one flag; it matters more now that each
section asks a different question.

`/status` gained `rootSet`, a BOOLEAN, and stays not-owner-only. the nav needs the
answer for every account that can see the section; the path itself stays behind
`/_config`, which is owner-only. whether a root has been chosen reveals nothing
about the machine — where it is would.

the empty-state line follows too: "set a root location below to begin" before there
is one, "connect fofos to open the rest" after — rather than one sentence naming a
step that is not the next one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-29 08:44:11 +01:00
co-authored by Claude Opus 5
parent 944d3d9c5b
commit c38d269faf
6 changed files with 97 additions and 14 deletions
+12 -4
View File
@@ -39,11 +39,19 @@ import { useFofosChanged } from './channel';
* assembling their own version of the condition out of the pieces.
*/
type Status = { configured: boolean; lastProbeOk: boolean | null };
type Status = { configured: boolean; lastProbeOk: boolean | null; rootSet: boolean };
export type Readiness = {
/** True only when every section may be opened. */
/** The fofos connection works. Gates every section that READS the site. */
ready: boolean;
/**
* A root location has been chosen.
*
* Separate from `ready` because the two are genuinely different questions and one section depends on
* each. Media needs a folder on this machine; it never speaks to fofos, and gating it behind a
* connection it does not use was the bug that made this distinction necessary.
*/
rootSet: boolean;
/** Still asking. Callers should render nothing rather than guess — see below. */
loading: boolean;
};
@@ -65,7 +73,7 @@ export const useReady = (): Readiness => {
"you have not set this up", which is a far more alarming thing to be told and invites somebody
to re-enter a connection that was never the problem.
*/
setStatus({ configured: true, lastProbeOk: null });
setStatus({ configured: true, lastProbeOk: null, rootSet: false });
}
}, []);
@@ -78,5 +86,5 @@ export const useReady = (): Readiness => {
// ────────────────────────────────────────────────────────────────────────────────────────────────
const ready = false;
return { ready, loading: status === null };
return { ready, rootSet: status?.rootSet ?? false, loading: status === null };
};