Unverified Commit f7af8721 authored by Andrey Azov's avatar Andrey Azov Committed by GitHub
Browse files

Refactor types retrieved from Thoas and used in components (#452)

parent c3fb8320
......@@ -26011,6 +26011,12 @@
"tslib": "^1.9.3"
}
},
"ts-multipick": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/ts-multipick/-/ts-multipick-1.0.0.tgz",
"integrity": "sha512-bqJKUPpUtXHQyHIbTmC2l87sluVNLCFu8GYX2ca3GbYXCQYylrx6UcT1cSUzk6goZjmKrp/bzkv0+mR4DXq4cQ==",
"dev": true
},
"ts-pnp": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz",
......@@ -163,6 +163,7 @@
"stylelint-scss": "3.18.0",
"stylelint-webpack-plugin": "2.1.0",
"terser-webpack-plugin": "4.1.0",
"ts-multipick": "1.0.0",
"typescript": "4.0.3",
"webpack": "4.44.1",
"webpack-bundle-analyzer": "3.8.0",
......
......@@ -17,6 +17,7 @@
import React from 'react';
import { useSelector } from 'react-redux';
import { gql, useQuery } from '@apollo/client';
import { Pick3 } from 'ts-multipick';
import * as urlFor from 'src/shared/helpers/urlHelper';
import { getFormattedLocation } from 'src/shared/helpers/formatters/regionFormatter';
......@@ -30,7 +31,7 @@ import { getBrowserActiveEnsObject } from 'src/content/app/browser/browserSelect
import ViewInApp from 'src/shared/components/view-in-app/ViewInApp';
import { EnsObjectGene } from 'src/shared/state/ens-object/ensObjectTypes';
import { Gene as GeneFromGraphql } from 'src/shared/types/thoas/gene';
import { FullGene } from 'src/shared/types/thoas/gene';
import styles from './GeneSummary.scss';
......@@ -49,7 +50,6 @@ const GENE_QUERY = gql`
slice {
strand {
code
value
}
location {
length
......@@ -59,19 +59,19 @@ const GENE_QUERY = gql`
}
`;
type Gene = Required<
Pick<
GeneFromGraphql,
| 'stable_id'
| 'unversioned_stable_id'
| 'symbol'
| 'name'
| 'alternative_symbols'
| 'so_term'
| 'transcripts'
| 'slice'
>
>;
type Gene = Pick<
FullGene,
| 'stable_id'
| 'unversioned_stable_id'
| 'symbol'
| 'name'
| 'alternative_symbols'
| 'so_term'
> &
Pick3<FullGene, 'slice', 'strand', 'code'> &
Pick3<FullGene, 'slice', 'location', 'length'> & {
transcripts: { stable_id: string }[];
};
const GeneSummary = () => {
const ensObjectGene = useSelector(getBrowserActiveEnsObject) as EnsObjectGene;
......
......@@ -40,31 +40,30 @@ import ExternalReference from 'src/shared/components/external-reference/External
import CloseButton from 'src/shared/components/close-button/CloseButton';
import { EnsObjectGene } from 'src/shared/state/ens-object/ensObjectTypes';
import { Transcript as TranscriptFromGraphql } from 'src/shared/types/thoas/transcript';
import { Gene as GeneFromGraphql } from 'src/shared/types/thoas/gene';
import { ProductGeneratingContext } from 'src/shared/types/thoas/productGeneratingContext';
import { FullTranscript } from 'src/shared/types/thoas/transcript';
import { FullGene } from 'src/shared/types/thoas/gene';
import styles from './TranscriptSummary.scss';
type Transcript = Required<
Pick<
TranscriptFromGraphql,
| 'stable_id'
| 'unversioned_stable_id'
| 'symbol'
| 'so_term'
| 'external_references'
| 'slice'
| 'spliced_exons'
| 'product_generating_contexts'
>
// TODO: narrow down the types for spliced exons and product-generating_contexts
type Transcript = Pick<
FullTranscript,
| 'stable_id'
| 'unversioned_stable_id'
| 'symbol'
| 'so_term'
| 'external_references'
| 'slice'
| 'spliced_exons'
| 'product_generating_contexts'
>;
type Gene = Required<
Pick<
GeneFromGraphql,
'stable_id' | 'unversioned_stable_id' | 'symbol' | 'name'
>
// TODO: narrow down the type and use it in the Transcript type
type ProductGeneratingContext = Transcript['product_generating_contexts'][number];
type Gene = Pick<
FullGene,
'stable_id' | 'unversioned_stable_id' | 'symbol' | 'name'
>;
const GENE_AND_TRANSCRIPT_QUERY = gql`
......
......@@ -36,19 +36,28 @@ import * as urlFor from 'src/shared/helpers/urlHelper';
import { buildFocusIdForUrl } from 'src/shared/state/ens-object/ensObjectHelpers';
import { parseFocusIdFromUrl } from 'src/shared/state/ens-object/ensObjectHelpers';
import GeneOverviewImage from './components/gene-overview-image/GeneOverviewImage';
import DefaultTranscriptslist from './components/default-transcripts-list/DefaultTranscriptsList';
import GeneOverviewImage, {
GeneOverviewImageProps
} from './components/gene-overview-image/GeneOverviewImage';
import DefaultTranscriptsList, {
Props as DefaultTranscriptsListProps
} from './components/default-transcripts-list/DefaultTranscriptsList';
import GeneViewTabs from './components/gene-view-tabs/GeneViewTabs';
import GeneFunction from 'src/content/app/entity-viewer/gene-view/components/gene-function/GeneFunction';
import GeneFunction, {
Props as GeneFunctionProps
} from 'src/content/app/entity-viewer/gene-view/components/gene-function/GeneFunction';
import GeneRelationships from 'src/content/app/entity-viewer/gene-view/components/gene-relationships/GeneRelationships';
import ViewInApp from 'src/shared/components/view-in-app/ViewInApp';
import { CircleLoader } from 'src/shared/components/loader/Loader';
import { Gene } from 'src/shared/types/thoas/gene';
import { TicksAndScale } from 'src/content/app/entity-viewer/gene-view/components/base-pairs-ruler/BasePairsRuler';
import styles from './GeneView.scss';
type Gene = GeneOverviewImageProps['gene'] &
DefaultTranscriptsListProps['gene'] &
GeneFunctionProps['gene'];
type GeneViewWithDataProps = {
gene: Gene;
};
......@@ -201,7 +210,7 @@ const GeneViewWithData = (props: GeneViewWithDataProps) => {
<div className={styles.geneViewTabContent}>
{selectedTabs.primaryTab === GeneViewTabName.TRANSCRIPTS &&
basePairsRulerTicks && (
<DefaultTranscriptslist
<DefaultTranscriptsList
gene={props.gene}
rulerTicks={basePairsRulerTicks}
/>
......
......@@ -17,6 +17,7 @@
import React, { useState, useEffect, useMemo } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import classNames from 'classnames';
import { Pick2, Pick3 } from 'ts-multipick';
import { getFeatureCoordinates } from 'src/content/app/entity-viewer/shared/helpers/entity-helpers';
import {
......@@ -35,18 +36,40 @@ import {
SortingRule
} from 'src/content/app/entity-viewer/state/gene-view/transcripts/geneViewTranscriptsSlice';
import DefaultTranscriptsListItem from './default-transcripts-list-item/DefaultTranscriptListItem';
import DefaultTranscriptsListItem, {
DefaultTranscriptListItemProps
} from './default-transcripts-list-item/DefaultTranscriptListItem';
import TranscriptsFilter from 'src/content/app/entity-viewer/gene-view/components/transcripts-filter/TranscriptsFilter';
import { TicksAndScale } from 'src/content/app/entity-viewer/gene-view/components/base-pairs-ruler/BasePairsRuler';
import { Gene } from 'src/shared/types/thoas/gene';
import { Transcript } from 'src/shared/types/thoas/transcript';
import { FullGene } from 'src/shared/types/thoas/gene';
import { FullTranscript } from 'src/shared/types/thoas/transcript';
import { FullProductGeneratingContext } from 'src/shared/types/thoas/productGeneratingContext';
import { FullCDS } from 'src/shared/types/thoas/cds';
import { SplicedExon } from 'src/shared/types/thoas/exon';
import { Slice } from 'src/shared/types/thoas/slice';
import { ReactComponent as ChevronDown } from 'static/img/shared/chevron-down.svg';
import styles from './DefaultTranscriptsList.scss';
type Props = {
type ProductGeneratingContext = {
product_type: FullProductGeneratingContext['product_type'];
cds: Pick<FullCDS, 'relative_start' | 'relative_end'>;
};
type Transcript = DefaultTranscriptListItemProps['transcript'] & {
so_term: FullTranscript['so_term'];
product_generating_contexts: ProductGeneratingContext[];
} & {
spliced_exons: Array<Pick3<SplicedExon, 'exon', 'slice', 'location'>>;
} & Pick2<FullTranscript, 'slice', 'location'>;
type Gene = DefaultTranscriptListItemProps['gene'] & {
stable_id: FullGene['stable_id'];
transcripts: Array<Transcript>;
slice: Pick2<Slice, 'location', 'start' | 'end'>;
};
export type Props = {
gene: Gene;
rulerTicks: TicksAndScale;
};
......
......@@ -17,21 +17,28 @@
import React from 'react';
import { connect } from 'react-redux';
import UnsplicedTranscript from 'src/content/app/entity-viewer/gene-view/components/unspliced-transcript/UnsplicedTranscript';
import TranscriptsListItemInfo from '../transcripts-list-item-info/TranscriptsListItemInfo';
import UnsplicedTranscript, {
UnsplicedTranscriptProps
} from 'src/content/app/entity-viewer/gene-view/components/unspliced-transcript/UnsplicedTranscript';
import TranscriptsListItemInfo, {
TranscriptsListItemInfoProps
} from '../transcripts-list-item-info/TranscriptsListItemInfo';
import { toggleTranscriptInfo } from 'src/content/app/entity-viewer/state/gene-view/transcripts/geneViewTranscriptsSlice';
import { Gene } from 'src/shared/types/thoas/gene';
import { Transcript } from 'src/shared/types/thoas/transcript';
import { FullTranscript } from 'src/shared/types/thoas/transcript';
import { TicksAndScale } from 'src/content/app/entity-viewer/gene-view/components/base-pairs-ruler/BasePairsRuler';
import { TranscriptQualityLabel } from 'src/content/app/entity-viewer/shared/components/default-transcript-label/TranscriptQualityLabel';
import transcriptsListStyles from '../DefaultTranscriptsList.scss';
import styles from './DefaultTranscriptListItem.scss';
type Transcript = Pick<FullTranscript, 'stable_id' | 'relative_location'> &
TranscriptsListItemInfoProps['transcript'] &
UnsplicedTranscriptProps['transcript'];
export type DefaultTranscriptListItemProps = {
gene: Gene;
gene: TranscriptsListItemInfoProps['gene'];
isDefault?: boolean;
transcript: Transcript;
rulerTicks: TicksAndScale;
......@@ -56,9 +63,7 @@ export const DefaultTranscriptListItem = (
return (
<div className={styles.defaultTranscriptListItem}>
<div className={transcriptsListStyles.row}>
{props.isDefault && (
<TranscriptQualityLabel transcript={props.transcript} />
)}
{props.isDefault && <TranscriptQualityLabel />}
<div className={transcriptsListStyles.middle}>
<div
......
......@@ -18,6 +18,7 @@ import React from 'react';
import { useParams, Link } from 'react-router-dom';
import classNames from 'classnames';
import { connect } from 'react-redux';
import { Pick2, Pick3, Pick4 } from 'ts-multipick';
import { getCommaSeparatedNumber } from 'src/shared/helpers/formatters/numberFormatter';
import { getFormattedLocation } from 'src/shared/helpers/formatters/regionFormatter';
......@@ -39,13 +40,42 @@ import CloseButton from 'src/shared/components/close-button/CloseButton';
import { toggleTranscriptDownload } from 'src/content/app/entity-viewer/state/gene-view/transcripts/geneViewTranscriptsSlice';
import { clearExpandedProteins } from 'src/content/app/entity-viewer/state/gene-view/proteins/geneViewProteinsSlice';
import { Gene } from 'src/shared/types/thoas/gene';
import { Transcript } from 'src/shared/types/thoas/transcript';
import { FullGene } from 'src/shared/types/thoas/gene';
import { FullTranscript } from 'src/shared/types/thoas/transcript';
import { SplicedExon, PhasedExon } from 'src/shared/types/thoas/exon';
import { FullProductGeneratingContext } from 'src/shared/types/thoas/productGeneratingContext';
import { View } from 'src/content/app/entity-viewer/state/gene-view/view/geneViewViewSlice';
import transcriptsListStyles from '../DefaultTranscriptsList.scss';
import styles from './TranscriptsListItemInfo.scss';
type Gene = Pick<FullGene, 'unversioned_stable_id'>;
type Transcript = Pick<
FullTranscript,
'stable_id' | 'unversioned_stable_id' | 'symbol' | 'so_term'
> &
Pick2<FullTranscript, 'slice', 'location'> &
Pick3<FullTranscript, 'slice', 'region', 'name'> & {
spliced_exons: Array<
Pick2<SplicedExon, 'exon', 'stable_id'> &
Pick4<SplicedExon, 'exon', 'slice', 'location', 'length'>
>;
} & {
product_generating_contexts: Array<
Pick<FullProductGeneratingContext, 'product_type'> &
Pick2<
FullProductGeneratingContext,
'product',
'length' | 'stable_id'
> & {
phased_exons: Array<
Pick<PhasedExon, 'start_phase' | 'end_phase'> &
Pick2<PhasedExon, 'exon', 'stable_id'>
>;
}
>;
};
export type TranscriptsListItemInfoProps = {
gene: Gene;
transcript: Transcript;
......
......@@ -32,9 +32,7 @@ import { isProteinCodingTranscript } from 'src/content/app/entity-viewer/shared/
import Tabs, { Tab } from 'src/shared/components/tabs/Tabs';
import Panel from 'src/shared/components/panel/Panel';
import ProteinsList from '../proteins-list/ProteinsList';
import { Gene } from 'src/shared/types/thoas/gene';
import ProteinsList, { ProteinsListProps } from '../proteins-list/ProteinsList';
import styles from './GeneFunction.scss';
......@@ -52,8 +50,8 @@ const tabClassNames = {
selected: styles.selectedTabName
};
type Props = {
gene: Gene;
export type Props = {
gene: ProteinsListProps['gene'];
};
const GeneFunction = (props: Props) => {
......
......@@ -16,21 +16,34 @@
import React from 'react';
import { scaleLinear } from 'd3';
import { Pick3 } from 'ts-multipick';
import { getFeatureCoordinates } from 'src/content/app/entity-viewer/shared/helpers/entity-helpers';
import { getStrandDisplayName } from 'src/shared/helpers/formatters/strandFormatter';
import { pluralise } from 'src/shared/helpers/formatters/pluralisationFormatter';
import UnsplicedTranscript from 'src/content/app/entity-viewer/gene-view/components/unspliced-transcript/UnsplicedTranscript';
import UnsplicedTranscript, {
UnsplicedTranscriptProps
} from 'src/content/app/entity-viewer/gene-view/components/unspliced-transcript/UnsplicedTranscript';
import BasePairsRuler from 'src/content/app/entity-viewer/gene-view/components/base-pairs-ruler/BasePairsRuler';
import { Gene } from 'src/shared/types/thoas/gene';
import { FullGene } from 'src/shared/types/thoas/gene';
import { FullTranscript } from 'src/shared/types/thoas/transcript';
import { TicksAndScale } from 'src/content/app/entity-viewer/gene-view/components/base-pairs-ruler/BasePairsRuler';
import styles from './GeneOverviewImage.scss';
import { pluralise } from 'src/shared/helpers/formatters/pluralisationFormatter';
import settings from 'src/content/app/entity-viewer/gene-view/styles/_constants.scss';
type GeneOverviewImageProps = {
type Gene = Pick<FullGene, 'stable_id'> &
Pick3<FullGene, 'slice', 'location', 'start' | 'end'> &
Pick3<FullGene, 'slice', 'strand', 'code'> & {
transcripts: Array<
UnsplicedTranscriptProps['transcript'] &
Pick3<FullTranscript, 'slice', 'location', 'start' | 'end'>
>;
};
export type GeneOverviewImageProps = {
gene: Gene;
onTicksCalculated: (payload: TicksAndScale) => void;
};
......
......@@ -18,6 +18,7 @@ import React, { useState } from 'react';
import { useQuery, gql } from '@apollo/client';
import { useParams } from 'react-router';
import sortBy from 'lodash/sortBy';
import { Pick2 } from 'ts-multipick';
import { parseEnsObjectIdFromUrl } from 'src/shared/state/ens-object/ensObjectHelpers';
import { defaultSort } from 'src/content/app/entity-viewer/shared/helpers/transcripts-sorter';
......@@ -36,8 +37,8 @@ import {
ExternalReferencesGroup
} from 'src/shared/types/thoas/externalReference';
import { EntityViewerParams } from 'src/content/app/entity-viewer/EntityViewer';
import { SliceWithLocationOnly } from 'src/shared/types/thoas/slice';
import { ProductGeneratingContext } from 'src/shared/types/thoas/productGeneratingContext';
import { Slice } from 'src/shared/types/thoas/slice';
import { FullProductGeneratingContext } from 'src/shared/types/thoas/productGeneratingContext';
import styles from './GeneExternalReferences.scss';
......@@ -97,11 +98,12 @@ const QUERY = gql`
type Transcript = {
stable_id: string;
so_term: string;
slice: SliceWithLocationOnly;
product_generating_contexts: Pick<
ProductGeneratingContext,
'product_type' | 'product'
>[];
slice: Pick2<Slice, 'location', 'length'>;
product_generating_contexts: Array<
Pick<FullProductGeneratingContext, 'product_type'> & {
product: { external_references: ExternalReferenceType[] };
}
>;
external_references: ExternalReferenceType[];
};
......
......@@ -23,7 +23,7 @@ import GenePublications from '../publications/GenePublications';
import MainAccordion from './MainAccordion';
import { EntityViewerParams } from 'src/content/app/entity-viewer/EntityViewer';
import { Gene as GeneFromGraphql } from 'src/shared/types/thoas/gene';
import { FullGene } from 'src/shared/types/thoas/gene';
import styles from './GeneOverview.scss';
......@@ -44,7 +44,7 @@ export const GENE_OVERVIEW_QUERY = gql`
`;
type Gene = Required<
Pick<GeneFromGraphql, 'stable_id' | 'symbol' | 'name' | 'alternative_symbols'>
Pick<FullGene, 'stable_id' | 'symbol' | 'name' | 'alternative_symbols'>
>;
const GeneOverview = () => {
......
......@@ -27,7 +27,7 @@ const TRACK_HEIGHT = 24;
const PROTEIN_HEIGHT = 10;
type ProteinImageProps = {
product: Product;
product: Pick<Product, 'length'>;
trackLength: number; // length in amino acids
className?: string;
width: number; // available width for drawing in pixels
......
......@@ -17,8 +17,11 @@
import React, { useEffect, useMemo } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { useLocation } from 'react-router';
import { Pick3 } from 'ts-multipick';
import ProteinsListItem from './proteins-list-item/ProteinsListItem';
import ProteinsListItem, {
Props as ProteinListItemProps
} from './proteins-list-item/ProteinsListItem';
import {
getLongestProteinLength,
......@@ -33,12 +36,25 @@ import { toggleExpandedProtein } from 'src/content/app/entity-viewer/state/gene-
import { getExpandedTranscriptIds } from 'src/content/app/entity-viewer/state/gene-view/proteins/geneViewProteinsSelectors';
import { getSortingRule } from 'src/content/app/entity-viewer/state/gene-view/transcripts/geneViewTranscriptsSelectors';
import { Gene } from 'src/shared/types/thoas/gene';
import { Transcript } from 'src/shared/types/thoas/transcript';
import { FullGene } from 'src/shared/types/thoas/gene';
import { FullTranscript } from 'src/shared/types/thoas/transcript';
import { Exon } from 'src/shared/types/thoas/exon';
import styles from './ProteinsList.scss';
type ProteinsListProps = {
type Transcript = Pick<FullTranscript, 'so_term'> &
ProteinListItemProps['transcript'] &
Pick3<FullTranscript, 'slice', 'location', 'length'> & {
spliced_exons: Array<{
exon: Pick3<Exon, 'slice', 'location', 'length'>;
}>;
};
type Gene = Pick<FullGene, 'stable_id'> & {
transcripts: Transcript[];
};
export type ProteinsListProps = {
gene: Gene;
};
......@@ -55,12 +71,10 @@ const ProteinsList = (props: ProteinsListProps) => {
const sortingRule = useSelector(getSortingRule);
const sortingFunction = transcriptSortingFunctions[sortingRule];
const sortedTranscripts = sortingFunction(
props.gene.transcripts
) as Transcript[];
const sortedTranscripts = sortingFunction(props.gene.transcripts);
const proteinCodingTranscripts = sortedTranscripts.filter(
isProteinCodingTranscript
);
) as Transcript[];
useEffect(() => {
const hasExpandedTranscripts = !!expandedTranscriptIds.length;
......
......@@ -17,6 +17,7 @@
import React, { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import set from 'lodash/fp/set';
import { Pick2 } from 'ts-multipick';
import { CircleLoader } from 'src/shared/components/loader/Loader';
import { PrimaryButton } from 'src/shared/components/button/Button';
......@@ -37,15 +38,45 @@ import {
} from 'src/content/app/entity-viewer/shared/rest/rest-data-fetchers/proteinData';
import { LoadingState } from 'src/shared/types/loading-state';
import { Transcript } from 'src/shared/types/thoas/transcript';
import { FullTranscript } from 'src/shared/types/thoas/transcript';
import { Product } from 'src/shared/types/thoas/product';
import { ProteinDomain } from 'src/shared/types/thoas/product';
import { ExternalReference as ExternalReferenceType } from 'src/shared/types/thoas/externalReference';
import { SWISSPROT_SOURCE } from '../protein-list-constants';
import styles from './ProteinsListItemInfo.scss';
import settings from 'src/content/app/entity-viewer/gene-view/styles/_constants.scss';
type Props = {
type ProductWithoutDomains = Pick<
Product,
'length' | 'unversioned_stable_id'
> & {
external_references: Array<
Pick<ExternalReferenceType, 'accession_id' | 'name'> &
Pick2<ExternalReferenceType, 'source', 'id'>
>;
};