2020-07-11 22:45:28 +00:00
|
|
|
import React, { useEffect, useState } from 'react';
|
2020-07-11 22:37:59 +00:00
|
|
|
import tw from 'twin.macro';
|
2022-06-20 18:16:42 +00:00
|
|
|
import { Button } from '@/components/elements/button/index';
|
2020-07-11 22:37:59 +00:00
|
|
|
import Fade from '@/components/elements/Fade';
|
|
|
|
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
|
|
|
|
import useFileManagerSwr from '@/plugins/useFileManagerSwr';
|
|
|
|
import useFlash from '@/plugins/useFlash';
|
|
|
|
import compressFiles from '@/api/server/files/compressFiles';
|
|
|
|
import { ServerContext } from '@/state/server';
|
|
|
|
import deleteFiles from '@/api/server/files/deleteFiles';
|
2020-07-11 23:47:13 +00:00
|
|
|
import RenameFileModal from '@/components/server/files/RenameFileModal';
|
2022-06-20 18:16:42 +00:00
|
|
|
import Portal from '@/components/elements/Portal';
|
|
|
|
import { Dialog } from '@/components/elements/dialog';
|
2020-07-11 22:37:59 +00:00
|
|
|
|
|
|
|
const MassActionsBar = () => {
|
2020-08-26 04:39:00 +00:00
|
|
|
const uuid = ServerContext.useStoreState(state => state.server.data!.uuid);
|
|
|
|
|
2020-07-11 22:37:59 +00:00
|
|
|
const { mutate } = useFileManagerSwr();
|
|
|
|
const { clearFlashes, clearAndAddHttpError } = useFlash();
|
|
|
|
const [ loading, setLoading ] = useState(false);
|
2020-07-11 22:45:28 +00:00
|
|
|
const [ loadingMessage, setLoadingMessage ] = useState('');
|
2020-07-11 22:37:59 +00:00
|
|
|
const [ showConfirm, setShowConfirm ] = useState(false);
|
2020-07-11 23:47:13 +00:00
|
|
|
const [ showMove, setShowMove ] = useState(false);
|
2020-07-11 22:37:59 +00:00
|
|
|
const directory = ServerContext.useStoreState(state => state.files.directory);
|
|
|
|
|
2020-07-11 23:47:13 +00:00
|
|
|
const selectedFiles = ServerContext.useStoreState(state => state.files.selectedFiles);
|
|
|
|
const setSelectedFiles = ServerContext.useStoreActions(actions => actions.files.setSelectedFiles);
|
|
|
|
|
2020-07-11 22:45:28 +00:00
|
|
|
useEffect(() => {
|
|
|
|
if (!loading) setLoadingMessage('');
|
|
|
|
}, [ loading ]);
|
|
|
|
|
2020-07-11 22:37:59 +00:00
|
|
|
const onClickCompress = () => {
|
|
|
|
setLoading(true);
|
|
|
|
clearFlashes('files');
|
2020-07-11 22:45:28 +00:00
|
|
|
setLoadingMessage('Archiving files...');
|
2020-07-11 22:37:59 +00:00
|
|
|
|
2020-07-11 23:47:13 +00:00
|
|
|
compressFiles(uuid, directory, selectedFiles)
|
2020-07-11 22:37:59 +00:00
|
|
|
.then(() => mutate())
|
2020-07-11 23:47:13 +00:00
|
|
|
.then(() => setSelectedFiles([]))
|
2020-07-11 22:37:59 +00:00
|
|
|
.catch(error => clearAndAddHttpError({ key: 'files', error }))
|
|
|
|
.then(() => setLoading(false));
|
|
|
|
};
|
|
|
|
|
|
|
|
const onClickConfirmDeletion = () => {
|
|
|
|
setLoading(true);
|
|
|
|
setShowConfirm(false);
|
|
|
|
clearFlashes('files');
|
2020-07-11 22:45:28 +00:00
|
|
|
setLoadingMessage('Deleting files...');
|
2020-07-11 22:37:59 +00:00
|
|
|
|
2020-07-11 23:47:13 +00:00
|
|
|
deleteFiles(uuid, directory, selectedFiles)
|
2020-07-11 22:37:59 +00:00
|
|
|
.then(() => {
|
2020-07-11 23:47:13 +00:00
|
|
|
mutate(files => files.filter(f => selectedFiles.indexOf(f.name) < 0), false);
|
|
|
|
setSelectedFiles([]);
|
2020-07-11 22:37:59 +00:00
|
|
|
})
|
|
|
|
.catch(error => {
|
|
|
|
mutate();
|
|
|
|
clearAndAddHttpError({ key: 'files', error });
|
|
|
|
})
|
|
|
|
.then(() => setLoading(false));
|
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
2022-06-20 18:16:42 +00:00
|
|
|
<>
|
2021-07-11 18:27:52 +00:00
|
|
|
<div css={tw`pointer-events-none fixed bottom-0 z-20 left-0 right-0 flex justify-center`}>
|
2020-07-11 22:45:28 +00:00
|
|
|
<SpinnerOverlay visible={loading} size={'large'} fixed>
|
|
|
|
{loadingMessage}
|
|
|
|
</SpinnerOverlay>
|
2022-06-20 18:16:42 +00:00
|
|
|
<Dialog.Confirm
|
|
|
|
title={'Delete Files'}
|
|
|
|
open={showConfirm}
|
|
|
|
confirm={'Delete'}
|
|
|
|
onClose={() => setShowConfirm(false)}
|
2020-07-11 22:37:59 +00:00
|
|
|
onConfirmed={onClickConfirmDeletion}
|
|
|
|
>
|
2022-06-20 18:16:42 +00:00
|
|
|
<p className={'mb-2'}>
|
|
|
|
Are you sure you want to delete
|
|
|
|
<span className={'font-semibold text-gray-50'}>{selectedFiles.length} files</span>? This is
|
|
|
|
a permanent action and the files cannot be recovered.
|
|
|
|
</p>
|
|
|
|
{selectedFiles.slice(0, 15).map(file => (
|
|
|
|
<li key={file}>{file}</li>))
|
|
|
|
}
|
|
|
|
{selectedFiles.length > 15 &&
|
|
|
|
<li>and {selectedFiles.length - 15} others</li>
|
|
|
|
}
|
|
|
|
</Dialog.Confirm>
|
2020-07-11 23:49:46 +00:00
|
|
|
{showMove &&
|
2022-06-20 18:16:42 +00:00
|
|
|
<RenameFileModal
|
|
|
|
files={selectedFiles}
|
|
|
|
visible
|
|
|
|
appear
|
|
|
|
useMoveTerminology
|
|
|
|
onDismissed={() => setShowMove(false)}
|
|
|
|
/>
|
2020-07-11 23:49:46 +00:00
|
|
|
}
|
2022-06-20 18:16:42 +00:00
|
|
|
<Portal>
|
|
|
|
<div className={'fixed bottom-0 mb-6 flex justify-center w-full z-50'}>
|
|
|
|
<Fade timeout={75} in={selectedFiles.length > 0} unmountOnExit>
|
|
|
|
<div css={tw`flex items-center space-x-4 pointer-events-auto rounded p-4 bg-black/50`}>
|
|
|
|
<Button onClick={() => setShowMove(true)}>Move</Button>
|
|
|
|
<Button onClick={onClickCompress}>Archive</Button>
|
|
|
|
<Button.Danger variant={Button.Variants.Secondary} onClick={() => setShowConfirm(true)}>
|
|
|
|
Delete
|
|
|
|
</Button.Danger>
|
|
|
|
</div>
|
|
|
|
</Fade>
|
|
|
|
</div>
|
|
|
|
</Portal>
|
2020-07-11 22:37:59 +00:00
|
|
|
</div>
|
2022-06-20 18:16:42 +00:00
|
|
|
</>
|
2020-07-11 22:37:59 +00:00
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export default MassActionsBar;
|