Conversation
Summary of ChangesHello @vibhatha, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces an experimental, foundational search capability to the application. It provides users with a new search bar in the header and a dedicated results page, allowing them to discover various entities like individuals, organizations, and datasets. The implementation focuses on robust data fetching and dynamic routing to enhance user navigation and information retrieval. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces a basic search functionality, which is a valuable addition. The implementation is well-structured across new components, hooks, and services. My review includes suggestions to enhance robustness, maintainability, and performance by consistently using URLSearchParams for query string construction, memoizing expensive computations, and ensuring component state remains synchronized with the URL.
| const navigate = useNavigate(); | ||
| const [searchParams] = useSearchParams(); | ||
| const initialQuery = searchParams.get("q") || ""; | ||
| const [query, setQuery] = useState(initialQuery); |
There was a problem hiding this comment.
The query state is initialized from the URL but doesn't update if the URL changes (e.g., using browser back/forward buttons). This can lead to a stale query in the search bar. Using a useEffect hook will keep the component's state synchronized with the URL's q parameter.
Don't forget to import useEffect from react.
const [query, setQuery] = useState(initialQuery);
useEffect(() => {
setQuery(searchParams.get("q") || "");
}, [searchParams]);| e.preventDefault(); | ||
| const trimmedQuery = query.trim(); | ||
| if (trimmedQuery.length >= 2) { | ||
| navigate(`/search?q=${encodeURIComponent(trimmedQuery)}`); |
There was a problem hiding this comment.
| const buildDatasetUrl = (datasetName, categories) => { | ||
| // Filter to Category types only, reverse to get root → child order | ||
| const categoryChain = categories | ||
| .filter((c) => c.kind?.major === "Category") | ||
| .reverse(); | ||
|
|
||
| if (categoryChain.length === 0) return "/data"; | ||
|
|
||
| const lastCategoryId = categoryChain[categoryChain.length - 1].id; | ||
|
|
||
| // Build breadcrumb array | ||
| const breadcrumb = categoryChain.map((cat) => ({ | ||
| label: formatCategoryName(cat.name), | ||
| path: `/data?categoryIds=${encodeURIComponent(JSON.stringify([cat.id]))}`, | ||
| })); | ||
|
|
||
| // Add dataset as final breadcrumb | ||
| breadcrumb.push({ | ||
| label: datasetName, | ||
| path: `/data?datasetName=${encodeURIComponent(datasetName)}&categoryIds=${encodeURIComponent(JSON.stringify([lastCategoryId]))}`, | ||
| }); | ||
|
|
||
| // Build final URL | ||
| const params = new URLSearchParams({ | ||
| categoryIds: JSON.stringify([lastCategoryId]), | ||
| datasetName: datasetName, | ||
| breadcrumb: JSON.stringify(breadcrumb), | ||
| }); | ||
|
|
||
| return `/data?${params.toString()}`; | ||
| }; |
There was a problem hiding this comment.
This function can be simplified and made more robust by consistently using URLSearchParams to build query strings. This approach automatically handles URL encoding, making the code cleaner and less prone to errors.
const buildDatasetUrl = (datasetName, categories) => {
// Filter to Category types only, reverse to get root → child order
const categoryChain = categories
.filter((c) => c.kind?.major === "Category")
.reverse();
if (categoryChain.length === 0) return "/data";
const lastCategoryId = categoryChain[categoryChain.length - 1].id;
// Build breadcrumb array
const breadcrumb = categoryChain.map((cat) => {
const params = new URLSearchParams({ categoryIds: JSON.stringify([cat.id]) });
return {
label: formatCategoryName(cat.name),
path: `/data?${params.toString()}`,
};
});
// Add dataset as final breadcrumb
const datasetParams = new URLSearchParams({
datasetName,
categoryIds: JSON.stringify([lastCategoryId]),
});
breadcrumb.push({
label: datasetName,
path: `/data?${datasetParams.toString()}`,
});
// Build final URL
const finalParams = new URLSearchParams({
categoryIds: JSON.stringify([lastCategoryId]),
datasetName,
breadcrumb: JSON.stringify(breadcrumb),
});
return `/data?${finalParams.toString()}`;
};| const sortedResults = data?.results | ||
| ? [...data.results].sort((a, b) => (b.match_score || 0) - (a.match_score || 0)) | ||
| : []; |
There was a problem hiding this comment.
The sortedResults array is recalculated on every render. To optimize performance, you can memoize this calculation using the useMemo hook. This will prevent re-sorting the results unless the data from the search query changes. Remember to import useMemo from react.
const sortedResults = useMemo(
() =>
data?.results
? [...data.results].sort((a, b) => (b.match_score || 0) - (a.match_score || 0))
: [],
[data]
);| e.preventDefault(); | ||
| const trimmedQuery = localQuery.trim(); | ||
| if (trimmedQuery.length >= 2) { | ||
| navigate(`/search?q=${encodeURIComponent(trimmedQuery)}`); |
| navigate( | ||
| `/organization?filterByName=${encodeURIComponent(result.name)}&viewMode=Grid&filterByType=all` | ||
| ); |
There was a problem hiding this comment.
This is an experimental work on adding a basic Search functionality.
Summary
Implemented a full-text search feature that allows users to search across persons, departments, ministers, and datasets using the GI-SERVICE backend.
Features
Files Added
Files Modified
API Integration
GET /v1/search?q={query}- Main search endpointGET /v1/data/datasets/{datasetId}/categories- Dataset category hierarchy for navigation