Skip to content

Web prototype#1457

Draft
troglobit wants to merge 19 commits intomainfrom
web
Draft

Web prototype#1457
troglobit wants to merge 19 commits intomainfrom
web

Conversation

@troglobit
Copy link
Copy Markdown
Contributor

@troglobit troglobit commented Mar 29, 2026

Description

In progress ... based on kernelkit/webui2 by @mattiaswal

web

Checklist

Tick relevant boxes, this PR is-a or has-a:

  • Bugfix
    • Regression tests
    • ChangeLog updates (for next release)
  • Feature
    • YANG model change => revision updated?
    • Regression tests added?
    • ChangeLog updates (for next release)
    • Documentation added?
  • Test changes
    • Checked in changed Readme.adoc (make test-spec)
    • Added new test to group Readme.adoc and yaml file
  • Code style update (formatting, renaming)
  • Refactoring (please detail in commit messages)
  • Build related changes
  • Documentation content changes
    • ChangeLog updated (for major changes)
  • Other (please describe):

Initial import of https://github.com/kernelkit/webui2 @ e344d3f

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Replace flat nav-section-header labels with collapsible <details>/<summary>
accordion groups (Network, Wireless, VPN, Services, System). Groups default
open; user state persists via localStorage. Tablet icon-only mode always
shows all items regardless of open/closed state.

Add badge-up/down/warning/info/neutral utility classes with full dark mode
support, complementing the existing firewall-specific badge variants.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Anonymise the login page: generic "Login" title, lock icon instead
of product logo — makes the device harder to fingerprint.

Add a floating theme toggle button to the login page so users can
switch theme before logging in (cycles auto→light→dark).

Replace the four cluttered sidebar footer buttons (theme, download
config, reboot, logout) with an always-visible topbar user menu.
The dropdown shows the username, three theme options with a checkmark
on the active one, download config, reboot, and logout.

Refactor all handler page-data structs to embed PageData instead of
repeating the four base fields, and add Username (sourced from the
request context) so the topbar can display the logged-in user.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Drop the useless 768–1024px icon-only sidebar mode; everything up to
1024px now uses the hamburger overlay and full-width sidebar.

Fix the user dropdown on touch devices: click now toggles aria-expanded
so CSS-driven visibility works without hover.  A document click listener
closes the menu when tapping outside.

Give the sidebar proper light/dark tokens instead of hardcoded dark
values. Introduce --sidebar-hover-fg (primary in light, white in dark)
so nav-link hover text is legible in both themes.

Fix dropdown hover background using --border instead of --border-subtle,
which had zero contrast against the surface in dark mode.

Keep active nav link in sync with the current URL via JS so it updates
correctly after htmx navigation instead of staying on the initial
server-rendered page.  Also, add YouTube-style progress when laoding
pages that take time, e.g., Dashboard.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Replace the RAUC-centric firmware page with a cleaner layout:

- Show software slots (primary/secondary) using their bootnames rather
  than internal RAUC slot names; filter to rootfs-class slots only
- Add boot order display (mirrors `show software` in the CLI)
- Show installed timestamp per slot (truncated to second precision)
- Fix Booted flag comparison: compare against bootname not slot name
- Lay out all three cards (Software, Install from URL, Upload & Install)
  in a responsive grid instead of full-width stacked sections

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Split the old monolithic Hardware card into dedicated Board, WiFi, and
Sensors cards, matching the structure of `show system` / `show hardware`
in the CLI:

- System Information: add Current Time row, rename Firmware → Boot Partition
- Board: model, manufacturer, Base MAC only (no sensors)
- WiFi (new, conditional): all radios with supported bands, standards
  (11n/11ac/11ax), and max AP count; card spans 2 grid columns so the
  table never needs horizontal scroll
- Sensors (new, conditional, collapsible): all hardware sensors grouped
  by parent component (SFP sub-sensors indent under sfp1/sfp2 headings);
  JS "Show more" button injected only when content overflows 300 px
- Disk Usage: replaced wide multi-column table with a per-mount widget
  (path + % on one line, health bar, "X free of Y" below); health colour
  follows the same warn/crit thresholds as the memory bar
- Fix humanKiB to output IEC units (MiB / GiB) with a space, matching
  the memory display style
- Fix info-table th wrapping (width:1%; white-space:nowrap)
- Fix JS collapsible init to run on DOMContentLoaded, not immediately in
  <head>, so scrollHeight check has a real DOM to inspect
- CSS scroll-shadow on data-table-wrap: pure-CSS right-edge shadow
  indicates overflow without needing JS or a scroll listener
- Equal-height grid rows via align-items:stretch; info-grid-span-2 for
  cards with wide tables

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Expandable detail row per key.  Clicking the ▶ arrow left of the name
unfolds a full-width row showing labeled key fields (Value / Public Key
/ Private Key) as word-wrapped monospace blocks (max-width: 72ch),
making base64 data easy to read and copy.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Display interfaces in a hierarchical tree: bridge and LAG parent rows
show a ▼ toggle in the tree column that collapses/expands their member
ports. The vertical connector line disappears when collapsed. Member
ports within each group are sorted alphabetically; loopback interfaces
always appear first, the rest alphabetically.

A ⚑ forwarding-flag column indicates which interfaces have IP
forwarding enabled, fetched concurrently from ietf-routing:routing.

The "Address" and "Detail" columns are replaced by a single "Data"
column matching the CLI layout: IP addresses, VLAN id, WiFi SSID/mode,
WireGuard peer count, etc. Table rows are top-aligned so interfaces
with multiple addresses don't cause odd vertical centering on other
cells; the two narrow icon columns (⚑ and tree) stay middle-aligned.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Add a zone-to-zone traffic matrix matching the CLI's traffic_flow logic:
- HOST row/column always present; zone→HOST uses zone action + services
  (not policies), producing allow/conditional/deny verdicts correctly
- Clicking a matrix cell shows a detail panel with the policy or zone
  reason for the verdict
- Conditional (⚠) detection for zones with services or port-forwarding

Enrich the policy and zone tables:
- Immutable (built-in) policies flagged with ⚷ in column header and row
- Policy rows show description as tooltip; sorted by priority
- Zones table renamed "Host Services" column; Policies drops Priority column
- Wide tables (Zones, Policies) span two grid columns like Dashboard WiFi

Fix the info-grid layout: #content lacked width:100% so margin:0 auto
was overriding flex stretch, collapsing the grid to a single column on
both the firewall and dashboard pages.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Shows NACM settings, a read/write/exec permission matrix per group
(✓ full / ⚠ restricted / ✗ denied), and users/groups tables.

Permission analysis mirrors cli_pretty._analyze_group_permissions:
permit-all rule bypasses global defaults and grants full access,
explicit deny rules reduce write/exec, and global deny rules
(group="*") are surfaced as restrictions on non-admin groups.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The contact and location leaves were absent from the operational
datastore.  Fetch each leaf from the running ds tool and inject
into ietf-system:system.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Group nav items by purpose:
- Security: Firewall, WireGuard, NACM
- Services: Services, DHCP, NTP, LLDP, mDNS (moved from Network)
- Network trimmed to: Interfaces, Routing, WiFi

Rename Dashboard → Overview for clearer Status > System > Overview
navigation hierarchy.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Implements the configure accordion section with a candidate datastore
workflow: opening Configure copies running → candidate (Enter), each
card saves directly to candidate, Apply copies candidate → running
atomically, and Abort discards by resetting candidate from running.

- RESTCONF client: add Put, Patch, Delete, GetDatastore, PutDatastore,
  CopyDatastore, and a shared doRequest/writeJSON helper
- Handlers: ConfigureHandler (enter/apply/abort), ConfigureSystemHandler
  (hostname, clock, NTP, DNS, motd, editor), ConfigureUsersHandler
  (add/delete user, shell, password, SSH keys)
- Sticky Apply/Abort toolbar with custom confirm dialog; server returns
  HX-Redirect:/ so HTMX does a full-page reload, keeping sidebar in sync
- Accordion persistence fixed: Configure excluded from localStorage so it
  never auto-reopens after Abort/Apply; restore no longer closes an
  accordion that contains the active page
- Password hashing by shelling out to mkpasswd(1)

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Replace browser-side HTMX polling with a Go SSE endpoint that polls
RESTCONF internally and streams rendered HTML fragments.  This fixes
the "Could not fetch firmware status" crash that occurred when the
RESTCONF server timed out during an upgrade.

- GET /firmware/progress: streams fw-progress-body fragments as SSE;
  events: progress (update), done (success/failure), reboot (auto-reboot)
- Go server polls every second with change detection to suppress
  redundant frames; RESTCONF timeouts leave Installer nil so the
  template renders "Installing..." without crashing
- Auto-reboot checkbox: triggers a reboot after successful install;
  JS handles the reboot SSE event and shows the reboot overlay
- URL history datalist: remembers the last 10 firmware URLs in
  localStorage and offers them as autocomplete suggestions
- Install complete / failed: persistent card replaces the progress
  bar with a green check or red X; includes Reboot to activate button
  when auto-reboot was not selected
- Reboot overlay: simplify to a fixed 4 s initial grace period before
  polling (avoids fast-reboot race where sawDown was never set);
  5 s DeviceStatus timeout keeps polls snappy; window.location.replace
  avoids stale firmware history entries
- Server-side guard: clears Installing flag when installer is already
  Done so navigating back to /firmware?installing=1 after a reboot
  does not re-open the SSE card or trigger a second reboot
- color-scheme: light/dark on .light/.dark fixes native checkbox
  rendering in forced-theme mode

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Copies candidate → running then running → startup in one step, so
users can commit changes to the running configuration and persist
them across reboots without two separate button clicks.

The existing Apply button confirm text is updated to remind the
user that changes will be lost on reboot unless saved.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant