Add offline overlay if backend cannot be reached
This commit is contained in:
+35
-2
@@ -1,12 +1,13 @@
|
||||
<script setup>
|
||||
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { Notification } from 'pankow';
|
||||
import { onMounted, ref, useTemplateRef } from 'vue';
|
||||
import { Notification, fetcher } from 'pankow';
|
||||
import { API_ORIGIN, TOKEN_TYPES } from './constants.js';
|
||||
import ProfileModel from './models/ProfileModel.js';
|
||||
import DashboardModel from './models/DashboardModel.js';
|
||||
import Sidebar from './components/Sidebar.vue';
|
||||
import Headerbar from './components/Headerbar.vue';
|
||||
import OfflineOverlay from './components/OfflineOverlay.vue';
|
||||
import AppsView from './views/AppsView.vue';
|
||||
import AppConfigureView from './views/AppConfigureView.vue';
|
||||
import AppstoreView from './views/AppstoreView.vue';
|
||||
@@ -53,6 +54,37 @@ const VIEWS = {
|
||||
VOLUMES: 'volumes',
|
||||
};
|
||||
|
||||
const offlineOverlay = useTemplateRef('offlineOverlay');
|
||||
|
||||
function onOnline() {
|
||||
ready.value = true;
|
||||
}
|
||||
|
||||
fetcher.globalOptions.errorHook = (error) => {
|
||||
// network error, request killed by browser
|
||||
if (error instanceof TypeError) {
|
||||
ready.value = false;
|
||||
return offlineOverlay.value.open();
|
||||
}
|
||||
|
||||
// // re-login will make the code get a new token
|
||||
// if (status === 401) return client.login();
|
||||
|
||||
if (error.status === 500 || error.status === 501) {
|
||||
// actual internal server error, most likely a bug or timeout log to console only to not alert the user
|
||||
if (!ready.value) {
|
||||
console.error(error);
|
||||
console.log('------\nCloudron Internal Error\n\nIf you see this, please send a mail with above log to support@cloudron.io\n------\n');
|
||||
}
|
||||
}
|
||||
|
||||
if (error.status >= 500) {
|
||||
// This means the box service is not reachable. We just show offline banner for now
|
||||
ready.value = false;
|
||||
return offlineOverlay.value.open();
|
||||
}
|
||||
};
|
||||
|
||||
const dashboardModel = DashboardModel.create();
|
||||
const profileModel = ProfileModel.create();
|
||||
|
||||
@@ -147,6 +179,7 @@ onMounted(async () => {
|
||||
<template>
|
||||
<div style="overflow: hidden; height: 100%;">
|
||||
<Notification />
|
||||
<OfflineOverlay ref="offlineOverlay" @online="onOnline()"/>
|
||||
|
||||
<Transition name="pankow-animation-pop-up">
|
||||
<div v-if="ready" style="display: flex; flex-direction: row; overflow: hidden; height: 100%;">
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
<script setup>
|
||||
|
||||
import { useTemplateRef, ref } from 'vue';
|
||||
import { fetcher, Spinner, Dialog } from 'pankow';
|
||||
import { API_ORIGIN } from '../constants.js';
|
||||
|
||||
const emits = defineEmits(['online']);
|
||||
|
||||
const dialog = useTemplateRef('dialog');
|
||||
const isOpen = ref(false);
|
||||
|
||||
async function waitForOnline() {
|
||||
let result;
|
||||
try {
|
||||
result = await fetcher.get(`${API_ORIGIN}/api/v1/cloudron/status`, {});
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
} catch (e) {
|
||||
return setTimeout(waitForOnline, 5000);
|
||||
}
|
||||
|
||||
if (result.status !== 200) return setTimeout(waitForOnline, 5000);
|
||||
|
||||
// back online
|
||||
emits('online');
|
||||
dialog.value.close();
|
||||
isOpen.value = false;
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
open() {
|
||||
if (isOpen.value) return;
|
||||
|
||||
isOpen.value = true;
|
||||
|
||||
dialog.value.open();
|
||||
waitForOnline();
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Dialog ref="dialog" :modal="true">
|
||||
<div style="display: flex; flex-direction: column; align-items: center;">
|
||||
<Spinner class="pankow-spinner-large" style="margin: 20px"/>
|
||||
<a href="https://docs.cloudron.io/troubleshooting/" target="_blank">{{ $t('main.offline') }}</a>
|
||||
</div>
|
||||
</Dialog>
|
||||
</template>
|
||||
Reference in New Issue
Block a user