Merge branch 'master' into restructure-status-page

# Conflicts:
#	src/pages/StatusPage.vue
This commit is contained in:
Louis Lam 2022-03-12 15:50:42 +08:00
commit d765b1c57a
7 changed files with 106 additions and 40 deletions

15
package-lock.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "uptime-kuma", "name": "uptime-kuma",
"version": "1.11.4", "version": "1.12.1",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "uptime-kuma", "name": "uptime-kuma",
"version": "1.11.4", "version": "1.12.1",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@fortawesome/fontawesome-svg-core": "~1.2.36", "@fortawesome/fontawesome-svg-core": "~1.2.36",
@ -29,6 +29,7 @@
"dayjs": "~1.10.7", "dayjs": "~1.10.7",
"express": "~4.17.1", "express": "~4.17.1",
"express-basic-auth": "~1.2.0", "express-basic-auth": "~1.2.0",
"favico.js": "^0.3.10",
"form-data": "~4.0.0", "form-data": "~4.0.0",
"http-graceful-shutdown": "~3.1.5", "http-graceful-shutdown": "~3.1.5",
"iconv-lite": "^0.6.3", "iconv-lite": "^0.6.3",
@ -6140,6 +6141,11 @@
"reusify": "^1.0.4" "reusify": "^1.0.4"
} }
}, },
"node_modules/favico.js": {
"version": "0.3.10",
"resolved": "https://registry.npmjs.org/favico.js/-/favico.js-0.3.10.tgz",
"integrity": "sha1-gFhuJ6EX8kqNUcGKmb3HFNQzkwE="
},
"node_modules/fb-watchman": { "node_modules/fb-watchman": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz",
@ -18240,6 +18246,11 @@
"reusify": "^1.0.4" "reusify": "^1.0.4"
} }
}, },
"favico.js": {
"version": "0.3.10",
"resolved": "https://registry.npmjs.org/favico.js/-/favico.js-0.3.10.tgz",
"integrity": "sha1-gFhuJ6EX8kqNUcGKmb3HFNQzkwE="
},
"fb-watchman": { "fb-watchman": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz",

View File

@ -68,12 +68,13 @@
"chardet": "^1.3.0", "chardet": "^1.3.0",
"chart.js": "~3.6.0", "chart.js": "~3.6.0",
"chartjs-adapter-dayjs": "~1.0.0", "chartjs-adapter-dayjs": "~1.0.0",
"check-password-strength": "^2.0.3", "check-password-strength": "^2.0.5",
"command-exists": "~1.2.9", "command-exists": "~1.2.9",
"compare-versions": "~3.6.0", "compare-versions": "~3.6.0",
"dayjs": "~1.10.7", "dayjs": "~1.10.7",
"express": "~4.17.1", "express": "~4.17.1",
"express-basic-auth": "~1.2.0", "express-basic-auth": "~1.2.0",
"favico.js": "^0.3.10",
"form-data": "~4.0.0", "form-data": "~4.0.0",
"http-graceful-shutdown": "~3.1.5", "http-graceful-shutdown": "~3.1.5",
"iconv-lite": "^0.6.3", "iconv-lite": "^0.6.3",

View File

@ -361,4 +361,13 @@ export default {
smtpDkimHashAlgo: "Хеш алгоритъм (по желание)", smtpDkimHashAlgo: "Хеш алгоритъм (по желание)",
smtpDkimheaderFieldNames: "Хедър ключове за подписване (по желание)", smtpDkimheaderFieldNames: "Хедър ключове за подписване (по желание)",
smtpDkimskipFields: "Хедър ключове, които да не се подписват (по желание)", smtpDkimskipFields: "Хедър ключове, които да не се подписват (по желание)",
PushByTechulus: "Push от Techulus",
GoogleChat: "Google Chat (Само за работното пространство на Google)",
gorush: "Gorush",
alerta: "Alerta",
alertaApiEndpoint: "Крайна точка на API",
alertaEnvironment: "Среда",
alertaApiKey: "API Ключ",
alertaAlertState: "Състояние на тревога",
alertaRecoverState: "Състояние на възстановяване",
}; };

View File

@ -362,4 +362,12 @@ export default {
smtpDkimHashAlgo: "Hash algoritmus (nem kötelező)", smtpDkimHashAlgo: "Hash algoritmus (nem kötelező)",
smtpDkimheaderFieldNames: "Fejléc kulcsok a bejelentkezéshez (nem kötelező)", smtpDkimheaderFieldNames: "Fejléc kulcsok a bejelentkezéshez (nem kötelező)",
smtpDkimskipFields: "Fejléc kulcsok egyéb esetben (nem kötelező)", smtpDkimskipFields: "Fejléc kulcsok egyéb esetben (nem kötelező)",
PushByTechulus: "Techulus push",
gorush: "Gorush",
alerta: "Alerta",
alertaApiEndpoint: "API végpont",
alertaEnvironment: "Környezet",
alertaApiKey: "API kulcs",
alertaAlertState: "Figyelmeztetési állapot",
alertaRecoverState: "Visszaállási állapot",
}; };

View File

@ -1,6 +1,7 @@
import { io } from "socket.io-client"; import { io } from "socket.io-client";
import { useToast } from "vue-toastification"; import { useToast } from "vue-toastification";
import jwt_decode from "jwt-decode"; import jwt_decode from "jwt-decode";
import Favico from "favico.js";
const toast = useToast(); const toast = useToast();
let socket; let socket;
@ -11,6 +12,10 @@ const noSocketIOPages = [
"/" "/"
]; ];
const favicon = new Favico({
animation: "none"
});
export default { export default {
data() { data() {
@ -398,10 +403,50 @@ export default {
return result; return result;
}, },
stats() {
let result = {
up: 0,
down: 0,
unknown: 0,
pause: 0,
};
for (let monitorID in this.$root.monitorList) {
let beat = this.$root.lastHeartbeatList[monitorID];
let monitor = this.$root.monitorList[monitorID];
if (monitor && ! monitor.active) {
result.pause++;
} else if (beat) {
if (beat.status === 1) {
result.up++;
} else if (beat.status === 0) {
result.down++;
} else if (beat.status === 2) {
result.up++;
} else {
result.unknown++;
}
} else {
result.unknown++;
}
}
return result;
},
}, },
watch: { watch: {
// Update Badge
"stats.down"(to, from) {
if (to !== from) {
favicon.badge(to);
console.log(to);
}
},
// Reload the SPA if the server version is changed. // Reload the SPA if the server version is changed.
"info.version"(to, from) { "info.version"(to, from) {
if (from && from !== to) { if (from && from !== to) {

View File

@ -9,19 +9,19 @@
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<h3>{{ $t("Up") }}</h3> <h3>{{ $t("Up") }}</h3>
<span class="num">{{ stats.up }}</span> <span class="num">{{ $root.stats.up }}</span>
</div> </div>
<div class="col"> <div class="col">
<h3>{{ $t("Down") }}</h3> <h3>{{ $t("Down") }}</h3>
<span class="num text-danger">{{ stats.down }}</span> <span class="num text-danger">{{ $root.stats.down }}</span>
</div> </div>
<div class="col"> <div class="col">
<h3>{{ $t("Unknown") }}</h3> <h3>{{ $t("Unknown") }}</h3>
<span class="num text-secondary">{{ stats.unknown }}</span> <span class="num text-secondary">{{ $root.stats.unknown }}</span>
</div> </div>
<div class="col"> <div class="col">
<h3>{{ $t("pauseDashboardHome") }}</h3> <h3>{{ $t("pauseDashboardHome") }}</h3>
<span class="num text-secondary">{{ stats.pause }}</span> <span class="num text-secondary">{{ $root.stats.pause }}</span>
</div> </div>
</div> </div>
</div> </div>
@ -89,37 +89,6 @@ export default {
}; };
}, },
computed: { computed: {
stats() {
let result = {
up: 0,
down: 0,
unknown: 0,
pause: 0,
};
for (let monitorID in this.$root.monitorList) {
let beat = this.$root.lastHeartbeatList[monitorID];
let monitor = this.$root.monitorList[monitorID];
if (monitor && ! monitor.active) {
result.pause++;
} else if (beat) {
if (beat.status === 1) {
result.up++;
} else if (beat.status === 0) {
result.down++;
} else if (beat.status === 2) {
result.up++;
} else {
result.unknown++;
}
} else {
result.unknown++;
}
}
return result;
},
importantHeartBeatList() { importantHeartBeatList() {
let result = []; let result = [];

View File

@ -220,12 +220,18 @@ import ImageCropUpload from "vue-image-crop-upload";
import { STATUS_PAGE_ALL_DOWN, STATUS_PAGE_ALL_UP, STATUS_PAGE_PARTIAL_DOWN, UP } from "../util.ts"; import { STATUS_PAGE_ALL_DOWN, STATUS_PAGE_ALL_UP, STATUS_PAGE_PARTIAL_DOWN, UP } from "../util.ts";
import { useToast } from "vue-toastification"; import { useToast } from "vue-toastification";
import dayjs from "dayjs"; import dayjs from "dayjs";
import Favico from "favico.js";
const toast = useToast(); const toast = useToast();
const leavePageMsg = "Do you really want to leave? you have unsaved changes!"; const leavePageMsg = "Do you really want to leave? you have unsaved changes!";
let feedInterval; let feedInterval;
const favicon = new Favico({
animation: "none"
});
export default { export default {
components: { components: {
PublicGroupList, PublicGroupList,
@ -446,8 +452,25 @@ export default {
// If editMode, it will use the data from websocket. // If editMode, it will use the data from websocket.
if (! this.editMode) { if (! this.editMode) {
axios.get("/api/status-page/heartbeat/" + this.slug).then((res) => { axios.get("/api/status-page/heartbeat/" + this.slug).then((res) => {
this.$root.heartbeatList = res.data.heartbeatList; const { heartbeatList, uptimeList } = res.data;
this.$root.uptimeList = res.data.uptimeList;
this.$root.heartbeatList = heartbeatList;
this.$root.uptimeList = uptimeList;
const heartbeatIds = Object.keys(heartbeatList);
const downMonitors = heartbeatIds.reduce((downMonitorsAmount, currentId) => {
const monitorHeartbeats = heartbeatList[currentId];
const lastHeartbeat = monitorHeartbeats.at(-1);
if (lastHeartbeat) {
return lastHeartbeat.status === 0 ? downMonitorsAmount + 1 : downMonitorsAmount;
} else {
return downMonitorsAmount;
}
}, 0);
favicon.badge(downMonitors);
this.loadedData = true; this.loadedData = true;
}); });
} }