import React, { useState } from 'react'; import { faBoxOpen, faCloudDownloadAlt, faEllipsisH, faLock, faTrashAlt, faUnlock, } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import DropdownMenu, { DropdownButtonRow } from '@/components/elements/DropdownMenu'; import getBackupDownloadUrl from '@/api/server/backups/getBackupDownloadUrl'; import useFlash from '@/plugins/useFlash'; import SpinnerOverlay from '@/components/elements/SpinnerOverlay'; import deleteBackup from '@/api/server/backups/deleteBackup'; import Can from '@/components/elements/Can'; import tw from 'twin.macro'; import getServerBackups from '@/api/swr/getServerBackups'; import { ServerBackup } from '@/api/server/types'; import { ServerContext } from '@/state/server'; import Input from '@/components/elements/Input'; import { restoreServerBackup } from '@/api/server/backups'; import http, { httpErrorToHuman } from '@/api/http'; import { Dialog } from '@/components/elements/dialog'; interface Props { backup: ServerBackup; } export default ({ backup }: Props) => { const uuid = ServerContext.useStoreState((state) => state.server.data!.uuid); const setServerFromState = ServerContext.useStoreActions((actions) => actions.server.setServerFromState); const [modal, setModal] = useState(''); const [loading, setLoading] = useState(false); const [truncate, setTruncate] = useState(false); const { clearFlashes, clearAndAddHttpError } = useFlash(); const { mutate } = getServerBackups(); const doDownload = () => { setLoading(true); clearFlashes('backups'); getBackupDownloadUrl(uuid, backup.uuid) .then((url) => { // @ts-expect-error this is valid window.location = url; }) .catch((error) => { console.error(error); clearAndAddHttpError({ key: 'backups', error }); }) .then(() => setLoading(false)); }; const doDeletion = () => { setLoading(true); clearFlashes('backups'); deleteBackup(uuid, backup.uuid) .then(() => mutate( (data) => ({ ...data, items: data.items.filter((b) => b.uuid !== backup.uuid), backupCount: data.backupCount - 1, }), false ) ) .catch((error) => { console.error(error); clearAndAddHttpError({ key: 'backups', error }); setLoading(false); setModal(''); }); }; const doRestorationAction = () => { setLoading(true); clearFlashes('backups'); restoreServerBackup(uuid, backup.uuid, truncate) .then(() => setServerFromState((s) => ({ ...s, status: 'restoring_backup', })) ) .catch((error) => { console.error(error); clearAndAddHttpError({ key: 'backups', error }); }) .then(() => setLoading(false)) .then(() => setModal('')); }; const onLockToggle = () => { if (backup.isLocked && modal !== 'unlock') { return setModal('unlock'); } http.post(`/api/client/servers/${uuid}/backups/${backup.uuid}/lock`) .then(() => mutate( (data) => ({ ...data, items: data.items.map((b) => b.uuid !== backup.uuid ? b : { ...b, isLocked: !b.isLocked, } ), }), false ) ) .catch((error) => alert(httpErrorToHuman(error))) .then(() => setModal('')); }; return ( <> setModal('')} title={`Unlock "${backup.name}"`} onConfirmed={onLockToggle} > This backup will no longer be protected from automated or accidental deletions. setModal('')} confirm={'Restore'} title={`Restore "${backup.name}"`} onConfirmed={() => doRestorationAction()} >

Your server will be stopped. You will not be able to control the power state, access the file manager, or create additional backups until completed.

setModal('')} onConfirmed={doDeletion} > This is a permanent operation. The backup cannot be recovered once deleted. {backup.isSuccessful ? ( ( )} >
Download setModal('restore')}> Restore <> {backup.isLocked ? 'Unlock' : 'Lock'} {!backup.isLocked && ( setModal('delete')}> Delete )}
) : ( )} ); };