diff --git a/Web App/web/src/i18n/da.json b/Web App/web/src/i18n/da.json index 973f175..568b930 100644 --- a/Web App/web/src/i18n/da.json +++ b/Web App/web/src/i18n/da.json @@ -82,6 +82,8 @@ "connected": "Forbundet", "disconnected": "Offline", "serialPlaceholder": "Laderens serienummer (f.eks. A5191-XXXXXXXX)", + "enterSerial": "Indtast et serienummer i stedet", + "pickSerial": "Vælg blandt dine ladere", "refresh": "Opdater", "status": "Stik", "meter": "Energi", diff --git a/Web App/web/src/i18n/en.json b/Web App/web/src/i18n/en.json index 439a9a1..24782b6 100644 --- a/Web App/web/src/i18n/en.json +++ b/Web App/web/src/i18n/en.json @@ -68,6 +68,8 @@ "connected": "Connected", "disconnected": "Offline", "serialPlaceholder": "Charger serial (e.g. A5191-XXXXXXXX)", + "enterSerial": "Enter a serial instead", + "pickSerial": "Choose from your chargers", "refresh": "Refresh", "status": "Connector", "meter": "Energy", diff --git a/Web App/web/src/i18n/pl.json b/Web App/web/src/i18n/pl.json index 2bc73c1..7007799 100644 --- a/Web App/web/src/i18n/pl.json +++ b/Web App/web/src/i18n/pl.json @@ -84,6 +84,8 @@ "connected": "Połączono", "disconnected": "Offline", "serialPlaceholder": "Numer seryjny ładowarki (np. A5191-XXXXXXXX)", + "enterSerial": "Wpisz numer seryjny zamiast tego", + "pickSerial": "Wybierz ze swoich ładowarek", "refresh": "Odśwież", "status": "Złącze", "meter": "Energia", diff --git a/Web App/web/src/views/Charging.vue b/Web App/web/src/views/Charging.vue index 2d83246..d9c535c 100644 --- a/Web App/web/src/views/Charging.vue +++ b/Web App/web/src/views/Charging.vue @@ -99,6 +99,15 @@ async function loadCtlMode() { // a list; without them (account not linked, or the cloud unreachable) the field // stays a plain text box so a serial can still be typed in by hand. const chargers = ref([]); +// Typing the serial rather than picking it. A dropdown can only show a serial it +// has an option for, so a remembered serial the account does not report — a +// charger imported before the account was linked, one the cloud is quiet about +// today — would render as a blank field with no way to read or fix it. Falling +// back to the text box shows the serial that is actually in force. +const manualSerial = ref(false); + +const serialInList = computed(() => chargers.value.some((c) => c.sn === ctlSerial.value.trim())); +const pickingFromList = computed(() => chargers.value.length > 0 && !manualSerial.value); async function loadChargers() { try { @@ -111,6 +120,22 @@ async function loadChargers() { if (!ctlSerial.value.trim() && chargers.value.length) { ctlSerial.value = chargers.value[0].sn; } + // Decided when the list arrives rather than on every keystroke: recomputing it + // as the serial is typed would swap the text box for a dropdown mid-word, the + // moment what had been typed happened to match a charger. + manualSerial.value = chargers.value.length > 0 && !serialInList.value; +} + +// One control for both directions, so a serial that is not on the account is +// never a dead end and the list is never the only option. +function toggleSerialEntry() { + manualSerial.value = !manualSerial.value; + // Returning to a list that does not hold this serial would blank the dropdown + // again, which is the thing being fixed; land on a charger it does hold. + if (!manualSerial.value && !serialInList.value && chargers.value.length) { + ctlSerial.value = chargers.value[0].sn; + refreshCtl(); + } } function chargerLabel(c) { @@ -590,7 +615,7 @@ onMounted(async () => {
- { class="dh-input" :placeholder="t('charging.control.serialPlaceholder')" autocomplete="off" + spellcheck="false" + @keyup.enter="refreshCtl" />
+ +