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

add spiner (fetch in memory and download from memory)

parent c918406b
No related branches found
No related tags found
2 merge requests!289Resolve "allow to have plugins without panel",!287add spiner (fetch in memory and download from memory)
Pipeline #97098 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