feat(frontend): add library paged types, syncStatus/triggerSync/admin API methods

This commit is contained in:
2026-03-20 00:30:03 +01:00
parent e1a885dcc9
commit 978ad1cdb0
2 changed files with 73 additions and 0 deletions

View File

@@ -19,6 +19,9 @@ import type {
ProviderTestResult,
ConfigSnapshot,
ScheduleHistoryEntry,
LibrarySyncLogEntry,
PagedLibraryResponse,
AdminSettings,
} from "@/lib/types";
const API_BASE =
@@ -235,6 +238,35 @@ export const api = {
if (provider) params.set("provider", provider);
return request<LibraryItemResponse[]>(`/library/items?${params}`, { token });
},
syncStatus: (token: string): Promise<LibrarySyncLogEntry[]> =>
request('/library/sync/status', { token }),
triggerSync: (token: string): Promise<void> =>
request('/library/sync', { method: 'POST', token }),
itemsPage: (
token: string,
filter: Partial<{
q: string; type: string; series: string[]; genres: string[]; collection: string;
provider: string; decade: number; min_duration: number; max_duration: number;
offset: number; limit: number;
}>
): Promise<PagedLibraryResponse> => {
const params = new URLSearchParams();
if (filter.q) params.set('q', filter.q);
if (filter.type) params.set('type', filter.type);
if (filter.series) filter.series.forEach(s => params.append('series[]', s));
if (filter.genres) filter.genres.forEach(g => params.append('genres[]', g));
if (filter.collection) params.set('collection', filter.collection);
if (filter.provider) params.set('provider', filter.provider);
if (filter.decade != null) params.set('decade', String(filter.decade));
if (filter.min_duration != null) params.set('min_duration', String(filter.min_duration));
if (filter.max_duration != null) params.set('max_duration', String(filter.max_duration));
params.set('offset', String(filter.offset ?? 0));
params.set('limit', String(filter.limit ?? 50));
return request(`/library/items?${params}`, { token });
},
},
files: {
@@ -266,6 +298,17 @@ export const api = {
activity: (token: string) =>
request<ActivityEvent[]>("/admin/activity", { token }),
getSettings: (token: string): Promise<AdminSettings> =>
request('/admin/settings', { token }),
updateSettings: (token: string, patch: Partial<AdminSettings>): Promise<AdminSettings> =>
request('/admin/settings', {
method: 'PUT',
token,
body: JSON.stringify(patch),
headers: { 'Content-Type': 'application/json' },
}),
providers: {
getProviders: (token: string) =>
request<ProviderConfig[]>("/admin/providers", { token }),

View File

@@ -292,3 +292,33 @@ export interface CurrentBroadcastResponse {
offset_secs: number;
block_access_mode: AccessMode;
}
// Library management
// Note: LibraryItemResponse is already defined in this file (search for it above).
// LibraryItemFull extends it with the extra fields returned by the DB-backed endpoint.
export interface LibraryItemFull extends LibraryItemResponse {
thumbnail_url?: string | null;
collection_id?: string | null;
collection_name?: string | null;
}
export interface PagedLibraryResponse {
items: LibraryItemFull[];
total: number;
}
export interface LibrarySyncLogEntry {
id: number;
provider_id: string;
started_at: string;
finished_at?: string | null;
items_found: number;
status: 'running' | 'done' | 'error';
error_msg?: string | null;
}
export interface AdminSettings {
library_sync_interval_hours: number;
[key: string]: unknown;
}