docs: v0.126.0 UI uniformity bundle — CHANGELOG (parts A-E + gate housekeeping), REUSE (app_list_row canonical row + gate list), README (shared-row pattern, infra identity, Part E display pick), CONTEXT
This commit is contained in:
+39
-1
@@ -2,10 +2,48 @@
|
||||
|
||||
### v0.126.0 — UI uniformity bundle: shared app-list rows, infra-app metadata, restore-form polish, mojibake gate (2026-07-13)
|
||||
|
||||
Operator review (2026-07-13 screenshots): app lists looked designed three different ways across
|
||||
four+ surfaces; infra stacks rendered as bare names; the .fab password input clipped its
|
||||
placeholder; the zero-toggle run-warning went stale. Controller-only, presentation-layer — NO
|
||||
backup/engine/toggle behavior change (render tests assert the action markup is untouched).
|
||||
|
||||
- **Part A — ONE row grammar, four surfaces:** `templates/app_row.html` defines
|
||||
`app_list_row`/`app_list_row_end` (the layout_start/_end idiom): icon + name (+ optional
|
||||
one-line secondary) left, caller action block right; compact 44px row. Applied to the Távoli
|
||||
mentés toggle list, the Visszaállítás restore-to-verify + .fab lists and the dashboard
|
||||
Telepített alkalmazások (state edge + data-href preserved); the Alkalmazások collapsed
|
||||
headers ALIGNED to the grammar (icon+name left, status dot moved right before the chevron;
|
||||
expander untouched — the one allowlisted aligned copy). funcmap: `dict` + `appHref`;
|
||||
`OffboxAppRow`/`AppBackupRow` gain `Slug`. Old `.stack-card`/`.storage-path-item` row CSS+markup
|
||||
retired. **NEW gate `scripts/app_row_dedup_gate.py`** — row markup single-sourced (red-proven:
|
||||
pasted an old row block back → exit 1).
|
||||
- **Part B — infra stacks carry identity:** `inframeta.go` static display-only map —
|
||||
cloudflared → „Cloudflare Tunnel", traefik → „Traefik", filebrowser → „FileBrowser", each with
|
||||
curated Hungarian description; dashboard rows + app cards show icon + description + the
|
||||
existing Védett chip. Generic embedded `/static/infra-logo.svg` as icon fallback. filebrowser
|
||||
is the ONLY Linked stack (files.<domain> Megnyitás); guarded WRONG outcome — no customer link
|
||||
for cloudflared/traefik (render test counts exactly one https:// link; red-proven by flipping
|
||||
Linked on cloudflared → FAIL).
|
||||
- **Part C — restore-form polish:** the .fab encryption input is a standard form field —
|
||||
placeholder „Opcionális jelszó" + helper under the field („Üresen hagyva a csomag titkosítás
|
||||
nélkül készül."); the import-page bundle-password input picks up `.form-input` (was a bare
|
||||
browser default).
|
||||
- **Part D — mojibake fixed-by-construction:** byte-level sweep found ZERO double-encoded
|
||||
literals in the committed source — the live „Tárhely"-class text on the import page is the
|
||||
felhom-usb DRIVE-LABEL DATA (settings.json), repaired via the label-edit UI during live
|
||||
validation. **NEW gate `scripts/mojibake_gate.py`** (Python per the multibyte rule): all
|
||||
templates + Go sources must strict-UTF-8-decode and contain none of Ã Â Ă ă ˘ ˇ; allowlist
|
||||
ZERO. Red-proven (reintroduced „Tárhely" → exit 1 naming file:line).
|
||||
- **Part E — the stale zero-toggle line tells the truth:** `offboxWarningDisplay` display pick
|
||||
(no state mutation): a persisted „nincs mentésre jelölt alkalmazás" run-warning is replaced by
|
||||
„A kijelölés módosult az utolsó futás óta — a következő távoli mentés már tartalmazza." once
|
||||
≥1 app is toggled (rendered neutral — reassurance, not deviation); 0 toggled keeps the
|
||||
v0.123.0 line verbatim; quota/partial warnings pass through. Red-proven at unit + render level.
|
||||
- **Gate housekeeping (first commit):** `scripts/backups_split_move_check.py` retired — the
|
||||
one-shot v0.124.0 migration gate served its purpose (it pinned the split to verbatim moves vs
|
||||
df7ad37); this release legitimately rewrites those blocks onto the shared row partial. All
|
||||
other template gates stay mandatory.
|
||||
other template gates stay mandatory (template_id, emoji, native_confirm, offbox_rename,
|
||||
docker_run_volume_path + the two new ones).
|
||||
|
||||
### v0.125.0 — .fab volume export/import: containerized path-strand data loss FIXED (IA finding 1, HIGH) (2026-07-13) — MinAgent: 0.81.0
|
||||
|
||||
|
||||
+20
-1
@@ -7,7 +7,26 @@
|
||||
>
|
||||
> Ask Claude Code: "Please update CONTEXT.md with what we did today"
|
||||
|
||||
Last updated: 2026-07-13 (v0.125.0 — .fab volume path-strand fix)
|
||||
Last updated: 2026-07-13 (v0.126.0 — UI uniformity bundle)
|
||||
|
||||
> **2026-07-13 — v0.126.0: UI UNIFORMITY BUNDLE (shared app-list rows + infra identity +
|
||||
> restore-form polish + mojibake gate + honest stale line). Presentation-layer only — NO
|
||||
> backup/toggle/engine behavior change. MinAgent 0.81 + floor unchanged.**
|
||||
> (A) `templates/app_row.html` `app_list_row`/`app_list_row_end` is THE canonical list row
|
||||
> (icon+name left, caller action right, compact 44px) — dashboard installed-apps, Távoli mentés
|
||||
> toggles, Visszaállítás restore-to-verify + .fab lists render through it; the backups-apps
|
||||
> expander header is ALIGNED (own markup, allowlisted); gate `scripts/app_row_dedup_gate.py`
|
||||
> (red-proven). funcmap: `dict`/`appHref`/`infraMeta`. (B) `inframeta.go`: cloudflared →
|
||||
> „Cloudflare Tunnel", traefik → „Traefik", filebrowser → „FileBrowser" + Hungarian descriptions
|
||||
> + generic `/static/infra-logo.svg` fallback; filebrowser = the ONLY Linked infra
|
||||
> (files.<domain>); render test counts exactly one customer link (red-proven). (C) .fab password
|
||||
> field standard („Opcionális jelszó" + helper; import-page input got `.form-input`).
|
||||
> (D) `scripts/mojibake_gate.py` — templates+Go strict UTF-8, zero Ã/Â/Ă-signature chars,
|
||||
> allowlist ZERO (red-proven); source had NO mojibake — the live „Tárhely" is the felhom-usb
|
||||
> drive-label DATA, repaired via the label-edit UI (live step). (E) `offboxWarningDisplay`
|
||||
> display pick — stale „nincs mentésre jelölt alkalmazás" run-warning → „A kijelölés módosult…"
|
||||
> note once ≥1 app toggled (neutral color); 0 toggled unchanged (red-proven).
|
||||
> Housekeeping: one-shot `backups_split_move_check.py` RETIRED (served its purpose).
|
||||
|
||||
> **2026-07-13 — v0.125.0: .FAB VOLUME PATH-STRAND DATA LOSS FIXED (IA finding 1, HIGH).
|
||||
> MinAgent 0.81 unchanged; floor may advance to 0.125.0 next train (must NOT halt above 0.124.0
|
||||
|
||||
@@ -207,10 +207,11 @@ Cross-repo edges:
|
||||
- **New REST endpoint**: path dispatch in `Router.ServeHTTP` (controller/internal/api/router.go); use `writeJSON` + `limitBody`.
|
||||
- **New background job**: `sched.Every`/`sched.Daily` registration block in controller/cmd/controller/main.go.
|
||||
- **New template function**: `Server.templateFuncMap` (controller/internal/web/funcmap.go) — obey v2 state-suffix vocabulary.
|
||||
- **New page/nav item**: `baseData` + sidebar in controller/internal/web/templates/ (nested sub-links pattern `.nav-links-nested`); must pass `controller/scripts/template_id_gate.py` + `controller/scripts/emoji_gate.py` + `controller/scripts/native_confirm_gate.py` + `controller/scripts/offbox_rename_gate.py`.
|
||||
- **New page/nav item**: `baseData` + sidebar in controller/internal/web/templates/ (nested sub-links pattern `.nav-links-nested`); must pass `controller/scripts/template_id_gate.py` + `controller/scripts/emoji_gate.py` + `controller/scripts/native_confirm_gate.py` + `controller/scripts/offbox_rename_gate.py` + `controller/scripts/app_row_dedup_gate.py` + `controller/scripts/mojibake_gate.py`.
|
||||
- **Docker volume tar streaming (v0.125.0)**: `appexport.dockerExec` (seam, package var) + `withVolumeHelper`/`exportVolumeTar`/`importVolumeTar` — stream volume content via `docker cp` through a stopped helper container. NEVER `docker run -v <controller-local path>` — the daemon resolves `-v` host-side and strands the data when the controller is containerized (the v0.124.0 HIGH finding); `controller/scripts/docker_run_volume_path_gate.py` enforces (every `"-v"` allowlisted with its WHY).
|
||||
- **Guarded file download (v0.124.0)**: `handler_export_download.go` — the canonical shape for streaming a server-side file to the browser: accept a BASENAME only (shape regexp + no separators/`..`), `filepath.Join` then assert `filepath.Dir(path) == dir`, `io.Copy` (never ReadAll), `Content-Disposition: attachment`, remove after a successful stream, TTL sweep (`sweepFabDownloads(dir, now, maxAge, logger)` — now injected for tests). Red-proof the guard by loosening to prefix-matching (the `..` case must fail).
|
||||
- **Backups sub-page data**: `backupsCommonData(page, title, r)` + `backupsOffboxData(data)` (handlers.go) — the ONLY builders for the four `/backups*` pages; a new backups section extends these, never re-derives in a page handler. (The one-shot v0.124.0 move gate `backups_split_move_check.py` was retired in v0.126.0.)
|
||||
- **App-list row (v0.126.0)**: `app_list_row`/`app_list_row_end` in `templates/app_row.html` is THE canonical list pattern — icon+name(+secondary) left, caller action block right; open with `dict "Slug" ... "Name" ...` (optional `Secondary`/`RowClass`/`Href`/`FallbackIcon`), close with `app_list_row_end`. Do NOT hand-roll app rows — `scripts/app_row_dedup_gate.py` enforces single-sourcing (the backups_apps expander header is the one allowlisted aligned copy). Infra display identity: `inframeta.go` map + `infraMeta` func (filebrowser is the only Linked stack).
|
||||
- **Consequential-action confirm (LIGHT)**: `felhomConfirm(el, question, onYes)` in layout.html (v0.123.0) — the trigger swaps in place to "kérdés + Igen/Mégse"; form buttons opt in with `data-confirm="…"` (delegated listener, `requestSubmit` keeps formaction/name-value). NEVER native `confirm()`/`prompt()` (OS-modals freeze browser automation — drill F-11; `native_confirm_gate.py` enforces). Heavy destructive flows keep the `.confirm-overlay` `openDialog` pattern.
|
||||
- **New hub event**: typed `Notify*` wrapper on Notifier + hub allowlist entry (cross-repo).
|
||||
- **New app integration**: `integrations.Manager.RegisterHandler` with `IntegrationKey(provider, target)`.
|
||||
|
||||
+13
-3
@@ -123,9 +123,19 @@ backups, monitoring and notifications. All Proxmox/disk operations are delegated
|
||||
(`felhomConfirm` in layout.html, v0.123.0: the trigger swaps in place to "kérdés + Igen/Mégse";
|
||||
form buttons opt in via `data-confirm="…"`) — never native `confirm()`/`prompt()` (OS-modals
|
||||
freeze browser automation; drill F-11).
|
||||
**Shared app-list row (v0.126.0):** `templates/app_row.html` (`app_list_row`/`app_list_row_end`)
|
||||
is the ONE row grammar for app lists — icon + name (+ optional secondary line) left, caller
|
||||
action block right; used by the dashboard installed-apps list, the Távoli mentés toggle list
|
||||
and the Visszaállítás restore-to-verify/.fab lists; the backups-apps expander header is
|
||||
ALIGNED to the same grammar (own markup — it carries the toggle). Protected infra stacks
|
||||
(traefik/cloudflared/filebrowser) get curated Hungarian display identity from the
|
||||
`inframeta.go` map (name + description + generic `/static/infra-logo.svg` fallback icon);
|
||||
filebrowser is the only infra stack with a customer link (`files.<domain>`).
|
||||
**Enforcement:** `scripts/template_id_gate.py` (JS element-ID integrity) + `scripts/emoji_gate.py`
|
||||
(no emoji) + `scripts/native_confirm_gate.py` (zero native confirm/prompt) — run after any
|
||||
template change; the Go `TestNoEmojiInTemplates` mirrors the emoji gate.
|
||||
(no emoji) + `scripts/native_confirm_gate.py` (zero native confirm/prompt) +
|
||||
`scripts/app_row_dedup_gate.py` (row markup single-sourced) + `scripts/mojibake_gate.py`
|
||||
(no double-encoded UTF-8 in templates/Go sources) — run after any template change; the Go
|
||||
`TestNoEmojiInTemplates` mirrors the emoji gate.
|
||||
- **Europe/Budapest timezone** — All scheduled jobs, timestamps, and UI labels use Hungarian timezone.
|
||||
|
||||
### Module Map
|
||||
@@ -361,7 +371,7 @@ self-sufficient backup** — any single tier can fully restore an app.
|
||||
| Route | Page | Sections |
|
||||
|-------|------|----------|
|
||||
| `/backups` | Áttekintés | storage overview, whole-guest Rendszermentés, status stat cards, single-copy warning |
|
||||
| `/backups/remote` | Távoli mentés | Felhom-offsite status card (3 states, display-only), tier-3 status block + quota, participation toggles (+ zero-toggle hint), manual-target form (`#offbox-section`) |
|
||||
| `/backups/remote` | Távoli mentés | Felhom-offsite status card (3 states, display-only), tier-3 status block + quota, participation toggles (+ zero-toggle hint; the persisted zero-toggle run-warning is DISPLAY-replaced by a "kijelölés módosult" note once ≥1 app is toggled — `offboxWarningDisplay`, v0.126.0), manual-target form (`#offbox-section`) |
|
||||
| `/backups/apps` | Alkalmazások | schedule, Adatbázisok table, per-app 1./2./3. tier rows (tier-2 config entry; tier-3 actions deep-link to `/backups/remote#offbox-section`) |
|
||||
| `/backups/restore` | Visszaállítás | restore panel, offbox restore-to-verify list, .fab download/import loop |
|
||||
|
||||
|
||||
Reference in New Issue
Block a user