From eea6e2a80edaf359754b945ed01bdca3fc7c00f1 Mon Sep 17 00:00:00 2001 From: Luca Sacchi Ricciardi Date: Sat, 25 Apr 2026 14:05:11 +0200 Subject: [PATCH] Fix model details modal interactions and scrolling --- app/web/static/js/app.js | 30 ++++++++++++++++++++++++++++-- app/web/templates/index.html | 26 +++++++++++++++++++++++--- 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/app/web/static/js/app.js b/app/web/static/js/app.js index b6847e7..0d04d86 100644 --- a/app/web/static/js/app.js +++ b/app/web/static/js/app.js @@ -7,6 +7,7 @@ class LLMMonitorApp { constructor() { this.worker = null; this.selectedModelName = null; + this.isModalOpen = false; this.hoverOpenDelayMs = 180; this.hoverOpenTimer = null; this.lastData = { @@ -175,15 +176,20 @@ class LLMMonitorApp { bindModelCardInteractions() { const cards = document.querySelectorAll("#models-container [data-model-key]"); cards.forEach((card) => { + if (card.dataset.modalBound === "true") { + return; + } + const modelKey = card.getAttribute("data-model-key"); if (!modelKey) { return; } const modelName = decodeURIComponent(modelKey); + card.dataset.modalBound = "true"; card.addEventListener("click", () => { - this.showModelDetails(modelName); + this.toggleModelDetails(modelName); }); card.addEventListener("mouseenter", () => { @@ -205,6 +211,15 @@ class LLMMonitorApp { }); } + toggleModelDetails(modelName) { + if (this.isModalOpen && this.selectedModelName === modelName) { + this.hideModelDetails(); + return; + } + + this.showModelDetails(modelName); + } + // Renderizzare singola card modello renderModelCard(model) { const formattedDate = this.formatDate(model.modified_at); @@ -237,20 +252,25 @@ class LLMMonitorApp { showModelDetails(modelName) { const detailsModal = document.getElementById("model-details-modal"); + const detailsDialog = document.getElementById("model-details-dialog"); const detailsName = document.getElementById("model-details-name"); const detailsContent = document.getElementById("model-details-content"); - if (!detailsModal || !detailsName || !detailsContent || !this.lastData.models) { + if (!detailsModal || !detailsDialog || !detailsName || !detailsContent || !this.lastData.models) { return; } const showByModel = this.lastData.models.showByModel || {}; const showData = showByModel[modelName]; this.selectedModelName = modelName; + this.isModalOpen = true; detailsModal.classList.remove("hidden"); + detailsModal.classList.add("flex"); + detailsDialog.classList.add("flex"); document.body.classList.add("overflow-hidden"); detailsName.textContent = modelName; + detailsModal.setAttribute("aria-hidden", "false"); if (!showData) { detailsContent.textContent = "Dettagli show non disponibili per questo modello."; @@ -262,12 +282,18 @@ class LLMMonitorApp { hideModelDetails() { const detailsModal = document.getElementById("model-details-modal"); + const detailsDialog = document.getElementById("model-details-dialog"); if (!detailsModal || detailsModal.classList.contains("hidden")) { return; } detailsModal.classList.add("hidden"); + detailsModal.classList.remove("flex"); + detailsDialog?.classList.remove("flex"); document.body.classList.remove("overflow-hidden"); + detailsModal.setAttribute("aria-hidden", "true"); + this.isModalOpen = false; + this.selectedModelName = null; } // Formattare bytes diff --git a/app/web/templates/index.html b/app/web/templates/index.html index 48f3cac..ac90806 100644 --- a/app/web/templates/index.html +++ b/app/web/templates/index.html @@ -14,6 +14,24 @@ .animate-spin { animation: spin 1s linear infinite; } + .modal-body { + max-height: 80vh; + overflow-y: auto; + padding-right: 10px; + scrollbar-width: thin; + scrollbar-color: #8b5cf6 #1f2937; + } + .modal-body::-webkit-scrollbar { + width: 8px; + } + .modal-body::-webkit-scrollbar-track { + background: #1f2937; + border-radius: 4px; + } + .modal-body::-webkit-scrollbar-thumb { + background: #8b5cf6; + border-radius: 4px; + } @@ -104,9 +122,9 @@ -