diff --git a/i18n/en.json b/i18n/en.json
index 67dd06198a..0e55252060 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -177,10 +177,17 @@
"machine_learning_smart_search_enabled": "Enable smart search",
"machine_learning_smart_search_enabled_description": "If disabled, images will not be encoded for smart search.",
"machine_learning_url_description": "The URL of the machine learning server. If more than one URL is provided, each server will be attempted one-at-a-time until one responds successfully, in order from first to last. Servers that don't respond will be temporarily ignored until they come back online.",
+ "maintenance_restore_backup": "Restore Backup",
+ "maintenance_delete_backup": "Delete Backup",
+ "maintenance_delete_backup_description": "This file will be irrevocably deleted.",
+ "maintenance_restore_backup_description": "Immich will be wiped and restored from the chosen backup. A backup will be created before continuing.",
"maintenance_settings": "Maintenance",
"maintenance_settings_description": "Put Immich into maintenance mode.",
"maintenance_start": "Start maintenance mode",
+ "maintenance_upload_backup": "Upload database backup file",
"maintenance_start_error": "Failed to start maintenance mode.",
+ "maintenance_delete_error": "Failed to delete backup.",
+ "maintenance_upload_backup_error": "Could not upload backup, is it an .sql/.sql.gz file?",
"manage_concurrency": "Manage Concurrency",
"manage_log_settings": "Manage log settings",
"map_dark_style": "Dark style",
@@ -1324,12 +1331,26 @@
"loop_videos_description": "Enable to automatically loop a video in the detail viewer.",
"main_branch_warning": "You're using a development version; we strongly recommend using a release version!",
"main_menu": "Main menu",
+ "maintenance_action_restore": "Restoring Database",
"maintenance_description": "Immich has been put into maintenance mode.",
"maintenance_end": "End maintenance mode",
"maintenance_end_error": "Failed to end maintenance mode.",
"maintenance_logged_in_as": "Currently logged in as {user}",
- "maintenance_task_backup": "Creating a backup of the existing database...",
- "maintenance_task_restore": "Restoring the chosen backup...",
+ "maintenance_restore_from_backup": "Restore From Backup",
+ "maintenance_restore_library": "Restore Your Library",
+ "maintenance_restore_library_confirm": "If this looks correct, continue to restoring a backup!",
+ "maintenance_restore_library_description": "Restoring Database",
+ "maintenance_restore_library_folder_has_files": "{folder} has {count} folder(s)",
+ "maintenance_restore_library_folder_no_files": "{folder} is missing files!",
+ "maintenance_restore_library_folder_pass": "readable and writable",
+ "maintenance_restore_library_folder_read_fail": "not readable",
+ "maintenance_restore_library_folder_write_fail": "not writable",
+ "maintenance_restore_library_hint_missing_files": "You may be missing important files",
+ "maintenance_restore_library_hint_regenerate_later": "You can regenerate these later in settings",
+ "maintenance_restore_library_hint_storage_template_missing_files": "Using storage template? You may be missing files",
+ "maintenance_restore_library_loading": "Loading integrity checks and heuristics…",
+ "maintenance_task_backup": "Creating a backup of the existing database…",
+ "maintenance_task_restore": "Restoring the chosen backup…",
"maintenance_title": "Temporarily Unavailable",
"make": "Make",
"manage_geolocation": "Manage location",
@@ -1916,6 +1937,12 @@
"shared_link_edit_expire_after_option_hours": "{count} hours",
"shared_link_edit_expire_after_option_minute": "1 minute",
"shared_link_edit_expire_after_option_minutes": "{count} minutes",
+ "created_day_ago": "Created 1 day ago",
+ "created_days_ago": "Created {count} days ago",
+ "created_hour_ago": "Created 1 hour ago",
+ "created_hours_ago": "Created {count} hours ago",
+ "created_minute_ago": "Created 1 minute ago",
+ "created_minutes_ago": "Created {count} minutes ago",
"shared_link_edit_expire_after_option_months": "{count} months",
"shared_link_edit_expire_after_option_year": "{count} year",
"shared_link_edit_password_hint": "Enter the share password",
diff --git a/web/src/lib/components/maintenance/MaintenanceBackupsList.svelte b/web/src/lib/components/maintenance/MaintenanceBackupsList.svelte
index fe111fe812..a2a0875809 100644
--- a/web/src/lib/components/maintenance/MaintenanceBackupsList.svelte
+++ b/web/src/lib/components/maintenance/MaintenanceBackupsList.svelte
@@ -18,6 +18,7 @@
IconButton,
menuManager,
modalManager,
+ ProgressBar,
Stack,
Text,
type ContextMenuBaseProps,
@@ -36,15 +37,15 @@
function mapBackups(filenames: string[]) {
return filenames.map((filename) => {
const date = /(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})/.exec(filename);
- const hoursAgo = date
+ const minutesAgo = date
? Math.floor(
- (+Date.now() - +new Date(`${date[1]}-${date[2]}-${date[3]}T${date[4]}:${date[5]}:${date[6]}`)) / 36e5,
+ (+Date.now() - +new Date(`${date[1]}-${date[2]}-${date[3]}T${date[4]}:${date[5]}:${date[6]}`)) / 60_000,
)
: null;
return {
filename,
- hoursAgo,
+ minutesAgo,
};
});
}
@@ -61,9 +62,9 @@
async function restore(filename: string) {
const confirm = await modalManager.showDialog({
- confirmText: 'Restore',
- title: 'Restore Backup',
- prompt: 'Immich will be wiped and restored from the chosen backup. A backup will be created before continuing.',
+ confirmText: $t('restore'),
+ title: $t('admin.maintenance_restore_backup'),
+ prompt: $t('admin.maintenance_restore_backup_description'),
});
if (confirm) {
@@ -82,9 +83,9 @@
async function remove(filename: string) {
const confirm = await modalManager.showDialog({
- confirmText: 'Delete',
- title: 'Delete Backup',
- prompt: 'This file will be irrevocably deleted.',
+ confirmText: $t('delete'),
+ title: $t('admin.maintenance_delete_backup'),
+ prompt: $t('admin.maintenance_delete_backup_description'),
});
if (confirm) {
@@ -97,7 +98,7 @@
backups = backups.filter((backup) => backup.filename !== filename);
} catch (error) {
- handleError(error, 'failed to delete backup i18n');
+ handleError(error, $t('admin.maintenance_delete_error'));
} finally {
deleting.delete(filename);
}
@@ -114,14 +115,14 @@
target: event.currentTarget as HTMLElement,
items: [
{
- title: 'Download',
+ title: $t('download'),
icon: mdiDownload,
onSelect() {
void download(filename);
},
},
{
- title: 'Delete',
+ title: $t('delete'),
icon: mdiTrashCanOutline,
color: 'danger',
onSelect() {
@@ -153,7 +154,7 @@
const { backups: newList } = await listBackups();
backups = mapBackups(newList);
} catch (error) {
- handleError(error, 'Could not upload backup, is it an .sql/.sql.gz file?');
+ handleError(error, $t('admin.maintenance_upload_backup_error'));
} finally {
uploadProgress = -1;
}
@@ -165,15 +166,13 @@
{error}