vole
Clone
Read only, no credentials:
https://rodent.software/vole.git
Write over SSH with a registered key:
git clone ssh://git@rodent.software:2222/vole.git
A free and open-source forge that lives in your Git repo.
Expand the admin status page into an operational dashboard
4506a4d3d279556435fdd414265e7499c3dada16 · Keenan Nemetz · 14d ago · parent 2e024cc9
server/web/static/vole.css +23−1
| @@ -465,6 +465,7 @@ a.label:hover { color: var(--accent); border-color: var(--accent); text-decorati | |||
| 465 | 465 | } | |
| 466 | 466 | .flash.bad { border-color: color-mix(in srgb, var(--bad) 50%, var(--border)); background: var(--bad-soft); } | |
| 467 | 467 | .flash.good { border-color: color-mix(in srgb, var(--good) 50%, var(--border)); background: var(--good-soft); } | |
| 468 | .flash.warn { border-color: color-mix(in srgb, var(--warn) 50%, var(--border)); background: var(--warn-soft); } | ||
| 468 | 469 | ||
| 469 | 470 | .empty-page { | |
| 470 | 471 | max-width: 34rem; | |
| @@ -2056,15 +2057,36 @@ textarea:focus-visible { | |||
| 2056 | 2057 | .repo-grid { grid-template-columns: 1fr; } | |
| 2057 | 2058 | } | |
| 2058 | 2059 | ||
| 2059 | /* Status page: a small metrics row above the per-service checks. */ | ||
| 2060 | /* Status page: no rule under the header itself; the tab row keeps its rule. */ | ||
| 2061 | .status-head { border-bottom: 0; margin-bottom: 8px; } | ||
| 2062 | .status-tabs { margin-bottom: 14px; border-bottom: 1px solid var(--border); } | ||
| 2060 | 2063 | .status-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); gap: 10px; margin: 14px 0; } | |
| 2061 | 2064 | .status-grid .card { margin: 0; display: flex; flex-direction: column; gap: 4px; } | |
| 2062 | 2065 | .status-grid strong { font-size: 20px; font-weight: 600; font-variant-numeric: tabular-nums; } | |
| 2066 | .status-note { color: var(--fg-muted); font-size: 11.5px; } | ||
| 2067 | .status-inventory { margin: 4px 0 18px; font-size: 12px; } | ||
| 2068 | .status-total td { font-weight: 600; border-top: 1px solid var(--border-strong); } | ||
| 2063 | 2069 | .check-state { font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; } | |
| 2064 | 2070 | .check-state.ok { color: var(--good); } | |
| 2065 | 2071 | .check-state.warn { color: var(--warn); } | |
| 2066 | 2072 | .check-state.fail { color: var(--bad); } | |
| 2067 | 2073 | ||
| 2074 | /* The admin-only effective-configuration table below the health checks. */ | ||
| 2075 | .config-table td:first-child { width: 15rem; } | ||
| 2076 | .config-table td:first-child code { white-space: nowrap; } | ||
| 2077 | .config-table td:last-child { overflow-wrap: anywhere; } | ||
| 2078 | .config-group td { | ||
| 2079 | background: var(--bg-raised); | ||
| 2080 | color: var(--fg-muted); | ||
| 2081 | font-size: 11px; | ||
| 2082 | font-weight: 500; | ||
| 2083 | letter-spacing: 0.04em; | ||
| 2084 | text-transform: uppercase; | ||
| 2085 | padding-top: 7px; | ||
| 2086 | padding-bottom: 7px; | ||
| 2087 | } | ||
| 2088 | .config-group:hover td { background: var(--bg-raised); } | ||
| 2089 | |||
| 2068 | 2090 | /* Language hints for file rows. Active tree rows still win through specificity. */ | |
| 2069 | 2091 | .tree-icon.lang-go, .dirlist a.file.lang-go .icon { color: #00add8; } | |
| 2070 | 2092 | .tree-icon.lang-rust, .dirlist a.file.lang-rust .icon { color: #dea584; } | |