diff --git a/resources/scripts/api/server/files/copyFile.ts b/resources/scripts/api/server/files/copyFile.ts new file mode 100644 index 000000000..b19525c40 --- /dev/null +++ b/resources/scripts/api/server/files/copyFile.ts @@ -0,0 +1,9 @@ +import http from '@/api/http'; + +export default (uuid: string, location: string): Promise => { + return new Promise((resolve, reject) => { + http.post(`/api/client/servers/${uuid}/files/copy`, { location }) + .then(() => resolve()) + .catch(reject); + }); +}; diff --git a/resources/scripts/components/elements/SpinnerOverlay.tsx b/resources/scripts/components/elements/SpinnerOverlay.tsx index 92eb43cf1..78ba2e050 100644 --- a/resources/scripts/components/elements/SpinnerOverlay.tsx +++ b/resources/scripts/components/elements/SpinnerOverlay.tsx @@ -3,10 +3,13 @@ import classNames from 'classnames'; import { CSSTransition } from 'react-transition-group'; import Spinner from '@/components/elements/Spinner'; -export default ({ large, visible }: { visible: boolean; large?: boolean }) => ( +export default ({ large, fixed, visible }: { visible: boolean; fixed?: boolean; large?: boolean }) => (
diff --git a/resources/scripts/components/server/files/CopyFileModal.tsx b/resources/scripts/components/server/files/CopyFileModal.tsx new file mode 100644 index 000000000..3f721e904 --- /dev/null +++ b/resources/scripts/components/server/files/CopyFileModal.tsx @@ -0,0 +1,28 @@ +import React, { useEffect } from 'react'; +import { FileObject } from '@/api/server/files/loadDirectory'; +import SpinnerOverlay from '@/components/elements/SpinnerOverlay'; +import { ServerContext } from '@/state/server'; +import copyFile from '@/api/server/files/copyFile'; +import { join } from 'path'; +import { httpErrorToHuman } from '@/api/http'; + +// This component copies the given file on mount, so only mount it when +// you actually want to copy the file... +export default ({ file, onCopyComplete }: { file: FileObject; onCopyComplete: () => void }) => { + const uuid = ServerContext.useStoreState(state => state.server.data!.uuid); + const directory = ServerContext.useStoreState(state => state.files.directory); + const getDirectoryContents = ServerContext.useStoreActions(actions => actions.files.getDirectoryContents); + + useEffect(() => { + copyFile(uuid, join(directory, file.name)) + .then(() => getDirectoryContents(directory)) + .catch(error => { + console.error('Error while attempting to copy file.', error); + alert(httpErrorToHuman(error)); + }); + }, []); + + return ( + + ); +}; diff --git a/resources/scripts/components/server/files/FileDropdownMenu.tsx b/resources/scripts/components/server/files/FileDropdownMenu.tsx index 1ab8877e3..dde1daff8 100644 --- a/resources/scripts/components/server/files/FileDropdownMenu.tsx +++ b/resources/scripts/components/server/files/FileDropdownMenu.tsx @@ -9,8 +9,9 @@ import { faCopy } from '@fortawesome/free-solid-svg-icons/faCopy'; import { faLevelUpAlt } from '@fortawesome/free-solid-svg-icons/faLevelUpAlt'; import RenameFileModal from '@/components/server/files/RenameFileModal'; import { ServerContext } from '@/state/server'; +import CopyFileModal from '@/components/server/files/CopyFileModal'; -type ModalType = 'rename' | 'move'; +type ModalType = 'rename' | 'move' | 'copy' | 'download' | 'delete'; export default ({ uuid }: { uuid: string }) => { const menu = createRef(); @@ -54,7 +55,7 @@ export default ({ uuid }: { uuid: string }) => { }, []); return ( -
+
{ @@ -70,9 +71,10 @@ export default ({ uuid }: { uuid: string }) => {
{visible && - - setModal(null)}/> - + + setModal(null)}/> + {modal === 'copy' && setModal(null)}/>} + }
{ ref={menu} >
setModal('rename')} + className={'hover:text-neutral-700 p-2 flex items-center hover:bg-neutral-100 rounded'} > Rename @@ -90,7 +92,10 @@ export default ({ uuid }: { uuid: string }) => { Move
-
+
setModal('copy')} + className={'hover:text-neutral-700 p-2 flex items-center hover:bg-neutral-100 rounded'} + > Copy
diff --git a/resources/scripts/components/server/files/FileManagerContainer.tsx b/resources/scripts/components/server/files/FileManagerContainer.tsx index 5799788e7..8003a8d9c 100644 --- a/resources/scripts/components/server/files/FileManagerContainer.tsx +++ b/resources/scripts/components/server/files/FileManagerContainer.tsx @@ -84,7 +84,7 @@ export default () => {
{ files.map(file => ( - + )) }