From 08aefa988830a5c35c79681ffbf26f9e4e61145c Mon Sep 17 00:00:00 2001 From: "Adriano (daitarn)" Date: Wed, 28 Oct 2026 21:23:55 +0100 Subject: [PATCH] =?UTF-8?q?Salva=20apre=20il=20=C2=ABSalva=20con=20nome?= =?UTF-8?q?=C2=BB=20prima=20di=20scaricare;=20riepilogo=20senza=20deviazio?= =?UTF-8?q?ne=200=20per=20quota=20NaN=20(Refs=20#119=20#118)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_019A9CSrh9rfM5WwqKtg8BSE --- src/frontend/flask_app/blueprints/measure.py | 3 ++- src/frontend/flask_app/static/js/save_image.js | 17 +++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/frontend/flask_app/blueprints/measure.py b/src/frontend/flask_app/blueprints/measure.py index dc19562..5448d3b 100644 --- a/src/frontend/flask_app/blueprints/measure.py +++ b/src/frontend/flask_app/blueprints/measure.py @@ -440,7 +440,8 @@ def task_complete(recipe_id: int): m["subtask"] = st m["task_info"] = subtask_task_map.get(m.get("subtask_id"), {}) # Compute deviation if not present - if m.get("deviation") is None and st.get("nominal") is not None: + # #118: quota non misurata (value None): la deviazione resta None (il template mostra NaN) + if m.get("deviation") is None and st.get("nominal") is not None and m.get("value") is not None: try: m["deviation"] = m["value"] - st["nominal"] except (TypeError, KeyError): diff --git a/src/frontend/flask_app/static/js/save_image.js b/src/frontend/flask_app/static/js/save_image.js index a723490..49f0496 100644 --- a/src/frontend/flask_app/static/js/save_image.js +++ b/src/frontend/flask_app/static/js/save_image.js @@ -40,17 +40,22 @@ async function tmfBlobToPng(blob) { // #119: scarica `src`, lo porta a PNG e lo salva; true = salvato, false = annullato dall'utente o errore async function tmfSaveImage(src, baseName) { + if (!src) return false; // #119: nessuna immagine mostrata try { + var name = tmfSaveImageName(baseName, new Date()); + // #119: «Salva con nome» per primo, finche' vale il gesto dell'utente (Chrome lo rifiuta dopo ~5 s di fetch e conversione) + var handle = null; + if (typeof window !== 'undefined' && typeof window.showSaveFilePicker === 'function') { + handle = await window.showSaveFilePicker({ + suggestedName: name, + types: [{ description: 'PNG', accept: { 'image/png': ['.png'] } }], + }); + } var resp = await fetch(src); if (!resp.ok) return false; var blob = await resp.blob(); if (blob.type !== 'image/png') blob = await tmfBlobToPng(blob); - var name = tmfSaveImageName(baseName, new Date()); - if (typeof window !== 'undefined' && typeof window.showSaveFilePicker === 'function') { - var handle = await window.showSaveFilePicker({ - suggestedName: name, - types: [{ description: 'PNG', accept: { 'image/png': ['.png'] } }], - }); + if (handle) { var w = await handle.createWritable(); await w.write(blob); await w.close();