feat: Update Proxmox extension with various improvements and bug fixes
- Change listStates method to accept nullable integer for limit parameter. - Modify TechnitiumDns class to return structured error messages on failure. - Enhance VNC and xterm popup routes with user authorization checks. - Update backups view to improve loading states and add unique keys for dynamic elements. - Refactor cloud-init view to ensure proper data binding and improve user experience. - Add wire:key attributes to various elements in views for better Livewire performance. - Improve error handling and user feedback in the firewall view. - Update server overview and statistics views to handle potential null values gracefully. - Add new migration files to extend database schema with user-set icons and notes for Proxmox nodes.
This commit is contained in:
@@ -206,7 +206,7 @@
|
||||
</div>
|
||||
<div class="text-xs text-base/60">
|
||||
{{ ucfirst($adapter['model'] ?? 'Unknown') }}
|
||||
@if($adapter['mac'])
|
||||
@if($adapter['mac'] ?? null)
|
||||
<span class="ml-2">{{ $adapter['mac'] }}</span>
|
||||
@endif
|
||||
</div>
|
||||
@@ -326,7 +326,7 @@
|
||||
@endif
|
||||
|
||||
{{-- Tabs Navigation --}}
|
||||
<div class="bg-background border border-neutral rounded-xl mb-6" x-data="{ activeTab: 'rules' }">
|
||||
<div class="bg-background border border-neutral rounded-xl mb-6" x-data="{ activeTab: 'rules', logsLoaded: false }">
|
||||
<div class="flex border-b border-neutral/20 overflow-x-auto">
|
||||
<button @click="activeTab = 'rules'"
|
||||
class="px-6 py-4 text-sm font-semibold transition-all relative whitespace-nowrap"
|
||||
@@ -409,7 +409,7 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($rules as $index => $rule)
|
||||
<tr class="border-b border-neutral/10 hover:bg-background-secondary/30 transition-colors">
|
||||
<tr wire:key="rule-{{ $rule['pos'] ?? $index }}" class="border-b border-neutral/10 hover:bg-background-secondary/30 transition-colors">
|
||||
<td class="py-3 px-4 text-sm">
|
||||
<div class="flex flex-col gap-1">
|
||||
@if($index > 0)
|
||||
@@ -727,9 +727,8 @@
|
||||
@if(count($ipsets) > 0)
|
||||
<div class="space-y-2">
|
||||
@foreach($ipsets as $ipset)
|
||||
<div class="p-3 bg-background-secondary/50 border border-neutral/20 rounded-lg hover:border-primary/40 transition-colors cursor-pointer"
|
||||
wire:click="selectIPSet('{{ $ipset['name'] }}')"
|
||||
class="{{ $selectedIPSetName === $ipset['name'] ? 'border-primary/60 bg-primary/5' : '' }}">
|
||||
<div class="p-3 bg-background-secondary/50 border border-neutral/20 rounded-lg hover:border-primary/40 transition-colors cursor-pointer {{ $selectedIPSetName === $ipset['name'] ? 'border-primary/60 bg-primary/5' : '' }}"
|
||||
wire:click="selectIPSet('{{ $ipset['name'] }}')">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex-1">
|
||||
<div class="font-semibold text-sm">{{ $ipset['name'] }}</div>
|
||||
@@ -808,8 +807,8 @@
|
||||
{{-- LOGS TAB --}}
|
||||
<div x-show="activeTab === 'logs'"
|
||||
x-transition
|
||||
wire:poll.30s="loadFirewallLogs"
|
||||
x-init="$watch('activeTab', value => { if (value === 'logs' && !@json($logsLoaded)) { $wire.loadFirewallLogs(); } })">
|
||||
wire:poll.30s.visible="loadFirewallLogs"
|
||||
x-init="$watch('activeTab', value => { if (value === 'logs' && !logsLoaded) { logsLoaded = true; $wire.loadFirewallLogs(); } })">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold">Firewall Logs</h3>
|
||||
@@ -907,7 +906,7 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($this->paginatedLogs as $log)
|
||||
<tr class="border-b border-neutral/10 hover:bg-background-secondary/30 transition-colors">
|
||||
<tr wire:key="log-{{ $loop->index }}-{{ $currentPage ?? 1 }}" class="border-b border-neutral/10 hover:bg-background-secondary/30 transition-colors">
|
||||
<td class="py-3 px-4 text-xs text-base/70">
|
||||
@if(isset($log['timestamp_iso']) && $log['timestamp_iso'] !== '-')
|
||||
<div x-data="{
|
||||
@@ -2571,7 +2570,7 @@
|
||||
ip = window.extractIP(ip);
|
||||
|
||||
try {
|
||||
const data = await @this.call('fetchIPLocation', ip);
|
||||
const data = await $wire.call('fetchIPLocation', ip);
|
||||
return data || { status: 'fail', message: 'No data returned' };
|
||||
} catch (error) {
|
||||
console.error('Error fetching IP location:', error);
|
||||
|
||||
Reference in New Issue
Block a user