From bd2f5293947bdd45b2dfd375b8f82e90e561c6c7 Mon Sep 17 00:00:00 2001 From: bogdanpydev Date: Thu, 9 Jul 2026 12:43:05 +0300 Subject: [PATCH] feat(web-ui): restructure Home + Settings onto the Oatmeal composition Bring the signed-in Home and Settings surfaces onto the theme's composition, finishing the rollout #261 deferred. Two signature moves applied uniformly: section titles move from the tiny uppercase-muted

labels to the shared Instrument Serif display idiom, and every olive-50 (bg-card) panel moves from the compact rounded-xl px-4 py-3 to the calmer rounded-2xl p-5 (the auth cards' radius + cloud spacing). Activity, the one section without an in-page heading, gains a serif "Activity" title. Pure composition pass: no behavior, IA, or routing change; no literal bg-olive-*, no raw hex. Home launcher grids stay open (the tiles are already olive-50 cards); the pill Button/input element-idiom is deferred as a follow-up. make check-web green. Closes #290 --- docs/progress/README.md | 1 + .../oatmeal-home-settings-composition.md | 41 +++++++++++++++++++ web-ui/src/views/HomeView.vue | 15 +++---- web-ui/src/views/settings/AboutSection.vue | 7 ++-- web-ui/src/views/settings/AccountSection.vue | 7 ++-- web-ui/src/views/settings/ActivitySection.vue | 12 +++--- .../settings/InstalledAppDetailSection.vue | 23 ++++++----- .../views/settings/InstalledAppsSection.vue | 7 ++-- .../views/settings/NotificationsSection.vue | 7 ++-- .../views/settings/OutgoingEmailSection.vue | 13 +++--- web-ui/src/views/settings/SettingsLayout.vue | 2 +- web-ui/src/views/settings/UsersSection.vue | 13 +++--- 12 files changed, 100 insertions(+), 48 deletions(-) create mode 100644 docs/progress/oatmeal-home-settings-composition.md diff --git a/docs/progress/README.md b/docs/progress/README.md index 46aa7de2..37145a9e 100644 --- a/docs/progress/README.md +++ b/docs/progress/README.md @@ -203,3 +203,4 @@ Oldest first; append new entries to the bottom. | [hosted-grow-root-disk.md](hosted-grow-root-disk.md) — Grow the hosted image's root filesystem to fill the whole provider disk on boot. The image bakes a fixed **8 GiB** root (sparse raw stays small) but nothing grew it onto the far larger provider disk, so a box ran on ~8 GiB — docker image storage + the brain's SQLite store share that one volume, so a single app install can fill it and the brain's first store write 500s login (the box looks offline though it is up). **Fix:** a runtime `repart.d` definition (`Type=root`, `GrowFileSystem=yes`, no size cap) + a `malmo-grow-root.service` oneshot running `systemd-repart --dry-run=no`, ordered `Before=docker.service host-agent.service` and **fail-closed** (`Requires=` from both, via a docker drop-in and host-agent's unit) so the write-heavy services refuse to start on an un-grown root. Build-time root stays pinned at 8 GiB; the two repart definitions are deliberately separate. Lean set gains `systemd-repart` + `libfdisk1` only (no `libcryptsetup`, cryptsetup cut preserved). Boot-proof asserts the tool is present and the unit reached `active`; real full-disk growth is a provider-box acceptance step. **Known:** the stock `systemd-repart.service` also runs the same config (harmless double execution — idempotent; consolidation deferred pending a live re-test), and a pre-existing unrelated `/setup` 503 boot-proof failure reproduces on clean `main`, tracked separately | done | | [hosted-setup-boot-proof-race.md](hosted-setup-boot-proof-race.md) — Close the `/setup` 503 boot-proof failure [hosted-grow-root-disk.md](hosted-grow-root-disk.md) tracked separately, and confirm the wildcard-TLS/`:443` path is green. The `unseeded` boot polled `POST /api/v1/setup` for **403** but broke on any of `403\|503\|409\|200`, so a transient **503** — Caddy answering "no ready `/api` upstream" in the first second after the control-plane stack comes up, before the brain's listener + dashboard route land — ended the loop and failed the proof, though the box is correct (the brain returns 403 unconditionally on hosted, no 503 path; the diag showed all four containers "Up <1–2 seconds"). **Fix:** break only on a definitive `403\|409\|200` and ride through `502\|503`, exactly as the `/api/v1/me` poll above already does; a genuinely stuck `/setup` still fails after the 30s window. The louder "`:443` never binds" symptom was a **broken-build artifact, not a live regression**: the build-and-boot CI job (`CI / Cloud image`, `publish=false`) passed both the `unseeded` and `seeded` boots (`seeded` hard-asserts `:443` bound + `caddy: wildcard TLS configured`), and every known real-box root cause (`certificates.automate` #301, seed-fetch keep-alive, static resolver) is already fixed in-tree — so no product change. Adds `docs/dev/hosted-boot-proof.md` (runbook: happy-path flow, brain-log milestones, symptom→where-to-look, how to run) and de-stales `TESTING.md`'s `/setup` gate description (the as-built SSO/403, superseding the secret 401/200). Test-lane + docs only | done | | [hosted-grow-root-fs.md](hosted-grow-root-fs.md) — Corrects [hosted-grow-root-disk.md](hosted-grow-root-disk.md)'s "verified on a real provider box" claim. A live acceptance run found the root **partition** grew to the full disk (`systemd-repart` extended it, GPT `GROWFS` bit set) but the **ext4 filesystem inside it stayed at the original 8 GiB** — the disk-full/500 failure mode was not actually closed. Found via the same **Hetzner rescue mode** technique as `hosted-wildcard-cert-automate.md`: booting the (still-running) probe box into rescue and reading its disk + persistent journal directly. **Root cause:** `GrowFileSystem=yes` only sets the GPT `GROWFS` attribute bit; actually growing the mounted root filesystem is normally `systemd-growfs-root.service`'s job, which `systemd-gpt-auto-generator` wires up only when booted with `root=gpt-auto` — Hetzner (and cloud providers generally) boot with an explicit `root=PARTUUID=...` instead, so that generator, and the growfs service, never ran; zero mention of `growfs` anywhere in the boot journal. The existing boot-proof assertion couldn't have caught this: on the QEMU disk (fixed-size, no spare space) growing the filesystem is a no-op regardless of whether the growfs step runs. **Fix:** `malmo-grow-root.service`'s `ExecStart` now calls `systemd-growfs /` (the exact call the generator-driven service would have made) after `systemd-repart`, in the same command rather than a separate `ExecStartPost` — a review catch found `ExecStartPost` runs even on `systemd-repart`'s accepted 76/77 "nothing to grow" exits and has no visibility into which code fired, so it would fail the fail-closed unit on those harmless cases; the merged step only calls `growfs` when `systemd-repart` exits 0 and passes 76/77 through as success. `cloud-assertions.sh` also checks `systemd-growfs` is present in the lean image, and its pass message no longer claims real growth is verified by this lane. **Live acceptance:** re-provisioned onto a real box with the fix; root volume reported 79.99 GB total / 78.21 GB free (was 8.35 GB pre-fix) — filesystem grow confirmed on real hardware. `ENVIRONMENT.md` # Storage corrected to describe the grow as the two explicit steps it actually is | done | +| [oatmeal-home-settings-composition.md](oatmeal-home-settings-composition.md) — Restructure the signed-in **Home + Settings** surfaces onto the Oatmeal composition (**closes #290**, finishes the rollout #261 deferred). Two signature moves applied uniformly: every section title moves from the tiny uppercase-muted `

` label to the shared `components/ui/Heading.vue` **Instrument Serif** display heading (top-level titles `:level=2`; app-detail sub-sections `:level=3`; the app-detail page title drops its bespoke `

` onto ``), and every olive-50 (`bg-card`) panel/row/table container moves from the compact `rounded-xl … px-4 py-3` to the calmer `rounded-2xl … p-5` (the auth cards' radius + cloud spacing). Covers `HomeView` (System health/Household/Yours) + all Settings sections (Account, Notifications, About, Users, Outgoing email, Installed apps, installed-app **detail**) + the desktop nav panel; **Activity** — the only section with no in-page heading — gains a serif "Activity" title. Pure composition: no behavior/IA/routing change, no literal `bg-olive-*`, no raw hex. **Two documented judgement calls**: (1) the Home launcher grids are left **open** (tiles are already olive-50 cards — wrapping them in an olive-50 panel washes their contrast and fights `DASHBOARD.md`'s calm-launcher north star), and (2) the pill `