diff --git a/dashboard/public/translation/en.json b/dashboard/public/translation/en.json index c6e26b0cb..6c413bf50 100644 --- a/dashboard/public/translation/en.json +++ b/dashboard/public/translation/en.json @@ -447,7 +447,7 @@ }, "backupEdit": { "title": "Edit Backup", - "label": "Backup label", + "label": "Label", "preserved": { "description": "Keep backup permanently (excluded from retention policy)", "tooltip": "This will also preserve the mail and {{ appsLength }} app backup(s)." @@ -1602,7 +1602,7 @@ }, "backup": { "target": { - "label": "Backup site", + "label": "Site", "size": "Size", "fileCount": "Files" }, diff --git a/dashboard/src/components/BackupInfoDialog.vue b/dashboard/src/components/BackupInfoDialog.vue new file mode 100644 index 000000000..847016662 --- /dev/null +++ b/dashboard/src/components/BackupInfoDialog.vue @@ -0,0 +1,159 @@ + + + \ No newline at end of file diff --git a/dashboard/src/components/SystemBackupList.vue b/dashboard/src/components/SystemBackupList.vue index 81e0a5120..08a0301cd 100644 --- a/dashboard/src/components/SystemBackupList.vue +++ b/dashboard/src/components/SystemBackupList.vue @@ -5,20 +5,19 @@ const i18n = useI18n(); const t = i18n.t; import { ref, onMounted, useTemplateRef } from 'vue'; -import { Button, ClipboardAction, Menu, FormGroup, TextInput, Checkbox, TableView, Dialog } from '@cloudron/pankow'; -import { prettyDuration, prettyLongDate, prettyFileSize } from '@cloudron/pankow/utils'; +import { Button, Menu, FormGroup, TextInput, Checkbox, TableView, Dialog } from '@cloudron/pankow'; +import { prettyLongDate, prettyFileSize } from '@cloudron/pankow/utils'; import { TASK_TYPES } from '../constants.js'; import Section from '../components/Section.vue'; import BackupsModel from '../models/BackupsModel.js'; import BackupSitesModel from '../models/BackupSitesModel.js'; -import AppsModel from '../models/AppsModel.js'; import TasksModel from '../models/TasksModel.js'; import DashboardModel from '../models/DashboardModel.js'; import { download } from '../utils.js'; +import BackupInfoDialog from './BackupInfoDialog.vue'; const backupsModel = BackupsModel.create(); const backupSitesModel = BackupSitesModel.create(); -const appsModel = AppsModel.create(); const tasksModel = TasksModel.create(); const dashboardModel = DashboardModel.create(); @@ -56,25 +55,6 @@ const columns = { actions: {} }; -const backupContentTableColumns = { - label: { - label: t('backups.listing.contents'), - sort: true, - }, - fileCount: { - label: t('backup.target.fileCount'), - sort(a, b, A, B) { - return A.stats?.upload?.fileCount - B.stats?.upload?.fileCount; - }, - }, - size: { - label: t('backup.target.size'), - sort(a, b, A , B) { - return A.stats?.upload?.size - B.stats?.upload?.size; - }, - } -}; - const actionMenuModel = ref([]); const actionMenuElement = useTemplateRef('actionMenuElement'); function onActionMenu(backup, event) { @@ -200,51 +180,9 @@ async function onDownloadConfig(backup) { download(filename, JSON.stringify(backupConfig, null, 4)); } -// backups info dialog const infoDialog = useTemplateRef('infoDialog'); -const infoDialogBusy = ref(true); -const infoBackup = ref({ contents: [] }); async function onInfo(backup) { - infoBackup.value = backup; - infoBackup.value.contents = []; - infoDialogBusy.value = true; - - infoDialog.value.open(); - - // amend detailed app info - const appsById = {}; - - const [appsError, apps] = await appsModel.list(); - if (appsError) console.error('Failed to get apps list:', appsError); - - (apps || []).forEach(function (app) { - appsById[app.id] = app; - }); - - for (const contentId of infoBackup.value.dependsOn) { - const match = contentId.match(/(mail|app)_(.*?)_.*/); // *? means non-greedy - if (!match) continue; - const [error, backup] = await backupsModel.get(contentId); - if (error) console.error(error); - const content = { id: null, label: null, fqdn: null, stats: null }; - content.stats = backup.stats; - if (match[1] === 'mail') { - content.id = 'mail'; - content.label = 'Mail Server'; - } else { - const app = appsById[match[2]]; - if (app) { - content.id = app.id; - content.label = app.label; - content.fqdn = app.fqdn; - } else { // uninstalled app - content.id = match[2]; - } - } - infoBackup.value.contents.push(content); - } - - infoDialogBusy.value = false; + infoDialog.value.open(backup); } // edit backups dialog @@ -302,65 +240,7 @@ defineExpose({ refresh });
- -
-
{{ $t('backups.backupDetails.id') }}
-
{{ infoBackup.id }}
-
-
-
{{ $t('backups.backupEdit.label') }}
-
{{ infoBackup.label }}
-
-
-
{{ $t('backups.backupEdit.remotePath') }}
-
-
- {{ infoBackup.remotePath }} - -
-
-
-
-
{{ $t('backups.backupDetails.date') }}
-
{{ prettyLongDate(infoBackup.creationTime) }}
-
-
-
{{ $t('backups.backupDetails.version') }}
-
{{ infoBackup.packageVersion }}
-
-
-
{{ $t('backups.backupDetails.size') }}
-
{{ prettyFileSize(infoBackup.stats.aggregatedUpload.size) }} | {{ infoBackup.stats.aggregatedUpload.fileCount }} file(s)
-
-
-
{{ $t('backups.backupDetails.duration') }}
-
{{ prettyDuration(infoBackup.stats.aggregatedUpload.duration + infoBackup.stats.aggregatedCopy.duration) }}
-
- -
-
{{ $t('backups.backupDetails.list', { appCount: infoBackup.appCount }) }}:
-
- - - - - - - -
+ { - -
-
-
{{ $t('backups.backupDetails.id') }}
-
{{ infoBackup.id }}
-
-
-
{{ $t('backups.backupEdit.remotePath') }}
-
{{ infoBackup.remotePath }}
-
-
-
{{ $t('backups.backupDetails.date') }}
-
{{ prettyLongDate(infoBackup.creationTime) }}
-
-
-
{{ $t('backups.backupDetails.version') }}
-
{{ infoBackup.packageVersion }}
-
-
-
+