import { createWebHistory, createRouter } from "vue-router"; import { storeActions } from "@/constants/store-actions.js"; import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js"; import { routingTable } from "@/router/router-constants/routing-table.js"; import ComponentTest from "@/layouts/component-test/component-test.vue"; import LoaderDemo from "@/layouts/loader-demo/loader-demo.vue"; import NotFound from "@/layouts/not-found/not-found.vue"; import store from "@/store"; const routes = [ { path: "/:pathMatch(.*)*", component: NotFound, name: "NotFound", }, { path: "/component-test", // This is a temporary route for testing. name: "ComponentTest", component: ComponentTest, }, { path: "/loader-demo", // This is a temporary route for testing. name: "LoaderDemo", component: LoaderDemo, }, { path: "/", beforeEnter(to, from, next) { // If we have no query string, or we don't have the FmgPage query string. if (to.query.fmgPage === undefined) { RetainStructureAndGoTo404(to, next); } else { // If we already have our route, go to it. if (router.hasRoute(to.query.fmgPage)) { return next({ name: to.query.fmgPage, query: to.query, }); } // Get route info for the given url. Names will have a 1:1 relationship with names in the Cms. GetRouteInfoFromPageName(to.query.fmgPage) .then((routeData) => { // Add our dynamic route. router.addRoute({ path: routeData[0].path, // Always the same path, because we control it with query strings. name: routeData[0].name, component: routeData[0].component, }); // Assign current query string parameters, as well as our fmgPage one. next({ name: routeData[0].name, query: Object.assign(to.query, { fmgPage: routeData[0].name }), }); }) .catch((error) => { // If we can't find the route, go to the 404 page. RetainStructureAndGoTo404(to, next); console.log("error:"); console.log(error); }); } }, }, ]; const router = createRouter({ history: createWebHistory("/fmg/"), routes, }); //---------------------------------------------------------- Router Functions ---------------------------------------------------------- // Navigate to the next route, depending on the scenario. router.navigate = ( scenario, currentRoute, optionalQuery = {}, optionalParams = {} ) => { if (!scenario) { console.error("No scenario provided. Please review the routing table."); return; } // Match our maps up and navigate if we have a destination. const matchingScenarioMap = router.getNavigationMap(scenario, currentRoute); if (matchingScenarioMap.destinationFmgPageValue !== undefined) { // We're always pushing the same path, just changing query strings. Make sure our optional query strings get combined with our fmgPage one. router.push({ path: "/", query: Object.assign(optionalQuery, { fmgPage: matchingScenarioMap.destinationFmgPageValue, }), params: optionalParams, }); } else if (matchingScenarioMap.destinationUrl !== undefined) { navigateToUrl(matchingScenarioMap.destinationUrl); } }; // Get navigation map depeding on the scenario and the current 'page' you're on. router.getNavigationMap = (scenario, currentRoute) => { const fmgPageValue = currentRoute.query.fmgPage; const matchedQueryValue = routingTable .filter( (item) => item.fmgPageValue === fmgPageValue && item.maps.filter((map) => map.scenario === scenario).length > 0 ) .map((m) => m.maps.filter((map) => map.scenario === scenario)); return matchedQueryValue[0][0]; }; //---------------------------------------------------------- Private Functions ---------------------------------------------------------- // Navigate to an external url. function navigateToUrl(url) { // possibly show some loading screen in the future here. window.location.assign(url); } // Get route information by page name. // This will reach out to the Cms and there is a 1:1 relationship between page names and route names. function GetRouteInfoFromPageName(pageName) { return new Promise((resolve, reject) => { store .dispatch(storeActions.GET_ROUTE_INFO_ACTION, { pageName: pageName }) .then((response) => { // Add our route data and return our array. let jsonFromResponse = JSON.parse(response.data.Result); let routeData = []; Object.keys(jsonFromResponse).forEach((key) => { routeData.push({ path: "/", name: `${key}`, component: lazyLoadComponent(jsonFromResponse[key].LayoutName), }); }); resolve(routeData); }) .catch((error) => { reject(error); }); }); } // Go to our 404 page but retain our structure when we go there (path, queryString, hash). function RetainStructureAndGoTo404(to, next) { next({ name: "NotFound", params: { pathMatch: to.path.split("/").slice(1) }, query: to.query, hash: to.hash, }); } export default router;