From 201ac9245b61fd702459c1cc5a456a7a1b291293 Mon Sep 17 00:00:00 2001
From: Bas Wieringa <bas.wieringa@waterplatformcompany.com>
Date: Fri, 15 Mar 2024 15:54:29 +0100
Subject: [PATCH] Add toggle to hide the uptime percentage on a statuspage

---
 db/patch-add-hide-uptime-percentage.sql       |  7 +++++
 server/database.js                            |  1 +
 server/model/status_page.js                   |  2 ++
 .../status-page-socket-handler.js             |  1 +
 src/components/PublicGroupList.vue            | 26 ++++++++++++++++---
 src/lang/en.json                              |  1 +
 src/pages/StatusPage.vue                      |  8 +++++-
 7 files changed, 42 insertions(+), 4 deletions(-)
 create mode 100644 db/patch-add-hide-uptime-percentage.sql

diff --git a/db/patch-add-hide-uptime-percentage.sql b/db/patch-add-hide-uptime-percentage.sql
new file mode 100644
index 00000000..263a90ad
--- /dev/null
+++ b/db/patch-add-hide-uptime-percentage.sql
@@ -0,0 +1,7 @@
+-- You should not modify if this have pushed to Github, unless it does serious wrong with the db.
+BEGIN TRANSACTION;
+
+ALTER TABLE status_page
+    ADD hide_uptime_percentage BOOLEAN default 0 NOT NULL;
+
+COMMIT;
diff --git a/server/database.js b/server/database.js
index cfe14fe7..01bbc200 100644
--- a/server/database.js
+++ b/server/database.js
@@ -106,6 +106,7 @@ class Database {
         "patch-notification-config.sql": true,
         "patch-fix-kafka-producer-booleans.sql": true,
         "patch-timeout.sql": true, // The last file so far converted to a knex migration file
+        "patch-add-hide-uptime-percentage.sql": true
     };
 
     /**
diff --git a/server/model/status_page.js b/server/model/status_page.js
index 23558298..01e4297d 100644
--- a/server/model/status_page.js
+++ b/server/model/status_page.js
@@ -246,6 +246,7 @@ class StatusPage extends BeanModel {
             showPoweredBy: !!this.show_powered_by,
             googleAnalyticsId: this.google_analytics_tag_id,
             showCertificateExpiry: !!this.show_certificate_expiry,
+            hideUptimePercentage: !!this.hide_uptime_percentage
         };
     }
 
@@ -268,6 +269,7 @@ class StatusPage extends BeanModel {
             showPoweredBy: !!this.show_powered_by,
             googleAnalyticsId: this.google_analytics_tag_id,
             showCertificateExpiry: !!this.show_certificate_expiry,
+            hideUptimePercentage: !!this.hide_uptime_percentage
         };
     }
 
diff --git a/server/socket-handlers/status-page-socket-handler.js b/server/socket-handlers/status-page-socket-handler.js
index ee1c68d3..d44b710a 100644
--- a/server/socket-handlers/status-page-socket-handler.js
+++ b/server/socket-handlers/status-page-socket-handler.js
@@ -163,6 +163,7 @@ module.exports.statusPageSocketHandler = (socket) => {
             statusPage.footer_text = config.footerText;
             statusPage.custom_css = config.customCSS;
             statusPage.show_powered_by = config.showPoweredBy;
+            statusPage.hide_uptime_percentage = config.hideUptimePercentage;
             statusPage.show_certificate_expiry = config.showCertificateExpiry;
             statusPage.modified_date = R.isoDateTime();
             statusPage.google_analytics_tag_id = config.googleAnalyticsId;
diff --git a/src/components/PublicGroupList.vue b/src/components/PublicGroupList.vue
index d1c1f4c5..3a24ac7f 100644
--- a/src/components/PublicGroupList.vue
+++ b/src/components/PublicGroupList.vue
@@ -37,8 +37,9 @@
                                         <div class="info">
                                             <font-awesome-icon v-if="editMode" icon="arrows-alt-v" class="action drag me-3" />
                                             <font-awesome-icon v-if="editMode" icon="times" class="action remove me-3" @click="removeMonitor(group.index, monitor.index)" />
-
-                                            <Uptime :monitor="monitor.element" type="24" :pill="true" />
+                                            
+                                            <Status v-if="hideUptimePercentage" :status="statusOfLastHeartbeat(monitor.element.id)" />
+                                            <Uptime v-if="!hideUptimePercentage" :monitor="monitor.element" type="24" :pill="true" />
                                             <a
                                                 v-if="showLink(monitor)"
                                                 :href="monitor.element.url"
@@ -90,6 +91,8 @@ import Draggable from "vuedraggable";
 import HeartbeatBar from "./HeartbeatBar.vue";
 import Uptime from "./Uptime.vue";
 import Tag from "./Tag.vue";
+import Status from "./Status.vue";
+import PublicStatus from "./PublicStatus.vue";
 
 export default {
     components: {
@@ -98,6 +101,8 @@ export default {
         HeartbeatBar,
         Uptime,
         Tag,
+        Status,
+        PublicStatus
     },
     props: {
         /** Are we in edit mode? */
@@ -112,7 +117,11 @@ export default {
         /** Should expiry be shown? */
         showCertificateExpiry: {
             type: Boolean,
-        }
+        },
+        /** Should uptime be hidden? */
+        hideUptimePercentage: {
+            type: Boolean,
+        },
     },
     data() {
         return {
@@ -181,6 +190,17 @@ export default {
             }
         },
 
+        /**
+         * Returns the status of the last heartbeat
+         * @param {object} monitor Monitor to get status for
+         * @returns {number} Status of the last heartbeat
+         */
+         statusOfLastHeartbeat(monitor) {
+            let heartbeats = this.$root.heartbeatList[this.monitorId] ?? [];
+            let lastHeartbeat = heartbeats[heartbeats.length - 1];
+            return lastHeartbeat?.status;
+        },
+
         /**
          * Returns certificate expiry color based on days remaining
          * @param {object} monitor Monitor to show expiry for
diff --git a/src/lang/en.json b/src/lang/en.json
index 11190a08..087d4a16 100644
--- a/src/lang/en.json
+++ b/src/lang/en.json
@@ -853,6 +853,7 @@
     "nostrRecipients": "Recipients Public Keys (npub)",
     "nostrRecipientsHelp": "npub format, one per line",
     "showCertificateExpiry": "Show Certificate Expiry",
+    "hideUptimePercentage": "Hide Uptime Percentage",
     "noOrBadCertificate": "No/Bad Certificate",
     "gamedigGuessPort": "Gamedig: Guess Port",
     "gamedigGuessPortDescription": "The port used by Valve Server Query Protocol may be different from the client port. Try this if the monitor cannot connect to your server.",
diff --git a/src/pages/StatusPage.vue b/src/pages/StatusPage.vue
index af2f028d..fdb92c8e 100644
--- a/src/pages/StatusPage.vue
+++ b/src/pages/StatusPage.vue
@@ -60,6 +60,12 @@
                     <label class="form-check-label" for="show-certificate-expiry">{{ $t("showCertificateExpiry") }}</label>
                 </div>
 
+                <!-- Hide uptime percentage -->
+                <div class="my-3 form-check form-switch">
+                    <input id="hide-uptime-percentage" v-model="config.hideUptimePercentage" class="form-check-input" type="checkbox">
+                    <label class="form-check-label" for="hide-uptime-percentage">{{ $t("hideUptimePercentage") }}</label>
+                </div>
+
                 <div v-if="false" class="my-3">
                     <label for="password" class="form-label">{{ $t("Password") }} <sup>{{ $t("Coming Soon") }}</sup></label>
                     <input id="password" v-model="config.password" disabled type="password" autocomplete="new-password" class="form-control">
@@ -319,7 +325,7 @@
                     👀 {{ $t("statusPageNothing") }}
                 </div>
 
-                <PublicGroupList :edit-mode="enableEditMode" :show-tags="config.showTags" :show-certificate-expiry="config.showCertificateExpiry" />
+                <PublicGroupList :edit-mode="enableEditMode" :show-tags="config.showTags" :show-certificate-expiry="config.showCertificateExpiry" :hide-uptime-percentage="config.hideUptimePercentage" />
             </div>
 
             <footer class="mt-5 mb-4">