Acquisizione: elenco calibrazioni a schede, parametri in lettura (Refs #91)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-24 16:14:37 +02:00
parent b2f82fe779
commit 8eb80e20a8
2 changed files with 42 additions and 38 deletions
+39 -37
View File
@@ -85,13 +85,13 @@ PAGINA = r"""<!doctype html>
flex: 0 1 auto; padding: 8px 18px; } flex: 0 1 auto; padding: 8px 18px; }
.tabs button[aria-selected=true] { color: var(--testo); background: var(--pannello); border-bottom-color: var(--accento); font-weight: 600; } .tabs button[aria-selected=true] { color: var(--testo); background: var(--pannello); border-bottom-color: var(--accento); font-weight: 600; }
/* #91: calibrazione con nome, elenco delle salvate */ /* #91: calibrazione con nome, elenco delle salvate */
.scorri { overflow-x: auto; margin-top: 8px; } /* #91: elenco a schede, una per calibrazione; nome e risoluzione sempre visibili, niente scorrimento orizzontale */
.elenco { width: 100%; } .elenco { margin-top: 8px; }
.elenco th { text-align: left; font-size: .78rem; font-weight: 600; color: var(--secondario); padding: 2px 12px 4px 0; white-space: nowrap; } .scheda-cal { border-top: 1px solid var(--bordo); padding: 8px 0; }
.elenco td { padding: 5px 12px 5px 0; border-top: 1px solid var(--bordo); vertical-align: top; } .scheda-cal .nome-cal { font-weight: 700; overflow-wrap: anywhere; }
.elenco td:first-child { color: var(--testo); } .scheda-cal .dettagli { font-size: .8rem; color: var(--secondario); margin-top: 2px; overflow-wrap: anywhere; }
.elenco .azioni { white-space: nowrap; } .scheda-cal .azioni { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.elenco button { padding: 3px 9px; font-size: .82rem; margin-right: 4px; } .scheda-cal .azioni button { padding: 3px 10px; font-size: .82rem; }
.segno { display: inline-block; font-size: .72rem; padding: 0 6px; border-radius: 9px; background: var(--ok); color: #052e16; margin-left: 6px; } .segno { display: inline-block; font-size: .72rem; padding: 0 6px; border-radius: 9px; background: var(--ok); color: #052e16; margin-left: 6px; }
.segno.diversa { background: var(--avviso); color: #422006; } .segno.diversa { background: var(--avviso); color: #422006; }
.origine label { display: inline-block; margin: 0 14px 4px 0; color: var(--testo); font-size: .92rem; } .origine label { display: inline-block; margin: 0 14px 4px 0; color: var(--testo); font-size: .92rem; }
@@ -227,7 +227,7 @@ PAGINA = r"""<!doctype html>
<section class="scheda" id="sezioneSalvate"> <section class="scheda" id="sezioneSalvate">
<h2>Calibrazioni salvate</h2> <h2>Calibrazioni salvate</h2>
<div id="stato" class="stato">-</div> <div id="stato" class="stato">-</div>
<div class="scorri"><table id="calibrazioni" class="elenco"></table></div> <div id="calibrazioni" class="elenco"></div> <!-- #91: una scheda per calibrazione, niente tabella larga -->
<div id="msgElenco" class="messaggio"></div> <div id="msgElenco" class="messaggio"></div>
</section> </section>
</div> </div>
@@ -488,6 +488,12 @@ async function caricaParametri() {
$("salvaParametriRiga").hidden = true; $("salvaParametriRiga").hidden = true;
dire("msgParametri", ""); dire("msgParametri", "");
if (!sorgente) { $("parametri").textContent = "-"; return; } if (!sorgente) { $("parametri").textContent = "-"; return; }
// #91: subito via il testo della sorgente precedente; la prima apertura della camera puo' durare ~20 s
$("parametri").textContent = "";
var attesa = document.createElement("div");
attesa.className = "nota";
attesa.textContent = "Lettura dei parametri...";
$("parametri").appendChild(attesa);
try { try {
var r = await fetch("/camera/parametri?source=" + encodeURIComponent(sorgente)); var r = await fetch("/camera/parametri?source=" + encodeURIComponent(sorgente));
if (g !== P.gen) return; if (g !== P.gen) return;
@@ -791,13 +797,6 @@ async function caricaCalibrazioni() {
} }
} }
function cella(tr, testo) {
var td = document.createElement("td");
td.textContent = testo;
tr.appendChild(td);
return td;
}
function bottone(testo, classe, fn) { function bottone(testo, classe, fn) {
var b = document.createElement("button"); var b = document.createElement("button");
b.textContent = testo; b.textContent = testo;
@@ -812,48 +811,51 @@ function disegnaElenco() {
t.textContent = ""; t.textContent = "";
C.celle = []; C.celle = [];
if (!C.elenco.length) { if (!C.elenco.length) {
var trVuota = document.createElement("tr"); var vuota = document.createElement("div");
cella(trVuota, "Nessuna calibrazione salvata."); vuota.className = "nota";
t.appendChild(trVuota); vuota.textContent = "Nessuna calibrazione salvata.";
t.appendChild(vuota);
return; return;
} }
var testa = document.createElement("tr");
["Nome", "Risoluzione", "px/mm", "Metodo", "Data", "Origine", ""].forEach(function (h) {
var th = document.createElement("th");
th.textContent = h;
testa.appendChild(th);
});
t.appendChild(testa);
C.elenco.forEach(function (c) { C.elenco.forEach(function (c) {
var tr = document.createElement("tr"); var sc = document.createElement("div"); // #91: scheda della calibrazione
var tdNome = cella(tr, c.nome); sc.className = "scheda-cal";
var attiva = C.attiva !== null && c.nome === C.attiva; var attiva = C.attiva !== null && c.nome === C.attiva;
var riga1 = document.createElement("div");
riga1.className = "nome-cal";
riga1.appendChild(document.createTextNode(c.nome));
if (attiva) { if (attiva) {
var s1 = document.createElement("span"); var s1 = document.createElement("span");
s1.className = "segno"; s1.className = "segno";
s1.textContent = "attiva"; s1.textContent = "attiva";
tdNome.appendChild(s1); riga1.appendChild(s1);
} }
var s2 = document.createElement("span"); // «risoluzione diversa» dal frame della sorgente (si accende in segnaRisoluzioni) var s2 = document.createElement("span"); // «risoluzione diversa» dal frame della sorgente (si accende in segnaRisoluzioni)
s2.className = "segno diversa"; s2.className = "segno diversa";
s2.textContent = "risoluzione diversa"; s2.textContent = "risoluzione diversa";
s2.hidden = true; s2.hidden = true;
tdNome.appendChild(s2); riga1.appendChild(s2);
C.celle.push({ w: Number(c.image_width), h: Number(c.image_height), span: s2 }); C.celle.push({ w: Number(c.image_width), h: Number(c.image_height), span: s2 });
cella(tr, c.image_width && c.image_height ? fmt(c.image_width, 0) + "×" + fmt(c.image_height, 0) : "-"); var riga2 = document.createElement("div");
cella(tr, fmt(c.px_per_mm, 3)); riga2.className = "dettagli";
cella(tr, c.metodo === "densa" ? "densa" : "planare"); riga2.textContent = [
cella(tr, c.calibrated_at ? dataItaliana(c.calibrated_at) : "-"); c.image_width && c.image_height ? fmt(c.image_width, 0) + "×" + fmt(c.image_height, 0) : "-",
cella(tr, descriviOrigine(c.origine)); fmt(c.px_per_mm, 3) + " px/mm",
var az = document.createElement("td"); c.metodo === "densa" ? "densa" : "planare",
c.calibrated_at ? dataItaliana(c.calibrated_at) : "-",
descriviOrigine(c.origine)
].join(" · ");
var az = document.createElement("div");
az.className = "azioni"; az.className = "azioni";
var bc = bottone("Carica", "", function () { caricaNome(c.nome); }); var bc = bottone("Carica", "", function () { caricaNome(c.nome); });
bc.disabled = !$("sorgente").value; bc.disabled = !$("sorgente").value;
az.appendChild(bc); az.appendChild(bc);
if (attiva) az.appendChild(bottone("Scollega", "secondario", scollega)); if (attiva) az.appendChild(bottone("Scollega", "secondario", scollega));
az.appendChild(bottone("Elimina", "secondario", function (e) { eliminaNome(c.nome, e.currentTarget); })); az.appendChild(bottone("Elimina", "secondario", function (e) { eliminaNome(c.nome, e.currentTarget); }));
tr.appendChild(az); sc.appendChild(riga1);
t.appendChild(tr); sc.appendChild(riga2);
sc.appendChild(az);
t.appendChild(sc);
}); });
segnaRisoluzioni(); segnaRisoluzioni();
} }
+3 -1
View File
@@ -72,4 +72,6 @@ def test_acquisizione_di_87_90_conservata():
def test_pagina_stretta(): def test_pagina_stretta():
assert "@media (max-width: 500px)" in PAGINA assert "@media (max-width: 500px)" in PAGINA
assert "overflow-x: auto" in PAGINA # l'elenco scorre di lato invece di rompere la pagina # #91: elenco a schede, niente tabella larga ne' scorrimento orizzontale
assert 'id="calibrazioni" class="elenco"' in PAGINA and "overflow-x" not in PAGINA
assert "Lettura dei parametri..." in PAGINA