[Status Page] WIP: Checkpoint

pull/124/head
LouisLam 3 years ago
parent 3e25f0e9d9
commit 934685637a

@ -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 - 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", async (_request, response) => {
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…
Cancel
Save