feat: warn when the equipped card and the selected preset disagree (v3.8.0)

Autoselection normally keeps the SCP80/RAM preset in step with the card, so
the mismatch is easy to miss.  Both views now carry an amber banner above the
preset selector (the existing warning style - no new Tailwind classes):

- the equipped card matches no preset: "The equipped card <ICCID> does not
  match any card preset - the selected preset may belong to another card.
  Add it in the Cards tab (From card)"; with no presets at all the banner says
  so instead;
- a preset is selected but it is not the equipped card's: a softer line naming
  the matching preset ("check that its keys and counters belong to this card").

`spPresetWarning(iccid, presets, selectedIdx)` is pure (unit-tested with the
ICCID forms the store accepts: digits, spaced, raw EF hex), `spPresetWarningRender`
fills both banners and runs on every card-state poll, preset load, preset
selection and page init.  No card session or an unreadable ICCID shows nothing
(the card-iccid gating already explains that state); the banner warns only -
it never blocks a send (preparing a packet for another card stays possible).

Tests: frontend/tests/preset_warning.test.js (5), the card-state/preset
harnesses stub the DOM-bound renderer.  sw cache simple-v336.
This commit is contained in:
2026-09-30 15:37:51 +03:00
parent cc2edb3d8a
commit 386958b261
9 changed files with 144 additions and 5 deletions
+1 -1
View File
@@ -37,7 +37,7 @@ for (const fn of ['cardsTarValue', 'cardsFormValues', 'cardsClearForm', 'cardsEd
'ramKeysetChanged', 'ramPresetIdx', 'spKeysetGuard', 'ramKeysetGuard']) {
code += extractFunc(html, fn, ASYNC_FNS.indexOf(fn) >= 0) + '\n';
}
code = 'var _cardsKeysetCount = 0;\n' + code;
code = 'var _cardsKeysetCount = 0;\nglobalThis.spPresetWarningRender = function() {};\n' + code;
eval(code);
const CARD_IDS = ['cards-name','cards-iccid','cards-adm',