Add backup target edit dialog

This commit is contained in:
Johannes Zellner
2025-08-06 16:26:00 +02:00
parent 8ba56f8b66
commit bf8f8d32a9
4 changed files with 104 additions and 18 deletions
@@ -77,7 +77,6 @@ async function getBlockDevices() {
if (error) return console.error(error);
console.log(providerConfig.value)
// amend label for UI
result.forEach(d => {
d.label = d.path;
@@ -226,17 +226,16 @@ defineExpose({
encryptedFilenames.value = false;
limits.value = {};
// ensure we have all required child objects
if (!providerConfig.value.mountOptions) providerConfig.value.mountOptions = {};
// some sane defaults
if (!limits.value.memoryLimit) limits.value.memoryLimit = 1024 * 1024 * 1024; // 1 GB
if (!limits.value.uploadPartSize) limits.value.uploadPartSize = 10 * 1024 * 1024;
if (!limits.value.syncConcurrency) limits.value.syncConcurrency = 10;
if (!limits.value.downloadConcurrency) limits.value.downloadConcurrency = 10;
if (!limits.value.copyConcurrency) limits.value.copyConcurrency = 10;
limits.value.memoryLimit = 1024 * 1024 * 1024; // 1 GB
limits.value.uploadPartSize = 10 * 1024 * 1024;
limits.value.syncConcurrency = 10;
limits.value.downloadConcurrency = 10;
limits.value.copyConcurrency = 10;
// ensure we have all required child objects
// needs translation for UI
providerConfig.value.mountOptions = {};
providerConfig.value.useHardlinks = false;
providerConfig.value.encryptionPassword = null;
@@ -249,13 +248,13 @@ defineExpose({
</script>
<template>
<Dialog ref="dialog" :title="$t('backups.configureBackupStorage.title')">
<!-- TODO translate -->
<Dialog ref="dialog" title="Add Backup Storage">
<div>
<div v-if="step === 'storage'">
<form @submit.prevent="onSubmit()" autocomplete="off" ref="form">
<fieldset :disabled="busy">
<input style="display: none;" type="submit"/>
<!-- TODO <div class="warning-label" v-show="oldProvider !== provider || oldFormat !== providerConfig.format">{{ $t('backups.configureBackupStorage.formatChangeNote') }}</div> -->
<FormGroup>
<!-- TODO translate -->
@@ -337,7 +336,7 @@ defineExpose({
</FormGroup>
<FormGroup>
<!-- TODO translate -->
<label for="encryptionPassswordHintInput">Password Hint</label>
<label for="encryptionPassswordHintInput">Encryption Password Hint</label>
<TextInput id="encryptionPassswordHintInput" v-model="encryptionPasswordHint" />
</FormGroup>
<Checkbox v-if="format === 'rsync'" v-model="encryptedFilenames" :label="$t('backups.configureBackupStorage.encryptFilenames')"/>
@@ -0,0 +1,86 @@
<script setup>
import { ref, useTemplateRef, watch } from 'vue';
import { Dialog, FormGroup, TextInput, PasswordInput, Button, Checkbox } from '@cloudron/pankow';
import { prettyBinarySize } from '@cloudron/pankow/utils';
import { REGIONS_CONTABO, REGIONS_VULTR, REGIONS_IONOS, REGIONS_OVH, REGIONS_LINODE, REGIONS_SCALEWAY, REGIONS_WASABI } from '../constants.js';
import { mountlike, s3like } from '../utils.js';
import BackupProviderForm from './BackupProviderForm.vue';
import BackupTargetsModel from '../models/BackupTargetsModel.js';
import SystemModel from '../models/SystemModel.js';
const emit = defineEmits([ 'success' ]);
const backupTargetsModel = BackupTargetsModel.create();
const systemModel = SystemModel.create();
const dialog = useTemplateRef('dialog');
const target = ref({});
const formError = ref({});
const busy = ref(false);
async function onSubmit() {
emit('success');
dialog.value.close();
}
defineExpose({
async open(t) {
formError.value = {};
busy.value = false;
target.value = t;
console.log(t)
dialog.value.open();
}
});
</script>
<template>
<Dialog ref="dialog"
:title="$t('backups.configureBackupStorage.title')"
:reject-label="$t('main.dialog.close')"
reject-style="secondary"
:confirm-label="$t('main.dialog.save')"
confirm-style="primary"
@confirm="onSubmit()"
>
<div>
<div>
<div class="info-row">
<div class="info-label">{{ $t('backups.configureBackupStorage.provider') }}</div>
<div class="info-value">{{ target.provider }}</div>
</div>
<div class="info-row" v-if="target.provider !== 'noop'">
<div class="info-label">{{ $t('backups.configureBackupStorage.format') }}</div>
<div class="info-value">{{ target.format }} <i v-if="target.encrypted" class="fa-solid fa-lock"></i></div>
</div>
<div class="info-row" v-if="target.provider !== 'noop'">
<div class="info-label">{{ $t('backups.location.location') }}</div>
<div class="info-value">
<span v-if="mountlike(target.provider) || target.provider === 'filesystem'">
<span v-if="target.provider === 'filesystem'">{{ target.config.backupDir }}{{ (target.config.prefix ? `/${target.config.prefix}` : '') }}</span>
<span v-if="target.provider === 'disk' || target.provider === 'ext4' || target.provider === 'xfs' || target.provider === 'mountpoint'">{{ target.config.mountOptions.diskPath || target.config.mountPoint }}{{ (target.config.prefix ? '/' : '') + target.config.prefix }}</span>
<span v-if="target.provider === 'cifs' || target.provider === 'nfs' || target.provider === 'sshfs'">{{ target.config.mountOptions.host }}:{{ target.config.mountOptions.remoteDir }}{{ (target.prefix ? '/' : '') + target.config.prefix }}</span>
</span>
<span v-if="target.provider !== 's3' && target.provider !== 'minio' && (s3like(target.provider) || target.provider === 'gcs')">{{ target.config.bucket + (target.config.prefix ? '/' : '') + target.config.prefix }}</span>
<span v-if="target.provider === 's3'">{{ target.config.region + ' ' + target.config.bucket + (target.config.prefix ? '/' : '') + target.config.prefix }}</span>
<span v-if="target.provider === 'minio'">{{ target.config.endpoint + ' ' + target.config.bucket + (target.config.prefix ? '/' : '') + target.config.prefix }}</span>
</div>
</div>
<div class="info-row" v-if="target.provider !== 'minio' && target.config?.endpoint">
<div class="info-label">{{ $t('backups.location.endpoint') }}</div>
<div class="info-value">{{ target.config.endpoint || target.config.region }}</div>
</div>
<div class="info-row" v-if="target.encrypted">
<!-- TODO translate -->
<div class="info-label">Encryption Password Hint</div>
<div class="info-value">{{ target.encryptionPasswordHint }}</div>
</div>
</div>
</div>
</Dialog>
</template>