diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a8dc1d..c2b5b04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,18 @@ Pre-1.0 versions treat MINOR as feature releases and PATCH as bug fixes. --- +## [0.4.5] — 2026-04-11 + +### Bug Fixes +- **Sidebar version refresh not updating** — clicking the refresh icon now clears the stale version immediately (shows spinner) and adds a `?_t=` cache-bust parameter so the browser never serves a cached response. Same fix applied to the "Retry" button in the error state. +- **`uptime` and `kill` missing from exec allowlist** — caused `GET /api/nixserver/system/info` to throw "Command not allowed", returning 500 and leaving Hostname/OS as `…` on the dashboard. +- **Version fetch auto-retry** — when the version API fails (e.g. during service restart after upgrade), the sidebar now automatically retries every 5 s until it succeeds instead of permanently showing "Version unavailable". + +### New Features +- **Day/Night mode toggle** — sun/moon flip switch at the right end of the dashboard info bar. Light palette: page `#f0f4f8`, cards `#ffffff`. Preference persisted to `localStorage`. All pages switch via seven `[data-theme="light"]` CSS overrides in `index.css` without touching individual page files. + +--- + ## [0.4.4] — 2026-04-11 ### New Features diff --git a/nixserver/src/components/Layout.tsx b/nixserver/src/components/Layout.tsx index 7e9d3df..f5f0f50 100644 --- a/nixserver/src/components/Layout.tsx +++ b/nixserver/src/components/Layout.tsx @@ -465,10 +465,16 @@ export default function Layout() { const [versionError, setVersionError] = useState(false) const [upgradeState, setUpgradeState] = useState<'idle' | 'confirm' | 'running' | 'done' | 'error'>('idle') - const fetchVersion = useCallback(async () => { + const fetchVersion = useCallback(async (manual = false) => { setVersionError(false) + // On a manual refresh, clear the stale value so the spinner shows + if (manual) setVersionInfo(null) try { - const { data } = await api.get('/nixserver/system/version', { timeout: 10_000 }) + const { data } = await api.get('/nixserver/system/version', { + timeout: 10_000, + // Cache-bust so the browser never serves a stale version response + params: { _t: Date.now() }, + }) setVersionInfo(data.data) } catch { setVersionError(true) @@ -685,7 +691,7 @@ export default function Layout() { )} diff --git a/package.json b/package.json index c895fc9..a6f7cc4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nixpanel-server", - "version": "0.4.4", + "version": "0.4.5", "private": true, "workspaces": [ "server", diff --git a/server/src/app.ts b/server/src/app.ts index 8cffc30..abcd1ab 100644 --- a/server/src/app.ts +++ b/server/src/app.ts @@ -73,7 +73,7 @@ export async function buildApp() { fastify.get('/api/health', async () => ({ status: 'ok', - version: '0.4.4', + version: '0.4.5', timestamp: new Date().toISOString(), }))