dispatch('$refresh'); } #[On('focus:domain')] public function focusDomain(int $id): void { // z. B. Domain nach oben holen / scrollen / highlighten // oder direkt den "+ Postfach" Dialog: // $this->openMailboxCreate($id); } #[On('focus:user')] public function focusUser(int $id): void { // später: Benutzerseite / Filter setzen ... } public function openMailboxCreate(int $domainId): void { $this->dispatch('openModal', component: 'ui.mail.modal.mailbox-create-modal', arguments: [ 'domainId' => $domainId, ]); } public function openMailboxEdit(int $domainId): void { // $domainId == mailbox_id $this->dispatch('openModal', component: 'ui.mail.modal.mailbox-edit-modal', arguments: [ $domainId, // <— nur der Wert, kein Key! ]); } public function openMailboxDelete(int $domainId): void { $this->dispatch('openModal', component: 'ui.mail.modal.mailbox-delete-modal', arguments: [ $domainId, // <— nur der Wert, kein Key! ]); } public function updateMailboxStats() { // führe Artisan-Command direkt aus Artisan::call('mail:update-stats'); $this->dispatch('$refresh'); $this->dispatch('toast', type: 'done', badge: 'Mailbox', title: 'Mailbox aktualisiert', text: 'Die Mailbox-Statistiken wurden aktualisiert.', duration: 6000, ); } public function updateMailboxStatsOne(string $email) { Artisan::call('mail:update-stats', ['--user' => $email]); $this->dispatch('$refresh'); $this->dispatch('toast', type: 'done', badge: 'Mailbox', title: 'Mailbox aktualisiert', text: 'Die Mailbox-Statistiken wurden aktualisiert.', duration: 6000 ); } public function render() { $system = Domain::query()->where('is_system', true)->first(); $term = trim($this->search); $hasTerm = $term !== ''; $needle = '%'.str_replace(['%','_'], ['\%','\_'], $term).'%'; // LIKE-sicher $domains = Domain::query() ->when($system, fn ($q) => $q->whereKeyNot($system->id)) // Domain selbst ODER MailUser müssen matchen ->when($hasTerm, function ($q) use ($needle) { $q->where(function ($w) use ($needle) { $w->where('domain', 'like', $needle) ->orWhereHas('mailUsers', fn($u) => $u->where('localpart', 'like', $needle)); }); }) ->withCount(['mailUsers']) // Relationen zunächst ggf. gefiltert laden ->with([ 'mailUsers' => function ($q) use ($hasTerm, $needle) { if ($hasTerm) $q->where('localpart', 'like', $needle); $q->orderBy('localpart'); }, ]) ->orderBy('domain') ->get(); // Wenn der Domainname selbst matched → alle Mailboxen/Aliasse vollständig nachladen if ($hasTerm) { $lower = Str::lower($term); foreach ($domains as $d) { if (Str::contains(Str::lower($d->domain), $lower)) { $d->setRelation('mailUsers', $d->mailUsers()->orderBy('localpart')->get()); $d->setRelation('mailAliases', $d->mailAliases()->orderBy('local')->get()); } } } // Vorbereitung für Blade foreach ($domains as $d) { $prepared = []; $domainActive = (bool)($d->is_active ?? true); foreach ($d->mailUsers as $u) { $email = trim($u->email ?? '') !== '' ? $u->email : ($u->localpart !== '' ? ($u->localpart.'@'.$d->domain) : null); $stats = $email ? Setting::get("mailbox.$email") : null; $usedBytes = is_array($stats) && isset($stats['used_bytes']) ? (int)$stats['used_bytes'] : (int)($u->used_bytes ?? 0); $messageCount = is_array($stats) && isset($stats['message_count']) ? (int)$stats['message_count'] : (int)($u->message_count ?? 0); $usedMB = (int) round($usedBytes / 1024 / 1024); $quota = (int)($u->quota_mb ?? 0); $usage = $quota > 0 ? min(100, (int) round($usedMB / max(1, $quota) * 100)) : 0; $mailboxActive = (bool)($u->is_active ?? true); $effective = $domainActive && $mailboxActive; $reason = null; if (!$effective) { $reason = !$domainActive ? 'Domain inaktiv' : (!$mailboxActive ? 'Postfach inaktiv' : null); } $prepared[] = [ 'id' => $u->id, 'localpart' => (string)$u->localpart, 'quota_mb' => $quota, 'usage_percent' => $usage, 'used_mb' => $usedMB, // MiB fürs UI 'message_count' => $messageCount, 'is_active' => $mailboxActive, 'is_effective_active' => $effective, 'inactive_reason' => $reason, ]; } $d->prepared_mailboxes = $prepared; } return view('livewire.ui.mail.mailbox-list', [ 'domains' => $domains, 'system' => $this->showSystemCard ? $system : null, ]); } // public function render() // { // $system = Domain::query()->where('is_system', true)->first(); // $term = trim($this->search); // $hasTerm = $term !== ''; // $needle = '%'.str_replace(['%','_'], ['\%','\_'], $term).'%'; // LIKE-sicher // // $domains = Domain::query() // ->when($system, fn ($q) => $q->whereKeyNot($system->id)) // // // Domain selbst ODER MailUser/ Aliasse müssen matchen // ->when($hasTerm, function ($q) use ($needle) { // $q->where(function ($w) use ($needle) { // $w->where('domain', 'like', $needle) // ->orWhereHas('mailUsers', fn($u) => $u->where('localpart', 'like', $needle)); // }); // }) // // ->withCount(['mailUsers']) // // // Beziehungen zunächst gefiltert laden (damit "test" nur passende Mailboxen zeigt) // ->with([ // 'mailUsers' => function ($q) use ($hasTerm, $needle) { // if ($hasTerm) $q->where('localpart', 'like', $needle); // $q->orderBy('localpart'); // }, // ]) // // ->orderBy('domain') // ->get(); // // // Domains, deren NAME den Suchbegriff trifft → ALLE Mailboxen/Aliasse zeigen // if ($hasTerm) { // $lower = Str::lower($term); // foreach ($domains as $d) { // if (Str::contains(Str::lower($d->domain), $lower)) { // // volle Relationen nachladen (überschreibt die gefilterten) // $d->setRelation('mailUsers', $d->mailUsers()->orderBy('localpart')->get()); // $d->setRelation('mailAliases', $d->mailAliases()->orderBy('local')->get()); // } // } // } // // // Vorbereitung für Blade (unverändert, arbeitet auf den ggf. gefilterten Relationen) // foreach ($domains as $d) { // $prepared = []; // $domainActive = (bool)($d->is_active ?? true); // // foreach ($d->mailUsers as $u) { // $stats = Setting::get("mailbox.{$u->email}"); // $usedBytes = $stats['used_bytes'] ?? ($u->used_bytes ?? 0); // $messageCount = $stats['message_count'] ?? ($u->message_count ?? 0); // $usedMB = (int) round(($usedBytes) / 1024 / 1024); // $quota = (int)($u->quota_mb ?? 0); // $usage = $quota > 0 ? min(100, (int) round($usedMB / max(1,$quota) * 100)) : 0; // // //// $quota = (int)($u->quota_mb ?? 0); //// $used = (int)($u->used_mb ?? 0); //// $usage = $quota > 0 ? min(100, (int)round($used / max(1, $quota) * 100)) : 0; // // $mailboxActive = (bool)($u->is_active ?? true); // $effective = $domainActive && $mailboxActive; // // $reason = null; // if (!$effective) { // $reason = !$domainActive ? 'Domain inaktiv' // : (!$mailboxActive ? 'Postfach inaktiv' : null); // } // // $prepared[] = [ // 'id' => $u->id, // 'localpart' => (string)$u->localpart, // 'quota_mb' => $quota, // 'usage_percent' => $usage, // 'used_mb' => $usedMB, // 'message_count' => $messageCount, // 'is_active' => $mailboxActive, // 'is_effective_active' => $effective, // 'inactive_reason' => $reason, // ]; // } // // // für Blade // $d->prepared_mailboxes = $prepared; // } // // return view('livewire.ui.mail.mailbox-list', [ // 'domains' => $domains, // 'system' => $this->showSystemCard ? $system : null, // ]); // } // public function render() // { // $system = Domain::query()->where('is_system', true)->first(); // $term = trim($this->search); // // $domains = Domain::query() // ->when($system, fn ($q) => $q->where('id', '!=', $system->id)) // ->withCount(['mailUsers','mailAliases']) // ->with([ // 'mailUsers' => fn ($q) => $q->orderBy('localpart'), // 'mailAliases' => fn ($q) => $q->orderBy('local'), // ]) // ->when($term !== '', function ($q) use ($term) { // $q->where(function ($w) use ($term) { // $w->where('domain', 'like', "%{$term}%") // ->orWhereHas('mailUsers', fn($u) => // $u->where('localpart', 'like', "%{$term}%") // ); // }); // }) // ->orderBy('domain') // ->get(); // // // Vorbereitung für Blade (unverändert) // foreach ($domains as $d) { // $prepared = []; // $domainActive = (bool)($d->is_active ?? true); // // foreach ($d->mailUsers as $u) { // $quota = (int) ($u->quota_mb ?? 0); // $used = (int) ($u->used_mb ?? 0); // $usage = $quota > 0 ? min(100, (int) round($used / max(1,$quota) * 100)) : 0; // // $mailboxActive = (bool)($u->is_active ?? true); // $effective = $domainActive && $mailboxActive; // // $reason = null; // if (!$effective) { // $reason = !$domainActive ? 'Domain inaktiv' // : (!$mailboxActive ? 'Postfach inaktiv' : null); // } // // $prepared[] = [ // 'id' => $u->id, // 'localpart' => (string) $u->localpart, // 'quota_mb' => $quota, // 'used_mb' => $used, // 'usage_percent' => $usage, // 'message_count' => (int) ($u->message_count ?? $u->mails_count ?? 0), // 'is_active' => $mailboxActive, // 'is_effective_active' => $effective, // 'inactive_reason' => $reason, // ]; // } // // $d->prepared_mailboxes = $prepared; // } // // return view('livewire.ui.mail.mailbox-list', [ // 'domains' => $domains, // 'system' => $this->showSystemCard ? $system : null, // ]); // } // public function render() // { // $system = Domain::query()->where('is_system', true)->first(); // // $term = trim($this->search); // // $domains = Domain::query() // ->when($system, fn ($q) => $q->where('id', '!=', $system->id)) // ->withCount(['mailUsers','mailAliases']) // ->with([ // 'mailUsers' => fn ($q) => $q->orderBy('localpart'), // 'mailAliases' => fn ($q) => $q->orderBy('source'), // ]) // ->when($term !== '', function ($q) use ($term) { // $q->where(function ($w) use ($term) { // $w->where('domain', 'like', "%{$term}%") // ->orWhereHas('mailUsers', fn($u) => // $u->where('localpart', 'like', "%{$term}%") // ); // }); // }) // ->orderBy('domain') // ->get(); // // // Für das Blade vorbereiten (ohne Relations zu mutieren) // foreach ($domains as $d) { // $prepared = []; // $domainActive = (bool)($d->is_active ?? true); // // foreach ($d->mailUsers as $u) { // $quota = (int) ($u->quota_mb ?? 0); // $used = (int) ($u->used_mb ?? 0); // $usage = $quota > 0 ? min(100, (int) round($used / max(1,$quota) * 100)) : 0; // // $mailboxActive = (bool)($u->is_active ?? true); // $effective = $domainActive && $mailboxActive; // // $reason = null; // if (!$effective) { // $reason = !$domainActive ? 'Domain inaktiv' // : (!$mailboxActive ? 'Postfach inaktiv' : null); // } // // $prepared[] = [ // 'id' => $u->id, // 'localpart' => (string) $u->localpart, // 'quota_mb' => $quota, // 'used_mb' => $used, // 'usage_percent' => $usage, // 'message_count' => (int) ($u->message_count ?? $u->mails_count ?? 0), // 'is_active' => $mailboxActive, // ursprünglicher Flag (falls du ihn brauchst) // 'is_effective_active' => $effective, // ← NEU: Domain & Mailbox aktiv? // 'inactive_reason' => $reason, // ← NEU: warum gesperrt // ]; // } // // $d->prepared_mailboxes = $prepared; // } // // return view('livewire.ui.mail.mailbox-list', [ // 'domains' => $domains, // 'system' => $this->showSystemCard ? $system : null, // ]); // } } //namespace App\Livewire\Ui\Mail; // //use App\Models\Domain; //use Livewire\Component; // //class MailboxList extends Component //{ // public string $search = ''; // public bool $showSystemCard = false; // optional: Info-Karte anzeigen // // public function openMailboxCreate(int $domainId): void // { // $this->dispatch('openModal', component: 'ui.mail.modal.mailbox-create-modal', arguments: [ // 'domainId' => $domainId, // ]); // } // // public function render() // { // // System-Domain direkt aus der DB (bool Spalte: is_system) // $system = Domain::query() // ->where('is_system', true) // <-- deine DB-Flag-Spalte // ->first(); // // // Benutzer-Domains (ohne System-Domain) // $domains = Domain::query() // ->when($system, fn($q) => $q->where('id', '!=', $system->id)) // ->withCount(['mailUsers', 'mailAliases']) // ->with([ // 'mailUsers' => fn($q) => $q->orderBy('localpart'), // 'mailAliases' => fn($q) => $q->orderBy('source'), // ]) // ->when($this->search !== '', function ($q) { // $q->where('domain', 'like', "%{$this->search}%") // ->orWhereHas('mailUsers', fn($qq) => $qq->where('localpart', 'like', "%{$this->search}%")); // }) // ->orderBy('domain') // falls bei dir anders: exakt die vorhandene Spalte eintragen // ->get(); // // // Alle Mailboxen vorbereiten (keine Logik im Blade) // $domains->each(function ($domain) { // $domain->mailUsers->transform(function ($u) use ($domain) { // $quota = (int)($u->quota_mb ?? 0); // $used = (int)($u->used_mb ?? 0); // $usage = $quota > 0 ? min(100, round(($used / max(1, $quota)) * 100)) : 0; // // // neue Properties für das Blade // $u->email = $u->localpart ? "{$u->localpart}@{$domain->domain}" : '—'; // $u->quota_mb = $quota; // $u->used_mb = $used; // $u->usage_percent = $usage; // $u->message_count = (int)($u->message_count ?? $u->mails_count ?? 0); // // return $u; // }); // }); // // // return view('livewire.ui.mail.mailbox-list', [ // 'domains' => $domains, // 'system' => $this->showSystemCard ? $system : null, // read-only Karte optional // ]); // } //}