mailwolt/app/Livewire/Ui/Search/Modal/SearchPaletteModal.php

156 lines
5.5 KiB
PHP

<?php
namespace App\Livewire\Ui\Search\Modal;
use App\Models\Domain;
use App\Models\MailUser;
use App\Models\User; // falls du App\User/Models\User hast, ggf. anpassen
use Livewire\Attributes\Computed;
use LivewireUI\Modal\ModalComponent;
class SearchPaletteModal extends ModalComponent
{
public string $q = '';
/** Konfiguration: neue Bereiche leicht ergänzbar */
private array $sections = [
// key => [label, limit]
'domains' => ['Domains', 8],
'mailboxes' => ['Postfächer',8],
'users' => ['Benutzer', 8],
];
#[Computed]
public function results(): array
{
$term = trim($this->q);
if ($term === '') {
return ['domains'=>[],'mailboxes'=>[],'users'=>[]];
}
$out = [];
// Domains
if (isset($this->sections['domains'])) {
[$label, $limit] = $this->sections['domains'];
$out['domains'] = Domain::query()
->where('is_system', false)
->where('domain', 'like', "%{$term}%")
->orderBy('domain')
->limit($limit)
->get(['id','domain','is_active'])
->map(fn($d)=>[
'id' => $d->id,
'title' => $d->domain,
'sub' => $d->is_active ? 'aktiv' : 'inaktiv',
// 'route' => route('domains.index'), // falls Route existiert
'route' => '#', // falls Route existiert
'type' => 'domain',
])->all();
}
// Mailboxen
if (isset($this->sections['mailboxes'])) {
[$label, $limit] = $this->sections['mailboxes'];
$out['mailboxes'] = \App\Models\MailUser::query()
// INNER JOIN: nur Mailboxen mit gültiger Domain
->join('domains', 'domains.id', '=', 'mail_users.domain_id')
// System-Domains ausschließen
->where('domains.is_system', false)
// Suchterm über localpart, gespeicherte email ODER Domain
->where(function ($w) use ($term) {
$w->where('mail_users.localpart', 'like', "%{$term}%")
->orWhere('mail_users.email', 'like', "%{$term}%")
->orWhere('domains.domain', 'like', "%{$term}%");
})
->orderBy('domains.domain')
->orderBy('mail_users.localpart')
->limit($limit)
->get([
'mail_users.id',
'mail_users.localpart',
'mail_users.email',
'mail_users.is_active',
'domains.domain as dom',
'domains.is_active as dom_active',
])
->map(function ($r) {
// Email bevorzugt rohe DB-Spalte; sonst sauber zusammensetzen
$rawEmail = $r->getRawOriginal('email');
$title = $rawEmail ?: ($r->localpart && $r->dom ? "{$r->localpart}@{$r->dom}" : '');
// Falls aus irgendeinem Grund beides leer wäre, gar keinen Geister-„@“ anzeigen:
if ($title === '') {
return null; // überspringen
}
$sub = ($r->dom_active ? '' : 'Domain inaktiv · ')
. ($r->is_active ? 'aktiv' : 'inaktiv');
return [
'id' => (int)$r->id,
'title' => $title,
'sub' => $sub,
'route' => '#',
'type' => 'mailbox',
];
})
->filter() // nulls (leere Titel) raus
->values()
->all();
}
// Benutzer (optional)
if (class_exists(User::class) && isset($this->sections['users'])) {
[$label, $limit] = $this->sections['users'];
$out['users'] = User::query()
->where(function($w) use ($term){
$w->where('name','like',"%{$term}%")
->orWhere('email','like',"%{$term}%");
})
->orderBy('name')
->limit($limit)
->get(['id','name','email'])
->map(fn($u)=>[
'id' => $u->id,
'title' => $u->name,
'sub' => $u->email,
'route' => '#', // ggf. Profilroute hinterlegen
'type' => 'user',
])->all();
}
return $out;
}
public function go(string $type, int $id): void
{
// Schließe die Palette …
$this->dispatch('closeModal');
// … und navigiere / öffne Kontext:
// - Domain → scrolle/markiere Domainkarte
// - Mailbox → öffne Bearbeiten-Modal
// Passe an, was du bevorzugst:
if ($type === 'domain') {
$this->dispatch('focus:domain', id: $id);
} elseif ($type === 'mailbox') {
// direkt Edit-Modal auf
$this->dispatch('openModal', component:'ui.mail.modal.mailbox-edit-modal', arguments: [$id]);
} elseif ($type === 'user') {
$this->dispatch('focus:user', id: $id);
}
}
public static function modalMaxWidth(): string
{
return '2xl';
}
public function render()
{
return view('livewire.ui.search.modal.search-palette-modal');
}
}