Follow-ups: reference reorder, detach service_id, named-dashboard widgets

Three reusable-widget follow-up fixes:

1. Reference sort_order independently reorderable. Reordering a
   referenced widget now updates the widget_references.sort_order (per-
   dashboard), not the shared widget instance sort_order. New backend
   update_widget_reference method + PUT /api/widgets/references/{id}
   endpoint. Frontend moveInstance checks _ref_id to choose the right
   mutation (updateRef for references, saveWidget for owned).

2. Detach preserves service_id. detach_widget_reference now copies the
   original widget's service_id into the clone, so service-bound widgets
   (Grafana chart, Jellyfin activity) continue to render after detach.

3. Named dashboards support widget references. NamedDashboardPage
   fetches useWidgetReferences('named:<slug>') and renders them via
   WidgetInstanceCard alongside pinned links. 'Edit widgets' button
   opens WidgetConfigDialog with dashboardScope='named:<slug>'.

Also: removed useMemo on combinedWidgets in WidgetConfigDialog to fix
a react-hooks/preserve-manual-memoization lint error (the React Compiler
ESLint plugin couldn't verify the spread+sort memoization).

283 backend tests pass (+1 update_reference test); 128 frontend tests
pass; ruff clean; 0 lint errors.
This commit is contained in:
Developer
2026-07-06 12:11:47 +00:00
parent c36262d7b6
commit 1e636fdbe2
9 changed files with 294 additions and 70 deletions
@@ -24,6 +24,7 @@ vi.mock("../../hooks/useWidgets", () => ({
useCreateWidgetReference: () => ({ mutateAsync: vi.fn() }),
useDeleteWidgetReference: () => ({ mutateAsync: vi.fn() }),
useDetachWidgetReference: () => ({ mutateAsync: vi.fn() }),
useUpdateWidgetReference: () => ({ mutateAsync: vi.fn() }),
}));
vi.mock("../../hooks/useServices", () => ({