Fix: Mailbox Stats über Dovecot mit config/mailpool.php

main v1.0.65
boban 2025-10-26 20:54:57 +01:00
parent 3b816e2198
commit d6f0c5d7cb
1 changed files with 112 additions and 41 deletions

View File

@ -45,60 +45,56 @@ class ServicesCard extends Component
public function load(): void public function load(): void
{ {
// 1) Karten aus Config laden
$cards = config('woltguard.cards', []); $cards = config('woltguard.cards', []);
if (empty($cards)) { // 1) Cache lesen (versionierter Key)
// Config-Clear/-Cache synchron ausführen (kostet ~ms) $raw = Cache::get(CacheVer::k('health:services'));
try {
Artisan::call('config:clear'); // 2) Neues Format { ts, rows } → entpacken
Artisan::call('config:cache'); if (is_array($raw) && array_key_exists('rows', $raw)) {
} catch (\Throwable $e) { $raw = $raw['rows'];
// ignoriere UI soll trotzdem laufen
}
$cards = config('woltguard.cards', []);
} }
// 2) Service-Status aus Cache (versionierter Key) // 3) Fallback: Legacy-Key ODER Settings (DB/Redis) ebenfalls entpacken
$key = \App\Support\CacheVer::k('health:services'); if (empty($raw)) {
$raw = Cache::get($key, []); $legacy = Cache::get('health:services', []);
// Legacy-Key als Fallback if (is_array($legacy) && array_key_exists('rows', $legacy)) {
if (empty($raw)) $raw = Cache::get('health:services', []); $raw = $legacy['rows'];
} elseif (!empty($legacy)) {
$raw = $legacy;
} else {
// persistierter Payload aus DB (Settings)
$persist = \App\Support\Setting::get('woltguard.services', []);
$raw = (is_array($persist) && isset($persist['rows']) && is_array($persist['rows']))
? $persist['rows']
: [];
}
}
// Ab hier ist $raw eine Liste von {name, ok}
$cached = collect($raw)->keyBy('name'); $cached = collect($raw)->keyBy('name');
$rows = []; $rows = [];
$ok = 0; foreach ($cards as $key => $card) {
$isOk = (bool) ($cached->get($key)['ok'] ?? false);
foreach ($cards as $name => $card) { // Nur wenn wirklich gar nichts im Cache ist, aktiv prüfen
$isOk = (bool) ($cached->get($name)['ok'] ?? false);
// 3) Wenn Cache leer → aktiv prüfen
if ($cached->isEmpty()) { if ($cached->isEmpty()) {
foreach ($card['sources'] as $src) { foreach ($card['sources'] as $src) {
if ($this->check($src)) { $isOk = true; break; } if ($this->check($src)) { $isOk = true; break; }
} }
} }
if ($isOk) $ok++;
$rows[] = [ $rows[] = [
'name' => $name, // <— wichtig, damit der Cache keyBy('name') später klappt 'label' => $card['label'],
'label' => $card['label'] ?? $name, 'hint' => $card['hint'],
'hint' => $card['hint'] ?? null,
'ok' => $isOk, 'ok' => $isOk,
]; ];
} }
// 4) Wenn wir aktiv geprüft haben (Cache war leer) → Cache auffüllen // Zähler / Badge / Compact wie vorher…
if ($cached->isEmpty() && !empty($rows)) {
Cache::put($key, $rows, 600); // 10 Minuten
Cache::forget('health:services'); // Legacy aufräumen
}
// 5) Kopfzahlen + UI-Daten
$this->totalCount = count($rows); $this->totalCount = count($rows);
$this->okCount = $ok; $this->okCount = collect($rows)->where('ok', true)->count();
$this->guardOk = $this->totalCount > 0 && $this->okCount === $this->totalCount; $this->guardOk = $this->totalCount > 0 && $this->okCount === $this->totalCount;
[$this->badgeText, $this->badgeClass, $this->badgeIcon] = [$this->badgeText, $this->badgeClass, $this->badgeIcon] =
@ -106,18 +102,93 @@ class ServicesCard extends Component
? ['alle Dienste OK', 'text-emerald-200 bg-emerald-500/10 border-emerald-400/30', 'ph ph-check-circle'] ? ['alle Dienste OK', 'text-emerald-200 bg-emerald-500/10 border-emerald-400/30', 'ph ph-check-circle']
: ["{$this->okCount}/{$this->totalCount} aktiv", 'text-amber-200 bg-amber-500/10 border-amber-400/30', 'ph ph-warning']; : ["{$this->okCount}/{$this->totalCount} aktiv", 'text-amber-200 bg-amber-500/10 border-amber-400/30', 'ph ph-warning'];
$this->servicesCompact = collect($rows)->map(fn($r) => [ $this->servicesCompact = collect($rows)->map(fn($row) => [
'label' => $r['label'], 'label' => $row['label'],
'hint' => $r['hint'], 'hint' => $row['hint'],
'ok' => $r['ok'], 'ok' => $row['ok'],
'dotClass' => $r['ok'] ? 'bg-emerald-400' : 'bg-rose-400', 'dotClass' => $row['ok'] ? 'bg-emerald-400' : 'bg-rose-400',
'pillText' => $r['ok'] ? 'Online' : 'Offline', 'pillText' => $row['ok'] ? 'Online' : 'Offline',
'pillClass' => $r['ok'] 'pillClass' => $row['ok']
? 'text-emerald-300 border-emerald-400/30 bg-emerald-500/10' ? 'text-emerald-300 border-emerald-400/30 bg-emerald-500/10'
: 'text-rose-300 border-rose-400/30 bg-rose-500/10', : 'text-rose-300 border-rose-400/30 bg-rose-500/10',
])->all(); ])->all();
} }
// public function load(): void
// {
// // 1) Karten aus Config laden
// $cards = config('woltguard.cards', []);
//
// if (empty($cards)) {
// // Config-Clear/-Cache synchron ausführen (kostet ~ms)
// try {
// Artisan::call('config:clear');
// Artisan::call('config:cache');
// } catch (\Throwable $e) {
// // ignoriere UI soll trotzdem laufen
// }
// $cards = config('woltguard.cards', []);
// }
//
// // 2) Service-Status aus Cache (versionierter Key)
// $key = \App\Support\CacheVer::k('health:services');
// $raw = Cache::get($key, []);
// // Legacy-Key als Fallback
// if (empty($raw)) $raw = Cache::get('health:services', []);
//
// $cached = collect($raw)->keyBy('name');
//
// $rows = [];
// $ok = 0;
//
// foreach ($cards as $name => $card) {
// $isOk = (bool) ($cached->get($name)['ok'] ?? false);
//
// // 3) Wenn Cache leer → aktiv prüfen
// if ($cached->isEmpty()) {
// foreach ($card['sources'] as $src) {
// if ($this->check($src)) { $isOk = true; break; }
// }
// }
//
// if ($isOk) $ok++;
//
// $rows[] = [
// 'name' => $name, // <— wichtig, damit der Cache keyBy('name') später klappt
// 'label' => $card['label'] ?? $name,
// 'hint' => $card['hint'] ?? null,
// 'ok' => $isOk,
// ];
// }
//
// // 4) Wenn wir aktiv geprüft haben (Cache war leer) → Cache auffüllen
// if ($cached->isEmpty() && !empty($rows)) {
// Cache::put($key, $rows, 600); // 10 Minuten
// Cache::forget('health:services'); // Legacy aufräumen
// }
//
// // 5) Kopfzahlen + UI-Daten
// $this->totalCount = count($rows);
// $this->okCount = $ok;
// $this->guardOk = $this->totalCount > 0 && $this->okCount === $this->totalCount;
//
// [$this->badgeText, $this->badgeClass, $this->badgeIcon] =
// $this->guardOk
// ? ['alle Dienste OK', 'text-emerald-200 bg-emerald-500/10 border-emerald-400/30', 'ph ph-check-circle']
// : ["{$this->okCount}/{$this->totalCount} aktiv", 'text-amber-200 bg-amber-500/10 border-amber-400/30', 'ph ph-warning'];
//
// $this->servicesCompact = collect($rows)->map(fn($r) => [
// 'label' => $r['label'],
// 'hint' => $r['hint'],
// 'ok' => $r['ok'],
// 'dotClass' => $r['ok'] ? 'bg-emerald-400' : 'bg-rose-400',
// 'pillText' => $r['ok'] ? 'Online' : 'Offline',
// 'pillClass' => $r['ok']
// ? 'text-emerald-300 border-emerald-400/30 bg-emerald-500/10'
// : 'text-rose-300 border-rose-400/30 bg-rose-500/10',
// ])->all();
// }
// public function load(): void // public function load(): void
// { // {
// $cards = config('woltguard.cards', []); // $cards = config('woltguard.cards', []);