mirror of
https://github.com/louislam/uptime-kuma.git
synced 2024-11-23 18:06:14 +03:00
Merge pull request #1550 from Computroniks/jsdoc-for-src
JSDoc for src/*/*
This commit is contained in:
commit
a3b94aa532
41 changed files with 543 additions and 31 deletions
|
@ -25,10 +25,12 @@ export default {
|
||||||
CertificateInfoRow,
|
CertificateInfoRow,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
/** Object representing certificate */
|
||||||
certInfo: {
|
certInfo: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
/** Is the TLS certificate valid? */
|
||||||
valid: {
|
valid: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true,
|
required: true,
|
||||||
|
|
|
@ -56,12 +56,19 @@ export default {
|
||||||
Datetime,
|
Datetime,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
/** Object representing certificate */
|
||||||
cert: {
|
cert: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
/**
|
||||||
|
* Format the subject of the certificate
|
||||||
|
* @param {Object} subject Object representing the certificates
|
||||||
|
* subject
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
formatSubject(subject) {
|
formatSubject(subject) {
|
||||||
if (subject.O && subject.CN && subject.C) {
|
if (subject.O && subject.CN && subject.C) {
|
||||||
return `${subject.CN} - ${subject.O} (${subject.C})`;
|
return `${subject.CN} - ${subject.O} (${subject.C})`;
|
||||||
|
|
|
@ -29,14 +29,17 @@ import { Modal } from "bootstrap";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
|
/** Style of button */
|
||||||
btnStyle: {
|
btnStyle: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "btn-primary",
|
default: "btn-primary",
|
||||||
},
|
},
|
||||||
|
/** Text to use as yes */
|
||||||
yesText: {
|
yesText: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "Yes", // TODO: No idea what to translate this
|
default: "Yes", // TODO: No idea what to translate this
|
||||||
},
|
},
|
||||||
|
/** Text to use as no */
|
||||||
noText: {
|
noText: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "No",
|
default: "No",
|
||||||
|
@ -50,9 +53,13 @@ export default {
|
||||||
this.modal = new Modal(this.$refs.modal);
|
this.modal = new Modal(this.$refs.modal);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
/** Show the confirm dialog */
|
||||||
show() {
|
show() {
|
||||||
this.modal.show();
|
this.modal.show();
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* @emits string "yes" Notify the parent when Yes is pressed
|
||||||
|
*/
|
||||||
yes() {
|
yes() {
|
||||||
this.$emit("yes");
|
this.$emit("yes");
|
||||||
},
|
},
|
||||||
|
|
|
@ -25,33 +25,41 @@ let timeout;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
|
/** ID of this input */
|
||||||
id: {
|
id: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ""
|
default: ""
|
||||||
},
|
},
|
||||||
|
/** Type of input */
|
||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "text"
|
default: "text"
|
||||||
},
|
},
|
||||||
|
/** The value of the input */
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ""
|
default: ""
|
||||||
},
|
},
|
||||||
|
/** A placeholder to use */
|
||||||
placeholder: {
|
placeholder: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ""
|
default: ""
|
||||||
},
|
},
|
||||||
|
/** Should the field auto complete */
|
||||||
autocomplete: {
|
autocomplete: {
|
||||||
type: String,
|
type: String,
|
||||||
default: undefined,
|
default: undefined,
|
||||||
},
|
},
|
||||||
|
/** Is the input required? */
|
||||||
required: {
|
required: {
|
||||||
type: Boolean
|
type: Boolean
|
||||||
},
|
},
|
||||||
|
/** Should the input be read only? */
|
||||||
readonly: {
|
readonly: {
|
||||||
type: String,
|
type: String,
|
||||||
default: undefined,
|
default: undefined,
|
||||||
},
|
},
|
||||||
|
/** Is the input disabled? */
|
||||||
disabled: {
|
disabled: {
|
||||||
type: String,
|
type: String,
|
||||||
default: undefined,
|
default: undefined,
|
||||||
|
@ -79,14 +87,21 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
||||||
|
/** Show the input */
|
||||||
showInput() {
|
showInput() {
|
||||||
this.visibility = "text";
|
this.visibility = "text";
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Hide the input */
|
||||||
hideInput() {
|
hideInput() {
|
||||||
this.visibility = "password";
|
this.visibility = "password";
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy the provided text to the users clipboard
|
||||||
|
* @param {string} textToCopy
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
copyToClipboard(textToCopy) {
|
copyToClipboard(textToCopy) {
|
||||||
this.icon = "check";
|
this.icon = "check";
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import { sleep } from "../util.ts";
|
||||||
export default {
|
export default {
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
|
/** Value to count */
|
||||||
value: {
|
value: {
|
||||||
type: [ String, Number ],
|
type: [ String, Number ],
|
||||||
default: 0,
|
default: 0,
|
||||||
|
@ -18,6 +19,7 @@ export default {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0.3,
|
default: 0.3,
|
||||||
},
|
},
|
||||||
|
/** Unit of the value */
|
||||||
unit: {
|
unit: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "ms",
|
default: "ms",
|
||||||
|
@ -43,9 +45,7 @@ export default {
|
||||||
let frames = 12;
|
let frames = 12;
|
||||||
let step = Math.floor(diff / frames);
|
let step = Math.floor(diff / frames);
|
||||||
|
|
||||||
if (isNaN(step) || ! this.isNum || (diff > 0 && step < 1) || (diff < 0 && step > 1) || diff === 0) {
|
if (! (isNaN(step) || ! this.isNum || (diff > 0 && step < 1) || (diff < 0 && step > 1) || diff === 0)) {
|
||||||
// Lazy to NOT this condition, hahaha.
|
|
||||||
} else {
|
|
||||||
for (let i = 1; i < frames; i++) {
|
for (let i = 1; i < frames; i++) {
|
||||||
this.output += step;
|
this.output += step;
|
||||||
await sleep(15);
|
await sleep(15);
|
||||||
|
|
|
@ -13,10 +13,12 @@ dayjs.extend(relativeTime);
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
|
/** Value of date time */
|
||||||
value: {
|
value: {
|
||||||
type: String,
|
type: String,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
|
/** Should only the date be displayed? */
|
||||||
dateOnly: {
|
dateOnly: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
|
|
|
@ -17,14 +17,17 @@
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
|
/** Size of the heartbeat bar */
|
||||||
size: {
|
size: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "big",
|
default: "big",
|
||||||
},
|
},
|
||||||
|
/** ID of the monitor */
|
||||||
monitorId: {
|
monitorId: {
|
||||||
type: Number,
|
type: Number,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
/** Array of the monitors heartbeats */
|
||||||
heartbeatList: {
|
heartbeatList: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: null,
|
default: null,
|
||||||
|
@ -160,12 +163,19 @@ export default {
|
||||||
this.resize();
|
this.resize();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
/** Resize the heartbeat bar */
|
||||||
resize() {
|
resize() {
|
||||||
if (this.$refs.wrap) {
|
if (this.$refs.wrap) {
|
||||||
this.maxBeat = Math.floor(this.$refs.wrap.clientWidth / (this.beatWidth + this.beatMargin * 2));
|
this.maxBeat = Math.floor(this.$refs.wrap.clientWidth / (this.beatWidth + this.beatMargin * 2));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the title of the beat.
|
||||||
|
* Used as the hover tooltip on the heartbeat bar.
|
||||||
|
* @param {Object} beat Beat to get title from
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
getBeatTitle(beat) {
|
getBeatTitle(beat) {
|
||||||
return `${this.$root.datetime(beat.time)}` + ((beat.msg) ? ` - ${beat.msg}` : "");
|
return `${this.$root.datetime(beat.time)}` + ((beat.msg) ? ` - ${beat.msg}` : "");
|
||||||
},
|
},
|
||||||
|
|
|
@ -24,25 +24,31 @@
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
|
/** The value of the input */
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ""
|
default: ""
|
||||||
},
|
},
|
||||||
|
/** A placeholder to use */
|
||||||
placeholder: {
|
placeholder: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ""
|
default: ""
|
||||||
},
|
},
|
||||||
|
/** Maximum length of the input */
|
||||||
maxlength: {
|
maxlength: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 255
|
default: 255
|
||||||
},
|
},
|
||||||
|
/** Should the field auto complete */
|
||||||
autocomplete: {
|
autocomplete: {
|
||||||
type: String,
|
type: String,
|
||||||
default: undefined,
|
default: undefined,
|
||||||
},
|
},
|
||||||
|
/** Is the input required? */
|
||||||
required: {
|
required: {
|
||||||
type: Boolean
|
type: Boolean
|
||||||
},
|
},
|
||||||
|
/** Should the input be read only? */
|
||||||
readonly: {
|
readonly: {
|
||||||
type: String,
|
type: String,
|
||||||
default: undefined,
|
default: undefined,
|
||||||
|
@ -68,9 +74,11 @@ export default {
|
||||||
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
/** Show users input in plain text */
|
||||||
showInput() {
|
showInput() {
|
||||||
this.visibility = "text";
|
this.visibility = "text";
|
||||||
},
|
},
|
||||||
|
/** Censor users input */
|
||||||
hideInput() {
|
hideInput() {
|
||||||
this.visibility = "password";
|
this.visibility = "password";
|
||||||
},
|
},
|
||||||
|
|
|
@ -55,6 +55,7 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
/** Submit the user details and attempt to log in */
|
||||||
submit() {
|
submit() {
|
||||||
this.processing = true;
|
this.processing = true;
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@ export default {
|
||||||
Tag,
|
Tag,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
/** Should the scrollbar be shown */
|
||||||
scrollbar: {
|
scrollbar: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
},
|
},
|
||||||
|
@ -136,6 +137,7 @@ export default {
|
||||||
window.removeEventListener("scroll", this.onScroll);
|
window.removeEventListener("scroll", this.onScroll);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
/** Handle user scroll */
|
||||||
onScroll() {
|
onScroll() {
|
||||||
if (window.top.scrollY <= 133) {
|
if (window.top.scrollY <= 133) {
|
||||||
this.windowTop = window.top.scrollY;
|
this.windowTop = window.top.scrollY;
|
||||||
|
@ -143,9 +145,15 @@ export default {
|
||||||
this.windowTop = 133;
|
this.windowTop = 133;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Get URL of monitor
|
||||||
|
* @param {number} id ID of monitor
|
||||||
|
* @returns {string} Relative URL of monitor
|
||||||
|
*/
|
||||||
monitorURL(id) {
|
monitorURL(id) {
|
||||||
return getMonitorRelativeURL(id);
|
return getMonitorRelativeURL(id);
|
||||||
},
|
},
|
||||||
|
/** Clear the search bar */
|
||||||
clearSearchText() {
|
clearSearchText() {
|
||||||
this.searchText = "";
|
this.searchText = "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,11 +125,16 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
||||||
|
/** Show dialog to confirm deletion */
|
||||||
deleteConfirm() {
|
deleteConfirm() {
|
||||||
this.modal.hide();
|
this.modal.hide();
|
||||||
this.$refs.confirmDelete.show();
|
this.$refs.confirmDelete.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show settings for specified notification
|
||||||
|
* @param {number} notificationID ID of notification to show
|
||||||
|
*/
|
||||||
show(notificationID) {
|
show(notificationID) {
|
||||||
if (notificationID) {
|
if (notificationID) {
|
||||||
this.id = notificationID;
|
this.id = notificationID;
|
||||||
|
@ -152,6 +157,7 @@ export default {
|
||||||
this.modal.show();
|
this.modal.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Submit the form to the server */
|
||||||
submit() {
|
submit() {
|
||||||
this.processing = true;
|
this.processing = true;
|
||||||
this.$root.getSocket().emit("addNotification", this.notification, this.id, (res) => {
|
this.$root.getSocket().emit("addNotification", this.notification, this.id, (res) => {
|
||||||
|
@ -170,6 +176,7 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Test the notification endpoint */
|
||||||
test() {
|
test() {
|
||||||
this.processing = true;
|
this.processing = true;
|
||||||
this.$root.getSocket().emit("testNotification", this.notification, (res) => {
|
this.$root.getSocket().emit("testNotification", this.notification, (res) => {
|
||||||
|
@ -178,6 +185,7 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Delete the notification endpoint */
|
||||||
deleteNotification() {
|
deleteNotification() {
|
||||||
this.processing = true;
|
this.processing = true;
|
||||||
this.$root.getSocket().emit("deleteNotification", this.id, (res) => {
|
this.$root.getSocket().emit("deleteNotification", this.id, (res) => {
|
||||||
|
@ -190,6 +198,7 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
|
* Get a unique default name for the notification
|
||||||
* @param {keyof NotificationFormList} notificationKey
|
* @param {keyof NotificationFormList} notificationKey
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -35,6 +35,7 @@ Chart.register(LineController, BarController, LineElement, PointElement, TimeSca
|
||||||
export default {
|
export default {
|
||||||
components: { LineChart },
|
components: { LineChart },
|
||||||
props: {
|
props: {
|
||||||
|
/** ID of monitor */
|
||||||
monitorId: {
|
monitorId: {
|
||||||
type: Number,
|
type: Number,
|
||||||
required: true,
|
required: true,
|
||||||
|
|
|
@ -130,11 +130,16 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
/** Show dialog to confirm deletion */
|
||||||
deleteConfirm() {
|
deleteConfirm() {
|
||||||
this.modal.hide();
|
this.modal.hide();
|
||||||
this.$refs.confirmDelete.show();
|
this.$refs.confirmDelete.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show settings for specified proxy
|
||||||
|
* @param {number} proxyID ID of proxy to show
|
||||||
|
*/
|
||||||
show(proxyID) {
|
show(proxyID) {
|
||||||
if (proxyID) {
|
if (proxyID) {
|
||||||
this.id = proxyID;
|
this.id = proxyID;
|
||||||
|
@ -163,6 +168,7 @@ export default {
|
||||||
this.modal.show();
|
this.modal.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Submit form data for saving */
|
||||||
submit() {
|
submit() {
|
||||||
this.processing = true;
|
this.processing = true;
|
||||||
this.$root.getSocket().emit("addProxy", this.proxy, this.id, (res) => {
|
this.$root.getSocket().emit("addProxy", this.proxy, this.id, (res) => {
|
||||||
|
@ -180,6 +186,7 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Delete this proxy */
|
||||||
deleteProxy() {
|
deleteProxy() {
|
||||||
this.processing = true;
|
this.processing = true;
|
||||||
this.$root.getSocket().emit("deleteProxy", this.id, (res) => {
|
this.$root.getSocket().emit("deleteProxy", this.id, (res) => {
|
||||||
|
|
|
@ -72,10 +72,12 @@ export default {
|
||||||
Tag,
|
Tag,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
/** Are we in edit mode? */
|
||||||
editMode: {
|
editMode: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
/** Should tags be shown? */
|
||||||
showTags: {
|
showTags: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
}
|
}
|
||||||
|
@ -94,10 +96,20 @@ export default {
|
||||||
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
/**
|
||||||
|
* Remove the specified group
|
||||||
|
* @param {number} index Index of group to remove
|
||||||
|
*/
|
||||||
removeGroup(index) {
|
removeGroup(index) {
|
||||||
this.$root.publicGroupList.splice(index, 1);
|
this.$root.publicGroupList.splice(index, 1);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a monitor from a group
|
||||||
|
* @param {number} groupIndex Index of group to remove monitor
|
||||||
|
* from
|
||||||
|
* @param {number} index Index of monitor to remove
|
||||||
|
*/
|
||||||
removeMonitor(groupIndex, index) {
|
removeMonitor(groupIndex, index) {
|
||||||
this.$root.publicGroupList[groupIndex].monitorList.splice(index, 1);
|
this.$root.publicGroupList[groupIndex].monitorList.splice(index, 1);
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
|
/** Current status of monitor */
|
||||||
status: {
|
status: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0,
|
default: 0,
|
||||||
|
|
|
@ -20,14 +20,20 @@
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
|
/** Object representing tag */
|
||||||
item: {
|
item: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
/** Function to remove tag */
|
||||||
remove: {
|
remove: {
|
||||||
type: Function,
|
type: Function,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Size of tag
|
||||||
|
* @values normal, small
|
||||||
|
*/
|
||||||
size: {
|
size: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "normal",
|
default: "normal",
|
||||||
|
|
|
@ -139,6 +139,7 @@ export default {
|
||||||
VueMultiselect,
|
VueMultiselect,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
/** Array of tags to be pre-selected */
|
||||||
preSelectedTags: {
|
preSelectedTags: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
|
@ -241,9 +242,11 @@ export default {
|
||||||
this.getExistingTags();
|
this.getExistingTags();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
/** Show the add tag dialog */
|
||||||
showAddDialog() {
|
showAddDialog() {
|
||||||
this.modal.show();
|
this.modal.show();
|
||||||
},
|
},
|
||||||
|
/** Get all existing tags */
|
||||||
getExistingTags() {
|
getExistingTags() {
|
||||||
this.$root.getSocket().emit("getTags", (res) => {
|
this.$root.getSocket().emit("getTags", (res) => {
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
|
@ -253,6 +256,10 @@ export default {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Delete the specified tag
|
||||||
|
* @param {Object} tag Object representing tag to delete
|
||||||
|
*/
|
||||||
deleteTag(item) {
|
deleteTag(item) {
|
||||||
if (item.new) {
|
if (item.new) {
|
||||||
// Undo Adding a new Tag
|
// Undo Adding a new Tag
|
||||||
|
@ -262,6 +269,13 @@ export default {
|
||||||
this.deleteTags.push(item);
|
this.deleteTags.push(item);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Get colour of text inside the tag
|
||||||
|
* @param {Object} option The tag that needs to be displayed.
|
||||||
|
* Defaults to "white" unless the tag has no color, which will
|
||||||
|
* then return the body color (based on application theme)
|
||||||
|
* @returns string
|
||||||
|
*/
|
||||||
textColor(option) {
|
textColor(option) {
|
||||||
if (option.color) {
|
if (option.color) {
|
||||||
return "white";
|
return "white";
|
||||||
|
@ -269,6 +283,7 @@ export default {
|
||||||
return this.$root.theme === "light" ? "var(--bs-body-color)" : "inherit";
|
return this.$root.theme === "light" ? "var(--bs-body-color)" : "inherit";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
/** Add a draft tag */
|
||||||
addDraftTag() {
|
addDraftTag() {
|
||||||
console.log("Adding Draft Tag: ", this.newDraftTag);
|
console.log("Adding Draft Tag: ", this.newDraftTag);
|
||||||
if (this.newDraftTag.select != null) {
|
if (this.newDraftTag.select != null) {
|
||||||
|
@ -296,6 +311,7 @@ export default {
|
||||||
}
|
}
|
||||||
this.clearDraftTag();
|
this.clearDraftTag();
|
||||||
},
|
},
|
||||||
|
/** Remove a draft tag */
|
||||||
clearDraftTag() {
|
clearDraftTag() {
|
||||||
this.newDraftTag = {
|
this.newDraftTag = {
|
||||||
name: null,
|
name: null,
|
||||||
|
@ -307,26 +323,51 @@ export default {
|
||||||
};
|
};
|
||||||
this.modal.hide();
|
this.modal.hide();
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Add a tag asynchronously
|
||||||
|
* @param {Object} newTag Object representing new tag to add
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
addTagAsync(newTag) {
|
addTagAsync(newTag) {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
this.$root.getSocket().emit("addTag", newTag, resolve);
|
this.$root.getSocket().emit("addTag", newTag, resolve);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Add a tag to a monitor asynchronously
|
||||||
|
* @param {number} tagId ID of tag to add
|
||||||
|
* @param {number} monitorId ID of monitor to add tag to
|
||||||
|
* @param {string} value Value of tag
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
addMonitorTagAsync(tagId, monitorId, value) {
|
addMonitorTagAsync(tagId, monitorId, value) {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
this.$root.getSocket().emit("addMonitorTag", tagId, monitorId, value, resolve);
|
this.$root.getSocket().emit("addMonitorTag", tagId, monitorId, value, resolve);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Delete a tag from a monitor asynchronously
|
||||||
|
* @param {number} tagId ID of tag to remove
|
||||||
|
* @param {number} monitorId ID of monitor to remove tag from
|
||||||
|
* @param {string} value Value of tag
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
deleteMonitorTagAsync(tagId, monitorId, value) {
|
deleteMonitorTagAsync(tagId, monitorId, value) {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
this.$root.getSocket().emit("deleteMonitorTag", tagId, monitorId, value, resolve);
|
this.$root.getSocket().emit("deleteMonitorTag", tagId, monitorId, value, resolve);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
/** Handle pressing Enter key when inside the modal */
|
||||||
onEnter() {
|
onEnter() {
|
||||||
if (!this.validateDraftTag.invalid) {
|
if (!this.validateDraftTag.invalid) {
|
||||||
this.addDraftTag();
|
this.addDraftTag();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Submit the form data
|
||||||
|
* @param {number} monitorId ID of monitor this change affects
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
async submit(monitorId) {
|
async submit(monitorId) {
|
||||||
console.log(`Submitting tag changes for monitor ${monitorId}...`);
|
console.log(`Submitting tag changes for monitor ${monitorId}...`);
|
||||||
this.processing = true;
|
this.processing = true;
|
||||||
|
|
|
@ -29,10 +29,12 @@
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
|
/** Heading of the section */
|
||||||
heading: {
|
heading: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "",
|
default: "",
|
||||||
},
|
},
|
||||||
|
/** Should the section be open by default? */
|
||||||
defaultOpen: {
|
defaultOpen: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
|
|
|
@ -100,18 +100,22 @@ export default {
|
||||||
this.getStatus();
|
this.getStatus();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
/** Show the dialog */
|
||||||
show() {
|
show() {
|
||||||
this.modal.show();
|
this.modal.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Show dialog to confirm enabling 2FA */
|
||||||
confirmEnableTwoFA() {
|
confirmEnableTwoFA() {
|
||||||
this.$refs.confirmEnableTwoFA.show();
|
this.$refs.confirmEnableTwoFA.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Show dialog to confirm disabling 2FA */
|
||||||
confirmDisableTwoFA() {
|
confirmDisableTwoFA() {
|
||||||
this.$refs.confirmDisableTwoFA.show();
|
this.$refs.confirmDisableTwoFA.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Prepare 2FA configuration */
|
||||||
prepare2FA() {
|
prepare2FA() {
|
||||||
this.processing = true;
|
this.processing = true;
|
||||||
|
|
||||||
|
@ -126,6 +130,7 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Save the current 2FA configuration */
|
||||||
save2FA() {
|
save2FA() {
|
||||||
this.processing = true;
|
this.processing = true;
|
||||||
|
|
||||||
|
@ -143,6 +148,7 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Disable 2FA for this user */
|
||||||
disable2FA() {
|
disable2FA() {
|
||||||
this.processing = true;
|
this.processing = true;
|
||||||
|
|
||||||
|
@ -160,6 +166,7 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Verify the token generated by the user */
|
||||||
verifyToken() {
|
verifyToken() {
|
||||||
this.$root.getSocket().emit("verifyToken", this.token, this.currentPassword, (res) => {
|
this.$root.getSocket().emit("verifyToken", this.token, this.currentPassword, (res) => {
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
|
@ -170,6 +177,7 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Get current status of 2FA */
|
||||||
getStatus() {
|
getStatus() {
|
||||||
this.$root.getSocket().emit("twoFAStatus", (res) => {
|
this.$root.getSocket().emit("twoFAStatus", (res) => {
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
|
|
|
@ -5,14 +5,17 @@
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
|
/** Monitor this represents */
|
||||||
monitor: {
|
monitor: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
|
/** Type of monitor */
|
||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
|
/** Is this a pill? */
|
||||||
pill: {
|
pill: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
|
|
|
@ -133,10 +133,15 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
/**
|
||||||
|
* Show the confimation dialog confirming the configuration
|
||||||
|
* be imported
|
||||||
|
*/
|
||||||
confirmImport() {
|
confirmImport() {
|
||||||
this.$refs.confirmImport.show();
|
this.$refs.confirmImport.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Download a backup of the configuration */
|
||||||
downloadBackup() {
|
downloadBackup() {
|
||||||
let time = dayjs().format("YYYY_MM_DD-hh_mm_ss");
|
let time = dayjs().format("YYYY_MM_DD-hh_mm_ss");
|
||||||
let fileName = `Uptime_Kuma_Backup_${time}.json`;
|
let fileName = `Uptime_Kuma_Backup_${time}.json`;
|
||||||
|
@ -157,6 +162,10 @@ export default {
|
||||||
downloadItem.click();
|
downloadItem.click();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import the specified backup file
|
||||||
|
* @returns {?string}
|
||||||
|
*/
|
||||||
importBackup() {
|
importBackup() {
|
||||||
this.processing = true;
|
this.processing = true;
|
||||||
let uploadItem = document.getElementById("import-backend").files;
|
let uploadItem = document.getElementById("import-backend").files;
|
||||||
|
|
|
@ -178,10 +178,12 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
/** Save the settings */
|
||||||
saveGeneral() {
|
saveGeneral() {
|
||||||
localStorage.timezone = this.$root.userTimezone;
|
localStorage.timezone = this.$root.userTimezone;
|
||||||
this.saveSettings();
|
this.saveSettings();
|
||||||
},
|
},
|
||||||
|
/** Get the base URL of the application */
|
||||||
autoGetPrimaryBaseURL() {
|
autoGetPrimaryBaseURL() {
|
||||||
this.settings.primaryBaseURL = location.protocol + "//" + location.host;
|
this.settings.primaryBaseURL = location.protocol + "//" + location.host;
|
||||||
},
|
},
|
||||||
|
|
|
@ -90,6 +90,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
/** Get the current size of the database */
|
||||||
loadDatabaseSize() {
|
loadDatabaseSize() {
|
||||||
log.debug("monitorhistory", "load database size");
|
log.debug("monitorhistory", "load database size");
|
||||||
this.$root.getSocket().emit("getDatabaseSize", (res) => {
|
this.$root.getSocket().emit("getDatabaseSize", (res) => {
|
||||||
|
@ -102,6 +103,7 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Request that the database is shrunk */
|
||||||
shrinkDatabase() {
|
shrinkDatabase() {
|
||||||
this.$root.getSocket().emit("shrinkDatabase", (res) => {
|
this.$root.getSocket().emit("shrinkDatabase", (res) => {
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
|
@ -113,10 +115,12 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Show the dialog to confirm clearing stats */
|
||||||
confirmClearStatistics() {
|
confirmClearStatistics() {
|
||||||
this.$refs.confirmClearStatistics.show();
|
this.$refs.confirmClearStatistics.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Send the request to clear stats */
|
||||||
clearStatistics() {
|
clearStatistics() {
|
||||||
this.$root.clearStatistics((res) => {
|
this.$root.clearStatistics((res) => {
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
|
|
|
@ -120,14 +120,17 @@ export default {
|
||||||
this.$root.getSocket().emit(prefix + "leave");
|
this.$root.getSocket().emit(prefix + "leave");
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
/** Start the Cloudflare tunnel */
|
||||||
start() {
|
start() {
|
||||||
this.$root.getSocket().emit(prefix + "start", this.cloudflareTunnelToken);
|
this.$root.getSocket().emit(prefix + "start", this.cloudflareTunnelToken);
|
||||||
},
|
},
|
||||||
|
/** Stop the Cloudflare tunnel */
|
||||||
stop() {
|
stop() {
|
||||||
this.$root.getSocket().emit(prefix + "stop", this.currentPassword, (res) => {
|
this.$root.getSocket().emit(prefix + "stop", this.currentPassword, (res) => {
|
||||||
this.$root.toastRes(res);
|
this.$root.toastRes(res);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
/** Remove the token for the Cloudflare tunnel */
|
||||||
removeToken() {
|
removeToken() {
|
||||||
this.$root.getSocket().emit(prefix + "removeToken");
|
this.$root.getSocket().emit(prefix + "removeToken");
|
||||||
this.cloudflareTunnelToken = "";
|
this.cloudflareTunnelToken = "";
|
||||||
|
|
|
@ -303,6 +303,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
/** Check new passwords match before saving them */
|
||||||
savePassword() {
|
savePassword() {
|
||||||
if (this.password.newPassword !== this.password.repeatNewPassword) {
|
if (this.password.newPassword !== this.password.repeatNewPassword) {
|
||||||
this.invalidPassword = true;
|
this.invalidPassword = true;
|
||||||
|
@ -320,6 +321,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Disable authentication for web app access */
|
||||||
disableAuth() {
|
disableAuth() {
|
||||||
this.settings.disableAuth = true;
|
this.settings.disableAuth = true;
|
||||||
|
|
||||||
|
@ -332,6 +334,7 @@ export default {
|
||||||
}, this.password.currentPassword);
|
}, this.password.currentPassword);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Enable authentication for web app access */
|
||||||
enableAuth() {
|
enableAuth() {
|
||||||
this.settings.disableAuth = false;
|
this.settings.disableAuth = false;
|
||||||
this.saveSettings();
|
this.saveSettings();
|
||||||
|
|
|
@ -18,14 +18,31 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
/**
|
||||||
|
* Return a given value in the format YYYY-MM-DD HH:mm:ss
|
||||||
|
* @param {any} value Value to format as date time
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
datetime(value) {
|
datetime(value) {
|
||||||
return this.datetimeFormat(value, "YYYY-MM-DD HH:mm:ss");
|
return this.datetimeFormat(value, "YYYY-MM-DD HH:mm:ss");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a given value in the format YYYY-MM-DD
|
||||||
|
* @param {any} value Value to format as date
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
date(value) {
|
date(value) {
|
||||||
return this.datetimeFormat(value, "YYYY-MM-DD");
|
return this.datetimeFormat(value, "YYYY-MM-DD");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a given value in the format HH:mm or if second is set
|
||||||
|
* to true, HH:mm:ss
|
||||||
|
* @param {any} value Value to format
|
||||||
|
* @param {boolean} second Should seconds be included?
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
time(value, second = true) {
|
time(value, second = true) {
|
||||||
let secondString;
|
let secondString;
|
||||||
if (second) {
|
if (second) {
|
||||||
|
@ -36,6 +53,12 @@ export default {
|
||||||
return this.datetimeFormat(value, "HH:mm" + secondString);
|
return this.datetimeFormat(value, "HH:mm" + secondString);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a value in a custom format
|
||||||
|
* @param {any} value Value to format
|
||||||
|
* @param {any} format Format to return value in
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
datetimeFormat(value, format) {
|
datetimeFormat(value, format) {
|
||||||
if (value !== undefined && value !== "") {
|
if (value !== undefined && value !== "") {
|
||||||
return dayjs.utc(value).tz(this.timezone).format(format);
|
return dayjs.utc(value).tz(this.timezone).format(format);
|
||||||
|
|
|
@ -22,6 +22,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
/** Change the application language */
|
||||||
async changeLang(lang) {
|
async changeLang(lang) {
|
||||||
let message = (await langModules["../languages/" + lang + ".js"]()).default;
|
let message = (await langModules["../languages/" + lang + ".js"]()).default;
|
||||||
this.$i18n.setLocaleMessage(lang, message);
|
this.$i18n.setLocaleMessage(lang, message);
|
||||||
|
|
|
@ -12,11 +12,13 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
/** Handle screen resize */
|
||||||
onResize() {
|
onResize() {
|
||||||
this.windowWidth = window.innerWidth;
|
this.windowWidth = window.innerWidth;
|
||||||
this.updateBody();
|
this.updateBody();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Add css-class "mobile" to body if needed */
|
||||||
updateBody() {
|
updateBody() {
|
||||||
if (this.isMobile) {
|
if (this.isMobile) {
|
||||||
document.body.classList.add("mobile");
|
document.body.classList.add("mobile");
|
||||||
|
|
|
@ -62,6 +62,12 @@ export default {
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize connection to socket server
|
||||||
|
* @param {boolean} [bypass = false] Should the check for if we
|
||||||
|
* are on a status page be bypassed?
|
||||||
|
* @returns {(void|null)}
|
||||||
|
*/
|
||||||
initSocketIO(bypass = false) {
|
initSocketIO(bypass = false) {
|
||||||
// No need to re-init
|
// No need to re-init
|
||||||
if (this.socket.initedSocketIO) {
|
if (this.socket.initedSocketIO) {
|
||||||
|
@ -258,10 +264,18 @@ export default {
|
||||||
socket.on("cloudflared_token", (res) => this.cloudflared.cloudflareTunnelToken = res);
|
socket.on("cloudflared_token", (res) => this.cloudflared.cloudflareTunnelToken = res);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The storage currently in use
|
||||||
|
* @returns {Storage}
|
||||||
|
*/
|
||||||
storage() {
|
storage() {
|
||||||
return (this.remember) ? localStorage : sessionStorage;
|
return (this.remember) ? localStorage : sessionStorage;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get payload of JWT cookie
|
||||||
|
* @returns {(Object|undefined)}
|
||||||
|
*/
|
||||||
getJWTPayload() {
|
getJWTPayload() {
|
||||||
const jwtToken = this.$root.storage().token;
|
const jwtToken = this.$root.storage().token;
|
||||||
|
|
||||||
|
@ -271,10 +285,18 @@ export default {
|
||||||
return undefined;
|
return undefined;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get current socket
|
||||||
|
* @returns {Socket}
|
||||||
|
*/
|
||||||
getSocket() {
|
getSocket() {
|
||||||
return socket;
|
return socket;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show success or error toast dependant on response status code
|
||||||
|
* @param {Object} res Response object
|
||||||
|
*/
|
||||||
toastRes(res) {
|
toastRes(res) {
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
toast.success(res.msg);
|
toast.success(res.msg);
|
||||||
|
@ -283,14 +305,35 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a success toast
|
||||||
|
* @param {string} msg Message to show
|
||||||
|
*/
|
||||||
toastSuccess(msg) {
|
toastSuccess(msg) {
|
||||||
toast.success(msg);
|
toast.success(msg);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show an error toast
|
||||||
|
* @param {string} msg Message to show
|
||||||
|
*/
|
||||||
toastError(msg) {
|
toastError(msg) {
|
||||||
toast.error(msg);
|
toast.error(msg);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for login
|
||||||
|
* @callback loginCB
|
||||||
|
* @param {Object} res Response object
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send request to log user in
|
||||||
|
* @param {string} username Username to log in with
|
||||||
|
* @param {string} password Password to log in with
|
||||||
|
* @param {string} token User token
|
||||||
|
* @param {loginCB} callback Callback to call with result
|
||||||
|
*/
|
||||||
login(username, password, token, callback) {
|
login(username, password, token, callback) {
|
||||||
socket.emit("login", {
|
socket.emit("login", {
|
||||||
username,
|
username,
|
||||||
|
@ -315,6 +358,10 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log in using a token
|
||||||
|
* @param {string} token Token to log in with
|
||||||
|
*/
|
||||||
loginByToken(token) {
|
loginByToken(token) {
|
||||||
socket.emit("loginByToken", token, (res) => {
|
socket.emit("loginByToken", token, (res) => {
|
||||||
this.allowLoginDialog = true;
|
this.allowLoginDialog = true;
|
||||||
|
@ -328,6 +375,7 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Log out of the web application */
|
||||||
logout() {
|
logout() {
|
||||||
socket.emit("logout", () => { });
|
socket.emit("logout", () => { });
|
||||||
this.storage().removeItem("token");
|
this.storage().removeItem("token");
|
||||||
|
@ -337,26 +385,54 @@ export default {
|
||||||
this.clearData();
|
this.clearData();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for general socket requests
|
||||||
|
* @callback socketCB
|
||||||
|
* @param {Object} res Result of operation
|
||||||
|
*/
|
||||||
|
/** Prepare 2FA configuration */
|
||||||
prepare2FA(callback) {
|
prepare2FA(callback) {
|
||||||
socket.emit("prepare2FA", callback);
|
socket.emit("prepare2FA", callback);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the current 2FA configuration
|
||||||
|
* @param {any} secret Unused
|
||||||
|
* @param {socketCB} callback
|
||||||
|
*/
|
||||||
save2FA(secret, callback) {
|
save2FA(secret, callback) {
|
||||||
socket.emit("save2FA", callback);
|
socket.emit("save2FA", callback);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable 2FA for this user
|
||||||
|
* @param {socketCB} callback
|
||||||
|
*/
|
||||||
disable2FA(callback) {
|
disable2FA(callback) {
|
||||||
socket.emit("disable2FA", callback);
|
socket.emit("disable2FA", callback);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify the provided 2FA token
|
||||||
|
* @param {string} token Token to verify
|
||||||
|
* @param {socketCB} callback
|
||||||
|
*/
|
||||||
verifyToken(token, callback) {
|
verifyToken(token, callback) {
|
||||||
socket.emit("verifyToken", token, callback);
|
socket.emit("verifyToken", token, callback);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get current 2FA status
|
||||||
|
* @param {socketCB} callback
|
||||||
|
*/
|
||||||
twoFAStatus(callback) {
|
twoFAStatus(callback) {
|
||||||
socket.emit("twoFAStatus", callback);
|
socket.emit("twoFAStatus", callback);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get list of monitors
|
||||||
|
* @param {socketCB} callback
|
||||||
|
*/
|
||||||
getMonitorList(callback) {
|
getMonitorList(callback) {
|
||||||
if (! callback) {
|
if (! callback) {
|
||||||
callback = () => { };
|
callback = () => { };
|
||||||
|
@ -364,36 +440,74 @@ export default {
|
||||||
socket.emit("getMonitorList", callback);
|
socket.emit("getMonitorList", callback);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a monitor
|
||||||
|
* @param {Object} monitor Object representing monitor to add
|
||||||
|
* @param {socketCB} callback
|
||||||
|
*/
|
||||||
add(monitor, callback) {
|
add(monitor, callback) {
|
||||||
socket.emit("add", monitor, callback);
|
socket.emit("add", monitor, callback);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete monitor by ID
|
||||||
|
* @param {number} monitorID ID of monitor to delete
|
||||||
|
* @param {socketCB} callback
|
||||||
|
*/
|
||||||
deleteMonitor(monitorID, callback) {
|
deleteMonitor(monitorID, callback) {
|
||||||
socket.emit("deleteMonitor", monitorID, callback);
|
socket.emit("deleteMonitor", monitorID, callback);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Clear the hearbeat list */
|
||||||
clearData() {
|
clearData() {
|
||||||
console.log("reset heartbeat list");
|
console.log("reset heartbeat list");
|
||||||
this.heartbeatList = {};
|
this.heartbeatList = {};
|
||||||
this.importantHeartbeatList = {};
|
this.importantHeartbeatList = {};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upload the provided backup
|
||||||
|
* @param {string} uploadedJSON JSON to upload
|
||||||
|
* @param {string} importHandle Type of import. If set to
|
||||||
|
* most data in database will be replaced
|
||||||
|
* @param {socketCB} callback
|
||||||
|
*/
|
||||||
uploadBackup(uploadedJSON, importHandle, callback) {
|
uploadBackup(uploadedJSON, importHandle, callback) {
|
||||||
socket.emit("uploadBackup", uploadedJSON, importHandle, callback);
|
socket.emit("uploadBackup", uploadedJSON, importHandle, callback);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear events for a specified monitor
|
||||||
|
* @param {number} monitorID ID of monitor to clear
|
||||||
|
* @param {socketCB} callback
|
||||||
|
*/
|
||||||
clearEvents(monitorID, callback) {
|
clearEvents(monitorID, callback) {
|
||||||
socket.emit("clearEvents", monitorID, callback);
|
socket.emit("clearEvents", monitorID, callback);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the heartbeats of a specified monitor
|
||||||
|
* @param {number} monitorID Id of monitor to clear
|
||||||
|
* @param {socketCB} callback
|
||||||
|
*/
|
||||||
clearHeartbeats(monitorID, callback) {
|
clearHeartbeats(monitorID, callback) {
|
||||||
socket.emit("clearHeartbeats", monitorID, callback);
|
socket.emit("clearHeartbeats", monitorID, callback);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all statistics
|
||||||
|
* @param {socketCB} callback
|
||||||
|
*/
|
||||||
clearStatistics(callback) {
|
clearStatistics(callback) {
|
||||||
socket.emit("clearStatistics", callback);
|
socket.emit("clearStatistics", callback);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get monitor beats for a specific monitor in a time range
|
||||||
|
* @param {number} monitorID ID of monitor to fetch
|
||||||
|
* @param {number} period Time in hours from now
|
||||||
|
* @param {socketCB} callback
|
||||||
|
*/
|
||||||
getMonitorBeats(monitorID, period, callback) {
|
getMonitorBeats(monitorID, period, callback) {
|
||||||
socket.emit("getMonitorBeats", monitorID, period, callback);
|
socket.emit("getMonitorBeats", monitorID, period, callback);
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,6 +75,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
/** Update the theme color meta tag */
|
||||||
updateThemeColorMeta() {
|
updateThemeColorMeta() {
|
||||||
if (this.theme === "dark") {
|
if (this.theme === "dark") {
|
||||||
document.querySelector("#theme-color").setAttribute("content", "#161B22");
|
document.querySelector("#theme-color").setAttribute("content", "#161B22");
|
||||||
|
|
|
@ -51,6 +51,7 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
/** Submit form data to add new status page */
|
||||||
async submit() {
|
async submit() {
|
||||||
this.processing = true;
|
this.processing = true;
|
||||||
|
|
||||||
|
|
|
@ -289,39 +289,47 @@ export default {
|
||||||
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
/** Request a test notification be sent for this monitor */
|
||||||
testNotification() {
|
testNotification() {
|
||||||
this.$root.getSocket().emit("testNotification", this.monitor.id);
|
this.$root.getSocket().emit("testNotification", this.monitor.id);
|
||||||
toast.success("Test notification is requested.");
|
toast.success("Test notification is requested.");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Show dialog to confirm pause */
|
||||||
pauseDialog() {
|
pauseDialog() {
|
||||||
this.$refs.confirmPause.show();
|
this.$refs.confirmPause.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Resume this monitor */
|
||||||
resumeMonitor() {
|
resumeMonitor() {
|
||||||
this.$root.getSocket().emit("resumeMonitor", this.monitor.id, (res) => {
|
this.$root.getSocket().emit("resumeMonitor", this.monitor.id, (res) => {
|
||||||
this.$root.toastRes(res);
|
this.$root.toastRes(res);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Request that this monitor is paused */
|
||||||
pauseMonitor() {
|
pauseMonitor() {
|
||||||
this.$root.getSocket().emit("pauseMonitor", this.monitor.id, (res) => {
|
this.$root.getSocket().emit("pauseMonitor", this.monitor.id, (res) => {
|
||||||
this.$root.toastRes(res);
|
this.$root.toastRes(res);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Show dialog to confirm deletion */
|
||||||
deleteDialog() {
|
deleteDialog() {
|
||||||
this.$refs.confirmDelete.show();
|
this.$refs.confirmDelete.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Show dialog to confirm clearing events */
|
||||||
clearEventsDialog() {
|
clearEventsDialog() {
|
||||||
this.$refs.confirmClearEvents.show();
|
this.$refs.confirmClearEvents.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Show dialog to confirm clearing heartbeats */
|
||||||
clearHeartbeatsDialog() {
|
clearHeartbeatsDialog() {
|
||||||
this.$refs.confirmClearHeartbeats.show();
|
this.$refs.confirmClearHeartbeats.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Request that this monitor is deleted */
|
||||||
deleteMonitor() {
|
deleteMonitor() {
|
||||||
this.$root.deleteMonitor(this.monitor.id, (res) => {
|
this.$root.deleteMonitor(this.monitor.id, (res) => {
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
|
@ -333,6 +341,7 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Request that this monitors events are cleared */
|
||||||
clearEvents() {
|
clearEvents() {
|
||||||
this.$root.clearEvents(this.monitor.id, (res) => {
|
this.$root.clearEvents(this.monitor.id, (res) => {
|
||||||
if (! res.ok) {
|
if (! res.ok) {
|
||||||
|
@ -341,6 +350,7 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Request that this monitors heartbeats are cleared */
|
||||||
clearHeartbeats() {
|
clearHeartbeats() {
|
||||||
this.$root.clearHeartbeats(this.monitor.id, (res) => {
|
this.$root.clearHeartbeats(this.monitor.id, (res) => {
|
||||||
if (! res.ok) {
|
if (! res.ok) {
|
||||||
|
@ -349,6 +359,11 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the correct title for the ping stat
|
||||||
|
* @param {boolean} [average=false] Is the statistic an average?
|
||||||
|
* @returns {string} Title formated dependant on monitor type
|
||||||
|
*/
|
||||||
pingTitle(average = false) {
|
pingTitle(average = false) {
|
||||||
let translationPrefix = "";
|
let translationPrefix = "";
|
||||||
if (average) {
|
if (average) {
|
||||||
|
|
|
@ -573,6 +573,7 @@ export default {
|
||||||
this.dnsresolvetypeOptions = dnsresolvetypeOptions;
|
this.dnsresolvetypeOptions = dnsresolvetypeOptions;
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
/** Initialize the edit monitor form */
|
||||||
init() {
|
init() {
|
||||||
if (this.isAdd) {
|
if (this.isAdd) {
|
||||||
|
|
||||||
|
@ -631,6 +632,10 @@ export default {
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate form input
|
||||||
|
* @returns {boolean} Is the form input valid?
|
||||||
|
*/
|
||||||
isInputValid() {
|
isInputValid() {
|
||||||
if (this.monitor.body) {
|
if (this.monitor.body) {
|
||||||
try {
|
try {
|
||||||
|
@ -651,6 +656,10 @@ export default {
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Submit the form data for processing
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
async submit() {
|
async submit() {
|
||||||
this.processing = true;
|
this.processing = true;
|
||||||
|
|
||||||
|
@ -695,14 +704,20 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Added a Notification Event
|
/**
|
||||||
// Enable it if the notification is added in EditMonitor.vue
|
* Added a Notification Event
|
||||||
|
* Enable it if the notification is added in EditMonitor.vue
|
||||||
|
* @param {number} id ID of notification to add
|
||||||
|
*/
|
||||||
addedNotification(id) {
|
addedNotification(id) {
|
||||||
this.monitor.notificationIDList[id] = true;
|
this.monitor.notificationIDList[id] = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
// Added a Proxy Event
|
/**
|
||||||
// Enable it if the proxy is added in EditMonitor.vue
|
* Added a Proxy Event
|
||||||
|
* Enable it if the proxy is added in EditMonitor.vue
|
||||||
|
* @param {number} id ID of proxy to add
|
||||||
|
*/
|
||||||
addedProxy(id) {
|
addedProxy(id) {
|
||||||
this.monitor.proxyId = id;
|
this.monitor.proxyId = id;
|
||||||
},
|
},
|
||||||
|
|
|
@ -51,6 +51,11 @@ export default {
|
||||||
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
/**
|
||||||
|
* Get the correct URL for the icon
|
||||||
|
* @param {string} icon Path for icon
|
||||||
|
* @returns {string} Correctly formatted path including port numbers
|
||||||
|
*/
|
||||||
icon(icon) {
|
icon(icon) {
|
||||||
if (icon === "/icon.svg") {
|
if (icon === "/icon.svg") {
|
||||||
return icon;
|
return icon;
|
||||||
|
|
|
@ -45,6 +45,7 @@ export default {
|
||||||
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
/** Go back 1 in browser history */
|
||||||
goBack() {
|
goBack() {
|
||||||
history.back();
|
history.back();
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,13 +118,17 @@ export default {
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
|
||||||
// For desktop only, mobile do nothing
|
/**
|
||||||
|
* Load the general settings page
|
||||||
|
* For desktop only, on mobile do nothing
|
||||||
|
*/
|
||||||
loadGeneralPage() {
|
loadGeneralPage() {
|
||||||
if (!this.currentPage && !this.$root.isMobile) {
|
if (!this.currentPage && !this.$root.isMobile) {
|
||||||
this.$router.push("/settings/general");
|
this.$router.push("/settings/general");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Load settings from server */
|
||||||
loadSettings() {
|
loadSettings() {
|
||||||
this.$root.getSocket().emit("getSettings", (res) => {
|
this.$root.getSocket().emit("getSettings", (res) => {
|
||||||
this.settings = res.data;
|
this.settings = res.data;
|
||||||
|
@ -153,9 +157,16 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for saving settings
|
||||||
|
* @callback saveSettingsCB
|
||||||
|
* @param {Object} res Result of operation
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save Settings
|
* Save Settings
|
||||||
* @param currentPassword (Optional) Only need for disableAuth to true
|
* @param {saveSettingsCB} [callback]
|
||||||
|
* @param {string} [currentPassword] Only need for disableAuth to true
|
||||||
*/
|
*/
|
||||||
saveSettings(callback, currentPassword) {
|
saveSettings(callback, currentPassword) {
|
||||||
this.$root.getSocket().emit("setSettings", this.settings, currentPassword, (res) => {
|
this.$root.getSocket().emit("setSettings", this.settings, currentPassword, (res) => {
|
||||||
|
|
|
@ -71,6 +71,10 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
/**
|
||||||
|
* Submit form data for processing
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
submit() {
|
submit() {
|
||||||
this.processing = true;
|
this.processing = true;
|
||||||
|
|
||||||
|
|
|
@ -332,6 +332,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
|
/** Override for the status page slug */
|
||||||
overrideSlug: {
|
overrideSlug: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
|
@ -587,10 +588,16 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide syntax highlighting for CSS
|
||||||
|
* @param {string} code Text to highlight
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
highlighter(code) {
|
highlighter(code) {
|
||||||
return highlight(code, languages.css);
|
return highlight(code, languages.css);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Update the heartbeat list and update favicon if neccessary */
|
||||||
updateHeartbeatList() {
|
updateHeartbeatList() {
|
||||||
// If editMode, it will use the data from websocket.
|
// If editMode, it will use the data from websocket.
|
||||||
if (! this.editMode) {
|
if (! this.editMode) {
|
||||||
|
@ -619,6 +626,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Enable editing mode */
|
||||||
edit() {
|
edit() {
|
||||||
if (this.hasToken) {
|
if (this.hasToken) {
|
||||||
this.$root.initSocketIO(true);
|
this.$root.initSocketIO(true);
|
||||||
|
@ -630,6 +638,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Save the status page */
|
||||||
save() {
|
save() {
|
||||||
let startTime = new Date();
|
let startTime = new Date();
|
||||||
this.config.slug = this.config.slug.trim().toLowerCase();
|
this.config.slug = this.config.slug.trim().toLowerCase();
|
||||||
|
@ -657,10 +666,12 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Show dialog confirming deletion */
|
||||||
deleteDialog() {
|
deleteDialog() {
|
||||||
this.$refs.confirmDelete.show();
|
this.$refs.confirmDelete.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Request deletion of this status page */
|
||||||
deleteStatusPage() {
|
deleteStatusPage() {
|
||||||
this.$root.getSocket().emit("deleteStatusPage", this.slug, (res) => {
|
this.$root.getSocket().emit("deleteStatusPage", this.slug, (res) => {
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
|
@ -672,10 +683,16 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns label for a specifed monitor
|
||||||
|
* @param {Object} monitor Object representing monitor
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
monitorSelectorLabel(monitor) {
|
monitorSelectorLabel(monitor) {
|
||||||
return `${monitor.name}`;
|
return `${monitor.name}`;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Add a group to the status page */
|
||||||
addGroup() {
|
addGroup() {
|
||||||
let groupName = this.$t("Untitled Group");
|
let groupName = this.$t("Untitled Group");
|
||||||
|
|
||||||
|
@ -689,27 +706,32 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Add a domain to the status page */
|
||||||
addDomainField() {
|
addDomainField() {
|
||||||
this.config.domainNameList.push("");
|
this.config.domainNameList.push("");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Discard changes to status page */
|
||||||
discard() {
|
discard() {
|
||||||
location.href = "/status/" + this.slug;
|
location.href = "/status/" + this.slug;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Crop Success
|
* Set URL of new image after successful crop operation
|
||||||
|
* @param {string} imgDataUrl URL of image in data:// format
|
||||||
*/
|
*/
|
||||||
cropSuccess(imgDataUrl) {
|
cropSuccess(imgDataUrl) {
|
||||||
this.imgDataUrl = imgDataUrl;
|
this.imgDataUrl = imgDataUrl;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Show image crop dialog if in edit mode */
|
||||||
showImageCropUploadMethod() {
|
showImageCropUploadMethod() {
|
||||||
if (this.editMode) {
|
if (this.editMode) {
|
||||||
this.showImageCropUpload = true;
|
this.showImageCropUpload = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Create an incident for this status page */
|
||||||
createIncident() {
|
createIncident() {
|
||||||
this.enableEditIncidentMode = true;
|
this.enableEditIncidentMode = true;
|
||||||
|
|
||||||
|
@ -724,6 +746,7 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Post the incident to the status page */
|
||||||
postIncident() {
|
postIncident() {
|
||||||
if (this.incident.title === "" || this.incident.content === "") {
|
if (this.incident.title === "" || this.incident.content === "") {
|
||||||
toast.error(this.$t("Please input title and content"));
|
toast.error(this.$t("Please input title and content"));
|
||||||
|
@ -743,14 +766,13 @@ export default {
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/** Click Edit Button */
|
||||||
* Click Edit Button
|
|
||||||
*/
|
|
||||||
editIncident() {
|
editIncident() {
|
||||||
this.enableEditIncidentMode = true;
|
this.enableEditIncidentMode = true;
|
||||||
this.previousIncident = Object.assign({}, this.incident);
|
this.previousIncident = Object.assign({}, this.incident);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Cancel creation or editing of incident */
|
||||||
cancelIncident() {
|
cancelIncident() {
|
||||||
this.enableEditIncidentMode = false;
|
this.enableEditIncidentMode = false;
|
||||||
|
|
||||||
|
@ -760,16 +782,25 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Unpin the incident */
|
||||||
unpinIncident() {
|
unpinIncident() {
|
||||||
this.$root.getSocket().emit("unpinIncident", this.slug, () => {
|
this.$root.getSocket().emit("unpinIncident", this.slug, () => {
|
||||||
this.incident = null;
|
this.incident = null;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the relative time difference of a date from now
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
dateFromNow(date) {
|
dateFromNow(date) {
|
||||||
return dayjs.utc(date).fromNow();
|
return dayjs.utc(date).fromNow();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a domain from the status page
|
||||||
|
* @param {number} index Index of domain to remove
|
||||||
|
*/
|
||||||
removeDomain(index) {
|
removeDomain(index) {
|
||||||
this.config.domainNameList.splice(index, 1);
|
this.config.domainNameList.splice(index, 1);
|
||||||
},
|
},
|
||||||
|
|
|
@ -26,8 +26,8 @@ function getTimezoneOffset(timeZone) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of timezones sorted by their offset from UTC.
|
* Returns a list of timezones sorted by their offset from UTC.
|
||||||
* @param {Array} timezones - An array of timezone objects.
|
* @param {Object[]} timezones An array of timezone objects.
|
||||||
* @returns {Array} A list of the given timezones sorted by their offset from UTC.
|
* @returns {Object[]} A list of the given timezones sorted by their offset from UTC.
|
||||||
*
|
*
|
||||||
* Generated by Trelent
|
* Generated by Trelent
|
||||||
*/
|
*/
|
||||||
|
@ -63,6 +63,7 @@ export function timezoneList() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Set the locale of the HTML page */
|
||||||
export function setPageLocale() {
|
export function setPageLocale() {
|
||||||
const html = document.documentElement;
|
const html = document.documentElement;
|
||||||
html.setAttribute("lang", currentLocale() );
|
html.setAttribute("lang", currentLocale() );
|
||||||
|
@ -70,7 +71,9 @@ export function setPageLocale() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Get the base URL
|
||||||
* Mainly used for dev, because the backend and the frontend are in different ports.
|
* Mainly used for dev, because the backend and the frontend are in different ports.
|
||||||
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
export function getResBaseURL() {
|
export function getResBaseURL() {
|
||||||
const env = process.env.NODE_ENV;
|
const env = process.env.NODE_ENV;
|
||||||
|
|
60
src/util.js
60
src/util.js
|
@ -18,6 +18,7 @@ exports.PENDING = 2;
|
||||||
exports.STATUS_PAGE_ALL_DOWN = 0;
|
exports.STATUS_PAGE_ALL_DOWN = 0;
|
||||||
exports.STATUS_PAGE_ALL_UP = 1;
|
exports.STATUS_PAGE_ALL_UP = 1;
|
||||||
exports.STATUS_PAGE_PARTIAL_DOWN = 2;
|
exports.STATUS_PAGE_PARTIAL_DOWN = 2;
|
||||||
|
/** Flip the status of s */
|
||||||
function flipStatus(s) {
|
function flipStatus(s) {
|
||||||
if (s === exports.UP) {
|
if (s === exports.UP) {
|
||||||
return exports.DOWN;
|
return exports.DOWN;
|
||||||
|
@ -28,6 +29,10 @@ function flipStatus(s) {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
exports.flipStatus = flipStatus;
|
exports.flipStatus = flipStatus;
|
||||||
|
/**
|
||||||
|
* Delays for specified number of seconds
|
||||||
|
* @param ms Number of milliseconds to sleep for
|
||||||
|
*/
|
||||||
function sleep(ms) {
|
function sleep(ms) {
|
||||||
return new Promise(resolve => setTimeout(resolve, ms));
|
return new Promise(resolve => setTimeout(resolve, ms));
|
||||||
}
|
}
|
||||||
|
@ -83,6 +88,12 @@ class Logger {
|
||||||
this.debug("server", this.hideLog);
|
this.debug("server", this.hideLog);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Write a message to the log
|
||||||
|
* @param module The module the log comes from
|
||||||
|
* @param msg Message to write
|
||||||
|
* @param level Log level. One of INFO, WARN, ERROR, DEBUG or can be customized.
|
||||||
|
*/
|
||||||
log(module, msg, level) {
|
log(module, msg, level) {
|
||||||
if (this.hideLog[level] && this.hideLog[level].includes(module)) {
|
if (this.hideLog[level] && this.hideLog[level].includes(module)) {
|
||||||
return;
|
return;
|
||||||
|
@ -109,18 +120,44 @@ class Logger {
|
||||||
console.log(formattedMessage);
|
console.log(formattedMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Log an INFO message
|
||||||
|
* @param module Module log comes from
|
||||||
|
* @param msg Message to write
|
||||||
|
*/
|
||||||
info(module, msg) {
|
info(module, msg) {
|
||||||
this.log(module, msg, "info");
|
this.log(module, msg, "info");
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Log a WARN message
|
||||||
|
* @param module Module log comes from
|
||||||
|
* @param msg Message to write
|
||||||
|
*/
|
||||||
warn(module, msg) {
|
warn(module, msg) {
|
||||||
this.log(module, msg, "warn");
|
this.log(module, msg, "warn");
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Log an ERROR message
|
||||||
|
* @param module Module log comes from
|
||||||
|
* @param msg Message to write
|
||||||
|
*/
|
||||||
error(module, msg) {
|
error(module, msg) {
|
||||||
this.log(module, msg, "error");
|
this.log(module, msg, "error");
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Log a DEBUG message
|
||||||
|
* @param module Module log comes from
|
||||||
|
* @param msg Message to write
|
||||||
|
*/
|
||||||
debug(module, msg) {
|
debug(module, msg) {
|
||||||
this.log(module, msg, "debug");
|
this.log(module, msg, "debug");
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Log an exeption as an ERROR
|
||||||
|
* @param module Module log comes from
|
||||||
|
* @param exception The exeption to include
|
||||||
|
* @param msg The message to write
|
||||||
|
*/
|
||||||
exception(module, exception, msg) {
|
exception(module, exception, msg) {
|
||||||
let finalMessage = exception;
|
let finalMessage = exception;
|
||||||
if (msg) {
|
if (msg) {
|
||||||
|
@ -130,13 +167,13 @@ class Logger {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.log = new Logger();
|
exports.log = new Logger();
|
||||||
function polyfill() {
|
|
||||||
/**
|
/**
|
||||||
* String.prototype.replaceAll() polyfill
|
* String.prototype.replaceAll() polyfill
|
||||||
* https://gomakethings.com/how-to-replace-a-section-of-a-string-with-another-one-with-vanilla-js/
|
* https://gomakethings.com/how-to-replace-a-section-of-a-string-with-another-one-with-vanilla-js/
|
||||||
* @author Chris Ferdinandi
|
* @author Chris Ferdinandi
|
||||||
* @license MIT
|
* @license MIT
|
||||||
*/
|
*/
|
||||||
|
function polyfill() {
|
||||||
if (!String.prototype.replaceAll) {
|
if (!String.prototype.replaceAll) {
|
||||||
String.prototype.replaceAll = function (str, newStr) {
|
String.prototype.replaceAll = function (str, newStr) {
|
||||||
// If a regex pattern
|
// If a regex pattern
|
||||||
|
@ -153,6 +190,10 @@ class TimeLogger {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.startTime = dayjs().valueOf();
|
this.startTime = dayjs().valueOf();
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Output time since start of monitor
|
||||||
|
* @param name Name of monitor
|
||||||
|
*/
|
||||||
print(name) {
|
print(name) {
|
||||||
if (exports.isDev && process.env.TIMELOGGER === "1") {
|
if (exports.isDev && process.env.TIMELOGGER === "1") {
|
||||||
console.log(name + ": " + (dayjs().valueOf() - this.startTime) + "ms");
|
console.log(name + ": " + (dayjs().valueOf() - this.startTime) + "ms");
|
||||||
|
@ -201,6 +242,13 @@ let getRandomBytes = ((typeof window !== 'undefined' && window.crypto)
|
||||||
: function () {
|
: function () {
|
||||||
return require("crypto").randomBytes;
|
return require("crypto").randomBytes;
|
||||||
})();
|
})();
|
||||||
|
/**
|
||||||
|
* Get a random integer suitable for use in cryptography between upper
|
||||||
|
* and lower bounds.
|
||||||
|
* @param min Minimum value of integer
|
||||||
|
* @param max Maximum value of integer
|
||||||
|
* @returns Cryptographically suitable random integer
|
||||||
|
*/
|
||||||
function getCryptoRandomInt(min, max) {
|
function getCryptoRandomInt(min, max) {
|
||||||
// synchronous version of: https://github.com/joepie91/node-random-number-csprng
|
// synchronous version of: https://github.com/joepie91/node-random-number-csprng
|
||||||
const range = max - min;
|
const range = max - min;
|
||||||
|
@ -231,6 +279,11 @@ function getCryptoRandomInt(min, max) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.getCryptoRandomInt = getCryptoRandomInt;
|
exports.getCryptoRandomInt = getCryptoRandomInt;
|
||||||
|
/**
|
||||||
|
* Generate a secret
|
||||||
|
* @param length Lenght of secret to generate
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
function genSecret(length = 64) {
|
function genSecret(length = 64) {
|
||||||
let secret = "";
|
let secret = "";
|
||||||
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
|
@ -241,6 +294,11 @@ function genSecret(length = 64) {
|
||||||
return secret;
|
return secret;
|
||||||
}
|
}
|
||||||
exports.genSecret = genSecret;
|
exports.genSecret = genSecret;
|
||||||
|
/**
|
||||||
|
* Get the path of a monitor
|
||||||
|
* @param id ID of monitor
|
||||||
|
* @returns Formatted relative path
|
||||||
|
*/
|
||||||
function getMonitorRelativeURL(id) {
|
function getMonitorRelativeURL(id) {
|
||||||
return "/dashboard/" + id;
|
return "/dashboard/" + id;
|
||||||
}
|
}
|
||||||
|
|
62
src/util.ts
62
src/util.ts
|
@ -19,7 +19,7 @@ export const STATUS_PAGE_ALL_DOWN = 0;
|
||||||
export const STATUS_PAGE_ALL_UP = 1;
|
export const STATUS_PAGE_ALL_UP = 1;
|
||||||
export const STATUS_PAGE_PARTIAL_DOWN = 2;
|
export const STATUS_PAGE_PARTIAL_DOWN = 2;
|
||||||
|
|
||||||
|
/** Flip the status of s */
|
||||||
export function flipStatus(s: number) {
|
export function flipStatus(s: number) {
|
||||||
if (s === UP) {
|
if (s === UP) {
|
||||||
return DOWN;
|
return DOWN;
|
||||||
|
@ -32,6 +32,10 @@ export function flipStatus(s: number) {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delays for specified number of seconds
|
||||||
|
* @param ms Number of milliseconds to sleep for
|
||||||
|
*/
|
||||||
export function sleep(ms: number) {
|
export function sleep(ms: number) {
|
||||||
return new Promise(resolve => setTimeout(resolve, ms));
|
return new Promise(resolve => setTimeout(resolve, ms));
|
||||||
}
|
}
|
||||||
|
@ -94,6 +98,12 @@ class Logger {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a message to the log
|
||||||
|
* @param module The module the log comes from
|
||||||
|
* @param msg Message to write
|
||||||
|
* @param level Log level. One of INFO, WARN, ERROR, DEBUG or can be customized.
|
||||||
|
*/
|
||||||
log(module: string, msg: any, level: string) {
|
log(module: string, msg: any, level: string) {
|
||||||
if (this.hideLog[level] && this.hideLog[level].includes(module)) {
|
if (this.hideLog[level] && this.hideLog[level].includes(module)) {
|
||||||
return;
|
return;
|
||||||
|
@ -120,22 +130,48 @@ class Logger {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log an INFO message
|
||||||
|
* @param module Module log comes from
|
||||||
|
* @param msg Message to write
|
||||||
|
*/
|
||||||
info(module: string, msg: any) {
|
info(module: string, msg: any) {
|
||||||
this.log(module, msg, "info");
|
this.log(module, msg, "info");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a WARN message
|
||||||
|
* @param module Module log comes from
|
||||||
|
* @param msg Message to write
|
||||||
|
*/
|
||||||
warn(module: string, msg: any) {
|
warn(module: string, msg: any) {
|
||||||
this.log(module, msg, "warn");
|
this.log(module, msg, "warn");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log an ERROR message
|
||||||
|
* @param module Module log comes from
|
||||||
|
* @param msg Message to write
|
||||||
|
*/
|
||||||
error(module: string, msg: any) {
|
error(module: string, msg: any) {
|
||||||
this.log(module, msg, "error");
|
this.log(module, msg, "error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a DEBUG message
|
||||||
|
* @param module Module log comes from
|
||||||
|
* @param msg Message to write
|
||||||
|
*/
|
||||||
debug(module: string, msg: any) {
|
debug(module: string, msg: any) {
|
||||||
this.log(module, msg, "debug");
|
this.log(module, msg, "debug");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log an exeption as an ERROR
|
||||||
|
* @param module Module log comes from
|
||||||
|
* @param exception The exeption to include
|
||||||
|
* @param msg The message to write
|
||||||
|
*/
|
||||||
exception(module: string, exception: any, msg: any) {
|
exception(module: string, exception: any, msg: any) {
|
||||||
let finalMessage = exception
|
let finalMessage = exception
|
||||||
|
|
||||||
|
@ -151,13 +187,13 @@ export const log = new Logger();
|
||||||
|
|
||||||
declare global { interface String { replaceAll(str: string, newStr: string): string; } }
|
declare global { interface String { replaceAll(str: string, newStr: string): string; } }
|
||||||
|
|
||||||
export function polyfill() {
|
|
||||||
/**
|
/**
|
||||||
* String.prototype.replaceAll() polyfill
|
* String.prototype.replaceAll() polyfill
|
||||||
* https://gomakethings.com/how-to-replace-a-section-of-a-string-with-another-one-with-vanilla-js/
|
* https://gomakethings.com/how-to-replace-a-section-of-a-string-with-another-one-with-vanilla-js/
|
||||||
* @author Chris Ferdinandi
|
* @author Chris Ferdinandi
|
||||||
* @license MIT
|
* @license MIT
|
||||||
*/
|
*/
|
||||||
|
export function polyfill() {
|
||||||
if (!String.prototype.replaceAll) {
|
if (!String.prototype.replaceAll) {
|
||||||
String.prototype.replaceAll = function (str: string, newStr: string) {
|
String.prototype.replaceAll = function (str: string, newStr: string) {
|
||||||
// If a regex pattern
|
// If a regex pattern
|
||||||
|
@ -177,7 +213,10 @@ export class TimeLogger {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.startTime = dayjs().valueOf();
|
this.startTime = dayjs().valueOf();
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Output time since start of monitor
|
||||||
|
* @param name Name of monitor
|
||||||
|
*/
|
||||||
print(name: string) {
|
print(name: string) {
|
||||||
if (isDev && process.env.TIMELOGGER === "1") {
|
if (isDev && process.env.TIMELOGGER === "1") {
|
||||||
console.log(name + ": " + (dayjs().valueOf() - this.startTime) + "ms")
|
console.log(name + ": " + (dayjs().valueOf() - this.startTime) + "ms")
|
||||||
|
@ -231,6 +270,13 @@ let getRandomBytes = (
|
||||||
}
|
}
|
||||||
)();
|
)();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a random integer suitable for use in cryptography between upper
|
||||||
|
* and lower bounds.
|
||||||
|
* @param min Minimum value of integer
|
||||||
|
* @param max Maximum value of integer
|
||||||
|
* @returns Cryptographically suitable random integer
|
||||||
|
*/
|
||||||
export function getCryptoRandomInt(min: number, max: number):number {
|
export function getCryptoRandomInt(min: number, max: number):number {
|
||||||
|
|
||||||
// synchronous version of: https://github.com/joepie91/node-random-number-csprng
|
// synchronous version of: https://github.com/joepie91/node-random-number-csprng
|
||||||
|
@ -267,6 +313,11 @@ export function getCryptoRandomInt(min: number, max: number):number {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a random alphanumeric string of fixed length
|
||||||
|
* @param length Length of string to generate
|
||||||
|
* @returns string
|
||||||
|
*/
|
||||||
export function genSecret(length = 64) {
|
export function genSecret(length = 64) {
|
||||||
let secret = "";
|
let secret = "";
|
||||||
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
|
@ -277,6 +328,11 @@ export function genSecret(length = 64) {
|
||||||
return secret;
|
return secret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the path of a monitor
|
||||||
|
* @param id ID of monitor
|
||||||
|
* @returns Formatted relative path
|
||||||
|
*/
|
||||||
export function getMonitorRelativeURL(id: string) {
|
export function getMonitorRelativeURL(id: string) {
|
||||||
return "/dashboard/" + id;
|
return "/dashboard/" + id;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue