From 88094afe061d2d4ecaeaecdf613276c03dcd961d Mon Sep 17 00:00:00 2001 From: root Date: Tue, 19 May 2026 05:39:23 +0900 Subject: [PATCH] fix: auto-select firmware after upload, guard flash button without selection - Auto-select uploaded firmware immediately after upload completes - Auto-select single firmware on list load (no manual click needed) - Hide flash button and show warning when no firmware is selected - Re-apply manifest on list reload to avoid stale state - Restore warning banner on firmware delete Co-Authored-By: Claude Sonnet 4.6 --- frontend/index.html | 43 +++++++++++++++++++++++++------------------ frontend/js/app.js | 22 ++++++++++++++++++---- 2 files changed, 43 insertions(+), 22 deletions(-) diff --git a/frontend/index.html b/frontend/index.html index bb365c6..be2f845 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -262,26 +262,33 @@
πŸ’Ύ - μ„ νƒλœ νŽŒμ›¨μ–΄ μ—†μŒ β€” μœ„ λͺ©λ‘μ—μ„œ μ„ νƒν•˜μ„Έμš” + μ„ νƒλœ νŽŒμ›¨μ–΄ μ—†μŒ β€” μœ„ λͺ©λ‘μ—μ„œ ν΄λ¦­ν•˜μ—¬ μ„ νƒν•˜μ„Έμš”
- - - - - ⚠ 이 λΈŒλΌμš°μ €λŠ” Web Serial을 μ§€μ›ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€ (Chrome/Edge ν•„μš”) - - + +
+ ⚠ +
+ νŽŒμ›¨μ–΄λ₯Ό λ¨Όμ € μ„ νƒν•˜μ„Έμš”. + μœ„ λͺ©λ‘μ—μ„œ ν”Œλž˜μ‹œν•  νŽŒμ›¨μ–΄λ₯Ό ν΄λ¦­ν•˜λ©΄ 이 λ²„νŠΌμ΄ ν™œμ„±ν™”λ©λ‹ˆλ‹€. +
+
+ + +
⚠ diff --git a/frontend/js/app.js b/frontend/js/app.js index 26bd558..2ee2312 100644 --- a/frontend/js/app.js +++ b/frontend/js/app.js @@ -288,6 +288,7 @@ uploadForm.addEventListener('submit', async e => { }); await loadFirmwareList(); + selectFirmware(data.id); // μ—…λ‘œλ“œ 직후 μžλ™ 선택 switchTab('tab-flash'); } catch (err) { progressPct.textContent = `βœ— ${err.message}`; @@ -324,6 +325,8 @@ async function loadFirmwareList() { const resp = await fetch(`${API}/api/firmware`); state.firmwareList = await resp.json(); renderFwList(); + // λͺ©λ‘ λ‘œλ“œ ν›„ μžλ™ 선택 적용 (μ„ νƒλœ 것이 있으면 manifest μž¬μ„€μ •) + if (state.selectedFwId) selectFirmware(state.selectedFwId); } catch (err) { log(`βœ— νŽŒμ›¨μ–΄ λͺ©λ‘ λ‘œλ“œ μ‹€νŒ¨: ${err.message}`, 'err'); } @@ -340,6 +343,11 @@ function renderFwList() { return; } + // μ„ νƒλœ νŽŒμ›¨μ–΄κ°€ μ—†κ³  ν•˜λ‚˜λ§Œ 있으면 μžλ™ 선택 + if (!state.selectedFwId && state.firmwareList.length === 1) { + state.selectedFwId = state.firmwareList[0].id; + } + fwListEl.innerHTML = ''; state.firmwareList.forEach(fw => { const el = document.createElement('div'); @@ -379,10 +387,14 @@ function selectFirmware(id) { const manifestUrl = `${location.origin}/api/firmware/${id}/manifest`; installBtn.setAttribute('manifest', manifestUrl); - $('#selected-fw-info').textContent = `선택됨: ${state.firmwareList.find(f=>f.id===id)?.name}`; - log(`βœ“ ν”Œλž˜μ‹œ λŒ€μƒ 선택: ${state.firmwareList.find(f=>f.id===id)?.name}`, 'ok'); - log(` Manifest: ${manifestUrl}`, 'info'); + const fw = state.firmwareList.find(f => f.id === id); + $('#selected-fw-info').textContent = `선택됨: ${fw?.name}`; + $('#flash-btn-wrap').style.display = 'block'; + $('#no-fw-warning').style.display = 'none'; + + log(`βœ“ ν”Œλž˜μ‹œ λŒ€μƒ 선택: ${fw?.name}`, 'ok'); + log(` Manifest URL: ${manifestUrl}`, 'info'); } async function deleteFirmware(id) { @@ -392,7 +404,9 @@ async function deleteFirmware(id) { if (state.selectedFwId === id) { state.selectedFwId = null; installBtn.removeAttribute('manifest'); - $('#selected-fw-info').textContent = 'μ„ νƒλœ νŽŒμ›¨μ–΄ μ—†μŒ'; + $('#selected-fw-info').textContent = 'μ„ νƒλœ νŽŒμ›¨μ–΄ μ—†μŒ β€” μœ„ λͺ©λ‘μ—μ„œ ν΄λ¦­ν•˜μ—¬ μ„ νƒν•˜μ„Έμš”'; + $('#flash-btn-wrap').style.display = 'none'; + $('#no-fw-warning').style.display = 'block'; } await loadFirmwareList(); log(`βœ“ νŽŒμ›¨μ–΄ μ‚­μ œ μ™„λ£Œ`, 'ok');