Add AdminLTE-style CSS framework to app.css
- Introduced AdminLTE CSS variables for color palette, body colors, card styles, and button styles. - Implemented card components with variants for primary, success, warning, danger, and info. - Added button styles including sizes and outline variants. - Created form controls, select inputs, and input groups with consistent styling. - Included utility classes for text and background colors, gradients, and shadows. - Developed components for badges, alerts, callouts, progress bars, tables, small boxes, and info boxes. - Integrated modal, dropdown, spinner, tooltip, and direct chat styles. - Established timeline and close button styles, with dark mode support for specific components.
This commit is contained in:
@@ -31,12 +31,12 @@
|
||||
<div class="flex-1 space-y-2">
|
||||
<div class="flex items-center justify-between">
|
||||
<h3 class="text-sm font-semibold text-base">Cloud-init Configuration Notice</h3>
|
||||
<button @click="toggle()" type="button" class="text-base/60 hover:text-base transition-colors">
|
||||
<button @click="toggle()" type="button" class="text-gray-500 dark:text-gray-400 hover:text-base transition-colors">
|
||||
<x-ri-arrow-down-s-line x-bind:class="isCollapsed ? 'size-4 transition-transform rotate-180' : 'size-4 transition-transform'" />
|
||||
</button>
|
||||
</div>
|
||||
<div x-show="!isCollapsed" x-transition>
|
||||
<p class="text-xs text-base/70 leading-relaxed">
|
||||
<p class="text-xs text-gray-600 dark:text-gray-400 leading-relaxed">
|
||||
Cloud-init controls the metadata injected into your VM on first boot and whenever you regenerate the cloud-init drive.
|
||||
Use <strong>Apply</strong> to save and regenerate the ISO, <strong>Refresh</strong> to pull fresh values, and <strong>Reset</strong> to discard local edits.
|
||||
Manual installs (ISO workflows, Windows, or images without cloud-init) still require in-guest configuration.
|
||||
@@ -50,12 +50,12 @@
|
||||
<div class="flex items-center gap-2 min-w-0">
|
||||
<h2 class="text-xl font-semibold break-words">Cloud-init Settings</h2>
|
||||
<div class="relative" x-data="{ open: false }" x-cloak>
|
||||
<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-gray-600 dark:text-gray-400 transition-colors">
|
||||
<x-ri-question-line class="size-4" />
|
||||
</button>
|
||||
<div x-show="open" x-transition.opacity class="fixed inset-0 z-50 flex items-center justify-center p-4">
|
||||
<div class="fixed inset-0 bg-black/40 backdrop-blur-sm" @click="open = false"></div>
|
||||
<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"
|
||||
<div class="relative w-full max-w-2xl max-h-[90vh] overflow-y-auto bg-background-secondary rounded-xl border border-gray-200 dark:border-gray-800 shadow-2xl p-6"
|
||||
x-on:keydown.escape.window="open = false">
|
||||
<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" />
|
||||
@@ -71,7 +71,7 @@
|
||||
<p class="block font-sans text-sm font-normal leading-relaxed text-base/90 mb-4">
|
||||
Configure cloud-init metadata that is injected into your virtual machine. These settings control user accounts, SSH keys, hostname, networking, and other first-boot configuration.
|
||||
</p>
|
||||
<div class="pt-4 mt-4 border-t border-neutral/30 space-y-2.5">
|
||||
<div class="pt-4 mt-4 border-t border-gray-200 dark:border-gray-800 space-y-2.5">
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Apply:</span> Saves your changes and regenerates the cloud-init ISO drive. Changes take effect on the next boot.
|
||||
</p>
|
||||
@@ -86,25 +86,25 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-sm text-base/60">
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">
|
||||
These values map directly to the QEMU configuration (`ciuser`, `nameserver`, `ipconfigX`, etc.). Changes take effect on the next cloud-init run or boot.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 xl:grid-cols-2 gap-6">
|
||||
<div class="bg-background-secondary border border-neutral rounded-lg p-4 space-y-4"
|
||||
<div class="bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-2xl shadow-theme-sm p-4 space-y-4"
|
||||
x-data="{ showNetworkModal: @entangle('showNetworkModal') }">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<div class="flex items-center gap-2 min-w-0">
|
||||
<h3 class="text-lg font-semibold break-words">Access & Credentials</h3>
|
||||
<div class="relative" x-data="{ open: false }" x-cloak>
|
||||
<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-gray-600 dark:text-gray-400 transition-colors">
|
||||
<x-ri-question-line class="size-4" />
|
||||
</button>
|
||||
<div x-show="open" x-transition.opacity class="fixed inset-0 z-50 flex items-center justify-center p-4">
|
||||
<div class="fixed inset-0 bg-black/40 backdrop-blur-sm" @click="open = false"></div>
|
||||
<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"
|
||||
<div class="relative w-full max-w-2xl max-h-[90vh] overflow-y-auto bg-background-secondary rounded-xl border border-gray-200 dark:border-gray-800 shadow-2xl p-6"
|
||||
x-on:keydown.escape.window="open = false">
|
||||
<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" />
|
||||
@@ -120,7 +120,7 @@
|
||||
<p class="block font-sans text-sm font-normal leading-relaxed text-base/90 mb-4">
|
||||
Configure the default user account and SSH access for your virtual machine. These settings are used by cloud-init to create accounts and configure SSH keys on first boot.
|
||||
</p>
|
||||
<div class="pt-4 mt-4 border-t border-neutral/30 space-y-2.5">
|
||||
<div class="pt-4 mt-4 border-t border-gray-200 dark:border-gray-800 space-y-2.5">
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Username:</span> The default user account created by cloud-init. This user typically has sudo privileges.
|
||||
</p>
|
||||
@@ -135,7 +135,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-xs text-base/60 mt-1">Defaults used by cloud-init to create accounts and authorize SSH.</p>
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400 mt-1">Defaults used by cloud-init to create accounts and authorize SSH.</p>
|
||||
</div>
|
||||
@if($this->accessCredentialsSynced)
|
||||
<span class="text-xs font-semibold text-success">Synced</span>
|
||||
@@ -153,18 +153,18 @@
|
||||
{{ $ciUser !== '' ? $ciUser : 'Template default (uses image-defined user)' }}
|
||||
</span>
|
||||
<button type="button"
|
||||
class="text-base/70 hover:text-base/60 ml-2"
|
||||
class="text-gray-600 dark:text-gray-400 hover:text-gray-500 dark:text-gray-400 ml-2"
|
||||
@click="showCiUserModal = true"
|
||||
aria-label="Edit Cloud-init user">
|
||||
<x-ri-edit-fill class="inline size-4" />
|
||||
</button>
|
||||
</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-gray-500 dark:text-gray-400">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">
|
||||
<div class="fixed inset-0 bg-black/40 backdrop-blur-sm" @click="showCiUserModal = false"></div>
|
||||
<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-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-2xl shadow-theme-sm shadow-xl w-full max-w-xl mx-4 p-5 space-y-4"
|
||||
x-on:keydown.escape.window="showCiUserModal = false">
|
||||
<div class="flex items-center justify-between">
|
||||
<h4 class="text-base font-semibold text-base/90">Edit Cloud-init User</h4>
|
||||
@@ -176,12 +176,12 @@
|
||||
</button>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<label class="text-xs font-semibold text-base/70">Username</label>
|
||||
<label class="text-xs font-semibold text-gray-600 dark:text-gray-400">Username</label>
|
||||
<input type="text"
|
||||
wire:model.live="ciUser"
|
||||
class="form-input w-full"
|
||||
placeholder="e.g. ubuntu" />
|
||||
<p class="text-xs text-base/60">Leave blank to retain the template default user.</p>
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400">Leave blank to retain the template default user.</p>
|
||||
</div>
|
||||
<div class="flex justify-end gap-2">
|
||||
<x-button.secondary type="button" @click="showCiUserModal = false">
|
||||
@@ -208,26 +208,26 @@
|
||||
</span>
|
||||
@if(isset($server->password) && $server->password)
|
||||
<button type="button"
|
||||
class="text-base/70 hover:text-base/60 ml-2"
|
||||
class="text-gray-600 dark:text-gray-400 hover:text-gray-500 dark:text-gray-400 ml-2"
|
||||
@click="showPasswordViewModal = true"
|
||||
aria-label="View Root Password">
|
||||
<x-ri-eye-line class="inline size-4" />
|
||||
</button>
|
||||
@endif
|
||||
<button type="button"
|
||||
class="text-base/70 hover:text-base/60 ml-2"
|
||||
class="text-gray-600 dark:text-gray-400 hover:text-gray-500 dark:text-gray-400 ml-2"
|
||||
wire:click="startEditingPassword"
|
||||
aria-label="Edit Root Password">
|
||||
<x-ri-edit-fill class="inline size-4" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<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-gray-500 dark:text-gray-400">Matches the Overview tab control. Use Save for database only, Save & Apply to push via cloud-init.</p>
|
||||
|
||||
@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">
|
||||
<div class="fixed inset-0 bg-black/40 backdrop-blur-sm" @click="showPasswordViewModal = false"></div>
|
||||
<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-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-2xl shadow-theme-sm shadow-xl w-full max-w-xl mx-4 p-5 space-y-4"
|
||||
x-on:keydown.escape.window="showPasswordViewModal = false"
|
||||
x-data="{
|
||||
copied: false,
|
||||
@@ -264,7 +264,7 @@
|
||||
|
||||
<div x-cloak x-show="showPasswordEditModal" x-transition.opacity class="fixed inset-0 z-50 flex items-center justify-center">
|
||||
<div class="fixed inset-0 bg-black/40 backdrop-blur-sm" @click="showPasswordEditModal = false; $wire.cancelEditingPassword()"></div>
|
||||
<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-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-2xl shadow-theme-sm shadow-xl w-full max-w-xl mx-4 p-5 space-y-4"
|
||||
x-on:keydown.escape.window="showPasswordEditModal = false; $wire.cancelEditingPassword()">
|
||||
<div class="flex items-center justify-between">
|
||||
<h4 class="text-base font-semibold text-base/90">Edit Root Password</h4>
|
||||
@@ -277,14 +277,14 @@
|
||||
</div>
|
||||
<div class="space-y-3">
|
||||
<div>
|
||||
<label class="text-xs font-semibold text-base/70">New Password</label>
|
||||
<label class="text-xs font-semibold text-gray-600 dark:text-gray-400">New Password</label>
|
||||
<input type="password"
|
||||
wire:model.defer="password"
|
||||
class="form-input w-full mt-1"
|
||||
placeholder="Enter new password" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-xs font-semibold text-base/70">Confirm Password</label>
|
||||
<label class="text-xs font-semibold text-gray-600 dark:text-gray-400">Confirm Password</label>
|
||||
<input type="password"
|
||||
wire:model.defer="password_confirmation"
|
||||
class="form-input w-full mt-1"
|
||||
@@ -293,7 +293,7 @@
|
||||
@if($passwordError)
|
||||
<div class="text-sm text-error">{{ $passwordError }}</div>
|
||||
@endif
|
||||
<p class="text-xs text-base/60">
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400">
|
||||
Save writes the password to the database. Save & Apply also pushes it to the hypervisor; reboot for cloud-init to configure the guest OS.
|
||||
</p>
|
||||
</div>
|
||||
@@ -316,7 +316,7 @@
|
||||
<label class="text-sm font-semibold text-base/80">SSH Public Keys</label>
|
||||
<div class="space-y-2">
|
||||
@forelse($sshKeys as $keyIndex => $key)
|
||||
<div class="flex items-center gap-2 border border-neutral rounded-md bg-background px-3 py-2 text-xs text-base/70 relative"
|
||||
<div class="flex items-center gap-2 border border-neutral rounded-md bg-background px-3 py-2 text-xs text-gray-600 dark:text-gray-400 relative"
|
||||
x-data="{
|
||||
showKeyModal: false,
|
||||
copied: false,
|
||||
@@ -329,7 +329,7 @@
|
||||
}">
|
||||
<span class="truncate flex-1" title="{{ $key }}">{{ $key }}</span>
|
||||
<button type="button"
|
||||
class="text-base/70 hover:text-base/60 ml-2"
|
||||
class="text-gray-600 dark:text-gray-400 hover:text-gray-500 dark:text-gray-400 ml-2"
|
||||
@click="showKeyModal = true"
|
||||
aria-label="View SSH key">
|
||||
<x-ri-eye-line class="inline size-4" />
|
||||
@@ -342,7 +342,7 @@
|
||||
|
||||
<div x-cloak x-show="showKeyModal" x-transition.opacity class="fixed inset-0 z-50 flex items-center justify-center">
|
||||
<div class="fixed inset-0 bg-black/40 backdrop-blur-sm" @click="showKeyModal = false"></div>
|
||||
<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-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-2xl shadow-theme-sm shadow-xl w-full max-w-xl mx-4 p-5 space-y-4"
|
||||
x-on:keydown.escape.window="showKeyModal = false">
|
||||
<div class="flex items-center justify-between">
|
||||
<h4 class="text-base font-semibold text-base/90">SSH Public Key</h4>
|
||||
@@ -376,11 +376,11 @@
|
||||
Add Key
|
||||
</x-button.secondary>
|
||||
</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-gray-500 dark:text-gray-400">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">
|
||||
<div class="fixed inset-0 bg-black/40 backdrop-blur-sm" @click="showAddKeyModal = false"></div>
|
||||
<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-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-2xl shadow-theme-sm shadow-xl w-full max-w-xl mx-4 p-5 space-y-4"
|
||||
x-on:keydown.escape.window="showAddKeyModal = false">
|
||||
<div class="flex items-center justify-between">
|
||||
<h4 class="text-base font-semibold text-base/90">Add SSH Public Key</h4>
|
||||
@@ -392,7 +392,7 @@
|
||||
</button>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<label class="text-xs font-semibold text-base/70">SSH Key</label>
|
||||
<label class="text-xs font-semibold text-gray-600 dark:text-gray-400">SSH Key</label>
|
||||
<textarea wire:model.defer="newSshKey"
|
||||
class="form-input w-full h-28 resize-y"
|
||||
placeholder="ssh-ed25519 AAAA... user@host"></textarea>
|
||||
@@ -415,24 +415,24 @@
|
||||
<input id="ci-upgrade" type="checkbox" wire:model.live="upgradePackages" class="form-checkbox" />
|
||||
<label for="ci-upgrade" class="text-sm font-semibold text-base/80">Upgrade packages on first boot</label>
|
||||
</div>
|
||||
<p class="text-xs text-base/60">
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400">
|
||||
Runs <code>apt/yum update && upgrade</code> when cloud-init executes. Enable only if your template supports unattended upgrades.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-background-secondary border border-neutral rounded-lg p-4 space-y-4"
|
||||
<div class="bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-2xl shadow-theme-sm p-4 space-y-4"
|
||||
x-data="{ showNetworkModal: @entangle('showNetworkModal') }">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<div class="flex items-center gap-2 min-w-0">
|
||||
<h3 class="text-lg font-semibold break-words">Network Configuration</h3>
|
||||
<div class="relative" x-data="{ open: false }" x-cloak>
|
||||
<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-gray-600 dark:text-gray-400 transition-colors">
|
||||
<x-ri-question-line class="size-4" />
|
||||
</button>
|
||||
<div x-show="open" x-transition.opacity class="fixed inset-0 z-50 flex items-center justify-center p-4">
|
||||
<div class="fixed inset-0 bg-black/40 backdrop-blur-sm" @click="open = false"></div>
|
||||
<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"
|
||||
<div class="relative w-full max-w-2xl max-h-[90vh] overflow-y-auto bg-background-secondary rounded-xl border border-gray-200 dark:border-gray-800 shadow-2xl p-6"
|
||||
x-on:keydown.escape.window="open = false">
|
||||
<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" />
|
||||
@@ -448,7 +448,7 @@
|
||||
<p class="block font-sans text-sm font-normal leading-relaxed text-base/90 mb-4">
|
||||
Configure network interfaces for your virtual machine. Each network card corresponds to an <code>ipconfigX</code> parameter in the QEMU configuration, allowing you to set IPv4 and IPv6 addresses independently.
|
||||
</p>
|
||||
<div class="pt-4 mt-4 border-t border-neutral/30 space-y-2.5">
|
||||
<div class="pt-4 mt-4 border-t border-gray-200 dark:border-gray-800 space-y-2.5">
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">IP Configuration:</span> Each network interface can have separate IPv4 and IPv6 configurations. Use CIDR notation (e.g., 192.168.1.100/24) for IP addresses.
|
||||
</p>
|
||||
@@ -463,9 +463,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-xs text-base/60 mt-1">Each card corresponds to an <code>ipconfigX</code>. Configure IPv4 and IPv6 independently.</p>
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400 mt-1">Each card corresponds to an <code>ipconfigX</code>. Configure IPv4 and IPv6 independently.</p>
|
||||
</div>
|
||||
<span class="text-xs text-base/60">{{ count($networks) }} interfaces</span>
|
||||
<span class="text-xs text-gray-500 dark:text-gray-400">{{ count($networks) }} interfaces</span>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 gap-4">
|
||||
@@ -474,12 +474,12 @@
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<span class="text-sm font-semibold text-base/80 uppercase">{{ $network['key'] }}</span>
|
||||
<p class="text-xs text-base/60">
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400">
|
||||
Network Device: NET{{ str_replace('ipconfig', '', $network['key']) }}
|
||||
</p>
|
||||
</div>
|
||||
<button wire:click="startEditingNetwork({{ $index }})" type="button"
|
||||
class="text-base/70 hover:text-base/60 ml-2"
|
||||
class="text-gray-600 dark:text-gray-400 hover:text-gray-500 dark:text-gray-400 ml-2"
|
||||
@click="showNetworkModal = true">
|
||||
<x-ri-edit-fill class="inline size-4" />
|
||||
</button>
|
||||
@@ -487,25 +487,25 @@
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-3">
|
||||
<div>
|
||||
<label class="text-xs font-semibold text-base/70">IPv4 Address (CIDR)</label>
|
||||
<label class="text-xs font-semibold text-gray-600 dark:text-gray-400">IPv4 Address (CIDR)</label>
|
||||
<div class="text-sm text-base/80 mt-1">
|
||||
{{ !empty($network['ip']) ? $network['ip'] : '—' }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-xs font-semibold text-base/70">IPv4 Gateway</label>
|
||||
<label class="text-xs font-semibold text-gray-600 dark:text-gray-400">IPv4 Gateway</label>
|
||||
<div class="text-sm text-base/80 mt-1">
|
||||
{{ !empty($network['gw']) ? $network['gw'] : '—' }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-xs font-semibold text-base/70">IPv6 Address (CIDR)</label>
|
||||
<label class="text-xs font-semibold text-gray-600 dark:text-gray-400">IPv6 Address (CIDR)</label>
|
||||
<div class="text-sm text-base/80 mt-1">
|
||||
{{ !empty($network['ip6']) ? $network['ip6'] : '—' }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-xs font-semibold text-base/70">IPv6 Gateway</label>
|
||||
<label class="text-xs font-semibold text-gray-600 dark:text-gray-400">IPv6 Gateway</label>
|
||||
<div class="text-sm text-base/80 mt-1">
|
||||
{{ !empty($network['gw6']) ? $network['gw6'] : '—' }}
|
||||
</div>
|
||||
@@ -513,12 +513,12 @@
|
||||
</div>
|
||||
|
||||
@if(($network['dhcp'] ?? false))
|
||||
<div class="text-xs text-base/60">
|
||||
<div class="text-xs text-gray-500 dark:text-gray-400">
|
||||
<span class="font-semibold">DHCP:</span> Enabled
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<p class="text-xs text-base/60">
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400">
|
||||
Leave fields blank to remove static addressing. If both IPv4 fields are empty, cloud-init omits the IPv4 stanza.
|
||||
</p>
|
||||
</div>
|
||||
@@ -527,7 +527,7 @@
|
||||
|
||||
<div x-cloak x-show="showNetworkModal" x-transition.opacity class="fixed inset-0 z-50 flex items-center justify-center">
|
||||
<div class="fixed inset-0 bg-black/40 backdrop-blur-sm" @click="showNetworkModal = false; $wire.cancelEditingNetwork()"></div>
|
||||
<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="relative bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-2xl shadow-theme-sm shadow-xl w-full max-w-2xl mx-4 p-5 space-y-4"
|
||||
x-on:keydown.escape.window="showNetworkModal = false; $wire.cancelEditingNetwork()">
|
||||
<div class="flex items-center justify-between">
|
||||
<h4 class="text-base font-semibold text-base/90">Edit Network Configuration</h4>
|
||||
@@ -542,27 +542,27 @@
|
||||
<div class="space-y-4">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-3">
|
||||
<div>
|
||||
<label class="text-xs font-semibold text-base/70">IPv4 Address (CIDR)</label>
|
||||
<label class="text-xs font-semibold text-gray-600 dark:text-gray-400">IPv4 Address (CIDR)</label>
|
||||
<input type="text" wire:model="editingNetwork.ip" class="form-input w-full mt-1"
|
||||
placeholder="45.154.99.28/24" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-xs font-semibold text-base/70">IPv4 Gateway</label>
|
||||
<label class="text-xs font-semibold text-gray-600 dark:text-gray-400">IPv4 Gateway</label>
|
||||
<input type="text" wire:model="editingNetwork.gw" class="form-input w-full mt-1"
|
||||
placeholder="45.154.99.17" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-xs font-semibold text-base/70">IPv6 Address (CIDR)</label>
|
||||
<label class="text-xs font-semibold text-gray-600 dark:text-gray-400">IPv6 Address (CIDR)</label>
|
||||
<input type="text" wire:model="editingNetwork.ip6" class="form-input w-full mt-1"
|
||||
placeholder="2a0b:4e07::2:10/64" />
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-xs font-semibold text-base/70">IPv6 Gateway</label>
|
||||
<label class="text-xs font-semibold text-gray-600 dark:text-gray-400">IPv6 Gateway</label>
|
||||
<input type="text" wire:model="editingNetwork.gw6" class="form-input w-full mt-1"
|
||||
placeholder="2a0b:4e07::1" />
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-xs text-base/60">
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400">
|
||||
Leave fields blank to remove static addressing. If both IPv4 fields are empty, cloud-init omits the IPv4 stanza.
|
||||
</p>
|
||||
<div class="flex justify-end gap-2">
|
||||
@@ -580,18 +580,18 @@
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 xl:grid-cols-2 gap-6">
|
||||
<div class="bg-background-secondary border border-neutral rounded-lg p-4 space-y-4">
|
||||
<div class="bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-2xl shadow-theme-sm p-4 space-y-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<div class="flex items-center gap-2 min-w-0">
|
||||
<h3 class="text-lg font-semibold break-words">DNS Settings</h3>
|
||||
<div class="relative" x-data="{ open: false }" x-cloak>
|
||||
<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-gray-600 dark:text-gray-400 transition-colors">
|
||||
<x-ri-question-line class="size-4" />
|
||||
</button>
|
||||
<div x-show="open" x-transition.opacity class="fixed inset-0 z-50 flex items-center justify-center p-4">
|
||||
<div class="fixed inset-0 bg-black/40 backdrop-blur-sm" @click="open = false"></div>
|
||||
<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"
|
||||
<div class="relative w-full max-w-2xl max-h-[90vh] overflow-y-auto bg-background-secondary rounded-xl border border-gray-200 dark:border-gray-800 shadow-2xl p-6"
|
||||
x-on:keydown.escape.window="open = false">
|
||||
<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" />
|
||||
@@ -607,7 +607,7 @@
|
||||
<p class="block font-sans text-sm font-normal leading-relaxed text-base/90 mb-4">
|
||||
Configure DNS (Domain Name System) settings for your virtual machine. These settings control how the guest OS resolves domain names to IP addresses.
|
||||
</p>
|
||||
<div class="pt-4 mt-4 border-t border-neutral/30 space-y-2.5">
|
||||
<div class="pt-4 mt-4 border-t border-gray-200 dark:border-gray-800 space-y-2.5">
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Search Domain:</span> The default domain suffix appended to hostnames that don't contain a domain. For example, with "example.com" as search domain, "server" resolves to "server.example.com".
|
||||
</p>
|
||||
@@ -622,7 +622,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-xs text-base/60 mt-1">Configures <code>searchdomain</code> and <code>nameserver</code> values.</p>
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400 mt-1">Configures <code>searchdomain</code> and <code>nameserver</code> values.</p>
|
||||
</div>
|
||||
@if($this->dnsSettingsSynced)
|
||||
<span class="text-xs font-semibold text-success">Synced</span>
|
||||
@@ -640,18 +640,18 @@
|
||||
{{ $dnsDomain !== '' ? $dnsDomain : 'Not configured (system default will be used)' }}
|
||||
</span>
|
||||
<button type="button"
|
||||
class="text-base/70 hover:text-base/60 ml-2"
|
||||
class="text-gray-600 dark:text-gray-400 hover:text-gray-500 dark:text-gray-400 ml-2"
|
||||
@click="showDnsDomainModal = true"
|
||||
aria-label="Edit DNS Domain">
|
||||
<x-ri-edit-fill class="inline size-4" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-xs text-base/60">Appended to short hostnames for resolution.</p>
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400">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">
|
||||
<div class="fixed inset-0 bg-black/40 backdrop-blur-sm" @click="showDnsDomainModal = false"></div>
|
||||
<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-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-2xl shadow-theme-sm shadow-xl w-full max-w-xl mx-4 p-5 space-y-4"
|
||||
x-on:keydown.escape.window="showDnsDomainModal = false">
|
||||
<div class="flex items-center justify-between">
|
||||
<h4 class="text-base font-semibold text-base/90">Edit DNS Domain</h4>
|
||||
@@ -663,12 +663,12 @@
|
||||
</button>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<label class="text-xs font-semibold text-base/70">DNS Domain (searchdomain)</label>
|
||||
<label class="text-xs font-semibold text-gray-600 dark:text-gray-400">DNS Domain (searchdomain)</label>
|
||||
<input type="text"
|
||||
wire:model.live="dnsDomain"
|
||||
class="form-input w-full"
|
||||
placeholder="example.internal" />
|
||||
<p class="text-xs text-base/60">Leave blank to use system default. Appended to short hostnames for resolution.</p>
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400">Leave blank to use system default. Appended to short hostnames for resolution.</p>
|
||||
</div>
|
||||
<div class="flex justify-end gap-2">
|
||||
<x-button.secondary type="button" @click="showDnsDomainModal = false">
|
||||
@@ -686,7 +686,7 @@
|
||||
<label class="text-sm font-semibold text-base/80">DNS Nameservers</label>
|
||||
<div class="space-y-2">
|
||||
@forelse($dnsServers as $dnsIndex => $resolver)
|
||||
<div class="flex items-center gap-2 border border-neutral rounded-md bg-background px-3 py-2 text-xs text-base/70">
|
||||
<div class="flex items-center gap-2 border border-neutral rounded-md bg-background px-3 py-2 text-xs text-gray-600 dark:text-gray-400">
|
||||
<span class="truncate flex-1" title="{{ $resolver }}">{{ $resolver }}</span>
|
||||
<button type="button" wire:click="removeDnsServer({{ $dnsIndex }})"
|
||||
class="text-error hover:text-error/80 ml-2">
|
||||
@@ -702,11 +702,11 @@
|
||||
Add Nameserver
|
||||
</x-button.secondary>
|
||||
</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-gray-500 dark:text-gray-400 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">
|
||||
<div class="fixed inset-0 bg-black/40 backdrop-blur-sm" @click="showAddDnsModal = false"></div>
|
||||
<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-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-2xl shadow-theme-sm shadow-xl w-full max-w-xl mx-4 p-5 space-y-4"
|
||||
x-on:keydown.escape.window="showAddDnsModal = false">
|
||||
<div class="flex items-center justify-between">
|
||||
<h4 class="text-base font-semibold text-base/90">Add DNS Nameserver</h4>
|
||||
@@ -719,12 +719,12 @@
|
||||
</div>
|
||||
<div class="space-y-3">
|
||||
<div class="space-y-2">
|
||||
<label class="text-xs font-semibold text-base/70">Quick Add</label>
|
||||
<label class="text-xs font-semibold text-gray-600 dark:text-gray-400">Quick Add</label>
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
<button type="button"
|
||||
wire:click="quickAddDnsServers('cloudflare')"
|
||||
@click="showAddDnsModal = false"
|
||||
class="flex items-center gap-2 px-3 py-2 bg-background border border-neutral rounded-md hover:bg-background/80 text-sm text-base/70 transition-colors">
|
||||
class="flex items-center gap-2 px-3 py-2 bg-background border border-neutral rounded-md hover:bg-background/80 text-sm text-gray-600 dark:text-gray-400 transition-colors">
|
||||
<svg viewBox="0 -70 256 256" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid" fill="#000000" class="size-4">
|
||||
<g id="SVGRepo_bgCarrier" stroke-width="0"></g>
|
||||
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g>
|
||||
@@ -743,7 +743,7 @@
|
||||
<button type="button"
|
||||
wire:click="quickAddDnsServers('google')"
|
||||
@click="showAddDnsModal = false"
|
||||
class="flex items-center gap-2 px-3 py-2 bg-background border border-neutral rounded-md hover:bg-background/80 text-sm text-base/70 transition-colors">
|
||||
class="flex items-center gap-2 px-3 py-2 bg-background border border-neutral rounded-md hover:bg-background/80 text-sm text-gray-600 dark:text-gray-400 transition-colors">
|
||||
<svg viewBox="-3 0 262 262" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid" fill="currentColor" class="size-4">
|
||||
<g id="SVGRepo_bgCarrier" stroke-width="0"></g>
|
||||
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g>
|
||||
@@ -759,7 +759,7 @@
|
||||
<button type="button"
|
||||
wire:click="quickAddDnsServers('quad9')"
|
||||
@click="showAddDnsModal = false"
|
||||
class="flex items-center gap-2 px-3 py-2 bg-background border border-neutral rounded-md hover:bg-background/80 text-sm text-base/70 transition-colors">
|
||||
class="flex items-center gap-2 px-3 py-2 bg-background border border-neutral rounded-md hover:bg-background/80 text-sm text-gray-600 dark:text-gray-400 transition-colors">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64" class="size-4">
|
||||
<path d="M18.235 63.971h14.953l16.888-25.26c3.897-5.83 6.091-11.2 6.091-17.06C56.167 9.238 45.746 0 32.034 0S7.9 9.295 7.9 21.882c0 12.586 9.209 21.333 22.228 21.333.953 0 1.934-.058 2.887-.173L18.205 64Zm13.799-31.639c-6.467 0-11.23-4.36-11.23-10.537s4.763-10.537 11.23-10.537c6.466 0 11.23 4.302 11.23 10.537s-4.822 10.537-11.23 10.537" style="fill:#dc205e;stroke-width:2.88678"/>
|
||||
<path d="M0 0h150v150H0Z" style="fill:none"/>
|
||||
@@ -769,7 +769,7 @@
|
||||
<button type="button"
|
||||
wire:click="quickAddDnsServers('nat64')"
|
||||
@click="showAddDnsModal = false"
|
||||
class="flex items-center gap-2 px-3 py-2 bg-background border border-neutral rounded-md hover:bg-background/80 text-sm text-base/70 transition-colors">
|
||||
class="flex items-center gap-2 px-3 py-2 bg-background border border-neutral rounded-md hover:bg-background/80 text-sm text-gray-600 dark:text-gray-400 transition-colors">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="512" width="512" viewBox="0 0 512 512" class="size-4">
|
||||
<circle style="fill:#FFDA44;" cx="256" cy="256" r="256"></circle>
|
||||
<path style="fill:#338AF3;" d="M0,256C0,114.616,114.616,0,256,0s256,114.616,256,256"></path>
|
||||
@@ -779,7 +779,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<label class="text-xs font-semibold text-base/70">Nameserver</label>
|
||||
<label class="text-xs font-semibold text-gray-600 dark:text-gray-400">Nameserver</label>
|
||||
<input type="text"
|
||||
wire:model.defer="newDnsServer"
|
||||
class="form-input w-full"
|
||||
@@ -802,18 +802,18 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-background-secondary border border-neutral rounded-lg p-4 space-y-4">
|
||||
<div class="bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-2xl shadow-theme-sm p-4 space-y-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<div class="flex items-center gap-2 min-w-0">
|
||||
<h3 class="text-lg font-semibold break-words">OS Type</h3>
|
||||
<div class="relative" x-data="{ open: false }" x-cloak>
|
||||
<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-gray-600 dark:text-gray-400 transition-colors">
|
||||
<x-ri-question-line class="size-4" />
|
||||
</button>
|
||||
<div x-show="open" x-transition.opacity class="fixed inset-0 z-50 flex items-center justify-center p-4">
|
||||
<div class="fixed inset-0 bg-black/40 backdrop-blur-sm" @click="open = false"></div>
|
||||
<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"
|
||||
<div class="relative w-full max-w-2xl max-h-[90vh] overflow-y-auto bg-background-secondary rounded-xl border border-gray-200 dark:border-gray-800 shadow-2xl p-6"
|
||||
x-on:keydown.escape.window="open = false">
|
||||
<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" />
|
||||
@@ -829,7 +829,7 @@
|
||||
<p class="block font-sans text-sm font-normal leading-relaxed text-base/90 mb-4">
|
||||
Specifies the operating system type for cloud-init metadata generation. This setting helps cloud-init apply the correct configuration format and optimizations for your guest OS.
|
||||
</p>
|
||||
<div class="pt-4 mt-4 border-t border-neutral/30 space-y-2.5">
|
||||
<div class="pt-4 mt-4 border-t border-gray-200 dark:border-gray-800 space-y-2.5">
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Linux:</span> Standard Linux distributions (Ubuntu, Debian, CentOS, etc.). Uses standard cloud-init configuration format.
|
||||
</p>
|
||||
@@ -844,7 +844,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-xs text-base/60 mt-1">Controls the <code>ostype</code> option used when generating cloud-init media.</p>
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400 mt-1">Controls the <code>ostype</code> option used when generating cloud-init media.</p>
|
||||
</div>
|
||||
@if($this->osTypeSynced)
|
||||
<span class="text-xs font-semibold text-success">Synced</span>
|
||||
@@ -863,10 +863,10 @@
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<p class="text-xs text-base/60 mt-1">
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400 mt-1">
|
||||
Determines whether the guest receives nocloud or config-drive metadata. Choose the entry that matches your template.
|
||||
</p>
|
||||
<div class="bg-warning/10 border border-warning/30 rounded-lg p-3 text-xs text-base/70 leading-relaxed mt-2">
|
||||
<div class="bg-warning/10 border border-warning/30 rounded-lg p-3 text-xs text-gray-600 dark:text-gray-400 leading-relaxed mt-2">
|
||||
<strong>Tip:</strong> Pick a Windows option only for cloud-ready Windows images (cloudbase-init). Using a Windows entry on Linux templates prevents the nocloud ISO from mounting.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user