256 lines
No EOL
8.2 KiB
JavaScript
256 lines
No EOL
8.2 KiB
JavaScript
import { createWebHistory, createRouter } from "vue-router";
|
|
import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader";
|
|
import {issPageValues} from '@/router/router-constants/issPage-values';
|
|
import { routingTable } from "@/router/router-constants/routing-table";
|
|
import { useMainStore } from '@/store';
|
|
import eventBus from "@/helpers/event-bus/event-bus";
|
|
import { globalEvents, globalEventTypes } from "@/constants/events";
|
|
import baseMixin from "@/mixins/base-mixin";
|
|
import {
|
|
getDeviceIdValue,
|
|
updateOrCreateISSCookie,
|
|
updateSessionIdCookie,
|
|
} from "@/helpers/cookie-helper";
|
|
import { experimentTriggers } from "@/constants/experiments";
|
|
import { applicationConfig } from "@/constants/application-config";
|
|
|
|
import analyticsMixin from "@/mixins/analytics-mixin";
|
|
|
|
const routes = [
|
|
{
|
|
path: '/',
|
|
name: 'root',
|
|
async beforeEnter(to, from, next) {
|
|
try {
|
|
to.query.issPage = !to.query.issPage ? issPageValues.VEHICLE_YEAR : to.query.issPage;
|
|
|
|
if (analyticsMixin.methods.noSession()) {
|
|
await analyticsMixin.methods.initSession();
|
|
} else {
|
|
updateSessionIdCookie();
|
|
}
|
|
|
|
await runExperiments(to.query.issPage);
|
|
|
|
// Process ISS cookie.
|
|
updateOrCreateISSCookie();
|
|
|
|
if (router.hasRoute(to.query.issPage)) {
|
|
return next({ name: to.query.issPage, query: to.query, params: to.params });
|
|
}
|
|
|
|
const routeData = await GetRouteInfoFromPageName(to.query.issPage);
|
|
|
|
if(routeData[0].name.toLowerCase() === "error")
|
|
{
|
|
throw("Page not found!");
|
|
}
|
|
|
|
// 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 issPage one.
|
|
next({
|
|
name: routeData[0].name,
|
|
query: Object.assign(to.query, { issPage: routeData[0].name }),
|
|
params: to.params
|
|
});
|
|
|
|
} catch (error) {
|
|
console.log(error);
|
|
GoToStartOn404(next);
|
|
}
|
|
}
|
|
}];
|
|
|
|
const router = createRouter({
|
|
history: createWebHistory("/"),
|
|
routes,
|
|
});
|
|
|
|
router.afterEach((to, from) => {
|
|
|
|
const store = useMainStore();
|
|
// Update lastPageVisited in the store
|
|
store.updateLastPageVisited(to.name);
|
|
|
|
// Push page view to GA
|
|
analyticsMixin.methods.pushPageViewToGA();
|
|
|
|
// Push experiments to Data Layer
|
|
analyticsMixin.methods.pushExperimentsToDataLayer();
|
|
});
|
|
|
|
// 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.
|
|
async function GetRouteInfoFromPageName(pageName) {
|
|
|
|
const response = await useMainStore().getRouteInfo(pageName);
|
|
|
|
const jsonFromResponse = JSON.parse(response.data.Result);
|
|
let routeData = [];
|
|
|
|
// Add our route data and return our array.
|
|
Object.keys(jsonFromResponse).forEach((key) => {
|
|
routeData.push({
|
|
path: "/",
|
|
name: `${key}`,
|
|
component: lazyLoadComponent(jsonFromResponse[key].LayoutName),
|
|
});
|
|
});
|
|
|
|
return routeData;
|
|
};
|
|
|
|
//Use this navigation when you need to call next() explicitly. beforeRouteEnter is a good example.
|
|
router.overrideNavigation = (
|
|
scenario,
|
|
currentRoute,
|
|
next,
|
|
isSavingNavigation,
|
|
optionalQuery = {},
|
|
optionalParams = {},
|
|
optionalPageData
|
|
) => {
|
|
navigate(
|
|
scenario,
|
|
currentRoute,
|
|
isSavingNavigation,
|
|
optionalQuery,
|
|
optionalParams,
|
|
optionalPageData
|
|
);
|
|
next();
|
|
};
|
|
|
|
router.navigate = (scenario, currentRoute, optionalQuery = {}, optionalParams = {}, optionalPageData = {}) => {
|
|
|
|
navigate(scenario, currentRoute, optionalQuery, optionalParams, optionalPageData);
|
|
|
|
}
|
|
|
|
// Navigate to the next route, depending on the scenario.
|
|
function navigate (scenario, currentRoute, optionalQuery = {}, optionalParams = {}, optionalPageData = {}) {
|
|
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 = getNavigationMap(scenario, currentRoute);
|
|
|
|
if (!matchingScenarioMap){
|
|
console.error("No matching scenario found. Please review the routing table.");
|
|
return;
|
|
}
|
|
|
|
if (matchingScenarioMap.destinationIssPageValue) {
|
|
|
|
// Update page data to the store for next page if provided. Otherwise, keep existing page data or set to empty object
|
|
const existingPageDataForPage = useMainStore().pageData(matchingScenarioMap.destinationIssPageValue);
|
|
baseMixin.methods.savePageDataToStore(
|
|
matchingScenarioMap.destinationIssPageValue,
|
|
Object.keys(optionalPageData).length > 0
|
|
? optionalPageData
|
|
: existingPageDataForPage ?? {}
|
|
);
|
|
|
|
// We're always pushing the same path, just changing query strings. Make sure our optional query strings get combined with our issPage one.
|
|
router.push({
|
|
name: "root",
|
|
query: Object.assign(optionalQuery, {
|
|
issPage: matchingScenarioMap.destinationIssPageValue,
|
|
}),
|
|
params: optionalParams
|
|
});
|
|
} else if (matchingScenarioMap.destinationUrl) {
|
|
navigateToUrl(matchingScenarioMap.destinationUrl, optionalQuery);
|
|
}
|
|
};
|
|
|
|
// Navigate to an external url.
|
|
function navigateToUrl(url, optionalQuery = {}) {
|
|
// possibly show some loading screen in the future here.
|
|
let externalUrl = new URL(url);
|
|
|
|
for (const queryKey in optionalQuery) {
|
|
externalUrl.searchParams.append(queryKey, optionalQuery[queryKey]);
|
|
}
|
|
|
|
window.location.assign(externalUrl);
|
|
};
|
|
|
|
// Get navigation map depending on the scenario and the current 'page' you're on.
|
|
function getNavigationMap (scenario, currentRoute) {
|
|
const issPageValue = currentRoute.query.issPage;
|
|
try {
|
|
|
|
const matchedQueryValue = routingTable(useMainStore())
|
|
.filter(
|
|
(item) =>
|
|
item.issPageValue === issPageValue &&
|
|
item.maps.filter((map) => map.scenario === scenario).length > 0
|
|
);
|
|
|
|
let maps = matchedQueryValue ? matchedQueryValue.map((m) => m.maps.filter((map) => map.scenario === scenario))[0] : undefined;
|
|
|
|
return maps ? maps.filter(x => x.filter === true || x.filter === undefined)[0] : undefined;
|
|
}
|
|
catch (e) {
|
|
console.error(e);
|
|
return undefined;
|
|
}
|
|
|
|
};
|
|
|
|
function GoToStartOn404(next) {
|
|
const errorPageName = issPageValues.VEHICLE_YEAR;
|
|
router.addRoute({
|
|
path: "/",
|
|
name: errorPageName,
|
|
component: lazyLoadComponent(errorPageName),
|
|
});
|
|
|
|
// Put item on the bus
|
|
eventBus.addEventToBus(
|
|
globalEvents.Categories.GLOBAL_ALERT,
|
|
globalEvents.SubCategories.PAGE_NOT_FOUND,
|
|
{
|
|
isDismissible: true,
|
|
messageCopy: "You can get a quote by starting on this page.",
|
|
messageHeadline: "We're sorry, something went wrong.",
|
|
type: globalEventTypes.Danger,
|
|
}
|
|
);
|
|
|
|
next({
|
|
name: errorPageName,
|
|
query: {issPage: errorPageName },
|
|
});
|
|
|
|
};
|
|
|
|
// Run SiteEntry and PageEntry triggers for experiments
|
|
async function runExperiments(nextPage) {
|
|
const store = useMainStore();
|
|
|
|
if (!store.applicationUser.triggeredSiteEntry) {
|
|
await store.runExperimentsForTrigger({
|
|
userId: getDeviceIdValue(),
|
|
triggerEvent: experimentTriggers.SITE_ENTRY,
|
|
triggerValue: applicationConfig.SITE_ENTRY_TRIGGER_VALUE,
|
|
});
|
|
}
|
|
|
|
await store.runExperimentsForTrigger({
|
|
userId: getDeviceIdValue(),
|
|
triggerEvent: experimentTriggers.PAGE_ENTRY,
|
|
triggerValue: nextPage,
|
|
});
|
|
}
|
|
|
|
export default router; |