The three admin pages (classify, caldav, bulk) had no shared entry point — m navigated around and couldn't find them. /admin is now their index: - 3 cards, each linking to the underlying tool, with live counts (orphan count via projax.items_unified predicate; calendar count via ListCalendars; item count via projax.items where deleted_at IS NULL AND archived = false) - CalDAV card auto-disables when DAV_URL isn't configured - System panel: version (build-time ldflags hook), last migration (projax.schema_migrations top row), MCP status (token present yes/no — token itself never displayed), upstream health (DAV + Gitea + Supabase, parallel-probed with 1s HTTP timeout each, cached 30s) web/admin.go houses the handler + cache + probeURL helper + count queries. Templates/admin.tmpl renders the cards + system grid. admin_test.go covers /admin render + nav-link presence on every chrome-bearing route. Nav consolidation: the three separate admin links in layout.tmpl collapse to one /admin entry. Pre-existing TestTreeRenders updated to assert the new shape. Probe-URL caveat: probeURL counts any HTTP response as "alive" (incl. 4xx) — the admin panel measures reachability, not authorisation. CalDAV returns 401 on bare GET; Gitea returns 200 at the root; Supabase same. All show green when alive.
52 lines
1.8 KiB
Cheetah
52 lines
1.8 KiB
Cheetah
{{define "content"}}
|
|
<h1>Admin</h1>
|
|
<p class="muted">Tools for ongoing maintenance of projax data + integrations. The pages also live as direct routes (linked in each card).</p>
|
|
|
|
<section class="admin-cards">
|
|
{{range .Cards}}
|
|
<article class="admin-card {{if .Disabled}}disabled{{end}}">
|
|
<header>
|
|
<h2>
|
|
{{if .Disabled}}{{.Title}}{{else}}<a href="{{.Href}}">{{.Title}}</a>{{end}}
|
|
</h2>
|
|
{{if not .Disabled}}
|
|
<p class="count"><strong>{{.Count}}</strong> <small class="muted">{{.CountLabel}}</small></p>
|
|
{{else}}
|
|
<p class="count muted">— {{.DisabledMsg}}</p>
|
|
{{end}}
|
|
</header>
|
|
<p class="desc">{{.Description}}</p>
|
|
</article>
|
|
{{end}}
|
|
</section>
|
|
|
|
<section class="admin-system">
|
|
<h2>System</h2>
|
|
<dl class="system-grid">
|
|
<dt>Version</dt>
|
|
<dd>{{if .Panel.Version}}<code>{{.Panel.Version}}</code>{{else}}<span class="muted">unset (build without -ldflags)</span>{{end}}</dd>
|
|
|
|
<dt>Last migration</dt>
|
|
<dd>{{if .Panel.MigrationLast}}<code>{{.Panel.MigrationLast}}</code>{{else}}<span class="muted">no migrations recorded</span>{{end}}</dd>
|
|
|
|
<dt>MCP</dt>
|
|
<dd>{{if .Panel.MCPEnabled}}<span class="ok">enabled</span> · <code>/mcp/rpc</code>{{else}}<span class="muted">disabled</span> (PROJAX_MCP_TOKEN unset){{end}}</dd>
|
|
|
|
{{if .Panel.Healths}}
|
|
<dt>Upstreams</dt>
|
|
<dd>
|
|
<ul class="health-list">
|
|
{{range .Panel.Healths}}
|
|
<li class="health-row {{if .OK}}health-ok{{else}}health-down{{end}}">
|
|
<span class="dot" aria-hidden="true"></span>
|
|
<strong>{{.Name}}</strong>
|
|
<a href="{{.URL}}" target="_blank" rel="noopener noreferrer"><code>{{.URL}}</code></a>
|
|
</li>
|
|
{{end}}
|
|
</ul>
|
|
</dd>
|
|
{{end}}
|
|
</dl>
|
|
</section>
|
|
{{end}}
|