feat: Added option to clone a existing maintenance (#6330)

This commit is contained in:
Teodor Moquist 2025-11-10 19:22:14 +01:00 committed by GitHub
parent 81544c8a39
commit 751ffd8e72
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 36 additions and 7 deletions

View File

@ -518,6 +518,12 @@
"Effective Date Range": "Effective Date Range (Optional)",
"Schedule Maintenance": "Schedule Maintenance",
"Edit Maintenance": "Edit Maintenance",
"Clone Maintenance": "Clone Maintenance",
"ariaPauseMaintenance": "Pause this maintenance schedule",
"ariaResumeMaintenance": "Resume this maintenance schedule",
"ariaCloneMaintenance": "Create a copy of this maintenance schedule",
"ariaEditMaintenance": "Edit this maintenance schedule",
"ariaDeleteMaintenance": "Delete this maintenance schedule",
"Date and Time": "Date and Time",
"DateTime Range": "DateTime Range",
"loadingError": "Cannot fetch the data, please try again later.",

View File

@ -354,7 +354,14 @@ export default {
},
pageName() {
return this.$t((this.isAdd) ? "Schedule Maintenance" : "Edit Maintenance");
let name = "Schedule Maintenance";
if (this.isEdit) {
name = "Edit Maintenance";
} else if (this.isClone) {
name = "Clone Maintenance";
}
return this.$t(name);
},
isAdd() {
@ -365,6 +372,9 @@ export default {
return this.$route.path.startsWith("/maintenance/edit");
},
isClone() {
return this.$route.path.startsWith("/maintenance/clone");
}
},
watch: {
"$route.fullPath"() {
@ -443,11 +453,16 @@ export default {
daysOfMonth: [],
timezoneOption: null,
};
} else if (this.isEdit) {
} else if (this.isEdit || this.isClone) {
this.$root.getSocket().emit("getMaintenance", this.$route.params.id, (res) => {
if (res.ok) {
this.maintenance = res.maintenance;
if (this.isClone) {
this.maintenance.id = undefined; // Remove id when cloning as we want a new id
this.maintenance.title = this.$t("cloneOf", [ this.maintenance.title ]);
}
this.$root.getSocket().emit("getMonitorMaintenance", this.$route.params.id, (res) => {
if (res.ok) {
Object.values(res.monitors).map(monitor => {
@ -491,7 +506,7 @@ export default {
return this.processing = false;
}
if (this.isAdd) {
if (this.isAdd || this.isClone) {
this.$root.addMaintenance(this.maintenance, async (res) => {
if (res.ok) {
await this.addMonitorMaintenance(res.maintenanceID, async () => {

View File

@ -41,19 +41,23 @@
<router-link v-if="false" :to="maintenanceURL(item.id)" class="btn btn-light">{{ $t("Details") }}</router-link>
<div class="btn-group" role="group">
<button v-if="item.active" class="btn btn-normal" @click="pauseDialog(item.id)">
<button v-if="item.active" class="btn btn-normal" :aria-label="$t('ariaPauseMaintenance')" @click="pauseDialog(item.id)">
<font-awesome-icon icon="pause" /> {{ $t("Pause") }}
</button>
<button v-if="!item.active" class="btn btn-primary" @click="resumeMaintenance(item.id)">
<button v-if="!item.active" class="btn btn-primary" :aria-label="$t('ariaResumeMaintenance')" @click="resumeMaintenance(item.id)">
<font-awesome-icon icon="play" /> {{ $t("Resume") }}
</button>
<router-link :to="'/maintenance/edit/' + item.id" class="btn btn-normal">
<router-link :to="'/maintenance/clone/' + item.id" class="btn btn-normal" :aria-label="$t('ariaCloneMaintenance')">
<font-awesome-icon icon="clone" /> {{ $t("Clone") }}
</router-link>
<router-link :to="'/maintenance/edit/' + item.id" class="btn btn-normal" :aria-label="$t('ariaEditMaintenance')">
<font-awesome-icon icon="edit" /> {{ $t("Edit") }}
</router-link>
<button class="btn btn-normal text-danger" @click="deleteDialog(item.id)">
<button class="btn btn-normal text-danger" :aria-label="$t('ariaDeleteMaintenance')" @click="deleteDialog(item.id)">
<font-awesome-icon icon="trash" /> {{ $t("Delete") }}
</button>
</div>

View File

@ -162,6 +162,10 @@ const routes = [
path: "/maintenance/edit/:id",
component: EditMaintenance,
},
{
path: "/maintenance/clone/:id",
component: EditMaintenance,
}
],
},
],