mirror of
https://github.com/louislam/uptime-kuma.git
synced 2025-09-27 01:19:20 +08:00
Merge branch 'master' into status-page-domain
This commit is contained in:
@@ -9,7 +9,9 @@
|
||||
<a v-if="searchText != ''" class="search-icon" @click="clearSearchText">
|
||||
<font-awesome-icon icon="times" />
|
||||
</a>
|
||||
<input v-model="searchText" class="form-control search-input" :placeholder="$t('Search...')" />
|
||||
<form>
|
||||
<input v-model="searchText" class="form-control search-input" :placeholder="$t('Search...')" autocomplete="off" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="monitor-list" :class="{ scrollbar: scrollbar }">
|
||||
|
206
src/components/ProxyDialog.vue
Normal file
206
src/components/ProxyDialog.vue
Normal file
@@ -0,0 +1,206 @@
|
||||
<template>
|
||||
<form @submit.prevent="submit">
|
||||
<div ref="modal" class="modal fade" tabindex="-1" data-bs-backdrop="static">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 id="exampleModalLabel" class="modal-title">
|
||||
{{ $t("Setup Proxy") }}
|
||||
</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" />
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="mb-3">
|
||||
<label for="proxy-protocol" class="form-label">{{ $t("Proxy Protocol") }}</label>
|
||||
<select id="proxy-protocol" v-model="proxy.protocol" class="form-select">
|
||||
<option value="https">HTTPS</option>
|
||||
<option value="http">HTTP</option>
|
||||
<option value="socks">SOCKS</option>
|
||||
<option value="socks5">SOCKS v5</option>
|
||||
<option value="socks4">SOCKS v4</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="proxy-host" class="form-label">{{ $t("Proxy Server") }}</label>
|
||||
<div class="d-flex">
|
||||
<input id="proxy-host" v-model="proxy.host" type="text" class="form-control" required :placeholder="$t('Server Address')">
|
||||
<input v-model="proxy.port" type="number" class="form-control ms-2" style="width: 100px" required min="1" max="65535" :placeholder="$t('Port')">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<div class="form-check form-switch">
|
||||
<input id="mark-auth" v-model="proxy.auth" class="form-check-input" type="checkbox">
|
||||
<label for="mark-auth" class="form-check-label">{{ $t("Proxy server has authentication") }}</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="proxy.auth" class="mb-3">
|
||||
<label for="proxy-username" class="form-label">{{ $t("User") }}</label>
|
||||
<input id="proxy-username" v-model="proxy.username" type="text" class="form-control" required>
|
||||
</div>
|
||||
|
||||
<div v-if="proxy.auth" class="mb-3">
|
||||
<label for="proxy-password" class="form-label">{{ $t("Password") }}</label>
|
||||
<input id="proxy-password" v-model="proxy.password" type="password" class="form-control" required>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 mt-4">
|
||||
<hr class="dropdown-divider mb-4">
|
||||
|
||||
<div class="form-check form-switch">
|
||||
<input id="mark-active" v-model="proxy.active" class="form-check-input" type="checkbox">
|
||||
<label for="mark-active" class="form-check-label">{{ $t("enabled") }}</label>
|
||||
</div>
|
||||
<div class="form-text">
|
||||
{{ $t("enableProxyDescription") }}
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<div class="form-check form-switch">
|
||||
<input id="mark-default" v-model="proxy.default" class="form-check-input" type="checkbox">
|
||||
<label for="mark-default" class="form-check-label">{{ $t("setAsDefault") }}</label>
|
||||
</div>
|
||||
<div class="form-text">
|
||||
{{ $t("setAsDefaultProxyDescription") }}
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<div class="form-check form-switch">
|
||||
<input id="apply-existing" v-model="proxy.applyExisting" class="form-check-input" type="checkbox">
|
||||
<label class="form-check-label" for="apply-existing">{{ $t("Apply on all existing monitors") }}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button v-if="id" type="button" class="btn btn-danger" :disabled="processing" @click="deleteConfirm">
|
||||
{{ $t("Delete") }}
|
||||
</button>
|
||||
<button type="submit" class="btn btn-primary" :disabled="processing">
|
||||
<div v-if="processing" class="spinner-border spinner-border-sm me-1"></div>
|
||||
{{ $t("Save") }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<Confirm ref="confirmDelete" btn-style="btn-danger" :yes-text="$t('Yes')" :no-text="$t('No')" @yes="deleteProxy">
|
||||
{{ $t("deleteProxyMsg") }}
|
||||
</Confirm>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Modal } from "bootstrap";
|
||||
|
||||
import Confirm from "./Confirm.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Confirm,
|
||||
},
|
||||
props: {},
|
||||
emits: ["added"],
|
||||
data() {
|
||||
return {
|
||||
model: null,
|
||||
processing: false,
|
||||
id: null,
|
||||
proxy: {
|
||||
protocol: null,
|
||||
host: null,
|
||||
port: null,
|
||||
auth: false,
|
||||
username: null,
|
||||
password: null,
|
||||
active: false,
|
||||
default: false,
|
||||
applyExisting: false,
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.modal = new Modal(this.$refs.modal);
|
||||
},
|
||||
|
||||
methods: {
|
||||
deleteConfirm() {
|
||||
this.modal.hide();
|
||||
this.$refs.confirmDelete.show();
|
||||
},
|
||||
|
||||
show(proxyID) {
|
||||
if (proxyID) {
|
||||
this.id = proxyID;
|
||||
|
||||
for (let proxy of this.$root.proxyList) {
|
||||
if (proxy.id === proxyID) {
|
||||
this.proxy = proxy;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.id = null;
|
||||
this.proxy = {
|
||||
protocol: "https",
|
||||
host: null,
|
||||
port: null,
|
||||
auth: false,
|
||||
username: null,
|
||||
password: null,
|
||||
active: true,
|
||||
default: false,
|
||||
applyExisting: false,
|
||||
};
|
||||
}
|
||||
|
||||
this.modal.show();
|
||||
},
|
||||
|
||||
submit() {
|
||||
this.processing = true;
|
||||
this.$root.getSocket().emit("addProxy", this.proxy, this.id, (res) => {
|
||||
this.$root.toastRes(res);
|
||||
this.processing = false;
|
||||
|
||||
if (res.ok) {
|
||||
this.modal.hide();
|
||||
|
||||
// Emit added event, doesn't emit edit.
|
||||
if (! this.id) {
|
||||
this.$emit("added", res.id);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
deleteProxy() {
|
||||
this.processing = true;
|
||||
this.$root.getSocket().emit("deleteProxy", this.id, (res) => {
|
||||
this.$root.toastRes(res);
|
||||
this.processing = false;
|
||||
|
||||
if (res.ok) {
|
||||
this.modal.hide();
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "../assets/vars.scss";
|
||||
|
||||
.dark {
|
||||
.modal-dialog .form-text, .modal-dialog p {
|
||||
color: $dark-font-color;
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -19,6 +19,19 @@
|
||||
</div>
|
||||
<p v-if="showURI && twoFAStatus == false" class="text-break mt-2">{{ uri }}</p>
|
||||
|
||||
<div v-if="!(uri && twoFAStatus == false)" class="mb-3">
|
||||
<label for="current-password" class="form-label">
|
||||
{{ $t("Current Password") }}
|
||||
</label>
|
||||
<input
|
||||
id="current-password"
|
||||
v-model="currentPassword"
|
||||
type="password"
|
||||
class="form-control"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<button v-if="uri == null && twoFAStatus == false" class="btn btn-primary" type="button" @click="prepare2FA()">
|
||||
{{ $t("Enable 2FA") }}
|
||||
</button>
|
||||
@@ -59,11 +72,11 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Modal } from "bootstrap"
|
||||
import { Modal } from "bootstrap";
|
||||
import Confirm from "./Confirm.vue";
|
||||
import VueQrcode from "vue-qrcode"
|
||||
import { useToast } from "vue-toastification"
|
||||
const toast = useToast()
|
||||
import VueQrcode from "vue-qrcode";
|
||||
import { useToast } from "vue-toastification";
|
||||
const toast = useToast();
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -73,35 +86,36 @@ export default {
|
||||
props: {},
|
||||
data() {
|
||||
return {
|
||||
currentPassword: "",
|
||||
processing: false,
|
||||
uri: null,
|
||||
tokenValid: false,
|
||||
twoFAStatus: null,
|
||||
token: null,
|
||||
showURI: false,
|
||||
}
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.modal = new Modal(this.$refs.modal)
|
||||
this.modal = new Modal(this.$refs.modal);
|
||||
this.getStatus();
|
||||
},
|
||||
methods: {
|
||||
show() {
|
||||
this.modal.show()
|
||||
this.modal.show();
|
||||
},
|
||||
|
||||
confirmEnableTwoFA() {
|
||||
this.$refs.confirmEnableTwoFA.show()
|
||||
this.$refs.confirmEnableTwoFA.show();
|
||||
},
|
||||
|
||||
confirmDisableTwoFA() {
|
||||
this.$refs.confirmDisableTwoFA.show()
|
||||
this.$refs.confirmDisableTwoFA.show();
|
||||
},
|
||||
|
||||
prepare2FA() {
|
||||
this.processing = true;
|
||||
|
||||
this.$root.getSocket().emit("prepare2FA", (res) => {
|
||||
this.$root.getSocket().emit("prepare2FA", this.currentPassword, (res) => {
|
||||
this.processing = false;
|
||||
|
||||
if (res.ok) {
|
||||
@@ -109,49 +123,51 @@ export default {
|
||||
} else {
|
||||
toast.error(res.msg);
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
save2FA() {
|
||||
this.processing = true;
|
||||
|
||||
this.$root.getSocket().emit("save2FA", (res) => {
|
||||
this.$root.getSocket().emit("save2FA", this.currentPassword, (res) => {
|
||||
this.processing = false;
|
||||
|
||||
if (res.ok) {
|
||||
this.$root.toastRes(res)
|
||||
this.$root.toastRes(res);
|
||||
this.getStatus();
|
||||
this.currentPassword = "";
|
||||
this.modal.hide();
|
||||
} else {
|
||||
toast.error(res.msg);
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
disable2FA() {
|
||||
this.processing = true;
|
||||
|
||||
this.$root.getSocket().emit("disable2FA", (res) => {
|
||||
this.$root.getSocket().emit("disable2FA", this.currentPassword, (res) => {
|
||||
this.processing = false;
|
||||
|
||||
if (res.ok) {
|
||||
this.$root.toastRes(res)
|
||||
this.$root.toastRes(res);
|
||||
this.getStatus();
|
||||
this.currentPassword = "";
|
||||
this.modal.hide();
|
||||
} else {
|
||||
toast.error(res.msg);
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
verifyToken() {
|
||||
this.$root.getSocket().emit("verifyToken", this.token, (res) => {
|
||||
this.$root.getSocket().emit("verifyToken", this.token, this.currentPassword, (res) => {
|
||||
if (res.ok) {
|
||||
this.tokenValid = res.valid;
|
||||
} else {
|
||||
toast.error(res.msg);
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
getStatus() {
|
||||
@@ -161,10 +177,10 @@ export default {
|
||||
} else {
|
||||
toast.error(res.msg);
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
48
src/components/settings/Proxies.vue
Normal file
48
src/components/settings/Proxies.vue
Normal file
@@ -0,0 +1,48 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- Proxies -->
|
||||
<div class="proxy-list my-4">
|
||||
<p v-if="$root.proxyList.length === 0">
|
||||
{{ $t("Not available, please setup.") }}
|
||||
</p>
|
||||
<p v-else>
|
||||
{{ $t("proxyDescription") }}
|
||||
</p>
|
||||
|
||||
<ul class="list-group mb-3" style="border-radius: 1rem;">
|
||||
<li v-for="(proxy, index) in $root.proxyList" :key="index" class="list-group-item">
|
||||
{{ proxy.host }}:{{ proxy.port }} ({{ proxy.protocol }})
|
||||
<span v-if="proxy.default === true" class="badge bg-primary ms-2">{{ $t("Default") }}</span><br>
|
||||
<a href="#" @click="$refs.proxyDialog.show(proxy.id)">{{ $t("Edit") }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<button class="btn btn-primary me-2" type="button" @click="$refs.proxyDialog.show()">
|
||||
{{ $t("Setup Proxy") }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<ProxyDialog ref="proxyDialog" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ProxyDialog from "../../components/ProxyDialog.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ProxyDialog
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "../../assets/vars.scss";
|
||||
|
||||
.dark {
|
||||
.list-group-item {
|
||||
background-color: $dark-bg2;
|
||||
color: $dark-font-color;
|
||||
}
|
||||
}
|
||||
</style>
|
139
src/components/settings/ReverseProxy.vue
Normal file
139
src/components/settings/ReverseProxy.vue
Normal file
@@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<div>
|
||||
<h4 class="mt-4">Cloudflare Tunnel</h4>
|
||||
|
||||
<div class="my-3">
|
||||
<div>
|
||||
cloudflared:
|
||||
<span v-if="installed === true" class="text-primary">{{ $t("Installed") }}</span>
|
||||
<span v-else-if="installed === false" class="text-danger">{{ $t("Not installed") }}</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{{ $t("Status") }}:
|
||||
<span v-if="running" class="text-primary">{{ $t("Running") }}</span>
|
||||
<span v-else-if="!running" class="text-danger">{{ $t("Not running") }}</span>
|
||||
</div>
|
||||
|
||||
<div v-if="false">
|
||||
{{ message }}
|
||||
</div>
|
||||
|
||||
<div v-if="errorMessage" class="mt-3">
|
||||
Message:
|
||||
<textarea v-model="errorMessage" class="form-control" readonly></textarea>
|
||||
</div>
|
||||
|
||||
<p v-if="installed === false">(Download cloudflared from <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/installation/">Cloudflare Website</a>)</p>
|
||||
</div>
|
||||
|
||||
<!-- If installed show token input -->
|
||||
<div v-if="installed" class="mb-2">
|
||||
<div class="mb-4">
|
||||
<label class="form-label" for="cloudflareTunnelToken">
|
||||
Cloudflare Tunnel {{ $t("Token") }}
|
||||
</label>
|
||||
<HiddenInput
|
||||
id="cloudflareTunnelToken"
|
||||
v-model="cloudflareTunnelToken"
|
||||
autocomplete="one-time-code"
|
||||
:readonly="running"
|
||||
/>
|
||||
<div class="form-text">
|
||||
<div v-if="cloudflareTunnelToken" class="mb-3">
|
||||
<span v-if="!running" class="remove-token" @click="removeToken">{{ $t("Remove Token") }}</span>
|
||||
</div>
|
||||
|
||||
Don't know how to get the token? Please read the guide:<br />
|
||||
<a href="https://github.com/louislam/uptime-kuma/wiki/Reverse-Proxy-with-Cloudflare-Tunnel" target="_blank">
|
||||
https://github.com/louislam/uptime-kuma/wiki/Reverse-Proxy-with-Cloudflare-Tunnel
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button v-if="!running" class="btn btn-primary" type="submit" @click="start">
|
||||
{{ $t("Start") }} cloudflared
|
||||
</button>
|
||||
|
||||
<button v-if="running" class="btn btn-danger" type="submit" @click="$refs.confirmStop.show();">
|
||||
{{ $t("Stop") }} cloudflared
|
||||
</button>
|
||||
|
||||
<Confirm ref="confirmStop" btn-style="btn-danger" :yes-text="$t('Stop') + ' cloudflared'" :no-text="$t('Cancel')" @yes="stop">
|
||||
The current connection may be lost if you are currently connecting via Cloudflare Tunnel. Are you sure want to stop it? Type your current password to confirm it.
|
||||
|
||||
<div class="mt-3">
|
||||
<label for="current-password2" class="form-label">
|
||||
{{ $t("Current Password") }}
|
||||
</label>
|
||||
<input
|
||||
id="current-password2"
|
||||
v-model="currentPassword"
|
||||
type="password"
|
||||
class="form-control"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</Confirm>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4 class="mt-4">Other Software</h4>
|
||||
<div>
|
||||
For example: nginx, Apache and Traefik. <br />
|
||||
Please read <a href="https://github.com/louislam/uptime-kuma/wiki/Reverse-Proxy" target="_blank">https://github.com/louislam/uptime-kuma/wiki/Reverse-Proxy</a>.
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import HiddenInput from "../../components/HiddenInput.vue";
|
||||
import Confirm from "../Confirm.vue";
|
||||
|
||||
const prefix = "cloudflared_";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
HiddenInput,
|
||||
Confirm
|
||||
},
|
||||
data() {
|
||||
// See /src/mixins/socket.js
|
||||
return this.$root.cloudflared;
|
||||
},
|
||||
computed: {
|
||||
|
||||
},
|
||||
watch: {
|
||||
|
||||
},
|
||||
created() {
|
||||
this.$root.getSocket().emit(prefix + "join");
|
||||
},
|
||||
unmounted() {
|
||||
this.$root.getSocket().emit(prefix + "leave");
|
||||
},
|
||||
methods: {
|
||||
start() {
|
||||
this.$root.getSocket().emit(prefix + "start", this.cloudflareTunnelToken);
|
||||
},
|
||||
stop() {
|
||||
this.$root.getSocket().emit(prefix + "stop", this.currentPassword, (res) => {
|
||||
this.$root.toastRes(res);
|
||||
});
|
||||
},
|
||||
removeToken() {
|
||||
this.$root.getSocket().emit(prefix + "removeToken");
|
||||
this.cloudflareTunnelToken = "";
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.remove-token {
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
@@ -192,6 +192,12 @@
|
||||
<p>Пожалуйста, используйте с осторожностью.</p>
|
||||
</template>
|
||||
|
||||
<template v-else-if="$i18n.locale === 'uk-UA' ">
|
||||
<p>Ви впевнені, що бажаєте <strong>вимкнути авторизацію</strong>?</p>
|
||||
<p>Це підходить для <strong>тих, у кого встановлена інша авторизація</strong> пееред відкриттям Uptime Kuma, наприклад Cloudflare Access.</p>
|
||||
<p>Будь ласка, використовуйте з обережністю.</p>
|
||||
</template>
|
||||
|
||||
<template v-else-if="$i18n.locale === 'fa' ">
|
||||
<p>آیا مطمئن هستید که میخواهید <strong>احراز هویت را غیر فعال کنید</strong>?</p>
|
||||
<p>این ویژگی برای کسانی است که <strong> لایه امنیتی شخص ثالث دیگر بر روی این آدرس فعال کردهاند</strong>، مانند Cloudflare Access.</p>
|
||||
@@ -215,14 +221,14 @@
|
||||
<p>Dette er for <strong>de som har tredjepartsautorisering</strong> foran Uptime Kuma, for eksempel Cloudflare Access.</p>
|
||||
<p>Vennligst vær forsiktig.</p>
|
||||
</template>
|
||||
|
||||
|
||||
<template v-else-if="$i18n.locale === 'cs-CZ' ">
|
||||
<p>Opravdu chcete <strong>deaktivovat autentifikaci</strong>?</p>
|
||||
<p>Tato možnost je určena pro případy, kdy <strong>máte autentifikaci zajištěnou třetí stranou</strong> ještě před přístupem do Uptime Kuma, například prostřednictvím Cloudflare Access.</p>
|
||||
<p>Používejte ji prosím s rozmyslem.</p>
|
||||
</template>
|
||||
|
||||
<template v-else-if="$i18n.locale === 'vi-VN' ">
|
||||
<template v-else-if="$i18n.locale === 'vi-VN' ">
|
||||
<p>Bạn có muốn <strong>TẮT XÁC THỰC</strong> không?</p>
|
||||
<p>Điều này rất nguy hiểm<strong>BẤT KỲ AI</strong> cũng có thể truy cập và cướp quyền điều khiển.</p>
|
||||
<p>Vui lòng <strong>cẩn thận</strong>.</p>
|
||||
@@ -234,6 +240,19 @@
|
||||
<p>It is designed for scenarios <strong>where you intend to implement third-party authentication</strong> in front of Uptime Kuma such as Cloudflare Access, Authelia or other authentication mechanisms.</p>
|
||||
<p>Please use this option carefully!</p>
|
||||
</template>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="current-password2" class="form-label">
|
||||
{{ $t("Current Password") }}
|
||||
</label>
|
||||
<input
|
||||
id="current-password2"
|
||||
v-model="password.currentPassword"
|
||||
type="password"
|
||||
class="form-control"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</Confirm>
|
||||
</div>
|
||||
</template>
|
||||
@@ -310,7 +329,12 @@ export default {
|
||||
|
||||
disableAuth() {
|
||||
this.settings.disableAuth = true;
|
||||
this.saveSettings();
|
||||
|
||||
// Need current password to disable auth
|
||||
// Set it to empty if done
|
||||
this.saveSettings(() => {
|
||||
this.password.currentPassword = "";
|
||||
}, this.password.currentPassword);
|
||||
},
|
||||
|
||||
enableAuth() {
|
||||
|
@@ -29,7 +29,8 @@ const languageList = {
|
||||
"pl": "Polski",
|
||||
"et-EE": "eesti",
|
||||
"vi-VN": "Tiếng Việt",
|
||||
"zh-TW": "繁體中文 (台灣)"
|
||||
"zh-TW": "繁體中文 (台灣)",
|
||||
"uk-UA": "Український",
|
||||
};
|
||||
|
||||
let messages = {
|
||||
|
@@ -371,4 +371,12 @@ export default {
|
||||
alertaAlertState: "Alert State",
|
||||
alertaRecoverState: "Recover State",
|
||||
deleteStatusPageMsg: "Are you sure want to delete this status page?",
|
||||
Proxies: "Proxies",
|
||||
default: "Default",
|
||||
enabled: "Enabled",
|
||||
setAsDefault: "Set As Default",
|
||||
deleteProxyMsg: "Are you sure want to delete this proxy for all monitors?",
|
||||
proxyDescription: "Proxies must be assigned to a monitor to function.",
|
||||
enableProxyDescription: "This proxy will not effect on monitor requests until it is activated. You can control temporarily disable the proxy from all monitors by activation status.",
|
||||
setAsDefaultProxyDescription: "This proxy will be enabled by default for new monitors. You can still disable the proxy separately for each monitor.",
|
||||
};
|
||||
|
@@ -183,7 +183,7 @@ export default {
|
||||
"Edit Status Page": "Uredi Statusnu stranicu",
|
||||
"Go to Dashboard": "Na Kontrolnu ploču",
|
||||
"Status Page": "Statusna stranica",
|
||||
"Status Pages": "Statusna stranica",
|
||||
"Status Pages": "Statusne stranice",
|
||||
defaultNotificationName: "Moja {number}. {notification} obavijest",
|
||||
here: "ovdje",
|
||||
Required: "Potrebno",
|
||||
@@ -347,4 +347,30 @@ export default {
|
||||
Cancel: "Otkaži",
|
||||
"Powered by": "Pokreće",
|
||||
Saved: "Spremljeno",
|
||||
PushByTechulus: "Push by Techulus",
|
||||
GoogleChat: "Google Chat (preko platforme Google Workspace)",
|
||||
shrinkDatabaseDescription: "Pokreni VACUUM operaciju za SQLite. Ako je baza podataka kreirana nakon inačice 1.10.0, AUTO_VACUUM opcija već je uključena te ova akcija nije nužna.",
|
||||
serwersms: "SerwerSMS.pl",
|
||||
serwersmsAPIUser: "API korisničko ime (uključujući webapi_ prefiks)",
|
||||
serwersmsAPIPassword: "API lozinka",
|
||||
serwersmsPhoneNumber: "Broj telefona",
|
||||
serwersmsSenderName: "Ime SMS pošiljatelja (registrirano preko korisničkog portala)",
|
||||
stackfield: "Stackfield",
|
||||
smtpDkimSettings: "DKIM postavke",
|
||||
smtpDkimDesc: "Za više informacija, postoji Nodemailer DKIM {0}.",
|
||||
documentation: "dokumentacija",
|
||||
smtpDkimDomain: "Domena",
|
||||
smtpDkimKeySelector: "Odabir ključa",
|
||||
smtpDkimPrivateKey: "Privatni ključ",
|
||||
smtpDkimHashAlgo: "Hash algoritam (neobavezno)",
|
||||
smtpDkimheaderFieldNames: "Ključevi zaglavlja za potpis (neobavezno)",
|
||||
smtpDkimskipFields: "Ključevi zaglavlja koji se neće potpisati (neobavezno)",
|
||||
gorush: "Gorush",
|
||||
alerta: "Alerta",
|
||||
alertaApiEndpoint: "Krajnja točka API-ja (Endpoint)",
|
||||
alertaEnvironment: "Okruženje (Environment)",
|
||||
alertaApiKey: "API ključ",
|
||||
alertaAlertState: "Stanje upozorenja",
|
||||
alertaRecoverState: "Stanje oporavka",
|
||||
deleteStatusPageMsg: "Sigurno želite obrisati ovu statusnu stranicu?",
|
||||
};
|
||||
|
@@ -197,7 +197,7 @@ export default {
|
||||
line: "Line Messenger",
|
||||
mattermost: "Mattermost",
|
||||
"Status Page": "Státusz oldal",
|
||||
"Status Pages": "Státusz oldal",
|
||||
"Status Pages": "Státusz oldalak",
|
||||
"Primary Base URL": "Elsődleges URL",
|
||||
"Push URL": "Meghívandó URL",
|
||||
needPushEvery: "Ezt az URL-t kell meghívni minden {0} másodpercben.",
|
||||
@@ -370,4 +370,5 @@ export default {
|
||||
alertaApiKey: "API kulcs",
|
||||
alertaAlertState: "Figyelmeztetési állapot",
|
||||
alertaRecoverState: "Visszaállási állapot",
|
||||
deleteStatusPageMsg: "Biztos, hogy törölni akarja a státusz oldalt?",
|
||||
};
|
||||
|
@@ -180,8 +180,8 @@ export default {
|
||||
"Add a monitor": "Добавить монитор",
|
||||
"Edit Status Page": "Редактировать",
|
||||
"Go to Dashboard": "Панель управления",
|
||||
"Status Page": "Мониторинг",
|
||||
"Status Pages": "Página de Status",
|
||||
"Status Page": "Страница статуса",
|
||||
"Status Pages": "Страницы статуса",
|
||||
Discard: "Отмена",
|
||||
"Create Incident": "Создать инцидент",
|
||||
"Switch to Dark Theme": "Тёмная тема",
|
||||
@@ -311,28 +311,28 @@ export default {
|
||||
"One record": "Одна запись",
|
||||
steamApiKeyDescription: "Для мониторинга игрового сервера Steam вам необходим Web-API ключ Steam. Зарегистрировать его можно здесь: ",
|
||||
"Certificate Chain": "Цепочка сертификатов",
|
||||
"Valid": "Действительный",
|
||||
Valid: "Действительный",
|
||||
"Hide Tags": "Скрыть тэги",
|
||||
Title: "Название инцидента:",
|
||||
Content: "Содержание инцидента:",
|
||||
Post: "Опубликовать",
|
||||
"Cancel": "Отмена",
|
||||
"Created": "Создано",
|
||||
"Unpin": "Открепить",
|
||||
Cancel: "Отмена",
|
||||
Created: "Создано",
|
||||
Unpin: "Открепить",
|
||||
"Show Tags": "Показать тэги",
|
||||
"recent": "Сейчас",
|
||||
recent: "Сейчас",
|
||||
"3h": "3 часа",
|
||||
"6h": "6 часов",
|
||||
"24h": "24 часа",
|
||||
"1w": "1 неделя",
|
||||
"No monitors available.": "Нет доступных мониторов",
|
||||
"Add one": "Добавить новый",
|
||||
"Backup": "Резервная копия",
|
||||
"Security": "Безопасность",
|
||||
Backup: "Резервная копия",
|
||||
Security: "Безопасность",
|
||||
"Shrink Database": "Сжать Базу Данных",
|
||||
"Current User": "Текущий пользователь",
|
||||
"About": "О программе",
|
||||
"Description": "Описание",
|
||||
About: "О программе",
|
||||
Description: "Описание",
|
||||
"Powered by": "Работает на основе скрипта от",
|
||||
shrinkDatabaseDescription: "Включает VACUUM для базы данных SQLite. Если ваша база данных была создана на версии 1.10.0 и более, AUTO_VACUUM уже включен и это действие не требуется.",
|
||||
deleteStatusPageMsg: "Вы действительно хотите удалить эту страницу статуса сервисов?",
|
||||
@@ -343,4 +343,50 @@ export default {
|
||||
primary: "ОСНОВНОЙ",
|
||||
light: "СВЕТЛЫЙ",
|
||||
dark: "ТЕМНЫЙ",
|
||||
"New Status Page": "Новая страница статуса",
|
||||
"Show update if available": "Показывать доступные обновления",
|
||||
"Also check beta release": "Проверять обновления для бета версий",
|
||||
"Add New Status Page": "Добавить страницу статуса",
|
||||
Next: "Далее",
|
||||
"Accept characters: a-z 0-9 -": "Разрешены символы: a-z 0-9 -",
|
||||
"Start or end with a-z 0-9 only": "Начало и окончание имени только на символы: a-z 0-9",
|
||||
"No consecutive dashes --": "Запрещено использовать тире --",
|
||||
"HTTP Options": "HTTP Опции",
|
||||
"Basic Auth": "HTTP Авторизация",
|
||||
PushByTechulus: "Push by Techulus",
|
||||
clicksendsms: "ClickSend SMS",
|
||||
GoogleChat: "Google Chat (только Google Workspace)",
|
||||
apiCredentials: "API реквизиты",
|
||||
Done: "Готово",
|
||||
Info: "Инфо",
|
||||
"Steam API Key": "Steam API-Ключ",
|
||||
"Pick a RR-Type...": "Выберите RR-Тип...",
|
||||
"Pick Accepted Status Codes...": "Выберите принятые коды состояния...",
|
||||
Default: "По умолчанию",
|
||||
"Please input title and content": "Пожалуйста, введите название и содержание",
|
||||
"Last Updated": "Последнее Обновление",
|
||||
"Untitled Group": "Группа без названия",
|
||||
Services: "Сервисы",
|
||||
serwersms: "SerwerSMS.pl",
|
||||
serwersmsAPIUser: "API Пользователь (включая префикс webapi_)",
|
||||
serwersmsAPIPassword: "API Пароль",
|
||||
serwersmsPhoneNumber: "Номер телефона",
|
||||
serwersmsSenderName: "SMS Имя Отправителя (регистрированный через пользовательский портал)",
|
||||
stackfield: "Stackfield",
|
||||
smtpDkimSettings: "DKIM Настройки",
|
||||
smtpDkimDesc: "Please refer to the Nodemailer DKIM {0} for usage.",
|
||||
documentation: "документация",
|
||||
smtpDkimDomain: "Имя Домена",
|
||||
smtpDkimKeySelector: "Ключ",
|
||||
smtpDkimPrivateKey: "Приватный ключ",
|
||||
smtpDkimHashAlgo: "Алгоритм хэша (опционально)",
|
||||
smtpDkimheaderFieldNames: "Заголовок ключей для подписи (опционально)",
|
||||
smtpDkimskipFields: "Заколовок ключей не для подписи (опционально)",
|
||||
gorush: "Gorush",
|
||||
alerta: "Alerta",
|
||||
alertaApiEndpoint: "Конечная точка API",
|
||||
alertaEnvironment: "Среда",
|
||||
alertaApiKey: "Ключ API",
|
||||
alertaAlertState: "Состояние алерта",
|
||||
alertaRecoverState: "Состояние восстановления",
|
||||
};
|
||||
|
392
src/languages/uk-UA.js
Normal file
392
src/languages/uk-UA.js
Normal file
@@ -0,0 +1,392 @@
|
||||
export default {
|
||||
languageName: "Український",
|
||||
checkEverySecond: "Перевірка кожні {0} секунд",
|
||||
retriesDescription: "Максимальна кількість спроб перед позначенням сервісу як недоступного та надсиланням повідомлення",
|
||||
ignoreTLSError: "Ігнорувати помилку TLS/SSL для сайтів HTTPS",
|
||||
upsideDownModeDescription: "Реверс статусу сервісу. Якщо сервіс доступний, він позначається як НЕДОСТУПНИЙ.",
|
||||
maxRedirectDescription: "Максимальна кількість перенаправлень. Поставте 0, щоб вимкнути перенаправлення.",
|
||||
acceptedStatusCodesDescription: "Виберіть коди статусів для визначення доступності сервісу.",
|
||||
passwordNotMatchMsg: "Повторення паролю не збігається.",
|
||||
notificationDescription: "Прив'яжіть повідомлення до моніторів.",
|
||||
keywordDescription: "Пошук слова в чистому HTML або JSON-відповіді (чутливо до регістру)",
|
||||
pauseDashboardHome: "Пауза",
|
||||
deleteMonitorMsg: "Ви дійсно хочете видалити цей монітор?",
|
||||
deleteNotificationMsg: "Ви дійсно хочете видалити це повідомлення для всіх моніторів?",
|
||||
resolverserverDescription: "Cloudflare є сервером за замовчуванням. Ви завжди можете змінити цей сервер.",
|
||||
rrtypeDescription: "Виберіть тип ресурсного запису, який ви хочете відстежувати",
|
||||
pauseMonitorMsg: "Ви дійсно хочете поставити на паузу?",
|
||||
Settings: "Налаштування",
|
||||
Dashboard: "Панель управління",
|
||||
"New Update": "Оновлення",
|
||||
Language: "Мова",
|
||||
Appearance: "Зовнішній вигляд",
|
||||
Theme: "Тема",
|
||||
General: "Загальне",
|
||||
Version: "Версія",
|
||||
"Check Update On GitHub": "Перевірити оновлення на GitHub",
|
||||
List: "Список",
|
||||
Add: "Додати",
|
||||
"Add New Monitor": "Новий монітор",
|
||||
"Quick Stats": "Статистика",
|
||||
Up: "Доступний",
|
||||
Down: "Недоступний",
|
||||
Pending: "Очікування",
|
||||
Unknown: "Невідомо",
|
||||
Pause: "Пауза",
|
||||
Name: "Ім'я",
|
||||
Status: "Статус",
|
||||
DateTime: "Дата і час",
|
||||
Message: "Повідомлення",
|
||||
"No important events": "Важливих подій немає",
|
||||
Resume: "Відновити",
|
||||
Edit: "Змінити",
|
||||
Delete: "Видалити",
|
||||
Current: "Поточний",
|
||||
Uptime: "Аптайм",
|
||||
"Cert Exp.": "Сертифікат спливає",
|
||||
days: "днів",
|
||||
day: "день",
|
||||
"-day": " днів",
|
||||
hour: "година",
|
||||
"-hour": " години",
|
||||
Response: "Відповідь",
|
||||
Ping: "Пінг",
|
||||
"Monitor Type": "Тип монітора",
|
||||
Keyword: "Ключове слово",
|
||||
"Friendly Name": "Ім'я",
|
||||
URL: "URL",
|
||||
Hostname: "Ім'я хоста",
|
||||
Port: "Порт",
|
||||
"Heartbeat Interval": "Частота опитування",
|
||||
Retries: "Спроб",
|
||||
Advanced: "Додатково",
|
||||
"Upside Down Mode": "Реверс статусу",
|
||||
"Max. Redirects": "Макс. кількість перенаправлень",
|
||||
"Accepted Status Codes": "Припустимі коди статусу",
|
||||
Save: "Зберегти",
|
||||
Notifications: "Повідомлення",
|
||||
"Not available, please setup.": "Доступних сповіщень немає, необхідно створити.",
|
||||
"Setup Notification": "Створити сповіщення",
|
||||
Light: "Світла",
|
||||
Dark: "Темна",
|
||||
Auto: "Авто",
|
||||
"Theme - Heartbeat Bar": "Тема - Смуга частоти опитування",
|
||||
Normal: "Звичайний",
|
||||
Bottom: "Знизу",
|
||||
None: "Відсутня",
|
||||
Timezone: "Часовий пояс",
|
||||
"Search Engine Visibility": "Індексація пошуковими системами:",
|
||||
"Allow indexing": "Дозволити індексування",
|
||||
"Discourage search engines from indexing site": "Заборонити індексування",
|
||||
"Change Password": "Змінити пароль",
|
||||
"Current Password": "Поточний пароль",
|
||||
"New Password": "Новий пароль",
|
||||
"Repeat New Password": "Повтор нового пароля",
|
||||
"Update Password": "Оновити пароль",
|
||||
"Disable Auth": "Вимкнути авторизацію",
|
||||
"Enable Auth": "Увімкнути авторизацію",
|
||||
Logout: "Вийти",
|
||||
Leave: "Відміна",
|
||||
"I understand, please disable": "Я розумію, все одно відключити",
|
||||
Confirm: "Підтвердити",
|
||||
Yes: "Так",
|
||||
No: "Ні",
|
||||
Username: "Логін",
|
||||
Password: "Пароль",
|
||||
"Remember me": "Запам'ятати мене",
|
||||
Login: "Вхід до системи",
|
||||
"No Monitors, please": "Моніторів немає, будь ласка",
|
||||
"No Monitors": "Монітори відсутні",
|
||||
"add one": "створіть новий",
|
||||
"Notification Type": "Тип повідомлення",
|
||||
Email: "Пошта",
|
||||
Test: "Перевірка",
|
||||
"Certificate Info": "Інформація про сертифікат",
|
||||
"Resolver Server": "DNS сервер",
|
||||
"Resource Record Type": "Тип ресурсного запису",
|
||||
"Last Result": "Останній результат",
|
||||
"Create your admin account": "Створіть обліковий запис адміністратора",
|
||||
"Repeat Password": "Повторіть пароль",
|
||||
respTime: "Час відповіді (мс)",
|
||||
notAvailableShort: "Н/д",
|
||||
Create: "Створити",
|
||||
clearEventsMsg: "Ви дійсно хочете видалити всю статистику подій цього монітора?",
|
||||
clearHeartbeatsMsg: "Ви дійсно хочете видалити всю статистику опитувань цього монітора?",
|
||||
confirmClearStatisticsMsg: "Ви дійсно хочете видалити ВСЮ статистику?",
|
||||
"Clear Data": "Видалити статистику",
|
||||
Events: "Події",
|
||||
Heartbeats: "Опитування",
|
||||
"Auto Get": "Авто-отримання",
|
||||
enableDefaultNotificationDescription: "Для кожного нового монітора це повідомлення буде включено за замовчуванням. Ви все ще можете відключити повідомлення в кожному моніторі окремо.",
|
||||
"Default enabled": "Використовувати за промовчанням",
|
||||
"Also apply to existing monitors": "Застосувати до існуючих моніторів",
|
||||
Export: "Експорт",
|
||||
Import: "Імпорт",
|
||||
backupDescription: "Ви можете зберегти резервну копію всіх моніторів та повідомлень у вигляді JSON-файлу",
|
||||
backupDescription2: "P.S.: Історія та події збережені не будуть",
|
||||
backupDescription3: "Важливі дані, такі як токени повідомлень, додаються під час експорту, тому зберігайте файли в безпечному місці",
|
||||
alertNoFile: "Виберіть файл для імпорту.",
|
||||
alertWrongFileType: "Виберіть JSON-файл.",
|
||||
twoFAVerifyLabel: "Будь ласка, введіть свій токен, щоб перевірити роботу 2FA",
|
||||
tokenValidSettingsMsg: "Токен дійсний! Тепер ви можете зберегти налаштування 2FA.",
|
||||
confirmEnableTwoFAMsg: "Ви дійсно хочете увімкнути 2FA?",
|
||||
confirmDisableTwoFAMsg: "Ви дійсно хочете вимкнути 2FA?",
|
||||
"Apply on all existing monitors": "Застосувати до всіх існуючих моніторів",
|
||||
"Verify Token": "Перевірити токен",
|
||||
"Setup 2FA": "Налаштування 2FA",
|
||||
"Enable 2FA": "Увімкнути 2FA",
|
||||
"Disable 2FA": "Вимкнути 2FA",
|
||||
"2FA Settings": "Налаштування 2FA",
|
||||
"Two Factor Authentication": "Двофакторна аутентифікація",
|
||||
Active: "Активно",
|
||||
Inactive: "Неактивно",
|
||||
Token: "Токен",
|
||||
"Show URI": "Показати URI",
|
||||
"Clear all statistics": "Очистити статистику",
|
||||
retryCheckEverySecond: "Повтор кожні {0} секунд",
|
||||
importHandleDescription: "Виберіть \"Пропустити існуючі\", якщо ви хочете пропустити кожен монітор або повідомлення з таким же ім'ям. \"Перезаписати\" видалить кожен існуючий монітор або повідомлення та додасть заново. Варіант \"Не перевіряти\" примусово відновлює всі монітори і повідомлення, навіть якщо вони вже існують.",
|
||||
confirmImportMsg: "Ви дійсно хочете відновити резервну копію? Переконайтеся, що ви вибрали відповідний варіант імпорту.",
|
||||
"Heartbeat Retry Interval": "Інтервал повтору опитування",
|
||||
"Import Backup": "Імпорт",
|
||||
"Export Backup": "Експорт",
|
||||
"Skip existing": "Пропустити існуючі",
|
||||
Overwrite: "Перезаписати",
|
||||
Options: "Опції",
|
||||
"Keep both": "Не перевіряти",
|
||||
Tags: "Теги",
|
||||
"Add New below or Select...": "Додати новий або вибрати...",
|
||||
"Tag with this name already exist.": "Такий тег вже існує.",
|
||||
"Tag with this value already exist.": "Тег із таким значенням вже існує.",
|
||||
color: "колір",
|
||||
"value (optional)": "значення (опціонально)",
|
||||
Gray: "Сірий",
|
||||
Red: "Червоний",
|
||||
Orange: "Помаранчевий",
|
||||
Green: "Зелений",
|
||||
Blue: "Синій",
|
||||
Indigo: "Індиго",
|
||||
Purple: "Пурпурний",
|
||||
Pink: "Рожевий",
|
||||
"Search...": "Пошук...",
|
||||
"Avg. Ping": "Середнє значення пінгу",
|
||||
"Avg. Response": "Середній час відповіді",
|
||||
"Entry Page": "Головна сторінка",
|
||||
statusPageNothing: "Тут порожньо. Додайте групу або монітор.",
|
||||
"No Services": "Немає сервісів",
|
||||
"All Systems Operational": "Всі системи працюють у штатному режимі",
|
||||
"Partially Degraded Service": "Сервіси працюють частково",
|
||||
"Degraded Service": "Всі сервіси не працюють",
|
||||
"Add Group": "Додати групу",
|
||||
"Add a monitor": "Додати монітор",
|
||||
"Edit Status Page": "Редагувати",
|
||||
"Go to Dashboard": "Панель управління",
|
||||
"Status Page": "Сторінка статусу",
|
||||
"Status Pages": "Сторінки статусу",
|
||||
Discard: "Скасування",
|
||||
"Create Incident": "Створити інцидент",
|
||||
"Switch to Dark Theme": "Темна тема",
|
||||
"Switch to Light Theme": "Світла тема",
|
||||
telegram: "Telegram",
|
||||
webhook: "Вебхук",
|
||||
smtp: "Email (SMTP)",
|
||||
discord: "Discord",
|
||||
teams: "Microsoft Teams",
|
||||
signal: "Signal",
|
||||
gotify: "Gotify",
|
||||
slack: "Slack",
|
||||
"rocket.chat": "Rocket.chat",
|
||||
pushover: "Pushover",
|
||||
pushy: "Pushy",
|
||||
octopush: "Octopush",
|
||||
promosms: "PromoSMS",
|
||||
lunasea: "LunaSea",
|
||||
apprise: "Apprise (Підтримка 50+ сервісів повідомлень)",
|
||||
pushbullet: "Pushbullet",
|
||||
line: "Line Messenger",
|
||||
mattermost: "Mattermost",
|
||||
"Primary Base URL": "Основна URL",
|
||||
"Push URL": "URL пуша",
|
||||
needPushEvery: "До цієї URL необхідно звертатися кожні {0} секунд",
|
||||
pushOptionalParams: "Опціональні параметри: {0}",
|
||||
defaultNotificationName: "Моє повідомлення {notification} ({number})",
|
||||
here: "тут",
|
||||
Required: "Потрібно",
|
||||
"Bot Token": "Токен бота",
|
||||
wayToGetTelegramToken: "Ви можете взяти токен тут - {0}.",
|
||||
"Chat ID": "ID чату",
|
||||
supportTelegramChatID: "Підтримуються ID чатів, груп та каналів",
|
||||
wayToGetTelegramChatID: "Ви можете взяти ID вашого чату, відправивши повідомлення боту і перейшовши по цьому URL для перегляду chat_id:",
|
||||
"YOUR BOT TOKEN HERE": "ВАШ ТОКЕН БОТА ТУТ",
|
||||
chatIDNotFound: "ID чату не знайдено; будь ласка, відправте спочатку повідомлення боту",
|
||||
"Post URL": "Post URL",
|
||||
"Content Type": "Тип контенту",
|
||||
webhookJsonDesc: "{0} підходить для будь-яких сучасних HTTP-серверів, наприклад Express.js",
|
||||
webhookFormDataDesc: "{multipart} підходить для PHP. JSON-вивід необхідно буде обробити за допомогою {decodeFunction}",
|
||||
secureOptionNone: "Ні / STARTTLS (25, 587)",
|
||||
secureOptionTLS: "TLS (465)",
|
||||
"Ignore TLS Error": "Ігнорувати помилки TLS",
|
||||
"From Email": "Від кого",
|
||||
emailCustomSubject: "Своя тема",
|
||||
"To Email": "Кому",
|
||||
smtpCC: "Копія",
|
||||
smtpBCC: "Прихована копія",
|
||||
"Discord Webhook URL": "Discord Вебхук URL",
|
||||
wayToGetDiscordURL: "Ви можете створити його в Параметрах сервера -> Інтеграції -> Створити вебхук",
|
||||
"Bot Display Name": "Ім'я бота, що відображається",
|
||||
"Prefix Custom Message": "Свій префікс повідомлення",
|
||||
"Hello @everyone is...": "Привіт {'@'}everyone це...",
|
||||
"Webhook URL": "URL вебхука",
|
||||
wayToGetTeamsURL: "Як створити URL вебхука ви можете дізнатися тут - {0}.",
|
||||
Номер: "Номер",
|
||||
Recipients: "Одержувачі",
|
||||
needSignalAPI: "Вам необхідний клієнт Signal із підтримкою REST API.",
|
||||
wayToCheckSignalURL: "Пройдіть по цьому URL, щоб дізнатися як налаштувати такий клієнт:",
|
||||
signalImportant: "ВАЖЛИВО: Не можна змішувати в Одержувачах групи та номери!",
|
||||
"Application Token": "Токен програми",
|
||||
"Server URL": "URL сервера",
|
||||
Priority: "Пріоритет",
|
||||
"Icon Emoji": "Іконка Emoji",
|
||||
"Channel Name": "Ім'я каналу",
|
||||
"Uptime Kuma URL": "Uptime Kuma URL",
|
||||
aboutWebhooks: "Більше інформації про вебхуки: {0}",
|
||||
aboutChannelName: "Введіть ім'я каналу в поле {0} Ім'я каналу, якщо ви хочете обійти канал вебхука. Наприклад: #other-channel",
|
||||
aboutKumaURL: "Якщо поле Uptime Kuma URL в налаштуваннях залишиться порожнім, за замовчуванням буде використовуватися посилання на проект на GitHub.",
|
||||
emojiCheatSheet: "Шпаргалка по Emoji: {0}",
|
||||
"User Key": "Ключ користувача",
|
||||
Device: "Пристрій",
|
||||
"Message Title": "Заголовок повідомлення",
|
||||
"Notification Sound": "Звук повідомлення",
|
||||
"More info on:": "Більше інформації: {0}",
|
||||
pushoverDesc1: "Екстренний пріоритет (2) має таймуут повтору за замовчуванням 30 секунд і закінчується через 1 годину.",
|
||||
pushoverDesc2: "Якщо ви бажаєте надсилати повідомлення різним пристроям, необхідно заповнити поле Пристрій.",
|
||||
"SMS Type": "Тип SMS",
|
||||
octopushTypePremium: "Преміум (Швидкий - рекомендується для алертів)",
|
||||
octopushTypeLowCost: "Дешевий (Повільний - іноді блокується операторами)",
|
||||
checkPrice: "Тарифи {0}:",
|
||||
octopushLegacyHint: "Ви використовуєте стару версію Octopush (2011-2020) або нову?",
|
||||
"Check octopush prices": "Тарифи Octopush {0}.",
|
||||
octopushPhoneNumber: "Номер телефону (між. формат, наприклад: +380123456789)",
|
||||
octopushSMSSender: "Ім'я відправника SMS: 3-11 символів алвафіту, цифр та пробілів (a-zA-Z0-9)",
|
||||
"LunaSea Device ID": "ID пристрою LunaSea",
|
||||
"Apprise URL": "Apprise URL",
|
||||
"Example:": "Приклад: {0}",
|
||||
"Read more:": "Докладніше: {0}",
|
||||
"Status:": "Статус: {0}",
|
||||
"Read more": "Докладніше",
|
||||
appriseInstalled: "Apprise встановлено.",
|
||||
appriseNotInstalled: "Apprise не встановлено. {0}",
|
||||
"Access Token": "Токен доступу",
|
||||
"Channel access token": "Токен доступу каналу",
|
||||
"Line Developers Console": "Консоль розробників Line",
|
||||
lineDevConsoleTo: "Консоль розробників Line - {0}",
|
||||
"Basic Settings": "Базові налаштування",
|
||||
"User ID": "ID користувача",
|
||||
"Messaging API": "API повідомлень",
|
||||
wayToGetLineChannelToken: "Спочатку зайдіть в {0}, створіть провайдера та канал (API повідомлень), потім ви зможете отримати токен доступу каналу та ID користувача з вищезгаданих пунктів меню.",
|
||||
"Icon URL": "URL іконки",
|
||||
aboutIconURL: "Ви можете надати посилання на іконку в полі \"URL іконки\", щоб перевизначити картинку профілю за замовчуванням. Не використовується, якщо задана іконка Emoji.",
|
||||
aboutMattermostChannelName: "Ви можете перевизначити канал за замовчуванням, в який пише вебхук, ввівши ім'я каналу в полі \"Ім'я каналу\". Це необхідно включити в налаштуваннях вебхука Mattermost. Наприклад: #other-channel",
|
||||
matrix: "Matrix",
|
||||
promosmsTypeEco: "SMS ECO - дешево та повільно, часто перевантажений. Тільки для одержувачів з Польщі.",
|
||||
promosmsTypeFlash: "SMS FLASH - повідомлення автоматично з'являться на пристрої одержувача. Тільки для одержувачів з Польщі.",
|
||||
promosmsTypeFull: "SMS FULL - преміум-рівень SMS, можна використовувати своє ім'я відправника (попередньо зареєструвавши його). Надійно для алертів.",
|
||||
promosmsTypeSpeed: "SMS SPEED - найвищий пріоритет у системі. Дуже швидко і надійно, але дуже дорого (вдвічі дорожче, ніж SMS FULL).",
|
||||
promosmsPhoneNumber: "Номер телефону (для одержувачів з Польщі можна пропустити код регіону)",
|
||||
promosmsSMSSender: "Ім'я відправника SMS: Зареєстроване або одне з імен за замовчуванням: InfoSMS, SMS Info, MaxSMS, INFO, SMS",
|
||||
"Feishu WebHookURL": "Feishu WebHookURL",
|
||||
matrixHomeserverURL: "URL сервера (разом з http(s):// і опціонально порт)",
|
||||
"Internal Room Id": "Внутрішній ID кімнати",
|
||||
matrixDesc1: "Внутрішній ID кімнати можна знайти в Подробицях у параметрах каналу вашого Matrix клієнта. Він повинен виглядати приблизно як !QMdRCpUIfLwsfjxye6:home.server.",
|
||||
matrixDesc2: "Рекомендується створити нового користувача і не використовувати токен доступу особистого користувача Matrix, тому що це спричиняє повний доступ до облікового запису та до кімнат, в яких ви є. Замість цього створіть нового користувача і запросіть його тільки в ту кімнату, в якій ви хочете отримувати повідомлення.Токен доступу можна отримати, виконавши команду {0}",
|
||||
Method: "Метод",
|
||||
Body: "Тіло",
|
||||
Headers: "Заголовки",
|
||||
PushUrl: "URL пуша",
|
||||
HeadersInvalidFormat: "Заголовки запиту некоректні JSON: ",
|
||||
BodyInvalidFormat: "Тіло запиту некоректне JSON: ",
|
||||
"Monitor History": "Статистика",
|
||||
clearDataOlderThan: "Зберігати статистику за {0} днів.",
|
||||
PasswordsDoNotMatch: "Паролі не співпадають.",
|
||||
records: "записів",
|
||||
"One record": "Один запис",
|
||||
steamApiKeyDescription: "Для моніторингу ігрового сервера Steam вам потрібен Web-API ключ Steam. Зареєструвати його можна тут: ",
|
||||
"Certificate Chain": "Ланцюжок сертифікатів",
|
||||
Valid: "Дійсний",
|
||||
"Hide Tags": "Приховати теги",
|
||||
Title: "Назва інциденту:",
|
||||
Content: "Зміст інциденту:",
|
||||
Post: "Опублікувати",
|
||||
Cancel: "Скасувати",
|
||||
Created: "Створено",
|
||||
Unpin: "Відкріпити",
|
||||
"Show Tags": "Показати теги",
|
||||
recent: "Зараз",
|
||||
"3h": "3 години",
|
||||
"6h": "6 годин",
|
||||
"24h": "24 години",
|
||||
"1w": "1 тиждень",
|
||||
"No monitors available.": "Немає доступних моніторів",
|
||||
"Add one": "Додати новий",
|
||||
Backup: "Резервна копія",
|
||||
Security: "Безпека",
|
||||
"Shrink Database": "Стиснути базу даних",
|
||||
"Current User": "Поточний користувач",
|
||||
About: "Про програму",
|
||||
Description: "Опис",
|
||||
"Powered by": "Працює на основі скрипту від",
|
||||
shrinkDatabaseDescription: "Включає VACUUM для бази даних SQLite. Якщо база даних була створена на версії 1.10.0 і більше, AUTO_VACUUM вже включений і ця дія не потрібна.",
|
||||
Style: "Стиль",
|
||||
info: "ІНФО",
|
||||
warning: "УВАГА",
|
||||
danger: "ПОМИЛКА",
|
||||
primary: "ОСНОВНИЙ",
|
||||
light: "СВІТЛИЙ",
|
||||
dark: "ТЕМНИЙ",
|
||||
"New Status Page": "Нова сторінка статусу",
|
||||
"Show update if available": "Показувати доступні оновлення",
|
||||
"Also check beta release": "Перевіряти оновлення для бета версій",
|
||||
"Add New Status Page": "Додати сторінку статусу",
|
||||
Next: "Далі",
|
||||
"Acz characters: a-z 0-9 -": "Дозволені символи: a-z 0-9 -",
|
||||
"Start or end with a-z 0-9 only": "Початок та закінчення імені лише на символи: a-z 0-9",
|
||||
"No consecutive dashes --": "Заборонено використовувати тире --",
|
||||
"HTTP Options": "HTTP Опції",
|
||||
"Basic Auth": "HTTP Авторизація",
|
||||
PushByTechulus: "Push by Techulus",
|
||||
clicksendsms: "ClickSend SMS",
|
||||
GoogleChat: "Google Chat (тільки Google Workspace)",
|
||||
apiCredentials: "API реквізити",
|
||||
Done: "Готово",
|
||||
Info: "Інфо",
|
||||
"Steam API Key": "Steam API-Ключ",
|
||||
"Pick a RR-Type...": "Виберіть RR-тип...",
|
||||
"Pick Accepted Status Codes...": "Виберіть прийняті коди стану...",
|
||||
Default: "За замовчуванням",
|
||||
"Please input title and content": "Будь ласка, введіть назву та зміст",
|
||||
"Last Updated": "Останнє Оновлення",
|
||||
"Untitled Group": "Група без назви",
|
||||
Services: "Сервіси",
|
||||
serwersms: "SerwerSMS.pl",
|
||||
serwersmsAPIUser: "API Користувач (включаючи префікс webapi_)",
|
||||
serwersmsAPIPassword: "API Пароль",
|
||||
serwersmsPhoneNumber: "Номер телефону",
|
||||
serwersmsSenderName: "SMS ім'я відправника (реєстрований через портал користувача)",
|
||||
stackfield: "Stackfield",
|
||||
smtpDkimSettings: "DKIM Налаштування",
|
||||
smtpDkimDesc: "Повернутися до Nodemailer DKIM {0} для використання.",
|
||||
documentation: "документація",
|
||||
smtpDkimDomain: "Ім'я домена",
|
||||
smtpDkimKeySelector: "Ключ",
|
||||
smtpDkimPrivateKey: "Приватний ключ",
|
||||
smtpDkimHashAlgo: "Алгоритм хеша (опціонально)",
|
||||
smtpDkimheaderFieldNames: "Заголовок ключів для підпису (опціонально)",
|
||||
smtpDkimskipFields: "Заколовок ключів не для підпису (опціонально)",
|
||||
gorush: "Gorush",
|
||||
alerta: "Alerta",
|
||||
alertaApiEndpoint: "Кінцева точка API",
|
||||
alertaEnvironment: "Середовище",
|
||||
alertaApiKey: "Ключ API",
|
||||
alertaAlertState: "Стан алерту",
|
||||
alertaRecoverState: "Стан відновлення",
|
||||
deleteStatusPageMsg: "Дійсно хочете видалити цю сторінку статусів?",
|
||||
};
|
@@ -48,7 +48,7 @@
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<router-view v-if="$root.loggedIn" />
|
||||
<router-view v-if="$root.loggedIn || forceShowContent" />
|
||||
<Login v-if="! $root.loggedIn && $root.allowLoginDialog" />
|
||||
</main>
|
||||
|
||||
@@ -189,6 +189,7 @@ main {
|
||||
color: white;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
z-index: 99999;
|
||||
}
|
||||
|
||||
.dark {
|
||||
|
@@ -40,8 +40,17 @@ export default {
|
||||
notificationList: [],
|
||||
statusPageListLoaded: false,
|
||||
statusPageList: [],
|
||||
proxyList: [],
|
||||
connectionErrorMsg: "Cannot connect to the socket server. Reconnecting...",
|
||||
showReverseProxyGuide: true,
|
||||
cloudflared: {
|
||||
cloudflareTunnelToken: "",
|
||||
installed: null,
|
||||
running: false,
|
||||
message: "",
|
||||
errorMessage: "",
|
||||
currentPassword: "",
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
@@ -120,6 +129,16 @@ export default {
|
||||
this.statusPageList = data;
|
||||
});
|
||||
|
||||
socket.on("proxyList", (data) => {
|
||||
this.proxyList = data.map(item => {
|
||||
item.auth = !!item.auth;
|
||||
item.active = !!item.active;
|
||||
item.default = !!item.default;
|
||||
|
||||
return item;
|
||||
});
|
||||
});
|
||||
|
||||
socket.on("heartbeat", (data) => {
|
||||
if (! (data.monitorID in this.heartbeatList)) {
|
||||
this.heartbeatList[data.monitorID] = [];
|
||||
@@ -231,6 +250,12 @@ export default {
|
||||
this.socket.firstConnect = false;
|
||||
});
|
||||
|
||||
// cloudflared
|
||||
socket.on("cloudflared_installed", (res) => this.cloudflared.installed = res);
|
||||
socket.on("cloudflared_running", (res) => this.cloudflared.running = res);
|
||||
socket.on("cloudflared_message", (res) => this.cloudflared.message = res);
|
||||
socket.on("cloudflared_errorMessage", (res) => this.cloudflared.errorMessage = res);
|
||||
socket.on("cloudflared_token", (res) => this.cloudflared.cloudflareTunnelToken = res);
|
||||
},
|
||||
|
||||
storage() {
|
||||
|
@@ -139,6 +139,15 @@
|
||||
|
||||
<h2 v-if="monitor.type !== 'push'" class="mt-5 mb-2">{{ $t("Advanced") }}</h2>
|
||||
|
||||
<div class="my-3 form-check">
|
||||
<input id="expiry-notification" v-model="monitor.expiryNotification" class="form-check-input" type="checkbox">
|
||||
<label class="form-check-label" for="expiry-notification">
|
||||
{{ $t("Domain Name Expiry Notification") }}
|
||||
</label>
|
||||
<div class="form-text">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="monitor.type === 'http' || monitor.type === 'keyword' " class="my-3 form-check">
|
||||
<input id="ignore-tls" v-model="monitor.ignoreTls" class="form-check-input" type="checkbox" value="">
|
||||
<label class="form-check-label" for="ignore-tls">
|
||||
@@ -222,6 +231,32 @@
|
||||
{{ $t("Setup Notification") }}
|
||||
</button>
|
||||
|
||||
<!-- Proxies -->
|
||||
<h2 class="mt-5 mb-2">{{ $t("Proxies") }}</h2>
|
||||
<p v-if="$root.proxyList.length === 0">
|
||||
{{ $t("Not available, please setup.") }}
|
||||
</p>
|
||||
|
||||
<div v-if="$root.proxyList.length > 0" class="form-check form-switch my-3">
|
||||
<input id="proxy-disable" v-model="monitor.proxyId" :value="null" name="proxy" class="form-check-input" type="radio">
|
||||
<label class="form-check-label" for="proxy-disable">{{ $t("No Proxy") }}</label>
|
||||
</div>
|
||||
|
||||
<div v-for="proxy in $root.proxyList" :key="proxy.id" class="form-check form-switch my-3">
|
||||
<input :id="`proxy-${proxy.id}`" v-model="monitor.proxyId" :value="proxy.id" name="proxy" class="form-check-input" type="radio">
|
||||
|
||||
<label class="form-check-label" :for="`proxy-${proxy.id}`">
|
||||
{{ proxy.host }}:{{ proxy.port }} ({{ proxy.protocol }})
|
||||
<a href="#" @click="$refs.proxyDialog.show(proxy.id)">{{ $t("Edit") }}</a>
|
||||
</label>
|
||||
|
||||
<span v-if="proxy.default === true" class="badge bg-primary ms-2">{{ $t("default") }}</span>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-primary me-2" type="button" @click="$refs.proxyDialog.show()">
|
||||
{{ $t("Setup Proxy") }}
|
||||
</button>
|
||||
|
||||
<!-- HTTP Options -->
|
||||
<template v-if="monitor.type === 'http' || monitor.type === 'keyword' ">
|
||||
<h2 class="mt-5 mb-2">{{ $t("HTTP Options") }}</h2>
|
||||
@@ -285,12 +320,14 @@
|
||||
</form>
|
||||
|
||||
<NotificationDialog ref="notificationDialog" @added="addedNotification" />
|
||||
<ProxyDialog ref="proxyDialog" @added="addedProxy" />
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NotificationDialog from "../components/NotificationDialog.vue";
|
||||
import ProxyDialog from "../components/ProxyDialog.vue";
|
||||
import TagsManager from "../components/TagsManager.vue";
|
||||
import CopyableInput from "../components/CopyableInput.vue";
|
||||
|
||||
@@ -302,6 +339,7 @@ const toast = useToast();
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ProxyDialog,
|
||||
CopyableInput,
|
||||
NotificationDialog,
|
||||
TagsManager,
|
||||
@@ -368,6 +406,17 @@ export default {
|
||||
|
||||
},
|
||||
watch: {
|
||||
"$root.proxyList"() {
|
||||
if (this.isAdd) {
|
||||
if (this.$root.proxyList && !this.monitor.proxyId) {
|
||||
const proxy = this.$root.proxyList.find(proxy => proxy.default);
|
||||
|
||||
if (proxy) {
|
||||
this.monitor.proxyId = proxy.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"$route.fullPath"() {
|
||||
this.init();
|
||||
@@ -435,12 +484,22 @@ export default {
|
||||
notificationIDList: {},
|
||||
ignoreTls: false,
|
||||
upsideDown: false,
|
||||
expiryNotification: false,
|
||||
maxredirects: 10,
|
||||
accepted_statuscodes: ["200-299"],
|
||||
dns_resolve_type: "A",
|
||||
dns_resolve_server: "1.1.1.1",
|
||||
proxyId: null,
|
||||
};
|
||||
|
||||
if (this.$root.proxyList && !this.monitor.proxyId) {
|
||||
const proxy = this.$root.proxyList.find(proxy => proxy.default);
|
||||
|
||||
if (proxy) {
|
||||
this.monitor.proxyId = proxy.id;
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < this.$root.notificationList.length; i++) {
|
||||
if (this.$root.notificationList[i].isDefault == true) {
|
||||
this.monitor.notificationIDList[this.$root.notificationList[i].id] = true;
|
||||
@@ -532,6 +591,12 @@ export default {
|
||||
addedNotification(id) {
|
||||
this.monitor.notificationIDList[id] = true;
|
||||
},
|
||||
|
||||
// Added a Proxy Event
|
||||
// Enable it if the proxy is added in EditMonitor.vue
|
||||
addedProxy(id) {
|
||||
this.monitor.proxyId = id;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
99
src/pages/NotFound.vue
Normal file
99
src/pages/NotFound.vue
Normal file
@@ -0,0 +1,99 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- Desktop header -->
|
||||
<header v-if="! $root.isMobile" class="d-flex flex-wrap justify-content-center py-3 mb-3 border-bottom">
|
||||
<router-link to="/" class="d-flex align-items-center mb-3 mb-md-0 me-md-auto text-dark text-decoration-none">
|
||||
<object class="bi me-2 ms-4" width="40" height="40" data="/icon.svg" />
|
||||
<span class="fs-4 title">Uptime Kuma</span>
|
||||
</router-link>
|
||||
</header>
|
||||
|
||||
<!-- Mobile header -->
|
||||
<header v-else class="d-flex flex-wrap justify-content-center pt-2 pb-2 mb-3">
|
||||
<router-link to="/dashboard" class="d-flex align-items-center text-dark text-decoration-none">
|
||||
<object class="bi" width="40" height="40" data="/icon.svg" />
|
||||
<span class="fs-4 title ms-2">Uptime Kuma</span>
|
||||
</router-link>
|
||||
</header>
|
||||
|
||||
<div class="content">
|
||||
<div>
|
||||
<strong>🐻 {{ $t("Page Not Found") }}</strong>
|
||||
</div>
|
||||
|
||||
<div class="guide">
|
||||
Most likely causes:
|
||||
<ul>
|
||||
<li>The resource is no longer available.</li>
|
||||
<li>There might be a typing error in the address.</li>
|
||||
</ul>
|
||||
|
||||
What you can try:<br />
|
||||
<ul>
|
||||
<li>Retype the address.</li>
|
||||
<li><a href="#" class="go-back" @click="goBack()">Go back to the previous page.</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
async mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
goBack() {
|
||||
history.back();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "../assets/vars.scss";
|
||||
|
||||
.go-back {
|
||||
text-decoration: none;
|
||||
color: $primary !important;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
gap: 50px;
|
||||
padding-top: 30px;
|
||||
|
||||
strong {
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.guide {
|
||||
max-width: 800px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.dark {
|
||||
header {
|
||||
background-color: $dark-header-bg;
|
||||
border-bottom-color: $dark-header-bg !important;
|
||||
|
||||
span {
|
||||
color: #f0f6fc;
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-nav {
|
||||
background-color: $dark-bg;
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -75,12 +75,18 @@ export default {
|
||||
notifications: {
|
||||
title: this.$t("Notifications"),
|
||||
},
|
||||
"reverse-proxy": {
|
||||
title: this.$t("Reverse Proxy"),
|
||||
},
|
||||
"monitor-history": {
|
||||
title: this.$t("Monitor History"),
|
||||
},
|
||||
security: {
|
||||
title: this.$t("Security"),
|
||||
},
|
||||
proxies: {
|
||||
title: this.$t("Proxies"),
|
||||
},
|
||||
backup: {
|
||||
title: this.$t("Backup"),
|
||||
},
|
||||
@@ -115,6 +121,10 @@ export default {
|
||||
this.$root.getSocket().emit("getSettings", (res) => {
|
||||
this.settings = res.data;
|
||||
|
||||
if (this.settings.checkUpdate === undefined) {
|
||||
this.settings.checkUpdate = true;
|
||||
}
|
||||
|
||||
if (this.settings.searchEngineIndex === undefined) {
|
||||
this.settings.searchEngineIndex = false;
|
||||
}
|
||||
@@ -131,10 +141,18 @@ export default {
|
||||
});
|
||||
},
|
||||
|
||||
saveSettings() {
|
||||
this.$root.getSocket().emit("setSettings", this.settings, (res) => {
|
||||
/**
|
||||
* Save Settings
|
||||
* @param currentPassword (Optional) Only need for disableAuth to true
|
||||
*/
|
||||
saveSettings(callback, currentPassword) {
|
||||
this.$root.getSocket().emit("setSettings", this.settings, currentPassword, (res) => {
|
||||
this.$root.toastRes(res);
|
||||
this.loadSettings();
|
||||
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
@@ -67,7 +67,7 @@
|
||||
<h1 class="mb-4 title-flex">
|
||||
<!-- Logo -->
|
||||
<span class="logo-wrapper" @click="showImageCropUploadMethod">
|
||||
<img :src="logoURL" alt class="logo me-2" :class="logoClass" />
|
||||
<img :src="logoURL" alt class="logo me-2" :class="logoClass" @load="statusPageLogoLoaded" />
|
||||
<font-awesome-icon v-if="enableEditMode" class="icon-upload" icon="upload" />
|
||||
</span>
|
||||
|
||||
@@ -592,6 +592,11 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
statusPageLogoLoaded(eventPayload) {
|
||||
// Remark: may not work in dev, due to cros
|
||||
favicon.image(eventPayload.target);
|
||||
},
|
||||
|
||||
createIncident() {
|
||||
this.enableEditIncidentMode = true;
|
||||
|
||||
|
@@ -14,12 +14,15 @@ import Entry from "./pages/Entry.vue";
|
||||
import Appearance from "./components/settings/Appearance.vue";
|
||||
import General from "./components/settings/General.vue";
|
||||
import Notifications from "./components/settings/Notifications.vue";
|
||||
import ReverseProxy from "./components/settings/ReverseProxy.vue";
|
||||
import MonitorHistory from "./components/settings/MonitorHistory.vue";
|
||||
import Security from "./components/settings/Security.vue";
|
||||
import Proxies from "./components/settings/Proxies.vue";
|
||||
import Backup from "./components/settings/Backup.vue";
|
||||
import About from "./components/settings/About.vue";
|
||||
import ManageStatusPage from "./pages/ManageStatusPage.vue";
|
||||
import AddStatusPage from "./pages/AddStatusPage.vue";
|
||||
import NotFound from "./pages/NotFound.vue";
|
||||
|
||||
const routes = [
|
||||
{
|
||||
@@ -82,6 +85,10 @@ const routes = [
|
||||
path: "notifications",
|
||||
component: Notifications,
|
||||
},
|
||||
{
|
||||
path: "reverse-proxy",
|
||||
component: ReverseProxy,
|
||||
},
|
||||
{
|
||||
path: "monitor-history",
|
||||
component: MonitorHistory,
|
||||
@@ -90,6 +97,10 @@ const routes = [
|
||||
path: "security",
|
||||
component: Security,
|
||||
},
|
||||
{
|
||||
path: "proxies",
|
||||
component: Proxies,
|
||||
},
|
||||
{
|
||||
path: "backup",
|
||||
component: Backup,
|
||||
@@ -128,6 +139,10 @@ const routes = [
|
||||
path: "/status/:slug",
|
||||
component: StatusPage,
|
||||
},
|
||||
{
|
||||
path: "/:pathMatch(.*)*",
|
||||
component: NotFound,
|
||||
},
|
||||
];
|
||||
|
||||
export const router = createRouter({
|
||||
|
Reference in New Issue
Block a user