import { route as defineRouter } from 'quasar/wrappers'; import { createRouter, createMemoryHistory, createWebHistory, createWebHashHistory, } from 'vue-router'; import routes from './routes'; import { i18n } from 'src/boot/i18n'; import { useState } from 'src/composables/useState'; import { useRole } from 'src/composables/useRole'; import { useUserConfig } from 'src/composables/useUserConfig'; import { useTokenConfig } from 'src/composables/useTokenConfig'; import { useAcl } from 'src/composables/useAcl'; import { isLoggedIn } from 'src/utils/session'; import { useSession } from 'src/composables/useSession'; import { Notify } from 'quasar'; import { useStateStore } from 'stores/useStateStore'; let session = null; const { t, te } = i18n.global; const createHistory = process.env.SERVER ? createMemoryHistory : process.env.VUE_ROUTER_MODE === 'history' ? createWebHistory : createWebHashHistory; const Router = createRouter({ scrollBehavior: () => ({ left: 0, top: 0 }), routes, // Leave this as is and make changes in quasar.conf.js instead! // quasar.conf.js -> build -> vueRouterMode // quasar.conf.js -> build -> publicPath history: createHistory(process.env.VUE_ROUTER_BASE), }); /* * If not building with SSR mode, you can * directly export the Router instantiation; * * The function below can be async too; either use * async/await or return a Promise which resolves * with the Router instance. */ export { Router }; export default defineRouter(function (/* { store, ssrContext } */) { const state = useState(); Router.beforeEach(async (to, from, next) => { if (!session) session = useSession(); const outLayout = Router.options.routes[0].children.map((r) => r.name); if (!session.isLoggedIn() && !outLayout.includes(to.name)) { return next({ name: 'Login', query: { redirect: to.fullPath } }); } if (isLoggedIn()) { const stateRoles = state.getRoles().value; if (stateRoles.length === 0) { await useRole().fetch(); await useAcl().fetch(); await useUserConfig().fetch(); await useTokenConfig().fetch(); } const matches = to.matched; const hasRequiredAcls = matches.every((route) => { const meta = route.meta; if (!meta?.acls) return true; return useAcl().hasAny(meta.acls); }); if (!hasRequiredAcls) return next({ path: '/' }); } next(); }); Router.afterEach((to) => { let title = t(`login.title`); const matches = to.matched; if (matches && matches.length > 1) { const module = matches[1]; const moduleTitle = module.meta && module.meta.title; if (moduleTitle) { title = t(`globals.pageTitles.${moduleTitle}`); } } const childPage = to.meta; const childPageTitle = childPage && childPage.title; if (childPageTitle && matches.length > 2) { if (title != '') title += ': '; const moduleLocale = `globals.pageTitles.${childPageTitle}`; const pageTitle = te(moduleLocale) ? t(moduleLocale) : t(`globals.pageTitles.${childPageTitle}`); const idParam = to.params && to.params.id; const idPageTitle = `${idParam} - ${pageTitle}`; const builtTitle = idParam ? idPageTitle : pageTitle; title += builtTitle; } setTimeout(() => { state.set('error', true); }, 1000); document.title = title; }); Router.onError((error, to) => { if ( error.message.includes('Failed to fetch dynamically imported module') || error.message.includes('Importing a module script failed') ) { state.set('error', { message: t('globals.errorLoadingPage'), timeout: 5000, type: 'negative', }); Notify.create({ message: t('globals.noSelectedRows'), type: 'negative', timeout: 5000, progress: true, }); } }); return Router; });