import Vue from 'vue' import Vuex from 'vuex' import VuexPersistence from 'vuex-persist' import IUser from '@/models/IUser' import userService from '@/services/UserService' import couchService from '@/services/CouchService' import IResponse from '@/models/IResponse' import IUserPassword from '@/models/IUserPassword' import IIdPassword from '@/models/IEmailPassword' import notif from '@/utils/notif' import { hasGoodNetwork } from '@/utils/network' import { toHex } from './utils' Vue.use(Vuex) const SET_LOCALE: string = 'SET_LOCALE' const SET_TITLE: string = 'SET_TITLE' const SET_USER: string = 'SET_USER' const ADD_PUBLIC_ACCOUNT: string = 'ADD_PUBLIC_ACCOUNT' const REMOVE_PUBLIC_ACCOUNT: string = 'REMOVE_PUBLIC_ACCOUNT' interface IState { locale: string user: IUser | null hexUser: string | null title: string | null publicAccountIds: string[] } export default new Vuex.Store({ state: { locale: '', user: null, hexUser: null, title: null, publicAccountIds: [] }, getters: { locale: ({ locale }) => locale, user: ({ user }) => user, title: ({ title }) => title, username: (state: IState) => state.user ? state.user.firstname && state.user.lastname ? `${state.user.firstname} ${state.user.lastname}`.trim() : state.user.email : '', isAppAdmin: (state: IState) => state.user && state.user.roles && state.user.roles.find((role: string) => role === 'vaquant-admin'), publicAccountIds: ({ publicAccountIds }) => publicAccountIds }, mutations: { [SET_LOCALE](store, locale: string) { store.locale = locale }, [SET_TITLE](store, title: string | null) { store.title = title }, [SET_USER]( store, { user, replicate }: { user: IUser; replicate?: boolean } ) { store.user = user store.hexUser = user ? toHex(user.userId) : null couchService.setUser(user, store.hexUser, replicate || false) }, [ADD_PUBLIC_ACCOUNT](store, { accountId }: { accountId: string }) { if (!accountId) { return } store.publicAccountIds = [ ...new Set([...store.publicAccountIds, accountId]) ] }, [REMOVE_PUBLIC_ACCOUNT](store, { accountId }: { accountId: string }) { if (!accountId) { return } store.publicAccountIds = store.publicAccountIds.filter( (id: string) => id !== accountId && id !== null ) } }, actions: { setLocale({ commit }, locale: string) { commit(SET_LOCALE, locale) }, setTitle({ commit }, title: string) { commit(SET_TITLE, title) }, async retrieveUser({ commit, state }) { let user = state.user if (navigator.onLine && hasGoodNetwork()) { user = await userService.getUser(user) } commit(SET_USER, { user, replicate: false }) }, async signup({ commit }, { user, password, replicate }: IUserPassword) { const response: IResponse = await userService.signup(user, password) if (response.ok) { commit(SET_USER, { user, replicate }) } else { notif.error(response.message || '') } }, async login({ commit, state }, { userId, password }: IIdPassword) { const response: IResponse = await userService.login(userId, password) if (response.ok) { const user: IUser | null = await userService.getUser(state.user) commit(SET_USER, { user }) } else { notif.error(response.message || '') } }, async logout({ commit }) { const response = await userService.logout() if (response.ok) { commit(SET_USER, { user: null }) } else { notif.error(response.message || '') } }, async remove({ commit, state }) { if (state.user) { const response = await userService.deleteUser(state.user.userId) if (response.ok) { commit(SET_USER, { user: null }) } else { notif.error(response.message || '') } } }, addAccountId({ commit }, { accountId }: { accountId: string }) { commit(ADD_PUBLIC_ACCOUNT, { accountId }) }, removeAccountId({ commit }, { accountId }: { accountId: string }) { commit(REMOVE_PUBLIC_ACCOUNT, { accountId }) } }, plugins: [ new VuexPersistence({ storage: window.localStorage }).plugin ] })