summaryrefslogtreecommitdiffstats
path: root/src/pages/Settings.vue
diff options
context:
space:
mode:
Diffstat (limited to 'src/pages/Settings.vue')
-rw-r--r--src/pages/Settings.vue317
1 files changed, 317 insertions, 0 deletions
diff --git a/src/pages/Settings.vue b/src/pages/Settings.vue
new file mode 100644
index 0000000..96bb1fe
--- /dev/null
+++ b/src/pages/Settings.vue
@@ -0,0 +1,317 @@
+<template>
+ <div>
+ <div v-if="$root.isMobile" class="shadow-box mb-3">
+ <router-link to="/manage-status-page" class="nav-link">
+ <font-awesome-icon icon="stream" /> {{ $t("Status Pages") }}
+ </router-link>
+ <router-link to="/maintenance" class="nav-link">
+ <font-awesome-icon icon="wrench" /> {{ $t("Maintenance") }}
+ </router-link>
+ </div>
+
+ <h1 v-show="show" class="mb-3">
+ {{ $t("Settings") }}
+ </h1>
+
+ <div class="shadow-box shadow-box-settings">
+ <div class="row">
+ <div v-if="showSubMenu" class="settings-menu col-lg-3 col-md-5">
+ <router-link
+ v-for="(item, key) in subMenus"
+ :key="key"
+ :to="`/settings/${key}`"
+ >
+ <div class="menu-item">
+ {{ item.title }}
+ </div>
+ </router-link>
+
+ <!-- Logout Button -->
+ <a v-if="$root.isMobile && $root.loggedIn && $root.socket.token !== 'autoLogin'" class="logout" @click.prevent="$root.logout">
+ <div class="menu-item">
+ <font-awesome-icon icon="sign-out-alt" />
+ {{ $t("Logout") }}
+ </div>
+ </a>
+ </div>
+ <div class="settings-content col-lg-9 col-md-7">
+ <div v-if="currentPage" class="settings-content-header">
+ {{ subMenus[currentPage].title }}
+ </div>
+ <div class="mx-3">
+ <router-view v-slot="{ Component }">
+ <transition name="slide-fade" appear>
+ <component :is="Component" />
+ </transition>
+ </router-view>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script>
+import { useRoute } from "vue-router";
+
+export default {
+ data() {
+ return {
+ show: true,
+ settings: {},
+ settingsLoaded: false,
+ };
+ },
+
+ computed: {
+ currentPage() {
+ let pathSplit = useRoute().path.split("/");
+ let pathEnd = pathSplit[pathSplit.length - 1];
+ if (!pathEnd || pathEnd === "settings") {
+ return null;
+ }
+ return pathEnd;
+ },
+
+ showSubMenu() {
+ if (this.$root.isMobile) {
+ return !this.currentPage;
+ } else {
+ return true;
+ }
+ },
+
+ subMenus() {
+ return {
+ general: {
+ title: this.$t("General"),
+ },
+ appearance: {
+ title: this.$t("Appearance"),
+ },
+ notifications: {
+ title: this.$t("Notifications"),
+ },
+ "reverse-proxy": {
+ title: this.$t("Reverse Proxy"),
+ },
+ tags: {
+ title: this.$t("Tags"),
+ },
+ "monitor-history": {
+ title: this.$t("Monitor History"),
+ },
+ "docker-hosts": {
+ title: this.$t("Docker Hosts"),
+ },
+ "remote-browsers": {
+ title: this.$t("Remote Browsers"),
+ },
+ security: {
+ title: this.$t("Security"),
+ },
+ "api-keys": {
+ title: this.$t("API Keys")
+ },
+ proxies: {
+ title: this.$t("Proxies"),
+ },
+ about: {
+ title: this.$t("About"),
+ },
+ };
+ },
+ },
+
+ watch: {
+ "$root.isMobile"() {
+ this.loadGeneralPage();
+ }
+ },
+
+ mounted() {
+ this.loadSettings();
+ this.loadGeneralPage();
+ },
+
+ methods: {
+
+ /**
+ * Load the general settings page
+ * For desktop only, on mobile do nothing
+ * @returns {void}
+ */
+ loadGeneralPage() {
+ if (!this.currentPage && !this.$root.isMobile) {
+ this.$router.push("/settings/general");
+ }
+ },
+
+ /**
+ * Load settings from server
+ * @returns {void}
+ */
+ loadSettings() {
+ 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;
+ }
+
+ if (this.settings.entryPage === undefined) {
+ this.settings.entryPage = "dashboard";
+ }
+
+ if (this.settings.nscd === undefined) {
+ this.settings.nscd = true;
+ }
+
+ if (this.settings.keepDataPeriodDays === undefined) {
+ this.settings.keepDataPeriodDays = 180;
+ }
+
+ if (this.settings.tlsExpiryNotifyDays === undefined) {
+ this.settings.tlsExpiryNotifyDays = [ 7, 14, 21 ];
+ }
+
+ if (this.settings.trustProxy === undefined) {
+ this.settings.trustProxy = false;
+ }
+
+ this.settingsLoaded = true;
+ });
+ },
+
+ /**
+ * Callback for saving settings
+ * @callback saveSettingsCB
+ * @param {object} res Result of operation
+ * @returns {void}
+ */
+
+ /**
+ * Save Settings
+ * @param {saveSettingsCB} callback Callback for socket response
+ * @param {string} currentPassword Only need for disableAuth to true
+ * @returns {void}
+ */
+ saveSettings(callback, currentPassword) {
+ let valid = this.validateSettings();
+ if (valid.success) {
+ this.$root.getSocket().emit("setSettings", this.settings, currentPassword, (res) => {
+ this.$root.toastRes(res);
+ this.loadSettings();
+
+ if (callback) {
+ callback();
+ }
+ });
+ } else {
+ this.$root.toastError(valid.msg);
+ }
+ },
+
+ /**
+ * Ensure settings are valid
+ * @returns {object} Contains success state and error msg
+ */
+ validateSettings() {
+ if (this.settings.keepDataPeriodDays < 0) {
+ return {
+ success: false,
+ msg: this.$t("dataRetentionTimeError"),
+ };
+ }
+ return {
+ success: true,
+ msg: "",
+ };
+ },
+ }
+};
+</script>
+
+<style lang="scss" scoped>
+@import "../assets/vars.scss";
+
+.shadow-box-settings {
+ padding: 20px;
+ min-height: calc(100vh - 155px);
+}
+
+footer {
+ color: $secondary-text;
+ font-size: 13px;
+ margin-top: 20px;
+ padding-bottom: 30px;
+ text-align: center;
+}
+
+.settings-menu {
+ a {
+ text-decoration: none !important;
+ }
+
+ .menu-item {
+ border-radius: 10px;
+ margin: 0.5em;
+ padding: 0.7em 1em;
+ cursor: pointer;
+ border-left-width: 0;
+ transition: all ease-in-out 0.1s;
+ }
+
+ .menu-item:hover {
+ background: $highlight-white;
+
+ .dark & {
+ background: $dark-header-bg;
+ }
+ }
+
+ .active .menu-item {
+ background: $highlight-white;
+ border-left: 4px solid $primary;
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+
+ .dark & {
+ background: $dark-header-bg;
+ }
+ }
+}
+
+.settings-content {
+ .settings-content-header {
+ width: calc(100% + 20px);
+ border-bottom: 1px solid #dee2e6;
+ border-radius: 0 10px 0 0;
+ margin-top: -20px;
+ margin-right: -20px;
+ padding: 12.5px 1em;
+ font-size: 26px;
+
+ .dark & {
+ background: $dark-header-bg;
+ border-bottom: 0;
+ }
+
+ .mobile & {
+ padding: 15px 0 0 0;
+
+ .dark & {
+ background-color: transparent;
+ }
+ }
+ }
+}
+
+.logout {
+ color: $danger !important;
+}
+</style>