diff options
Diffstat (limited to 'src/components/settings/Notifications.vue')
-rw-r--r-- | src/components/settings/Notifications.vue | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/src/components/settings/Notifications.vue b/src/components/settings/Notifications.vue new file mode 100644 index 0000000..2a65d79 --- /dev/null +++ b/src/components/settings/Notifications.vue @@ -0,0 +1,218 @@ +<template> + <div> + <div class="notification-list my-4"> + <p v-if="$root.notificationList.length === 0"> + {{ $t("Not available, please setup.") }} + </p> + <p v-else> + {{ $t("notificationDescription") }} + </p> + + <ul class="list-group mb-3" style="border-radius: 1rem;"> + <li v-for="(notification, index) in $root.notificationList" :key="index" class="list-group-item"> + {{ notification.name }}<br> + <a href="#" @click="$refs.notificationDialog.show(notification.id)">{{ $t("Edit") }}</a> + </li> + </ul> + + <button class="btn btn-primary me-2" type="button" @click="$refs.notificationDialog.show()"> + {{ $t("Setup Notification") }} + </button> + </div> + + <div class="my-4 pt-4"> + <h5 class="my-4 settings-subheading">{{ $t("monitorToastMessagesLabel") }}</h5> + <p>{{ $t("monitorToastMessagesDescription") }}</p> + + <div class="my-4"> + <label for="toastErrorTimeoutSecs" class="form-label"> + {{ $t("toastErrorTimeout") }} + </label> + <input + id="toastErrorTimeoutSecs" + v-model="toastErrorTimeoutSecs" + type="number" + class="form-control" + min="-1" + step="1" + /> + </div> + + <div class="my-4"> + <label for="toastSuccessTimeoutSecs" class="form-label"> + {{ $t("toastSuccessTimeout") }} + </label> + <input + id="toastSuccessTimeoutSecs" + v-model="toastSuccessTimeoutSecs" + type="number" + class="form-control" + min="-1" + step="1" + /> + </div> + </div> + + <div class="my-4 pt-4"> + <h5 class="my-4 settings-subheading">{{ $t("settingsCertificateExpiry") }}</h5> + <p>{{ $t("certificationExpiryDescription") }}</p> + <p>{{ $t("notificationDescription") }}</p> + <div class="mt-1 mb-3 ps-2 cert-exp-days col-12 col-xl-6"> + <div v-for="day in settings.tlsExpiryNotifyDays" :key="day" class="d-flex align-items-center justify-content-between cert-exp-day-row py-2"> + <span>{{ day }} {{ $tc("day", day) }}</span> + <button type="button" class="btn-rm-expiry btn btn-outline-danger ms-2 py-1" :aria-label="$t('Remove the expiry notification')" @click="removeExpiryNotifDay(day)"> + <font-awesome-icon icon="times" /> + </button> + </div> + </div> + <div class="col-12 col-xl-6"> + <ActionInput v-model="expiryNotifInput" :type="'number'" :placeholder="$t('day')" :icon="'plus'" :action="() => addExpiryNotifDay(expiryNotifInput)" :action-aria-label="$t('Add a new expiry notification day')" /> + </div> + <div> + <button class="btn btn-primary" type="button" @click="saveSettings()"> + {{ $t("Save") }} + </button> + </div> + </div> + + <NotificationDialog ref="notificationDialog" /> + </div> +</template> + +<script> +import NotificationDialog from "../../components/NotificationDialog.vue"; +import ActionInput from "../ActionInput.vue"; + +export default { + components: { + NotificationDialog, + ActionInput, + }, + + data() { + return { + toastSuccessTimeoutSecs: 20, + toastErrorTimeoutSecs: -1, + /** + * Variable to store the input for new certificate expiry day. + */ + expiryNotifInput: null, + }; + }, + + computed: { + settings() { + return this.$parent.$parent.$parent.settings; + }, + saveSettings() { + return this.$parent.$parent.$parent.saveSettings; + }, + settingsLoaded() { + return this.$parent.$parent.$parent.settingsLoaded; + }, + }, + + watch: { + // Parse, store and apply new timeout settings. + toastSuccessTimeoutSecs(newTimeout) { + const parsedTimeout = parseInt(newTimeout); + if (parsedTimeout != null && !Number.isNaN(parsedTimeout)) { + localStorage.toastSuccessTimeout = newTimeout > 0 ? newTimeout * 1000 : newTimeout; + } + }, + toastErrorTimeoutSecs(newTimeout) { + const parsedTimeout = parseInt(newTimeout); + if (parsedTimeout != null && !Number.isNaN(parsedTimeout)) { + localStorage.toastErrorTimeout = newTimeout > 0 ? newTimeout * 1000 : newTimeout; + } + } + }, + + mounted() { + this.loadToastTimeoutSettings(); + }, + + methods: { + /** + * Remove a day from expiry notification days. + * @param {number} day The day to remove. + * @returns {void} + */ + removeExpiryNotifDay(day) { + this.settings.tlsExpiryNotifyDays = this.settings.tlsExpiryNotifyDays.filter(d => d !== day); + }, + /** + * Add a new expiry notification day. + * Will verify: + * - day is not null or empty string. + * - day is a number. + * - day is > 0. + * - The day is not already in the list. + * @param {number} day The day number to add. + * @returns {void} + */ + addExpiryNotifDay(day) { + if (day != null && day !== "") { + const parsedDay = parseInt(day); + if (parsedDay != null && !isNaN(parsedDay) && parsedDay > 0) { + if (!this.settings.tlsExpiryNotifyDays.includes(parsedDay)) { + this.settings.tlsExpiryNotifyDays.push(parseInt(day)); + this.settings.tlsExpiryNotifyDays.sort((a, b) => a - b); + this.expiryNotifInput = null; + } + } + } + }, + + /** + * Loads toast timeout settings from storage to component data. + * @returns {void} + */ + loadToastTimeoutSettings() { + const successTimeout = localStorage.toastSuccessTimeout; + if (successTimeout !== undefined) { + const parsedTimeout = parseInt(successTimeout); + if (parsedTimeout != null && !Number.isNaN(parsedTimeout)) { + this.toastSuccessTimeoutSecs = parsedTimeout > 0 ? parsedTimeout / 1000 : parsedTimeout; + } + } + + const errorTimeout = localStorage.toastErrorTimeout; + if (errorTimeout !== undefined) { + const parsedTimeout = parseInt(errorTimeout); + if (parsedTimeout != null && !Number.isNaN(parsedTimeout)) { + this.toastErrorTimeoutSecs = parsedTimeout > 0 ? parsedTimeout / 1000 : parsedTimeout; + } + } + }, + }, +}; +</script> + +<style lang="scss" scoped> +@import "../../assets/vars.scss"; + +.btn-rm-expiry { + padding-left: 11px; + padding-right: 11px; +} + +.dark { + .list-group-item { + background-color: $dark-bg2; + color: $dark-font-color; + } +} + +.cert-exp-days .cert-exp-day-row { + border-bottom: 1px solid rgba(0, 0, 0, 0.125); + + .dark & { + border-bottom: 1px solid $dark-border-color; + } +} + +.cert-exp-days .cert-exp-day-row:last-child { + border: none; +} +</style> |