From 09857de4c855d02bca3ee910535ddb0c2b441335 Mon Sep 17 00:00:00 2001 From: Brendan Allan Date: Sun, 27 Aug 2023 12:45:29 +0800 Subject: [PATCH] [ENG-1004] Add offset pagination to search queries (#1255) fix undefined cursors --- core/src/api/search.rs | 42 ++++++++++++++++++----- interface/app/$libraryId/location/$id.tsx | 8 ++++- interface/app/$libraryId/overview/data.ts | 16 +++++++-- packages/client/src/core.ts | 8 +++-- 4 files changed, 61 insertions(+), 13 deletions(-) diff --git a/core/src/api/search.rs b/core/src/api/search.rs index 6a91e23b6..d59d6baff 100644 --- a/core/src/api/search.rs +++ b/core/src/api/search.rs @@ -357,6 +357,13 @@ pub fn mount() -> AlphaRouter { ) }) .procedure("paths", { + #[derive(Deserialize, Type, Debug)] + #[serde(rename_all = "camelCase")] + enum FilePathPagination { + Cursor { pub_id: file_path::pub_id::Type }, + Offset(i32), + } + #[derive(Deserialize, Type, Debug)] #[serde(rename_all = "camelCase")] struct FilePathSearchArgs { @@ -365,7 +372,7 @@ pub fn mount() -> AlphaRouter { #[specta(optional)] order: Option, #[specta(optional)] - cursor: Option>, + pagination: Option, #[serde(default)] filter: FilePathFilterArgs, #[serde(default = "default_group_directories")] @@ -381,7 +388,7 @@ pub fn mount() -> AlphaRouter { FilePathSearchArgs { take, order, - cursor, + pagination, filter, group_directories, }| async move { @@ -404,8 +411,13 @@ pub fn mount() -> AlphaRouter { query = query.order_by(order.into_param()); } - if let Some(cursor) = cursor { - query = query.cursor(file_path::pub_id::equals(cursor)); + if let Some(pagination) = pagination { + match pagination { + FilePathPagination::Cursor { pub_id } => { + query = query.cursor(file_path::pub_id::equals(pub_id)); + } + FilePathPagination::Offset(offset) => query = query.skip(offset as i64), + } } let (file_paths, cursor) = { @@ -466,6 +478,13 @@ pub fn mount() -> AlphaRouter { }) }) .procedure("objects", { + #[derive(Deserialize, Type, Debug)] + #[serde(rename_all = "camelCase")] + enum ObjectPagination { + Cursor { pub_id: object::pub_id::Type }, + Offset(i32), + } + #[derive(Deserialize, Type, Debug)] #[serde(rename_all = "camelCase")] struct ObjectSearchArgs { @@ -474,7 +493,7 @@ pub fn mount() -> AlphaRouter { #[specta(optional)] order: Option, #[specta(optional)] - cursor: Option>, + pagination: Option, #[serde(default)] filter: ObjectFilterArgs, } @@ -484,7 +503,7 @@ pub fn mount() -> AlphaRouter { ObjectSearchArgs { take, order, - cursor, + pagination, filter, }| async move { let Library { db, .. } = library.as_ref(); @@ -500,8 +519,15 @@ pub fn mount() -> AlphaRouter { query = query.order_by(order.into_param()); } - if let Some(cursor) = cursor { - query = query.cursor(object::pub_id::equals(cursor)); + if let Some(pagination) = pagination { + match pagination { + ObjectPagination::Cursor { pub_id } => { + query = query.cursor(object::pub_id::equals(pub_id)); + } + ObjectPagination::Offset(offset) => { + query = query.skip(offset as i64); + } + } } let (objects, cursor) = { diff --git a/interface/app/$libraryId/location/$id.tsx b/interface/app/$libraryId/location/$id.tsx index 3516bfbcb..c3fbedbb7 100644 --- a/interface/app/$libraryId/location/$id.tsx +++ b/interface/app/$libraryId/location/$id.tsx @@ -178,7 +178,13 @@ const useItems = ({ 'search.paths', { ...queryKey[1].arg, - cursor + pagination: cursor + ? { + cursor: { + pub_id: cursor + } + } + : undefined } ]), getNextPageParam: (lastPage) => lastPage.cursor ?? undefined, diff --git a/interface/app/$libraryId/overview/data.ts b/interface/app/$libraryId/overview/data.ts index fe5df5f48..fb27c8ffd 100644 --- a/interface/app/$libraryId/overview/data.ts +++ b/interface/app/$libraryId/overview/data.ts @@ -87,7 +87,13 @@ export function useItems( 'search.paths', { ...queryKey[1].arg, - cursor + pagination: cursor + ? { + cursor: { + pub_id: cursor + } + } + : undefined } ]), getNextPageParam: (lastPage) => lastPage.cursor ?? undefined, @@ -116,7 +122,13 @@ export function useItems( 'search.objects', { ...queryKey[1].arg, - cursor + pagination: cursor + ? { + cursor: { + pub_id: cursor + } + } + : undefined } ]), getNextPageParam: (lastPage) => lastPage.cursor ?? undefined diff --git a/packages/client/src/core.ts b/packages/client/src/core.ts index b41eef871..1ea550660 100644 --- a/packages/client/src/core.ts +++ b/packages/client/src/core.ts @@ -142,7 +142,9 @@ export type FilePath = { id: number; pub_id: number[]; is_dir: boolean | null; c export type FilePathFilterArgs = { locationId?: number | null; search?: string | null; extension?: string | null; createdAt?: OptionalRange; path?: string | null; object?: ObjectFilterArgs | null } -export type FilePathSearchArgs = { take?: number | null; order?: FilePathSearchOrdering | null; cursor?: number[] | null; filter?: FilePathFilterArgs; groupDirectories?: boolean } +export type FilePathPagination = { cursor: { pub_id: number[] } } | { offset: number } + +export type FilePathSearchArgs = { take?: number | null; order?: FilePathSearchOrdering | null; pagination?: FilePathPagination | null; filter?: FilePathFilterArgs; groupDirectories?: boolean } export type FilePathSearchOrdering = { field: "name"; value: SortOrder } | { field: "sizeInBytes"; value: SortOrder } | { field: "dateCreated"; value: SortOrder } | { field: "dateModified"; value: SortOrder } | { field: "dateIndexed"; value: SortOrder } | { field: "object"; value: ObjectSearchOrdering } @@ -262,7 +264,9 @@ export type ObjectFilterArgs = { favorite?: boolean | null; hidden?: ObjectHidde export type ObjectHiddenFilter = "exclude" | "include" -export type ObjectSearchArgs = { take?: number | null; order?: ObjectSearchOrdering | null; cursor?: number[] | null; filter?: ObjectFilterArgs } +export type ObjectPagination = { cursor: { pub_id: number[] } } | { offset: number } + +export type ObjectSearchArgs = { take?: number | null; order?: ObjectSearchOrdering | null; pagination?: ObjectPagination | null; filter?: ObjectFilterArgs } export type ObjectSearchOrdering = { field: "dateAccessed"; value: SortOrder } | { field: "kind"; value: SortOrder }