ui: bordered header badges and ICCID-labelled card actions (v2.6.2)

- ADM/SCP80/SCP81 header indicators become bordered chips (neutral gray
  border, rounded, px-1.5 py-0.5); SCP80/SCP81 get an even ml-1 gap, so no
  separator glyph is needed
- profiler/snapshot card actions carry the equipped card's ICCID:
  'Profile from card <ICCID>', 'Check card <ICCID>' (row button, arrow
  dropped), 'New snapshot: <ICCID>'; pysimUpdateCardActionLabels() fills
  the spans on every status poll and after a language switch
- these buttons switch to data-needs='card-iccid': disabled without a
  readable ICCID ('Card equipped but its ICCID is not readable' hint)
- profiler rows wrap so the longer button cannot break the layout;
  help EN/RU updated; SW cache simple-v202
This commit is contained in:
2026-09-20 01:40:39 +03:00
parent 97bc8f929d
commit 81b50199cc
8 changed files with 65 additions and 17 deletions
+28
View File
@@ -26,6 +26,7 @@ code += extractFunc(html, 'pysimAvailabilityState') + '\n';
code += extractFunc(html, 'pysimControlDisabled') + '\n';
code += extractFunc(html, 'pysimNeedsHint') + '\n';
code += extractFunc(html, 'pysimApplyAvailability') + '\n';
code += extractFunc(html, 'pysimUpdateCardActionLabels') + '\n';
code += extractFunc(html, 'pysimUpdateStateIndicator') + '\n';
code += extractFunc(html, 'pysimUpdateIccidIndicator') + '\n';
code += extractFunc(html, 'pysimUpdatePresetIndicator') + '\n';
@@ -231,3 +232,30 @@ test('indicator image stays within the 32px header row budget', () => {
const size = Number(m[1]);
assert.ok(size >= 24 && size <= 32, 'size ' + size + 'px would change the header height');
});
test('header badges are bordered chips with even spacing', () => {
for (const id of ['state-indicator-adm', 'state-indicator-scp80', 'state-indicator-scp81']) {
const m = new RegExp('id="' + id + '"[^>]*class="([^"]*)"').exec(html);
assert.ok(m, id + ' markup not found');
assert.match(m[1], /\bborder\b/);
assert.match(m[1], /\brounded\b/);
}
assert.match(html, /id="state-indicator-scp80"[^>]*class="[^"]*ml-1/);
assert.match(html, /id="state-indicator-scp81"[^>]*class="[^"]*ml-1/);
});
test('card action labels carry the equipped ICCID', () => {
setup();
const plain = fakeEl();
const colon = fakeEl();
colon.attrs['data-iccid-sep'] = ': ';
globalThis.document.querySelectorAll = sel => sel === '.profiler-iccid-label' ? [plain, colon] : [];
_pysimCardIccid = '89701450001700031958';
pysimUpdateCardActionLabels();
assert.strictEqual(plain.textContent, ' 89701450001700031958');
assert.strictEqual(colon.textContent, ': 89701450001700031958');
_pysimCardIccid = null;
pysimUpdateCardActionLabels();
assert.strictEqual(plain.textContent, '');
assert.strictEqual(colon.textContent, '');
});