UX-46: Dutch status rows, banners, notes and wizard lines on the NL pages

Rows and banners are built once with their Dutch beside them (messages.Bi)
and status_payload() picks one by the page's language. Settings notes and the
wizard's checks carry a Dutch twin (Note.nl) that /config/validate picks by
the posted language. The peak forecast label drops "(W)" in EN and NL.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
glenn schrooyen
2026-10-22 03:21:41 +02:00
co-authored by Claude
parent e077ae7f97
commit 7a392a5367
10 changed files with 1244 additions and 204 deletions
+14 -6
View File
@@ -51,7 +51,7 @@ from aiohttp import web
from . import messages, price, selfconfig, uipage, uitext
from .haentities import EntityCache
from .homeview import priced_hours, region_of
from .validate import config_notes, setup_checks
from .validate import config_notes, note_text, setup_checks
from .config_page import CONFIG_PAGE
from .configui import (changed_keys, field_model, hide_secrets, keep_secrets,
problems_by_field, secret_keys)
@@ -105,6 +105,9 @@ def page() -> str:
DEVICE_NOTE = (
"%s did not report its power range, so two checks were skipped, here and "
"at start. If they fail later, the add-on will not start then.")
DEVICE_NOTE_NL = (
"%s meldde geen vermogensbereik, dus twee controles zijn overgeslagen, "
"hier en bij het starten. Falen ze later, dan start de add-on dan niet.")
def build_app(controller, selfcfg=None) -> web.Application:
@@ -301,22 +304,27 @@ def build_app(controller, selfcfg=None) -> web.Application:
# UX-13: warnings and info beside the refusals. Never block a save.
# The entity checks use the picker's cached list and never wait on HA.
notes += config_notes(options, entities=entities.peek())
# UX-46: one language choice for everything below that has words.
lang = uitext.lang_of(_body.get("lang"))
payload = {"problems": problems, "by_key": by_key,
"unanchored": unanchored,
"notes": [n._asdict() for n in notes]}
if unread:
payload["device_note"] = DEVICE_NOTE % ", ".join(sorted(set(unread)))
payload["device_note"] = (DEVICE_NOTE_NL if lang == "nl"
else DEVICE_NOTE) % ", ".join(
sorted(set(unread)))
if model is not None:
payload["messages"] = (
uipage.derive_messages(errors, problems, notes, model,
_keys_of(options),
uitext.lang_of(_body.get("lang")))
_keys_of(options), lang)
if errors
else uipage.anchors(problems, notes, model, _keys_of(options),
uitext.lang_of(_body.get("lang"))))
lang))
payload["steps"] = uipage.step_problems(payload["messages"], model)
if _body.get("setup"):
payload["setup"] = [n._asdict() for n in await _setup_checks(options)]
payload["setup"] = [
dict(n._asdict(), text=note_text(n, lang))
for n in await _setup_checks(options)]
return web.json_response(payload)
async def _setup_checks(options):