perf: make delete statistics modal open instantly

- Remove @entangle which caused server round-trip on modal open
- Pass statistic data inline via Alpine event dispatch instead of fetching from DB
- Add direct deleteStatistic(id) method for simpler deletion
- Modal now opens immediately without any server communication
This commit is contained in:
2025-12-06 07:38:19 -05:00
parent f8427d8773
commit 3508a032db
2 changed files with 68 additions and 43 deletions

View File

@@ -866,7 +866,8 @@
</td>
<td class="py-3 px-4 text-sm whitespace-nowrap">
<button
wire:click="openDeleteModal({{ $stat->id }})"
x-data
@click="$dispatch('open-delete-stat-modal', { id: {{ $stat->id }}, date: '{{ $stat->DateTime->format('Y-m-d H:i:s') }}', cpu: '{{ number_format($stat->cpumax > 0 ? ($stat->cpuused / $stat->cpumax * 100) : 0, 2) }}', memory: '{{ number_format($stat->memorymax > 0 ? ($stat->memoryused / $stat->memorymax * 100) : 0, 2) }}', disk: '{{ number_format(($stat->diskmax ?? 0) > 0 ? (($stat->diskused ?? 0) / ($stat->diskmax ?? 1) * 100) : 0, 2) }}', status: '{{ $stat->vmstatus ?? '' }}' })"
class="p-1.5 text-danger hover:text-danger/80 hover:bg-danger/10 rounded transition-colors"
title="Delete statistics entry"
>
@@ -3168,30 +3169,31 @@
</div>
<!-- Delete Confirmation Modal -->
<div x-data="{ showDeleteModal: @entangle('showDeleteModal') }">
<div x-data="{ open: false, statId: null, statDate: '', statCpu: '', statMemory: '', statDisk: '', statStatus: '' }"
@open-delete-stat-modal.window="open = true; statId = $event.detail.id; statDate = $event.detail.date; statCpu = $event.detail.cpu; statMemory = $event.detail.memory; statDisk = $event.detail.disk; statStatus = $event.detail.status">
<!-- Modal Backdrop -->
<div x-cloak x-show="showDeleteModal"
<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.closeDeleteModal()"
@keydown.escape.window="$wire.closeDeleteModal()"
@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-cloak x-show="showDeleteModal"
<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"
@click.away="$wire.closeDeleteModal()"
@keydown.escape.window="$wire.closeDeleteModal()"
@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 bg-background-secondary border border-neutral rounded-xl shadow-xl max-w-md w-full mx-4">
@@ -3206,53 +3208,48 @@
</div>
</div>
@php
$statToDelete = $this->statisticToDelete;
@endphp
@if($statToDelete)
<div class="mb-4 p-4 bg-background rounded-lg border border-neutral/40">
<p class="text-sm text-base/70 mb-2">You are about to delete the following statistics entry:</p>
<div class="space-y-1 text-sm">
<div class="flex justify-between">
<span class="text-base/70">Date & Time:</span>
<span class="font-semibold">{{ $statToDelete->DateTime->format('Y-m-d H:i:s') }}</span>
</div>
<div class="flex justify-between">
<span class="text-base/70">Processor Utilization:</span>
<span class="font-semibold">{{ number_format($statToDelete->cpumax > 0 ? ($statToDelete->cpuused / $statToDelete->cpumax * 100) : 0, 2) }}%</span>
</div>
<div class="flex justify-between">
<span class="text-base/70">Memory Utilization:</span>
<span class="font-semibold">{{ number_format($statToDelete->memorymax > 0 ? ($statToDelete->memoryused / $statToDelete->memorymax * 100) : 0, 2) }}%</span>
</div>
<div class="flex justify-between">
<span class="text-base/70">Storage I/O:</span>
<span class="font-semibold">{{ number_format(($statToDelete->diskmax ?? 0) > 0 ? (($statToDelete->diskused ?? 0) / ($statToDelete->diskmax ?? 1) * 100) : 0, 2) }}%</span>
</div>
@if($statToDelete->vmstatus)
<div class="mb-4 p-4 bg-background rounded-lg border border-neutral/40">
<p class="text-sm text-base/70 mb-2">You are about to delete the following statistics entry:</p>
<div class="space-y-1 text-sm">
<div class="flex justify-between">
<span class="text-base/70">Date & Time:</span>
<span class="font-semibold" x-text="statDate"></span>
</div>
<div class="flex justify-between">
<span class="text-base/70">Processor Utilization:</span>
<span class="font-semibold"><span x-text="statCpu"></span>%</span>
</div>
<div class="flex justify-between">
<span class="text-base/70">Memory Utilization:</span>
<span class="font-semibold"><span x-text="statMemory"></span>%</span>
</div>
<div class="flex justify-between">
<span class="text-base/70">Storage I/O:</span>
<span class="font-semibold"><span x-text="statDisk"></span>%</span>
</div>
<template x-if="statStatus">
<div class="flex justify-between">
<span class="text-base/70">VM Status:</span>
<span class="font-semibold">
<span class="px-2 py-1 rounded text-xs font-semibold {{ $statToDelete->vmstatus === 'running' ? 'bg-success/20 text-success' : 'bg-inactive/20 text-inactive' }}">
{{ ucfirst($statToDelete->vmstatus) }}
</span>
<span class="px-2 py-1 rounded text-xs font-semibold"
:class="statStatus === 'running' ? 'bg-success/20 text-success' : 'bg-inactive/20 text-inactive'"
x-text="statStatus.charAt(0).toUpperCase() + statStatus.slice(1)"></span>
</span>
</div>
@endif
</div>
</template>
</div>
@endif
</div>
<div class="flex gap-3 justify-end">
<x-button.secondary wire:click="closeDeleteModal" @click="showDeleteModal = false">
<x-button.secondary @click="open = false">
Cancel
</x-button.secondary>
<x-button.danger wire:click="confirmDeleteStatistic" @click="showDeleteModal = false">
<x-loading target="confirmDeleteStatistic" />
<div wire:loading.remove wire:target="confirmDeleteStatistic">
<x-button.danger @click="$wire.deleteStatistic(statId); open = false">
<x-loading target="deleteStatistic" />
<div wire:loading.remove wire:target="deleteStatistic">
Delete
</div>
<div wire:loading wire:target="confirmDeleteStatistic">
<div wire:loading wire:target="deleteStatistic">
Deleting...
</div>
</x-button.danger>