Skip to content

Commit

Permalink
add a separate publication tab to the explore page
Browse files Browse the repository at this point in the history
  • Loading branch information
onursumer committed Jan 9, 2025
1 parent 541405c commit 60c6c39
Show file tree
Hide file tree
Showing 5 changed files with 246 additions and 26 deletions.
15 changes: 15 additions & 0 deletions packages/data-portal-commons/src/lib/publicationHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,21 @@ export function getPublicationTitle(
return publicationSummary?.title || publicationManifest?.Title;
}

export function getPublicationDate(
publicationSummary?: PublicationSummary,
publicationManifest?: PublicationManifest
) {
let date: string | undefined;

if (publicationSummary) {
date = publicationSummary.pubdate;
} else if (publicationManifest) {
date = publicationManifest.YearofPublication?.toString();
}

return date;
}

export function getPublicationSupportingLinks(
publicationManifest?: PublicationManifest
): GeneralLink[] {
Expand Down
18 changes: 14 additions & 4 deletions packages/data-portal-explore/src/components/Explore.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
HTANToGenericAttributeMap,
LoadDataResult,
PublicationManifest,
PublicationSummary,
} from '@htan/data-portal-commons';
import { AttributeNames } from '@htan/data-portal-utils';
import {
Expand All @@ -53,7 +54,8 @@ export interface IExploreState {
filters: { [key: string]: string[] };
schemaDataById?: { [schemaDataId: string]: DataSchemaData };
atlases: Atlas[];
publicationsByUid: { [uid: string]: PublicationManifest };
publicationManifestByUid: { [uid: string]: PublicationManifest };
publicationSummaryByPubMedID?: { [pubMedId: string]: PublicationSummary };
atlasData?: any;
}

Expand Down Expand Up @@ -84,7 +86,8 @@ export class Explore extends React.Component<IExploreProps, IExploreState> {
files: [],
filters: {},
atlases: [],
publicationsByUid: {},
publicationManifestByUid: {},
publicationSummaryByPubMedID: {},
schemaDataById: {},
};

Expand Down Expand Up @@ -162,7 +165,9 @@ export class Explore extends React.Component<IExploreProps, IExploreState> {
this.setState({
files: fillInEntities(data),
atlases: data.atlases,
publicationsByUid: data.publicationManifestByUid,
publicationManifestByUid: data.publicationManifestByUid,
publicationSummaryByPubMedID:
data.publicationSummaryByPubMedID,
});
});

Expand Down Expand Up @@ -369,7 +374,12 @@ export class Explore extends React.Component<IExploreProps, IExploreState> {
toggleShowAllCases={this.toggleShowAllCases}
cloudBaseUrl={this.props.cloudBaseUrl}
getAtlasMetaData={this.props.getAtlasMetaData}
publicationsByUid={this.state.publicationsByUid}
publicationManifestByUid={
this.state.publicationManifestByUid
}
publicationSummaryByPubMedID={
this.state.publicationSummaryByPubMedID
}
genericAttributeMap={HTANToGenericAttributeMap} // TODO needs to be configurable, different mappings for each portal
/>
</div>
Expand Down
74 changes: 52 additions & 22 deletions packages/data-portal-explore/src/components/ExploreTabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
Entity,
getNormalizedOrgan,
PublicationManifest,
PublicationSummary,
} from '@htan/data-portal-commons';
import { DataSchemaData } from '@htan/data-portal-schema';

Expand All @@ -19,6 +20,7 @@ import { BiospecimenTable } from './BiospecimenTable';
import { CaseTable } from './CaseTable';
import { DEFAULT_EXPLORE_PLOT_OPTIONS, ExplorePlot } from './ExplorePlot';
import { FileTable } from './FileTable';
import { PublicationTable } from './PublicationTable';
import { ExploreTab } from '../lib/types';

import styles from './exploreTabs.module.scss';
Expand Down Expand Up @@ -53,7 +55,8 @@ interface IExploreTabsProps {

genericAttributeMap?: { [attr: string]: GenericAttributeNames };
getAtlasMetaData: () => AtlasMetaData;
publicationsByUid: { [uid: string]: PublicationManifest };
publicationManifestByUid: { [uid: string]: PublicationManifest };
publicationSummaryByPubMedID?: { [pubMedId: string]: PublicationSummary };
}

const metricTypes = [
Expand Down Expand Up @@ -182,23 +185,31 @@ export const ExploreTabs: React.FunctionComponent<IExploreTabsProps> = observer(
Files
</a>
</li>
{
<li className="nav-item">
<a
onClick={() => setTab(ExploreTab.PLOTS)}
className={`nav-link ${
activeTab === ExploreTab.PLOTS
? 'active'
: ''
}`}
>
Plots{' '}
<span style={{ color: 'orange' }}>
Beta!
</span>
</a>
</li>
}
<li className="nav-item">
<a
onClick={() => setTab(ExploreTab.PUBLICATION)}
className={`nav-link ${
activeTab === ExploreTab.PUBLICATION
? 'active'
: ''
}`}
>
Publications
</a>
</li>
<li className="nav-item">
<a
onClick={() => setTab(ExploreTab.PLOTS)}
className={`nav-link ${
activeTab === ExploreTab.PLOTS
? 'active'
: ''
}`}
>
Plots{' '}
<span style={{ color: 'orange' }}>Beta!</span>
</a>
</li>
</ul>
</div>

Expand All @@ -214,7 +225,7 @@ export const ExploreTabs: React.FunctionComponent<IExploreTabsProps> = observer(
props.groupsByPropertyFiltered
}
patientCount={props.cases.length}
publicationsByUid={props.publicationsByUid}
publicationsByUid={props.publicationManifestByUid}
/>
</div>
)}
Expand All @@ -238,7 +249,7 @@ export const ExploreTabs: React.FunctionComponent<IExploreTabsProps> = observer(
samples={props.samples}
schemaDataById={props.schemaDataById}
genericAttributeMap={props.genericAttributeMap}
publicationsByUid={props.publicationsByUid}
publicationsByUid={props.publicationManifestByUid}
/>
</div>
)}
Expand All @@ -262,7 +273,24 @@ export const ExploreTabs: React.FunctionComponent<IExploreTabsProps> = observer(
cases={props.cases}
schemaDataById={props.schemaDataById}
genericAttributeMap={props.genericAttributeMap}
publicationsByUid={props.publicationsByUid}
publicationsByUid={props.publicationManifestByUid}
/>
</div>
)}

{activeTab === ExploreTab.PUBLICATION && (
<div
className={`tab-content publications ${
activeTab !== ExploreTab.PUBLICATION ? 'd-none' : ''
}`}
>
<PublicationTable
publicationManifestByUid={
props.publicationManifestByUid
}
publicationSummaryByPubMedID={
props.publicationSummaryByPubMedID
}
/>
</div>
)}
Expand All @@ -275,7 +303,9 @@ export const ExploreTabs: React.FunctionComponent<IExploreTabsProps> = observer(
>
<AtlasTable
setTab={setTab}
publications={_.values(props.publicationsByUid)}
publications={_.values(
props.publicationManifestByUid
)}
getAtlasMetaData={props.getAtlasMetaData}
synapseAtlasData={props.allSynapseAtlases}
selectedAtlases={props.selectedSynapseAtlases}
Expand Down
164 changes: 164 additions & 0 deletions packages/data-portal-explore/src/components/PublicationTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
import _ from 'lodash';
import React from 'react';
import { faExternalLinkAlt } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {
AtlasDescription,
getPublicationAuthors,
getPublicationDate,
getPublicationDOI,
getPublicationJournal,
getPublicationPubMedID,
getPublicationTitle,
getPublicationUid,
PublicationContentType,
PublicationManifest,
PublicationSummary,
} from '@htan/data-portal-commons';
import {
EnhancedDataTable,
getDefaultDataTableStyle,
} from '@htan/data-portal-table';
import { truncatedTableCell } from '@htan/data-portal-explore';

interface IPublicationTableProps {
publicationManifestByUid: { [uid: string]: PublicationManifest };
publicationSummaryByPubMedID?: { [pubMedId: string]: PublicationSummary };
}

export const PublicationTable: React.FunctionComponent<IPublicationTableProps> = (
props
) => {
const getSummary = (manifest: PublicationManifest) =>
props.publicationSummaryByPubMedID?.[getPublicationPubMedID(manifest)];

const columns = [
{
name: 'Title',
selector: (manifest: PublicationManifest) =>
getPublicationTitle(getSummary(manifest), manifest),
cell: (manifest: PublicationManifest) => (
<a
href={`//${
window.location.host
}/publications/${getPublicationUid(manifest)}`}
>
{getPublicationTitle(getSummary(manifest), manifest)}
</a>
),
wrap: true,
sortable: true,
},
{
name: 'Atlas',
selector: (manifest: PublicationManifest) => manifest.atlas_name,
cell: (manifest: PublicationManifest) => (
<AtlasDescription
atlasMeta={manifest.AtlasMeta}
atlasName={manifest.AtlasMeta.lead_institutions}
/>
),
wrap: true,
sortable: true,
},
{
name: 'Authors',
selector: (manifest: PublicationManifest) =>
getPublicationAuthors(getSummary(manifest), manifest).join(
', '
),
cell: truncatedTableCell,
wrap: true,
sortable: true,
},
{
name: 'Journal',
selector: (manifest: PublicationManifest) =>
getPublicationJournal(getSummary(manifest), manifest),
wrap: true,
sortable: true,
},
{
name: 'DOI',
selector: (manifest: PublicationManifest) =>
getPublicationDOI(getSummary(manifest), manifest),
cell: (manifest: PublicationManifest) => {
const doi = getPublicationDOI(getSummary(manifest), manifest);
return doi ? (
<a href={`https://doi.org/${doi}`}>
{doi} <FontAwesomeIcon icon={faExternalLinkAlt} />
</a>
) : undefined;
},
wrap: true,
sortable: true,
},
{
name: 'PubMed',
selector: (manifest: PublicationManifest) =>
getPublicationPubMedID(manifest),
cell: (manifest: PublicationManifest) => {
const pubmedId = getPublicationPubMedID(manifest);
return pubmedId ? (
<a href={`https://pubmed.ncbi.nlm.nih.gov/${pubmedId}`}>
{pubmedId} <FontAwesomeIcon icon={faExternalLinkAlt} />
</a>
) : undefined;
},
wrap: true,
sortable: true,
},
{
name: 'Content Type',
selector: (manifest: PublicationManifest) =>
manifest.PublicationContentType,
cell: (manifest: PublicationManifest) => {
if (
manifest.PublicationContentType?.toLowerCase() ===
PublicationContentType.Prepublication
) {
return <span className="text-danger">In Review</span>;
} else if (
manifest.PublicationContentType?.toLowerCase() ===
PublicationContentType.Preprint
) {
return <span>Preprint</span>;
} else if (
manifest.PublicationContentType?.toLowerCase() ===
PublicationContentType.Published
) {
return <span>Published</span>;
} else {
return manifest.PublicationContentType;
}
},
wrap: true,
sortable: true,
},
{
name: 'Publication Date',
selector: (manifest: PublicationManifest) =>
getPublicationDate(getSummary(manifest), manifest),
wrap: true,
sortable: true,
},
];

return (
<EnhancedDataTable
columns={columns}
data={_.values(props.publicationManifestByUid)}
defaultSortField="YearofPublication"
defaultSortAsc={false}
striped={true}
dense={false}
noHeader={true}
pagination={true}
paginationPerPage={50}
paginationRowsPerPageOptions={[10, 20, 50, 100, 500]}
customStyles={getDefaultDataTableStyle()}
/>
);
};

export default PublicationTable;
1 change: 1 addition & 0 deletions packages/data-portal-explore/src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ export enum ExploreTab {
ATLAS = 'atlas',
BIOSPECIMEN = 'biospecimen',
CASES = 'cases',
PUBLICATION = 'publication',
PLOTS = 'plots',
}

0 comments on commit 60c6c39

Please sign in to comment.