feat(proxmox): add smart firewall workflow and UI refresh

Introduce starter firewall rule templates, one-click rule creation from log entries, and quick log filter presets to speed up incident response. Add a shared quick actions hub plus refreshed help and overview surfaces to improve discoverability and make key VPS tasks faster.

Made-with: Cursor
This commit is contained in:
2026-03-28 16:24:12 -04:00
parent 3246a86f91
commit b8677f5b7d
5 changed files with 320 additions and 11 deletions

View File

@@ -360,7 +360,7 @@
<div class="flex items-center gap-2">
<x-ri-file-list-3-line class="size-4" />
<span>Firewall Logs</span>
<span class="ml-1.5 inline-flex items-center justify-center px-1.5 py-0.5 text-[10px] font-bold rounded-full bg-primary/15 text-primary min-w-[1.25rem]">{{ count($firewallLogs) }}</span>
<span class="ml-1.5 inline-flex items-center justify-center px-1.5 py-0.5 text-[10px] font-bold rounded-full bg-primary/15 text-primary min-w-[1.25rem]">{{ count($this->filteredLogs) }}</span>
</div>
<div x-show="activeTab === 'logs'" class="absolute bottom-0 left-0 right-0 h-0.5 bg-primary rounded-t"></div>
</button>
@@ -389,6 +389,20 @@
</button>
</div>
<div class="mb-5">
<p class="text-xs font-semibold uppercase tracking-wide text-base/60 mb-2">Starter templates</p>
<div class="grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-4 gap-2">
@foreach($this->ruleTemplates as $templateKey => $template)
<button type="button"
wire:click="applyRuleTemplate('{{ $templateKey }}')"
class="text-left p-3 rounded-lg border border-neutral/30 bg-background-secondary/40 hover:border-primary/40 hover:bg-primary/5 transition-colors">
<p class="text-sm font-semibold text-base">{{ $template['label'] }}</p>
<p class="text-xs text-base/60 mt-0.5">{{ $template['description'] }}</p>
</button>
@endforeach
</div>
</div>
@if(count($rules) > 0)
<div class="overflow-x-auto">
<table class="w-full">
@@ -825,7 +839,7 @@
<button type="button"
x-data
@click="
const logs = @js($firewallLogs);
const logs = @js($this->filteredLogs);
if (!logs || logs.length === 0) {
alert('No logs to export');
return;
@@ -874,7 +888,20 @@
<span wire:loading wire:target="loadFirewallLogs">Loading...</span>
</button>
</div>
</div>
</div>
<div class="mb-4">
<p class="text-xs font-semibold uppercase tracking-wide text-base/60 mb-2">Quick filters</p>
<div class="flex flex-wrap gap-2">
@foreach($this->logPresets as $presetKey => $presetLabel)
<button type="button"
wire:click="setLogPreset('{{ $presetKey }}')"
class="px-3 py-1.5 rounded-full border text-xs font-semibold transition-colors {{ $activeLogPreset === $presetKey ? 'border-primary/60 text-primary bg-primary/10' : 'border-neutral/30 text-base/70 hover:border-primary/40 hover:text-primary' }}">
{{ $presetLabel }}
</button>
@endforeach
</div>
</div>
@if(!empty($logError))
<div class="bg-warning/10 border border-warning/30 rounded-lg p-4 mb-4">
@@ -885,12 +912,12 @@
</div>
@endif
@if(!$logsLoaded && count($firewallLogs) === 0)
@if(!$logsLoaded && count($this->filteredLogs) === 0)
<div class="text-center py-12 text-base/60">
<div class="fw-loader-xl text-primary mx-auto mb-4"></div>
<p class="text-sm">Loading firewall logs...</p>
</div>
@elseif(count($firewallLogs) > 0)
@elseif(count($this->filteredLogs) > 0)
<div class="overflow-x-auto">
<table class="w-full">
<thead>
@@ -903,6 +930,7 @@
<th class="text-left py-3 px-4 text-xs font-semibold text-base/70 uppercase">Src Port</th>
<th class="text-left py-3 px-4 text-xs font-semibold text-base/70 uppercase">Dest Port</th>
<th class="text-center py-3 px-4 text-xs font-semibold text-base/70 uppercase">Analysis</th>
<th class="text-center py-3 px-4 text-xs font-semibold text-base/70 uppercase">Rule</th>
</tr>
</thead>
<tbody>
@@ -1386,6 +1414,18 @@
</div>
@endif
</td>
<td class="py-3 px-4 text-center">
@php
$logAbsoluteIndex = (($currentPage - 1) * $perPage) + $loop->index;
@endphp
<button type="button"
wire:click="startCreateRuleFromLog({{ $logAbsoluteIndex }})"
class="inline-flex items-center gap-1.5 px-2.5 py-1.5 rounded-md text-xs font-semibold border border-primary/30 text-primary bg-primary/10 hover:bg-primary/15 transition-colors"
title="Create firewall rule from this log">
<x-ri-add-circle-line class="size-3.5" />
Rule
</button>
</td>
</tr>
@endforeach
</tbody>
@@ -1410,7 +1450,7 @@
{{-- Page info and navigation --}}
<div class="flex items-center gap-4">
<span class="text-sm text-base/60">
Showing {{ (($currentPage - 1) * $perPage) + 1 }} - {{ min($currentPage * $perPage, count($firewallLogs)) }} of {{ count($firewallLogs) }} logs
Showing {{ (($currentPage - 1) * $perPage) + 1 }} - {{ min($currentPage * $perPage, count($this->filteredLogs)) }} of {{ count($this->filteredLogs) }} logs
</span>
<div class="flex items-center gap-1">