From e0d2ab12d32636569bd13001a65b276d20577910 Mon Sep 17 00:00:00 2001 From: marijo Date: Thu, 25 Jun 2026 11:47:35 +0000 Subject: [PATCH] Values editable in the top row --- app.js | 64 ++++++++++++++++++++++++++++++++++++++++++------------- style.css | 12 +++++++++++ 2 files changed, 61 insertions(+), 15 deletions(-) diff --git a/app.js b/app.js index c5f5faf..7c4021c 100644 --- a/app.js +++ b/app.js @@ -356,24 +356,39 @@ function resetEntryForm() { function renderDashboard() { const current = state.plan.current; + const { year, month } = currentMonthParts(); const cards = [ - ['Feriefridage', days(current.feriefridage), 'Use before 31 August', current.feriefridage > 0.001 ? 'warn' : ''], - ['Vacation days', days(current.vacation), 'Available today', current.vacation < -0.001 ? 'bad' : 'good'], + { + kind: 'feriefridage', + label: 'Feriefridage', + value: current.feriefridage, + hint: 'Use before 31 August', + tone: current.feriefridage > 0.001 ? 'warn' : '', + step: '0.01', + overridden: hasCorrection(state.feriefridageOverrides, year, month), + }, + { + kind: 'vacation', + label: 'Vacation days', + value: current.vacation, + hint: 'Available today', + tone: current.vacation < -0.001 ? 'bad' : 'good', + step: '0.01', + overridden: hasCorrection(state.corrections, year, month), + }, + { + kind: 'flex', + label: 'FLEX hours', + value: current.flex, + hint: 'Current balance', + tone: current.flex < -0.001 ? 'bad' : 'good', + step: '0.25', + overridden: hasCorrection(state.flexOverrides, year, month), + }, ]; $('dashboard').innerHTML = ` - ${cards.map(([label, value, hint, tone]) => ` -
-
${escapeHtml(label)}
-
${value}
-
${escapeHtml(hint)}
-
- `).join('')} -
-
FLEX hours
-
${hours(current.flex)}
-
Current balance
-
+ ${cards.map((card) => renderDashboardBalanceCard(card, year, month)).join('')}
Total days
${days(current.totalDays)}
@@ -382,6 +397,21 @@ function renderDashboard() { `; } +function renderDashboardBalanceCard(card, year, month) { + return ` +
+
${escapeHtml(card.label)}
+ +
${escapeHtml(card.hint)}
+
+ `; +} + +function currentMonthParts() { + const today = new Date(); + return { year: today.getFullYear(), month: today.getMonth() + 1 }; +} + function renderHeaderWarnings() { const warnings = state.plan.current.warnings; $('headerWarnings').innerHTML = warnings.length @@ -444,10 +474,14 @@ function renderPlanner() { `; + bindBalanceOverrideInputs(); + syncPlannerScroll(); +} + +function bindBalanceOverrideInputs() { document.querySelectorAll('.balance-override-input').forEach((input) => { input.addEventListener('change', (event) => saveBalanceOverride(event).catch((error) => toast(error.message || String(error)))); }); - syncPlannerScroll(); } function syncPlannerScroll() { diff --git a/style.css b/style.css index 2263815..07e5b2a 100644 --- a/style.css +++ b/style.css @@ -175,6 +175,17 @@ main { .header-cards .card .label { font-size: .88rem; font-weight: 950; white-space: nowrap; } .header-cards .card .value { font-size: 1.55rem; font-weight: 950; margin: 0; } .header-cards .card .hint { display: none; } +.header-cards .card .dashboard-balance-input { + width: 5.25rem; + min-width: 0; + padding: .05rem .18rem; + border-radius: 6px; + text-align: right; + background: rgba(16,16,16,.55); + font-size: 1.45rem; + font-weight: 950; + line-height: 1; +} .card.bad .value { color: var(--bad); } .card.warn .value { color: var(--warn); } .card.good .value { color: var(--good); } @@ -397,6 +408,7 @@ tbody tr:hover { background: rgba(255,255,255,.04); } .header-cards .card { padding: .14rem .2rem; gap: .18rem; } .header-cards .card .label { font-size: .72rem; font-weight: 950; } .header-cards .card .value { font-size: 1.45rem; font-weight: 950; } + .header-cards .card .dashboard-balance-input { width: 3.9rem; padding: .04rem .12rem; font-size: 1rem; } .header-entries { padding: .16rem .22rem; margin: .16rem 0; } .header-entries .table-wrap { overflow-x: visible; overflow-y: visible; }