11import React , { useState } from 'react' ;
2- import { faCloudDownloadAlt , faEllipsisH , faLock , faTrashAlt } from '@fortawesome/free-solid-svg-icons' ;
2+ import { faBoxOpen , faCloudDownloadAlt , faEllipsisH , faLock , faTrashAlt } from '@fortawesome/free-solid-svg-icons' ;
33import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' ;
44import DropdownMenu , { DropdownButtonRow } from '@/components/elements/DropdownMenu' ;
55import getBackupDownloadUrl from '@/api/server/backups/getBackupDownloadUrl' ;
@@ -13,6 +13,7 @@ import tw from 'twin.macro';
1313import getServerBackups from '@/api/swr/getServerBackups' ;
1414import { ServerBackup } from '@/api/server/types' ;
1515import { ServerContext } from '@/state/server' ;
16+ import Input from '@/components/elements/Input' ;
1617
1718interface Props {
1819 backup : ServerBackup ;
@@ -23,6 +24,7 @@ export default ({ backup }: Props) => {
2324 const [ loading , setLoading ] = useState ( false ) ;
2425 const [ visible , setVisible ] = useState ( false ) ;
2526 const [ deleteVisible , setDeleteVisible ] = useState ( false ) ;
27+ const [ restoreVisible , setRestoreVisible ] = useState ( false ) ;
2628 const { clearFlashes, clearAndAddHttpError } = useFlash ( ) ;
2729 const { mutate } = getServerBackups ( ) ;
2830
@@ -69,6 +71,33 @@ export default ({ backup }: Props) => {
6971 checksum = { backup . checksum }
7072 />
7173 }
74+ < ConfirmationModal
75+ visible = { restoreVisible }
76+ title = { 'Restore this backup?' }
77+ buttonText = { 'Restore backup' }
78+ onConfirmed = { ( ) => null }
79+ onModalDismissed = { ( ) => setRestoreVisible ( false ) }
80+ >
81+ < p css = { tw `text-neutral-300` } >
82+ This server will be stopped in order to restore the backup. Once the backup has started you will
83+ not be able to control the server power state, access the file manager, or create additional backups
84+ until it has completed.
85+ </ p >
86+ < p css = { tw `text-neutral-300 mt-4` } >
87+ Are you sure you want to continue?
88+ </ p >
89+ < p css = { tw `mt-4 -mb-2 bg-neutral-900 p-3 rounded` } >
90+ < label htmlFor = { 'restore_truncate' } css = { tw `text-base text-neutral-200 flex items-center cursor-pointer` } >
91+ < Input
92+ type = { 'checkbox' }
93+ css = { tw `text-red-500! w-5! h-5! mr-2` }
94+ id = { 'restore_truncate' }
95+ value = { 'true' }
96+ />
97+ Remove all files and folders before restoring this backup.
98+ </ label >
99+ </ p >
100+ </ ConfirmationModal >
72101 < ConfirmationModal
73102 visible = { deleteVisible }
74103 title = { 'Delete this backup?' }
@@ -98,6 +127,12 @@ export default ({ backup }: Props) => {
98127 < span css = { tw `ml-2` } > Download</ span >
99128 </ DropdownButtonRow >
100129 </ Can >
130+ < Can action = { 'backup.restore' } >
131+ < DropdownButtonRow onClick = { ( ) => setRestoreVisible ( true ) } >
132+ < FontAwesomeIcon fixedWidth icon = { faBoxOpen } css = { tw `text-xs` } />
133+ < span css = { tw `ml-2` } > Restore</ span >
134+ </ DropdownButtonRow >
135+ </ Can >
101136 < DropdownButtonRow onClick = { ( ) => setVisible ( true ) } >
102137 < FontAwesomeIcon fixedWidth icon = { faLock } css = { tw `text-xs` } />
103138 < span css = { tw `ml-2` } > Checksum</ span >
0 commit comments