feat(services): select Jellyfin via jellyfin_service_id on the frontend

Slice 4b frontend half. Jellyfin-touching pages now select a Jellyfin service
instance instead of a machine.

- api/client.ts: Jellyfin-backed calls (counts/libraries/activity/users, media
  status/build/stop/force-stop, queryMedia) send jellyfin_service_id.
- hooks/useDashboard, useUsers, useMedia: selector param renamed to
  jellyfinServiceId.
- pages/Media + Applications: list jellyfin service instances and persist
  jellyfin_service_id in the URL.
- Dashboard (widgets) and Users (default instance) need no selector change.
- Update Applications + Media tests for the new hook/param.

Files/SSH transport keeps machine_id. Verification: frontend lint 0 errors,
build success, 70 tests; backend ruff clean, 222 tests.
This commit is contained in:
Developer
2026-06-23 12:10:27 +00:00
parent a13f560df2
commit cbb703341e
9 changed files with 113 additions and 89 deletions
+24 -22
View File
@@ -134,26 +134,26 @@ async function del<T>(path: string): Promise<T> {
return response.json();
}
// Dashboard
export const fetchCounts = (machineId?: string) =>
// Dashboard (Jellyfin-backed; selected via jellyfin_service_id)
export const fetchCounts = (jellyfinServiceId?: string) =>
get<MediaCounts>(
"/api/dashboard/counts",
machineId ? { machine_id: machineId } : undefined,
jellyfinServiceId ? { jellyfin_service_id: jellyfinServiceId } : undefined,
);
export const fetchLibraries = (machineId?: string) =>
export const fetchLibraries = (jellyfinServiceId?: string) =>
get<LibraryCount[]>(
"/api/dashboard/libraries",
machineId ? { machine_id: machineId } : undefined,
jellyfinServiceId ? { jellyfin_service_id: jellyfinServiceId } : undefined,
);
export const fetchActivity = (machineId?: string) =>
export const fetchActivity = (jellyfinServiceId?: string) =>
get<NowPlayingSession[]>(
"/api/dashboard/activity",
machineId ? { machine_id: machineId } : undefined,
jellyfinServiceId ? { jellyfin_service_id: jellyfinServiceId } : undefined,
);
export const fetchUsers = (machineId?: string) =>
export const fetchUsers = (jellyfinServiceId?: string) =>
get<UserDirectoryResponse>(
"/api/users",
machineId ? { machine_id: machineId } : undefined,
jellyfinServiceId ? { jellyfin_service_id: jellyfinServiceId } : undefined,
);
// Backward-compatible alias used by older hooks/components.
@@ -293,27 +293,27 @@ export const resetLocalDatabase = (payload: ResetLocalDatabaseInput) =>
);
// Media
export const fetchMediaStatus = (machineId?: string) =>
export const fetchMediaStatus = (jellyfinServiceId?: string) =>
get<MediaIndexStatus>(
"/api/media/status",
machineId ? { machine_id: machineId } : undefined,
jellyfinServiceId ? { jellyfin_service_id: jellyfinServiceId } : undefined,
);
export const buildMediaIndex = (machineId?: string) =>
export const buildMediaIndex = (jellyfinServiceId?: string) =>
post<MediaIndexActionResponse>(
machineId
? `/api/media/build?machine_id=${encodeURIComponent(machineId)}`
jellyfinServiceId
? `/api/media/build?jellyfin_service_id=${encodeURIComponent(jellyfinServiceId)}`
: "/api/media/build",
);
export const stopMediaIndexBuild = (machineId?: string) =>
export const stopMediaIndexBuild = (jellyfinServiceId?: string) =>
post<MediaIndexActionResponse>(
machineId
? `/api/media/stop?machine_id=${encodeURIComponent(machineId)}`
jellyfinServiceId
? `/api/media/stop?jellyfin_service_id=${encodeURIComponent(jellyfinServiceId)}`
: "/api/media/stop",
);
export const forceStopMediaIndexBuild = (machineId?: string) =>
export const forceStopMediaIndexBuild = (jellyfinServiceId?: string) =>
post<MediaIndexActionResponse>(
machineId
? `/api/media/force-stop?machine_id=${encodeURIComponent(machineId)}`
jellyfinServiceId
? `/api/media/force-stop?jellyfin_service_id=${encodeURIComponent(jellyfinServiceId)}`
: "/api/media/force-stop",
);
export const queryMedia = (params: {
@@ -325,7 +325,7 @@ export const queryMedia = (params: {
sort_order?: string;
limit?: number;
offset?: number;
machineId?: string;
jellyfinServiceId?: string;
}) =>
get<MediaQueryResponse>("/api/media/query", {
libraries: params.libraries || "",
@@ -336,7 +336,9 @@ export const queryMedia = (params: {
sort_order: params.sort_order || "Ascending",
limit: String(params.limit || 100),
offset: String(params.offset || 0),
...(params.machineId ? { machine_id: params.machineId } : {}),
...(params.jellyfinServiceId
? { jellyfin_service_id: params.jellyfinServiceId }
: {}),
});
// Files