Unverified Commit 8017ad67 authored by Ridwan Amode's avatar Ridwan Amode Committed by GitHub
Browse files

display gene source using gene metadata.name field from thoas (#542)

* ENSWBSITES-958 and ENSWBSITES-957
* display gene source using gene metadata.name
* fix test by adding gene metadata
* check for gene metadata name should be for xref only
* Add margin top to source
* Remove unused regex for gene name formatting
* update test for genename formatting
parent 53b1dbc2
Pipeline #182401 passed with stages
in 4 minutes and 51 seconds
......@@ -21,6 +21,9 @@
margin-top: 30px;
}
.marginTop {
margin-top: 6px;
}
.featureDetails {
display: flex;
......
......@@ -17,19 +17,21 @@
import React, { useState } from 'react';
import { useSelector } from 'react-redux';
import { gql, useQuery } from '@apollo/client';
import { Pick2, Pick3 } from 'ts-multipick';
import { Pick3 } from 'ts-multipick';
import classNames from 'classnames';
import * as urlFor from 'src/shared/helpers/urlHelper';
import { getFormattedLocation } from 'src/shared/helpers/formatters/regionFormatter';
import { getStrandDisplayName } from 'src/shared/helpers/formatters/strandFormatter';
import { getGeneName } from 'src/shared/helpers/formatters/geneFormatter';
import {
buildFocusIdForUrl,
getDisplayStableId
} from 'src/shared/state/ens-object/ensObjectHelpers';
import { getBrowserActiveEnsObject } from 'src/content/app/browser/browserSelectors';
import ExternalReference from 'src/shared/components/external-reference/ExternalReference';
import InstantDownloadGene from 'src/shared/components/instant-download/instant-download-gene/InstantDownloadGene';
import ViewInApp from 'src/shared/components/view-in-app/ViewInApp';
import CloseButton from 'src/shared/components/close-button/CloseButton';
......@@ -63,6 +65,10 @@ const GENE_QUERY = gql`
label
value
}
name {
accession_id
url
}
}
}
}
......@@ -75,8 +81,8 @@ type Gene = Pick<
| 'symbol'
| 'name'
| 'alternative_symbols'
| 'metadata'
> &
Pick2<FullGene, 'metadata', 'biotype'> &
Pick3<FullGene, 'slice', 'strand', 'code'> &
Pick3<FullGene, 'slice', 'location', 'length'> & {
transcripts: { stable_id: string }[];
......@@ -136,7 +142,16 @@ const GeneSummary = () => {
<div className={rowClasses}>
<div className={styles.label}>Gene name</div>
<div className={styles.value}>{getGeneName(gene.name)}</div>
<div className={styles.geneName}>
{getGeneName(gene.name)}
{gene.metadata.name && (
<ExternalReference
classNames={{ container: styles.marginTop }}
to={gene.metadata.name.url}
linkText={gene.metadata.name.accession_id}
/>
)}
</div>
</div>
{gene.alternative_symbols.length > 0 && (
......
......@@ -282,7 +282,6 @@ const TranscriptSummary = () => {
)}
{uniprotXref && (
<ExternalReference
classNames={{ label: styles.lightText }}
label={'UniProtKB/Swiss-Prot'}
to={uniprotXref.url}
linkText={uniprotXref.accession_id}
......
......@@ -4,6 +4,9 @@
font-size: 13px;
}
.marginTop {
margin-top: 6px;
}
.sectionHead {
color: $dark-grey;
......@@ -22,7 +25,6 @@
}
}
.accordionContainer {
width: 100%;
......
......@@ -45,11 +45,19 @@ const alternativeSymbols = [
'gene_synonym_3'
];
const metadata = {
name: {
accession_id: 'name_accession_id',
url: 'name_url'
}
};
const completeGeneData = {
name: geneName,
stable_id: stableId,
symbol: geneSymbol,
alternative_symbols: alternativeSymbols
alternative_symbols: alternativeSymbols,
metadata: metadata
};
describe('<GeneOverview />', () => {
......@@ -110,6 +118,9 @@ describe('<GeneOverview />', () => {
const geneDetailsElement = container.querySelector('.geneDetails');
const geneNameElement = container.querySelector('.geneName');
const synonymsElement = container.querySelector('.synonyms');
const xrefElement = container.querySelector(
'.externalLinkContainer .link'
);
// child components
const genePublications = container.querySelector('.genePublications');
......@@ -117,6 +128,7 @@ describe('<GeneOverview />', () => {
expect(geneDetailsElement?.textContent).toMatch(geneSymbol);
expect(geneDetailsElement?.textContent).toMatch(stableId);
expect(geneNameElement?.textContent).toMatch(geneName);
expect(xrefElement?.textContent).toMatch(metadata.name.accession_id);
expect(synonymsElement?.textContent).toMatch(
alternativeSymbols.join(', ')
);
......
......@@ -22,6 +22,7 @@ import { getGeneName } from 'src/shared/helpers/formatters/geneFormatter';
import GenePublications from '../publications/GenePublications';
import MainAccordion from './MainAccordion';
import ExternalReference from 'src/shared/components/external-reference/ExternalReference';
import { EntityViewerParams } from 'src/content/app/entity-viewer/EntityViewer';
import { FullGene } from 'src/shared/types/thoas/gene';
......@@ -40,12 +41,21 @@ export const GENE_OVERVIEW_QUERY = gql`
name
stable_id
symbol
metadata {
name {
accession_id
url
}
}
}
}
`;
type Gene = Required<
Pick<FullGene, 'stable_id' | 'symbol' | 'name' | 'alternative_symbols'>
Pick<
FullGene,
'stable_id' | 'symbol' | 'name' | 'alternative_symbols' | 'metadata'
>
>;
const GeneOverview = () => {
......@@ -82,7 +92,13 @@ const GeneOverview = () => {
<div className={styles.sectionHead}>Gene name</div>
<div className={styles.geneName}>{getGeneName(gene.name)}</div>
{gene.metadata.name && (
<ExternalReference
classNames={{ container: styles.marginTop }}
to={gene.metadata.name.url}
linkText={gene.metadata.name.accession_id}
/>
)}
<div className={styles.sectionHead}>Synonyms</div>
<div className={styles.synonyms}>
{gene.alternative_symbols.length
......
......@@ -14,13 +14,12 @@
* limitations under the License.
*/
import { getGeneName } from './geneFormatter';
describe('getGeneName', () => {
it('returns the correct gene display name', () => {
expect(getGeneName('novel transcript')).toBe('None');
expect(getGeneName('')).toBe('None');
expect(getGeneName(null)).toBe('None');
expect(getGeneName('Heat shock protein 101 [Source:UniProtKB/TrEMBL;Acc:Q9SPH4]')).toBe('Heat shock protein 101');
});
});
import { getGeneName } from './geneFormatter';
describe('getGeneName', () => {
it('returns the correct gene display name', () => {
expect(getGeneName('novel transcript')).toBe('None');
expect(getGeneName('')).toBe('None');
expect(getGeneName(null)).toBe('None');
});
});
......@@ -15,8 +15,8 @@
*/
export function getGeneName(geneName: string | null) {
if(geneName && geneName !== 'novel transcript') {
return geneName.replace(/\[Source:.*\]/,'').trim();
if (geneName && geneName !== 'novel transcript') {
return geneName;
} else {
return 'None';
}
......
......@@ -20,6 +20,11 @@ export type ValueSetMetadata = {
definition: string;
};
export type XrefMetadata = {
accession_id: string;
url: string;
};
type CanonicalMetadata = Omit<ValueSetMetadata, 'value'> & { value: boolean };
type NCBITranscriptMetadata = {
......@@ -41,4 +46,5 @@ export type TranscriptMetadata = {
export type GeneMetadata = {
biotype: ValueSetMetadata;
name: XrefMetadata | null;
};
......@@ -29,13 +29,6 @@ const buildProteinCodingGene = () => {
});
const gene = createGene({
unversioned_stable_id: 'ENSG00000157764',
metadata: {
biotype: {
label: 'Protein coding',
value: 'protein_coding',
definition: 'Protein coding'
}
},
transcripts: [transcript]
});
return gene;
......
......@@ -48,6 +48,10 @@ export const createGene = (fragment: Partial<FullGene> = {}): FullGene => {
label: faker.lorem.words(),
value: faker.lorem.word(),
definition: faker.lorem.sentence()
},
name: {
accession_id: faker.lorem.word(),
url: faker.internet.url()
}
},
...fragment
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment