diff --git a/client/src/pages/openalex-ror/results/index.jsx b/client/src/pages/openalex-ror/results/index.jsx index b5e1933..052f5d6 100644 --- a/client/src/pages/openalex-ror/results/index.jsx +++ b/client/src/pages/openalex-ror/results/index.jsx @@ -3,12 +3,14 @@ import { Button, Col, Container, - Modal, ModalContent, ModalFooter, ModalTitle, + Modal, + ModalContent, + ModalFooter, + ModalTitle, Row, Tag, Text, TextInput, - Title, } from '@dataesr/dsfr-plus'; import { useQuery } from '@tanstack/react-query'; import { useEffect, useState } from 'react'; @@ -55,15 +57,23 @@ export default function Affiliations() { const [rorMessageType, setRorMessageType] = useState(''); const [selectedOpenAlex, setSelectedOpenAlex] = useState([]); const [timer, setTimer] = useState(); + const [uniqueRors, setUniqueRors] = useState({}); const { data, error, isFetched, isFetching, refetch } = useQuery({ queryKey: ['openalex-ror', JSON.stringify(body)], // Search for works from affiliations for each affiliation strictly longer than 2 letters - queryFn: () => getWorks({ - ...body, - affiliationStrings: body.affiliations.filter((affiliation) => !affiliation.isDisabled).map((affiliation) => affiliation.label), - rors: body.affiliations.filter((affiliation) => affiliation.isRor).map((affiliation) => affiliation.label), - }, toast), + queryFn: () => getWorks( + { + ...body, + affiliationStrings: body.affiliations + .filter((affiliation) => !affiliation.isDisabled) + .map((affiliation) => affiliation.label), + rors: body.affiliations + .filter((affiliation) => affiliation.isRor) + .map((affiliation) => affiliation.label), + }, + toast, + ), enabled: false, }); @@ -83,18 +93,8 @@ export default function Affiliations() { setAllOpenalexCorrections(getAffiliationsCorrections(newAffiliations)); }; - const listOfUniqueRors = {}; - selectedOpenAlex.forEach((affiliation) => { - affiliation.rors.forEach((ror) => { - if (!Object.keys(listOfUniqueRors).includes(ror.rorId)) { - listOfUniqueRors[ror.rorId] = { ...ror, countAffiliations: 0 }; - } - listOfUniqueRors[ror.rorId].countAffiliations += 1; - }); - }); - const actionToOpenAlex = (action, _ror) => { - selectedOpenAlex.map((item) => { + selectedOpenAlex.forEach((item) => { let rorsToCorrect = item.rorsToCorrect.trim().split(';'); if (action === 'add') { rorsToCorrect.push(_ror.rorId); @@ -112,11 +112,41 @@ export default function Affiliations() { const applyActions = () => { removeList.forEach((rorId) => { - const rorItem = listOfUniqueRors[rorId]; + const rorItem = uniqueRors[rorId]; actionToOpenAlex('remove', rorItem); }); }; + useEffect(() => { + const uniqueRorsTmp = {}; + selectedOpenAlex.forEach((affiliation) => { + affiliation.rors.forEach((_ror) => { + if (!Object.keys(uniqueRorsTmp).includes(_ror.rorId)) { + uniqueRorsTmp[_ror.rorId] = { ..._ror, countAffiliations: 0 }; + } + uniqueRorsTmp[_ror.rorId].countAffiliations += 1; + }); + }); + setUniqueRors(uniqueRorsTmp); + }, [selectedOpenAlex]); + + useEffect(() => { + const get = async () => { + const addedRorsData = await Promise.all( + addList.map((add) => getRorData(add)), + ); + const uniqueRorsTmp = {}; + addedRorsData.flat().forEach((dd) => { + if (!Object.keys(uniqueRors).includes(dd.rorId)) { + uniqueRorsTmp[dd.rorId] = { ...dd, countAffiliations: 0 }; + } + }); + setUniqueRors({ ...uniqueRors, ...uniqueRorsTmp }); + }; + get(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [addList]); + useEffect(() => { const getData = async () => { const queryParams = { @@ -125,27 +155,32 @@ export default function Affiliations() { }; queryParams.deletedAffiliations = []; queryParams.rorExclusions = []; - queryParams.affiliations = await Promise.all(searchParams.getAll('affiliations').map(async (affiliation) => { - const label = normalize(affiliation); - let children = []; - // Compute rorNames - if (isRor(label)) { - const rorNames = await getRorData(label); - children = rorNames.map((item) => item.names).flat().map((name) => ({ - isDisabled: name.length < VITE_APP_TAG_LIMIT, - isRor: false, - label: name, - source: 'ror', - })); - } - return { - children, - isDisabled: label.length < VITE_APP_TAG_LIMIT, - isRor: isRor(label), - label, - source: 'user', - }; - })); + queryParams.affiliations = await Promise.all( + searchParams.getAll('affiliations').map(async (affiliation) => { + const label = normalize(affiliation); + let children = []; + // Compute rorNames + if (isRor(label)) { + const rorNames = await getRorData(label); + children = rorNames + .map((item) => item.names) + .flat() + .map((name) => ({ + isDisabled: name.length < VITE_APP_TAG_LIMIT, + isRor: false, + label: name, + source: 'ror', + })); + } + return { + children, + isDisabled: label.length < VITE_APP_TAG_LIMIT, + isRor: isRor(label), + label, + source: 'user', + }; + }), + ); searchParams.getAll('deletedAffiliations').forEach((item) => { if (isRor(item)) { @@ -172,13 +207,17 @@ export default function Affiliations() { clearTimeout(timer); } const timerTmp = setTimeout(() => { - const openAlexAffiliations = affiliations.filter((affiliation) => affiliation.source === 'OpenAlex'); - const filteredAffiliationsTmp = openAlexAffiliations.filter((affiliation) => { - const regex = new RegExp(removeDiacritics(filteredAffiliationName)); - return regex.test( - affiliation.key.replace('[ source: ', '').replace(' ]', ''), - ); - }); + const openAlexAffiliations = affiliations.filter( + (affiliation) => affiliation.source === 'OpenAlex', + ); + const filteredAffiliationsTmp = openAlexAffiliations.filter( + (affiliation) => { + const regex = new RegExp(removeDiacritics(filteredAffiliationName)); + return regex.test( + affiliation.key.replace('[ source: ', '').replace(' ]', ''), + ); + }, + ); // Recompute corrections only when the array has changed if (filteredAffiliationsTmp.length !== filteredAffiliations.length) { setAllOpenalexCorrections( @@ -199,13 +238,13 @@ export default function Affiliations() { } else if (!isRor(ror)) { setRorMessage('Invalid ROR'); setRorMessageType('error'); - } else if (Object.keys(listOfUniqueRors).includes(ror)) { + } else if (Object.keys(uniqueRors).includes(ror)) { setRorMessage('Already listed ROR'); setRorMessageType('error'); } else { setRorMessage('Valid ROR'); setRorMessageType('valid'); - }; + } }, [ror]); return ( @@ -213,12 +252,18 @@ export default function Affiliations() {
{isFetching && ( - +
Loading data from OpenAlex, please wait...

- OpenAlex + OpenAlex
Loading
@@ -253,11 +298,18 @@ export default function Affiliations() {
-
- + {`Start: ${body.startYear}`} @@ -271,15 +323,19 @@ export default function Affiliations() {
-
- {body.affiliations.map((affiliation) => ( @@ -287,7 +343,9 @@ export default function Affiliations() { {affiliation.children.map((child) => ( @@ -302,16 +360,27 @@ export default function Affiliations() {
- setIsModalOpen((prev) => !prev)} size="xl"> + setIsModalOpen((prev) => !prev)} + size="xl" + > Modify ROR in - {selectedOpenAlex.length} - {` OpenAlex selected affiliation${selectedOpenAlex.length > 1 ? 's' : ''}`} + + {selectedOpenAlex.length} + + {` OpenAlex selected affiliation${ + selectedOpenAlex.length > 1 ? 's' : '' + }`} -
+
@@ -325,130 +394,103 @@ export default function Affiliations() { - {Object.values(listOfUniqueRors).map((rorItem) => ( - - - - ROR logo - { - removeList.includes(rorItem.rorId) ? ( + {Object.values(uniqueRors).map( + (rorItem) => ( + + + + ROR logo + {removeList.includes( + rorItem.rorId, + ) ? ( {` https://ror.org/${rorItem.rorId}`} - ) : ( - ` https://ror.org/${rorItem.rorId}` - ) - } - - - - {`${rorItem.rorCountry} - - { - removeList.includes(rorItem.rorId) ? ( - {rorItem.rorName} - ) : ( - rorItem.rorName - ) - } - - - {rorItem.countAffiliations} - - { - removeList.includes(rorItem.rorId) ? ( + ) : ( + ` https://ror.org/${rorItem.rorId}` + )} + + + + {`${rorItem.rorCountry} + + {removeList.includes( + rorItem.rorId, + ) ? ( + + {rorItem.rorName} + + ) : ( + rorItem.rorName + )} + + + + {rorItem.countAffiliations} + {' '} + / + {' '} + {selectedOpenAlex.length} + + + {removeList.includes( + rorItem.rorId, + ) ? ( <> - - - - ))} - {addList.map((add) => ( - - - - ROR logo - { - removeList.includes(add.rorId) ? ( - {` https://ror.org/${add.rorId}`} - ) : ( - ` https://ror.org/${add.rorId}` - ) - } - - - - {`${add.country} - - { - removeList.includes(add.rorId) ? ( - {add.names[0]} + ) : ( - add.names[0] - ) - } - - - {add?.countAffiliations} - - { - removeList.includes(add.rorId) ? ( - <> - - - ))} + )} + + + + ), + )}
@@ -463,15 +505,15 @@ export default function Affiliations() { messageType={rorMessageType} message={rorMessage} onChange={(e) => setRor(e.target.value)} + value={ror} /> -
+
- {selectedOpenAlex.length} + + {selectedOpenAlex.length} + - {` selected affiliation${selectedOpenAlex.length === 1 ? '' : 's'}`} + {` selected affiliation${ + selectedOpenAlex.length === 1 ? '' : 's' + }`}