mirror of
https://github.com/louislam/uptime-kuma.git
synced 2025-07-18 23:34:04 +02:00
fix: lint
This commit is contained in:
parent
e6ce7e7a61
commit
7064932c16
4 changed files with 65 additions and 55 deletions
|
@ -10,4 +10,4 @@ exports.down = function (knex) {
|
||||||
return knex.schema.alterTable("monitor_group", function (table) {
|
return knex.schema.alterTable("monitor_group", function (table) {
|
||||||
table.dropColumn("daily_view");
|
table.dropColumn("daily_view");
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -142,7 +142,7 @@ router.get("/api/status-page/heartbeat-daily/:slug", cache("5 minutes"), async (
|
||||||
for (let monitor of monitorData) {
|
for (let monitor of monitorData) {
|
||||||
const monitorID = monitor.monitor_id;
|
const monitorID = monitor.monitor_id;
|
||||||
const useDailyView = monitor.daily_view;
|
const useDailyView = monitor.daily_view;
|
||||||
|
|
||||||
dailyViewSettings[monitorID] = useDailyView;
|
dailyViewSettings[monitorID] = useDailyView;
|
||||||
|
|
||||||
if (useDailyView) {
|
if (useDailyView) {
|
||||||
|
@ -173,7 +173,7 @@ router.get("/api/status-page/heartbeat-daily/:slug", cache("5 minutes"), async (
|
||||||
// Determine overall status for the day based on majority
|
// Determine overall status for the day based on majority
|
||||||
if (row.maintenance_beats > 0) {
|
if (row.maintenance_beats > 0) {
|
||||||
status = 3; // Maintenance
|
status = 3; // Maintenance
|
||||||
} else if (row.down_beats > row.up_beats / 2) {
|
} else if (row.down_beats > row.up_beats / 2) {
|
||||||
status = 0; // Down if more than 50% down
|
status = 0; // Down if more than 50% down
|
||||||
} else if (row.up_beats > 0) {
|
} else if (row.up_beats > 0) {
|
||||||
status = 1; // Up
|
status = 1; // Up
|
||||||
|
@ -200,15 +200,15 @@ router.get("/api/status-page/heartbeat-daily/:slug", cache("5 minutes"), async (
|
||||||
});
|
});
|
||||||
|
|
||||||
heartbeatList[monitorID] = processedData;
|
heartbeatList[monitorID] = processedData;
|
||||||
|
|
||||||
// Calculate uptime based only on actual daily data (not including missing days)
|
// Calculate uptime based only on actual daily data (not including missing days)
|
||||||
if (processedData.length > 0) {
|
if (processedData.length > 0) {
|
||||||
// Get recent data (last 30 days worth of actual data)
|
// Get recent data (last 30 days worth of actual data)
|
||||||
const recentData = processedData.slice(-30);
|
const recentData = processedData.slice(-30);
|
||||||
|
|
||||||
let totalUp = 0;
|
let totalUp = 0;
|
||||||
let totalDown = 0;
|
let totalDown = 0;
|
||||||
|
|
||||||
recentData.forEach(day => {
|
recentData.forEach(day => {
|
||||||
if (day.dailyStats) {
|
if (day.dailyStats) {
|
||||||
// Convert strings to numbers to avoid concatenation
|
// Convert strings to numbers to avoid concatenation
|
||||||
|
@ -216,7 +216,7 @@ router.get("/api/status-page/heartbeat-daily/:slug", cache("5 minutes"), async (
|
||||||
totalDown += parseInt(day.dailyStats.down) || 0;
|
totalDown += parseInt(day.dailyStats.down) || 0;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const totalChecks = totalUp + totalDown;
|
const totalChecks = totalUp + totalDown;
|
||||||
uptimeList[`${monitorID}_24`] = totalChecks > 0 ? (totalUp / totalChecks) : 0;
|
uptimeList[`${monitorID}_24`] = totalChecks > 0 ? (totalUp / totalChecks) : 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -235,7 +235,7 @@ router.get("/api/status-page/heartbeat-daily/:slug", cache("5 minutes"), async (
|
||||||
|
|
||||||
list = R.convertToBeans("heartbeat", list);
|
list = R.convertToBeans("heartbeat", list);
|
||||||
heartbeatList[monitorID] = list.reverse().map(row => row.toPublicJSON());
|
heartbeatList[monitorID] = list.reverse().map(row => row.toPublicJSON());
|
||||||
|
|
||||||
const uptimeCalculator = await UptimeCalculator.getUptimeCalculator(monitorID);
|
const uptimeCalculator = await UptimeCalculator.getUptimeCalculator(monitorID);
|
||||||
uptimeList[`${monitorID}_24`] = uptimeCalculator.get24Hour().uptime;
|
uptimeList[`${monitorID}_24`] = uptimeCalculator.get24Hour().uptime;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,12 +11,12 @@
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="beat daily-beat"
|
class="beat daily-beat"
|
||||||
:class="{
|
:class="{
|
||||||
'empty': (beat === 0),
|
'empty': (beat === 0),
|
||||||
'missing': (beat.missing || beat.status === -1),
|
'missing': (beat.missing || beat.status === -1),
|
||||||
'down': (beat.status === 0),
|
'down': (beat.status === 0),
|
||||||
'pending': (beat.status === 2),
|
'pending': (beat.status === 2),
|
||||||
'maintenance': (beat.status === 3)
|
'maintenance': (beat.status === 3)
|
||||||
}"
|
}"
|
||||||
:style="getBeatStyle(beat)"
|
:style="getBeatStyle(beat)"
|
||||||
/>
|
/>
|
||||||
|
@ -178,8 +178,10 @@ export default {
|
||||||
*/
|
*/
|
||||||
timeSinceFirstBeat() {
|
timeSinceFirstBeat() {
|
||||||
const firstValidBeat = this.shortBeatList.at(this.numPadding);
|
const firstValidBeat = this.shortBeatList.at(this.numPadding);
|
||||||
if (!firstValidBeat || !firstValidBeat.date) return "";
|
if (!firstValidBeat || !firstValidBeat.date) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
const days = dayjs().diff(dayjs(firstValidBeat.date), "days");
|
const days = dayjs().diff(dayjs(firstValidBeat.date), "days");
|
||||||
if (days > 30) {
|
if (days > 30) {
|
||||||
return Math.floor(days / 30) + "mo";
|
return Math.floor(days / 30) + "mo";
|
||||||
|
@ -194,10 +196,12 @@ export default {
|
||||||
*/
|
*/
|
||||||
timeSinceLastBeat() {
|
timeSinceLastBeat() {
|
||||||
const lastValidBeat = this.shortBeatList.at(-1);
|
const lastValidBeat = this.shortBeatList.at(-1);
|
||||||
if (!lastValidBeat || !lastValidBeat.date) return "";
|
if (!lastValidBeat || !lastValidBeat.date) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
const days = dayjs().diff(dayjs(lastValidBeat.date), "days");
|
const days = dayjs().diff(dayjs(lastValidBeat.date), "days");
|
||||||
|
|
||||||
if (days === 0) {
|
if (days === 0) {
|
||||||
return this.$t("Today");
|
return this.$t("Today");
|
||||||
} else if (days === 1) {
|
} else if (days === 1) {
|
||||||
|
@ -273,31 +277,37 @@ export default {
|
||||||
* @returns {string} Beat title
|
* @returns {string} Beat title
|
||||||
*/
|
*/
|
||||||
getBeatTitle(beat) {
|
getBeatTitle(beat) {
|
||||||
if (!beat || beat === 0) return "";
|
if (!beat || beat === 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
// Handle missing data
|
// Handle missing data
|
||||||
if (beat.missing || beat.status === -1) {
|
if (beat.missing || beat.status === -1) {
|
||||||
const date = beat.date || beat.time.split(' ')[0];
|
const date = beat.date || beat.time.split(" ")[0];
|
||||||
return `${date}\nNo data available`;
|
return `${date}\nNo data available`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const date = beat.date || beat.time.split(' ')[0];
|
const date = beat.date || beat.time.split(" ")[0];
|
||||||
const uptime = Math.round(beat.uptime * 100);
|
const uptime = Math.round(beat.uptime * 100);
|
||||||
const stats = beat.dailyStats;
|
const stats = beat.dailyStats;
|
||||||
|
|
||||||
let tooltip = `${date}\nUptime: ${uptime}%`;
|
let tooltip = `${date}\nUptime: ${uptime}%`;
|
||||||
|
|
||||||
if (stats) {
|
if (stats) {
|
||||||
tooltip += `\nUp: ${stats.up}, Down: ${stats.down}`;
|
tooltip += `\nUp: ${stats.up}, Down: ${stats.down}`;
|
||||||
if (stats.pending > 0) tooltip += `, Pending: ${stats.pending}`;
|
if (stats.pending > 0) {
|
||||||
if (stats.maintenance > 0) tooltip += `, Maintenance: ${stats.maintenance}`;
|
tooltip += `, Pending: ${stats.pending}`;
|
||||||
|
}
|
||||||
|
if (stats.maintenance > 0) {
|
||||||
|
tooltip += `, Maintenance: ${stats.maintenance}`;
|
||||||
|
}
|
||||||
tooltip += `\nTotal checks: ${stats.total}`;
|
tooltip += `\nTotal checks: ${stats.total}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (beat.ping) {
|
if (beat.ping) {
|
||||||
tooltip += `\nAvg ping: ${beat.ping}ms`;
|
tooltip += `\nAvg ping: ${beat.ping}ms`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return tooltip;
|
return tooltip;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -329,23 +339,23 @@ export default {
|
||||||
*/
|
*/
|
||||||
generateCompleteTimeline(actualData) {
|
generateCompleteTimeline(actualData) {
|
||||||
const timeline = [];
|
const timeline = [];
|
||||||
const today = dayjs().startOf('day');
|
const today = dayjs().startOf("day");
|
||||||
const startDate = today.subtract(90, 'day'); // 3 months back
|
const startDate = today.subtract(90, "day"); // 3 months back
|
||||||
|
|
||||||
// Create a map of existing data by date for quick lookup
|
// Create a map of existing data by date for quick lookup
|
||||||
const dataMap = {};
|
const dataMap = {};
|
||||||
actualData.forEach(beat => {
|
actualData.forEach(beat => {
|
||||||
if (beat && beat.date) {
|
if (beat && beat.date) {
|
||||||
const dateKey = dayjs(beat.date).format('YYYY-MM-DD');
|
const dateKey = dayjs(beat.date).format("YYYY-MM-DD");
|
||||||
dataMap[dateKey] = beat;
|
dataMap[dateKey] = beat;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Generate complete timeline from startDate to today
|
// Generate complete timeline from startDate to today
|
||||||
for (let i = 0; i <= 90; i++) {
|
for (let i = 0; i <= 90; i++) {
|
||||||
const currentDate = startDate.add(i, 'day');
|
const currentDate = startDate.add(i, "day");
|
||||||
const dateKey = currentDate.format('YYYY-MM-DD');
|
const dateKey = currentDate.format("YYYY-MM-DD");
|
||||||
|
|
||||||
if (dataMap[dateKey]) {
|
if (dataMap[dateKey]) {
|
||||||
// Use actual data if available
|
// Use actual data if available
|
||||||
timeline.push(dataMap[dateKey]);
|
timeline.push(dataMap[dateKey]);
|
||||||
|
@ -354,7 +364,7 @@ export default {
|
||||||
timeline.push({
|
timeline.push({
|
||||||
status: -1, // Special status for missing data
|
status: -1, // Special status for missing data
|
||||||
date: dateKey,
|
date: dateKey,
|
||||||
time: dateKey + ' 00:00:00',
|
time: dateKey + " 00:00:00",
|
||||||
uptime: 0,
|
uptime: 0,
|
||||||
ping: 0,
|
ping: 0,
|
||||||
missing: true,
|
missing: true,
|
||||||
|
@ -368,7 +378,7 @@ export default {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return timeline;
|
return timeline;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -429,23 +439,23 @@ export default {
|
||||||
// Daily beats get special styling
|
// Daily beats get special styling
|
||||||
&.daily-beat {
|
&.daily-beat {
|
||||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
|
|
||||||
&.down {
|
&.down {
|
||||||
border-color: darken($danger, 10%);
|
border-color: darken($danger, 10%);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.pending {
|
&.pending {
|
||||||
border-color: darken($warning, 10%);
|
border-color: darken($warning, 10%);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.maintenance {
|
&.maintenance {
|
||||||
border-color: darken($maintenance, 10%);
|
border-color: darken($maintenance, 10%);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not(.empty):not(.down):not(.pending):not(.maintenance):not(.missing) {
|
&:not(.empty):not(.down):not(.pending):not(.maintenance):not(.missing) {
|
||||||
border-color: darken($primary, 10%);
|
border-color: darken($primary, 10%);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.missing {
|
&.missing {
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
}
|
}
|
||||||
|
@ -458,31 +468,31 @@ export default {
|
||||||
.hp-bar-big .beat.empty {
|
.hp-bar-big .beat.empty {
|
||||||
background-color: #848484;
|
background-color: #848484;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hp-bar-big .beat.missing {
|
.hp-bar-big .beat.missing {
|
||||||
background-color: #555555;
|
background-color: #555555;
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hp-bar-big .beat.daily-beat {
|
.hp-bar-big .beat.daily-beat {
|
||||||
border-color: rgba(255, 255, 255, 0.2);
|
border-color: rgba(255, 255, 255, 0.2);
|
||||||
|
|
||||||
&.down {
|
&.down {
|
||||||
border-color: lighten($danger, 10%);
|
border-color: lighten($danger, 10%);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.pending {
|
&.pending {
|
||||||
border-color: lighten($warning, 10%);
|
border-color: lighten($warning, 10%);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.maintenance {
|
&.maintenance {
|
||||||
border-color: lighten($maintenance, 10%);
|
border-color: lighten($maintenance, 10%);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not(.empty):not(.down):not(.pending):not(.maintenance):not(.missing) {
|
&:not(.empty):not(.down):not(.pending):not(.maintenance):not(.missing) {
|
||||||
border-color: lighten($primary, 10%);
|
border-color: lighten($primary, 10%);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.missing {
|
&.missing {
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
}
|
}
|
||||||
|
@ -506,4 +516,4 @@ export default {
|
||||||
background-color: #333;
|
background-color: #333;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -773,7 +773,7 @@ export default {
|
||||||
if (! this.editMode) {
|
if (! this.editMode) {
|
||||||
// Fetch mixed data based on per-monitor daily view settings
|
// Fetch mixed data based on per-monitor daily view settings
|
||||||
axios.get("/api/status-page/heartbeat-daily/" + this.slug).then((res) => {
|
axios.get("/api/status-page/heartbeat-daily/" + this.slug).then((res) => {
|
||||||
const { heartbeatList, uptimeList, dailyViewSettings, hasMixedData } = res.data;
|
const { heartbeatList, uptimeList, dailyViewSettings } = res.data;
|
||||||
|
|
||||||
// Store both regular and daily data appropriately
|
// Store both regular and daily data appropriately
|
||||||
this.$root.heartbeatList = {};
|
this.$root.heartbeatList = {};
|
||||||
|
@ -785,12 +785,12 @@ export default {
|
||||||
if (dailyViewSettings[monitorId]) {
|
if (dailyViewSettings[monitorId]) {
|
||||||
// This monitor uses daily view
|
// This monitor uses daily view
|
||||||
this.$root.dailyHeartbeatList[monitorId] = heartbeatList[monitorId];
|
this.$root.dailyHeartbeatList[monitorId] = heartbeatList[monitorId];
|
||||||
|
|
||||||
// Set up lastHeartbeatList for uptime color calculation
|
// Set up lastHeartbeatList for uptime color calculation
|
||||||
if (heartbeatList[monitorId] && heartbeatList[monitorId].length > 0) {
|
if (heartbeatList[monitorId] && heartbeatList[monitorId].length > 0) {
|
||||||
const lastDailyBeat = heartbeatList[monitorId][heartbeatList[monitorId].length - 1];
|
const lastDailyBeat = heartbeatList[monitorId][heartbeatList[monitorId].length - 1];
|
||||||
// Create a minimal heartbeat list with just the last beat for color calculation
|
// Create a minimal heartbeat list with just the last beat for color calculation
|
||||||
this.$root.heartbeatList[monitorId] = [lastDailyBeat];
|
this.$root.heartbeatList[monitorId] = [ lastDailyBeat ];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// This monitor uses regular view
|
// This monitor uses regular view
|
||||||
|
|
Loading…
Add table
Reference in a new issue