mirror of
				https://github.com/louislam/uptime-kuma.git
				synced 2025-11-04 13:46:13 +08:00 
			
		
		
		
	Merge branch 'louislam:master' into master
This commit is contained in:
		@@ -7,12 +7,12 @@ class Pushover extends NotificationProvider {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
 | 
					    async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
 | 
				
			||||||
        let okMsg = "Sent Successfully.";
 | 
					        let okMsg = "Sent Successfully.";
 | 
				
			||||||
        let pushoverlink = "https://api.pushover.net/1/messages.json"
 | 
					        let pushoverlink = "https://api.pushover.net/1/messages.json";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            if (heartbeatJSON == null) {
 | 
					            if (heartbeatJSON == null) {
 | 
				
			||||||
                let data = {
 | 
					                let data = {
 | 
				
			||||||
                    "message": "<b>Uptime Kuma Pushover testing successful.</b>",
 | 
					                    "message": msg,
 | 
				
			||||||
                    "user": notification.pushoveruserkey,
 | 
					                    "user": notification.pushoveruserkey,
 | 
				
			||||||
                    "token": notification.pushoverapptoken,
 | 
					                    "token": notification.pushoverapptoken,
 | 
				
			||||||
                    "sound": notification.pushoversounds,
 | 
					                    "sound": notification.pushoversounds,
 | 
				
			||||||
@@ -21,8 +21,8 @@ class Pushover extends NotificationProvider {
 | 
				
			|||||||
                    "retry": "30",
 | 
					                    "retry": "30",
 | 
				
			||||||
                    "expire": "3600",
 | 
					                    "expire": "3600",
 | 
				
			||||||
                    "html": 1,
 | 
					                    "html": 1,
 | 
				
			||||||
                }
 | 
					                };
 | 
				
			||||||
                await axios.post(pushoverlink, data)
 | 
					                await axios.post(pushoverlink, data);
 | 
				
			||||||
                return okMsg;
 | 
					                return okMsg;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -36,11 +36,11 @@ class Pushover extends NotificationProvider {
 | 
				
			|||||||
                "retry": "30",
 | 
					                "retry": "30",
 | 
				
			||||||
                "expire": "3600",
 | 
					                "expire": "3600",
 | 
				
			||||||
                "html": 1,
 | 
					                "html": 1,
 | 
				
			||||||
            }
 | 
					            };
 | 
				
			||||||
            await axios.post(pushoverlink, data)
 | 
					            await axios.post(pushoverlink, data);
 | 
				
			||||||
            return okMsg;
 | 
					            return okMsg;
 | 
				
			||||||
        } catch (error) {
 | 
					        } catch (error) {
 | 
				
			||||||
            this.throwGeneralAxiosError(error)
 | 
					            this.throwGeneralAxiosError(error);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										44
									
								
								server/notification-providers/serwersms.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								server/notification-providers/serwersms.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
				
			|||||||
 | 
					const NotificationProvider = require("./notification-provider");
 | 
				
			||||||
 | 
					const axios = require("axios");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SerwerSMS extends NotificationProvider {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    name = "serwersms";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
 | 
				
			||||||
 | 
					        let okMsg = "Sent Successfully.";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            let config = {
 | 
				
			||||||
 | 
					                headers: {
 | 
				
			||||||
 | 
					                    "Content-Type": "application/json",
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            let data = {
 | 
				
			||||||
 | 
					                "username": notification.serwersmsUsername,
 | 
				
			||||||
 | 
					                "password": notification.serwersmsPassword,
 | 
				
			||||||
 | 
					                "phone": notification.serwersmsPhoneNumber,
 | 
				
			||||||
 | 
					                "text": msg.replace(/[^\x00-\x7F]/g, ""),
 | 
				
			||||||
 | 
					                "sender": notification.serwersmsSenderName,
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            let resp = await axios.post("https://api2.serwersms.pl/messages/send_sms", data, config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!resp.data.success) {
 | 
				
			||||||
 | 
					                if (resp.data.error) {
 | 
				
			||||||
 | 
					                    let error = `SerwerSMS.pl API returned error code ${resp.data.error.code} (${resp.data.error.type}) with error message: ${resp.data.error.message}`;
 | 
				
			||||||
 | 
					                    this.throwGeneralAxiosError(error);
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    let error = "SerwerSMS.pl API returned an unexpected response";
 | 
				
			||||||
 | 
					                    this.throwGeneralAxiosError(error);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return okMsg;
 | 
				
			||||||
 | 
					        } catch (error) {
 | 
				
			||||||
 | 
					            this.throwGeneralAxiosError(error);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports = SerwerSMS;
 | 
				
			||||||
@@ -23,6 +23,7 @@ const Feishu = require("./notification-providers/feishu");
 | 
				
			|||||||
const AliyunSms = require("./notification-providers/aliyun-sms");
 | 
					const AliyunSms = require("./notification-providers/aliyun-sms");
 | 
				
			||||||
const DingDing = require("./notification-providers/dingding");
 | 
					const DingDing = require("./notification-providers/dingding");
 | 
				
			||||||
const Bark = require("./notification-providers/bark");
 | 
					const Bark = require("./notification-providers/bark");
 | 
				
			||||||
 | 
					const SerwerSMS = require("./notification-providers/serwersms");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Notification {
 | 
					class Notification {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -58,6 +59,7 @@ class Notification {
 | 
				
			|||||||
            new Telegram(),
 | 
					            new Telegram(),
 | 
				
			||||||
            new Webhook(),
 | 
					            new Webhook(),
 | 
				
			||||||
            new Bark(),
 | 
					            new Bark(),
 | 
				
			||||||
 | 
					            new SerwerSMS(),
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (let item of list) {
 | 
					        for (let item of list) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
        <label for="clicksendsms-login" class="form-label">API Username</label>
 | 
					        <label for="clicksendsms-login" class="form-label">API Username</label>
 | 
				
			||||||
        <div class="form-text">
 | 
					        <div class="form-text">
 | 
				
			||||||
            {{ $t("apiCredentials") }}
 | 
					            {{ $t("apiCredentials") }}
 | 
				
			||||||
            <a href="http://dashboard.clicksend.com/account/subaccounts" target="_blank">here</a>
 | 
					            <a href="http://dashboard.clicksend.com/account/subaccounts" target="_blank">{{ $t("here") }}</a>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <input id="clicksendsms-login" v-model="$parent.notification.clicksendsmsLogin" type="text" class="form-control" required>
 | 
					        <input id="clicksendsms-login" v-model="$parent.notification.clicksendsmsLogin" type="text" class="form-control" required>
 | 
				
			||||||
        <label for="clicksendsms-key" class="form-label">API Key</label>
 | 
					        <label for="clicksendsms-key" class="form-label">API Key</label>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,7 @@
 | 
				
			|||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <div class="mb-3">
 | 
					    <div class="mb-3">
 | 
				
			||||||
        <label for="secure" class="form-label">Secure</label>
 | 
					        <label for="secure" class="form-label">{{ $t("Security") }}</label>
 | 
				
			||||||
        <select id="secure" v-model="$parent.notification.smtpSecure" class="form-select">
 | 
					        <select id="secure" v-model="$parent.notification.smtpSecure" class="form-select">
 | 
				
			||||||
            <option :value="false">{{ $t("secureOptionNone") }}</option>
 | 
					            <option :value="false">{{ $t("secureOptionNone") }}</option>
 | 
				
			||||||
            <option :value="true">{{ $t("secureOptionTLS") }}</option>
 | 
					            <option :value="true">{{ $t("secureOptionTLS") }}</option>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										28
									
								
								src/components/notifications/SerwerSMS.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/components/notifications/SerwerSMS.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					    <div class="mb-3">
 | 
				
			||||||
 | 
					        <label for="serwersms-username" class="form-label">{{ $t('serwersmsAPIUser') }}</label>
 | 
				
			||||||
 | 
					        <input id="serwersms-username" v-model="$parent.notification.serwersmsUsername" type="text" class="form-control" required>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="mb-3">
 | 
				
			||||||
 | 
					        <label for="serwersms-key" class="form-label">{{ $t('serwersmsAPIPassword') }}</label>
 | 
				
			||||||
 | 
					        <HiddenInput id="serwersms-key" v-model="$parent.notification.serwersmsPassword" :required="true" autocomplete="one-time-code"></HiddenInput>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="mb-3">
 | 
				
			||||||
 | 
					        <label for="serwersms-phone-number" class="form-label">{{ $t("serwersmsPhoneNumber") }}</label>
 | 
				
			||||||
 | 
					        <input id="serwersms-phone-number" v-model="$parent.notification.serwersmsPhoneNumber" type="text" class="form-control" required>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="mb-3">
 | 
				
			||||||
 | 
					        <label for="serwersms-sender-name" class="form-label">{{ $t("serwersmsSenderName") }}</label>
 | 
				
			||||||
 | 
					        <input id="serwersms-sender-name" v-model="$parent.notification.serwersmsSenderName" type="text" minlength="3" maxlength="11" class="form-control">
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script>
 | 
				
			||||||
 | 
					import HiddenInput from "../HiddenInput.vue";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default {
 | 
				
			||||||
 | 
					    components: {
 | 
				
			||||||
 | 
					        HiddenInput,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
@@ -22,6 +22,7 @@ import Matrix from "./Matrix.vue";
 | 
				
			|||||||
import AliyunSMS from "./AliyunSms.vue";
 | 
					import AliyunSMS from "./AliyunSms.vue";
 | 
				
			||||||
import DingDing from "./DingDing.vue";
 | 
					import DingDing from "./DingDing.vue";
 | 
				
			||||||
import Bark from "./Bark.vue";
 | 
					import Bark from "./Bark.vue";
 | 
				
			||||||
 | 
					import SerwerSMS from "./SerwerSMS.vue";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Manage all notification form.
 | 
					 * Manage all notification form.
 | 
				
			||||||
@@ -52,7 +53,8 @@ const NotificationFormList = {
 | 
				
			|||||||
    "mattermost": Mattermost,
 | 
					    "mattermost": Mattermost,
 | 
				
			||||||
    "matrix": Matrix,
 | 
					    "matrix": Matrix,
 | 
				
			||||||
    "DingDing": DingDing,
 | 
					    "DingDing": DingDing,
 | 
				
			||||||
    "Bark": Bark
 | 
					    "Bark": Bark,
 | 
				
			||||||
 | 
					    "serwersms": SerwerSMS,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default NotificationFormList
 | 
					export default NotificationFormList
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@
 | 
				
			|||||||
            <label for="language" class="form-label">
 | 
					            <label for="language" class="form-label">
 | 
				
			||||||
                {{ $t("Language") }}
 | 
					                {{ $t("Language") }}
 | 
				
			||||||
            </label>
 | 
					            </label>
 | 
				
			||||||
            <select id="language" v-model="$i18n.locale" class="form-select">
 | 
					            <select id="language" v-model="$root.language" class="form-select">
 | 
				
			||||||
                <option
 | 
					                <option
 | 
				
			||||||
                    v-for="(lang, i) in $i18n.availableLocales"
 | 
					                    v-for="(lang, i) in $i18n.availableLocales"
 | 
				
			||||||
                    :key="`Lang${i}`"
 | 
					                    :key="`Lang${i}`"
 | 
				
			||||||
@@ -116,14 +116,8 @@
 | 
				
			|||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
import { setPageLocale } from "../../util-frontend";
 | 
					 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
    watch: {
 | 
					
 | 
				
			||||||
        "$i18n.locale"() {
 | 
					 | 
				
			||||||
            localStorage.locale = this.$i18n.locale;
 | 
					 | 
				
			||||||
            setPageLocale();
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -122,6 +122,7 @@
 | 
				
			|||||||
                <HiddenInput
 | 
					                <HiddenInput
 | 
				
			||||||
                    id="steamAPIKey"
 | 
					                    id="steamAPIKey"
 | 
				
			||||||
                    v-model="settings.steamAPIKey"
 | 
					                    v-model="settings.steamAPIKey"
 | 
				
			||||||
 | 
					                    autocomplete="one-time-code"
 | 
				
			||||||
                />
 | 
					                />
 | 
				
			||||||
                <div class="form-text">
 | 
					                <div class="form-text">
 | 
				
			||||||
                    {{ $t("steamApiKeyDescription") }}
 | 
					                    {{ $t("steamApiKeyDescription") }}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										91
									
								
								src/i18n.js
									
									
									
									
									
								
							
							
						
						
									
										91
									
								
								src/i18n.js
									
									
									
									
									
								
							@@ -1,62 +1,45 @@
 | 
				
			|||||||
import { createI18n } from "vue-i18n/index";
 | 
					import { createI18n } from "vue-i18n/index";
 | 
				
			||||||
import daDK from "./languages/da-DK";
 | 
					 | 
				
			||||||
import deDE from "./languages/de-DE";
 | 
					 | 
				
			||||||
import en from "./languages/en";
 | 
					import en from "./languages/en";
 | 
				
			||||||
import esEs from "./languages/es-ES";
 | 
					 | 
				
			||||||
import etEE from "./languages/et-EE";
 | 
					 | 
				
			||||||
import fa from "./languages/fa";
 | 
					 | 
				
			||||||
import frFR from "./languages/fr-FR";
 | 
					 | 
				
			||||||
import hu from "./languages/hu";
 | 
					 | 
				
			||||||
import hrHR from "./languages/hr-HR";
 | 
					 | 
				
			||||||
import itIT from "./languages/it-IT";
 | 
					 | 
				
			||||||
import idID from "./languages/id-ID";
 | 
					 | 
				
			||||||
import ja from "./languages/ja";
 | 
					 | 
				
			||||||
import koKR from "./languages/ko-KR";
 | 
					 | 
				
			||||||
import nlNL from "./languages/nl-NL";
 | 
					 | 
				
			||||||
import nbNO from "./languages/nb-NO";
 | 
					 | 
				
			||||||
import pl from "./languages/pl";
 | 
					 | 
				
			||||||
import ptBR from "./languages/pt-BR";
 | 
					 | 
				
			||||||
import bgBG from "./languages/bg-BG";
 | 
					 | 
				
			||||||
import ruRU from "./languages/ru-RU";
 | 
					 | 
				
			||||||
import sr from "./languages/sr";
 | 
					 | 
				
			||||||
import srLatn from "./languages/sr-latn";
 | 
					 | 
				
			||||||
import svSE from "./languages/sv-SE";
 | 
					 | 
				
			||||||
import trTR from "./languages/tr-TR";
 | 
					 | 
				
			||||||
import vi from "./languages/vi";
 | 
					 | 
				
			||||||
import zhCN from "./languages/zh-CN";
 | 
					 | 
				
			||||||
import zhHK from "./languages/zh-HK";
 | 
					 | 
				
			||||||
import zhTW from "./languages/zh-TW";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const languageList = {
 | 
					const languageList = {
 | 
				
			||||||
    en,
 | 
					    "zh-HK": "繁體中文 (香港)",
 | 
				
			||||||
    "zh-HK": zhHK,
 | 
					    "bg-BG": "Български",
 | 
				
			||||||
    "bg-BG": bgBG,
 | 
					    "de-DE": "Deutsch (Deutschland)",
 | 
				
			||||||
    "de-DE": deDE,
 | 
					    "nl-NL": "Nederlands",
 | 
				
			||||||
    "nl-NL": nlNL,
 | 
					    "nb-NO": "Norsk",
 | 
				
			||||||
    "nb-NO": nbNO,
 | 
					    "es-ES": "Español",
 | 
				
			||||||
    "es-ES": esEs,
 | 
					    "fa": "Farsi",
 | 
				
			||||||
    "fa": fa,
 | 
					    "pt-BR": "Português (Brasileiro)",
 | 
				
			||||||
    "pt-BR": ptBR,
 | 
					    "fr-FR": "Français (France)",
 | 
				
			||||||
    "fr-FR": frFR,
 | 
					    "hu": "Magyar",
 | 
				
			||||||
    "hu": hu,
 | 
					    "hr-HR": "Hrvatski",
 | 
				
			||||||
    "hr-HR": hrHR,
 | 
					    "it-IT": "Italiano (Italian)",
 | 
				
			||||||
    "it-IT": itIT,
 | 
					    "id-ID": "Bahasa Indonesia (Indonesian)",
 | 
				
			||||||
    "id-ID" : idID,
 | 
					    "ja": "日本語",
 | 
				
			||||||
    "ja": ja,
 | 
					    "da-DK": "Danish (Danmark)",
 | 
				
			||||||
    "da-DK": daDK,
 | 
					    "sr": "Српски",
 | 
				
			||||||
    "sr": sr,
 | 
					    "sr-latn": "Srpski",
 | 
				
			||||||
    "sr-latn": srLatn,
 | 
					    "sv-SE": "Svenska",
 | 
				
			||||||
    "sv-SE": svSE,
 | 
					    "tr-TR": "Türkçe",
 | 
				
			||||||
    "tr-TR": trTR,
 | 
					    "ko-KR": "한국어",
 | 
				
			||||||
    "ko-KR": koKR,
 | 
					    "ru-RU": "Русский",
 | 
				
			||||||
    "ru-RU": ruRU,
 | 
					    "zh-CN": "简体中文",
 | 
				
			||||||
    "zh-CN": zhCN,
 | 
					    "pl": "Polski",
 | 
				
			||||||
    "pl": pl,
 | 
					    "et-EE": "eesti",
 | 
				
			||||||
    "et-EE": etEE,
 | 
					    "vi": "Vietnamese",
 | 
				
			||||||
    "vi": vi,
 | 
					    "zh-TW": "繁體中文 (台灣)"
 | 
				
			||||||
    "zh-TW": zhTW
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let messages = {
 | 
				
			||||||
 | 
					    en,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for (let lang in languageList) {
 | 
				
			||||||
 | 
					    messages[lang] = {
 | 
				
			||||||
 | 
					        languageName: languageList[lang]
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const rtlLangs = ["fa"];
 | 
					const rtlLangs = ["fa"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const currentLocale = () => localStorage.locale
 | 
					export const currentLocale = () => localStorage.locale
 | 
				
			||||||
@@ -73,5 +56,5 @@ export const i18n = createI18n({
 | 
				
			|||||||
    fallbackLocale: "en",
 | 
					    fallbackLocale: "en",
 | 
				
			||||||
    silentFallbackWarn: true,
 | 
					    silentFallbackWarn: true,
 | 
				
			||||||
    silentTranslationWarn: true,
 | 
					    silentTranslationWarn: true,
 | 
				
			||||||
    messages: languageList,
 | 
					    messages: messages,
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,10 +5,7 @@
 | 
				
			|||||||
3. Run `npm run update-language-files`. You can also use this command to check if there are new strings to translate for your language.
 | 
					3. Run `npm run update-language-files`. You can also use this command to check if there are new strings to translate for your language.
 | 
				
			||||||
4. Your language file should be filled in. You can translate now.
 | 
					4. Your language file should be filled in. You can translate now.
 | 
				
			||||||
5. Translate `src/components/settings/Security.vue` (search for a `Confirm` component with `rel="confirmDisableAuth"`).
 | 
					5. Translate `src/components/settings/Security.vue` (search for a `Confirm` component with `rel="confirmDisableAuth"`).
 | 
				
			||||||
6. Import your language file in `src/i18n.js` and add it to `languageList` constant.
 | 
					6. Add it into `languageList` constant.
 | 
				
			||||||
7. Make a [pull request](https://github.com/louislam/uptime-kuma/pulls) when you have done.
 | 
					7. Make a [pull request](https://github.com/louislam/uptime-kuma/pulls) when you have done.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
One of good examples:
 | 
					 | 
				
			||||||
https://github.com/louislam/uptime-kuma/pull/316/files
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If you do not have programming skills, let me know in [Issues section](https://github.com/louislam/uptime-kuma/issues). I will assist you. 😏
 | 
					If you do not have programming skills, let me know in [Issues section](https://github.com/louislam/uptime-kuma/issues). I will assist you. 😏
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -89,7 +89,7 @@ export default {
 | 
				
			|||||||
    Timezone: "Часова зона",
 | 
					    Timezone: "Часова зона",
 | 
				
			||||||
    "Search Engine Visibility": "Видимост за търсачки",
 | 
					    "Search Engine Visibility": "Видимост за търсачки",
 | 
				
			||||||
    "Allow indexing": "Разреши индексиране",
 | 
					    "Allow indexing": "Разреши индексиране",
 | 
				
			||||||
    "Discourage search engines from indexing site": "Обезкуражи индексирането на сайта от търсачките",
 | 
					    "Discourage search engines from indexing site": "Не позволявай на търсачките да индексират този сайт",
 | 
				
			||||||
    "Change Password": "Промени парола",
 | 
					    "Change Password": "Промени парола",
 | 
				
			||||||
    "Current Password": "Текуща парола",
 | 
					    "Current Password": "Текуща парола",
 | 
				
			||||||
    "New Password": "Нова парола",
 | 
					    "New Password": "Нова парола",
 | 
				
			||||||
@@ -307,4 +307,5 @@ export default {
 | 
				
			|||||||
    PasswordsDoNotMatch: "Паролите не съвпадат.",
 | 
					    PasswordsDoNotMatch: "Паролите не съвпадат.",
 | 
				
			||||||
    "Current User": "Текущ потребител",
 | 
					    "Current User": "Текущ потребител",
 | 
				
			||||||
    recent: "Скорошни",
 | 
					    recent: "Скорошни",
 | 
				
			||||||
 | 
					    shrinkDatabaseDescription: "Инициира \"VACUUM\" за \"SQLite\" база данни. Ако Вашата база данни е създадена след версия 1.10.0, \"AUTO_VACUUM\" функцията е активна и това действие не нужно.",
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -307,5 +307,48 @@ export default {
 | 
				
			|||||||
    steamApiKeyDescription: "For monitoring a Steam Game Server you need a Steam Web-API key. You can register your API key here: ",
 | 
					    steamApiKeyDescription: "For monitoring a Steam Game Server you need a Steam Web-API key. You can register your API key here: ",
 | 
				
			||||||
    "Current User": "Current User",
 | 
					    "Current User": "Current User",
 | 
				
			||||||
    recent: "Recent",
 | 
					    recent: "Recent",
 | 
				
			||||||
 | 
					    Done: "Done",
 | 
				
			||||||
 | 
					    Info: "Info",
 | 
				
			||||||
 | 
					    Security: "Security",
 | 
				
			||||||
 | 
					    "Steam API Key": "Steam API Key",
 | 
				
			||||||
 | 
					    "Shrink Database": "Shrink Database",
 | 
				
			||||||
 | 
					    "Pick a RR-Type...": "Pick a RR-Type...",
 | 
				
			||||||
 | 
					    "Pick Accepted Status Codes...": "Pick Accepted Status Codes...",
 | 
				
			||||||
 | 
					    Default: "Default",
 | 
				
			||||||
 | 
					    "HTTP Options": "HTTP Options",
 | 
				
			||||||
 | 
					    "Create Incident": "Create Incident",
 | 
				
			||||||
 | 
					    Title: "Title",
 | 
				
			||||||
 | 
					    Content: "Content",
 | 
				
			||||||
 | 
					    Style: "Style",
 | 
				
			||||||
 | 
					    info: "info",
 | 
				
			||||||
 | 
					    warning: "warning",
 | 
				
			||||||
 | 
					    danger: "danger",
 | 
				
			||||||
 | 
					    primary: "primary",
 | 
				
			||||||
 | 
					    light: "light",
 | 
				
			||||||
 | 
					    dark: "dark",
 | 
				
			||||||
 | 
					    Post: "Post",
 | 
				
			||||||
 | 
					    "Please input title and content": "Please input title and content",
 | 
				
			||||||
 | 
					    Created: "Created",
 | 
				
			||||||
 | 
					    "Last Updated": "Last Updated",
 | 
				
			||||||
 | 
					    Unpin: "Unpin",
 | 
				
			||||||
 | 
					    "Switch to Light Theme": "Switch to Light Theme",
 | 
				
			||||||
 | 
					    "Switch to Dark Theme": "Switch to Dark Theme",
 | 
				
			||||||
 | 
					    "Show Tags": "Show Tags",
 | 
				
			||||||
 | 
					    "Hide Tags": "Hide Tags",
 | 
				
			||||||
 | 
					    Description: "Description",
 | 
				
			||||||
 | 
					    "No monitors available.": "No monitors available.",
 | 
				
			||||||
 | 
					    "Add one": "Add one",
 | 
				
			||||||
 | 
					    "No Monitors": "No Monitors",
 | 
				
			||||||
 | 
					    "Add one": "Add one",
 | 
				
			||||||
 | 
					    "Untitled Group": "Untitled Group",
 | 
				
			||||||
 | 
					    Services: "Services",
 | 
				
			||||||
 | 
					    Discard: "Discard",
 | 
				
			||||||
 | 
					    Cancel: "Cancel",
 | 
				
			||||||
 | 
					    "Powered by": "Powered by",
 | 
				
			||||||
    shrinkDatabaseDescription: "Trigger database VACUUM for SQLite. If your database is created after 1.10.0, AUTO_VACUUM is already enabled and this action is not needed.",
 | 
					    shrinkDatabaseDescription: "Trigger database VACUUM for SQLite. If your database is created after 1.10.0, AUTO_VACUUM is already enabled and this action is not needed.",
 | 
				
			||||||
 | 
					    serwersms: "SerwerSMS.pl",
 | 
				
			||||||
 | 
					    serwersmsAPIUser: "API Username (incl. webapi_ prefix)",
 | 
				
			||||||
 | 
					    serwersmsAPIPassword: "API Password",
 | 
				
			||||||
 | 
					    serwersmsPhoneNumber: "Phone number",
 | 
				
			||||||
 | 
					    serwersmsSenderName: "SMS Sender Name (registered via customer portal)",
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -308,4 +308,43 @@ export default {
 | 
				
			|||||||
    steamApiKeyDescription: "Za praćenje Steam poslužitelja za igru, potrebno je imati Steam Web-API ključ. Možete registrirati vlastiti ključ ovdje: ",
 | 
					    steamApiKeyDescription: "Za praćenje Steam poslužitelja za igru, potrebno je imati Steam Web-API ključ. Možete registrirati vlastiti ključ ovdje: ",
 | 
				
			||||||
    "Current User": "Trenutni korisnik",
 | 
					    "Current User": "Trenutni korisnik",
 | 
				
			||||||
    recent: "Nedavno",
 | 
					    recent: "Nedavno",
 | 
				
			||||||
 | 
					    Done: "Gotovo",
 | 
				
			||||||
 | 
					    Info: "Informacije",
 | 
				
			||||||
 | 
					    Security: "Sigurnost",
 | 
				
			||||||
 | 
					    "Shrink Database": "Smanji bazu podataka",
 | 
				
			||||||
 | 
					    "Pick a RR-Type...": "Odaberite vrstu DNS zapisa od navedenih...",
 | 
				
			||||||
 | 
					    "Pick Accepted Status Codes...": "Odaberite HTTP statusne kodove koji će biti prihvaćeni...",
 | 
				
			||||||
 | 
					    "Steam API Key": "Steam API ključ",
 | 
				
			||||||
 | 
					    Default: "Zadano",
 | 
				
			||||||
 | 
					    "HTTP Options": "HTTP Postavke",
 | 
				
			||||||
 | 
					    "Create Incident": "Novi izvještaj o incidentu",
 | 
				
			||||||
 | 
					    Title: "Naslov",
 | 
				
			||||||
 | 
					    Content: "Sadržaj",
 | 
				
			||||||
 | 
					    Style: "Stil",
 | 
				
			||||||
 | 
					    info: "informacija",
 | 
				
			||||||
 | 
					    warning: "upozorenje",
 | 
				
			||||||
 | 
					    danger: "opasnost",
 | 
				
			||||||
 | 
					    primary: "primarno",
 | 
				
			||||||
 | 
					    light: "svijetlo",
 | 
				
			||||||
 | 
					    dark: "tamno",
 | 
				
			||||||
 | 
					    Post: "Objavi",
 | 
				
			||||||
 | 
					    Created: "Stvoreno",
 | 
				
			||||||
 | 
					    "Last Updated": "Uređeno",
 | 
				
			||||||
 | 
					    "Please input title and content": "Naslov i sadržaj ne mogu biti prazni",
 | 
				
			||||||
 | 
					    Unpin: "Ukloni",
 | 
				
			||||||
 | 
					    "Switch to Light Theme": "Prebaci na svijetli način",
 | 
				
			||||||
 | 
					    "Switch to Dark Theme": "Prebaci na tamni način",
 | 
				
			||||||
 | 
					    "Show Tags": "Pokaži oznake",
 | 
				
			||||||
 | 
					    "Hide Tags": "Sakrij oznake",
 | 
				
			||||||
 | 
					    Description: "Opis",
 | 
				
			||||||
 | 
					    "No monitors available.": "Nema dostupnih monitora.",
 | 
				
			||||||
 | 
					    "Add one": "Add one",
 | 
				
			||||||
 | 
					    "No Monitors": "Bez monitora",
 | 
				
			||||||
 | 
					    "Add one": "Stvori jednog",
 | 
				
			||||||
 | 
					    "Untitled Group": "Bezimena grupa",
 | 
				
			||||||
 | 
					    Services: "Usluge",
 | 
				
			||||||
 | 
					    Discard: "Odbaci",
 | 
				
			||||||
 | 
					    Cancel: "Otkaži",
 | 
				
			||||||
 | 
					    "Powered by": "Pokreće",
 | 
				
			||||||
 | 
					    Saved: "Spremljeno",
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -307,4 +307,9 @@ export default {
 | 
				
			|||||||
    recent: "Ostatnie",
 | 
					    recent: "Ostatnie",
 | 
				
			||||||
    clicksendsms: "ClickSend SMS",
 | 
					    clicksendsms: "ClickSend SMS",
 | 
				
			||||||
    apiCredentials: "Poświadczenia API",
 | 
					    apiCredentials: "Poświadczenia API",
 | 
				
			||||||
 | 
					    serwersms: "SerwerSMS.pl",
 | 
				
			||||||
 | 
					    serwersmsAPIUser: "Nazwa użytkownika API (z prefiksem webapi_)",
 | 
				
			||||||
 | 
					    serwersmsAPIPassword: "Hasło API",
 | 
				
			||||||
 | 
					    serwersmsPhoneNumber: "Numer telefonu",
 | 
				
			||||||
 | 
					    serwersmsSenderName: "Nazwa nadawcy (zatwierdzona w panelu klienta)",
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,6 +12,7 @@ import mobile from "./mixins/mobile";
 | 
				
			|||||||
import publicMixin from "./mixins/public";
 | 
					import publicMixin from "./mixins/public";
 | 
				
			||||||
import socket from "./mixins/socket";
 | 
					import socket from "./mixins/socket";
 | 
				
			||||||
import theme from "./mixins/theme";
 | 
					import theme from "./mixins/theme";
 | 
				
			||||||
 | 
					import lang from "./mixins/lang";
 | 
				
			||||||
import { router } from "./router";
 | 
					import { router } from "./router";
 | 
				
			||||||
import { appName } from "./util.ts";
 | 
					import { appName } from "./util.ts";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -22,6 +23,7 @@ const app = createApp({
 | 
				
			|||||||
        mobile,
 | 
					        mobile,
 | 
				
			||||||
        datetime,
 | 
					        datetime,
 | 
				
			||||||
        publicMixin,
 | 
					        publicMixin,
 | 
				
			||||||
 | 
					        lang,
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    data() {
 | 
					    data() {
 | 
				
			||||||
        return {
 | 
					        return {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										33
									
								
								src/mixins/lang.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/mixins/lang.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
				
			|||||||
 | 
					import { currentLocale } from "../i18n";
 | 
				
			||||||
 | 
					import { setPageLocale } from "../util-frontend";
 | 
				
			||||||
 | 
					const langModules = import.meta.glob("../languages/*.js");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default {
 | 
				
			||||||
 | 
					    data() {
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					            language: currentLocale(),
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async created() {
 | 
				
			||||||
 | 
					        if (this.language !== "en") {
 | 
				
			||||||
 | 
					            await this.changeLang(this.language);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    watch: {
 | 
				
			||||||
 | 
					        async language(lang) {
 | 
				
			||||||
 | 
					            await this.changeLang(lang);
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    methods: {
 | 
				
			||||||
 | 
					        async changeLang(lang) {
 | 
				
			||||||
 | 
					            let message = (await langModules["../languages/" + lang + ".js"]()).default;
 | 
				
			||||||
 | 
					            this.$i18n.setLocaleMessage(lang, message);
 | 
				
			||||||
 | 
					            this.$i18n.locale = lang;
 | 
				
			||||||
 | 
					            localStorage.locale = lang;
 | 
				
			||||||
 | 
					            setPageLocale();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@@ -103,7 +103,7 @@
 | 
				
			|||||||
                                        :close-on-select="true"
 | 
					                                        :close-on-select="true"
 | 
				
			||||||
                                        :clear-on-select="false"
 | 
					                                        :clear-on-select="false"
 | 
				
			||||||
                                        :preserve-search="false"
 | 
					                                        :preserve-search="false"
 | 
				
			||||||
                                        placeholder="Pick a RR-Type..."
 | 
					                                        :placeholder="$t('Pick a RR-Type...')"
 | 
				
			||||||
                                        :preselect-first="false"
 | 
					                                        :preselect-first="false"
 | 
				
			||||||
                                        :max-height="500"
 | 
					                                        :max-height="500"
 | 
				
			||||||
                                        :taggable="false"
 | 
					                                        :taggable="false"
 | 
				
			||||||
@@ -177,7 +177,7 @@
 | 
				
			|||||||
                                        :close-on-select="false"
 | 
					                                        :close-on-select="false"
 | 
				
			||||||
                                        :clear-on-select="false"
 | 
					                                        :clear-on-select="false"
 | 
				
			||||||
                                        :preserve-search="true"
 | 
					                                        :preserve-search="true"
 | 
				
			||||||
                                        placeholder="Pick Accepted Status Codes..."
 | 
					                                        :placeholder="$t('Pick Accepted Status Codes...')"
 | 
				
			||||||
                                        :preselect-first="false"
 | 
					                                        :preselect-first="false"
 | 
				
			||||||
                                        :max-height="600"
 | 
					                                        :max-height="600"
 | 
				
			||||||
                                        :taggable="true"
 | 
					                                        :taggable="true"
 | 
				
			||||||
@@ -215,7 +215,7 @@
 | 
				
			|||||||
                                    <a href="#" @click="$refs.notificationDialog.show(notification.id)">{{ $t("Edit") }}</a>
 | 
					                                    <a href="#" @click="$refs.notificationDialog.show(notification.id)">{{ $t("Edit") }}</a>
 | 
				
			||||||
                                </label>
 | 
					                                </label>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                                <span v-if="notification.isDefault == true" class="badge bg-primary ms-2">Default</span>
 | 
					                                <span v-if="notification.isDefault == true" class="badge bg-primary ms-2">{{ $t("Default") }}</span>
 | 
				
			||||||
                            </div>
 | 
					                            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            <button class="btn btn-primary me-2" type="button" @click="$refs.notificationDialog.show()">
 | 
					                            <button class="btn btn-primary me-2" type="button" @click="$refs.notificationDialog.show()">
 | 
				
			||||||
@@ -353,17 +353,17 @@ export default {
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        bodyPlaceholder() {
 | 
					        bodyPlaceholder() {
 | 
				
			||||||
            return `Example:
 | 
					            return this.$t("Example:", [`
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    "key": "value"
 | 
					    "key": "value"
 | 
				
			||||||
}`;
 | 
					}`]);
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        headersPlaceholder() {
 | 
					        headersPlaceholder() {
 | 
				
			||||||
            return `Example:
 | 
					            return this.$t("Example:", [`
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    "HeaderName": "HeaderValue"
 | 
					    "HeaderName": "HeaderValue"
 | 
				
			||||||
}`;
 | 
					}`]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,8 +44,20 @@ export default {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            settings: {},
 | 
					            settings: {},
 | 
				
			||||||
            settingsLoaded: false,
 | 
					            settingsLoaded: false,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            subMenus: {
 | 
					    computed: {
 | 
				
			||||||
 | 
					        currentPage() {
 | 
				
			||||||
 | 
					            let pathEnd = useRoute().path.split("/").at(-1);
 | 
				
			||||||
 | 
					            if (pathEnd == "settings" || pathEnd == null) {
 | 
				
			||||||
 | 
					                return "general";
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return pathEnd;
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        subMenus() {
 | 
				
			||||||
 | 
					            return {
 | 
				
			||||||
                general: {
 | 
					                general: {
 | 
				
			||||||
                    title: this.$t("General"),
 | 
					                    title: this.$t("General"),
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
@@ -67,18 +79,8 @@ export default {
 | 
				
			|||||||
                about: {
 | 
					                about: {
 | 
				
			||||||
                    title: this.$t("About"),
 | 
					                    title: this.$t("About"),
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					 | 
				
			||||||
    computed: {
 | 
					 | 
				
			||||||
        currentPage() {
 | 
					 | 
				
			||||||
            let pathEnd = useRoute().path.split("/").at(-1);
 | 
					 | 
				
			||||||
            if (pathEnd == "settings" || pathEnd == null) {
 | 
					 | 
				
			||||||
                return "general";
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            return pathEnd;
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mounted() {
 | 
					    mounted() {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -101,9 +101,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            <!-- Incident Date -->
 | 
					            <!-- Incident Date -->
 | 
				
			||||||
            <div class="date mt-3">
 | 
					            <div class="date mt-3">
 | 
				
			||||||
                Created: {{ $root.datetime(incident.createdDate) }} ({{ dateFromNow(incident.createdDate) }})<br />
 | 
					                {{ $t("Created") }}: {{ $root.datetime(incident.createdDate) }} ({{ dateFromNow(incident.createdDate) }})<br />
 | 
				
			||||||
                <span v-if="incident.lastUpdatedDate">
 | 
					                <span v-if="incident.lastUpdatedDate">
 | 
				
			||||||
                    Last Updated: {{ $root.datetime(incident.lastUpdatedDate) }} ({{ dateFromNow(incident.lastUpdatedDate) }})
 | 
					                    {{ $t("Last Updated") }}: {{ $root.datetime(incident.lastUpdatedDate) }} ({{ dateFromNow(incident.lastUpdatedDate) }})
 | 
				
			||||||
                </span>
 | 
					                </span>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -125,15 +125,15 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                <div v-if="editIncidentMode" class="dropdown d-inline-block me-2">
 | 
					                <div v-if="editIncidentMode" class="dropdown d-inline-block me-2">
 | 
				
			||||||
                    <button id="dropdownMenuButton1" class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
 | 
					                    <button id="dropdownMenuButton1" class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
 | 
				
			||||||
                        Style: {{ incident.style }}
 | 
					                        {{ $t("Style") }}: {{ $t(incident.style) }}
 | 
				
			||||||
                    </button>
 | 
					                    </button>
 | 
				
			||||||
                    <ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
 | 
					                    <ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
 | 
				
			||||||
                        <li><a class="dropdown-item" href="#" @click="incident.style = 'info'">info</a></li>
 | 
					                        <li><a class="dropdown-item" href="#" @click="incident.style = 'info'">{{ $t("info") }}</a></li>
 | 
				
			||||||
                        <li><a class="dropdown-item" href="#" @click="incident.style = 'warning'">warning</a></li>
 | 
					                        <li><a class="dropdown-item" href="#" @click="incident.style = 'warning'">{{ $t("warning") }}</a></li>
 | 
				
			||||||
                        <li><a class="dropdown-item" href="#" @click="incident.style = 'danger'">danger</a></li>
 | 
					                        <li><a class="dropdown-item" href="#" @click="incident.style = 'danger'">{{ $t("danger") }}</a></li>
 | 
				
			||||||
                        <li><a class="dropdown-item" href="#" @click="incident.style = 'primary'">primary</a></li>
 | 
					                        <li><a class="dropdown-item" href="#" @click="incident.style = 'primary'">{{ $t("primary") }}</a></li>
 | 
				
			||||||
                        <li><a class="dropdown-item" href="#" @click="incident.style = 'light'">light</a></li>
 | 
					                        <li><a class="dropdown-item" href="#" @click="incident.style = 'light'">{{ $t("light") }}</a></li>
 | 
				
			||||||
                        <li><a class="dropdown-item" href="#" @click="incident.style = 'dark'">dark</a></li>
 | 
					                        <li><a class="dropdown-item" href="#" @click="incident.style = 'dark'">{{ $t("dark") }}</a></li>
 | 
				
			||||||
                    </ul>
 | 
					                    </ul>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -468,10 +468,10 @@ export default {
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        addGroup() {
 | 
					        addGroup() {
 | 
				
			||||||
            let groupName = "Untitled Group";
 | 
					            let groupName = this.$t("Untitled Group");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (this.$root.publicGroupList.length === 0) {
 | 
					            if (this.$root.publicGroupList.length === 0) {
 | 
				
			||||||
                groupName = "Services";
 | 
					                groupName = this.$t("Services");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            this.$root.publicGroupList.unshift({
 | 
					            this.$root.publicGroupList.unshift({
 | 
				
			||||||
@@ -536,7 +536,7 @@ export default {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        postIncident() {
 | 
					        postIncident() {
 | 
				
			||||||
            if (this.incident.title == "" || this.incident.content == "") {
 | 
					            if (this.incident.title == "" || this.incident.content == "") {
 | 
				
			||||||
                toast.error("Please input title and content.");
 | 
					                toast.error(this.$t("Please input title and content"));
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -83,6 +83,7 @@ describe("Init", () => {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Settings Page
 | 
					    // Settings Page
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
    describe("Settings", () => {
 | 
					    describe("Settings", () => {
 | 
				
			||||||
        beforeEach(async () => {
 | 
					        beforeEach(async () => {
 | 
				
			||||||
            await page.goto(baseURL + "/settings");
 | 
					            await page.goto(baseURL + "/settings");
 | 
				
			||||||
@@ -261,6 +262,7 @@ describe("Init", () => {
 | 
				
			|||||||
        //     }, { timeout: 3000 });
 | 
					        //     }, { timeout: 3000 });
 | 
				
			||||||
        // });
 | 
					        // });
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /*
 | 
					    /*
 | 
				
			||||||
     * TODO
 | 
					     * TODO
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user