feat: enhance Proxmox cloud-init and firewall views by improving modal transition effects, backdrop handling, and enabling drag-and-drop rule editing for a better user experience
This commit is contained in:
@@ -53,10 +53,32 @@
|
|||||||
<button type="button" @click="open = true" class="text-base/50 hover:text-base/70 transition-colors">
|
<button type="button" @click="open = true" class="text-base/50 hover:text-base/70 transition-colors">
|
||||||
<x-ri-question-line class="size-4" />
|
<x-ri-question-line class="size-4" />
|
||||||
</button>
|
</button>
|
||||||
<div x-show="open" x-transition.opacity class="fixed inset-0 z-50 flex items-center justify-center p-4">
|
<!-- Modal Backdrop -->
|
||||||
<div class="absolute inset-0 bg-black/40 backdrop-blur-sm" @click="open = false"></div>
|
<div x-show="open"
|
||||||
<div class="relative w-full max-w-2xl max-h-[90vh] overflow-y-auto bg-background-secondary rounded-xl border border-neutral/20 shadow-2xl p-6"
|
x-transition:enter="transition ease-out duration-300"
|
||||||
x-on:keydown.escape.window="open = false">
|
x-transition:enter-start="opacity-0"
|
||||||
|
x-transition:enter-end="opacity-100"
|
||||||
|
x-transition:leave="transition ease-in duration-200"
|
||||||
|
x-transition:leave-start="opacity-100"
|
||||||
|
x-transition:leave-end="opacity-0"
|
||||||
|
@click="open = false"
|
||||||
|
@keydown.escape.window="open = false"
|
||||||
|
class="fixed inset-0 z-50 bg-black/50 backdrop-blur-sm"
|
||||||
|
style="display: none;">
|
||||||
|
</div>
|
||||||
|
<!-- Modal -->
|
||||||
|
<div x-show="open"
|
||||||
|
x-transition:enter="transition ease-out duration-300"
|
||||||
|
x-transition:enter-start="opacity-0 scale-95"
|
||||||
|
x-transition:enter-end="opacity-100 scale-100"
|
||||||
|
x-transition:leave="transition ease-in duration-200"
|
||||||
|
x-transition:leave-start="opacity-100 scale-100"
|
||||||
|
x-transition:leave-end="opacity-0 scale-95"
|
||||||
|
@click.away="open = false"
|
||||||
|
@keydown.escape.window="open = false"
|
||||||
|
class="fixed inset-0 z-50 flex items-center justify-center p-4"
|
||||||
|
style="display: none;">
|
||||||
|
<div class="relative w-full max-w-2xl max-h-[90vh] overflow-y-auto bg-background-secondary rounded-xl border border-neutral/20 shadow-2xl p-6">
|
||||||
<button @click="open = false" class="absolute top-4 right-4 text-base/50 hover:text-base transition-colors">
|
<button @click="open = false" class="absolute top-4 right-4 text-base/50 hover:text-base transition-colors">
|
||||||
<x-ri-close-line class="size-5" />
|
<x-ri-close-line class="size-5" />
|
||||||
</button>
|
</button>
|
||||||
@@ -102,10 +124,32 @@
|
|||||||
<button type="button" @click="open = true" class="text-base/50 hover:text-base/70 transition-colors">
|
<button type="button" @click="open = true" class="text-base/50 hover:text-base/70 transition-colors">
|
||||||
<x-ri-question-line class="size-4" />
|
<x-ri-question-line class="size-4" />
|
||||||
</button>
|
</button>
|
||||||
<div x-show="open" x-transition.opacity class="fixed inset-0 z-50 flex items-center justify-center p-4">
|
<!-- Modal Backdrop -->
|
||||||
<div class="absolute inset-0 bg-black/40 backdrop-blur-sm" @click="open = false"></div>
|
<div x-show="open"
|
||||||
<div class="relative w-full max-w-2xl max-h-[90vh] overflow-y-auto bg-background-secondary rounded-xl border border-neutral/20 shadow-2xl p-6"
|
x-transition:enter="transition ease-out duration-300"
|
||||||
x-on:keydown.escape.window="open = false">
|
x-transition:enter-start="opacity-0"
|
||||||
|
x-transition:enter-end="opacity-100"
|
||||||
|
x-transition:leave="transition ease-in duration-200"
|
||||||
|
x-transition:leave-start="opacity-100"
|
||||||
|
x-transition:leave-end="opacity-0"
|
||||||
|
@click="open = false"
|
||||||
|
@keydown.escape.window="open = false"
|
||||||
|
class="fixed inset-0 z-50 bg-black/50 backdrop-blur-sm"
|
||||||
|
style="display: none;">
|
||||||
|
</div>
|
||||||
|
<!-- Modal -->
|
||||||
|
<div x-show="open"
|
||||||
|
x-transition:enter="transition ease-out duration-300"
|
||||||
|
x-transition:enter-start="opacity-0 scale-95"
|
||||||
|
x-transition:enter-end="opacity-100 scale-100"
|
||||||
|
x-transition:leave="transition ease-in duration-200"
|
||||||
|
x-transition:leave-start="opacity-100 scale-100"
|
||||||
|
x-transition:leave-end="opacity-0 scale-95"
|
||||||
|
@click.away="open = false"
|
||||||
|
@keydown.escape.window="open = false"
|
||||||
|
class="fixed inset-0 z-50 flex items-center justify-center p-4"
|
||||||
|
style="display: none;">
|
||||||
|
<div class="relative w-full max-w-2xl max-h-[90vh] overflow-y-auto bg-background-secondary rounded-xl border border-neutral/20 shadow-2xl p-6">
|
||||||
<button @click="open = false" class="absolute top-4 right-4 text-base/50 hover:text-base transition-colors">
|
<button @click="open = false" class="absolute top-4 right-4 text-base/50 hover:text-base transition-colors">
|
||||||
<x-ri-close-line class="size-5" />
|
<x-ri-close-line class="size-5" />
|
||||||
</button>
|
</button>
|
||||||
@@ -162,10 +206,32 @@
|
|||||||
</div>
|
</div>
|
||||||
<p class="text-xs text-base/60">Use distro-friendly names. Leave blank to keep the template default.</p>
|
<p class="text-xs text-base/60">Use distro-friendly names. Leave blank to keep the template default.</p>
|
||||||
|
|
||||||
<div x-cloak x-show="showCiUserModal" x-transition.opacity class="fixed inset-0 z-50 flex items-center justify-center">
|
<!-- Modal Backdrop -->
|
||||||
<div class="absolute inset-0 bg-black/40 backdrop-blur-sm" @click="showCiUserModal = false"></div>
|
<div x-cloak x-show="showCiUserModal"
|
||||||
<div class="relative bg-background-secondary border border-neutral rounded-lg shadow-xl w-full max-w-xl mx-4 p-5 space-y-4"
|
x-transition:enter="transition ease-out duration-300"
|
||||||
x-on:keydown.escape.window="showCiUserModal = false">
|
x-transition:enter-start="opacity-0"
|
||||||
|
x-transition:enter-end="opacity-100"
|
||||||
|
x-transition:leave="transition ease-in duration-200"
|
||||||
|
x-transition:leave-start="opacity-100"
|
||||||
|
x-transition:leave-end="opacity-0"
|
||||||
|
@click="showCiUserModal = false"
|
||||||
|
@keydown.escape.window="showCiUserModal = false"
|
||||||
|
class="fixed inset-0 z-50 bg-black/50 backdrop-blur-sm"
|
||||||
|
style="display: none;">
|
||||||
|
</div>
|
||||||
|
<!-- Modal -->
|
||||||
|
<div x-cloak x-show="showCiUserModal"
|
||||||
|
x-transition:enter="transition ease-out duration-300"
|
||||||
|
x-transition:enter-start="opacity-0 scale-95"
|
||||||
|
x-transition:enter-end="opacity-100 scale-100"
|
||||||
|
x-transition:leave="transition ease-in duration-200"
|
||||||
|
x-transition:leave-start="opacity-100 scale-100"
|
||||||
|
x-transition:leave-end="opacity-0 scale-95"
|
||||||
|
@click.away="showCiUserModal = false"
|
||||||
|
@keydown.escape.window="showCiUserModal = false"
|
||||||
|
class="fixed inset-0 z-50 flex items-center justify-center p-4"
|
||||||
|
style="display: none;">
|
||||||
|
<div class="relative bg-background-secondary border border-neutral rounded-lg shadow-xl w-full max-w-xl mx-4 p-5 space-y-4">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<h4 class="text-base font-semibold text-base/90">Edit Cloud-init User</h4>
|
<h4 class="text-base font-semibold text-base/90">Edit Cloud-init User</h4>
|
||||||
<button type="button"
|
<button type="button"
|
||||||
@@ -225,10 +291,32 @@
|
|||||||
<p class="text-xs text-base/60">Matches the Overview tab control. Use Save for database only, Save & Apply to push via cloud-init.</p>
|
<p class="text-xs text-base/60">Matches the Overview tab control. Use Save for database only, Save & Apply to push via cloud-init.</p>
|
||||||
|
|
||||||
@if(isset($server->password) && $server->password)
|
@if(isset($server->password) && $server->password)
|
||||||
<div x-cloak x-show="showPasswordViewModal" x-transition.opacity class="fixed inset-0 z-50 flex items-center justify-center">
|
<!-- Modal Backdrop -->
|
||||||
<div class="absolute inset-0 bg-black/40 backdrop-blur-sm" @click="showPasswordViewModal = false"></div>
|
<div x-cloak x-show="showPasswordViewModal"
|
||||||
|
x-transition:enter="transition ease-out duration-300"
|
||||||
|
x-transition:enter-start="opacity-0"
|
||||||
|
x-transition:enter-end="opacity-100"
|
||||||
|
x-transition:leave="transition ease-in duration-200"
|
||||||
|
x-transition:leave-start="opacity-100"
|
||||||
|
x-transition:leave-end="opacity-0"
|
||||||
|
@click="showPasswordViewModal = false"
|
||||||
|
@keydown.escape.window="showPasswordViewModal = false"
|
||||||
|
class="fixed inset-0 z-50 bg-black/50 backdrop-blur-sm"
|
||||||
|
style="display: none;">
|
||||||
|
</div>
|
||||||
|
<!-- Modal -->
|
||||||
|
<div x-cloak x-show="showPasswordViewModal"
|
||||||
|
x-transition:enter="transition ease-out duration-300"
|
||||||
|
x-transition:enter-start="opacity-0 scale-95"
|
||||||
|
x-transition:enter-end="opacity-100 scale-100"
|
||||||
|
x-transition:leave="transition ease-in duration-200"
|
||||||
|
x-transition:leave-start="opacity-100 scale-100"
|
||||||
|
x-transition:leave-end="opacity-0 scale-95"
|
||||||
|
@click.away="showPasswordViewModal = false"
|
||||||
|
@keydown.escape.window="showPasswordViewModal = false"
|
||||||
|
class="fixed inset-0 z-50 flex items-center justify-center p-4"
|
||||||
|
style="display: none;">
|
||||||
<div class="relative bg-background-secondary border border-neutral rounded-lg shadow-xl w-full max-w-xl mx-4 p-5 space-y-4"
|
<div class="relative bg-background-secondary border border-neutral rounded-lg shadow-xl w-full max-w-xl mx-4 p-5 space-y-4"
|
||||||
x-on:keydown.escape.window="showPasswordViewModal = false"
|
|
||||||
x-data="{
|
x-data="{
|
||||||
copied: false,
|
copied: false,
|
||||||
copyText: {{ json_encode($server->password) }},
|
copyText: {{ json_encode($server->password) }},
|
||||||
@@ -262,10 +350,32 @@
|
|||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<div x-cloak x-show="showPasswordEditModal" x-transition.opacity class="fixed inset-0 z-50 flex items-center justify-center">
|
<!-- Modal Backdrop -->
|
||||||
<div class="absolute inset-0 bg-black/40 backdrop-blur-sm" @click="showPasswordEditModal = false; $wire.cancelEditingPassword()"></div>
|
<div x-cloak x-show="showPasswordEditModal"
|
||||||
<div class="relative bg-background-secondary border border-neutral rounded-lg shadow-xl w-full max-w-xl mx-4 p-5 space-y-4"
|
x-transition:enter="transition ease-out duration-300"
|
||||||
x-on:keydown.escape.window="showPasswordEditModal = false; $wire.cancelEditingPassword()">
|
x-transition:enter-start="opacity-0"
|
||||||
|
x-transition:enter-end="opacity-100"
|
||||||
|
x-transition:leave="transition ease-in duration-200"
|
||||||
|
x-transition:leave-start="opacity-100"
|
||||||
|
x-transition:leave-end="opacity-0"
|
||||||
|
@click="showPasswordEditModal = false; $wire.cancelEditingPassword()"
|
||||||
|
@keydown.escape.window="showPasswordEditModal = false; $wire.cancelEditingPassword()"
|
||||||
|
class="fixed inset-0 z-50 bg-black/50 backdrop-blur-sm"
|
||||||
|
style="display: none;">
|
||||||
|
</div>
|
||||||
|
<!-- Modal -->
|
||||||
|
<div x-cloak x-show="showPasswordEditModal"
|
||||||
|
x-transition:enter="transition ease-out duration-300"
|
||||||
|
x-transition:enter-start="opacity-0 scale-95"
|
||||||
|
x-transition:enter-end="opacity-100 scale-100"
|
||||||
|
x-transition:leave="transition ease-in duration-200"
|
||||||
|
x-transition:leave-start="opacity-100 scale-100"
|
||||||
|
x-transition:leave-end="opacity-0 scale-95"
|
||||||
|
@click.away="showPasswordEditModal = false; $wire.cancelEditingPassword()"
|
||||||
|
@keydown.escape.window="showPasswordEditModal = false; $wire.cancelEditingPassword()"
|
||||||
|
class="fixed inset-0 z-50 flex items-center justify-center p-4"
|
||||||
|
style="display: none;">
|
||||||
|
<div class="relative bg-background-secondary border border-neutral rounded-lg shadow-xl w-full max-w-xl mx-4 p-5 space-y-4">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<h4 class="text-base font-semibold text-base/90">Edit Root Password</h4>
|
<h4 class="text-base font-semibold text-base/90">Edit Root Password</h4>
|
||||||
<button type="button"
|
<button type="button"
|
||||||
@@ -340,12 +450,32 @@
|
|||||||
<x-ri-close-line class="inline size-4" />
|
<x-ri-close-line class="inline size-4" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div x-cloak x-show="showKeyModal" x-transition.opacity
|
<!-- Modal Backdrop -->
|
||||||
class="fixed inset-0 z-50 flex items-center justify-center">
|
<div x-cloak x-show="showKeyModal"
|
||||||
<div class="absolute inset-0 bg-black/40 backdrop-blur-sm"
|
x-transition:enter="transition ease-out duration-300"
|
||||||
@click="showKeyModal = false"></div>
|
x-transition:enter-start="opacity-0"
|
||||||
<div class="relative bg-background-secondary border border-neutral rounded-lg shadow-xl w-full max-w-xl mx-4 p-5 space-y-4"
|
x-transition:enter-end="opacity-100"
|
||||||
x-on:keydown.escape.window="showKeyModal = false">
|
x-transition:leave="transition ease-in duration-200"
|
||||||
|
x-transition:leave-start="opacity-100"
|
||||||
|
x-transition:leave-end="opacity-0"
|
||||||
|
@click="showKeyModal = false"
|
||||||
|
@keydown.escape.window="showKeyModal = false"
|
||||||
|
class="fixed inset-0 z-50 bg-black/50 backdrop-blur-sm"
|
||||||
|
style="display: none;">
|
||||||
|
</div>
|
||||||
|
<!-- Modal -->
|
||||||
|
<div x-cloak x-show="showKeyModal"
|
||||||
|
x-transition:enter="transition ease-out duration-300"
|
||||||
|
x-transition:enter-start="opacity-0 scale-95"
|
||||||
|
x-transition:enter-end="opacity-100 scale-100"
|
||||||
|
x-transition:leave="transition ease-in duration-200"
|
||||||
|
x-transition:leave-start="opacity-100 scale-100"
|
||||||
|
x-transition:leave-end="opacity-0 scale-95"
|
||||||
|
@click.away="showKeyModal = false"
|
||||||
|
@keydown.escape.window="showKeyModal = false"
|
||||||
|
class="fixed inset-0 z-50 flex items-center justify-center p-4"
|
||||||
|
style="display: none;">
|
||||||
|
<div class="relative bg-background-secondary border border-neutral rounded-lg shadow-xl w-full max-w-xl mx-4 p-5 space-y-4">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<h4 class="text-base font-semibold text-base/90">SSH Public Key</h4>
|
<h4 class="text-base font-semibold text-base/90">SSH Public Key</h4>
|
||||||
<button type="button"
|
<button type="button"
|
||||||
@@ -380,10 +510,32 @@
|
|||||||
</div>
|
</div>
|
||||||
<p class="text-xs text-base/60">Add as many keys as needed. The platform management key is always kept but never shown.</p>
|
<p class="text-xs text-base/60">Add as many keys as needed. The platform management key is always kept but never shown.</p>
|
||||||
|
|
||||||
<div x-cloak x-show="showAddKeyModal" x-transition.opacity class="fixed inset-0 z-50 flex items-center justify-center">
|
<!-- Modal Backdrop -->
|
||||||
<div class="absolute inset-0 bg-black/40 backdrop-blur-sm" @click="showAddKeyModal = false"></div>
|
<div x-cloak x-show="showAddKeyModal"
|
||||||
<div class="relative bg-background-secondary border border-neutral rounded-lg shadow-xl w-full max-w-xl mx-4 p-5 space-y-4"
|
x-transition:enter="transition ease-out duration-300"
|
||||||
x-on:keydown.escape.window="showAddKeyModal = false">
|
x-transition:enter-start="opacity-0"
|
||||||
|
x-transition:enter-end="opacity-100"
|
||||||
|
x-transition:leave="transition ease-in duration-200"
|
||||||
|
x-transition:leave-start="opacity-100"
|
||||||
|
x-transition:leave-end="opacity-0"
|
||||||
|
@click="showAddKeyModal = false"
|
||||||
|
@keydown.escape.window="showAddKeyModal = false"
|
||||||
|
class="fixed inset-0 z-50 bg-black/50 backdrop-blur-sm"
|
||||||
|
style="display: none;">
|
||||||
|
</div>
|
||||||
|
<!-- Modal -->
|
||||||
|
<div x-cloak x-show="showAddKeyModal"
|
||||||
|
x-transition:enter="transition ease-out duration-300"
|
||||||
|
x-transition:enter-start="opacity-0 scale-95"
|
||||||
|
x-transition:enter-end="opacity-100 scale-100"
|
||||||
|
x-transition:leave="transition ease-in duration-200"
|
||||||
|
x-transition:leave-start="opacity-100 scale-100"
|
||||||
|
x-transition:leave-end="opacity-0 scale-95"
|
||||||
|
@click.away="showAddKeyModal = false"
|
||||||
|
@keydown.escape.window="showAddKeyModal = false"
|
||||||
|
class="fixed inset-0 z-50 flex items-center justify-center p-4"
|
||||||
|
style="display: none;">
|
||||||
|
<div class="relative bg-background-secondary border border-neutral rounded-lg shadow-xl w-full max-w-xl mx-4 p-5 space-y-4">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<h4 class="text-base font-semibold text-base/90">Add SSH Public Key</h4>
|
<h4 class="text-base font-semibold text-base/90">Add SSH Public Key</h4>
|
||||||
<button type="button"
|
<button type="button"
|
||||||
@@ -432,10 +584,32 @@
|
|||||||
<button type="button" @click="open = true" class="text-base/50 hover:text-base/70 transition-colors">
|
<button type="button" @click="open = true" class="text-base/50 hover:text-base/70 transition-colors">
|
||||||
<x-ri-question-line class="size-4" />
|
<x-ri-question-line class="size-4" />
|
||||||
</button>
|
</button>
|
||||||
<div x-show="open" x-transition.opacity class="fixed inset-0 z-50 flex items-center justify-center p-4">
|
<!-- Modal Backdrop -->
|
||||||
<div class="absolute inset-0 bg-black/40 backdrop-blur-sm" @click="open = false"></div>
|
<div x-show="open"
|
||||||
<div class="relative w-full max-w-2xl max-h-[90vh] overflow-y-auto bg-background-secondary rounded-xl border border-neutral/20 shadow-2xl p-6"
|
x-transition:enter="transition ease-out duration-300"
|
||||||
x-on:keydown.escape.window="open = false">
|
x-transition:enter-start="opacity-0"
|
||||||
|
x-transition:enter-end="opacity-100"
|
||||||
|
x-transition:leave="transition ease-in duration-200"
|
||||||
|
x-transition:leave-start="opacity-100"
|
||||||
|
x-transition:leave-end="opacity-0"
|
||||||
|
@click="open = false"
|
||||||
|
@keydown.escape.window="open = false"
|
||||||
|
class="fixed inset-0 z-50 bg-black/50 backdrop-blur-sm"
|
||||||
|
style="display: none;">
|
||||||
|
</div>
|
||||||
|
<!-- Modal -->
|
||||||
|
<div x-show="open"
|
||||||
|
x-transition:enter="transition ease-out duration-300"
|
||||||
|
x-transition:enter-start="opacity-0 scale-95"
|
||||||
|
x-transition:enter-end="opacity-100 scale-100"
|
||||||
|
x-transition:leave="transition ease-in duration-200"
|
||||||
|
x-transition:leave-start="opacity-100 scale-100"
|
||||||
|
x-transition:leave-end="opacity-0 scale-95"
|
||||||
|
@click.away="open = false"
|
||||||
|
@keydown.escape.window="open = false"
|
||||||
|
class="fixed inset-0 z-50 flex items-center justify-center p-4"
|
||||||
|
style="display: none;">
|
||||||
|
<div class="relative w-full max-w-2xl max-h-[90vh] overflow-y-auto bg-background-secondary rounded-xl border border-neutral/20 shadow-2xl p-6">
|
||||||
<button @click="open = false" class="absolute top-4 right-4 text-base/50 hover:text-base transition-colors">
|
<button @click="open = false" class="absolute top-4 right-4 text-base/50 hover:text-base transition-colors">
|
||||||
<x-ri-close-line class="size-5" />
|
<x-ri-close-line class="size-5" />
|
||||||
</button>
|
</button>
|
||||||
@@ -527,11 +701,32 @@
|
|||||||
@endforeach
|
@endforeach
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div x-cloak x-show="showNetworkModal" x-transition.opacity class="fixed inset-0 z-50 flex items-center justify-center">
|
<!-- Modal Backdrop -->
|
||||||
<div class="absolute inset-0 bg-black/40 backdrop-blur-sm"
|
<div x-cloak x-show="showNetworkModal"
|
||||||
@click="showNetworkModal = false; $wire.cancelEditingNetwork()"></div>
|
x-transition:enter="transition ease-out duration-300"
|
||||||
<div class="relative bg-background-secondary border border-neutral rounded-lg shadow-xl w-full max-w-2xl mx-4 p-5 space-y-4"
|
x-transition:enter-start="opacity-0"
|
||||||
x-on:keydown.escape.window="showNetworkModal = false; $wire.cancelEditingNetwork()">
|
x-transition:enter-end="opacity-100"
|
||||||
|
x-transition:leave="transition ease-in duration-200"
|
||||||
|
x-transition:leave-start="opacity-100"
|
||||||
|
x-transition:leave-end="opacity-0"
|
||||||
|
@click="showNetworkModal = false; $wire.cancelEditingNetwork()"
|
||||||
|
@keydown.escape.window="showNetworkModal = false; $wire.cancelEditingNetwork()"
|
||||||
|
class="fixed inset-0 z-50 bg-black/50 backdrop-blur-sm"
|
||||||
|
style="display: none;">
|
||||||
|
</div>
|
||||||
|
<!-- Modal -->
|
||||||
|
<div x-cloak x-show="showNetworkModal"
|
||||||
|
x-transition:enter="transition ease-out duration-300"
|
||||||
|
x-transition:enter-start="opacity-0 scale-95"
|
||||||
|
x-transition:enter-end="opacity-100 scale-100"
|
||||||
|
x-transition:leave="transition ease-in duration-200"
|
||||||
|
x-transition:leave-start="opacity-100 scale-100"
|
||||||
|
x-transition:leave-end="opacity-0 scale-95"
|
||||||
|
@click.away="showNetworkModal = false; $wire.cancelEditingNetwork()"
|
||||||
|
@keydown.escape.window="showNetworkModal = false; $wire.cancelEditingNetwork()"
|
||||||
|
class="fixed inset-0 z-50 flex items-center justify-center p-4"
|
||||||
|
style="display: none;">
|
||||||
|
<div class="relative bg-background-secondary border border-neutral rounded-lg shadow-xl w-full max-w-2xl mx-4 p-5 space-y-4">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<h4 class="text-base font-semibold text-base/90">Edit Network Configuration</h4>
|
<h4 class="text-base font-semibold text-base/90">Edit Network Configuration</h4>
|
||||||
<button type="button"
|
<button type="button"
|
||||||
@@ -592,10 +787,32 @@
|
|||||||
<button type="button" @click="open = true" class="text-base/50 hover:text-base/70 transition-colors">
|
<button type="button" @click="open = true" class="text-base/50 hover:text-base/70 transition-colors">
|
||||||
<x-ri-question-line class="size-4" />
|
<x-ri-question-line class="size-4" />
|
||||||
</button>
|
</button>
|
||||||
<div x-show="open" x-transition.opacity class="fixed inset-0 z-50 flex items-center justify-center p-4">
|
<!-- Modal Backdrop -->
|
||||||
<div class="absolute inset-0 bg-black/40 backdrop-blur-sm" @click="open = false"></div>
|
<div x-show="open"
|
||||||
<div class="relative w-full max-w-2xl max-h-[90vh] overflow-y-auto bg-background-secondary rounded-xl border border-neutral/20 shadow-2xl p-6"
|
x-transition:enter="transition ease-out duration-300"
|
||||||
x-on:keydown.escape.window="open = false">
|
x-transition:enter-start="opacity-0"
|
||||||
|
x-transition:enter-end="opacity-100"
|
||||||
|
x-transition:leave="transition ease-in duration-200"
|
||||||
|
x-transition:leave-start="opacity-100"
|
||||||
|
x-transition:leave-end="opacity-0"
|
||||||
|
@click="open = false"
|
||||||
|
@keydown.escape.window="open = false"
|
||||||
|
class="fixed inset-0 z-50 bg-black/50 backdrop-blur-sm"
|
||||||
|
style="display: none;">
|
||||||
|
</div>
|
||||||
|
<!-- Modal -->
|
||||||
|
<div x-show="open"
|
||||||
|
x-transition:enter="transition ease-out duration-300"
|
||||||
|
x-transition:enter-start="opacity-0 scale-95"
|
||||||
|
x-transition:enter-end="opacity-100 scale-100"
|
||||||
|
x-transition:leave="transition ease-in duration-200"
|
||||||
|
x-transition:leave-start="opacity-100 scale-100"
|
||||||
|
x-transition:leave-end="opacity-0 scale-95"
|
||||||
|
@click.away="open = false"
|
||||||
|
@keydown.escape.window="open = false"
|
||||||
|
class="fixed inset-0 z-50 flex items-center justify-center p-4"
|
||||||
|
style="display: none;">
|
||||||
|
<div class="relative w-full max-w-2xl max-h-[90vh] overflow-y-auto bg-background-secondary rounded-xl border border-neutral/20 shadow-2xl p-6">
|
||||||
<button @click="open = false" class="absolute top-4 right-4 text-base/50 hover:text-base transition-colors">
|
<button @click="open = false" class="absolute top-4 right-4 text-base/50 hover:text-base transition-colors">
|
||||||
<x-ri-close-line class="size-5" />
|
<x-ri-close-line class="size-5" />
|
||||||
</button>
|
</button>
|
||||||
@@ -652,10 +869,32 @@
|
|||||||
</div>
|
</div>
|
||||||
<p class="text-xs text-base/60">Appended to short hostnames for resolution.</p>
|
<p class="text-xs text-base/60">Appended to short hostnames for resolution.</p>
|
||||||
|
|
||||||
<div x-cloak x-show="showDnsDomainModal" x-transition.opacity class="fixed inset-0 z-50 flex items-center justify-center">
|
<!-- Modal Backdrop -->
|
||||||
<div class="absolute inset-0 bg-black/40 backdrop-blur-sm" @click="showDnsDomainModal = false"></div>
|
<div x-cloak x-show="showDnsDomainModal"
|
||||||
<div class="relative bg-background-secondary border border-neutral rounded-lg shadow-xl w-full max-w-xl mx-4 p-5 space-y-4"
|
x-transition:enter="transition ease-out duration-300"
|
||||||
x-on:keydown.escape.window="showDnsDomainModal = false">
|
x-transition:enter-start="opacity-0"
|
||||||
|
x-transition:enter-end="opacity-100"
|
||||||
|
x-transition:leave="transition ease-in duration-200"
|
||||||
|
x-transition:leave-start="opacity-100"
|
||||||
|
x-transition:leave-end="opacity-0"
|
||||||
|
@click="showDnsDomainModal = false"
|
||||||
|
@keydown.escape.window="showDnsDomainModal = false"
|
||||||
|
class="fixed inset-0 z-50 bg-black/50 backdrop-blur-sm"
|
||||||
|
style="display: none;">
|
||||||
|
</div>
|
||||||
|
<!-- Modal -->
|
||||||
|
<div x-cloak x-show="showDnsDomainModal"
|
||||||
|
x-transition:enter="transition ease-out duration-300"
|
||||||
|
x-transition:enter-start="opacity-0 scale-95"
|
||||||
|
x-transition:enter-end="opacity-100 scale-100"
|
||||||
|
x-transition:leave="transition ease-in duration-200"
|
||||||
|
x-transition:leave-start="opacity-100 scale-100"
|
||||||
|
x-transition:leave-end="opacity-0 scale-95"
|
||||||
|
@click.away="showDnsDomainModal = false"
|
||||||
|
@keydown.escape.window="showDnsDomainModal = false"
|
||||||
|
class="fixed inset-0 z-50 flex items-center justify-center p-4"
|
||||||
|
style="display: none;">
|
||||||
|
<div class="relative bg-background-secondary border border-neutral rounded-lg shadow-xl w-full max-w-xl mx-4 p-5 space-y-4">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<h4 class="text-base font-semibold text-base/90">Edit DNS Domain</h4>
|
<h4 class="text-base font-semibold text-base/90">Edit DNS Domain</h4>
|
||||||
<button type="button"
|
<button type="button"
|
||||||
@@ -707,10 +946,32 @@
|
|||||||
</div>
|
</div>
|
||||||
<p class="text-xs text-base/60 mt-1">Entries are applied in order. Add one IPv4/IPv6 resolver per line.</p>
|
<p class="text-xs text-base/60 mt-1">Entries are applied in order. Add one IPv4/IPv6 resolver per line.</p>
|
||||||
|
|
||||||
<div x-cloak x-show="showAddDnsModal" x-transition.opacity class="fixed inset-0 z-50 flex items-center justify-center">
|
<!-- Modal Backdrop -->
|
||||||
<div class="absolute inset-0 bg-black/40 backdrop-blur-sm" @click="showAddDnsModal = false"></div>
|
<div x-cloak x-show="showAddDnsModal"
|
||||||
<div class="relative bg-background-secondary border border-neutral rounded-lg shadow-xl w-full max-w-xl mx-4 p-5 space-y-4"
|
x-transition:enter="transition ease-out duration-300"
|
||||||
x-on:keydown.escape.window="showAddDnsModal = false">
|
x-transition:enter-start="opacity-0"
|
||||||
|
x-transition:enter-end="opacity-100"
|
||||||
|
x-transition:leave="transition ease-in duration-200"
|
||||||
|
x-transition:leave-start="opacity-100"
|
||||||
|
x-transition:leave-end="opacity-0"
|
||||||
|
@click="showAddDnsModal = false"
|
||||||
|
@keydown.escape.window="showAddDnsModal = false"
|
||||||
|
class="fixed inset-0 z-50 bg-black/50 backdrop-blur-sm"
|
||||||
|
style="display: none;">
|
||||||
|
</div>
|
||||||
|
<!-- Modal -->
|
||||||
|
<div x-cloak x-show="showAddDnsModal"
|
||||||
|
x-transition:enter="transition ease-out duration-300"
|
||||||
|
x-transition:enter-start="opacity-0 scale-95"
|
||||||
|
x-transition:enter-end="opacity-100 scale-100"
|
||||||
|
x-transition:leave="transition ease-in duration-200"
|
||||||
|
x-transition:leave-start="opacity-100 scale-100"
|
||||||
|
x-transition:leave-end="opacity-0 scale-95"
|
||||||
|
@click.away="showAddDnsModal = false"
|
||||||
|
@keydown.escape.window="showAddDnsModal = false"
|
||||||
|
class="fixed inset-0 z-50 flex items-center justify-center p-4"
|
||||||
|
style="display: none;">
|
||||||
|
<div class="relative bg-background-secondary border border-neutral rounded-lg shadow-xl w-full max-w-xl mx-4 p-5 space-y-4">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<h4 class="text-base font-semibold text-base/90">Add DNS Nameserver</h4>
|
<h4 class="text-base font-semibold text-base/90">Add DNS Nameserver</h4>
|
||||||
<button type="button"
|
<button type="button"
|
||||||
@@ -814,10 +1075,32 @@
|
|||||||
<button type="button" @click="open = true" class="text-base/50 hover:text-base/70 transition-colors">
|
<button type="button" @click="open = true" class="text-base/50 hover:text-base/70 transition-colors">
|
||||||
<x-ri-question-line class="size-4" />
|
<x-ri-question-line class="size-4" />
|
||||||
</button>
|
</button>
|
||||||
<div x-show="open" x-transition.opacity class="fixed inset-0 z-50 flex items-center justify-center p-4">
|
<!-- Modal Backdrop -->
|
||||||
<div class="absolute inset-0 bg-black/40 backdrop-blur-sm" @click="open = false"></div>
|
<div x-show="open"
|
||||||
<div class="relative w-full max-w-2xl max-h-[90vh] overflow-y-auto bg-background-secondary rounded-xl border border-neutral/20 shadow-2xl p-6"
|
x-transition:enter="transition ease-out duration-300"
|
||||||
x-on:keydown.escape.window="open = false">
|
x-transition:enter-start="opacity-0"
|
||||||
|
x-transition:enter-end="opacity-100"
|
||||||
|
x-transition:leave="transition ease-in duration-200"
|
||||||
|
x-transition:leave-start="opacity-100"
|
||||||
|
x-transition:leave-end="opacity-0"
|
||||||
|
@click="open = false"
|
||||||
|
@keydown.escape.window="open = false"
|
||||||
|
class="fixed inset-0 z-50 bg-black/50 backdrop-blur-sm"
|
||||||
|
style="display: none;">
|
||||||
|
</div>
|
||||||
|
<!-- Modal -->
|
||||||
|
<div x-show="open"
|
||||||
|
x-transition:enter="transition ease-out duration-300"
|
||||||
|
x-transition:enter-start="opacity-0 scale-95"
|
||||||
|
x-transition:enter-end="opacity-100 scale-100"
|
||||||
|
x-transition:leave="transition ease-in duration-200"
|
||||||
|
x-transition:leave-start="opacity-100 scale-100"
|
||||||
|
x-transition:leave-end="opacity-0 scale-95"
|
||||||
|
@click.away="open = false"
|
||||||
|
@keydown.escape.window="open = false"
|
||||||
|
class="fixed inset-0 z-50 flex items-center justify-center p-4"
|
||||||
|
style="display: none;">
|
||||||
|
<div class="relative w-full max-w-2xl max-h-[90vh] overflow-y-auto bg-background-secondary rounded-xl border border-neutral/20 shadow-2xl p-6">
|
||||||
<button @click="open = false" class="absolute top-4 right-4 text-base/50 hover:text-base transition-colors">
|
<button @click="open = false" class="absolute top-4 right-4 text-base/50 hover:text-base transition-colors">
|
||||||
<x-ri-close-line class="size-5" />
|
<x-ri-close-line class="size-5" />
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -95,7 +95,7 @@
|
|||||||
/* Drag and Drop Styles */
|
/* Drag and Drop Styles */
|
||||||
.rule-row {
|
.rule-row {
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
cursor: default;
|
cursor: move;
|
||||||
}
|
}
|
||||||
.rule-row.dragging {
|
.rule-row.dragging {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
@@ -114,7 +114,6 @@
|
|||||||
}
|
}
|
||||||
.drag-handle:hover {
|
.drag-handle:hover {
|
||||||
color: rgba(var(--color-primary), 1);
|
color: rgba(var(--color-primary), 1);
|
||||||
cursor: grab;
|
|
||||||
}
|
}
|
||||||
.drag-handle:active {
|
.drag-handle:active {
|
||||||
cursor: grabbing;
|
cursor: grabbing;
|
||||||
@@ -506,13 +505,13 @@
|
|||||||
<!-- Firewall Rules Card -->
|
<!-- Firewall Rules Card -->
|
||||||
<div class="bg-background border border-neutral rounded-lg p-6"
|
<div class="bg-background border border-neutral rounded-lg p-6"
|
||||||
x-data="{
|
x-data="{
|
||||||
|
editingPositions: false,
|
||||||
rules: @js($rules),
|
rules: @js($rules),
|
||||||
draggedIndex: null,
|
draggedIndex: null,
|
||||||
dragOverIndex: null,
|
dragOverIndex: null,
|
||||||
|
|
||||||
startDrag(event, index) {
|
startDrag(event, index) {
|
||||||
// Only allow dragging from the handle
|
if (!this.editingPositions) {
|
||||||
if (!event.target.closest('.drag-handle')) {
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -590,6 +589,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
|
<button
|
||||||
|
@click="editingPositions = !editingPositions"
|
||||||
|
class="px-4 py-2 rounded-lg transition-colors text-sm font-medium border"
|
||||||
|
:class="editingPositions ? 'bg-primary text-white border-primary hover:bg-primary/90' : 'bg-background-secondary text-base border-neutral/20 hover:bg-background-secondary/80'"
|
||||||
|
:title="editingPositions ? 'Done editing positions' : 'Edit rule positions'">
|
||||||
|
<x-ri-draggable class="size-4 inline mr-1" />
|
||||||
|
<span x-text="editingPositions ? 'Done' : 'Edit Positions'"></span>
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
wire:click="startCreateRule"
|
wire:click="startCreateRule"
|
||||||
class="px-4 py-2 bg-primary text-white rounded-lg hover:bg-primary/90 transition-colors text-sm font-medium">
|
class="px-4 py-2 bg-primary text-white rounded-lg hover:bg-primary/90 transition-colors text-sm font-medium">
|
||||||
@@ -619,7 +626,7 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
<template x-for="(rule, index) in rules" :key="rule.pos">
|
<template x-for="(rule, index) in rules" :key="rule.pos">
|
||||||
<tr class="rule-row border-b border-neutral/20 hover:bg-background-secondary/50"
|
<tr class="rule-row border-b border-neutral/20 hover:bg-background-secondary/50"
|
||||||
draggable="true"
|
:draggable="editingPositions"
|
||||||
@dragstart="startDrag($event, index)"
|
@dragstart="startDrag($event, index)"
|
||||||
@dragend="endDrag($event)"
|
@dragend="endDrag($event)"
|
||||||
@dragover="dragOver($event, index)"
|
@dragover="dragOver($event, index)"
|
||||||
@@ -627,7 +634,7 @@
|
|||||||
@drop="drop($event, index)"
|
@drop="drop($event, index)"
|
||||||
:class="{ 'drag-over': dragOverIndex === index }">
|
:class="{ 'drag-over': dragOverIndex === index }">
|
||||||
<td class="py-3 px-2 text-sm">
|
<td class="py-3 px-2 text-sm">
|
||||||
<div class="drag-handle" title="Drag to reorder">
|
<div x-show="editingPositions" class="drag-handle" title="Drag to reorder">
|
||||||
<x-ri-menu-line class="size-4" />
|
<x-ri-menu-line class="size-4" />
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
Reference in New Issue
Block a user