webapp: Added global reboot wait screen

This commit is contained in:
Thomas Basler 2024-10-21 21:59:38 +02:00
parent 2e23c7e0ae
commit 521fce35e4
11 changed files with 105 additions and 43 deletions

View File

@ -37,6 +37,13 @@
"Release": "Soltar para refrescar", "Release": "Soltar para refrescar",
"Close": "Cerrar" "Close": "Cerrar"
}, },
"wait": {
"NotReady": "OpenDTU is not yet ready",
"PleaseWait": "Please wait. You will be automatically redirected to the home page."
},
"Error": {
"Oops": "Oops!"
},
"localeswitcher": { "localeswitcher": {
"Dark": "Oscuro", "Dark": "Oscuro",
"Light": "Claro", "Light": "Claro",

View File

@ -37,6 +37,10 @@
"Release": "Rilascia per aggiornare", "Release": "Rilascia per aggiornare",
"Close": "Chiudi" "Close": "Chiudi"
}, },
"wait": {
"NotReady": "OpenDTU is not yet ready",
"PleaseWait": "Please wait. You will be automatically redirected to the home page."
},
"Error": { "Error": {
"Oops": "Oops!" "Oops": "Oops!"
}, },

View File

@ -32,6 +32,10 @@
"Release": "Loslassen zum Aktualisieren", "Release": "Loslassen zum Aktualisieren",
"Close": "Schließen" "Close": "Schließen"
}, },
"wait": {
"NotReady": "OpenDTU ist noch nicht bereit",
"PleaseWait": "Bitte warten. Sie werden automatisch auf die Startseite weitergeleitet."
},
"Error": { "Error": {
"Oops": "Oops!" "Oops": "Oops!"
}, },

View File

@ -32,6 +32,10 @@
"Release": "Release to refresh", "Release": "Release to refresh",
"Close": "Close" "Close": "Close"
}, },
"wait": {
"NotReady": "OpenDTU is not yet ready",
"PleaseWait": "Please wait. You will be automatically redirected to the home page."
},
"Error": { "Error": {
"Oops": "Oops!" "Oops": "Oops!"
}, },

View File

@ -32,6 +32,10 @@
"Release": "Release to refresh", "Release": "Release to refresh",
"Close": "Fermer" "Close": "Fermer"
}, },
"wait": {
"NotReady": "OpenDTU is not yet ready",
"PleaseWait": "Please wait. You will be automatically redirected to the home page."
},
"Error": { "Error": {
"Oops": "Oops!" "Oops": "Oops!"
}, },

View File

@ -17,6 +17,7 @@ import NtpAdminView from '@/views/NtpAdminView.vue';
import NtpInfoView from '@/views/NtpInfoView.vue'; import NtpInfoView from '@/views/NtpInfoView.vue';
import SecurityAdminView from '@/views/SecurityAdminView.vue'; import SecurityAdminView from '@/views/SecurityAdminView.vue';
import SystemInfoView from '@/views/SystemInfoView.vue'; import SystemInfoView from '@/views/SystemInfoView.vue';
import WaitRestartView from '@/views/WaitRestartView.vue';
import { createRouter, createWebHistory } from 'vue-router'; import { createRouter, createWebHistory } from 'vue-router';
const router = createRouter({ const router = createRouter({
@ -118,6 +119,11 @@ const router = createRouter({
name: 'Device Reboot', name: 'Device Reboot',
component: MaintenanceRebootView, component: MaintenanceRebootView,
}, },
{
path: '/wait',
name: 'Wait Restart',
component: WaitRestartView,
},
], ],
}); });

View File

@ -0,0 +1,7 @@
import type { Router } from 'vue-router';
export function waitRestart(router: Router) {
setTimeout(() => {
router.push('/wait');
}, 1000);
}

View File

@ -52,11 +52,6 @@
<BIconCheckCircle /> <BIconCheckCircle />
</span> </span>
<span> {{ $t('fileadmin.UploadSuccess') }} </span> <span> {{ $t('fileadmin.UploadSuccess') }} </span>
<br />
<br />
<button class="btn btn-primary" @click="clearUpload">
<BIconArrowLeft /> {{ $t('fileadmin.Back') }}
</button>
</div> </div>
<div v-else-if="!uploading"> <div v-else-if="!uploading">
@ -137,6 +132,7 @@ import ModalDialog from '@/components/ModalDialog.vue';
import type { AlertResponse } from '@/types/Alert'; import type { AlertResponse } from '@/types/Alert';
import type { FileInfo } from '@/types/File'; import type { FileInfo } from '@/types/File';
import { authHeader, handleResponse } from '@/utils/authentication'; import { authHeader, handleResponse } from '@/utils/authentication';
import { waitRestart } from '@/utils/waitRestart';
import * as bootstrap from 'bootstrap'; import * as bootstrap from 'bootstrap';
import { import {
BIconArrowLeft, BIconArrowLeft,
@ -251,6 +247,7 @@ export default defineComponent({
// request.response will hold the response from the server // request.response will hold the response from the server
if (request.status === 200) { if (request.status === 200) {
this.UploadSuccess = true; this.UploadSuccess = true;
waitRestart(this.$router);
} else if (request.status !== 500) { } else if (request.status !== 500) {
this.UploadError = `[HTTP ERROR] ${request.statusText}`; this.UploadError = `[HTTP ERROR] ${request.statusText}`;
} else { } else {

View File

@ -39,13 +39,6 @@
<BIconCheckCircle /> <BIconCheckCircle />
</span> </span>
<span> {{ $t('firmwareupgrade.OtaSuccess') }} </span> <span> {{ $t('firmwareupgrade.OtaSuccess') }} </span>
<br />
<br />
<div class="text-center">
<div class="spinner-border" role="status">
<span class="visually-hidden"></span>
</div>
</div>
</CardElement> </CardElement>
<CardElement <CardElement
@ -88,6 +81,7 @@ import { authHeader, isLoggedIn } from '@/utils/authentication';
import { BIconArrowLeft, BIconArrowRepeat, BIconCheckCircle, BIconExclamationCircleFill } from 'bootstrap-icons-vue'; import { BIconArrowLeft, BIconArrowRepeat, BIconCheckCircle, BIconExclamationCircleFill } from 'bootstrap-icons-vue';
import SparkMD5 from 'spark-md5'; import SparkMD5 from 'spark-md5';
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { waitRestart } from '@/utils/waitRestart';
export default defineComponent({ export default defineComponent({
components: { components: {
@ -107,7 +101,6 @@ export default defineComponent({
OTASuccess: false, OTASuccess: false,
type: 'firmware', type: 'firmware',
file: {} as Blob, file: {} as Blob,
hostCheckInterval: 0,
}; };
}, },
methods: { methods: {
@ -154,7 +147,7 @@ export default defineComponent({
// request.response will hold the response from the server // request.response will hold the response from the server
if (request.status === 200) { if (request.status === 200) {
this.OTASuccess = true; this.OTASuccess = true;
this.hostCheckInterval = setInterval(this.checkRemoteHostAndReload, 1000); waitRestart(this.$router);
} else if (request.status !== 500) { } else if (request.status !== 500) {
this.OTAError = `[HTTP ERROR] ${request.statusText}`; this.OTAError = `[HTTP ERROR] ${request.statusText}`;
} else { } else {
@ -193,32 +186,6 @@ export default defineComponent({
this.OTAError = ''; this.OTAError = '';
this.OTASuccess = false; this.OTASuccess = false;
}, },
checkRemoteHostAndReload(): void {
// Check if the browser is online
if (navigator.onLine) {
const remoteHostUrl = '/api/system/status';
// Use a simple fetch request to check if the remote host is reachable
fetch(remoteHostUrl, { method: 'GET' })
.then((response) => {
// Check if the response status is OK (200-299 range)
if (response.ok) {
console.log('Remote host is available. Reloading page...');
clearInterval(this.hostCheckInterval);
this.hostCheckInterval = 0;
// Perform a page reload
window.location.replace('/');
} else {
console.log('Remote host is not reachable. Do something else if needed.');
}
})
.catch((error) => {
console.error('Error checking remote host:', error);
});
} else {
console.log('Browser is offline. Cannot check remote host.');
}
},
}, },
mounted() { mounted() {
if (!isLoggedIn()) { if (!isLoggedIn()) {
@ -229,8 +196,5 @@ export default defineComponent({
} }
this.loading = false; this.loading = false;
}, },
unmounted() {
clearInterval(this.hostCheckInterval);
},
}); });
</script> </script>

View File

@ -36,6 +36,7 @@ import ModalDialog from '@/components/ModalDialog.vue';
import { authHeader, handleResponse, isLoggedIn } from '@/utils/authentication'; import { authHeader, handleResponse, isLoggedIn } from '@/utils/authentication';
import * as bootstrap from 'bootstrap'; import * as bootstrap from 'bootstrap';
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { waitRestart } from '@/utils/waitRestart';
export default defineComponent({ export default defineComponent({
components: { components: {
@ -80,6 +81,7 @@ export default defineComponent({
this.alertMessage = this.$t('apiresponse.' + data.code, data.param); this.alertMessage = this.$t('apiresponse.' + data.code, data.param);
this.alertType = data.type; this.alertType = data.type;
this.showAlert = true; this.showAlert = true;
waitRestart(this.$router);
}); });
this.onCloseModal(this.performReboot); this.onCloseModal(this.performReboot);
}, },

View File

@ -0,0 +1,63 @@
<template>
<BasePage :title="$t('wait.NotReady')">
<CardElement :text="$t('wait.PleaseWait')" textVariant="text-bg-primary">
<div class="text-center">
<div class="spinner-border" role="status">
<span class="visually-hidden"></span>
</div>
</div>
</CardElement>
</BasePage>
</template>
<script lang="ts">
import BasePage from '@/components/BasePage.vue';
import CardElement from '@/components/CardElement.vue';
import { defineComponent } from 'vue';
export default defineComponent({
components: {
BasePage,
CardElement,
},
data() {
return {
hostCheckInterval: 0,
};
},
mounted() {
this.hostCheckInterval = setInterval(this.checkRemoteHostAndReload, 1000);
},
unmounted() {
clearInterval(this.hostCheckInterval);
},
methods: {
checkRemoteHostAndReload(): void {
// Check if the browser is online
if (navigator.onLine) {
const remoteHostUrl = '/api/system/status';
// Use a simple fetch request to check if the remote host is reachable
fetch(remoteHostUrl, { method: 'GET' })
.then((response) => {
// Check if the response status is OK (200-299 range)
if (response.ok) {
console.log('Remote host is available. Reloading page...');
clearInterval(this.hostCheckInterval);
this.hostCheckInterval = 0;
// Perform a page reload
window.location.replace('/');
} else {
console.log('Remote host is not reachable. Do something else if needed.');
}
})
.catch((error) => {
console.error('Error checking remote host:', error);
});
} else {
console.log('Browser is offline. Cannot check remote host.');
}
},
},
});
</script>