import * as React from 'react'; import { SyntheticEvent } from 'react'; import { observer } from 'mobx-react'; import GroupComparisonStore from './GroupComparisonStore'; import { DefaultTooltip } from 'cbioportal-frontend-commons'; import autobind from 'autobind-decorator'; import { action, computed, makeObservable, observable } from 'mobx'; import { ComparisonGroup, DUPLICATE_GROUP_NAME_MSG, } from './GroupComparisonUtils'; import { MakeMobxView } from '../../shared/components/MobxView'; import LoadingIndicator from '../../shared/components/loadingIndicator/LoadingIndicator'; import { getStudiesAttrForPatientOverlapGroup, getStudiesAttrForSampleOverlapGroup, joinGroupNames, } from './OverlapUtils'; import InfoIcon from '../../shared/components/InfoIcon'; import FlexAlignedCheckbox from '../../shared/components/FlexAlignedCheckbox'; import { serializeEvent } from 'shared/lib/tracking'; import ComparisonStore from '../../shared/lib/comparison/ComparisonStore'; import { SessionGroupData } from 'shared/api/session-service/sessionServiceModels'; export interface ICreateGroupFromOverlapProps { store: ComparisonStore; includedRegions: string[][]; // group.uid[][] allGroupsInPlot: string[]; // uid[] submitGroup: (group: SessionGroupData, saveToUser: boolean) => void; caseType: 'sample' | 'patient'; width: number; style?: any; } function getRegionSummary( region: string[], allGroupsInVenn: string[], uidToGroup: { [uid: string]: ComparisonGroup }, caseType: 'sample' | 'patient' ) { const includedGroups = region.map(uid => uidToGroup[uid]); let ret = ( {caseType[0].toUpperCase()} {caseType.substring(1)}s only in{' '} {joinGroupNames(includedGroups, 'and')} ); ret = {ret}.; return ret; } @observer export default class CreateGroupFromOverlap extends React.Component< ICreateGroupFromOverlapProps, {} > { @observable inputGroupName = ''; @observable saveGroupToUser = true; constructor(props: ICreateGroupFromOverlapProps) { super(props); makeObservable(this); } @action.bound private toggleSaveGroupToUser() { this.saveGroupToUser = !this.saveGroupToUser; } @action.bound private onChangeInputGroupName(e: SyntheticEvent) { this.inputGroupName = (e.target as HTMLInputElement).value; } @action.bound private submit() { let studiesAttr: SessionGroupData['studies']; if (this.props.caseType === 'sample') { studiesAttr = getStudiesAttrForSampleOverlapGroup( this.props.store._originalGroups.result!, this.props.includedRegions, this.props.allGroupsInPlot ); } else { studiesAttr = getStudiesAttrForPatientOverlapGroup( this.props.store._originalGroups.result!, this.props.includedRegions, this.props.allGroupsInPlot, this.props.store.patientToSamplesSet.result! ); } this.props.submitGroup( { name: this.inputGroupName, description: '', studies: studiesAttr, origin: this.props.store.origin.result!, color: undefined, }, this.saveGroupToUser ); } @computed get isDuplicateName() { const existingGroupNamesObj = this.props.store.existingGroupNames .result!; let existingGroupNames = existingGroupNamesObj.session; if (this.saveGroupToUser) { // if we're going to save the group to the user, we have to compare the group name // with all existing groups on the user for these studies existingGroupNames = existingGroupNames.concat( existingGroupNamesObj.user ); } return existingGroupNames.includes(this.inputGroupName.trim()); } private readonly enterNameInterface = MakeMobxView({ await: () => [ this.props.store.origin, this.props.store.sampleMap, this.props.store.existingGroupNames, this.props.store._originalGroups, this.props.store.patientToSamplesSet, ], render: () => (
{this.props.store.isLoggedIn && ( Save group to user account , Selecting this will save the new group with the associated study in your user account. } />, ]} /> )}
{this.isDuplicateName && (
{DUPLICATE_GROUP_NAME_MSG}
)}
), renderPending: () => , }); private readonly includedRegionsDescription = MakeMobxView({ await: () => [this.props.store.uidToGroup], render: () => { return (
{this.props.includedRegions.map(region => (
{getRegionSummary( region, this.props.allGroupsInPlot, this.props.store.uidToGroup.result!, this.props.caseType )}
))}
); }, }); render() { return (
{this.includedRegionsDescription.component}
); } }