diff --git a/client/src/pages/filters.jsx b/client/src/pages/filters.jsx index 3b6e8f4..e4bcba1 100644 --- a/client/src/pages/filters.jsx +++ b/client/src/pages/filters.jsx @@ -62,7 +62,7 @@ export default function Filters({ useEffect(() => { const getData = async () => { if (searchParams.size === 0) { - // default values + // Set default params values setSearchParams({ affiliations: [], datasets: false, diff --git a/client/src/pages/mentions.jsx b/client/src/pages/mentions.jsx index e086a86..93a0d64 100644 --- a/client/src/pages/mentions.jsx +++ b/client/src/pages/mentions.jsx @@ -12,37 +12,26 @@ import { DataTable } from 'primereact/datatable'; import { useEffect, useState } from 'react'; import { useSearchParams } from 'react-router-dom'; -import { authorsTemplate } from '../utils/templates'; +import { affiliations2Template, authorsTemplate } from '../utils/templates'; import { getMentions } from '../utils/works'; -const DEFAULT_ROWS = 50; +const DEFAULT_SEARCH = ''; +const DEFAULT_SIZE = 50; export default function Mentions() { const [searchParams, setSearchParams] = useSearchParams(); - const [currentTab, setCurrentTab] = useState(0); - const [affiliation, setAffiliation] = useState(''); - const [author, setAuthor] = useState(''); - const [doi, setDoi] = useState(''); - const [from, setFrom] = useState(0); const [loading, setLoading] = useState(false); const [mentions, setMentions] = useState([]); - const [rows, setRows] = useState(DEFAULT_ROWS); - const [search, setSearch] = useState(''); + const [search, setSearch] = useState(DEFAULT_SEARCH); const [totalRecords, setTotalRecords] = useState(0); - const [lazyState, setlazyState] = useState({ - first: 0, - page: 1, - rows: DEFAULT_ROWS, + const [urlSearchParams, setUrlSearchParams] = useState({ + from: 0, + search: DEFAULT_SEARCH, + size: DEFAULT_SIZE, + type: 'software', }); // Templates - const affiliationsTemplate = (rowData) => ( - - ); const contextTemplate = (rowData) => ( ); @@ -53,11 +42,7 @@ export default function Mentions() { ? 'fr-icon-check-line' : 'fr-icon-close-line' }`} - style={{ color: - rowData.mention_context.created - ? '#8dc572' - : '#be6464', - }} + style={{ color: rowData.mention_context.created ? '#8dc572' : '#be6464' }} /> ); const doiTemplate = (rowData) => ( @@ -70,11 +55,7 @@ export default function Mentions() { ? 'fr-icon-check-line' : 'fr-icon-close-line' }`} - style={{ color: - rowData.mention_context.shared - ? '#8dc572' - : '#be6464', - }} + style={{ color: rowData.mention_context.shared ? '#8dc572' : '#be6464' }} /> ); const usedTemplate = (rowData) => ( @@ -84,69 +65,60 @@ export default function Mentions() { ? 'fr-icon-check-line' : 'fr-icon-close-line' }`} - style={{ color: - rowData.mention_context.used - ? '#8dc572' - : '#be6464', - }} + style={{ color: rowData.mention_context.used ? '#8dc572' : '#be6464' }} /> ); // Events - const loadLazyData = async () => { - setLoading(true); - const data = await getMentions({ - affiliation: searchParams.get('affiliation'), - author: searchParams.get('author'), - doi: searchParams.get('doi'), - from: searchParams.get('from'), - search: searchParams.get('search'), - size: searchParams.get('size'), - type: currentTab === 0 ? 'software' : 'datasets', - }); - setMentions(data?.mentions ?? []); - setTotalRecords(data?.count ?? 0); - setLoading(false); - }; const onPage = (event) => { - setFrom(event.first); - setRows(event.rows); + searchParams.set('from', parseInt(event.first, 10)); + setSearchParams(searchParams); }; const onSubmit = () => { - setSearchParams((params) => { - params.set('affiliation', affiliation); - params.set('author', author); - params.set('doi', doi); - params.set('from', from); - params.set('search', search); - params.set('size', rows); - return params; - }); + searchParams.set('search', search); + setSearchParams(searchParams); }; // Effects - useEffect(() => setFrom(0), [currentTab]); useEffect(() => { - setlazyState({ - ...lazyState, - first: parseInt(searchParams.get('from'), 10), - rows: searchParams.get('size'), - }); - }, [currentTab, searchParams]); + console.log('searchParams changed'); + if (searchParams.size === 0) { + setSearchParams({ + from: 0, + search: DEFAULT_SEARCH, + size: DEFAULT_SIZE, + type: 'software', + }); + } else { + setUrlSearchParams({ + from: searchParams.get('from'), + search: searchParams.get('search'), + size: searchParams.get('size'), + type: searchParams.get('type'), + }); + } + }, [searchParams]); useEffect(() => { - loadLazyData(); - }, [lazyState]); + const getData = async () => { + setLoading(true); + const data = await getMentions(urlSearchParams); + setMentions(data?.mentions ?? []); + setTotalRecords(data?.count ?? 0); + setLoading(false); + }; + getData(); + }, [urlSearchParams]); return ( - +
Search
-
Example "Coq"
+
Example "Coq" or "Cern"
- +
- - -
Affiliation
-
Example "Cern"
- - - setAffiliation(e.target.value)} - value={affiliation} - /> - -
- - -
Author
-
Example "Bruno Latour"
- - - setAuthor(e.target.value)} - value={author} - /> - -
- - -
DOI
-
- Example "10.4000/proceedings.elpub.2019.20" -
- - - setDoi(e.target.value)} - value={doi} - /> - -
- +
setCurrentTab(i)} + defaultActiveIndex={0} + onTabChange={(i) => setUrlSearchParams({ ...urlSearchParams, type: i === 0 ? 'software' : 'datasets' })} > @@ -265,14 +190,14 @@ export default function Mentions() { diff --git a/client/src/styles/index.scss b/client/src/styles/index.scss index 69d3a6d..016e08a 100644 --- a/client/src/styles/index.scss +++ b/client/src/styles/index.scss @@ -4,6 +4,10 @@ cursor: pointer; } +.list-none { + list-style: none; +} + .text-center { text-align: center; } @@ -20,10 +24,6 @@ vertical-align: middle; } -.list-none { - list-style: none; -} - /* General */ @@ -31,14 +31,6 @@ body { height: auto; } -.fr-tags-group > li { - line-height: 0rem; -} - -.text-right { - text-align: right; -} - .filters { background-color: white; border-bottom: 2px solid #000; @@ -47,8 +39,8 @@ body { .actions-menu { background-color: #eee; - border-bottom: 2px solid #000; border-bottom-right-radius: 5px; + border-bottom: 2px solid #000; border-top-right-radius: 5px; box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.3); left: 0; @@ -124,18 +116,20 @@ body { margin: 0; } + /* Pge Mentions */ -.mentions { - .label { - font-size: 1em; - font-weight: bold; - text-align: end; - } +.mentions { .hint { color: grey; font-size: .8em; font-style: italic; text-align: end; } + + .label { + font-size: 1em; + font-weight: bold; + text-align: end; + } } diff --git a/client/src/utils/templates.jsx b/client/src/utils/templates.jsx index dfb0fd7..f19a6c4 100644 --- a/client/src/utils/templates.jsx +++ b/client/src/utils/templates.jsx @@ -16,6 +16,26 @@ const affiliationsTemplate = (rowData) => ( ); +const affiliations2Template = (rowData) => { + let affiliationsHtml = `
    `; + affiliationsHtml += rowData.affiliations.slice(0, 3).map((affiliation, index) => `
  • ${affiliation}
  • `).join(''); + if (rowData.affiliations.length > 3) { + affiliationsHtml += `
  • others (${rowData.affiliations.length - 3})
  • `; + } + affiliationsHtml += '
'; + let affiliationsTooltip = '
    '; + affiliationsTooltip += rowData.affiliations.map((affiliation, index) => `
  • ${affiliation}
  • `).join(''); + affiliationsTooltip += '
'; + return ( + <> + + + + + + ); +}; + const statusesItemTemplate = (option) => (
{option.name} @@ -153,6 +173,7 @@ const hasCorrectionTemplate = (rowData) => (rowData?.hasCorrection export { affiliationsTemplate, + affiliations2Template, allIdsTemplate, authorsTemplate, correctionTemplate, diff --git a/server/src/routes/works.routes.js b/server/src/routes/works.routes.js index d912bd0..3b9ffe4 100644 --- a/server/src/routes/works.routes.js +++ b/server/src/routes/works.routes.js @@ -223,9 +223,7 @@ router.route('/works').post(async (req, res) => { }); const getMentions = async ({ options }) => { - const { - affiliation, author, doi, from, search, size, type, - } = options; + const { from, search, size, type } = options; let types = []; if (type === 'software') { types = ['software']; @@ -266,19 +264,7 @@ const getMentions = async ({ options }) => { ], }, }; - if (affiliation?.length > 0) { - body.query.bool.must.push({ - term: { 'authors.affiliations.name': affiliation }, - }); - } - if (author?.length > 0) { - body.query.bool.must.push({ term: { 'authors.last_name': author } }); - } - if (doi?.length > 0) { - body.query.bool.must.push({ term: { 'doi.keyword': doi } }); - } if (search?.length > 0) { - // body.query.bool.should.push({ term: { context: search } }); body.query.bool.must.push({ simple_query_string: { query: search } }); } body = JSON.stringify(body); @@ -296,8 +282,13 @@ const getMentions = async ({ options }) => { const count = data?.hits?.total?.value ?? 0; const mentions = (data?.hits?.hits ?? []).map((mention) => ({ ...mention._source, - affiliations: - mention._source?.authors?.map((_author) => _author?.affiliations?.map((_affiliation) => _affiliation.name)).flat() ?? [], + affiliations: [ + ...new Set( + mention._source?.authors + ?.map((_author) => _author?.affiliations?.map((_affiliation) => _affiliation.name)) + .flat().filter((item) => !!item) ?? [], + ), + ], authors: mention._source?.authors?.map((_author) => _author.last_name) ?? [], context: mention?.highlight?.context ?? mention._source.context,