feat: Add toggle to hide the uptime percentage on a statuspage (#4587)

Co-authored-by: Bas Wieringa <bas.wieringa@waterplatformcompany.com>
Co-authored-by: Frank Elsinga <frank@elsinga.de>
This commit is contained in:
broodroosterdev
2025-11-25 01:28:42 +01:00
committed by GitHub
parent eb783897da
commit 5c83b17992
6 changed files with 47 additions and 3 deletions

View File

@@ -0,0 +1,15 @@
exports.up = function (knex) {
// Add new column status_page.show_only_last_heartbeat
return knex.schema
.alterTable("status_page", function (table) {
table.boolean("show_only_last_heartbeat").notNullable().defaultTo(false);
});
};
exports.down = function (knex) {
// Drop column status_page.show_only_last_heartbeat
return knex.schema
.alterTable("status_page", function (table) {
table.dropColumn("show_only_last_heartbeat");
});
};

View File

@@ -409,6 +409,7 @@ class StatusPage extends BeanModel {
showPoweredBy: !!this.show_powered_by,
googleAnalyticsId: this.google_analytics_tag_id,
showCertificateExpiry: !!this.show_certificate_expiry,
showOnlyLastHeartbeat: !!this.show_only_last_heartbeat
};
}
@@ -432,6 +433,7 @@ class StatusPage extends BeanModel {
showPoweredBy: !!this.show_powered_by,
googleAnalyticsId: this.google_analytics_tag_id,
showCertificateExpiry: !!this.show_certificate_expiry,
showOnlyLastHeartbeat: !!this.show_only_last_heartbeat
};
}

View File

@@ -164,6 +164,7 @@ module.exports.statusPageSocketHandler = (socket) => {
statusPage.footer_text = config.footerText;
statusPage.custom_css = config.customCSS;
statusPage.show_powered_by = config.showPoweredBy;
statusPage.show_only_last_heartbeat = config.showOnlyLastHeartbeat;
statusPage.show_certificate_expiry = config.showCertificateExpiry;
statusPage.modified_date = R.isoDateTime();
statusPage.google_analytics_tag_id = config.googleAnalyticsId;

View File

@@ -46,6 +46,7 @@
<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)" />
<font-awesome-icon
v-if="editMode"
icon="cog"
@@ -54,7 +55,8 @@
data-testid="monitor-settings"
@click="$refs.monitorSettingDialog.show(group, monitor)"
/>
<Uptime :monitor="monitor.element" type="24" :pill="true" />
<Status v-if="showOnlyLastHeartbeat" :status="statusOfLastHeartbeat(monitor.element.id)" />
<Uptime v-else :monitor="monitor.element" type="24" :pill="true" />
<a
v-if="showLink(monitor)"
:href="monitor.element.url"
@@ -96,6 +98,7 @@ 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 GroupSortDropdown from "./GroupSortDropdown.vue";
export default {
@@ -105,6 +108,7 @@ export default {
HeartbeatBar,
Uptime,
Tag,
Status,
GroupSortDropdown,
},
props: {
@@ -120,7 +124,11 @@ export default {
/** Should expiry be shown? */
showCertificateExpiry: {
type: Boolean,
}
},
/** Should only the last heartbeat be shown? */
showOnlyLastHeartbeat: {
type: Boolean,
},
},
data() {
return {
@@ -192,6 +200,17 @@ export default {
}
},
/**
* Returns the status of the last heartbeat
* @param {number} monitorId Id of the monitor to get status for
* @returns {number} Status of the last heartbeat
*/
statusOfLastHeartbeat(monitorId) {
let heartbeats = this.$root.heartbeatList[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

View File

@@ -950,6 +950,7 @@
"nostrRecipients": "Recipients Public Keys (npub)",
"nostrRecipientsHelp": "npub format, one per line",
"showCertificateExpiry": "Show Certificate Expiry",
"showOnlyLastHeartbeat": "Show Only Last Heartbeat",
"noOrBadCertificate": "No/Bad Certificate",
"cacheBusterParam": "Add the {0} parameter",
"cacheBusterParamDescription": "Randomly generated parameter to skip caches.",

View File

@@ -68,6 +68,12 @@
<label class="form-check-label" for="show-certificate-expiry">{{ $t("showCertificateExpiry") }}</label>
</div>
<!-- Show only last heartbeat -->
<div class="my-3 form-check form-switch">
<input id="show-only-last-heartbeat" v-model="config.showOnlyLastHeartbeat" class="form-check-input" type="checkbox">
<label class="form-check-label" for="show-only-last-heartbeat">{{ $t("showOnlyLastHeartbeat") }}</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">
@@ -328,7 +334,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" :show-only-last-heartbeat="config.showOnlyLastHeartbeat" />
</div>
<footer class="mt-5 mb-4">