import axios from '@/axios-client.js'; import Vue from 'vue'; import Vuex from 'vuex'; import router from '../router'; import modules from './modules'; Vue.use(Vuex); const noPermissions = { can_view_project: true, can_create_project: false, can_update_project: false, can_view_feature: true, can_view_archived_feature: true, can_create_feature: false, can_update_feature: false, can_delete_feature: false, can_publish_feature: false, can_create_feature_type: false, can_view_feature_type: true, is_project_administrator: false }; export default new Vuex.Store({ modules, state: { cancellableSearchRequest: [], configuration: null, isOnline: true, levelsPermissions: [], loader: { isLoading: false, message: 'En cours de chargement' }, logged: false, messageCount: 0, messages: [], reloadIntervalId: null, staticPages: null, user: false, USER_LEVEL_PROJECTS: null, user_permissions: null, userToken: null }, mutations: { SET_IS_ONLINE(state, payload) { state.isOnline = payload; }, SET_USER(state, payload) { state.user = payload; }, SET_CONFIG(state, payload) { state.configuration = payload; }, SET_COOKIE(state, cookie) { // ! not called anywhere. Delete it ? state.cookie = cookie; }, SET_STATIC_PAGES(state, staticPages) { state.staticPages = staticPages; }, SET_USER_LEVEL_PROJECTS(state, USER_LEVEL_PROJECTS) { state.USER_LEVEL_PROJECTS = USER_LEVEL_PROJECTS; }, SET_LOGGED(state, value) { state.logged = value; }, SET_USER_TOKEN(state, payload) { state.userToken = payload; }, SET_USER_PERMISSIONS(state, userPermissions) { state.user_permissions = userPermissions; }, SET_LEVELS_PERMISSIONS(state, levelsPermissions) { state.levelsPermissions = levelsPermissions; }, DISPLAY_MESSAGE(state, message) { message['counter'] = state.messageCount; state.messageCount += 1; state.messages = [message, ...state.messages]; // add new message at the beginning of the list if (document.getElementById('scroll-top-anchor')) { document.getElementById('scroll-top-anchor').scrollIntoView({ block: 'start', inline: 'nearest' }); } setTimeout(() => { state.messages = state.messages.slice(0, -1); // remove one message from the end of the list }, 3000); }, DISCARD_MESSAGE(state, messageCount) { state.messages = state.messages.filter((mess) => mess.counter !== messageCount); }, CLEAR_MESSAGES(state) { state.messages = []; }, DISPLAY_LOADER(state, message) { state.loader = { isLoading: true, message }; }, DISCARD_LOADER(state) { state.loader = { isLoading: false, message: 'En cours de chargement' }; }, SET_CANCELLABLE_SEARCH_REQUEST(state, payload) { state.cancellableSearchRequest.push(payload); }, RESET_CANCELLABLE_SEARCH_REQUEST(state) { state.cancellableSearchRequest = []; }, SET_RELOAD_INTERVAL_ID(state, payload) { state.reloadIntervalId = payload; }, CLEAR_RELOAD_INTERVAL_ID(state) { clearInterval(state.reloadIntervalId); state.reloadIntervalId = null; }, }, getters: { permissions: state => state.user_permissions && state.projects.project ? state.user_permissions[state.projects.project.slug] : noPermissions }, actions: { GET_STATIC_PAGES({ commit }) { return axios .get(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}flat-pages/`) .then((response) => (commit('SET_STATIC_PAGES', response.data))) .catch((error) => { throw error; }); }, LOGIN({ commit, dispatch }, payload) { if (payload.username && payload.password) { return axios .post(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}login/`, { username: payload.username, password: payload.password, }) .then((response) => { if (response.status === 200 && response.data) { commit('SET_USER', response.data.user); dispatch('REDIRECT_AFTER_LOGIN'); dispatch('GET_USER_LEVEL_PROJECTS'); dispatch('GET_USER_LEVEL_PERMISSIONS'); return response.status; } }) .catch(() => { commit('SET_USER', false); return 'error'; }); } }, REDIRECT_AFTER_LOGIN() { // * use stored previous route to go back after login if page not open on login at first let routerHistory = ''; if (router.options.routerHistory[0] !== undefined) { routerHistory = router.options.routerHistory[0].name !== 'login' ? router.options.routerHistory : '/'; } else { routerHistory = '/'; } const slug = router.history.current.params.slug; if (slug) { router.push({ name: 'project_detail', params: { slug } }).catch(() => { // prevent redundant navigation error console.error('Not critic: caught error from vue-router -> redundant navigation to same url.'); }); } else { //* not working at page load, routerHistory filled afterwards, could try history.back() router.push(routerHistory[routerHistory.length - 1] || '/').catch(() => { // prevent redundant navigation error console.error('Not critic: caught error from vue-router -> redundant navigation to same url.'); }); } }, async GET_USER_INFO({ state, commit, dispatch }) { const token = new URLSearchParams(window.location.search).get('token'); if (token && this.state.configuration.VUE_APP_LOGIN_URL) { // if user was previously connected through SSO, make sure he's logout before connecting through SSO, in case user changed await dispatch('LOGOUT'); dispatch('CONNECT_SSO_WITH_TOKEN', token); } else if (!state.user) { axios .get(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}user_info/`) .then((response) => { if (response && response.status === 200) { const user = response.data.user; commit('SET_USER', user); } }) .catch((err) => { console.error(err); commit('DISPLAY_MESSAGE', { comment: `Vous n'êtes pas connecté actuellement. Vous pouvez accéder à l'application en tant qu'utilisateur anonyme` }); }); } }, async CONNECT_SSO_WITH_TOKEN({ state, commit, dispatch }, token) { axios .get(`${state.configuration.VUE_APP_DJANGO_API_BASE}login-token/?token=${token}`) .then((response) => { if (response && (response.status === 200 || response.status === 201)) { const user = response.data; commit('SET_USER', user); dispatch('GET_USER_LEVEL_PROJECTS'); dispatch('GET_USER_LEVEL_PERMISSIONS'); commit('DISPLAY_MESSAGE', { comment: `Vous êtes maintenant connecté ${ user.first_name} ${ user.last_name}`, level: 'positive' }); dispatch('projects/GET_PROJECTS'); } }) .catch((err) => { console.error(err); commit('DISPLAY_MESSAGE', { comment: 'La connexion a échoué.', level: 'negative' }); }); }, async GET_USER_TOKEN({ state, commit }) { const response = await axios.get(`${state.configuration.VUE_APP_DJANGO_API_BASE}get-token`); if ( response.status === 200 && response.data ) { commit('SET_USER_TOKEN', response.data); } }, LOGOUT({ state, commit, dispatch }) { return axios .get(`${state.configuration.VUE_APP_DJANGO_API_BASE}logout/`) .then((response) => { if (response && response.status === 200) { commit('SET_USER', false); commit('SET_USER_LEVEL_PROJECTS', null); dispatch('GET_USER_LEVEL_PERMISSIONS'); if (router.history.current.name !== 'index' && !window.location.pathname.includes('projet-partage') && !state.configuration.VUE_APP_LOGIN_URL ) { router.push('/'); } } }) .catch((error) => { console.error(error); }); }, GET_CONFIG({ commit }) { axios .get('./config/config.json') .then((response) => { if (response && response.status === 200) { commit('SET_CONFIG', response.data); } }) .catch((error) => { throw error; }); }, GET_USER_LEVEL_PROJECTS({ commit }) { return axios .get(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}user-level-projects/`) .then((response) => { if (response && response.status === 200) { commit('SET_USER_LEVEL_PROJECTS', response.data); } }) .catch((error) => { throw error; }); }, GET_USER_LEVEL_PERMISSIONS({ commit }) { return axios .get(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}user-permissions/`) .then((response) => { if (response && response.status === 200) { commit('SET_USER_PERMISSIONS', response.data); } }) .catch((error) => { throw error; }); }, GET_LEVELS_PERMISSIONS({ commit }) { return axios .get(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}v2/levels-permissions/`) .then((response) => { if (response && response.status === 200) { commit('SET_LEVELS_PERMISSIONS', response.data); } }) .catch((error) => { throw error; }); }, CANCEL_CURRENT_SEARCH_REQUEST({ state }) { if (state.cancellableSearchRequest.length > 0) { const currentRequestCancelToken = state.cancellableSearchRequest[state.cancellableSearchRequest.length - 1]; currentRequestCancelToken.cancel('Current search request was canceled'); } }, } });