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

View file

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

View file

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

View file

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