Skip to content

Commit 655a0bd

Browse files
authored
feat: use search v2 from renku-data-services (#3680)
Closes #3677.
1 parent 87d0530 commit 655a0bd

19 files changed

Lines changed: 976 additions & 511 deletions

client/.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ src/features/projectsV2/api/projectV2.api.ts
88
src/features/sessionsV2/api/sessionLaunchersV2.generated-api.ts
99
src/features/sessionsV2/api/sessionsV2.generated-api.ts
1010
src/features/usersV2/api/users.generated-api.ts
11+
src/features/searchV2/api/searchV2Api.generated-api.ts

client/package-lock.json

Lines changed: 182 additions & 47 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

client/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@
3636
"generate-api:users": "rtk-query-codegen-openapi src/features/usersV2/api/users.api-config.ts",
3737
"update-api:dataConnectors": "node scripts/update_api_spec.js dataConnectors",
3838
"update-api:projectCloudStorage": "node scripts/update_api_spec.js projectCloudStorage",
39-
"update-api:users": "node scripts/update_api_spec.js users"
39+
"update-api:users": "node scripts/update_api_spec.js users",
40+
"update-api:searchV2": "node scripts/update_api_spec.js searchV2"
4041
},
4142
"type": "module",
4243
"dependencies": {
@@ -135,6 +136,7 @@
135136
"@typescript-eslint/parser": "^6.13.2",
136137
"@vitejs/plugin-react": "^4.3.4",
137138
"concurrently": "^8.2.2",
139+
"esbuild-runner": "^2.2.2",
138140
"eslint": "^8.54.0",
139141
"eslint-config-prettier": "^9.0.0",
140142
"eslint-plugin-jest": "^27.6.0",

client/scripts/update_api_spec.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ async function main() {
3434
updateProjectCloudStorageApi();
3535
} else if (arg.trim() === "users") {
3636
updateUsersApi();
37+
} else if (arg.trim() === "searchV2") {
38+
updateSearchV2Api();
3739
}
3840
});
3941
}
@@ -60,6 +62,13 @@ async function updateUsersApi() {
6062
});
6163
}
6264

65+
async function updateSearchV2Api() {
66+
updateApiFiles({
67+
specFile: "components/renku_data_services/search/api.spec.yaml",
68+
destFile: "src/features/searchV2/api/search.openapi.json",
69+
});
70+
}
71+
6372
async function updateApiFiles({ specFile, destFile }) {
6473
const API_SPEC_FILE = specFile;
6574
const DEST_FILE = destFile;

client/src/features/projectsV2/fields/AddProjectMemberModal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import {
3232
ModalHeader,
3333
} from "reactstrap";
3434
import { RtkOrNotebooksError } from "../../../components/errors/RtkErrorAlert";
35-
import { User } from "../../searchV2/api/searchV2Api.api";
35+
import type { User } from "../../searchV2/api/searchV2Api.api";
3636
import type {
3737
ProjectMemberPatchRequest,
3838
ProjectMemberResponse,

client/src/features/projectsV2/fields/UserSelector.tsx

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ import Select, {
3131
SingleValue,
3232
SingleValueProps,
3333
} from "react-select";
34-
import { useGetQueryQuery, User } from "../../searchV2/api/searchV2Api.api";
34+
import {
35+
useGetSearchQueryQuery,
36+
type User,
37+
} from "../../searchV2/api/searchV2Api.api";
3538
import styles from "./ProjectNamespaceFormField.module.scss";
3639

3740
const USER_REQUEST_LIMIT = 100;
@@ -47,7 +50,7 @@ function OptionOrSingleValueContent({ user }: OptionOrSingleValueContentProps) {
4750
{user.firstName} {user.lastName}
4851
</span>
4952
<span className={cx("fst-italic", "text-body-secondary", styles.kind)}>
50-
@{user.namespace}
53+
@{user.path}
5154
</span>
5255
</>
5356
);
@@ -181,7 +184,7 @@ export function UserSelector({
181184
unstyled
182185
getOptionValue={(option) => option.id}
183186
getOptionLabel={(option) =>
184-
`${option.firstName} ${option.lastName} @${option.namespace}`
187+
`${option.firstName} ${option.lastName} @${option.path}`
185188
}
186189
onChange={onChange}
187190
classNames={selectClassNames}
@@ -213,11 +216,13 @@ export function UserControl(props: UserControlProps) {
213216
data: users,
214217
isFetching,
215218
isLoading,
216-
} = useGetQueryQuery(
219+
} = useGetSearchQueryQuery(
217220
{
218-
page: 1,
219-
perPage: USER_REQUEST_LIMIT,
220-
q: `type:user ${lookupQuery}`,
221+
params: {
222+
page: 1,
223+
per_page: USER_REQUEST_LIMIT,
224+
q: `type:user ${lookupQuery}`,
225+
},
221226
},
222227
{ skip: !lookupQuery || lookupQuery == null || lookupQuery.length < 2 }
223228
);

client/src/features/searchV2/api/search.openapi.json

Lines changed: 321 additions & 244 deletions
Large diffs are not rendered by default.

client/src/features/searchV2/api/searchV2-empty.api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/dist/query/react";
2020

2121
// initialize an empty api service that we'll inject endpoints into later as needed
2222
export const searchV2EmptyApi = createApi({
23-
baseQuery: fetchBaseQuery({ baseUrl: "/ui-server/api/search" }),
23+
baseQuery: fetchBaseQuery({ baseUrl: "/api/data" }),
2424
endpoints: () => ({}),
2525
reducerPath: "searchV2Api",
2626
});

client/src/features/searchV2/api/searchV2.api-config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ import path from "path";
2323
const config: ConfigFile = {
2424
apiFile: "./searchV2-empty.api.ts",
2525
apiImport: "searchV2EmptyApi",
26-
outputFile: "./searchV2Api.api.ts",
27-
exportName: "searchV2Api",
26+
outputFile: "./searchV2Api.generated-api.ts",
27+
exportName: "searchV2GeneratedApi",
2828
hooks: true,
2929
schemaFile: path.join(__dirname, "search.openapi.json"),
3030
};
Lines changed: 38 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -1,132 +1,43 @@
1-
import { searchV2EmptyApi as api } from "./searchV2-empty.api";
2-
const injectedRtkApi = api.injectEndpoints({
1+
/*!
2+
* Copyright 2025 - Swiss Data Science Center (SDSC)
3+
* A partnership between École Polytechnique Fédérale de Lausanne (EPFL) and
4+
* Eidgenössische Technische Hochschule Zürich (ETHZ).
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
import {
20+
GetSearchQueryApiArg,
21+
GetSearchQueryApiResponse,
22+
searchV2GeneratedApi,
23+
} from "./searchV2Api.generated-api";
24+
25+
// Fixes some API endpoints
26+
export const searchV2Api = searchV2GeneratedApi.injectEndpoints({
27+
overrideExisting: true,
328
endpoints: (build) => ({
4-
getQuery: build.query<GetQueryApiResponse, GetQueryApiArg>({
5-
query: (queryArg) => ({
6-
url: `/query`,
7-
headers: { "Renku-Auth-Anon-Id": queryArg["Renku-Auth-Anon-Id"] },
8-
params: {
9-
q: queryArg.q,
10-
page: queryArg.page,
11-
per_page: queryArg.perPage,
12-
},
13-
}),
14-
}),
15-
getVersion: build.query<GetVersionApiResponse, GetVersionApiArg>({
16-
query: () => ({ url: `/version` }),
17-
}),
18-
$get: build.query<$getApiResponse, $getApiArg>({
19-
query: (queryArg) => ({
20-
url: `/`,
21-
headers: { "Renku-Auth-Anon-Id": queryArg["Renku-Auth-Anon-Id"] },
22-
params: {
23-
q: queryArg.q,
24-
page: queryArg.page,
25-
per_page: queryArg.perPage,
26-
},
29+
getSearchQuery: build.query<
30+
GetSearchQueryApiResponse,
31+
GetSearchQueryApiArg
32+
>({
33+
query: ({ params }) => ({
34+
url: "/search/query",
35+
params,
2736
}),
2837
}),
2938
}),
30-
overrideExisting: false,
3139
});
32-
export { injectedRtkApi as searchV2Api };
33-
export type GetQueryApiResponse = /** status 200 */ SearchResult;
34-
export type GetQueryApiArg = {
35-
"Renku-Auth-Anon-Id"?: string;
36-
/** User defined search query */
37-
q?: string;
38-
/** The page to retrieve, starting at 1 */
39-
page?: number;
40-
/** How many items to return for one page */
41-
perPage?: number;
42-
};
43-
export type GetVersionApiResponse = /** status 200 */ CurrentVersion;
44-
export type GetVersionApiArg = void;
45-
export type $getApiResponse = /** status 200 */ SearchResult;
46-
export type $getApiArg = {
47-
"Renku-Auth-Anon-Id"?: string;
48-
/** User defined search query */
49-
q?: string;
50-
/** The page to retrieve, starting at 1 */
51-
page?: number;
52-
/** How many items to return for one page */
53-
perPage?: number;
54-
};
55-
export type Group = {
56-
id: string;
57-
name: string;
58-
namespace: string;
59-
description?: string;
60-
score?: number;
61-
type: string;
62-
};
63-
export type User = {
64-
id: string;
65-
namespace?: string;
66-
firstName?: string;
67-
lastName?: string;
68-
score?: number;
69-
type: string;
70-
};
71-
export type UserOrGroup =
72-
| ({
73-
type: "Group";
74-
} & Group)
75-
| ({
76-
type: "User";
77-
} & User);
78-
export type Visibility = "Private" | "Public";
79-
export type Project = {
80-
id: string;
81-
name: string;
82-
slug: string;
83-
namespace?: UserOrGroup;
84-
repositories?: string[];
85-
visibility: Visibility;
86-
description?: string;
87-
createdBy?: User;
88-
creationDate: string;
89-
keywords?: string[];
90-
score?: number;
91-
type: string;
92-
};
93-
export type SearchEntity =
94-
| ({
95-
type: "Group";
96-
} & Group)
97-
| ({
98-
type: "Project";
99-
} & Project)
100-
| ({
101-
type: "User";
102-
} & User);
103-
export type MapEntityTypeInt = {
104-
[key: string]: number;
105-
};
106-
export type FacetData = {
107-
entityType: MapEntityTypeInt;
108-
};
109-
export type PageDef = {
110-
limit: number;
111-
offset: number;
112-
};
113-
export type PageWithTotals = {
114-
page: PageDef;
115-
totalResult: number;
116-
totalPages: number;
117-
prevPage?: number;
118-
nextPage?: number;
119-
};
120-
export type SearchResult = {
121-
items?: SearchEntity[];
122-
facets: FacetData;
123-
pagingInfo: PageWithTotals;
124-
};
125-
export type CurrentVersion = {
126-
name: string;
127-
version: string;
128-
headCommit: string;
129-
describedVersion: string;
130-
};
131-
export const { useGetQueryQuery, useGetVersionQuery, use$getQuery } =
132-
injectedRtkApi;
40+
41+
export const { useGetSearchQueryQuery } = searchV2Api;
42+
43+
export type * from "./searchV2Api.generated-api";

0 commit comments

Comments
 (0)