Unverified Commit 0da2c9fa authored by Manoj Pandian Sakthivel's avatar Manoj Pandian Sakthivel Committed by GitHub
Browse files

Protein info error handling (#373)

Displaying an error message when the data fails to load along with a button to retry.
parent e8335403
Pipeline #107621 passed with stages
in 7 minutes and 46 seconds
......@@ -53,7 +53,7 @@ const ProteinsList = (props: ProteinsListProps) => {
const hasExpandedTranscripts = !!props.expandedTranscriptIds.length;
const firstProteinId =
proteinCodingTranscripts[0].product_generating_contexts[0].product
.unversioned_stable_id;
.stable_id;
// Expand the first transcript by default
if (!hasExpandedTranscripts && !proteinIdToFocus) {
props.toggleExpandedProtein(firstProteinId);
......
......@@ -52,8 +52,15 @@ $content-width: 695px;
margin-left: 177px;
}
.statsLoadingContainer {
.statusContainer {
height: 50px;
display: flex;
align-items: center;
justify-content: center;
margin-top: 40px;
}
.errorMessage{
color: $red;
margin-right:20px;
font-weight: $normal;
}
......@@ -18,6 +18,7 @@ import React, { useEffect, useState } from 'react';
import set from 'lodash/fp/set';
import { CircleLoader } from 'src/shared/components/loader/Loader';
import { PrimaryButton } from 'src/shared/components/button/Button';
import ProteinDomainImage from 'src/content/app/entity-viewer/gene-view/components/protein-domain-image/ProteinDomainImage';
import ProteinImage from 'src/content/app/entity-viewer/gene-view/components/protein-image/ProteinImage';
import ProteinFeaturesCount from 'src/content/app/entity-viewer/gene-view/components/protein-features-count/ProteinFeaturesCount';
......@@ -34,6 +35,7 @@ import {
ProteinSummary
} from 'src/content/app/entity-viewer/shared/rest/rest-data-fetchers/proteinData';
import { LoadingState } from 'src/shared/types/loading-state';
import { Transcript } from 'src/content/app/entity-viewer/types/transcript';
import { ProteinDomain } from 'src/content/app/entity-viewer/types/product';
......@@ -65,38 +67,66 @@ const ProteinsListItemInfo = (props: Props) => {
ProteinSummary | null | undefined
>();
const [domainsLoadingState, setDomainsLoadingState] = useState<LoadingState>(
LoadingState.LOADING
);
const [summaryLoadingState, setSummaryLoadingState] = useState<LoadingState>(
LoadingState.LOADING
);
const proteinId =
transcript.product_generating_contexts[0].product.unversioned_stable_id;
const { product } =
transcriptWithProteinDomains?.product_generating_contexts[0] || {};
useEffect(() => {
const abortController = new AbortController();
fetchProteinDomains(proteinId, abortController.signal).then(
(proteinDomains) => {
if (!abortController.signal.aborted) {
setTranscriptWithProteinDomains(
addProteinDomains(transcript, proteinDomains)
);
}
}
);
fetchProteinSummary(proteinId, abortController.signal).then(
(proteinSummaryData) => {
if (!abortController.signal.aborted) {
proteinSummaryData
? setProteinSummary(proteinSummaryData)
: setProteinSummary(null);
}
}
);
if (domainsLoadingState === LoadingState.LOADING) {
fetchProteinDomains(proteinId, abortController.signal)
.then((proteinDomains) => {
if (!abortController.signal.aborted) {
setTranscriptWithProteinDomains(
addProteinDomains(transcript, proteinDomains)
);
setDomainsLoadingState(LoadingState.SUCCESS);
}
})
.catch(() => {
setDomainsLoadingState(LoadingState.ERROR);
});
}
return function cleanup() {
abortController.abort();
};
}, [transcript.stable_id]);
}, [domainsLoadingState]);
const { product } =
transcriptWithProteinDomains?.product_generating_contexts[0] || {};
useEffect(() => {
const abortController = new AbortController();
if (summaryLoadingState === LoadingState.LOADING) {
fetchProteinSummary(proteinId, abortController.signal)
.then((response) => {
if (!abortController.signal.aborted) {
response
? setProteinSummary(response as ProteinSummary)
: setProteinSummary(null);
setSummaryLoadingState(LoadingState.SUCCESS);
}
})
.catch(() => {
setSummaryLoadingState(LoadingState.ERROR);
});
}
return function cleanup() {
abortController.abort();
};
}, [summaryLoadingState]);
// FIXME: the 695 below is by now a very magic number (also exists in transcript images);
// we need to move it to a constant
......@@ -153,17 +183,56 @@ const ProteinsListItemInfo = (props: Props) => {
</>
)}
{(!product || proteinSummary === undefined) && (
<div className={styles.statsLoadingContainer}>
<CircleLoader />
</div>
)}
<StatusContent
summaryLoadingState={summaryLoadingState}
domainsLoadingState={domainsLoadingState}
setSummaryLoadingState={setSummaryLoadingState}
setDomainsLoadingState={setDomainsLoadingState}
/>
<div className={styles.keyline}></div>
</div>
</div>
);
};
type StatusContentProps = {
summaryLoadingState: LoadingState;
domainsLoadingState: LoadingState;
setSummaryLoadingState: (loadingState: LoadingState) => void;
setDomainsLoadingState: (loadingState: LoadingState) => void;
};
const StatusContent = (props: StatusContentProps) => {
if (
props.domainsLoadingState === LoadingState.LOADING ||
props.summaryLoadingState === LoadingState.LOADING
) {
return (
<div className={styles.statusContainer}>
<CircleLoader />
</div>
);
}
const retryHandler = () => {
if (props.domainsLoadingState === LoadingState.ERROR) {
props.setDomainsLoadingState(LoadingState.LOADING);
}
if (props.summaryLoadingState === LoadingState.ERROR) {
props.setSummaryLoadingState(LoadingState.LOADING);
}
};
return props.domainsLoadingState === LoadingState.ERROR ||
props.summaryLoadingState === LoadingState.ERROR ? (
<div className={styles.statusContainer}>
<span className={styles.errorMessage}>Failed to get data</span>
<PrimaryButton onClick={retryHandler}>Try again</PrimaryButton>
</div>
) : null;
};
type ProteinExternalReferenceProps = {
source: ExternalSource;
externalId: string | undefined;
......
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