diff --git a/db/patch-monitor-public.sql b/db/patch-monitor-public.sql new file mode 100644 index 000000000..d554547cd --- /dev/null +++ b/db/patch-monitor-public.sql @@ -0,0 +1,6 @@ +BEGIN TRANSACTION; + +alter table monitor + add public BOOLEAN default 0 not null; + +COMMIT; diff --git a/server/database.js b/server/database.js index e0bb0c9b8..0b6332e2e 100644 --- a/server/database.js +++ b/server/database.js @@ -30,6 +30,7 @@ class Database { static patchList = { "patch-setting-value-type.sql": true, "patch-improve-performance.sql": true, + "patch-monitor-public.sql": true, } /** diff --git a/server/server.js b/server/server.js index aec4528da..78e24eae4 100644 --- a/server/server.js +++ b/server/server.js @@ -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. diff --git a/src/assets/app.scss b/src/assets/app.scss index 581645735..f25e4c467 100644 --- a/src/assets/app.scss +++ b/src/assets/app.scss @@ -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; + } + } +} diff --git a/src/components/HeartbeatBar.vue b/src/components/HeartbeatBar.vue index fb6086d00..4dc2c712c 100644 --- a/src/components/HeartbeatBar.vue +++ b/src/components/HeartbeatBar.vue @@ -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] = []; + } } }, diff --git a/src/components/MonitorList.vue b/src/components/MonitorList.vue index e72155891..5dae04d06 100644 --- a/src/components/MonitorList.vue +++ b/src/components/MonitorList.vue @@ -1,5 +1,5 @@