diff --git a/src/constants/application-config.js b/src/constants/application-config.js index ff2229e3..9c3a3d05 100644 --- a/src/constants/application-config.js +++ b/src/constants/application-config.js @@ -2,7 +2,8 @@ const applicationConfig = { CURRENT_ENVIRONMENT: process.env.VUE_APP_CURRENT_ENVIRONMENT, // "Localhost", "Dev", "QA", and "Prod" CONSUMER_CF_DISTRO: process.env.VUE_APP_CONSUMER_CF_DISTRO, APPLICATION_NAME: "SelfService", - SITE_ENTRY_TRIGGER_VALUE: "SelfService" + SITE_ENTRY_TRIGGER_VALUE: "SelfService", + APPLICATION_ABBREVIATION: "iss", }; export { applicationConfig }; \ No newline at end of file diff --git a/src/constants/endpoints.js b/src/constants/endpoints.js index 7581f022..19833112 100644 --- a/src/constants/endpoints.js +++ b/src/constants/endpoints.js @@ -1,17 +1,17 @@ const endpoints = { - GetRouteInfo: { - url: "/content/api/v1/content/RouteInfo", - method: "POST", - }, - GetHomepageInfo: { - url: "/content/api/v1/content/HomepageInfo", - method: "GET", - }, - GetPageData: { - url: "/content/api/v1/content", - method: "GET", - }, - }; + GetRouteInfo: { + url: (applicationAbbreviation) => `/content/api/v1/content/${applicationAbbreviation}/RouteInfo`, + method: "POST", + }, + GetHomepageInfo: { + url: (applicationAbbreviation) => `/content/api/v1/content/${applicationAbbreviation}/HomepageInfo`, + method: "GET", + }, + GetPageData: { + url: (applicationAbbreviation, pageName) => `/content/api/v1/content/${applicationAbbreviation}/${pageName}`, + method: "GET", + }, +}; - export { endpoints }; +export { endpoints }; \ No newline at end of file diff --git a/src/helpers/cms-content-helper.js b/src/helpers/cms-content-helper.js new file mode 100644 index 00000000..9a7c0925 --- /dev/null +++ b/src/helpers/cms-content-helper.js @@ -0,0 +1,118 @@ +export function fetchCmsContentForPage(issPage) { + return this.mainStore.getRouteInfo(issPage) + .then((response) => { + const pageDataFromCms = {}; + + response.data.Result.forEach((widget) => { + let widgetWithReplacements = findAndReplaceGlobalStateValues( + widget.Model, + widget.Name + ); + + // If we already have this widget, push it on the collection + if (widgetWithReplacements.Name in pageDataFromCms) { + pageDataFromCms[widgetWithReplacements.Name].push( + widgetWithReplacements.Model + ); + return; + } + + pageDataFromCms[widgetWithReplacements.Name] = [ + widgetWithReplacements.Model, + ]; + }); + + Object.keys(pageDataFromCms).forEach((key) => { + if (pageDataFromCms[key].length === 1) { + pageDataFromCms[key] = pageDataFromCms[key][0]; + } + }); + + return pageDataFromCms; + }); + } + + // Parent function for processWidgetItemForReplacement. This will loop through the parent +// object and pass any objects that need additional processing to the processWidgetItemForReplacement function. +function findAndReplaceGlobalStateValues(widgetModel, widgetName) { + const objWithReplacements = { + Name: widgetName, + Model: {}, + }; + + Object.keys(widgetModel).forEach((key) => { + let modelWithReplacements = processWidgetItemForReplacement( + widgetModel, + key + ); + + objWithReplacements.Model[key] = modelWithReplacements; + }); + + return objWithReplacements; + } + + // This function will process the widget item and replace any global state variables with their values. +// This is a recursive function, it will call itself until it runs out of items to iterate on given the object. +function processWidgetItemForReplacement(widgetModel, key) { + // If we have a string, and it needs to be replaced. + if (typeof widgetModel[key] === "string") { + if (widgetModel[key].includes(dynamicStrings.GLOBAL_STATE)) { + widgetModel[key] = mapStringToState(widgetModel[key]); + } + return widgetModel[key]; + } + + // If we have an object. array, etc + if ( + typeof widgetModel[key] === "object" && + Object.keys(widgetModel[key]).length + ) { + Object.keys(widgetModel[key]).forEach((item) => { + processWidgetItemForReplacement(widgetModel[key], item); + }); + + return widgetModel[key]; + } + + // If we have something else like a number, boolean, etc. just return it + return widgetModel[key]; + } + + // Function to convert a string, into a matching global state item. +function mapStringToState(str) { + // Pull all matches out of the string. + const regexExp = new RegExp("{(.*?):(.*?)}", "g"); + const regexMatches = [...str.matchAll(regexExp)]; + const globalStateMatches = regexMatches.filter(match => { + return match[1] === dynamicStrings.GLOBAL_STATE; + }) + + // Our final string value that will be built from the matches. + let stringBuilder = ""; + + for (const match of globalStateMatches) { + // Reset store state for each match. + let storeState = store.state; + + for (const s of match[2].split(".")) { + if (storeState[s] != undefined) { + storeState = storeState[s]; + } else { + return ""; // if we can't map our string to state data, return an empty string. + } + } + + const stringWithReplacement = str.replace(match[0], storeState); + + // If we still have values we need to substitute, call this function again. + if (stringWithReplacement.includes(dynamicStrings.GLOBAL_STATE)) { + return mapStringToState(stringWithReplacement); + } + + // Concatenate the string. + stringBuilder = `${stringBuilder} ${stringWithReplacement}`; + } + + return stringBuilder.trimStart(); + } \ No newline at end of file diff --git a/src/router/index.js b/src/router/index.js index ab5cae25..30e4980b 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -1,7 +1,5 @@ import { createWebHistory, createRouter } from "vue-router"; import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader"; -import { endpoints } from "@/constants/mock-endpoints"; -import globalMethods from "@/global-methods"; import {issPageValues} from '@/router/router-constants/issPage-values'; import { routingTable } from "@/router/router-constants/routing-table"; import { useMainStore } from '@/store'; @@ -56,15 +54,8 @@ const router = createRouter({ // 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) { - - //move to store actions later? - /* - const response = await store.dispatch(storeActions.GET_ROUTE_INFO_ACTION, { - pageName: pageName, - }); - */ + const response = await this.mainStore.getRouteInfo(pageName); - const response = await globalMethods.mockCallHttpClient("GET", endpoints.GetRouteInfo.url + "?route=" + pageName) const jsonFromResponse = JSON.parse(response.data.Result); let routeData = []; diff --git a/src/store/index.js b/src/store/index.js index c78651c0..aa067c5c 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1,4 +1,7 @@ import { defineStore } from "pinia"; +import { endpoints } from "@/constants/endpoints.js"; +import { globalMethods } from "@/global-methods"; +import { applicationConfig } from "@/constants/application-config"; const storeId = 'main'; @@ -47,13 +50,39 @@ export const useMainStore = defineStore({ getters: {}, actions: { - // Vehicle + // Content API Actions + getRouteInfo(context, { pageName }) { + return globalMethods.callHttpClient({ + method: endpoints.GetRouteInfo.method, + endpoint: endpoints.GetRouteInfo.url(applicationConfig.APPLICATION_ABBREVIATION), + payload: { + pageName: pageName, + }, + }); + }, + getHomepageName(context) { + return globalMethods.callHttpClient({ + method: endpoints.GetHomepageInfo.method, + endpoint: endpoints.GetHomepageInfo.url(applicationConfig.APPLICATION_ABBREVIATION), + }); + }, + getPageData(context, { pageName }) { + return globalMethods.callHttpClient({ + method: endpoints.GetPageData.method, + endpoint: endpoints.GetPageData.url(applicationConfig.APPLICATION_ABBREVIATION, pageName), + payload: {}, + }); + }, + + // Vehicle API Actions updateVehicleYear(year) { - if (this.order.vehicle.year !== year) { - this.order.vehicle.year = year; - } + if (this.order.vehicle.year !== year) { + this.order.vehicle.year = year; + } }, + + // populate initial state populateInitialState() { if(!localStorage.getItem(storeId)) {