Skip to content

Commit

Permalink
feat(transcriptomics): SJIP-984 add download data buttons
Browse files Browse the repository at this point in the history
  • Loading branch information
lflangis committed Dec 4, 2024
1 parent 3c0a88b commit 935e39b
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/common/downloader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const getDefaultContentType = (responseType: string) => {
}
};

const getBlobFromResponse = (res: AxiosResponse<any, any>, responseType = 'json') => {
export const getBlobFromResponse = (res: AxiosResponse<any, any>, responseType = 'json') => {
const contentType = res.headers['content-type'] || getDefaultContentType(responseType);

switch (responseType) {
Expand Down
2 changes: 2 additions & 0 deletions src/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1518,6 +1518,8 @@ const en = {
},
footer: {
download: 'Download data',
notification:
'Please wait while we generate your report. This process may take a few moments.',
},
about: {
title: 'About this dataset',
Expand Down
9 changes: 4 additions & 5 deletions src/services/api/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import axios, { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios';
import keycloak from 'auth/keycloak-api/keycloak';
import axios, { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios';

const apiInstance = axios.create();

interface ApiResponse<T> {
export interface ApiResponse<T> {
data: T | undefined;
response: AxiosResponse;
error: AxiosError | undefined;
Expand All @@ -24,8 +24,8 @@ apiInstance.interceptors.request.use((config) => {
return config;
});

export const sendRequest = async <T,>(config: AxiosRequestConfig) => {
return apiInstance
export const sendRequest = async <T,>(config: AxiosRequestConfig) =>
apiInstance
.request<T>(config)
.then(
(response): ApiResponse<T> => ({
Expand All @@ -41,6 +41,5 @@ export const sendRequest = async <T,>(config: AxiosRequestConfig) => {
error: err,
}),
);
};

export default apiInstance;
16 changes: 16 additions & 0 deletions src/services/api/transcriptomics/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,20 @@ const fetchSampleGeneExp = (id: string) =>
},
});

const fetchExportUrlDiffGeneExp = () =>
sendRequest<{ url: string }>({
method: 'GET',
url: `${ARRANGER_API}/transcriptomics/diffGeneExp/export`,
headers: headers(),
});

const fetchExportUrlSampleGeneExp = () =>
sendRequest<{ url: string }>({
method: 'GET',
url: `${ARRANGER_API}/transcriptomics/sampleGeneExp/export`,
headers: headers(),
});

const checkSampleIdsAndGene = (data: { ensembl_gene_id?: string; sample_ids: string[] }) =>
sendRequest<ITranscriptomicsSampleGeneExp>({
method: 'POST',
Expand All @@ -62,4 +76,6 @@ export const TranscriptomicsApi = {
fetchDiffGeneExp,
checkSampleIdsAndGene,
checkGenesExist,
fetchExportUrlDiffGeneExp,
fetchExportUrlSampleGeneExp,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { useState } from 'react';
import intl from 'react-intl-universal';
import { useDispatch } from 'react-redux';
import { DownloadOutlined } from '@ant-design/icons';
import { Button } from 'antd';
import { BaseButtonProps } from 'antd/lib/button/button';
import axios from 'axios';
import saveAs from 'file-saver';

import { getBlobFromResponse } from 'common/downloader';
import { ApiResponse } from 'services/api';
import { globalActions } from 'store/global';

type TDownloadTranscriptomics = BaseButtonProps & {
handleUrl: () => Promise<ApiResponse<{ url: string }>>;
filename: string;
displayNotification?: boolean;
};

const DownloadTranscriptomics = ({
handleUrl,
filename,
displayNotification = false,
...props
}: TDownloadTranscriptomics) => {
const [loading, setLoading] = useState<boolean>(false);
const dispatch = useDispatch();
return (
<Button
loading={loading}
icon={<DownloadOutlined />}
onClick={async () => {
setLoading(true);
const response = await handleUrl();

if (displayNotification) {
dispatch(
globalActions.displayMessage({
type: 'loading',
key: filename,
content: intl.get('screen.analytics.transcriptomic.footer.notification'),
duration: 0,
}),
);
}

await axios({
url: response.data?.url ?? '',
method: 'GET',
responseType: 'blob',
headers: {
'Content-Type': 'application/json',
Accept: '*/*',
},
}).then((response) => {
const blob = getBlobFromResponse(response, 'blob');
saveAs(blob, filename);
setLoading(false);
dispatch(globalActions.destroyMessages([filename]));
});
}}
{...props}
>
{intl.get('screen.analytics.transcriptomic.footer.download')}
</Button>
);
};

export default DownloadTranscriptomics;
13 changes: 11 additions & 2 deletions src/views/Analytics/Transcriptomic/Footer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { SortDirection } from '@ferlab/ui/core/graphql/constants';
import { Button } from 'antd';
import { useBiospecimen } from 'graphql/biospecimens/actions';
import { INDEXES } from 'graphql/constants';
import DownloadTranscriptomics from 'views/Analytics/Transcriptomic/Footer/DownloadTranscriptomics';
import SetsManagementDropdown from 'views/DataExploration/components/SetsManagementDropdown';
import {
BIOSPECIMENS_SAVED_SETS_FIELD,
Expand All @@ -18,6 +19,7 @@ import { DEFAULT_OFFSET } from 'views/Variants/utils/constants';

import ExternalLinkIcon from 'components/Icons/ExternalLinkIcon';
import { SetType } from 'services/api/savedSet/models';
import { TranscriptomicsApi } from 'services/api/transcriptomics';
import {
TTranscriptomicsDatum,
TTranscriptomicsSwarmPlotData,
Expand Down Expand Up @@ -100,10 +102,17 @@ const TranscriptomicFooter = ({
return (
<div className={styles.footer}>
<div className={styles.gene}>
{/* <Button>{intl.get('screen.analytics.transcriptomic.footer.download')}</Button> */}
<DownloadTranscriptomics
filename="htp-dge-data"
handleUrl={TranscriptomicsApi.fetchExportUrlDiffGeneExp}
/>
</div>
<div className={styles.sample}>
{/* <Button>{intl.get('screen.analytics.transcriptomic.footer.download')}</Button> */}
<DownloadTranscriptomics
filename="htp-rnaseq-data"
displayNotification
handleUrl={TranscriptomicsApi.fetchExportUrlSampleGeneExp}
/>
<SetsManagementDropdown
idField={BIOSPECIMENS_SAVED_SETS_FIELD}
key="setManagementDropdown"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
DownOutlined,
ExperimentOutlined,
FileTextOutlined,
FolderOutlined,
InfoCircleOutlined,
PlusOutlined,
UserOutlined,
Expand Down Expand Up @@ -233,7 +234,11 @@ const SetsManagementDropdown = ({
document.getElementById(`${type}-set-dropdown-container`) as HTMLElement
}
>
<Button className={'save-set-btn'} onClick={(e) => e.preventDefault()}>
<Button
className={'save-set-btn'}
icon={<FolderOutlined />}
onClick={(e) => e.preventDefault()}
>
{intl.get('screen.dataExploration.setsManagementDropdown.saveSet', {
type: singularizeSetTypeIfNeeded(type),
})}
Expand Down

0 comments on commit 935e39b

Please sign in to comment.