parent
0beb12569b
commit
afce3d9687
|
|
@ -29,26 +29,46 @@ class QuarantineList extends Component
|
||||||
#[On('quarantine:updated')]
|
#[On('quarantine:updated')]
|
||||||
public function refresh(): void {}
|
public function refresh(): void {}
|
||||||
|
|
||||||
public function clearHistory(): void
|
// ── Löschen (lokal via Cache, RSpamd hat keine per-entry API) ────────────
|
||||||
{
|
|
||||||
$password = env('RSPAMD_PASSWORD', '');
|
|
||||||
$opts = [
|
|
||||||
'http' => [
|
|
||||||
'method' => 'POST',
|
|
||||||
'timeout' => 5,
|
|
||||||
'ignore_errors' => true,
|
|
||||||
'content' => '',
|
|
||||||
'header' => "Content-Type: application/json\r\n" .
|
|
||||||
($password !== '' ? "Password: {$password}\r\n" : ''),
|
|
||||||
],
|
|
||||||
];
|
|
||||||
$ctx = stream_context_create($opts);
|
|
||||||
@file_get_contents('http://127.0.0.1:11334/historyreset', false, $ctx);
|
|
||||||
|
|
||||||
$this->dispatch('toast', type: 'done', badge: 'Quarantäne',
|
private function hiddenKey(): string
|
||||||
title: 'Verlauf geleert',
|
{
|
||||||
text: 'RSpamd-History wurde zurückgesetzt.',
|
return 'quarantine.hidden.' . session()->getId();
|
||||||
duration: 3000);
|
}
|
||||||
|
|
||||||
|
private function getHidden(): array
|
||||||
|
{
|
||||||
|
return \Cache::get($this->hiddenKey(), []);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function saveHidden(array $ids): void
|
||||||
|
{
|
||||||
|
\Cache::put($this->hiddenKey(), array_values(array_unique($ids)), now()->addDays(7));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteEntry(string $id): void
|
||||||
|
{
|
||||||
|
$hidden = $this->getHidden();
|
||||||
|
$hidden[] = $id;
|
||||||
|
$this->saveHidden($hidden);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteCurrentTab(): void
|
||||||
|
{
|
||||||
|
$all = $this->fetchHistory();
|
||||||
|
$hidden = $this->getHidden();
|
||||||
|
|
||||||
|
$toHide = match($this->filter) {
|
||||||
|
'suspicious' => array_filter($all, fn($m) => $m['action'] !== 'no action'),
|
||||||
|
'all' => $all,
|
||||||
|
default => array_filter($all, fn($m) => $m['action'] === $this->filter),
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach ($toHide as $m) {
|
||||||
|
$hidden[] = $m['id'];
|
||||||
|
}
|
||||||
|
$this->saveHidden($hidden);
|
||||||
|
$this->resetPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updatedFilter(): void { $this->resetPage(); }
|
public function updatedFilter(): void { $this->resetPage(); }
|
||||||
|
|
@ -65,7 +85,11 @@ class QuarantineList extends Component
|
||||||
|
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
$all = $this->fetchHistory();
|
$hidden = $this->getHidden();
|
||||||
|
$all = array_values(array_filter(
|
||||||
|
$this->fetchHistory(),
|
||||||
|
fn($m) => !in_array($m['id'], $hidden, true)
|
||||||
|
));
|
||||||
|
|
||||||
$suspicious = array_values(array_filter($all, fn($m) => $m['action'] !== 'no action'));
|
$suspicious = array_values(array_filter($all, fn($m) => $m['action'] !== 'no action'));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,14 +20,14 @@
|
||||||
<option value="50">50 / Seite</option>
|
<option value="50">50 / Seite</option>
|
||||||
<option value="100">100 / Seite</option>
|
<option value="100">100 / Seite</option>
|
||||||
</select>
|
</select>
|
||||||
@if($counts['all'] > 0)
|
@if($messages->total() > 0)
|
||||||
<button wire:click="clearHistory"
|
<button wire:click="deleteCurrentTab"
|
||||||
wire:confirm="Gesamten RSpamd-Verlauf löschen?"
|
wire:confirm="Alle Einträge in diesem Tab ausblenden?"
|
||||||
class="mw-btn-del" title="Verlauf leeren">
|
class="mw-btn-del" title="Tab leeren">
|
||||||
<svg width="13" height="13" viewBox="0 0 14 14" fill="none">
|
<svg width="13" height="13" viewBox="0 0 14 14" fill="none">
|
||||||
<path d="M2 3.5h10M5.5 3.5V2.5h3v1M6 6v4M8 6v4M3 3.5l.7 8h6.6l.7-8" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
<path d="M2 3.5h10M5.5 3.5V2.5h3v1M6 6v4M8 6v4M3 3.5l.7 8h6.6l.7-8" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
</svg>
|
</svg>
|
||||||
Verlauf leeren
|
Tab leeren
|
||||||
</button>
|
</button>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -104,10 +104,16 @@
|
||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
<td class="mq-num">{{ $msg['time'] > 0 ? date('d.m H:i', $msg['time']) : '—' }}</td>
|
<td class="mq-num">{{ $msg['time'] > 0 ? date('d.m H:i', $msg['time']) : '—' }}</td>
|
||||||
<td>
|
<td style="display:flex;gap:4px;align-items:center;justify-content:flex-end">
|
||||||
<button wire:click="openMessage('{{ $msg['id'] }}')" class="mq-btn-icon" title="Details">
|
<button wire:click="openMessage('{{ $msg['id'] }}')" class="mq-btn-icon" title="Details">
|
||||||
<svg width="13" height="13" viewBox="0 0 14 14" fill="none"><circle cx="7" cy="7" r="5.5" stroke="currentColor" stroke-width="1.2"/><path d="M7 6.5v4" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/><circle cx="7" cy="4.5" r=".7" fill="currentColor"/></svg>
|
<svg width="13" height="13" viewBox="0 0 14 14" fill="none"><circle cx="7" cy="7" r="5.5" stroke="currentColor" stroke-width="1.2"/><path d="M7 6.5v4" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/><circle cx="7" cy="4.5" r=".7" fill="currentColor"/></svg>
|
||||||
</button>
|
</button>
|
||||||
|
<button wire:click="deleteEntry('{{ $msg['id'] }}')" class="mq-btn-icon" title="Ausblenden"
|
||||||
|
style="color:var(--mw-t4);hover:color:var(--rose-400)">
|
||||||
|
<svg width="13" height="13" viewBox="0 0 14 14" fill="none">
|
||||||
|
<path d="M2 3.5h10M5.5 3.5V2.5h3v1M6 6v4M8 6v4M3 3.5l.7 8h6.6l.7-8" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue