mirror of
https://github.com/louislam/uptime-kuma.git
synced 2025-08-10 21:54:41 +08:00
Merge branch 'louislam:master' into master
This commit is contained in:
@@ -22,8 +22,10 @@
|
||||
<option value="slack">Slack</option>
|
||||
<option value="pushover">Pushover</option>
|
||||
<option value="pushy">Pushy</option>
|
||||
<option value="octopush">Octopush</option>
|
||||
<option value="lunasea">LunaSea</option>
|
||||
<option value="apprise">Apprise (Support 50+ Notification services)</option>
|
||||
<option value="pushbullet">Pushbullet</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
@@ -252,6 +254,37 @@
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<template v-if="notification.type === 'octopush'">
|
||||
<div class="mb-3">
|
||||
<label for="octopush-key" class="form-label">API KEY</label>
|
||||
<input id="octopush-key" v-model="notification.octopushAPIKey" type="text" class="form-control" required>
|
||||
<label for="octopush-login" class="form-label">API LOGIN</label>
|
||||
<input id="octopush-login" v-model="notification.octopushLogin" type="text" class="form-control" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="octopush-type-sms" class="form-label">SMS Type</label>
|
||||
<select id="octopush-type-sms" v-model="notification.octopushSMSType" class="form-select">
|
||||
<option value="sms_premium">Premium (Fast - recommended for alerting)</option>
|
||||
<option value="sms_low_cost">Low Cost (Slow, sometimes blocked by operator)</option>
|
||||
</select>
|
||||
<div class="form-text">
|
||||
Check octopush prices <a href="https://octopush.com/tarifs-sms-international/" target="_blank">https://octopush.com/tarifs-sms-international/</a>.
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="octopush-phone-number" class="form-label">Phone number (intl format, eg : +33612345678) </label>
|
||||
<input id="octopush-phone-number" v-model="notification.octopushPhoneNumber" type="text" class="form-control" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="octopush-sender-name" class="form-label">SMS Sender Name : 3-11 alphanumeric characters and space (a-zA-Z0-9)</label>
|
||||
<input id="octopush-sender-name" v-model="notification.octopushSenderName" type="text" minlength="3" maxlength="11" class="form-control">
|
||||
</div>
|
||||
|
||||
<p style="margin-top: 8px;">
|
||||
More info on: <a href="https://octopush.com/api-sms-documentation/envoi-de-sms/" target="_blank">https://octopush.com/api-sms-documentation/envoi-de-sms/</a>
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<template v-if="notification.type === 'pushover'">
|
||||
<div class="mb-3">
|
||||
<label for="pushover-user" class="form-label">User Key<span style="color:red;"><sup>*</sup></span></label>
|
||||
@@ -339,6 +372,17 @@
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-if="notification.type === 'pushbullet'">
|
||||
<div class="mb-3">
|
||||
<label for="pushbullet-access-token" class="form-label">Access Token</label>
|
||||
<input id="pushbullet-access-token" v-model="notification.pushbulletAccessToken" type="text" class="form-control" required>
|
||||
</div>
|
||||
|
||||
<p style="margin-top: 8px;">
|
||||
More info on: <a href="https://docs.pushbullet.com" target="_blank">https://docs.pushbullet.com</a>
|
||||
</p>
|
||||
</template>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button v-if="id" type="button" class="btn btn-danger" :disabled="processing" @click="deleteConfirm">
|
||||
|
152
src/components/PingChart.vue
Normal file
152
src/components/PingChart.vue
Normal file
@@ -0,0 +1,152 @@
|
||||
<template>
|
||||
<LineChart :chart-data="chartData" :height="100" :options="chartOptions" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { BarController, BarElement, Chart, Filler, LinearScale, LineController, LineElement, PointElement, TimeScale, Tooltip } from "chart.js";
|
||||
import dayjs from "dayjs";
|
||||
import utc from "dayjs/plugin/utc";
|
||||
import timezone from "dayjs/plugin/timezone";
|
||||
import "chartjs-adapter-dayjs";
|
||||
import { LineChart } from "vue-chart-3";
|
||||
dayjs.extend(utc);
|
||||
dayjs.extend(timezone);
|
||||
|
||||
Chart.register(LineController, BarController, LineElement, PointElement, TimeScale, BarElement, LinearScale, Tooltip, Filler);
|
||||
|
||||
export default {
|
||||
components: { LineChart },
|
||||
props: {
|
||||
monitorId: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
chartPeriodHrs: 6,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
chartOptions() {
|
||||
return {
|
||||
responsive: true,
|
||||
layout: {
|
||||
padding: {
|
||||
left: 10,
|
||||
right: 30,
|
||||
top: 30,
|
||||
bottom: 10,
|
||||
},
|
||||
},
|
||||
|
||||
elements: {
|
||||
point: {
|
||||
radius: 0,
|
||||
},
|
||||
bar: {
|
||||
barThickness: "flex",
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
type: "time",
|
||||
time: {
|
||||
unit: "minute",
|
||||
},
|
||||
ticks: {
|
||||
maxRotation: 0,
|
||||
autoSkipPadding: 10,
|
||||
},
|
||||
grid: {
|
||||
color: this.$root.theme === "light" ? "rgba(0,0,0,0.1)" : "rgba(255,255,255,0.1)",
|
||||
},
|
||||
},
|
||||
y: {
|
||||
title: {
|
||||
display: true,
|
||||
text: "Response Time (ms)",
|
||||
},
|
||||
offset: false,
|
||||
grid: {
|
||||
color: this.$root.theme === "light" ? "rgba(0,0,0,0.1)" : "rgba(255,255,255,0.1)",
|
||||
},
|
||||
},
|
||||
y1: {
|
||||
display: false,
|
||||
position: "right",
|
||||
grid: {
|
||||
drawOnChartArea: false,
|
||||
},
|
||||
min: 0,
|
||||
max: 1,
|
||||
offset: false,
|
||||
},
|
||||
},
|
||||
bounds: "ticks",
|
||||
plugins: {
|
||||
tooltip: {
|
||||
mode: "nearest",
|
||||
intersect: false,
|
||||
padding: 10,
|
||||
filter: function (tooltipItem) {
|
||||
return tooltipItem.datasetIndex === 0;
|
||||
},
|
||||
callbacks: {
|
||||
label: (context) => {
|
||||
return ` ${new Intl.NumberFormat().format(context.parsed.y)} ms`
|
||||
},
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
display: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
chartData() {
|
||||
let ping_data = [];
|
||||
let down_data = [];
|
||||
if (this.monitorId in this.$root.heartbeatList) {
|
||||
ping_data = this.$root.heartbeatList[this.monitorId]
|
||||
.filter(
|
||||
(beat) => dayjs.utc(beat.time).tz(this.$root.timezone).isAfter(dayjs().subtract(this.chartPeriodHrs, "hours")))
|
||||
.map((beat) => {
|
||||
return {
|
||||
x: dayjs.utc(beat.time).tz(this.$root.timezone).format("YYYY-MM-DD HH:mm:ss"),
|
||||
y: beat.ping,
|
||||
};
|
||||
});
|
||||
down_data = this.$root.heartbeatList[this.monitorId]
|
||||
.filter(
|
||||
(beat) => dayjs.utc(beat.time).tz(this.$root.timezone).isAfter(dayjs().subtract(this.chartPeriodHrs, "hours")))
|
||||
.map((beat) => {
|
||||
return {
|
||||
x: dayjs.utc(beat.time).tz(this.$root.timezone).format("YYYY-MM-DD HH:mm:ss"),
|
||||
y: beat.status === 0 ? 1 : 0,
|
||||
};
|
||||
});
|
||||
}
|
||||
return {
|
||||
datasets: [
|
||||
{
|
||||
data: ping_data,
|
||||
fill: "origin",
|
||||
tension: 0.2,
|
||||
borderColor: "#5CDD8B",
|
||||
backgroundColor: "#5CDD8B38",
|
||||
yAxisID: "y",
|
||||
},
|
||||
{
|
||||
type: "bar",
|
||||
data: down_data,
|
||||
borderColor: "#00000000",
|
||||
backgroundColor: "#DC354568",
|
||||
yAxisID: "y1",
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
@@ -2,7 +2,7 @@ export default {
|
||||
|
||||
data() {
|
||||
return {
|
||||
system: (window.matchMedia("(prefers-color-scheme: dark)")) ? "dark" : "light",
|
||||
system: (window.matchMedia("(prefers-color-scheme: dark)").matches) ? "dark" : "light",
|
||||
userTheme: localStorage.theme,
|
||||
};
|
||||
},
|
||||
@@ -14,6 +14,7 @@ export default {
|
||||
}
|
||||
|
||||
document.body.classList.add(this.theme);
|
||||
this.updateThemeColorMeta();
|
||||
},
|
||||
|
||||
computed: {
|
||||
@@ -33,6 +34,17 @@ export default {
|
||||
theme(to, from) {
|
||||
document.body.classList.remove(from);
|
||||
document.body.classList.add(this.theme);
|
||||
this.updateThemeColorMeta();
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
updateThemeColorMeta() {
|
||||
if (this.theme === "dark") {
|
||||
document.querySelector("#theme-color").setAttribute("content", "#161B22");
|
||||
} else {
|
||||
document.querySelector("#theme-color").setAttribute("content", "#5cdd8b");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -42,7 +42,11 @@
|
||||
<div class="col">
|
||||
<h4>{{ pingTitle }}</h4>
|
||||
<p>(Current)</p>
|
||||
<span class="num"><CountUp :value="ping" /></span>
|
||||
<span class="num">
|
||||
<a href="#" @click.prevent="showPingChartBox = !showPingChartBox">
|
||||
<CountUp :value="ping" />
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h4>Avg. {{ pingTitle }}</h4>
|
||||
@@ -70,6 +74,14 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="showPingChartBox" class="shadow-box big-padding text-center">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<PingChart :monitor-id="monitor.id" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="showCertInfoBox" class="shadow-box big-padding text-center">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
@@ -155,6 +167,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineAsyncComponent } from "vue";
|
||||
import { useToast } from "vue-toastification"
|
||||
const toast = useToast()
|
||||
import Confirm from "../components/Confirm.vue";
|
||||
@@ -164,6 +177,7 @@ import Datetime from "../components/Datetime.vue";
|
||||
import CountUp from "../components/CountUp.vue";
|
||||
import Uptime from "../components/Uptime.vue";
|
||||
import Pagination from "v-pagination-3";
|
||||
const PingChart = defineAsyncComponent(() => import("../components/PingChart.vue"));
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -174,6 +188,7 @@ export default {
|
||||
Confirm,
|
||||
Status,
|
||||
Pagination,
|
||||
PingChart,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -181,6 +196,7 @@ export default {
|
||||
perPage: 25,
|
||||
heartBeatList: [],
|
||||
toggleCertInfoBox: false,
|
||||
showPingChartBox: true,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
Reference in New Issue
Block a user