* feat(web): the Display tab is an ES-module page, with a page-visibility service (stage 4)
- core/visibility.js: each page gets ctx.visibility (whileVisible, every,
isVisible). Work registered there runs only while the page's tab is
active and the browser tab visible, and ends when the page is swapped
out. It reads the active tab from window.LEDVisibility, so it agrees
with the classic partials. The registry gained a mountContext option for
per-mount services.
- pages/display.js replaces display.html's two inline scripts. The 5 s
sync status poll runs through ctx.visibility.every; the status and
scroll-speed hint requests go through ctx.api with ctx.signal, as does
the Vegas order widget's plugin-list request. The Advanced toggle is a
delegated data-action; window.updateSyncUI is a deprecated alias.
- New DOM suites test_visibility_service.js and test_display_page.js;
test_display_partial_ids.js imports the module.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* refactor(web): no computed keys in the Display page's readout and destroy
Codacy's object-injection rule flagged v[id] and ctx.state[name].
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* feat(web): Schedule and General become ES-module pages (stage 3)
Schedule and General follow stage 2 (#727): no inline scripts or inline
handlers in either partial. Their code moves to static/v3/js/pages/schedule.js
and pages/general.js, started per swap-in by the page registry.
- Schedule: both pickers are drawn from the saved config carried as JSON in
data-* attributes. The forms' hx-on save handlers become one
htmx:afterRequest listener on the page; the forms are marked
data-reports-result, which app.js now treats like an hx-on after-request
handler, so a save still shows one notification.
- General: the timezone picker reads data-timezone. The Security section's
forms and buttons are delegated data-actions; requests go through
core/api.js, so the login redirect is quiet, and a change made just
before a swap is still reported.
- handleScheduleResponse, handleDimScheduleResponse and webLogin stay as
deprecated aliases through window.LEDMatrix.
- New DOM suites test_schedule_page.js and test_general_page.js; the web
login unit suite imports the module; test_es_modules.py pins the pages,
the aliases, and the schedule config's round trip through its attribute.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* refactor(web): no unused catch bindings or computed writes in the stage 3 modules
Codacy flagged two unused catch variables and dynamic-key writes in
pages/schedule.js and boot.js. The schedule config is read with
getAttribute, and the default days and the webLogin alias object are built
with Object.fromEntries. No behaviour change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Rotation, Operation History, Config Editor and Backup & Restore become ES-module pages (stage 2): no inline scripts or onclick in the four partials, delegated data-action listeners, reads cancelled on swap-out, old globals kept as deprecated aliases through window.LEDMatrix, and four new DOM suites.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds a native ES-module layer to the web UI (core/boot, registry, api, facade; window.LEDMatrix as the one global), a page lifecycle that the Cache tab is converted to as the reference, text/javascript serving and revalidation for unversioned module requests, and src/plugin_system/field_model.py with a parity test against the render_field macro. Also: the cache page toggles its grey 'Not configured' style instead of only adding it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>