Add support for locking backups to prevent any accidental deletions

This commit is contained in:
Dane Everitt 2021-05-03 21:26:09 -07:00
parent 5f48712c28
commit 5d5e4ca7b1
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
18 changed files with 250 additions and 88 deletions

View file

@ -1,7 +1,7 @@
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 { boolean, object, string } from 'yup';
import Field from '@/components/elements/Field';
import FormikFieldWrapper from '@/components/elements/FormikFieldWrapper';
import useFlash from '@/plugins/useFlash';
@ -12,10 +12,13 @@ import tw from 'twin.macro';
import { Textarea } from '@/components/elements/Input';
import getServerBackups from '@/api/swr/getServerBackups';
import { ServerContext } from '@/state/server';
import FormikSwitch from '@/components/elements/FormikSwitch';
import Can from '@/components/elements/Can';
interface Values {
name: string;
ignored: string;
isLocked: boolean;
}
const ModalContent = ({ ...props }: RequiredModalProps) => {
@ -26,14 +29,12 @@ const ModalContent = ({ ...props }: RequiredModalProps) => {
<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`}>
<Field
name={'name'}
label={'Backup name'}
description={'If provided, the name that should be used to reference this backup.'}
/>
</div>
<div css={tw`mb-6`}>
<Field
name={'name'}
label={'Backup name'}
description={'If provided, the name that should be used to reference this backup.'}
/>
<div css={tw`mt-6`}>
<FormikFieldWrapper
name={'ignored'}
label={'Ignored Files & Directories'}
@ -47,7 +48,16 @@ const ModalContent = ({ ...props }: RequiredModalProps) => {
<FormikField as={Textarea} name={'ignored'} rows={6}/>
</FormikFieldWrapper>
</div>
<div css={tw`flex justify-end`}>
<Can action={'backup.delete'}>
<div css={tw`mt-6 bg-neutral-700 border border-neutral-800 shadow-inner p-4 rounded`}>
<FormikSwitch
name={'isLocked'}
label={'Locked'}
description={'Prevents this backup from being deleted until explicitly unlocked.'}
/>
</div>
</Can>
<div css={tw`flex justify-end mt-6`}>
<Button type={'submit'} disabled={isSubmitting}>
Start backup
</Button>
@ -67,9 +77,9 @@ export default () => {
clearFlashes('backups:create');
}, [ visible ]);
const submit = ({ name, ignored }: Values, { setSubmitting }: FormikHelpers<Values>) => {
const submit = (values: Values, { setSubmitting }: FormikHelpers<Values>) => {
clearFlashes('backups:create');
createServerBackup(uuid, name, ignored)
createServerBackup(uuid, values)
.then(backup => {
mutate(data => ({ ...data, items: data.items.concat(backup) }), false);
setVisible(false);
@ -85,10 +95,11 @@ export default () => {
{visible &&
<Formik
onSubmit={submit}
initialValues={{ name: '', ignored: '' }}
initialValues={{ name: '', ignored: '', isLocked: false }}
validationSchema={object().shape({
name: string().max(191),
ignored: string(),
isLocked: boolean(),
})}
>
<ModalContent appear visible={visible} onDismissed={() => setVisible(false)}/>