Merge branch 'master' into cert-notification

pull/781/head
Louis Lam 3 years ago
commit 110ec491ee

@ -1,21 +0,0 @@
---
name: Ask for help
about: You can ask any question related to Uptime Kuma.
title: ''
labels: help
assignees: ''
---
**Is it a duplicated question?**
Please search in Issues without filters: https://github.com/louislam/uptime-kuma/issues?q=
**Describe your problem**
Please describe what you are asking for
**Info**
Uptime Kuma Version:
Using Docker?: Yes/No
Docker Version:
Node.js Version (Without Docker only):
OS:
Browser:

@ -0,0 +1,76 @@
name: "❓ Ask for help"
description: "Submit any question related to Uptime Kuma"
title: "[Help]: <title>"
labels: [help]
body:
- type: textarea
id: steps-to-reproduce
validations:
required: true
attributes:
label: "📝 Describe your problem"
description: "Please walk us through it step by step."
placeholder: "Describe what are you asking for..."
- type: input
id: uptime-kuma-version
attributes:
label: "🐻 Uptime-Kuma version"
description: "Which version of Uptime-Kuma are you running?"
placeholder: "Ex. 1.9.x"
validations:
required: true
- type: input
id: operating-system
attributes:
label: "💻 Operating System"
description: "Which OS is your server/device running on?"
placeholder: "Ex. Ubuntu 20.04"
validations:
required: true
- type: input
id: browser-vendor
attributes:
label: "🌐 Browser"
description: "Which browser are you running on?"
placeholder: "Ex. Firefox"
validations:
required: true
- type: input
id: docker-version
attributes:
label: "🐋 Docker"
description: "If running with Docker, which version are you running?"
placeholder: "Ex. 20.10.9"
validations:
required: false
- type: input
id: docker-image-tag
attributes:
label: "🏷️ Docker Image Tag"
description: "Which Docker image tag are you using? If running '1' or 'latest', please specify image hash."
placeholder: "Ex. 1.9.1"
validations:
required: false
- type: input
id: nodejs-version
attributes:
label: "🟩 NodeJS Version"
description: "If running with Node.js? which version are you running?"
placeholder: "14.x"
validations:
required: false
- type: checkboxes
id: no-duplicate-issues
attributes:
label: "👀 Have you spent some time to check if this question has been raised before?"
description: "Please search in the issues without filters [here](https://github.com/louislam/uptime-kuma/issues?q=)"
options:
- label: "I checked and didn't find similar question"
required: true
- type: checkboxes
attributes:
label: "🛡️ Security Policy"
description: Please review the security policy before reporting security related issues/bugs.
options:
- label: I agree to have read this project [Security Policy](https://github.com/louislam/uptime-kuma/security/policy)
required: true

@ -1,42 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
**Is it a duplicated question?**
Please search in Issues without filters: https://github.com/louislam/uptime-kuma/issues?q=
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Info**
Uptime Kuma Version:
Using Docker?: Yes/No
Docker Version:
Node.js Version (Without Docker only):
OS:
Browser:
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Error Log**
It is easier for us to find out the problem.
Docker: `docker logs <container id>`
PM2: `~/.pm2/logs/` (e.g. `/home/ubuntu/.pm2/logs`)

@ -0,0 +1,100 @@
name: "🐛 Bug Report"
description: "Submit a bug report to help us improve"
title: "[Bug]: <title>"
labels: [bug]
body:
- type: textarea
id: steps-to-reproduce
validations:
required: true
attributes:
label: "👟 Reproduction steps"
description: "How do you trigger this bug? Please walk us through it step by step."
placeholder: "..."
- type: textarea
id: expected-behavior
validations:
required: true
attributes:
label: "👍 Expected behavior"
description: "What did you think would happen?"
placeholder: "..."
- type: textarea
id: actual-behavior
validations:
required: true
attributes:
label: "👎 Actual Behavior"
description: "What actually happen?"
placeholder: "..."
- type: input
id: uptime-kuma-version
attributes:
label: "🐻 Uptime-Kuma version"
description: "Which version of Uptime-Kuma are you running?"
placeholder: "Ex. 1.9.x"
validations:
required: true
- type: input
id: operating-system
attributes:
label: "💻 Operating System"
description: "Which OS is your server/device running on?"
placeholder: "Ex. Ubuntu 20.04"
validations:
required: true
- type: input
id: browser-vendor
attributes:
label: "🌐 Browser"
description: "Which browser are you running on?"
placeholder: "Ex. Firefox"
validations:
required: true
- type: input
id: docker-version
attributes:
label: "🐋 Docker"
description: "If running with Docker, which version are you running?"
placeholder: "Ex. 20.10.9"
validations:
required: false
- type: input
id: docker-image-tag
attributes:
label: "🏷️ Docker Image Tag"
description: "Which Docker image tag are you using? If running '1' or 'latest', please specify image hash."
placeholder: "Ex. 1.9.1"
validations:
required: false
- type: input
id: nodejs-version
attributes:
label: "🟩 NodeJS Version"
description: "If running with Node.js? which version are you running?"
placeholder: "14.x"
validations:
required: false
- type: textarea
id: logs
attributes:
label: "📝 Relevant log output"
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
render: shell
validations:
required: false
- type: checkboxes
id: no-duplicate-issues
attributes:
label: "👀 Have you spent some time to check if this issue has been raised before?"
description: "Please search in the issues without filters [here](https://github.com/louislam/uptime-kuma/issues?q=)"
options:
- label: "I checked and didn't find similar issue"
required: true
- type: checkboxes
attributes:
label: "🛡️ Security Policy"
description: Please review the security policy before reporting security related issues/bugs.
options:
- label: I agree to have read this project [Security Policy](https://github.com/louislam/uptime-kuma/security/policy)
required: true

@ -1,22 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''
---
**Is it a duplicated question?**
Please search in Issues without filters: https://github.com/louislam/uptime-kuma/issues?q=
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

@ -0,0 +1,59 @@
name: 🚀 Feature Request
description: "Submit a proposal for a new feature"
title: "[Feature]: <title>"
labels: [enhancement]
body:
- type: dropdown
id: feature-area
attributes:
label: "🏷️ Feature Request Type"
description: "What kind of feature request is this?"
multiple: true
options:
- API
- New Notification
- New Monitor
- UI Feature
- Other
validations:
required: true
- type: textarea
id: feature-description
validations:
required: true
attributes:
label: "🔖 Feature description"
description: "A clear and concise description of what the feature request is."
placeholder: "You should add ..."
- type: textarea
id: solution
validations:
required: true
attributes:
label: "✔️ Solution"
description: "A clear and concise description of what you want to happen."
placeholder: "In my use-case, ..."
- type: textarea
id: alternatives
validations:
required: false
attributes:
label: "❓ Alternatives"
description: "A clear and concise description of any alternative solutions or features you've considered."
placeholder: "I have considered ..."
- type: textarea
id: additional-context
validations:
required: false
attributes:
label: "📝 Additional Context"
description: "Add any other context or screenshots about the feature request here."
placeholder: "..."
- type: checkboxes
id: no-duplicate-issues
attributes:
label: "👀 Have you spent some time to check if this feature request has been raised before?"
description: "Please search in the issues without filters [here](https://github.com/louislam/uptime-kuma/issues?q=)"
options:
- label: "I checked and didn't find similar feature request"
required: true

@ -0,0 +1,26 @@
# Description
Fixes #(issue)
## Type of change
Please delete options that are not relevant.
- Bug fix (non-breaking change which fixes an issue)
- User Interface
- New feature (non-breaking change which adds functionality)
- Breaking change (fix or feature that would cause existing functionality to not work as expected)
- Translation update
- Other
- This change requires a documentation update
## Checklist
- [ ] My code follows the style guidelines of this project
- [ ] I ran ESLint and other linters for modified files
- [ ] I have performed a self-review of my own code and test it
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] My changes generate no new warnings
- [ ] My code needed automated testing. I have added them (this is optional task)
## Screenshots (if any)

@ -16,7 +16,7 @@ jobs:
strategy: strategy:
matrix: matrix:
os: [macos-latest, ubuntu-latest, windows-latest] os: [macos-latest, ubuntu-latest, windows-latest]
node-version: [14.x, 16.x] node-version: [14.x, 16.x, 17.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/ # See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps: steps:

@ -29,16 +29,34 @@ The frontend code build into "dist" directory. The server (express.js) exposes t
Generally, if the pull request is working fine and it do not affect any existing logic, workflow and perfomance, I will merge into the master branch once it is tested. Generally, if the pull request is working fine and it do not affect any existing logic, workflow and perfomance, I will merge into the master branch once it is tested.
If you are not sure, feel free to create an empty pull request draft first. If you are not sure whether I will accept your pull request, feel free to create an empty pull request draft first.
### Recommended Pull Request Guideline
1. Fork the project
1. Clone your fork repo to local
1. Create a new branch
1. Create an empty commit
`git commit -m "[empty commit] pull request for <YOUR TASK NAME>" --allow-empty`
1. Push to your fork repo
1. Create a pull request: https://github.com/louislam/uptime-kuma/compare
1. Write a proper description
1. Click "Change to draft"
### Pull Request Examples ### Pull Request Examples
Here are some example situations in the past.
#### ✅ High - Medium Priority #### ✅ High - Medium Priority
Easy to review, no breaking change and not touching the existing code
- Add a new notification - Add a new notification
- Add a chart - Add a chart
- Fix a bug - Fix a bug
- Translations - Translations
- Add a independent new feature
#### *️⃣ Requires one more reviewer #### *️⃣ Requires one more reviewer
@ -46,6 +64,17 @@ I do not have such knowledge to test it.
- Add k8s supports - Add k8s supports
#### ⚠ Low Priority - Harsh Mode
Some pull requests are required to modifiy the core. To be honest, I do not want anyone to try to do that, because it would spend a lot of your time. I will review your pull request harshly. Also you may need to write a lot of unit tests to ensure that there is no breaking change.
- Touch large parts of code of any very important features
- Touch monitoring logic
- Drop a table or drop a column for any reason
- Touch the entry point of Docker or Node.js
- Modifiy auth
#### *️⃣ Low Priority #### *️⃣ Low Priority
It changed my current workflow and require further studies. It changed my current workflow and require further studies.
@ -54,6 +83,7 @@ It changed my current workflow and require further studies.
#### ❌ Won't Merge #### ❌ Won't Merge
- Any breaking changes
- Duplicated pull request - Duplicated pull request
- Buggy - Buggy
- Existing logic is completely modified or deleted - Existing logic is completely modified or deleted
@ -180,6 +210,13 @@ Patch release = the third digit ([Semantic Versioning](https://semver.org/))
Please read: https://github.com/louislam/uptime-kuma/tree/master/src/languages Please read: https://github.com/louislam/uptime-kuma/tree/master/src/languages
## Wiki
Since there is no way to make a pull request to wiki's repo, I have setup another repo to do that.
https://github.com/louislam/uptime-kuma-wiki
## Maintainer ## Maintainer
Check the latest issues and pull requests: Check the latest issues and pull requests:
@ -199,3 +236,19 @@ Checking:
- Check all tags is fine on https://hub.docker.com/r/louislam/uptime-kuma/tags - Check all tags is fine on https://hub.docker.com/r/louislam/uptime-kuma/tags
- Try the Docker image with tag 1.X.X (Clean install / amd64 / arm64 / armv7) - Try the Docker image with tag 1.X.X (Clean install / amd64 / arm64 / armv7)
- Try clean install with Node.js - Try clean install with Node.js
### Release Wiki
#### Setup Repo
```
git clone https://github.com/louislam/uptime-kuma-wiki.git
cd uptime-kuma-wiki
git remote add production https://github.com/louislam/uptime-kuma.wiki.git
```
#### Push to Production Wiki
```
git pull
git push production master
```

@ -1,6 +1,7 @@
# Uptime Kuma # Uptime Kuma
<a target="_blank" href="https://github.com/louislam/uptime-kuma"><img src="https://img.shields.io/github/stars/louislam/uptime-kuma" /></a> <a target="_blank" href="https://hub.docker.com/r/louislam/uptime-kuma"><img src="https://img.shields.io/docker/pulls/louislam/uptime-kuma" /></a> <a target="_blank" href="https://hub.docker.com/r/louislam/uptime-kuma"><img src="https://img.shields.io/docker/v/louislam/uptime-kuma/latest?label=docker%20image%20ver." /></a> <a target="_blank" href="https://github.com/louislam/uptime-kuma"><img src="https://img.shields.io/github/last-commit/louislam/uptime-kuma" /></a> <a target="_blank" href="https://opencollective.com/uptime-kuma"><img src="https://opencollective.com/uptime-kuma/total/badge.svg?label=Backers&color=brightgreen" /></a> <a target="_blank" href="https://github.com/louislam/uptime-kuma"><img src="https://img.shields.io/github/stars/louislam/uptime-kuma" /></a> <a target="_blank" href="https://hub.docker.com/r/louislam/uptime-kuma"><img src="https://img.shields.io/docker/pulls/louislam/uptime-kuma" /></a> <a target="_blank" href="https://hub.docker.com/r/louislam/uptime-kuma"><img src="https://img.shields.io/docker/v/louislam/uptime-kuma/latest?label=docker%20image%20ver." /></a> <a target="_blank" href="https://github.com/louislam/uptime-kuma"><img src="https://img.shields.io/github/last-commit/louislam/uptime-kuma" /></a> <a target="_blank" href="https://opencollective.com/uptime-kuma"><img src="https://opencollective.com/uptime-kuma/total/badge.svg?label=Open%20Collective%20Backers&color=brightgreen" /></a>
[![GitHub Sponsors](https://img.shields.io/github/sponsors/louislam?label=GitHub%20Sponsors)](https://github.com/sponsors/louislam)
<div align="center" width="100%"> <div align="center" width="100%">
<img src="./public/icon.svg" width="128" alt="" /> <img src="./public/icon.svg" width="128" alt="" />
@ -42,7 +43,7 @@ docker run -d --restart=always -p 3001:3001 -v uptime-kuma:/app/data --name upti
Browse to http://localhost:3001 after starting. Browse to http://localhost:3001 after starting.
### 💪🏻 Without Docker ### 💪🏻 Non-Docker
Required Tools: Node.js >= 14, git and pm2. Required Tools: Node.js >= 14, git and pm2.

@ -9,8 +9,8 @@ currently being supported with security updates.
| Version | Supported | | Version | Supported |
| ------- | ------------------ | | ------- | ------------------ |
| 1.8.X | :white_check_mark: | | 1.9.X | :white_check_mark: |
| <= 1.7.X | ❌ | | <= 1.8.X | ❌ |
### Upgradable Docker Tags ### Upgradable Docker Tags

@ -34,9 +34,11 @@ function download(url) {
}); });
tarStream.on("close", () => { tarStream.on("close", () => {
fs.rmdirSync("./dist-backup", { if (fs.existsSync("./dist-backup")) {
recursive: true fs.rmdirSync("./dist-backup", {
}); recursive: true
});
}
console.log("Done"); console.log("Done");
}); });
@ -44,7 +46,7 @@ function download(url) {
if (fs.existsSync("./dist-backup")) { if (fs.existsSync("./dist-backup")) {
fs.renameSync("./dist-backup", "./dist"); fs.renameSync("./dist-backup", "./dist");
} }
console.log("Done"); console.error("Error from tarStream");
}); });
response.pipe(tarStream); response.pipe(tarStream);

11
package-lock.json generated

@ -33,6 +33,7 @@
"http-graceful-shutdown": "~3.1.4", "http-graceful-shutdown": "~3.1.4",
"iconv-lite": "^0.6.3", "iconv-lite": "^0.6.3",
"jsonwebtoken": "~8.5.1", "jsonwebtoken": "~8.5.1",
"jwt-decode": "^3.1.2",
"limiter": "^2.1.0", "limiter": "^2.1.0",
"nodemailer": "~6.6.5", "nodemailer": "~6.6.5",
"notp": "~2.0.3", "notp": "~2.0.3",
@ -7846,6 +7847,11 @@
"safe-buffer": "^5.0.1" "safe-buffer": "^5.0.1"
} }
}, },
"node_modules/jwt-decode": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz",
"integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A=="
},
"node_modules/kind-of": { "node_modules/kind-of": {
"version": "3.2.2", "version": "3.2.2",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
@ -18495,6 +18501,11 @@
"safe-buffer": "^5.0.1" "safe-buffer": "^5.0.1"
} }
}, },
"jwt-decode": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz",
"integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A=="
},
"kind-of": { "kind-of": {
"version": "3.2.2", "version": "3.2.2",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",

@ -76,6 +76,7 @@
"http-graceful-shutdown": "~3.1.4", "http-graceful-shutdown": "~3.1.4",
"iconv-lite": "^0.6.3", "iconv-lite": "^0.6.3",
"jsonwebtoken": "~8.5.1", "jsonwebtoken": "~8.5.1",
"jwt-decode": "^3.1.2",
"limiter": "^2.1.0", "limiter": "^2.1.0",
"nodemailer": "~6.6.5", "nodemailer": "~6.6.5",
"notp": "~2.0.3", "notp": "~2.0.3",

@ -114,6 +114,7 @@ class Database {
// Change to WAL // Change to WAL
await R.exec("PRAGMA journal_mode = WAL"); await R.exec("PRAGMA journal_mode = WAL");
await R.exec("PRAGMA cache_size = -12000"); await R.exec("PRAGMA cache_size = -12000");
await R.exec("PRAGMA auto_vacuum = FULL");
console.log("SQLite config:"); console.log("SQLite config:");
console.log(await R.getAll("PRAGMA journal_mode")); console.log(await R.getAll("PRAGMA journal_mode"));
@ -374,6 +375,17 @@ class Database {
console.log("Nothing to restore"); console.log("Nothing to restore");
} }
} }
static getSize() {
debug("Database.getSize()");
let stats = fs.statSync(Database.path);
debug(stats);
return stats.size;
}
static async shrink() {
await R.exec("VACUUM");
}
} }
module.exports = Database; module.exports = Database;

@ -351,6 +351,10 @@ class Monitor extends BeanModel {
if (isImportant) { if (isImportant) {
bean.important = true; bean.important = true;
await Monitor.sendNotification(isFirstBeat, this, bean); await Monitor.sendNotification(isFirstBeat, this, bean);
// Clear Status Page Cache
apicache.clear();
} else { } else {
bean.important = false; bean.important = false;
} }
@ -383,18 +387,32 @@ class Monitor extends BeanModel {
} }
} }
this.heartbeatInterval = setTimeout(beat, beatInterval * 1000); this.heartbeatInterval = setTimeout(safeBeat, beatInterval * 1000);
} }
}; };
const safeBeat = async () => {
try {
await beat();
} catch (e) {
console.trace(e);
console.error("Please report to https://github.com/louislam/uptime-kuma/issues");
if (! this.isStop) {
console.log("Try to restart the monitor");
this.heartbeatInterval = setTimeout(safeBeat, this.interval * 1000);
}
}
};
// Delay Push Type // Delay Push Type
if (this.type === "push") { if (this.type === "push") {
setTimeout(() => { setTimeout(() => {
beat(); safeBeat();
}, this.interval * 1000); }, this.interval * 1000);
} else { } else {
beat(); safeBeat();
} }
} }
@ -598,9 +616,6 @@ class Monitor extends BeanModel {
console.log(e); console.log(e);
} }
} }
// Clear Status Page Cache
apicache.clear();
} }
} }

@ -0,0 +1,89 @@
//
// bark.js
// UptimeKuma
//
// Created by Lakr Aream on 2021/10/24.
// Copyright © 2021 Lakr Aream. All rights reserved.
//
const NotificationProvider = require("./notification-provider");
const { DOWN, UP } = require("../../src/util");
const { default: axios } = require("axios");
// bark is an APN bridge that sends notifications to Apple devices.
const barkNotificationGroup = "UptimeKuma";
const barkNotificationAvatar = "https://github.com/louislam/uptime-kuma/raw/master/public/icon.png";
const barkNotificationSound = "telegraph";
const successMessage = "Successes!";
class Bark extends NotificationProvider {
name = "Bark";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
try {
var barkEndpoint = notification.barkEndpoint;
// check if the endpoint has a "/" suffix, if so, delete it first
if (barkEndpoint.endsWith("/")) {
barkEndpoint = barkEndpoint.substring(0, barkEndpoint.length - 1);
}
if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] == UP) {
let title = "UptimeKuma Monitor Up";
return await this.postNotification(title, msg, barkEndpoint);
}
if (msg != null && heartbeatJSON != null && heartbeatJSON["status"] == DOWN) {
let title = "UptimeKuma Monitor Down";
return await this.postNotification(title, msg, barkEndpoint);
}
if (msg != null) {
let title = "UptimeKuma Message";
return await this.postNotification(title, msg, barkEndpoint);
}
} catch (error) {
throw error;
}
}
// add additional parameter for better on device styles (iOS 15 optimized)
appendAdditionalParameters(postUrl) {
// grouping all our notifications
postUrl += "?group=" + barkNotificationGroup;
// set icon to uptime kuma icon, 11kb should be fine
postUrl += "&icon=" + barkNotificationAvatar;
// picked a sound, this should follow system's mute status when arrival
postUrl += "&sound=" + barkNotificationSound;
return postUrl;
}
// thrown if failed to check result, result code should be in range 2xx
checkResult(result) {
if (result.status == null) {
throw new Error("Bark notification failed with invalid response!");
}
if (result.status < 200 || result.status >= 300) {
throw new Error("Bark notification failed with status code " + result.status);
}
}
async postNotification(title, subtitle, endpoint) {
// url encode title and subtitle
title = encodeURIComponent(title);
subtitle = encodeURIComponent(subtitle);
let postUrl = endpoint + "/" + title + "/" + subtitle;
postUrl = this.appendAdditionalParameters(postUrl);
let result = await axios.get(postUrl);
this.checkResult(result);
if (result.statusText != null) {
return "Bark notification succeed: " + result.statusText;
}
// because returned in range 200 ..< 300
return successMessage;
}
}
module.exports = Bark;

@ -0,0 +1,42 @@
const NotificationProvider = require("./notification-provider");
const axios = require("axios");
class ClickSendSMS extends NotificationProvider {
name = "clicksendsms";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
let okMsg = "Sent Successfully.";
try {
console.log({ notification });
let config = {
headers: {
"Content-Type": "application/json",
"Authorization": "Basic " + Buffer.from(notification.clicksendsmsLogin + ":" + notification.clicksendsmsPassword).toString('base64'),
"Accept": "text/json",
}
};
let data = {
messages: [
{
"body": msg.replace(/[^\x00-\x7F]/g, ""),
"to": notification.clicksendsmsToNumber,
"source": "uptime-kuma",
"from": notification.clicksendsmsSenderName,
}
]
};
let resp = await axios.post("https://rest.clicksend.com/v3/sms/send", data, config);
if (resp.data.data.messages[0].status !== "SUCCESS") {
let error = "Something gone wrong. Api returned " + resp.data.data.messages[0].status + ".";
this.throwGeneralAxiosError(error);
}
return okMsg;
} catch (error) {
this.throwGeneralAxiosError(error);
}
}
}
module.exports = ClickSendSMS;

@ -8,6 +8,7 @@ const Mattermost = require("./notification-providers/mattermost");
const Matrix = require("./notification-providers/matrix"); const Matrix = require("./notification-providers/matrix");
const Octopush = require("./notification-providers/octopush"); const Octopush = require("./notification-providers/octopush");
const PromoSMS = require("./notification-providers/promosms"); const PromoSMS = require("./notification-providers/promosms");
const ClickSendSMS = require("./notification-providers/clicksendsms");
const Pushbullet = require("./notification-providers/pushbullet"); const Pushbullet = require("./notification-providers/pushbullet");
const Pushover = require("./notification-providers/pushover"); const Pushover = require("./notification-providers/pushover");
const Pushy = require("./notification-providers/pushy"); const Pushy = require("./notification-providers/pushy");
@ -21,6 +22,7 @@ const Webhook = require("./notification-providers/webhook");
const Feishu = require("./notification-providers/feishu"); 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");
class Notification { class Notification {
@ -45,6 +47,7 @@ class Notification {
new Matrix(), new Matrix(),
new Octopush(), new Octopush(),
new PromoSMS(), new PromoSMS(),
new ClickSendSMS(),
new Pushbullet(), new Pushbullet(),
new Pushover(), new Pushover(),
new Pushy(), new Pushy(),
@ -54,6 +57,7 @@ class Notification {
new SMTP(), new SMTP(),
new Telegram(), new Telegram(),
new Webhook(), new Webhook(),
new Bark(),
]; ];
for (let item of list) { for (let item of list) {

@ -119,6 +119,7 @@ module.exports.io = io;
// Must be after io instantiation // Must be after io instantiation
const { sendNotificationList, sendHeartbeatList, sendImportantHeartbeatList, sendInfo } = require("./client"); const { sendNotificationList, sendHeartbeatList, sendImportantHeartbeatList, sendInfo } = require("./client");
const { statusPageSocketHandler } = require("./socket-handlers/status-page-socket-handler"); const { statusPageSocketHandler } = require("./socket-handlers/status-page-socket-handler");
const databaseSocketHandler = require("./socket-handlers/database-socket-handler");
app.use(express.json()); app.use(express.json());
@ -644,6 +645,38 @@ exports.entryPage = "dashboard";
} }
}); });
socket.on("getMonitorBeats", async (monitorID, period, callback) => {
try {
checkLogin(socket);
console.log(`Get Monitor Beats: ${monitorID} User ID: ${socket.userID}`);
if (period == null) {
throw new Error("Invalid period.");
}
let list = await R.getAll(`
SELECT * FROM heartbeat
WHERE monitor_id = ? AND
time > DATETIME('now', '-' || ? || ' hours')
ORDER BY time ASC
`, [
monitorID,
period,
]);
callback({
ok: true,
data: list,
});
} catch (e) {
callback({
ok: false,
msg: e.message,
});
}
});
// Start or Resume the monitor // Start or Resume the monitor
socket.on("resumeMonitor", async (monitorID, callback) => { socket.on("resumeMonitor", async (monitorID, callback) => {
try { try {
@ -1263,6 +1296,7 @@ exports.entryPage = "dashboard";
// Status Page Socket Handler for admin only // Status Page Socket Handler for admin only
statusPageSocketHandler(socket); statusPageSocketHandler(socket);
databaseSocketHandler(socket);
debug("added all socket handlers"); debug("added all socket handlers");

@ -0,0 +1,37 @@
const { checkLogin } = require("../util-server");
const Database = require("../database");
module.exports = (socket) => {
// Post or edit incident
socket.on("getDatabaseSize", async (callback) => {
try {
checkLogin(socket);
callback({
ok: true,
size: Database.getSize(),
});
} catch (error) {
callback({
ok: false,
msg: error.message,
});
}
});
socket.on("shrinkDatabase", async (callback) => {
try {
checkLogin(socket);
Database.shrink();
callback({
ok: true,
});
} catch (error) {
callback({
ok: false,
msg: error.message,
});
}
});
};

@ -1,16 +1,34 @@
<template> <template>
<LineChart :chart-data="chartData" :options="chartOptions" /> <div>
<div class="period-options">
<button type="button" class="btn btn-light dropdown-toggle btn-period-toggle" data-bs-toggle="dropdown" aria-expanded="false">
{{ chartPeriodOptions[chartPeriodHrs] }}&nbsp;
</button>
<ul class="dropdown-menu dropdown-menu-end">
<li v-for="(item, key) in chartPeriodOptions" :key="key">
<a class="dropdown-item" :class="{ active: chartPeriodHrs == key }" href="#" @click="chartPeriodHrs = key">{{ item }}</a>
</li>
</ul>
</div>
<div class="chart-wrapper" :class="{ loading : loading}">
<LineChart :chart-data="chartData" :options="chartOptions" />
</div>
</div>
</template> </template>
<script> <script lang="ts">
import { BarController, BarElement, Chart, Filler, LinearScale, LineController, LineElement, PointElement, TimeScale, Tooltip } from "chart.js"; import { BarController, BarElement, Chart, Filler, LinearScale, LineController, LineElement, PointElement, TimeScale, Tooltip } from "chart.js";
import dayjs from "dayjs"; import dayjs from "dayjs";
import utc from "dayjs/plugin/utc"; import utc from "dayjs/plugin/utc";
import timezone from "dayjs/plugin/timezone"; import timezone from "dayjs/plugin/timezone";
import "chartjs-adapter-dayjs"; import "chartjs-adapter-dayjs";
import { LineChart } from "vue-chart-3"; import { LineChart } from "vue-chart-3";
import { useToast } from "vue-toastification";
import { UP, DOWN, PENDING } from "../util.ts";
dayjs.extend(utc); dayjs.extend(utc);
dayjs.extend(timezone); dayjs.extend(timezone);
const toast = useToast();
Chart.register(LineController, BarController, LineElement, PointElement, TimeScale, BarElement, LinearScale, Tooltip, Filler); Chart.register(LineController, BarController, LineElement, PointElement, TimeScale, BarElement, LinearScale, Tooltip, Filler);
@ -24,8 +42,23 @@ export default {
}, },
data() { data() {
return { return {
loading: false,
// Configurable filtering on top of the returned data // Configurable filtering on top of the returned data
chartPeriodHrs: 6, chartPeriodHrs: 0,
chartPeriodOptions: {
0: this.$t("recent"),
3: "3h",
6: "6h",
24: "24h",
168: "1w",
},
// A heartbeatList for 3h, 6h, 24h, 1w
// Uses the $root.heartbeatList when value is null
heartbeatList: null
}; };
}, },
computed: { computed: {
@ -117,7 +150,7 @@ export default {
}, },
callbacks: { callbacks: {
label: (context) => { label: (context) => {
return ` ${new Intl.NumberFormat().format(context.parsed.y)} ms` return ` ${new Intl.NumberFormat().format(context.parsed.y)} ms`;
}, },
} }
}, },
@ -125,27 +158,36 @@ export default {
display: false, display: false,
}, },
}, },
} };
}, },
chartData() { chartData() {
let pingData = []; // Ping Data for Line Chart, y-axis contains ping time let pingData = []; // Ping Data for Line Chart, y-axis contains ping time
let downData = []; // Down Data for Bar Chart, y-axis is 1 if target is down, 0 if target is up let downData = []; // Down Data for Bar Chart, y-axis is 1 if target is down, 0 if target is up
if (this.monitorId in this.$root.heartbeatList) {
this.$root.heartbeatList[this.monitorId] let heartbeatList = this.heartbeatList ||
.filter( (this.monitorId in this.$root.heartbeatList && this.$root.heartbeatList[this.monitorId]) ||
(beat) => dayjs.utc(beat.time).tz(this.$root.timezone).isAfter(dayjs().subtract(this.chartPeriodHrs, "hours"))) [];
.map((beat) => {
const x = this.$root.datetime(beat.time); heartbeatList
pingData.push({ .filter(
x, // Filtering as data gets appended
y: beat.ping, // not the most efficient, but works for now
}); (beat) => dayjs.utc(beat.time).tz(this.$root.timezone).isAfter(
downData.push({ dayjs().subtract(Math.max(this.chartPeriodHrs, 6), "hours")
x, )
y: beat.status === 0 ? 1 : 0, )
}) .map((beat) => {
const x = this.$root.datetime(beat.time);
pingData.push({
x,
y: beat.ping,
}); });
} downData.push({
x,
y: beat.status === DOWN ? 1 : 0,
});
});
return { return {
datasets: [ datasets: [
{ {
@ -172,5 +214,110 @@ export default {
}; };
}, },
}, },
watch: {
// Update chart data when the selected chart period changes
chartPeriodHrs: function (newPeriod) {
if (newPeriod == "0") {
newPeriod = null;
this.heartbeatList = null;
} else {
this.loading = true;
this.$root.getMonitorBeats(this.monitorId, newPeriod, (res) => {
if (!res.ok) {
toast.error(res.msg);
} else {
this.heartbeatList = res.data;
}
this.loading = false;
});
}
}
},
created() {
// Setup Watcher on the root heartbeatList,
// And mirror latest change to this.heartbeatList
this.$watch(() => this.$root.heartbeatList[this.monitorId],
(heartbeatList) => {
if (this.chartPeriodHrs != 0) {
const newBeat = heartbeatList.at(-1);
if (newBeat && dayjs.utc(newBeat.time) > dayjs.utc(this.heartbeatList.at(-1)?.time)) {
this.heartbeatList.push(heartbeatList.at(-1));
}
}
},
{ deep: true }
);
}
}; };
</script> </script>
<style lang="scss" scoped>
@import "../assets/vars.scss";
.form-select {
width: unset;
display: inline-flex;
}
.period-options {
padding: 0.1em 1em;
margin-bottom: -1.2em;
float: right;
position: relative;
z-index: 10;
.dropdown-menu {
padding: 0;
min-width: 50px;
font-size: 0.9em;
.dark & {
background: $dark-bg;
}
.dropdown-item {
border-radius: 0.3rem;
padding: 2px 16px 4px 16px;
.dark & {
background: $dark-bg;
}
.dark &:hover {
background: $dark-font-color;
}
}
.dark & .dropdown-item.active {
background: $primary;
color: $dark-font-color2;
}
}
.btn-period-toggle {
padding: 2px 15px;
background: transparent;
border: 0;
color: $link-color;
opacity: 0.7;
font-size: 0.9em;
&::after {
vertical-align: 0.155em;
}
.dark & {
color: $dark-font-color;
}
}
}
.chart-wrapper {
margin-bottom: 0.5em;
&.loading {
filter: blur(10px);
}
}
</style>

@ -0,0 +1,15 @@
<template>
<div class="mb-3">
<label for="Bark Endpoint" class="form-label">{{ $t("Bark Endpoint") }}<span style="color: red;"><sup>*</sup></span></label>
<input id="Bark Endpoint" v-model="$parent.notification.barkEndpoint" type="text" class="form-control" required>
<div class="form-text">
<p><span style="color: red;"><sup>*</sup></span>{{ $t("Required") }}</p>
</div>
<i18n-t tag="div" keypath="wayToGetTeamsURL" class="form-text">
<a
href="https://github.com/Finb/Bark"
target="_blank"
>{{ $t("here") }}</a>
</i18n-t>
</div>
</template>

@ -0,0 +1,38 @@
<template>
<div class="mb-3">
<label for="clicksendsms-login" class="form-label">API Username</label>
<div class="form-text">
{{ $t("apiCredentials") }}
<a href="http://dashboard.clicksend.com/account/subaccounts" target="_blank">here</a>
</div>
<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>
<HiddenInput id="clicksendsms-key" v-model="$parent.notification.clicksendsmsPassword" :required="true" autocomplete="one-time-code"></HiddenInput>
</div>
<div class="mb-3">
<div class="form-text">
{{ $t("checkPrice", [$t("clicksendsms")]) }}
<a href="https://www.clicksend.com/us/pricing" target="_blank">https://clicksend.com/us/pricing</a>
</div>
</div>
<div class="mb-3">
<label for="clicksendsms-to-number" class="form-label">Recipient Number</label>
<input id="clicksendsms-to-number" v-model="$parent.notification.clicksendsmsToNumber" type="text" minlength="8" maxlength="14" class="form-control" required>
</div>
<div class="mb-3">
<label for="clicksendsms-sender-name" class="form-label">From Name/Number -
<a href="https://help.clicksend.com/article/4kgj7krx00-what-is-a-sender-id-or-sender-number" target="_blank">More Info</a>
</label>
<input id="clicksendsms-sender-name" v-model="$parent.notification.clicksendsmsSenderName" type="text" minlength="3" maxlength="11" class="form-control">
<div class="form-text">Leave blank to use a shared sender number.</div>
</div>
</template>
<script>
import HiddenInput from "../HiddenInput.vue";
export default {
components: {
HiddenInput,
},
};
</script>

@ -11,6 +11,7 @@ import Pushover from "./Pushover.vue";
import Pushy from "./Pushy.vue"; import Pushy from "./Pushy.vue";
import Octopush from "./Octopush.vue"; import Octopush from "./Octopush.vue";
import PromoSMS from "./PromoSMS.vue"; import PromoSMS from "./PromoSMS.vue";
import ClickSendSMS from "./ClickSendSMS.vue";
import LunaSea from "./LunaSea.vue"; import LunaSea from "./LunaSea.vue";
import Feishu from "./Feishu.vue"; import Feishu from "./Feishu.vue";
import Apprise from "./Apprise.vue"; import Apprise from "./Apprise.vue";
@ -20,6 +21,7 @@ import Mattermost from "./Mattermost.vue";
import Matrix from "./Matrix.vue"; 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";
/** /**
* Manage all notification form. * Manage all notification form.
@ -40,6 +42,7 @@ const NotificationFormList = {
"pushy": Pushy, "pushy": Pushy,
"octopush": Octopush, "octopush": Octopush,
"promosms": PromoSMS, "promosms": PromoSMS,
"clicksendsms": ClickSendSMS,
"lunasea": LunaSea, "lunasea": LunaSea,
"Feishu": Feishu, "Feishu": Feishu,
"AliyunSMS": AliyunSMS, "AliyunSMS": AliyunSMS,
@ -48,7 +51,8 @@ const NotificationFormList = {
"line": Line, "line": Line,
"mattermost": Mattermost, "mattermost": Mattermost,
"matrix": Matrix, "matrix": Matrix,
"DingDing": DingDing "DingDing": DingDing,
"Bark": Bark
} }
export default NotificationFormList export default NotificationFormList

@ -6,7 +6,7 @@ export default {
ignoreTLSError: "Игнорирай TLS/SSL грешки за HTTPS уебсайтове", ignoreTLSError: "Игнорирай TLS/SSL грешки за HTTPS уебсайтове",
upsideDownModeDescription: "Обръща статуса от достъпен на недостъпен. Ако услугата е достъпна, ще се вижда като НЕДОСТЪПНА.", upsideDownModeDescription: "Обръща статуса от достъпен на недостъпен. Ако услугата е достъпна, ще се вижда като НЕДОСТЪПНА.",
maxRedirectDescription: "Максимален брой пренасочвания, които да бъдат следвани. Въведете 0 за да изключите пренасочване.", maxRedirectDescription: "Максимален брой пренасочвания, които да бъдат следвани. Въведете 0 за да изключите пренасочване.",
acceptedStatusCodesDescription: "Изберете статус кодове, които се считат за успешен отговор.", acceptedStatusCodesDescription: "Изберете статус кодове, които да се считат за успешен отговор.",
passwordNotMatchMsg: "Повторената парола не съвпада.", passwordNotMatchMsg: "Повторената парола не съвпада.",
notificationDescription: "Моля, задайте известието към монитор(и), за да функционира.", notificationDescription: "Моля, задайте известието към монитор(и), за да функционира.",
keywordDescription: "Търси ключова дума в чист html или JSON отговор - чувствителна е към регистъра", keywordDescription: "Търси ключова дума в чист html или JSON отговор - чувствителна е към регистъра",
@ -130,7 +130,7 @@ export default {
"Clear Data": "Изтрий данни", "Clear Data": "Изтрий данни",
Events: "Събития", Events: "Събития",
Heartbeats: "Проверки", Heartbeats: "Проверки",
"Auto Get": "Автоматияно получаване", "Auto Get": "Авт. попълване",
backupDescription: "Можете да архивирате всички монитори и всички известия в JSON файл.", backupDescription: "Можете да архивирате всички монитори и всички известия в JSON файл.",
backupDescription2: "PS: Данни за история и събития не са включени.", backupDescription2: "PS: Данни за история и събития не са включени.",
backupDescription3: "Чувствителни данни, като токен кодове за известяване, се съдържат в експортирания файл. Моля, бъдете внимателни с неговото съхранение.", backupDescription3: "Чувствителни данни, като токен кодове за известяване, се съдържат в експортирания файл. Моля, бъдете внимателни с неговото съхранение.",
@ -199,7 +199,7 @@ export default {
"Status Page": "Статус страница", "Status Page": "Статус страница",
"Primary Base URL": "Основен базов URL адрес", "Primary Base URL": "Основен базов URL адрес",
"Push URL": "Генериран Push URL адрес", "Push URL": "Генериран Push URL адрес",
needPushEvery: "Необходимо е да извършвате заявка към този URL адрес на всеки {0} секунди.", needPushEvery: "Необходимо е да извършвате заявка към този URL адрес на всеки {0} секунди",
pushOptionalParams: "Допълнителни, но незадължителни параметри: {0}", pushOptionalParams: "Допълнителни, но незадължителни параметри: {0}",
defaultNotificationName: "Моето {notification} известяване ({number})", defaultNotificationName: "Моето {notification} известяване ({number})",
here: "тук", here: "тук",
@ -252,14 +252,14 @@ export default {
"More info on:": "Повече информация на: {0}", "More info on:": "Повече информация на: {0}",
pushoverDesc1: "Приоритет Спешно (2) по подразбиране изчаква 30 секунди между повторните опити и изтича след 1 час.", pushoverDesc1: "Приоритет Спешно (2) по подразбиране изчаква 30 секунди между повторните опити и изтича след 1 час.",
pushoverDesc2: "Ако желаете да изпратите известявания до различни устройства, попълнете полето Устройство.", pushoverDesc2: "Ако желаете да изпратите известявания до различни устройства, попълнете полето Устройство.",
"SMS Type": "СМС тип", "SMS Type": "SMS тип",
octopushTypePremium: "Премиум (Бърз - препоръчителен в случай на тревога)", octopushTypePremium: "Премиум (Бърз - препоръчителен в случай на тревога)",
octopushTypeLowCost: "Евтин (Бавен - понякога бива блокиран от оператора)", octopushTypeLowCost: "Евтин (Бавен - понякога бива блокиран от оператора)",
checkPrice: "Тарифни планове на {0}:", checkPrice: "Тарифни планове на {0}:",
octopushLegacyHint: "Дали използвате съвместима версия на Octopush (2011-2020) или нова версия?", octopushLegacyHint: "Дали използвате съвместима версия на Octopush (2011-2020) или нова версия?",
"Check octopush prices": "Тарифни планове на octopush {0}.", "Check octopush prices": "Тарифни планове на octopush {0}.",
octopushPhoneNumber: "Телефонен номер (в международен формат, например: +33612345678) ", octopushPhoneNumber: "Телефонен номер (в международен формат, например: +33612345678) ",
octopushSMSSender: "СМС подател Име: 3-11 знака - букви, цифри и интервал (a-zA-Z0-9)", octopushSMSSender: "SMS подател Име: 3-11 знака - букви, цифри и интервал (a-zA-Z0-9)",
"LunaSea Device ID": "LunaSea ID на устройство", "LunaSea Device ID": "LunaSea ID на устройство",
"Apprise URL": "Apprise URL адрес", "Apprise URL": "Apprise URL адрес",
"Example:": "Пример: {0}", "Example:": "Пример: {0}",
@ -280,12 +280,12 @@ export default {
aboutIconURL: "Може да предоставите линк към картинка в поле \"URL Адрес за иконка\" за да отмените картинката на профила по подразбиране. Няма да се използва, ако вече сте настроили емотикон.", aboutIconURL: "Може да предоставите линк към картинка в поле \"URL Адрес за иконка\" за да отмените картинката на профила по подразбиране. Няма да се използва, ако вече сте настроили емотикон.",
aboutMattermostChannelName: "Може да замените канала по подразбиране, към който публикува уеб куката, като въведете името на канала в полето \"Канал име\". Tрябва да бъде активирано в настройките за уеб кука на Mattermost. Например: #other-channel", aboutMattermostChannelName: "Може да замените канала по подразбиране, към който публикува уеб куката, като въведете името на канала в полето \"Канал име\". Tрябва да бъде активирано в настройките за уеб кука на Mattermost. Например: #other-channel",
matrix: "Matrix", matrix: "Matrix",
promosmsTypeEco: "СМС ECO - евтин, но бавен. Често е претоварен. Само за получатели от Полша.", promosmsTypeEco: "SMS ECO - евтин, но бавен. Често е претоварен. Само за получатели от Полша.",
promosmsTypeFlash: "СМС FLASH - Съобщението автоматично се показва на устройството на получателя. Само за получатели от Полша.", promosmsTypeFlash: "SMS FLASH - Съобщението автоматично се показва на устройството на получателя. Само за получатели от Полша.",
promosmsTypeFull: "СМС FULL - Високо ниво на СМС услуга. Може да използвате Вашето име като подател (Необходимо е първо да регистрирате името). Надежден метод за съобщения тип тревога.", promosmsTypeFull: "SMS FULL - Високо ниво на SMS услуга. Може да използвате Вашето име като подател (Необходимо е първо да регистрирате името). Надежден метод за съобщения тип тревога.",
promosmsTypeSpeed: "СМС SPEED - Най-висок приоритет в системата. Много бърза и надеждна, но същвременно скъпа услуга. (Около два пъти по-висока цена в сравнение с SMS FULL).", promosmsTypeSpeed: "SMS SPEED - Най-висок приоритет в системата. Много бърза и надеждна, но същвременно скъпа услуга. (Около два пъти по-висока цена в сравнение с SMS FULL).",
promosmsPhoneNumber: "Телефонен номер (за получатели от Полша, може да пропуснете въвеждането на код за населено място)", promosmsPhoneNumber: "Телефонен номер (за получатели от Полша, може да пропуснете въвеждането на код за населено място)",
promosmsSMSSender: "СМС Подател име: Предварително регистрирано име или някое от имената по подразбиране: InfoSMS, SMS Info, MaxSMS, INFO, SMS", promosmsSMSSender: "SMS Подател име: Предварително регистрирано име или някое от имената по подразбиране: InfoSMS, SMS Info, MaxSMS, INFO, SMS",
"Feishu WebHookUrl": "Feishu URL адрес за уеб кука", "Feishu WebHookUrl": "Feishu URL адрес за уеб кука",
matrixHomeserverURL: "Сървър URL адрес (започва с http(s):// и порт по желание)", matrixHomeserverURL: "Сървър URL адрес (започва с http(s):// и порт по желание)",
"Internal Room Id": "ID на вътрешна стая", "Internal Room Id": "ID на вътрешна стая",
@ -297,7 +297,7 @@ export default {
PushUrl: "Push URL адрес", PushUrl: "Push URL адрес",
HeadersInvalidFormat: "Заявените хедъри не са валидни JSON: ", HeadersInvalidFormat: "Заявените хедъри не са валидни JSON: ",
BodyInvalidFormat: "Заявеното съобщение не е валиден JSON: ", BodyInvalidFormat: "Заявеното съобщение не е валиден JSON: ",
"Monitor History": "История на мониторите:", "Monitor History": "История на мониторите",
clearDataOlderThan: "Ще се съхранява за {0} дни.", clearDataOlderThan: "Ще се съхранява за {0} дни.",
records: "записа", records: "записа",
"One record": "Един запис", "One record": "Един запис",

@ -197,4 +197,112 @@ export default {
pushbullet: "Pushbullet", pushbullet: "Pushbullet",
line: "Line Messenger", line: "Line Messenger",
mattermost: "Mattermost", mattermost: "Mattermost",
"Primary Base URL": "Primär URL",
"Push URL": "Push URL",
needPushEvery: "Du solltest diese URL alle {0} Sekunden aufrufen",
pushOptionalParams: "Optionale Parameter: {0}",
defaultNotificationName: "Meine {notification} Alarm ({number})",
here: "hier",
Required: "Erforderlich",
"Bot Token": "Bot Token",
wayToGetTelegramToken: "Hier kannst du einen Token erhalten {0}.",
"Chat ID": "Chat ID",
supportTelegramChatID: "Unterstützt Direkt Chat / Gruppe / Kanal Chat-ID's",
wayToGetTelegramChatID: "Du kannst die Chat-ID erhalten, indem du eine Nachricht an den Bot sendest und zu dieser URL gehst, um die chat_id: zu sehen.",
"YOUR BOT TOKEN HERE": "HIER DEIN BOT TOKEN",
chatIDNotFound: "Chat-ID wurde nicht gefunden: bitte sende zuerst eine Nachricht an diesen Bot",
"Post URL": "Post URL",
"Content Type": "Content Type",
webhookJsonDesc: "{0} ist gut für alle modernen HTTP-Server sowie Express.js",
webhookFormDataDesc: "{multipart} ist gut für PHP. Die JSON muss mit {decodeFunction} geparst werden",
secureOptionNone: "Keine / STARTTLS (25, 587)",
secureOptionTLS: "TLS (465)",
"Ignore TLS Error": "TLS-Fehler ignorieren",
"From Email": "Von Email",
emailCustomSubject: "Benutzerdefinierter Betreff",
"To Email": "Zu Email",
smtpCC: "CC",
smtpBCC: "BCC",
"Discord Webhook URL": "Discord Webhook URL",
wayToGetDiscordURL: "Du kannst diesen erhalten, indem du zu den Servereinstellungen gehst -> Integrationen -> Neuer Webhook",
"Bot Display Name": "Bot-Anzeigename",
"Prefix Custom Message": "Benutzerdefinierter Nachrichten Präfix",
"Hello @everyone is...": "Hallo {'@'}everyone ist...",
"Webhook URL": "Webhook URL",
wayToGetTeamsURL: "Hier erfährst du, wie eine Webhook-URL erstellt werden kann {0}.",
Number: "Nummer",
Recipients: "Empfänger",
needSignalAPI: "Es wird ein Signal Client mit REST-API benötigt.",
wayToCheckSignalURL: "Du kannst diese URL aufrufen, um zu sehen, wie du eine einrichtest:",
signalImportant: "WICHTIG: Gruppen und Nummern können in Empfängern nicht gemischt werden!",
"Application Token": "Anwendungs Token",
"Server URL": "Server URL",
Priority: "Priorität",
"Icon Emoji": "Icon Emoji",
"Channel Name": "Kanalname",
"Uptime Kuma URL": "Uptime Kuma URL",
aboutWebhooks: "Weitere Informationen zu Webhooks auf: {0}",
aboutChannelName: "Gebe den Kanalnamen ein auf {0} Feld Kanalname, wenn du den Webhook-Kanal umgehen möchtest. Ex: #other-channel",
aboutKumaURL: "Wenn das Feld für die Uptime Kuma URL leer gelassen wird, wird es standardmäßig die GitHub Projekt Seite verwenden.",
emojiCheatSheet: "Emoji Cheat Sheet: {0}",
"User Key": "Benutzerschlüssel",
Device: "Gerät",
"Message Title": "Nachrichtentitel",
"Notification Sound": "Benachrichtigungston",
"More info on:": "Mehr Infos auf: {0}",
pushoverDesc1: "Notfallpriorität (2) hat Standardmäßig 30 Sekunden Auszeit, zwischen den Versuchen und läuft nach 1 Stunde ab.",
pushoverDesc2: "Fülle das Geräte Feld aus, wenn du Benachrichtigungen an verschiedene Geräte senden möchtest.",
"SMS Type": "SMS Typ",
octopushTypePremium: "Premium (Schnell - zur Benachrichtigung empfohlen)",
octopushTypeLowCost: "Kostengünstig (Langsam - manchmal vom Betreiber gesperrt)",
checkPrice: "Prüfe {0} Preise:",
octopushLegacyHint: "Verwendest du die Legacy-Version von Octopush (2011-2020) oder die neue Version?",
"Check octopush prices": "Überprüfe die Oktopush Preise {0}.",
octopushPhoneNumber: "Telefonnummer (Internationales Format, z.B : +49612345678) ",
octopushSMSSender: "Name des SMS-Absenders : 3-11 alphanumerische Zeichen und Leerzeichen (a-zA-Z0-9)",
"LunaSea Device ID": "LunaSea Geräte ID",
"Apprise URL": "Apprise URL",
"Example:": "Beispiel: {0}",
"Read more:": "Weiterlesen: {0}",
"Status:": "Status: {0}",
"Read more": "Weiterlesen",
appriseInstalled: "Apprise ist installiert.",
appriseNotInstalled: "Apprise ist nicht installiert. {0}",
"Access Token": "Access Token",
"Channel access token": "Channel access token",
"Line Developers Console": "Line Developers Console",
lineDevConsoleTo: "Line Developers Console - {0}",
"Basic Settings": "Basic Settings",
"User ID": "User ID",
"Messaging API": "Messaging API",
wayToGetLineChannelToken: "Rufe zuerst {0} auf, erstelle dann einen Provider und Channel (Messaging API). Als nächstes kannst du den Channel access token und die User ID aus den oben genannten Menüpunkten abrufen.",
"Icon URL": "Icon URL",
aboutIconURL: "Du kannst einen Link zu einem Bild in 'Icon URL' übergeben um das Standardprofilbild zu überschreiben. Wird nicht verwendet, wenn ein Icon Emoji gesetzt ist.",
aboutMattermostChannelName: "Du kannst den Standardkanal, auf dem der Webhook postet überschreiben, indem der Kanalnamen in das Feld 'Channel Name' eingeben wird. Dies muss in den Mattermost Webhook-Einstellungen aktiviert werden. Ex: #other-channel",
matrix: "Matrix",
promosmsTypeEco: "SMS ECO - billig, aber langsam und oft überladen. Nur auf polnische Empfänger beschränkt.",
promosmsTypeFlash: "SMS FLASH - Die Nachricht wird automatisch auf dem Empfängergerät angezeigt. Nur auf polnische Empfänger beschränkt.",
promosmsTypeFull: "SMS FULL - Premium Stufe von SMS, es kann der Absendernamen verwendet werden (Der Name musst zuerst registriert werden). Zuverlässig für Warnungen.",
promosmsTypeSpeed: "SMS SPEED - Höchste Priorität im System. Sehr schnell und zuverlässig, aber teuer (Ungefähr das doppelte von SMS FULL).",
promosmsPhoneNumber: "Phone number (Für polnische Empfänger können die Vorwahlen übersprungen werden)",
promosmsSMSSender: "Name des SMS-Absenders : vorregistrierter Name oder einer der Standardwerte: InfoSMS, SMS Info, MaxSMS, INFO, SMS",
"Feishu WebHookUrl": "Feishu Webhook URL",
matrixHomeserverURL: "Heimserver URL (mit http(s):// und optionalen Ports)",
"Internal Room Id": "Interne Raum-ID",
matrixDesc1: "Die interne Raum-ID findest du im erweiterten Bereich der Raumeinstellungen im Matrix-Client. Es sollte es aussehen wie z.B. !QMdRCpUIfLwsfjxye6:home.server.",
matrixDesc2: "Es wird dringend empfohlen, dass ein neuen Benutzer erstellt wird und nicht den Zugriffstoken deines eigenen Matrix-Benutzers verwendest. Anderfalls ermöglicht es vollen Zugriff auf dein Konto und alle Räume, denen du beigetreten bist. Erstelle stattdessen einen neuen Benutzer und lade ihn nur in den Raum ein, in dem du die Benachrichtigung erhalten möchtest. Du kannst den Zugriffstoken erhalten, indem du folgendes ausführst {0}",
Method: "Method",
Body: "Body",
Headers: "Headers",
PushUrl: "Push URL",
HeadersInvalidFormat: "Die Header ist kein gültiges JSON: ",
BodyInvalidFormat: "Der Body ist kein gültiges JSON: ",
"Monitor History": "Monitor Verlauf",
clearDataOlderThan: "Bewahre die Monitor-Verlaufsdaten für {0} Tage auf.",
PasswordsDoNotMatch: "Passwörter stimmen nicht überein.",
records: "Einträge",
"One record": "Ein Eintrag",
"Showing {from} to {to} of {count} records": "Zeige {from} zu {to} von {count} Einträge",
steamApiKeyDescription: "Um einen Steam Game Server zu überwachen, wird ein Steam Web-API-Schlüssel benötigt. Dieser kann hier registriert werden: ",
"Current User": "Aktueller Benutzer",
}; };

@ -183,11 +183,10 @@ export default {
"Edit Status Page": "Edit Status Page", "Edit Status Page": "Edit Status Page",
"Go to Dashboard": "Go to Dashboard", "Go to Dashboard": "Go to Dashboard",
"Status Page": "Status Page", "Status Page": "Status Page",
// Start notification form
defaultNotificationName: "My {notification} Alert ({number})", defaultNotificationName: "My {notification} Alert ({number})",
here: "here", here: "here",
"Required": "Required", Required: "Required",
"telegram": "Telegram", telegram: "Telegram",
"Bot Token": "Bot Token", "Bot Token": "Bot Token",
wayToGetTelegramToken: "You can get a token from {0}.", wayToGetTelegramToken: "You can get a token from {0}.",
"Chat ID": "Chat ID", "Chat ID": "Chat ID",
@ -195,12 +194,12 @@ export default {
wayToGetTelegramChatID: "You can get your chat ID by sending a message to the bot and going to this URL to view the chat_id:", wayToGetTelegramChatID: "You can get your chat ID by sending a message to the bot and going to this URL to view the chat_id:",
"YOUR BOT TOKEN HERE": "YOUR BOT TOKEN HERE", "YOUR BOT TOKEN HERE": "YOUR BOT TOKEN HERE",
chatIDNotFound: "Chat ID is not found; please send a message to this bot first", chatIDNotFound: "Chat ID is not found; please send a message to this bot first",
"webhook": "Webhook", webhook: "Webhook",
"Post URL": "Post URL", "Post URL": "Post URL",
"Content Type": "Content Type", "Content Type": "Content Type",
webhookJsonDesc: "{0} is good for any modern HTTP servers such as Express.js", webhookJsonDesc: "{0} is good for any modern HTTP servers such as Express.js",
webhookFormDataDesc: "{multipart} is good for PHP. The JSON will need to be parsed with {decodeFunction}", webhookFormDataDesc: "{multipart} is good for PHP. The JSON will need to be parsed with {decodeFunction}",
"smtp": "Email (SMTP)", smtp: "Email (SMTP)",
secureOptionNone: "None / STARTTLS (25, 587)", secureOptionNone: "None / STARTTLS (25, 587)",
secureOptionTLS: "TLS (465)", secureOptionTLS: "TLS (465)",
"Ignore TLS Error": "Ignore TLS Error", "Ignore TLS Error": "Ignore TLS Error",
@ -209,26 +208,26 @@ export default {
"To Email": "To Email", "To Email": "To Email",
smtpCC: "CC", smtpCC: "CC",
smtpBCC: "BCC", smtpBCC: "BCC",
"discord": "Discord", discord: "Discord",
"Discord Webhook URL": "Discord Webhook URL", "Discord Webhook URL": "Discord Webhook URL",
wayToGetDiscordURL: "You can get this by going to Server Settings -> Integrations -> Create Webhook", wayToGetDiscordURL: "You can get this by going to Server Settings -> Integrations -> Create Webhook",
"Bot Display Name": "Bot Display Name", "Bot Display Name": "Bot Display Name",
"Prefix Custom Message": "Prefix Custom Message", "Prefix Custom Message": "Prefix Custom Message",
"Hello @everyone is...": "Hello {'@'}everyone is...", "Hello @everyone is...": "Hello {'@'}everyone is...",
"teams": "Microsoft Teams", teams: "Microsoft Teams",
"Webhook URL": "Webhook URL", "Webhook URL": "Webhook URL",
wayToGetTeamsURL: "You can learn how to create a webhook URL {0}.", wayToGetTeamsURL: "You can learn how to create a webhook URL {0}.",
"signal": "Signal", signal: "Signal",
"Number": "Number", Number: "Number",
"Recipients": "Recipients", Recipients: "Recipients",
needSignalAPI: "You need to have a signal client with REST API.", needSignalAPI: "You need to have a signal client with REST API.",
wayToCheckSignalURL: "You can check this URL to view how to set one up:", wayToCheckSignalURL: "You can check this URL to view how to set one up:",
signalImportant: "IMPORTANT: You cannot mix groups and numbers in recipients!", signalImportant: "IMPORTANT: You cannot mix groups and numbers in recipients!",
"gotify": "Gotify", gotify: "Gotify",
"Application Token": "Application Token", "Application Token": "Application Token",
"Server URL": "Server URL", "Server URL": "Server URL",
"Priority": "Priority", Priority: "Priority",
"slack": "Slack", slack: "Slack",
"Icon Emoji": "Icon Emoji", "Icon Emoji": "Icon Emoji",
"Channel Name": "Channel Name", "Channel Name": "Channel Name",
"Uptime Kuma URL": "Uptime Kuma URL", "Uptime Kuma URL": "Uptime Kuma URL",
@ -241,13 +240,14 @@ export default {
pushy: "Pushy", pushy: "Pushy",
octopush: "Octopush", octopush: "Octopush",
promosms: "PromoSMS", promosms: "PromoSMS",
clicksendsms: "ClickSend SMS",
lunasea: "LunaSea", lunasea: "LunaSea",
apprise: "Apprise (Support 50+ Notification services)", apprise: "Apprise (Support 50+ Notification services)",
pushbullet: "Pushbullet", pushbullet: "Pushbullet",
line: "Line Messenger", line: "Line Messenger",
mattermost: "Mattermost", mattermost: "Mattermost",
"User Key": "User Key", "User Key": "User Key",
"Device": "Device", Device: "Device",
"Message Title": "Message Title", "Message Title": "Message Title",
"Notification Sound": "Notification Sound", "Notification Sound": "Notification Sound",
"More info on:": "More info on: {0}", "More info on:": "More info on: {0}",
@ -257,6 +257,7 @@ export default {
octopushTypePremium: "Premium (Fast - recommended for alerting)", octopushTypePremium: "Premium (Fast - recommended for alerting)",
octopushTypeLowCost: "Low Cost (Slow - sometimes blocked by operator)", octopushTypeLowCost: "Low Cost (Slow - sometimes blocked by operator)",
checkPrice: "Check {0} prices:", checkPrice: "Check {0} prices:",
apiCredentials: "API credentials",
octopushLegacyHint: "Do you use the legacy version of Octopush (2011-2020) or the new version?", octopushLegacyHint: "Do you use the legacy version of Octopush (2011-2020) or the new version?",
"Check octopush prices": "Check octopush prices {0}.", "Check octopush prices": "Check octopush prices {0}.",
octopushPhoneNumber: "Phone number (intl format, eg : +33612345678) ", octopushPhoneNumber: "Phone number (intl format, eg : +33612345678) ",
@ -280,7 +281,7 @@ export default {
"Icon URL": "Icon URL", "Icon URL": "Icon URL",
aboutIconURL: "You can provide a link to a picture in \"Icon URL\" to override the default profile picture. Will not be used if Icon Emoji is set.", aboutIconURL: "You can provide a link to a picture in \"Icon URL\" to override the default profile picture. Will not be used if Icon Emoji is set.",
aboutMattermostChannelName: "You can override the default channel that the Webhook posts to by entering the channel name into \"Channel Name\" field. This needs to be enabled in the Mattermost Webhook settings. Ex: #other-channel", aboutMattermostChannelName: "You can override the default channel that the Webhook posts to by entering the channel name into \"Channel Name\" field. This needs to be enabled in the Mattermost Webhook settings. Ex: #other-channel",
"matrix": "Matrix", matrix: "Matrix",
promosmsTypeEco: "SMS ECO - cheap but slow and often overloaded. Limited only to Polish recipients.", promosmsTypeEco: "SMS ECO - cheap but slow and often overloaded. Limited only to Polish recipients.",
promosmsTypeFlash: "SMS FLASH - Message will automatically show on recipient device. Limited only to Polish recipients.", promosmsTypeFlash: "SMS FLASH - Message will automatically show on recipient device. Limited only to Polish recipients.",
promosmsTypeFull: "SMS FULL - Premium tier of SMS, You can use your Sender Name (You need to register name first). Reliable for alerts.", promosmsTypeFull: "SMS FULL - Premium tier of SMS, You can use your Sender Name (You need to register name first). Reliable for alerts.",
@ -292,18 +293,18 @@ export default {
"Internal Room Id": "Internal Room ID", "Internal Room Id": "Internal Room ID",
matrixDesc1: "You can find the internal room ID by looking in the advanced section of the room settings in your Matrix client. It should look like !QMdRCpUIfLwsfjxye6:home.server.", matrixDesc1: "You can find the internal room ID by looking in the advanced section of the room settings in your Matrix client. It should look like !QMdRCpUIfLwsfjxye6:home.server.",
matrixDesc2: "It is highly recommended you create a new user and do not use your own Matrix user's access token as it will allow full access to your account and all the rooms you joined. Instead, create a new user and only invite it to the room that you want to receive the notification in. You can get the access token by running {0}", matrixDesc2: "It is highly recommended you create a new user and do not use your own Matrix user's access token as it will allow full access to your account and all the rooms you joined. Instead, create a new user and only invite it to the room that you want to receive the notification in. You can get the access token by running {0}",
// End notification form
Method: "Method", Method: "Method",
Body: "Body", Body: "Body",
Headers: "Headers", Headers: "Headers",
PushUrl: "Push URL", PushUrl: "Push URL",
HeadersInvalidFormat: "The request headers are not valid JSON: ", HeadersInvalidFormat: "The request headers are not valid JSON: ",
BodyInvalidFormat: "The request body is not valid JSON: ", BodyInvalidFormat: "The request body is not valid JSON: ",
"Monitor History": "Monitor History:", "Monitor History": "Monitor History",
clearDataOlderThan: "Keep monitor history data for {0} days.", clearDataOlderThan: "Keep monitor history data for {0} days.",
PasswordsDoNotMatch: "Passwords do not match.", PasswordsDoNotMatch: "Passwords do not match.",
records: "records", records: "records",
"One record": "One record", "One record": "One record",
"Showing {from} to {to} of {count} records": "Showing {from} to {to} of {count} records", "Showing {from} to {to} of {count} records": "Showing {from} to {to} of {count} records",
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",
}; };

@ -198,7 +198,7 @@ export default {
pushbullet: "Pushbullet", pushbullet: "Pushbullet",
line: "Line Messenger", line: "Line Messenger",
mattermost: "Mattermost", mattermost: "Mattermost",
"Monitor History": "Historial de monitor:", "Monitor History": "Historial de monitor",
clearDataOlderThan: "Mantener los datos del historial del monitor durante {0} días.", clearDataOlderThan: "Mantener los datos del historial del monitor durante {0} días.",
records: "registros", records: "registros",
"One record": "Un registro", "One record": "Un registro",

@ -179,11 +179,10 @@ export default {
"Edit Status Page": "Modifier la page de statut", "Edit Status Page": "Modifier la page de statut",
"Go to Dashboard": "Accéder au tableau de bord", "Go to Dashboard": "Accéder au tableau de bord",
"Status Page": "Status Page", "Status Page": "Status Page",
// Start notification form
defaultNotificationName: "Ma notification {notification} numéro ({number})", defaultNotificationName: "Ma notification {notification} numéro ({number})",
here: "ici", here: "ici",
"Required": "Requis", Required: "Requis",
"telegram": "Telegram", telegram: "Telegram",
"Bot Token": "Bot Token", "Bot Token": "Bot Token",
wayToGetTelegramToken: "Vous pouvez obtenir un token depuis {0}.", wayToGetTelegramToken: "Vous pouvez obtenir un token depuis {0}.",
"Chat ID": "Chat ID", "Chat ID": "Chat ID",
@ -191,12 +190,12 @@ export default {
wayToGetTelegramChatID: "Vous pouvez obtenir l'ID du chat en envoyant un message avec le bot puis en récupérant l'URL pour voir l'ID du salon :", wayToGetTelegramChatID: "Vous pouvez obtenir l'ID du chat en envoyant un message avec le bot puis en récupérant l'URL pour voir l'ID du salon :",
"YOUR BOT TOKEN HERE": "VOTRE TOKEN BOT ICI", "YOUR BOT TOKEN HERE": "VOTRE TOKEN BOT ICI",
chatIDNotFound: "ID du salon introuvable, envoyez un message via le bot avant", chatIDNotFound: "ID du salon introuvable, envoyez un message via le bot avant",
"webhook": "Webhook", webhook: "Webhook",
"Post URL": "Post URL", "Post URL": "Post URL",
"Content Type": "Content Type", "Content Type": "Content Type",
webhookJsonDesc: "{0} est bien/bon pour tous les serveurs HTTP modernes comme express.js", webhookJsonDesc: "{0} est bien/bon pour tous les serveurs HTTP modernes comme express.js",
webhookFormDataDesc: "{multipart} est bien/bon pour du PHP, vous avez juste besoin de mettre le json via/depuis {decodeFunction}", webhookFormDataDesc: "{multipart} est bien/bon pour du PHP, vous avez juste besoin de mettre le json via/depuis {decodeFunction}",
"smtp": "Email (SMTP)", smtp: "Email (SMTP)",
secureOptionNone: "Aucun / STARTTLS (25, 587)", secureOptionNone: "Aucun / STARTTLS (25, 587)",
secureOptionTLS: "TLS (465)", secureOptionTLS: "TLS (465)",
"Ignore TLS Error": "Ignorer les erreurs TLS", "Ignore TLS Error": "Ignorer les erreurs TLS",
@ -204,26 +203,26 @@ export default {
"To Email": "Vers l'Email", "To Email": "Vers l'Email",
smtpCC: "CC", smtpCC: "CC",
smtpBCC: "BCC", smtpBCC: "BCC",
"discord": "Discord", discord: "Discord",
"Discord Webhook URL": "Discord Webhook URL", "Discord Webhook URL": "Discord Webhook URL",
wayToGetDiscordURL: "Vous pouvez l'obtenir en allant dans 'Paramètres du Serveur' -> 'Intégrations' -> 'Créer un Webhook'", wayToGetDiscordURL: "Vous pouvez l'obtenir en allant dans 'Paramètres du Serveur' -> 'Intégrations' -> 'Créer un Webhook'",
"Bot Display Name": "Nom du bot (affiché)", "Bot Display Name": "Nom du bot (affiché)",
"Prefix Custom Message": "Prefix Custom Message", "Prefix Custom Message": "Prefix Custom Message",
"Hello @everyone is...": "Bonjour {'@'}everyone il...", "Hello @everyone is...": "Bonjour {'@'}everyone il...",
"teams": "Microsoft Teams", teams: "Microsoft Teams",
"Webhook URL": "Webhook URL", "Webhook URL": "Webhook URL",
wayToGetTeamsURL: "Vous pouvez apprendre comment créer un Webhook {0}.", wayToGetTeamsURL: "Vous pouvez apprendre comment créer un Webhook {0}.",
"signal": "Signal", signal: "Signal",
"Number": "Numéro", Number: "Numéro",
"Recipients": "Destinataires", Recipients: "Destinataires",
needSignalAPI: "Vous avez besoin d'un client Signal avec l'API REST.", needSignalAPI: "Vous avez besoin d'un client Signal avec l'API REST.",
wayToCheckSignalURL: "Vous pouvez regarder l'URL sur comment le mettre en place :", wayToCheckSignalURL: "Vous pouvez regarder l'URL sur comment le mettre en place :",
signalImportant: "IMPORTANT: Vous ne pouvez pas mixer les groupes et les numéros en destinataires !", signalImportant: "IMPORTANT: Vous ne pouvez pas mixer les groupes et les numéros en destinataires !",
"gotify": "Gotify", gotify: "Gotify",
"Application Token": "Application Token", "Application Token": "Application Token",
"Server URL": "Server URL", "Server URL": "Server URL",
"Priority": "Priorité", Priority: "Priorité",
"slack": "Slack", slack: "Slack",
"Icon Emoji": "Icon Emoji", "Icon Emoji": "Icon Emoji",
"Channel Name": "Nom du salon", "Channel Name": "Nom du salon",
"Uptime Kuma URL": "Uptime Kuma URL", "Uptime Kuma URL": "Uptime Kuma URL",
@ -242,7 +241,7 @@ export default {
line: "Line Messenger", line: "Line Messenger",
mattermost: "Mattermost", mattermost: "Mattermost",
"User Key": "Clé d'utilisateur", "User Key": "Clé d'utilisateur",
"Device": "Appareil", Device: "Appareil",
"Message Title": "Titre du message", "Message Title": "Titre du message",
"Notification Sound": "Son de notification", "Notification Sound": "Son de notification",
"More info on:": "Plus d'informations sur: {0}", "More info on:": "Plus d'informations sur: {0}",
@ -273,12 +272,11 @@ export default {
"Icon URL": "Icon URL", "Icon URL": "Icon URL",
aboutIconURL: "Vous pouvez mettre un lien vers l'image dans \"Icon URL\" pour remplacer l'image de profil par défaut. Ne sera pas utilisé si Icon Emoji est défini.", aboutIconURL: "Vous pouvez mettre un lien vers l'image dans \"Icon URL\" pour remplacer l'image de profil par défaut. Ne sera pas utilisé si Icon Emoji est défini.",
aboutMattermostChannelName: "Vous pouvez remplacer le salon par défaut que le Webhook utilise en mettant le nom du salon dans le champ \"Channel Name\". Vous aurez besoin de l'activer depuis les paramètres de Mattermost. Ex : #autre-salon", aboutMattermostChannelName: "Vous pouvez remplacer le salon par défaut que le Webhook utilise en mettant le nom du salon dans le champ \"Channel Name\". Vous aurez besoin de l'activer depuis les paramètres de Mattermost. Ex : #autre-salon",
"matrix": "Matrix", matrix: "Matrix",
promosmsTypeEco: "SMS ECO - Pas cher mais lent et souvent surchargé. Limité uniquement aux déstinataires Polonais.", promosmsTypeEco: "SMS ECO - Pas cher mais lent et souvent surchargé. Limité uniquement aux déstinataires Polonais.",
promosmsTypeFlash: "SMS FLASH - Le message sera automatiquement affiché sur l'appareil du destinataire. Limité uniquement aux déstinataires Polonais.", promosmsTypeFlash: "SMS FLASH - Le message sera automatiquement affiché sur l'appareil du destinataire. Limité uniquement aux déstinataires Polonais.",
promosmsTypeFull: "SMS FULL - Version Premium des SMS, Vous pouvez mettre le nom de l'expéditeur (Vous devez vous enregistrer avant). Fiable pour les alertes.", promosmsTypeFull: "SMS FULL - Version Premium des SMS, Vous pouvez mettre le nom de l'expéditeur (Vous devez vous enregistrer avant). Fiable pour les alertes.",
promosmsTypeSpeed: "SMS SPEED - La plus haute des priorités dans le système. Très rapide et fiable mais cher (environ le double du prix d'un SMS FULL).", promosmsTypeSpeed: "SMS SPEED - La plus haute des priorités dans le système. Très rapide et fiable mais cher (environ le double du prix d'un SMS FULL).",
promosmsPhoneNumber: "Numéro de téléphone (Poiur les déstinataires Polonais, vous pouvez enlever les codes interna.)", promosmsPhoneNumber: "Numéro de téléphone (Poiur les déstinataires Polonais, vous pouvez enlever les codes interna.)",
promosmsSMSSender: "SMS Expéditeur : Nom pré-enregistré ou l'un de base: InfoSMS, SMS Info, MaxSMS, INFO, SMS", promosmsSMSSender: "SMS Expéditeur : Nom pré-enregistré ou l'un de base: InfoSMS, SMS Info, MaxSMS, INFO, SMS",
// End notification form
}; };

@ -179,11 +179,10 @@ export default {
"Edit Status Page": "Edit Halaman Status", "Edit Status Page": "Edit Halaman Status",
"Go to Dashboard": "Pergi ke Dasbor", "Go to Dashboard": "Pergi ke Dasbor",
"Status Page": "Halaman Status", "Status Page": "Halaman Status",
// Start notification form
defaultNotificationName: "{notification} saya Peringatan ({number})", defaultNotificationName: "{notification} saya Peringatan ({number})",
here: "di sini", here: "di sini",
"Required": "Dibutuhkan", Required: "Dibutuhkan",
"telegram": "Telegram", telegram: "Telegram",
"Bot Token": "Bot Token", "Bot Token": "Bot Token",
"You can get a token from": "Anda bisa mendapatkan token dari", "You can get a token from": "Anda bisa mendapatkan token dari",
"Chat ID": "Chat ID", "Chat ID": "Chat ID",
@ -191,12 +190,12 @@ export default {
wayToGetTelegramChatID: "Anda bisa mendapatkan chat id Anda dengan mengirim pesan ke bot dan pergi ke url ini untuk melihat chat_id:", wayToGetTelegramChatID: "Anda bisa mendapatkan chat id Anda dengan mengirim pesan ke bot dan pergi ke url ini untuk melihat chat_id:",
"YOUR BOT TOKEN HERE": "BOT TOKEN ANDA DI SINI", "YOUR BOT TOKEN HERE": "BOT TOKEN ANDA DI SINI",
chatIDNotFound: "Chat ID tidak ditemukan, tolong kirim pesan ke bot ini dulu", chatIDNotFound: "Chat ID tidak ditemukan, tolong kirim pesan ke bot ini dulu",
"webhook": "Webhook", webhook: "Webhook",
"Post URL": "Post URL", "Post URL": "Post URL",
"Content Type": "Tipe konten", "Content Type": "Tipe konten",
webhookJsonDesc: "{0} bagus untuk peladen http modern seperti express.js", webhookJsonDesc: "{0} bagus untuk peladen http modern seperti express.js",
webhookFormDataDesc: "{multipart} bagus untuk PHP, Anda hanya perlu mengurai json dengan {decodeFunction}", webhookFormDataDesc: "{multipart} bagus untuk PHP, Anda hanya perlu mengurai json dengan {decodeFunction}",
"smtp": "Surel (SMTP)", smtp: "Surel (SMTP)",
secureOptionNone: "None / STARTTLS (25, 587)", secureOptionNone: "None / STARTTLS (25, 587)",
secureOptionTLS: "TLS (465)", secureOptionTLS: "TLS (465)",
"Ignore TLS Error": "Abaikan Kesalahan TLS", "Ignore TLS Error": "Abaikan Kesalahan TLS",
@ -204,26 +203,26 @@ export default {
"To Email": "Ke Surel", "To Email": "Ke Surel",
smtpCC: "CC", smtpCC: "CC",
smtpBCC: "BCC", smtpBCC: "BCC",
"discord": "Discord", discord: "Discord",
"Discord Webhook URL": "Discord Webhook URL", "Discord Webhook URL": "Discord Webhook URL",
wayToGetDiscordURL: "Anda bisa mendapatkan ini dengan pergi ke Server Settings -> Integrations -> Create Webhook", wayToGetDiscordURL: "Anda bisa mendapatkan ini dengan pergi ke Server Settings -> Integrations -> Create Webhook",
"Bot Display Name": "Nama Bot", "Bot Display Name": "Nama Bot",
"Prefix Custom Message": "Awalan Pesan", "Prefix Custom Message": "Awalan Pesan",
"Hello @everyone is...": "Halo {'@'}everyone is...", "Hello @everyone is...": "Halo {'@'}everyone is...",
"teams": "Microsoft Teams", teams: "Microsoft Teams",
"Webhook URL": "Webhook URL", "Webhook URL": "Webhook URL",
wayToGetTeamsURL: "Anda dapat mempelajari cara membuat url webhook {0}.", wayToGetTeamsURL: "Anda dapat mempelajari cara membuat url webhook {0}.",
"signal": "Sinyal", signal: "Sinyal",
"Number": "Nomer", Number: "Nomer",
"Recipients": "Penerima", Recipients: "Penerima",
needSignalAPI: "Anda harus memiliki klien sinyal dengan REST API.", needSignalAPI: "Anda harus memiliki klien sinyal dengan REST API.",
wayToCheckSignalURL: "Anda dapat memeriksa url ini untuk melihat cara menyiapkannya:", wayToCheckSignalURL: "Anda dapat memeriksa url ini untuk melihat cara menyiapkannya:",
signalImportant: "PENTING: Anda tidak dapat mencampur grup dan nomor di penerima!", signalImportant: "PENTING: Anda tidak dapat mencampur grup dan nomor di penerima!",
"gotify": "Gotify", gotify: "Gotify",
"Application Token": "Token Aplikasi", "Application Token": "Token Aplikasi",
"Server URL": "URL Peladen", "Server URL": "URL Peladen",
"Priority": "Prioritas", Priority: "Prioritas",
"slack": "Slack", slack: "Slack",
"Icon Emoji": "Ikon Emoji", "Icon Emoji": "Ikon Emoji",
"Channel Name": "Nama Saluran", "Channel Name": "Nama Saluran",
"Uptime Kuma URL": "Uptime Kuma URL", "Uptime Kuma URL": "Uptime Kuma URL",
@ -242,7 +241,7 @@ export default {
line: "Line Messenger", line: "Line Messenger",
mattermost: "Mattermost", mattermost: "Mattermost",
"User Key": "Kunci pengguna", "User Key": "Kunci pengguna",
"Device": "Perangkat", Device: "Perangkat",
"Message Title": "Judul Pesan", "Message Title": "Judul Pesan",
"Notification Sound": "Suara Nofifikasi", "Notification Sound": "Suara Nofifikasi",
"More info on:": "Info lebih lanjut tentang: {0}", "More info on:": "Info lebih lanjut tentang: {0}",
@ -273,7 +272,7 @@ export default {
"Icon URL": "Icon URL", "Icon URL": "Icon URL",
aboutIconURL: "Anda dapat memberikan tautan ke gambar di \"Icon URL\" untuk mengganti gambar profil bawaan. Tidak akan digunakan jika Ikon Emoji diset.", aboutIconURL: "Anda dapat memberikan tautan ke gambar di \"Icon URL\" untuk mengganti gambar profil bawaan. Tidak akan digunakan jika Ikon Emoji diset.",
aboutMattermostChannelName: "Anda dapat mengganti saluran bawaan tujuan posting webhook dengan memasukkan nama saluran ke dalam Kolom \"Channel Name\". Ini perlu diaktifkan di pengaturan webhook Mattermost. contoh: #other-channel", aboutMattermostChannelName: "Anda dapat mengganti saluran bawaan tujuan posting webhook dengan memasukkan nama saluran ke dalam Kolom \"Channel Name\". Ini perlu diaktifkan di pengaturan webhook Mattermost. contoh: #other-channel",
"matrix": "Matrix", matrix: "Matrix",
promosmsTypeEco: "SMS ECO - murah tapi lambat dan sering kelebihan beban. Terbatas hanya untuk penerima Polandia.", promosmsTypeEco: "SMS ECO - murah tapi lambat dan sering kelebihan beban. Terbatas hanya untuk penerima Polandia.",
promosmsTypeFlash: "SMS FLASH - Pesan akan otomatis muncul di perangkat penerima. Terbatas hanya untuk penerima Polandia.", promosmsTypeFlash: "SMS FLASH - Pesan akan otomatis muncul di perangkat penerima. Terbatas hanya untuk penerima Polandia.",
promosmsTypeFull: "SMS FULL - SMS tingkat premium, Anda dapat menggunakan Nama Pengirim Anda (Anda harus mendaftarkan nama terlebih dahulu). Dapat diAndalkan untuk peringatan.", promosmsTypeFull: "SMS FULL - SMS tingkat premium, Anda dapat menggunakan Nama Pengirim Anda (Anda harus mendaftarkan nama terlebih dahulu). Dapat diAndalkan untuk peringatan.",
@ -281,5 +280,4 @@ export default {
promosmsPhoneNumber: "Nomor telepon (untuk penerima Polandia Anda dapat melewati kode area)", promosmsPhoneNumber: "Nomor telepon (untuk penerima Polandia Anda dapat melewati kode area)",
promosmsSMSSender: "Nama Pengirim SMS : Nama pra-registrasi atau salah satu bawaan: InfoSMS, Info SMS, MaxSMS, INFO, SMS", promosmsSMSSender: "Nama Pengirim SMS : Nama pra-registrasi atau salah satu bawaan: InfoSMS, Info SMS, MaxSMS, INFO, SMS",
"Feishu WebHookUrl": "Feishu WebHookUrl", "Feishu WebHookUrl": "Feishu WebHookUrl",
// End notification form
}; };

@ -179,11 +179,10 @@ export default {
"Edit Status Page": "Rediger statusside", "Edit Status Page": "Rediger statusside",
"Go to Dashboard": "Gå til Dashboard", "Go to Dashboard": "Gå til Dashboard",
"Status Page": "Statusside", "Status Page": "Statusside",
// Start notification form
defaultNotificationName: "Min {notification} varsling ({number})", defaultNotificationName: "Min {notification} varsling ({number})",
here: "here", here: "here",
"Required": "Obligatorisk", Required: "Obligatorisk",
"telegram": "Telegram", telegram: "Telegram",
"Bot Token": "Bot Token", "Bot Token": "Bot Token",
wayToGetTelegramToken: "Du kan få et token fra {0}.", wayToGetTelegramToken: "Du kan få et token fra {0}.",
"Chat ID": "Chat ID", "Chat ID": "Chat ID",
@ -191,12 +190,12 @@ export default {
wayToGetTelegramChatID: "Du kan få chat-ID-en din ved å sende meldingen til boten og gå til denne nettadressen for å se chat_id:", wayToGetTelegramChatID: "Du kan få chat-ID-en din ved å sende meldingen til boten og gå til denne nettadressen for å se chat_id:",
"YOUR BOT TOKEN HERE": "DITT BOT TOKEN HER", "YOUR BOT TOKEN HERE": "DITT BOT TOKEN HER",
chatIDNotFound: "Chat-ID ble ikke funnet. Send en melding til denne boten først", chatIDNotFound: "Chat-ID ble ikke funnet. Send en melding til denne boten først",
"webhook": "Webhook", webhook: "Webhook",
"Post URL": "Post URL", "Post URL": "Post URL",
"Content Type": "Content Type", "Content Type": "Content Type",
webhookJsonDesc: "{0} er bra for alle moderne HTTP-servere som express.js", webhookJsonDesc: "{0} er bra for alle moderne HTTP-servere som express.js",
webhookFormDataDesc: "{multipart} er bra for PHP, du trenger bare å analysere JSON etter {decodeFunction}", webhookFormDataDesc: "{multipart} er bra for PHP, du trenger bare å analysere JSON etter {decodeFunction}",
"smtp": "E-post (SMTP)", smtp: "E-post (SMTP)",
secureOptionNone: "None / STARTTLS (25, 587)", secureOptionNone: "None / STARTTLS (25, 587)",
secureOptionTLS: "TLS (465)", secureOptionTLS: "TLS (465)",
"Ignore TLS Error": "Ignorer TLS feilmelding", "Ignore TLS Error": "Ignorer TLS feilmelding",
@ -204,26 +203,26 @@ export default {
"To Email": "Til E-post", "To Email": "Til E-post",
smtpCC: "CC", smtpCC: "CC",
smtpBCC: "BCC", smtpBCC: "BCC",
"discord": "Discord", discord: "Discord",
"Discord Webhook URL": "Discord Webhook URL", "Discord Webhook URL": "Discord Webhook URL",
wayToGetDiscordURL: "Du kan få dette ved å gå til Serverinnstillinger -> Integrasjoner -> Webhooks -> Ny webhook", wayToGetDiscordURL: "Du kan få dette ved å gå til Serverinnstillinger -> Integrasjoner -> Webhooks -> Ny webhook",
"Bot Display Name": "Bot Visningsnavn", "Bot Display Name": "Bot Visningsnavn",
"Prefix Custom Message": "Prefiks tilpasset melding", "Prefix Custom Message": "Prefiks tilpasset melding",
"Hello @everyone is...": "Hei {'@'}everyone det er...", "Hello @everyone is...": "Hei {'@'}everyone det er...",
"teams": "Microsoft Teams", teams: "Microsoft Teams",
"Webhook URL": "Webhook URL", "Webhook URL": "Webhook URL",
wayToGetTeamsURL: "Du kan lære hvordan du oppretter en webhook-URL {0}.", wayToGetTeamsURL: "Du kan lære hvordan du oppretter en webhook-URL {0}.",
"signal": "Signal", signal: "Signal",
"Number": "Nummer", Number: "Nummer",
"Recipients": "Mottakere", Recipients: "Mottakere",
needSignalAPI: "Du må ha en Signal-klient med REST API.", needSignalAPI: "Du må ha en Signal-klient med REST API.",
wayToCheckSignalURL: "Du kan sjekke denne nettadressen for å se hvordan du konfigurerer en:", wayToCheckSignalURL: "Du kan sjekke denne nettadressen for å se hvordan du konfigurerer en:",
signalImportant: "VIKTIG: Du kan ikke blande grupper og nummere i mottakere!", signalImportant: "VIKTIG: Du kan ikke blande grupper og nummere i mottakere!",
"gotify": "Gotify", gotify: "Gotify",
"Application Token": "Application Token", "Application Token": "Application Token",
"Server URL": "Server URL", "Server URL": "Server URL",
"Priority": "Prioritet", Priority: "Prioritet",
"slack": "Slack", slack: "Slack",
"Icon Emoji": "Icon Emoji", "Icon Emoji": "Icon Emoji",
"Channel Name": "Kanal navn", "Channel Name": "Kanal navn",
"Uptime Kuma URL": "Uptime Kuma URL", "Uptime Kuma URL": "Uptime Kuma URL",
@ -242,7 +241,7 @@ export default {
line: "Line Messenger", line: "Line Messenger",
mattermost: "Mattermost", mattermost: "Mattermost",
"User Key": "User Key", "User Key": "User Key",
"Device": "Device", Device: "Device",
"Message Title": "Message Title", "Message Title": "Message Title",
"Notification Sound": "Notification Sound", "Notification Sound": "Notification Sound",
"More info on:": "More info on: {0}", "More info on:": "More info on: {0}",
@ -273,12 +272,11 @@ export default {
"Icon URL": "Icon URL", "Icon URL": "Icon URL",
aboutIconURL: "You can provide a link to a picture in \"Icon URL\" to override the default profile picture. Will not be used if Icon Emoji is set.", aboutIconURL: "You can provide a link to a picture in \"Icon URL\" to override the default profile picture. Will not be used if Icon Emoji is set.",
aboutMattermostChannelName: "You can override the default channel that webhook posts to by entering the channel name into \"Channel Name\" field. This needs to be enabled in Mattermost webhook settings. Ex: #other-channel", aboutMattermostChannelName: "You can override the default channel that webhook posts to by entering the channel name into \"Channel Name\" field. This needs to be enabled in Mattermost webhook settings. Ex: #other-channel",
"matrix": "Matrix", matrix: "Matrix",
promosmsTypeEco: "SMS ECO - cheap but slow and often overloaded. Limited only to Polish recipients.", promosmsTypeEco: "SMS ECO - cheap but slow and often overloaded. Limited only to Polish recipients.",
promosmsTypeFlash: "SMS FLASH - Message will automatically show on recipient device. Limited only to Polish recipients.", promosmsTypeFlash: "SMS FLASH - Message will automatically show on recipient device. Limited only to Polish recipients.",
promosmsTypeFull: "SMS FULL - Premium tier of SMS, You can use Your Sender Name (You need to register name first). Reliable for alerts.", promosmsTypeFull: "SMS FULL - Premium tier of SMS, You can use Your Sender Name (You need to register name first). Reliable for alerts.",
promosmsTypeSpeed: "SMS SPEED - Highest priority in system. Very quick and reliable but costly (about twice of SMS FULL price).", promosmsTypeSpeed: "SMS SPEED - Highest priority in system. Very quick and reliable but costly (about twice of SMS FULL price).",
promosmsPhoneNumber: "Phone number (for Polish recipient You can skip area codes)", promosmsPhoneNumber: "Phone number (for Polish recipient You can skip area codes)",
promosmsSMSSender: "SMS Sender Name : Pre-registred name or one of defaults: InfoSMS, SMS Info, MaxSMS, INFO, SMS", promosmsSMSSender: "SMS Sender Name : Pre-registred name or one of defaults: InfoSMS, SMS Info, MaxSMS, INFO, SMS",
// End notification form
}; };

@ -203,5 +203,5 @@ export default {
Headers: "Headers", Headers: "Headers",
PushUrl: "Push URL", PushUrl: "Push URL",
HeadersInvalidFormat: "The request headers is geen geldige JSON: ", HeadersInvalidFormat: "The request headers is geen geldige JSON: ",
BodyInvalidFormat: "De request body is geen geldige JSON: " BodyInvalidFormat: "De request body is geen geldige JSON: ",
}; };

@ -118,8 +118,8 @@ export default {
"Last Result": "Ostatni wynik", "Last Result": "Ostatni wynik",
"Create your admin account": "Utwórz swoje konto administratora", "Create your admin account": "Utwórz swoje konto administratora",
"Repeat Password": "Powtórz hasło", "Repeat Password": "Powtórz hasło",
"Import Backup": "Importuj Kopię", "Import Backup": "Importuj kopię zapasową",
"Export Backup": "Eksportuj Kopię", "Export Backup": "Eksportuj kopię zapasową",
Export: "Eksportuj", Export: "Eksportuj",
Import: "Importuj", Import: "Importuj",
respTime: "Czas Odp. (ms)", respTime: "Czas Odp. (ms)",
@ -127,7 +127,7 @@ export default {
"Default enabled": "Włącz domyślnie", "Default enabled": "Włącz domyślnie",
"Apply on all existing monitors": "Zastosuj do istniejących monitorów", "Apply on all existing monitors": "Zastosuj do istniejących monitorów",
Create: "Stwórz", Create: "Stwórz",
"Clear Data": "Usuń Dane", "Clear Data": "Usuń dane",
Events: "Wydarzenia", Events: "Wydarzenia",
Heartbeats: "Bicia serca", Heartbeats: "Bicia serca",
"Auto Get": "Wykryj", "Auto Get": "Wykryj",
@ -179,11 +179,10 @@ export default {
"Edit Status Page": "Edytuj stronę statusu", "Edit Status Page": "Edytuj stronę statusu",
"Go to Dashboard": "Idź do panelu", "Go to Dashboard": "Idź do panelu",
"Status Page": "Strona statusu", "Status Page": "Strona statusu",
// Start notification form
defaultNotificationName: "Moje powiadomienie {notification} ({number})", defaultNotificationName: "Moje powiadomienie {notification} ({number})",
here: "tutaj", here: "tutaj",
"Required": "Wymagane", Required: "Wymagane",
"telegram": "Telegram", telegram: "Telegram",
"Bot Token": "Token Bota", "Bot Token": "Token Bota",
wayToGetTelegramToken: "Token można uzyskać z {0}.", wayToGetTelegramToken: "Token można uzyskać z {0}.",
"Chat ID": "Identyfikator Czatu", "Chat ID": "Identyfikator Czatu",
@ -191,12 +190,12 @@ export default {
wayToGetTelegramChatID: "Możesz uzyskać swój identyfikator czatu, wysyłając wiadomość do bota i przechodząc pod ten adres URL, aby wyświetlić identyfikator czatu:", wayToGetTelegramChatID: "Możesz uzyskać swój identyfikator czatu, wysyłając wiadomość do bota i przechodząc pod ten adres URL, aby wyświetlić identyfikator czatu:",
"YOUR BOT TOKEN HERE": "TWOJ TOKEN BOTA", "YOUR BOT TOKEN HERE": "TWOJ TOKEN BOTA",
chatIDNotFound: "Identyfikator czatu nie znaleziony, najpierw napisz do bota", chatIDNotFound: "Identyfikator czatu nie znaleziony, najpierw napisz do bota",
"webhook": "Webhook", webhook: "Webhook",
"Post URL": "Adres URL", "Post URL": "Adres URL",
"Content Type": "Rodzaj danych", "Content Type": "Rodzaj danych",
webhookJsonDesc: "{0} jest dobry w przypadku serwerów HTTP, takich jak express.js", webhookJsonDesc: "{0} jest dobry w przypadku serwerów HTTP, takich jak express.js",
webhookFormDataDesc: "{multipart} jest dobry dla PHP, musisz jedynie przetowrzyć dane przez {decodeFunction}", webhookFormDataDesc: "{multipart} jest dobry dla PHP, musisz jedynie przetowrzyć dane przez {decodeFunction}",
"smtp": "Email (SMTP)", smtp: "Email (SMTP)",
secureOptionNone: "Brak / STARTTLS (25, 587)", secureOptionNone: "Brak / STARTTLS (25, 587)",
secureOptionTLS: "TLS (465)", secureOptionTLS: "TLS (465)",
"Ignore TLS Error": "Zignrouj Błędy TLS", "Ignore TLS Error": "Zignrouj Błędy TLS",
@ -204,26 +203,26 @@ export default {
"To Email": "Odbiorca (DO)", "To Email": "Odbiorca (DO)",
smtpCC: "DW", smtpCC: "DW",
smtpBCC: "UDW", smtpBCC: "UDW",
"discord": "Discord", discord: "Discord",
"Discord Webhook URL": "URL Webhook Discorda", "Discord Webhook URL": "URL Webhook Discorda",
wayToGetDiscordURL: "Możesz go uzyskać przechodząc do Ustawienia Serwera -> Integracje -> Tworzenie Webhooka", wayToGetDiscordURL: "Możesz go uzyskać przechodząc do Ustawienia Serwera -> Integracje -> Tworzenie Webhooka",
"Bot Display Name": "Wyświetlana Nazwa Bota", "Bot Display Name": "Wyświetlana Nazwa Bota",
"Prefix Custom Message": "Własny Początek Wiadomości", "Prefix Custom Message": "Własny Początek Wiadomości",
"Hello @everyone is...": "Hej {'@'}everyone ...", "Hello @everyone is...": "Hej {'@'}everyone ...",
"teams": "Microsoft Teams", teams: "Microsoft Teams",
"Webhook URL": "URL Webhooka", "Webhook URL": "URL Webhooka",
wayToGetTeamsURL: "You can learn how to create a webhook url {0}.", wayToGetTeamsURL: "You can learn how to create a webhook url {0}.",
"signal": "Signal", signal: "Signal",
"Number": "Numer", Number: "Numer",
"Recipients": "Odbiorcy", Recipients: "Odbiorcy",
needSignalAPI: "Musisz posiadać klienta Signal z REST API.", needSignalAPI: "Musisz posiadać klienta Signal z REST API.",
wayToCheckSignalURL: "W celu dowiedzenia się, jak go skonfigurować, odwiedź poniższy link:", wayToCheckSignalURL: "W celu dowiedzenia się, jak go skonfigurować, odwiedź poniższy link:",
signalImportant: "UWAGA: Nie można mieszać nazw grup i numerów odbiorców!", signalImportant: "UWAGA: Nie można mieszać nazw grup i numerów odbiorców!",
"gotify": "Gotify", gotify: "Gotify",
"Application Token": "Token Aplikacji", "Application Token": "Token Aplikacji",
"Server URL": "Server URL", "Server URL": "Server URL",
"Priority": "Priorytet", Priority: "Priorytet",
"slack": "Slack", slack: "Slack",
"Icon Emoji": "Ikona Emoji", "Icon Emoji": "Ikona Emoji",
"Channel Name": "Nazwa Kanału", "Channel Name": "Nazwa Kanału",
"Uptime Kuma URL": "Adres Uptime Kuma", "Uptime Kuma URL": "Adres Uptime Kuma",
@ -242,7 +241,7 @@ export default {
line: "Line Messenger", line: "Line Messenger",
mattermost: "Mattermost", mattermost: "Mattermost",
"User Key": "Klucz Użytkownika", "User Key": "Klucz Użytkownika",
"Device": "Urządzenie", Device: "Urządzenie",
"Message Title": "Tytuł Wiadomości", "Message Title": "Tytuł Wiadomości",
"Notification Sound": "Dźwięk Powiadomienia", "Notification Sound": "Dźwięk Powiadomienia",
"More info on:": "Więcej informacji na: {0}", "More info on:": "Więcej informacji na: {0}",
@ -271,14 +270,38 @@ export default {
"Messaging API": "API Wiadomości", "Messaging API": "API Wiadomości",
wayToGetLineChannelToken: "Najpierw uzyskaj dostęp do {0}, utwórz dostawcę i kanał (Messaging API), a następnie możesz uzyskać token dostępu do kanału i identyfikator użytkownika z wyżej wymienionych pozycji menu.", wayToGetLineChannelToken: "Najpierw uzyskaj dostęp do {0}, utwórz dostawcę i kanał (Messaging API), a następnie możesz uzyskać token dostępu do kanału i identyfikator użytkownika z wyżej wymienionych pozycji menu.",
"Icon URL": "Adres Ikony", "Icon URL": "Adres Ikony",
aboutIconURL: "You can provide a link to a picture in \"Icon URL\" to override the default profile picture. Will not be used if Icon Emoji is set.", aboutIconURL: "Możesz podać link do zdjęcia w \"Adres URL ikony\", aby zastąpić domyślne zdjęcie profilowe. Nie będzie używany, jeśli ustawiona jest ikona Emoji.",
aboutMattermostChannelName: "You can override the default channel that webhook posts to by entering the channel name into \"Channel Name\" field. This needs to be enabled in Mattermost webhook settings. Ex: #other-channel", aboutMattermostChannelName: "Możesz zastąpić domyślny kanał, na którym publikowane są posty webhooka, wpisując nazwę kanału w polu \"Nazwa Kanału\". Należy to włączyć w ustawieniach webhooka Mattermost. Np.: #inny-kanał",
"matrix": "Matrix", matrix: "Matrix",
promosmsTypeEco: "SMS ECO - Tanie, lecz wolne. Dostępne tylko w Polsce", promosmsTypeEco: "SMS ECO - Tanie, lecz wolne. Dostępne tylko w Polsce",
promosmsTypeFlash: "SMS FLASH - Wiadomość automatycznie wyświetli się na urządzeniu. Dostępne tylko w Polsce.", promosmsTypeFlash: "SMS FLASH - Wiadomość automatycznie wyświetli się na urządzeniu. Dostępne tylko w Polsce.",
promosmsTypeFull: "SMS FULL - Szybkie i dostępne międzynarodowo. Wersja premium usługi, która pozwala min. ustawić własną nazwę nadawcy.", promosmsTypeFull: "SMS FULL - Szybkie i dostępne międzynarodowo. Wersja premium usługi, która pozwala min. ustawić własną nazwę nadawcy.",
promosmsTypeSpeed: "SMS SPEED - Wysyłka priorytetowa, posiada wszystkie zalety SMS FULL", promosmsTypeSpeed: "SMS SPEED - Wysyłka priorytetowa, posiada wszystkie zalety SMS FULL",
promosmsPhoneNumber: "Numer Odbiorcy", promosmsPhoneNumber: "Numer Odbiorcy",
promosmsSMSSender: "Nadawca SMS (Wcześniej zatwierdzone nazwy z panelu PromoSMS)", promosmsSMSSender: "Nadawca SMS (Wcześniej zatwierdzone nazwy z panelu PromoSMS)",
// End notification form "Primary Base URL": "Główny URL",
"Push URL": "Push URL",
needPushEvery: "Powinieneś wywoływać ten URL co {0} sekund",
pushOptionalParams: "Parametry opcjonalne: {0}",
emailCustomSubject: "Niestandardowy temat",
checkPrice: "Sprawdź ceny {0}:",
octopushLegacyHint: "Czy używasz starszej wersji Octopush (2011-2020) czy nowej wersji?",
"Feishu WebHookUrl": "Feishu WebHookURL",
matrixHomeserverURL: "Adres URL serwera domowego (z http(s):// i opcjonalnie port)",
"Internal Room Id": "Wewnętrzne ID pokoju",
matrixDesc1: "Możesz znaleźć wewnętrzne ID pokoju patrząc w zaawansowanej sekcji ustawień pokoju w twoim kliencie Matrix. Powinien on wyglądać jak !QMdRCpUIfLwsfjxye6:home.server.",
matrixDesc2: "Jest wysoce zalecane, abyś stworzył nowego użytkownika i nie używał tokena dostępu swojego użytkownika Matrix, ponieważ pozwoli on na pełny dostęp do twojego konta i wszystkich pokoi, do których dołączyłeś. Zamiast tego, utwórz nowego użytkownika i zaproś go tylko do pokoju, w którym chcesz otrzymywać powiadomienia. Możesz uzyskać token dostępu przez uruchomienie {0}",
Method: "Metoda",
Body: "Treść",
Headers: "Nagłówki",
PushUrl: "Push URL",
HeadersInvalidFormat: "Nagłówki żądania nie są w poprawnym formacie JSON: ",
BodyInvalidFormat: "Treść żądania nie jest w poprawnym formacie JSON: ",
"Monitor History": "Historia monitorów",
clearDataOlderThan: "Przechowuj dane dotyczące historii monitorowania {0} dni.",
PasswordsDoNotMatch: "Hasła nie pasują.",
records: "rekordy",
"One record": "Jeden rekord",
"Showing {from} to {to} of {count} records": "Wyświetlanie {from} do {to} z {count} rekordów",
steamApiKeyDescription: "Do monitorowania serwera gier Steam potrzebny jest klucz Steam Web-API. Możesz zarejestrować swój klucz API tutaj: ",
}; };

@ -204,7 +204,7 @@ export default {
mattermost: "Mattermost", mattermost: "Mattermost",
"Primary Base URL": "Основной URL", "Primary Base URL": "Основной URL",
"Push URL": "URL пуша", "Push URL": "URL пуша",
needPushEvery: "К этому URL необходимо обращаться каждые {0} секунд.", needPushEvery: "К этому URL необходимо обращаться каждые {0} секунд",
pushOptionalParams: "Опциональные параметры: {0}", pushOptionalParams: "Опциональные параметры: {0}",
defaultNotificationName: "Моё уведомление {notification} ({number})", defaultNotificationName: "Моё уведомление {notification} ({number})",
here: "здесь", here: "здесь",

@ -1,285 +1,283 @@
export default { export default {
languageName: "Vietnamese", languageName: "Vietnamese",
checkEverySecond: "Kiểm tra mỗi {0} giây.", checkEverySecond: "Kiểm tra mỗi {0} giây.",
retryCheckEverySecond: "Thử lại mỗi {0} giây.", retryCheckEverySecond: "Thử lại mỗi {0} giây.",
retriesDescription: "Số lần thử lại tối đa trước khi dịch vụ được đánh dấu là down và gửi thông báo.", retriesDescription: "Số lần thử lại tối đa trước khi dịch vụ được đánh dấu là down và gửi thông báo.",
ignoreTLSError: "Bỏ qua lỗi TLS/SSL với các web HTTPS.", ignoreTLSError: "Bỏ qua lỗi TLS/SSL với các web HTTPS.",
upsideDownModeDescription: "Trạng thái đảo ngược, nếu dịch vụ có thể truy cập được nghĩa là DOWN.", upsideDownModeDescription: "Trạng thái đảo ngược, nếu dịch vụ có thể truy cập được nghĩa là DOWN.",
maxRedirectDescription: "Số lần chuyển hướng (redirect) tối đa. Đặt thành 0 để tắt chuyển hướng", maxRedirectDescription: "Số lần chuyển hướng (redirect) tối đa. Đặt thành 0 để tắt chuyển hướng",
acceptedStatusCodesDescription: "Chọn mã code trạng thái được coi là phản hồi thành công.", acceptedStatusCodesDescription: "Chọn mã code trạng thái được coi là phản hồi thành công.",
passwordNotMatchMsg: "Mật khẩu nhập lại không khớp.", passwordNotMatchMsg: "Mật khẩu nhập lại không khớp.",
notificationDescription: "Vui lòng chỉ định một kênh thông báo.", notificationDescription: "Vui lòng chỉ định một kênh thông báo.",
keywordDescription: "Từ khoá tìm kiếm phản hồi ở dạng html hoặc JSON, có phân biệt chữ HOA - thường", keywordDescription: "Từ khoá tìm kiếm phản hồi ở dạng html hoặc JSON, có phân biệt chữ HOA - thường",
pauseDashboardHome: "Tạm dừng", pauseDashboardHome: "Tạm dừng",
deleteMonitorMsg: "Bạn chắc chắn muốn xóa monitor này chứ?", deleteMonitorMsg: "Bạn chắc chắn muốn xóa monitor này chứ?",
deleteNotificationMsg: "Bạn có chắc chắn muốn xóa kênh thông báo này cho tất cả monitor?", deleteNotificationMsg: "Bạn có chắc chắn muốn xóa kênh thông báo này cho tất cả monitor?",
resoverserverDescription: "Cloudflare là máy chủ mặc định, bạn có thể thay đổi bất cứ lúc nào.", resoverserverDescription: "Cloudflare là máy chủ mặc định, bạn có thể thay đổi bất cứ lúc nào.",
rrtypeDescription: "Hãy chọn RR-Type mà bạn muốn giám sát", rrtypeDescription: "Hãy chọn RR-Type mà bạn muốn giám sát",
pauseMonitorMsg: "Bạn chắc chắn muốn tạm dừng chứ?", pauseMonitorMsg: "Bạn chắc chắn muốn tạm dừng chứ?",
enableDefaultNotificationDescription: "Bật làm mặc định cho mọi monitor mới về sau. Bạn vẫn có thể tắt thông báo riêng cho từng monitor.", enableDefaultNotificationDescription: "Bật làm mặc định cho mọi monitor mới về sau. Bạn vẫn có thể tắt thông báo riêng cho từng monitor.",
clearEventsMsg: "Bạn chắc chắn muốn xoá TẤT CẢ sự kiện cho monitor này chứ?", clearEventsMsg: "Bạn chắc chắn muốn xoá TẤT CẢ sự kiện cho monitor này chứ?",
clearHeartbeatsMsg: "Bạn chắc chắn muốn xoá TẤT CẢ heartbeats cho monitor này chứ?", clearHeartbeatsMsg: "Bạn chắc chắn muốn xoá TẤT CẢ heartbeats cho monitor này chứ?",
confirmClearStatisticsMsg: "Bạn chắc chắn muốn xoá TẤT CẢ số liệu thống kê?", confirmClearStatisticsMsg: "Bạn chắc chắn muốn xoá TẤT CẢ số liệu thống kê?",
importHandleDescription: "Chọn 'Skip existing' nếu bạn muốn bỏ qua mọi monitor và kênh thông báo trùng tên. 'Overwrite' sẽ ghi đè lên tất cả các monitor và kênh thông báo.", importHandleDescription: "Chọn 'Skip existing' nếu bạn muốn bỏ qua mọi monitor và kênh thông báo trùng tên. 'Overwrite' sẽ ghi đè lên tất cả các monitor và kênh thông báo.",
confirmImportMsg: "Bạn có chắc chắn muốn khôi phục bản bản sao lưu này không?.", confirmImportMsg: "Bạn có chắc chắn muốn khôi phục bản bản sao lưu này không?.",
twoFAVerifyLabel: "Vui lòng nhập mã token của bạn để xác minh rằng 2FA đang hoạt động", twoFAVerifyLabel: "Vui lòng nhập mã token của bạn để xác minh rằng 2FA đang hoạt động",
tokenValidSettingsMsg: "Mã token hợp lệ! Bạn có thể lưu cài đặt 2FA bây giờ.", tokenValidSettingsMsg: "Mã token hợp lệ! Bạn có thể lưu cài đặt 2FA bây giờ.",
confirmEnableTwoFAMsg: "Bạn chắc chắn muốn bật 2FA chứ?", confirmEnableTwoFAMsg: "Bạn chắc chắn muốn bật 2FA chứ?",
confirmDisableTwoFAMsg: "Bạn chắc chắn muốn tắt 2FA chứ?", confirmDisableTwoFAMsg: "Bạn chắc chắn muốn tắt 2FA chứ?",
Settings: "Cài đặt", Settings: "Cài đặt",
Dashboard: "Dashboard", Dashboard: "Dashboard",
"New Update": "Bản cập nhật mới", "New Update": "Bản cập nhật mới",
Language: "Ngôn ngữ", Language: "Ngôn ngữ",
Appearance: "Giao diện", Appearance: "Giao diện",
Theme: "Theme", Theme: "Theme",
General: "Chung", General: "Chung",
Version: "Phiên bản", Version: "Phiên bản",
"Check Update On GitHub": "Kiểm tra bản cập nhật mới trên GitHub", "Check Update On GitHub": "Kiểm tra bản cập nhật mới trên GitHub",
List: "List", List: "List",
Add: "Thêm", Add: "Thêm",
"Add New Monitor": "Thêm mới Monitor", "Add New Monitor": "Thêm mới Monitor",
"Quick Stats": "Thống kê nhanh", "Quick Stats": "Thống kê nhanh",
Up: "Lên", Up: "Lên",
Down: "Xuống", Down: "Xuống",
Pending: "Chờ xử lý", Pending: "Chờ xử lý",
Unknown: "Không xác định", Unknown: "Không xác định",
Pause: "Tạm dừng", Pause: "Tạm dừng",
Name: "Tên", Name: "Tên",
Status: "Trạng thái", Status: "Trạng thái",
DateTime: "Ngày tháng", DateTime: "Ngày tháng",
Message: "Tin nhắn", Message: "Tin nhắn",
"No important events": "Không có sự kiện quan trọng nào", "No important events": "Không có sự kiện quan trọng nào",
Resume: "Khôi phục", Resume: "Khôi phục",
Edit: "Sửa", Edit: "Sửa",
Delete: "Xoá", Delete: "Xoá",
Current: "Hiện tại", Current: "Hiện tại",
Uptime: "Uptime", Uptime: "Uptime",
"Cert Exp.": "Cert hết hạn", "Cert Exp.": "Cert hết hạn",
days: "ngày", days: "ngày",
day: "ngày", day: "ngày",
"-day": "-ngày", "-day": "-ngày",
hour: "giờ", hour: "giờ",
"-hour": "-giờ", "-hour": "-giờ",
Response: "Phản hồi", Response: "Phản hồi",
Ping: "Ping", Ping: "Ping",
"Monitor Type": "Kiểu monitor", "Monitor Type": "Kiểu monitor",
Keyword: "Từ khoá", Keyword: "Từ khoá",
"Friendly Name": "Tên dễ hiểu", "Friendly Name": "Tên dễ hiểu",
URL: "URL", URL: "URL",
Hostname: "Hostname", Hostname: "Hostname",
Port: "Port", Port: "Port",
"Heartbeat Interval": "Tần suất heartbeat", "Heartbeat Interval": "Tần suất heartbeat",
Retries: "Thử lại", Retries: "Thử lại",
"Heartbeat Retry Interval": "Tần suất thử lại của Heartbeat", "Heartbeat Retry Interval": "Tần suất thử lại của Heartbeat",
Advanced: "Nâng cao", Advanced: "Nâng cao",
"Upside Down Mode": "Trạng thái đảo ngược", "Upside Down Mode": "Trạng thái đảo ngược",
"Max. Redirects": "Chuyển hướng tối đa", "Max. Redirects": "Chuyển hướng tối đa",
"Accepted Status Codes": "Codes trạng thái chấp nhận", "Accepted Status Codes": "Codes trạng thái chấp nhận",
Save: "Lưu", Save: "Lưu",
Notifications: "Thông báo", Notifications: "Thông báo",
"Not available, please setup.": "Chưa sẵn sàng, hãy cài đặt.", "Not available, please setup.": "Chưa sẵn sàng, hãy cài đặt.",
"Setup Notification": "Cài đặt thông báo", "Setup Notification": "Cài đặt thông báo",
Light: "Sáng", Light: "Sáng",
Dark: "Tối", Dark: "Tối",
Auto: "Tự động", Auto: "Tự động",
"Theme - Heartbeat Bar": "Theme - Heartbeat Bar", "Theme - Heartbeat Bar": "Theme - Heartbeat Bar",
Normal: "Bình thường", Normal: "Bình thường",
Bottom: "Dưới", Bottom: "Dưới",
None: "Không có", None: "Không có",
Timezone: "Múi giờ", Timezone: "Múi giờ",
"Search Engine Visibility": "Hiển thị với các công cụ tìm kiếm", "Search Engine Visibility": "Hiển thị với các công cụ tìm kiếm",
"Allow indexing": "Cho phép indexing", "Allow indexing": "Cho phép indexing",
"Discourage search engines from indexing site": "Ngăn chặn các công cụ tìm kiếm indexing trang", "Discourage search engines from indexing site": "Ngăn chặn các công cụ tìm kiếm indexing trang",
"Change Password": "Thay đổi mật khẩu", "Change Password": "Thay đổi mật khẩu",
"Current Password": "Mật khẩu hiện tại", "Current Password": "Mật khẩu hiện tại",
"New Password": "Mật khẩu mới", "New Password": "Mật khẩu mới",
"Repeat New Password": "Lặp lại mật khẩu mới", "Repeat New Password": "Lặp lại mật khẩu mới",
"Update Password": "Cập nhật mật khẩu", "Update Password": "Cập nhật mật khẩu",
"Disable Auth": "Tắt xác minh", "Disable Auth": "Tắt xác minh",
"Enable Auth": "Bật xác minh", "Enable Auth": "Bật xác minh",
Logout: "Đăng xuất", Logout: "Đăng xuất",
Leave: "Rời", Leave: "Rời",
"I understand, please disable": "Tôi hiểu, làm ơn hãy tắt!", "I understand, please disable": "Tôi hiểu, làm ơn hãy tắt!",
Confirm: "Xác nhận", Confirm: "Xác nhận",
Yes: "Có", Yes: "Có",
No: "Không", No: "Không",
Username: "Tài khoản", Username: "Tài khoản",
Password: "Mật khẩu", Password: "Mật khẩu",
"Remember me": "Lưu phiên đăng nhập", "Remember me": "Lưu phiên đăng nhập",
Login: "Đăng nhập", Login: "Đăng nhập",
"No Monitors, please": "Không có monitor nào", "No Monitors, please": "Không có monitor nào",
"add one": "Thêm mới", "add one": "Thêm mới",
"Notification Type": "Kiểu thông báo", "Notification Type": "Kiểu thông báo",
Email: "Email", Email: "Email",
Test: "Thử", Test: "Thử",
"Certificate Info": "Thông tin Certificate", "Certificate Info": "Thông tin Certificate",
"Resolver Server": "Máy chủ Resolver", "Resolver Server": "Máy chủ Resolver",
"Resource Record Type": "Loại bản ghi", "Resource Record Type": "Loại bản ghi",
"Last Result": "Kết quả cuối cùng", "Last Result": "Kết quả cuối cùng",
"Create your admin account": "Tạo tài khoản quản trị", "Create your admin account": "Tạo tài khoản quản trị",
"Repeat Password": "Lặp lại mật khẩu", "Repeat Password": "Lặp lại mật khẩu",
"Import Backup": "Khôi phục bản sao lưu", "Import Backup": "Khôi phục bản sao lưu",
"Export Backup": "Xuất bản sao lưu", "Export Backup": "Xuất bản sao lưu",
Export: "Xuất", Export: "Xuất",
Import: "Khôi phục", Import: "Khôi phục",
respTime: "Thời gian phản hồi (ms)", respTime: "Thời gian phản hồi (ms)",
notAvailableShort: "N/A", notAvailableShort: "N/A",
"Default enabled": "Mặc định bật", "Default enabled": "Mặc định bật",
"Apply on all existing monitors": "Áp dụng cho tất cả monitor đang có", "Apply on all existing monitors": "Áp dụng cho tất cả monitor đang có",
Create: "Tạo", Create: "Tạo",
"Clear Data": "Xoá dữ liệu", "Clear Data": "Xoá dữ liệu",
Events: "Sự kiện", Events: "Sự kiện",
Heartbeats: "Heartbeats", Heartbeats: "Heartbeats",
"Auto Get": "Tự động lấy", "Auto Get": "Tự động lấy",
backupDescription: "Bạn có thể sao lưu tất cả các màn hình và tất cả các thông báo vào một file JSON.", backupDescription: "Bạn có thể sao lưu tất cả các màn hình và tất cả các thông báo vào một file JSON.",
backupDescription2: "PS: Không bao gồm dữ liệu lịch sử các sự kiện.", backupDescription2: "PS: Không bao gồm dữ liệu lịch sử các sự kiện.",
backupDescription3: "Hãy lưu giữ file này cẩn thận vì trong file đó chứa cả các mã token thông báo.", backupDescription3: "Hãy lưu giữ file này cẩn thận vì trong file đó chứa cả các mã token thông báo.",
alertNoFile: "Hãy chọn file để khôi phục.", alertNoFile: "Hãy chọn file để khôi phục.",
alertWrongFileType: "Hãy chọn file JSON.", alertWrongFileType: "Hãy chọn file JSON.",
"Clear all statistics": "Xoá tất cả thống kê", "Clear all statistics": "Xoá tất cả thống kê",
"Skip existing": "Skip existing", "Skip existing": "Skip existing",
Overwrite: "Ghi đè", Overwrite: "Ghi đè",
Options: "Tuỳ chọn", Options: "Tuỳ chọn",
"Keep both": "Giữ lại cả hai", "Keep both": "Giữ lại cả hai",
"Verify Token": "Xác minh Token", "Verify Token": "Xác minh Token",
"Setup 2FA": "Cài đặt 2FA", "Setup 2FA": "Cài đặt 2FA",
"Enable 2FA": "Bật 2FA", "Enable 2FA": "Bật 2FA",
"Disable 2FA": "Tắt 2FA", "Disable 2FA": "Tắt 2FA",
"2FA Settings": "Cài đặt 2FA", "2FA Settings": "Cài đặt 2FA",
"Two Factor Authentication": "Xác thực hai yếu tố", "Two Factor Authentication": "Xác thực hai yếu tố",
Active: "Hoạt động", Active: "Hoạt động",
Inactive: "Ngừng hoạt động", Inactive: "Ngừng hoạt động",
Token: "Token", Token: "Token",
"Show URI": "Hiển thị URI", "Show URI": "Hiển thị URI",
Tags: "Tags", Tags: "Tags",
"Add New below or Select...": "Thêm mới ở dưới hoặc Chọn...", "Add New below or Select...": "Thêm mới ở dưới hoặc Chọn...",
"Tag with this name already exist.": "Tag với tên đã tồn tại.", "Tag with this name already exist.": "Tag với tên đã tồn tại.",
"Tag with this value already exist.": "Tag với value đã tồn tại.", "Tag with this value already exist.": "Tag với value đã tồn tại.",
color: "Màu sắc", color: "Màu sắc",
"value (optional)": "Value (tuỳ chọn)", "value (optional)": "Value (tuỳ chọn)",
Gray: "Xám", Gray: "Xám",
Red: "Đỏ", Red: "Đỏ",
Orange: "Cam", Orange: "Cam",
Green: "Xanh lá", Green: "Xanh lá",
Blue: "Xanh da trời", Blue: "Xanh da trời",
Indigo: "Chàm", Indigo: "Chàm",
Purple: "Tím", Purple: "Tím",
Pink: "Hồng", Pink: "Hồng",
"Search...": "Tìm kiếm...", "Search...": "Tìm kiếm...",
"Avg. Ping": "Ping Trung bình", "Avg. Ping": "Ping Trung bình",
"Avg. Response": "Phản hồi trung bình", "Avg. Response": "Phản hồi trung bình",
"Entry Page": "Entry Page", "Entry Page": "Entry Page",
statusPageNothing: "Không có gì, hãy thêm nhóm monitor hoặc monitor.", statusPageNothing: "Không có gì, hãy thêm nhóm monitor hoặc monitor.",
"No Services": "Không có dịch vụ", "No Services": "Không có dịch vụ",
"All Systems Operational": "Tất cả các hệ thống hoạt động", "All Systems Operational": "Tất cả các hệ thống hoạt động",
"Partially Degraded Service": "Dịch vụ xuống cấp một phần", "Partially Degraded Service": "Dịch vụ xuống cấp một phần",
"Degraded Service": "Degraded Service", "Degraded Service": "Degraded Service",
"Add Group": "Thêm nhóm", "Add Group": "Thêm nhóm",
"Add a monitor": "Thêm monitor", "Add a monitor": "Thêm monitor",
"Edit Status Page": "Sửa trang trạng thái", "Edit Status Page": "Sửa trang trạng thái",
"Go to Dashboard": "Đi tới Dashboard", "Go to Dashboard": "Đi tới Dashboard",
"Status Page": "Trang trạng thái", "Status Page": "Trang trạng thái",
// Start notification form defaultNotificationName: "My {notification} Alerts ({number})",
defaultNotificationName: "My {notification} Alerts ({number})", here: "tại đây",
here: "tại đây", Required: "Bắt buộc",
"Required": "Bắt buộc", telegram: "Telegram",
"telegram": "Telegram", "Bot Token": "Bot Token",
"Bot Token": "Bot Token", "You can get a token from": "Bạn có thể lấy mã token từ",
"You can get a token from": "Bạn có thể lấy mã token từ", "Chat ID": "Chat ID",
"Chat ID": "Chat ID", supportTelegramChatID: "Hỗ trợ chat trực tiếp / Nhóm / Kênh Chat ID",
supportTelegramChatID: "Hỗ trợ chat trực tiếp / Nhóm / Kênh Chat ID", wayToGetTelegramChatID: "Bạn có thể lấy chat id của mình bằng cách gửi tin nhắn tới bot và truy cập url này để xem chat_id:",
wayToGetTelegramChatID: "Bạn có thể lấy chat id của mình bằng cách gửi tin nhắn tới bot và truy cập url này để xem chat_id:", "YOUR BOT TOKEN HERE": "MÃ BOT TOKEN CỦA BẠN",
"YOUR BOT TOKEN HERE": "MÃ BOT TOKEN CỦA BẠN", chatIDNotFound: "Không tìm thấy Chat ID, vui lòng gửi tin nhắn cho bot này trước",
chatIDNotFound: "Không tìm thấy Chat ID, vui lòng gửi tin nhắn cho bot này trước", webhook: "Webhook",
"webhook": "Webhook", "Post URL": "URL đăng",
"Post URL": "URL đăng", "Content Type": "Loại nội dung",
"Content Type": "Loại nội dung", webhookJsonDesc: "{0} phù hợp với bất kỳ máy chủ http hiện đại nào như express.js",
webhookJsonDesc: "{0} phù hợp với bất kỳ máy chủ http hiện đại nào như express.js", webhookFormDataDesc: "{multipart} phù hợp với PHP, bạn chỉ cần phân tích cú pháp json bằng {decodeFunction}",
webhookFormDataDesc: "{multipart} phù hợp với PHP, bạn chỉ cần phân tích cú pháp json bằng {decodeFunction}", smtp: "Email (SMTP)",
"smtp": "Email (SMTP)", secureOptionNone: "None / STARTTLS (25, 587)",
secureOptionNone: "None / STARTTLS (25, 587)", secureOptionTLS: "TLS (465)",
secureOptionTLS: "TLS (465)", "Ignore TLS Error": "Bỏ qua lỗi TLS",
"Ignore TLS Error": "Bỏ qua lỗi TLS", "From Email": "Từ Email",
"From Email": "Từ Email", "To Email": "Tới Email",
"To Email": "Tới Email", smtpCC: "CC",
smtpCC: "CC", smtpBCC: "BCC",
smtpBCC: "BCC", discord: "Discord",
"discord": "Discord", "Discord Webhook URL": "Discord Webhook URL",
"Discord Webhook URL": "Discord Webhook URL", wayToGetDiscordURL: "Để lấy Discord, hãy vào: Server Settings -> Integrations -> Create Webhook",
wayToGetDiscordURL: "Để lấy Discord, hãy vào: Server Settings -> Integrations -> Create Webhook", "Bot Display Name": "Tên hiển thị của Bot",
"Bot Display Name": "Tên hiển thị của Bot", "Prefix Custom Message": "Tiền tố tin nhắn tuỳ chọn",
"Prefix Custom Message": "Tiền tố tin nhắn tuỳ chọn", "Hello @everyone is...": "Xin chào {'@'} mọi người đang...",
"Hello @everyone is...": "Xin chào {'@'} mọi người đang...", teams: "Microsoft Teams",
"teams": "Microsoft Teams", "Webhook URL": "Webhook URL",
"Webhook URL": "Webhook URL", wayToGetTeamsURL: "Bạn có thể học cách tạo webhook url {0}.",
wayToGetTeamsURL: "Bạn có thể học cách tạo webhook url {0}.", signal: "Signal",
"signal": "Signal", Number: "Số",
"Number": "Số", Recipients: "Người nhận",
"Recipients": "Người nhận", needSignalAPI: "Bạn cần một tín hiệu client với REST API.",
needSignalAPI: "Bạn cần một tín hiệu client với REST API.", wayToCheckSignalURL: "Bạn có thể kiểm tra url này để xem cách thiết lập:",
wayToCheckSignalURL: "Bạn có thể kiểm tra url này để xem cách thiết lập:", signalImportant: "QUAN TRỌNG: Bạn không thể kết hợp các nhóm và số trong người nhận!",
signalImportant: "QUAN TRỌNG: Bạn không thể kết hợp các nhóm và số trong người nhận!", gotify: "Gotify",
"gotify": "Gotify", "Application Token": "Mã Token ứng dụng",
"Application Token": "Mã Token ứng dụng", "Server URL": "URL máy chủ",
"Server URL": "URL máy chủ", Priority: "Mức ưu tiên",
"Priority": "Mức ưu tiên", slack: "Slack",
"slack": "Slack", "Icon Emoji": "Icon Emoji",
"Icon Emoji": "Icon Emoji", "Channel Name": "Tên Channel",
"Channel Name": "Tên Channel", "Uptime Kuma URL": "Uptime Kuma URL",
"Uptime Kuma URL": "Uptime Kuma URL", aboutWebhooks: "Thông tin thêm về webhook trên: {0}",
aboutWebhooks: "Thông tin thêm về webhook trên: {0}", aboutChannelName: "Nhập tên kênh trên {0} trường Channel Name nếu bạn muốn bỏ qua kênh webhook. vd: #other-channel",
aboutChannelName: "Nhập tên kênh trên {0} trường Channel Name nếu bạn muốn bỏ qua kênh webhook. vd: #other-channel", aboutKumaURL: "Nếu bạn để trống trường Uptime Kuma URL, mặc định sẽ là trang Project Github.",
aboutKumaURL: "Nếu bạn để trống trường Uptime Kuma URL, mặc định sẽ là trang Project Github.", emojiCheatSheet: "Bảng tra cứu Emoji: {0}",
emojiCheatSheet: "Bảng tra cứu Emoji: {0}", "rocket.chat": "Rocket.chat",
"rocket.chat": "Rocket.chat", pushover: "Pushover",
pushover: "Pushover", pushy: "Pushy",
pushy: "Pushy", octopush: "Octopush",
octopush: "Octopush", promosms: "PromoSMS",
promosms: "PromoSMS", lunasea: "LunaSea",
lunasea: "LunaSea", apprise: "Thông báo (Hỗ trợ 50+ dịch vụ thông báo)",
apprise: "Thông báo (Hỗ trợ 50+ dịch vụ thông báo)", pushbullet: "Pushbullet",
pushbullet: "Pushbullet", line: "Line Messenger",
line: "Line Messenger", mattermost: "Mattermost",
mattermost: "Mattermost", "User Key": "User Key",
"User Key": "User Key", Device: "Thiết bị",
"Device": "Thiết bị", "Message Title": "Tiêu đề tin nhắn",
"Message Title": "Tiêu đề tin nhắn", "Notification Sound": "Âm thanh thông báo",
"Notification Sound": "Âm thanh thông báo", "More info on:": "Thông tin chi tiết tại: {0}",
"More info on:": "Thông tin chi tiết tại: {0}", pushoverDesc1: "Mức ưu tiên khẩn cấp (2) có thời gian chờ mặc định là 30 giây giữa các lần thử lại và sẽ hết hạn sau 1 giờ.",
pushoverDesc1: "Mức ưu tiên khẩn cấp (2) có thời gian chờ mặc định là 30 giây giữa các lần thử lại và sẽ hết hạn sau 1 giờ.", pushoverDesc2: "Nếu bạn muốn gửi thông báo đến các thiết bị khác nhau, hãy điền vào trường Thiết bị.",
pushoverDesc2: "Nếu bạn muốn gửi thông báo đến các thiết bị khác nhau, hãy điền vào trường Thiết bị.", "SMS Type": "SMS Type",
"SMS Type": "SMS Type", octopushTypePremium: "Premium (Nhanh - Khuyến nghị nên dùng cho cảnh báo)",
octopushTypePremium: "Premium (Nhanh - Khuyến nghị nên dùng cho cảnh báo)", octopushTypeLowCost: "Giá rẻ (Chậm, thỉnh thoảng bị chặn)",
octopushTypeLowCost: "Giá rẻ (Chậm, thỉnh thoảng bị chặn)", "Check octopush prices": "Kiểm tra giá octopush {0}.",
"Check octopush prices": "Kiểm tra giá octopush {0}.", octopushPhoneNumber: "Số điện thoại (Định dạng intl, vd : +33612345678) ",
octopushPhoneNumber: "Số điện thoại (Định dạng intl, vd : +33612345678) ", octopushSMSSender: "SMS người gửi : 3-11 ký tự chữ, số và dấu cách (a-zA-Z0-9)",
octopushSMSSender: "SMS người gửi : 3-11 ký tự chữ, số và dấu cách (a-zA-Z0-9)", "LunaSea Device ID": "LunaSea ID thiết bị",
"LunaSea Device ID": "LunaSea ID thiết bị", "Apprise URL": "Apprise URL",
"Apprise URL": "Apprise URL", "Example:": "Ví dụ: {0}",
"Example:": "Ví dụ: {0}", "Read more:": "Đọc thêm: {0}",
"Read more:": "Đọc thêm: {0}", "Status:": "Trạng thái: {0}",
"Status:": "Trạng thái: {0}", "Read more": "Đọc thêm",
"Read more": "Đọc thêm", appriseInstalled: "Đã cài đặt Apprise.",
appriseInstalled: "Đã cài đặt Apprise.", appriseNotInstalled: "Chưa cài đặt Apprise. {0}",
appriseNotInstalled: "Chưa cài đặt Apprise. {0}", "Access Token": "Token truy cập",
"Access Token": "Token truy cập", "Channel access token": "Token kênh truy cập",
"Channel access token": "Token kênh truy cập", "Line Developers Console": "Line Developers Console",
"Line Developers Console": "Line Developers Console", lineDevConsoleTo: "Line Developers Console - {0}",
lineDevConsoleTo: "Line Developers Console - {0}", "Basic Settings": "Cài đặt cơ bản",
"Basic Settings": "Cài đặt cơ bản", "User ID": "User ID",
"User ID": "User ID", "Messaging API": "Messaging API",
"Messaging API": "Messaging API", wayToGetLineChannelToken: "Trước tiên, hãy truy cập {0},tạo nhà cung cấp và kênh (Messaging API), sau đó bạn có thể nhận mã token truy cập kênh và id người dùng từ các mục menu được đề cập ở trên.",
wayToGetLineChannelToken: "Trước tiên, hãy truy cập {0},tạo nhà cung cấp và kênh (Messaging API), sau đó bạn có thể nhận mã token truy cập kênh và id người dùng từ các mục menu được đề cập ở trên.", "Icon URL": "Icon URL",
"Icon URL": "Icon URL", aboutIconURL: "Bạn có thể cung cấp liên kết đến ảnh trong \"Icon URL\" để ghi đè ảnh hồ sơ mặc định. Sẽ không được sử dụng nếu Biểu tượng cảm xúc được thiết lập.",
aboutIconURL: "Bạn có thể cung cấp liên kết đến ảnh trong \"Icon URL\" để ghi đè ảnh hồ sơ mặc định. Sẽ không được sử dụng nếu Biểu tượng cảm xúc được thiết lập.", aboutMattermostChannelName: "Bạn có thể ghi đè kênh mặc định mà webhook đăng lên bằng cách nhập tên kênh vào trường \"Channel Name\". Điều này cần được bật trong cài đặt Mattermost webhook. Ví dụ: #other-channel",
aboutMattermostChannelName: "Bạn có thể ghi đè kênh mặc định mà webhook đăng lên bằng cách nhập tên kênh vào trường \"Channel Name\". Điều này cần được bật trong cài đặt Mattermost webhook. Ví dụ: #other-channel", matrix: "Matrix",
"matrix": "Matrix", promosmsTypeEco: "SMS ECO - rẻ nhưng chậm và thường xuyên quá tải. Chỉ dành cho người Ba Lan.",
promosmsTypeEco: "SMS ECO - rẻ nhưng chậm và thường xuyên quá tải. Chỉ dành cho người Ba Lan.", promosmsTypeFlash: "SMS FLASH - Tin nhắn sẽ tự động hiển thị trên thiết bị của người nhận. Chỉ dành cho người Ba Lan.",
promosmsTypeFlash: "SMS FLASH - Tin nhắn sẽ tự động hiển thị trên thiết bị của người nhận. Chỉ dành cho người Ba Lan.", promosmsTypeFull: "SMS FULL - SMS cao cấp, Bạn có thể sử dụng Tên Người gửi (Bạn cần đăng ký tên trước). Đáng tin cậy cho các cảnh báo.",
promosmsTypeFull: "SMS FULL - SMS cao cấp, Bạn có thể sử dụng Tên Người gửi (Bạn cần đăng ký tên trước). Đáng tin cậy cho các cảnh báo.", promosmsTypeSpeed: "SMS SPEED - Ưu tiên cao nhất trong hệ thống. Rất nhanh chóng và đáng tin cậy nhưng tốn kém, (giá gấp đôi SMS FULL).",
promosmsTypeSpeed: "SMS SPEED - Ưu tiên cao nhất trong hệ thống. Rất nhanh chóng và đáng tin cậy nhưng tốn kém, (giá gấp đôi SMS FULL).", promosmsPhoneNumber: "Số điện thoại (Bỏ qua mã vùng với người Ba Lan)",
promosmsPhoneNumber: "Số điện thoại (Bỏ qua mã vùng với người Ba Lan)", promosmsSMSSender: "SMS Tên người gửi: Tên đã đăng ký trước hoặc tên mặc định: InfoSMS, SMS Info, MaxSMS, INFO, SMS",
promosmsSMSSender: "SMS Tên người gửi: Tên đã đăng ký trước hoặc tên mặc định: InfoSMS, SMS Info, MaxSMS, INFO, SMS", "Feishu WebHookUrl": "Feishu WebHookUrl",
"Feishu WebHookUrl": "Feishu WebHookUrl", };
// End notification form
};

@ -65,7 +65,7 @@ export default {
"Max. Redirects": "重定向次数", "Max. Redirects": "重定向次数",
"Accepted Status Codes": "有效状态码", "Accepted Status Codes": "有效状态码",
"Push URL": "推送链接", "Push URL": "推送链接",
needPushEvery: "你需要每 {0} 秒调用一次", needPushEvery: "你需要每 {0} 秒调用一次",
pushOptionalParams: "可选参数:{0}", pushOptionalParams: "可选参数:{0}",
Save: "保存", Save: "保存",
Notifications: "消息通知", Notifications: "消息通知",

@ -328,6 +328,10 @@ export default {
clearStatistics(callback) { clearStatistics(callback) {
socket.emit("clearStatistics", callback); socket.emit("clearStatistics", callback);
}, },
getMonitorBeats(monitorID, period, callback) {
socket.emit("getMonitorBeats", monitorID, period, callback);
}
}, },
computed: { computed: {

@ -340,11 +340,17 @@ export default {
}, },
bodyPlaceholder() { bodyPlaceholder() {
return "{\n\t\"id\": 124357,\n\t\"username\": \"admin\",\n\t\"password\": \"myAdminPassword\"\n}"; return `Example:
{
"key": "value"
}`;
}, },
headersPlaceholder() { headersPlaceholder() {
return "{\n\t\"Authorization\": \"Bearer abc123\",\n\t\"Content-Type\": \"application/json\"\n}"; return `Example:
{
"HeaderName": "HeaderValue"
}`;
} }
}, },

@ -112,7 +112,7 @@
<div class="input-group mb-3"> <div class="input-group mb-3">
<input id="primaryBaseURL" v-model="settings.primaryBaseURL" class="form-control" name="primaryBaseURL" placeholder="https://" pattern="https?://.+"> <input id="primaryBaseURL" v-model="settings.primaryBaseURL" class="form-control" name="primaryBaseURL" placeholder="https://" pattern="https?://.+">
<button class="btn btn-outline-primary" type="button" @click="autoGetPrimaryBaseURL">Auto Get</button> <button class="btn btn-outline-primary" type="button" @click="autoGetPrimaryBaseURL">{{ $t("Auto Get") }}</button>
</div> </div>
<div class="form-text"> <div class="form-text">
@ -149,6 +149,7 @@
<!-- Change Password --> <!-- Change Password -->
<template v-if="! settings.disableAuth"> <template v-if="! settings.disableAuth">
<h2 class="mt-5 mb-2">{{ $t("Change Password") }}</h2> <h2 class="mt-5 mb-2">{{ $t("Change Password") }}</h2>
<p>{{ $t("Current User") }}: <strong>{{ this.username }}</strong></p>
<form class="mb-3" @submit.prevent="savePassword"> <form class="mb-3" @submit.prevent="savePassword">
<div class="mb-3"> <div class="mb-3">
<label for="current-password" class="form-label">{{ $t("Current Password") }}</label> <label for="current-password" class="form-label">{{ $t("Current Password") }}</label>
@ -231,13 +232,15 @@
{{ importAlert }} {{ importAlert }}
</div> </div>
<!-- Advanced -->
<h2 class="mt-5 mb-2">{{ $t("Advanced") }}</h2> <h2 class="mt-5 mb-2">{{ $t("Advanced") }}</h2>
<div class="mb-3"> <div class="mb-3">
<button v-if="settings.disableAuth" class="btn btn-outline-primary me-2 mb-2" @click="enableAuth">{{ $t("Enable Auth") }}</button> <button v-if="settings.disableAuth" class="btn btn-outline-primary me-2 mb-2" @click="enableAuth">{{ $t("Enable Auth") }}</button>
<button v-if="! settings.disableAuth" class="btn btn-primary me-2 mb-2" @click="confirmDisableAuth">{{ $t("Disable Auth") }}</button> <button v-if="! settings.disableAuth" class="btn btn-primary me-2 mb-2" @click="confirmDisableAuth">{{ $t("Disable Auth") }}</button>
<button v-if="! settings.disableAuth" class="btn btn-danger me-2 mb-2" @click="$root.logout">{{ $t("Logout") }}</button> <button v-if="! settings.disableAuth" class="btn btn-danger me-2 mb-2" @click="$root.logout">{{ $t("Logout") }}</button>
<button class="btn btn-outline-danger me-1 mb-1" @click="confirmClearStatistics">{{ $t("Clear all statistics") }}</button> <button class="btn btn-outline-danger me-2 mb-2" @click="confirmClearStatistics">{{ $t("Clear all statistics") }}</button>
<button class="btn btn-info me-2 mb-2" @click="shrinkDatabase">{{ $t("Shrink Database") }} ({{ databaseSizeDisplay }})</button>
</div> </div>
</template> </template>
</div> </div>
@ -413,11 +416,13 @@ import utc from "dayjs/plugin/utc";
import timezone from "dayjs/plugin/timezone"; import timezone from "dayjs/plugin/timezone";
import NotificationDialog from "../components/NotificationDialog.vue"; import NotificationDialog from "../components/NotificationDialog.vue";
import TwoFADialog from "../components/TwoFADialog.vue"; import TwoFADialog from "../components/TwoFADialog.vue";
import jwt_decode from "jwt-decode";
dayjs.extend(utc); dayjs.extend(utc);
dayjs.extend(timezone); dayjs.extend(timezone);
import { timezoneList, setPageLocale } from "../util-frontend"; import { timezoneList, setPageLocale } from "../util-frontend";
import { useToast } from "vue-toastification"; import { useToast } from "vue-toastification";
import { debug } from "../util.ts";
const toast = useToast(); const toast = useToast();
@ -427,6 +432,7 @@ export default {
TwoFADialog, TwoFADialog,
Confirm, Confirm,
}, },
data() { data() {
return { return {
timezoneList: timezoneList(), timezoneList: timezoneList(),
@ -445,8 +451,16 @@ export default {
importAlert: null, importAlert: null,
importHandle: "skip", importHandle: "skip",
processing: false, processing: false,
databaseSize: 0,
}; };
}, },
computed: {
databaseSizeDisplay() {
return Math.round(this.databaseSize / 1024 / 1024 * 10) / 10 + " MB";
}
},
watch: { watch: {
"password.repeatNewPassword"() { "password.repeatNewPassword"() {
this.invalidPassword = false; this.invalidPassword = false;
@ -459,7 +473,9 @@ export default {
}, },
mounted() { mounted() {
this.loadUsername();
this.loadSettings(); this.loadSettings();
this.loadDatabaseSize();
}, },
methods: { methods: {
@ -484,6 +500,12 @@ export default {
} }
}, },
loadUsername() {
const jwtToken = this.$root.storage().token;
const jwtPayload = jwt_decode(jwtToken);
this.username = jwtPayload.username;
},
loadSettings() { loadSettings() {
this.$root.getSocket().emit("getSettings", (res) => { this.$root.getSocket().emit("getSettings", (res) => {
this.settings = res.data; this.settings = res.data;
@ -592,7 +614,33 @@ export default {
autoGetPrimaryBaseURL() { autoGetPrimaryBaseURL() {
this.settings.primaryBaseURL = location.protocol + "//" + location.host; this.settings.primaryBaseURL = location.protocol + "//" + location.host;
},
shrinkDatabase() {
this.$root.getSocket().emit("shrinkDatabase", (res) => {
if (res.ok) {
this.loadDatabaseSize();
toast.success("Done");
} else {
debug(res);
}
});
},
loadDatabaseSize() {
debug("load database size");
this.$root.getSocket().emit("getDatabaseSize", (res) => {
if (res.ok) {
this.databaseSize = res.size;
debug("database size: " + res.size);
} else {
debug(res);
}
});
} }
}, },
}; };
</script> </script>

@ -51,7 +51,7 @@ export function timezoneList() {
} }
export function setPageLocale() { export function setPageLocale() {
const html = document.documentElement const html = document.documentElement
html.setAttribute('lang', currentLocale() ) html.setAttribute('lang', currentLocale() )
html.setAttribute('dir', localeDirection() ) html.setAttribute('dir', localeDirection() )
} }

Loading…
Cancel
Save