webapp: finally show alert

This commit is contained in:
Thomas Basler 2022-04-17 14:26:55 +02:00
parent e30c43a66a
commit e6c954456e
2 changed files with 100 additions and 79 deletions

View File

@ -3,9 +3,9 @@
<div class="page-header"> <div class="page-header">
<h1>Network Settings</h1> <h1>Network Settings</h1>
</div> </div>
<!--<BootstrapAlert v-bind:variant="this.infoType" v-bind:show="this.infoShow">--> <BootstrapAlert v-model="showAlert" dismissible :variant="alertType">
{{ this.infoMessage }} {{ this.alertMessage }}
<!--</BootstrapAlert>--> </BootstrapAlert>
<form @submit="saveNetworkConfig"> <form @submit="saveNetworkConfig">
<div class="card"> <div class="card">
<div class="card-header text-white bg-primary">WiFi Configuration</div> <div class="card-header text-white bg-primary">WiFi Configuration</div>
@ -172,9 +172,9 @@ export default {
return { return {
networkConfigList: [], networkConfigList: [],
test: {}, test: {},
infoMessage: "", alertMessage: "",
infoType: "info", alertType: "info",
infoShow: false, showAlert: false,
}; };
}, },
created() { created() {
@ -196,20 +196,18 @@ export default {
method: "POST", method: "POST",
body: formData, body: formData,
}) })
.then( .then(function (response) {
function (response) {
if (response.status != 200) { if (response.status != 200) {
throw response.status; throw response.status;
} else { } else {
return response.json(); return response.json();
} }
}.bind(this) })
)
.then( .then(
function (response) { function (response) {
this.infoMessage = response.message; this.alertMessage = response.message;
this.infoType = response.type; this.alertType = response.type;
this.infoShow = true; this.showAlert = true;
}.bind(this) }.bind(this)
); );
}, },

View File

@ -1,5 +1,11 @@
<template> <template>
<div v-if="isAlertVisible" ref="element" class="alert" role="alert" :class="classes"> <div
v-if="isAlertVisible"
ref="element"
class="alert"
role="alert"
:class="classes"
>
<slot /> <slot />
<button <button
v-if="dismissible" v-if="dismissible"
@ -13,92 +19,109 @@
</template> </template>
<script> <script>
import {computed, defineComponent, onBeforeUnmount, ref, watch} from 'vue' import { computed, defineComponent, onBeforeUnmount, ref, watch } from "vue";
import Alert from 'bootstrap/js/dist/alert' import Alert from "bootstrap/js/dist/alert";
export const toInteger = (value, defaultValue = NaN) => {
return Number.isInteger(value) ? value : defaultValue;
};
export default defineComponent({ export default defineComponent({
name: 'BAlert', name: "BAlert",
props: { props: {
dismissLabel: {type: String, default: 'Close'}, dismissLabel: { type: String, default: "Close" },
dismissible: {type: Boolean, default: false}, dismissible: { type: Boolean, default: false },
fade: {type: Boolean, default: false}, fade: { type: Boolean, default: false },
modelValue: {type: [Boolean, Number], default: false}, modelValue: { type: [Boolean, Number], default: false },
show: {type: Boolean, default: false}, show: { type: Boolean, default: false },
variant: {type: String, default: 'info'}, variant: { type: String, default: "info" },
}, },
emits: ['dismissed', 'dismiss-count-down', 'update:modelValue'], emits: ["dismissed", "dismiss-count-down", "update:modelValue"],
setup(props, {emit}) { setup(props, { emit }) {
const element = 0; // = ref<HTMLElement>() const element = undefined;
const instance = 0; // = ref<Alert>() let instance = undefined;
const classes = computed(() => ({ const classes = computed(() => ({
[`alert-${props.variant}`]: props.variant, [`alert-${props.variant}`]: props.variant,
'show': props.modelValue, show: props.modelValue,
'alert-dismissible': props.dismissible, "alert-dismissible": props.dismissible,
'fade': props.modelValue, fade: props.modelValue,
})) }));
let _countDownTimeout = 0
let _countDownTimeout = 0;
const parseCountDown = (value) => { const parseCountDown = (value) => {
if (typeof value === 'boolean') { if (typeof value === "boolean") {
return 0 return 0;
}
const numberValue = value || 0
return numberValue > 0 ? numberValue : 0
} }
const numberValue = toInteger(value, 0);
return numberValue > 0 ? numberValue : 0;
};
const clearCountDownInterval = () => { const clearCountDownInterval = () => {
if (_countDownTimeout === undefined) return if (_countDownTimeout === undefined) return;
clearTimeout(_countDownTimeout) clearTimeout(_countDownTimeout);
_countDownTimeout = undefined _countDownTimeout = undefined;
} };
const countDown = ref(parseCountDown(props.modelValue))
const isAlertVisible = computed(() => props.modelValue || props.show) const countDown = ref(parseCountDown(props.modelValue));
const isAlertVisible = computed(() => props.modelValue || props.show);
onBeforeUnmount(() => { onBeforeUnmount(() => {
clearCountDownInterval() clearCountDownInterval();
instance.value?.dispose() instance?.dispose();
instance.value = undefined instance = undefined;
}) });
const parsedModelValue = computed(() => { const parsedModelValue = computed(() => {
if (props.modelValue === true) { if (props.modelValue === true) {
return true return true;
} }
if (props.modelValue === false) return false if (props.modelValue === false) return false;
if ((props.modelValue || 0) < 1) {
if (toInteger(props.modelValue, 0) < 1) {
// Boolean will always return false for the above comparison // Boolean will always return false for the above comparison
return false return false;
} }
return !!props.modelValue return !!props.modelValue;
}) });
const handleShowAndModelChanged = () => { const handleShowAndModelChanged = () => {
countDown.value = parseCountDown(props.modelValue) countDown.value = parseCountDown(props.modelValue);
if ((parsedModelValue.value || props.show) && !instance.value) if ((parsedModelValue.value || props.show) && !instance)
instance.value = new Alert(element.value) instance = new Alert(element);
} };
const dismissClicked = () => { const dismissClicked = () => {
if (typeof props.modelValue === 'boolean') { if (typeof props.modelValue === "boolean") {
emit('update:modelValue', false) emit("update:modelValue", false);
} else { } else {
emit('update:modelValue', 0) emit("update:modelValue", 0);
} }
emit('dismissed') emit("dismissed");
} };
watch(() => props.modelValue, handleShowAndModelChanged)
watch(() => props.show, handleShowAndModelChanged) watch(() => props.modelValue, handleShowAndModelChanged);
watch(() => props.show, handleShowAndModelChanged);
watch(countDown, (newValue) => { watch(countDown, (newValue) => {
clearCountDownInterval() clearCountDownInterval();
if (typeof props.modelValue === 'boolean') return if (typeof props.modelValue === "boolean") return;
emit('dismiss-count-down', newValue) emit("dismiss-count-down", newValue);
if (newValue === 0 && props.modelValue > 0) emit('dismissed') if (newValue === 0 && props.modelValue > 0) emit("dismissed");
if (props.modelValue !== newValue) emit('update:modelValue', newValue) if (props.modelValue !== newValue) emit("update:modelValue", newValue);
if (newValue > 0) { if (newValue > 0) {
_countDownTimeout = setTimeout(() => { _countDownTimeout = setTimeout(() => {
countDown.value-- countDown.value--;
}, 1000) }, 1000);
} }
}) });
return { return {
dismissClicked, dismissClicked,
isAlertVisible, isAlertVisible,
element, element,
classes, classes,
} };
}, },
}) });
</script> </script>