Add create directory button

This commit is contained in:
Dane Everitt 2019-12-15 19:10:01 -08:00
parent ba0757f05c
commit d07ee9a36b
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
3 changed files with 142 additions and 25 deletions

View file

@ -0,0 +1,9 @@
import http from '@/api/http';
export default (uuid: string, root: string, name: string): Promise<void> => {
return new Promise((resolve, reject) => {
http.post(`/api/client/servers/${uuid}/files/create-folder`, { root, name })
.then(() => resolve())
.catch(reject);
});
};

View file

@ -8,6 +8,13 @@ import { CSSTransition } from 'react-transition-group';
import Spinner from '@/components/elements/Spinner'; import Spinner from '@/components/elements/Spinner';
import FileObjectRow from '@/components/server/files/FileObjectRow'; import FileObjectRow from '@/components/server/files/FileObjectRow';
import FileManagerBreadcrumbs from '@/components/server/files/FileManagerBreadcrumbs'; import FileManagerBreadcrumbs from '@/components/server/files/FileManagerBreadcrumbs';
import { FileObject } from '@/api/server/files/loadDirectory';
import NewDirectoryButton from '@/components/server/files/NewDirectoryButton';
const sortFiles = (files: FileObject[]): FileObject[] => {
return files.sort((a, b) => a.name.localeCompare(b.name))
.sort((a, b) => a.isFile === b.isFile ? 0 : (a.isFile ? 1 : -1));
};
export default () => { export default () => {
const [ loading, setLoading ] = useState(true); const [ loading, setLoading ] = useState(true);
@ -37,35 +44,47 @@ export default () => {
loading ? loading ?
<Spinner size={'large'} centered={true}/> <Spinner size={'large'} centered={true}/>
: :
!files.length ? <React.Fragment>
{!files.length ?
<p className={'text-sm text-neutral-600 text-center'}> <p className={'text-sm text-neutral-600 text-center'}>
This directory seems to be empty. This directory seems to be empty.
</p> </p>
: :
<CSSTransition classNames={'fade'} timeout={250} appear={true} in={true}> <CSSTransition classNames={'fade'} timeout={250} appear={true} in={true}>
<React.Fragment>
<div> <div>
{files.length > 250 ? {files.length > 250 ?
<React.Fragment> <React.Fragment>
<div className={'rounded bg-yellow-400 mb-px p-3'}> <div className={'rounded bg-yellow-400 mb-px p-3'}>
<p className={'text-yellow-900 text-sm text-center'}> <p className={'text-yellow-900 text-sm text-center'}>
This directory is too large to display in the browser, limiting This directory is too large to display in the browser,
limiting
the output to the first 250 files. the output to the first 250 files.
</p> </p>
</div> </div>
{ {
files.slice(0, 250).map(file => ( sortFiles(files.slice(0, 250)).map(file => (
<FileObjectRow key={file.uuid} file={file}/> <FileObjectRow key={file.uuid} file={file}/>
)) ))
} }
</React.Fragment> </React.Fragment>
: :
files.map(file => ( sortFiles(files).map(file => (
<FileObjectRow key={file.uuid} file={file}/> <FileObjectRow key={file.uuid} file={file}/>
)) ))
} }
</div> </div>
</React.Fragment>
</CSSTransition> </CSSTransition>
} }
<div className={'flex justify-end mt-8'}>
<NewDirectoryButton/>
<button className={'btn btn-sm btn-primary'}>
New File
</button>
</div>
</React.Fragment>
}
</React.Fragment> </React.Fragment>
</div> </div>
); );

View file

@ -0,0 +1,89 @@
import React, { useState } from 'react';
import Modal from '@/components/elements/Modal';
import { ServerContext } from '@/state/server';
import { Form, Formik, FormikActions } from 'formik';
import Field from '@/components/elements/Field';
import { join } from 'path';
import { object, string } from 'yup';
import createDirectory from '@/api/server/files/createDirectory';
import v4 from 'uuid/v4';
interface Values {
directoryName: string;
}
const schema = object().shape({
directoryName: string().required('A valid directory name must be provided.'),
});
export default () => {
const [ visible, setVisible ] = useState(false);
const uuid = ServerContext.useStoreState(state => state.server.data!.uuid);
const directory = ServerContext.useStoreState(state => state.files.directory);
const pushFile = ServerContext.useStoreActions(actions => actions.files.pushFile);
const submit = (values: Values, { setSubmitting }: FormikActions<Values>) => {
createDirectory(uuid, directory, values.directoryName)
.then(() => {
pushFile({
uuid: v4(),
name: values.directoryName,
mode: '0644',
size: 0,
isFile: false,
isEditable: false,
isSymlink: false,
mimetype: '',
createdAt: new Date(),
modifiedAt: new Date(),
});
setVisible(false);
})
.catch(error => {
console.error(error);
setSubmitting(false);
});
};
return (
<React.Fragment>
<Formik
onSubmit={submit}
validationSchema={schema}
initialValues={{ directoryName: '' }}
>
{({ resetForm, isSubmitting, values }) => (
<Modal
visible={visible}
dismissable={!isSubmitting}
showSpinnerOverlay={isSubmitting}
onDismissed={() => {
setVisible(false);
resetForm();
}}
>
<Form className={'m-0'}>
<Field
id={'directoryName'}
name={'directoryName'}
label={'Directory Name'}
/>
<p className={'text-xs mt-2 text-neutral-400'}>
<span className={'text-neutral-200'}>This directory will be created as</span>
&nbsp;/home/container/<span className={'text-cyan-200'}>{join(directory, values.directoryName).replace(/^(\.\.\/|\/)+/, '')}</span>
</p>
<div className={'flex justify-end'}>
<button className={'btn btn-sm btn-primary mt-8'}>
Create Directory
</button>
</div>
</Form>
</Modal>
)}
</Formik>
<button className={'btn btn-sm btn-secondary mr-2'} onClick={() => setVisible(true)}>
Create Directory
</button>
</React.Fragment>
);
};