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