diff --git a/surfsense_backend/app/schemas/documents.py b/surfsense_backend/app/schemas/documents.py index 80f6dc0a7..fc83d24be 100644 --- a/surfsense_backend/app/schemas/documents.py +++ b/surfsense_backend/app/schemas/documents.py @@ -1,7 +1,7 @@ from datetime import datetime +from typing import TypeVar from pydantic import BaseModel, ConfigDict -from typing import Generic, TypeVar from app.db import DocumentType @@ -58,6 +58,6 @@ class DocumentWithChunksRead(DocumentRead): model_config = ConfigDict(from_attributes=True) -class PaginatedResponse(BaseModel, Generic[T]): +class PaginatedResponse[T](BaseModel): items: list[T] total: int diff --git a/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/page.tsx b/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/page.tsx index ce7fc3b50..86e702843 100644 --- a/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/page.tsx +++ b/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/page.tsx @@ -173,7 +173,6 @@ export default function DocumentsTable() { /> -export { DocumentsTable }; { diff --git a/surfsense_web/hooks/use-documents.ts b/surfsense_web/hooks/use-documents.ts index 091149641..4c22a8707 100644 --- a/surfsense_web/hooks/use-documents.ts +++ b/surfsense_web/hooks/use-documents.ts @@ -37,10 +37,7 @@ export interface UseDocumentsOptions { lazy?: boolean; } -export function useDocuments( - searchSpaceId: number, - options?: UseDocumentsOptions | boolean -) { +export function useDocuments(searchSpaceId: number, options?: UseDocumentsOptions | boolean) { // Support both old boolean API and new options API for backward compatibility const opts = typeof options === "boolean" ? { lazy: options } : options || {}; const { page, pageSize = 300, lazy = false } = opts; diff --git a/surfsense_web/lib/pagination.ts b/surfsense_web/lib/pagination.ts index 0c618e56e..f9cabc64b 100644 --- a/surfsense_web/lib/pagination.ts +++ b/surfsense_web/lib/pagination.ts @@ -1,34 +1,33 @@ // Helper to normalize list responses from the API // Supports shapes: Array, { items: T[]; total: number }, and tuple [T[], total] export type ListResponse = { - items: T[]; - total: number; + items: T[]; + total: number; }; export function normalizeListResponse(payload: any): ListResponse { - try { - // Case 1: already in desired shape - if (payload && Array.isArray(payload.items)) { - const total = typeof payload.total === "number" ? payload.total : payload.items.length; - return { items: payload.items as T[], total }; - } + try { + // Case 1: already in desired shape + if (payload && Array.isArray(payload.items)) { + const total = typeof payload.total === "number" ? payload.total : payload.items.length; + return { items: payload.items as T[], total }; + } - // Case 2: tuple [items, total] - if (Array.isArray(payload) && payload.length === 2 && Array.isArray(payload[0])) { - const items = (payload[0] ?? []) as T[]; - const rawTotal = payload[1]; - const total = typeof rawTotal === "number" ? rawTotal : items.length; - return { items, total }; - } + // Case 2: tuple [items, total] + if (Array.isArray(payload) && payload.length === 2 && Array.isArray(payload[0])) { + const items = (payload[0] ?? []) as T[]; + const rawTotal = payload[1]; + const total = typeof rawTotal === "number" ? rawTotal : items.length; + return { items, total }; + } - // Case 3: plain array - if (Array.isArray(payload)) { - return { items: payload as T[], total: (payload as T[]).length }; - } - } catch (e) { - // fallthrough to default - } + // Case 3: plain array + if (Array.isArray(payload)) { + return { items: payload as T[], total: (payload as T[]).length }; + } + } catch (e) { + // fallthrough to default + } - return { items: [], total: 0 }; + return { items: [], total: 0 }; } -