Fix: ClamAV Feedback – Loading-Overlay + Erfolg/Fehler-Banner inline
- Loading-Overlay über Status-Karte beim Aktivieren/Deaktivieren/Installieren - $lastSuccess Property für grünen Erfolg-Banner (kein Toast nötig) - runCmd() helper mit Log für Debugging - Fehler-Text white-space:pre-wrap für mehrzeilige Ausgaben Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>main v1.1.329
parent
a9ad26757b
commit
dc5d8582e1
|
|
@ -17,6 +17,7 @@ class ClamavManager extends Component
|
|||
public string $dbVersion = '—';
|
||||
public ?int $ramMb = null;
|
||||
public string $lastError = '';
|
||||
public string $lastSuccess = '';
|
||||
public bool $installing = false;
|
||||
|
||||
public function mount(): void
|
||||
|
|
@ -26,11 +27,12 @@ class ClamavManager extends Component
|
|||
|
||||
public function refresh(): void
|
||||
{
|
||||
$this->lastError = '';
|
||||
$this->running = $this->serviceActive();
|
||||
$this->enabled = $this->serviceEnabled();
|
||||
$this->installed = true; // Mailwolt setzt ClamAV voraus; Fehler kommen vom Wrapper
|
||||
$this->ramMb = $this->running ? $this->readRamMb() : null;
|
||||
$this->lastError = '';
|
||||
$this->lastSuccess = '';
|
||||
$this->running = $this->serviceActive();
|
||||
$this->enabled = $this->serviceEnabled();
|
||||
$this->installed = true;
|
||||
$this->ramMb = $this->running ? $this->readRamMb() : null;
|
||||
[$this->dbDate, $this->dbVersion] = $this->readDbInfo();
|
||||
}
|
||||
|
||||
|
|
@ -51,41 +53,37 @@ class ClamavManager extends Component
|
|||
|
||||
public function enable(): void
|
||||
{
|
||||
$out = [];
|
||||
@exec('sudo -n /usr/local/sbin/mailwolt-clamav enable 2>&1', $out, $rc);
|
||||
if ($rc !== 0) {
|
||||
$this->lastError = implode(' ', $out) ?: 'Fehler beim Aktivieren.';
|
||||
} else {
|
||||
$this->dispatch('toast', type: 'success', badge: 'ClamAV',
|
||||
title: 'Aktiviert', text: 'ClamAV läuft jetzt und startet automatisch beim Booten.');
|
||||
}
|
||||
$this->refresh();
|
||||
[$ok, $msg] = $this->runCmd('enable');
|
||||
if ($ok) $this->lastSuccess = 'ClamAV wurde aktiviert und gestartet.';
|
||||
else $this->lastError = $msg;
|
||||
$this->running = $this->serviceActive();
|
||||
$this->enabled = $this->serviceEnabled();
|
||||
}
|
||||
|
||||
public function disable(): void
|
||||
{
|
||||
$out = [];
|
||||
@exec('sudo -n /usr/local/sbin/mailwolt-clamav disable 2>&1', $out, $rc);
|
||||
if ($rc !== 0) {
|
||||
$this->lastError = implode(' ', $out) ?: 'Fehler beim Deaktivieren.';
|
||||
} else {
|
||||
$this->dispatch('toast', type: 'success', badge: 'ClamAV',
|
||||
title: 'Deaktiviert', text: 'ClamAV wurde gestoppt und aus dem Autostart entfernt.');
|
||||
}
|
||||
$this->refresh();
|
||||
[$ok, $msg] = $this->runCmd('disable');
|
||||
if ($ok) $this->lastSuccess = 'ClamAV wurde gestoppt und deaktiviert.';
|
||||
else $this->lastError = $msg;
|
||||
$this->running = $this->serviceActive();
|
||||
$this->enabled = $this->serviceEnabled();
|
||||
}
|
||||
|
||||
public function updateDb(): void
|
||||
{
|
||||
$out = [];
|
||||
@exec('sudo -n /usr/local/sbin/mailwolt-clamav freshclam 2>&1', $out, $rc);
|
||||
if ($rc !== 0) {
|
||||
$this->lastError = implode(' ', $out) ?: 'Fehler beim Aktualisieren.';
|
||||
} else {
|
||||
$this->dispatch('toast', type: 'success', badge: 'ClamAV',
|
||||
title: 'Datenbank aktualisiert', text: 'Virensignaturen wurden aktualisiert.');
|
||||
}
|
||||
$this->refresh();
|
||||
[$ok, $msg] = $this->runCmd('freshclam');
|
||||
if ($ok) $this->lastSuccess = 'Virensignaturen wurden aktualisiert.';
|
||||
else $this->lastError = $msg;
|
||||
[$this->dbDate, $this->dbVersion] = $this->readDbInfo();
|
||||
}
|
||||
|
||||
private function runCmd(string $action): array
|
||||
{
|
||||
$out = []; $rc = null;
|
||||
exec('sudo -n /usr/local/sbin/mailwolt-clamav ' . escapeshellarg($action) . ' 2>&1', $out, $rc);
|
||||
\Log::info('ClamAV ' . $action, ['rc' => $rc, 'out' => $out]);
|
||||
$msg = implode(' ', $out) ?: 'Unbekannter Fehler (rc=' . $rc . ')';
|
||||
return [$rc === 0, $msg];
|
||||
}
|
||||
|
||||
private function serviceActive(): bool
|
||||
|
|
|
|||
|
|
@ -19,11 +19,16 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Fehler-Banner --}}
|
||||
@if($lastSuccess)
|
||||
<div style="margin-bottom:16px;padding:10px 14px;background:rgba(52,211,153,.08);border:1px solid rgba(52,211,153,.25);border-radius:8px;display:flex;align-items:center;gap:8px">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" style="color:#34d399;flex-shrink:0"><circle cx="7" cy="7" r="6" stroke="currentColor" stroke-width="1.3"/><path d="M4.5 7l2 2 3-3" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
<span style="font-size:12.5px;color:#6ee7b7;font-weight:500">{{ $lastSuccess }}</span>
|
||||
</div>
|
||||
@endif
|
||||
@if($lastError)
|
||||
<div style="margin-bottom:16px;padding:10px 14px;background:rgba(239,68,68,.08);border:1px solid rgba(239,68,68,.25);border-radius:8px;display:flex;align-items:center;gap:8px">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" style="color:#ef4444;flex-shrink:0"><circle cx="7" cy="7" r="6" stroke="currentColor" stroke-width="1.3"/><path d="M7 4v3.5" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/><circle cx="7" cy="10" r=".6" fill="currentColor"/></svg>
|
||||
<span style="font-size:12.5px;color:#fca5a5">{{ $lastError }}</span>
|
||||
<span style="font-size:12.5px;color:#fca5a5;white-space:pre-wrap">{{ $lastError }}</span>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
|
@ -33,7 +38,13 @@
|
|||
<div style="min-width:0;display:flex;flex-direction:column;gap:16px">
|
||||
|
||||
{{-- Status-Karte --}}
|
||||
<div class="mbx-section">
|
||||
<div class="mbx-section" style="position:relative">
|
||||
<div wire:loading wire:target="enable,disable,install" style="position:absolute;inset:0;background:rgba(0,0,0,.45);border-radius:11px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;z-index:10">
|
||||
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" style="color:#a78bfa;animation:spin 1s linear infinite"><path d="M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>
|
||||
<span style="font-size:12.5px;color:#e2d9fa;font-weight:500" wire:loading wire:target="enable">ClamAV wird gestartet…</span>
|
||||
<span style="font-size:12.5px;color:#e2d9fa;font-weight:500" wire:loading wire:target="disable">ClamAV wird gestoppt…</span>
|
||||
<span style="font-size:12.5px;color:#e2d9fa;font-weight:500" wire:loading wire:target="install">ClamAV wird installiert…</span>
|
||||
</div>
|
||||
<div class="mbx-domain-head">
|
||||
<div class="mbx-domain-info">
|
||||
<span class="mbx-badge-mute">Status</span>
|
||||
|
|
|
|||
Loading…
Reference in New Issue