diff --git a/web/src/lib/components/maintenance/MaintenanceBackupsList.svelte b/web/src/lib/components/maintenance/MaintenanceBackupsList.svelte index 699d6de74f..c8fe5b30d1 100644 --- a/web/src/lib/components/maintenance/MaintenanceBackupsList.svelte +++ b/web/src/lib/components/maintenance/MaintenanceBackupsList.svelte @@ -1,10 +1,12 @@ diff --git a/web/src/lib/services/database-backups.service.ts b/web/src/lib/services/database-backups.service.ts index bd0292cfbb..540d532e92 100644 --- a/web/src/lib/services/database-backups.service.ts +++ b/web/src/lib/services/database-backups.service.ts @@ -1,7 +1,36 @@ +import { uploadRequest } from '$lib/utils'; +import { openFilePicker } from '$lib/utils/file-uploader'; import { handleError } from '$lib/utils/handle-error'; import { getFormatter } from '$lib/utils/i18n'; -import { deleteDatabaseBackup, MaintenanceAction, setMaintenanceMode } from '@immich/sdk'; -import { modalManager } from '@immich/ui'; +import { + deleteDatabaseBackup, + getBaseUrl, + MaintenanceAction, + setMaintenanceMode, + type DatabaseBackupUploadDto, +} from '@immich/sdk'; +import { modalManager, type ActionItem } from '@immich/ui'; +import { mdiDownload, mdiTrashCanOutline } from '@mdi/js'; +import type { MessageFormatter } from 'svelte-i18n'; + +export const getDatabaseBackupActions = ($t: MessageFormatter, filename: string, remove: () => void) => { + const Download: ActionItem = { + title: $t('download'), + icon: mdiDownload, + onAction() { + void handleDownloadDatabaseBackup(filename); + }, + }; + + const Delete: ActionItem = { + title: $t('delete'), + icon: mdiTrashCanOutline, + color: 'danger', + onAction: remove, + }; + + return { Download, Delete }; +}; export const handleRestoreDatabaseBackup = async (filename: string) => { const $t = await getFormatter(); @@ -51,3 +80,33 @@ export const handleDeleteDatabaseBackup = async (...filenames: string[]) => { handleError(error, $t('admin.maintenance_delete_error')); } }; + +export const handleDownloadDatabaseBackup = (filename: string) => { + location.href = getBaseUrl() + '/admin/database-backups/' + filename; +}; + +export const handleUploadDatabaseBackup = async (progressFn?: (progress: number) => void) => { + const $t = await getFormatter(); + + try { + const [file] = await openFilePicker({ multiple: false }); + const formData = new FormData(); + formData.append('file', file); + + await uploadRequest({ + url: getBaseUrl() + '/admin/database-backups/upload', + data: formData, + onUploadProgress(event) { + progressFn?.(event.loaded / event.total); + }, + }); + + progressFn?.(1); + + return true; + } catch (error) { + handleError(error, $t('admin.maintenance_upload_backup_error')); + } finally { + progressFn?.(-1); + } +};