Refactor Proxmox views for improved styling and consistency
- Updated subdomain.blade.php to enhance button styles and modal transitions. - Changed text colors for better readability and consistency across the UI. - Refactored system.blade.php to unify button components and improve layout structure. - Adjusted modal z-index values for consistent layering. - Enhanced accessibility by ensuring proper text contrast and hover states.
This commit is contained in:
@@ -45,7 +45,7 @@
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<div class="bg-error-50 dark:bg-error-500 border border-error-200 dark:border-error-500 rounded-xl p-4 mb-6"
|
||||
<div class="bg-error/10 border border-error/30 rounded-lg p-4 mb-6"
|
||||
x-data="{
|
||||
isCollapsed: localStorage.getItem('network-policy-collapsed') === 'true',
|
||||
isAdvancedView: localStorage.getItem('proxmox-view-mode') === 'advanced',
|
||||
@@ -101,16 +101,68 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<x-proxmox::ui.section-header
|
||||
title="Assigned Network Addresses"
|
||||
icon="ri-global-line"
|
||||
class="mb-0">
|
||||
</x-proxmox::ui.section-header>
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="flex items-center gap-2 min-w-0">
|
||||
<h2 class="text-xl font-semibold break-words">Assigned Network Addresses</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">
|
||||
<x-ri-question-line class="size-4" />
|
||||
</button>
|
||||
<!-- Modal Backdrop -->
|
||||
<div x-show="open"
|
||||
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="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">
|
||||
<x-ri-close-line class="size-5" />
|
||||
</button>
|
||||
<div class="flex items-center gap-3 mb-4 pr-8">
|
||||
<div class="flex items-center justify-center w-10 h-10 rounded-lg bg-primary/10">
|
||||
<x-ri-global-line class="size-5 text-primary" />
|
||||
</div>
|
||||
<h6 class="font-sans text-lg font-semibold leading-tight text-base/100">
|
||||
Assigned Network Addresses
|
||||
</h6>
|
||||
</div>
|
||||
<p class="block font-sans text-sm font-normal leading-relaxed text-base/90 mb-4">
|
||||
Displays all IP addresses (both IPv4 and IPv6) that have been assigned to this virtual machine. These addresses are configured through the QEMU API and are part of your service allocation.
|
||||
</p>
|
||||
<div class="pt-4 mt-4 border-t border-neutral/30">
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Note:</span> These addresses are managed by the hosting provider and cannot be modified directly. Contact support if you need additional IP addresses or changes to your network configuration.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-2xl p-4 mb-6 shadow-theme-sm"
|
||||
<div class="bg-background-secondary border border-neutral rounded-lg p-4 mb-6"
|
||||
x-data="{ isAdvancedView: localStorage.getItem('proxmox-view-mode') === 'advanced' }"
|
||||
x-init="
|
||||
isAdvancedView = localStorage.getItem('proxmox-view-mode') === 'advanced';
|
||||
@@ -137,7 +189,7 @@
|
||||
x-transition:leave-end="opacity-0"
|
||||
@click="open = false"
|
||||
@keydown.escape.window="open = false"
|
||||
class="fixed inset-0 z-[60] bg-black/50 backdrop-blur-sm"
|
||||
class="fixed inset-0 z-50 bg-black/50 backdrop-blur-sm"
|
||||
style="display: none;">
|
||||
</div>
|
||||
<!-- Modal -->
|
||||
@@ -150,14 +202,14 @@
|
||||
x-transition:leave-end="opacity-0 scale-95"
|
||||
@click.away="open = false"
|
||||
@keydown.escape.window="open = false"
|
||||
class="fixed inset-0 z-[60] flex items-center justify-center p-4"
|
||||
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">
|
||||
<x-ri-close-line class="size-5" />
|
||||
</button>
|
||||
<div class="flex items-center gap-3 mb-4 pr-8">
|
||||
<div class="flex items-center justify-center w-10 h-10 rounded-lg bg-primary">
|
||||
<div class="flex items-center justify-center w-10 h-10 rounded-lg bg-primary/10">
|
||||
<x-ri-router-line class="size-5 text-primary" />
|
||||
</div>
|
||||
<h6 class="font-sans text-lg font-semibold leading-tight">
|
||||
@@ -192,9 +244,7 @@
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="overflow-x-auto rounded-xl border border-gray-200 dark:border-gray-800 mb-4 transition-all duration-300 hover:shadow-md"
|
||||
x-data="{ tableLoaded: false }"
|
||||
x-init="setTimeout(() => tableLoaded = true, 150)">
|
||||
<div class="overflow-x-auto rounded-lg border border-neutral/40 mb-4">
|
||||
<table class="min-w-full divide-y divide-neutral/30 text-sm">
|
||||
<thead class="bg-background">
|
||||
<tr class="text-left text-xs font-semibold text-base/60 uppercase tracking-wide">
|
||||
@@ -207,11 +257,8 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-neutral/20 text-base text-base/80">
|
||||
@foreach($interfaces as $index => $type)
|
||||
@php $name = array_keys($interfaces)[$loop->index]; @endphp
|
||||
<tr class="transition-all duration-200 hover:bg-gray-50 dark:hover:bg-gray-800/50"
|
||||
:class="tableLoaded ? 'opacity-100 translate-x-0' : 'opacity-0 -translate-x-2'"
|
||||
:style="'transition-delay: {{ $loop->index * 50 }}ms'">
|
||||
@foreach($interfaces as $name => $type)
|
||||
<tr>
|
||||
<td class="px-4 py-3 font-semibold">{{ strtoupper($name) }}</td>
|
||||
<td class="px-4 py-3">
|
||||
<select wire:model.live="interfaceSelections.{{ $name }}"
|
||||
@@ -273,26 +320,26 @@
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col sm:flex-row gap-3">
|
||||
<x-proxmox::ui.button wire:click="addInterface" wire:loading.attr="disabled" class="w-full sm:w-1/3"
|
||||
:disabled="!$this->canAddInterface" variant="secondary">
|
||||
<x-button.secondary wire:click="addInterface" wire:loading.attr="disabled" class="w-full sm:w-1/3"
|
||||
:disabled="!$this->canAddInterface">
|
||||
<x-loading target="addInterface" />
|
||||
<span wire:loading.remove wire:target="addInterface">
|
||||
<x-ri-add-line class="inline size-4 mr-1" />
|
||||
Add Device
|
||||
</span>
|
||||
<span wire:loading wire:target="addInterface">Adding...</span>
|
||||
</x-proxmox::ui.button>
|
||||
<x-proxmox::ui.button wire:click="refreshInterfaces" wire:loading.attr="disabled" class="w-full" variant="secondary">
|
||||
</x-button.secondary>
|
||||
<x-button.secondary wire:click="refreshInterfaces" wire:loading.attr="disabled" class="w-full">
|
||||
<x-loading target="refreshInterfaces" />
|
||||
<span wire:loading.remove wire:target="refreshInterfaces">Refresh Interfaces</span>
|
||||
<span wire:loading wire:target="refreshInterfaces">Refreshing...</span>
|
||||
</x-proxmox::ui.button>
|
||||
<x-proxmox::ui.button wire:click="updateInterfaceType" wire:loading.attr="disabled" class="w-full"
|
||||
:disabled="!$this->canUpdateInterface" variant="primary">
|
||||
</x-button.secondary>
|
||||
<x-button.primary wire:click="updateInterfaceType" wire:loading.attr="disabled" class="w-full"
|
||||
:disabled="!$this->canUpdateInterface">
|
||||
<x-loading target="updateInterfaceType" />
|
||||
<span wire:loading.remove wire:target="updateInterfaceType">Save Interface Type</span>
|
||||
<span wire:loading wire:target="updateInterfaceType">Saving...</span>
|
||||
</x-proxmox::ui.button>
|
||||
</x-button.primary>
|
||||
</div>
|
||||
<p class="text-xs text-base/50 mt-2">VirtIO provides the best performance; legacy adapters (E1000, Realtek, PCnet, VMware) improve compatibility.</p>
|
||||
<p class="text-xs text-base/50 mt-1">
|
||||
@@ -301,10 +348,10 @@
|
||||
</div>
|
||||
|
||||
@foreach($server->ipAddresses as $network)
|
||||
<div class="relative flex flex-col gap-4 bg-white dark:bg-gray-900 hover:shadow-theme-sm border border-gray-200 dark:border-gray-800 p-4 rounded-2xl mb-4 transition-all duration-200">
|
||||
<div class="relative flex flex-col gap-4 bg-background-secondary hover:bg-background-secondary/80 border border-neutral p-4 rounded-lg mb-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">{{ strtoupper($network->type ?? 'IPv4') }} Address</h3>
|
||||
<span class="text-xs font-medium px-2 py-1 rounded-lg bg-gray-100 dark:bg-gray-800 border border-gray-200 dark:border-gray-700 text-gray-700 dark:text-gray-300">
|
||||
<h3 class="text-lg font-semibold">{{ strtoupper($network->type ?? 'IPv4') }} Address</h3>
|
||||
<span class="text-xs font-medium px-2 py-1 rounded bg-background border border-neutral">
|
||||
{{ $network->type === 'ipv6' ? 'IPv6' : 'IPv4' }}
|
||||
</span>
|
||||
</div>
|
||||
@@ -427,37 +474,37 @@
|
||||
<div class="flex-1"></div>
|
||||
<div class="flex gap-2 justify-end mt-auto">
|
||||
@if($isIpv6)
|
||||
<x-proxmox::ui.button
|
||||
<x-button.primary
|
||||
onclick="window.open('https://ping6.ping.pe/{{ $network->ip }}', '_blank')"
|
||||
class="text-xs" variant="primary">
|
||||
class="text-xs">
|
||||
Ping
|
||||
</x-proxmox::ui.button>
|
||||
<x-proxmox::ui.button
|
||||
</x-button.primary>
|
||||
<x-button.primary
|
||||
onclick="window.open('https://mtr6.ping.pe/{{ $network->ip }}', '_blank')"
|
||||
class="text-xs" variant="primary">
|
||||
class="text-xs">
|
||||
MTR
|
||||
</x-proxmox::ui.button>
|
||||
<x-proxmox::ui.button
|
||||
</x-button.primary>
|
||||
<x-button.primary
|
||||
onclick="window.open('https://bgp.ping.pe/{{ $network->ip }}', '_blank')"
|
||||
class="text-xs" variant="primary">
|
||||
class="text-xs">
|
||||
BGP
|
||||
</x-proxmox::ui.button>
|
||||
</x-button.primary>
|
||||
@else
|
||||
<x-proxmox::ui.button
|
||||
<x-button.primary
|
||||
onclick="window.open('https://ping.pe/{{ $network->ip }}', '_blank')"
|
||||
class="text-xs" variant="primary">
|
||||
class="text-xs">
|
||||
Ping
|
||||
</x-proxmox::ui.button>
|
||||
<x-proxmox::ui.button
|
||||
</x-button.primary>
|
||||
<x-button.primary
|
||||
onclick="window.open('https://mtr.ping.pe/{{ $network->ip }}', '_blank')"
|
||||
class="text-xs" variant="primary">
|
||||
class="text-xs">
|
||||
MTR
|
||||
</x-proxmox::ui.button>
|
||||
<x-proxmox::ui.button
|
||||
</x-button.primary>
|
||||
<x-button.primary
|
||||
onclick="window.open('https://bgp.ping.pe/{{ $network->ip }}', '_blank')"
|
||||
class="text-xs" variant="primary">
|
||||
class="text-xs">
|
||||
BGP
|
||||
</x-proxmox::ui.button>
|
||||
</x-button.primary>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@@ -581,7 +628,7 @@
|
||||
x-transition:leave-end="opacity-0"
|
||||
@click="open = false"
|
||||
@keydown.escape.window="open = false"
|
||||
class="fixed inset-0 z-[60] bg-black/50 backdrop-blur-sm"
|
||||
class="fixed inset-0 z-50 bg-black/50 backdrop-blur-sm"
|
||||
style="display: none;">
|
||||
</div>
|
||||
<!-- Modal -->
|
||||
@@ -594,14 +641,14 @@
|
||||
x-transition:leave-end="opacity-0 scale-95"
|
||||
@click.away="open = false"
|
||||
@keydown.escape.window="open = false"
|
||||
class="fixed inset-0 z-[60] flex items-center justify-center p-4"
|
||||
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">
|
||||
<x-ri-close-line class="size-5" />
|
||||
</button>
|
||||
<div class="flex items-center gap-3 mb-4 pr-8">
|
||||
<div class="flex items-center justify-center w-10 h-10 rounded-lg bg-primary">
|
||||
<div class="flex items-center justify-center w-10 h-10 rounded-lg bg-primary/10">
|
||||
<x-ri-information-line class="size-5 text-primary" />
|
||||
</div>
|
||||
<h6 class="font-sans text-lg font-semibold leading-tight">
|
||||
@@ -626,7 +673,7 @@
|
||||
The following addresses were detected by the QEMU guest agent but are not configured in the system database.
|
||||
</p>
|
||||
@else
|
||||
<div class="bg-info border border-info rounded-lg p-4 mb-4">
|
||||
<div class="bg-info/10 border border-info/30 rounded-lg p-4 mb-4">
|
||||
<div class="flex items-start gap-3">
|
||||
<x-ri-information-line class="size-5 text-info flex-shrink-0 mt-0.5" />
|
||||
<div class="flex-1">
|
||||
@@ -645,10 +692,10 @@
|
||||
|
||||
@if(count($additionalAddresses) > 0)
|
||||
@foreach($additionalAddresses as $address)
|
||||
<div class="relative flex flex-col gap-4 bg-white dark:bg-gray-900 hover:shadow-theme-sm border border-gray-200 dark:border-gray-800 p-4 rounded-2xl mb-4 transition-all duration-200">
|
||||
<div class="relative flex flex-col gap-4 bg-background-secondary hover:bg-background-secondary/80 border border-neutral p-4 rounded-lg mb-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">{{ strtoupper($address['type'] === 'ipv6' ? 'IPv6' : 'IPv4') }} Address</h3>
|
||||
<span class="text-xs font-medium px-2 py-1 rounded-lg bg-gray-100 dark:bg-gray-800 border border-gray-200 dark:border-gray-700 text-gray-700 dark:text-gray-300">
|
||||
<h3 class="text-lg font-semibold">{{ strtoupper($address['type'] === 'ipv6' ? 'IPv6' : 'IPv4') }} Address</h3>
|
||||
<span class="text-xs font-medium px-2 py-1 rounded bg-background border border-neutral">
|
||||
{{ $address['type'] === 'ipv6' ? 'IPv6' : 'IPv4' }}
|
||||
</span>
|
||||
</div>
|
||||
@@ -717,37 +764,37 @@
|
||||
<div class="flex-1"></div>
|
||||
<div class="flex gap-2 justify-end mt-auto">
|
||||
@if($isIpv6)
|
||||
<x-proxmox::ui.button
|
||||
<x-button.primary
|
||||
onclick="window.open('https://ping6.ping.pe/{{ $address['ip'] }}', '_blank')"
|
||||
class="text-xs" variant="primary">
|
||||
class="text-xs">
|
||||
Ping
|
||||
</x-proxmox::ui.button>
|
||||
<x-proxmox::ui.button
|
||||
</x-button.primary>
|
||||
<x-button.primary
|
||||
onclick="window.open('https://mtr6.ping.pe/{{ $address['ip'] }}', '_blank')"
|
||||
class="text-xs" variant="primary">
|
||||
class="text-xs">
|
||||
MTR
|
||||
</x-proxmox::ui.button>
|
||||
<x-proxmox::ui.button
|
||||
</x-button.primary>
|
||||
<x-button.primary
|
||||
onclick="window.open('https://bgp.ping.pe/{{ $address['ip'] }}', '_blank')"
|
||||
class="text-xs" variant="primary">
|
||||
class="text-xs">
|
||||
BGP
|
||||
</x-proxmox::ui.button>
|
||||
</x-button.primary>
|
||||
@else
|
||||
<x-proxmox::ui.button
|
||||
<x-button.primary
|
||||
onclick="window.open('https://ping.pe/{{ $address['ip'] }}', '_blank')"
|
||||
class="text-xs" variant="primary">
|
||||
class="text-xs">
|
||||
Ping
|
||||
</x-proxmox::ui.button>
|
||||
<x-proxmox::ui.button
|
||||
</x-button.primary>
|
||||
<x-button.primary
|
||||
onclick="window.open('https://mtr.ping.pe/{{ $address['ip'] }}', '_blank')"
|
||||
class="text-xs" variant="primary">
|
||||
class="text-xs">
|
||||
MTR
|
||||
</x-proxmox::ui.button>
|
||||
<x-proxmox::ui.button
|
||||
</x-button.primary>
|
||||
<x-button.primary
|
||||
onclick="window.open('https://bgp.ping.pe/{{ $address['ip'] }}', '_blank')"
|
||||
class="text-xs" variant="primary">
|
||||
class="text-xs">
|
||||
BGP
|
||||
</x-proxmox::ui.button>
|
||||
</x-button.primary>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@@ -756,7 +803,7 @@
|
||||
|
||||
@if($address['interface'])
|
||||
<!-- Additional Technical Information from QEMU Guest Agent -->
|
||||
<div class="border-t border-gray-200 dark:border-gray-800 pt-4 mt-2">
|
||||
<div class="border-t border-neutral/40 pt-4 mt-2">
|
||||
<h4 class="text-sm font-semibold text-base/70 mb-3">Technical Details (Guest Agent)</h4>
|
||||
<div class="grid md:grid-cols-2 grid-cols-1 gap-4">
|
||||
@if(isset($address['interface']['hardware-address']))
|
||||
@@ -830,4 +877,4 @@
|
||||
@endif
|
||||
</div>
|
||||
|
||||
</x-proxmox::layout>
|
||||
</x-proxmox::layout>
|
||||
Reference in New Issue
Block a user