e87e19ee467e6d455c7a69f93341aec196fd631a
7
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
3dd4dd6592 |
one header instead of three rows, and the folder lives in the URL
THE TOP WAS THREE ROWS OF FURNITURE before any content: the workspace's chrome header saying "Detail", the panel's own strip saying "Media — Photos and video the site is built from", and then the browser's toolbar. a panel meta may supply its own `header`, which is the mechanism for exactly this and which gitea, invoices and desktop already use. so the section's name goes where a panel's name goes, and the strip inside is gone. "Detail" was never information — the panel is the detail panel, and the useful word is which section is open. the hint went with it. "Photos and video the site is built from" earns its place in the NAV, where somebody is choosing between ten sections. repeated above the one they chose, it is a caption for a decision already made. AND THE FOLDER IS IN THE QUERY STRING. `urlPath` puts it in `?path=`, so a reload lands where you were and a link can be sent to somebody — which for a media folder somebody else uploads into is the point. it is opt-in in the platform because a screen with two browsers would have them fighting over one parameter; this screen has one. `panelId` stays alongside it: the URL covers a reload or a shared link, and panelId covers a panel re-opened later, which the URL cannot. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
c38d269faf |
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>
|
||
|
|
944d3d9c5b |
a Media section, browsing the site's originals in place
a new section above Administration. it embeds THE PLATFORM'S OWN file browser rather than drawing a file list — upload, delete, rename, move, thumbnails, the context menu and every task hanging off it already exist and are maintained in one place. a plugin's own would be a second to keep in step, arriving without any of that. `basePath` IS A JAIL, not a starting folder: `useFileBrowserApp` resets currentPath whenever it leaves, so pointing it at `<root>/media/originals` means the breadcrumb stops there and `derived/` is not reachable by navigating. that is what was asked for — people work in originals, derived is made for them. IT IS A GUARDRAIL AND NOT A PERMISSION BOUNDARY, and the panel says so in its own docstring because the difference will matter to whoever reads this next. the file-browser API is unchanged and still addresses the whole home: anyone with file access reaches derived/ through the Files screen. this prevents an accident, not a determined person. confining it properly means scoping that API per user, which is a platform change and a much larger one. the panel also says, once, that derived/ exists and is made from these — otherwise somebody who knows about it would think it had been lost. `rootRelative` is new on the settings API because only the SERVER knows what home is. the file browser addresses everything relative to a root, and a browser deriving that prefix from the absolute path would be guessing. null when the root sits outside home — a legitimate setting the browser cannot address, which the panel explains rather than rendering an empty folder. NOTHING HERE IS FOFOS-SPECIFIC, which matters now that this plugin is the template for other site admins: the root is a setting, media/originals is the layout this plugin creates, and both are read from the API. another site's plugin changes the label. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
fcc7436965 |
Administration is emptied, and starts again with a Database block
the address-and-token form is gone from the screen and ConnectionPanel.tsx with it. leaving an unreferenced component behind would have been worse than deleting it: it is in the history, and a file nothing renders rots without anyone noticing. in its place, Administration is a LIST OF BLOCKS rather than one form. it will hold several unrelated settings, and giving each a titled block now means the second one moves nothing — a single form would have to be broken up the first time anything joined it. the first block is Database, and it is empty on purpose. it says "nothing to set yet" rather than rendering nothing, because a section that draws blank reads as one somebody abandoned. what goes in it is not decided, and inventing fields to fill the space would be deciding it in the wrong place. WHAT THIS COSTS, plainly: there is now no way to configure this plugin from the screen at all. the server half is untouched — `/_config` still stores a URL and a token and the proxy in api/router.ts still reads them — but nothing can set them. that is consistent with the gate being hardcoded false rather than a second breakage: both are the same unfinished change, and neither is worth half-fixing while the shape of the connection is being replaced. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
10b7bc34f7 |
nothing but Administration opens until the plugin is ready
every section was clickable and every one of them showed the same connection form, because the panel forced it and the nav did not know. nine doors onto one message taught nobody anything and made a setup step look like nine faults. so there is now a gate, `useReady`, and both panels read it. that is the point of putting it in a hook rather than in either panel: a nav that offers a row the detail panel then refuses is worse than one that does not offer it. the nav DECLINES TO OFFER — a locked section is a <div>, not a <Link>, so there is no href to hover, no cmd-click into a new tab and nothing to focus. rendering a link and swallowing the click leaves a row that looks navigable and behaves like one everywhere except the click. the detail panel HOLDS THE LOCK, and it has to, because `?section=gallery` typed into the address bar or arriving from an old bookmark never passes through the nav. one line of copy in the foot rather than a badge on nine dimmed rows. without it a locked nav reads as broken instead of as one step not done: the rows go grey and nothing says why or what to do about it. THE CONDITION IS HARDCODED FALSE, as asked. the plumbing around it is real — it asks /status, re-asks when the connection changes, and reports while it is still asking — so switching the gate on is one line. it returns a single boolean and not its parts deliberately: "all the info needed in Administration" will grow past `configured && lastProbeOk`, and callers must not start assembling their own version of it out of the pieces. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
7eec2ec51d |
Administration is a section, not an overlay
the connection form — where fofos is, and the token — was reached through `?config=1` and a link in the detail header, because it was not one of the nine sections. it is now the tenth, called Administration, last in the nav. that removes the overlay and the second route to it. the two could disagree: the form covered whatever section was selected underneath, so the nav highlighted one thing while the panel showed another, and an unconfigured plugin rendered the form with no header at all — which reads as the selected section being broken rather than as one setup step not done yet. unconfigured now goes to Administration and the header says so. `site` and `administration` are deliberately separate and the file says why. Site settings is the CLIENT's — partners, social links, contact details, all of it public copy. Administration is Officer's end: how this plugin reaches fofos, and whatever else it will need to know. nothing in it ever appears on the site, and the people who touch the two are not the same people. `path: null`, alone among the sections: it reads nothing from fofos, which is why it keeps working when fofos is unreachable and the others do not. the header's settings link is replaced by the section's own hint, so the row still says what it is once you are in it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
6b87956e44 |
Everything needed to be a plugin
manifest, one table, a router and two panels. Discovery is by convention, so
this is the point at which the directory stops being a directory and becomes
something Officer can install.
The manifest holds only what a listing cannot say. One permission, grantable,
with ownerOnly on /_config — reading and editing the site is exactly what a
member might be brought in for, but the token is unrestricted write authority
over everything the public sees, so handing it over is the owner's.
db/schema.ts is ONE table and should stay that way. fofos owns its own Postgres
and its own media store; this holds a URL and a token. That is what makes the
strongest thing about this plugin true: no operation on it can destroy the
client's work, checkbox ticked or not, because none of it was ever here. A cache
would be the thin end of that.
The router mostly forwards. fofos's /api/admin already answers in the shape a
panel wants, so re-wrapping it would be a second place for the contract to drift.
Two things in it are load-bearing rather than style:
registerProxiedPrefix('/api/fofos-admin/media'). bodyParser calls parseBody on
multipart across the whole protected router, and Hono then caches the parsed
FormData — so asking for the bytes afterwards re-serialises them under a NEW
boundary while the ORIGINAL content-type header is what gets forwarded. Header
and body disagree and every upload fails with "Unexpected end of form".
Narrow to the one route: everything else is JSON that is fine to parse.
The catch-all is LAST in the file. Hono runs matching handlers in registration
order, so /* above /_config would swallow it and the settings form would
forward itself to fofos, which has no such endpoint — a 404 from a plugin that
is working perfectly.
Panels are a nav and a detail pane that never speak to each other: the nav writes
?section=, the detail pane reads it. Real <Link>s rather than the buttons
proxy-manager uses — AGENTS.md says nav items are links, and the file documenting
that pattern says not to copy the older one. <Link> and not <NavLink> because
active state here is a query parameter and NavLink compares paths, which would
light every row at once.
Which component renders which section is a MAP, not a conditional on `built`.
The first version read `built ? <MessagesPanel/> : <Planned/>`, which is correct
only while exactly one section exists — the second one finished would have
rendered Messages under its own name.
Messages is the only section built, chosen because it is one read-only route: it
proves the path from an Officer panel through this proxy to fofos and back with
nothing else able to be wrong at the same time. The other eight are in the nav,
dimmed and labelled, saying what they will do and that the old admin still edits
them. A nav that hides what is unfinished gives no sense of what the thing is for.
Typechecked against the platform — and the typechecker was verified to actually
cover plugins/ by planting an error and watching it fail, because a clean run
that does not include your files is worse than no run.
NOT yet: installed, or run against a live fofos. Nothing here has been through
the permission gate or a real request.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|