diff --git a/client/configuration/eslint/eslint.js b/client/configuration/eslint/eslint.js index 21fbfe8d..bafb7d31 100644 --- a/client/configuration/eslint/eslint.js +++ b/client/configuration/eslint/eslint.js @@ -39,6 +39,7 @@ module.exports = { }, }, rules: { + "react/jsx-no-target-blank": "off", "eslint-comments/require-description": ["error"], "no-magic-numbers": "off", "no-nested-ternary": "off", diff --git a/client/src/components/infoDrawer/infoDrawer.js b/client/src/components/infoDrawer/infoDrawer.js index 047e5017..49189ff2 100644 --- a/client/src/components/infoDrawer/infoDrawer.js +++ b/client/src/components/infoDrawer/infoDrawer.js @@ -1,7 +1,9 @@ import React, { PureComponent } from "react"; import { connect, shallowEqual } from "react-redux"; -import { Drawer, H3, H1, UL, Classes } from "@blueprintjs/core"; +import { Drawer } from "@blueprintjs/core"; import Async from "react-async"; + +import InfoFormat from "./infoFormat"; import { selectableCategoryNames, createCategorySummaryFromDfCol, @@ -14,6 +16,7 @@ import { datasetTitle: state.config?.displayNames?.dataset ?? "", aboutURL: state.config?.links?.["about-dataset"], isOpen: state.controls.datasetDrawer, + dataPortalProps: state.config?.["corpora_props"] ?? {}, }; }) class InfoDrawer extends PureComponent { @@ -60,7 +63,14 @@ class InfoDrawer extends PureComponent { }; render() { - const { position, aboutURL, datasetTitle, schema, isOpen } = this.props; + const { + position, + aboutURL, + datasetTitle, + schema, + isOpen, + dataPortalProps, + } = this.props; return ( - + {(error) => { @@ -87,7 +100,12 @@ class InfoDrawer extends PureComponent { const { singleValueCategories } = asyncProps; return ( ); }} @@ -97,56 +115,4 @@ class InfoDrawer extends PureComponent { ); } } - -const NUM_CATEGORIES = 8; - -const singleValueCategoriesPlaceholder = Array.from(Array(NUM_CATEGORIES)).map( - (_, index) => { - return [index, index]; - } -); - -const InfoFormat = ({ - datasetTitle, - singleValueCategories = new Map(singleValueCategoriesPlaceholder), - aboutURL = "thisisabouthtelengthofaurl", - skeleton = false, -}) => { - return ( -
-

{datasetTitle}

- {singleValueCategories.size > 0 && ( - <> -

- Dataset Metadata -

-
    - {Array.from(singleValueCategories).map((pair) => { - if (!pair[1] || pair[1] === "") return null; - return ( -
  • {`${pair[0]}: ${pair[1]}`}
  • - ); - })} -
- - )} - {aboutURL && ( - <> -

More Info

- - {aboutURL} - - - )} -
- ); -}; export default InfoDrawer; diff --git a/client/src/components/infoDrawer/infoFormat.js b/client/src/components/infoDrawer/infoFormat.js new file mode 100644 index 00000000..5a3db6a5 --- /dev/null +++ b/client/src/components/infoDrawer/infoFormat.js @@ -0,0 +1,194 @@ +import { H3, H1, UL, Classes } from "@blueprintjs/core"; +import React from "react"; + +const renderContributors = (contributors, affiliations, skeleton) => { + // eslint-disable-next-line no-constant-condition -- Temp removed contributor section to avoid publishing PII + if (contributors?.length === 0 && true) return null; + return ( + <> +

Contributors

+

+ {contributors.map((contributor) => { + const { email, name, institution } = contributor; + + return ( + + {name} + {email && `(${email})`} + {affiliations.indexOf(institution) + 1} + + ); + })} +

+ {renderAffiliations(affiliations, skeleton)} + + ); +}; + +const buildAffiliations = (contributors = []) => { + const affiliations = []; + contributors.forEach((contributor) => { + const { institution } = contributor; + if (affiliations.indexOf(institution) === -1) { + affiliations.push(institution); + } + }); + return affiliations; +}; + +const renderAffiliations = (affiliations, skeleton) => { + if (affiliations.length === 0) return null; + return ( + <> +

Affiliations

+
    + {affiliations.map((item, index) => ( +
    + {index + 1} + {" "} + {item} +
    + ))} +
+ + ); +}; + +const renderDOILink = (type, doi, skeleton) => { + if (!doi) return null; + return ( + doi && ( + <> +

{type}

+

+ + {doi} + +

+ + ) + ); +}; + +const renderOrganism = (organism, skeleton) => { + if (!organism) return null; + return ( + <> +

Organism

+

{organism}

+ + ); +}; + +const renderSingleValueCategories = (singleValueCategories, skeleton) => { + if (singleValueCategories.size === 0) return null; + return ( + <> +

Dataset Metadata

+
    + {Array.from(singleValueCategories).map((pair) => { + if (!pair[1] || pair[1] === "") return null; + return ( +
  • {`${pair[0]}: ${pair[1]}`}
  • + ); + })} +
+ + ); +}; + +const renderLinks = (projectLinks, aboutURL, skeleton) => { + if (!projectLinks && !aboutURL) return null; + if (projectLinks) + return ( + <> +

Project Links

+
    + {projectLinks.map((link) => { + if (link.link_type === "SUMMARY") return null; + return ( +
  • + + {link.link_name} + +
  • + ); + })} +
+ + ); + + return ( + <> +

More Info

+

+ + {aboutURL} + +

+ + ); +}; + +const NUM_CATEGORIES = 8; + +const singleValueCategoriesPlaceholder = Array.from(Array(NUM_CATEGORIES)).map( + (_, index) => { + return [index, index]; + } +); + +const InfoFormat = React.memo( + ({ + datasetTitle, + singleValueCategories = new Map(singleValueCategoriesPlaceholder), + aboutURL = "thisisabouthtelengthofaurl", + dataPortalProps = {}, + skeleton = false, + }) => { + if (dataPortalProps.corpora_schema_version === "1.0.0") { + dataPortalProps = {}; + } + const { + title, + publication_doi: doi, + preprint_doi: preprintDOI, + organism, + contributors, + project_links: projectLinks, + } = dataPortalProps; + + const affiliations = buildAffiliations(contributors); + + return ( +
+

+ {title ?? datasetTitle} +

+ {renderContributors(contributors, affiliations, skeleton)} + {renderDOILink("DOI", doi, skeleton)} + {renderDOILink("Preprint DOI", preprintDOI, skeleton)} + {renderOrganism(organism, skeleton)} + {renderSingleValueCategories(singleValueCategories, skeleton)} + {renderLinks(projectLinks, aboutURL, skeleton)} +
+ ); + } +); + +export default InfoFormat; diff --git a/client/src/components/termsPrompt/index.js b/client/src/components/termsPrompt/index.js index e99efe92..c6209a00 100644 --- a/client/src/components/termsPrompt/index.js +++ b/client/src/components/termsPrompt/index.js @@ -84,7 +84,7 @@ class TermsPrompt extends React.PureComponent { }} href={tosURL} target="_blank" - rel="noopener noreferrer" + rel="noopener" > terms of service @@ -106,7 +106,7 @@ class TermsPrompt extends React.PureComponent { }} href={privacyURL} target="_blank" - rel="noopener noreferrer" + rel="noopener" > privacy policy diff --git a/client/src/reducers/controls.js b/client/src/reducers/controls.js index e97038de..d5c4d406 100644 --- a/client/src/reducers/controls.js +++ b/client/src/reducers/controls.js @@ -21,7 +21,6 @@ const Controls = ( scatterplotYYaccessor: null, graphRenderCounter: 0 /* integer as