Skip to content
Snippets Groups Projects
Commit cc768bbb authored by Piotr Gawron's avatar Piotr Gawron
Browse files

Merge branch '297-a-loading-button-while-exporting' into 'main'

add spiner (fetch in memory and download from memory)

See merge request !287
parents c918406b f2c955fd
No related branches found
Tags v18.0.2
2 merge requests!289Resolve "allow to have plugins without panel",!287add spiner (fetch in memory and download from memory)
Pipeline #97104 passed
minerva-front (18.0.2) stable; urgency=medium
* Bug fix: Terms of Service modal is not hidden by Select project modal when
login via ORCID (#305)
* Bug fix: when downloading map there was missing spinner indicating the
download is in progress (#297)
-- Piotr Gawron <piotr.gawron@uni.lu> Wed, 30 Oct 2024 13:00:00 +0200
......
......@@ -2,18 +2,34 @@ import { formatsHandlersSelector } from '@/redux/configuration/configuration.sel
import { Button } from '@/shared/Button';
import { useSelect } from 'downshift';
import { useSelector } from 'react-redux';
import Image from 'next/image';
import spinnerIcon from '@/assets/vectors/icons/spinner.svg';
import { useState } from 'react';
import { downloadFileFromUrl } from '@/redux/export/export.utils';
import { SUBMAP_DOWNLOAD_HANDLERS_NAMES } from './DownloadSubmap.constants';
import { useGetSubmapDownloadUrl } from './utils/useGetSubmapDownloadUrl';
export const DownloadSubmap = (): JSX.Element => {
export const DownloadSubmap = (): React.ReactNode => {
const formatsHandlers = useSelector(formatsHandlersSelector);
const formatsHandlersItems = Object.entries(formatsHandlers);
const getSubmapDownloadUrl = useGetSubmapDownloadUrl();
const { isOpen, getToggleButtonProps, getMenuProps } = useSelect({
const [isDownloading, setIsDownloading] = useState<boolean>(false);
const { isOpen, getToggleButtonProps, getMenuProps, closeMenu } = useSelect({
items: formatsHandlersItems,
});
const downloadSubmap = (handler: string) => {
return function () {
closeMenu();
setIsDownloading(true);
downloadFileFromUrl(getSubmapDownloadUrl({ handler })).finally(function () {
setIsDownloading(false);
});
};
};
return (
<div className="relative">
<Button
......@@ -22,6 +38,15 @@ export const DownloadSubmap = (): JSX.Element => {
className="mr-4"
{...getToggleButtonProps()}
>
{isDownloading && (
<Image
src={spinnerIcon}
alt="spinner icon"
height={12}
width={12}
className="mr-5 animate-spin"
/>
)}
Download
</Button>
<ul
......@@ -34,14 +59,13 @@ export const DownloadSubmap = (): JSX.Element => {
{isOpen &&
formatsHandlersItems.map(([formatId, handler]) => (
<li key={formatId}>
<a
className="flex flex-col border-t px-4 py-2 shadow-sm"
href={getSubmapDownloadUrl({ handler })}
target="_blank"
download
<Button
variantStyles="ghost"
className="flex w-full flex-col border-t px-4 py-2 shadow-sm"
onClick={downloadSubmap(handler)}
>
<span>{SUBMAP_DOWNLOAD_HANDLERS_NAMES[formatId]}</span>
</a>
{SUBMAP_DOWNLOAD_HANDLERS_NAMES[formatId]}
</Button>
</li>
))}
</ul>
......
import axios from 'axios';
export const downloadFileFromBlob = (data: string, filename: string): void => {
const url = window.URL.createObjectURL(new Blob([data]));
const link = document.createElement('a');
......@@ -7,3 +9,27 @@ export const downloadFileFromBlob = (data: string, filename: string): void => {
link.click();
link.remove();
};
export const downloadFileFromUrl = async (url: string): Promise<void> => {
const genericAxios = axios.create();
const response = await genericAxios.get(url, {
withCredentials: true,
responseType: 'arraybuffer',
});
const content = Buffer.from(response.data, 'binary');
let filename = 'file.xml';
if (response.headers && response.headers['content-type'] === 'application/zip') {
filename = 'file.zip';
}
const tmpUrl = window.URL.createObjectURL(new Blob([content], { type: 'application/zip' }));
const link = document.createElement('a');
link.href = tmpUrl;
link.setAttribute('download', filename);
document.body.appendChild(link);
link.click();
link.remove();
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment