feat: show monitor descriptions on status page

- configure description visibility per monitor
- configure description visiblitiy per status page
This commit is contained in:
David Roizenman 2024-03-22 21:39:14 -07:00
parent 45690a25a0
commit 56fc66a2ab
No known key found for this signature in database
GPG key ID: CD7B405D13E241B6
9 changed files with 70 additions and 11 deletions

View file

@ -0,0 +1,27 @@
/**
* @param { import("knex").Knex } knex Knex instance
* @returns { Promise<void> }
*/
exports.up = function (knex) {
return knex.schema
.alterTable("status_page", function (table) {
table.boolean("show_descriptions").notNullable().defaultTo(false);
})
.alterTable("monitor", function (table) {
table.boolean("show_description").notNullable().defaultTo(false);
});
};
/**
* @param { import("knex").Knex } knex Knex instance
* @returns { Promise<void> }
*/
exports.down = function (knex) {
return knex.schema
.alterTable("status_page", function (table) {
table.dropColumn("show_descriptions");
})
.alterTable("monitor", function (table) {
table.dropColumn("show_description");
});
};

View file

@ -8,15 +8,16 @@ class Group extends BeanModel {
* necessary data to public
* @param {boolean} showTags Should the JSON include monitor tags
* @param {boolean} certExpiry Should JSON include info about
* @param {boolean} showDescriptions Include description in JSON
* certificate expiry?
* @returns {Promise<object>} Object ready to parse
*/
async toPublicJSON(showTags = false, certExpiry = false) {
async toPublicJSON(showTags = false, certExpiry = false, showDescriptions = false) {
let monitorBeanList = await this.getMonitorList();
let monitorList = [];
for (let bean of monitorBeanList) {
monitorList.push(await bean.toPublicJSON(showTags, certExpiry));
monitorList.push(await bean.toPublicJSON(showTags, certExpiry, showDescriptions));
}
return {

View file

@ -42,10 +42,11 @@ class Monitor extends BeanModel {
* necessary data to public
* @param {boolean} showTags Include tags in JSON
* @param {boolean} certExpiry Include certificate expiry info in
* @param {boolean} showDescriptions Include description in JSON
* JSON
* @returns {Promise<object>} Object ready to parse
*/
async toPublicJSON(showTags = false, certExpiry = false) {
async toPublicJSON(showTags = false, certExpiry = false, showDescriptions = false) {
let obj = {
id: this.id,
name: this.name,
@ -61,6 +62,10 @@ class Monitor extends BeanModel {
obj.tags = await this.getTags();
}
if (showDescriptions && !!this.show_description) {
obj.description = this.description;
}
if (certExpiry && (this.type === "http" || this.type === "keyword" || this.type === "json-query") && this.getURLProtocol() === "https:") {
const { certExpiryDaysRemaining, validCert } = await this.getCertExpiry(this.id);
obj.certExpiryDaysRemaining = certExpiryDaysRemaining;
@ -103,6 +108,7 @@ class Monitor extends BeanModel {
id: this.id,
name: this.name,
description: this.description,
show_description: !!this.show_description,
path,
pathName,
parent: this.parent,

View file

@ -115,13 +115,14 @@ class StatusPage extends BeanModel {
// Public Group List
const publicGroupList = [];
const showTags = !!statusPage.show_tags;
const showDescriptions = !!statusPage.show_descriptions;
const list = await R.find("group", " public = 1 AND status_page_id = ? ORDER BY weight ", [
statusPage.id
]);
for (let groupBean of list) {
let monitorGroup = await groupBean.toPublicJSON(showTags, config?.showCertificateExpiry);
let monitorGroup = await groupBean.toPublicJSON(showTags, config?.showCertificateExpiry, showDescriptions);
publicGroupList.push(monitorGroup);
}
@ -240,6 +241,7 @@ class StatusPage extends BeanModel {
theme: this.theme,
published: !!this.published,
showTags: !!this.show_tags,
showDescriptions: !!this.show_descriptions,
domainNameList: this.getDomainNameList(),
customCSS: this.custom_css,
footerText: this.footer_text,
@ -263,6 +265,7 @@ class StatusPage extends BeanModel {
theme: this.theme,
published: !!this.published,
showTags: !!this.show_tags,
showDescriptions: !!this.show_descriptions,
customCSS: this.custom_css,
footerText: this.footer_text,
showPoweredBy: !!this.show_powered_by,

View file

@ -752,6 +752,7 @@ let needSetup = false;
bean.name = monitor.name;
bean.description = monitor.description;
bean.show_description = monitor.show_description;
bean.parent = monitor.parent;
bean.type = monitor.type;
bean.url = monitor.url;

View file

@ -159,6 +159,7 @@ module.exports.statusPageSocketHandler = (socket) => {
//statusPage.published = ;
//statusPage.search_engine_index = ;
statusPage.show_tags = config.showTags;
statusPage.showDescriptions = config.showDescriptions;
//statusPage.password = null;
statusPage.footer_text = config.footerText;
statusPage.custom_css = config.customCSS;

View file

@ -62,11 +62,14 @@
</span>
</div>
<div class="extra-info">
<div v-if="showCertificateExpiry && monitor.element.certExpiryDaysRemaining">
<Tag :item="{name: $t('Cert Exp.'), value: formattedCertExpiryMessage(monitor), color: certExpiryColor(monitor)}" :size="'sm'" />
</div>
<div v-if="showTags">
<Tag v-for="tag in monitor.element.tags" :key="tag" :item="tag" :size="'sm'" />
<p v-if="showDescriptions && !!monitor.element.description">{{ monitor.element.description }}</p>
<div class="tags">
<div v-if="showCertificateExpiry && monitor.element.certExpiryDaysRemaining">
<Tag :item="{name: $t('Cert Exp.'), value: formattedCertExpiryMessage(monitor), color: certExpiryColor(monitor)}" :size="'sm'" />
</div>
<div v-if="showTags">
<Tag v-for="tag in monitor.element.tags" :key="tag" :item="tag" :size="'sm'" />
</div>
</div>
</div>
</div>
@ -109,6 +112,10 @@ export default {
showTags: {
type: Boolean,
},
/** Should descriptions be shown? */
showDescriptions: {
type: Boolean
},
/** Should expiry be shown? */
showCertificateExpiry: {
type: Boolean,
@ -200,10 +207,13 @@ export default {
@import "../assets/vars";
.extra-info {
display: flex;
margin-bottom: 0.5rem;
}
.extra-info .tags {
display: flex;
}
.extra-info > div > div:first-child {
margin-left: 0 !important;
}

View file

@ -568,6 +568,11 @@
<input id="description" v-model="monitor.description" type="text" class="form-control">
</div>
<div class="my-3 form-check form-switch">
<input id="showDescription" v-model="monitor.show_description" class="form-check-input" type="checkbox">
<label class="form-check-label" for="showDescription">{{ $t("Show description on Status Page") }}</label>
</div>
<div class="my-3">
<tags-manager ref="tagsManager" :pre-selected-tags="monitor.tags"></tags-manager>
</div>

View file

@ -48,6 +48,11 @@
<label class="form-check-label" for="showTags">{{ $t("Show Tags") }}</label>
</div>
<div class="my-3 form-check form-switch">
<input id="showDescriptions" v-model="config.showDescriptions" class="form-check-input" type="checkbox">
<label class="form-check-label" for="showDescriptions">{{ $t("Show Descriptions") }}</label>
</div>
<!-- Show Powered By -->
<div class="my-3 form-check form-switch">
<input id="show-powered-by" v-model="config.showPoweredBy" class="form-check-input" type="checkbox">
@ -319,7 +324,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-descriptions="config.showDescriptions" :show-certificate-expiry="config.showCertificateExpiry" />
</div>
<footer class="mt-5 mb-4">