From 5479896bf31800164ab1684d5e65ff116b8c43f6 Mon Sep 17 00:00:00 2001 From: boban Date: Fri, 12 Jun 2026 23:32:28 +0200 Subject: [PATCH] fix(modal)+ux: panel above backdrop, one style, SSH credential form MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The modal panel rendered *behind* its own backdrop (it "appeared then vanished"): Tailwind v4 no longer turns `transform` into a stacking context, so the static panel sat under the fixed/blurred backdrop. Fixed with `relative z-10` on the panel (interactively verified by force-opening the modal). - New component: one compact, consistent style (h-8 text-xs) with variants (primary/accent/secondary/danger/ghost/ghost-danger). Replaced every ad-hoc action button — modals, service start/stop/restart, file row actions + upload, server-details (Zugang/Dateien/key add+remove). No more oversized, inconsistent buttons. - New EditCredential form modal + "Zugang" button on Server-Details: deposit or update a server's SSH login (e.g. root) — this is where the privileged credential for systemctl/journal gets stored (encrypted vault). Changing it re-pulls the snapshot with the new login. Co-Authored-By: Claude Opus 4.8 (1M context) --- app/Livewire/Modals/EditCredential.php | 85 +++++++++++++++++++ app/Livewire/Servers/Show.php | 9 ++ resources/views/components/btn.blade.php | 17 ++++ .../views/livewire/files/index.blade.php | 19 ++--- .../livewire/modals/add-ssh-key.blade.php | 20 ++--- .../livewire/modals/confirm-action.blade.php | 24 ++---- .../livewire/modals/edit-credential.blade.php | 59 +++++++++++++ .../views/livewire/servers/show.blade.php | 24 +++--- .../views/livewire/services/index.blade.php | 21 +---- .../wire-elements-modal/modal.blade.php | 2 +- 10 files changed, 199 insertions(+), 81 deletions(-) create mode 100644 app/Livewire/Modals/EditCredential.php create mode 100644 resources/views/components/btn.blade.php create mode 100644 resources/views/livewire/modals/edit-credential.blade.php diff --git a/app/Livewire/Modals/EditCredential.php b/app/Livewire/Modals/EditCredential.php new file mode 100644 index 0000000..55644ef --- /dev/null +++ b/app/Livewire/Modals/EditCredential.php @@ -0,0 +1,85 @@ +serverId = $serverId; + + if ($cred = Server::find($serverId)?->credential) { + $this->username = $cred->username; + $this->authType = $cred->auth_type; + // secret/passphrase are never pre-filled (encrypted at rest) + } + } + + public static function modalMaxWidth(): string + { + return 'lg'; + } + + public function save(): void + { + $this->error = null; + + $server = Server::find($this->serverId); + if (! $server) { + $this->error = 'Server nicht gefunden.'; + + return; + } + if (trim($this->username) === '' || trim($this->secret) === '') { + $this->error = 'Benutzer und Passwort/Schlüssel sind erforderlich.'; + + return; + } + + $server->credential()->updateOrCreate([], [ + 'username' => trim($this->username), + 'auth_type' => $this->authType === 'key' ? 'key' : 'password', + 'secret' => $this->secret, + 'passphrase' => $this->passphrase !== '' ? $this->passphrase : null, + ]); + + AuditEvent::create([ + 'user_id' => Auth::id(), + 'server_id' => $server->id, + 'actor' => Auth::user()?->name ?? 'system', + 'action' => 'server.credential_updated', + 'target' => $server->name.' · '.trim($this->username), + 'ip' => request()->ip(), + ]); + + $this->dispatch('credentialChanged'); + $this->dispatch('notify', message: 'Zugangsdaten gespeichert.'); + $this->closeModal(); + } + + public function render() + { + return view('livewire.modals.edit-credential'); + } +} diff --git a/app/Livewire/Servers/Show.php b/app/Livewire/Servers/Show.php index 51cedb0..ad3849a 100644 --- a/app/Livewire/Servers/Show.php +++ b/app/Livewire/Servers/Show.php @@ -138,6 +138,15 @@ class Show extends Component } } + /** Credential changed -> reconnect with the new login and re-pull the snapshot. */ + #[On('credentialChanged')] + public function reloadAfterCredential(FleetService $fleet): void + { + $this->server->refresh(); + $this->ready = false; + $this->load($fleet); + } + /** Open the file manager scoped to this server. */ public function openFiles() { diff --git a/resources/views/components/btn.blade.php b/resources/views/components/btn.blade.php new file mode 100644 index 0000000..d146236 --- /dev/null +++ b/resources/views/components/btn.blade.php @@ -0,0 +1,17 @@ +@props(['variant' => 'secondary', 'icon' => false]) +@php + // One button style for the whole app — compact, consistent (R10). + $variants = [ + 'primary' => 'bg-accent text-void hover:bg-accent-bright', + 'accent' => 'border border-accent/25 bg-accent/10 text-accent-text hover:bg-accent/15', + 'secondary' => 'border border-line bg-inset text-ink-2 hover:bg-raised hover:text-ink', + 'danger' => 'bg-offline text-void hover:bg-offline/90', + 'ghost' => 'text-ink-2 hover:bg-raised hover:text-ink', + 'ghost-danger' => 'text-ink-3 hover:bg-offline/10 hover:text-offline', + ]; + $shape = $icon ? 'h-8 w-8 justify-center' : 'h-8 px-3'; + $classes = 'inline-flex items-center gap-1.5 rounded-md text-xs font-medium transition-colors ' + .'disabled:opacity-50 disabled:pointer-events-none ' + .$shape.' '.($variants[$variant] ?? $variants['secondary']); +@endphp + diff --git a/resources/views/livewire/files/index.blade.php b/resources/views/livewire/files/index.blade.php index 457d690..4f96d41 100644 --- a/resources/views/livewire/files/index.blade.php +++ b/resources/views/livewire/files/index.blade.php @@ -49,9 +49,9 @@ {{-- Listing --}} - + {{-- Column header (desktop only) --}} @@ -116,19 +116,10 @@ {{-- Row actions --}}
@unless ($isDir) - {{-- R5: wire to wire-elements/modal --}} - + Download @endunless - {{-- R5: wire to wire-elements/modal --}} - - {{-- R5: destructive → wire-elements/modal confirm + audit --}} - + Bearbeiten + Löschen
@endforeach diff --git a/resources/views/livewire/modals/add-ssh-key.blade.php b/resources/views/livewire/modals/add-ssh-key.blade.php index 9c05dd9..44fd256 100644 --- a/resources/views/livewire/modals/add-ssh-key.blade.php +++ b/resources/views/livewire/modals/add-ssh-key.blade.php @@ -24,21 +24,11 @@
- - +
diff --git a/resources/views/livewire/modals/confirm-action.blade.php b/resources/views/livewire/modals/confirm-action.blade.php index 4320489..1b93702 100644 --- a/resources/views/livewire/modals/confirm-action.blade.php +++ b/resources/views/livewire/modals/confirm-action.blade.php @@ -17,25 +17,11 @@
- - +
diff --git a/resources/views/livewire/modals/edit-credential.blade.php b/resources/views/livewire/modals/edit-credential.blade.php new file mode 100644 index 0000000..a437d39 --- /dev/null +++ b/resources/views/livewire/modals/edit-credential.blade.php @@ -0,0 +1,59 @@ +
+
+ + + +
+

SSH-Zugang

+

Hier den Zugang hinterlegen — z. B. root für volle Steuerung (systemctl, Journal).

+
+
+ +
+
+ + +
+
+ + +
+
+ + @if ($authType === 'key') + + @else + + @endif +
+ @if ($authType === 'key') +
+ + +
+ @endif + + @if ($error) +

+ {{ $error }} +

+ @endif +
+ +
+ Abbrechen + + + + Speichern + +
+
diff --git a/resources/views/livewire/servers/show.blade.php b/resources/views/livewire/servers/show.blade.php index e5c4b08..4415b9d 100644 --- a/resources/views/livewire/servers/show.blade.php +++ b/resources/views/livewire/servers/show.blade.php @@ -43,11 +43,12 @@

- + + Zugang + + + Dateien + {{ $statusLabel }}
@@ -157,12 +158,10 @@ {{-- R5: wire to wire-elements/modal --}} - +
@foreach ($sshKeys as $key) @@ -178,12 +177,9 @@

{{ $key['fingerprint'] }}

{{-- R5: destructive → wire-elements/modal confirm + audit --}} - + @endforeach diff --git a/resources/views/livewire/services/index.blade.php b/resources/views/livewire/services/index.blade.php index 15733ee..7cf3a62 100644 --- a/resources/views/livewire/services/index.blade.php +++ b/resources/views/livewire/services/index.blade.php @@ -70,24 +70,9 @@ {{-- R5: wire to wire-elements/modal --}}
- - - + Starten + Stopp + Neustart
diff --git a/resources/views/vendor/wire-elements-modal/modal.blade.php b/resources/views/vendor/wire-elements-modal/modal.blade.php index 85e8386..7a41b78 100644 --- a/resources/views/vendor/wire-elements-modal/modal.blade.php +++ b/resources/views/vendor/wire-elements-modal/modal.blade.php @@ -39,7 +39,7 @@ x-transition:leave="ease-in duration-200" x-transition:leave-start="opacity-100 translate-y-0 sm:scale-100" x-transition:leave-end="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95" - class="inline-block w-full max-w-lg align-bottom bg-surface border border-line rounded-lg text-left overflow-hidden shadow-pop transform transition-all sm:my-8 sm:align-middle" + class="relative z-10 inline-block w-full max-w-lg align-bottom bg-surface border border-line rounded-lg text-left overflow-hidden shadow-pop transform transition-all sm:my-8 sm:align-middle" id="modal-container" x-trap.noscroll.inert="show && showActiveComponent" aria-modal="true"