diff --git a/client/src/pages/affiliationsTab.jsx b/client/src/pages/affiliationsTab.jsx
index ab4b02b0..64fd1796 100644
--- a/client/src/pages/affiliationsTab.jsx
+++ b/client/src/pages/affiliationsTab.jsx
@@ -4,7 +4,6 @@ import {
Col,
Notice,
Row,
- Tab,
TextInput,
} from '@dataesr/react-dsfr';
import PropTypes from 'prop-types';
@@ -49,7 +48,7 @@ export default function AffiliationsTab({ affiliations, tagAffiliations }) {
};
return (
-
+ <>
{affiliationsNotice && (
@@ -110,7 +109,7 @@ export default function AffiliationsTab({ affiliations, tagAffiliations }) {
{renderButtons(selectedAffiliations, tagAffiliations)}
-
+ >
);
}
diff --git a/client/src/pages/index.jsx b/client/src/pages/index.jsx
index 9f05b8bf..75eb613c 100644
--- a/client/src/pages/index.jsx
+++ b/client/src/pages/index.jsx
@@ -3,21 +3,19 @@
/* eslint-disable jsx-a11y/control-has-associated-label */
/* eslint-disable no-case-declarations */
import {
- Checkbox,
- CheckboxGroup,
Col,
Container,
Row,
Tab,
Tabs,
- TextInput,
} from '@dataesr/react-dsfr';
import { useQuery } from '@tanstack/react-query';
import { useEffect, useState } from 'react';
import Actions from './actions';
-import Filters from './filters';
import AffiliationsTab from './affiliationsTab';
+import Filters from './filters';
+import PublicationsTab from './publicationsTab';
import WorksView from './worksView';
import Gauge from '../components/gauge';
import { PageSpinner } from '../components/spinner';
@@ -29,35 +27,20 @@ import {
getAuthorsHtmlField,
getAuthorsTooltipField,
} from '../utils/templates';
-import {
- getData,
- renderButtons,
-} from '../utils/works.jsx';
+import { getData, renderButtons } from '../utils/works';
import { status } from '../config';
import 'primereact/resources/primereact.min.css';
import 'primereact/resources/themes/lara-light-indigo/theme.css';
-const DATASOURCES = [{ key: 'bso', label: 'French OSM' }, { key: 'openalex', label: 'OpenAlex' }];
-
export default function Home() {
const [allAffiliations, setAllAffiliations] = useState([]);
const [allDatasets, setAllDatasets] = useState([]);
const [allPublications, setAllPublications] = useState([]);
- const [filteredAffiliationName, setFilteredAffiliationName] = useState('');
- const [filteredDatasources, setFilteredDatasources] = useState(DATASOURCES.map((datasource) => datasource.key));
- const [filteredPublications, setFilteredPublications] = useState([]);
- const [filteredStatus, setFilteredStatus] = useState(Object.keys(status));
- const [filteredTypes, setFilteredTypes] = useState([]);
- const [filteredYears, setFilteredYears] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const [options, setOptions] = useState({});
const [regexp, setRegexp] = useState();
const [selectedDatasets, setSelectedDatasets] = useState([]);
- const [selectedPublications, setSelectedPublications] = useState([]);
- const [timer, setTimer] = useState();
- const [types, setTypes] = useState([]);
- const [years, setYears] = useState([]);
const { data, isFetching, refetch } = useQuery({
queryKey: ['data'],
@@ -173,28 +156,8 @@ export default function Home() {
}
setAllDatasets(allDatasetsTmp);
setAllPublications(allPublicationsTmp);
- setFilteredPublications(allPublicationsTmp);
- const allYears = [...new Set(allPublicationsTmp.map((publication) => publication?.year).filter((year) => !!year))];
- setYears(allYears);
- setFilteredYears(allYears);
- const allTypes = [...new Set(allPublicationsTmp.map((publication) => publication?.type))];
- setTypes(allTypes);
- setFilteredTypes(allTypes);
}, [data, regexp]);
- useEffect(() => {
- if (timer) {
- clearTimeout(timer);
- }
- const timerTmp = setTimeout(() => {
- const filteredPublicationsTmp = allPublications.filter((publication) => publication.affiliationsTooltip.includes(filteredAffiliationName) && filteredDatasources.includes(publication.datasource) && filteredStatus.includes(publication.status) && filteredTypes.includes(publication.type) && filteredYears.includes(publication.year));
- setFilteredPublications(filteredPublicationsTmp);
- }, 500);
- setTimer(timerTmp);
- // The timer should not be tracked
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [allPublications, filteredAffiliationName, filteredDatasources, filteredStatus, filteredTypes, filteredYears]);
-
useEffect(() => {
groupByAffiliations();
// eslint-disable-next-line react-hooks/exhaustive-deps
@@ -205,7 +168,6 @@ export default function Home() {
const publicationsIds = publications.map((publication) => publication.id);
allPublicationsTmp.filter((publication) => publicationsIds.includes(publication.id)).map((publication) => publication.status = action);
setAllPublications(allPublicationsTmp);
- setSelectedPublications([]);
};
const tagDatasets = (datasets, action) => {
@@ -232,38 +194,6 @@ export default function Home() {
setAllAffiliations(allAffiliationsTmp);
};
- const onDatasourcesChange = (datasource) => {
- if (filteredDatasources.includes(datasource.key)) {
- setFilteredDatasources(filteredDatasources.filter((filteredDatasource) => filteredDatasource !== datasource.key));
- } else {
- setFilteredDatasources(filteredDatasources.concat([datasource.key]));
- }
- };
-
- const onStatusChange = (st) => {
- if (filteredStatus.includes(st)) {
- setFilteredStatus(filteredStatus.filter((filteredSt) => filteredSt !== st));
- } else {
- setFilteredStatus(filteredStatus.concat([st]));
- }
- };
-
- const onTypesChange = (type) => {
- if (filteredTypes.includes(type)) {
- setFilteredTypes(filteredTypes.filter((filteredType) => filteredType !== type));
- } else {
- setFilteredTypes(filteredTypes.concat([type]));
- }
- };
-
- const onYearsChange = (year) => {
- if (filteredYears.includes(year)) {
- setFilteredYears(filteredYears.filter((filteredYear) => filteredYear !== year));
- } else {
- setFilteredYears(filteredYears.concat([year]));
- }
- };
-
return (
<>
@@ -286,105 +216,17 @@ export default function Home() {
/>
{allAffiliations.length > 0 && (
-
+
+
+
-
-
- {renderButtons(selectedPublications, tagPublications)}
-
-
- ({
- ...st,
- value: allPublications.filter((publication) => publication.status === st.id).length,
- }))}
- />
-
-
- {(isFetching || isLoading) && ()}
- {(!isFetching && !isLoading) && (
-
-
-
- {Object.values(status).map((st) => (
- onStatusChange(st.id)}
- size="sm"
- />
- ))}
-
-
- {DATASOURCES.map((datasource) => (
- onDatasourcesChange(datasource)}
- size="sm"
- />
- ))}
-
-
- {years.map((year) => (
- onYearsChange(year)}
- size="sm"
- />
- ))}
-
-
- {types.map((type) => (
- onTypesChange(type)}
- size="sm"
- />
- ))}
-
- setFilteredAffiliationName(e.target.value)}
- value={filteredAffiliationName}
- />
-
-
-
-
-
- )}
-
-
- {renderButtons(selectedPublications, tagPublications)}
-
-
+
diff --git a/client/src/pages/publicationsTab.jsx b/client/src/pages/publicationsTab.jsx
new file mode 100644
index 00000000..d782ad80
--- /dev/null
+++ b/client/src/pages/publicationsTab.jsx
@@ -0,0 +1,196 @@
+import {
+ Checkbox,
+ CheckboxGroup,
+ Col,
+ Row,
+ TextInput,
+} from '@dataesr/react-dsfr';
+import PropTypes from 'prop-types';
+import { useEffect, useState } from 'react';
+
+import WorksView from './worksView';
+import Gauge from '../components/gauge';
+import { status } from '../config';
+import { renderButtons } from '../utils/works';
+
+const DATASOURCES = [{ key: 'bso', label: 'French OSM' }, { key: 'openalex', label: 'OpenAlex' }];
+
+export default function PublicationsTab({ publications, tagPublications }) {
+ const [filteredPublications, setFilteredPublications] = useState([]);
+ const [filteredAffiliationName, setFilteredAffiliationName] = useState('');
+ const [filteredDatasources, setFilteredDatasources] = useState(DATASOURCES.map((datasource) => datasource.key));
+ const [filteredStatus, setFilteredStatus] = useState(Object.keys(status));
+ const [filteredTypes, setFilteredTypes] = useState([]);
+ const [filteredYears, setFilteredYears] = useState([]);
+ const [selectedPublications, setSelectedPublications] = useState([]);
+ const [timer, setTimer] = useState();
+ const [types, setTypes] = useState([]);
+ const [years, setYears] = useState([]);
+
+ useEffect(() => {
+ setFilteredPublications(publications);
+ const allYears = [...new Set(publications.map((publication) => publication?.year).filter((year) => !!year))];
+ setYears(allYears);
+ setFilteredYears(allYears);
+ const allTypes = [...new Set(publications.map((publication) => publication?.type))];
+ setTypes(allTypes);
+ setFilteredTypes(allTypes);
+ }, [publications]);
+
+ useEffect(() => {
+ if (timer) {
+ clearTimeout(timer);
+ }
+ const timerTmp = setTimeout(() => {
+ const filteredPublicationsTmp = publications.filter((publication) => publication.affiliationsTooltip.includes(filteredAffiliationName)
+ && filteredDatasources.includes(publication.datasource)
+ && filteredStatus.includes(publication.status)
+ && filteredTypes.includes(publication.type)
+ && filteredYears.includes(publication.year));
+ setFilteredPublications(filteredPublicationsTmp);
+ }, 500);
+ setTimer(timerTmp);
+ // The timer should not be tracked
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [publications, filteredAffiliationName, filteredDatasources, filteredStatus, filteredTypes, filteredYears]);
+
+ const onDatasourcesChange = (datasource) => {
+ if (filteredDatasources.includes(datasource.key)) {
+ setFilteredDatasources(filteredDatasources.filter((filteredDatasource) => filteredDatasource !== datasource.key));
+ } else {
+ setFilteredDatasources(filteredDatasources.concat([datasource.key]));
+ }
+ };
+
+ const onStatusChange = (st) => {
+ if (filteredStatus.includes(st)) {
+ setFilteredStatus(filteredStatus.filter((filteredSt) => filteredSt !== st));
+ } else {
+ setFilteredStatus(filteredStatus.concat([st]));
+ }
+ };
+
+ const onTypesChange = (type) => {
+ if (filteredTypes.includes(type)) {
+ setFilteredTypes(filteredTypes.filter((filteredType) => filteredType !== type));
+ } else {
+ setFilteredTypes(filteredTypes.concat([type]));
+ }
+ };
+
+ const onYearsChange = (year) => {
+ if (filteredYears.includes(year)) {
+ setFilteredYears(filteredYears.filter((filteredYear) => filteredYear !== year));
+ } else {
+ setFilteredYears(filteredYears.concat([year]));
+ }
+ };
+
+ return (
+ <>
+
+
+ {renderButtons(selectedPublications, tagPublications)}
+
+
+ ({
+ ...st,
+ value: publications.filter((publication) => publication.status === st.id).length,
+ }))}
+ />
+
+
+
+
+
+ {Object.values(status).map((st) => (
+ onStatusChange(st.id)}
+ size="sm"
+ />
+ ))}
+
+
+ {DATASOURCES.map((datasource) => (
+ onDatasourcesChange(datasource)}
+ size="sm"
+ />
+ ))}
+
+
+ {years.map((year) => (
+ onYearsChange(year)}
+ size="sm"
+ />
+ ))}
+
+
+ {types.map((type) => (
+ onTypesChange(type)}
+ size="sm"
+ />
+ ))}
+
+ setFilteredAffiliationName(e.target.value)}
+ value={filteredAffiliationName}
+ />
+
+
+
+
+
+
+
+ {renderButtons(selectedPublications, tagPublications)}
+
+
+ >
+ );
+}
+
+PublicationsTab.propTypes = {
+ publications: PropTypes.arrayOf(PropTypes.shape({
+ affiliations: PropTypes.arrayOf(PropTypes.object).isRequired,
+ allIds: PropTypes.arrayOf(PropTypes.object).isRequired,
+ authors: PropTypes.arrayOf(PropTypes.object).isRequired,
+ datasource: PropTypes.string.isRequired,
+ id: PropTypes.string.isRequired,
+ status: PropTypes.string.isRequired,
+ type: PropTypes.string.isRequired,
+ })).isRequired,
+ tagPublications: PropTypes.func.isRequired,
+};