refactor(proxmox): recreate statistics page UI, inline telemetry charts
- Match overview design: resource card, gradient section headers, help modals - Inline Live Telemetry (ApexCharts IDs unchanged); remove telemetry partial - Add copyToClipboard script for parity with overview Made-with: Cursor
This commit is contained in:
@@ -2,6 +2,22 @@
|
||||
@once
|
||||
<script src="https://cdn.jsdelivr.net/npm/apexcharts" onload="window.apexChartsLoaded = true"></script>
|
||||
@endonce
|
||||
<script data-navigate-track>
|
||||
if (typeof window.copyToClipboard === 'undefined') {
|
||||
window.copyToClipboard = function(text, el) {
|
||||
navigator.clipboard.writeText(text).then(() => {
|
||||
const icon = el.querySelector('svg');
|
||||
if (icon) {
|
||||
icon.classList.add('text-success');
|
||||
setTimeout(() => icon.classList.remove('text-success'), 1500);
|
||||
}
|
||||
window.dispatchEvent(new CustomEvent('toast', {
|
||||
detail: { message: 'Copied to clipboard', type: 'success' }
|
||||
}));
|
||||
}).catch(() => {});
|
||||
};
|
||||
}
|
||||
</script>
|
||||
<div class="flex flex-col gap-6" data-server-id="{{ $server->id }}">
|
||||
<!-- Header Section -->
|
||||
<div class="flex flex-col gap-4">
|
||||
@@ -79,87 +95,400 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-base/70">
|
||||
<p class="text-sm text-base/70">
|
||||
Monitor your server's performance metrics and resource utilization over time.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('proxmox::partials.telemetry-charts')
|
||||
<style>
|
||||
.telemetry-spinner {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border: 3px solid rgba(0, 143, 251, 0.2);
|
||||
border-top-color: #008FFB;
|
||||
border-radius: 50%;
|
||||
animation: telemetrySpin 0.8s linear infinite;
|
||||
}
|
||||
@keyframes telemetrySpin {
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
.telemetry-chart-host { min-height: 280px; }
|
||||
</style>
|
||||
<div class="bg-background-secondary border border-neutral rounded-xl p-6 mt-8 relative overflow-hidden">
|
||||
<section
|
||||
wire:poll.120s="stats"
|
||||
x-data="{ chartsLoaded: false }"
|
||||
@proxmox-all-stats-loaded.window="chartsLoaded = true"
|
||||
class="relative"
|
||||
>
|
||||
<div
|
||||
x-show="!chartsLoaded"
|
||||
x-transition:leave="transition ease-in duration-500"
|
||||
x-transition:leave-start="opacity-100"
|
||||
x-transition:leave-end="opacity-0"
|
||||
class="absolute inset-0 z-10 flex items-center justify-center bg-background/75 backdrop-blur-sm rounded-xl"
|
||||
>
|
||||
<div class="flex flex-col items-center gap-3">
|
||||
<div class="telemetry-spinner"></div>
|
||||
<span class="text-sm text-base/70">Loading telemetry…</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-2 md:flex-row md:items-center md:justify-between mb-6">
|
||||
<div>
|
||||
<div class="flex items-center gap-2 min-w-0">
|
||||
<h3 class="text-lg font-semibold">Live Telemetry</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">
|
||||
<x-ri-question-line class="size-4" />
|
||||
</button>
|
||||
<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>
|
||||
<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.self="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-pulse-line class="size-5 text-primary" />
|
||||
</div>
|
||||
<h6 class="font-sans text-lg font-semibold leading-tight">Live Telemetry</h6>
|
||||
</div>
|
||||
<p class="block font-sans text-sm font-normal leading-relaxed text-base/90 mb-4">
|
||||
RRD-backed series from your hypervisor. Each chart supports time range, aggregation (average/maximum), and CSV export. Data refreshes every two minutes and when filters change.
|
||||
</p>
|
||||
<div class="pt-4 mt-4 border-t border-neutral/30 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">Processor:</span> CPU utilization as a share of allocated cores (percent). Export includes timestamps and values.
|
||||
</p>
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Network:</span> Inbound and outbound rates plus a dashed 95th percentile of combined traffic.
|
||||
</p>
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Memory:</span> Guest RAM from RRD; axis capped by VM max memory when available.
|
||||
</p>
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Disk I/O:</span> Read and write bytes per second. Pair with task history when investigating spikes.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-sm text-base/70">CPU, memory, network (with 95th percentile), and disk I/O from Proxmox <code class="rounded bg-neutral/15 px-1 py-0.5 text-xs">rrddata</code>.</p>
|
||||
</div>
|
||||
<p class="text-xs text-base/50">Polls with graph refresh every 2 minutes.</p>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 gap-6 xl:grid-cols-2">
|
||||
{{-- CPU --}}
|
||||
<div class="border border-neutral/50 rounded-xl overflow-hidden bg-background-secondary/30 transition-all duration-200 hover:border-primary/30 hover:shadow-md">
|
||||
<div class="flex flex-col gap-3 border-b border-neutral/25 p-4 sm:flex-row sm:items-center sm:justify-between">
|
||||
<div class="flex items-center gap-3 min-w-0">
|
||||
<div class="flex items-center justify-center w-10 h-10 rounded-lg bg-sky-500/15">
|
||||
<x-ri-cpu-line class="size-5 text-sky-600 dark:text-sky-400" />
|
||||
</div>
|
||||
<div class="min-w-0">
|
||||
<h4 class="text-sm font-semibold truncate">Processor</h4>
|
||||
<p class="text-xs text-base/50 truncate">Utilization (%)</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<select wire:model.live="cpuTimeRange" aria-label="CPU time range" class="bg-background border border-neutral rounded-md px-2 py-1 text-sm">
|
||||
<option value="hour">Hour</option>
|
||||
<option value="day">Day</option>
|
||||
<option value="week">Week</option>
|
||||
<option value="month">Month</option>
|
||||
<option value="year">Year</option>
|
||||
</select>
|
||||
<select wire:model.live="cpuAggregation" aria-label="CPU aggregation" class="bg-background border border-neutral rounded-md px-2 py-1 text-sm">
|
||||
<option value="average">Average</option>
|
||||
<option value="maximum">Maximum</option>
|
||||
</select>
|
||||
<button type="button" onclick="exportCpuChartToCSV()"
|
||||
class="inline-flex items-center gap-1.5 rounded-md border border-neutral bg-background px-2.5 py-1.5 text-xs font-semibold hover:bg-background/80"
|
||||
title="Export CPU series to CSV">
|
||||
<x-ri-download-line class="size-3.5" />
|
||||
CSV
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative p-4">
|
||||
<div class="relative telemetry-chart-host" x-data="{ ready: false }" x-init="
|
||||
let n = 0;
|
||||
const t = setInterval(() => {
|
||||
n++;
|
||||
if (document.querySelector('#cpu-chart .apexcharts-canvas')) { ready = true; clearInterval(t); }
|
||||
else if (n >= 150) clearInterval(t);
|
||||
}, 200);
|
||||
">
|
||||
<div class="absolute inset-0 z-[1] flex items-center justify-center rounded-lg border border-dashed border-neutral/20 bg-background/40"
|
||||
x-show="!ready" x-transition:leave="transition ease-in duration-300"
|
||||
x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0">
|
||||
<span class="text-xs text-base/50">Preparing chart…</span>
|
||||
</div>
|
||||
<div id="cpu-chart" wire:ignore class="min-h-[280px]"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Network --}}
|
||||
<div class="border border-neutral/50 rounded-xl overflow-hidden bg-background-secondary/30 transition-all duration-200 hover:border-primary/30 hover:shadow-md">
|
||||
<div class="flex flex-col gap-3 border-b border-neutral/25 p-4 sm:flex-row sm:items-center sm:justify-between">
|
||||
<div class="flex items-center gap-3 min-w-0">
|
||||
<div class="flex items-center justify-center w-10 h-10 rounded-lg bg-amber-500/15">
|
||||
<x-ri-arrow-left-right-line class="size-5 text-amber-600 dark:text-amber-400" />
|
||||
</div>
|
||||
<div class="min-w-0">
|
||||
<h4 class="text-sm font-semibold truncate">Network</h4>
|
||||
<p class="text-xs text-base/50 truncate">Throughput + 95th percentile</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<select wire:model.live="networkTimeRange" aria-label="Network time range" class="bg-background border border-neutral rounded-md px-2 py-1 text-sm">
|
||||
<option value="hour">Hour</option>
|
||||
<option value="day">Day</option>
|
||||
<option value="week">Week</option>
|
||||
<option value="month">Month</option>
|
||||
<option value="year">Year</option>
|
||||
</select>
|
||||
<select wire:model.live="networkAggregation" aria-label="Network aggregation" class="bg-background border border-neutral rounded-md px-2 py-1 text-sm">
|
||||
<option value="average">Average</option>
|
||||
<option value="maximum">Maximum</option>
|
||||
</select>
|
||||
<button type="button" onclick="exportNetworkChartToCSV()"
|
||||
class="inline-flex items-center gap-1.5 rounded-md border border-neutral bg-background px-2.5 py-1.5 text-xs font-semibold hover:bg-background/80"
|
||||
title="Export network series to CSV">
|
||||
<x-ri-download-line class="size-3.5" />
|
||||
CSV
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative p-4">
|
||||
<div class="relative telemetry-chart-host" x-data="{ ready: false }" x-init="
|
||||
let n = 0;
|
||||
const t = setInterval(() => {
|
||||
n++;
|
||||
if (document.querySelector('#network-chart .apexcharts-canvas')) { ready = true; clearInterval(t); }
|
||||
else if (n >= 150) clearInterval(t);
|
||||
}, 200);
|
||||
">
|
||||
<div class="absolute inset-0 z-[1] flex items-center justify-center rounded-lg border border-dashed border-neutral/20 bg-background/40"
|
||||
x-show="!ready" x-transition:leave="transition ease-in duration-300"
|
||||
x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0">
|
||||
<span class="text-xs text-base/50">Preparing chart…</span>
|
||||
</div>
|
||||
<div id="network-chart" wire:ignore class="min-h-[280px]"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Memory --}}
|
||||
<div class="border border-neutral/50 rounded-xl overflow-hidden bg-background-secondary/30 transition-all duration-200 hover:border-primary/30 hover:shadow-md">
|
||||
<div class="flex flex-col gap-3 border-b border-neutral/25 p-4 sm:flex-row sm:items-center sm:justify-between">
|
||||
<div class="flex items-center gap-3 min-w-0">
|
||||
<div class="flex items-center justify-center w-10 h-10 rounded-lg bg-emerald-500/15">
|
||||
<x-ri-ram-line class="size-5 text-emerald-600 dark:text-emerald-400" />
|
||||
</div>
|
||||
<div class="min-w-0">
|
||||
<h4 class="text-sm font-semibold truncate">Memory</h4>
|
||||
<p class="text-xs text-base/50 truncate">Guest RAM (bytes)</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<select wire:model.live="memoryTimeRange" aria-label="Memory time range" class="bg-background border border-neutral rounded-md px-2 py-1 text-sm">
|
||||
<option value="hour">Hour</option>
|
||||
<option value="day">Day</option>
|
||||
<option value="week">Week</option>
|
||||
<option value="month">Month</option>
|
||||
<option value="year">Year</option>
|
||||
</select>
|
||||
<select wire:model.live="memoryAggregation" aria-label="Memory aggregation" class="bg-background border border-neutral rounded-md px-2 py-1 text-sm">
|
||||
<option value="average">Average</option>
|
||||
<option value="maximum">Maximum</option>
|
||||
</select>
|
||||
<button type="button" onclick="exportMemoryChartToCSV()"
|
||||
class="inline-flex items-center gap-1.5 rounded-md border border-neutral bg-background px-2.5 py-1.5 text-xs font-semibold hover:bg-background/80"
|
||||
title="Export memory series to CSV">
|
||||
<x-ri-download-line class="size-3.5" />
|
||||
CSV
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative p-4">
|
||||
<div class="relative telemetry-chart-host" x-data="{ ready: false }" x-init="
|
||||
let n = 0;
|
||||
const t = setInterval(() => {
|
||||
n++;
|
||||
if (document.querySelector('#memory-chart .apexcharts-canvas')) { ready = true; clearInterval(t); }
|
||||
else if (n >= 150) clearInterval(t);
|
||||
}, 200);
|
||||
">
|
||||
<div class="absolute inset-0 z-[1] flex items-center justify-center rounded-lg border border-dashed border-neutral/20 bg-background/40"
|
||||
x-show="!ready" x-transition:leave="transition ease-in duration-300"
|
||||
x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0">
|
||||
<span class="text-xs text-base/50">Preparing chart…</span>
|
||||
</div>
|
||||
<div id="memory-chart" wire:ignore class="min-h-[280px]"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Disk --}}
|
||||
<div class="border border-neutral/50 rounded-xl overflow-hidden bg-background-secondary/30 transition-all duration-200 hover:border-primary/30 hover:shadow-md">
|
||||
<div class="flex flex-col gap-3 border-b border-neutral/25 p-4 sm:flex-row sm:items-center sm:justify-between">
|
||||
<div class="flex items-center gap-3 min-w-0">
|
||||
<div class="flex items-center justify-center w-10 h-10 rounded-lg bg-violet-500/15">
|
||||
<x-ri-hard-drive-line class="size-5 text-violet-600 dark:text-violet-400" />
|
||||
</div>
|
||||
<div class="min-w-0">
|
||||
<h4 class="text-sm font-semibold truncate">Disk I/O</h4>
|
||||
<p class="text-xs text-base/50 truncate">Read / write rates</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<select wire:model.live="diskTimeRange" aria-label="Disk time range" class="bg-background border border-neutral rounded-md px-2 py-1 text-sm">
|
||||
<option value="hour">Hour</option>
|
||||
<option value="day">Day</option>
|
||||
<option value="week">Week</option>
|
||||
<option value="month">Month</option>
|
||||
<option value="year">Year</option>
|
||||
</select>
|
||||
<select wire:model.live="diskAggregation" aria-label="Disk aggregation" class="bg-background border border-neutral rounded-md px-2 py-1 text-sm">
|
||||
<option value="average">Average</option>
|
||||
<option value="maximum">Maximum</option>
|
||||
</select>
|
||||
<button type="button" onclick="exportDiskChartToCSV()"
|
||||
class="inline-flex items-center gap-1.5 rounded-md border border-neutral bg-background px-2.5 py-1.5 text-xs font-semibold hover:bg-background/80"
|
||||
title="Export disk series to CSV">
|
||||
<x-ri-download-line class="size-3.5" />
|
||||
CSV
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative p-4">
|
||||
<div class="relative telemetry-chart-host" x-data="{ ready: false }" x-init="
|
||||
let n = 0;
|
||||
const t = setInterval(() => {
|
||||
n++;
|
||||
if (document.querySelector('#disk-chart .apexcharts-canvas')) { ready = true; clearInterval(t); }
|
||||
else if (n >= 150) clearInterval(t);
|
||||
}, 200);
|
||||
">
|
||||
<div class="absolute inset-0 z-[1] flex items-center justify-center rounded-lg border border-dashed border-neutral/20 bg-background/40"
|
||||
x-show="!ready" x-transition:leave="transition ease-in duration-300"
|
||||
x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0">
|
||||
<span class="text-xs text-base/50">Preparing chart…</span>
|
||||
</div>
|
||||
<div id="disk-chart" wire:ignore class="min-h-[280px]"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<!-- Statistics History Table -->
|
||||
@php
|
||||
$statisticsExportRows = [];
|
||||
@endphp
|
||||
<div class="bg-background-secondary border border-neutral rounded-xl overflow-hidden" id="statistics-history-card">
|
||||
<div class="p-6 border-b border-neutral flex items-center justify-between gap-3 flex-wrap">
|
||||
<h2 class="text-lg font-semibold flex items-center gap-2">
|
||||
<x-ri-history-line class="size-5" />
|
||||
Statistics History
|
||||
<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.self="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" />
|
||||
<div class="mt-8 bg-background-secondary border border-neutral rounded-xl overflow-hidden" id="statistics-history-card">
|
||||
<div class="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between p-4 border-b border-neutral bg-gradient-to-r from-primary/10 via-primary/5 to-transparent">
|
||||
<div class="flex items-start gap-3 min-w-0 flex-1">
|
||||
<div class="flex items-center justify-center w-10 h-10 rounded-lg bg-primary/15 shrink-0">
|
||||
<x-ri-history-line class="size-5 text-primary" />
|
||||
</div>
|
||||
<div class="min-w-0">
|
||||
<div class="flex items-center gap-2 flex-wrap">
|
||||
<h3 class="text-base font-semibold">Statistics History</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">
|
||||
<x-ri-question-line class="size-4" />
|
||||
</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-history-line class="size-5 text-primary" />
|
||||
</div>
|
||||
<h6 class="font-sans text-lg font-semibold leading-tight">
|
||||
Statistics History
|
||||
</h6>
|
||||
<!-- 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>
|
||||
<p class="block font-sans text-sm font-normal leading-relaxed text-base/90 mb-4">
|
||||
View historical performance data for your virtual machine. Each entry represents a snapshot of your server's resource utilization at a specific point in time.
|
||||
</p>
|
||||
<div class="pt-4 mt-4 border-t border-neutral/30 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">Automatic Statistics:</span> Collected hourly in the background for all VPS. The system maintains a maximum of 24 automatic statistics, automatically removing the oldest entries when the limit is reached.
|
||||
</p>
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Manual Statistics:</span> You can create up to 5 manual statistics snapshots. These appear alongside automatic statistics and can be deleted individually if needed.
|
||||
</p>
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Metrics Displayed:</span> CPU and Memory show percentage utilization. Network In/Out and Disk I/O display the difference since the previous statistic. Disk shows percentage of total disk space used. Uptime indicates how long the VM has been running.
|
||||
</p>
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Deleting Statistics:</span> You can delete individual statistics entries by clicking the delete icon. Manual statistics can be removed to free up space for new manual snapshots.
|
||||
</p>
|
||||
<!-- 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.self="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-history-line class="size-5 text-primary" />
|
||||
</div>
|
||||
<h6 class="font-sans text-lg font-semibold leading-tight">
|
||||
Statistics History
|
||||
</h6>
|
||||
</div>
|
||||
<p class="block font-sans text-sm font-normal leading-relaxed text-base/90 mb-4">
|
||||
View historical performance data for your virtual machine. Each entry represents a snapshot of your server's resource utilization at a specific point in time.
|
||||
</p>
|
||||
<div class="pt-4 mt-4 border-t border-neutral/30 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">Automatic Statistics:</span> Collected hourly in the background for all VPS. The system maintains a maximum of 24 automatic statistics, automatically removing the oldest entries when the limit is reached.
|
||||
</p>
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Manual Statistics:</span> You can create up to 5 manual statistics snapshots. These appear alongside automatic statistics and can be deleted individually if needed.
|
||||
</p>
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Metrics Displayed:</span> CPU and Memory show percentage utilization. Network In/Out and Disk I/O display the difference since the previous statistic. Disk shows percentage of total disk space used. Uptime indicates how long the VM has been running.
|
||||
</p>
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Deleting Statistics:</span> You can delete individual statistics entries by clicking the delete icon. Manual statistics can be removed to free up space for new manual snapshots.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h2>
|
||||
<div class="flex items-center gap-2"
|
||||
</div>
|
||||
<div class="flex items-center gap-2 shrink-0 flex-wrap"
|
||||
x-data
|
||||
@statistics-export:no-data.window="$wire.showExportInfo($event.detail.message)">
|
||||
<x-button.primary wire:click="createLiveStatistic" class="whitespace-nowrap">
|
||||
@@ -514,74 +843,80 @@
|
||||
@php
|
||||
$taskHistoryExportRows = [];
|
||||
@endphp
|
||||
<div class="bg-background-secondary border border-neutral rounded-xl overflow-hidden" wire:poll.30s="refreshTaskData" id="task-history-card">
|
||||
<div class="p-6 border-b border-neutral flex items-center justify-between gap-3">
|
||||
<h2 class="text-lg font-semibold flex items-center gap-2">
|
||||
<x-ri-task-line class="size-5" />
|
||||
Task History
|
||||
<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.self="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" />
|
||||
<div class="mt-8 bg-background-secondary border border-neutral rounded-xl overflow-hidden" wire:poll.30s="refreshTaskData" id="task-history-card">
|
||||
<div class="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between p-4 border-b border-neutral bg-gradient-to-r from-primary/10 via-primary/5 to-transparent">
|
||||
<div class="flex items-start gap-3 min-w-0 flex-1">
|
||||
<div class="flex items-center justify-center w-10 h-10 rounded-lg bg-primary/15 shrink-0">
|
||||
<x-ri-task-line class="size-5 text-primary" />
|
||||
</div>
|
||||
<div class="min-w-0">
|
||||
<div class="flex items-center gap-2 flex-wrap">
|
||||
<h3 class="text-base font-semibold">Task History</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">
|
||||
<x-ri-question-line class="size-4" />
|
||||
</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-task-line class="size-5 text-primary" />
|
||||
</div>
|
||||
<h6 class="font-sans text-lg font-semibold leading-tight">
|
||||
Task History
|
||||
</h6>
|
||||
<!-- 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>
|
||||
<p class="block font-sans text-sm font-normal leading-relaxed text-base/90 mb-4">
|
||||
View the execution history of tasks performed on your virtual machine. This includes operations like VM creation, configuration changes, backups, and other administrative tasks.
|
||||
</p>
|
||||
<div class="pt-4 mt-4 border-t border-neutral/30 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">Task Types:</span> Tasks can include VM operations (start, stop, reboot), configuration changes, backup operations, migration tasks, and other administrative actions performed on your virtual machine.
|
||||
</p>
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Task Details:</span> Click the expand arrow next to any task to view detailed information including execution logs, status messages, and task-specific parameters. The details are fetched from the server API when expanded.
|
||||
</p>
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Status Indicators:</span> Tasks show their completion status (Success or Failure) and include start time, end time, and duration. Running tasks will show the current elapsed time.
|
||||
</p>
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Auto-Refresh:</span> The task history automatically refreshes every 10 seconds to show the latest tasks and their current status.
|
||||
</p>
|
||||
<!-- 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.self="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-task-line class="size-5 text-primary" />
|
||||
</div>
|
||||
<h6 class="font-sans text-lg font-semibold leading-tight">
|
||||
Task History
|
||||
</h6>
|
||||
</div>
|
||||
<p class="block font-sans text-sm font-normal leading-relaxed text-base/90 mb-4">
|
||||
View the execution history of tasks performed on your virtual machine. This includes operations like VM creation, configuration changes, backups, and other administrative tasks.
|
||||
</p>
|
||||
<div class="pt-4 mt-4 border-t border-neutral/30 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">Task Types:</span> Tasks can include VM operations (start, stop, reboot), configuration changes, backup operations, migration tasks, and other administrative actions performed on your virtual machine.
|
||||
</p>
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Task Details:</span> Click the expand arrow next to any task to view detailed information including execution logs, status messages, and task-specific parameters. The details are fetched from the server API when expanded.
|
||||
</p>
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Status Indicators:</span> Tasks show their completion status (Success or Failure) and include start time, end time, and duration. Running tasks will show the current elapsed time.
|
||||
</p>
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Auto-Refresh:</span> The task history automatically refreshes every 10 seconds to show the latest tasks and their current status.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h2>
|
||||
<div class="flex items-center gap-2"
|
||||
</div>
|
||||
<div class="flex items-center gap-2 shrink-0 flex-wrap"
|
||||
x-data
|
||||
@task-export:no-data.window="$wire.showExportInfo($event.detail.message)">
|
||||
<button type="button"
|
||||
@@ -1009,77 +1344,83 @@
|
||||
@php
|
||||
$lifecycleEventsExportRows = [];
|
||||
@endphp
|
||||
<div class="bg-background-secondary border border-neutral rounded-xl overflow-hidden" wire:poll.30s="refreshTaskData" id="lifecycle-events-card">
|
||||
<div class="p-6 border-b border-neutral flex items-center justify-between gap-3">
|
||||
<h2 class="text-lg font-semibold flex items-center gap-2">
|
||||
<x-ri-shut-down-line class="size-5" />
|
||||
Recent Lifecycle Events
|
||||
<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.self="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" />
|
||||
<div class="mt-8 bg-background-secondary border border-neutral rounded-xl overflow-hidden" wire:poll.30s="refreshTaskData" id="lifecycle-events-card">
|
||||
<div class="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between p-4 border-b border-neutral bg-gradient-to-r from-primary/10 via-primary/5 to-transparent">
|
||||
<div class="flex items-start gap-3 min-w-0 flex-1">
|
||||
<div class="flex items-center justify-center w-10 h-10 rounded-lg bg-primary/15 shrink-0">
|
||||
<x-ri-shut-down-line class="size-5 text-primary" />
|
||||
</div>
|
||||
<div class="min-w-0">
|
||||
<div class="flex items-center gap-2 flex-wrap">
|
||||
<h3 class="text-base font-semibold">Recent Lifecycle Events</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">
|
||||
<x-ri-question-line class="size-4" />
|
||||
</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-shut-down-line class="size-5 text-primary" />
|
||||
</div>
|
||||
<h6 class="font-sans text-lg font-semibold leading-tight">
|
||||
Recent Lifecycle Events
|
||||
</h6>
|
||||
<!-- 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>
|
||||
<p class="block font-sans text-sm font-normal leading-relaxed text-base/90 mb-4">
|
||||
This section displays the lifecycle events of your virtual machine, tracking critical state changes and operations. Lifecycle events represent key moments in your VM's operation, including power state changes (start, shutdown, reboot, reset) and backup operations. These events are automatically extracted from the task history and provide a chronological view of your virtual machine's operational history.
|
||||
</p>
|
||||
<div class="pt-4 mt-4 border-t border-neutral/30 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">Event Types:</span> The section tracks five primary lifecycle event types: Start (VM power-on), Shutdown (graceful power-off), Reboot (restart operation), Reset (hard reset), and Backup (backup operations). Each event type is color-coded for easy identification.
|
||||
</p>
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Event Details:</span> Click the expand arrow next to any event to view comprehensive information including the original Proxmox task type, execution status, task ID, and precise timing details. This helps correlate lifecycle events with specific operations in the system.
|
||||
</p>
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Status Indicators:</span> Each event displays its completion status: Success (green) for completed operations, Running (blue) for operations in progress, or Failure (red) for failed operations. Start and end times are shown when available, along with calculated duration.
|
||||
</p>
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Auto-Refresh:</span> The lifecycle events table automatically refreshes every 10 seconds to ensure you always see the most current operational state and event history of your virtual machine.
|
||||
</p>
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Export:</span> All lifecycle events can be exported to CSV format, allowing you to analyze operational patterns, track system changes over time, and maintain records of your virtual machine's lifecycle events.
|
||||
</p>
|
||||
<!-- 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.self="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-shut-down-line class="size-5 text-primary" />
|
||||
</div>
|
||||
<h6 class="font-sans text-lg font-semibold leading-tight">
|
||||
Recent Lifecycle Events
|
||||
</h6>
|
||||
</div>
|
||||
<p class="block font-sans text-sm font-normal leading-relaxed text-base/90 mb-4">
|
||||
This section displays the lifecycle events of your virtual machine, tracking critical state changes and operations. Lifecycle events represent key moments in your VM's operation, including power state changes (start, shutdown, reboot, reset) and backup operations. These events are automatically extracted from the task history and provide a chronological view of your virtual machine's operational history.
|
||||
</p>
|
||||
<div class="pt-4 mt-4 border-t border-neutral/30 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">Event Types:</span> The section tracks five primary lifecycle event types: Start (VM power-on), Shutdown (graceful power-off), Reboot (restart operation), Reset (hard reset), and Backup (backup operations). Each event type is color-coded for easy identification.
|
||||
</p>
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Event Details:</span> Click the expand arrow next to any event to view comprehensive information including the original Proxmox task type, execution status, task ID, and precise timing details. This helps correlate lifecycle events with specific operations in the system.
|
||||
</p>
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Status Indicators:</span> Each event displays its completion status: Success (green) for completed operations, Running (blue) for operations in progress, or Failure (red) for failed operations. Start and end times are shown when available, along with calculated duration.
|
||||
</p>
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Auto-Refresh:</span> The lifecycle events table automatically refreshes every 10 seconds to ensure you always see the most current operational state and event history of your virtual machine.
|
||||
</p>
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Export:</span> All lifecycle events can be exported to CSV format, allowing you to analyze operational patterns, track system changes over time, and maintain records of your virtual machine's lifecycle events.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h2>
|
||||
<div class="flex items-center gap-2"
|
||||
</div>
|
||||
<div class="flex items-center gap-2 shrink-0 flex-wrap"
|
||||
x-data
|
||||
@lifecycle-export:no-data.window="$wire.showExportInfo($event.detail.message)">
|
||||
<button type="button"
|
||||
@@ -1427,74 +1768,80 @@
|
||||
@php
|
||||
$historicalComparison = $this->historicalComparison;
|
||||
@endphp
|
||||
<div class="bg-background-secondary border border-neutral rounded-xl overflow-hidden mt-6" id="historical-comparison-card">
|
||||
<div class="p-6 border-b border-neutral flex items-center justify-between gap-3 flex-wrap">
|
||||
<h2 class="text-lg font-semibold flex items-center gap-2">
|
||||
<x-ri-bar-chart-2-line class="size-5" />
|
||||
Historical Data Comparison
|
||||
<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.self="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" />
|
||||
<div class="mt-8 bg-background-secondary border border-neutral rounded-xl overflow-hidden" id="historical-comparison-card">
|
||||
<div class="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between p-4 border-b border-neutral bg-gradient-to-r from-primary/10 via-primary/5 to-transparent">
|
||||
<div class="flex items-start gap-3 min-w-0 flex-1">
|
||||
<div class="flex items-center justify-center w-10 h-10 rounded-lg bg-primary/15 shrink-0">
|
||||
<x-ri-bar-chart-2-line class="size-5 text-primary" />
|
||||
</div>
|
||||
<div class="min-w-0">
|
||||
<div class="flex items-center gap-2 flex-wrap">
|
||||
<h3 class="text-base font-semibold">Historical Data Comparison</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">
|
||||
<x-ri-question-line class="size-4" />
|
||||
</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-bar-chart-2-line class="size-5 text-primary" />
|
||||
</div>
|
||||
<h6 class="font-sans text-lg font-semibold leading-tight">
|
||||
Historical Data Comparison
|
||||
</h6>
|
||||
<!-- 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>
|
||||
<p class="block font-sans text-sm font-normal leading-relaxed text-base/90 mb-4">
|
||||
Compare current server statistics with historical data from a previous time period. This helps you identify trends, performance changes, and resource utilization patterns over time.
|
||||
</p>
|
||||
<div class="pt-4 mt-4 border-t border-neutral/30 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">Period Selection:</span> Choose both a historical period (to compare against) and a current period (to compare from). You can select predefined time periods or use custom date/time ranges.
|
||||
</p>
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Metrics Compared:</span> All major statistics are compared including CPU usage, memory utilization, disk usage, network traffic rates (in/out), and disk I/O rates (read/write).
|
||||
</p>
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Visualizations:</span> Side-by-side comparisons with visual indicators show percentage changes, absolute differences, and trend directions for each metric.
|
||||
</p>
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Export:</span> Comparison data can be exported to CSV format for further analysis or reporting.
|
||||
</p>
|
||||
<!-- 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.self="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-bar-chart-2-line class="size-5 text-primary" />
|
||||
</div>
|
||||
<h6 class="font-sans text-lg font-semibold leading-tight">
|
||||
Historical Data Comparison
|
||||
</h6>
|
||||
</div>
|
||||
<p class="block font-sans text-sm font-normal leading-relaxed text-base/90 mb-4">
|
||||
Compare current server statistics with historical data from a previous time period. This helps you identify trends, performance changes, and resource utilization patterns over time.
|
||||
</p>
|
||||
<div class="pt-4 mt-4 border-t border-neutral/30 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">Period Selection:</span> Choose both a historical period (to compare against) and a current period (to compare from). You can select predefined time periods or use custom date/time ranges.
|
||||
</p>
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Metrics Compared:</span> All major statistics are compared including CPU usage, memory utilization, disk usage, network traffic rates (in/out), and disk I/O rates (read/write).
|
||||
</p>
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Visualizations:</span> Side-by-side comparisons with visual indicators show percentage changes, absolute differences, and trend directions for each metric.
|
||||
</p>
|
||||
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
|
||||
<span class="font-semibold text-base/90">Export:</span> Comparison data can be exported to CSV format for further analysis or reporting.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h2>
|
||||
<div class="flex items-center gap-2">
|
||||
</div>
|
||||
<div class="flex items-center gap-2 shrink-0 flex-wrap">
|
||||
<button type="button"
|
||||
wire:click="exportHistoricalComparison"
|
||||
class="bg-background border border-neutral px-3 py-2 rounded-md text-sm font-semibold hover:bg-background/80 flex items-center gap-2 h-[calc(0.5rem*2+1.25rem)]"
|
||||
@@ -1741,17 +2088,19 @@
|
||||
|
||||
<!-- Network Analysis Section -->
|
||||
<div
|
||||
class="relative bg-background-secondary border border-neutral rounded-xl overflow-hidden mt-6"
|
||||
class="relative mt-8 bg-background-secondary border border-neutral rounded-xl overflow-hidden"
|
||||
id="network-analysis-card"
|
||||
style="width: 100%;"
|
||||
wire:init="loadNetworkAnalysis"
|
||||
>
|
||||
<div class="p-6 border-b border-neutral flex items-center justify-between gap-3 flex-wrap">
|
||||
<div class="flex items-center gap-2">
|
||||
<x-ri-router-line class="size-5" />
|
||||
<div>
|
||||
<h2 class="text-lg font-semibold flex items-center gap-2">
|
||||
Network Analysis
|
||||
<div class="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between p-4 border-b border-neutral bg-gradient-to-r from-primary/10 via-primary/5 to-transparent">
|
||||
<div class="flex items-start gap-3 min-w-0 flex-1">
|
||||
<div class="flex items-center justify-center w-10 h-10 rounded-lg bg-primary/15 shrink-0">
|
||||
<x-ri-router-line class="size-5 text-primary" />
|
||||
</div>
|
||||
<div class="min-w-0">
|
||||
<div class="flex items-center gap-2 flex-wrap">
|
||||
<h3 class="text-base font-semibold">Network Analysis</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">
|
||||
<x-ri-question-line class="size-4" />
|
||||
@@ -1816,13 +2165,13 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h2>
|
||||
<p class="text-xs text-base/60">
|
||||
</div>
|
||||
<p class="text-xs text-base/50 mt-1">
|
||||
Deep visibility into firewall sessions, security threats, and top consumers of bandwidth powered by the Core Router API.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="flex items-center gap-2 shrink-0 flex-wrap">
|
||||
<button
|
||||
type="button"
|
||||
wire:click="exportNetworkAnalysis"
|
||||
|
||||
Reference in New Issue
Block a user