uptime-kuma/src/pages/Details.vue

623 lines
22 KiB
Vue
Raw Normal View History

2021-06-25 09:55:49 -04:00
<template>
2021-08-19 14:37:59 -04:00
<transition name="slide-fade" appear>
<div v-if="monitor">
2023-01-28 08:53:40 -05:00
<router-link v-if="group !== ''" :to="monitorURL(monitor.parent)"> {{ group }}</router-link>
2021-08-19 14:37:59 -04:00
<h1> {{ monitor.name }}</h1>
<p v-if="monitor.description">{{ monitor.description }}</p>
<div class="tags">
<Tag v-for="tag in monitor.tags" :key="tag.id" :item="tag" :size="'sm'" />
</div>
2021-08-19 14:37:59 -04:00
<p class="url">
✨ feat: json-query monitor added (#3253) * ✨ feat: json-query monitor added Signed-off-by: Muhammed Hussein Karimi <info@karimi.dev> * 🐛 fix: import warning error Signed-off-by: Muhammed Hussein Karimi <info@karimi.dev> * 🐛 fix: br tag and remove comment Signed-off-by: Muhammed Hussein Karimi <info@karimi.dev> * 🐛 fix: supporting compare string with other types Signed-off-by: Muhammed Hussein Karimi <info@karimi.dev> * 🐛 fix: switch to a better lib for json query Signed-off-by: Muhammed Hussein Karimi <info@karimi.dev> * 🐛 fix: better description on json query and using `v-html` in jsonQueryDescription element to fix `a` tags Signed-off-by: Muhammed Hussein Karimi <info@karimi.dev> * 🐛 fix: result variable in error message Signed-off-by: Muhammed Hussein Karimi <info@karimi.dev> * 🐛 fix: typos in json query description Co-authored-by: Frank Elsinga <frank@elsinga.de> * 📝 docs: `HTTP(s) Json Query` added to monitor list in `README.md` Signed-off-by: Muhammed Hussein Karimi <info@karimi.dev> * 🐛 fix: needed white space in `README.md` Co-authored-by: Frank Elsinga <frank@elsinga.de> * Nostr dm notifications (#3051) * Add nostr DM notification provider * require crypto for node 18 compatibility * remove whitespace Co-authored-by: Frank Elsinga <frank@elsinga.de> * move closer to where it is used * simplify success or failure logic * don't clobber the non-alert msg * Update server/notification-providers/nostr.js Co-authored-by: Frank Elsinga <frank@elsinga.de> * polyfills required for node <= 18 * resolve linter warnings * missing comma --------- Co-authored-by: Frank Elsinga <frank@elsinga.de> * Drop nostr * Rebuild package-lock.json * Lint --------- Signed-off-by: Muhammed Hussein Karimi <info@karimi.dev> Co-authored-by: Frank Elsinga <frank@elsinga.de> Co-authored-by: zappityzap <128872140+zappityzap@users.noreply.github.com> Co-authored-by: Louis Lam <louislam@users.noreply.github.com>
2023-07-13 11:37:26 -04:00
<a v-if="monitor.type === 'http' || monitor.type === 'keyword' || monitor.type === 'json-query' || monitor.type === 'mp-health' " :href="monitor.url" target="_blank" rel="noopener noreferrer">{{ filterPassword(monitor.url) }}</a>
2023-04-27 03:34:01 -04:00
<span v-if="monitor.type === 'port'">TCP Port {{ monitor.hostname }}:{{ monitor.port }}</span>
2021-08-19 14:37:59 -04:00
<span v-if="monitor.type === 'ping'">Ping: {{ monitor.hostname }}</span>
<span v-if="monitor.type === 'keyword'">
<br>
2023-04-05 20:10:21 -04:00
<span>{{ $t("Keyword") }}: </span>
<span class="keyword">{{ monitor.keyword }}</span>
<span v-if="monitor.invertKeyword" alt="Inverted keyword" class="keyword-inverted"> </span>
2021-08-19 14:37:59 -04:00
</span>
✨ feat: json-query monitor added (#3253) * ✨ feat: json-query monitor added Signed-off-by: Muhammed Hussein Karimi <info@karimi.dev> * 🐛 fix: import warning error Signed-off-by: Muhammed Hussein Karimi <info@karimi.dev> * 🐛 fix: br tag and remove comment Signed-off-by: Muhammed Hussein Karimi <info@karimi.dev> * 🐛 fix: supporting compare string with other types Signed-off-by: Muhammed Hussein Karimi <info@karimi.dev> * 🐛 fix: switch to a better lib for json query Signed-off-by: Muhammed Hussein Karimi <info@karimi.dev> * 🐛 fix: better description on json query and using `v-html` in jsonQueryDescription element to fix `a` tags Signed-off-by: Muhammed Hussein Karimi <info@karimi.dev> * 🐛 fix: result variable in error message Signed-off-by: Muhammed Hussein Karimi <info@karimi.dev> * 🐛 fix: typos in json query description Co-authored-by: Frank Elsinga <frank@elsinga.de> * 📝 docs: `HTTP(s) Json Query` added to monitor list in `README.md` Signed-off-by: Muhammed Hussein Karimi <info@karimi.dev> * 🐛 fix: needed white space in `README.md` Co-authored-by: Frank Elsinga <frank@elsinga.de> * Nostr dm notifications (#3051) * Add nostr DM notification provider * require crypto for node 18 compatibility * remove whitespace Co-authored-by: Frank Elsinga <frank@elsinga.de> * move closer to where it is used * simplify success or failure logic * don't clobber the non-alert msg * Update server/notification-providers/nostr.js Co-authored-by: Frank Elsinga <frank@elsinga.de> * polyfills required for node <= 18 * resolve linter warnings * missing comma --------- Co-authored-by: Frank Elsinga <frank@elsinga.de> * Drop nostr * Rebuild package-lock.json * Lint --------- Signed-off-by: Muhammed Hussein Karimi <info@karimi.dev> Co-authored-by: Frank Elsinga <frank@elsinga.de> Co-authored-by: zappityzap <128872140+zappityzap@users.noreply.github.com> Co-authored-by: Louis Lam <louislam@users.noreply.github.com>
2023-07-13 11:37:26 -04:00
<span v-if="monitor.type === 'json-query'">
<br>
<span>{{ $t("Json Query") }}:</span> <span class="keyword">{{ monitor.jsonPath }}</span>
<br>
<span>{{ $t("Expected Value") }}:</span> <span class="keyword">{{ monitor.expectedValue }}</span>
</span>
2021-08-28 21:57:26 -04:00
<span v-if="monitor.type === 'dns'">[{{ monitor.dns_resolve_type }}] {{ monitor.hostname }}
<br>
<span>{{ $t("Last Result") }}:</span> <span class="keyword">{{ monitor.dns_last_result }}</span>
</span>
<span v-if="monitor.type === 'docker'">Docker container: {{ monitor.docker_container }}</span>
<span v-if="monitor.type === 'gamedig'">Gamedig - {{ monitor.game }}: {{ monitor.hostname }}:{{ monitor.port }}</span>
2023-04-18 15:20:35 -04:00
<span v-if="monitor.type === 'grpc-keyword'">gRPC - {{ filterPassword(monitor.grpcUrl) }}
<br>
<span>{{ $t("Keyword") }}:</span> <span class="keyword">{{ monitor.keyword }}</span>
</span>
2023-04-18 15:20:35 -04:00
<span v-if="monitor.type === 'mongodb'">{{ filterPassword(monitor.databaseConnectionString) }}</span>
<span v-if="monitor.type === 'mqtt'">MQTT: {{ monitor.hostname }}:{{ monitor.port }}/{{ monitor.mqttTopic }}</span>
2023-04-18 15:20:35 -04:00
<span v-if="monitor.type === 'mysql'">{{ filterPassword(monitor.databaseConnectionString) }}</span>
<span v-if="monitor.type === 'postgres'">{{ filterPassword(monitor.databaseConnectionString) }}</span>
<span v-if="monitor.type === 'push'">Push: <a :href="pushURL" target="_blank" rel="noopener noreferrer">{{ pushURL }}</a></span>
2023-04-18 15:20:35 -04:00
<span v-if="monitor.type === 'radius'">Radius: {{ filterPassword(monitor.hostname) }}</span>
<span v-if="monitor.type === 'redis'">{{ filterPassword(monitor.databaseConnectionString) }}</span>
<span v-if="monitor.type === 'sqlserver'">SQL Server: {{ filterPassword(monitor.databaseConnectionString) }}</span>
<span v-if="monitor.type === 'steam'">Steam Game Server: {{ monitor.hostname }}:{{ monitor.port }}</span>
2021-08-19 14:37:59 -04:00
</p>
2021-06-25 09:55:49 -04:00
2021-08-19 14:37:59 -04:00
<div class="functions">
2022-10-15 09:01:48 -04:00
<div class="btn-group" role="group">
<button v-if="monitor.active" class="btn btn-normal" @click="pauseDialog">
<font-awesome-icon icon="pause" /> {{ $t("Pause") }}
</button>
<button v-if="! monitor.active" class="btn btn-primary" :disabled="monitor.forceInactive" @click="resumeMonitor">
2022-10-15 09:01:48 -04:00
<font-awesome-icon icon="play" /> {{ $t("Resume") }}
</button>
<router-link :to=" '/edit/' + monitor.id " class="btn btn-normal">
<font-awesome-icon icon="edit" /> {{ $t("Edit") }}
</router-link>
<router-link :to=" '/clone/' + monitor.id " class="btn btn-normal">
<font-awesome-icon icon="clone" /> {{ $t("Clone") }}
</router-link>
2022-10-15 09:01:48 -04:00
<button class="btn btn-danger" @click="deleteDialog">
<font-awesome-icon icon="trash" /> {{ $t("Delete") }}
</button>
</div>
2021-06-25 09:55:49 -04:00
</div>
2021-08-19 14:37:59 -04:00
<div class="shadow-box">
<div class="row">
<div class="col-md-8">
<HeartbeatBar :monitor-id="monitor.id" />
<span class="word">{{ $t("checkEverySecond", [ monitor.interval ]) }}</span>
2021-08-19 14:37:59 -04:00
</div>
<div class="col-md-4 text-center">
2021-10-18 12:19:26 -04:00
<span class="badge rounded-pill" :class=" 'bg-' + status.color " style="font-size: 30px;">{{ status.text }}</span>
2021-08-19 14:37:59 -04:00
</div>
</div>
2021-06-30 09:04:58 -04:00
</div>
2021-07-26 10:53:07 -04:00
2023-06-27 03:54:33 -04:00
<!-- Stats -->
2021-08-19 14:37:59 -04:00
<div class="shadow-box big-padding text-center stats">
<div class="row">
<div v-if="monitor.type !== 'group'" class="col-12 col-sm col row d-flex align-items-center d-sm-block">
2023-04-11 09:16:45 -04:00
<h4 class="col-4 col-sm-12">{{ pingTitle() }}</h4>
<p class="col-4 col-sm-12 mb-0 mb-sm-2">({{ $t("Current") }})</p>
<span class="col-4 col-sm-12 num">
2021-08-19 14:37:59 -04:00
<a href="#" @click.prevent="showPingChartBox = !showPingChartBox">
<CountUp :value="ping" />
</a>
</span>
</div>
<div v-if="monitor.type !== 'group'" class="col-12 col-sm col row d-flex align-items-center d-sm-block">
2023-04-11 09:16:45 -04:00
<h4 class="col-4 col-sm-12">{{ pingTitle(true) }}</h4>
<p class="col-4 col-sm-12 mb-0 mb-sm-2">(24{{ $t("-hour") }})</p>
<span class="col-4 col-sm-12 num">
<CountUp :value="avgPing" />
</span>
2021-08-19 14:37:59 -04:00
</div>
2023-04-11 09:16:45 -04:00
<div class="col-12 col-sm col row d-flex align-items-center d-sm-block">
<h4 class="col-4 col-sm-12">{{ $t("Uptime") }}</h4>
<p class="col-4 col-sm-12 mb-0 mb-sm-2">(24{{ $t("-hour") }})</p>
<span class="col-4 col-sm-12 num">
<Uptime :monitor="monitor" type="24" />
</span>
2021-08-19 14:37:59 -04:00
</div>
2023-04-11 09:16:45 -04:00
<div class="col-12 col-sm col row d-flex align-items-center d-sm-block">
<h4 class="col-4 col-sm-12">{{ $t("Uptime") }}</h4>
<p class="col-4 col-sm-12 mb-0 mb-sm-2">(30{{ $t("-day") }})</p>
<span class="col-4 col-sm-12 num">
<Uptime :monitor="monitor" type="720" />
</span>
2021-08-19 14:37:59 -04:00
</div>
2023-04-11 09:16:45 -04:00
<div v-if="tlsInfo" class="col-12 col-sm col row d-flex align-items-center d-sm-block">
<h4 class="col-4 col-sm-12">{{ $t("Cert Exp.") }}</h4>
<p class="col-4 col-sm-12 mb-0 mb-sm-2">(<Datetime :value="tlsInfo.certInfo.validTo" date-only />)</p>
<span class="col-4 col-sm-12 num">
2022-05-30 05:53:32 -04:00
<a href="#" @click.prevent="toggleCertInfoBox = !toggleCertInfoBox">{{ tlsInfo.certInfo.daysRemaining }} {{ $tc("day", tlsInfo.certInfo.daysRemaining) }}</a>
2021-08-19 14:37:59 -04:00
</span>
</div>
</div>
2021-07-26 10:53:07 -04:00
</div>
2021-06-30 09:04:58 -04:00
<!-- Cert Info Box -->
2021-08-19 14:37:59 -04:00
<transition name="slide-fade" appear>
<div v-if="showCertInfoBox" class="shadow-box big-padding text-center">
<div class="row">
<div class="col">
2021-10-01 06:44:32 -04:00
<certificate-info :certInfo="tlsInfo.certInfo" :valid="tlsInfo.valid" />
2021-08-19 14:37:59 -04:00
</div>
</div>
</div>
</transition>
<!-- Ping Chart -->
2021-08-19 14:37:59 -04:00
<div v-if="showPingChartBox" class="shadow-box big-padding text-center ping-chart-wrapper">
<div class="row">
<div class="col">
<PingChart :monitor-id="monitor.id" />
</div>
</div>
2021-08-10 07:34:47 -04:00
</div>
2023-06-27 03:54:33 -04:00
<!-- Screenshot -->
<div v-if="monitor.type === 'real-browser'" class="shadow-box">
<div class="row">
<div class="col-md-6">
<img :src="screenshotURL" alt style="width: 100%;">
</div>
</div>
</div>
<div class="shadow-box table-shadow-box">
<div class="dropdown dropdown-clear-data">
<button class="btn btn-sm btn-outline-danger dropdown-toggle" type="button" data-bs-toggle="dropdown">
<font-awesome-icon icon="trash" /> {{ $t("Clear Data") }}
</button>
<ul class="dropdown-menu dropdown-menu-end">
<li>
<button type="button" class="dropdown-item" @click="clearEventsDialog">
{{ $t("Events") }}
</button>
</li>
<li>
<button type="button" class="dropdown-item" @click="clearHeartbeatsDialog">
{{ $t("Heartbeats") }}
</button>
</li>
</ul>
</div>
2021-08-19 14:37:59 -04:00
<table class="table table-borderless table-hover">
<thead>
<tr>
<th>{{ $t("Status") }}</th>
<th>{{ $t("DateTime") }}</th>
<th>{{ $t("Message") }}</th>
</tr>
2021-08-19 14:37:59 -04:00
</thead>
<tbody>
2023-04-11 09:16:45 -04:00
<tr v-for="(beat, index) in displayedRecords" :key="index" style="padding: 10px;">
2021-08-19 14:37:59 -04:00
<td><Status :status="beat.status" /></td>
2021-08-22 19:22:55 -04:00
<td :class="{ 'border-0':! beat.msg}"><Datetime :value="beat.time" /></td>
<td class="border-0">{{ beat.msg }}</td>
</tr>
2021-08-19 14:37:59 -04:00
<tr v-if="importantHeartBeatList.length === 0">
<td colspan="3">
{{ $t("No important events") }}
2021-07-27 13:47:13 -04:00
</td>
</tr>
</tbody>
</table>
2021-08-19 14:37:59 -04:00
<div class="d-flex justify-content-center kuma_pagination">
<pagination
v-model="page"
:records="importantHeartBeatList.length"
:per-page="perPage"
2021-09-26 11:20:12 -04:00
:options="paginationConfig"
2021-08-19 14:37:59 -04:00
/>
</div>
</div>
2021-06-30 09:04:58 -04:00
<Confirm ref="confirmPause" :yes-text="$t('Yes')" :no-text="$t('No')" @yes="pauseMonitor">
{{ $t("pauseMonitorMsg") }}
2021-08-19 14:37:59 -04:00
</Confirm>
2021-07-17 21:04:40 -04:00
2021-08-25 20:43:26 -04:00
<Confirm ref="confirmDelete" btn-style="btn-danger" :yes-text="$t('Yes')" :no-text="$t('No')" @yes="deleteMonitor">
{{ $t("deleteMonitorMsg") }}
2021-08-19 14:37:59 -04:00
</Confirm>
<Confirm ref="confirmClearEvents" btn-style="btn-danger" :yes-text="$t('Yes')" :no-text="$t('No')" @yes="clearEvents">
{{ $t("clearEventsMsg") }}
</Confirm>
<Confirm ref="confirmClearHeartbeats" btn-style="btn-danger" :yes-text="$t('Yes')" :no-text="$t('No')" @yes="clearHeartbeats">
{{ $t("clearHeartbeatsMsg") }}
</Confirm>
2021-07-17 21:04:40 -04:00
</div>
2021-08-19 14:37:59 -04:00
</transition>
2021-06-25 09:55:49 -04:00
</template>
<script>
2021-08-11 12:47:58 -04:00
import { defineAsyncComponent } from "vue";
2021-10-01 06:44:32 -04:00
import { useToast } from "vue-toastification";
const toast = useToast();
2021-06-25 09:55:49 -04:00
import Confirm from "../components/Confirm.vue";
2021-06-25 15:03:06 -04:00
import HeartbeatBar from "../components/HeartbeatBar.vue";
2021-06-30 09:04:58 -04:00
import Status from "../components/Status.vue";
import Datetime from "../components/Datetime.vue";
import CountUp from "../components/CountUp.vue";
2021-07-01 01:11:16 -04:00
import Uptime from "../components/Uptime.vue";
2021-07-17 21:04:40 -04:00
import Pagination from "v-pagination-3";
2021-08-11 12:47:58 -04:00
const PingChart = defineAsyncComponent(() => import("../components/PingChart.vue"));
import Tag from "../components/Tag.vue";
2021-10-01 06:44:32 -04:00
import CertificateInfo from "../components/CertificateInfo.vue";
2023-01-28 08:53:40 -05:00
import { getMonitorRelativeURL } from "../util.ts";
2023-04-18 15:20:35 -04:00
import { URL } from "whatwg-url";
2023-06-27 03:54:33 -04:00
import { getResBaseURL } from "../util-frontend";
2021-06-25 09:55:49 -04:00
export default {
components: {
2021-07-01 01:11:16 -04:00
Uptime,
2021-06-30 09:04:58 -04:00
CountUp,
Datetime,
2021-06-25 15:03:06 -04:00
HeartbeatBar,
2021-06-30 09:04:58 -04:00
Confirm,
Status,
2021-07-17 21:04:40 -04:00
Pagination,
2021-08-10 07:34:47 -04:00
PingChart,
Tag,
2021-10-01 06:44:32 -04:00
CertificateInfo,
2021-06-25 09:55:49 -04:00
},
data() {
return {
2021-07-17 21:04:40 -04:00
page: 1,
perPage: 25,
heartBeatList: [],
2021-07-26 10:53:07 -04:00
toggleCertInfoBox: false,
2021-08-11 08:59:33 -04:00
showPingChartBox: true,
2021-09-26 11:20:12 -04:00
paginationConfig: {
2021-10-29 07:37:38 -04:00
hideCount: true,
chunksNavigation: "scroll",
},
2023-06-27 03:54:33 -04:00
cacheTime: Date.now(),
2021-10-01 06:44:32 -04:00
};
2021-06-25 09:55:49 -04:00
},
computed: {
monitor() {
2021-10-01 06:44:32 -04:00
let id = this.$route.params.id;
2021-06-27 04:10:55 -04:00
return this.$root.monitorList[id];
},
2021-06-25 09:55:49 -04:00
2021-06-27 04:10:55 -04:00
lastHeartBeat() {
2023-06-27 03:54:33 -04:00
// Also trigger screenshot refresh here
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
this.cacheTime = Date.now();
2021-06-27 04:10:55 -04:00
if (this.monitor.id in this.$root.lastHeartbeatList && this.$root.lastHeartbeatList[this.monitor.id]) {
2021-10-01 06:44:32 -04:00
return this.$root.lastHeartbeatList[this.monitor.id];
2021-07-27 13:47:13 -04:00
}
return {
status: -1,
2021-10-01 06:44:32 -04:00
};
2021-06-25 09:55:49 -04:00
},
2021-06-27 04:10:55 -04:00
2021-06-30 09:04:58 -04:00
ping() {
2021-07-11 23:20:18 -04:00
if (this.lastHeartBeat.ping || this.lastHeartBeat.ping === 0) {
2021-06-30 09:04:58 -04:00
return this.lastHeartBeat.ping;
}
2021-07-27 13:47:13 -04:00
2021-10-01 06:44:32 -04:00
return this.$t("notAvailableShort");
2021-06-30 09:04:58 -04:00
},
avgPing() {
2021-07-11 23:20:18 -04:00
if (this.$root.avgPingList[this.monitor.id] || this.$root.avgPingList[this.monitor.id] === 0) {
2021-06-30 09:04:58 -04:00
return this.$root.avgPingList[this.monitor.id];
}
2021-07-27 13:47:13 -04:00
2021-10-01 06:44:32 -04:00
return this.$t("notAvailableShort");
2021-06-30 09:04:58 -04:00
},
importantHeartBeatList() {
if (this.$root.importantHeartbeatList[this.monitor.id]) {
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
2021-07-17 21:04:40 -04:00
this.heartBeatList = this.$root.importantHeartbeatList[this.monitor.id];
2021-10-01 06:44:32 -04:00
return this.$root.importantHeartbeatList[this.monitor.id];
2021-06-30 09:04:58 -04:00
}
2021-07-27 13:47:13 -04:00
return [];
2021-06-30 09:04:58 -04:00
},
2021-06-27 04:10:55 -04:00
status() {
if (this.$root.statusList[this.monitor.id]) {
2021-10-01 06:44:32 -04:00
return this.$root.statusList[this.monitor.id];
2021-06-27 04:10:55 -04:00
}
2021-07-27 13:47:13 -04:00
2021-10-01 06:44:32 -04:00
return { };
2021-07-17 21:04:40 -04:00
},
2021-06-27 04:10:55 -04:00
2021-10-01 06:44:32 -04:00
tlsInfo() {
// Add: this.$root.tlsInfoList[this.monitor.id].certInfo
// Fix: TypeError: Cannot read properties of undefined (reading 'validTo')
// Reason: TLS Info object format is changed in 1.8.0, if for some reason, it cannot connect to the site after update to 1.8.0, the object is still in the old format.
if (this.$root.tlsInfoList[this.monitor.id] && this.$root.tlsInfoList[this.monitor.id].certInfo) {
2021-10-01 06:44:32 -04:00
return this.$root.tlsInfoList[this.monitor.id];
}
2021-07-27 13:47:13 -04:00
2021-10-01 06:44:32 -04:00
return null;
},
2021-07-26 10:53:07 -04:00
showCertInfoBox() {
2021-10-01 06:44:32 -04:00
return this.tlsInfo != null && this.toggleCertInfoBox;
2021-07-26 10:53:07 -04:00
},
2021-07-17 21:04:40 -04:00
displayedRecords() {
const startIndex = this.perPage * (this.page - 1);
const endIndex = startIndex + this.perPage;
return this.heartBeatList.slice(startIndex, endIndex);
},
group() {
if (!this.monitor.pathName.includes("/")) {
return "";
}
return this.monitor.pathName.substr(0, this.monitor.pathName.lastIndexOf("/"));
2023-05-31 15:19:46 -04:00
},
pushURL() {
return this.$root.baseURL + "/api/push/" + this.monitor.pushToken + "?status=up&msg=OK&ping=";
},
2023-06-27 03:54:33 -04:00
screenshotURL() {
return getResBaseURL() + this.monitor.screenshot + "?time=" + this.cacheTime;
}
2021-07-27 13:47:13 -04:00
},
mounted() {
2021-06-25 09:55:49 -04:00
},
methods: {
2023-06-27 03:54:33 -04:00
getResBaseURL,
/** Request a test notification be sent for this monitor */
2021-06-30 09:04:58 -04:00
testNotification() {
2021-10-01 06:44:32 -04:00
this.$root.getSocket().emit("testNotification", this.monitor.id);
toast.success("Test notification is requested.");
2021-06-30 09:04:58 -04:00
},
/** Show dialog to confirm pause */
2021-06-25 09:55:49 -04:00
pauseDialog() {
this.$refs.confirmPause.show();
},
2021-06-30 09:04:58 -04:00
/** Resume this monitor */
2021-06-25 09:55:49 -04:00
resumeMonitor() {
this.$root.getSocket().emit("resumeMonitor", this.monitor.id, (res) => {
2021-10-01 06:44:32 -04:00
this.$root.toastRes(res);
});
2021-06-25 09:55:49 -04:00
},
2021-06-30 09:04:58 -04:00
/** Request that this monitor is paused */
2021-06-25 09:55:49 -04:00
pauseMonitor() {
this.$root.getSocket().emit("pauseMonitor", this.monitor.id, (res) => {
2021-10-01 06:44:32 -04:00
this.$root.toastRes(res);
});
2021-06-25 09:55:49 -04:00
},
2021-06-30 09:04:58 -04:00
/** Show dialog to confirm deletion */
2021-06-25 09:55:49 -04:00
deleteDialog() {
this.$refs.confirmDelete.show();
},
2021-06-30 09:04:58 -04:00
/** Show dialog to confirm clearing events */
clearEventsDialog() {
this.$refs.confirmClearEvents.show();
},
/** Show dialog to confirm clearing heartbeats */
clearHeartbeatsDialog() {
this.$refs.confirmClearHeartbeats.show();
},
/** Request that this monitor is deleted */
2021-06-25 09:55:49 -04:00
deleteMonitor() {
this.$root.deleteMonitor(this.monitor.id, (res) => {
if (res.ok) {
toast.success(res.msg);
2021-10-01 06:44:32 -04:00
this.$router.push("/dashboard");
2021-06-25 09:55:49 -04:00
} else {
toast.error(res.msg);
}
2021-10-01 06:44:32 -04:00
});
2021-07-27 13:47:13 -04:00
},
2021-06-30 09:04:58 -04:00
/** Request that this monitors events are cleared */
clearEvents() {
this.$root.clearEvents(this.monitor.id, (res) => {
if (! res.ok) {
toast.error(res.msg);
}
2021-10-01 06:44:32 -04:00
});
},
/** Request that this monitors heartbeats are cleared */
clearHeartbeats() {
this.$root.clearHeartbeats(this.monitor.id, (res) => {
if (! res.ok) {
toast.error(res.msg);
}
2021-10-01 06:44:32 -04:00
});
},
/**
* 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) {
2021-10-01 06:44:32 -04:00
let translationPrefix = "";
if (average) {
2021-10-01 06:44:32 -04:00
translationPrefix = "Avg. ";
}
✨ feat: json-query monitor added (#3253) * ✨ feat: json-query monitor added Signed-off-by: Muhammed Hussein Karimi <info@karimi.dev> * 🐛 fix: import warning error Signed-off-by: Muhammed Hussein Karimi <info@karimi.dev> * 🐛 fix: br tag and remove comment Signed-off-by: Muhammed Hussein Karimi <info@karimi.dev> * 🐛 fix: supporting compare string with other types Signed-off-by: Muhammed Hussein Karimi <info@karimi.dev> * 🐛 fix: switch to a better lib for json query Signed-off-by: Muhammed Hussein Karimi <info@karimi.dev> * 🐛 fix: better description on json query and using `v-html` in jsonQueryDescription element to fix `a` tags Signed-off-by: Muhammed Hussein Karimi <info@karimi.dev> * 🐛 fix: result variable in error message Signed-off-by: Muhammed Hussein Karimi <info@karimi.dev> * 🐛 fix: typos in json query description Co-authored-by: Frank Elsinga <frank@elsinga.de> * 📝 docs: `HTTP(s) Json Query` added to monitor list in `README.md` Signed-off-by: Muhammed Hussein Karimi <info@karimi.dev> * 🐛 fix: needed white space in `README.md` Co-authored-by: Frank Elsinga <frank@elsinga.de> * Nostr dm notifications (#3051) * Add nostr DM notification provider * require crypto for node 18 compatibility * remove whitespace Co-authored-by: Frank Elsinga <frank@elsinga.de> * move closer to where it is used * simplify success or failure logic * don't clobber the non-alert msg * Update server/notification-providers/nostr.js Co-authored-by: Frank Elsinga <frank@elsinga.de> * polyfills required for node <= 18 * resolve linter warnings * missing comma --------- Co-authored-by: Frank Elsinga <frank@elsinga.de> * Drop nostr * Rebuild package-lock.json * Lint --------- Signed-off-by: Muhammed Hussein Karimi <info@karimi.dev> Co-authored-by: Frank Elsinga <frank@elsinga.de> Co-authored-by: zappityzap <128872140+zappityzap@users.noreply.github.com> Co-authored-by: Louis Lam <louislam@users.noreply.github.com>
2023-07-13 11:37:26 -04:00
if (this.monitor.type === "http" || this.monitor.type === "keyword" || this.monitor.type === "json-query") {
return this.$t(translationPrefix + "Response");
}
return this.$t(translationPrefix + "Ping");
},
2023-01-28 08:53:40 -05:00
/**
* Get URL of monitor
* @param {number} id ID of monitor
* @returns {string} Relative URL of monitor
*/
monitorURL(id) {
return getMonitorRelativeURL(id);
},
2023-05-31 15:19:46 -04:00
2023-04-18 15:20:35 -04:00
/** Filter and hide password in URL for display */
filterPassword(urlString) {
try {
let parsedUrl = new URL(urlString);
if (parsedUrl.password !== "") {
parsedUrl.password = "******";
}
return parsedUrl.toString();
} catch (e) {
// Handle SQL Server
return urlString.replaceAll(/Password=(.+);/ig, "Password=******;");
}
}
2021-07-27 13:47:13 -04:00
},
2021-10-01 06:44:32 -04:00
};
2021-06-25 09:55:49 -04:00
</script>
<style lang="scss" scoped>
@import "../assets/vars.scss";
2021-08-18 00:22:45 -04:00
@media (max-width: 767px) {
.badge {
margin-top: 14px;
}
}
2021-08-18 00:22:45 -04:00
@media (max-width: 550px) {
.functions {
text-align: center;
}
2021-08-18 00:22:45 -04:00
.ping-chart-wrapper {
padding: 10px !important;
}
.dropdown-clear-data {
margin-bottom: 10px;
}
}
2021-08-18 00:22:45 -04:00
@media (max-width: 400px) {
.btn {
display: inline-flex;
flex-direction: column;
align-items: center;
padding-top: 10px;
2023-04-11 09:16:45 -04:00
font-size: 0.9em;
}
a.btn {
padding-left: 25px;
padding-right: 25px;
}
.dropdown-clear-data {
button {
display: block;
padding-top: 4px;
}
}
}
2021-06-27 04:10:55 -04:00
.url {
2021-06-25 09:55:49 -04:00
color: $primary;
margin-bottom: 20px;
2021-06-27 04:10:55 -04:00
font-weight: bold;
a {
color: $primary;
}
2021-06-25 09:55:49 -04:00
}
.shadow-box {
padding: 20px;
margin-top: 25px;
}
2021-06-27 04:10:55 -04:00
.word {
2021-08-24 11:38:25 -04:00
color: #aaa;
2021-06-27 04:10:55 -04:00
font-size: 14px;
}
2021-06-30 09:04:58 -04:00
table {
font-size: 14px;
tr {
transition: all ease-in-out 0.2ms;
}
}
.stats p {
font-size: 13px;
2021-08-24 11:38:25 -04:00
color: #aaa;
2021-06-30 09:04:58 -04:00
}
2021-07-26 10:53:07 -04:00
.stats {
padding: 10px;
.col {
margin: 20px 0;
}
}
2023-04-11 09:16:45 -04:00
@media (max-width: 550px) {
.stats {
.col {
margin: 10px 0 !important;
}
2023-04-11 09:27:03 -04:00
2023-04-11 09:16:45 -04:00
h4 {
font-size: 1.1rem;
}
}
}
.keyword {
color: black;
}
.dropdown-clear-data {
float: right;
ul {
width: 100%;
min-width: unset;
padding-left: 0;
}
}
2021-08-24 11:38:25 -04:00
.dark {
.keyword {
color: $dark-font-color;
}
2023-04-05 20:10:21 -04:00
.keyword-inverted {
color: $dark-font-color;
}
.dropdown-clear-data {
ul {
background-color: $dark-bg;
border-color: $dark-bg2;
border-width: 2px;
li button {
color: $dark-font-color;
}
li button:hover {
background-color: $dark-bg2;
}
}
}
}
2021-08-29 14:22:49 -04:00
.tags {
margin-bottom: 0.5rem;
}
.tags > div:first-child {
margin-left: 0 !important;
}
2021-06-25 09:55:49 -04:00
</style>