import Vue from 'vue'; import VueRouter from 'vue-router'; import ProjectsList from '../views/Projects/ProjectsList.vue'; import store from '@/store'; import featureAPI from '@/services/feature-api'; Vue.use(VueRouter); let projectBase = 'projet'; if (window.location.pathname.includes('projet-partage')) { projectBase = 'projet-partage'; } const routes = [ { path: '/', name: 'index', component: ProjectsList }, { path: `${projectBase === 'projet' ? '': `/${projectBase}/:slug`}/connexion/`, name: 'login', component: () => import('../views/Login.vue') }, { path: `${projectBase === 'projet' ? '': `/${projectBase}/:slug`}/my_account/`, name: 'my_account', component: () => import('../views/Account.vue') }, { path: `${projectBase === 'projet' ? '': '/' + projectBase}/mentions/`, name: 'mentions', component: () => import('../views/FlatPages/LegalMentions.vue') }, { path: `${projectBase === 'projet' ? '': '/' + projectBase}/aide/`, name: 'aide', component: () => import('../views/FlatPages/Help.vue') }, // * PROJECT { path: '/creer-projet/', name: 'project_create', component: () => import('../views/Project/ProjectEdit.vue') }, { path: `/${projectBase}/:slug`, name: 'project_detail', props: true, component: () => import('../views/Project/ProjectDetail.vue'), }, { path: `/${projectBase}/:slug/signalement/lister/`, name: 'liste-signalements', component: () => import('../views/Project/FeaturesListAndMap.vue') }, { path: `/${projectBase}/:slug/editer`, name: 'project_edit', component: () => import('../views/Project/ProjectEdit.vue') }, { path: '/projet-type/', name: 'project_type_list', component: () => import('../views/Projects/ProjectsTypes.vue') }, { path: '/creer-projet/create_from/:slug/', name: 'project_create_from', component: () => import('../views/Project/ProjectEdit.vue') }, { path: `/${projectBase}/:slug/administration-carte/`, name: 'project_mapping', component: () => import('../views/Project/ProjectBasemaps.vue') }, { path: `/${projectBase}/:slug/membres/`, name: 'project_members', component: () => import('../views/Project/ProjectMembers.vue') }, { path: `/${projectBase}/:slug/signalement-filtre/`, name: 'details-signalement-filtre', component: () => import('../views/Feature/FeatureDetail.vue') }, // * FEATURE TYPE { path: `/${projectBase}/:slug/type-signalement/ajouter/`, name: 'ajouter-type-signalement', props: true, component: () => import('../views/FeatureType/FeatureTypeEdit.vue') }, { path: `/${projectBase}/:slug/type-signalement/ajouter/create_from/:slug_type_signal`, name: 'dupliquer-type-signalement', component: () => import('../views/FeatureType/FeatureTypeEdit.vue') }, { path: `/${projectBase}/:slug/type-signalement/:feature_type_slug/`, name: 'details-type-signalement', component: () => import('../views/FeatureType/FeatureTypeDetail.vue') }, { path: `/${projectBase}/:slug/type-signalement/:slug_type_signal/editer/`, name: 'editer-type-signalement', component: () => import('../views/FeatureType/FeatureTypeEdit.vue') }, { path: `/${projectBase}/:slug/type-signalement/:slug_type_signal/affichage/`, name: 'editer-affichage-signalement', component: () => import('../views/FeatureType/FeatureTypeDisplay.vue') }, // * FEATURE { path: `/${projectBase}/:slug/type-signalement/:slug_type_signal/signalement/ajouter/`, name: 'ajouter-signalement', component: () => import('../views/Feature/FeatureEdit.vue') }, { path: `/${projectBase}/:slug/type-signalement/:slug_type_signal/signalement/:slug_signal`, name: 'details-signalement', component: () => import('../views/Feature/FeatureDetail.vue'), /** * Handles routing logic before entering the details-signalement route. * This function manages access and navigation based on user permissions and feature data. */ beforeEnter: async (to, from, next) => { try { const { slug, slug_type_signal, slug_signal } = to.params; // Retrieve the project details from the store const project = await store.dispatch('projects/GET_PROJECT', slug); // Prepare query based on the project settings for feature browsing const query = { ordering: project.feature_browsing_default_sort }; // Check if the default filter of the project is set to feature_type and apply it if (project.feature_browsing_default_filter) { // when feature_type is the default filter of the project, query['feature_type_slug'] = slug_type_signal; // set feature_type slug in query } // Get the feature's position based on the feature slug and query settings const offset = await featureAPI.getFeaturePosition(slug, slug_signal, query); // Decide next routing based on the offset result if (offset >= 0) { next({ name: 'details-signalement-filtre', params: { slug }, query: { ...query, offset } }); } else if (offset === 'No Content') { // API return no content when user is not allowed to see the feature or isn't connected if (store.state.user) { // If the user is connected, display information that he's not allowed to view the feature store.commit('DISPLAY_MESSAGE', { comment: 'Vous n\'avez pas accès à ce signalement avec cet utilisateur', level: 'negative' }); // and redirect to main page next({ path: '/' }); } else { // If the user is not connected, remove other messages to avoid displaying twice that the user is not connected store.commit('CLEAR_MESSAGES'); // display information that user need to be connected store.commit('DISPLAY_MESSAGE', { comment: 'Vous n\'avez pas accès à ce signalement hors connexion, veuillez-vous connecter au préalable', level: 'negative' }); // Then redirect to login page if (store.state.configuration.VUE_APP_LOGIN_URL) { // If the login is through SSO, redirect to external login page (if the instance accepts a redirect_url it would be caught before when requesting user_info with GET_USER_INFO) setTimeout(() => { // delay switching page to allow the info message to be read by user window.open(store.state.configuration.VUE_APP_LOGIN_URL); }, 1500); } else { // In a classic installation, redirect to the login page of this application next({ name: 'login' }); } } } else { store.commit('DISPLAY_MESSAGE', { comment: 'Désolé, une erreur est survenue pendant la recherche du signalement', level: 'negative' }); next({ path: '/' }); } } catch (error) { console.error('error', error); store.commit('DISPLAY_MESSAGE', { comment: `Désolé, une erreur est survenue pendant la recherche du signalement - ${error}`, level: 'negative' }); next({ path: '/' }); } } }, { path: `/${projectBase}/:slug/type-signalement/:slug_type_signal/offline`, name: 'offline-signalement', component: () => import('../views/Feature/FeatureOffline.vue') }, { path: `/${projectBase}/:slug/type-signalement/:slug_type_signal/signalement/:slug_signal/editer/`, name: 'editer-signalement', component: () => import('../views/Feature/FeatureEdit.vue') }, { path: `/${projectBase}/:slug/type-signalement/:slug_type_signal/editer-signalements-attributs/`, name: 'editer-attribut-signalement', component: () => import('../views/Feature/FeatureEdit.vue') }, { path: '/projet/:slug/catalog/:feature_type_slug', name: 'catalog-import', component: () => import('../views/Catalog.vue') }, { path: '/projet/:slug/type-signalement/:slug_type_signal/signalement/:slug_signal/attachment-preview/', name: 'attachment-preview', component: () => import('../views/AttachmentPreview.vue') }, { path: '/:pathMatch(.*)*', name: 'NotFound', component: () => import('../views/NotFound.vue') }, ]; const router = new VueRouter({ mode: 'history', base: '/geocontrib/', routes, routerHistory: [], scrollBehavior(to, from, savedPosition) { //* record each route change to keep scroll position const fromHistory = Boolean(savedPosition); if (fromHistory && this.options.routerHistory.length > 0) { this.options.routerHistory.splice(-1, 1); } else { this.options.routerHistory.push(from); } return savedPosition || { x: 0, y: 0 }; }, }); export default router;