ui: gate controls by server/card state; move Custom files to Profiler

Availability model: server-down / server-up-no-card / card-equipped.
- header shows a symbolic indicator dot (red/yellow/green, tooltip)
- a 5s probe tracks /api/version+/api/status while not fully ready; the
  2s status poll takes over once connected
- controls declare data-needs='server' or 'card'; disabled + tooltip when
  the state does not satisfy them: equip (server), status/reset, file
  manager read/save/edit, raw APDU, profile-from-card, new snapshot,
  profiler list Check card, event Send, RAM install/explore delete,
  STK menu, Send STATUS, Verify vs pySim (server), pySim execute (server),
  PLI save/poll toggle (server)
- pysimConnect no longer conflates server and card: it records both and
  Connect stays usable without a card
- ramSendOta/ramInstallCap now use pysimFetch instead of raw fetch
  (relative /api URLs broke custom server URLs)

Custom files moved from the Card reader sub-tabs to the Profiler list
tabs (Profiles / Card snapshots / Custom files); help/README/AGENTS
updated. Tests: availability gating, indicator structure, moved tab.
SW cache v103 -> v104.
This commit is contained in:
2026-09-12 17:58:30 +03:00
parent f1ed6a2a48
commit 5b9e821d6d
9 changed files with 235 additions and 103 deletions
+7
View File
@@ -41,3 +41,10 @@ test('scan name input starts scanning on Enter', () => {
test('snapshot view has a timing summary block', () => {
assert.ok(html.includes('id="snapshot-summary"'));
});
test('header state indicator and profiler custom-files tab', () => {
assert.ok(html.includes('id="state-indicator"'));
assert.ok(html.includes('id="profiler-list-custom"'));
assert.ok(html.includes('data-list-tab="custom"'));
assert.ok(!html.includes('data-pysim-sub="custom"'));
});