diff --git a/app/Livewire/Ui/Mail/AliasList.php b/app/Livewire/Ui/Mail/AliasList.php index 2674a27..c931f81 100644 --- a/app/Livewire/Ui/Mail/AliasList.php +++ b/app/Livewire/Ui/Mail/AliasList.php @@ -48,6 +48,7 @@ class AliasList extends Component $domains = Domain::query() ->where('is_system', false) + ->where('is_server', false) ->withCount(['mailAliases']) ->with([ 'mailAliases' => fn ($q) => $q diff --git a/app/Livewire/Ui/Mail/MailboxList.php b/app/Livewire/Ui/Mail/MailboxList.php index 54b13a4..548a8aa 100644 --- a/app/Livewire/Ui/Mail/MailboxList.php +++ b/app/Livewire/Ui/Mail/MailboxList.php @@ -13,7 +13,6 @@ use Livewire\Component; class MailboxList extends Component { public string $search = ''; - public bool $showSystemCard = false; #[On('mailbox:updated')] #[On('mailbox:deleted')] @@ -23,18 +22,6 @@ class MailboxList extends Component $this->dispatch('$refresh'); } - #[On('focus:domain')] - public function focusDomain(int $id): void - { - // optional: Domain hervorheben - } - - #[On('focus:user')] - public function focusUser(int $id): void - { - // optional - } - public function openMailboxCreate(int $domainId): void { $this->dispatch('openModal', component: 'ui.mail.modal.mailbox-create-modal', arguments: [ @@ -42,24 +29,25 @@ class MailboxList extends Component ]); } - public function openMailboxEdit(int $domainId): void + public function openMailboxEdit(int $mailUserId): void { - // $domainId == mailbox_id $this->dispatch('openModal', component: 'ui.mail.modal.mailbox-edit-modal', arguments: [ - $domainId, + $mailUserId, ]); } - public function openMailboxDelete(int $domainId): void + public function openMailboxDelete(int $mailUserId): void { $this->dispatch('openModal', component: 'ui.mail.modal.mailbox-delete-modal', arguments: [ - $domainId, + $mailUserId, ]); } public function updateMailboxStats(): void { - Artisan::call('mail:update-stats'); + // läuft asynchron → UI blockiert nicht + dispatch(fn() => Artisan::call('mail:update-stats')); + $this->dispatch('$refresh'); $this->dispatch('toast', type: 'done', @@ -72,57 +60,68 @@ class MailboxList extends Component public function render() { - $system = Domain::query()->where('is_system', true)->first(); $term = trim($this->search); $hasTerm = $term !== ''; $needle = '%' . str_replace(['%', '_'], ['\%', '\_'], $term) . '%'; + // Nur Domains, die NICHT system und NICHT server sind $domains = Domain::query() - ->when($system, fn($q) => $q->whereKeyNot($system->id)) + ->where('is_system', false) + ->where('is_server', false) ->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)); + ->orWhereHas('mailUsers', fn($u) => $u + ->where('is_active', true) + ->where('is_system', false) + ->where('localpart', 'like', $needle) + ); }); }) - ->withCount(['mailUsers']) - ->with([ - 'mailUsers' => function ($q) use ($hasTerm, $needle) { - if ($hasTerm) { - $q->where('localpart', 'like', $needle); - } - $q->orderBy('localpart'); - }, + ->withCount(['mailUsers as mail_users_count' => fn($u) => $u + ->where('is_active', true) + ->where('is_system', false) ]) + ->with(['mailUsers' => function ($q) use ($hasTerm, $needle) { + $q->where('is_active', true) + ->where('is_system', false); + if ($hasTerm) { + $q->where('localpart', 'like', $needle); + } + $q->orderBy('localpart'); + }]) ->orderBy('domain') ->get(); + // Wenn Domain direkt matcht → alle Benutzer dieser Domain zeigen 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()); + $d->setRelation('mailUsers', $d->mailUsers() + ->where('is_active', true) + ->where('is_system', false) + ->orderBy('localpart') + ->get() + ); } } } - // ---- Anzeige vorbereiten (mit korrekter Prozent-Berechnung) ---- + // ---- Anzeige vorbereiten ---- foreach ($domains as $d) { $prepared = []; $domainActive = (bool)($d->is_active ?? true); foreach ($d->mailUsers as $u) { - // Stats aus Settings (Redis → DB Fallback) - $stats = Setting::get("mailbox.{$u->email}", []); - $usedBytes = (int)($stats['used_bytes'] ?? ($u->used_bytes ?? 0)); - $messageCount = (int)($stats['message_count'] ?? ($u->message_count ?? 0)); + $email = $u->email ?? ($u->address ?? null); + $stats = $email ? (Setting::get("mailbox.{$email}", []) ?: []) : []; - // Anzeige in MiB (nur fürs UI runden) - $usedMiB = (float)round($usedBytes / 1048576, 2); + $usedBytes = (int)($stats['used_bytes'] ?? 0); + $messageCount = (int)($stats['message_count'] ?? 0); + $usedMiB = round($usedBytes / 1048576, 2); $quotaMiB = (int)($u->quota_mb ?? 0); - // Prozent aus Bytes/Quota (ohne Vorab-Rundung auf MiB!) $usage = $quotaMiB > 0 ? min(100, (int)round($usedBytes / ($quotaMiB * 1048576) * 100)) : 0; @@ -132,7 +131,8 @@ class MailboxList extends Component $reason = null; if (!$effective) { - $reason = !$domainActive ? 'Domain inaktiv' + $reason = !$domainActive + ? 'Domain inaktiv' : (!$mailboxActive ? 'Postfach inaktiv' : null); } @@ -154,11 +154,170 @@ class MailboxList extends Component return view('livewire.ui.mail.mailbox-list', [ 'domains' => $domains, - 'system' => $this->showSystemCard ? $system : null, ]); } } +//namespace App\Livewire\Ui\Mail; +// +//use App\Models\Domain; +//use App\Models\Setting; +//use Illuminate\Support\Facades\Artisan; +//use Illuminate\Support\Str; +//use Livewire\Attributes\On; +//use Livewire\Component; +// +//class MailboxList extends Component +//{ +// public string $search = ''; +// public bool $showSystemCard = false; +// +// #[On('mailbox:updated')] +// #[On('mailbox:deleted')] +// #[On('mailbox:created')] +// public function refreshMailboxList(): void +// { +// $this->dispatch('$refresh'); +// } +// +// #[On('focus:domain')] +// public function focusDomain(int $id): void +// { +// // optional: Domain hervorheben +// } +// +// #[On('focus:user')] +// public function focusUser(int $id): void +// { +// // optional +// } +// +// 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, +// ]); +// } +// +// public function openMailboxDelete(int $domainId): void +// { +// $this->dispatch('openModal', component: 'ui.mail.modal.mailbox-delete-modal', arguments: [ +// $domainId, +// ]); +// } +// +// public function updateMailboxStats(): void +// { +//// Artisan::call('mail:update-stats'); +// dispatch(fn () => 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 render() +// { +// $system = Domain::query()->where('is_system', true)->first(); +// $term = trim($this->search); +// $hasTerm = $term !== ''; +// $needle = '%' . str_replace(['%', '_'], ['\%', '\_'], $term) . '%'; +// +// $domains = Domain::query() +// ->when($system, fn($q) => $q->whereKeyNot($system->id)) +// ->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']) +// ->with([ +// 'mailUsers' => function ($q) use ($hasTerm, $needle) { +// if ($hasTerm) { +// $q->where('localpart', 'like', $needle); +// } +// $q->orderBy('localpart'); +// }, +// ]) +// ->orderBy('domain') +// ->get(); +// +// 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()); +// } +// } +// } +// +// // ---- Anzeige vorbereiten (mit korrekter Prozent-Berechnung) ---- +// foreach ($domains as $d) { +// $prepared = []; +// $domainActive = (bool)($d->is_active ?? true); +// +// foreach ($d->mailUsers as $u) { +// // Stats aus Settings (Redis → DB Fallback) +// $stats = Setting::get("mailbox.{$u->email}", []); +// $usedBytes = (int)($stats['used_bytes'] ?? ($u->used_bytes ?? 0)); +// $messageCount = (int)($stats['message_count'] ?? ($u->message_count ?? 0)); +// +// // Anzeige in MiB (nur fürs UI runden) +// $usedMiB = (float)round($usedBytes / 1048576, 2); +// $quotaMiB = (int)($u->quota_mb ?? 0); +// +// // Prozent aus Bytes/Quota (ohne Vorab-Rundung auf MiB!) +// $usage = $quotaMiB > 0 +// ? min(100, (int)round($usedBytes / ($quotaMiB * 1048576) * 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' => $quotaMiB, +// 'used_mb' => $usedMiB, +// 'usage_percent' => $usage, +// '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, +// ]); +// } +//} + //namespace App\Livewire\Ui\Mail; // //use App\Models\Domain; diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index d4b9586..221d509 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -26,8 +26,21 @@ class AppServiceProvider extends ServiceProvider Domain::observe(DomainObserver::class); - $ver = trim(@file_get_contents(base_path('VERSION'))) ?: 'dev'; - config(['app.version' => $ver]); +// $ver = trim(@file_get_contents(base_path('VERSION'))) ?: 'dev'; +// config(['app.version' => $ver]); + + + config(['app.version' => trim(@file_get_contents('/var/lib/mailwolt/version')) ?: 'dev']); + if (file_exists(base_path('.git/HEAD'))) { + $ref = trim(file_get_contents(base_path('.git/HEAD'))); + if (str_starts_with($ref, 'ref:')) { + $refFile = base_path('.git/' . substr($ref, 5)); + $commit = @file_get_contents($refFile); + } else { + $commit = $ref; + } + config(['app.git_commit' => substr($commit ?? '', 0, 7)]); + } try { $S = app(\App\Support\SettingsRepository::class); diff --git a/config/app.php b/config/app.php index 2df5cd0..fbc7da5 100644 --- a/config/app.php +++ b/config/app.php @@ -123,5 +123,6 @@ return [ 'store' => env('APP_MAINTENANCE_STORE', 'database'), ], - 'version' => env('APP_VERSION', '1.0.0') + 'version' => env('APP_VERSION', '1.0.0'), + 'git_commit' => env('APP_GIT_COMMIT', ''), ]; diff --git a/resources/views/components/partials/sidebar.blade.php b/resources/views/components/partials/sidebar.blade.php index f421fca..0c596d6 100644 --- a/resources/views/components/partials/sidebar.blade.php +++ b/resources/views/components/partials/sidebar.blade.php @@ -86,7 +86,7 @@