What the charger is set to, where the setting is made

The nine values the charger reports back about itself — the current limit, the
timeout, the phase setting, whether boost took, the last command it accepted,
the charging mode, the two balancing flags, the LED — sat fourth in the readings
card, under a phase table and a live-data block. They are the readback of what
the control card's buttons just wrote, so they were being read straight after
pressing something, at the bottom of the longest card on the page.

They get their own card, directly under control in the default order, and the
readings card keeps what it is for: what the charger is doing right now, what it
is, and any alarm. Nothing is shown twice.

The card folds and drags by its heading like the other four, on the same
chargerCardOrder. A column somebody has already arranged doesn't mention this
key, so there it arrives at the end rather than in the middle of a layout that
was chosen — the rule a tab added in a later release already follows — and one
drag settles it.

It appears on the Modbus path only, because that is the only transport that
reports a settings snapshot at all; the OCPP one has nothing to put in it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
tajniak81
2026-09-02 09:11:54 +02:00
co-authored by Claude Opus 5
parent 6877d311ea
commit e1c063d4b1
4 changed files with 54 additions and 14 deletions
+1
View File
@@ -116,6 +116,7 @@
"phases": "Pr. fase",
"live": "Live data",
"settings": "Indstillinger",
"settingsTitle": "Laderindstillinger",
"device": "Enhed",
"alarms": "Alarmer",
"phase": "Fase",
+1
View File
@@ -102,6 +102,7 @@
"phases": "Per phase",
"live": "Live data",
"settings": "Settings",
"settingsTitle": "Charger settings",
"device": "Device",
"alarms": "Alarms",
"phase": "Phase",
+1
View File
@@ -118,6 +118,7 @@
"phases": "Na fazę",
"live": "Dane na żywo",
"settings": "Ustawienia",
"settingsTitle": "Ustawienia ładowarki",
"device": "Urządzenie",
"alarms": "Alarmy",
"phase": "Faza",
+51 -14
View File
@@ -164,15 +164,20 @@ const sessionMetrics = computed(() =>
// via the control endpoints when the user has picked Own/Proxy CSMS in Settings.
// --- Arranging the cards ---
//
// The four cards drag into any order, like the provider panel's readings, and
// the arrangement is saved on the profile beside the tab order. The column is a
// The cards drag into any order, like the provider panel's readings, and the
// arrangement is saved on the profile beside the tab order. The column is a
// flex box, so a card is placed with the CSS order property rather than by
// moving markup: these are four different things, not four of one thing.
// moving markup: these are different things, not several of one thing.
//
// The handle is the card's own header. Making the whole card draggable would
// fight the controls inside it — a range slider and two text fields cannot
// share a pointer with a native drag.
const ALL_CHARGER_CARDS = ["control", "connection", "readings", "info"];
//
// Settings follows control by default because it is the readback of what those
// buttons just did: the limit that was applied, whether boost took. An account
// that has already arranged this column gets it at the end instead, the same
// rule a tab added in a later release follows, and one drag puts it anywhere.
const ALL_CHARGER_CARDS = ["control", "settings", "connection", "readings", "info"];
const cardKeys = ref([...ALL_CHARGER_CARDS]);
watch(
@@ -1084,6 +1089,48 @@ onMounted(async () => {
</div>
</div>
<!-- What the charger is set to, as it reports it back. Its own card
under the control one: these are the values those buttons write, so
they are read right after pressing them, and they were buried at
the bottom of a long readings card. -->
<div
v-if="ctlIsModbus && ctlConnected && modbusSettings.length"
class="dh-card p-4 transition-shadow duration-150"
:class="dropCard === 'settings' ? 'ring-2 ring-accent' : ''"
:style="{ order: cardOrder('settings') }"
@dragenter.prevent="onCardDragEnter('settings')"
@dragover.prevent
@drop.prevent="commitCardOrder"
>
<button
type="button"
:draggable="canArrangeCards"
:title="canArrangeCards ? t('charging.cards.dragHint') : ''"
class="flex w-full items-center justify-between gap-3 text-left"
:class="[canArrangeCards ? 'cursor-grab active:cursor-grabbing' : '', dragCard === 'settings' ? 'opacity-50' : '']"
:aria-expanded="isOpen('settings')"
@click="toggleCard('settings')"
@dragstart="onCardDragStart('settings', $event)"
@dragend="commitCardOrder"
>
<p class="text-sm font-semibold text-strong">{{ t("charging.modbus.settingsTitle") }}</p>
<svg
viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
class="h-4 w-4 shrink-0 text-muted transition-transform" :class="isOpen('settings') ? '' : '-rotate-90'"
><path stroke-linecap="round" stroke-linejoin="round" d="m6 9 6 6 6-6" /></svg>
</button>
<div v-show="isOpen('settings')">
<!-- The card is the heading, so the group needs none of its own. -->
<dl class="mt-3 grid grid-cols-2 gap-x-3 gap-y-1 rounded-control bg-sunken p-3">
<template v-for="r in modbusSettings" :key="r.label">
<dt class="text-xs text-muted">{{ r.label }}</dt>
<dd class="data text-right text-xs text-strong">{{ r.value }}</dd>
</template>
</dl>
</div>
</div>
<!-- Which charger, and how to reach it. Below the controls: it is
touched once and then left alone. -->
<div
@@ -1272,16 +1319,6 @@ onMounted(async () => {
</dl>
</section>
<section v-if="modbusSettings.length" class="rounded-control bg-sunken p-3">
<h4 class="eyebrow">{{ t("charging.modbus.settings") }}</h4>
<dl class="mt-2 grid grid-cols-2 gap-x-3 gap-y-1">
<template v-for="r in modbusSettings" :key="r.label">
<dt class="text-xs text-muted">{{ r.label }}</dt>
<dd class="data text-right text-xs text-strong">{{ r.value }}</dd>
</template>
</dl>
</section>
<section v-if="modbusDevice.length" class="rounded-control bg-sunken p-3">
<h4 class="eyebrow">{{ t("charging.modbus.device") }}</h4>
<dl class="mt-2 grid grid-cols-2 gap-x-3 gap-y-1">