feat(widgets): dashboard loop, widget config UI, and addon pages
PR 4 of 4 for configurable dashboard widgets. - Replace hard-coded Jellyfin/Backups dashboard sections with a loop that renders enabled widget instances by sort_order. - Add WidgetInstance renderer and WidgetConfigDialog for adding, editing, enabling/disabling, deleting, and reordering widgets. - Add addon pages for grafana, prometheus, and ssh-tasks at /addons/:addonId. - Register /addons/:addonId route in App.tsx. - Update docs/REQUIREMENTS.md with the widget system design and API. Verification: - backend ruff clean; pytest 200 passed - frontend npm run lint: 0 errors - frontend npm run build: success - frontend npm run test -- src/widgets/registry.test.ts: 3 passed
This commit is contained in:
@@ -141,9 +141,55 @@ npm run test -- src/widgets/registry.test.ts # 3 passed
|
||||
- Registry unit test is colocated at `frontend/src/widgets/registry.test.ts` and runs with Vitest, matching the project's existing `npm run test` setup, instead of `frontend/tests/widgets.test.mjs`.
|
||||
- `JellyfinWidget` uses `SessionActivityPanel` directly because `NowPlaying` does not expose an `emptyMessage` prop.
|
||||
|
||||
## Completed tasks (Slice 4)
|
||||
|
||||
All Slice 4 tasks are marked `- [x]` in `tasks.md`:
|
||||
|
||||
- [x] 4.1 Refactor `Dashboard.tsx` to render enabled widget instances in sort order
|
||||
- [x] 4.2 Create `WidgetInstance` renderer component
|
||||
- [x] 4.3 Create `WidgetConfigDialog` for add/edit/reorder/delete widgets
|
||||
- [x] 4.4 Create addon pages (`AddonPage`, `GrafanaAddonPage`, `PrometheusAddonPage`, `SshTasksAddonPage`)
|
||||
- [x] 4.5 Register `/addons/:addonId` route in `App.tsx`
|
||||
- [x] 4.6 Update `docs/REQUIREMENTS.md` with widget system documentation
|
||||
|
||||
## Files changed (Slice 4)
|
||||
|
||||
### New files
|
||||
|
||||
- `frontend/src/components/WidgetInstance.tsx` — Renders a widget instance by looking up its definition and dispatching to the registered component.
|
||||
- `frontend/src/components/WidgetConfigDialog.tsx` — Dashboard widget configuration UI: list, add, edit, delete, reorder, enable/disable.
|
||||
- `frontend/src/pages/AddonPage.tsx` — Route mapper for `/addons/:addonId`.
|
||||
- `frontend/src/addons/GrafanaAddonPage.tsx` — Grafana addon landing page (deep-link only).
|
||||
- `frontend/src/addons/PrometheusAddonPage.tsx` — Prometheus addon landing page.
|
||||
- `frontend/src/addons/SshTasksAddonPage.tsx` — SSH tasks addon landing page.
|
||||
- `frontend/src/addons/index.ts` — Barrel exports.
|
||||
|
||||
### Modified files
|
||||
|
||||
- `frontend/src/pages/Dashboard.tsx` — Replaced hard-coded Jellyfin/Backups sections with widget instance loop; kept Shortcuts section; added "Edit dashboard" button.
|
||||
- `frontend/src/App.tsx` — Registered `/addons/:addonId` route in both OIDC and non-OIDC route trees.
|
||||
- `docs/REQUIREMENTS.md` — Added Configurable Dashboard Widgets section.
|
||||
|
||||
## Verification (Slice 4)
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
.venv/bin/python -m ruff check . # All checks passed
|
||||
PYTHONPATH=src .venv/bin/python -m pytest # 200 passed, 2 warnings
|
||||
cd ../frontend
|
||||
npm run lint # 2 pre-existing warnings, 0 errors
|
||||
npm run build # Built successfully
|
||||
npm run test -- src/widgets/registry.test.ts # 3 passed
|
||||
```
|
||||
|
||||
## Deviations from design (Slice 4)
|
||||
|
||||
- The "Edit dashboard" button lives in the Shortcuts section action area for now. A future UI pass can move it to a dedicated dashboard header.
|
||||
- Machine/task selectors in the config dialog filter to enabled Jellyfin machines / enabled tasks, which is slightly stricter than the design's generic string field.
|
||||
|
||||
## Remaining work
|
||||
|
||||
- Slice 4: Dashboard loop + configuration UI + addon pages
|
||||
- Phase 1 widget system is complete. Future work could include widget grid layout, drag-and-drop reorder, richer Prometheus visualizations, or migrating shortcuts into the widget system.
|
||||
|
||||
## PR boundary
|
||||
|
||||
|
||||
Reference in New Issue
Block a user