From d354855e9646236c7aa24a76a17dd53406f3112c Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Mon, 4 Mar 2024 18:29:30 -0500 Subject: [PATCH 01/10] Makes $me check conditional --- src/lib/components/MainLayout.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/components/MainLayout.svelte b/src/lib/components/MainLayout.svelte index 6eb1734b1..3a606e1f5 100644 --- a/src/lib/components/MainLayout.svelte +++ b/src/lib/components/MainLayout.svelte @@ -61,7 +61,7 @@
From 2be9074e59cf24c3a3d9822a4df041595683653d Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Fri, 1 Mar 2024 15:36:02 -0500 Subject: [PATCH 02/10] Loads pinned add-on data in sidebar --- src/addons/types.ts | 5 ---- src/lib/api/addons.ts | 16 ++++++++++++ src/lib/api/types.d.ts | 49 ++++++++++++++++++++++++++++++++++++ src/lib/utils/index.ts | 1 + src/lib/utils/isErrorCode.ts | 5 ++++ src/routes/app/+layout.js | 3 +++ src/routes/app/+page.svelte | 34 +++++++++++++++---------- 7 files changed, 95 insertions(+), 18 deletions(-) create mode 100644 src/lib/api/addons.ts create mode 100644 src/lib/utils/index.ts create mode 100644 src/lib/utils/isErrorCode.ts diff --git a/src/addons/types.ts b/src/addons/types.ts index 9f143cf07..01f82602a 100644 --- a/src/addons/types.ts +++ b/src/addons/types.ts @@ -1,8 +1,3 @@ -interface Author { - name?: string; - avatar?: string; -} - type AddOnCategory = "premium" | string; interface AddOnProperty { diff --git a/src/lib/api/addons.ts b/src/lib/api/addons.ts new file mode 100644 index 000000000..b58d64328 --- /dev/null +++ b/src/lib/api/addons.ts @@ -0,0 +1,16 @@ +import { error } from "@sveltejs/kit"; +import { BASE_API_URL } from "@/config/config.js"; +import { type AddOnListItem } from "@/addons/types"; +import { isErrorCode } from "../utils"; + +export async function getPinnedAddons(): Promise { + const endpoint = new URL( + "/api/addons/?active=true&per_page=100", + BASE_API_URL, + ); + const resp = await fetch(endpoint, { credentials: "include" }); + if (isErrorCode(resp.status)) { + error(resp.status, resp.statusText); + } + return resp.json(); +} diff --git a/src/lib/api/types.d.ts b/src/lib/api/types.d.ts index fcc8507ba..d686d6680 100644 --- a/src/lib/api/types.d.ts +++ b/src/lib/api/types.d.ts @@ -17,6 +17,55 @@ export type sizes = "thumbnail" | "small" | "normal" | "large" | "xlarge"; export type Highlight = Record; +type AddOnCategory = "premium" | string; + +interface AddOnProperty { + type: string; + title: string; + description?: string; + default?: string; + format?: string; + enum?: string[]; +} + +interface AddOnParameters { + type: string; + version: number; + title: string; + description: string; + instructions: string; + categories: AddOnCategory[]; + documents: string[]; + required: string[]; + properties: Record; + cost: { + amount: number; + price: number; + unit: string; + }; + eventOptions: { + name: string; + events: string[]; + }; +} + +// API endpoint https://api.www.documentcloud.org/api/addons/ +export interface AddOnListItem { + id: number; + user: number; + organization: number; + access: "public" | "private"; + name: string; + repository: string; + parameters: Partial; + created_at: string; + updated_at: string; + active: boolean; + featured: boolean; + default: boolean; + usage?: number; +} + // https://www.documentcloud.org/help/api#documents export interface Document { id: number | string; diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts new file mode 100644 index 000000000..93e586613 --- /dev/null +++ b/src/lib/utils/index.ts @@ -0,0 +1 @@ +export { isErrorCode } from "./isErrorCode"; diff --git a/src/lib/utils/isErrorCode.ts b/src/lib/utils/isErrorCode.ts new file mode 100644 index 000000000..66bcf58c9 --- /dev/null +++ b/src/lib/utils/isErrorCode.ts @@ -0,0 +1,5 @@ +import type { NumericRange } from "@sveltejs/kit"; + +export function isErrorCode(status: number): status is NumericRange<400, 599> { + return status >= 400 && status <= 599; +} diff --git a/src/routes/app/+layout.js b/src/routes/app/+layout.js index 908d2efa2..75c1c01d4 100644 --- a/src/routes/app/+layout.js +++ b/src/routes/app/+layout.js @@ -1,12 +1,15 @@ import { search } from "$lib/api/documents.js"; +import { getPinnedAddons } from "@/lib/api/addons.js"; export async function load({ url, fetch }) { const query = url.searchParams.get("q") || ""; const searchResults = search(query, true, fetch); + const pinnedAddons = getPinnedAddons(); return { searchResults, query, + pinnedAddons, }; } diff --git a/src/routes/app/+page.svelte b/src/routes/app/+page.svelte index 812a1435e..58203b335 100644 --- a/src/routes/app/+page.svelte +++ b/src/routes/app/+page.svelte @@ -12,6 +12,7 @@ Share16, Book16, Hourglass24, + Pin24, } from "svelte-octicons"; import MainLayout from "$lib/components/MainLayout.svelte"; import Button from "$lib/components/common/Button.svelte"; @@ -26,8 +27,14 @@ import Search from "$lib/components/Search.svelte"; import Empty from "$lib/components/common/Empty.svelte"; import Paginator from "@/common/Paginator.svelte"; + import type { DocumentResults } from "@/lib/api/types"; + import type { AddOnListItem } from "@/addons/types"; - export let data; + export let data: { + query: string; + searchResults: Promise; + pinnedAddons: Promise; + }; let page = 1; let per_page = 25; @@ -35,6 +42,7 @@ $: searchResults = data.searchResults; $: query = data.query; + $: pinnedAddons = data.pinnedAddons; $: count = searchResults.count; $: next = searchResults.next; $: previous = searchResults.previous; @@ -151,18 +159,18 @@ Add-Ons Explore - - Scraper - - - Regex Extractor - - - Tabula Spreadsheet Analysis - - - GPT 3.5 Analysis - + {#await pinnedAddons} + Loading… + {:then addons} + {#each addons as addon} + + + {addon.name} + + {:else} + Pinned add-ons will appear here + {/each} + {/await} From e75da94cef3da809609d80a03ab6f6df91e8afb2 Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Mon, 4 Mar 2024 10:20:17 -0500 Subject: [PATCH 03/10] Fix addon data loading --- src/lib/api/addons.ts | 3 ++- src/routes/app/+page.svelte | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/lib/api/addons.ts b/src/lib/api/addons.ts index b58d64328..6f8d35384 100644 --- a/src/lib/api/addons.ts +++ b/src/lib/api/addons.ts @@ -2,8 +2,9 @@ import { error } from "@sveltejs/kit"; import { BASE_API_URL } from "@/config/config.js"; import { type AddOnListItem } from "@/addons/types"; import { isErrorCode } from "../utils"; +import type { Page } from "@/api/types/common"; -export async function getPinnedAddons(): Promise { +export async function getPinnedAddons(): Promise> { const endpoint = new URL( "/api/addons/?active=true&per_page=100", BASE_API_URL, diff --git a/src/routes/app/+page.svelte b/src/routes/app/+page.svelte index 58203b335..eceb6e915 100644 --- a/src/routes/app/+page.svelte +++ b/src/routes/app/+page.svelte @@ -29,11 +29,12 @@ import Paginator from "@/common/Paginator.svelte"; import type { DocumentResults } from "@/lib/api/types"; import type { AddOnListItem } from "@/addons/types"; + import type { Page } from "@/api/types/common"; export let data: { query: string; searchResults: Promise; - pinnedAddons: Promise; + pinnedAddons: Promise>; }; let page = 1; @@ -162,7 +163,7 @@ {#await pinnedAddons} Loading… {:then addons} - {#each addons as addon} + {#each addons.results as addon} {addon.name} From 366b3904a0deff27a4136e87aaa02f50feebaa09 Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Mon, 4 Mar 2024 17:02:39 -0500 Subject: [PATCH 04/10] Fix addon URL Co-authored-by: Chris Amico --- src/routes/app/+page.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/app/+page.svelte b/src/routes/app/+page.svelte index eceb6e915..ca30ddc9f 100644 --- a/src/routes/app/+page.svelte +++ b/src/routes/app/+page.svelte @@ -164,7 +164,7 @@ Loading… {:then addons} {#each addons.results as addon} - + {addon.name} From d977f8a37384b4405b94dcaa3eae414e39ce33d7 Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Mon, 4 Mar 2024 18:30:25 -0500 Subject: [PATCH 05/10] Links to add-ons page --- src/routes/app/+layout.js | 2 +- src/routes/app/+page.svelte | 4 +++- src/routes/app/add-ons/+page.svelte | 5 +++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/routes/app/+layout.js b/src/routes/app/+layout.js index 75c1c01d4..b5360db2d 100644 --- a/src/routes/app/+layout.js +++ b/src/routes/app/+layout.js @@ -1,5 +1,5 @@ import { search } from "$lib/api/documents.js"; -import { getPinnedAddons } from "@/lib/api/addons.js"; +import { getPinnedAddons } from "@/lib/api/addons"; export async function load({ url, fetch }) { const query = url.searchParams.get("q") || ""; diff --git a/src/routes/app/+page.svelte b/src/routes/app/+page.svelte index ca30ddc9f..01ec3bfa5 100644 --- a/src/routes/app/+page.svelte +++ b/src/routes/app/+page.svelte @@ -158,7 +158,9 @@ Add-Ons - Explore + + Explore + {#await pinnedAddons} Loading… diff --git a/src/routes/app/add-ons/+page.svelte b/src/routes/app/add-ons/+page.svelte index e69de29bb..b7daf89b5 100644 --- a/src/routes/app/add-ons/+page.svelte +++ b/src/routes/app/add-ons/+page.svelte @@ -0,0 +1,5 @@ + + + From ba976ab433f5979238291c789e17cb4da971230b Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Mon, 4 Mar 2024 18:46:43 -0500 Subject: [PATCH 06/10] Load data on add-ons route --- src/lib/api/addons.ts | 15 ++++++- src/routes/app/+layout.js | 15 ------- src/routes/app/+page.ts | 15 +++++++ src/routes/app/add-ons/+page.svelte | 67 ++++++++++++++++++++++++++++- src/routes/app/add-ons/+page.ts | 8 ++++ 5 files changed, 102 insertions(+), 18 deletions(-) create mode 100644 src/routes/app/+page.ts create mode 100644 src/routes/app/add-ons/+page.ts diff --git a/src/lib/api/addons.ts b/src/lib/api/addons.ts index 6f8d35384..61ffddb2c 100644 --- a/src/lib/api/addons.ts +++ b/src/lib/api/addons.ts @@ -4,7 +4,9 @@ import { type AddOnListItem } from "@/addons/types"; import { isErrorCode } from "../utils"; import type { Page } from "@/api/types/common"; -export async function getPinnedAddons(): Promise> { +export async function getPinnedAddons( + fetch = globalThis.fetch, +): Promise> { const endpoint = new URL( "/api/addons/?active=true&per_page=100", BASE_API_URL, @@ -15,3 +17,14 @@ export async function getPinnedAddons(): Promise> { } return resp.json(); } + +export async function getAddons( + fetch = globalThis.fetch, +): Promise> { + const endpoint = new URL("/api/addons/?per_page=100", BASE_API_URL); + const resp = await fetch(endpoint, { credentials: "include" }); + if (isErrorCode(resp.status)) { + error(resp.status, resp.statusText); + } + return resp.json(); +} diff --git a/src/routes/app/+layout.js b/src/routes/app/+layout.js index b5360db2d..e69de29bb 100644 --- a/src/routes/app/+layout.js +++ b/src/routes/app/+layout.js @@ -1,15 +0,0 @@ -import { search } from "$lib/api/documents.js"; -import { getPinnedAddons } from "@/lib/api/addons"; - -export async function load({ url, fetch }) { - const query = url.searchParams.get("q") || ""; - - const searchResults = search(query, true, fetch); - const pinnedAddons = getPinnedAddons(); - - return { - searchResults, - query, - pinnedAddons, - }; -} diff --git a/src/routes/app/+page.ts b/src/routes/app/+page.ts new file mode 100644 index 000000000..e5ee0d7a4 --- /dev/null +++ b/src/routes/app/+page.ts @@ -0,0 +1,15 @@ +import { search } from "$lib/api/documents.js"; +import { getPinnedAddons } from "@/lib/api/addons"; + +export async function load({ url, fetch }) { + const query = url.searchParams.get("q") || ""; + + const searchResults = search(query, true, fetch); + const pinnedAddons = getPinnedAddons(fetch); + + return { + searchResults, + query, + pinnedAddons, + }; +} diff --git a/src/routes/app/add-ons/+page.svelte b/src/routes/app/add-ons/+page.svelte index b7daf89b5..50a516113 100644 --- a/src/routes/app/add-ons/+page.svelte +++ b/src/routes/app/add-ons/+page.svelte @@ -1,5 +1,68 @@ - +
+
+

{$_("addonBrowserDialog.title")}

+

{$_("addonBrowserDialog.subtitle")}

+
+ +
+
+ {#if $filter === "active"} + + {:else if $filter === "featured"} + + {:else if $filter === "premium"} + + {/if} + {#await data.addons then res} + + {/await} +
+ +
+
diff --git a/src/routes/app/add-ons/+page.ts b/src/routes/app/add-ons/+page.ts new file mode 100644 index 000000000..1cbad8089 --- /dev/null +++ b/src/routes/app/add-ons/+page.ts @@ -0,0 +1,8 @@ +import { getAddons } from "@/lib/api/addons"; + +export async function load({ fetch }) { + const addons = getAddons(fetch); + return { + addons, + }; +} From e0ebc18c538a6e72a04a3fab1c33f74940cfe37e Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Mon, 4 Mar 2024 18:50:14 -0500 Subject: [PATCH 07/10] Adds styles to add-on browser --- src/routes/app/add-ons/+page.svelte | 102 ++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/src/routes/app/add-ons/+page.svelte b/src/routes/app/add-ons/+page.svelte index 50a516113..3d796170e 100644 --- a/src/routes/app/add-ons/+page.svelte +++ b/src/routes/app/add-ons/+page.svelte @@ -66,3 +66,105 @@ --> + + From 7444fd92ff407dde635224e2e88312479ac27be7 Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Mon, 4 Mar 2024 18:52:48 -0500 Subject: [PATCH 08/10] Fix addonlist variable --- src/routes/app/add-ons/+page.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/app/add-ons/+page.svelte b/src/routes/app/add-ons/+page.svelte index 3d796170e..05c567b31 100644 --- a/src/routes/app/add-ons/+page.svelte +++ b/src/routes/app/add-ons/+page.svelte @@ -50,7 +50,7 @@ {#await data.addons then res} From a51c09d2216a1b590335a8f6c5b2124624a274bc Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Mon, 4 Mar 2024 18:53:49 -0500 Subject: [PATCH 09/10] Fix Action button --- src/lib/components/common/Action.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/components/common/Action.svelte b/src/lib/components/common/Action.svelte index d35930168..6dd7bb41d 100644 --- a/src/lib/components/common/Action.svelte +++ b/src/lib/components/common/Action.svelte @@ -8,7 +8,7 @@ class="container" role="button" tabindex={0} - on:click|stopPropagation|preventDefault + on:click|stopPropagation on:keydown|stopPropagation > {#if icon}{/if} From 2fe5888bda29e415ca2b831426cbf8bcf5593251 Mon Sep 17 00:00:00 2001 From: Allan Lasser Date: Tue, 5 Mar 2024 09:27:34 -0500 Subject: [PATCH 10/10] Update browser data loading --- src/routes/app/add-ons/+page.svelte | 52 ++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/src/routes/app/add-ons/+page.svelte b/src/routes/app/add-ons/+page.svelte index 05c567b31..2357e95e6 100644 --- a/src/routes/app/add-ons/+page.svelte +++ b/src/routes/app/add-ons/+page.svelte @@ -11,10 +11,49 @@ import Star from "@/common/icons/Star.svelte"; import Credit from "@/common/icons/Credit.svelte"; - let visible = false; let per_page = 10; export let data; + + $: urlParams = buildParams({ + per_page, + query: $query, + filter: $filter, + }); + $: url = buildUrl(urlParams); + $: next_url = data.addons.next ? new URL(data.addons.next).toString() : null; + $: previous_url = data.addons.previous + ? new URL(data.addons.previous).toString() + : null; + $: items = data.addons.results; + + /** Network logic */ + let loading = false; + let error = null; + + export async function load(url) { + loading = true; + + data = await fetch(url, { + credentials: "include", + }) + .then(async (r) => { + const data = await r.json(); + if (!r.ok) throw data; + return data; + }) + .catch((err) => { + error = err; + loading = false; + return {}; + }); + + loading = false; + } + + $: loadNext = () => load(next_url); + $: loadPrev = () => load(previous_url); + $: reload = () => load(url);
@@ -48,22 +87,17 @@ {/if} {#await data.addons then res} - + {/await}
- +