mirror of
https://github.com/louislam/uptime-kuma.git
synced 2024-12-17 11:44:38 -05:00
Merge branch 'master' into public-dashboard
# Conflicts: # server/server.js # src/main.js
This commit is contained in:
commit
d7a230ac15
1
.github/ISSUE_TEMPLATE/ask-for-help.md
vendored
1
.github/ISSUE_TEMPLATE/ask-for-help.md
vendored
@ -16,4 +16,3 @@ Docker Version:
|
||||
Node.js Version (Without Docker only):
|
||||
OS:
|
||||
Browser:
|
||||
|
||||
|
8
.github/ISSUE_TEMPLATE/bug_report.md
vendored
8
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -15,6 +15,7 @@ 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 '....'
|
||||
@ -23,7 +24,6 @@ Steps to reproduce the behavior:
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
|
||||
**Info**
|
||||
Uptime Kuma Version:
|
||||
Using Docker?: Yes/No
|
||||
@ -32,13 +32,11 @@ 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)
|
||||
|
||||
Docker: `docker logs <container id>`
|
||||
PM2: `~/.pm2/logs/` (e.g. `/home/ubuntu/.pm2/logs`)
|
||||
|
@ -52,8 +52,8 @@ For example, recently, because I am not a python expert, I spent a 2 hours to re
|
||||
|
||||
# Coding Styles
|
||||
|
||||
- Follow .editorconfig
|
||||
- Follow eslint
|
||||
- Follow `.editorconfig`
|
||||
- Follow ESLint
|
||||
|
||||
## Name convention
|
||||
|
||||
@ -62,9 +62,10 @@ For example, recently, because I am not a python expert, I spent a 2 hours to re
|
||||
- CSS/SCSS: dash-type
|
||||
|
||||
# Tools
|
||||
|
||||
- Node.js >= 14
|
||||
- Git
|
||||
- IDE that supports .editorconfig and eslint (I am using Intellji Idea)
|
||||
- IDE that supports EditorConfig and ESLint (I am using Intellji Idea)
|
||||
- A SQLite tool (I am using SQLite Expert Personal)
|
||||
|
||||
# Install dependencies
|
||||
@ -75,7 +76,7 @@ npm install --dev
|
||||
|
||||
For npm@7, you need --legacy-peer-deps
|
||||
|
||||
```
|
||||
```bash
|
||||
npm install --legacy-peer-deps --dev
|
||||
```
|
||||
|
||||
@ -89,8 +90,7 @@ npm run start-server
|
||||
node server/server.js
|
||||
```
|
||||
|
||||
It binds to 0.0.0.0:3001 by default.
|
||||
|
||||
It binds to `0.0.0.0:3001` by default.
|
||||
|
||||
## Backend Details
|
||||
|
||||
@ -100,7 +100,7 @@ express.js is just used for serving the frontend built files (index.html, .js an
|
||||
|
||||
# Frontend Dev
|
||||
|
||||
Start frontend dev server. Hot-reload enabled in this way. It binds to 0.0.0.0:3000.
|
||||
Start frontend dev server. Hot-reload enabled in this way. It binds to `0.0.0.0:3000` by default.
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
@ -108,7 +108,7 @@ npm run dev
|
||||
|
||||
PS: You can ignore those scss warnings, those warnings are from Bootstrap that I cannot fix.
|
||||
|
||||
You can use Vue Devtool Chrome extension for debugging.
|
||||
You can use Vue.js devtools Chrome extension for debugging.
|
||||
|
||||
After the frontend server started. It cannot connect to the websocket server even you have started the server. You need to tell the frontend that is a dev env by running this in DevTool console and refresh:
|
||||
|
||||
@ -118,8 +118,7 @@ localStorage.dev = "dev";
|
||||
|
||||
So that the frontend will try to connect websocket server in 3001.
|
||||
|
||||
Alternately, you can specific NODE_ENV to "development".
|
||||
|
||||
Alternately, you can specific `NODE_ENV` to "development".
|
||||
|
||||
## Build the frontend
|
||||
|
||||
@ -131,22 +130,17 @@ npm run build
|
||||
|
||||
Uptime Kuma Frontend is a single page application (SPA). Most paths are handled by Vue Router.
|
||||
|
||||
The router in "src/main.js"
|
||||
The router is in `src/router.js`
|
||||
|
||||
As you can see, most data in frontend is stored in root level, even though you changed the current router to any other pages.
|
||||
|
||||
The data and socket logic in "src/mixins/socket.js"
|
||||
The data and socket logic are in `src/mixins/socket.js`.
|
||||
|
||||
# Database Migration
|
||||
|
||||
1. create `patch{num}.sql` in `./db/`
|
||||
1. update `latestVersion` in `./server/database.js`
|
||||
1. Create `patch{num}.sql` in `./db/`
|
||||
2. Update `latestVersion` in `./server/database.js`
|
||||
|
||||
# Unit Test
|
||||
|
||||
Yes, no unit test for now. I know it is very important, but at the same time my spare time is very limited. I want to implement my ideas first. I will go back to this in some points.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -20,7 +20,6 @@ It is a 5 minutes live demo, all data will be deleted after that. The server is
|
||||
|
||||
VPS is sponsored by Uptime Kuma sponsors on [Open Collective](https://opencollective.com/uptime-kuma)! Thank you so much!
|
||||
|
||||
|
||||
## ⭐ Features
|
||||
|
||||
* Monitoring uptime for HTTP(s) / TCP / Ping / DNS Record.
|
||||
@ -65,7 +64,6 @@ If you need more options or need to browse via a reserve proxy, please read:
|
||||
|
||||
https://github.com/louislam/uptime-kuma/wiki/%F0%9F%94%A7-How-to-Install
|
||||
|
||||
|
||||
## 🆙 How to Update
|
||||
|
||||
Please read:
|
||||
@ -107,7 +105,6 @@ Telegram Notification Sample:
|
||||
|
||||
If you love this project, please consider giving me a ⭐.
|
||||
|
||||
|
||||
## 🗣️ Discussion
|
||||
|
||||
You can also discuss or ask for help in [Issues](https://github.com/louislam/uptime-kuma/issues).
|
||||
@ -116,7 +113,6 @@ Alternatively, you can discuss in my original post on reddit: https://www.reddit
|
||||
|
||||
I think the real "Discussion" tab is hard to use, as it is reddit-like flow, I always missed new comments.
|
||||
|
||||
|
||||
## Contribute
|
||||
|
||||
If you want to report a bug or request a new feature. Free feel to open a [new issue](https://github.com/louislam/uptime-kuma/issues).
|
||||
@ -126,4 +122,3 @@ If you want to translate Uptime Kuma into your langauge, please read: https://gi
|
||||
If you want to modify Uptime Kuma, this guideline may be useful for you: https://github.com/louislam/uptime-kuma/blob/master/CONTRIBUTING.md
|
||||
|
||||
English proofreading is needed too because my grammar is not that great sadly. Feel free to correct my grammar in this readme, source code, or wiki.
|
||||
|
||||
|
@ -8,24 +8,25 @@ Kustomize is a tool which builds a complete deployment file for all config eleme
|
||||
You can edit the files in the ```uptime-kuma``` folder except the ```kustomization.yml``` until you know what you're doing.
|
||||
If you want to choose another namespace you can edit the ```kustomization.yml``` in the ```kubernetes```-Folder and change the ```namespace: uptime-kuma``` to something you like.
|
||||
|
||||
It creates a certificate with the specified Issuer and creates the Ingress for the Uptime-Kuma ClusterIP-Service
|
||||
It creates a certificate with the specified Issuer and creates the Ingress for the Uptime-Kuma ClusterIP-Service.
|
||||
|
||||
## What do I have to edit?
|
||||
|
||||
## What do i have to edit?
|
||||
You have to edit the ```ingressroute.yml``` to your needs.
|
||||
This ingressroute.yml is for the [nginx-ingress-controller](https://kubernetes.github.io/ingress-nginx/) in combination with the [cert-manager](https://cert-manager.io/).
|
||||
|
||||
- host
|
||||
- secrets and secret names
|
||||
- Host
|
||||
- Secrets and secret names
|
||||
- (Cluster)Issuer (optional)
|
||||
- the Version in the Deployment-File
|
||||
- update:
|
||||
- change to newer version and run the above commands, it will update the pods one after another
|
||||
- The Version in the Deployment-File
|
||||
- Update:
|
||||
- Change to newer version and run the above commands, it will update the pods one after another
|
||||
|
||||
## How To use:
|
||||
## How To use
|
||||
|
||||
- install [kustomize](https://kubectl.docs.kubernetes.io/installation/kustomize/)
|
||||
- Install [kustomize](https://kubectl.docs.kubernetes.io/installation/kustomize/)
|
||||
- Edit files mentioned above to your needs
|
||||
- run ```kustomize build > apply.yml```
|
||||
- run ```kubectl apply -f apply.yml```
|
||||
- Run ```kustomize build > apply.yml```
|
||||
- Run ```kubectl apply -f apply.yml```
|
||||
|
||||
Now you should see some k8s magic and Uptime-Kuma should be available at the specified address.
|
||||
|
661
package-lock.json
generated
661
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
29
package.json
29
package.json
@ -42,16 +42,16 @@
|
||||
"@fortawesome/free-regular-svg-icons": "^5.15.4",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.15.4",
|
||||
"@fortawesome/vue-fontawesome": "^3.0.0-4",
|
||||
"@popperjs/core": "^2.9.3",
|
||||
"@popperjs/core": "^2.10.1",
|
||||
"args-parser": "^1.3.0",
|
||||
"axios": "^0.21.1",
|
||||
"axios": "^0.21.4",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"bootstrap": "^5.1.0",
|
||||
"bootstrap": "^5.1.1",
|
||||
"chart.js": "^3.5.1",
|
||||
"chartjs-adapter-dayjs": "^1.0.0",
|
||||
"command-exists": "^1.2.9",
|
||||
"compare-versions": "^3.6.0",
|
||||
"dayjs": "^1.10.6",
|
||||
"dayjs": "^1.10.7",
|
||||
"express": "^4.17.1",
|
||||
"express-basic-auth": "^1.2.0",
|
||||
"form-data": "^4.0.0",
|
||||
@ -68,10 +68,11 @@
|
||||
"socket.io-client": "^4.2.0",
|
||||
"sqlite3": "github:mapbox/node-sqlite3#593c9d",
|
||||
"tcp-ping": "^0.1.1",
|
||||
"timezones-list": "^3.0.1",
|
||||
"thirty-two": "^1.0.2",
|
||||
"v-pagination-3": "^0.1.6",
|
||||
"vue": "^3.2.8",
|
||||
"vue-chart-3": "^0.5.7",
|
||||
"vue-chart-3": "^0.5.8",
|
||||
"vue-confirm-dialog": "^1.0.2",
|
||||
"vue-contenteditable": "^3.0.4",
|
||||
"vue-i18n": "^9.1.7",
|
||||
@ -82,19 +83,19 @@
|
||||
"vuedraggable": "^4.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/eslint-parser": "^7.15.0",
|
||||
"@types/bootstrap": "^5.1.2",
|
||||
"@vitejs/plugin-legacy": "^1.5.2",
|
||||
"@vitejs/plugin-vue": "^1.6.0",
|
||||
"@vue/compiler-sfc": "^3.2.6",
|
||||
"core-js": "^3.17.0",
|
||||
"@babel/eslint-parser": "^7.15.4",
|
||||
"@types/bootstrap": "^5.1.4",
|
||||
"@vitejs/plugin-legacy": "^1.5.3",
|
||||
"@vitejs/plugin-vue": "^1.6.2",
|
||||
"@vue/compiler-sfc": "^3.2.11",
|
||||
"core-js": "^3.17.3",
|
||||
"dns2": "^2.0.1",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-plugin-vue": "^7.17.0",
|
||||
"sass": "^1.38.2",
|
||||
"sass": "^1.39.2",
|
||||
"stylelint": "^13.13.1",
|
||||
"stylelint-config-standard": "^22.0.0",
|
||||
"typescript": "^4.4.2",
|
||||
"vite": "^2.5.3"
|
||||
"typescript": "^4.4.3",
|
||||
"vite": "^2.5.7"
|
||||
}
|
||||
}
|
||||
|
@ -62,6 +62,11 @@ class Discord extends NotificationProvider {
|
||||
],
|
||||
}],
|
||||
}
|
||||
|
||||
if (notification.discordPrefixMessage) {
|
||||
discorddowndata.content = notification.discordPrefixMessage;
|
||||
}
|
||||
|
||||
await axios.post(notification.discordWebhookUrl, discorddowndata)
|
||||
return okMsg;
|
||||
|
||||
@ -92,6 +97,11 @@ class Discord extends NotificationProvider {
|
||||
],
|
||||
}],
|
||||
}
|
||||
|
||||
if (notification.discordPrefixMessage) {
|
||||
discordupdata.content = notification.discordPrefixMessage;
|
||||
}
|
||||
|
||||
await axios.post(notification.discordWebhookUrl, discordupdata)
|
||||
return okMsg;
|
||||
}
|
||||
|
@ -153,6 +153,10 @@ let indexHTML = fs.readFileSync("./dist/index.html").toString();
|
||||
|
||||
app.use("/", express.static("dist"));
|
||||
|
||||
app.get("/.well-known/change-password", async (_, response) => {
|
||||
response.redirect("https://github.com/louislam/uptime-kuma/wiki/Reset-Password-via-CLI");
|
||||
});
|
||||
|
||||
// ***************************
|
||||
// Public API
|
||||
// ***************************
|
||||
|
@ -80,6 +80,11 @@
|
||||
<label for="discord-username" class="form-label">Bot Display Name</label>
|
||||
<input id="discord-username" v-model="notification.discordUsername" type="text" class="form-control" autocomplete="false" :placeholder="$root.appName">
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="discord-prefix-message" class="form-label">Prefix Custom Message</label>
|
||||
<input id="discord-prefix-message" v-model="notification.discordPrefixMessage" type="text" class="form-control" autocomplete="false" placeholder="Hello @everyone is...">
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-if="notification.type === 'signal'">
|
||||
|
@ -33,7 +33,7 @@
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="password" class="form-label">{{ $t("Password") }}</label>
|
||||
<HiddenInput id="password" v-model="$parent.notification.smtpPassword" :required="true" autocomplete="one-time-code"></HiddenInput>
|
||||
<HiddenInput id="password" v-model="$parent.notification.smtpPassword" :required="false" autocomplete="one-time-code"></HiddenInput>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
|
46
src/i18n.js
Normal file
46
src/i18n.js
Normal file
@ -0,0 +1,46 @@
|
||||
import { createI18n } from "vue-i18n";
|
||||
import daDK from "./languages/da-DK";
|
||||
import deDE from "./languages/de-DE";
|
||||
import en from "./languages/en";
|
||||
import esEs from "./languages/es-ES";
|
||||
import etEE from "./languages/et-EE";
|
||||
import frFR from "./languages/fr-FR";
|
||||
import itIT from "./languages/it-IT";
|
||||
import ja from "./languages/ja";
|
||||
import koKR from "./languages/ko-KR";
|
||||
import nlNL from "./languages/nl-NL";
|
||||
import pl from "./languages/pl";
|
||||
import ruRU from "./languages/ru-RU";
|
||||
import sr from "./languages/sr";
|
||||
import srLatn from "./languages/sr-latn";
|
||||
import svSE from "./languages/sv-SE";
|
||||
import zhCN from "./languages/zh-CN";
|
||||
import zhHK from "./languages/zh-HK";
|
||||
|
||||
const languageList = {
|
||||
en,
|
||||
"zh-HK": zhHK,
|
||||
"de-DE": deDE,
|
||||
"nl-NL": nlNL,
|
||||
"es-ES": esEs,
|
||||
"fr-FR": frFR,
|
||||
"it-IT": itIT,
|
||||
"ja": ja,
|
||||
"da-DK": daDK,
|
||||
"sr": sr,
|
||||
"sr-latn": srLatn,
|
||||
"sv-SE": svSE,
|
||||
"ko-KR": koKR,
|
||||
"ru-RU": ruRU,
|
||||
"zh-CN": zhCN,
|
||||
"pl": pl,
|
||||
"et-EE": etEE,
|
||||
};
|
||||
|
||||
export const i18n = createI18n({
|
||||
locale: localStorage.locale || "en",
|
||||
fallbackLocale: "en",
|
||||
silentFallbackWarn: true,
|
||||
silentTranslationWarn: false,
|
||||
messages: languageList,
|
||||
});
|
@ -3,16 +3,12 @@
|
||||
1. Fork this repo.
|
||||
2. Create a language file. (e.g. `zh-TW.js`) The filename must be ISO language code: http://www.lingoes.net/en/translator/langcode.htm
|
||||
3. `npm run update-language-files --base-lang=de-DE`
|
||||
6. Your language file should be filled in. You can translate now.
|
||||
7. Translate `src/pages/Settings.vue` (search for a `Confirm` component with `rel="confirmDisableAuth"`).
|
||||
8. Import your language file in `src/main.js` and add it to `languageList` constant.
|
||||
9. Make a [pull request](https://github.com/louislam/uptime-kuma/pulls) when you have done.
|
||||
|
||||
|
||||
4. Your language file should be filled in. You can translate now.
|
||||
5. Translate `src/pages/Settings.vue` (search for a `Confirm` component with `rel="confirmDisableAuth"`).
|
||||
6. Import your language file in `src/i18n.js` and add it to `languageList` constant.
|
||||
7. Make a [pull request](https://github.com/louislam/uptime-kuma/pulls) when you have done.
|
||||
|
||||
One of good examples:
|
||||
https://github.com/louislam/uptime-kuma/pull/316/files
|
||||
|
||||
|
||||
If you do not have programming skills, let me know in [Issues section](https://github.com/louislam/uptime-kuma/issues). I will assist you. 😏
|
||||
|
||||
|
@ -16,6 +16,7 @@ export default {
|
||||
resoverserverDescription: "Cloudflare è il server predefinito, è possibile cambiare il server DNS.",
|
||||
rrtypeDescription: "Scegliere il tipo di RR che si vuole monitorare",
|
||||
pauseMonitorMsg: "Si è certi di voler mettere in pausa?",
|
||||
enableDefaultNotificationDescription: "Per ogni nuovo monitoraggio questa notifica sarà abilitata di default. È comunque possibile disabilitare la notifica separatamente per ogni monitoraggio.",
|
||||
clearEventsMsg: "Si è certi di voler eliminare tutti gli eventi per questo servizio?",
|
||||
clearHeartbeatsMsg: "Si è certi di voler eliminare tutti gli intervalli di controllo per questo servizio?",
|
||||
confirmClearStatisticsMsg: "Si è certi di voler eliminare TUTTE le statistiche?",
|
||||
@ -110,24 +111,24 @@ export default {
|
||||
"Last Result": "Ultimo risultato",
|
||||
"Create your admin account": "Crea l'account amministratore",
|
||||
"Repeat Password": "Ripeti Password",
|
||||
"Import/Export Backup": "Importa/Esporta Backup",
|
||||
Export: "Esporta",
|
||||
Import: "Importa",
|
||||
respTime: "Tempo di Risposta (ms)",
|
||||
notAvailableShort: "N/D",
|
||||
"Default enabled": "Abilitato di default",
|
||||
"Also apply to existing monitors": "Applica anche ai monitoraggi esistenti",
|
||||
Create: "Crea",
|
||||
"Clear Data": "Cancella dati",
|
||||
Events: "Eventi",
|
||||
Heartbeats: "Controlli",
|
||||
"Auto Get": "Auto Get",
|
||||
enableDefaultNotificationDescription: "For every new monitor this notification will be enabled by default. You can still disable the notification separately for each monitor.",
|
||||
"Import/Export Backup": "Import/Export Backup",
|
||||
Export: "Export",
|
||||
Import: "Import",
|
||||
"Default enabled": "Default enabled",
|
||||
"Also apply to existing monitors": "Also apply to existing monitors",
|
||||
backupDescription: "You can backup all monitors and all notifications into a JSON file.",
|
||||
backupDescription2: "PS: History and event data is not included.",
|
||||
backupDescription3: "Sensitive data such as notification tokens is included in the export file, please keep it carefully.",
|
||||
alertNoFile: "Please select a file to import.",
|
||||
alertWrongFileType: "Please select a JSON file.",
|
||||
backupDescription: "È possibile fare il backup di tutti i monitoraggi e di tutte le notifiche in un file JSON.",
|
||||
backupDescription2: "P.S.: lo storico e i dati relativi agli eventi non saranno inclusi.",
|
||||
backupDescription3: "Dati sensibili come i token di autenticazione saranno inclusi nel backup, tenere quindi in un luogo sicuro.",
|
||||
alertNoFile: "Selezionare il file da importare.",
|
||||
alertWrongFileType: "Selezionare un file JSON.",
|
||||
"Clear all statistics": "Pulisci tutte le statistiche",
|
||||
twoFAVerifyLabel: "Please type in your token to verify that 2FA is working",
|
||||
tokenValidSettingsMsg: "Token is valid! You can now save the 2FA settings.",
|
||||
confirmEnableTwoFAMsg: "Are you sure you want to enable 2FA?",
|
||||
@ -143,5 +144,4 @@ export default {
|
||||
Inactive: "Inactive",
|
||||
Token: "Token",
|
||||
"Show URI": "Show URI",
|
||||
"Clear all statistics": "Clear all Statistics",
|
||||
}
|
||||
|
130
src/main.js
130
src/main.js
@ -1,142 +1,20 @@
|
||||
import "bootstrap";
|
||||
import { createApp, h } from "vue";
|
||||
import { createI18n } from "vue-i18n"
|
||||
import { createRouter, createWebHistory } from "vue-router";
|
||||
import Toast from "vue-toastification";
|
||||
import "vue-toastification/dist/index.css";
|
||||
import App from "./App.vue";
|
||||
import "./assets/app.scss";
|
||||
import { i18n } from "./i18n";
|
||||
import { FontAwesomeIcon } from "./icon.js";
|
||||
import EmptyLayout from "./layouts/EmptyLayout.vue";
|
||||
import Layout from "./layouts/Layout.vue";
|
||||
import datetime from "./mixins/datetime";
|
||||
import mobile from "./mixins/mobile";
|
||||
import socket from "./mixins/socket";
|
||||
import theme from "./mixins/theme";
|
||||
import mobile from "./mixins/mobile";
|
||||
import datetime from "./mixins/datetime";
|
||||
import publicMixin from "./mixins/public";
|
||||
|
||||
import Dashboard from "./pages/Dashboard.vue";
|
||||
import DashboardHome from "./pages/DashboardHome.vue";
|
||||
import Details from "./pages/Details.vue";
|
||||
import EditMonitor from "./pages/EditMonitor.vue";
|
||||
import Settings from "./pages/Settings.vue";
|
||||
import Setup from "./pages/Setup.vue";
|
||||
import List from "./pages/List.vue";
|
||||
import StatusPage from "./pages/StatusPage.vue";
|
||||
|
||||
import { router } from "./router";
|
||||
import { appName } from "./util.ts";
|
||||
|
||||
import en from "./languages/en";
|
||||
import zhHK from "./languages/zh-HK";
|
||||
import deDE from "./languages/de-DE";
|
||||
import nlNL from "./languages/nl-NL";
|
||||
import esEs from "./languages/es-ES";
|
||||
import frFR from "./languages/fr-FR";
|
||||
import itIT from "./languages/it-IT";
|
||||
import ja from "./languages/ja";
|
||||
import daDK from "./languages/da-DK";
|
||||
import sr from "./languages/sr";
|
||||
import srLatn from "./languages/sr-latn";
|
||||
import svSE from "./languages/sv-SE";
|
||||
import koKR from "./languages/ko-KR";
|
||||
import ruRU from "./languages/ru-RU";
|
||||
import zhCN from "./languages/zh-CN";
|
||||
import pl from "./languages/pl"
|
||||
import etEE from "./languages/et-EE"
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: "/",
|
||||
component: Layout,
|
||||
children: [
|
||||
{
|
||||
name: "root",
|
||||
path: "",
|
||||
component: Dashboard,
|
||||
children: [
|
||||
{
|
||||
name: "DashboardHome",
|
||||
path: "/dashboard",
|
||||
component: DashboardHome,
|
||||
children: [
|
||||
{
|
||||
path: "/dashboard/:id",
|
||||
component: EmptyLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
component: Details,
|
||||
},
|
||||
{
|
||||
path: "/edit/:id",
|
||||
component: EditMonitor,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/add",
|
||||
component: EditMonitor,
|
||||
},
|
||||
{
|
||||
path: "/list",
|
||||
component: List,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/settings",
|
||||
component: Settings,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
],
|
||||
|
||||
},
|
||||
{
|
||||
path: "/setup",
|
||||
component: Setup,
|
||||
},
|
||||
{
|
||||
path: "/status-page",
|
||||
component: StatusPage,
|
||||
},
|
||||
]
|
||||
|
||||
const router = createRouter({
|
||||
linkActiveClass: "active",
|
||||
history: createWebHistory(),
|
||||
routes,
|
||||
})
|
||||
|
||||
const languageList = {
|
||||
en,
|
||||
"zh-HK": zhHK,
|
||||
"de-DE": deDE,
|
||||
"nl-NL": nlNL,
|
||||
"es-ES": esEs,
|
||||
"fr-FR": frFR,
|
||||
"it-IT": itIT,
|
||||
"ja": ja,
|
||||
"da-DK": daDK,
|
||||
"sr": sr,
|
||||
"sr-latn": srLatn,
|
||||
"sv-SE": svSE,
|
||||
"ko-KR": koKR,
|
||||
"ru-RU": ruRU,
|
||||
"zh-CN": zhCN,
|
||||
"pl": pl,
|
||||
"et-EE": etEE,
|
||||
};
|
||||
|
||||
const i18n = createI18n({
|
||||
locale: localStorage.locale || "en",
|
||||
fallbackLocale: "en",
|
||||
silentFallbackWarn: true,
|
||||
silentTranslationWarn: true,
|
||||
messages: languageList
|
||||
});
|
||||
|
||||
const app = createApp({
|
||||
mixins: [
|
||||
socket,
|
||||
|
@ -120,11 +120,10 @@
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<h2 class="mt-5 mb-2">
|
||||
<div v-if="! settings.disableAuth" class="mt-5 mb-3">
|
||||
<h2 class="mb-2">
|
||||
{{ $t("Two Factor Authentication") }}
|
||||
</h2>
|
||||
|
||||
<div class="mb-3">
|
||||
<button class="btn btn-primary me-2" type="button" @click="$refs.TwoFADialog.show()">{{ $t("2FA Settings") }}</button>
|
||||
</div>
|
||||
|
||||
@ -396,7 +395,7 @@ export default {
|
||||
}
|
||||
exportData = JSON.stringify(exportData, null, 4);
|
||||
let downloadItem = document.createElement("a");
|
||||
downloadItem.setAttribute("href", "data:application/json;charset=utf-8," + encodeURI(exportData));
|
||||
downloadItem.setAttribute("href", "data:application/json;charset=utf-8," + encodeURIComponent(exportData));
|
||||
downloadItem.setAttribute("download", fileName);
|
||||
downloadItem.click();
|
||||
},
|
||||
|
71
src/router.js
Normal file
71
src/router.js
Normal file
@ -0,0 +1,71 @@
|
||||
import { createRouter, createWebHistory } from "vue-router";
|
||||
import EmptyLayout from "./layouts/EmptyLayout.vue";
|
||||
import Layout from "./layouts/Layout.vue";
|
||||
import Dashboard from "./pages/Dashboard.vue";
|
||||
import DashboardHome from "./pages/DashboardHome.vue";
|
||||
import Details from "./pages/Details.vue";
|
||||
import EditMonitor from "./pages/EditMonitor.vue";
|
||||
import List from "./pages/List.vue";
|
||||
import Settings from "./pages/Settings.vue";
|
||||
import Setup from "./pages/Setup.vue";
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: "/",
|
||||
component: Layout,
|
||||
children: [
|
||||
{
|
||||
name: "root",
|
||||
path: "",
|
||||
component: Dashboard,
|
||||
children: [
|
||||
{
|
||||
name: "DashboardHome",
|
||||
path: "/dashboard",
|
||||
component: DashboardHome,
|
||||
children: [
|
||||
{
|
||||
path: "/dashboard/:id",
|
||||
component: EmptyLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
component: Details,
|
||||
},
|
||||
{
|
||||
path: "/edit/:id",
|
||||
component: EditMonitor,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/add",
|
||||
component: EditMonitor,
|
||||
},
|
||||
{
|
||||
path: "/list",
|
||||
component: List,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/settings",
|
||||
component: Settings,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
],
|
||||
|
||||
},
|
||||
{
|
||||
path: "/setup",
|
||||
component: Setup,
|
||||
},
|
||||
]
|
||||
|
||||
export const router = createRouter({
|
||||
linkActiveClass: "active",
|
||||
history: createWebHistory(),
|
||||
routes,
|
||||
});
|
@ -1,6 +1,7 @@
|
||||
import dayjs from "dayjs";
|
||||
import timezone from "dayjs/plugin/timezone";
|
||||
import utc from "dayjs/plugin/utc";
|
||||
import timezones from "timezones-list";
|
||||
|
||||
dayjs.extend(utc)
|
||||
dayjs.extend(timezone)
|
||||
@ -16,376 +17,21 @@ function getTimezoneOffset(timeZone) {
|
||||
return -offset;
|
||||
}
|
||||
|
||||
// From: https://stackoverflow.com/questions/38399465/how-to-get-list-of-all-timezones-in-javascript
|
||||
// TODO: Move to separate file
|
||||
const aryIannaTimeZones = [
|
||||
"Europe/Andorra",
|
||||
"Asia/Dubai",
|
||||
"Asia/Kabul",
|
||||
"Europe/Tirane",
|
||||
"Asia/Yerevan",
|
||||
"Antarctica/Casey",
|
||||
"Antarctica/Davis",
|
||||
"Antarctica/Mawson",
|
||||
"Antarctica/Palmer",
|
||||
"Antarctica/Rothera",
|
||||
"Antarctica/Syowa",
|
||||
"Antarctica/Troll",
|
||||
"Antarctica/Vostok",
|
||||
"America/Argentina/Buenos_Aires",
|
||||
"America/Argentina/Cordoba",
|
||||
"America/Argentina/Salta",
|
||||
"America/Argentina/Jujuy",
|
||||
"America/Argentina/Tucuman",
|
||||
"America/Argentina/Catamarca",
|
||||
"America/Argentina/La_Rioja",
|
||||
"America/Argentina/San_Juan",
|
||||
"America/Argentina/Mendoza",
|
||||
"America/Argentina/San_Luis",
|
||||
"America/Argentina/Rio_Gallegos",
|
||||
"America/Argentina/Ushuaia",
|
||||
"Pacific/Pago_Pago",
|
||||
"Europe/Vienna",
|
||||
"Australia/Lord_Howe",
|
||||
"Antarctica/Macquarie",
|
||||
"Australia/Hobart",
|
||||
"Australia/Currie",
|
||||
"Australia/Melbourne",
|
||||
"Australia/Sydney",
|
||||
"Australia/Broken_Hill",
|
||||
"Australia/Brisbane",
|
||||
"Australia/Lindeman",
|
||||
"Australia/Adelaide",
|
||||
"Australia/Darwin",
|
||||
"Australia/Perth",
|
||||
"Australia/Eucla",
|
||||
"Asia/Baku",
|
||||
"America/Barbados",
|
||||
"Asia/Dhaka",
|
||||
"Europe/Brussels",
|
||||
"Europe/Sofia",
|
||||
"Atlantic/Bermuda",
|
||||
"Asia/Brunei",
|
||||
"America/La_Paz",
|
||||
"America/Noronha",
|
||||
"America/Belem",
|
||||
"America/Fortaleza",
|
||||
"America/Recife",
|
||||
"America/Araguaina",
|
||||
"America/Maceio",
|
||||
"America/Bahia",
|
||||
"America/Sao_Paulo",
|
||||
"America/Campo_Grande",
|
||||
"America/Cuiaba",
|
||||
"America/Santarem",
|
||||
"America/Porto_Velho",
|
||||
"America/Boa_Vista",
|
||||
"America/Manaus",
|
||||
"America/Eirunepe",
|
||||
"America/Rio_Branco",
|
||||
"America/Nassau",
|
||||
"Asia/Thimphu",
|
||||
"Europe/Minsk",
|
||||
"America/Belize",
|
||||
"America/St_Johns",
|
||||
"America/Halifax",
|
||||
"America/Glace_Bay",
|
||||
"America/Moncton",
|
||||
"America/Goose_Bay",
|
||||
"America/Blanc-Sablon",
|
||||
"America/Toronto",
|
||||
"America/Nipigon",
|
||||
"America/Thunder_Bay",
|
||||
"America/Iqaluit",
|
||||
"America/Pangnirtung",
|
||||
"America/Atikokan",
|
||||
"America/Winnipeg",
|
||||
"America/Rainy_River",
|
||||
"America/Resolute",
|
||||
"America/Rankin_Inlet",
|
||||
"America/Regina",
|
||||
"America/Swift_Current",
|
||||
"America/Edmonton",
|
||||
"America/Cambridge_Bay",
|
||||
"America/Yellowknife",
|
||||
"America/Inuvik",
|
||||
"America/Creston",
|
||||
"America/Dawson_Creek",
|
||||
"America/Fort_Nelson",
|
||||
"America/Vancouver",
|
||||
"America/Whitehorse",
|
||||
"America/Dawson",
|
||||
"Indian/Cocos",
|
||||
"Europe/Zurich",
|
||||
"Africa/Abidjan",
|
||||
"Pacific/Rarotonga",
|
||||
"America/Santiago",
|
||||
"America/Punta_Arenas",
|
||||
"Pacific/Easter",
|
||||
"Asia/Shanghai",
|
||||
"Asia/Urumqi",
|
||||
"America/Bogota",
|
||||
"America/Costa_Rica",
|
||||
"America/Havana",
|
||||
"Atlantic/Cape_Verde",
|
||||
"America/Curacao",
|
||||
"Indian/Christmas",
|
||||
"Asia/Nicosia",
|
||||
"Asia/Famagusta",
|
||||
"Europe/Prague",
|
||||
"Europe/Berlin",
|
||||
"Europe/Copenhagen",
|
||||
"America/Santo_Domingo",
|
||||
"Africa/Algiers",
|
||||
"America/Guayaquil",
|
||||
"Pacific/Galapagos",
|
||||
"Europe/Tallinn",
|
||||
"Africa/Cairo",
|
||||
"Africa/El_Aaiun",
|
||||
"Europe/Madrid",
|
||||
"Africa/Ceuta",
|
||||
"Atlantic/Canary",
|
||||
"Europe/Helsinki",
|
||||
"Pacific/Fiji",
|
||||
"Atlantic/Stanley",
|
||||
"Pacific/Chuuk",
|
||||
"Pacific/Pohnpei",
|
||||
"Pacific/Kosrae",
|
||||
"Atlantic/Faroe",
|
||||
"Europe/Paris",
|
||||
"Europe/London",
|
||||
"Asia/Tbilisi",
|
||||
"America/Cayenne",
|
||||
"Africa/Accra",
|
||||
"Europe/Gibraltar",
|
||||
"America/Godthab",
|
||||
"America/Danmarkshavn",
|
||||
"America/Scoresbysund",
|
||||
"America/Thule",
|
||||
"Europe/Athens",
|
||||
"Atlantic/South_Georgia",
|
||||
"America/Guatemala",
|
||||
"Pacific/Guam",
|
||||
"Africa/Bissau",
|
||||
"America/Guyana",
|
||||
"Asia/Hong_Kong",
|
||||
"America/Tegucigalpa",
|
||||
"America/Port-au-Prince",
|
||||
"Europe/Budapest",
|
||||
"Asia/Jakarta",
|
||||
"Asia/Pontianak",
|
||||
"Asia/Makassar",
|
||||
"Asia/Jayapura",
|
||||
"Europe/Dublin",
|
||||
"Asia/Jerusalem",
|
||||
"Asia/Kolkata",
|
||||
"Indian/Chagos",
|
||||
"Asia/Baghdad",
|
||||
"Asia/Tehran",
|
||||
"Atlantic/Reykjavik",
|
||||
"Europe/Rome",
|
||||
"America/Jamaica",
|
||||
"Asia/Amman",
|
||||
"Asia/Tokyo",
|
||||
"Africa/Nairobi",
|
||||
"Asia/Bishkek",
|
||||
"Pacific/Tarawa",
|
||||
"Pacific/Enderbury",
|
||||
"Pacific/Kiritimati",
|
||||
"Asia/Pyongyang",
|
||||
"Asia/Seoul",
|
||||
"Asia/Almaty",
|
||||
"Asia/Qyzylorda",
|
||||
"Asia/Aqtobe",
|
||||
"Asia/Aqtau",
|
||||
"Asia/Atyrau",
|
||||
"Asia/Oral",
|
||||
"Asia/Beirut",
|
||||
"Asia/Colombo",
|
||||
"Africa/Monrovia",
|
||||
"Europe/Vilnius",
|
||||
"Europe/Luxembourg",
|
||||
"Europe/Riga",
|
||||
"Africa/Tripoli",
|
||||
"Africa/Casablanca",
|
||||
"Europe/Monaco",
|
||||
"Europe/Chisinau",
|
||||
"Pacific/Majuro",
|
||||
"Pacific/Kwajalein",
|
||||
"Asia/Yangon",
|
||||
"Asia/Ulaanbaatar",
|
||||
"Asia/Hovd",
|
||||
"Asia/Choibalsan",
|
||||
"Asia/Macau",
|
||||
"America/Martinique",
|
||||
"Europe/Malta",
|
||||
"Indian/Mauritius",
|
||||
"Indian/Maldives",
|
||||
"America/Mexico_City",
|
||||
"America/Cancun",
|
||||
"America/Merida",
|
||||
"America/Monterrey",
|
||||
"America/Matamoros",
|
||||
"America/Mazatlan",
|
||||
"America/Chihuahua",
|
||||
"America/Ojinaga",
|
||||
"America/Hermosillo",
|
||||
"America/Tijuana",
|
||||
"America/Bahia_Banderas",
|
||||
"Asia/Kuala_Lumpur",
|
||||
"Asia/Kuching",
|
||||
"Africa/Maputo",
|
||||
"Africa/Windhoek",
|
||||
"Pacific/Noumea",
|
||||
"Pacific/Norfolk",
|
||||
"Africa/Lagos",
|
||||
"America/Managua",
|
||||
"Europe/Amsterdam",
|
||||
"Europe/Oslo",
|
||||
"Asia/Kathmandu",
|
||||
"Pacific/Nauru",
|
||||
"Pacific/Niue",
|
||||
"Pacific/Auckland",
|
||||
"Pacific/Chatham",
|
||||
"America/Panama",
|
||||
"America/Lima",
|
||||
"Pacific/Tahiti",
|
||||
"Pacific/Marquesas",
|
||||
"Pacific/Gambier",
|
||||
"Pacific/Port_Moresby",
|
||||
"Pacific/Bougainville",
|
||||
"Asia/Manila",
|
||||
"Asia/Karachi",
|
||||
"Europe/Warsaw",
|
||||
"America/Miquelon",
|
||||
"Pacific/Pitcairn",
|
||||
"America/Puerto_Rico",
|
||||
"Asia/Gaza",
|
||||
"Asia/Hebron",
|
||||
"Europe/Lisbon",
|
||||
"Atlantic/Madeira",
|
||||
"Atlantic/Azores",
|
||||
"Pacific/Palau",
|
||||
"America/Asuncion",
|
||||
"Asia/Qatar",
|
||||
"Indian/Reunion",
|
||||
"Europe/Bucharest",
|
||||
"Europe/Belgrade",
|
||||
"Europe/Kaliningrad",
|
||||
"Europe/Moscow",
|
||||
"Europe/Simferopol",
|
||||
"Europe/Kirov",
|
||||
"Europe/Astrakhan",
|
||||
"Europe/Volgograd",
|
||||
"Europe/Saratov",
|
||||
"Europe/Ulyanovsk",
|
||||
"Europe/Samara",
|
||||
"Asia/Yekaterinburg",
|
||||
"Asia/Omsk",
|
||||
"Asia/Novosibirsk",
|
||||
"Asia/Barnaul",
|
||||
"Asia/Tomsk",
|
||||
"Asia/Novokuznetsk",
|
||||
"Asia/Krasnoyarsk",
|
||||
"Asia/Irkutsk",
|
||||
"Asia/Chita",
|
||||
"Asia/Yakutsk",
|
||||
"Asia/Khandyga",
|
||||
"Asia/Vladivostok",
|
||||
"Asia/Ust-Nera",
|
||||
"Asia/Magadan",
|
||||
"Asia/Sakhalin",
|
||||
"Asia/Srednekolymsk",
|
||||
"Asia/Kamchatka",
|
||||
"Asia/Anadyr",
|
||||
"Asia/Riyadh",
|
||||
"Pacific/Guadalcanal",
|
||||
"Indian/Mahe",
|
||||
"Africa/Khartoum",
|
||||
"Europe/Stockholm",
|
||||
"Asia/Singapore",
|
||||
"America/Paramaribo",
|
||||
"Africa/Juba",
|
||||
"Africa/Sao_Tome",
|
||||
"America/El_Salvador",
|
||||
"Asia/Damascus",
|
||||
"America/Grand_Turk",
|
||||
"Africa/Ndjamena",
|
||||
"Indian/Kerguelen",
|
||||
"Asia/Bangkok",
|
||||
"Asia/Dushanbe",
|
||||
"Pacific/Fakaofo",
|
||||
"Asia/Dili",
|
||||
"Asia/Ashgabat",
|
||||
"Africa/Tunis",
|
||||
"Pacific/Tongatapu",
|
||||
"Europe/Istanbul",
|
||||
"America/Port_of_Spain",
|
||||
"Pacific/Funafuti",
|
||||
"Asia/Taipei",
|
||||
"Europe/Kiev",
|
||||
"Europe/Uzhgorod",
|
||||
"Europe/Zaporozhye",
|
||||
"Pacific/Wake",
|
||||
"America/New_York",
|
||||
"America/Detroit",
|
||||
"America/Kentucky/Louisville",
|
||||
"America/Kentucky/Monticello",
|
||||
"America/Indiana/Indianapolis",
|
||||
"America/Indiana/Vincennes",
|
||||
"America/Indiana/Winamac",
|
||||
"America/Indiana/Marengo",
|
||||
"America/Indiana/Petersburg",
|
||||
"America/Indiana/Vevay",
|
||||
"America/Chicago",
|
||||
"America/Indiana/Tell_City",
|
||||
"America/Indiana/Knox",
|
||||
"America/Menominee",
|
||||
"America/North_Dakota/Center",
|
||||
"America/North_Dakota/New_Salem",
|
||||
"America/North_Dakota/Beulah",
|
||||
"America/Denver",
|
||||
"America/Boise",
|
||||
"America/Phoenix",
|
||||
"America/Los_Angeles",
|
||||
"America/Anchorage",
|
||||
"America/Juneau",
|
||||
"America/Sitka",
|
||||
"America/Metlakatla",
|
||||
"America/Yakutat",
|
||||
"America/Nome",
|
||||
"America/Adak",
|
||||
"Pacific/Honolulu",
|
||||
"America/Montevideo",
|
||||
"Asia/Samarkand",
|
||||
"Asia/Tashkent",
|
||||
"America/Caracas",
|
||||
"Asia/Ho_Chi_Minh",
|
||||
"Pacific/Efate",
|
||||
"Pacific/Wallis",
|
||||
"Pacific/Apia",
|
||||
"Africa/Johannesburg",
|
||||
];
|
||||
|
||||
export function timezoneList() {
|
||||
|
||||
let result = [];
|
||||
|
||||
for (let timezone of aryIannaTimeZones) {
|
||||
|
||||
for (let timezone of timezones) {
|
||||
try {
|
||||
let display = dayjs().tz(timezone).format("Z");
|
||||
let display = dayjs().tz(timezone.tzCode).format("Z");
|
||||
|
||||
result.push({
|
||||
name: `(UTC${display}) ${timezone}`,
|
||||
value: timezone,
|
||||
time: getTimezoneOffset(timezone),
|
||||
name: `(UTC${display}) ${timezone.tzCode}`,
|
||||
value: timezone.tzCode,
|
||||
time: getTimezoneOffset(timezone.tzCode),
|
||||
})
|
||||
} catch (e) {
|
||||
console.error(e.message);
|
||||
console.log("Skip this timezone")
|
||||
console.log("Skip Timezone: " + timezone.tzCode);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
result.sort((a, b) => {
|
||||
|
Loading…
Reference in New Issue
Block a user