Merge branch 'master' into http-basicauth
This commit is contained in:
commit
34d8984e3a
|
@ -1,6 +1,6 @@
|
|||
name: "❓ Ask for help"
|
||||
description: "Submit any question related to Uptime Kuma"
|
||||
title: "[Help] "
|
||||
#title: "[Help] "
|
||||
labels: [help]
|
||||
body:
|
||||
- type: checkboxes
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
name: "🐛 Bug Report"
|
||||
description: "Submit a bug report to help us improve"
|
||||
title: "[Bug] "
|
||||
#title: "[Bug] "
|
||||
labels: [bug]
|
||||
body:
|
||||
- type: checkboxes
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
name: 🚀 Feature Request
|
||||
description: "Submit a proposal for a new feature"
|
||||
title: "[Feature] "
|
||||
#title: "[Feature] "
|
||||
labels: [enhancement]
|
||||
body:
|
||||
- type: checkboxes
|
||||
|
|
|
@ -160,6 +160,8 @@ class Monitor extends BeanModel {
|
|||
};
|
||||
}
|
||||
|
||||
debug(`[${this.name}] Prepare Options for axios`);
|
||||
|
||||
const options = {
|
||||
url: this.url,
|
||||
method: (this.method || "get").toLowerCase(),
|
||||
|
@ -180,6 +182,8 @@ class Monitor extends BeanModel {
|
|||
return checkStatusCode(status, this.getAcceptedStatuscodes());
|
||||
},
|
||||
};
|
||||
|
||||
debug(`[${this.name}] Axios Request`);
|
||||
let res = await axios.request(options);
|
||||
bean.msg = `${res.status} - ${res.statusText}`;
|
||||
bean.ping = dayjs().valueOf() - startTime;
|
||||
|
@ -187,12 +191,13 @@ class Monitor extends BeanModel {
|
|||
// Check certificate if https is used
|
||||
let certInfoStartTime = dayjs().valueOf();
|
||||
if (this.getUrl()?.protocol === "https:") {
|
||||
debug(`[${this.name}] Check cert`);
|
||||
try {
|
||||
let tlsInfoObject = checkCertificate(res);
|
||||
tlsInfo = await this.updateTlsInfo(tlsInfoObject);
|
||||
|
||||
if (!this.getIgnoreTls()) {
|
||||
debug("call sendCertNotification");
|
||||
debug(`[${this.name}] call sendCertNotification`);
|
||||
await this.sendCertNotification(tlsInfoObject);
|
||||
}
|
||||
|
||||
|
@ -371,15 +376,19 @@ class Monitor extends BeanModel {
|
|||
|
||||
let beatInterval = this.interval;
|
||||
|
||||
debug(`[${this.name}] Check isImportant`);
|
||||
let isImportant = Monitor.isImportantBeat(isFirstBeat, previousBeat?.status, bean.status);
|
||||
|
||||
// Mark as important if status changed, ignore pending pings,
|
||||
// Don't notify if disrupted changes to up
|
||||
if (isImportant) {
|
||||
bean.important = true;
|
||||
|
||||
debug(`[${this.name}] sendNotification`);
|
||||
await Monitor.sendNotification(isFirstBeat, this, bean);
|
||||
|
||||
// Clear Status Page Cache
|
||||
debug(`[${this.name}] Check isImportant`);
|
||||
apicache.clear();
|
||||
|
||||
} else {
|
||||
|
@ -397,10 +406,14 @@ class Monitor extends BeanModel {
|
|||
console.warn(`Monitor #${this.id} '${this.name}': Failing: ${bean.msg} | Interval: ${beatInterval} seconds | Type: ${this.type}`);
|
||||
}
|
||||
|
||||
debug(`[${this.name}] Send to socket`);
|
||||
io.to(this.user_id).emit("heartbeat", bean.toJSON());
|
||||
Monitor.sendStats(io, this.id, this.user_id);
|
||||
|
||||
debug(`[${this.name}] Store`);
|
||||
await R.store(bean);
|
||||
|
||||
debug(`[${this.name}] prometheus.update`);
|
||||
prometheus.update(bean, tlsInfo);
|
||||
|
||||
previousBeat = bean;
|
||||
|
@ -414,7 +427,10 @@ class Monitor extends BeanModel {
|
|||
}
|
||||
}
|
||||
|
||||
debug(`[${this.name}] SetTimeout for next check.`);
|
||||
this.heartbeatInterval = setTimeout(safeBeat, beatInterval * 1000);
|
||||
} else {
|
||||
console.log(`[${this.name}] isStop = true, no next check.`);
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -101,6 +101,10 @@ router.get("/api/status-page/config", async (_request, response) => {
|
|||
config.statusPagePublished = true;
|
||||
}
|
||||
|
||||
if (! config.statusPageTags) {
|
||||
config.statusPageTags = false;
|
||||
}
|
||||
|
||||
if (! config.title) {
|
||||
config.title = "Uptime Kuma";
|
||||
}
|
||||
|
@ -140,10 +144,25 @@ router.get("/api/status-page/monitor-list", cache("5 minutes"), async (_request,
|
|||
try {
|
||||
await checkPublished();
|
||||
const publicGroupList = [];
|
||||
let list = await R.find("group", " public = 1 ORDER BY weight ");
|
||||
|
||||
const tagsVisible = (await getSettings("statusPage")).statusPageTags;
|
||||
const list = await R.find("group", " public = 1 ORDER BY weight ");
|
||||
for (let groupBean of list) {
|
||||
publicGroupList.push(await groupBean.toPublicJSON());
|
||||
let monitorGroup = await groupBean.toPublicJSON();
|
||||
if (tagsVisible) {
|
||||
monitorGroup.monitorList = await Promise.all(monitorGroup.monitorList.map(async (monitor) => {
|
||||
// Includes tags as an array in response, allows for tags to be displayed on public status page
|
||||
const tags = await R.getAll(
|
||||
`SELECT monitor_tag.monitor_id, monitor_tag.value, tag.name, tag.color
|
||||
FROM monitor_tag
|
||||
JOIN tag
|
||||
ON monitor_tag.tag_id = tag.id
|
||||
WHERE monitor_tag.monitor_id = ?`, [monitor.id]
|
||||
);
|
||||
return {...monitor, tags: tags}
|
||||
}));
|
||||
}
|
||||
|
||||
publicGroupList.push(monitorGroup);
|
||||
}
|
||||
|
||||
response.json(publicGroupList);
|
||||
|
|
|
@ -346,6 +346,10 @@ textarea.form-control {
|
|||
&.active {
|
||||
background-color: #cdf8f4;
|
||||
}
|
||||
.tags {
|
||||
// Removes margin to line up tags list with uptime percentage
|
||||
margin-left: -0.25rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,9 @@
|
|||
<Uptime :monitor="monitor.element" type="24" :pill="true" />
|
||||
{{ monitor.element.name }}
|
||||
</div>
|
||||
<div class="tags">
|
||||
<Tag v-for="tag in monitor.element.tags" :key="tag" :item="tag" :size="'sm'" />
|
||||
</div>
|
||||
</div>
|
||||
<div :key="$root.userHeartbeatBar" class="col-3 col-md-4">
|
||||
<HeartbeatBar size="small" :monitor-id="monitor.element.id" />
|
||||
|
@ -59,12 +62,14 @@
|
|||
import Draggable from "vuedraggable";
|
||||
import HeartbeatBar from "./HeartbeatBar.vue";
|
||||
import Uptime from "./Uptime.vue";
|
||||
import Tag from "./Tag.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Draggable,
|
||||
HeartbeatBar,
|
||||
Uptime,
|
||||
Tag,
|
||||
},
|
||||
props: {
|
||||
editMode: {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<span :class="className">{{ uptime }}</span>
|
||||
<span :class="className" :title="24 + $t('-hour')">{{ uptime }}</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
|
@ -279,4 +279,29 @@ export default {
|
|||
promosmsTypeSpeed: "SMS SPEED - La plus haute des priorités dans le système. Très rapide et fiable mais cher (environ le double du prix d'un SMS FULL).",
|
||||
promosmsPhoneNumber: "Numéro de téléphone (Poiur les déstinataires Polonais, vous pouvez enlever les codes interna.)",
|
||||
promosmsSMSSender: "SMS Expéditeur : Nom pré-enregistré ou l'un de base: InfoSMS, SMS Info, MaxSMS, INFO, SMS",
|
||||
"Primary Base URL": "Primary Base URL",
|
||||
emailCustomSubject: "Sujet personalisé",
|
||||
clicksendsms: "ClickSend SMS",
|
||||
checkPrice: "Vérification {0} tarifs:",
|
||||
apiCredentials: "Crédentials de l'API",
|
||||
octopushLegacyHint: "Vous utilisez l'ancienne version d'Octopush (2011-2020) ou la nouvelle version ?",
|
||||
"Feishu WebHookUrl": "Feishu WebHookURL",
|
||||
matrixHomeserverURL: "L'URL du serveur (avec http(s):// et le port de manière facultatif)",
|
||||
"Internal Room Id": "ID de la salle interne",
|
||||
matrixDesc1: "Vous pouvez trouvez l'ID de salle interne en regardant dans la section avancée des paramètres dans le client Matrix. C'est sensé ressembler à: !QMdRCpUIfLwsfjxye6:home.server.",
|
||||
matrixDesc2: "Il est fortement recommandé de créer un nouvel utilisateur et de ne pas utiliser le jeton d'accès de votre propre utilisateur Matrix, car il vous donnera un accès complet à votre compte et à toutes les salles que vous avez rejointes. Au lieu de cela, créez un nouvel utilisateur et invitez-le uniquement dans la salle dans laquelle vous souhaitez recevoir la notification. Vous pouvez obtenir le jeton d'accès en exécutant {0}",
|
||||
Method: "Méthode",
|
||||
Body: "Le corps",
|
||||
Headers: "En-têtes",
|
||||
PushUrl: "Push URL",
|
||||
HeadersInvalidFormat: "L'en-têtes de la requête n'est pas dans un format JSON valide: ",
|
||||
BodyInvalidFormat: "Le corps de la requête n'est pas dans un format JSON valide: ",
|
||||
"Monitor History": "Historique de la sonde",
|
||||
clearDataOlderThan: "Garder l'historique des données de la sonde durant {0} jours.",
|
||||
PasswordsDoNotMatch: "Les mots de passe ne correspondent pas.",
|
||||
records: "Enregistrements",
|
||||
"One record": "Un enregistrement",
|
||||
steamApiKeyDescription: "Pour surveiller un serveur Steam, vous avez besoin d'une clé Steam Web-API. Vous pouvez enregistrer votre clé ici: ",
|
||||
"Current User": "Utilisateur actuel",
|
||||
recent: "Récent",
|
||||
};
|
||||
|
|
|
@ -77,6 +77,17 @@
|
|||
<font-awesome-icon icon="save" />
|
||||
{{ $t("Switch to Dark Theme") }}
|
||||
</button>
|
||||
|
||||
<button class="btn btn-secondary me-2" @click="changeTagsVisibilty(!tagsVisible)">
|
||||
<template v-if="tagsVisible">
|
||||
<font-awesome-icon icon="eye-slash" />
|
||||
{{ $t("Hide Tags") }}
|
||||
</template>
|
||||
<template v-else>
|
||||
<font-awesome-icon icon="eye" />
|
||||
{{ $t("Show Tags") }}
|
||||
</template>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -292,6 +303,10 @@ export default {
|
|||
return this.config.statusPageTheme;
|
||||
},
|
||||
|
||||
tagsVisible() {
|
||||
return this.config.statusPageTags
|
||||
},
|
||||
|
||||
logoClass() {
|
||||
if (this.editMode) {
|
||||
return {
|
||||
|
@ -472,6 +487,25 @@ export default {
|
|||
changeTheme(name) {
|
||||
this.config.statusPageTheme = name;
|
||||
},
|
||||
changeTagsVisibilty(newState) {
|
||||
this.config.statusPageTags = newState;
|
||||
|
||||
// On load, the status page will not include tags if it's not enabled for security reasons
|
||||
// Which means if we enable tags, it won't show in the UI until saved
|
||||
// So we have this to enhance UX and load in the tags from the authenticated source instantly
|
||||
this.$root.publicGroupList = this.$root.publicGroupList.map((group) => {
|
||||
return {
|
||||
...group,
|
||||
monitorList: group.monitorList.map((monitor) => {
|
||||
// We only include the tags if visible so we can reuse the logic to hide the tags on disable
|
||||
return {
|
||||
...monitor,
|
||||
tags: newState ? this.$root.monitorList[monitor.id].tags : []
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Crop Success
|
||||
|
|
Loading…
Reference in New Issue