2021-10-09 00:30:20 +02:00
< template >
2024-03-16 21:12:33 +01:00
< div class = "text-center mt-4 relative" >
2021-10-09 00:30:20 +02:00
< div class = "flex py-4" >
2022-11-08 01:27:17 +01:00
< ui -file -input ref = "fileInput" class = "mr-2" accept = ".audiobookshelf" @change ="backupUploaded" > {{ $ strings.ButtonUploadBackup }} < / ui -file -input >
2021-10-09 00:30:20 +02:00
< div class = "flex-grow" / >
2022-11-08 01:27:17 +01:00
< ui -btn :loading ="isBackingUp" @click ="clickCreateBackup" > {{ $ strings.ButtonCreateBackup }} < / ui -btn >
2021-10-09 00:30:20 +02:00
< / div >
< div class = "relative" >
< table id = "backups" >
< tr >
2022-11-08 01:27:17 +01:00
< th > { { $strings . LabelFile } } < / th >
< th class = "hidden sm:table-cell w-32 md:w-56" > { { $strings . LabelDatetime } } < / th >
< th class = "hidden sm:table-cell w-20 md:w-28" > { { $strings . LabelSize } } < / th >
2021-10-09 00:30:20 +02:00
< th class = "w-36" > < / th >
< / tr >
2022-04-14 01:51:06 +02:00
< tr v-for ="backup in backups" :key="backup.id" :class="!backup.serverVersion ? 'bg-error bg-opacity-10' : ''" >
2021-10-09 00:30:20 +02:00
< td >
2022-02-09 18:19:02 +01:00
< p class = "truncate text-xs sm:text-sm md:text-base" > / { { backup . path . replace ( /\\/g , '/' ) } } < / p >
2021-10-09 00:30:20 +02:00
< / td >
2023-02-27 19:04:26 +01:00
< td class = "hidden sm:table-cell font-sans text-sm" > { { $formatDatetime ( backup . createdAt , dateFormat , timeFormat ) } } < / td >
2022-04-14 01:51:06 +02:00
< td class = "hidden sm:table-cell font-mono md:text-sm text-xs" > { { $bytesPretty ( backup . fileSize ) } } < / td >
2021-10-09 00:30:20 +02:00
< td >
2022-02-09 18:19:02 +01:00
< div class = "w-full flex flex-row items-center justify-center" >
2023-07-14 21:20:35 +02:00
< ui -btn v-if ="backup.serverVersion && backup.key" small color="primary" @click="applyBackup(backup)" > {{ $ strings.ButtonRestore }} < / ui -btn >
2022-04-14 01:51:06 +02:00
< ui -tooltip v -else text = "This backup was created with an old version of audiobookshelf no longer supported" direction = "bottom" class = "mx-2 flex items-center" >
2024-07-08 18:36:37 +02:00
< span class = "material-symbols-outlined text-2xl text-error" > error _outline < / span >
2022-04-14 01:51:06 +02:00
< / u i - t o o l t i p >
2021-10-09 00:30:20 +02:00
2024-07-08 18:36:37 +02:00
< button aria -label = " Download Backup " class = "inline-flex material-symbols text-xl mx-1 mt-1 text-white/70 hover:text-white/100" @click.stop ="downloadBackup(backup)" > download < / button >
2023-07-14 21:20:35 +02:00
2024-07-08 18:36:37 +02:00
< button aria -label = " Delete Backup " class = "inline-flex material-symbols text-xl mx-1 text-white/70 hover:text-error" @click ="deleteBackupClick(backup)" > delete < / button >
2021-10-09 00:30:20 +02:00
< / div >
< / td >
< / tr >
< tr v-if ="!backups.length" class="staticrow" >
2022-11-09 00:10:08 +01:00
< td colspan = "4" class = "text-lg" > { { $strings . MessageNoBackups } } < / td >
2021-10-09 00:30:20 +02:00
< / tr >
< / table >
< div v-show ="processing" class="absolute top-0 left-0 w-full h-full bg-black bg-opacity-25 flex items-center justify-center" >
< ui -loading -indicator / >
< / div >
< / div >
< prompt -dialog v-model ="showConfirmApply" :width ="675" >
< div v-if ="selectedBackup" class="px-4 w-full text-sm py-6 rounded-lg bg-bg shadow-lg border border-black-300" >
2022-11-08 01:27:17 +01:00
< p class = "text-error text-lg font-semibold" > { { $strings . MessageImportantNotice } } < / p >
< p class = "text-base py-1" v -html = " $ strings.MessageRestoreBackupWarning " / >
2021-10-09 00:30:20 +02:00
2023-02-27 19:04:26 +01:00
< p class = "text-lg text-center my-8" > { { $strings . MessageRestoreBackupConfirm } } { { $formatDatetime ( selectedBackup . createdAt , dateFormat , timeFormat ) } } ? < / p >
2021-10-09 00:30:20 +02:00
< div class = "flex px-1 items-center" >
2022-11-08 01:27:17 +01:00
< ui -btn color = "primary" @ click = "showConfirmApply = false" > { { $strings . ButtonNevermind } } < / u i - b t n >
2021-10-09 00:30:20 +02:00
< div class = "flex-grow" / >
2022-11-08 01:27:17 +01:00
< ui -btn color = "success" @click ="confirm" > {{ $ strings.ButtonRestore }} < / ui -btn >
2021-10-09 00:30:20 +02:00
< / div >
< / div >
< / p r o m p t - d i a l o g >
2024-03-16 21:12:33 +01:00
< div v-if ="isApplyingBackup" class="absolute inset-0 w-full h-full flex items-center justify-center bg-black/20 rounded-md" >
< ui -loading -indicator / >
< / div >
2021-10-09 00:30:20 +02:00
< / div >
< / template >
< script >
export default {
data ( ) {
return {
showConfirmApply : false ,
selectedBackup : null ,
isBackingUp : false ,
2024-03-16 21:12:33 +01:00
isApplyingBackup : false ,
2022-11-24 20:14:29 +01:00
processing : false ,
backups : [ ]
2021-10-09 00:30:20 +02:00
}
} ,
computed : {
userToken ( ) {
return this . $store . getters [ 'user/getToken' ]
2023-02-27 19:04:26 +01:00
} ,
dateFormat ( ) {
return this . $store . state . serverSettings . dateFormat
} ,
timeFormat ( ) {
return this . $store . state . serverSettings . timeFormat
2021-10-09 00:30:20 +02:00
}
} ,
methods : {
2023-06-27 23:41:32 +02:00
downloadBackup ( backup ) {
this . $downloadFile ( ` ${ process . env . serverUrl } /api/backups/ ${ backup . id } /download?token= ${ this . userToken } ` )
} ,
2021-10-09 00:30:20 +02:00
confirm ( ) {
this . showConfirmApply = false
2024-03-16 21:12:33 +01:00
this . isApplyingBackup = true
2022-03-18 19:44:29 +01:00
this . $axios
. $get ( ` /api/backups/ ${ this . selectedBackup . id } /apply ` )
. then ( ( ) => {
location . replace ( '/config/backups?backup=1' )
} )
. catch ( ( error ) => {
2023-07-08 21:40:49 +02:00
console . error ( 'Failed to apply backup' , error )
const errorMsg = error . response . data || this . $strings . ToastBackupRestoreFailed
this . $toast . error ( errorMsg )
2022-03-18 19:44:29 +01:00
} )
2024-03-16 21:12:33 +01:00
. finally ( ( ) => {
this . isApplyingBackup = false
} )
2021-10-09 00:30:20 +02:00
} ,
deleteBackupClick ( backup ) {
2023-02-27 19:04:26 +01:00
if ( confirm ( this . $getString ( 'MessageConfirmDeleteBackup' , [ this . $formatDatetime ( backup . createdAt , this . dateFormat , this . timeFormat ) ] ) ) ) {
2021-10-09 00:30:20 +02:00
this . processing = true
this . $axios
2022-03-18 19:44:29 +01:00
. $delete ( ` /api/backups/ ${ backup . id } ` )
2022-11-24 20:14:29 +01:00
. then ( ( data ) => {
this . setBackups ( data . backups || [ ] )
2022-11-09 00:10:08 +01:00
this . $toast . success ( this . $strings . ToastBackupDeleteSuccess )
2021-10-09 00:30:20 +02:00
this . processing = false
} )
. catch ( ( error ) => {
console . error ( error )
2022-11-09 00:10:08 +01:00
this . $toast . error ( this . $strings . ToastBackupDeleteFailed )
2021-10-09 00:30:20 +02:00
this . processing = false
} )
}
} ,
applyBackup ( backup ) {
this . selectedBackup = backup
this . showConfirmApply = true
} ,
clickCreateBackup ( ) {
this . isBackingUp = true
2022-03-18 19:44:29 +01:00
this . $axios
. $post ( '/api/backups' )
2022-11-24 20:14:29 +01:00
. then ( ( data ) => {
2022-03-18 19:44:29 +01:00
this . isBackingUp = false
2022-11-09 00:10:08 +01:00
this . $toast . success ( this . $strings . ToastBackupCreateSuccess )
2022-11-24 20:14:29 +01:00
this . setBackups ( data . backups || [ ] )
2022-03-18 19:44:29 +01:00
} )
. catch ( ( error ) => {
this . isBackingUp = false
console . error ( 'Failed' , error )
2022-11-09 00:10:08 +01:00
this . $toast . error ( this . $strings . ToastBackupCreateFailed )
2022-03-18 19:44:29 +01:00
} )
2021-10-09 00:30:20 +02:00
} ,
backupUploaded ( file ) {
var form = new FormData ( )
form . set ( 'file' , file )
this . processing = true
this . $axios
2022-03-18 19:44:29 +01:00
. $post ( '/api/backups/upload' , form )
2022-11-24 20:14:29 +01:00
. then ( ( data ) => {
this . setBackups ( data . backups || [ ] )
2022-11-09 00:10:08 +01:00
this . $toast . success ( this . $strings . ToastBackupUploadSuccess )
2021-10-09 00:30:20 +02:00
this . processing = false
} )
. catch ( ( error ) => {
console . error ( error )
2022-11-09 00:10:08 +01:00
var errorMessage = error . response && error . response . data ? error . response . data : this . $strings . ToastBackupUploadFailed
2021-10-09 00:30:20 +02:00
this . $toast . error ( errorMessage )
this . processing = false
} )
2022-11-24 20:14:29 +01:00
} ,
setBackups ( backups ) {
backups . sort ( ( a , b ) => b . createdAt - a . createdAt )
this . backups = backups
} ,
loadBackups ( ) {
this . processing = true
this . $axios
. $get ( '/api/backups' )
. then ( ( data ) => {
2024-07-05 23:10:07 +02:00
this . $emit ( 'loaded' , data )
2022-11-24 20:14:29 +01:00
this . setBackups ( data . backups || [ ] )
} )
. catch ( ( error ) => {
console . error ( 'Failed to load backups' , error )
2024-05-13 23:58:41 +02:00
this . $toast . error ( this . $strings . ToastFailedToLoadData )
2022-11-24 20:14:29 +01:00
} )
. finally ( ( ) => {
this . processing = false
} )
2021-10-09 00:30:20 +02:00
}
} ,
mounted ( ) {
2022-11-24 20:14:29 +01:00
this . loadBackups ( )
2021-10-09 00:30:20 +02:00
if ( this . $route . query . backup ) {
this . $toast . success ( 'Backup applied successfully' )
}
}
}
< / script >
< style >
# backups {
table - layout : fixed ;
border - collapse : collapse ;
width : 100 % ;
}
# backups td ,
# backups th {
border : 1 px solid # 2 e2e2e ;
padding : 8 px 8 px ;
text - align : left ;
}
# backups tr . staticrow td {
text - align : center ;
}
2022-04-14 01:51:06 +02:00
# backups tr : nth - child ( even ) : not ( . bg - error ) {
2021-10-09 00:30:20 +02:00
background - color : # 3 a3a3a ;
}
2022-04-14 01:51:06 +02:00
# backups tr : not ( . staticrow ) : not ( . bg - error ) : hover {
2021-10-09 00:30:20 +02:00
background - color : # 444 ;
}
# backups th {
font - size : 0.8 rem ;
font - weight : 600 ;
padding - top : 5 px ;
padding - bottom : 5 px ;
background - color : # 333 ;
}
2023-02-27 19:04:26 +01:00
< / style >