mirror of
https://github.com/louislam/uptime-kuma.git
synced 2024-11-28 01:04:05 +00:00
Merge branch 'louislam:master' into master
This commit is contained in:
commit
4bc84d2122
21 changed files with 286 additions and 108 deletions
|
@ -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,17 +79,7 @@ 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;
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue