From 10441a4761f912d5c3de65b2549d6dd2d566ecdf Mon Sep 17 00:00:00 2001 From: Paul Trowbridge Date: Wed, 1 Apr 2026 12:24:20 -0400 Subject: [PATCH] Show baseline/reference form in a modal with live month preview Replaces the small inline form with a centred modal dialog. When both dates are selected, a live chip list shows every month covered (up to 36 months) so it is immediately clear what periods will be loaded. Co-Authored-By: Claude Sonnet 4.6 --- public/app.js | 49 +++++++++++++++++++++++++++--- public/index.html | 37 +++++++++++++++-------- public/styles.css | 77 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 146 insertions(+), 17 deletions(-) diff --git a/public/app.js b/public/app.js index f2a75a9..a795e1e 100644 --- a/public/app.js +++ b/public/app.js @@ -375,10 +375,48 @@ function showLoadForm(op) { state.loadDataOp = op; document.getElementById('load-data-title').textContent = op === 'baseline' ? 'Load Baseline' : 'Load Reference'; - document.getElementById('load-data-form').classList.remove('hidden'); + document.getElementById('load-date-from').value = ''; + document.getElementById('load-date-to').value = ''; + document.getElementById('load-note').value = ''; + document.getElementById('load-date-preview').classList.add('hidden'); + document.getElementById('load-data-modal').classList.remove('hidden'); document.getElementById('load-date-from').focus(); } +function hideLoadModal() { + document.getElementById('load-data-modal').classList.add('hidden'); +} + +function updateDatePreview() { + const fromVal = document.getElementById('load-date-from').value; + const toVal = document.getElementById('load-date-to').value; + const preview = document.getElementById('load-date-preview'); + const chips = document.getElementById('load-date-chips'); + const label = preview.querySelector('.load-preview-label'); + + if (!fromVal || !toVal) { preview.classList.add('hidden'); return; } + + const from = new Date(fromVal + 'T00:00:00'); + const to = new Date(toVal + 'T00:00:00'); + if (isNaN(from) || isNaN(to) || from > to) { preview.classList.add('hidden'); return; } + + const months = []; + const cur = new Date(from.getFullYear(), from.getMonth(), 1); + const end = new Date(to.getFullYear(), to.getMonth(), 1); + while (cur <= end) { months.push(new Date(cur)); cur.setMonth(cur.getMonth() + 1); } + + const fmt = new Intl.DateTimeFormat('en-US', { month: 'short', year: 'numeric' }); + label.textContent = `${months.length} month${months.length !== 1 ? 's' : ''} covered`; + + if (months.length <= 36) { + chips.innerHTML = months.map(m => `${fmt.format(m)}`).join(''); + } else { + chips.innerHTML = `${months.length} months — ${fmt.format(months[0])} → ${fmt.format(months[months.length - 1])}`; + } + + preview.classList.remove('hidden'); +} + async function submitLoadData() { const date_from = document.getElementById('load-date-from').value; const date_to = document.getElementById('load-date-to').value; @@ -394,7 +432,7 @@ async function submitLoadData() { try { showStatus(`Loading ${state.loadDataOp}...`, 'info'); const result = await api('POST', `/versions/${state.selectedVersionId}/${state.loadDataOp}`, body); - document.getElementById('load-data-form').classList.add('hidden'); + hideLoadModal(); showStatus(`${state.loadDataOp} loaded — ${result.rows_affected} rows`, 'success'); } catch (err) { showStatus(err.message, 'error'); @@ -879,9 +917,10 @@ document.addEventListener('DOMContentLoaded', () => { document.getElementById('vbtn-toggle').addEventListener('click', toggleVersionStatus); document.getElementById('vbtn-delete').addEventListener('click', deleteVersion); document.getElementById('btn-load-submit').addEventListener('click', submitLoadData); - document.getElementById('btn-load-cancel').addEventListener('click', () => { - document.getElementById('load-data-form').classList.add('hidden'); - }); + document.getElementById('btn-load-cancel').addEventListener('click', hideLoadModal); + document.getElementById('btn-load-close').addEventListener('click', hideLoadModal); + document.getElementById('load-date-from').addEventListener('change', updateDatePreview); + document.getElementById('load-date-to').addEventListener('change', updateDatePreview); // forecast view buttons document.getElementById('btn-forecast-refresh').addEventListener('click', loadForecastData); diff --git a/public/index.html b/public/index.html index 16d62f2..1f06ac2 100644 --- a/public/index.html +++ b/public/index.html @@ -94,18 +94,6 @@ - @@ -170,6 +158,31 @@ + + +