Route switching was slow because each page did its SSH reads inside mount(),
blocking the response. Now mount() only sets cheap shell state and the SSH read
runs in load() via wire:init — the page shell + skeletons render instantly and
content streams in.
- Lazy-load Dashboard (services), Services, Files, Server-Details: SSH moved from
mount() to load(); skeleton placeholders (new <x-skeleton>) while !$ready.
- Modal container: z-10 -> z-50 (was rendering *under* the z-40 sidebar) and a
real max-w-lg (the dynamic modalWidth classes were never generated by Tailwind,
so modals spanned full width). This also fixes the "flash + disappear".
- Modal/action buttons: normalize size (min-h-11 uppercase font-display -> h-9
text-sm font-medium) and add a wire:loading spinner + disabled-while-running on
the confirm/save actions (no double-submit, clear feedback).
- Server-Details gauges keep wire:poll (live) but no longer block initial render.
Verified: every page renders ready=false + skeleton with no SSH, then load()
populates real data; modal buttons carry the spinner.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Make the panel actually operate the server, not just display it — for everything
that works in the SSH user's own space (no sudo required).
- FleetService: addAuthorizedKey (append, dedup, perms-safe via base64 transport),
removeAuthorizedKey (by SHA256 fingerprint, preserves every other key — never
rewrites blindly, no lockout), sshKeys (reload), deleteFile (SFTP unlink).
- AddSshKey form modal: paste a public key -> appended over SSH + AuditEvent +
list reload. Wired to the "Schlüssel hinzufügen" button on Server-Details.
- Server-Details: key removal now performs the real SSH removal then reloads;
new "Dateien" button opens the file manager scoped to this server.
- Files: delete performs the real SFTP unlink then reloads the directory.
Verified live: add+remove of a throwaway key leaves the existing key intact;
real file delete confirmed gone. systemctl start/stop/restart still need a
privileged credential (the demo account has no passwordless sudo).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>