mirror of
https://github.com/louislam/uptime-kuma.git
synced 2025-06-19 18:56:48 +02:00
feat: Add configurable heartbeat bar range for status pages
Add a configurable range option (7/30/60/90/180/365 days) for heartbeat bars on status pages. This allows status page owners to customize how much historical data is shown to visitors. Changes: - Add database migration for heartbeat_bar_range_days column - Update StatusPage model to include heartbeat bar range setting - Modify heartbeat API endpoint to respect configured range - Add UI controls in status page editor for range selection - Update English translations for new settings - Default to 90 days for backward compatibility Resolves #1888
This commit is contained in:
parent
55817061c0
commit
ad713eda4b
7 changed files with 54 additions and 4 deletions
12
db/knex_migrations/2025-06-14-0000-heartbeat-range-config.js
Normal file
12
db/knex_migrations/2025-06-14-0000-heartbeat-range-config.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
exports.up = function (knex) {
|
||||
return knex.schema
|
||||
.alterTable("status_page", function (table) {
|
||||
table.integer("heartbeat_bar_range_days").defaultTo(90).unsigned();
|
||||
});
|
||||
};
|
||||
|
||||
exports.down = function (knex) {
|
||||
return knex.schema.alterTable("status_page", function (table) {
|
||||
table.dropColumn("heartbeat_bar_range_days");
|
||||
});
|
||||
};
|
4
package-lock.json
generated
4
package-lock.json
generated
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "uptime-kuma",
|
||||
"version": "2.0.0-beta.2",
|
||||
"version": "2.0.0-beta.3",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "uptime-kuma",
|
||||
"version": "2.0.0-beta.2",
|
||||
"version": "2.0.0-beta.3",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@grpc/grpc-js": "~1.8.22",
|
||||
|
|
|
@ -409,6 +409,7 @@ class StatusPage extends BeanModel {
|
|||
showPoweredBy: !!this.show_powered_by,
|
||||
googleAnalyticsId: this.google_analytics_tag_id,
|
||||
showCertificateExpiry: !!this.show_certificate_expiry,
|
||||
heartbeatBarRangeDays: this.heartbeat_bar_range_days || 90,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -432,6 +433,7 @@ class StatusPage extends BeanModel {
|
|||
showPoweredBy: !!this.show_powered_by,
|
||||
googleAnalyticsId: this.google_analytics_tag_id,
|
||||
showCertificateExpiry: !!this.show_certificate_expiry,
|
||||
heartbeatBarRangeDays: this.heartbeat_bar_range_days || 90,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -84,14 +84,22 @@ router.get("/api/status-page/heartbeat/:slug", cache("1 minutes"), async (reques
|
|||
statusPageID
|
||||
]);
|
||||
|
||||
// Get the status page to determine the heartbeat range
|
||||
let statusPage = await R.findOne("status_page", " id = ? ", [ statusPageID ]);
|
||||
let heartbeatRangeDays = (statusPage && statusPage.heartbeat_bar_range_days) ? statusPage.heartbeat_bar_range_days : 90;
|
||||
|
||||
// Calculate the date range for heartbeats
|
||||
let dateFrom = new Date();
|
||||
dateFrom.setDate(dateFrom.getDate() - heartbeatRangeDays);
|
||||
|
||||
for (let monitorID of monitorIDList) {
|
||||
let list = await R.getAll(`
|
||||
SELECT * FROM heartbeat
|
||||
WHERE monitor_id = ?
|
||||
WHERE monitor_id = ? AND time >= ?
|
||||
ORDER BY time DESC
|
||||
LIMIT 100
|
||||
`, [
|
||||
monitorID,
|
||||
dateFrom.toISOString(),
|
||||
]);
|
||||
|
||||
list = R.convertToBeans("heartbeat", list);
|
||||
|
|
|
@ -165,6 +165,7 @@ module.exports.statusPageSocketHandler = (socket) => {
|
|||
statusPage.custom_css = config.customCSS;
|
||||
statusPage.show_powered_by = config.showPoweredBy;
|
||||
statusPage.show_certificate_expiry = config.showCertificateExpiry;
|
||||
statusPage.heartbeat_bar_range_days = config.heartbeatBarRangeDays || 90;
|
||||
statusPage.modified_date = R.isoDateTime();
|
||||
statusPage.google_analytics_tag_id = config.googleAnalyticsId;
|
||||
|
||||
|
|
|
@ -375,6 +375,14 @@
|
|||
"Footer Text": "Footer Text",
|
||||
"Refresh Interval": "Refresh Interval",
|
||||
"Refresh Interval Description": "The status page will do a full site refresh every {0} seconds",
|
||||
"Heartbeat Bar Range": "Heartbeat Bar Range",
|
||||
"7 days": "7 days",
|
||||
"30 days": "30 days",
|
||||
"60 days": "60 days",
|
||||
"90 days": "90 days",
|
||||
"180 days": "180 days",
|
||||
"365 days": "365 days",
|
||||
"How many days of heartbeat history to show in the status page": "How many days of heartbeat history to show in the status page",
|
||||
"Show Powered By": "Show Powered By",
|
||||
"Domain Names": "Domain Names",
|
||||
"signedInDisp": "Signed in as {0}",
|
||||
|
|
|
@ -42,6 +42,21 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="my-3">
|
||||
<label for="heartbeat-bar-range" class="form-label">{{ $t("Heartbeat Bar Range") }}</label>
|
||||
<select id="heartbeat-bar-range" v-model="config.heartbeatBarRangeDays" class="form-select" data-testid="heartbeat-bar-range-select">
|
||||
<option value="7">{{ $t("7 days") }}</option>
|
||||
<option value="30">{{ $t("30 days") }}</option>
|
||||
<option value="60">{{ $t("60 days") }}</option>
|
||||
<option value="90">{{ $t("90 days") }}</option>
|
||||
<option value="180">{{ $t("180 days") }}</option>
|
||||
<option value="365">{{ $t("365 days") }}</option>
|
||||
</select>
|
||||
<div class="form-text">
|
||||
{{ $t("How many days of heartbeat history to show in the status page") }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="my-3">
|
||||
<label for="switch-theme" class="form-label">{{ $t("Theme") }}</label>
|
||||
<select id="switch-theme" v-model="config.theme" class="form-select" data-testid="theme-select">
|
||||
|
@ -707,6 +722,10 @@ export default {
|
|||
this.config.domainNameList = [];
|
||||
}
|
||||
|
||||
if (!this.config.heartbeatBarRangeDays) {
|
||||
this.config.heartbeatBarRangeDays = 90;
|
||||
}
|
||||
|
||||
if (this.config.icon) {
|
||||
this.imgDataUrl = this.config.icon;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue