Added Clickable hostname on status page. #1221

This should fully implement #1221 by modifying the API and adding two
new properties to the result. The `sendUrl` property denotes if the URL
is sent and `url` is included when required.
Client side checks have been implemented in order to only show a link
when the URL is vaugely correct. I.e not "" or "https://". This prevents
the link from being included if the monitor type is not HTTP without
having to publicly expose the monitor type.
The exposure of the URL is configuarable for each monitor on each
status page by clicking on the link icon.

Signed-off-by: Matthew Nickson <mnickson@sidingsmedia.com>
This commit is contained in:
Matthew Nickson 2022-06-11 17:23:12 +01:00
parent 87428231ad
commit fbfa5a33ed
No known key found for this signature in database
GPG key ID: BF229DCFD4748E05
7 changed files with 62 additions and 2 deletions

View file

@ -0,0 +1,5 @@
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db.
BEGIN TRANSACTION;
ALTER TABLE monitor_group
ADD send_url BOOLEAN DEFAULT 0 NOT NULL;
COMMIT;

View file

@ -58,6 +58,7 @@ class Database {
"patch-monitor-expiry-notification.sql": true, "patch-monitor-expiry-notification.sql": true,
"patch-status-page-footer-css.sql": true, "patch-status-page-footer-css.sql": true,
"patch-added-mqtt-monitor.sql": true, "patch-added-mqtt-monitor.sql": true,
"patch-add-clickable-status-page-link.sql": true,
}; };
/** /**

View file

@ -31,7 +31,7 @@ class Group extends BeanModel {
*/ */
async getMonitorList() { async getMonitorList() {
return R.convertToBeans("monitor", await R.getAll(` return R.convertToBeans("monitor", await R.getAll(`
SELECT monitor.* FROM monitor, monitor_group SELECT monitor.*, monitor_group.send_url FROM monitor, monitor_group
WHERE monitor.id = monitor_group.monitor_id WHERE monitor.id = monitor_group.monitor_id
AND group_id = ? AND group_id = ?
ORDER BY monitor_group.weight ORDER BY monitor_group.weight

View file

@ -34,7 +34,13 @@ class Monitor extends BeanModel {
let obj = { let obj = {
id: this.id, id: this.id,
name: this.name, name: this.name,
sendUrl: this.sendUrl,
}; };
if (this.sendUrl) {
obj.url = this.url;
}
if (showTags) { if (showTags) {
obj.tags = await this.getTags(); obj.tags = await this.getTags();
} }

View file

@ -202,6 +202,7 @@ module.exports.statusPageSocketHandler = (socket) => {
relationBean.weight = monitorOrder++; relationBean.weight = monitorOrder++;
relationBean.group_id = groupBean.id; relationBean.group_id = groupBean.id;
relationBean.monitor_id = monitor.id; relationBean.monitor_id = monitor.id;
relationBean.send_url = monitor.sendUrl;
await R.store(relationBean); await R.store(relationBean);
} }

View file

@ -39,7 +39,21 @@
<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" /> <Uptime :monitor="monitor.element" type="24" :pill="true" />
{{ monitor.element.name }} <a
v-if="showLink(monitor)"
:href="monitor.element.url"
class="item-name"
target="_blank"
>
{{ monitor.element.name }}
</a>
<p v-else class="item-name"> {{ monitor.element.name }} </p>
<font-awesome-icon
v-if="editMode"
:class="{'link-active': monitor.element.sendUrl}"
icon="link" class="action me-3"
@click="toggleLink(group.index, monitor.index)"
/>
</div> </div>
<div v-if="showTags" class="tags"> <div v-if="showTags" class="tags">
<Tag v-for="tag in monitor.element.tags" :key="tag" :item="tag" :size="'sm'" /> <Tag v-for="tag in monitor.element.tags" :key="tag" :item="tag" :size="'sm'" />
@ -101,6 +115,27 @@ export default {
removeMonitor(groupIndex, index) { removeMonitor(groupIndex, index) {
this.$root.publicGroupList[groupIndex].monitorList.splice(index, 1); this.$root.publicGroupList[groupIndex].monitorList.splice(index, 1);
}, },
/**
* Toggle the value of sendUrl
* @param {number} groupIndex Index of group monitor is member of
* @param {number} index Index of monitor within group
*/
toggleLink(groupIndex, index) {
this.$root.publicGroupList[groupIndex].monitorList[index].sendUrl = !this.$root.publicGroupList[groupIndex].monitorList[index].sendUrl;
},
/**
* Should a link to the monitor be shown?
* Attempts to guess if a link should be shown based upon if
* sendUrl is set and if the URL is default or not.
* @param {Object} monitor Monitor to check
* @returns {boolean}
*/
showLink(monitor) {
return monitor.element.sendUrl && monitor.element.url && monitor.element.url !== "https://";
},
} }
}; };
</script> </script>
@ -119,6 +154,17 @@ export default {
min-height: 46px; min-height: 46px;
} }
.item-name {
padding-left: 5px;
padding-right: 5px;
margin: 0;
display: inline-block;
}
.link-active {
color: #4caf50;
}
.flip-list-move { .flip-list-move {
transition: transform 0.5s; transition: transform 0.5s;
} }

View file

@ -81,6 +81,7 @@ library.add(
faUndo, faUndo,
faPlusCircle, faPlusCircle,
faAngleDown, faAngleDown,
faLink,
); );
export { FontAwesomeIcon }; export { FontAwesomeIcon };