Add warning if backend is offline (implements #416)
This commit is contained in:
parent
458cf81a91
commit
e566a89860
|
@ -27,14 +27,18 @@ export default boot<Store<StateInterface>>(({ Vue, store }) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* Intercept responses, filter 401 and logout
|
* Intercept responses
|
||||||
|
* - filter 401 --> logout
|
||||||
|
* - filter timeout or 502 --> backendOffline
|
||||||
*/
|
*/
|
||||||
axios.interceptors.response.use(
|
axios.interceptors.response.use(
|
||||||
response => response,
|
response => response,
|
||||||
error => {
|
error => {
|
||||||
if (error && 'response' in error) {
|
if (error) {
|
||||||
const e = <AxiosError>error;
|
const e = <AxiosError>error;
|
||||||
if (e.response && e.response.status == 401) {
|
if (e.code === 'ECONNABORTED' || e.response && e.response.status === 502) {
|
||||||
|
store.commit('session/setOffline', true);
|
||||||
|
} else if (e.response && e.response.status == 401) {
|
||||||
return store.dispatch('session/clearup');
|
return store.dispatch('session/clearup');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
<template>
|
||||||
|
<div class="q-pa-md q-gutter-sm">
|
||||||
|
<q-dialog
|
||||||
|
v-model="offline"
|
||||||
|
persistent
|
||||||
|
transition-show="scale"
|
||||||
|
transition-hide="scale"
|
||||||
|
>
|
||||||
|
<q-card style="width: 400px">
|
||||||
|
<q-card-section class="bg-negative text-white">
|
||||||
|
<div class="text-h6 col-12">Backend offline</div>
|
||||||
|
</q-card-section>
|
||||||
|
|
||||||
|
<q-card-section>
|
||||||
|
<span>Es scheint, dass das Backend aktuell offline ist.</span>
|
||||||
|
</q-card-section>
|
||||||
|
|
||||||
|
<q-card-actions align="right" class="bg-white text-negative">
|
||||||
|
<q-btn flat label="Erneut versuchen" v-close-popup @click="reload" />
|
||||||
|
</q-card-actions>
|
||||||
|
</q-card>
|
||||||
|
</q-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { computed, defineComponent } from '@vue/composition-api';
|
||||||
|
import { Store } from 'vuex';
|
||||||
|
import { StateInterface } from 'src/store';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'BackendOffline',
|
||||||
|
setup(_, { root }) {
|
||||||
|
const offline = computed(
|
||||||
|
() => (<Store<StateInterface>>root.$store).state.session.backendOffline
|
||||||
|
);
|
||||||
|
|
||||||
|
const reload = function() {
|
||||||
|
root.$store.commit('session/setOffline', false);
|
||||||
|
root.$router.go(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
return { offline, reload };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -15,8 +15,6 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent } from '@vue/composition-api';
|
import { computed, defineComponent } from '@vue/composition-api';
|
||||||
import { Store } from 'vuex';
|
|
||||||
import { StateInterface } from 'src/store';
|
|
||||||
import { hasPermissions } from 'src/components/permission';
|
import { hasPermissions } from 'src/components/permission';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
|
|
|
@ -4,8 +4,6 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent } from '@vue/composition-api';
|
import { computed, defineComponent } from '@vue/composition-api';
|
||||||
import { Store } from 'vuex';
|
|
||||||
import { StateInterface } from 'src/store';
|
|
||||||
import { hasPermissions } from 'src/components/permission';
|
import { hasPermissions } from 'src/components/permission';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
|
|
|
@ -93,6 +93,8 @@
|
||||||
/>
|
/>
|
||||||
</q-drawer>
|
</q-drawer>
|
||||||
|
|
||||||
|
<BackendOffline />
|
||||||
|
|
||||||
<q-page-container>
|
<q-page-container>
|
||||||
<router-view />
|
<router-view />
|
||||||
</q-page-container>
|
</q-page-container>
|
||||||
|
@ -102,6 +104,7 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import EssentialLink from 'components/navigation/EssentialLink.vue';
|
import EssentialLink from 'components/navigation/EssentialLink.vue';
|
||||||
import ShortCutLink from 'components/navigation/ShortCutLink.vue';
|
import ShortCutLink from 'components/navigation/ShortCutLink.vue';
|
||||||
|
import BackendOffline from 'components/loading/BackendOffline.vue';
|
||||||
import { Screen } from 'quasar';
|
import { Screen } from 'quasar';
|
||||||
import { defineComponent, ref, computed } from '@vue/composition-api';
|
import { defineComponent, ref, computed } from '@vue/composition-api';
|
||||||
import { Store } from 'vuex';
|
import { Store } from 'vuex';
|
||||||
|
@ -140,7 +143,7 @@ declare module 'vue/types/vue' {
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'MainLayout',
|
name: 'MainLayout',
|
||||||
components: { EssentialLink, ShortCutLink },
|
components: { EssentialLink, ShortCutLink, BackendOffline },
|
||||||
setup(_, ctx) {
|
setup(_, ctx) {
|
||||||
const leftDrawer = ref(false);
|
const leftDrawer = ref(false);
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<q-layout view="hHh lpr lFf">
|
<q-layout view="hHh lpr lFf">
|
||||||
<!-- Be sure to play with the Layout demo on docs -->
|
|
||||||
|
|
||||||
<!-- (Optional) The Header -->
|
|
||||||
<q-header elevated>
|
<q-header elevated>
|
||||||
<q-toolbar>
|
<q-toolbar>
|
||||||
<q-toolbar-title>
|
<q-toolbar-title>
|
||||||
|
@ -40,12 +37,9 @@
|
||||||
</q-toolbar>
|
</q-toolbar>
|
||||||
</q-header>
|
</q-header>
|
||||||
|
|
||||||
<!-- (Optional) The Footer -->
|
<BackendOffline />
|
||||||
|
|
||||||
<!-- (Optional) A Drawer; you can add one more with side="right" or change this one's side -->
|
|
||||||
|
|
||||||
<q-page-container>
|
<q-page-container>
|
||||||
<!-- This is where pages get injected -->
|
|
||||||
<router-view />
|
<router-view />
|
||||||
</q-page-container>
|
</q-page-container>
|
||||||
</q-layout>
|
</q-layout>
|
||||||
|
@ -54,8 +48,10 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from '@vue/composition-api';
|
import { defineComponent } from '@vue/composition-api';
|
||||||
import ShortCutLink from 'components/navigation/ShortCutLink.vue';
|
import ShortCutLink from 'components/navigation/ShortCutLink.vue';
|
||||||
|
import BackendOffline from 'components/loading/BackendOffline.vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'OutLayout',
|
name: 'OutLayout',
|
||||||
components: { ShortCutLink }
|
components: { ShortCutLink, BackendOffline }
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -10,6 +10,7 @@ export interface SessionInterface {
|
||||||
currentSession?: FG.Session;
|
currentSession?: FG.Session;
|
||||||
sessions: FG.Session[];
|
sessions: FG.Session[];
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
|
backendOffline: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadFromLocal() {
|
function loadFromLocal() {
|
||||||
|
@ -21,7 +22,8 @@ function loadFromLocal() {
|
||||||
const state: SessionInterface = {
|
const state: SessionInterface = {
|
||||||
sessions: [],
|
sessions: [],
|
||||||
currentSession: loadFromLocal() || undefined,
|
currentSession: loadFromLocal() || undefined,
|
||||||
loading: false
|
loading: false,
|
||||||
|
backendOffline: false
|
||||||
};
|
};
|
||||||
|
|
||||||
const mutations: MutationTree<SessionInterface> = {
|
const mutations: MutationTree<SessionInterface> = {
|
||||||
|
@ -38,6 +40,9 @@ const mutations: MutationTree<SessionInterface> = {
|
||||||
},
|
},
|
||||||
setLoading(state, value: boolean) {
|
setLoading(state, value: boolean) {
|
||||||
state.loading = value;
|
state.loading = value;
|
||||||
|
},
|
||||||
|
setOffline(state, value: boolean) {
|
||||||
|
state.backendOffline = value;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue