mirror of
https://github.com/louislam/uptime-kuma.git
synced 2024-11-23 23:04:04 +00:00
Compare commits
13 commits
57ff05f7aa
...
21f7c08b8c
Author | SHA1 | Date | |
---|---|---|---|
|
21f7c08b8c | ||
|
d2f71d11d6 | ||
|
2192bfa42b | ||
|
fb50d5f77c | ||
|
f381d64fce | ||
|
75f2c69ac5 | ||
|
629b15c56e | ||
|
612581a5d5 | ||
|
e539e5aa73 | ||
|
a34ca83844 | ||
|
488504c3fd | ||
|
26e234c132 | ||
|
201ac9245b |
7 changed files with 50 additions and 5 deletions
16
db/knex_migrations/2024-03-15-0000-show-last-heartbeat.js
Normal file
16
db/knex_migrations/2024-03-15-0000-show-last-heartbeat.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
exports.up = function (knex) {
|
||||||
|
// Add new column status_page.show_last_heartbeat
|
||||||
|
return knex.schema
|
||||||
|
.alterTable("status_page", function (table) {
|
||||||
|
table.boolean("show_last_heartbeat").notNullable().defaultTo(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.down = function (knex) {
|
||||||
|
// Drop column status_page.show_last_heartbeat
|
||||||
|
return knex.schema
|
||||||
|
.alterTable("status_page", function (table) {
|
||||||
|
table.dropColumn("show_last_heartbeat");
|
||||||
|
});
|
||||||
|
};
|
|
@ -409,6 +409,7 @@ class StatusPage extends BeanModel {
|
||||||
showPoweredBy: !!this.show_powered_by,
|
showPoweredBy: !!this.show_powered_by,
|
||||||
googleAnalyticsId: this.google_analytics_tag_id,
|
googleAnalyticsId: this.google_analytics_tag_id,
|
||||||
showCertificateExpiry: !!this.show_certificate_expiry,
|
showCertificateExpiry: !!this.show_certificate_expiry,
|
||||||
|
showLastHeartbeat: !!this.show_last_heartbeat
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,6 +433,7 @@ class StatusPage extends BeanModel {
|
||||||
showPoweredBy: !!this.show_powered_by,
|
showPoweredBy: !!this.show_powered_by,
|
||||||
googleAnalyticsId: this.google_analytics_tag_id,
|
googleAnalyticsId: this.google_analytics_tag_id,
|
||||||
showCertificateExpiry: !!this.show_certificate_expiry,
|
showCertificateExpiry: !!this.show_certificate_expiry,
|
||||||
|
showLastHeartbeat: !!this.show_last_heartbeat
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,9 @@ class ServerChan extends NotificationProvider {
|
||||||
const okMsg = "Sent Successfully.";
|
const okMsg = "Sent Successfully.";
|
||||||
|
|
||||||
// serverchan3 requires sending via ft07.com
|
// serverchan3 requires sending via ft07.com
|
||||||
const url = String(notification.serverChanSendKey).startsWith("sctp")
|
const matchResult = String(notification.serverChanSendKey).match(/^sctp(\d+)t/i);
|
||||||
? `https://${notification.serverChanSendKey}.push.ft07.com/send`
|
const url = matchResult && matchResult[1]
|
||||||
|
? `https://${matchResult[1]}.push.ft07.com/send/${notification.serverChanSendKey}.send`
|
||||||
: `https://sctapi.ftqq.com/${notification.serverChanSendKey}.send`;
|
: `https://sctapi.ftqq.com/${notification.serverChanSendKey}.send`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -164,6 +164,7 @@ module.exports.statusPageSocketHandler = (socket) => {
|
||||||
statusPage.footer_text = config.footerText;
|
statusPage.footer_text = config.footerText;
|
||||||
statusPage.custom_css = config.customCSS;
|
statusPage.custom_css = config.customCSS;
|
||||||
statusPage.show_powered_by = config.showPoweredBy;
|
statusPage.show_powered_by = config.showPoweredBy;
|
||||||
|
statusPage.show_last_heartbeat = config.showLastHeartbeat;
|
||||||
statusPage.show_certificate_expiry = config.showCertificateExpiry;
|
statusPage.show_certificate_expiry = config.showCertificateExpiry;
|
||||||
statusPage.modified_date = R.isoDateTime();
|
statusPage.modified_date = R.isoDateTime();
|
||||||
statusPage.google_analytics_tag_id = config.googleAnalyticsId;
|
statusPage.google_analytics_tag_id = config.googleAnalyticsId;
|
||||||
|
|
|
@ -38,7 +38,8 @@
|
||||||
<font-awesome-icon v-if="editMode" icon="arrows-alt-v" class="action drag me-3" />
|
<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="times" class="action remove me-3" @click="removeMonitor(group.index, monitor.index)" />
|
||||||
|
|
||||||
<Uptime :monitor="monitor.element" type="24" :pill="true" />
|
<Status v-if="showLastHeartbeat" :status="statusOfLastHeartbeat(monitor.element.id)" />
|
||||||
|
<Uptime v-else :monitor="monitor.element" type="24" :pill="true" />
|
||||||
<a
|
<a
|
||||||
v-if="showLink(monitor)"
|
v-if="showLink(monitor)"
|
||||||
:href="monitor.element.url"
|
:href="monitor.element.url"
|
||||||
|
@ -91,6 +92,7 @@ import Draggable from "vuedraggable";
|
||||||
import HeartbeatBar from "./HeartbeatBar.vue";
|
import HeartbeatBar from "./HeartbeatBar.vue";
|
||||||
import Uptime from "./Uptime.vue";
|
import Uptime from "./Uptime.vue";
|
||||||
import Tag from "./Tag.vue";
|
import Tag from "./Tag.vue";
|
||||||
|
import Status from "./Status.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
@ -99,6 +101,7 @@ export default {
|
||||||
HeartbeatBar,
|
HeartbeatBar,
|
||||||
Uptime,
|
Uptime,
|
||||||
Tag,
|
Tag,
|
||||||
|
Status,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
/** Are we in edit mode? */
|
/** Are we in edit mode? */
|
||||||
|
@ -113,7 +116,11 @@ export default {
|
||||||
/** Should expiry be shown? */
|
/** Should expiry be shown? */
|
||||||
showCertificateExpiry: {
|
showCertificateExpiry: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
}
|
},
|
||||||
|
/** Should only the last heartbeat be shown? */
|
||||||
|
showLastHeartbeat: {
|
||||||
|
type: Boolean,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -182,6 +189,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
|
* Returns certificate expiry color based on days remaining
|
||||||
* @param {object} monitor Monitor to show expiry for
|
* @param {object} monitor Monitor to show expiry for
|
||||||
|
|
|
@ -890,6 +890,7 @@
|
||||||
"nostrRecipients": "Recipients Public Keys (npub)",
|
"nostrRecipients": "Recipients Public Keys (npub)",
|
||||||
"nostrRecipientsHelp": "npub format, one per line",
|
"nostrRecipientsHelp": "npub format, one per line",
|
||||||
"showCertificateExpiry": "Show Certificate Expiry",
|
"showCertificateExpiry": "Show Certificate Expiry",
|
||||||
|
"showLastHeartbeat": "Show Last Heartbeat Only",
|
||||||
"noOrBadCertificate": "No/Bad Certificate",
|
"noOrBadCertificate": "No/Bad Certificate",
|
||||||
"cacheBusterParam": "Add the {0} parameter",
|
"cacheBusterParam": "Add the {0} parameter",
|
||||||
"cacheBusterParamDescription": "Randomly generated parameter to skip caches.",
|
"cacheBusterParamDescription": "Randomly generated parameter to skip caches.",
|
||||||
|
|
|
@ -68,6 +68,12 @@
|
||||||
<label class="form-check-label" for="show-certificate-expiry">{{ $t("showCertificateExpiry") }}</label>
|
<label class="form-check-label" for="show-certificate-expiry">{{ $t("showCertificateExpiry") }}</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Show last heartbeat -->
|
||||||
|
<div class="my-3 form-check form-switch">
|
||||||
|
<input id="show-last-heartbeat" v-model="config.showLastHeartbeat" class="form-check-input" type="checkbox">
|
||||||
|
<label class="form-check-label" for="show-last-heartbeat">{{ $t("showLastHeartbeat") }}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div v-if="false" class="my-3">
|
<div v-if="false" class="my-3">
|
||||||
<label for="password" class="form-label">{{ $t("Password") }} <sup>{{ $t("Coming Soon") }}</sup></label>
|
<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">
|
<input id="password" v-model="config.password" disabled type="password" autocomplete="new-password" class="form-control">
|
||||||
|
@ -328,7 +334,7 @@
|
||||||
👀 {{ $t("statusPageNothing") }}
|
👀 {{ $t("statusPageNothing") }}
|
||||||
</div>
|
</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-last-heartbeat="config.showLastHeartbeat" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer class="mt-5 mb-4">
|
<footer class="mt-5 mb-4">
|
||||||
|
|
Loading…
Reference in a new issue