Rename backup label to name and separate backup listing into new view

This commit is contained in:
Johannes Zellner
2025-08-04 14:40:29 +02:00
parent 0ff760fe4a
commit 1016d41d7a
8 changed files with 77 additions and 41 deletions
+12 -15
View File
@@ -7,19 +7,17 @@ const t = i18n.t;
import { ref, onMounted, useTemplateRef } from 'vue';
import { Button, ButtonGroup, ProgressBar, FormGroup, TextInput, Checkbox, TableView, Dialog } from '@cloudron/pankow';
import { prettyLongDate, copyToClipboard } from '@cloudron/pankow/utils';
import { TASK_TYPES, SECRET_PLACEHOLDER } from '../constants.js';
import { TASK_TYPES } from '../constants.js';
import Section from '../components/Section.vue';
import BackupsModel from '../models/BackupsModel.js';
import BackupTargetsModel from '../models/BackupTargetsModel.js';
import AppsModel from '../models/AppsModel.js';
import TasksModel from '../models/TasksModel.js';
import DashboardModel from '../models/DashboardModel.js';
import { download } from '../utils.js';
const props = defineProps({
config: Object
});
const backupsModel = BackupsModel.create();
const backupTargetsModel = BackupTargetsModel.create();
const appsModel = AppsModel.create();
const tasksModel = TasksModel.create();
const dashboardModel = DashboardModel.create();
@@ -167,24 +165,23 @@ async function onStopBackup() {
}
async function onDownloadConfig(backup) {
const [error, result] = await dashboardModel.config();
const [error, dashboardConfig] = await dashboardModel.config();
if (error) return console.error(error);
// secrets and tokens already come with placeholder characters we remove them
const [backupTargetError, backupTarget] = await backupTargetsModel.get(backup.targetId);
if (backupTargetError) return console.error(backupTargetError);
const tmp = {
remotePath: backup.remotePath,
encrypted: !!props.config.password // we add this just to help the import UI
remotePath: backup.remotePath
};
for (const k of ['provider', 'config', 'limits', 'format', 'encrypted', 'encryptedFilenames']) {
tmp[k] = backupTarget[k];
}
Object.keys(props.config).forEach((k) => {
if (props.config[k] !== SECRET_PLACEHOLDER) tmp[k] = props.config[k];
});
const filename = `${result.adminFqdn}-backup-config-${(new Date(backup.creationTime)).toISOString().split('T')[0]}.json`;
const filename = `${dashboardConfig.adminFqdn}-backup-config-${(new Date(backup.creationTime)).toISOString().split('T')[0]}.json`;
download(filename, JSON.stringify(tmp, null, 4));
}
// backups info dialog
const infoDialog = useTemplateRef('infoDialog');
const infoBackup = ref({ contents: [] });
@@ -17,7 +17,7 @@ const systemModel = SystemModel.create();
const dialog = useTemplateRef('dialog');
const form = useTemplateRef('form');
const target = ref({});
const label = ref('');
const name = ref('');
const encrypted = ref(false);
const encryptedFilenames = ref(false);
const formError = ref({});
@@ -146,7 +146,7 @@ async function onSubmitAdd() {
formError.value = {};
busy.value = true;
const [error, targetId] = await backupTargetsModel.add(label.value, format.value, provider.value, data, schedulePattern, retention, limitsConfig, encryptionPassword, encryptedFilenames);
const [error, targetId] = await backupTargetsModel.add(name.value, format.value, provider.value, data, schedulePattern, retention, limitsConfig, encryptionPassword, encryptedFilenames);
if (error) {
formError.value.generic = error.body ? error.body.message : 'Internal error';
busy.value = false;
@@ -168,7 +168,14 @@ async function onSubmitAdd() {
async function onSubmitEdit() {
// TODO set config (eg. provider config passwords)
// TODO set label somehow?
// name
let [error] = await backupTargetsModel.setName(target.value.id, name.value);
if (error) {
formError.value.generic = 'Failed to set name';
busy.value = false;
return console.error(error);
}
// limits
const limitsConfig = {
@@ -180,7 +187,7 @@ async function onSubmitEdit() {
// deleteConcurrency: parseInt(providerConfig.value.limits.deleteConcurrency),
};
const [error] = await backupTargetsModel.setLimits(target.value.id, limitsConfig);
[error] = await backupTargetsModel.setLimits(target.value.id, limitsConfig);
if (error) {
formError.value.generic = 'Failed to set limits';
busy.value = false;
@@ -227,7 +234,7 @@ defineExpose({
formError.value = {};
busy.value = false;
label.value = t?.label || '';
name.value = t?.name || '';
provider.value = t?.provider || '';
format.value = t?.format || '';
isPrimary.value = t?.primary || false;
@@ -273,14 +280,14 @@ defineExpose({
<input style="display: none;" type="submit"/>
<!-- TODO <div class="warning-label" v-show="oldProvider !== provider || oldFormat !== providerConfig.format">{{ $t('backups.configureBackupStorage.formatChangeNote') }}</div> -->
<BackupProviderForm v-model:provider="provider" v-model:format="format" v-model:provider-config="providerConfig" :form-error="formError"/>
<FormGroup>
<!-- TODO translate -->
<label for="labelInput">Label</label>
<TextInput id="labelInput" v-model="label" />
<label for="nameInput">Name</label>
<TextInput id="nameInput" v-model="name" required/>
</FormGroup>
<BackupProviderForm v-model:provider="provider" v-model:format="format" v-model:provider-config="providerConfig" :form-error="formError"/>
<!-- TODO translate -->
<Checkbox v-model="isPrimary" label="primary backup target" />