From 02d74bb14773366955e5215ee364d25825da040f Mon Sep 17 00:00:00 2001 From: boban Date: Mon, 15 Jun 2026 03:06:59 +0200 Subject: [PATCH] ui(servers): full-width lone firewall/fail2ban panel with internal 2-col layout On the Server-Details security section, a single installed tool was capped at lg:max-w-2xl and left-aligned, leaving a large void to its right. Now a lone panel spans the full content width and splits its own body into two columns on lg ($lone flag): firewall = defaults/state | rules list; fail2ban = status summary + view-bans | whitelist (ignoreip). Two tools keep the side-by-side lg:grid-cols-2 grid. All wire:click / $dispatch bindings, buttons, and __() keys preserved; no new lang keys. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../views/livewire/servers/show.blade.php | 137 +++++++++++------- 1 file changed, 81 insertions(+), 56 deletions(-) diff --git a/resources/views/livewire/servers/show.blade.php b/resources/views/livewire/servers/show.blade.php index bd24244..d5f5545 100644 --- a/resources/views/livewire/servers/show.blade.php +++ b/resources/views/livewire/servers/show.blade.php @@ -276,14 +276,20 @@ $showFw = $fwSupported && ($fwInstalled || $fwReadError); $showF2b = $f2bSupported && ($f2bInstalled || $f2bReadError); $panelCount = ($showFw ? 1 : 0) + ($showF2b ? 1 : 0); + + // A single installed tool would otherwise sit in a capped, left-aligned box + // beside a large void. Instead the lone panel spans the full content width and + // splits its OWN body into two columns on lg — a rich, deliberate card rather + // than a fragment. Two tools keep the side-by-side grid. + $lone = $panelCount === 1; @endphp @if ($panelCount > 0) - {{-- Two tools → side-by-side; a lone tool is capped so it doesn't stretch edge-to-edge. --}} + {{-- Two tools → side-by-side; a lone tool spans full width and lays its body out + internally in two columns (see $lone), so neither case leaves dead space. --}}
$panelCount === 2, - 'lg:max-w-2xl' => $panelCount === 1, ])> @if ($showFw) {{-- Firewall-Regeln --}} @@ -313,26 +319,31 @@
@else -
- @if ($fwTool === 'ufw') - {{ __('servers.firewall_default') }} - {{ __('servers.firewall_incoming', ['value' => $fwDefaults['incoming'] ?? '—']) }} - {{ __('servers.firewall_outgoing', ['value' => $fwDefaults['outgoing'] ?? '—']) }} - @else - {{ __('servers.firewall_zone') }} - {{ $fwDefaults['zone'] ?? '—' }} - @endif -
+ {{-- Lone firewall: defaults/state in the left column, rules list in the + right. Two-tool case keeps the single stacked column. --}} +
$lone])> +
+
+ @if ($fwTool === 'ufw') + {{ __('servers.firewall_default') }} + {{ __('servers.firewall_incoming', ['value' => $fwDefaults['incoming'] ?? '—']) }} + {{ __('servers.firewall_outgoing', ['value' => $fwDefaults['outgoing'] ?? '—']) }} + @else + {{ __('servers.firewall_zone') }} + {{ $fwDefaults['zone'] ?? '—' }} + @endif +
- @if ($fwReadOnly) -
- -

{{ __('servers.firewall_readonly') }}

+ @if ($fwReadOnly) +
+ +

{{ __('servers.firewall_readonly') }}

+
+ @endif
- @endif -
- @forelse ($fwRules as $rule) +
+ @forelse ($fwRules as $rule) {{-- $ruleTone, NOT $tone: the page-level $tone is a closure used by the gauges/Volumes panel; reusing the name here would clobber it. --}} @php $ruleTone = $actTone[$rule['action'] ?? 'ALLOW'] ?? 'online'; @endphp @@ -362,11 +373,12 @@ @endunless
- @empty -
-

{{ __('servers.firewall_no_rules') }}

-
- @endforelse + @empty +
+

{{ __('servers.firewall_no_rules') }}

+
+ @endforelse +
@endif @@ -404,39 +416,52 @@
@else - {{-- Compact summary; the full jail/banned-IP list (which can grow very - long) lives in a scrollable modal, opened via the button below. --}} -
-

- {{ __('common.active') }} - · $f2bBanned > 0])>{{ __('servers.fail2ban_banned', ['count' => $f2bBanned]) }} - · {{ __('servers.fail2ban_jails_count', ['count' => count($f2bJails)]) }} -

- - {{ __('servers.fail2ban_view_bans') }} - -
- - {{-- Whitelist (ignoreip) --}} -
-

{{ __('servers.whitelist_label') }}

-
- @foreach ($f2bIgnore as $ip) - - {{ $ip }} - @unless (in_array($ip, ['127.0.0.1/8', '::1'], true)) - - @endunless - - @endforeach + {{-- Lone fail2ban: status summary + "Gesperrte IPs ansehen" in the left + column, the whitelist (ignoreip) management in the right. Two-tool + case keeps the single stacked column. --}} +
$lone])> + {{-- Compact summary; the full jail/banned-IP list (which can grow very + long) lives in a scrollable modal, opened via the button below. --}} +
$lone, + 'border-b border-line' => ! $lone, + ])> +

+ {{ __('common.active') }} + · $f2bBanned > 0])>{{ __('servers.fail2ban_banned', ['count' => $f2bBanned]) }} + · {{ __('servers.fail2ban_jails_count', ['count' => count($f2bJails)]) }} +

+ + {{ __('servers.fail2ban_view_bans') }} +
-
- - {{ __('common.add') }} + + {{-- Whitelist (ignoreip) --}} +
$lone, + 'border-t border-line' => ! $lone, + ])> +

{{ __('servers.whitelist_label') }}

+
+ @foreach ($f2bIgnore as $ip) + + {{ $ip }} + @unless (in_array($ip, ['127.0.0.1/8', '::1'], true)) + + @endunless + + @endforeach +
+
+ + {{ __('common.add') }} +
@endif