mirror of
https://github.com/louislam/uptime-kuma.git
synced 2024-11-27 16:54:04 +00:00
[Status Page] WIP: Checkpoint
This commit is contained in:
parent
3e25f0e9d9
commit
934685637a
8 changed files with 123 additions and 75 deletions
6
db/patch-monitor-public.sql
Normal file
6
db/patch-monitor-public.sql
Normal file
|
@ -0,0 +1,6 @@
|
|||
BEGIN TRANSACTION;
|
||||
|
||||
alter table monitor
|
||||
add public BOOLEAN default 0 not null;
|
||||
|
||||
COMMIT;
|
|
@ -30,6 +30,7 @@ class Database {
|
|||
static patchList = {
|
||||
"patch-setting-value-type.sql": true,
|
||||
"patch-improve-performance.sql": true,
|
||||
"patch-monitor-public.sql": true,
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -165,9 +165,36 @@ let indexHTML = fs.readFileSync("./dist/index.html").toString();
|
|||
response.json(config);
|
||||
});
|
||||
|
||||
// Status Page Polling Data
|
||||
app.get("/api/status-page", async (_request, response) => {
|
||||
// Status Page - Monitor List
|
||||
app.get("/api/status-page/monitor-list", async (_request, response) => {
|
||||
allowDevAllOrigin(response);
|
||||
|
||||
const monitorList = {};
|
||||
let list = await R.find("monitor", " public = 1 ORDER BY weight DESC, name ", [
|
||||
]);
|
||||
|
||||
for (let monitor of list) {
|
||||
monitorList[monitor.id] = await monitor.toJSON();
|
||||
}
|
||||
|
||||
response.json(monitorList);
|
||||
});
|
||||
|
||||
// Status Page Polling Data
|
||||
app.get("/api/status-page/heartbeat", async (_request, response) => {
|
||||
allowDevAllOrigin(response);
|
||||
|
||||
const monitorList = {};
|
||||
let list = await R.find("", " ", [
|
||||
])
|
||||
|
||||
for (let monitor of list) {
|
||||
monitorList[monitor.id] = await monitor.toJSON();
|
||||
}
|
||||
|
||||
response.json({
|
||||
monitorList: monitorList,
|
||||
});
|
||||
});
|
||||
|
||||
// Universal Route Handler, must be at the end of all express route.
|
||||
|
|
|
@ -255,6 +255,18 @@ h2 {
|
|||
background-color: $dark-bg;
|
||||
}
|
||||
|
||||
.monitor-list {
|
||||
.item {
|
||||
&:hover {
|
||||
background-color: $dark-bg2;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: $dark-bg2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 550px) {
|
||||
.table-shadow-box {
|
||||
tbody {
|
||||
|
@ -288,3 +300,39 @@ h2 {
|
|||
transform: translateY(50px);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.monitor-list {
|
||||
&.scrollbar {
|
||||
min-height: calc(100vh - 240px);
|
||||
max-height: calc(100vh - 30px);
|
||||
overflow-y: auto;
|
||||
position: sticky;
|
||||
top: 10px;
|
||||
}
|
||||
|
||||
.item {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
padding: 13px 15px 10px 15px;
|
||||
border-radius: 10px;
|
||||
transition: all ease-in-out 0.15s;
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.info {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $highlight-white;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: #cdf8f4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,10 @@ export default {
|
|||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
heartbeatList: {
|
||||
type: Array,
|
||||
default: null,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -38,8 +42,15 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
|
||||
/**
|
||||
* If heartbeatList is null, get it from $root.heartbeatList
|
||||
*/
|
||||
beatList() {
|
||||
return this.$root.heartbeatList[this.monitorId]
|
||||
if (this.heartbeatList === null) {
|
||||
return this.$root.heartbeatList[this.monitorId];
|
||||
} else {
|
||||
return this.heartbeatList;
|
||||
}
|
||||
},
|
||||
|
||||
shortBeatList() {
|
||||
|
@ -118,8 +129,10 @@ export default {
|
|||
window.removeEventListener("resize", this.resize);
|
||||
},
|
||||
beforeMount() {
|
||||
if (! (this.monitorId in this.$root.heartbeatList)) {
|
||||
this.$root.heartbeatList[this.monitorId] = [];
|
||||
if (this.heartbeatList === null) {
|
||||
if (! (this.monitorId in this.$root.heartbeatList)) {
|
||||
this.$root.heartbeatList[this.monitorId] = [];
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="shadow-box list mb-3" :class="{ scrollbar: scrollbar }">
|
||||
<div class="shadow-box monitor-list mb-3" :class="{ scrollbar: scrollbar }">
|
||||
<div v-if="Object.keys($root.monitorList).length === 0" class="text-center mt-3">
|
||||
{{ $t("No Monitors, please") }} <router-link to="/add">{{ $t("add one") }}</router-link>
|
||||
</div>
|
||||
|
@ -87,56 +87,6 @@ export default {
|
|||
padding-right: 5px !important;
|
||||
}
|
||||
|
||||
.list {
|
||||
&.scrollbar {
|
||||
min-height: calc(100vh - 240px);
|
||||
max-height: calc(100vh - 30px);
|
||||
overflow-y: auto;
|
||||
position: sticky;
|
||||
top: 10px;
|
||||
}
|
||||
|
||||
.item {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
padding: 13px 15px 10px 15px;
|
||||
border-radius: 10px;
|
||||
transition: all ease-in-out 0.15s;
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.info {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $highlight-white;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: #cdf8f4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dark {
|
||||
.list {
|
||||
.item {
|
||||
&:hover {
|
||||
background-color: $dark-bg2;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: $dark-bg2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.monitorItem {
|
||||
width: 100%;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
</a>
|
||||
|
||||
<ul class="nav nav-pills">
|
||||
<li class="nav-item">
|
||||
<li class="nav-item me-2">
|
||||
<router-link to="/status-page" class="nav-link status-page">
|
||||
<font-awesome-icon icon="stream" /> {{ $t("Status Page") }}
|
||||
</router-link>
|
||||
|
|
|
@ -18,30 +18,24 @@
|
|||
<font-awesome-icon icon="check-circle" class="ok" /> All Systems Operational
|
||||
</div>
|
||||
|
||||
<div class="shadow-box list mt-4" :class="{ scrollbar: scrollbar }">
|
||||
<div v-if="Object.keys($root.monitorList).length === 0" class="text-center mt-3">
|
||||
{{ $t("No Monitors, please") }} <router-link to="/add">{{ $t("add one") }}</router-link>
|
||||
<div class="shadow-box monitor-list mt-4">
|
||||
<div v-if="Object.keys(monitorList).length === 0" class="text-center my-3">
|
||||
{{ $t("No Monitors") }}
|
||||
</div>
|
||||
|
||||
<router-link v-for="(item, index) in sortedMonitorList" :key="index" :to="monitorURL(item.id)" class="item" :class="{ 'disabled': ! item.active }">
|
||||
<div v-for="(item, index) in monitorList" :key="index" class="item">
|
||||
<div class="row">
|
||||
<div class="col-6 col-md-8 small-padding" :class="{ 'monitorItem': $root.userHeartbeatBar == 'bottom' || $root.userHeartbeatBar == 'none' }">
|
||||
<div class="col-6 col-md-8 small-padding">
|
||||
<div class="info">
|
||||
<Uptime :monitor="item" type="24" :pill="true" />
|
||||
{{ item.name }}
|
||||
</div>
|
||||
</div>
|
||||
<div v-show="$root.userHeartbeatBar == 'normal'" :key="$root.userHeartbeatBar" class="col-6 col-md-4">
|
||||
<div :key="$root.userHeartbeatBar" class="col-6 col-md-4">
|
||||
<HeartbeatBar size="small" :monitor-id="item.id" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="$root.userHeartbeatBar == 'bottom'" class="row">
|
||||
<div class="col-12">
|
||||
<HeartbeatBar size="small" :monitor-id="item.id" />
|
||||
</div>
|
||||
</div>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="mt-4">
|
||||
|
@ -51,9 +45,13 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { useToast } from "vue-toastification"
|
||||
import axios from "axios";
|
||||
import { useToast } from "vue-toastification";
|
||||
const toast = useToast();
|
||||
|
||||
import axios from "axios";
|
||||
import HeartbeatBar from "../components/HeartbeatBar.vue";
|
||||
import Uptime from "../components/Uptime.vue";
|
||||
|
||||
const env = process.env.NODE_ENV || "production";
|
||||
|
||||
// change the axios base url for development
|
||||
|
@ -62,10 +60,15 @@ if (env === "development" || localStorage.dev === "dev") {
|
|||
}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
HeartbeatBar,
|
||||
Uptime,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
hasToken: false,
|
||||
config: {},
|
||||
monitorList: {},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -76,13 +79,13 @@ export default {
|
|||
},
|
||||
async created() {
|
||||
this.hasToken = ("token" in localStorage);
|
||||
this.config = await axios.get("/api/status-page/config");
|
||||
this.config = (await axios.get("/api/status-page/config")).data;
|
||||
|
||||
// Set Theme
|
||||
this.$root.statusPageTheme = this.config.statusPageTheme;
|
||||
},
|
||||
mounted() {
|
||||
|
||||
async mounted() {
|
||||
this.monitorList = (await axios.get("/api/status-page/monitor-list")).data;
|
||||
},
|
||||
methods: {
|
||||
edit() {
|
||||
|
|
Loading…
Reference in a new issue