2020-04-04 17:59:25 +00:00
|
|
|
import React, { useEffect, useState } from 'react';
|
|
|
|
import Modal, { RequiredModalProps } from '@/components/elements/Modal';
|
|
|
|
import { Field as FormikField, Form, Formik, FormikHelpers, useFormikContext } from 'formik';
|
|
|
|
import { object, string } from 'yup';
|
|
|
|
import Field from '@/components/elements/Field';
|
|
|
|
import FormikFieldWrapper from '@/components/elements/FormikFieldWrapper';
|
|
|
|
import useFlash from '@/plugins/useFlash';
|
|
|
|
import createServerBackup from '@/api/server/backups/createServerBackup';
|
|
|
|
import FlashMessageRender from '@/components/FlashMessageRender';
|
2020-07-04 23:26:07 +00:00
|
|
|
import Button from '@/components/elements/Button';
|
|
|
|
import tw from 'twin.macro';
|
2020-07-05 01:46:09 +00:00
|
|
|
import { Textarea } from '@/components/elements/Input';
|
2020-08-21 04:44:33 +00:00
|
|
|
import getServerBackups from '@/api/swr/getServerBackups';
|
2020-08-26 05:09:54 +00:00
|
|
|
import { ServerContext } from '@/state/server';
|
2020-04-04 17:59:25 +00:00
|
|
|
|
|
|
|
interface Values {
|
|
|
|
name: string;
|
|
|
|
ignored: string;
|
|
|
|
}
|
|
|
|
|
|
|
|
const ModalContent = ({ ...props }: RequiredModalProps) => {
|
|
|
|
const { isSubmitting } = useFormikContext<Values>();
|
|
|
|
|
|
|
|
return (
|
|
|
|
<Modal {...props} showSpinnerOverlay={isSubmitting}>
|
2020-07-04 23:26:07 +00:00
|
|
|
<Form>
|
|
|
|
<FlashMessageRender byKey={'backups:create'} css={tw`mb-4`}/>
|
|
|
|
<h2 css={tw`text-2xl mb-6`}>Create server backup</h2>
|
|
|
|
<div css={tw`mb-6`}>
|
2020-04-04 17:59:25 +00:00
|
|
|
<Field
|
|
|
|
name={'name'}
|
|
|
|
label={'Backup name'}
|
|
|
|
description={'If provided, the name that should be used to reference this backup.'}
|
|
|
|
/>
|
|
|
|
</div>
|
2020-07-04 23:26:07 +00:00
|
|
|
<div css={tw`mb-6`}>
|
2020-04-04 17:59:25 +00:00
|
|
|
<FormikFieldWrapper
|
2020-04-19 06:26:59 +00:00
|
|
|
name={'ignored'}
|
2020-04-04 17:59:25 +00:00
|
|
|
label={'Ignored Files & Directories'}
|
|
|
|
description={`
|
|
|
|
Enter the files or folders to ignore while generating this backup. Leave blank to use
|
|
|
|
the contents of the .pteroignore file in the root of the server directory if present.
|
|
|
|
Wildcard matching of files and folders is supported in addition to negating a rule by
|
|
|
|
prefixing the path with an exclamation point.
|
|
|
|
`}
|
|
|
|
>
|
2020-07-04 23:26:07 +00:00
|
|
|
<FormikField as={Textarea} name={'ignored'} css={tw`h-32`}/>
|
2020-04-04 17:59:25 +00:00
|
|
|
</FormikFieldWrapper>
|
|
|
|
</div>
|
2020-07-04 23:26:07 +00:00
|
|
|
<div css={tw`flex justify-end`}>
|
2020-08-02 02:49:38 +00:00
|
|
|
<Button type={'submit'} disabled={isSubmitting}>
|
2020-04-04 17:59:25 +00:00
|
|
|
Start backup
|
2020-07-04 23:26:07 +00:00
|
|
|
</Button>
|
2020-04-04 17:59:25 +00:00
|
|
|
</div>
|
|
|
|
</Form>
|
|
|
|
</Modal>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2020-04-07 05:25:54 +00:00
|
|
|
export default () => {
|
2020-08-26 05:09:54 +00:00
|
|
|
const uuid = ServerContext.useStoreState(state => state.server.data!.uuid);
|
2020-08-21 04:44:33 +00:00
|
|
|
const { clearFlashes, clearAndAddHttpError } = useFlash();
|
2020-04-04 17:59:25 +00:00
|
|
|
const [ visible, setVisible ] = useState(false);
|
2020-08-21 04:44:33 +00:00
|
|
|
const { mutate } = getServerBackups();
|
2020-04-07 05:25:54 +00:00
|
|
|
|
2020-04-04 17:59:25 +00:00
|
|
|
useEffect(() => {
|
|
|
|
clearFlashes('backups:create');
|
2020-04-07 05:25:54 +00:00
|
|
|
}, [ visible ]);
|
2020-04-04 17:59:25 +00:00
|
|
|
|
|
|
|
const submit = ({ name, ignored }: Values, { setSubmitting }: FormikHelpers<Values>) => {
|
2020-04-07 05:25:54 +00:00
|
|
|
clearFlashes('backups:create');
|
2020-04-04 17:59:25 +00:00
|
|
|
createServerBackup(uuid, name, ignored)
|
|
|
|
.then(backup => {
|
2020-08-21 04:44:33 +00:00
|
|
|
mutate(data => ({ ...data, items: data.items.concat(backup) }), false);
|
2020-04-04 17:59:25 +00:00
|
|
|
setVisible(false);
|
|
|
|
})
|
|
|
|
.catch(error => {
|
2020-08-21 04:44:33 +00:00
|
|
|
clearAndAddHttpError({ key: 'backups:create', error });
|
2020-04-04 17:59:25 +00:00
|
|
|
setSubmitting(false);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
|
|
|
<>
|
|
|
|
{visible &&
|
|
|
|
<Formik
|
|
|
|
onSubmit={submit}
|
|
|
|
initialValues={{ name: '', ignored: '' }}
|
|
|
|
validationSchema={object().shape({
|
2020-04-04 19:30:45 +00:00
|
|
|
name: string().max(255),
|
2020-04-04 17:59:25 +00:00
|
|
|
ignored: string(),
|
|
|
|
})}
|
|
|
|
>
|
2020-08-02 02:49:38 +00:00
|
|
|
<ModalContent appear visible={visible} onDismissed={() => setVisible(false)}/>
|
2020-04-04 17:59:25 +00:00
|
|
|
</Formik>
|
|
|
|
}
|
2020-07-04 23:26:07 +00:00
|
|
|
<Button onClick={() => setVisible(true)}>
|
2020-04-04 17:59:25 +00:00
|
|
|
Create backup
|
2020-07-04 23:26:07 +00:00
|
|
|
</Button>
|
2020-04-04 17:59:25 +00:00
|
|
|
</>
|
|
|
|
);
|
|
|
|
};
|