From 2c6d410c603450c17b9cee82f87645a429eac43b Mon Sep 17 00:00:00 2001 From: Doruk Date: Sat, 14 Jun 2025 12:10:00 +0200 Subject: [PATCH] modularized with a heartbeat range util --- server/routers/status-page-router.js | 24 ++------------- server/util/heartbeat-range.js | 44 ++++++++++++++++++++++++++++ src/components/HeartbeatBar.vue | 15 ++++------ 3 files changed, 52 insertions(+), 31 deletions(-) create mode 100644 server/util/heartbeat-range.js diff --git a/server/routers/status-page-router.js b/server/routers/status-page-router.js index a0aee9978..cf190596a 100644 --- a/server/routers/status-page-router.js +++ b/server/routers/status-page-router.js @@ -3,6 +3,7 @@ const apicache = require("../modules/apicache"); const { UptimeKumaServer } = require("../uptime-kuma-server"); const StatusPage = require("../model/status_page"); const { allowDevAllOrigin, sendHttpError } = require("../util-server"); +const { rangeToDatabaseDate } = require("../util/heartbeat-range"); const { R } = require("redbean-node"); const { badgeConstants } = require("../../src/util"); const { makeBadge } = require("badge-maker"); @@ -89,28 +90,7 @@ router.get("/api/status-page/heartbeat/:slug", cache("1 minutes"), async (reques let heartbeatRange = statusPage ? statusPage.heartbeat_bar_range : "auto"; // Calculate the date range for heartbeats based on range setting - let dateFrom = null; - if (heartbeatRange === "auto") { - // Auto mode: limit to last 100 beats (original behavior) - dateFrom = null; - } else if (heartbeatRange.endsWith("h")) { - // Hours - let hours = parseInt(heartbeatRange); - let date = new Date(); - date.setHours(date.getHours() - hours); - dateFrom = date.toISOString().slice(0, 19).replace('T', ' '); - } else if (heartbeatRange.endsWith("d")) { - // Days - let days = parseInt(heartbeatRange); - let date = new Date(); - date.setDate(date.getDate() - days); - dateFrom = date.toISOString().slice(0, 19).replace('T', ' '); - } else { - // Fallback to 90 days - let date = new Date(); - date.setDate(date.getDate() - 90); - dateFrom = date.toISOString().slice(0, 19).replace('T', ' '); - } + let dateFrom = rangeToDatabaseDate(heartbeatRange); for (let monitorID of monitorIDList) { let list; diff --git a/server/util/heartbeat-range.js b/server/util/heartbeat-range.js new file mode 100644 index 000000000..a55a7f00e --- /dev/null +++ b/server/util/heartbeat-range.js @@ -0,0 +1,44 @@ +/** + * Utility functions for heartbeat range handling + */ + +/** + * Parse heartbeat range string and return hours + * @param {string} range - Range string like "6h", "7d", "auto" + * @returns {number|null} Hours or null for auto + */ +function parseRangeHours(range) { + if (!range || range === "auto") { + return null; + } + + if (range.endsWith("h")) { + return parseInt(range); + } else if (range.endsWith("d")) { + return parseInt(range) * 24; + } + + // Fallback + return 90 * 24; +} + +/** + * Convert range to database-compatible date string + * @param {string} range - Range string like "6h", "7d", "auto" + * @returns {string|null} Date string or null for auto + */ +function rangeToDatabaseDate(range) { + const hours = parseRangeHours(range); + if (hours === null) { + return null; + } + + const date = new Date(); + date.setHours(date.getHours() - hours); + return date.toISOString().slice(0, 19).replace('T', ' '); +} + +module.exports = { + parseRangeHours, + rangeToDatabaseDate +}; \ No newline at end of file diff --git a/src/components/HeartbeatBar.vue b/src/components/HeartbeatBar.vue index 4f15b124d..c6464480e 100644 --- a/src/components/HeartbeatBar.vue +++ b/src/components/HeartbeatBar.vue @@ -137,22 +137,19 @@ export default { const buckets = []; // Parse the range to get total time and determine bucket size + // Parse range to get total hours let totalHours; - let bucketSize; // in hours - let totalBuckets = this.maxBeat || 50; // Use maxBeat to determine bucket count - if (this.heartbeatBarRange.endsWith("h")) { totalHours = parseInt(this.heartbeatBarRange); } else if (this.heartbeatBarRange.endsWith("d")) { - const days = parseInt(this.heartbeatBarRange); - totalHours = days * 24; + totalHours = parseInt(this.heartbeatBarRange) * 24; } else { - // Fallback - totalHours = 90 * 24; + totalHours = 90 * 24; // Fallback } - // Calculate bucket size to fit the desired number of buckets - bucketSize = totalHours / totalBuckets; + // Calculate bucket size and count + const totalBuckets = this.maxBeat || 50; + const bucketSize = totalHours / totalBuckets; // Create time buckets from oldest to newest const startTime = now.subtract(totalHours, "hours");