Skip to content

Commit 41efac1

Browse files
use paginated api for search suggestions
1 parent 3a4323f commit 41efac1

6 files changed

Lines changed: 35 additions & 26 deletions

File tree

packages/web/src/app/[domain]/components/searchBar/searchSuggestionsBox.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ const SearchSuggestionsBox = forwardRef(({
155155
list: repoSuggestions,
156156
DefaultIcon: VscRepo,
157157
onSuggestionClicked: createOnSuggestionClickedHandler({ regexEscaped: true }),
158+
isClientSideSearchEnabled: false,
158159
}
159160
case "language": {
160161
return {

packages/web/src/app/[domain]/components/searchBar/useSuggestionsData.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import { useQuery } from "@tanstack/react-query";
44
import { Suggestion, SuggestionMode } from "./searchSuggestionsBox";
5-
import { getRepos, search } from "@/app/api/(client)/client";
5+
import { listRepos, search } from "@/app/api/(client)/client";
66
import { getSearchContexts } from "@/actions";
77
import { useMemo } from "react";
88
import { SearchSymbol } from "@/features/search";
@@ -37,8 +37,14 @@ export const useSuggestionsData = ({
3737
}: Props) => {
3838
const domain = useDomain();
3939
const { data: repoSuggestions, isLoading: _isLoadingRepos } = useQuery({
40-
queryKey: ["repoSuggestions"],
41-
queryFn: () => unwrapServiceError(getRepos()),
40+
queryKey: ["repoSuggestions", suggestionQuery],
41+
queryFn: () => unwrapServiceError(listRepos({
42+
page: 1,
43+
direction: "asc",
44+
sort: "name",
45+
perPage: 15,
46+
query: suggestionQuery,
47+
})),
4248
select: (data): Suggestion[] => {
4349
return data
4450
.map(r => ({

packages/web/src/app/api/(client)/client.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use client';
22

33
import { ServiceError } from "@/lib/serviceError";
4-
import { GetVersionResponse, GetReposResponse } from "@/lib/types";
4+
import { GetVersionResponse, ListReposQueryParams, ListReposResponse } from "@/lib/types";
55
import { isServiceError } from "@/lib/utils";
66
import {
77
SearchRequest,
@@ -38,12 +38,10 @@ export const search = async (body: SearchRequest): Promise<SearchResponse | Serv
3838
return result as SearchResponse | ServiceError;
3939
}
4040

41-
export const getFileSource = async ({ fileName, repository, branch }: FileSourceRequest): Promise<FileSourceResponse | ServiceError> => {
41+
export const getFileSource = async (queryParams: FileSourceRequest): Promise<FileSourceResponse | ServiceError> => {
4242
const url = new URL("/api/source", window.location.origin);
43-
url.searchParams.set("repo", repository);
44-
url.searchParams.set("path", fileName);
45-
if (branch) {
46-
url.searchParams.set("ref", branch);
43+
for (const [key, value] of Object.entries(queryParams)) {
44+
url.searchParams.set(key, value.toString());
4745
}
4846

4947
const result = await fetch(url, {
@@ -53,15 +51,20 @@ export const getFileSource = async ({ fileName, repository, branch }: FileSource
5351
return result as FileSourceResponse | ServiceError;
5452
}
5553

56-
export const getRepos = async (): Promise<GetReposResponse> => {
57-
const result = await fetch("/api/repos", {
54+
export const listRepos = async (queryParams: ListReposQueryParams): Promise<ListReposResponse | ServiceError> => {
55+
const url = new URL("/api/repos", window.location.origin);
56+
for (const [key, value] of Object.entries(queryParams)) {
57+
url.searchParams.set(key, value.toString());
58+
}
59+
60+
const result = await fetch(url, {
5861
method: "GET",
5962
headers: {
6063
"Content-Type": "application/json",
6164
},
6265
}).then(response => response.json());
6366

64-
return result as GetReposResponse | ServiceError;
67+
return result as ListReposResponse | ServiceError;
6568
}
6669

6770
export const getVersion = async (): Promise<GetVersionResponse> => {

packages/web/src/app/api/(server)/repos/route.ts

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,11 @@
11
import { NextRequest } from "next/server";
2-
import { z } from "zod";
32
import { sew } from "@/actions";
43
import { withOptionalAuthV2 } from "@/withAuthV2";
54
import { queryParamsSchemaValidationError, serviceErrorResponse } from "@/lib/serviceError";
65
import { isServiceError } from "@/lib/utils";
7-
import { repositoryQuerySchema } from "@/lib/schemas";
6+
import { listReposQueryParamsSchema, repositoryQuerySchema } from "@/lib/schemas";
87
import { buildLinkHeader, getBaseUrl } from "@/lib/pagination";
98

10-
const listReposQueryParamsSchema = z.object({
11-
page: z.coerce.number().int().positive().default(1),
12-
perPage: z.coerce.number().int().positive().max(100).default(30),
13-
sort: z.enum(['name', 'pushed']).default('name'),
14-
direction: z.enum(['asc', 'desc']).default('asc'),
15-
query: z.string().optional(),
16-
});
17-
189
export const GET = async (request: NextRequest) => {
1910
const rawParams = Object.fromEntries(
2011
Object.keys(listReposQueryParamsSchema.shape).map(key => [

packages/web/src/lib/schemas.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { checkIfOrgDomainExists } from "@/actions";
22
import { z } from "zod";
33
import { isServiceError } from "./utils";
4-
import { serviceErrorSchema } from "./serviceError";
54
import { CodeHostType } from "@sourcebot/db";
65

76
export const secretCreateRequestSchema = z.object({
@@ -72,4 +71,12 @@ export const getVersionResponseSchema = z.object({
7271
version: z.string(),
7372
});
7473

75-
export const getReposResponseSchema = z.union([repositoryQuerySchema.array(), serviceErrorSchema]);
74+
export const listReposQueryParamsSchema = z.object({
75+
page: z.coerce.number().int().positive().default(1),
76+
perPage: z.coerce.number().int().positive().max(100).default(30),
77+
sort: z.enum(['name', 'pushed']).default('name'),
78+
direction: z.enum(['asc', 'desc']).default('asc'),
79+
query: z.string().optional(),
80+
});
81+
82+
export const listReposResponseSchema = repositoryQuerySchema.array();

packages/web/src/lib/types.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { z } from "zod";
2-
import { getReposResponseSchema, getVersionResponseSchema, repositoryQuerySchema, searchContextQuerySchema } from "./schemas";
2+
import { listReposResponseSchema, getVersionResponseSchema, repositoryQuerySchema, searchContextQuerySchema, listReposQueryParamsSchema } from "./schemas";
33
import { tenancyModeSchema } from "@sourcebot/shared";
44

55
export type KeymapType = "default" | "vim";
@@ -29,4 +29,5 @@ export type NewsItem = {
2929
export type TenancyMode = z.infer<typeof tenancyModeSchema>;
3030
export type RepositoryQuery = z.infer<typeof repositoryQuerySchema>;
3131
export type SearchContextQuery = z.infer<typeof searchContextQuerySchema>;
32-
export type GetReposResponse = z.infer<typeof getReposResponseSchema>;
32+
export type ListReposResponse = z.infer<typeof listReposResponseSchema>;
33+
export type ListReposQueryParams = z.infer<typeof listReposQueryParamsSchema>;

0 commit comments

Comments
 (0)