156 lines
5.5 KiB
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');
|
|
}
|
|
}
|