uptime-kuma/src/components/NotificationDialog.vue

353 lines
13 KiB
Vue
Raw Normal View History

2021-06-29 08:06:20 +00:00
<template>
2021-07-09 06:14:03 +00:00
<form @submit.prevent="submit">
2024-02-13 01:24:42 +00:00
<div ref="modal" class="modal fade" tabindex="-1" data-bs-backdrop="static">
2021-07-09 06:14:03 +00:00
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
2021-07-27 17:47:13 +00:00
<h5 id="exampleModalLabel" class="modal-title">
{{ $t("Setup Notification") }}
2021-07-27 17:47:13 +00:00
</h5>
2024-02-13 01:24:42 +00:00
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" />
2021-07-09 06:14:03 +00:00
</div>
<div class="modal-body">
2021-07-18 10:51:58 +00:00
<div class="mb-3">
2024-02-13 01:24:42 +00:00
<label for="notification-type" class="form-label">{{ $t("Notification Type") }}</label>
<select id="notification-type" v-model="notification.type" class="form-select">
<option v-for="(name, type) in notificationNameList.regularList" :key="type" :value="type">{{ name }}</option>
2023-02-23 10:01:42 +00:00
<optgroup :label="$t('notificationRegional')">
2024-02-13 01:24:42 +00:00
<option v-for="(name, type) in notificationNameList.regionalList" :key="type" :value="type">{{ name }}</option>
2023-02-23 10:01:42 +00:00
</optgroup>
2021-07-18 10:51:58 +00:00
</select>
</div>
<div class="mb-3">
2024-02-13 01:24:42 +00:00
<label for="notification-name" class="form-label">{{ $t("Friendly Name") }}</label>
<input id="notification-name" v-model="notification.name" type="text" class="form-control" required>
2021-07-18 10:51:58 +00:00
</div>
<!-- form body -->
<component :is="currentForm" />
<div class="mb-3 mt-4">
2024-02-13 01:24:42 +00:00
<hr class="dropdown-divider mb-4">
<div class="form-check form-switch">
2024-02-13 01:24:42 +00:00
<input v-model="notification.isDefault" class="form-check-input" type="checkbox">
<label class="form-check-label">{{ $t("Default enabled") }}</label>
</div>
<div class="form-text">
{{ $t("enableDefaultNotificationDescription") }}
</div>
2024-02-13 01:24:42 +00:00
<br>
<div class="form-check form-switch">
2024-02-13 01:24:42 +00:00
<input v-model="notification.applyExisting" class="form-check-input" type="checkbox">
<label class="form-check-label">{{ $t("Apply on all existing monitors") }}</label>
</div>
</div>
2021-07-09 06:14:03 +00:00
</div>
2021-07-09 06:14:03 +00:00
<div class="modal-footer">
2024-02-13 01:24:42 +00:00
<button v-if="id" type="button" class="btn btn-danger" :disabled="processing" @click="deleteConfirm">
{{ $t("Delete") }}
2021-07-27 17:47:13 +00:00
</button>
2024-02-13 01:24:42 +00:00
<button type="button" class="btn btn-warning" :disabled="processing" @click="test">
{{ $t("Test") }}
2021-07-27 17:47:13 +00:00
</button>
2024-02-13 01:24:42 +00:00
<button type="submit" class="btn btn-primary" :disabled="processing">
<div v-if="processing" class="spinner-border spinner-border-sm me-1"></div>
{{ $t("Save") }}
2021-07-27 17:47:13 +00:00
</button>
2021-07-09 06:14:03 +00:00
</div>
2021-06-29 08:06:20 +00:00
</div>
</div>
</div>
2021-07-09 06:14:03 +00:00
</form>
2024-02-13 01:24:42 +00:00
<Confirm ref="confirmDelete" btn-style="btn-danger" :yes-text="$t('Yes')" :no-text="$t('No')" @yes="deleteNotification">
2021-08-26 00:43:26 +00:00
{{ $t("deleteNotificationMsg") }}
2021-07-27 17:47:13 +00:00
</Confirm>
2021-06-29 08:06:20 +00:00
</template>
<script>
import { Modal } from "bootstrap";
2021-09-07 15:32:05 +00:00
import Confirm from "./Confirm.vue";
import NotificationFormList from "./notifications";
2021-06-29 08:06:20 +00:00
export default {
2021-07-27 17:47:13 +00:00
components: {
Confirm,
2021-06-29 08:06:20 +00:00
},
2021-07-27 17:47:13 +00:00
props: {},
2022-04-17 07:27:35 +00:00
emits: [ "added" ],
2021-06-29 08:06:20 +00:00
data() {
return {
model: null,
2021-07-09 06:14:03 +00:00
processing: false,
id: null,
notificationTypes: Object.keys(NotificationFormList).sort((a, b) => {
return a.toLowerCase().localeCompare(b.toLowerCase());
}),
2021-07-09 06:14:03 +00:00
notification: {
name: "",
2021-09-17 12:40:57 +00:00
/** @type { null | keyof NotificationFormList } */
2021-07-09 06:14:03 +00:00
type: null,
2021-09-07 23:03:24 +00:00
isDefault: false,
// Do not set default value here, please scroll to show()
2021-09-17 08:54:50 +00:00
}
};
2021-06-29 08:06:20 +00:00
},
2021-07-27 17:47:13 +00:00
computed: {
currentForm() {
if (!this.notification.type) {
return null;
}
return NotificationFormList[this.notification.type];
},
notificationNameList() {
2023-02-23 10:01:42 +00:00
let regularList = {
"alerta": "Alerta",
"AlertNow": "AlertNow",
"apprise": this.$t("apprise"),
"Bark": "Bark",
"Bitrix24": "Bitrix24",
"clicksendsms": "ClickSend SMS",
"CallMeBot": "CallMeBot (WhatsApp, Telegram Call, Facebook Messanger)",
"discord": "Discord",
"Elks": "46elks",
"GoogleChat": "Google Chat (Google Workspace)",
"gorush": "Gorush",
"gotify": "Gotify",
"GrafanaOncall": "Grafana Oncall",
2024-02-13 01:48:53 +00:00
"HeiiOnCall": "Heii On-Call",
"HomeAssistant": "Home Assistant",
"Keep": "Keep",
"Kook": "Kook",
"line": "LINE Messenger",
"LineNotify": "LINE Notify",
"lunasea": "LunaSea",
"matrix": "Matrix",
"mattermost": "Mattermost",
"nostr": "Nostr",
"ntfy": "Ntfy",
"octopush": "Octopush",
"OneBot": "OneBot",
"Onesender": "Onesender",
2023-03-21 18:29:37 +00:00
"Opsgenie": "Opsgenie",
"PagerDuty": "PagerDuty",
2023-05-11 06:54:00 +00:00
"PagerTree": "PagerTree",
"pushbullet": "Pushbullet",
"PushByTechulus": "Push by Techulus",
"pushover": "Pushover",
"pushy": "Pushy",
"rocket.chat": "Rocket.Chat",
"signal": "Signal",
"SIGNL4": "SIGNL4",
"slack": "Slack",
"squadcast": "SquadCast",
"SMSEagle": "SMSEagle",
"SMSPartner": "SMS Partner",
"smtp": this.$t("smtp"),
"stackfield": "Stackfield",
"teams": "Microsoft Teams",
"telegram": "Telegram",
"threema": "Threema",
2023-03-25 16:56:01 +00:00
"twilio": "Twilio",
"Splunk": "Splunk",
"webhook": "Webhook",
"GoAlert": "GoAlert",
"ZohoCliq": "ZohoCliq",
"SevenIO": "SevenIO",
"whapi": "WhatsApp (Whapi)",
"gtxmessaging": "GtxMessaging",
"Cellsynt": "Cellsynt",
"SendGrid": "SendGrid"
};
2023-02-23 10:01:42 +00:00
// Put notifications here if it's not supported in most regions or its documentation is not in English
let regionalList = {
"AliyunSMS": "AliyunSMS (阿里云短信服务)",
"DingDing": "DingDing (钉钉自定义机器人)",
"Feishu": "Feishu (飞书)",
"FlashDuty": "FlashDuty (快猫星云)",
2023-02-23 10:01:42 +00:00
"FreeMobile": "FreeMobile (mobile.free.fr)",
"PushDeer": "PushDeer",
"promosms": "PromoSMS",
"serwersms": "SerwerSMS.pl",
"SMSManager": "SmsManager (smsmanager.cz)",
"WeCom": "WeCom (企业微信群机器人)",
"ServerChan": "ServerChan (Server酱)",
"smsc": "SMSC",
"WPush": "WPush(wpush.cn)",
2023-02-23 10:01:42 +00:00
};
// Sort by notification name
// No idea how, but it works
// https://stackoverflow.com/questions/1069666/sorting-object-property-by-values
2023-02-23 10:01:42 +00:00
let sort = (list2) => {
return Object.entries(list2)
.sort(([ , a ], [ , b ]) => a.localeCompare(b))
.reduce((r, [ k, v ]) => ({
...r,
[k]: v
}), {});
};
return {
regularList: sort(regularList),
regionalList: sort(regionalList),
};
},
notificationFullNameList() {
let list = {};
for (let [ key, value ] of Object.entries(this.notificationNameList.regularList)) {
list[key] = value;
}
for (let [ key, value ] of Object.entries(this.notificationNameList.regionalList)) {
list[key] = value;
}
return list;
},
},
2021-07-27 17:47:13 +00:00
watch: {
"notification.type"(to, from) {
let oldName;
if (from) {
oldName = this.getUniqueDefaultName(from);
2021-07-27 17:47:13 +00:00
} else {
oldName = "";
}
if (! this.notification.name || this.notification.name === oldName) {
this.notification.name = this.getUniqueDefaultName(to);
2021-07-27 17:47:13 +00:00
}
},
},
2021-06-29 08:06:20 +00:00
mounted() {
this.modal = new Modal(this.$refs.modal);
2021-06-29 08:06:20 +00:00
},
methods: {
2021-07-09 06:14:03 +00:00
/**
* Show dialog to confirm deletion
* @returns {void}
*/
deleteConfirm() {
this.modal.hide();
this.$refs.confirmDelete.show();
},
/**
* Show settings for specified notification
* @param {number} notificationID ID of notification to show
* @returns {void}
*/
2021-07-09 06:14:03 +00:00
show(notificationID) {
if (notificationID) {
this.id = notificationID;
for (let n of this.$root.notificationList) {
if (n.id === notificationID) {
this.notification = JSON.parse(n.config);
break;
}
}
} else {
this.id = null;
this.notification = {
name: "",
type: "telegram",
2021-09-07 23:03:24 +00:00
isDefault: false,
};
2021-07-09 06:14:03 +00:00
}
this.modal.show();
2021-06-29 08:06:20 +00:00
},
2021-07-09 06:14:03 +00:00
/**
* Submit the form to the server
* @returns {void}
*/
2021-06-29 08:06:20 +00:00
submit() {
2021-07-09 06:14:03 +00:00
this.processing = true;
this.$root.getSocket().emit("addNotification", this.notification, this.id, (res) => {
this.$root.toastRes(res);
2021-07-09 06:14:03 +00:00
this.processing = false;
2021-06-29 08:06:20 +00:00
2021-07-09 06:14:03 +00:00
if (res.ok) {
this.modal.hide();
// Emit added event, doesn't emit edit.
if (! this.id) {
this.$emit("added", res.id);
}
2021-07-09 06:14:03 +00:00
}
});
2021-07-09 06:14:03 +00:00
},
/**
* Test the notification endpoint
* @returns {void}
*/
2021-07-09 06:14:03 +00:00
test() {
this.processing = true;
this.$root.getSocket().emit("testNotification", this.notification, (res) => {
this.$root.toastRes(res);
2021-07-09 06:14:03 +00:00
this.processing = false;
});
2021-07-09 06:14:03 +00:00
},
/**
* Delete the notification endpoint
* @returns {void}
*/
2021-07-09 06:14:03 +00:00
deleteNotification() {
this.processing = true;
this.$root.getSocket().emit("deleteNotification", this.id, (res) => {
this.$root.toastRes(res);
2021-07-09 06:14:03 +00:00
this.processing = false;
if (res.ok) {
this.modal.hide();
2021-07-09 06:14:03 +00:00
}
});
2021-07-09 06:14:03 +00:00
},
/**
* Get a unique default name for the notification
2021-09-22 08:13:23 +00:00
* @param {keyof NotificationFormList} notificationKey
* Notification to retrieve
* @returns {string} Default name
*/
getUniqueDefaultName(notificationKey) {
2023-02-21 20:29:43 +00:00
let index = 1;
let name = "";
do {
name = this.$t("defaultNotificationName", {
2023-02-23 10:01:42 +00:00
notification: this.notificationFullNameList[notificationKey].replace(/\(.+\)/, "").trim(),
number: index++
});
} while (this.$root.notificationList.find(it => it.name === name));
2023-02-21 20:29:43 +00:00
return name;
}
2021-07-09 06:14:03 +00:00
},
};
2021-06-29 08:06:20 +00:00
</script>
<style lang="scss" scoped>
@import "../assets/vars.scss";
.dark {
2024-02-13 01:24:42 +00:00
.modal-dialog .form-text, .modal-dialog p {
color: $dark-font-color;
}
}
</style>