Compare commits

..

45 Commits

Author SHA1 Message Date
Louis Lam
4ae437dd61 Update to 1.21.1 2023-03-27 20:09:24 +08:00
Louis Lam
6cb296b07a Update SQLite and Vue 2023-03-27 19:05:18 +08:00
Louis Lam
644c6a872f Merge pull request #2978 from UptimeKumaBot/weblate-uptime-kuma-uptime-kuma
Translations Update from Weblate
2023-03-27 17:54:50 +08:00
Weblate
8c69c18f6d Merge remote-tracking branch 'origin/master' 2023-03-27 08:38:00 +00:00
Mirinek
c1a1160767 Translated using Weblate (Czech)
Currently translated at 100.0% (709 of 709 strings)

Co-authored-by: Mirinek <mirek.nozicka77@gmail.com>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/cs/
Translation: Uptime Kuma/Uptime Kuma
2023-03-27 08:37:51 +00:00
Louis Lam
a0ebd88849 Translated using Weblate (Chinese (Traditional, Hong Kong))
Currently translated at 96.0% (681 of 709 strings)

Co-authored-by: Louis Lam <louislam@users.noreply.github.com>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/zh_Hant_HK/
Translation: Uptime Kuma/Uptime Kuma
2023-03-27 08:37:51 +00:00
401Unauthorized
2e9413cf33 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (709 of 709 strings)

Co-authored-by: 401Unauthorized <hi@4o1.to>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/zh_Hans/
Translation: Uptime Kuma/Uptime Kuma
2023-03-27 08:37:51 +00:00
Taha İPEK
278b52ec34 Translated using Weblate (Turkish)
Currently translated at 100.0% (709 of 709 strings)

Co-authored-by: Taha İPEK <ti.tahaipek@gmail.com>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/tr/
Translation: Uptime Kuma/Uptime Kuma
2023-03-27 08:37:51 +00:00
Alex
caa757a27c Translated using Weblate (Russian)
Currently translated at 99.8% (708 of 709 strings)

Co-authored-by: Alex <proactivecam@inbox.ru>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/ru/
Translation: Uptime Kuma/Uptime Kuma
2023-03-27 08:37:51 +00:00
Cyril59310
3ce117a943 Translated using Weblate (French)
Currently translated at 100.0% (709 of 709 strings)

Co-authored-by: Cyril59310 <archas.cyril@hotmail.fr>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/fr/
Translation: Uptime Kuma/Uptime Kuma
2023-03-27 08:37:51 +00:00
Peter Petrík
cefe484b47 Translated using Weblate (Slovak)
Currently translated at 27.2% (193 of 708 strings)

Co-authored-by: Peter Petrík <peter.petrik.fefe@gmail.com>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/sk/
Translation: Uptime Kuma/Uptime Kuma
2023-03-27 08:37:51 +00:00
ilya12077
a700892709 Translated using Weblate (Russian)
Currently translated at 100.0% (708 of 708 strings)

Co-authored-by: ilya12077 <mr.ilya.1207@gmail.com>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/ru/
Translation: Uptime Kuma/Uptime Kuma
2023-03-27 08:37:50 +00:00
Alex
13d721ccf8 Translated using Weblate (Russian)
Currently translated at 100.0% (708 of 708 strings)

Co-authored-by: Alex <proactivecam@inbox.ru>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/ru/
Translation: Uptime Kuma/Uptime Kuma
2023-03-27 08:37:50 +00:00
DoyunShin
6c66bff518 Translated using Weblate (Korean)
Currently translated at 97.7% (692 of 708 strings)

Co-authored-by: DoyunShin <doyun.shin@gmail.com>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/ko/
Translation: Uptime Kuma/Uptime Kuma
2023-03-27 08:37:50 +00:00
AmadeusGraves
bea51d048b Translated using Weblate (Spanish)
Currently translated at 99.2% (703 of 708 strings)

Co-authored-by: AmadeusGraves <angelfx19@gmail.com>
Translate-URL: https://weblate.kuma.pet/projects/uptime-kuma/uptime-kuma/es/
Translation: Uptime Kuma/Uptime Kuma
2023-03-27 08:37:50 +00:00
Louis Lam
2e1a0fe4d5 Merge pull request #2983 from GrantBirki/master
GitHub Actions - Validate json / yaml files 📁
2023-03-27 16:36:20 +08:00
grantbirki
27b0895722 fix branch names 2023-03-26 22:35:00 +01:00
grantbirki
e687698851 add json / yaml validate job 2023-03-26 22:34:25 +01:00
Louis Lam
fbdeb30ce7 Merge pull request #2973 from chakflying/fix/limit-precision
Fix: Apply toPrecision as last step
2023-03-26 15:46:00 +08:00
Louis Lam
41bda4e1d7 Merge pull request #2975 from chakflying/fix/badge-no-label
Fix: Allow status badge with empty label
2023-03-26 15:42:12 +08:00
Louis Lam
4869e6531c Merge pull request #2980 from Genc/feature/twilio-notification-provider
Add Twilio Sms Notification Provider
2023-03-26 15:38:53 +08:00
Louis Lam
302b9cf644 Merge pull request #2956 from wwniclask25/feature/opsgenie-alerts
Feat: Add opsgenie notification provider
2023-03-26 15:36:50 +08:00
Louis Lam
3c3a192943 Merge pull request #2906 from chakflying/fix/duplicate-expiry-notif
Fix: Check for TLS expiry notified days smaller than target
2023-03-26 15:34:26 +08:00
Faruk Genç
b64c835cee Add Twilio Sms Notification Provider 2023-03-25 19:56:01 +03:00
Louis Lam
5266e713e6 Update ask-for-help.yaml 2023-03-25 23:06:51 +08:00
Louis Lam
86579d245f Update ask-for-help.yaml 2023-03-25 23:06:23 +08:00
Louis Lam
b6169408be Merge pull request #2962 from chakflying/fix/missing-clear-form
Fix: Add missing clearForm func.
2023-03-25 14:31:47 +08:00
Nelson Chan
4f05912276 Fix: Allow status badge with empty label 2023-03-25 02:44:15 +08:00
Nelson Chan
bf525371d9 Fix: Apply toPrecision as last step 2023-03-24 22:42:50 +08:00
Louis Lam
89bfc3bf33 Merge pull request #2908 from chakflying/chore/encrypted-private-key
Chore: Add support for encrypted SSL-key
2023-03-24 21:36:22 +08:00
Louis Lam
a2014278b8 Fix #2969 2023-03-24 19:16:12 +08:00
Louis Lam
70572af1af Fix #2969 2023-03-24 18:40:05 +08:00
Louis Lam
b31c23a43b Merge pull request #2970 from louislam/fix-2968
Fix crash issue caused by mysqlQuery()
2023-03-24 18:20:15 +08:00
Louis Lam
f4ee5271af Improve error handling of mysqlQuery and return row count as result 2023-03-24 16:24:00 +08:00
Louis Lam
7330db3563 Improve error handling of mysqlQuery and return row count as result 2023-03-24 16:08:30 +08:00
Louis Lam
097567e5f0 Merge pull request #2878 from chakflying/feat/status-page-countdown
Feat: Add status page countdown to refresh
2023-03-23 17:18:57 +08:00
Louis Lam
35f300c8eb Improve and reuse language keys 2023-03-23 17:17:53 +08:00
Nelson Chan
4c9d7ac8ca Fix: Add missing clearForm func. 2023-03-22 15:06:38 +08:00
niclas.koegl
d9558833fc Fix linting 2023-03-21 19:45:44 +01:00
niclas.koegl
776a482a1d Add Opsgenie notification provider 2023-03-21 19:29:37 +01:00
niclas.koegl
d2527d7254 Merge branch 'master' into feature/opsgenie-alerts 2023-03-21 18:10:10 +01:00
niclas.koegl
6dfca0c163 Add Opsgenie notification provider 2023-03-21 18:07:19 +01:00
Nelson Chan
391692a708 Chore: Add support for encrypted SSL-key 2023-03-09 00:00:07 +08:00
Nelson Chan
f32fcb204f Fix: Check for notified days smaller than target 2023-03-08 22:26:19 +08:00
Nelson Chan
193a273557 Feat: Add status page countdown to refresh 2023-03-03 08:25:41 +08:00
29 changed files with 1891 additions and 15736 deletions

View File

@@ -26,6 +26,12 @@ body:
label: "📝 Describe your problem"
description: "Please walk us through it step by step."
placeholder: "Describe what are you asking for..."
- type: textarea
id: error-msg
validations:
required: false
attributes:
label: "📝 Error Message(s) or Log"
- type: input
id: uptime-kuma-version
attributes:

View File

@@ -0,0 +1,25 @@
name: json-yaml-validate
on:
push:
branches:
- master
pull_request:
branches:
- master
workflow_dispatch:
permissions:
contents: read
pull-requests: write # enable write permissions for pull request comments
jobs:
json-yaml-validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: json-yaml-validate
id: json-yaml-validate
uses: GrantBirki/json-yaml-validate@v1.2.0
with:
comment: "true" # enable comment mode

16909
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "uptime-kuma",
"version": "1.21.0",
"version": "1.21.1",
"license": "MIT",
"repository": {
"type": "git",
@@ -39,7 +39,7 @@
"build-docker-nightly-amd64": "docker buildx build -f docker/dockerfile --platform linux/amd64 -t louislam/uptime-kuma:nightly-amd64 --target nightly . --push --progress plain",
"build-docker-pr-test": "docker buildx build -f docker/dockerfile --platform linux/amd64,linux/arm64 -t louislam/uptime-kuma:pr-test --target pr-test . --push",
"upload-artifacts": "docker buildx build -f docker/dockerfile --platform linux/amd64 -t louislam/uptime-kuma:upload-artifact --build-arg VERSION --build-arg GITHUB_TOKEN --target upload-artifact . --progress plain",
"setup": "git checkout 1.21.0 && npm ci --production && npm run download-dist",
"setup": "git checkout 1.21.1 && npm ci --production && npm run download-dist",
"download-dist": "node extra/download-dist.js",
"mark-as-nightly": "node extra/mark-as-nightly.js",
"reset-password": "node extra/reset-password.js",
@@ -70,7 +70,7 @@
"dependencies": {
"@grpc/grpc-js": "~1.7.3",
"@louislam/ping": "~0.4.4-mod.0",
"@louislam/sqlite3": "15.1.2",
"@louislam/sqlite3": "15.1.6",
"args-parser": "~1.3.0",
"axios": "~0.27.0",
"axios-ntlm": "1.3.0",
@@ -172,7 +172,7 @@
"v-pagination-3": "~0.1.7",
"vite": "~3.1.0",
"vite-plugin-compression": "^0.5.1",
"vue": "next",
"vue": "~3.2.47",
"vue-chart-3": "3.0.9",
"vue-confirm-dialog": "~1.0.2",
"vue-contenteditable": "~3.0.4",

View File

@@ -637,9 +637,7 @@ class Monitor extends BeanModel {
} else if (this.type === "mysql") {
let startTime = dayjs().valueOf();
await mysqlQuery(this.databaseConnectionString, this.databaseQuery);
bean.msg = "";
bean.msg = await mysqlQuery(this.databaseConnectionString, this.databaseQuery);
bean.status = UP;
bean.ping = dayjs().valueOf() - startTime;
} else if (this.type === "mongodb") {
@@ -1247,7 +1245,7 @@ class Monitor extends BeanModel {
if (notificationList.length > 0) {
let row = await R.getRow("SELECT * FROM notification_sent_history WHERE type = ? AND monitor_id = ? AND days = ?", [
let row = await R.getRow("SELECT * FROM notification_sent_history WHERE type = ? AND monitor_id = ? AND days <= ?", [
"certificate",
this.id,
targetDays,

View File

@@ -0,0 +1,97 @@
const NotificationProvider = require("./notification-provider");
const axios = require("axios");
const { UP, DOWN } = require("../../src/util");
const opsgenieAlertsUrlEU = "https://api.eu.opsgenie.com/v2/alerts";
const opsgenieAlertsUrlUS = "https://api.opsgenie.com/v2/alerts";
let okMsg = "Sent Successfully.";
class Opsgenie extends NotificationProvider {
name = "Opsgenie";
/**
* @inheritdoc
*/
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
let opsgenieAlertsUrl;
let priority = (notification.opsgeniePriority == "") ? 3 : notification.opsgeniePriority;
const textMsg = "Uptime Kuma Alert";
try {
switch (notification.opsgenieRegion) {
case "US":
opsgenieAlertsUrl = opsgenieAlertsUrlUS;
break;
case "EU":
opsgenieAlertsUrl = opsgenieAlertsUrlEU;
break;
default:
opsgenieAlertsUrl = opsgenieAlertsUrlUS;
}
if (heartbeatJSON == null) {
let notificationTestAlias = "uptime-kuma-notification-test";
let data = {
"message": msg,
"alias": notificationTestAlias,
"source": "Uptime Kuma",
"priority": "P5"
};
return this.post(notification, opsgenieAlertsUrl, data);
}
if (heartbeatJSON.status === DOWN) {
let data = {
"message": monitorJSON ? textMsg + `: ${monitorJSON.name}` : textMsg,
"alias": monitorJSON.name,
"description": msg,
"source": "Uptime Kuma",
"priority": `P${priority}`
};
return this.post(notification, opsgenieAlertsUrl, data);
}
if (heartbeatJSON.status === UP) {
let opsgenieAlertsCloseUrl = `${opsgenieAlertsUrl}/${encodeURIComponent(monitorJSON.name)}/close?identifierType=alias`;
let data = {
"source": "Uptime Kuma",
};
return this.post(notification, opsgenieAlertsCloseUrl, data);
}
} catch (error) {
this.throwGeneralAxiosError(error);
}
}
/**
*
* @param {BeanModel} notification
* @param {string} url Request url
* @param {Object} data Request body
* @returns {Promise<string>}
*/
async post(notification, url, data) {
let config = {
headers: {
"Content-Type": "application/json",
"Authorization": `GenieKey ${notification.opsgenieApiKey}`,
}
};
let res = await axios.post(url, data, config);
if (res.status == null) {
return "Opsgenie notification failed with invalid response!";
}
if (res.status < 200 || res.status >= 300) {
return `Opsgenie notification failed with status code ${res.status}`;
}
return okMsg;
}
}
module.exports = Opsgenie;

View File

@@ -0,0 +1,41 @@
const NotificationProvider = require("./notification-provider");
const axios = require("axios");
class Twilio extends NotificationProvider {
name = "twilio";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
let okMsg = "Sent Successfully.";
let accountSID = notification.twilioAccountSID;
let authToken = notification.twilioAuthToken;
try {
let config = {
headers: {
"Content-Type": "application/x-www-form-urlencoded;charset=utf-8",
"Authorization": "Basic " + Buffer.from(accountSID + ":" + authToken).toString("base64"),
}
};
let data = new URLSearchParams();
data.append("To", notification.twilioToNumber);
data.append("From", notification.twilioFromNumber);
data.append("Body", msg);
let url = "https://api.twilio.com/2010-04-01/Accounts/" + accountSID + "/Messages.json";
await axios.post(url, data, config);
return okMsg;
} catch (error) {
this.throwGeneralAxiosError(error);
}
}
}
module.exports = Twilio;

View File

@@ -23,6 +23,7 @@ const Mattermost = require("./notification-providers/mattermost");
const Ntfy = require("./notification-providers/ntfy");
const Octopush = require("./notification-providers/octopush");
const OneBot = require("./notification-providers/onebot");
const Opsgenie = require("./notification-providers/opsgenie");
const PagerDuty = require("./notification-providers/pagerduty");
const PagerTree = require("./notification-providers/pagertree");
const PromoSMS = require("./notification-providers/promosms");
@@ -41,6 +42,7 @@ const Stackfield = require("./notification-providers/stackfield");
const Teams = require("./notification-providers/teams");
const TechulusPush = require("./notification-providers/techulus-push");
const Telegram = require("./notification-providers/telegram");
const Twilio = require("./notification-providers/twilio");
const Splunk = require("./notification-providers/splunk");
const Webhook = require("./notification-providers/webhook");
const WeCom = require("./notification-providers/wecom");
@@ -83,6 +85,7 @@ class Notification {
new Ntfy(),
new Octopush(),
new OneBot(),
new Opsgenie(),
new PagerDuty(),
new PagerTree(),
new PromoSMS(),
@@ -103,6 +106,7 @@ class Notification {
new Teams(),
new TechulusPush(),
new Telegram(),
new Twilio(),
new Splunk(),
new Webhook(),
new WeCom(),

View File

@@ -147,7 +147,11 @@ router.get("/api/badge/:id/status", cache("5 minutes"), async (request, response
const heartbeat = await Monitor.getPreviousHeartbeat(requestedMonitorId);
const state = overrideValue !== undefined ? overrideValue : heartbeat.status;
badgeValues.label = label ?? "Status";
if (label === undefined) {
badgeValues.label = "Status";
} else {
badgeValues.label = label;
}
switch (state) {
case DOWN:
badgeValues.color = downColor;
@@ -224,7 +228,7 @@ router.get("/api/badge/:id/uptime/:duration?", cache("5 minutes"), async (reques
);
// limit the displayed uptime percentage to four (two, when displayed as percent) decimal digits
const cleanUptime = parseFloat(uptime.toPrecision(4));
const cleanUptime = (uptime * 100).toPrecision(4);
// use a given, custom color or calculate one based on the uptime value
badgeValues.color = color ?? percentageToColor(uptime);
@@ -235,7 +239,7 @@ router.get("/api/badge/:id/uptime/:duration?", cache("5 minutes"), async (reques
labelPrefix,
label ?? `Uptime (${requestedDuration}${labelSuffix})`,
]);
badgeValues.message = filterAndJoin([ prefix, `${cleanUptime * 100}`, suffix ]);
badgeValues.message = filterAndJoin([ prefix, cleanUptime, suffix ]);
}
// build the SVG based on given values

View File

@@ -74,6 +74,7 @@ class UptimeKumaServer {
// SSL
const sslKey = args["ssl-key"] || process.env.UPTIME_KUMA_SSL_KEY || process.env.SSL_KEY || undefined;
const sslCert = args["ssl-cert"] || process.env.UPTIME_KUMA_SSL_CERT || process.env.SSL_CERT || undefined;
const sslKeyPassphrase = args["ssl-key-passphrase"] || process.env.UPTIME_KUMA_SSL_KEY_PASSPHRASE || process.env.SSL_KEY_PASSPHRASE || undefined;
log.info("server", "Creating express and socket.io instance");
this.app = express();
@@ -81,7 +82,8 @@ class UptimeKumaServer {
log.info("server", "Server Type: HTTPS");
this.httpServer = https.createServer({
key: fs.readFileSync(sslKey),
cert: fs.readFileSync(sslCert)
cert: fs.readFileSync(sslCert),
passphrase: sslKeyPassphrase,
}, this.app);
} else {
log.info("server", "Server Type: HTTP");

View File

@@ -322,21 +322,28 @@ exports.postgresQuery = function (connectionString, query) {
* Run a query on MySQL/MariaDB
* @param {string} connectionString The database connection string
* @param {string} query The query to validate the database with
* @returns {Promise<(string[]|Object[]|Object)>}
* @returns {Promise<(string)>}
*/
exports.mysqlQuery = function (connectionString, query) {
return new Promise((resolve, reject) => {
const connection = mysql.createConnection(connectionString);
connection.promise().query(query)
.then(res => {
resolve(res);
})
.catch(err => {
connection.on("error", (err) => {
reject(err);
});
connection.query(query, (err, res) => {
if (err) {
reject(err);
})
.finally(() => {
connection.destroy();
});
} else {
if (Array.isArray(res)) {
resolve("Rows: " + res.length);
} else {
resolve("No Error, but the result is not an array. Type: " + typeof res);
}
}
connection.destroy();
});
});
};

View File

@@ -159,6 +159,16 @@ export default {
}
});
},
/** Clear Form inputs */
clearForm() {
this.key = {
name: "",
expires: this.minDate,
active: 1,
};
this.noExpire = false;
},
}
};
</script>

View File

@@ -13,6 +13,9 @@
:disabled="disabled"
>
<!-- A hidden textarea for copying text on non-https -->
<textarea ref="hiddenTextarea" style="position: fixed; left: -999999px; top: -999999px;"></textarea>
<a class="btn btn-outline-primary" @click="copyToClipboard(model)">
<font-awesome-icon :icon="icon" />
</a>
@@ -111,24 +114,19 @@ export default {
}, 3000);
// navigator clipboard api needs a secure context (https)
// For http, use the text area method (else part)
if (navigator.clipboard && window.isSecureContext) {
// navigator clipboard api method'
return navigator.clipboard.writeText(textToCopy);
} else {
// text area method
let textArea = document.createElement("textarea");
let textArea = this.$refs.hiddenTextarea;
textArea.value = textToCopy;
// make the textarea out of viewport
textArea.style.position = "fixed";
textArea.style.left = "-999999px";
textArea.style.top = "-999999px";
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
return new Promise((res, rej) => {
// here the magic happens
document.execCommand("copy") ? res() : rej();
textArea.remove();
});
}
}

View File

@@ -129,6 +129,7 @@ export default {
"ntfy": "Ntfy",
"octopush": "Octopush",
"OneBot": "OneBot",
"Opsgenie": "Opsgenie",
"PagerDuty": "PagerDuty",
"pushbullet": "Pushbullet",
"PushByTechulus": "Push by Techulus",
@@ -143,6 +144,7 @@ export default {
"stackfield": "Stackfield",
"teams": "Microsoft Teams",
"telegram": "Telegram",
"twilio": "Twilio",
"Splunk": "Splunk",
"webhook": "Webhook",
"GoAlert": "GoAlert",

View File

@@ -0,0 +1,36 @@
<template>
<div class="mb-3">
<label for="opsgenie-region" class="form-label">{{ $t("Region") }}<span style="color: red;"><sup>*</sup></span></label>
<select id="opsgenie-region" v-model="$parent.notification.opsgenieRegion" class="form-select" required>
<option value="us">
US (Default)
</option>
<option value="eu">
EU
</option>
</select>
</div>
<div class="mb-3">
<label for="opsgenie-apikey" class="form-label">{{ $t("API Key") }}<span style="color: red;"><sup>*</sup></span></label>
<HiddenInput id="opsgenie-apikey" v-model="$parent.notification.opsgenieApiKey" required="true" autocomplete="false"></HiddenInput>
</div>
<div class="mb-3">
<label for="opsgenie-priority" class="form-label">{{ $t("Priority") }}</label>
<input id="opsgenie-priority" v-model="$parent.notification.opsgeniePriority" type="number" class="form-control" min="1" max="5" step="1">
</div>
<div class="form-text">
<span style="color: red;"><sup>*</sup></span>{{ $t("Required") }}
<i18n-t tag="p" keypath="aboutWebhooks" style="margin-top: 8px;">
<a href="https://docs.opsgenie.com/docs/alert-api" target="_blank">https://docs.opsgenie.com/docs/alert-api</a>
</i18n-t>
</div>
</template>
<script>
import HiddenInput from "../HiddenInput.vue";
export default {
components: {
HiddenInput,
},
};
</script>

View File

@@ -0,0 +1,27 @@
<template>
<div class="mb-3">
<label for="twilio-account-sid" class="form-label">{{ $t("Account SID") }}</label>
<input id="twilio-account-sid" v-model="$parent.notification.twilioAccountSID" type="text" class="form-control" required>
</div>
<div class="mb-3">
<label for="twilio-auth-token" class="form-label">{{ $t("Auth Token") }}</label>
<input id="twilio-auth-token" v-model="$parent.notification.twilioAuthToken" type="text" class="form-control" required>
</div>
<div class="mb-3">
<label for="twilio-from-number" class="form-label">{{ $t("From Number") }}</label>
<input id="twilio-from-number" v-model="$parent.notification.twilioFromNumber" type="text" class="form-control" required>
</div>
<div class="mb-3">
<label for="twilio-to-number" class="form-label">{{ $t("To Number") }}</label>
<input id="twilio-to-number" v-model="$parent.notification.twilioToNumber" type="text" class="form-control" required>
</div>
<div class="mb-3">
<i18n-t tag="p" keypath="More info on:" style="margin-top: 8px;">
<a href="https://www.twilio.com/docs/sms" target="_blank">https://www.twilio.com/docs/sms</a>
</i18n-t>
</div>
</template>

View File

@@ -21,6 +21,7 @@ import Mattermost from "./Mattermost.vue";
import Ntfy from "./Ntfy.vue";
import Octopush from "./Octopush.vue";
import OneBot from "./OneBot.vue";
import Opsgenie from "./Opsgenie.vue";
import PagerDuty from "./PagerDuty.vue";
import PagerTree from "./PagerTree.vue";
import PromoSMS from "./PromoSMS.vue";
@@ -41,6 +42,7 @@ import STMP from "./SMTP.vue";
import Teams from "./Teams.vue";
import TechulusPush from "./TechulusPush.vue";
import Telegram from "./Telegram.vue";
import Twilio from "./Twilio.vue";
import Webhook from "./Webhook.vue";
import WeCom from "./WeCom.vue";
import GoAlert from "./GoAlert.vue";
@@ -76,6 +78,7 @@ const NotificationFormList = {
"ntfy": Ntfy,
"octopush": Octopush,
"OneBot": OneBot,
"Opsgenie": Opsgenie,
"PagerDuty": PagerDuty,
"PagerTree": PagerTree,
"promosms": PromoSMS,
@@ -95,6 +98,7 @@ const NotificationFormList = {
"stackfield": Stackfield,
"teams": Teams,
"telegram": Telegram,
"twilio": Twilio,
"Splunk": Splunk,
"webhook": Webhook,
"WeCom": WeCom,

View File

@@ -738,5 +738,6 @@
"Add New Tag": "Přidat nový štítek",
"lunaseaTarget": "Cíl",
"lunaseaDeviceID": "ID zařízení",
"lunaseaUserID": "ID uživatele"
"lunaseaUserID": "ID uživatele",
"statusPageRefreshIn": "Obnovení za: {0}"
}

View File

@@ -174,6 +174,7 @@
"Avg. Response": "Avg. Response",
"Entry Page": "Entry Page",
"statusPageNothing": "Nothing here, please add a group or a monitor.",
"statusPageRefreshIn": "Refresh in: {0}",
"No Services": "No Services",
"All Systems Operational": "All Systems Operational",
"Partially Degraded Service": "Partially Degraded Service",
@@ -706,5 +707,9 @@
"wayToGetPagerTreeIntegrationURL": "After creating the Uptime Kuma integration in PagerTree, copy the Endpoint. See full details {0}",
"lunaseaTarget": "Target",
"lunaseaDeviceID": "Device ID",
"lunaseaUserID": "User ID"
"lunaseaUserID": "User ID",
"twilioAccountSID": "Account SID",
"twilioAuthToken": "Auth Token",
"twilioFromNumber": "From Number",
"twilioToNumber": "To Number"
}

View File

@@ -696,5 +696,47 @@
"Bark Endpoint": "Endpoint Bark",
"WebHookUrl": "WebHookUrl",
"High": "Alto",
"alertaApiEndpoint": "Endpoint API"
"alertaApiEndpoint": "Endpoint API",
"Body Encoding": "Codificación del cuerpo",
"Expiry date": "Fecha de expiración",
"Expiry": "Expiración",
"API Keys": "Claves API",
"Key Added": "Clave añadida",
"Add Another": "Añadir otro",
"Continue": "Continuar",
"Don't expire": "No caduca",
"apiKey-inactive": "Inactivo",
"apiKey-expired": "Expirado",
"apiKey-active": "Activo",
"No API Keys": "No hay claves API",
"Add API Key": "Añadir clave API",
"apiKeyAddedMsg": "Su clave API ha sido añadida. Anótala, ya que no se volverá a mostrar.",
"Clone": "Clonar",
"cloneOf": "Clon de {0}",
"pagertreeDoNothing": "No hacer nada",
"pagertreeResolve": "Resolución automática",
"pagertreeCritical": "Crítico",
"pagertreeHigh": "Alto",
"pagertreeMedium": "Medio",
"pagertreeLow": "Bajo",
"pagertreeSilent": "Silencio",
"pagertreeUrgency": "Urgencia",
"pagertreeIntegrationUrl": "URL de integración",
"lunaseaTarget": "Objetivo",
"wayToGetPagerTreeIntegrationURL": "Después de crear la integración Uptime Kuma en PagerTree, copie el Endpoint. Ver todos los detalles {0}",
"Generate": "Generar",
"deleteAPIKeyMsg": "¿Está seguro de que desea eliminar esta clave API?",
"telegramMessageThreadID": "(Opcional) ID del hilo de mensajes",
"telegramMessageThreadIDDescription": "Opcional Identificador único para el hilo de mensajes de destino (asunto) del foro; solo para supergrupos de foros",
"telegramProtectContent": "Proteger Forwarding/Saving",
"telegramProtectContentDescription": "Si se activa, los mensajes del bot en Telegram estarán protegidos contra el reenvío y el guardado.",
"notificationRegional": "Regional",
"Clone Monitor": "Clonar Monitor",
"telegramSendSilently": "Enviar en silencio",
"telegramSendSilentlyDescription": "Envía el mensaje en silencio. Los usuarios recibirán una notificación sin sonido.",
"Add New Tag": "Añadir nueva etiqueta",
"lunaseaUserID": "ID Usuario",
"lunaseaDeviceID": "ID Dispositivo",
"disableAPIKeyMsg": "¿Está seguro de que desea desactivar esta clave API?",
"Expires": "Expira"
}

View File

@@ -738,5 +738,6 @@
"lunaseaDeviceID": "Identifiant de l'appareil",
"lunaseaUserID": "Identifiant de l'utilisateur",
"Add New Tag": "Ajouter une étiquette",
"lunaseaTarget": "Cible"
"lunaseaTarget": "Cible",
"statusPageRefreshIn": "Actualisation dans: {0}"
}

View File

@@ -719,5 +719,10 @@
"notificationRegional": "지역별",
"Google Analytics ID": "Google Analytics ID",
"Add API Key": "API 키 추가",
"apiKeyAddedMsg": "API 키가 추가되었습니다. 다시 표시되지 않을 것이므로 메모해 두세요."
"apiKeyAddedMsg": "API 키가 추가되었습니다. 다시 표시되지 않을 것이므로 메모해 두세요.",
"pagertreeCritical": "치명적인",
"apiKey-active": "사용 가능",
"lunaseaUserID": "사용자 ID",
"apiKey-expired": "만료됨",
"Expires": "만료일"
}

View File

@@ -8,7 +8,7 @@
"acceptedStatusCodesDescription": "Выберите коды статусов для определения доступности сервиса.",
"passwordNotMatchMsg": "Повтор пароля не совпадает.",
"notificationDescription": "Привяжите уведомления к мониторам.",
"keywordDescription": "Поиск слова в чистом HTML или в JSON-ответе (чувствительно к регистру)",
"keywordDescription": "Поиск слова в чистом HTML или в JSON-ответе (чувствительно к регистру).",
"pauseDashboardHome": "Пауза",
"deleteMonitorMsg": "Вы действительно хотите удалить данный монитор?",
"deleteNotificationMsg": "Вы действительно хотите удалить это уведомление для всех мониторов?",
@@ -45,9 +45,9 @@
"Uptime": "Аптайм",
"Cert Exp.": "Сертификат истекает.",
"day": "день | дней",
"-day": " дней",
"-day": "-дней",
"hour": "час",
"-hour": " часа",
"-hour": "-часа",
"Response": "Ответ",
"Ping": "Пинг",
"Monitor Type": "Тип монитора",
@@ -124,12 +124,12 @@
"Also apply to existing monitors": "Применить к существующим мониторам",
"Export": "Экспорт",
"Import": "Импорт",
"backupDescription": "Вы можете сохранить резервную копию всех мониторов и уведомлений в виде JSON-файла",
"backupDescription2": "P.S. История и события сохранены не будут",
"backupDescription3": "Важные данные, такие как токены уведомлений, добавляются при экспорте, поэтому храните файлы в безопасном месте",
"backupDescription": "Вы можете сохранить резервную копию всех мониторов и уведомлений в виде JSON-файла.",
"backupDescription2": "Важно: история и события сохранены не будут.",
"backupDescription3": "Важные данные, такие как токены уведомлений, добавляются при экспорте, поэтому храните файлы в безопасном месте.",
"alertNoFile": "Выберите файл для импорта.",
"alertWrongFileType": "Выберите JSON-файл.",
"twoFAVerifyLabel": "Пожалуйста, введите свой токен, чтобы проверить работу 2FA",
"twoFAVerifyLabel": "Пожалуйста, введите свой токен, чтобы проверить работу 2FA:",
"tokenValidSettingsMsg": "Токен действителен! Теперь вы можете сохранить настройки 2FA.",
"confirmEnableTwoFAMsg": "Вы действительно хотите включить 2FA?",
"confirmDisableTwoFAMsg": "Вы действительно хотите выключить 2FA?",
@@ -444,11 +444,11 @@
"The slug is already taken. Please choose another slug.": "The slug is already taken. Please choose another slug.",
"Page Not Found": "Страница не найдена",
"wayToGetCloudflaredURL": "(Скачать cloudflared с {0})",
"cloudflareWebsite": "Cloudflare Website",
"cloudflareWebsite": "Веб-сайт Cloudflare",
"Message:": "Сообщение:",
"Don't know how to get the token? Please read the guide:": "Don't know how to get the token? Please read the guide:",
"The current connection may be lost if you are currently connecting via Cloudflare Tunnel. Are you sure want to stop it? Type your current password to confirm it.": "The current connection may be lost if you are currently connecting via Cloudflare Tunnel. Are you sure want to stop it? Type your current password to confirm it.",
"HTTP Headers": "HTTP заголовки",
"Don't know how to get the token? Please read the guide:": "Не знаете, как получить токен? Пожалуйста, прочтите руководство:",
"The current connection may be lost if you are currently connecting via Cloudflare Tunnel. Are you sure want to stop it? Type your current password to confirm it.": "Текущее соединение может быть потеряно, если вы в данный момент подключаетесь через туннель Cloudflare. Вы уверены, что хотите это остановить? Введите свой текущий пароль, чтобы подтвердить это.",
"HTTP Headers": "заголовки HTTP",
"Trust Proxy": "Доверять прокси",
"Other Software": "Другое программное обеспечение",
"For example: nginx, Apache and Traefik.": "К примеру: nginx, Apache и Traefik.",
@@ -463,13 +463,13 @@
"Proxy": "Прокси",
"Date Created": "Дата создания",
"HomeAssistant": "Home Assistant",
"onebotHttpAddress": "OneBot HTTP Address",
"onebotMessageType": "OneBot Message Type",
"onebotHttpAddress": "HTTP-адрес OneBot",
"onebotMessageType": "Тип сообщения OneBot",
"onebotGroupMessage": "Группа",
"onebotPrivateMessage": "Private",
"onebotUserOrGroupId": "ID группы или пользователя",
"onebotSafetyTips": "В целях безопасности необходимо установить токен доступа",
"PushDeer Key": "PushDeer Key",
"PushDeer Key": "ключ PushDeer",
"Footer Text": "Текст нижнего колонтитула",
"Show Powered By": "Показывать на чем создано",
"Domain Names": "Доменные имена",
@@ -488,40 +488,40 @@
"From Name/Number": "Имя/номер отправителя",
"Leave blank to use a shared sender number.": "Оставьте пустым, чтобы использовать общий номер отправителя.",
"Octopush API Version": "Версия API Octopush",
"Legacy Octopush-DM": "Legacy Octopush-DM",
"endpoint": "endpoint",
"Legacy Octopush-DM": "устаревший Octopush-DM",
"endpoint": "конечная точка",
"octopushAPIKey": "\"API key\" из учетных данных HTTP API в панели управления",
"octopushLogin": "\"Login\" из учетных данных HTTP API в панели управления",
"promosmsLogin": "Логин API",
"promosmsPassword": "Пароль API",
"pushoversounds pushover": "Pushover (default)",
"pushoversounds bike": "Bike",
"pushoversounds bugle": "Bugle",
"pushoversounds cashregister": "Cash Register",
"pushoversounds pushover": "Pushover (по умолчанию)",
"pushoversounds bike": "Велосипед",
"pushoversounds bugle": "Горн",
"pushoversounds cashregister": "Кассовый аппарат",
"pushoversounds classical": "Classical",
"pushoversounds cosmic": "Cosmic",
"pushoversounds falling": "Falling",
"pushoversounds gamelan": "Gamelan",
"pushoversounds incoming": "Incoming",
"pushoversounds intermission": "Intermission",
"pushoversounds magic": "Magic",
"pushoversounds mechanical": "Mechanical",
"pushoversounds pianobar": "Piano Bar",
"pushoversounds siren": "Siren",
"pushoversounds spacealarm": "Space Alarm",
"pushoversounds tugboat": "Tug Boat",
"pushoversounds alien": "Alien Alarm (long)",
"pushoversounds climb": "Climb (long)",
"pushoversounds persistent": "Persistent (long)",
"pushoversounds echo": "Pushover Echo (long)",
"pushoversounds updown": "Up Down (long)",
"pushoversounds vibrate": "Vibrate Only",
"pushoversounds none": "None (silent)",
"pushyAPIKey": "Secret API Key",
"pushoversounds cosmic": "Космический",
"pushoversounds falling": "Падающий",
"pushoversounds gamelan": "Гамелан",
"pushoversounds incoming": "Входящий",
"pushoversounds intermission": "Антракт",
"pushoversounds magic": "Магия",
"pushoversounds mechanical": "Механический",
"pushoversounds pianobar": "Пиано-бар",
"pushoversounds siren": "Сирена",
"pushoversounds spacealarm": "Космическая сигнализация",
"pushoversounds tugboat": "Буксирное судно",
"pushoversounds alien": "Инопланетная тревога (долгое)",
"pushoversounds climb": "Подъем (долгое)",
"pushoversounds persistent": "Стойкий (долгое)",
"pushoversounds echo": "Pushover Эхо (долгое)",
"pushoversounds updown": "Вверх вниз (долгое)",
"pushoversounds vibrate": "Только вибрация",
"pushoversounds none": "Нет (тихо)",
"pushyAPIKey": "Секретный ключ API",
"pushyToken": "Токен устройства",
"Using a Reverse Proxy?": "Используете обратный прокси?",
"Check how to config it for WebSocket": "Проверьте, как настроить его для WebSocket",
"Steam Game Server": "Steam Game Server",
"Steam Game Server": "Игровой сервер Steam",
"Most likely causes:": "Наиболее вероятные причины:",
"The resource is no longer available.": "Ресурс больше не доступен.",
"There might be a typing error in the address.": "В адресе может быть опечатка.",
@@ -536,24 +536,24 @@
"certificationExpiryDescription": "HTTPS Мониторы инициируют уведомление, когда срок действия сертификата TLS истечет:",
"Setup Docker Host": "Настроить Docker Host",
"Connection Type": "Тип соединения",
"Docker Daemon": "Docker Daemon",
"deleteDockerHostMsg": "Are you sure want to delete this docker host for all monitors?",
"socket": "Socket",
"Docker Daemon": "Демон Docker",
"deleteDockerHostMsg": "Вы уверены, что хотите удалить этот узел docker для всех мониторов?",
"socket": "Сокет",
"tcp": "TCP / HTTP",
"Docker Container": "Docker контейнер",
"Container Name / ID": "Название контейнера / ID",
"Docker Host": "Docker Host",
"Docker Hosts": "Docker Hosts",
"ntfy Topic": "ntfy Topic",
"Docker Host": "Хост Docker",
"Docker Hosts": "Хосты Docker",
"ntfy Topic": "тема ntfy",
"Domain": "Домен",
"Workstation": "Workstation",
"Workstation": "Рабочая станция",
"disableCloudflaredNoAuthMsg": "Вы находитесь в режиме без авторизации, пароль не требуется.",
"trustProxyDescription": "Доверять заголовкам 'X-Forwarded-*'. Если вы хотите получить правильный IP-адрес клиента, а ваш Uptime Kuma находится под Nginx или Apache, вам следует включить этот параметр.",
"wayToGetLineNotifyToken": "Вы можете получить токен доступа в {0}",
"Examples": "Примеры",
"Home Assistant URL": "Home Assistant URL",
"Home Assistant URL": "URL-адрес Home Assistant",
"Long-Lived Access Token": "Токен доступа с длительным сроком службы",
"Long-Lived Access Token can be created by clicking on your profile name (bottom left) and scrolling to the bottom then click Create Token. ": "Long-Lived Access Token can be created by clicking on your profile name (bottom left) and scrolling to the bottom then click Create Token. ",
"Long-Lived Access Token can be created by clicking on your profile name (bottom left) and scrolling to the bottom then click Create Token. ": "Токен доступа с длительным сроком действия можно создать, нажав на имя вашего профиля (внизу слева) и прокрутив его вниз, затем нажмите Создать токен. ",
"Notification Service": "Служба уведомлений",
"default: notify all devices": "по стандарту: уведомлять все устройства",
"A list of Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.": "Список служб уведомлений можно найти в Home Assistant в разделе \"Инструменты разработчика > Службы\", выполнив поиск по слову \"уведомление\", чтобы найти название вашего устройства/телефона.",
@@ -618,7 +618,7 @@
"Custom CSS": "Пользовательские CSS",
"weekdayShortTue": "Вт",
"dayOfWeek": "День недели",
"confirmDeleteTagMsg": "Вы уверены, что хотите удалить этот тег? Мониторы, связанные с этим тегом не будут удалены.",
"confirmDeleteTagMsg": "Вы уверены, что хотите удалить этот тег? Мониторы, связанные с этим тегом не будут удалены.",
"loadingError": "Невозможно получить данные, пожалуйста попробуйте позже.",
"Packet Size": "Размер пакета",
"warningTimezone": "Используется часовой пояс сервера",
@@ -676,10 +676,10 @@
"Integration URL": "URL интеграции",
"do nothing": "ничего не делать",
"smseagleTo": "Номер(а) телефона",
"smseagleGroup": "Имена групп в телефонной книжке",
"smseagleGroup": "Название(я) групп телефонной книги",
"smseagleContact": "Имена контактов из телефонной книжки",
"smseagleRecipientType": "Тип получателя",
"smseagleRecipient": "Получатель (через запятую, если несколько)",
"smseagleRecipient": "Получатель(я) (через запятую, если необходимо указать несколько)",
"smseagleToken": "Токен доступа API",
"smseagleUrl": "URL вашего SMSEagle устройства",
"smseagleEncoding": "Отправить в юникоде",
@@ -687,9 +687,9 @@
"Server Address": "Адрес сервера",
"Learn More": "Узнать больше",
"topicExplanation": "MQTT топик для мониторинга",
"Guild ID": "Guild ID",
"Guild ID": "Идентификатор гильдии",
"Kook": "Kook",
"wayToGetKookBotToken": "Создайте приложение и получите токен вашего бота тут {0}.",
"wayToGetKookBotToken": "Создайте приложение и получите токен бота по адресу {0}",
"Resend Notification if Down X times consecutively": "Повторная отправка уведомления при падении несколько раз",
"telegramProtectContent": "Запретить пересылку/сохранение",
"telegramProtectContentDescription": "Если включено, сообщения бота в Telegram будут запрещены для пересылки и сохранения.",
@@ -700,5 +700,53 @@
"Clone": "Копия",
"cloneOf": "Копия {0}",
"notificationRegional": "Региональный",
"Add New Tag": "Добавить тег"
"Add New Tag": "Добавить тег",
"Body Encoding": "Тип содержимого запроса.(JSON or XML)",
"Strategy": "Стратегия",
"Free Mobile User Identifier": "Бесплатный идентификатор мобильного пользователя",
"Auto resolve or acknowledged": "Автоматическое разрешение или подтверждение",
"auto acknowledged": "автоматическое подтверждение",
"auto resolve": "автоматическое разрешение",
"API Keys": "Ключи API",
"Expiry": "Истекает",
"Expiry date": "Дата окончания действия",
"Don't expire": "Не истекает",
"Continue": "Продолжать",
"Add Another": "Добавьте еще один",
"Key Added": "Ключ добавлен",
"Add API Key": "Добавить ключ API",
"No API Keys": "Нет API ключей",
"apiKey-active": "Активный",
"apiKey-expired": "Истёк",
"apiKey-inactive": "Неактивный",
"Expires": "Истекает",
"disableAPIKeyMsg": "Вы уверены, что хотите отключить этот ключ?",
"Generate": "Создать",
"pagertreeResolve": "Автоматическое разрешение",
"pagertreeDoNothing": "ничего не делать",
"lunaseaTarget": "Цель",
"lunaseaDeviceID": "Идентификатор устройства",
"lunaseaUserID": "Идентификатор пользователя",
"Lowcost": "Низкая стоимость",
"pagertreeIntegrationUrl": "URL-адрес интеграции",
"pagertreeUrgency": "Срочность",
"pagertreeSilent": "Тихий",
"pagertreeLow": "Низкий",
"pagertreeMedium": "Средний",
"pagertreeHigh": "Высокий",
"pagertreeCritical": "Критический",
"high": "высокий",
"promosmsAllowLongSMS": "Разрешить длинные SMS-сообщения",
"Economy": "Экономия",
"wayToGetPagerDutyKey": "Вы можете получить это, перейдя в службу -> Каталог служб -> (Выберите службу) -> Интеграции -> Добавить интеграцию. Здесь вы можете выполнить поиск по \"Events API V2\". Дополнительная информация {0}",
"apiKeyAddedMsg": "Ваш API ключ был добавлен. Пожалуйста, запишите это, так как оно больше не будет показан.",
"deleteAPIKeyMsg": "Вы уверены, что хотите удалить этот ключ?",
"wayToGetPagerTreeIntegrationURL": "После создания интеграции Uptime Kuma в PagerTree, скопируйте конечную точку. Смотрите полную информацию {0}",
"telegramMessageThreadIDDescription": "Необязательный уникальный идентификатор для цепочки сообщений (темы) форума; только для форумов-супергрупп",
"grpcMethodDescription": "Название метода - преобразовать в формат cammelCase, такой как sayHello, check и т.д.",
"Proto Service Name": "название службы Proto",
"Proto Method": "Метод Proto",
"Proto Content": "Содержание Proto",
"telegramMessageThreadID": "(Необязательно) ID цепочки сообщений",
"statusPageRefreshIn": "Обновлять каждые: {0}"
}

View File

@@ -64,7 +64,7 @@
"Up": "Dostupné",
"Down": "Nedostupné",
"Unknown": "Neznáme",
"markdownSupported": "Podpora Markdown syntaxe",
"markdownSupported": "Podpora Markdown syntaxu",
"Name": "Názov",
"DateTime": "Dátum a čas",
"Resume": "Pokračovať",
@@ -81,5 +81,115 @@
"maxRedirectDescription": "Maximálny počet presmerovaní. Hodnota 0 vypne presmerovania.",
"needPushEvery": "Tuto adresu by ste mali volať každých {0} sekúnd.",
"pushOptionalParams": "Voliteľné parametre: {0}",
"Theme - Heartbeat Bar": "Téma - Heartbeat riadok"
"Theme - Heartbeat Bar": "Téma - Heartbeat riadok",
"Game": "Hra",
"Search Engine Visibility": "Viditeľnosť vyhľadávačmi",
"Allow indexing": "Povoliť indexovanie",
"Change Password": "Zmeniť heslo",
"Current Password": "Aktuálne heslo",
"New Password": "Nové heslo",
"Repeat New Password": "Zopakovať nové heslo",
"Update Password": "Aktualizovať heslo",
"Disable Auth": "Vypnúť autentifikáciu",
"Enable Auth": "Zapnúť autentifikáciu",
"Please use this option carefully!": "Túto možnosť používajte opatrne!",
"Logout": "Odhlásiť sa",
"Leave": "Odísť",
"I understand, please disable": "Rozumiem, vypnite to",
"Yes": "Áno",
"No": "Nie",
"Username": "Používateľské meno",
"Password": "Heslo",
"Login": "Prihlásiť sa",
"No Monitors, please": "Žiadne sledovanie, prosím",
"add one": "pridať jeden",
"Notification Type": "Typ notifikácie",
"Email": "E-mail",
"Test": "Test",
"Certificate Info": "Informácie o certifikáte",
"Resolver Server": "DNS server",
"Last Result": "Posledný výsledok",
"Repeat Password": "Zopakovať heslo",
"Import Backup": "Importovať zálohu",
"Export Backup": "Exportovať zálohu",
"Export": "Exportovať",
"Import": "Importovať",
"respTime": "Čas odozvy (ms)",
"notAvailableShort": "Nie je číslo",
"Default enabled": "Predvolene povolené",
"Create": "Vytvoriť",
"Clear Data": "Vyčistiť dáta",
"Events": "Udalosti",
"Heartbeats": "Odpovede",
"Auto Get": "Získať automaticky",
"Schedule maintenance": "Naplánovať údržbu",
"Affected Monitors": "Dotknuté sledovania",
"Pick Affected Monitors...": "Vybrať dotknuté sledovania…",
"Start of maintenance": "Začiatok údržby",
"All Status Pages": "Všetky stavové stránky",
"Select status pages...": "Vybrať stránky stavu…",
"alertNoFile": "Vyberte súbor na import.",
"alertWrongFileType": "Vyberte súbor JSON.",
"Clear all statistics": "Vymazať všetky štatistiky",
"Skip existing": "Preskočiť existujúce",
"Overwrite": "Prepísať",
"Options": "Možnosti",
"Keep both": "Ponechať obe",
"Setup 2FA": "Nastavenie 2FA",
"Disable 2FA": "Zakázať 2FA",
"2FA Settings": "Nastavenia 2FA",
"Two Factor Authentication": "Dvojfaktorová autentifikácia",
"Inactive": "Neaktívne",
"Token": "Token",
"Show URI": "Zobraziť URI",
"Tags": "Značky",
"Add New below or Select...": "Pridať novú nižšie alebo vybrať…",
"Tag with this value already exist.": "Značka s touto hodnotou už existuje.",
"color": "Farba",
"value (optional)": "hodnota (voliteľné)",
"Gray": "Šedá",
"Red": "Červená",
"Orange": "Oranžová",
"Green": "Zelená",
"Indigo": "Indigo",
"Purple": "Fialová",
"Pink": "Ružová",
"Custom": "Vlastná",
"Avg. Ping": "Priemerný ping",
"Avg. Response": "Priemerný čas odpovede",
"Entry Page": "Vstupná stránka",
"No Services": "Žiadne služby",
"All Systems Operational": "Všetky systémy funkčné",
"Partially Degraded Service": "Čiastočne zhoršená služba",
"Degraded Service": "Degradovaná služba",
"Add Group": "Pridať skupinu",
"Add a monitor": "Pridať sledovanie",
"Edit Status Page": "Upraviť stavovú stránku",
"Go to Dashboard": "Prejdite na informačný panel",
"Status Page": "Stavová stránka",
"Status Pages": "Stavové stránky",
"defaultNotificationName": "Moje {notification} upozornenie ({number})",
"here": "tu",
"Required": "Povinné",
"Post URL": "Post URL",
"Content Type": "Druh obsahu",
"webhookJsonDesc": "{0} je vhodný pre všetky moderné servery HTTP, ako napríklad Express.js",
"webhookFormDataDesc": "{multipart} je dobré pre PHP. JSON bude potrebné analyzovať pomocou {decodeFunction}",
"Generate": "Generovať",
"Discourage search engines from indexing site": "Odradiť vyhľadávacie nástroje od indexovania stránky",
"disableauth.message1": "Ste si istý, že chcete <strong>vypnúť autentifikáciu</strong>?",
"disableauth.message2": "Je navrhnutý pre scenáre, <strong>kde máte v úmysle implementovať autentifikáciu treťou stranou</strong> pred Uptime Kuma, ako je Cloudflare Access, Authelia alebo iné autentifikačné mechanizmy.",
"Confirm": "Potvrdiť",
"Remember me": "Zapamätať si ma",
"Resource Record Type": "Typ záznamu",
"Create your admin account": "Vytvorte si účet administrátora",
"Apply on all existing monitors": "Aplikujte na všetky existujúce sledovania",
"Verify Token": "Overiť token",
"Enable 2FA": "Povoliť 2FA",
"Active": "Aktívne",
"Add New Tag": "Pridať novú značku",
"Tag with this name already exist.": "Značka s týmto názvom už existuje.",
"Blue": "Modrá",
"Search...": "Hľadať…",
"statusPageNothing": "Nič tu nie je, pridajte skupinu alebo sledovanie."
}

View File

@@ -738,5 +738,6 @@
"lunaseaTarget": "Hedef",
"Add New Tag": "Yeni Etiket Ekle",
"lunaseaDeviceID": "Cihaz ID",
"lunaseaUserID": "Kullanıcı ID"
"lunaseaUserID": "Kullanıcı ID",
"statusPageRefreshIn": "{0} içinde yenilenecek"
}

View File

@@ -740,5 +740,6 @@
"Add New Tag": "添加新标签",
"lunaseaDeviceID": "设备ID",
"lunaseaTarget": "目标",
"lunaseaUserID": "用户ID"
"lunaseaUserID": "用户ID",
"statusPageRefreshIn": "将于 {0} 后刷新"
}

View File

@@ -228,7 +228,7 @@
"smtpCC": "CC",
"smtpBCC": "BCC",
"Discord Webhook URL": "Discord Webhook 網址",
"wayToGetDiscordURL": "您可以前往伺服器設定 -> 整合 -> Webhook -> 新 Webhook 以取得",
"wayToGetDiscordURL": "您可以前往 伺服器設定 -> 整合 -> Webhook -> 新 Webhook 以取得",
"Bot Display Name": "機器人顯示名稱",
"Prefix Custom Message": "前綴自訂訊息",
"Webhook URL": "Webhook 網址",
@@ -706,5 +706,8 @@
"Add New Tag": "加新標籤",
"Economy": "經濟",
"Lowcost": "平價",
"high": "高價"
"high": "高價",
"statusPageRefreshIn": "將於 {0} 後重新整理",
"SendKey": "SendKey",
"SMSManager API Docs": "SMSManager API 文件 "
}

View File

@@ -944,6 +944,14 @@ message HealthCheckResponse {
} else if (this.isEdit || this.isClone) {
this.$root.getSocket().emit("getMonitor", this.$route.params.id, (res) => {
if (res.ok) {
if (this.isClone) {
// Reset push token for cloned monitors
if (res.monitor.type === "push") {
res.monitor.pushToken = undefined;
}
}
this.monitor = res.monitor;
if (this.isClone) {

View File

@@ -306,6 +306,11 @@
<p v-if="config.showPoweredBy">
{{ $t("Powered by") }} <a target="_blank" rel="noopener noreferrer" href="https://github.com/louislam/uptime-kuma">{{ $t("Uptime Kuma" ) }}</a>
</p>
<div class="refresh-info mb-2">
<div>{{ $t("Last Updated") }}: <date-time :value="lastUpdateTime" /></div>
<div>{{ $tc("statusPageRefreshIn", [ updateCountdownText]) }}</div>
</div>
</footer>
</div>
@@ -322,6 +327,7 @@
<script>
import axios from "axios";
import dayjs from "dayjs";
import duration from "dayjs/plugin/duration";
import Favico from "favico.js";
// import highlighting library (you can use any library you want just return html string)
import { highlight, languages } from "prismjs/components/prism-core";
@@ -337,10 +343,12 @@ import DOMPurify from "dompurify";
import Confirm from "../components/Confirm.vue";
import PublicGroupList from "../components/PublicGroupList.vue";
import MaintenanceTime from "../components/MaintenanceTime.vue";
import DateTime from "../components/Datetime.vue";
import { getResBaseURL } from "../util-frontend";
import { STATUS_PAGE_ALL_DOWN, STATUS_PAGE_ALL_UP, STATUS_PAGE_MAINTENANCE, STATUS_PAGE_PARTIAL_DOWN, UP, MAINTENANCE } from "../util.ts";
const toast = useToast();
dayjs.extend(duration);
const leavePageMsg = "Do you really want to leave? you have unsaved changes!";
@@ -359,6 +367,7 @@ export default {
Confirm,
PrismEditor,
MaintenanceTime,
DateTime,
},
// Leave Page for vue route change
@@ -400,6 +409,10 @@ export default {
baseURL: "",
clickedEditButton: false,
maintenanceList: [],
autoRefreshInterval: 5,
lastUpdateTime: dayjs(),
updateCountdown: null,
updateCountdownText: null,
};
},
computed: {
@@ -637,11 +650,13 @@ export default {
console.log(error);
});
// 5mins a loop
// Configure auto-refresh loop
this.updateHeartbeatList();
feedInterval = setInterval(() => {
this.updateHeartbeatList();
}, (300 + 10) * 1000);
}, (this.autoRefreshInterval * 60 + 10) * 1000);
this.updateUpdateTimer();
// Go to edit page if ?edit present
// null means ?edit present, but no value
@@ -700,10 +715,29 @@ export default {
favicon.badge(downMonitors);
this.loadedData = true;
this.lastUpdateTime = dayjs();
this.updateUpdateTimer();
});
}
},
/**
* Setup timer to display countdown to refresh
* @returns {void}
*/
updateUpdateTimer() {
clearInterval(this.updateCountdown);
this.updateCountdown = setInterval(() => {
const countdown = dayjs.duration(this.lastUpdateTime.add(this.autoRefreshInterval, "minutes").add(10, "seconds").diff(dayjs()));
if (countdown.as("seconds") < 0) {
clearInterval(this.updateCountdown);
} else {
this.updateCountdownText = countdown.format("mm:ss");
}
}, 1000);
},
/** Enable editing mode */
edit() {
if (this.hasToken) {
@@ -1118,4 +1152,8 @@ footer {
}
}
.refresh-info {
opacity: 0.7;
}
</style>