import * as React from 'react'; import { observer } from 'mobx-react'; import { action, computed, makeObservable, observable, toJS } from 'mobx'; import autobind from 'autobind-decorator'; import 'rc-tooltip/assets/bootstrap_white.css'; import _ from 'lodash'; import ComparisonStore from 'shared/lib/comparison/ComparisonStore'; import { amplificationGroup, cnaGroup, CopyNumberEnrichmentEventType, deletionGroup, doEnrichmentEventTypeMapsMatch, EnrichmentEventType, frameshiftDeletionGroup, frameshiftGroup, frameshiftInsertionGroup, inframeDeletionGroup, inframeGroup, inframeInsertionGroup, missenseGroup, MutationEnrichmentEventType, mutationGroup, nonsenseGroup, nonstartGroup, nonstopGroup, otherGroup, spliceGroup, StructuralVariantEnrichmentEventType, truncationGroup, } from 'shared/lib/comparison/ComparisonStoreUtils'; export interface IAlterationEnrichmentTypeSelectorProps { updateSelectedEnrichmentEventTypes: (t: EnrichmentEventType[]) => void; store: ComparisonStore; showMutations?: boolean; showStructuralVariants?: boolean; showCnas?: boolean; classNames?: string; } enum checkbox { mutations = 'mutations', missense = 'missense', inframe = 'inframe', inframedeletion = 'inframedeletion', inframeinsertion = 'inframeinsertion', truncating = 'truncating', nonsense = 'nonsense', frameshift = 'frameshift', frameshiftinsertion = 'frameshiftinsertion', frameshiftdeletion = 'frameshiftdeletion', nonstart = 'nonstart', nonstop = 'nonstop', splice = 'splice', other = 'other', structvar = 'structvar', cna = 'cna', amplification = 'amplification', deletion = 'deletion', } @observer export default class AlterationEnrichmentTypeSelector extends React.Component< IAlterationEnrichmentTypeSelectorProps, {} > { constructor(props: IAlterationEnrichmentTypeSelectorProps, context: any) { super(props, context); makeObservable(this); } private currentSelectedMutations: { [key in MutationEnrichmentEventType]?: boolean; }; private currentSelectedCopyNumber: { [key in CopyNumberEnrichmentEventType]?: boolean; }; @observable private isStructuralVariantSelected?: boolean; componentWillMount() { this.currentSelectedMutations = observable( toJS(this.props.store.selectedMutationEnrichmentEventTypes) ); this.currentSelectedCopyNumber = observable( toJS(this.props.store.selectedCopyNumberEnrichmentEventTypes) ); this.isStructuralVariantSelected = this.props.store.isStructuralVariantEnrichmentSelected; } @computed get isAnyMutationsSelected() { return this.isAnySelectedMut(mutationGroup); } @computed get isAnyMissenseSelected() { return this.isAnySelectedMut(missenseGroup); } @computed get isAnyInframeSelected() { return this.isAnySelectedMut(inframeGroup); } @computed get isAnyInframeDeletionsSelected() { return this.isAnySelectedMut(inframeDeletionGroup); } @computed get isAnyInframeInsertionsSelected() { return this.isAnySelectedMut(inframeInsertionGroup); } @computed get isAnyTruncationsSelected() { return this.isAnySelectedMut(truncationGroup); } @computed get isAnyNonsenseSelected() { return this.isAnySelectedMut(nonsenseGroup); } @computed get isAnyFrameshiftSelected() { return this.isAnySelectedMut(frameshiftGroup); } @computed get isAnyFrameshiftInsertionsSelected() { return this.isAnySelectedMut(frameshiftInsertionGroup); } @computed get isAnyFrameshiftDeletionsSelected() { return this.isAnySelectedMut(frameshiftDeletionGroup); } @computed get isAnyNonStartSelected() { return this.isAnySelectedMut(nonstartGroup); } @computed get isAnyNonStopSelected() { return this.isAnySelectedMut(nonstopGroup); } @computed get isAnySpliceSelected() { return this.isAnySelectedMut(spliceGroup); } @computed get isAnyOtherSelected() { return this.isAnySelectedMut(otherGroup); } @computed get isAnyCopyNumberSelected() { return this.isAnySelectedCna(cnaGroup); } @computed get isAnyAmplificationsSelected() { return this.isAnySelectedCna(amplificationGroup); } @computed get isAnyDeletionsSelected() { return this.isAnySelectedCna(deletionGroup); } private isAnySelectedMut(group: MutationEnrichmentEventType[]): boolean { return _.some(group, type => this.currentSelectedMutations[type]); } private isAnySelectedCna(group: CopyNumberEnrichmentEventType[]): boolean { return _.some(group, type => this.currentSelectedCopyNumber[type]); } @autobind private onInputClick(event: React.MouseEvent) { console.log((event.target as HTMLInputElement).value); switch ((event.target as HTMLInputElement).value) { case checkbox.mutations: this.toggleMutGroup( mutationGroup, !this.isAnyMutationsSelected ); break; case checkbox.missense: this.toggleMutGroup(missenseGroup, !this.isAnyMissenseSelected); break; case checkbox.inframe: this.toggleMutGroup(inframeGroup, !this.isAnyInframeSelected); break; case checkbox.inframedeletion: this.toggleMutGroup( inframeDeletionGroup, !this.isAnyInframeDeletionsSelected ); break; case checkbox.inframeinsertion: this.toggleMutGroup( inframeInsertionGroup, !this.isAnyInframeInsertionsSelected ); break; case checkbox.truncating: this.toggleMutGroup( truncationGroup, !this.isAnyTruncationsSelected ); break; case checkbox.nonsense: this.toggleMutGroup(nonsenseGroup, !this.isAnyNonsenseSelected); break; case checkbox.frameshift: this.toggleMutGroup( frameshiftGroup, !this.isAnyFrameshiftSelected ); break; case checkbox.frameshiftinsertion: this.toggleMutGroup( frameshiftInsertionGroup, !this.isAnyFrameshiftInsertionsSelected ); break; case checkbox.frameshiftdeletion: this.toggleMutGroup( frameshiftDeletionGroup, !this.isAnyFrameshiftDeletionsSelected ); break; case checkbox.nonstart: this.toggleMutGroup(nonstartGroup, !this.isAnyNonStartSelected); break; case checkbox.nonstop: this.toggleMutGroup(nonstopGroup, !this.isAnyNonStopSelected); break; case checkbox.splice: this.toggleMutGroup(spliceGroup, !this.isAnySpliceSelected); break; case checkbox.other: this.toggleMutGroup(otherGroup, !this.isAnyOtherSelected); break; case checkbox.structvar: this.isStructuralVariantSelected = !this .isStructuralVariantSelected; break; case checkbox.cna: this.toggleCnaGroup(cnaGroup, !this.isAnyCopyNumberSelected); break; case checkbox.amplification: this.toggleCnaGroup( amplificationGroup, !this.isAnyAmplificationsSelected ); break; case checkbox.deletion: this.toggleCnaGroup( deletionGroup, !this.isAnyDeletionsSelected ); break; } } @action private toggleCnaGroup( group: CopyNumberEnrichmentEventType[], value: boolean ) { _.forEach(group, type => { this.currentSelectedCopyNumber[type] = value; }); } @action private toggleMutGroup( group: MutationEnrichmentEventType[], value: boolean ) { _.forEach(group, type => { this.currentSelectedMutations[type] = value; }); } @autobind private updateSelectedAlterations( event: React.MouseEvent ) { const selectedMutations = _(this.currentSelectedMutations) .pickBy() .keys() .value(); const selectedCopyNumber = _(this.currentSelectedCopyNumber) .pickBy() .keys() .value(); const selectedTypes: EnrichmentEventType[] = selectedMutations.concat( selectedCopyNumber ) as EnrichmentEventType[]; if (this.isStructuralVariantSelected) { selectedTypes.push( StructuralVariantEnrichmentEventType.structural_variant ); } this.props.updateSelectedEnrichmentEventTypes(selectedTypes); } @computed get hasSelectionChanged() { return ( !doEnrichmentEventTypeMapsMatch( toJS(this.currentSelectedMutations), toJS(this.props.store.selectedMutationEnrichmentEventTypes) ) || !doEnrichmentEventTypeMapsMatch( toJS(this.currentSelectedCopyNumber), toJS(this.props.store.selectedCopyNumberEnrichmentEventTypes) ) || !_.isEqual( this.isStructuralVariantSelected, this.props.store.isStructuralVariantEnrichmentSelected ) ); } render() { return (
Alteration Types
{this.props.showMutations && (
{/*-+=+ MISSENSE +-+-*/}
{/*-+=+ INFRAME +-+-*/}
{/*-+=+ TRUNCATING +-+-*/}
)} {this.props.showStructuralVariants && (
)} {this.props.showCnas && (
)}
); } }