import * as React from 'react'; import { CancerStudy } from 'cbioportal-ts-api-client'; import * as styles_any from './styles.module.scss'; import classNames from 'classnames'; import FontAwesome from 'react-fontawesome'; import LabeledCheckbox from '../../labeledCheckbox/LabeledCheckbox'; import { observer, Observer } from 'mobx-react'; import { computed, makeObservable } from 'mobx'; import _ from 'lodash'; import { getPubMedUrl } from '../../../api/urls'; import { QueryStoreComponent } from '../QueryStore'; import { DefaultTooltip } from 'cbioportal-frontend-commons'; import { FilteredCancerTreeView } from '../StudyListLogic'; import { CancerTreeNode, CancerTypeWithVisibility, } from '../CancerStudyTreeData'; import { StudyLink } from '../../StudyLink/StudyLink'; import StudyTagsTooltip, { IconType, } from '../../studyTagsTooltip/StudyTagsTooltip'; import { formatStudyReferenceGenome } from 'shared/lib/referenceGenomeUtils'; import { getServerConfig } from 'config/config'; const styles = { ...styles_any, Level: (level: number) => (styles_any as any)[`Level${level}`], }; export interface IStudyListProps { showSelectedStudiesOnly?: boolean; } @observer export default class StudyList extends QueryStoreComponent< IStudyListProps, {} > { private _view: FilteredCancerTreeView; get view() { return ( this._view || (this.props.showSelectedStudiesOnly ? this.logic.selectedStudiesView : this.logic.mainView) ); } get logic() { return this.store.studyListLogic; } get rootCancerType() { return this.store.treeData.rootCancerType; } componentDidMount() { // when rendering selected studies view, // cache the view object so studies do not disappear immediately when deselected. if (this.props.showSelectedStudiesOnly) this._view = this.view; } render() { let studyList = this.renderCancerType(this.rootCancerType); if (this.props.showSelectedStudiesOnly) { return (
{ this.view.onCheck( this.store.treeData.rootCancerType, false ); this.store.showSelectedStudiesOnly = false; }} > Deselect all {studyList}
); } return studyList; } renderCancerType = ( cancerType: CancerTypeWithVisibility, arrayIndex: number = 0 ): JSX.Element | null => { let currentLevel = this.logic.getDepth(cancerType); let childCancerTypes = this.view.getChildCancerTypes(cancerType); let childStudies = this.view.getChildCancerStudies(cancerType); let childStudyIds = this.logic.cancerTypeListView .getDescendantCancerStudies(cancerType) .map(study => study.studyId); let heading: JSX.Element | undefined; let indentArrow: JSX.Element | undefined; if (cancerType != this.rootCancerType) { let liClassName = classNames( styles.CancerType, styles.Level(currentLevel) // this.logic.isHighlighted(cancerType) && styles.highlighted ); if (currentLevel === 3) indentArrow = ( ); heading = (
  • {indentArrow} {cancerType.name} {!this.store.forDownloadTab && ( {_.intersection( childStudyIds, this.store.selectableSelectedStudyIds ).length ? 'Deselect All' : 'Select All'} )}
  • ); } let ulClassName = classNames( styles.StudyList, styles.Level(currentLevel) ); return ( ); }; renderCancerStudy = (study: CancerStudy, arrayIndex: number) => { let liClassName = classNames( styles.Study // this.logic.isHighlighted(study) && styles.highlighted ); const isOverlap = study.studyId in this.store.getOverlappingStudiesMap; const overlapWarning = isOverlap ? ( This study has overlapping data with another selected study. } > ) : null; const isMixedReferenceGenome = _.includes(this.store.selectableSelectedStudyIds, study.studyId) && this.store.isMixedReferenceGenome; const mixedReferenceGenomeWarning = isMixedReferenceGenome ? ( You are combining studies with molecular data based on both GRCh37/hg19 and GRCh38/hg38. This is not fully supported yet. Please double check your findings } > {' '} {formatStudyReferenceGenome(study.referenceGenome)} ) : null; return (
  • {() => { const classes = classNames({ [styles.StudyName]: true, overlappingStudy: isOverlap || isMixedReferenceGenome, [styles.DeletedStudy]: this.store.isDeletedVirtualStudy( study.studyId ), [`studyItem_${study.studyId}`]: true, [styles.UnauthorizedStudy]: getServerConfig() .skin_home_page_show_unauthorized_studies && study.readPermission === false, }); return ( {study.name} {overlapWarning} {mixedReferenceGenomeWarning} ); }} {() => { return (
    {!this.store.isDeletedVirtualStudy( study.studyId ) && this.renderSamples(study)} {this.renderStudyLinks(study)}
    ); }}
  • ); }; // renderStudyName = (study:CancerStudy, afterName?:any) => // { // return ( // // // {study.name} {afterName || null} // // // ); // } renderSamples = (study: CancerStudy) => { return ( {`${study.allSampleCount} samples`} ); }; renderStudyLinks = (study: CancerStudy) => { if (this.store.isDeletedVirtualStudy(study.studyId)) { return ( Restore study } children={ } /> ); } else { const links: { icon: string; onClick?: string | (() => void); tooltip?: string; }[] = [ { icon: 'info-circle', tooltip: '', }, ]; if (this.store.isVirtualStudy(study.studyId)) { links.push({ icon: 'trash', tooltip: 'Delete this virtual study.', onClick: () => this.store.deleteVirtualStudy(study.studyId), }); } else { links.push({ icon: 'book', onClick: study.pmid && getPubMedUrl(study.pmid), tooltip: study.pmid && 'PubMed', }); } return ( {links.map((link, i) => { let content = ( ); if (link.onClick) { let anchorProps: any = { key: i, }; if (typeof link.onClick === 'string') { anchorProps.href = link.onClick; anchorProps.target = '_blank'; } else { anchorProps.onClick = link.onClick; } content = {content}; } if (link.tooltip) { let overlay = (
    ); content = ( ); } if (link.icon === 'info-circle') { content = ( ' ) : study.description } studyId={study.studyId} isVirtualStudy={this.store.isVirtualStudy( study.studyId )} mouseEnterDelay={0} placement="top" iconType={IconType.INFO_ICON} > {content} ); } return content; })} {study.studyId && ( View clinical and genomic data of this study
    } >
    )} {getServerConfig() .skin_home_page_show_unauthorized_studies && study.studyId && study.readPermission === false && ( ' ) : study.description } studyId={study.studyId} isVirtualStudy={this.store.isVirtualStudy( study.studyId )} mouseEnterDelay={0} placement="top" iconType={IconType.LOCK_ICON} > )} ); } }; } export interface ICancerTreeCheckboxProps { view: FilteredCancerTreeView; node: CancerTreeNode; } @observer export class CancerTreeCheckbox extends QueryStoreComponent< ICancerTreeCheckboxProps, {} > { constructor(props: any) { super(props); makeObservable(this); } @computed.struct get checkboxProps() { return this.props.view.getCheckboxProps(this.props.node); } render() { return ( { this.props.view.onCheck( this.props.node, (event.target as HTMLInputElement).checked ); }} > {this.props.children} ); } }