Skip to content

Commit

Permalink
feat(ui): Filter on datasources
Browse files Browse the repository at this point in the history
  • Loading branch information
annelhote committed Oct 22, 2023
1 parent 70500a6 commit fffb872
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 64 deletions.
27 changes: 0 additions & 27 deletions client/src/pages/home/filters.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,6 @@ export default function Filters({ sendQuery }) {
}
}, [searchParams, setSearchParams]);

const onDatasourcesChange = (key) => {
const { datasources } = currentSearchParams;
if (datasources.includes(key)) {
setSearchParams({ ...currentSearchParams, datasources: datasources.filter((datasource) => datasource !== key) });
} else {
setSearchParams({ ...currentSearchParams, datasources: [...datasources, key] });
}
};

const onIdentifiersChange = (label) => {
const { dataIdentifiers } = currentSearchParams;
if (dataIdentifiers.includes(label)) {
Expand All @@ -74,8 +65,6 @@ export default function Filters({ sendQuery }) {
sendQuery(currentSearchParams);
};

const checkSource = (source) => (currentSearchParams?.datasources ?? []).includes(source);

return (
<>
<Row gutters>
Expand All @@ -88,22 +77,6 @@ export default function Filters({ sendQuery }) {
onInputHandler={setOnInputAffiliationsHandler}
/>
</Col>
<Col n="2" className="fr-pt-4w">
Datasources
<CheckboxGroup className="fr-mb-0">
{
sources.map((source) => (
<Checkbox
checked={checkSource(source.key)}
key={source.key}
label={source.label}
onChange={() => onDatasourcesChange(source.key)}
size="sm"
/>
))
}
</CheckboxGroup>
</Col>
</Row>
<Row gutters alignItems="bottom">
<Col n="5">
Expand Down
67 changes: 48 additions & 19 deletions client/src/pages/home/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/* eslint-disable indent */
/* eslint-disable jsx-a11y/control-has-associated-label */
/* eslint-disable no-case-declarations */
import { Button, Col, Container, Notice, Row, Tab, Tabs } from '@dataesr/react-dsfr';
import { Button, Checkbox, CheckboxGroup, Col, Container, Notice, Row, Tab, Tabs } from '@dataesr/react-dsfr';
import { useQuery } from '@tanstack/react-query';
import { useEffect, useState } from 'react';

Expand Down Expand Up @@ -41,6 +41,7 @@ const TO_BE_DECIDED_STATUS = 'to be decided';
const VALIDATED_STATUS = 'validated';
const EXCLUDED_STATUS = 'excluded';
const REGEXP_ROR = /^(https:\/\/ror\.org\/|ror\.org\/){0,1}0[a-hj-km-np-tv-z|0-9]{6}[0-9]{2}$/;
const DATASOURCES = [{ key: 'bso', label: 'French OSM' }, { key: 'openalex', label: 'OpenAlex' }];

const getRorAffiliations = (affiliations) => {
const notRorAffiliations = [];
Expand Down Expand Up @@ -104,6 +105,7 @@ export default function Home() {
const [allAffiliations, setAllAffiliations] = useState([]);
const [allDatasets, setAllDatasets] = useState([]);
const [allPublications, setAllPublications] = useState([]);
const [filteredDatasources, setFilteredDatasources] = useState(DATASOURCES.map((datasource) => datasource.key));
const [isLoading, setIsLoading] = useState(false);
const [options, setOptions] = useState({});
const [regexp, setRegexp] = useState();
Expand Down Expand Up @@ -200,16 +202,18 @@ export default function Home() {
let allDatasetsTmp = [];
let allPublicationsTmp = [];
if (data) {
allDatasetsTmp = data.datasets.map((dataset) => ({
...dataset,
affiliationsHtml: getAffiliationsHtmlField(dataset, regexp),
affiliationsSearch: getAffiliationsSearchField(dataset),
allIdsHtml: getAllIdsHtmlField(dataset),
authorsHtml: getAuthorsHtmlField(dataset),
authorsTooltip: getAuthorsTooltipField(dataset),
status: TO_BE_DECIDED_STATUS,
}));
allDatasetsTmp = data.datasets
.map((dataset) => ({
...dataset,
affiliationsHtml: getAffiliationsHtmlField(dataset, regexp),
affiliationsSearch: getAffiliationsSearchField(dataset),
allIdsHtml: getAllIdsHtmlField(dataset),
authorsHtml: getAuthorsHtmlField(dataset),
authorsTooltip: getAuthorsTooltipField(dataset),
status: TO_BE_DECIDED_STATUS,
}));
allPublicationsTmp = data.publications
.filter((publication) => filteredDatasources.includes(publication.datasource))
.map((publication) => ({
...publication,
affiliationsHtml: getAffiliationsHtmlField(publication, regexp),
Expand All @@ -222,12 +226,12 @@ export default function Home() {
}
setAllDatasets(allDatasetsTmp);
setAllPublications(allPublicationsTmp);
}, [data, regexp]);
}, [data, filteredDatasources, regexp]);

useEffect(() => {
groupByAffiliations(allPublications, regexp);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [allPublications]);
}, [allPublications, regexp]);

const tagPublications = (publications, action) => {
const allPublicationsTmp = [...allPublications];
Expand All @@ -250,6 +254,7 @@ export default function Home() {
setAllAffiliations(allAffiliationsTmp);
setSelectedAffiliations([]);
};

const renderAffiliationsButtons = () => (
<>
<Button
Expand Down Expand Up @@ -320,6 +325,14 @@ export default function Home() {
</>
);

const onDatasourcesChange = (datasource) => {
if (filteredDatasources.includes(datasource.key)) {
setFilteredDatasources(filteredDatasources.filter((filteredDatasource) => filteredDatasource !== datasource.key));
} else {
setFilteredDatasources(filteredDatasources.concat([datasource.key]));
}
};

return (
<>
<Container className="fr-my-5w" as="section" fluid>
Expand Down Expand Up @@ -394,18 +407,34 @@ export default function Home() {
/>
</Col>
</Row>
<Row>
<Col>
{(isFetching || isLoading) && (<Container as="section"><PageSpinner /></Container>)}
{!isFetching && !isLoading && (
{(isFetching || isLoading) && (<Container as="section"><PageSpinner /></Container>)}
{(!isFetching && !isLoading) && (
<Row>
<Col n="2">
<CheckboxGroup
hint="Filter results on available datasources"
legend="Datasources"
>
{DATASOURCES.map((datasource) => (
<Checkbox
checked={filteredDatasources.includes(datasource.key)}
key={datasource.key}
label={datasource.label}
onChange={() => onDatasourcesChange(datasource)}
size="sm"
/>
))}
</CheckboxGroup>
</Col>
<Col>
<WorksView
allPublications={allPublications}
selectedPublications={selectedPublications}
setSelectedPublications={setSelectedPublications}
/>
)}
</Col>
</Row>
</Col>
</Row>
)}
<Row>
<Col>
{renderWorksButtons(selectedPublications)}
Expand Down
3 changes: 1 addition & 2 deletions client/src/pages/home/views/works.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
affiliationsTemplate,
allIdsTemplate,
authorsTemplate,
sourcesFilterTemplate,
statusFilterTemplate,
statusTemplate,
typeFilterTemplate,
Expand Down Expand Up @@ -40,7 +39,7 @@ export default function WorksView({
<Column selectionMode="multiple" />
<Column field="status" header="Status" body={statusTemplate} filter showFilterMenu={false} filterElement={statusFilterTemplate} style={{ minWidth: '10px' }} />
<Column field="allIdsHtml" header="Ids" body={allIdsTemplate} filter filterMatchMode="contains" filterPlaceholder="Search by id" />
<Column field="datasource" header="Source" filter showFilterMenu={false} filterElement={sourcesFilterTemplate} filterMatchMode="contains" />
<Column field="datasource" header="Source" />
<Column field="type" header="Type" filter showFilterMenu={false} filterElement={typeFilterTemplate} filterMatchMode="equals" />
<Column field="affiliationsHtml" header="Affiliations" body={affiliationsTemplate} filter filterField="affiliationsSearch" filterMatchMode="contains" filterPlaceholder="Search by affiliation" style={{ minWidth: '300px' }} />
<Column field="authorsHtml" header="Authors" body={authorsTemplate} filter filterMatchMode="contains" filterPlaceholder="Search by author" style={{ minWidth: '10px' }} />
Expand Down
19 changes: 3 additions & 16 deletions client/src/utils/templates.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const getAffiliationsHtmlField = (rowData, regexp) => {
.flat();
affiliations = [...new Set(affiliations)];
let html = '<ul>';
html += affiliations.map((affiliation, index) => `<li key=affilition-${index}>${affiliation}</li>`);
html += affiliations.map((affiliation, index) => `<li key=affilition-${index}>${affiliation}</li>`).join('');
html += '</ul>';
return html;
};
Expand Down Expand Up @@ -63,7 +63,7 @@ const getAllIdsHtmlField = (rowData) => {

const getAuthorsHtmlField = (rowData) => {
let html = `<ul data-tooltip-id="tooltip-author-${rowData.id}">`;
html += rowData.authors.slice(0, 3).map((author, index) => `<li key="author-${rowData.id}-${index}">${author.full_name}</li>`);
html += rowData.authors.slice(0, 3).map((author, index) => `<li key="author-${rowData.id}-${index}">${author.full_name}</li>`).join('');
if (rowData.authors.length > 3) {
html += `<li>et al. (${rowData.authors.length - 3})</li>`;
}
Expand All @@ -73,7 +73,7 @@ const getAuthorsHtmlField = (rowData) => {

const getAuthorsTooltipField = (rowData) => {
let html = '<ul>';
html += rowData.authors.map((author, index) => `<li key="tooltip-author-${rowData.id}-${index}">${author.full_name}</li>`);
html += rowData.authors.map((author, index) => `<li key="tooltip-author-${rowData.id}-${index}">${author.full_name}</li>`).join('');
html += '</ul>';
return html;
};
Expand Down Expand Up @@ -111,18 +111,6 @@ const statusFilterTemplate = (options) => (
/>
);

const sourcesFilterTemplate = (options) => (
<Dropdown
className="p-column-filter"
onChange={(e) => options.filterApplyCallback(e.value)}
options={['bso', 'openalex']}
placeholder=""
showClear
style={{ width: '3rem' }}
value={options.value}
/>
);

const typeFilterTemplate = (options) => (
<Dropdown
className="p-column-filter"
Expand All @@ -146,7 +134,6 @@ export {
getAuthorsHtmlField,
getAuthorsTooltipField,
nameTemplate,
sourcesFilterTemplate,
statusFilterTemplate,
statusTemplate,
typeFilterTemplate,
Expand Down

0 comments on commit fffb872

Please sign in to comment.