diff --git a/src/pages/patientView/PatientViewPage.tsx b/src/pages/patientView/PatientViewPage.tsx
index ac5fe279361..21d606533fe 100644
--- a/src/pages/patientView/PatientViewPage.tsx
+++ b/src/pages/patientView/PatientViewPage.tsx
@@ -547,6 +547,7 @@ export default class PatientViewPage extends React.Component
)
diff --git a/src/pages/patientView/copyNumberAlterations/CopyNumberTableWrapper.tsx b/src/pages/patientView/copyNumberAlterations/CopyNumberTableWrapper.tsx
index 3ca23d6f17c..f679fc4e223 100644
--- a/src/pages/patientView/copyNumberAlterations/CopyNumberTableWrapper.tsx
+++ b/src/pages/patientView/copyNumberAlterations/CopyNumberTableWrapper.tsx
@@ -21,6 +21,7 @@ import CopyNumberCountCache from "../clinicalInformation/CopyNumberCountCache";
import {ICivicGeneDataWrapper, ICivicVariantDataWrapper} from "shared/model/Civic.ts";
import HeaderIconMenu from '../mutation/HeaderIconMenu';
import GeneFilterMenu, { GeneFilterOption } from '../mutation/GeneFilterMenu';
+import PanelColumnFormatter from "shared/components/mutationTable/column/PanelColumnFormatter";
class CNATableComponent extends LazyMobXTable {
@@ -55,6 +56,7 @@ type ICopyNumberTableWrapperProps = {
showGeneFilterMenu?:boolean;
currentGeneFilter:GeneFilterOption;
onFilterGenes?:(option:GeneFilterOption)=>void;
+ sampleToMutationGenePanelId?: {[sampleId:string]:string};
};
@observer
@@ -112,6 +114,15 @@ export default class CopyNumberTableWrapper extends React.Component PanelColumnFormatter.renderFunction(d, this.props.sampleToMutationGenePanelId),
+ download: (d:DiscreteCopyNumberData[]) => PanelColumnFormatter.download(d, this.props.sampleToMutationGenePanelId),
+ sortBy: (d:DiscreteCopyNumberData[]) => PanelColumnFormatter.getGenePanelIds(d, this.props.sampleToMutationGenePanelId),
+ visible: false,
+ order: 35
+ });
columns.push({
name: "CNA",
diff --git a/src/pages/patientView/mutation/PatientViewMutationTable.tsx b/src/pages/patientView/mutation/PatientViewMutationTable.tsx
index 556438d57f8..350a264b490 100644
--- a/src/pages/patientView/mutation/PatientViewMutationTable.tsx
+++ b/src/pages/patientView/mutation/PatientViewMutationTable.tsx
@@ -9,6 +9,7 @@ import {Mutation} from "shared/api/generated/CBioPortalAPI";
import AlleleCountColumnFormatter from "shared/components/mutationTable/column/AlleleCountColumnFormatter";
import AlleleFreqColumnFormatter from "./column/AlleleFreqColumnFormatter";
import TumorColumnFormatter from "./column/TumorColumnFormatter";
+import PanelColumnFormatter from "shared/components/mutationTable/column/PanelColumnFormatter";
import {isUncalled} from "shared/lib/MutationUtils";
import TumorAlleleFreqColumnFormatter from "shared/components/mutationTable/column/TumorAlleleFreqColumnFormatter";
import ExonColumnFormatter from "shared/components/mutationTable/column/ExonColumnFormatter";
@@ -66,7 +67,8 @@ export default class PatientViewMutationTable extends MutationTableTumorColumnFormatter.getSortValue(d, this.props.sampleManager),
download: (d:Mutation[])=>TumorColumnFormatter.getSample(d),
};
+
+ this._columns[MutationTableColumnType.GENE_PANEL] = {
+ name: "Gene panel",
+ render: (d:Mutation[]) => PanelColumnFormatter.renderFunction(d, this.props.sampleToMutationGenePanelId),
+ download: (d:Mutation[]) => PanelColumnFormatter.download(d, this.props.sampleToMutationGenePanelId),
+ visible: false,
+ sortBy: (d:Mutation[]) => PanelColumnFormatter.getGenePanelIds(d, this.props.sampleToMutationGenePanelId)
+ }
// customization for allele count columns
@@ -136,6 +146,7 @@ export default class PatientViewMutationTable extends MutationTable&{order?:number, shouldExclude?:()=>boolean};
diff --git a/src/shared/components/mutationTable/column/PanelColumnFormatter.spec.tsx b/src/shared/components/mutationTable/column/PanelColumnFormatter.spec.tsx
new file mode 100644
index 00000000000..dc1ae81daf1
--- /dev/null
+++ b/src/shared/components/mutationTable/column/PanelColumnFormatter.spec.tsx
@@ -0,0 +1,49 @@
+import PanelColumnFormatter from "./PanelColumnFormatter";
+import { shallow } from "enzyme";
+import { assert } from 'chai';
+
+const mockData = [
+ {
+ alteration: 1,
+ entrezGeneId: 1,
+ gene: {
+ entrezGeneId: 1,
+ hugoGeneSymbol: 'test',
+ geneticEntityId: 1,
+ type: 'test'
+ },
+ molecularProfileId: 'test',
+ patientId: 'test',
+ sampleId: 'sampleId',
+ studyId: 'test',
+ uniquePatientKey: 'test',
+ uniqueSampleKey: 'test',
+ }
+];
+
+const mockSampleToMutationGenePanelId = { 'sampleId': 'genePanelId' };
+
+describe("PanelColumnFormatter", () => {
+ it('renders spinner icon if sampleToMutationGenePanelId object is empty', () => {
+ const PanelColumn = shallow(PanelColumnFormatter.renderFunction(mockData, {}));
+ assert.isTrue(PanelColumn.find('i.fa-spinner').exists());
+ });
+
+ it('renders gene panel information', () => {
+ const PanelColumn = shallow(PanelColumnFormatter.renderFunction(
+ mockData,
+ mockSampleToMutationGenePanelId
+ ));
+ assert.isTrue(PanelColumn.text().includes('genePanelId'));
+ });
+
+ it('returns a list of gene panel ids on download', () => {
+ const genePanelIds = PanelColumnFormatter.download(mockData, mockSampleToMutationGenePanelId);
+ assert.deepEqual(genePanelIds, ['genePanelId'])
+ });
+
+ it('returns a list of gene panel ids on getGenePanelIds', () => {
+ const genePanelIds = PanelColumnFormatter.getGenePanelIds(mockData, mockSampleToMutationGenePanelId);
+ assert.deepEqual(genePanelIds, ['genePanelId'])
+ })
+})
diff --git a/src/shared/components/mutationTable/column/PanelColumnFormatter.tsx b/src/shared/components/mutationTable/column/PanelColumnFormatter.tsx
new file mode 100644
index 00000000000..009a710c556
--- /dev/null
+++ b/src/shared/components/mutationTable/column/PanelColumnFormatter.tsx
@@ -0,0 +1,67 @@
+import * as React from 'react';
+import {
+ Mutation,
+ DiscreteCopyNumberData
+} from 'shared/api/generated/CBioPortalAPI';
+
+interface PanelColumnFormatterProps {
+ data: Mutation[] | DiscreteCopyNumberData[];
+ sampleToMutationGenePanelId: {[sampleId:string]: string} | undefined;
+}
+
+class PanelColumn extends React.Component {
+ constructor(props: PanelColumnFormatterProps) {
+ super(props);
+ }
+
+ render() {
+ const { data, sampleToMutationGenePanelId } = this.props;
+
+ if (!sampleToMutationGenePanelId) return;
+
+ if (sampleToMutationGenePanelId && !Object.keys(sampleToMutationGenePanelId).length) {
+ return ;
+ }
+
+ const genePanelIds: string[] = getGenePanelIds(
+ data,
+ sampleToMutationGenePanelId
+ );
+
+ return (
+
+
+ {genePanelIds.join(', ')}
+
+
+ );
+ }
+}
+
+const getGenePanelIds = (
+ data: any[],
+ sampleToMutationGenePanelId: {[sampleId:string]: string} | undefined
+) => {
+ if (sampleToMutationGenePanelId) {
+ const sampleIds = data.map((datum) => datum.sampleId);
+ return sampleIds.map((id) => sampleToMutationGenePanelId[id]);
+ }
+ return [];
+};
+
+export default {
+ renderFunction: (
+ data: Mutation[] | DiscreteCopyNumberData[],
+ sampleToMutationGenePanelId: {[sampleId:string]: string} | undefined
+ ) => (
+
+ ),
+ download: (
+ data: Mutation[] | DiscreteCopyNumberData[],
+ sampleToMutationGenePanelId: {[sampleId:string]: string} | undefined
+ ) => getGenePanelIds(data, sampleToMutationGenePanelId),
+ getGenePanelIds
+};