Skip to content
This repository was archived by the owner on Jan 28, 2026. It is now read-only.

Commit 989ac65

Browse files
authored
Merge pull request #190 from DigitalProductInnovationAndDevelopment/development
Development
2 parents 7fbd9e0 + dcd4d24 commit 989ac65

3 files changed

Lines changed: 437 additions & 104 deletions

File tree

frontend/src/pages/search.js

Lines changed: 185 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,25 @@ const SearchPageLight = ({ darkMode = true }) => {
9696
const searchParam = urlParams.get('search');
9797
const yearParam = urlParams.get('publication_year');
9898
const institutionIdParam = urlParams.get('institution_id');
99+
const authorIdParams = urlParams.getAll('author_id');
100+
const institutionIdParams = urlParams.getAll('institution_id');
101+
const publicationTypeParams = urlParams.getAll('publication_type');
102+
const journalIdParams = urlParams.getAll('journal_id');
103+
const startYearParam = urlParams.get('start_year');
104+
const endYearParam = urlParams.get('end_year');
99105

100106
// Check if we have any chart-related parameters (coming from graph click)
101-
const hasChartParams = searchParam || yearParam || institutionIdParam;
107+
const hasChartParams = searchParam || yearParam || institutionIdParam || authorIdParams.length > 0 ||
108+
institutionIdParams.length > 0 || publicationTypeParams.length > 0 ||
109+
journalIdParams.length > 0 || startYearParam || endYearParam;
102110

103111
if (hasChartParams) {
104112
// Has URL parameters - came from graph click, auto-search
105-
console.log('Graph navigation detected - auto-searching with params:', { searchParam, yearParam, institutionIdParam });
113+
console.log('Graph navigation detected - auto-searching with params:', {
114+
searchParam, yearParam, institutionIdParam, authorIdParams,
115+
institutionIdParams, publicationTypeParams, journalIdParams,
116+
startYearParam, endYearParam
117+
});
106118

107119
// Set search keyword if provided
108120
if (searchParam) {
@@ -114,15 +126,91 @@ const SearchPageLight = ({ darkMode = true }) => {
114126
setPublicationYear(yearParam);
115127
}
116128

117-
// Handle institution if provided
118-
if (institutionIdParam) {
119-
fetchInstitutionById(institutionIdParam);
129+
// Set year range if provided
130+
if (startYearParam) {
131+
setStartYear(startYearParam);
132+
}
133+
if (endYearParam) {
134+
setEndYear(endYearParam);
135+
}
136+
137+
// Handle authors if provided
138+
if (authorIdParams.length > 0) {
139+
console.log('Setting author details for:', authorIdParams);
140+
141+
// Get author names from URL parameters if available
142+
const authorNameParams = urlParams.getAll('author_name');
143+
console.log('Author name params received:', authorNameParams);
144+
145+
// Create author objects with real names if available, otherwise use IDs
146+
const authors = authorIdParams.map((id, index) => {
147+
const displayName = authorNameParams[index] || `Author ${id}`;
148+
console.log(`Author ${id}: using display name "${displayName}"`);
149+
return {
150+
id: `A${id}`,
151+
display_name: displayName
152+
};
153+
});
154+
155+
console.log('Setting selected authors:', authors);
156+
setSelectedAuthors(authors);
157+
}
158+
159+
// Handle institutions if provided
160+
if (institutionIdParams.length > 0) {
161+
console.log('Setting institution details for:', institutionIdParams);
162+
163+
// Get institution names from URL parameters if available
164+
const institutionNameParams = urlParams.getAll('institution_name');
165+
console.log('Institution name params received:', institutionNameParams);
166+
167+
// Create institution objects with real names if available, otherwise use IDs
168+
const institutions = institutionIdParams.map((id, index) => {
169+
const displayName = institutionNameParams[index] || `Institution ${id}`;
170+
console.log(`Institution ${id}: using display name "${displayName}"`);
171+
return {
172+
id: `I${id}`,
173+
display_name: displayName
174+
};
175+
});
176+
177+
console.log('Setting selected institutions:', institutions);
178+
setSelectedInstitutions(institutions);
179+
}
180+
181+
// Handle publication types if provided
182+
if (publicationTypeParams.length > 0) {
183+
const selectedTypes = publicationTypes.filter(pt =>
184+
publicationTypeParams.includes(pt.id)
185+
);
186+
setSelectedPublicationTypes(selectedTypes);
187+
}
188+
189+
// Handle journals if provided
190+
if (journalIdParams.length > 0) {
191+
// Fetch journal details for each journal ID
192+
Promise.all(journalIdParams.map(async (journalId) => {
193+
try {
194+
const response = await fetch(`${OPENALEX_API_BASE}/sources/S${journalId}`);
195+
if (response.ok) {
196+
const journalData = await response.json();
197+
return { id: journalData.id, display_name: journalData.display_name };
198+
}
199+
} catch (error) {
200+
console.error('Failed to fetch journal details:', error);
201+
}
202+
})).then(journals => {
203+
const validJournals = journals.filter(journal => journal);
204+
setSelectedJournals(validJournals);
205+
});
120206
}
121207

122208
// Auto-search with URL parameters
123209
setTimeout(() => {
124-
performAutoSearchWithParams(searchParam, yearParam, institutionIdParam);
125-
}, 200);
210+
performAutoSearchWithParams(searchParam, yearParam, institutionIdParam, authorIdParams,
211+
institutionIdParams, publicationTypeParams, journalIdParams,
212+
startYearParam, endYearParam);
213+
}, 1000); // Increased timeout to allow for author/institution fetching
126214
} else {
127215
// No URL parameters - any other navigation, just clear fields
128216
console.log('Direct navigation - clearing fields, no auto-search');
@@ -145,8 +233,14 @@ const SearchPageLight = ({ darkMode = true }) => {
145233
};
146234

147235
// Separate function for auto-search with URL parameters
148-
const performAutoSearchWithParams = async (searchParam, yearParam, institutionIdParam, page = 1) => {
149-
console.log('performAutoSearchWithParams called with:', { searchParam, yearParam, institutionIdParam, page });
236+
const performAutoSearchWithParams = async (searchParam, yearParam, institutionIdParam, authorIdParams,
237+
institutionIdParams, publicationTypeParams, journalIdParams,
238+
startYearParam, endYearParam, page = 1) => {
239+
console.log('performAutoSearchWithParams called with:', {
240+
searchParam, yearParam, institutionIdParam, authorIdParams,
241+
institutionIdParams, publicationTypeParams, journalIdParams,
242+
startYearParam, endYearParam, page
243+
});
150244

151245
setLoading(true);
152246
setError(null);
@@ -161,7 +255,6 @@ const SearchPageLight = ({ darkMode = true }) => {
161255
// Use search parameter directly from URL
162256
if (searchParam && searchParam.trim()) {
163257
const keyword = searchParam.trim();
164-
// Format: title_and_abstract.search:keyword (spaces become + in URL)
165258
filters.push(`title_and_abstract.search:${keyword}`);
166259
}
167260

@@ -170,9 +263,33 @@ const SearchPageLight = ({ darkMode = true }) => {
170263
filters.push(`publication_year:${yearParam.trim()}`);
171264
}
172265

173-
// Use institution parameter directly from URL
174-
if (institutionIdParam && institutionIdParam.trim()) {
175-
filters.push(`authorships.institutions.id:I${institutionIdParam.trim()}`);
266+
// Use year range parameters directly from URL
267+
if (startYearParam && endYearParam && startYearParam.trim() && endYearParam.trim()) {
268+
filters.push(`publication_year:${startYearParam.trim()}-${endYearParam.trim()}`);
269+
}
270+
271+
// Use institution parameters directly from URL
272+
if (institutionIdParams && institutionIdParams.length > 0) {
273+
const institutionFilters = institutionIdParams.map(id => `authorships.institutions.id:I${id.trim()}`);
274+
filters.push(institutionFilters.join('|'));
275+
}
276+
277+
// Use author parameters directly from URL
278+
if (authorIdParams && authorIdParams.length > 0) {
279+
const authorFilters = authorIdParams.map(id => `authorships.author.id:A${id.trim()}`);
280+
filters.push(authorFilters.join('|'));
281+
}
282+
283+
// Use publication type parameters directly from URL
284+
if (publicationTypeParams && publicationTypeParams.length > 0) {
285+
const typeFilters = publicationTypeParams.map(type => `type:${type}`);
286+
filters.push(typeFilters.join('|'));
287+
}
288+
289+
// Use journal parameters directly from URL
290+
if (journalIdParams && journalIdParams.length > 0) {
291+
const journalFilters = journalIdParams.map(id => `primary_location.source.id:S${id.trim()}`);
292+
filters.push(journalFilters.join('|'));
176293
}
177294

178295
const filterString = filters.join(',');
@@ -182,20 +299,35 @@ const SearchPageLight = ({ darkMode = true }) => {
182299
params.append('page', page.toString());
183300
params.append('sort', 'cited_by_count:desc');
184301

185-
const finalUrl = `${OPENALEX_API_BASE}/works?${params.toString()}`;
186-
console.log('Auto-search URL:', finalUrl);
187-
console.log('Search filters:', filters);
188-
console.log('URL matches format: https://openalex.org/works?page=X&filter=...&sort=cited_by_count:desc');
302+
const url = `${OPENALEX_API_BASE}/works?${params.toString()}`;
189303

190304
// Track API call for disclaimer
191-
setApiCalls([finalUrl]);
305+
setApiCalls([url]);
192306

193-
const url = `${OPENALEX_API_BASE}/works?${params.toString()}`;
194307
const response = await fetch(url);
195308
if (!response.ok) throw new Error('Failed to fetch search results');
196309
const data = await response.json();
197310

198-
setResults(data.results || []);
311+
// Deduplicate results based on work ID and title to prevent duplicates
312+
const uniqueResults = [];
313+
const seenIds = new Set();
314+
const seenTitles = new Set();
315+
316+
if (data.results && Array.isArray(data.results)) {
317+
data.results.forEach(result => {
318+
const title = result.title || result.display_name || '';
319+
const normalizedTitle = title.toLowerCase().trim();
320+
321+
// Check both ID and title for duplicates
322+
if (result.id && !seenIds.has(result.id) && !seenTitles.has(normalizedTitle)) {
323+
seenIds.add(result.id);
324+
seenTitles.add(normalizedTitle);
325+
uniqueResults.push(result);
326+
}
327+
});
328+
}
329+
330+
setResults(uniqueResults);
199331
setTotalResults(data.meta?.count || 0);
200332
setTotalPages(Math.ceil((data.meta?.count || 0) / resultsPerPage));
201333
setCurrentPage(page);
@@ -293,7 +425,26 @@ const SearchPageLight = ({ darkMode = true }) => {
293425
if (!response.ok) throw new Error('Failed to fetch search results');
294426
const data = await response.json();
295427

296-
setResults(data.results || []);
428+
// Deduplicate results based on work ID and title to prevent duplicates
429+
const uniqueResults = [];
430+
const seenIds = new Set();
431+
const seenTitles = new Set();
432+
433+
if (data.results && Array.isArray(data.results)) {
434+
data.results.forEach(result => {
435+
const title = result.title || result.display_name || '';
436+
const normalizedTitle = title.toLowerCase().trim();
437+
438+
// Check both ID and title for duplicates
439+
if (result.id && !seenIds.has(result.id) && !seenTitles.has(normalizedTitle)) {
440+
seenIds.add(result.id);
441+
seenTitles.add(normalizedTitle);
442+
uniqueResults.push(result);
443+
}
444+
});
445+
}
446+
447+
setResults(uniqueResults);
297448
setTotalResults(data.meta?.count || 0);
298449
setTotalPages(Math.ceil((data.meta?.count || 0) / resultsPerPage));
299450
setCurrentPage(page);
@@ -318,10 +469,20 @@ const SearchPageLight = ({ darkMode = true }) => {
318469
const searchParam = urlParams.get('search');
319470
const yearParam = urlParams.get('publication_year');
320471
const institutionIdParam = urlParams.get('institution_id');
321-
322-
if (searchParam || yearParam || institutionIdParam) {
472+
const authorIdParams = urlParams.getAll('author_id');
473+
const institutionIdParams = urlParams.getAll('institution_id');
474+
const publicationTypeParams = urlParams.getAll('publication_type');
475+
const journalIdParams = urlParams.getAll('journal_id');
476+
const startYearParam = urlParams.get('start_year');
477+
const endYearParam = urlParams.get('end_year');
478+
479+
if (searchParam || yearParam || institutionIdParam || authorIdParams.length > 0 ||
480+
institutionIdParams.length > 0 || publicationTypeParams.length > 0 ||
481+
journalIdParams.length > 0 || startYearParam || endYearParam) {
323482
// Use auto-search with parameters
324-
performAutoSearchWithParams(searchParam, yearParam, institutionIdParam, newPage);
483+
performAutoSearchWithParams(searchParam, yearParam, institutionIdParam, authorIdParams,
484+
institutionIdParams, publicationTypeParams, journalIdParams,
485+
startYearParam, endYearParam, newPage);
325486
} else {
326487
// Use regular search
327488
handleSearch(newPage);

0 commit comments

Comments
 (0)