revert: remove customizable server icon feature and restore all Proxmox Livewire files to pre-icon state (d24fa01)
This commit is contained in:
@@ -22,12 +22,6 @@ class Overview extends Component
|
||||
public $isEditingPassword = false;
|
||||
public $passwordError = '';
|
||||
|
||||
// Icon customization properties
|
||||
public bool $showIconModal = false;
|
||||
public string $selectedIcon = '';
|
||||
public string $selectedIconColor = '#3b82f6';
|
||||
public string $iconSearchQuery = '';
|
||||
|
||||
public string $cpuTimeRange = 'hour';
|
||||
public string $cpuAggregation = 'average';
|
||||
|
||||
@@ -527,44 +521,6 @@ class Overview extends Component
|
||||
}
|
||||
}
|
||||
|
||||
// Icon customization methods
|
||||
public function openIconModal()
|
||||
{
|
||||
$this->selectedIcon = $this->server->user_set_icon ?? '';
|
||||
$this->selectedIconColor = $this->server->user_set_icon_color ?? '#3b82f6';
|
||||
$this->iconSearchQuery = '';
|
||||
$this->showIconModal = true;
|
||||
}
|
||||
|
||||
public function closeIconModal()
|
||||
{
|
||||
$this->showIconModal = false;
|
||||
}
|
||||
|
||||
public function saveIcon($icon = null, $color = null)
|
||||
{
|
||||
$this->server->update([
|
||||
'user_set_icon' => $icon ?: null,
|
||||
'user_set_icon_color' => $color ?: null,
|
||||
]);
|
||||
|
||||
$this->showIconModal = false;
|
||||
$this->notify('Icon saved successfully', 'success');
|
||||
}
|
||||
|
||||
public function resetIcon()
|
||||
{
|
||||
$this->server->update([
|
||||
'user_set_icon' => null,
|
||||
'user_set_icon_color' => null,
|
||||
]);
|
||||
|
||||
$this->selectedIcon = '';
|
||||
$this->selectedIconColor = '#3b82f6';
|
||||
$this->showIconModal = false;
|
||||
$this->notify('Icon reset to default', 'success');
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('proxmox::overview')->layoutData([
|
||||
|
||||
@@ -6,20 +6,12 @@
|
||||
'statusPollingInterval' => '30s',
|
||||
])
|
||||
|
||||
{{-- Remix Icons CSS for server icon customization --}}
|
||||
@push('styles')
|
||||
<link href="https://cdn.jsdelivr.net/npm/remixicon@4.5.0/fonts/remixicon.css" rel="stylesheet" />
|
||||
@endpush
|
||||
|
||||
@php
|
||||
$vmStatus = optional($status)->status;
|
||||
$pollSuffix = $statusPollingInterval ? '.' . $statusPollingInterval : '';
|
||||
$pollAttribute = $statusPolling ? 'wire:poll' . $pollSuffix . '="loadVmStatus"' : '';
|
||||
@endphp
|
||||
|
||||
{{-- Inline load Remix Icons CSS as fallback --}}
|
||||
<link href="https://cdn.jsdelivr.net/npm/remixicon@4.5.0/fonts/remixicon.css" rel="stylesheet" />
|
||||
|
||||
<div {!! $pollAttribute !!} class="flex flex-col" style="min-height: calc(100vh - 30rem);">
|
||||
@if($server->status === 'active')
|
||||
|
||||
@@ -46,46 +38,9 @@
|
||||
@endphp
|
||||
|
||||
<div class="flex flex-col gap-4 pb-6 pt-6 lg:flex-row lg:items-center lg:justify-between">
|
||||
<div class="flex items-center gap-3">
|
||||
<!-- Server Icon -->
|
||||
@if($view === 'overview')
|
||||
<button
|
||||
wire:click="openIconModal"
|
||||
class="bg-secondary/10 p-2 rounded-lg hover:bg-secondary/20 transition-colors cursor-pointer"
|
||||
title="Click to customize server icon"
|
||||
>
|
||||
@if($server->user_set_icon)
|
||||
@php
|
||||
$iconColor = $server->user_set_icon_color ?: 'currentColor';
|
||||
// Handle both old format (ri-icon-name) and new format (icon-name)
|
||||
$iconName = str_starts_with($server->user_set_icon, 'ri-')
|
||||
? $server->user_set_icon
|
||||
: 'ri-' . $server->user_set_icon;
|
||||
@endphp
|
||||
<x-dynamic-component :component="$iconName" class="size-5" style="color: {{ $iconColor }}" />
|
||||
@else
|
||||
<x-ri-server-line class="size-5 text-secondary" />
|
||||
@endif
|
||||
</button>
|
||||
@else
|
||||
<div class="bg-secondary/10 p-2 rounded-lg">
|
||||
@if($server->user_set_icon)
|
||||
@php
|
||||
$iconColor = $server->user_set_icon_color ?: 'currentColor';
|
||||
$iconName = str_starts_with($server->user_set_icon, 'ri-')
|
||||
? $server->user_set_icon
|
||||
: 'ri-' . $server->user_set_icon;
|
||||
@endphp
|
||||
<x-dynamic-component :component="$iconName" class="size-5" style="color: {{ $iconColor }}" />
|
||||
@else
|
||||
<x-ri-server-line class="size-5 text-secondary" />
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
<span class="text-2xl font-bold">
|
||||
{{ $server->hostname }}
|
||||
</span>
|
||||
</div>
|
||||
<span class="text-2xl font-bold">
|
||||
{{ $server->hostname }}
|
||||
</span>
|
||||
|
||||
|
||||
<div class="hidden lg:flex flex-row gap-2 ml-auto justify-end items-center">
|
||||
@@ -942,157 +897,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if($view === 'overview')
|
||||
<!-- Server Icon Customization Modal -->
|
||||
<div x-data="{
|
||||
open: @entangle('showIconModal'),
|
||||
selectedIcon: @entangle('selectedIcon'),
|
||||
selectedColor: @entangle('selectedIconColor'),
|
||||
searchQuery: '',
|
||||
icons: [
|
||||
'server-line', 'database-2-line', 'computer-line', 'cpu-line', 'hard-drive-2-line',
|
||||
'cloud-line', 'terminal-box-line', 'code-s-slash-line', 'braces-line',
|
||||
'global-line', 'earth-line', 'wifi-line', 'signal-tower-line',
|
||||
'shield-check-line', 'shield-keyhole-line', 'lock-line', 'lock-unlock-line', 'key-2-line',
|
||||
'rocket-line', 'rocket-2-line', 'send-plane-line', 'flashlight-line', 'fire-line',
|
||||
'sparkling-line', 'star-line', 'heart-line', 'home-line', 'home-2-line',
|
||||
'building-line', 'building-2-line', 'store-line', 'box-3-line', 'archive-line',
|
||||
'inbox-line', 'inbox-2-line', 'folder-line', 'folder-open-line',
|
||||
'settings-3-line', 'settings-4-line', 'tools-line', 'hammer-line',
|
||||
'flask-line', 'bug-line', 'puzzle-line', 'bar-chart-box-line', 'pie-chart-line',
|
||||
'line-chart-line', 'money-dollar-circle-line', 'money-euro-circle-line',
|
||||
'bank-card-line', 'wallet-line', 'user-line', 'user-3-line', 'group-line', 'team-line',
|
||||
'mail-line', 'mail-open-line', 'chat-3-line', 'discuss-line',
|
||||
'camera-line', 'vidicon-line', 'film-line', 'music-line',
|
||||
'book-open-line', 'file-text-line', 'sun-line', 'moon-line',
|
||||
'palette-line', 'brush-line', 'trophy-line', 'graduation-cap-line',
|
||||
'lightbulb-line', 'fingerprint-line', 'eye-line', 'map-2-line', 'map-pin-line',
|
||||
'time-line', 'calendar-line', 'gift-line', 'cake-2-line',
|
||||
'gamepad-line', 'ghost-line', 'aliens-line', 'space-ship-line',
|
||||
'android-line', 'apple-line', 'windows-line', 'ubuntu-line',
|
||||
'github-line', 'gitlab-line', 'discord-line', 'slack-line'
|
||||
],
|
||||
colors: [
|
||||
'', '#ef4444', '#f97316', '#f59e0b', '#eab308', '#84cc16', '#22c55e', '#10b981',
|
||||
'#14b8a6', '#06b6d4', '#0ea5e9', '#3b82f6', '#6366f1', '#8b5cf6', '#a855f7',
|
||||
'#d946ef', '#ec4899', '#f43f5e', '#78716c', '#64748b'
|
||||
],
|
||||
get filteredIcons() {
|
||||
if (!this.searchQuery) return this.icons;
|
||||
const query = this.searchQuery.toLowerCase();
|
||||
return this.icons.filter(icon => icon.toLowerCase().includes(query));
|
||||
}
|
||||
}">
|
||||
<!-- Modal Backdrop -->
|
||||
<div x-cloak 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="$wire.closeIconModal()"
|
||||
@keydown.escape.window="$wire.closeIconModal()"
|
||||
class="fixed inset-0 z-50 bg-black/50 backdrop-blur-sm"
|
||||
style="display: none;">
|
||||
</div>
|
||||
<!-- Modal Content -->
|
||||
<div x-cloak 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"
|
||||
class="fixed inset-0 z-50 flex items-center justify-center p-4"
|
||||
style="display: none;">
|
||||
<div class="bg-background-secondary border border-neutral rounded-2xl shadow-2xl w-full max-w-2xl max-h-[80vh] flex flex-col" @click.away="$wire.closeIconModal()">
|
||||
<!-- Header -->
|
||||
<div class="p-6 border-b border-neutral">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h3 class="text-lg font-semibold">Customize Server Icon</h3>
|
||||
<button @click="$wire.closeIconModal()" class="text-base/50 hover:text-base transition-colors">
|
||||
<i class="ri-close-line text-xl"></i>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Search -->
|
||||
<input type="text"
|
||||
x-model="searchQuery"
|
||||
placeholder="Search icons..."
|
||||
class="w-full px-4 py-2 bg-background border border-neutral rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-primary/50">
|
||||
</div>
|
||||
|
||||
<!-- Preview -->
|
||||
<div class="px-6 py-4 border-b border-neutral bg-background/50">
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="size-16 rounded-xl bg-background-secondary border-2 border-neutral flex items-center justify-center"
|
||||
:style="selectedColor ? 'border-color: ' + selectedColor : ''">
|
||||
<template x-if="selectedIcon">
|
||||
<span class="size-8 flex items-center justify-center" :style="selectedColor ? 'color: ' + selectedColor : ''">
|
||||
<i class="text-3xl" :class="'ri-' + selectedIcon"></i>
|
||||
</span>
|
||||
</template>
|
||||
<template x-if="!selectedIcon">
|
||||
<i class="ri-server-line text-3xl text-base/40"></i>
|
||||
</template>
|
||||
</div>
|
||||
<div>
|
||||
<p class="font-medium">Preview</p>
|
||||
<p class="text-sm text-base/60" x-text="selectedIcon || 'No icon selected'"></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Color Picker -->
|
||||
<div class="px-6 py-4 border-b border-neutral">
|
||||
<p class="text-sm font-medium mb-3">Color</p>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<template x-for="color in colors" :key="color || 'default'">
|
||||
<button @click="selectedColor = color"
|
||||
class="size-8 rounded-full border-2 transition-all duration-150 hover:scale-110"
|
||||
:class="selectedColor === color ? 'ring-2 ring-offset-2 ring-primary' : ''"
|
||||
:style="color ? 'background-color: ' + color + '; border-color: ' + color : 'background: linear-gradient(135deg, #666 50%, #999 50%); border-color: #888'"
|
||||
:title="color || 'Default'">
|
||||
</button>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Icons Grid -->
|
||||
<div class="flex-1 overflow-y-auto p-6">
|
||||
<div class="grid grid-cols-8 sm:grid-cols-10 gap-2">
|
||||
<template x-for="icon in filteredIcons" :key="icon">
|
||||
<button @click="selectedIcon = icon"
|
||||
class="aspect-square rounded-lg border flex items-center justify-center transition-all duration-150 hover:bg-background hover:border-primary/50"
|
||||
:class="selectedIcon === icon ? 'bg-primary/10 border-primary ring-2 ring-primary/30' : 'border-neutral'"
|
||||
:data-icon-preview="icon">
|
||||
<span class="size-5 flex items-center justify-center" :style="selectedColor ? 'color: ' + selectedColor : ''">
|
||||
<i class="text-xl" :class="'ri-' + icon"></i>
|
||||
</span>
|
||||
</button>
|
||||
</template>
|
||||
</div>
|
||||
<p x-show="filteredIcons.length === 0" class="text-center text-base/50 py-8">No icons match your search</p>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="p-6 border-t border-neutral flex items-center justify-between gap-4">
|
||||
<button @click="$wire.resetIcon()"
|
||||
class="px-4 py-2 text-sm text-base/70 hover:text-danger transition-colors">
|
||||
Reset to Default
|
||||
</button>
|
||||
<div class="flex gap-3">
|
||||
<x-button.secondary @click="$wire.closeIconModal()">Cancel</x-button.secondary>
|
||||
<x-button.primary @click="$wire.saveIcon(selectedIcon, selectedColor)">
|
||||
Save Icon
|
||||
</x-button.primary>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@else
|
||||
@php
|
||||
$statuses = [
|
||||
|
||||
Reference in New Issue
Block a user