feat: dedicated server StatusPage for lifecycle states - #1452
Merged
Merged
Conversation
- Rename DatabaseBlocked.Status to Reason - Remove non-existent Progress field - Add optional CanShutdown, CanRestart, BootstrappedAt, StartedAt, StartupTime fields - Make Uptime optional to match server TimeSpan?
- Add useServerRestartMutation and useServerShutdownMutation - Add Server Status section with restart/shutdown buttons - Buttons conditionally rendered based on CanRestart/CanShutdown - Confirmation modals with toast notifications - Use mutateAsync with inline error handling
Add a dedicated StatusPage covering server lifecycle states (Starting/Failed/Restarting/Shutting-down/Shutdown/Offline) with a serverLifecycle Redux slice that is ephemeral and excluded from persistence. AuthenticatedRoute now guards authenticated access and a /webui/status route is added. - serverLifecycle Redux slice (ephemeral, excluded from persistence) - AuthenticatedRoute guard + /webui/status route - SignalR toast suppression and requiresRestart suppression with comment fixes - GeneralSettings restart/shutdown handoff to StatusPage - LoginPage redirect handling for lifecycle states - axios 401 fix for /api/v3/Settings - StatusPage simplifications (detail/variantIconMap, !! checks, etc.)
revam
reviewed
Aug 27, 2026
revam
left a comment
Member
There was a problem hiding this comment.
Got asked to review text, so reviewed text. My human findings are below. Rest of 'em seem fine-ish.
hidden4003
approved these changes
Aug 27, 2026
…, abstract copy - GeneralSettings: treat ERR_NETWORK/no-response as success navigating to /webui/status - queries: native refetchInterval function form - StatusPage: derive interval via query.state, remove extra render, dash→'.', starting/restarting abstracted
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a dedicated, full-bleed StatusPage (
/webui/status) that is the single canonical surface for all non-ready server states —Starting,Failed,Restarting,Shutting-down,Shutdown, andOffline— plus an automatic recovery redirect back into the app once the server isStarted. This fixes the auto-login gap that occurred when the server transitionedStarting → Startedwhile the user was on the login page.Why
LoginPagelived outsideAuthenticatedRoute, so theStartingstate was handled ad-hoc there and theStarting → Startedtransition was never reliably caught (auto-login gap during the boot window).Startingproduced a blank crossfade / stuck state because nothing canonical owned the "server not reachable yet" state.Changes
serverLifecycleslice (src/core/slices/serverLifecycle.ts) — ephemeral UI intent (idle|restarting|shutting-down,initiatedAt). Deliberately excluded from sessionStorage persistence (bothloadStateandsaveStateinsrc/core/localStorage.ts) so a reload mid-restart never rehydrates a stalerestartingand traps the user on a stuck StatusPage.StatusPage.tsx(src/pages/StatusPage.tsx) — 7 variants (loading,starting,failed,restarting,shutting-down,shutdown,offline). Drive text viavariantDetailMapand icons viavariantIconMap. Polling at 2s / retry 5s that backs off to 15s / 15s once the server is unreachable. A 3-minute restart timeout promotesrestarting → offline; 2 consecutive failures promotesshutting-down → shutdown. Immediate redirect onStartedis guarded bylastSeenStartedAtRef+sawDisruptionRef+STATUS_FRESH_MSso the redirect only fires after a genuine disruption. Variantsfailed/offline/shutdownrender action buttons — "Restart Server" (gated onCanRestart), "Retry Now", and "Retry Connection" respectively — so recovery is possible directly from the page.AuthenticatedRouteguard (src/core/router/AuthenticatedRoute.tsx) —isErroror active lifecycleaction→StatusPage;Waiting→ login;Started→ authenticated children / login redirected;Starting/Failed→StatusPage; otherwise optimistically render when authenticated./webui/statusroute added insrc/core/router/index.tsx.src/core/signalr/signalr.ts) —onreconnecting/onreconnected/oncloseandrequiresRestartare gated onserverLifecycle.action === 'idle', so StatusPage is the only UX during a user-initiated restart/shutdown.GeneralSettingshandoff (src/pages/settings/tabs/GeneralSettings.tsx) — new Restart/Shutdown buttons (gated onCanRestart/CanShutdown) withConfirmationPromptModal;onConfirmRestart/onConfirmShutdowndispatchsetAction→ mutate (Init/Restart,Init/Shutdown) →navigate('/webui/status').LoginPageredirect (src/pages/login/LoginPage.tsx) — any non-Started/non-Waitingstate (orisError) redirects to/webui/status; removed the bespokeStarting/Failedblocks from the login UI.src/core/axios.ts) —fullPathnow uses a proper/${url}slash, addsSettingsexclusion (/api/v3/Settings) for the boot window so settings reads don't trigger a logout.!!truthiness checks, retry-interval consolidation, icon map, etc.pnpm lintandpnpm buildpass; dev override removed before commit; a11y/aria removed per codebase conventions.Testing
pnpm lintandpnpm buildpass.Started).