+50
−2
+75
−79
+70
−54
Loading
- ui.js: nuovi helper withBusyButton(el, fn) (disabilita l'elemento
per la durata di fn; spinner solo sui <button> veri, checkbox/select
restano solo disabled) e fetchWithTimeout(url, options,
timeoutMs=12000) (AbortController, nessun fetch() nel codice ne
aveva uno).
- Dedup delle 3 copie hand-rolled del pattern busy-button: actions.js
(.btn-universal), control.js (btn-check-target), guider-panel.js
(postGuider).
- Applicato a tutti gli handler confermati non protetti dal documento
delle convenzioni: Expose (control.js, un withBusyButton per
bottone stazione via e.currentTarget), Loop toggle (loop-toggle.js,
solo il change handler -- il poll a 5s di refresh() resta com'era,
idempotente), stage relative (control.js -- i bottoni +/- si
disabilitano anche a vicenda, non solo se stessi, per la race
read-then-write segnalata esplicitamente), select-universal
(actions.js), webcam move/preset (webcam.js), sequencer
save/delete/refresh (sequencer.js -- deleteOB guadagna anche un
try/catch che non aveva).
- Eccezione deliberata: postExpose usa withBusyButton ma fetch()
normale, non fetchWithTimeout -- /api/sequencer/run blocca lato
server finche' tutta la sequenza non finisce (sequencer.py:execute),
puo' essere minuti per un'esposizione reale. Verificato che loop/
guider-start/stage-position invece ritornano subito, quindi per
quelli il timeout di default e' sicuro.
- Verificato con node --check su tutti i file toccati.
- PLAN.md aggiornato.
Co-Authored-By:
Claude Sonnet 5 <noreply@anthropic.com>