import autobind from "autobind-decorator"; import { action, computed, makeObservable, observable } from "mobx"; import { observer } from "mobx-react"; import React from "react"; import { Button, Checkbox, FormControl, ListGroup, ListGroupItem, Modal, } from "react-bootstrap"; import { EModalType, IDataTypeMetaData } from "../ui/react-pathway-mapper"; import CBioPortalAccessor from "../utils/CBioPortalAccessor"; interface IStudyModalProps { show: boolean; loadFromCBio: Function; handleClose: Function; } @observer export default class StudyModal extends React.Component { @observable dataTypes: { [dataType: string]: IDataTypeMetaData } = {}; @observable dataTypeFetchResultsReady: boolean = false; currentlySelectedItemIndex = -1; @observable selectedStudies: { data: any[]; dataTypes: { [dataType: string]: IDataTypeMetaData }; }[] = []; checkboxModalPosition: { bottom: number; } = { bottom: 0, }; @observable selectedDataTypesPerStudy: string[] = []; @observable itemArray: any[] = []; @observable searchQuery: string = ""; @observable showDataTypeSelectionModal = false; @observable studyListItemCheckboxChecked: boolean[] = []; @observable selectedStudyData: any[]; @observable portalAccessor: CBioPortalAccessor; constructor(props: IStudyModalProps) { super(props); makeObservable(this); this.selectedStudyData = []; this.portalAccessor = new CBioPortalAccessor(); this.fetchStudy(); } @action.bound setDataTypeFetchResultsReady(ready: boolean) { this.dataTypeFetchResultsReady = ready; } @action.bound setItemArray(itemArray: any[]) { this.itemArray = itemArray; } @action.bound setSearchQuery(query: string) { this.searchQuery = query; } @action.bound setSelectedStudyData(data: any[]) { this.selectedStudyData = data; } @action.bound setDataTypeProperties(dataType: string, properties: IDataTypeMetaData) { this.dataTypes[dataType] = properties; } @action.bound initStudyListItemCheckboxChecked(studyCount: number) { this.studyListItemCheckboxChecked = Array(studyCount).fill(false); } @action.bound initSelectedDataTypesPerStudy(studyCount: number) { this.selectedDataTypesPerStudy = Array(studyCount).fill(""); } @action.bound toggleStudyListItemCheckboxChecked(studyIndex: number) { this.studyListItemCheckboxChecked[studyIndex] = !this .studyListItemCheckboxChecked[studyIndex]; } @action.bound addSelectedStudy(selectedStudy: { data: any[]; dataTypes: { [dataType: string]: IDataTypeMetaData }; }) { this.selectedStudies.push(selectedStudy); } @action.bound removeSelectedStudy(selectedStudyData: any[]) { this.selectedStudies = this.selectedStudies.filter( (study) => study.data[0] != selectedStudyData[0] ); } @action.bound clearSelectedStudies() { this.selectedStudies = []; } @action.bound setShowDataTypeSelectionModal(show: boolean) { this.showDataTypeSelectionModal = show; } @action.bound clearStudyCheckboxesChecked() { const length = this.studyListItemCheckboxChecked.length; this.studyListItemCheckboxChecked = Array(length).fill(false); } @action.bound clearSelectedDataTypesPerStudy() { const length = this.studyListItemCheckboxChecked.length; this.selectedDataTypesPerStudy = Array(length).fill(""); } @action.bound unselectDataTypesForStudy(index: number) { this.selectedDataTypesPerStudy[index] = ""; } preparePortalAccess(studyId: string) { this.setDataTypeFetchResultsReady(false); this.portalAccessor.getSupportedGeneticProfiles(studyId, (data) => { this.disableAllDataTypes(); // Iterate through profiles for (const profile of Object.keys(data)) { const type = CBioPortalAccessor.getDataType(profile); if (type !== "") { this.setDataTypeProperties(type, { ...this.dataTypes[type], enabled: true, profile: profile, }); setTimeout(() => this.setDataTypeFetchResultsReady(true), 500); } } }); } disableAllDataTypes() { for (const dataType of Object.keys(this.dataTypes)) { this.setDataTypeProperties(dataType, { enabled: false, checked: false, profile: undefined, }); } } fetchStudy() { this.portalAccessor.getDataTypes().forEach((dataType) => { this.setDataTypeProperties(dataType, { enabled: false, checked: false, profile: undefined, }); }); this.portalAccessor.fetchCancerStudies((cancerStudies: any) => { let temp = []; for (const studyTitle in cancerStudies) { if (!cancerStudies.hasOwnProperty(studyTitle)) { continue; } const studyData = cancerStudies[studyTitle]; temp.push(studyData); } const numOfStudies = temp.length; this.initStudyListItemCheckboxChecked(numOfStudies); this.initSelectedDataTypesPerStudy(numOfStudies); this.setItemArray(temp); }); } @autobind resetModal() { this.disableAllDataTypes(); this.setSelectedStudyData([]); this.clearSelectedStudies(); this.clearStudyCheckboxesChecked(); this.clearSelectedDataTypesPerStudy(); this.currentlySelectedItemIndex = -1; this.searchQuery = ""; } @autobind handleCheckboxClick(dataType) { this.setDataTypeProperties(dataType, { ...this.dataTypes[dataType], checked: !this.dataTypes[dataType].checked, }); } @computed get selectedStudyDataTitle() { if (this.selectedStudyData.length > 1) { return this.selectedStudyData[1] || "Choose study"; } else { return "Choose study"; } } render() { return ( { this.props.handleClose(EModalType.STUDY); this.resetModal(); }} > Profile Data from cBioPortal

Select Cancer Study

this.setSearchQuery(event.target.value)} /> {this.itemArray.length < 1 ? ( Fetching studies from cBioPortal... ) : ( this.itemArray .map((item, index) => { return { item: item, index: index }; }) .filter((obj) => obj.item[1] .toLowerCase() .includes(this.searchQuery.toLowerCase()) ) .map((obj) => { const item = obj.item; const index = obj.index; const studyTitle = item[1]; const studyId = item[0]; return ( { const boundingRect = document .getElementById("listgroupitem" + index) .getBoundingClientRect(); const modalMargin = 30; this.checkboxModalPosition = { bottom: boundingRect.bottom - modalMargin, }; this.setSelectedStudyData(item); this.preparePortalAccess(studyId); this.toggleStudyListItemCheckboxChecked(index); this.currentlySelectedItemIndex = index; if (this.studyListItemCheckboxChecked[index]) { this.setShowDataTypeSelectionModal(true); } else { this.removeSelectedStudy(item); this.unselectDataTypesForStudy(index); } }} > {studyTitle} {this.selectedDataTypesPerStudy[index] != "" && ( {this.selectedDataTypesPerStudy[index]} )} ); }) )}

Warning: At most six different data sets will be overlayed on the genes. You can toggle which ones are to be displayed via "Alteration %" {">"} "View Settings" menu.

{ this.setShowDataTypeSelectionModal(false); }} > {this.dataTypeFetchResultsReady === false ? ( Fetching data types from cBioPortal... ) : ( Object.keys(this.dataTypes).map((dataType: string) => { return ( { this.handleCheckboxClick(dataType); }} checked={this.dataTypes[dataType].checked} > {dataType} ); }) )}
); } }