feat(jellyseer): sortable/filterable requests table on the Requests tab

Replace the static "recent requests" list with a proper table of all Jellyseerr
requests, sorted by date added (newest first by default) with standard sorting
and filtering.

Backend:
- JellyseerrClient.requests(max_count=500): paginated GET /api/v1/request
  (sort=added), mapped with type (movie/tv), status, media_status, and
  created_at labels. Returns up to 500 so the table can sort/filter client-side.
- fetch_jellyseer_requests(service) reuses the per-service cached client
  (shared with the stats widgets).
- new GET /api/jellyseerr/requests endpoint.

Frontend:
- JellyseerRequestsTable: TanStack Table (sorting via getSortedRowModel,
  pagination via getPaginationRowModel) reusing the Table primitives +
  TablePagination. Columns: Name / Type / Status / Media / Requested, all
  sortable; default sort Requested desc. A search box filters by name and a
  status dropdown defaults to "Open" (pending+approved+processing) with
  All/Pending/Approved/Declined options. (The shared DataTable is deliberately
  visibility-only, so this is a dedicated sortable table.)
- RequestsTab renders the stats grid + the new table (the compact recent list
  stays on the Requests overview widget).
- useJellyseerRequests hook + fetchJellyseerRequests API client.

Tests: client requests() mapping + single-page stop; fetch helper not-configured;
RequestsTab test mocks both hooks. 404/404 backend + 184/184 frontend pass;
build (tsc -b && vite build) + ESLint clean.
This commit is contained in:
Developer
2026-07-12 17:18:21 +00:00
parent 54851779fb
commit 7665ef4d10
21 changed files with 447 additions and 77 deletions
+3 -3
View File
@@ -4,18 +4,18 @@ dir: frontend/src/api
index: frontend/src/api/.pi-map.index.md
## role
Typed API client layer that centralizes all backend communication for the frontend application across multiple service domains.
Frontend API client layer that centralizes typed HTTP requests to backend services and external integrations.
## files
- authentik.ts | API client providing functions to fetch users, send messages, and check message status from the Authentik service. | exp: AuthentikUser, AuthentikUsersResponse, AuthentikMessageInput, AuthentikMessageResponse, func:fetchAuthentikUsers(serviceId: string, params: { search?: string; page?: number; page_size?: number }) → Promise<AuthentikUsersResponse>, call:get, call:String, func:sendAuthentikMessage(serviceId: string, input: AuthentikMessageInput) → Promise<AuthentikMessageResponse>, call:post, func:fetchAuthentikMessageStatus(serviceId: string) → Promise<Record<string, unknown>>, call:get | dep: ./shared
- backups.ts | API client functions for fetching and managing backup jobs, runs, alerts, and dashboard summaries. | exp: func:fetchBackupJobs(serviceId: string) → Promise<BackupJob[]>, call:get, func:fetchBackupJob(jobId: string) → Promise<{ job: BackupJob; runs: BackupRun[] }>, call:get, func:fetchBackupRuns(jobId: string, status: string, serviceId: string) → Promise<BackupRun[]>, call:get, func:fetchBackupRun(runId: string) → Promise<BackupRun>, call:get, func:fetchBackupAlerts(jobId: string, acknowledged: boolean, severity: string, serviceId: string) → Promise<BackupAlert[]>, call:get, call:String, func:acknowledgeBackupAlert(alertId: string) → Promise<BackupAlert>, call:post, func:fetchBackupDashboard() → Promise<BackupDashboardSummary>, call:get | dep: ./shared, ../types/backups
- client.ts | Typed API client providing functions for interacting with a FastAPI backend across dashboard, monitoring, media, files, jobs, and observability endpoints. | exp: fetchCounts, fetchLibraries, fetchActivity, fetchUsers, fetchNowPlaying, fetchMonitoringMachines, fetchAppVersion, fetchDashboardShortcuts, saveDashboardShortcut, deleteDashboardShortcut, fetchMonitoringSettings, fetchSSHKeys, generateSSHKey, saveSSHKey, deleteSSHKey, fetchSavedTasks, fetchSavedTaskRuns, saveTask, deleteTask, runTask, saveMonitoringMachine, testMonitoringMachineSSH, deleteMonitoringMachine, resetLocalDatabase, fetchMediaStatus, buildMediaIndex, stopMediaIndexBuild, forceStopMediaIndexBuild, queryMedia, fetchDirectoryListing, fetchFfprobe, fetchStat, resolvePath, fetchJobTemplates, runJob, fetchUserMessageQueueStatus, sendUserMessage, fetchAlertmanagerAlerts, fetchAlertmanagerStatus, fetchPrometheusStatus, fetchPrometheusTargets | dep: ../types, ./shared
- dashboards.ts | API client providing CRUD operations for named dashboards via REST endpoints. | exp: NamedDashboard, NamedDashboardInput, func:fetchDashboards() → Promise<NamedDashboard[]>, call:get, func:fetchDashboardBySlug(slug: string) → Promise<NamedDashboard>, call:get, call:encodeURIComponent, func:createDashboard(input: NamedDashboardInput) → Promise<NamedDashboard>, call:post, func:updateDashboard(input: NamedDashboardInput) → Promise<NamedDashboard>, call:put, func:deleteDashboard(id: string) → Promise<{ status: string }>, call:del | dep: ./shared
- jellyseerr.ts | Fetches Jellyseerr request statistics and recent requests for a Jellyfin service instance via an API endpoint. | exp: JellyseerStat, JellyseerRecentRequest, JellyseerStatsResponse, func:fetchJellyseerrStats(jellyfinServiceId: string) → Promise<JellyseerStatsResponse>, call:get | dep: ./shared
- jellyseerr.ts | This file provides API client functions to fetch Jellyseerr request statistics and request lists for a Jellyfin service instance. | exp: JellyseerStat, JellyseerRecentRequest, JellyseerStatsResponse, JellyseerRequest, func:fetchJellyseerrStats(jellyfinServiceId: string) → Promise<JellyseerStatsResponse>, call:get, func:fetchJellyseerrRequests(jellyfinServiceId: string) → Promise<JellyseerRequest[]> | dep: ./shared
- services.ts | API client functions for CRUD operations and testing of service instances. | exp: func:fetchServiceTypes() → Promise<ServiceTypeInfo[]>, call:get, func:fetchServiceInstances(serviceType: string) → Promise<ServiceInstance[]>, call:get, func:createServiceInstance(input: ServiceInstanceInput) → Promise<ServiceInstance>, call:post, func:updateServiceInstance(input: ServiceInstanceInput) → Promise<ServiceInstance>, call:put, raise:Error, func:deleteServiceInstance(serviceId: string) → Promise<{ status: string }>, call:del, func:testServiceInstance(input: ServiceInstanceInput) → Promise<ServiceTestResult>, call:post | dep: ./shared, ../types
- shared.ts | Provides shared API helper functions (GET, POST, PUT, DELETE, etc.) that automatically attach OIDC auth tokens and handle URL building and error parsing for backend requests. | exp: API_BASE, func:buildUrl(path: string, params: Record<string, string>) → string, call:isAbsoluteUrl, call:Object.entries, call:url.searchParams.set, call:url.toString, func:readErrorDetail(response: Response) → Promise<string>, call:response.text, call:JSON.parse, call:detail.trim, func:buildHeaders(isJsonBody: boolean) → Headers, call:getAccessToken, call:headers.set, func:get(path: string, params: Record<string, string>) → Promise<T>, call:fetch, call:buildUrl, call:buildHeaders, call:response.json, raise:Error, func:post(path: string, body: unknown) → Promise<T>, call:fetch, call:buildUrl, call:buildHeaders, call:JSON.stringify, call:response.json, raise:Error, func:postForm(path: string, body: FormData) → Promise<T>, call:fetch, call:buildUrl, call:buildHeaders, call:response.json, raise:Error, func:put(path: string, body: unknown) → Promise<T>, call:fetch, call:buildUrl, call:buildHeaders, call:JSON.stringify, call:response.json, raise:Error, func:del(path: string) → Promise<T>, call:fetch, call:buildUrl, call:buildHeaders, call:response.json, raise:Error | dep: ../auth, getAccessToken (from ../auth), fetch API, Headers API, URL API, import.meta.env
- widgets.ts | API client module providing CRUD operations for widget instances, widget references, builtin widget kinds, and widget data retrieval. | exp: WidgetReference, WidgetReferenceInput, func:fetchBuiltinWidgetKinds() → Promise< BuiltinWidgetKindInfo[] >, call:get, func:fetchWidgetInstances(serviceId: string, scope: "dashboard" | "service") → Promise<WidgetInstance[]>, call:get, func:createWidgetInstance(input: WidgetInstanceInput) → Promise<WidgetInstance>, call:post, func:updateWidgetInstance(input: WidgetInstanceInput) → Promise<WidgetInstance>, call:put, raise:Error, func:deleteWidgetInstance(widgetId: string) → Promise<{ status: string }>, call:del, func:fetchWidgetData(widgetId: string) → Promise<WidgetDataResponse>, call:get, func:fetchWidgetReferences(dashboardScope: string) → Promise<WidgetReference[]>, call:get, func:createWidgetReference(input: WidgetReferenceInput) → Promise<WidgetReference>, call:post, func:deleteWidgetReference(referenceId: string) → Promise<{ status: string }>, call:del, func:detachWidgetReference(referenceId: string) → Promise<WidgetInstance>, call:post, func:updateWidgetReference(referenceId: string, sortOrder: number) → Promise<WidgetReference>, call:put | dep: ./shared, ../types
## arch
Modular domain-based API clients built on a shared HTTP helper that handles OIDC authentication, URL building, and error parsing, with each module exposing typed functions for specific service endpoints.
Modular API client pattern with a shared helper module for authentication, URL building, and error handling, alongside domain-specific client files organized by service area.
## tags
fetch, call:get, widget, dashboard, call:build, authentik, delete, call:post
## symbols