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):
|
Node.js Version (Without Docker only):
|
||||||
OS:
|
OS:
|
||||||
Browser:
|
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**
|
**To Reproduce**
|
||||||
Steps to reproduce the behavior:
|
Steps to reproduce the behavior:
|
||||||
|
|
||||||
1. Go to '...'
|
1. Go to '...'
|
||||||
2. Click on '....'
|
2. Click on '....'
|
||||||
3. Scroll down to '....'
|
3. Scroll down to '....'
|
||||||
@ -23,7 +24,6 @@ Steps to reproduce the behavior:
|
|||||||
**Expected behavior**
|
**Expected behavior**
|
||||||
A clear and concise description of what you expected to happen.
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
|
|
||||||
**Info**
|
**Info**
|
||||||
Uptime Kuma Version:
|
Uptime Kuma Version:
|
||||||
Using Docker?: Yes/No
|
Using Docker?: Yes/No
|
||||||
@ -32,13 +32,11 @@ Node.js Version (Without Docker only):
|
|||||||
OS:
|
OS:
|
||||||
Browser:
|
Browser:
|
||||||
|
|
||||||
|
|
||||||
**Screenshots**
|
**Screenshots**
|
||||||
If applicable, add screenshots to help explain your problem.
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
**Error Log**
|
**Error Log**
|
||||||
It is easier for us to find out the problem.
|
It is easier for us to find out the problem.
|
||||||
|
|
||||||
Docker: "docker logs <container id>"
|
Docker: `docker logs <container id>`
|
||||||
PM2: "~/.pm2/logs/" (e.g. /home/ubuntu/.pm2/logs)
|
PM2: `~/.pm2/logs/` (e.g. `/home/ubuntu/.pm2/logs`)
|
||||||
|
|
||||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -7,4 +7,4 @@ dist-ssr
|
|||||||
|
|
||||||
/data
|
/data
|
||||||
!/data/.gitkeep
|
!/data/.gitkeep
|
||||||
.vscode
|
.vscode
|
||||||
|
@ -106,7 +106,7 @@ Violating these terms may lead to a permanent ban.
|
|||||||
### 4. Permanent Ban
|
### 4. Permanent Ban
|
||||||
|
|
||||||
**Community Impact**: Demonstrating a pattern of violation of community
|
**Community Impact**: Demonstrating a pattern of violation of community
|
||||||
standards, including sustained inappropriate behavior, harassment of an
|
standards, including sustained inappropriate behavior, harassment of an
|
||||||
individual, or aggression toward or disparagement of classes of individuals.
|
individual, or aggression toward or disparagement of classes of individuals.
|
||||||
|
|
||||||
**Consequence**: A permanent ban from any sort of public interaction within
|
**Consequence**: A permanent ban from any sort of public interaction within
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
First of all, thank you everyone who made pull requests for Uptime Kuma, I never thought GitHub Community can be that nice! And also because of this, I also never thought other people actually read my code and edit my code. It is not structed and commented so well, lol. Sorry about that.
|
First of all, thank you everyone who made pull requests for Uptime Kuma, I never thought GitHub Community can be that nice! And also because of this, I also never thought other people actually read my code and edit my code. It is not structed and commented so well, lol. Sorry about that.
|
||||||
|
|
||||||
The project was created with vite.js (vue3). Then I created a sub-directory called "server" for server part. Both frontend and backend share the same package.json.
|
The project was created with vite.js (vue3). Then I created a sub-directory called "server" for server part. Both frontend and backend share the same package.json.
|
||||||
|
|
||||||
The frontend code build into "dist" directory. The server uses "dist" as root. This is how production is working.
|
The frontend code build into "dist" directory. The server uses "dist" as root. This is how production is working.
|
||||||
|
|
||||||
@ -20,13 +20,13 @@ If you are not sure, feel free to create an empty pull request draft first.
|
|||||||
- Add a chart
|
- Add a chart
|
||||||
- Fix a bug
|
- Fix a bug
|
||||||
|
|
||||||
### *️⃣ Requires one more reviewer
|
### *️⃣ Requires one more reviewer
|
||||||
|
|
||||||
I do not have such knowledge to test it.
|
I do not have such knowledge to test it.
|
||||||
|
|
||||||
- Add k8s supports
|
- Add k8s supports
|
||||||
|
|
||||||
### *️⃣ Low Priority
|
### *️⃣ Low Priority
|
||||||
|
|
||||||
It changed my current workflow and require further studies.
|
It changed my current workflow and require further studies.
|
||||||
|
|
||||||
@ -41,9 +41,9 @@ It changed my current workflow and require further studies.
|
|||||||
|
|
||||||
# Project Styles
|
# Project Styles
|
||||||
|
|
||||||
I personally do not like something need to learn so much and need to config so much before you can finally start the app.
|
I personally do not like something need to learn so much and need to config so much before you can finally start the app.
|
||||||
|
|
||||||
For example, recently, because I am not a python expert, I spent a 2 hours to resolve all problems in order to install and use the Apprise cli. Apprise requires so many hidden requirements, I have to figure out myself how to solve the problems by Google search for my OS. That is painful. I do not want Uptime Kuma to be like this way, so:
|
For example, recently, because I am not a python expert, I spent a 2 hours to resolve all problems in order to install and use the Apprise cli. Apprise requires so many hidden requirements, I have to figure out myself how to solve the problems by Google search for my OS. That is painful. I do not want Uptime Kuma to be like this way, so:
|
||||||
|
|
||||||
- Easy to install for non-Docker users, no native build dependency is needed (at least for x86_64), no extra config, no extra effort to get it run
|
- Easy to install for non-Docker users, no native build dependency is needed (at least for x86_64), no extra config, no extra effort to get it run
|
||||||
- Single container for Docker users, no very complex docker-composer file. Just map the volume and expose the port, then good to go
|
- Single container for Docker users, no very complex docker-composer file. Just map the volume and expose the port, then good to go
|
||||||
@ -52,8 +52,8 @@ For example, recently, because I am not a python expert, I spent a 2 hours to re
|
|||||||
|
|
||||||
# Coding Styles
|
# Coding Styles
|
||||||
|
|
||||||
- Follow .editorconfig
|
- Follow `.editorconfig`
|
||||||
- Follow eslint
|
- Follow ESLint
|
||||||
|
|
||||||
## Name convention
|
## Name convention
|
||||||
|
|
||||||
@ -62,12 +62,13 @@ For example, recently, because I am not a python expert, I spent a 2 hours to re
|
|||||||
- CSS/SCSS: dash-type
|
- CSS/SCSS: dash-type
|
||||||
|
|
||||||
# Tools
|
# Tools
|
||||||
|
|
||||||
- Node.js >= 14
|
- Node.js >= 14
|
||||||
- Git
|
- 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)
|
- A SQLite tool (I am using SQLite Expert Personal)
|
||||||
|
|
||||||
# Install dependencies
|
# Install dependencies
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install --dev
|
npm install --dev
|
||||||
@ -75,7 +76,7 @@ npm install --dev
|
|||||||
|
|
||||||
For npm@7, you need --legacy-peer-deps
|
For npm@7, you need --legacy-peer-deps
|
||||||
|
|
||||||
```
|
```bash
|
||||||
npm install --legacy-peer-deps --dev
|
npm install --legacy-peer-deps --dev
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -84,23 +85,22 @@ npm install --legacy-peer-deps --dev
|
|||||||
```bash
|
```bash
|
||||||
npm run start-server
|
npm run start-server
|
||||||
|
|
||||||
# Or
|
# Or
|
||||||
|
|
||||||
node server/server.js
|
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
|
## Backend Details
|
||||||
|
|
||||||
It is mainly a socket.io app + express.js.
|
It is mainly a socket.io app + express.js.
|
||||||
|
|
||||||
express.js is just used for serving the frontend built files (index.html, .js and .css etc.)
|
express.js is just used for serving the frontend built files (index.html, .js and .css etc.)
|
||||||
|
|
||||||
# Frontend Dev
|
# 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
|
```bash
|
||||||
npm run dev
|
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.
|
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:
|
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.
|
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
|
## 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.
|
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.
|
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
|
# Database Migration
|
||||||
|
|
||||||
1. create `patch{num}.sql` in `./db/`
|
1. Create `patch{num}.sql` in `./db/`
|
||||||
1. update `latestVersion` in `./server/database.js`
|
2. Update `latestVersion` in `./server/database.js`
|
||||||
|
|
||||||
# Unit Test
|
# 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.
|
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,12 +20,11 @@ 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!
|
VPS is sponsored by Uptime Kuma sponsors on [Open Collective](https://opencollective.com/uptime-kuma)! Thank you so much!
|
||||||
|
|
||||||
|
|
||||||
## ⭐ Features
|
## ⭐ Features
|
||||||
|
|
||||||
* Monitoring uptime for HTTP(s) / TCP / Ping / DNS Record.
|
* Monitoring uptime for HTTP(s) / TCP / Ping / DNS Record.
|
||||||
* Fancy, Reactive, Fast UI/UX.
|
* Fancy, Reactive, Fast UI/UX.
|
||||||
* Notifications via Telegram, Discord, Gotify, Slack, Pushover, Email (SMTP), and [70+ notification services, click here for the full list](https://github.com/louislam/uptime-kuma/issues/284).
|
* Notifications via Telegram, Discord, Gotify, Slack, Pushover, Email (SMTP), and [70+ notification services, click here for the full list](https://github.com/louislam/uptime-kuma/issues/284).
|
||||||
* 20 seconds interval.
|
* 20 seconds interval.
|
||||||
* [Multi Languages](https://github.com/louislam/uptime-kuma/tree/master/src/languages)
|
* [Multi Languages](https://github.com/louislam/uptime-kuma/tree/master/src/languages)
|
||||||
|
|
||||||
@ -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
|
https://github.com/louislam/uptime-kuma/wiki/%F0%9F%94%A7-How-to-Install
|
||||||
|
|
||||||
|
|
||||||
## 🆙 How to Update
|
## 🆙 How to Update
|
||||||
|
|
||||||
Please read:
|
Please read:
|
||||||
@ -107,15 +105,13 @@ Telegram Notification Sample:
|
|||||||
|
|
||||||
If you love this project, please consider giving me a ⭐.
|
If you love this project, please consider giving me a ⭐.
|
||||||
|
|
||||||
|
|
||||||
## 🗣️ Discussion
|
## 🗣️ Discussion
|
||||||
|
|
||||||
You can also discuss or ask for help in [Issues](https://github.com/louislam/uptime-kuma/issues).
|
You can also discuss or ask for help in [Issues](https://github.com/louislam/uptime-kuma/issues).
|
||||||
|
|
||||||
Alternatively, you can discuss in my original post on reddit: https://www.reddit.com/r/selfhosted/comments/oi7dc7/uptime_kuma_a_fancy_selfhosted_monitoring_tool_an/
|
Alternatively, you can discuss in my original post on reddit: https://www.reddit.com/r/selfhosted/comments/oi7dc7/uptime_kuma_a_fancy_selfhosted_monitoring_tool_an/
|
||||||
|
|
||||||
I think the real "Discussion" tab is hard to use, as it is reddit-like flow, I always missed new comments.
|
I think the real "Discussion" tab is hard to use, as it is reddit-like flow, I always missed new comments.
|
||||||
|
|
||||||
|
|
||||||
## Contribute
|
## Contribute
|
||||||
|
|
||||||
@ -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
|
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.
|
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.
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ WORKDIR /app
|
|||||||
RUN apt update && \
|
RUN apt update && \
|
||||||
apt --yes install python3 python3-pip python3-dev git g++ make && \
|
apt --yes install python3 python3-pip python3-dev git g++ make && \
|
||||||
ln -s /usr/bin/python3 /usr/bin/python && \
|
ln -s /usr/bin/python3 /usr/bin/python && \
|
||||||
npm install mapbox/node-sqlite3#593c9d --build-from-source
|
npm install mapbox/node-sqlite3#593c9d --build-from-source
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN npm install --legacy-peer-deps && npm run build && npm prune --production
|
RUN npm install --legacy-peer-deps && npm run build && npm prune --production
|
||||||
@ -26,7 +26,7 @@ RUN apt update && \
|
|||||||
rm -rf /var/lib/apt/lists/*
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Copy app files from build layer
|
# Copy app files from build layer
|
||||||
COPY --from=build /app /app
|
COPY --from=build /app /app
|
||||||
|
|
||||||
EXPOSE 3001
|
EXPOSE 3001
|
||||||
VOLUME ["/app/data"]
|
VOLUME ["/app/data"]
|
||||||
|
@ -22,7 +22,7 @@ RUN apk add --no-cache python3 py3-cryptography py3-pip py3-six py3-yaml py3-cli
|
|||||||
rm -rf /root/.cache
|
rm -rf /root/.cache
|
||||||
|
|
||||||
# Copy app files from build layer
|
# Copy app files from build layer
|
||||||
COPY --from=build /app /app
|
COPY --from=build /app /app
|
||||||
|
|
||||||
EXPOSE 3001
|
EXPOSE 3001
|
||||||
VOLUME ["/app/data"]
|
VOLUME ["/app/data"]
|
||||||
|
@ -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.
|
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.
|
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.
|
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/).
|
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
|
- Host
|
||||||
- secrets and secret names
|
- Secrets and secret names
|
||||||
- (Cluster)Issuer (optional)
|
- (Cluster)Issuer (optional)
|
||||||
- the Version in the Deployment-File
|
- The Version in the Deployment-File
|
||||||
- update:
|
- Update:
|
||||||
- change to newer version and run the above commands, it will update the pods one after another
|
- 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
|
- Edit files mentioned above to your needs
|
||||||
- run ```kustomize build > apply.yml```
|
- Run ```kustomize build > apply.yml```
|
||||||
- run ```kubectl apply -f 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.
|
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-regular-svg-icons": "^5.15.4",
|
||||||
"@fortawesome/free-solid-svg-icons": "^5.15.4",
|
"@fortawesome/free-solid-svg-icons": "^5.15.4",
|
||||||
"@fortawesome/vue-fontawesome": "^3.0.0-4",
|
"@fortawesome/vue-fontawesome": "^3.0.0-4",
|
||||||
"@popperjs/core": "^2.9.3",
|
"@popperjs/core": "^2.10.1",
|
||||||
"args-parser": "^1.3.0",
|
"args-parser": "^1.3.0",
|
||||||
"axios": "^0.21.1",
|
"axios": "^0.21.4",
|
||||||
"bcryptjs": "^2.4.3",
|
"bcryptjs": "^2.4.3",
|
||||||
"bootstrap": "^5.1.0",
|
"bootstrap": "^5.1.1",
|
||||||
"chart.js": "^3.5.1",
|
"chart.js": "^3.5.1",
|
||||||
"chartjs-adapter-dayjs": "^1.0.0",
|
"chartjs-adapter-dayjs": "^1.0.0",
|
||||||
"command-exists": "^1.2.9",
|
"command-exists": "^1.2.9",
|
||||||
"compare-versions": "^3.6.0",
|
"compare-versions": "^3.6.0",
|
||||||
"dayjs": "^1.10.6",
|
"dayjs": "^1.10.7",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"express-basic-auth": "^1.2.0",
|
"express-basic-auth": "^1.2.0",
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.0",
|
||||||
@ -68,10 +68,11 @@
|
|||||||
"socket.io-client": "^4.2.0",
|
"socket.io-client": "^4.2.0",
|
||||||
"sqlite3": "github:mapbox/node-sqlite3#593c9d",
|
"sqlite3": "github:mapbox/node-sqlite3#593c9d",
|
||||||
"tcp-ping": "^0.1.1",
|
"tcp-ping": "^0.1.1",
|
||||||
|
"timezones-list": "^3.0.1",
|
||||||
"thirty-two": "^1.0.2",
|
"thirty-two": "^1.0.2",
|
||||||
"v-pagination-3": "^0.1.6",
|
"v-pagination-3": "^0.1.6",
|
||||||
"vue": "^3.2.8",
|
"vue": "^3.2.8",
|
||||||
"vue-chart-3": "^0.5.7",
|
"vue-chart-3": "^0.5.8",
|
||||||
"vue-confirm-dialog": "^1.0.2",
|
"vue-confirm-dialog": "^1.0.2",
|
||||||
"vue-contenteditable": "^3.0.4",
|
"vue-contenteditable": "^3.0.4",
|
||||||
"vue-i18n": "^9.1.7",
|
"vue-i18n": "^9.1.7",
|
||||||
@ -82,19 +83,19 @@
|
|||||||
"vuedraggable": "^4.1.0"
|
"vuedraggable": "^4.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/eslint-parser": "^7.15.0",
|
"@babel/eslint-parser": "^7.15.4",
|
||||||
"@types/bootstrap": "^5.1.2",
|
"@types/bootstrap": "^5.1.4",
|
||||||
"@vitejs/plugin-legacy": "^1.5.2",
|
"@vitejs/plugin-legacy": "^1.5.3",
|
||||||
"@vitejs/plugin-vue": "^1.6.0",
|
"@vitejs/plugin-vue": "^1.6.2",
|
||||||
"@vue/compiler-sfc": "^3.2.6",
|
"@vue/compiler-sfc": "^3.2.11",
|
||||||
"core-js": "^3.17.0",
|
"core-js": "^3.17.3",
|
||||||
"dns2": "^2.0.1",
|
"dns2": "^2.0.1",
|
||||||
"eslint": "^7.32.0",
|
"eslint": "^7.32.0",
|
||||||
"eslint-plugin-vue": "^7.17.0",
|
"eslint-plugin-vue": "^7.17.0",
|
||||||
"sass": "^1.38.2",
|
"sass": "^1.39.2",
|
||||||
"stylelint": "^13.13.1",
|
"stylelint": "^13.13.1",
|
||||||
"stylelint-config-standard": "^22.0.0",
|
"stylelint-config-standard": "^22.0.0",
|
||||||
"typescript": "^4.4.2",
|
"typescript": "^4.4.3",
|
||||||
"vite": "^2.5.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)
|
await axios.post(notification.discordWebhookUrl, discorddowndata)
|
||||||
return okMsg;
|
return okMsg;
|
||||||
|
|
||||||
@ -92,6 +97,11 @@ class Discord extends NotificationProvider {
|
|||||||
],
|
],
|
||||||
}],
|
}],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (notification.discordPrefixMessage) {
|
||||||
|
discordupdata.content = notification.discordPrefixMessage;
|
||||||
|
}
|
||||||
|
|
||||||
await axios.post(notification.discordWebhookUrl, discordupdata)
|
await axios.post(notification.discordWebhookUrl, discordupdata)
|
||||||
return okMsg;
|
return okMsg;
|
||||||
}
|
}
|
||||||
|
@ -153,6 +153,10 @@ let indexHTML = fs.readFileSync("./dist/index.html").toString();
|
|||||||
|
|
||||||
app.use("/", express.static("dist"));
|
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
|
// Public API
|
||||||
// ***************************
|
// ***************************
|
||||||
|
@ -80,6 +80,11 @@
|
|||||||
<label for="discord-username" class="form-label">Bot Display Name</label>
|
<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">
|
<input id="discord-username" v-model="notification.discordUsername" type="text" class="form-control" autocomplete="false" :placeholder="$root.appName">
|
||||||
</div>
|
</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>
|
||||||
|
|
||||||
<template v-if="notification.type === 'signal'">
|
<template v-if="notification.type === 'signal'">
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="password" class="form-label">{{ $t("Password") }}</label>
|
<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>
|
||||||
|
|
||||||
<div class="mb-3">
|
<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.
|
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
|
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`
|
3. `npm run update-language-files --base-lang=de-DE`
|
||||||
6. Your language file should be filled in. You can translate now.
|
4. 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"`).
|
5. 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.
|
6. Import your language file in `src/i18n.js` and add it to `languageList` constant.
|
||||||
9. Make a [pull request](https://github.com/louislam/uptime-kuma/pulls) when you have done.
|
7. Make a [pull request](https://github.com/louislam/uptime-kuma/pulls) when you have done.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
One of good examples:
|
One of good examples:
|
||||||
https://github.com/louislam/uptime-kuma/pull/316/files
|
https://github.com/louislam/uptime-kuma/pull/316/files
|
||||||
|
|
||||||
|
|
||||||
If you do not have programming skills, let me know in [Issues section](https://github.com/louislam/uptime-kuma/issues). I will assist you. 😏
|
If you do not have programming skills, let me know in [Issues section](https://github.com/louislam/uptime-kuma/issues). I will assist you. 😏
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ export default {
|
|||||||
resoverserverDescription: "Cloudflare è il server predefinito, è possibile cambiare il server DNS.",
|
resoverserverDescription: "Cloudflare è il server predefinito, è possibile cambiare il server DNS.",
|
||||||
rrtypeDescription: "Scegliere il tipo di RR che si vuole monitorare",
|
rrtypeDescription: "Scegliere il tipo di RR che si vuole monitorare",
|
||||||
pauseMonitorMsg: "Si è certi di voler mettere in pausa?",
|
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?",
|
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?",
|
clearHeartbeatsMsg: "Si è certi di voler eliminare tutti gli intervalli di controllo per questo servizio?",
|
||||||
confirmClearStatisticsMsg: "Si è certi di voler eliminare TUTTE le statistiche?",
|
confirmClearStatisticsMsg: "Si è certi di voler eliminare TUTTE le statistiche?",
|
||||||
@ -110,24 +111,24 @@ export default {
|
|||||||
"Last Result": "Ultimo risultato",
|
"Last Result": "Ultimo risultato",
|
||||||
"Create your admin account": "Crea l'account amministratore",
|
"Create your admin account": "Crea l'account amministratore",
|
||||||
"Repeat Password": "Ripeti Password",
|
"Repeat Password": "Ripeti Password",
|
||||||
|
"Import/Export Backup": "Importa/Esporta Backup",
|
||||||
|
Export: "Esporta",
|
||||||
|
Import: "Importa",
|
||||||
respTime: "Tempo di Risposta (ms)",
|
respTime: "Tempo di Risposta (ms)",
|
||||||
notAvailableShort: "N/D",
|
notAvailableShort: "N/D",
|
||||||
|
"Default enabled": "Abilitato di default",
|
||||||
|
"Also apply to existing monitors": "Applica anche ai monitoraggi esistenti",
|
||||||
Create: "Crea",
|
Create: "Crea",
|
||||||
"Clear Data": "Cancella dati",
|
"Clear Data": "Cancella dati",
|
||||||
Events: "Eventi",
|
Events: "Eventi",
|
||||||
Heartbeats: "Controlli",
|
Heartbeats: "Controlli",
|
||||||
"Auto Get": "Auto Get",
|
"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.",
|
backupDescription: "È possibile fare il backup di tutti i monitoraggi e di tutte le notifiche in un file JSON.",
|
||||||
"Import/Export Backup": "Import/Export Backup",
|
backupDescription2: "P.S.: lo storico e i dati relativi agli eventi non saranno inclusi.",
|
||||||
Export: "Export",
|
backupDescription3: "Dati sensibili come i token di autenticazione saranno inclusi nel backup, tenere quindi in un luogo sicuro.",
|
||||||
Import: "Import",
|
alertNoFile: "Selezionare il file da importare.",
|
||||||
"Default enabled": "Default enabled",
|
alertWrongFileType: "Selezionare un file JSON.",
|
||||||
"Also apply to existing monitors": "Also apply to existing monitors",
|
"Clear all statistics": "Pulisci tutte le statistiche",
|
||||||
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.",
|
|
||||||
twoFAVerifyLabel: "Please type in your token to verify that 2FA is working",
|
twoFAVerifyLabel: "Please type in your token to verify that 2FA is working",
|
||||||
tokenValidSettingsMsg: "Token is valid! You can now save the 2FA settings.",
|
tokenValidSettingsMsg: "Token is valid! You can now save the 2FA settings.",
|
||||||
confirmEnableTwoFAMsg: "Are you sure you want to enable 2FA?",
|
confirmEnableTwoFAMsg: "Are you sure you want to enable 2FA?",
|
||||||
@ -143,5 +144,4 @@ export default {
|
|||||||
Inactive: "Inactive",
|
Inactive: "Inactive",
|
||||||
Token: "Token",
|
Token: "Token",
|
||||||
"Show URI": "Show URI",
|
"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 "bootstrap";
|
||||||
import { createApp, h } from "vue";
|
import { createApp, h } from "vue";
|
||||||
import { createI18n } from "vue-i18n"
|
|
||||||
import { createRouter, createWebHistory } from "vue-router";
|
|
||||||
import Toast from "vue-toastification";
|
import Toast from "vue-toastification";
|
||||||
import "vue-toastification/dist/index.css";
|
import "vue-toastification/dist/index.css";
|
||||||
import App from "./App.vue";
|
import App from "./App.vue";
|
||||||
import "./assets/app.scss";
|
import "./assets/app.scss";
|
||||||
|
import { i18n } from "./i18n";
|
||||||
import { FontAwesomeIcon } from "./icon.js";
|
import { FontAwesomeIcon } from "./icon.js";
|
||||||
import EmptyLayout from "./layouts/EmptyLayout.vue";
|
import datetime from "./mixins/datetime";
|
||||||
import Layout from "./layouts/Layout.vue";
|
import mobile from "./mixins/mobile";
|
||||||
import socket from "./mixins/socket";
|
import socket from "./mixins/socket";
|
||||||
import theme from "./mixins/theme";
|
import theme from "./mixins/theme";
|
||||||
import mobile from "./mixins/mobile";
|
|
||||||
import datetime from "./mixins/datetime";
|
|
||||||
import publicMixin from "./mixins/public";
|
import publicMixin from "./mixins/public";
|
||||||
|
|
||||||
import Dashboard from "./pages/Dashboard.vue";
|
import { router } from "./router";
|
||||||
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 { appName } from "./util.ts";
|
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({
|
const app = createApp({
|
||||||
mixins: [
|
mixins: [
|
||||||
socket,
|
socket,
|
||||||
|
@ -120,11 +120,10 @@
|
|||||||
</form>
|
</form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<h2 class="mt-5 mb-2">
|
<div v-if="! settings.disableAuth" class="mt-5 mb-3">
|
||||||
{{ $t("Two Factor Authentication") }}
|
<h2 class="mb-2">
|
||||||
</h2>
|
{{ $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>
|
<button class="btn btn-primary me-2" type="button" @click="$refs.TwoFADialog.show()">{{ $t("2FA Settings") }}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -396,7 +395,7 @@ export default {
|
|||||||
}
|
}
|
||||||
exportData = JSON.stringify(exportData, null, 4);
|
exportData = JSON.stringify(exportData, null, 4);
|
||||||
let downloadItem = document.createElement("a");
|
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.setAttribute("download", fileName);
|
||||||
downloadItem.click();
|
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 dayjs from "dayjs";
|
||||||
import timezone from "dayjs/plugin/timezone";
|
import timezone from "dayjs/plugin/timezone";
|
||||||
import utc from "dayjs/plugin/utc";
|
import utc from "dayjs/plugin/utc";
|
||||||
|
import timezones from "timezones-list";
|
||||||
|
|
||||||
dayjs.extend(utc)
|
dayjs.extend(utc)
|
||||||
dayjs.extend(timezone)
|
dayjs.extend(timezone)
|
||||||
@ -16,376 +17,21 @@ function getTimezoneOffset(timeZone) {
|
|||||||
return -offset;
|
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() {
|
export function timezoneList() {
|
||||||
|
|
||||||
let result = [];
|
let result = [];
|
||||||
|
|
||||||
for (let timezone of aryIannaTimeZones) {
|
for (let timezone of timezones) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let display = dayjs().tz(timezone).format("Z");
|
let display = dayjs().tz(timezone.tzCode).format("Z");
|
||||||
|
|
||||||
result.push({
|
result.push({
|
||||||
name: `(UTC${display}) ${timezone}`,
|
name: `(UTC${display}) ${timezone.tzCode}`,
|
||||||
value: timezone,
|
value: timezone.tzCode,
|
||||||
time: getTimezoneOffset(timezone),
|
time: getTimezoneOffset(timezone.tzCode),
|
||||||
})
|
})
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e.message);
|
console.log("Skip Timezone: " + timezone.tzCode);
|
||||||
console.log("Skip this timezone")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result.sort((a, b) => {
|
result.sort((a, b) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user