From 1204ede1400477e2bf5d1369704ce92ba32c8352 Mon Sep 17 00:00:00 2001 From: Falkan Date: Wed, 18 Mar 2026 19:42:56 -0400 Subject: [PATCH] feat: Enter to save, Escape to discard, auto-save on unit/group selection - selectUnit/selectGroup now async; call autoSaveCurrentForm before switching - Enter in any form field (except textarea) triggers save - Escape restores form to snapshot (discards unsaved changes) - discardUnitForm/discardGroupForm helpers for snapshot restore --- data/units.json | 37 ++++++++++++++------------- src/routes/admin/+page.svelte | 48 +++++++++++++++++++++++++++++++++-- 2 files changed, 65 insertions(+), 20 deletions(-) diff --git a/data/units.json b/data/units.json index 19907d3..dda85f8 100644 --- a/data/units.json +++ b/data/units.json @@ -2,68 +2,69 @@ "units": [ { "id": "pound", - "label": "Pound", - "labelPlural": "Pounds", + "label": "pound", + "labelPlural": "pounds", "symbol": "lb", "group": "dickloads", "toBase": 0.038 }, { "id": "dickload", - "label": "Dickload", - "labelPlural": "Dickloads", + "label": "dickload", + "labelPlural": "dickloads", "symbol": "dl", "group": "dickloads", "toBase": 1 }, { "id": "barrel", - "label": "Barrel", - "labelPlural": "Barrels", + "label": "barrel", + "labelPlural": "barrels", "symbol": "bbl", "group": "dickloads", "toBase": 19 }, { "id": "hogshead", - "label": "Hogshead", - "labelPlural": "Hogsheads", + "label": "hogshead", + "labelPlural": "hogsheads", "symbol": "hhd", "group": "dickloads", "toBase": 38 }, { "id": "short-ton", - "label": "Short ton", - "labelPlural": "Short tons", + "label": "short ton", + "labelPlural": "short tons", "symbol": "t", "group": "dickloads", "toBase": 76 }, { "id": "fuckton", - "label": "Fuck ton", - "labelPlural": "Fucktons", + "label": "fuck ton", + "labelPlural": "fuck tons", "symbol": "fcktn", "group": "dickloads", "toBase": 152 }, { "id": "long-ton", - "label": "Long ton", - "labelPlural": "Long tons", + "label": "long ton", + "labelPlural": "long tons", "symbol": "long tn", "group": "dickloads", - "toBase": 85.1199999999 + "toBase": 85.1199999999, + "hidden": false }, { "id": "metric-fuckton", - "label": "Metric fuckton", - "labelPlural": "Metric fucktons", + "label": "metric fuckton", + "labelPlural": "metric fucktons", "symbol": "mfcktn", "group": "dickloads", "toBase": 170.2399999998, - "description": "Trivia: although the name is \"metric fuckton,\" it is actually equal to two long tons!", + "description": "Trivia: although the name is \"metric fuckton,\" it is actually equal to two {long-ton:plural}!", "hidden": false }, { diff --git a/src/routes/admin/+page.svelte b/src/routes/admin/+page.svelte index 8094326..ba1d7e9 100644 --- a/src/routes/admin/+page.svelte +++ b/src/routes/admin/+page.svelte @@ -214,7 +214,9 @@ }); // ── Selection ──────────────────────────────────────────────────────────────── - function selectUnit(unit: Unit) { + async function selectUnit(unit: Unit) { + const ok = await autoSaveCurrentForm(); + if (!ok) return; selectedItem = { type: 'unit', id: unit.id }; unitForm = { ...unit }; unitFormSnapshot = { ...unit }; @@ -226,7 +228,9 @@ formSuccess = null; } - function selectGroup(group: Group) { + async function selectGroup(group: Group) { + const ok = await autoSaveCurrentForm(); + if (!ok) return; selectedItem = { type: 'group', id: group.id }; groupForm = { ...group }; groupFormSnapshot = { ...group }; @@ -446,6 +450,40 @@ await loadData(); } + // ── Keyboard shortcuts for forms ───────────────────────────────────────────── + function discardUnitForm() { + unitForm = { ...unitFormSnapshot }; + unitFieldError = null; + formError = null; + formSuccess = null; + } + + function discardGroupForm() { + groupForm = { ...groupFormSnapshot }; + groupFieldError = null; + formError = null; + formSuccess = null; + } + + function onUnitFormKeydown(e: KeyboardEvent) { + // Don't intercept Enter inside textareas + if (e.key === 'Enter' && (e.target as HTMLElement).tagName !== 'TEXTAREA') { + e.preventDefault(); + saveUnit(); + } else if (e.key === 'Escape') { + discardUnitForm(); + } + } + + function onGroupFormKeydown(e: KeyboardEvent) { + if (e.key === 'Enter' && (e.target as HTMLElement).tagName !== 'TEXTAREA') { + e.preventDefault(); + saveGroup(); + } else if (e.key === 'Escape') { + discardGroupForm(); + } + } + // ── Unit save/delete ───────────────────────────────────────────────────────── async function saveUnit() { formError = null; @@ -817,6 +855,8 @@ {/if} {#if selectedItem?.type === 'unit' || unitFormNew} + +

{unitFormNew ? 'New Unit' : 'Edit Unit'}

+ {:else if selectedItem?.type === 'group' || groupFormNew} + +

{groupFormNew ? 'New Group' : 'Edit Group'}

+ {:else}

Select a unit or group to edit, or add a new one.