diff --git a/client/src/components/tag-input/index.jsx b/client/src/components/tag-input/index.jsx
index 357b59fe..aeb6c13b 100644
--- a/client/src/components/tag-input/index.jsx
+++ b/client/src/components/tag-input/index.jsx
@@ -11,9 +11,11 @@ export default function TagInput({
onTagsChange,
placeholder,
tags,
+ deletedTags,
}) {
const [input, setInput] = useState('');
const [values, setValues] = useState(tags);
+ const [excludedValues, setExcludedValues] = useState(deletedTags);
const handleKeyDown = (e) => {
if ([9, 13].includes(e.keyCode) && input) {
@@ -25,7 +27,7 @@ export default function TagInput({
const newValues = [...values, { label: input.trim(), source: 'user' }];
setValues(newValues);
setInput('');
- onTagsChange(newValues);
+ onTagsChange(newValues, excludedValues);
}
};
@@ -38,13 +40,18 @@ export default function TagInput({
}, [input, onInputHandler]);
const handleDeleteClick = (tag) => {
+ const deletedValues = excludedValues;
+ console.log('handleDeleteClick - deletedValues', deletedValues);
+ deletedValues.push(tag);
const newValues = [...values.filter((el) => el !== tag)];
- // TODO this is buggy now, deleted tags should be memorized in the URL (searchParams)
setValues(newValues);
- onTagsChange(newValues);
+ setExcludedValues(deletedValues);
+ console.log('deletedValues', deletedValues);
+ onTagsChange(newValues, deletedValues);
};
useEffect(() => setValues(tags), [tags]);
+ useEffect(() => setExcludedValues(deletedTags), [deletedTags]);
return (
@@ -95,6 +102,7 @@ TagInput.propTypes = {
onTagsChange: PropTypes.func.isRequired,
placeholder: PropTypes.string,
tags: PropTypes.arrayOf(PropTypes.object),
+ deletedTags: PropTypes.arrayOf(PropTypes.object),
};
TagInput.defaultProps = {
@@ -104,4 +112,5 @@ TagInput.defaultProps = {
onInputHandler: () => { },
placeholder: '',
tags: [],
+ deletedTags: [],
};
diff --git a/client/src/pages/actions.jsx b/client/src/pages/actions.jsx
index e28b3881..5cb7e2f5 100644
--- a/client/src/pages/actions.jsx
+++ b/client/src/pages/actions.jsx
@@ -80,7 +80,7 @@ Actions.propTypes = {
worksNumber: PropTypes.number.isRequired,
})).isRequired,
allDatasets: PropTypes.arrayOf(PropTypes.shape({
- affiliations: PropTypes.arrayOf(PropTypes.object).isRequired,
+ affiliations: PropTypes.arrayOf(PropTypes.object),
allIds: PropTypes.arrayOf(PropTypes.object).isRequired,
datasource: PropTypes.arrayOf(PropTypes.string).isRequired,
id: PropTypes.string.isRequired,
diff --git a/client/src/pages/affiliationsView.jsx b/client/src/pages/affiliationsView.jsx
index 40a69b9e..30f66217 100644
--- a/client/src/pages/affiliationsView.jsx
+++ b/client/src/pages/affiliationsView.jsx
@@ -2,7 +2,7 @@ import { Column } from 'primereact/column';
import { DataTable } from 'primereact/datatable';
import PropTypes from 'prop-types';
-import { nameTemplate, rorTemplate, statusTemplate } from '../utils/templates';
+import { nameTemplate, rorTemplate, statusTemplate, worksExampleTemplate } from '../utils/templates';
export default function AffiliationsView({
allAffiliations,
@@ -33,10 +33,11 @@ export default function AffiliationsView({
value={allAffiliations}
>
-
-
-
-
+
+
+
+
+
);
}
diff --git a/client/src/pages/datasetsTab.jsx b/client/src/pages/datasetsTab.jsx
index 546f429c..35e8c199 100644
--- a/client/src/pages/datasetsTab.jsx
+++ b/client/src/pages/datasetsTab.jsx
@@ -199,7 +199,7 @@ export default function DatasetsTab({ datasets, publishers, selectedDatasets, se
DatasetsTab.propTypes = {
datasets: PropTypes.arrayOf(PropTypes.shape({
- affiliations: PropTypes.arrayOf(PropTypes.object).isRequired,
+ affiliations: PropTypes.arrayOf(PropTypes.object),
allIds: PropTypes.arrayOf(PropTypes.object).isRequired,
authors: PropTypes.arrayOf(PropTypes.string).isRequired,
datasource: PropTypes.arrayOf(PropTypes.string).isRequired,
@@ -210,7 +210,7 @@ DatasetsTab.propTypes = {
})).isRequired,
publishers: PropTypes.object.isRequired,
selectedDatasets: PropTypes.arrayOf(PropTypes.shape({
- affiliations: PropTypes.arrayOf(PropTypes.object).isRequired,
+ affiliations: PropTypes.arrayOf(PropTypes.object),
allIds: PropTypes.arrayOf(PropTypes.object).isRequired,
authors: PropTypes.arrayOf(PropTypes.string).isRequired,
datasource: PropTypes.arrayOf(PropTypes.string).isRequired,
diff --git a/client/src/pages/filters.jsx b/client/src/pages/filters.jsx
index 8481d7ad..4ec357ee 100644
--- a/client/src/pages/filters.jsx
+++ b/client/src/pages/filters.jsx
@@ -31,21 +31,25 @@ export default function Filters({ sendQuery }) {
if (searchParams.size === 0) {
setSearchParams({
affiliations: [],
+ deletedAffiliations: [],
datasets: false,
- endYear: '2021',
- startYear: '2021',
+ endYear: '2023',
+ startYear: '2023',
});
setTags([]);
} else {
setCurrentSearchParams({
affiliations: searchParams.getAll('affiliations'),
+ deletedAffiliations: searchParams.getAll('deletedAffiliations'),
datasets: searchParams.get('datasets') === 'true',
- endYear: searchParams.get('endYear'),
- startYear: searchParams.get('startYear'),
+ endYear: searchParams.get('endYear', '2023'),
+ startYear: searchParams.get('startYear', '2023'),
});
const affiliations = searchParams.getAll('affiliations');
+ const deletedAffiliations = searchParams.getAll('deletedAffiliations') || [];
const queries = affiliations.map((affiliation) => getRorData(affiliation));
- const rorNames = await Promise.all(queries);
+ let rorNames = await Promise.all(queries);
+ rorNames = rorNames.filter((aff) => !deletedAffiliations.includes(aff));
const allTags = [];
const knownTags = {};
affiliations.forEach((affiliation) => {
@@ -58,14 +62,18 @@ export default function Filters({ sendQuery }) {
});
rorNames.flat().forEach((rorElt) => {
if (knownTags[rorElt.rorId.toLowerCase()] === undefined) {
- allTags.push({ label: rorElt.rorId, source: 'ror', type: 'rorId' });
- knownTags[rorElt.rorId.toLowerCase()] = 1;
+ if (!deletedAffiliations.includes(rorElt.rorId)) {
+ allTags.push({ label: rorElt.rorId, source: 'ror', type: 'rorId' });
+ knownTags[rorElt.rorId.toLowerCase()] = 1;
+ }
}
rorElt.names.forEach((rorName) => {
if (knownTags[rorName.toLowerCase()] === undefined) {
- const isDangerous = rorName.length < 4;
- allTags.push({ label: rorName, source: 'ror', type: 'affiliationString', rorId: rorElt.rorId, isDangerous });
- knownTags[rorName.toLowerCase()] = 1;
+ if (!deletedAffiliations.includes(rorName)) {
+ const isDangerous = rorName.length < 4;
+ allTags.push({ label: rorName, source: 'ror', type: 'affiliationString', rorId: rorElt.rorId, isDangerous });
+ knownTags[rorName.toLowerCase()] = 1;
+ }
}
});
});
@@ -75,8 +83,13 @@ export default function Filters({ sendQuery }) {
getData();
}, [searchParams, setSearchParams]);
- const onTagsChange = async (affiliations) => {
- setSearchParams({ ...currentSearchParams, affiliations: affiliations.filter((affiliation) => affiliation.source === 'user').map((affiliation) => affiliation.label) });
+ const onTagsChange = async (affiliations, deletedAffiliations) => {
+ const previousDeleted = currentSearchParams.deletedAffiliations || [];
+ setSearchParams({
+ ...currentSearchParams,
+ affiliations: affiliations.filter((affiliation) => affiliation.source === 'user').map((affiliation) => affiliation.label),
+ deletedAffiliations: deletedAffiliations.filter((affiliation) => affiliation.source !== 'user').map((affiliation) => affiliation.label).concat(previousDeleted),
+ });
};
const checkAndSendQuery = () => {
@@ -141,7 +154,7 @@ export default function Filters({ sendQuery }) {
{
if (data) {
// TODO do it on the API
- const allDatasetsTmp = data.datasets.results
- .map((dataset) => ({
+ const allDatasetsTmp = data.datasets?.results
+ ?.map((dataset) => ({
...dataset,
affiliationsHtml: getAffiliationsHtmlField(dataset, regexp),
affiliationsTooltip: getAffiliationsTooltipField(dataset),
status: status.tobedecided.id,
}));
- const allPublicationsTmp = data.publications.results
- .map((publication) => ({
+ const allPublicationsTmp = data.publications?.results
+ ?.map((publication) => ({
...publication,
affiliationsHtml: getAffiliationsHtmlField(publication, regexp),
affiliationsTooltip: getAffiliationsTooltipField(publication),
@@ -164,7 +164,7 @@ export default function Home() {
>
)}
- {!isFetching && (allAffiliations.length > 0 || allDatasets.length > 0 || allPublications.length > 0) && (
+ {!isFetching && (allAffiliations?.length > 0 || allDatasets?.length > 0 || allPublications?.length > 0) && (
diff --git a/client/src/utils/templates.jsx b/client/src/utils/templates.jsx
index deedd836..91036a56 100644
--- a/client/src/utils/templates.jsx
+++ b/client/src/utils/templates.jsx
@@ -40,6 +40,19 @@ const linkedDOITemplate = (rowData) => {
return ;
};
+//TODO: is there a way not to duplicate code : linkedDOITemplate and allIdsTemplate are the same but do not use the same field
+const worksExampleTemplate = (rowData) => {
+ let html = '';
+ rowData.worksExample.filter((e) => ['doi', 'hal_id', 'crossref', 'datacite'].includes(e.id_type)).slice(0, 5).forEach((id) => {
+ html += `- ${id.id_type}:`;
+ const idLink = getIdLink(id.id_type, id.id_value);
+ html += idLink ? `${id.id_value}` : `${id.id_value}`;
+ html += '
';
+ });
+ html += '
';
+ return ;
+};
+
const rorTemplate = (rowData) => {
let html = '';
rowData.rors.forEach((id) => {
@@ -116,4 +129,5 @@ export {
nameTemplate,
rorTemplate,
statusTemplate,
+ worksExampleTemplate
};
diff --git a/server/src/utils/works.js b/server/src/utils/works.js
index 0e0d8dcf..db33482e 100644
--- a/server/src/utils/works.js
+++ b/server/src/utils/works.js
@@ -283,6 +283,9 @@ const groupByAffiliations = ({ options, works }) => {
if (displayAffiliation.includes('')) {
if (deduplicatedAffiliations?.[normalizedAffiliation]) {
deduplicatedAffiliations[normalizedAffiliation].works.push(id);
+ if (deduplicatedAffiliations[normalizedAffiliation].worksExample.length < 10) {
+ deduplicatedAffiliations[normalizedAffiliation].worksExample.push(work.allIds);
+ }
} else {
// eslint-disable-next-line no-param-reassign
deduplicatedAffiliations[normalizedAffiliation] = {
@@ -293,10 +296,8 @@ const groupByAffiliations = ({ options, works }) => {
key: affiliation.key,
status: 'tobedecided',
works: [id],
+ worksExample: [work.allIds],
};
- if (affiliation.key.includes('essec business school cergy [ source: OpenAlex ]')) {
- console.log('ttttt', affiliation.key);
- }
}
}
}
@@ -306,10 +307,12 @@ const groupByAffiliations = ({ options, works }) => {
allAffiliationsTmp = Object.values(allAffiliationsTmp)
.map((affiliation, index) => {
const uniqueWorks = [...new Set(affiliation.works)];
+ const uniqueWorksExample = [...new Set(affiliation.worksExample.flat())];
return ({
...affiliation,
id: index.toString(),
works: uniqueWorks,
+ worksExample: uniqueWorksExample,
worksNumber: uniqueWorks.length,
});
});