import * as React from 'react'; import { GenePanel, GenePanelToGene } from 'cbioportal-ts-api-client'; import { observer } from 'mobx-react'; import { SimpleCopyDownloadControls } from 'shared/components/copyDownloadControls/SimpleCopyDownloadControls'; import { serializeData } from 'shared/lib/Serializer'; import styles from './styles.module.scss'; import { chunk, flatten } from 'lodash'; import { observable, action, computed, makeObservable } from 'mobx'; import autobind from 'autobind-decorator'; import classnames from 'classnames'; import SimpleTable from 'shared/components/simpleTable/SimpleTable'; interface IGenesListProps { genePanel: GenePanel; columns?: number; id?: string | undefined; } @observer export default class GenesList extends React.Component { @observable filter: string = ''; constructor(props: IGenesListProps) { super(props); makeObservable(this); } @action.bound handleChangeInput(value: string) { this.filter = value; } @computed get filteredGenes() { const { genes } = this.props.genePanel; if (this.filter) { const regex = new RegExp(this.filter, 'i'); return genes.filter( gene => regex.test(gene.entrezGeneId.toString()) || regex.test(gene.hugoGeneSymbol) ); } return genes; } genesDividedToColumns = (genes: GenePanelToGene[]) => { let result = []; let columnCount = this.columnCount; let remainingGenes = [...genes]; while (columnCount > 0) { const chunked = chunk( remainingGenes, Math.ceil(remainingGenes.length / columnCount) ); if (chunked.length === columnCount) { result = result.concat(chunked); break; } else { result.push(chunked[0]); remainingGenes = remainingGenes.slice(flatten(result).length); columnCount--; } } return result; }; @computed get renderTableRows() { const filtered = this.filteredGenes; if (filtered.length === 0) { return []; } const rows: JSX.Element[] = []; this.genesDividedToRows(filtered).forEach(row => { const tdValues = row.map(gene => ( {gene} )); rows.push({tdValues}); }); return rows; } getDownloadData = () => { const downloadData = [ ['Genes'], ...this.props.genePanel.genes.map(gene => [gene.hugoGeneSymbol]), ]; return serializeData(downloadData); }; genesDividedToRows = (genes: GenePanelToGene[]) => { const genesByColumns = this.genesDividedToColumns(genes); const genesByRows = []; const geneCountPerColumn = this.geneCountPerColumn(genes.length); for (let i = 0; i < geneCountPerColumn; i++) { const genesPerRow = []; for (let j = 0; j < this.columnCount; j++) { genesPerRow.push( genesByColumns[j] && genesByColumns[j][i] ? genesByColumns[j][i].hugoGeneSymbol : '' ); } genesByRows.push(genesPerRow); } return genesByRows; }; @computed get columnCount() { return this.props.columns || 1; } geneCountPerColumn = (totalLength: number) => { return Math.ceil(totalLength / this.columnCount); }; @computed get renderTableHeaders() { const thValues = [Genes]; return thValues.concat(Array(this.columnCount - 1).fill()); } render() { return (

{this.props.genePanel.genePanelId}

Number of genes: {this.props.genePanel.genes.length}
) => this.handleChangeInput(e.target.value) } className="form-control" />
); } }