Skip to content

Commit c8cc226

Browse files
committed
updated frontend to update query cache with additional information provdided by the search endpoint
1 parent 43eb361 commit c8cc226

File tree

7 files changed

+132
-10
lines changed

7 files changed

+132
-10
lines changed

INSTRUCTIONS.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# DATS Coding Instructions
2+
3+
useCallback: wrap all functions in useCallback if
4+
5+
- it uses dispatch
6+
- it uses a mutation
7+
- the function is used by a non-presentational component. Presentational components are simple components that are either plain MUI components, or components that compose multiple MUI component with NO additional complex logic.
8+
9+
Hi, I want you to help me start optimizing my components. I plan to properly memoize my components using useCallback, useMemo and memo.
10+
Please optimize all components in this directory (and all sub-directories) frontend/src/components/Memo/ according to the following guidelines:
11+
12+
Functions:
13+
I want you to memoize all functions with useCallback. If there are any inline function definitions (in the rendering part), please create a new callback function for this.
14+
15+
Components:
16+
If possible, try to memoize the component itself using memo. All my components should be normal functions and exported default at the bottom. If you think the component can be memoized with memo(), wrap the export default!
17+
If there are multiple components defined inside a file, still, only wrap the component that is exported.
18+
If the component is a very basic presentational component, there is no need to memoize it.
19+
20+
Mutations:
21+
Sometimes, I am using react query mutations. Beware! The mutation is not a stable reference and should not used in dependency arrays of useCallbacks. We need to destructure the mutation like that {mutate: functionName, isPending } = useMyMutation(). The functionName is now a stable reference that can be used
22+
23+
Computed variables:
24+
In case you see any variables that are a result of heavy computation, please consider using useMemo.
25+
26+
Rendering:
27+
By default, please do not useMemo to memoize components that are rendered. Instead, first see if we can optimize the rendered component.
28+
Only as a last resort, memoize the component with useMemo.
29+
30+
Comments:
31+
Keep all my comments! Never delete my comments! You may add new comments if you think that is necessary, but DO NOT delete my comments.
32+
33+
General Guidelines:
34+
35+
- DO NOT rename existing variables, functions, components, except if they have typos!
36+
- only optimize Components, do not optimize hooks
37+
- DO NOT move (sub-)components inside a file, the order is fine!
38+
39+
Sometimes, the component is already optimized. Then, you can simply skip it!

frontend/src/api/SdocHooks.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ const useGetAnnotators = (sdocId: number | null | undefined) =>
110110
SourceDocumentService.getAnnotators({
111111
sdocId: sdocId!,
112112
}),
113+
staleTime: 1000 * 60 * 5,
113114
enabled: !!sdocId,
114115
});
115116

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/* generated using openapi-typescript-codegen -- do not edit */
2+
/* istanbul ignore file */
3+
/* tslint:disable */
4+
/* eslint-disable */
5+
import type { ElasticSearchDocumentHit } from "./ElasticSearchDocumentHit";
6+
import type { SourceDocumentRead } from "./SourceDocumentRead";
7+
export type PaginatedSDocHits = {
8+
/**
9+
* The IDs, scores and (optional) highlights of Document search results on the requested page.
10+
*/
11+
hits: Array<ElasticSearchDocumentHit>;
12+
/**
13+
* A dictionary with the additional information about the documents. The key is the document ID and the value is a dictionary with the additional information.
14+
*/
15+
sdocs: Record<string, SourceDocumentRead>;
16+
/**
17+
* A dictionary with the additional information about the documents. The key is the document ID and the value is a dictionary with the additional information.
18+
*/
19+
annotators: Record<string, Array<number>>;
20+
/**
21+
* A dictionary with the additional information about the documents. The key is the document ID and the value is a dictionary with the additional information.
22+
*/
23+
tags: Record<string, Array<number>>;
24+
/**
25+
* The total number of hits. Used for pagination.
26+
*/
27+
total_results: number;
28+
};

frontend/src/api/openapi/services/SearchService.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import type { Body_search_find_similar_sentences } from "../models/Body_search_f
77
import type { Body_search_search_sdocs } from "../models/Body_search_search_sdocs";
88
import type { ColumnInfo_SdocColumns_ } from "../models/ColumnInfo_SdocColumns_";
99
import type { KeywordStat } from "../models/KeywordStat";
10-
import type { PaginatedElasticSearchDocumentHits } from "../models/PaginatedElasticSearchDocumentHits";
10+
import type { PaginatedSDocHits } from "../models/PaginatedSDocHits";
1111
import type { SimSearchImageHit } from "../models/SimSearchImageHit";
1212
import type { SimSearchSentenceHit } from "../models/SimSearchSentenceHit";
1313
import type { SpanEntityStat } from "../models/SpanEntityStat";
@@ -39,7 +39,7 @@ export class SearchService {
3939
}
4040
/**
4141
* Returns all SourceDocument Ids and their scores and (optional) hightlights that match the query parameters.
42-
* @returns PaginatedElasticSearchDocumentHits Successful Response
42+
* @returns PaginatedSDocHits Successful Response
4343
* @throws ApiError
4444
*/
4545
public static searchSdocs({
@@ -58,7 +58,7 @@ export class SearchService {
5858
requestBody: Body_search_search_sdocs;
5959
pageNumber?: number | null;
6060
pageSize?: number | null;
61-
}): CancelablePromise<PaginatedElasticSearchDocumentHits> {
61+
}): CancelablePromise<PaginatedSDocHits> {
6262
return __request(OpenAPI, {
6363
method: "POST",
6464
url: "/search/sdoc",

frontend/src/components/Tag/TagMenu/TagMenu.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ function TagMenuContent({
100100
const { mutate: addTagsMutation } = TagHooks.useBulkLinkDocumentTags();
101101
const { mutate: removeTagsMutation } = TagHooks.useBulkUnlinkDocumentTags();
102102
const handleClickTag = (tagId: number) => () => {
103-
console.log("HI!");
104103
if (initialChecked.get(tagId) === CheckboxState.CHECKED) {
105104
removeTagsMutation({
106105
requestBody: {

frontend/src/openapi.json

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2802,9 +2802,7 @@
28022802
"responses": {
28032803
"200": {
28042804
"description": "Successful Response",
2805-
"content": {
2806-
"application/json": { "schema": { "$ref": "#/components/schemas/PaginatedElasticSearchDocumentHits" } }
2807-
}
2805+
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/PaginatedSDocHits" } } }
28082806
},
28092807
"422": {
28102808
"description": "Validation Error",
@@ -8091,6 +8089,42 @@
80918089
"required": ["hits", "total_results"],
80928090
"title": "PaginatedElasticSearchDocumentHits"
80938091
},
8092+
"PaginatedSDocHits": {
8093+
"properties": {
8094+
"hits": {
8095+
"items": { "$ref": "#/components/schemas/ElasticSearchDocumentHit" },
8096+
"type": "array",
8097+
"title": "Hits",
8098+
"description": "The IDs, scores and (optional) highlights of Document search results on the requested page."
8099+
},
8100+
"sdocs": {
8101+
"additionalProperties": { "$ref": "#/components/schemas/SourceDocumentRead" },
8102+
"type": "object",
8103+
"title": "Sdocs",
8104+
"description": "A dictionary with the additional information about the documents. The key is the document ID and the value is a dictionary with the additional information."
8105+
},
8106+
"annotators": {
8107+
"additionalProperties": { "items": { "type": "integer" }, "type": "array" },
8108+
"type": "object",
8109+
"title": "Annotators",
8110+
"description": "A dictionary with the additional information about the documents. The key is the document ID and the value is a dictionary with the additional information."
8111+
},
8112+
"tags": {
8113+
"additionalProperties": { "items": { "type": "integer" }, "type": "array" },
8114+
"type": "object",
8115+
"title": "Tags",
8116+
"description": "A dictionary with the additional information about the documents. The key is the document ID and the value is a dictionary with the additional information."
8117+
},
8118+
"total_results": {
8119+
"type": "integer",
8120+
"title": "Total Results",
8121+
"description": "The total number of hits. Used for pagination."
8122+
}
8123+
},
8124+
"type": "object",
8125+
"required": ["hits", "sdocs", "annotators", "tags", "total_results"],
8126+
"title": "PaginatedSDocHits"
8127+
},
80948128
"PreProProjectStatus": {
80958129
"properties": {
80968130
"project_id": {

frontend/src/views/search/DocumentSearch/SearchDocumentTable.tsx

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { ElasticSearchDocumentHit } from "../../../api/openapi/models/ElasticSea
1717
import { PaginatedElasticSearchDocumentHits } from "../../../api/openapi/models/PaginatedElasticSearchDocumentHits.ts";
1818
import { SdocColumns } from "../../../api/openapi/models/SdocColumns.ts";
1919
import { SortDirection } from "../../../api/openapi/models/SortDirection.ts";
20+
import { SourceDocumentRead } from "../../../api/openapi/models/SourceDocumentRead.ts";
2021
import { SearchService } from "../../../api/openapi/services/SearchService.ts";
2122
import { useAuth } from "../../../auth/useAuth.ts";
2223
import DocumentUploadButton from "../../../components/DocumentUpload/DocumentUploadButton.tsx";
@@ -34,6 +35,7 @@ import SdocRenderer from "../../../components/SourceDocument/SdocRenderer.tsx";
3435
import SdocTagsRenderer from "../../../components/SourceDocument/SdocTagRenderer.tsx";
3536
import TagMenuButton from "../../../components/Tag/TagMenu/TagMenuButton.tsx";
3637
import { selectSelectedDocumentIds } from "../../../components/tableSlice.ts";
38+
import queryClient from "../../../plugins/ReactQueryClient.ts";
3739
import { useAppDispatch, useAppSelector } from "../../../plugins/ReduxHooks.ts";
3840
import { RootState } from "../../../store/store.ts";
3941
import { useReduxConnector } from "../../../utils/useReduxConnector.ts";
@@ -166,8 +168,8 @@ function SearchDocumentTable({ projectId, onSearchResultsChange }: DocumentTable
166168
sortingModel, // refetch when sorting changes
167169
fetchSize,
168170
],
169-
queryFn: ({ pageParam }) =>
170-
SearchService.searchSdocs({
171+
queryFn: async ({ pageParam }) => {
172+
const data = await SearchService.searchSdocs({
171173
searchQuery: searchQuery || "",
172174
projectId: projectId!,
173175
highlight: true,
@@ -181,7 +183,26 @@ function SearchDocumentTable({ projectId, onSearchResultsChange }: DocumentTable
181183
},
182184
pageNumber: pageParam as number,
183185
pageSize: fetchSize,
184-
}),
186+
});
187+
188+
// initialize the query cache
189+
console.log("Initializing sdoc query cache");
190+
Object.entries(data.sdocs).forEach(([sdocId, sdoc]) => {
191+
queryClient.setQueryData<SourceDocumentRead>([QueryKey.SDOC, parseInt(sdocId)], sdoc);
192+
queryClient.setQueryData<number>([QueryKey.SDOC_ID, projectId, sdoc.filename], sdoc.id);
193+
});
194+
195+
console.log("Initializing annotators query cache");
196+
Object.entries(data.annotators).forEach(([sdocId, annotators]) => {
197+
queryClient.setQueryData<number[]>([QueryKey.SDOC_ANNOTATORS, parseInt(sdocId)], annotators);
198+
});
199+
200+
console.log("Initializing tags query cache");
201+
Object.entries(data.tags).forEach(([sdocId, tags]) => {
202+
queryClient.setQueryData<number[]>([QueryKey.SDOC_TAGS, parseInt(sdocId)], tags);
203+
});
204+
return data;
205+
},
185206
initialPageParam: 0,
186207
enabled: !!projectId,
187208
getNextPageParam: (_lastGroup, groups) => {

0 commit comments

Comments
 (0)