diff --git a/src/lib/api/documents.ts b/src/lib/api/documents.ts index d08213b82..855a7e01f 100644 --- a/src/lib/api/documents.ts +++ b/src/lib/api/documents.ts @@ -1,7 +1,7 @@ /** API helpers related to documents. * Lots of duplicated code here that should get consolidated at some point. */ -import type { Document, DocumentResults, sizes } from "./types"; +import type { Document, DocumentResults, SearchOptions, sizes } from "./types"; import { error } from "@sveltejs/kit"; @@ -10,15 +10,21 @@ import { isOrg } from "@/api/types/orgAndUser"; import { APP_URL, BASE_API_URL } from "@/config/config.js"; import { isErrorCode } from "../utils"; -/** Search documents */ +/** + * Search documents + * https://www.documentcloud.org/help/search/ + * + * Note that in some environments, pagination works by setting page=N + * while in others we use cursers. + * */ export async function search( query = "", - options = { hl: false, per_page: 25, cursor: "" }, + options: SearchOptions = { hl: false, per_page: 25, cursor: "" }, fetch = globalThis.fetch, ): Promise { const endpoint = new URL("documents/search/", BASE_API_URL); - // endpoint.searchParams.set("expand", DEFAULT_EXPAND); + endpoint.searchParams.set("expand", DEFAULT_EXPAND); endpoint.searchParams.set("q", query); for (const [k, v] of Object.entries(options)) { diff --git a/src/lib/api/types.d.ts b/src/lib/api/types.d.ts index d686d6680..e6ca97492 100644 --- a/src/lib/api/types.d.ts +++ b/src/lib/api/types.d.ts @@ -135,6 +135,14 @@ export interface Section { export type SectionResults = Page
; +export interface SearchOptions { + hl?: boolean; + per_page?: number; + page?: number; + cursor?: string; + expand?: string; +} + export interface OEmbed { version: "1.0"; provider_name: "DocumentCloud"; diff --git a/src/routes/app/+page.svelte b/src/routes/app/+page.svelte index 6b26f831d..ba6f80756 100644 --- a/src/routes/app/+page.svelte +++ b/src/routes/app/+page.svelte @@ -14,23 +14,28 @@ export let data; let page_number = 1; - let error: Error; $: searchResults = data.searchResults; $: query = data.query; $: per_page = data.per_page; + $: page_number = data.page; // update the cursor URL param, forcing refresh of search results function setCursor(url: URL) { - const c = url.searchParams.get("cursor"); - $page.url.searchParams.set("cursor", c); - goto($page.url); + const cursor = url.searchParams.get("cursor"); + const page_number = url.searchParams.get("page"); + + // handle different environments that paginate differently + if (cursor) $page.url.searchParams.set("cursor", cursor); + if (per_page) $page.url.searchParams.set("page", page_number); + + return goto($page.url); } // update the per_page query param function setPerPage(e) { $page.url.searchParams.set("per_page", e.target.value); - goto($page.url); + return goto($page.url); } @@ -56,18 +61,19 @@ {@const total_pages = Math.ceil(count / per_page)} {@const next = sr.next} {@const previous = sr.previous} + { - page_number = Math.min(total_pages, page_number + 1); if (next) setCursor(new URL(next)); + page_number = Math.min(total_pages, page_number + 1); }} on:previous={(e) => { - page_number = Math.max(1, page_number - 1); if (previous) setCursor(new URL(previous)); + page_number = Math.max(1, page_number - 1); }} /> {/await} diff --git a/src/routes/app/+page.ts b/src/routes/app/+page.ts index 280051418..babb0cdef 100644 --- a/src/routes/app/+page.ts +++ b/src/routes/app/+page.ts @@ -1,21 +1,34 @@ +import type { SearchOptions } from "$lib/api/types"; import { search } from "$lib/api/documents.js"; export async function load({ url, fetch }) { const query = url.searchParams.get("q") || ""; const per_page = +url.searchParams.get("per_page") || 25; const cursor = url.searchParams.get("cursor") || ""; + const page = +url.searchParams.get("page") || null; - const options = { + const options: SearchOptions = { hl: true, - per_page, - cursor, }; + if (per_page) { + options.per_page = per_page; + } + + if (cursor) { + options.cursor = cursor; + } + + if (page) { + options.page = page; + } + const searchResults = search(query, options, fetch); return { query, per_page, + page, cursor, searchResults, };