Add "Apply to All Servers" functionality in Firewall component and view
This commit is contained in:
@@ -1402,10 +1402,26 @@
|
||||
<h3 class="text-lg font-semibold">Saved Configurations</h3>
|
||||
<p class="text-sm text-base/60 mt-1">Save and reuse firewall configurations across your VPS instances</p>
|
||||
</div>
|
||||
<button type="button" wire:click="openSaveConfigModal" class="px-4 py-2 bg-primary text-white rounded-lg hover:bg-primary/90 transition-colors text-sm font-medium flex items-center gap-2">
|
||||
<x-ri-save-3-line class="size-4" />
|
||||
Save Current Configuration
|
||||
</button>
|
||||
<div class="flex items-center gap-2">
|
||||
{{-- Apply to All Button --}}
|
||||
<button type="button"
|
||||
wire:click="openApplyToAllModal"
|
||||
@if(!$this->canApplyToAll()) disabled @endif
|
||||
class="px-4 py-2 bg-success text-white rounded-lg transition-colors text-sm font-medium flex items-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed {{ $this->canApplyToAll() ? 'hover:bg-success/90' : '' }}"
|
||||
title="{{ !$this->currentConfigMatchesSaved() ? 'Save the current configuration first' : (count($this->getUserOtherServers()) === 0 ? 'No other servers to apply to' : 'Apply to all your other servers') }}">
|
||||
<x-ri-global-line class="size-4" />
|
||||
Apply to All
|
||||
</button>
|
||||
{{-- Save Current Configuration Button --}}
|
||||
<button type="button"
|
||||
wire:click="openSaveConfigModal"
|
||||
@if($this->currentConfigMatchesSaved()) disabled @endif
|
||||
class="px-4 py-2 bg-primary text-white rounded-lg transition-colors text-sm font-medium flex items-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed {{ !$this->currentConfigMatchesSaved() ? 'hover:bg-primary/90' : '' }}"
|
||||
title="{{ $this->currentConfigMatchesSaved() ? 'This configuration is already saved' : 'Save the current configuration' }}">
|
||||
<x-ri-save-3-line class="size-4" />
|
||||
Save Current Configuration
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if(count($savedConfigurations) > 0)
|
||||
@@ -2236,6 +2252,123 @@
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Apply to All Servers Modal --}}
|
||||
@if($showApplyToAllModal)
|
||||
<div class="fixed inset-0 z-50 bg-black/50 backdrop-blur-sm flex items-center justify-center p-4">
|
||||
<div class="relative w-full max-w-2xl bg-background-secondary rounded-xl border border-neutral/20 shadow-2xl p-6">
|
||||
<button wire:click="closeApplyToAllModal" class="absolute top-4 right-4 text-base/50 hover:text-base transition-colors">
|
||||
<x-ri-close-line class="size-5" />
|
||||
</button>
|
||||
<div class="flex items-start gap-4 mb-6">
|
||||
<div class="w-12 h-12 rounded-full bg-success/10 flex items-center justify-center flex-shrink-0">
|
||||
<x-ri-global-line class="size-6 text-success" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-xl font-bold mb-2">Apply to All Servers</h3>
|
||||
<p class="text-sm text-base/70">Apply the current firewall configuration to all your other VPS instances.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@php $otherServers = $this->getUserOtherServers(); @endphp
|
||||
|
||||
@if(count($applyToAllResults) > 0)
|
||||
{{-- Show Results --}}
|
||||
<div class="mb-6">
|
||||
<h4 class="text-sm font-semibold mb-3">Results</h4>
|
||||
<div class="space-y-2 max-h-64 overflow-y-auto">
|
||||
@foreach($applyToAllResults as $result)
|
||||
<div class="flex items-center justify-between p-3 rounded-lg {{ $result['success'] ? 'bg-success/10 border border-success/20' : 'bg-error/10 border border-error/20' }}">
|
||||
<div class="flex items-center gap-3">
|
||||
@if($result['success'])
|
||||
<x-ri-checkbox-circle-fill class="size-5 text-success" />
|
||||
@else
|
||||
<x-ri-close-circle-fill class="size-5 text-error" />
|
||||
@endif
|
||||
<span class="font-medium">{{ $result['hostname'] }}</span>
|
||||
</div>
|
||||
<span class="text-xs {{ $result['success'] ? 'text-success' : 'text-error' }}">{{ $result['message'] }}</span>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-3 justify-end">
|
||||
<button wire:click="closeApplyToAllModal" class="px-4 py-2 bg-primary text-white rounded-lg hover:bg-primary/90 transition-colors text-sm font-medium">
|
||||
Done
|
||||
</button>
|
||||
</div>
|
||||
@else
|
||||
{{-- Show Confirmation --}}
|
||||
<div class="bg-warning/10 border border-warning/30 rounded-lg p-4 mb-6">
|
||||
<div class="flex items-start gap-3">
|
||||
<x-ri-alert-line class="size-5 text-warning flex-shrink-0 mt-0.5" />
|
||||
<div>
|
||||
<h4 class="font-semibold text-warning mb-1">Warning</h4>
|
||||
<p class="text-sm text-base/70">This will replace the firewall configuration on all your other servers. Existing rules will be deleted and replaced with the current configuration.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if(count($otherServers) > 0)
|
||||
<div class="mb-6">
|
||||
<h4 class="text-sm font-semibold mb-3">Servers to Update ({{ count($otherServers) }})</h4>
|
||||
<div class="space-y-2 max-h-48 overflow-y-auto">
|
||||
@foreach($otherServers as $otherServer)
|
||||
<div class="flex items-center justify-between p-3 bg-background/50 border border-neutral/20 rounded-lg">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-8 h-8 rounded-lg bg-primary/10 flex items-center justify-center">
|
||||
<x-ri-server-line class="size-4 text-primary" />
|
||||
</div>
|
||||
<div>
|
||||
<span class="font-medium">{{ $otherServer['hostname'] ?? 'VPS ' . $otherServer['vm_id'] }}</span>
|
||||
<span class="text-xs text-base/50 ml-2">VM {{ $otherServer['vm_id'] }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-background/50 border border-neutral/30 rounded-lg p-4 mb-6">
|
||||
<h4 class="text-sm font-semibold mb-2">Configuration to Apply</h4>
|
||||
<div class="grid grid-cols-3 gap-3 text-sm">
|
||||
<div>
|
||||
<span class="text-base/60">Rules:</span>
|
||||
<span class="font-medium ml-1">{{ count($rules) }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-base/60">Policy In:</span>
|
||||
<span class="font-medium ml-1 {{ $policyIn === 'DROP' ? 'text-error' : 'text-success' }}">{{ $policyIn }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-base/60">Policy Out:</span>
|
||||
<span class="font-medium ml-1 {{ $policyOut === 'DROP' ? 'text-error' : 'text-success' }}">{{ $policyOut }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
<div class="text-center py-8 text-base/60">
|
||||
<x-ri-server-line class="size-12 mx-auto mb-3 opacity-30" />
|
||||
<p>No other servers found to apply the configuration to.</p>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="flex gap-3 justify-end">
|
||||
<button wire:click="closeApplyToAllModal" class="px-4 py-2 bg-background border border-neutral rounded-lg hover:bg-background-secondary transition-colors text-sm font-medium">
|
||||
Cancel
|
||||
</button>
|
||||
@if(count($otherServers) > 0)
|
||||
<button wire:click="applyToAllServers" wire:loading.attr="disabled" class="px-4 py-2 bg-success text-white rounded-lg hover:bg-success/90 transition-colors text-sm font-medium disabled:opacity-50">
|
||||
<span wire:loading.remove wire:target="applyToAllServers">Apply to {{ count($otherServers) }} Server{{ count($otherServers) > 1 ? 's' : '' }}</span>
|
||||
<span wire:loading wire:target="applyToAllServers">Applying...</span>
|
||||
</button>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@script
|
||||
<script>
|
||||
// IP location helper functions
|
||||
|
||||
Reference in New Issue
Block a user