feat: add error handling when calling the api failed

This commit is contained in:
kolaente 2021-10-31 21:41:30 +01:00
parent dc30de9176
commit e2cc505564
Signed by untrusted user: konrad
GPG Key ID: F40E70337AB24C9B
5 changed files with 122 additions and 67 deletions

View File

@ -1,40 +1,20 @@
<template>
<div class="no-auth-wrapper">
<div class="noauth-container">
<img alt="Vikunja" :src="logoUrl" width="400" height="117" />
<div class="message is-info" v-if="motd !== ''">
<div class="message-header">
<p>{{ $t('misc.info') }}</p>
</div>
<div class="message-body">
{{ motd }}
</div>
</div>
<router-view/>
</div>
</div>
<no-auth-wrapper>
<router-view/>
</no-auth-wrapper>
</template>
<script>
import {mapState} from 'vuex'
import logoUrl from '@/assets/logo-full.svg'
import { saveLastVisited } from '@/helpers/saveLastVisited'
import {saveLastVisited} from '@/helpers/saveLastVisited'
import NoAuthWrapper from '@/components/misc/no-auth-wrapper'
export default {
name: 'contentNoAuth',
data() {
return {
logoUrl,
}
},
components: {NoAuthWrapper},
computed: {
routeName() {
return this.$route.name
},
...mapState({
motd: state => state.config.motd,
}),
},
watch: {
routeName: {
@ -65,17 +45,3 @@ export default {
},
}
</script>
<style lang="scss" scoped>
.no-auth-wrapper {
background: url('@/assets/llama.svg') no-repeat bottom left fixed $light-background;
min-height: 100vh;
}
.noauth-container {
max-width: 450px;
width: 100%;
margin: 0 auto;
padding: 1rem;
}
</style>

View File

@ -70,30 +70,45 @@ export default {
return parseURL(this.apiUrl).host
},
},
props: {
configureOpen: {
type: Boolean,
required: false,
default: false,
},
},
watch: {
configureOpen: {
handler(value) {
this.configureApi = value
},
immediate: true,
},
},
methods: {
setApiUrl() {
async setApiUrl() {
if (this.apiUrl === '') {
return
}
checkAndSetApiUrl(this.apiUrl, () => this.$store.dispatch('config/update'))
.catch(() => {
// Still not found, url is still invalid
this.successMsg = ''
this.errorMsg = this.$t('apiConfig.error', {domain: this.apiDomain})
})
.then(url => {
if (url === '') {
return
}
try {
const url = await checkAndSetApiUrl(this.apiUrl, () => this.$store.dispatch('config/update'))
// Set it + save it to local storage to save us the hoops
this.errorMsg = ''
this.successMsg = this.$t('apiConfig.success', {domain: this.apiDomain})
this.configureApi = false
this.apiUrl = url
this.$emit('foundApi', this.apiUrl)
})
if (url === '') {
return
}
// Set it + save it to local storage to save us the hoops
this.errorMsg = ''
this.successMsg = this.$t('apiConfig.success', {domain: this.apiDomain})
this.configureApi = false
this.apiUrl = url
this.$emit('foundApi', this.apiUrl)
} catch (e) {
// Still not found, url is still invalid
this.successMsg = ''
this.errorMsg = this.$t('apiConfig.error', {domain: this.apiDomain})
}
},
},
}

View File

@ -0,0 +1,47 @@
<template>
<div class="no-auth-wrapper">
<div class="noauth-container">
<img alt="Vikunja" :src="logoUrl" width="400" height="117"/>
<div class="message is-info" v-if="motd !== ''">
<div class="message-header">
<p>{{ $t('misc.info') }}</p>
</div>
<div class="message-body">
{{ motd }}
</div>
</div>
<slot/>
</div>
</div>
</template>
<script>
import logoUrl from '@/assets/logo-full.svg'
import {mapState} from 'vuex'
export default {
name: 'no-auth-wrapper',
data() {
return {
logoUrl,
}
},
computed: mapState({
motd: state => state.config.motd,
}),
}
</script>
<style lang="scss" scoped>
.no-auth-wrapper {
background: url('@/assets/llama.svg') no-repeat bottom left fixed $light-background;
min-height: 100vh;
}
.noauth-container {
max-width: 450px;
width: 100%;
margin: 0 auto;
padding: 1rem;
}
</style>

View File

@ -3,23 +3,41 @@
<slot/>
</template>
<section v-else-if="error !== ''">
{{ error }}
<no-auth-wrapper>
<card>
<div class="notification is-danger">
<p>
{{ $t('ready.errorOccured') }}<br/>
{{ error }}
</p>
<p>
{{ $t('ready.checkApiUrl') }}
</p>
</div>
<api-config :configure-open="true" @found-api="load"/>
</card>
</no-auth-wrapper>
</section>
<section class="vikunja-loading" v-else>
<img alt="Vikunja" :src="logoUrl" width="100" height="100"/>
<p>
<span class="loader-container is-loading-small is-loading"></span>
{{ $t('home.vikunjaLoading') }}
{{ $t('ready.loading') }}
</p>
</section>
</template>
<script>
import logoUrl from '@/assets/logo.svg'
import {setLanguage} from '@/i18n'
import ApiConfig from '@/components/misc/api-config'
import NoAuthWrapper from '@/components/misc/no-auth-wrapper'
export default {
name: 'ready',
components: {
NoAuthWrapper,
ApiConfig,
},
data() {
return {
logoUrl,
@ -27,16 +45,21 @@ export default {
}
},
mounted() {
this.$store.dispatch('loadApp')
.catch(e => {
this.error = e
})
this.load()
},
computed: {
ready() {
return this.$store.state.vikunjaReady
},
},
methods: {
load() {
this.$store.dispatch('loadApp')
.catch(e => {
this.error = e
})
},
},
}
</script>

View File

@ -1,6 +1,5 @@
{
"home": {
"vikunjaLoading": "Vikunja is loading…",
"welcomeNight": "Good Night {username}",
"welcomeMorning": "Good Morning {username}",
"welcomeDay": "Hi {username}",
@ -17,6 +16,11 @@
"title": "Not found",
"text": "The page you requested does not exist."
},
"ready": {
"loading": "Vikunja is loading…",
"errorOccured": "An error occured:",
"checkApiUrl": "Please check if the api url is correct below."
},
"user": {
"auth": {
"username": "Username",
@ -777,7 +781,7 @@
"urlPlaceholder": "eg. https://localhost:3456",
"change": "change",
"signInOn": "Sign in to your Vikunja account on {0}",
"error": "Could not find or use Vikunja installation at \"{domain}\".",
"error": "Could not find or use Vikunja installation at \"{domain}\". Please try a different url.",
"success": "Using Vikunja installation at \"{domain}\"."
},
"loadingError": {