wifi-densepose/frontend
ruv e7215a16e5 feat(homecore-ui iter 1): Modal + EntityForm + Add Entity flow
First CRUD increment. Click "+ Add entity" on the Dashboard
toolbar → modal opens → form with entity_id / state / attributes
fields → Create validates client-side then POSTs /api/states/<id>
→ modal closes, toast confirms, dashboard refreshes.

New components:
  frontend/src/components/Modal.ts (~110 LOC) — reusable accessible
    overlay. open property; closes on Escape and backdrop click.
    Heading prop; default + footer slots.

  frontend/src/components/EntityForm.ts (~130 LOC) — three-field form
    with public requestSubmit()/requestCancel() methods. Client-side
    validation:
      - entity_id matches /^[a-z][a-z0-9_]*\.[a-z][a-z0-9_]*$/
      - state non-empty
      - attributes parses as a JSON object (rejects array/scalar)
    Emits hc-entity-submit / hc-entity-cancel events for host to
    handle. Footer buttons live in the host (modal slot=footer).

  frontend/src/pages/Dashboard.ts (+60 LOC) — toolbar with
    "+ Add entity" button, modal state, POST handler that wraps
    fetch with bearer token, success toast (3 s), refresh().

Browser-verified end-to-end (real homecore-server :8123):
  - Toolbar button visible: Y
  - Modal opens: Y
  - 3/3 validation paths fire correctly:
      BadID → "entity_id must match domain.snake_case"
      blank state → "state must not be empty"
      [1,2,3] attrs → "attributes must be a JSON object"
  - Successful create: light.test_bulb POSTed; modal closes; toast
    "Created light.test_bulb = on"; grid count went 10 → 11
  - Persistence: hard reload, count stays
  - 0 console errors (Lit dev-mode notices excluded)

Note: TypeScript caught a name collision — `attributes` is reserved
on HTMLElement (NamedNodeMap). Renamed the Lit @property to
`entityAttrs` so the class extends LitElement cleanly.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-05-26 14:33:01 -04:00
..
src feat(homecore-ui iter 1): Modal + EntityForm + Add Entity flow 2026-05-26 14:33:01 -04:00
.gitignore HOMECORE: native Rust/WASM/TS port of Home Assistant — ADRs 125-134 implementation (#800) 2026-05-25 22:47:48 -04:00
README.md HOMECORE: native Rust/WASM/TS port of Home Assistant — ADRs 125-134 implementation (#800) 2026-05-25 22:47:48 -04:00
index.html HOMECORE: native Rust/WASM/TS port of Home Assistant — ADRs 125-134 implementation (#800) 2026-05-25 22:47:48 -04:00
package-lock.json HOMECORE: native Rust/WASM/TS port of Home Assistant — ADRs 125-134 implementation (#800) 2026-05-25 22:47:48 -04:00
package.json HOMECORE: native Rust/WASM/TS port of Home Assistant — ADRs 125-134 implementation (#800) 2026-05-25 22:47:48 -04:00
tsconfig.json HOMECORE: native Rust/WASM/TS port of Home Assistant — ADRs 125-134 implementation (#800) 2026-05-25 22:47:48 -04:00
vite.config.ts HOMECORE: native Rust/WASM/TS port of Home Assistant — ADRs 125-134 implementation (#800) 2026-05-25 22:47:48 -04:00
vitest.config.ts HOMECORE: native Rust/WASM/TS port of Home Assistant — ADRs 125-134 implementation (#800) 2026-05-25 22:47:48 -04:00

README.md

@ruvnet/homecore-frontend

HOMECORE web UI — built with Lit 3, TypeScript, and Vite. Design system mirrors the cognitum-v0 / v0-appliance dashboard (ADR-131).

Quick start

cd frontend
npm install
npm run dev          # http://localhost:5173

The Vite dev server proxies /apihttp://localhost:8123, so you need a homecore-api-server (or the wifi-densepose-sensing-server crate) running on :8123.

Scripts

Script Description
npm run dev Start Vite dev server on port 5173
npm run build TypeScript compile + Vite production bundle → dist/
npm run lint ESLint on src/
npm test Vitest unit tests (3 suites, jsdom)

Package layout

frontend/
  src/
    api/
      client.ts        # fetch + WebSocket client (REST + WS)
      types.ts         # TypeScript types matching homecore-api JSON shapes
    components/
      AppShell.ts      # <hc-app-shell> — header + nav + content slot
      StateCard.ts     # <hc-state-card> — single entity state card
    icons/
      lucide.ts        # Tree-shaken Lucide icon wrapper
    styles/
      tokens.css       # 16 CSS custom properties (--hc-*)
      base.css         # Typography reset, page shell, nav layout
    __tests__/         # Vitest unit tests
  index.html           # Shell loading src/main.ts
  vite.config.ts
  tsconfig.json
  vitest.config.ts

Design system

Colors, typography, and components mirror the cognitum-v0 dashboard (http://cognitum-v0:9000/). Dark-only; no light-mode. Key tokens:

  • --hc-primary #19d4e5 — teal (active nav, focus ring, CTA borders)
  • --hc-accent #26d867 — green (success, secondary CTA)
  • --hc-bg #0b0e13 — near-black navy page root
  • Font: Outfit (display) + JetBrains Mono (mono)
  • Icons: Lucide (SVG, stroke: currentColor, no icon font)

See docs/design/HOMECORE-FRONTEND-design-recon.md for the full recon.

Architecture notes

  • Components are standard Lit LitElement custom elements — compatible with any HTML page and with Home Assistant's Lit-based frontend.
  • The REST client uses fetch; the WS client uses WebSocket. Both accept a bearer token and are fully typed against the Rust homecore-api JSON shapes.
  • WASM: vite.config.ts enables .wasm asset import. Hook up via dynamic import('/path/to/module.wasm?init') when WASM bindings are ready.