Servers is a block in Administration, not a section of its own
It is the same KIND of thing as the root location and the databases — this machine, not the site's content — and a nav row leading to one card was a whole screen to reach three lines. Last of the three, because it needs both of the others: a server has nowhere to run without the checkout and nothing to read without a database. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { RootLocationBlock } from './RootLocationBlock';
|
||||
import { DatabaseBlock } from './DatabaseBlock';
|
||||
import { ServersBlock } from './ServersBlock';
|
||||
|
||||
/**
|
||||
* Administration — this plugin's own machinery, not the client's site.
|
||||
@@ -8,8 +9,9 @@ import { DatabaseBlock } from './DatabaseBlock';
|
||||
* message; this file decides only which of them exist and in what order.
|
||||
*
|
||||
* The order is the order things are needed in: where the site is on this machine, then how to read its
|
||||
* data. Building `derived/` from `originals/` lives with the folders it acts on, inside Root Location,
|
||||
* rather than as a section here describing the same two directories a second time.
|
||||
* data, then the processes that serve it — which need both. Building `derived/` from `originals/`
|
||||
* lives with the folders it acts on, inside Root Location, rather than as a section here describing the
|
||||
* same two directories a second time.
|
||||
*
|
||||
* ── What used to be here ──
|
||||
*
|
||||
@@ -23,5 +25,6 @@ export const AdministrationPanel = () => (
|
||||
<div className="flex size-full flex-col gap-4 overflow-auto p-5">
|
||||
<RootLocationBlock />
|
||||
<DatabaseBlock />
|
||||
<ServersBlock />
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { useSearchParams } from 'react-router';
|
||||
import { DEFAULT_SECTION, isSectionKey, sectionFor, sectionOpen, type SectionKey } from './sections';
|
||||
import { AdministrationPanel } from './AdministrationPanel';
|
||||
import { ServersPanel } from './ServersPanel';
|
||||
import { MediaPanel } from './MediaPanel';
|
||||
import { MessagesPanel } from './MessagesPanel';
|
||||
import { PlannedSection } from './PlannedSection';
|
||||
@@ -41,7 +40,6 @@ import { useReady } from './useReady';
|
||||
const PANELS: Partial<Record<SectionKey, () => React.JSX.Element>> = {
|
||||
messages: MessagesPanel,
|
||||
administration: AdministrationPanel,
|
||||
servers: ServersPanel,
|
||||
media: MediaPanel,
|
||||
};
|
||||
|
||||
|
||||
@@ -11,6 +11,10 @@ import { useFlash } from './useFlash';
|
||||
/**
|
||||
* The two servers that serve the site, under pm2.
|
||||
*
|
||||
* A block inside Administration rather than a section of its own: it is the same KIND of thing as the
|
||||
* root location and the databases — this machine, not the site's content — and a nav row for one card
|
||||
* was a whole screen to reach three lines.
|
||||
*
|
||||
* ── Both under pm2, development included ──
|
||||
*
|
||||
* A `bun dev` started in a terminal dies with the terminal, and nobody can tell whether it is running
|
||||
@@ -47,7 +51,7 @@ const uptime = (ms: number) => {
|
||||
return hours < 24 ? `${hours}h ${minutes % 60}m` : `${Math.floor(hours / 24)}d ${hours % 24}h`;
|
||||
};
|
||||
|
||||
export const ServersPanel = () => {
|
||||
export const ServersBlock = () => {
|
||||
const client = useClient();
|
||||
const clientRef = useRef(client);
|
||||
clientRef.current = client;
|
||||
@@ -193,40 +197,38 @@ export const ServersPanel = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex size-full flex-col gap-4 overflow-auto p-5">
|
||||
<Block
|
||||
icon={Server}
|
||||
title="Servers"
|
||||
hint="The site's development and production processes, run under pm2."
|
||||
status={
|
||||
flashing ? (
|
||||
<span className="flex items-center gap-1 text-xs text-success">
|
||||
<Check className="size-3.5" />
|
||||
Saved
|
||||
</span>
|
||||
) : undefined
|
||||
}
|
||||
>
|
||||
{!servers ? null : (
|
||||
<>
|
||||
{servers.map((server) =>
|
||||
server.name === 'development' ? row(server, dev, setDev) : row(server, prod, setProd),
|
||||
)}
|
||||
<Block
|
||||
icon={Server}
|
||||
title="Servers"
|
||||
hint="The site's development and production processes, run under pm2."
|
||||
status={
|
||||
flashing ? (
|
||||
<span className="flex items-center gap-1 text-xs text-success">
|
||||
<Check className="size-3.5" />
|
||||
Saved
|
||||
</span>
|
||||
) : undefined
|
||||
}
|
||||
>
|
||||
{!servers ? null : (
|
||||
<>
|
||||
{servers.map((server) =>
|
||||
server.name === 'development' ? row(server, dev, setDev) : row(server, prod, setProd),
|
||||
)}
|
||||
|
||||
{error && <p className="text-xs text-destructive">{error}</p>}
|
||||
<Console output={output} failed={failed} />
|
||||
{error && <p className="text-xs text-destructive">{error}</p>}
|
||||
<Console output={output} failed={failed} />
|
||||
|
||||
{dirty && (
|
||||
<div className="flex justify-end border-t border-border pt-3">
|
||||
<Button size="sm" onClick={() => void savePorts()} disabled={busy !== null || !dev || !prod}>
|
||||
{busy === 'ports' ? <Loader2 className="size-3.5 animate-spin" /> : <Check className="size-3.5" />}
|
||||
Save ports
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</Block>
|
||||
</div>
|
||||
{dirty && (
|
||||
<div className="flex justify-end border-t border-border pt-3">
|
||||
<Button size="sm" onClick={() => void savePorts()} disabled={busy !== null || !dev || !prod}>
|
||||
{busy === 'ports' ? <Loader2 className="size-3.5 animate-spin" /> : <Check className="size-3.5" />}
|
||||
Save ports
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</Block>
|
||||
);
|
||||
};
|
||||
+1
-23
@@ -1,5 +1,5 @@
|
||||
import type { LucideIcon } from 'lucide-react';
|
||||
import { Home, Info, Layers, Images, Handshake, Sparkles, Wrench, Settings, Mail, Cog, FolderOpen, Server } from 'lucide-react';
|
||||
import { Home, Info, Layers, Images, Handshake, Sparkles, Wrench, Settings, Mail, Cog, FolderOpen } from 'lucide-react';
|
||||
|
||||
/**
|
||||
* The sections of the fofos admin, in nav order.
|
||||
@@ -29,7 +29,6 @@ import { Home, Info, Layers, Images, Handshake, Sparkles, Wrench, Settings, Mail
|
||||
|
||||
export type SectionKey =
|
||||
| 'administration'
|
||||
| 'servers'
|
||||
| 'media'
|
||||
| 'messages'
|
||||
| 'site'
|
||||
@@ -178,27 +177,6 @@ export const SECTIONS: Section[] = [
|
||||
// Pinned beside Administration: both are about this machine rather than about the site's pages.
|
||||
pinned: true,
|
||||
},
|
||||
{
|
||||
/*
|
||||
The two processes that serve the site, under pm2.
|
||||
|
||||
Beside Administration and above it, because it is the same KIND of thing — this machine rather
|
||||
than the site's content — but it is the one somebody opens most: whether the site is up is a
|
||||
question with a different urgency from where its files are.
|
||||
|
||||
`requires: 'root'`, not a connection. It needs the checkout to run, and nothing from fofos itself:
|
||||
a site that is down is exactly when its API cannot be reached, which is precisely when this has to
|
||||
keep working.
|
||||
*/
|
||||
key: 'servers',
|
||||
label: 'Servers',
|
||||
icon: Server,
|
||||
hint: 'Development and production, and whether they are up',
|
||||
path: null,
|
||||
built: true,
|
||||
requires: 'root',
|
||||
pinned: true,
|
||||
},
|
||||
{
|
||||
/*
|
||||
Last, and `path: null` — it reads nothing from fofos. Every other section is a window onto the
|
||||
|
||||
Reference in New Issue
Block a user