rework store and add actions to mutate connected state

This commit is contained in:
Axolotle 2020-08-27 18:30:45 +02:00
parent 33a0820c4b
commit d3f112ac06
7 changed files with 97 additions and 33 deletions

View file

@ -42,7 +42,7 @@
<b-nav-item href="https://donate.yunohost.org/" target="_blank" link-classes="text-secondary">
<icon iname="heart" /> Donate
</b-nav-item>
<i18n v-if="yunohostInfos" path="footer_version" tag="b-nav-text"
<i18n v-if="yunohost" path="footer_version" tag="b-nav-text"
id="yunohost-version" class="ml-auto"
>
<template v-slot:ynh>
@ -51,10 +51,10 @@
</b-link>
</template>
<template v-slot:version>
{{ yunohostInfos.version }}
{{ yunohost.version }}
</template>
<template v-slot:repo>
{{ yunohostInfos.repo }}
{{ yunohost.repo }}
</template>
</i18n>
</b-nav>
@ -64,9 +64,7 @@
</template>
<script>
import { mapState } from 'vuex'
import api from '@/helpers/api'
import { mapGetters } from 'vuex'
export default {
name: 'App',
@ -78,38 +76,40 @@ export default {
}
},
computed: {
...mapState(['connected', 'yunohostInfos'])
...mapGetters(['connected', 'yunohost'])
},
methods: {
async logout () {
await api.logout()
this.$store.commit('CONNECTED', false)
this.$router.push('/login')
this.$store.dispatch('LOGOUT').then(() => {
this.$router.push({ name: 'login' })
})
}
},
// This hook is only triggered at page reload so the value of state.connected
// always come from the localStorage
async created () {
if (!this.$store.state.connected) {
if (!this.connected) {
// user is not connected: allow the login view to be rendered.
this.isReady = true
return
}
// localStorage 'connected' value may be true, but session may have expired.
// Try to get the yunohost version.
try {
const data = await api.getVersion()
this.$store.commit('YUNOHOST_INFOS', data.yunohost)
} catch (err) {
this.$store.dispatch(
'GET_YUNOHOST_INFOS'
).catch(() => {
// Session expired, reset the 'connected' state and redirect with a query
// FIXME is there a case where the error may not be a 401 therefor requires
// better handling ?
this.$store.commit('CONNECTED', false)
this.$router.push({ name: 'login', query: { redirect: this.$route.path } })
} finally {
this.$store.dispatch('RESET_CONNECTED')
this.$router.push({
name: 'login',
query: { redirect: this.$route.path !== '/login' ? this.$route.path : '/' }
})
}).finally(() => {
// in any case allow the router-view to be rendered
this.isReady = true
}
})
}
}
</script>

View file

@ -3,7 +3,7 @@ import App from './App.vue'
import './plugins/bootstrap-vue'
import i18n from './plugins/i18n'
import router from './plugins/router'
import store from './plugins/store'
import store from './store'
import * as globalsComponents from './components/globals'

View file

@ -1,7 +1,7 @@
import Vue from 'vue'
import VueRouter from 'vue-router'
import routes from '../routes'
import store from './store'
import store from '@/store'
Vue.use(VueRouter)
@ -14,7 +14,7 @@ const router = new VueRouter({
// Before each route request hook
router.beforeEach((to, from, next) => {
// Allow if connected or route is not protected
if (store.state.connected || to.meta.noAuth) {
if (store.getters.connected || to.meta.noAuth) {
next()
} else {
next({ name: 'login', query: { redirect: to.path } })

View file

@ -1,5 +1,5 @@
import Vue from 'vue'
import api from './api'
import api from '@/helpers/api'
export default {
state: () => ({

14
app/src/store/index.js Normal file
View file

@ -0,0 +1,14 @@
import Vue from 'vue'
import Vuex from 'vuex'
import info from './info'
import data from './data'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
info,
data
}
})

52
app/src/store/info.js Normal file
View file

@ -0,0 +1,52 @@
import api from '@/helpers/api'
export default {
state: {
connected: localStorage.getItem('connected') === 'true',
yunohost: null // yunohost app infos: Object {version, repo}
},
mutations: {
'SET_CONNECTED' (state, connected) {
localStorage.setItem('connected', connected)
state.connected = connected
},
'SET_YUNOHOST_INFOS' (state, yunohost) {
state.yunohost = yunohost
}
},
actions: {
'LOGIN' ({ commit }, password) {
return api.post('login', { password }).then(() => {
commit('SET_CONNECTED', true)
}).catch(err => {
commit('SET_CONNECTED', false)
throw err
})
},
'RESET_CONNECTED' ({ commit }) {
commit('SET_CONNECTED', false)
commit('SET_YUNOHOST_INFOS', null)
},
'LOGOUT' ({ dispatch }) {
return api.get('logout').then(() => {
dispatch('RESET_CONNECTED')
})
},
'GET_YUNOHOST_INFOS' ({ commit }) {
return api.get('versions').then(versions => {
commit('SET_YUNOHOST_INFOS', versions.yunohost)
})
}
},
getters: {
connected: state => (state.connected),
yunohost: state => (state.yunohost)
}
}

View file

@ -27,28 +27,26 @@
</template>
<script>
import api from '@/helpers/api'
export default {
name: 'Login',
data: () => {
return {
password: '',
isValid: null
}
},
methods: {
async login () {
const connected = await api.login(this.password)
if (connected) {
this.$store.commit('CONNECTED', true)
this.$store.dispatch(
'LOGIN', this.password
).then(() => {
this.$store.dispatch('GET_YUNOHOST_INFOS')
this.$router.push(this.$route.query.redirect || '/')
const infos = await api.getVersion()
this.$store.commit('YUNOHOST_INFOS', infos.yunohost)
} else {
this.$store.commit('CONNECTED', false)
}).catch(() => {
this.isValid = false
}
})
}
}
// TODO checkInstall