Files
Dash/ROADMAP.md
T
Tomas Dvorak 55fb57456e feat: phase 3 renderers & ergonomics — index/console, ⌘K palette, icon suggest
- Index renderer (editorial): serif masthead + section heads, numbered
  full-width rows, live stat strip (time/services/up/down/widgets)
- Console renderer (terminal): $ dash status banner, bordered stat panels,
  ## section heads, › prompt rows, [ up ]/[ down ] tags
- Renderer contract gains index prop for row/section numbering
- Settings: 2x2 renderer radio grid with per-renderer descriptions
- ⌘K/Ctrl+K// palette: actions + service endpoints, arrow-key nav,
  zero-dep implementation on the existing Dialog primitive
- Icon picker: dashboard-icons slug suggestion chip + live preview
- Fonts: Instrument Serif, JetBrains Mono (fontsource)
- Fix: global :focus-visible rule was unlayered and silently overrode all
  focus-visible: utilities since phase 1 — moved into @layer base

Verified: typecheck/lint/build clean, dnd + collapse + popover in both new
renderers, palette filter + execute, icon suggest resolves real CDN assets,
360px + light theme, docker image 43.9 MB serving board + widget types.

Generated with [Devin](https://devin.ai)

Authored By: TDvorak <[email protected]>
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 20:29:22 +02:00

128 lines
7.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Dash — Roadmap
A self-hosted homelab dashboard. CasaOS-grade ease of use, Vercel-grade design.
Single container, UI-managed, no YAML, no auth required.
Stack: **Go + Gin + SQLite** (single static binary, embeds frontend) · **React 18 + Vite + TS strict + Tailwind + shadcn/ui + dnd-kit** · OpenAPI-generated client.
---
## Design system
Multiple board styles are a core feature: same system, same functionality,
different UI structure per style. A **renderer** supplies the layout; board
state, drag-drop, popovers, and dialogs are shared primitives underneath.
| Renderer | Source mockup | Ships |
|---|---|---|
| Bento (default) | `d-bento-mono.html` | v0.1.0 — mixed-size grid, widgets inline |
| Cards | `a-vercel-mono.html` | v0.1.0 — uniform compact grid; validates the seam early |
| Index | `e-editorial.html` | v0.3.0 — serif headers, list rows, stat strip |
| Console | `f-console.html` | v0.3.0 — terminal panels, `[ up ]` tags |
Contract: `renderers/<name>/{BoardView, SectionView, ItemView, WidgetView}`.
Tokens (`--bg`, `--surface`, `--border`, …) shared; dark/light is orthogonal.
User picks renderer in settings; persisted. Renderers never reimplement dnd
or popover logic.
---
## Releases
| Version | Contents | Gate |
|---|---|---|
| `v0.1.0` | Phase 0 + 1 — working MVP, single image | manual smoke test |
| `v0.2.0` | Phase 2 — widget layer + first integrations | Pi-hole widget live |
| `v0.3.0` | Phase 3 — alternate themes, search, icon packs | theme switcher works |
| `v1.0.0` | Phase 4 — OSS polish, docs, importers, CI releases | public repo launch |
| `v1.x` | Phase 5 — demand-driven extras only | per-feature |
---
## Phase 0 — Foundation → part of v0.1.0 ✅ done 2026-09-17
Repo hygiene and pipelines before features.
- [x] Monorepo scaffold (`apps/frontend`, `apps/backend`, `packages/api-client`, `infra/`, `data/`)
- [x] MIT `LICENSE`, `README.md`, `.gitignore`, `AGENTS.md`
- [x] `openapi.yaml` stub → generated TS client (`packages/api-client`)
- [x] Backend skeleton: Gin router, `zap` logging, `/api/healthz`, SQLite open + goose migrations runner
- [x] Frontend skeleton: Vite + TS strict + Tailwind + shadcn/ui, theme tokens matching `d-bento-mono.html` CSS vars
- [x] CI (GitHub Actions): `go build ./...`, `go vet ./...`, `go test ./...`, `tsc --noEmit`, `oxlint` + vendored anti-slop rules, `npm run build`
- [x] Multi-stage `Dockerfile` (frontend build → Go build → distroless, `embed.FS` serves UI)
- [x] `docker-compose.yml` — one service, `./data:/data` volume
**Exit:** `docker compose up` serves a blank board — verified locally (33.6 MB image). CI green on `main` — pending first push.
## Phase 1 — MVP → v0.1.0 ✅ done 2026-09-17
The product's spine: sections, services, drag-drop, multi-URL.
- [x] Schema: `sections`, `items`, `urls`, `settings` (fractional `position REAL` ordering)
- [x] REST API: CRUD for sections/items/urls, `reorder` endpoints, icon upload, `settings`, `export`/`import` JSON
- [x] Renderer contract: shared board store + `BoardView`/`SectionView`/`ItemView`/`WidgetView` seam, dnd + popover as shared primitives
- [x] **Bento** renderer (default): mixed-size grid, hairline section headers, tiles with status chips
- [x] **Cards** renderer: uniform compact grid — second renderer proves the seam while code is small
- [x] dnd-kit: reorder items in a section, move items between sections, reorder sections; persist on drop
- [x] Collapse/expand sections (persisted)
- [x] `UrlPopover`: 1 URL → direct open, 2+ → chooser (`local`/`external`/custom tags)
- [x] `AddServiceDialog` / `EditServiceDialog` (name, URLs+labels, icon URL or file upload)
- [x] Icon handling: upload to `data/icons/`, remote URL passthrough, letter-tile fallback
- [x] Dark/light toggle (persisted), renderer picker in settings, responsive to ~360px
- [x] Status ping: server-side HEAD request per service URL, cached ~60s → `up`/`down` chip
**Exit:** create sections, add services with icons and dual URLs, drag everything, reload — state persists. `docker run` single image works. Export/import round-trips. — verified: full API + browser smoke (dnd, popover, upload, collapse, themes, both renderers, 360px), `api_test.go` covers reorder/URL-validation/settings.
## Phase 2 — Widgets → v0.2.0 ✅ done 2026-09-17
- [x] Go widget registry: `Widget` interface (`Type()`, `Fetch(cfg)`), `GET /api/widgets/:id/data` with ~30s in-process TTL cache
- [x] `GET /api/widgets/types` → registry metadata drives the add-widget dialog
- [x] `WidgetHost` component: maps `config.type` → React component, polls with backoff
- [x] Widgets as grid items (same `items` table, `kind = 'widget'`, `config JSON`)
- [x] Clock/timezone widget (frontend-only)
- [x] Pi-hole fetcher (blocked %, queries today) — per-day bar series deferred: v5 `api.php` lacks it, needs Pi-hole v6 `/api/history`
- [x] AdGuard Home fetcher (blocked %, queries, avg processing ms)
- [x] Immich fetcher (photo/video count, library size)
- [x] Per-widget config UI (endpoint URL, API key — stored in `config`, never logged)
**Exit:** Pi-hole widget shows real data; adding a new integration = one Go file + one React component. — verified: registry, cache, 502 path, generic config dialog, clock live in-browser, Pi-hole fetcher against stubbed v5 API.
## Phase 3 — Renderers & ergonomics → v0.3.0 ✅ done 2026-09-17
- [x] **Index** renderer: serif section headers, full-width rows, masthead stat strip
- [x] **Console** renderer: bordered panels/tables, JetBrains Mono, `[ up ]` tags
- [x] Renderer switcher polished (2×2 radio grid with per-renderer descriptions)
- [x] ⌘K command palette: jump to service, add service, toggle theme, switch renderer (⌘K / Ctrl+K / `/`)
- [x] dashboard-icons auto-suggest in icon picker (name → slug → CDN URL chip + live preview)
- [ ] User services list → prioritized widget backlog (owner-supplied list pending)
**Exit:** all four renderers work off the same board state; palette navigates everything. — verified: both new renderers render/persist/dnd/collapse, palette filters and executes, icon suggest resolves real CDN assets, 360px + light theme.
## Phase 4 — Open-source launch → v1.0.0
- [ ] Docs: install, configuration, widget development guide (`docs/`)
- [ ] Importers: Homepage `services.yml`, Homarr JSON, Dashy `conf.yml` → sections/items/urls
- [ ] `README.md` hero: screenshots (4 themes), demo GIF, `docker run` one-liner
- [ ] goreleaser → binaries; GHCR image on tag; semver + `CHANGELOG.md`
- [ ] `CONTRIBUTING.md`, issue/PR templates, code of conduct, security policy
- [ ] i18n scaffolding (en default)
- [ ] Public repo flip + announcement assets
**Exit:** a stranger can `docker run`, import their Homepage config, and have a working board in under two minutes.
## Phase 5 — Post-1.0 (demand-driven only)
Build only what users actually ask for. Candidates, unordered:
- Optional auth (local password + OIDC) — most-requested, likely first
- Health-check history + uptime graphs
- Custom CSS / accent color / wallpaper
- Iframe/embed widgets, API-status widgets (generic JSON path)
- PWA install, mobile layout polish
- Multiple boards
## Non-goals (v1)
Auth, Postgres/external DB, multi-user, mobile app, container lifecycle
management, YAML-as-source-of-truth. Revisit only with evidence of demand.