diff --git a/src/lang/en.json b/src/lang/en.json
index 09a99998d..7463c89d1 100644
--- a/src/lang/en.json
+++ b/src/lang/en.json
@@ -646,7 +646,8 @@
"recurringIntervalMessage": "Run once every day | Run once every {0} days",
"affectedMonitorsDescription": "Select monitors that are affected by current maintenance",
"affectedStatusPages": "Show this maintenance message on selected status pages",
- "atLeastOneMonitor": "Select at least one affected monitor",
+ "noMonitorsSelectedWarning": "You are creating a maintenance without any affected monitors. Are you sure you want to continue?",
+ "noMonitorsOrStatusPagesSelectedError": "Cannot create maintenance without affected monitors or status pages",
"passwordNotMatchMsg": "The repeat password does not match.",
"notificationDescription": "Notifications must be assigned to a monitor to function.",
"keywordDescription": "Search keyword in plain HTML or JSON response. The search is case-sensitive.",
diff --git a/src/pages/EditMaintenance.vue b/src/pages/EditMaintenance.vue
index 3833aeb49..928199f38 100644
--- a/src/pages/EditMaintenance.vue
+++ b/src/pages/EditMaintenance.vue
@@ -341,6 +341,10 @@
+
+
+ {{ $t("noMonitorsSelectedWarning") }}
+
@@ -350,11 +354,13 @@ import VueMultiselect from "vue-multiselect";
import Datepicker from "@vuepic/vue-datepicker";
import { timezoneList } from "../util-frontend";
import cronstrue from "cronstrue/i18n";
+import Confirm from "../components/Confirm.vue";
export default {
components: {
VueMultiselect,
Datepicker,
+ Confirm,
},
data() {
@@ -489,6 +495,22 @@ export default {
isClone() {
return this.$route.path.startsWith("/maintenance/clone");
},
+
+ /**
+ * Check if maintenance has monitors
+ * @returns {boolean} True if maintenance has monitors
+ */
+ hasMonitors() {
+ return this.affectedMonitors.length > 0;
+ },
+
+ /**
+ * Check if maintenance status pages assigned
+ * @returns {boolean} True if maintenance status pages
+ */
+ hasStatusPages() {
+ return this.showOnAllPages || this.selectedStatusPages.length > 0;
+ },
},
watch: {
"$route.fullPath"() {
@@ -633,16 +655,30 @@ export default {
}
},
+ /**
+ * Handle form submission - show confirmation if no monitors selected
+ * @returns {void}
+ */
+ submit() {
+ // While unusual, not requiring montiors can allow showing on status pages if a "currently unmonitored" service goes down
+ if (!this.hasMonitors && this.hasStatusPages) {
+ this.$refs.confirmNoMonitors.show();
+ return;
+ }
+ this.doSubmit();
+ },
+
/**
* Create new maintenance
* @returns {Promise}
*/
- async submit() {
+ async doSubmit() {
this.processing = true;
- if (this.affectedMonitors.length === 0) {
- this.$root.toastError(this.$t("atLeastOneMonitor"));
- return (this.processing = false);
+ if (!this.hasMonitors && !this.hasStatusPages) {
+ this.$root.toastError(this.$t("noMonitorsOrStatusPagesSelectedError"));
+ this.processing = false;
+ return;
}
if (this.isAdd || this.isClone) {