import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router'; import { useUserStore } from '@KTXC/stores/userStore'; import { useLayoutStore } from '@KTXC/stores/layoutStore'; import BlankLayout from '@KTXC/layouts/blank/BlankLayout.vue'; import PrivateLayout from '@KTXC/views/PrivateLayout.vue'; import { usePreferencesStore } from '@KTXC/stores/preferencesStore'; import { useIntegrationStore } from '@KTXC/stores/integrationStore'; const routes: RouteRecordRaw[] = [ // Public login route { name: 'login', path: '/login', meta: { requiresAuth: false }, component: BlankLayout, children: [ { path: '', component: () => import('@KTXC/views/authentication/LoginPage.vue') } ] }, // Logout performs action then redirects { name: 'logout', path: '/logout', meta: { requiresAuth: true }, component: BlankLayout, beforeEnter: async () => { const userStore = useUserStore(); await userStore.logout(); return false; } }, // Private area (shell layout). Module routes under /m/{namespace} are added at runtime. { name: 'private', path: '/', component: PrivateLayout, meta: { requiresAuth: true }, children: [ // Index redirects to the first available module route (if any) { name: 'home', path: '', meta: { requiresAuth: true }, component: BlankLayout, beforeEnter: (to, from, next) => { const integrationStore = useIntegrationStore(); const preferences = usePreferencesStore(); // Treat preference as a route name (e.g., "samples.overview") const preferredRouteName = preferences.preferences.default_module; if (preferredRouteName) { // If a route with this name exists, go there try { // using router variable at runtime: // eslint-disable-next-line @typescript-eslint/no-use-before-define const exists = router.getRoutes().some(r => r.name === preferredRouteName); if (exists) return next({ name: preferredRouteName }); } catch {} } // Get first available menu item from app_menu const entries = integrationStore.getPoint('app_menu'); for (const entry of entries) { // Check if it's a group with items if ('items' in entry && entry.items.length > 0) { const first = entry.items[0]?.to; if (first) return next(first); } // Or a standalone item if ('to' in entry && entry.to) { return next(entry.to); } } return next(); } } ] } ]; export const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes }); router.beforeEach(async (to, from, next) => { const userStore = useUserStore(); const authRequired = to.matched.some((record) => record.meta?.requiresAuth); if (authRequired && !userStore.user && to.path !== '/login') { userStore.returnUrl = to.fullPath; return next('/login'); } if (userStore.user && to.path === '/login') { const dest = userStore.returnUrl && userStore.returnUrl !== '/' ? userStore.returnUrl : '/'; return next(dest); } return next(); }); router.beforeEach(() => { const layoutStore = useLayoutStore(); layoutStore.isLoading = true; }); router.afterEach(() => { const layoutStore = useLayoutStore(); layoutStore.isLoading = false; }); export default router