uptime-kuma/src/components/NotificationDialog.vue

416 lines
14 KiB
Vue
Raw Normal View History

2021-06-29 16:06:20 +08:00
<template>
2021-07-09 14:14:03 +08:00
<form @submit.prevent="submit">
2024-02-12 15:58:54 -08:00
<div
ref="modal"
class="modal fade"
tabindex="-1"
data-bs-backdrop="static"
>
2021-07-09 14:14:03 +08:00
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
2021-07-27 19:47:13 +02:00
<h5 id="exampleModalLabel" class="modal-title">
{{ $t("Setup Notification") }}
2021-07-27 19:47:13 +02:00
</h5>
2024-02-12 15:58:54 -08:00
<button
type="button"
class="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
/>
2021-07-09 14:14:03 +08:00
</div>
<div class="modal-body">
2021-07-18 18:51:58 +08:00
<div class="mb-3">
2024-02-12 15:58:54 -08: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 18:01:42 +08:00
<optgroup :label="$t('notificationRegional')">
2024-02-12 15:58:54 -08:00
<option
v-for="(
name, type
) in notificationNameList.regionalList"
:key="type"
:value="type"
>
{{ name }}
</option>
2023-02-23 18:01:42 +08:00
</optgroup>
2021-07-18 18:51:58 +08:00
</select>
</div>
<div class="mb-3">
2024-02-12 15:58:54 -08: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 18:51:58 +08:00
</div>
<!-- form body -->
<component :is="currentForm" />
<div class="mb-3 mt-4">
2024-02-12 15:58:54 -08:00
<hr class="dropdown-divider mb-4" />
<div class="form-check form-switch">
2024-02-12 15:58:54 -08: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-12 15:58:54 -08:00
<br />
<div class="form-check form-switch">
2024-02-12 15:58:54 -08: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 14:14:03 +08:00
</div>
2021-07-09 14:14:03 +08:00
<div class="modal-footer">
2024-02-12 15:58:54 -08:00
<button
v-if="id"
type="button"
class="btn btn-danger"
:disabled="processing"
@click="deleteConfirm"
>
{{ $t("Delete") }}
2021-07-27 19:47:13 +02:00
</button>
2024-02-12 15:58:54 -08:00
<button
type="button"
class="btn btn-warning"
:disabled="processing"
@click="test"
>
{{ $t("Test") }}
2021-07-27 19:47:13 +02:00
</button>
2024-02-12 15:58:54 -08: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 19:47:13 +02:00
</button>
2021-07-09 14:14:03 +08:00
</div>
2021-06-29 16:06:20 +08:00
</div>
</div>
</div>
2021-07-09 14:14:03 +08:00
</form>
2024-02-12 15:58:54 -08:00
<Confirm
ref="confirmDelete"
btn-style="btn-danger"
:yes-text="$t('Yes')"
:no-text="$t('No')"
@yes="deleteNotification"
>
2021-08-26 02:43:26 +02:00
{{ $t("deleteNotificationMsg") }}
2021-07-27 19:47:13 +02:00
</Confirm>
2021-06-29 16:06:20 +08:00
</template>
<script>
import { Modal } from "bootstrap";
2021-09-07 23:32:05 +08:00
import Confirm from "./Confirm.vue";
import NotificationFormList from "./notifications";
2021-06-29 16:06:20 +08:00
export default {
2021-07-27 19:47:13 +02:00
components: {
Confirm,
2021-06-29 16:06:20 +08:00
},
2021-07-27 19:47:13 +02:00
props: {},
2022-04-17 15:27:35 +08:00
emits: [ "added" ],
2021-06-29 16:06:20 +08:00
data() {
return {
model: null,
2021-07-09 14:14:03 +08:00
processing: false,
id: null,
notificationTypes: Object.keys(NotificationFormList).sort((a, b) => {
return a.toLowerCase().localeCompare(b.toLowerCase());
}),
2021-07-09 14:14:03 +08:00
notification: {
name: "",
2021-09-17 20:40:57 +08:00
/** @type { null | keyof NotificationFormList } */
2021-07-09 14:14:03 +08:00
type: null,
2021-09-08 01:03:24 +02:00
isDefault: false,
// Do not set default value here, please scroll to show()
2021-09-17 16:54:50 +08:00
}
};
2021-06-29 16:06:20 +08:00
},
2021-07-27 19:47:13 +02:00
computed: {
currentForm() {
if (!this.notification.type) {
return null;
}
return NotificationFormList[this.notification.type];
},
notificationNameList() {
2023-02-23 18:01:42 +08:00
let regularList = {
"alerta": "Alerta",
"AlertNow": "AlertNow",
"apprise": this.$t("apprise"),
"Bark": "Bark",
"clicksendsms": "ClickSend SMS",
"discord": "Discord",
"GoogleChat": "Google Chat (Google Workspace)",
"gorush": "Gorush",
"gotify": "Gotify",
"GrafanaOncall": "Grafana Oncall",
"HomeAssistant": "Home Assistant",
2024-02-12 15:58:54 -08:00
"HeiiOnCall": "Heii On-Call",
"Kook": "Kook",
"line": "LINE Messenger",
"LineNotify": "LINE Notify",
"lunasea": "LunaSea",
"matrix": "Matrix",
"mattermost": "Mattermost",
"nostr": "Nostr",
"ntfy": "Ntfy",
"octopush": "Octopush",
"OneBot": "OneBot",
2023-03-21 19:29:37 +01:00
"Opsgenie": "Opsgenie",
"PagerDuty": "PagerDuty",
2023-05-11 14:54:00 +08:00
"PagerTree": "PagerTree",
"pushbullet": "Pushbullet",
"PushByTechulus": "Push by Techulus",
"pushover": "Pushover",
"pushy": "Pushy",
"rocket.chat": "Rocket.Chat",
"signal": "Signal",
"slack": "Slack",
"squadcast": "SquadCast",
"SMSEagle": "SMSEagle",
"smtp": this.$t("smtp"),
"stackfield": "Stackfield",
"teams": "Microsoft Teams",
"telegram": "Telegram",
2023-03-25 19:56:01 +03:00
"twilio": "Twilio",
"Splunk": "Splunk",
"webhook": "Webhook",
"GoAlert": "GoAlert",
"ZohoCliq": "ZohoCliq"
};
2023-02-23 18:01:42 +08: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 18:01:42 +08:00
"FreeMobile": "FreeMobile (mobile.free.fr)",
"PushDeer": "PushDeer",
"promosms": "PromoSMS",
"serwersms": "SerwerSMS.pl",
"SMSManager": "SmsManager (smsmanager.cz)",
"WeCom": "WeCom (企业微信群机器人)",
"ServerChan": "ServerChan (Server酱)",
"smsc": "SMSC",
2023-02-23 18:01:42 +08:00
};
// Sort by notification name
// No idea how, but it works
// https://stackoverflow.com/questions/1069666/sorting-object-property-by-values
2023-02-23 18:01:42 +08: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 19:47:13 +02:00
watch: {
"notification.type"(to, from) {
let oldName;
if (from) {
oldName = this.getUniqueDefaultName(from);
2021-07-27 19:47:13 +02:00
} else {
oldName = "";
}
if (! this.notification.name || this.notification.name === oldName) {
this.notification.name = this.getUniqueDefaultName(to);
2021-07-27 19:47:13 +02:00
}
},
},
2021-06-29 16:06:20 +08:00
mounted() {
this.modal = new Modal(this.$refs.modal);
2021-06-29 16:06:20 +08:00
},
methods: {
2021-07-09 14:14:03 +08: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 14:14:03 +08: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-08 01:03:24 +02:00
isDefault: false,
};
2021-07-09 14:14:03 +08:00
}
this.modal.show();
2021-06-29 16:06:20 +08:00
},
2021-07-09 14:14:03 +08:00
/**
* Submit the form to the server
* @returns {void}
*/
2021-06-29 16:06:20 +08:00
submit() {
2021-07-09 14:14:03 +08:00
this.processing = true;
this.$root.getSocket().emit("addNotification", this.notification, this.id, (res) => {
this.$root.toastRes(res);
2021-07-09 14:14:03 +08:00
this.processing = false;
2021-06-29 16:06:20 +08:00
2021-07-09 14:14:03 +08: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 14:14:03 +08:00
}
});
2021-07-09 14:14:03 +08:00
},
/**
* Test the notification endpoint
* @returns {void}
*/
2021-07-09 14:14:03 +08:00
test() {
this.processing = true;
this.$root.getSocket().emit("testNotification", this.notification, (res) => {
this.$root.toastRes(res);
2021-07-09 14:14:03 +08:00
this.processing = false;
});
2021-07-09 14:14:03 +08:00
},
/**
* Delete the notification endpoint
* @returns {void}
*/
2021-07-09 14:14:03 +08:00
deleteNotification() {
this.processing = true;
this.$root.getSocket().emit("deleteNotification", this.id, (res) => {
this.$root.toastRes(res);
2021-07-09 14:14:03 +08:00
this.processing = false;
if (res.ok) {
this.modal.hide();
2021-07-09 14:14:03 +08:00
}
});
2021-07-09 14:14:03 +08:00
},
/**
* Get a unique default name for the notification
2021-09-22 16:13:23 +08:00
* @param {keyof NotificationFormList} notificationKey
* Notification to retrieve
* @returns {string} Default name
*/
getUniqueDefaultName(notificationKey) {
2023-02-22 04:29:43 +08:00
let index = 1;
let name = "";
do {
name = this.$t("defaultNotificationName", {
2023-02-23 18:01:42 +08:00
notification: this.notificationFullNameList[notificationKey].replace(/\(.+\)/, "").trim(),
number: index++
});
} while (this.$root.notificationList.find(it => it.name === name));
2023-02-22 04:29:43 +08:00
return name;
}
2021-07-09 14:14:03 +08:00
},
};
2021-06-29 16:06:20 +08:00
</script>
<style lang="scss" scoped>
@import "../assets/vars.scss";
.dark {
2024-02-12 15:58:54 -08:00
.modal-dialog .form-text,
.modal-dialog p {
color: $dark-font-color;
}
}
</style>