diff --git a/resources/scripts/components/server/files/FileDropdownMenu.tsx b/resources/scripts/components/server/files/FileDropdownMenu.tsx index 07bec2912..5db5d90e6 100644 --- a/resources/scripts/components/server/files/FileDropdownMenu.tsx +++ b/resources/scripts/components/server/files/FileDropdownMenu.tsx @@ -13,7 +13,8 @@ import { join } from 'path'; import deleteFile from '@/api/server/files/deleteFile'; import SpinnerOverlay from '@/components/elements/SpinnerOverlay'; import copyFile from '@/api/server/files/copyFile'; -import http, { httpErrorToHuman } from '@/api/http'; +import { httpErrorToHuman } from '@/api/http'; +import Can from '@/components/elements/Can'; type ModalType = 'rename' | 'move'; @@ -118,30 +119,37 @@ export default ({ uuid }: { uuid: string }) => {
{ e.stopPropagation(); setMenuVisible(false); }} + onClick={e => { + e.stopPropagation(); + setMenuVisible(false); + }} className={'absolute bg-white p-2 rounded border border-neutral-700 shadow-lg text-neutral-500 min-w-48'} > -
setModal('rename')} - className={'hover:text-neutral-700 p-2 flex items-center hover:bg-neutral-100 rounded'} - > - - Rename -
-
setModal('move')} - className={'hover:text-neutral-700 p-2 flex items-center hover:bg-neutral-100 rounded'} - > - - Move -
-
doCopy()} - className={'hover:text-neutral-700 p-2 flex items-center hover:bg-neutral-100 rounded'} - > - - Copy -
+ +
setModal('rename')} + className={'hover:text-neutral-700 p-2 flex items-center hover:bg-neutral-100 rounded'} + > + + Rename +
+
setModal('move')} + className={'hover:text-neutral-700 p-2 flex items-center hover:bg-neutral-100 rounded'} + > + + Move +
+
+ +
doCopy()} + className={'hover:text-neutral-700 p-2 flex items-center hover:bg-neutral-100 rounded'} + > + + Copy +
+
doDownload()} @@ -149,13 +157,15 @@ export default ({ uuid }: { uuid: string }) => { Download
-
doDeletion()} - className={'hover:text-red-700 p-2 flex items-center hover:bg-red-100 rounded'} - > - - Delete -
+ +
doDeletion()} + className={'hover:text-red-700 p-2 flex items-center hover:bg-red-100 rounded'} + > + + Delete +
+
diff --git a/resources/scripts/components/server/files/FileEditContainer.tsx b/resources/scripts/components/server/files/FileEditContainer.tsx index 2d0de6576..a44698fd9 100644 --- a/resources/scripts/components/server/files/FileEditContainer.tsx +++ b/resources/scripts/components/server/files/FileEditContainer.tsx @@ -2,7 +2,7 @@ import React, { lazy, useEffect, useState } from 'react'; import { ServerContext } from '@/state/server'; import getFileContents from '@/api/server/files/getFileContents'; import useRouter from 'use-react-router'; -import { Actions, useStoreState } from 'easy-peasy'; +import { Actions, useStoreActions, useStoreState } from 'easy-peasy'; import { ApplicationStore } from '@/state'; import { httpErrorToHuman } from '@/api/http'; import SpinnerOverlay from '@/components/elements/SpinnerOverlay'; @@ -10,6 +10,8 @@ import saveFileContents from '@/api/server/files/saveFileContents'; import FileManagerBreadcrumbs from '@/components/server/files/FileManagerBreadcrumbs'; import { useParams } from 'react-router'; import FileNameModal from '@/components/server/files/FileNameModal'; +import Can from '@/components/elements/Can'; +import FlashMessageRender from '@/components/FlashMessageRender'; const LazyAceEditor = lazy(() => import(/* webpackChunkName: "editor" */'@/components/elements/AceEditor')); @@ -21,15 +23,20 @@ export default () => { const [ modalVisible, setModalVisible ] = useState(false); const { id, uuid } = ServerContext.useStoreState(state => state.server.data!); - const addError = useStoreState((state: Actions) => state.flashes.addError); + const { addError, clearFlashes } = useStoreActions((actions: Actions) => actions.flashes); let fetchFileContent: null | (() => Promise) = null; if (action !== 'new') { useEffect(() => { + setLoading(true); + clearFlashes('files:view'); getFileContents(uuid, hash.replace(/^#/, '')) .then(setContent) - .catch(error => console.error(error)) + .catch(error => { + console.error(error); + addError({ key: 'files:view', message: httpErrorToHuman(error) }); + }) .then(() => setLoading(false)); }, [ uuid, hash ]); } @@ -40,10 +47,10 @@ export default () => { } setLoading(true); - fetchFileContent() - .then(content => { - return saveFileContents(uuid, name || hash.replace(/^#/, ''), content); - }) + clearFlashes('files:view'); + fetchFileContent().then(content => { + return saveFileContents(uuid, name || hash.replace(/^#/, ''), content); + }) .then(() => { if (name) { history.push(`/server/${id}/files/edit#/${name}`); @@ -54,13 +61,14 @@ export default () => { }) .catch(error => { console.error(error); - addError({ message: httpErrorToHuman(error), key: 'files' }); + addError({ message: httpErrorToHuman(error), key: 'files:view' }); }) .then(() => setLoading(false)); }; return (
+ {
{action === 'edit' ? - + + + : - + + + }
diff --git a/resources/scripts/components/server/files/FileManagerContainer.tsx b/resources/scripts/components/server/files/FileManagerContainer.tsx index bec0c2a31..41adcd8e2 100644 --- a/resources/scripts/components/server/files/FileManagerContainer.tsx +++ b/resources/scripts/components/server/files/FileManagerContainer.tsx @@ -11,6 +11,7 @@ import FileManagerBreadcrumbs from '@/components/server/files/FileManagerBreadcr import { FileObject } from '@/api/server/files/loadDirectory'; import NewDirectoryButton from '@/components/server/files/NewDirectoryButton'; import { Link } from 'react-router-dom'; +import Can from '@/components/elements/Can'; const sortFiles = (files: FileObject[]): FileObject[] => { return files.sort((a, b) => a.name.localeCompare(b.name)) @@ -34,7 +35,6 @@ export default () => { console.error(error.message, { error }); addError({ message: httpErrorToHuman(error), key: 'files' }); }); - // eslint-disable-next-line react-hooks/exhaustive-deps }, [ directory ]); return ( @@ -78,12 +78,17 @@ export default () => { } -
- - - New File - -
+ +
+ + + New File + +
+
}