Peer restore works

Still need to SQL Dump the table aswell
This commit is contained in:
Donald Zou
2024-10-16 17:44:49 +08:00
parent 51712ed2a8
commit e2e821881c
6 changed files with 367 additions and 138 deletions

View File

@@ -0,0 +1,144 @@
<script setup>
import dayjs from "dayjs";
import {computed, ref} from "vue";
import {fetchPost} from "@/utilities/fetch.js";
import {useRoute} from "vue-router";
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
const props = defineProps(["b", "delay"])
const deleteConfirmation = ref(false)
const restoreConfirmation = ref(false)
const route = useRoute()
const emit = defineEmits(["refresh", "refreshPeersList"])
const store = DashboardConfigurationStore()
const loading = ref(false);
const deleteBackup = () => {
loading.value = true;
fetchPost("/api/deleteWireguardConfigurationBackup", {
configurationName: route.params.id,
backupFileName: props.b.filename
}, (res) => {
loading.value = false;
if (res.status){
emit("refresh")
store.newMessage("Server", "Backup deleted", "success")
}else{
store.newMessage("Server", "Backup failed to delete", "danger")
}
})
}
const restoreBackup = () => {
loading.value = true;
fetchPost("/api/restoreWireguardConfigurationBackup", {
configurationName: route.params.id,
backupFileName: props.b.filename
}, (res) => {
loading.value = false;
if (res.status){
emit("refresh")
store.newMessage("Server", "Backup restored", "success")
}else{
store.newMessage("Server", "Backup failed to restore", "danger")
}
})
}
const delaySeconds = computed(() => {
return props.delay + 's'
})
</script>
<template>
<div class="card my-0 rounded-3">
<div class="card-body position-relative">
<Transition name="zoomReversed">
<div
v-if="deleteConfirmation"
class="position-absolute w-100 h-100 confirmationContainer start-0 top-0 rounded-3 d-flex p-2">
<div class="m-auto">
<h5>Are you sure to delete this backup?</h5>
<div class="d-flex gap-2 align-items-center justify-content-center">
<button class="btn btn-danger rounded-3"
:disabled="loading"
@click='deleteBackup()'>
Yes
</button>
<button
@click="deleteConfirmation = false"
:disabled="loading"
class="btn bg-secondary-subtle text-secondary-emphasis border-secondary-subtle rounded-3">
No
</button>
</div>
</div>
</div>
</Transition>
<Transition name="zoomReversed">
<div
v-if="restoreConfirmation"
class="position-absolute w-100 h-100 confirmationContainer start-0 top-0 rounded-3 d-flex p-2">
<div class="m-auto">
<h5>Are you sure to restore this backup?</h5>
<div class="d-flex gap-2 align-items-center justify-content-center">
<button
:disabled="loading"
@click="restoreBackup()"
class="btn btn-danger rounded-3">
Yes
</button>
<button
@click="restoreConfirmation = false"
:disabled="loading"
class="btn bg-secondary-subtle text-secondary-emphasis border-secondary-subtle rounded-3">
No
</button>
</div>
</div>
</div>
</Transition>
<div class="d-flex gap-3">
<div class="d-flex flex-column">
<small class="text-muted">
Filename
</small>
<samp>{{b.filename}}</samp>
</div>
<div class="d-flex flex-column">
<small class="text-muted">
Backup Date
</small>
{{dayjs(b.backupDate, "YYYYMMDDHHmmss").format("YYYY-MM-DD HH:mm:ss")}}
</div>
<div class="d-flex gap-2 align-items-center ms-auto">
<button
@click="restoreConfirmation = true"
class="btn bg-warning-subtle text-warning-emphasis border-warning-subtle rounded-3 btn-sm">
<i class="bi bi-clock-history"></i>
</button>
<button
@click="deleteConfirmation = true"
class="btn bg-danger-subtle text-danger-emphasis border-danger-subtle rounded-3 btn-sm">
<i class="bi bi-trash-fill"></i>
</button>
</div>
</div>
<hr>
<textarea class="form-control rounded-3" :value="b.content"
disabled
style="height: 400px; font-family: var(--bs-font-monospace),sans-serif !important;"></textarea>
</div>
</div>
</template>
<style scoped>
.confirmationContainer{
background-color: rgba(0, 0, 0, 0.53);
z-index: 9999;
backdrop-filter: blur(1px);
-webkit-backdrop-filter: blur(1px);
}
.list1-enter-active{
transition-delay: v-bind(delaySeconds) !important;
}
</style>

View File

@@ -0,0 +1,122 @@
<script setup>
import {onBeforeUnmount, onMounted, reactive, ref} from "vue";
import {fetchGet} from "@/utilities/fetch.js";
import {useRoute} from "vue-router";
import dayjs from "dayjs";
import LocaleText from "@/components/text/localeText.vue";
import Backup from "@/components/configurationComponents/backupRestoreComponents/backup.vue";
const route = useRoute()
const backups = ref([])
const loading = ref(true)
const emit = defineEmits(["close", "refreshPeersList"])
onMounted(() => {
loadBackup();
})
const loadBackup = () => {
loading.value = true
fetchGet("/api/getWireguardConfigurationBackup", {
configurationName: route.params.id
}, (res) => {
backups.value = res.data;
loading.value = false;
})
}
const createBackup = () => {
fetchGet("/api/createWireguardConfigurationBackup", {
configurationName: route.params.id
}, (res) => {
backups.value = res.data;
loading.value = false;
})
}
</script>
<template>
<div class="peerSettingContainer w-100 h-100 position-absolute top-0 start-0 overflow-y-scroll" ref="editConfigurationContainer">
<div class="d-flex h-100 w-100">
<div class="modal-dialog-centered dashboardModal w-100 h-100 overflow-x-scroll flex-column gap-3 mx-3">
<div class="my-5 d-flex gap-3 flex-column position-relative">
<div class="title">
<div class="d-flex mb-3">
<h4 class="mb-0">
<LocaleText t="Backup & Restore"></LocaleText>
</h4>
<button type="button" class="btn-close ms-auto" @click="$emit('close')"></button>
</div>
<button
@click="createBackup()"
class="btn bg-primary-subtle text-primary-emphasis border-primary-subtle rounded-3 w-100">
<i class="bi bi-plus-circle-fill me-2"></i> Create Backup
</button>
</div>
<div class="position-relative d-flex flex-column gap-3">
<TransitionGroup name="list1" >
<div class="text-center title"
key="spinner"
v-if="loading && backups.length === 0">
<div class="spinner-border"></div>
</div>
<div class="card my-0 rounded-3"
v-else-if="!loading && backups.length === 0"
key="noBackups"
>
<div class="card-body text-center text-muted">
<i class="bi bi-x-circle-fill me-2"></i> No backup yet, click the button above to create backup.
</div>
</div>
<Backup
@refresh="loadBackup()"
@refreshPeersList="emit('refreshPeersList')"
:b="b" v-for="(b, index) in backups"
:delay="index*0.05"
:key="b.filename"
></Backup>
</TransitionGroup>
</div>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.card, .title{
width: 100%;
}
@media screen and (min-width: 700px) {
.card, .title{
width: 700px;
}
}
.animate__fadeInUp{
animation-timing-function: cubic-bezier(0.42, 0, 0.22, 1.0)
}
.list1-move, /* apply transition to moving elements */
.list1-enter-active,
.list1-leave-active {
transition: all 0.5s cubic-bezier(0.42, 0, 0.22, 1.0);
}
.list1-enter-from,
.list1-leave-to {
opacity: 0;
transform: translateY(30px);
}
/* ensure leaving items are taken out of layout flow so that moving
animations can be calculated correctly. */
.list1-leave-active {
width: 100%;
position: absolute;
}
</style>

View File

@@ -4,9 +4,6 @@ import {onMounted, reactive, ref, useTemplateRef, watch} from "vue";
import {WireguardConfigurationsStore} from "@/stores/WireguardConfigurationsStore.js";
import {fetchPost} from "@/utilities/fetch.js";
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
import router from "@/router/index.js";
import ConfigurationBackupRestore
from "@/components/configurationComponents/editConfigurationComponents/configurationBackupRestore.vue";
const props = defineProps({
configurationInfo: Object
})

View File

@@ -1,109 +0,0 @@
<script setup>
import {onBeforeUnmount, onMounted, reactive, ref} from "vue";
import {fetchGet} from "@/utilities/fetch.js";
import {useRoute} from "vue-router";
import dayjs from "dayjs";
import LocaleText from "@/components/text/localeText.vue";
const route = useRoute()
const backups = ref([])
const loading = ref(false)
const emit = defineEmits(["close"])
onMounted(() => {
loadBackup();
})
const loadBackup = () => {
loading.value = true
fetchGet("/api/getWireguardConfigurationBackup", {
configurationName: route.params.id
}, (res) => {
backups.value = res.data;
loading.value = false;
})
}
</script>
<template>
<div class="peerSettingContainer w-100 h-100 position-absolute top-0 start-0 overflow-y-scroll" ref="editConfigurationContainer">
<div class="d-flex h-100 w-100">
<div class="modal-dialog-centered dashboardModal w-100 h-100 overflow-x-scroll flex-column gap-3 mx-3">
<div class="my-5 d-flex gap-3 flex-column position-relative">
<div class="title">
<div class="d-flex mb-3">
<h4 class="mb-0">
<LocaleText t="Backup & Restore"></LocaleText>
</h4>
<button type="button" class="btn-close ms-auto" @click="$emit('close')"></button>
</div>
<button class="btn bg-primary-subtle text-primary-emphasis border-primary-subtle rounded-3 w-100">
<i class="bi bi-plus-circle-fill me-2"></i> Create Backup
</button>
</div>
<div class="position-relative d-flex gap-3 flex-column">
<div class="text-center" v-if="loading">
<div class="spinner-border"></div>
</div>
<div class="card animate__animated animate__fadeInUp animate__fast my-0 rounded-3"
v-else-if="!loading && backups.length === 0">
<div class="card-body text-center text-muted">
<i class="bi bi-x-circle-fill me-2"></i> No backup yet, click the button above to create backup.
</div>
</div>
<div class="card animate__animated animate__fadeInUp animate__fast my-0 rounded-3"
v-for="(b, index) in backups" :style="{'animation-delay': index*0.05 + 's'}">
<div class="card-body">
<div class="d-flex gap-3">
<div class="d-flex flex-column">
<small class="text-muted">
Filename
</small>
<samp>{{b.filename}}</samp>
</div>
<div class="d-flex flex-column">
<small class="text-muted">
Backup Date
</small>
{{dayjs(b.backupDate, "YYYYMMDDHHmmss").format("YYYY-MM-DD HH:mm:ss")}}
</div>
<div class="d-flex gap-2 align-items-center ms-auto">
<button class="btn bg-warning-subtle text-warning-emphasis border-warning-subtle rounded-3 btn-sm">
<i class="bi bi-clock-history"></i>
</button>
<button class="btn bg-danger-subtle text-danger-emphasis border-danger-subtle rounded-3 btn-sm">
<i class="bi bi-trash-fill"></i>
</button>
</div>
</div>
<hr>
<textarea class="form-control rounded-3" :value="b.content"
disabled
style="height: 400px; font-family: var(--bs-font-monospace),sans-serif !important;"></textarea>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.card, .title{
width: 100%;
}
@media screen and (min-width: 700px) {
.card, .title{
width: 700px;
}
}
.animate__fadeInUp{
animation-timing-function: cubic-bezier(0.42, 0, 0.22, 1.0)
}
</style>

View File

@@ -45,7 +45,7 @@ import LocaleText from "@/components/text/localeText.vue";
import EditConfiguration from "@/components/configurationComponents/editConfiguration.vue";
import SelectPeers from "@/components/configurationComponents/selectPeers.vue";
import ConfigurationBackupRestore
from "@/components/configurationComponents/editConfigurationComponents/configurationBackupRestore.vue";
from "@/components/configurationComponents/configurationBackupRestore.vue";
Chart.register(
ArcElement,
@@ -682,6 +682,7 @@ export default {
<Transition name="zoom">
<ConfigurationBackupRestore
@close="backupRestore.modalOpen = false"
@refreshPeersList="this.getPeers()"
v-if="backupRestore.modalOpen"></ConfigurationBackupRestore>
</Transition>