Merge pull request #246 from Safelite/feature/digital/SSR-313

Feature/digital/ssr 313
This commit is contained in:
DavidAtSafelite 2023-04-20 09:56:57 -04:00 committed by GitHub
commit 080b9b4b1c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
37 changed files with 1584 additions and 673 deletions

1
.gitignore vendored
View file

@ -25,3 +25,4 @@ pnpm-debug.log*
# Misc # Misc
coverage/* coverage/*
junit.xml junit.xml
/.vs

View file

@ -14,5 +14,5 @@
@import "@/styles/common-error-styles.scss"; @import "@/styles/common-error-styles.scss";
@import "@/styles/common-animations.scss"; @import "@/styles/common-animations.scss";
@import "@/styles/shared-input-button-styles.scss"; @import "@/styles/shared-input-button-styles.scss";
@import "@/styles/client-customizations.scss" @import "@/styles/client-customizations.scss";
</style> </style>

View file

@ -11,6 +11,7 @@ const applicationConfig = {
CLIENTTAG_QUERYSTRING: 'CientTag', CLIENTTAG_QUERYSTRING: 'CientTag',
GOOGLE_PLACES_API_KEY: process.env.VUE_APP_GOOGLE_PLACES_API_KEY, GOOGLE_PLACES_API_KEY: process.env.VUE_APP_GOOGLE_PLACES_API_KEY,
ISS_DEV_CMS_DOMAIN: "https://digitalisscms.dev.safelite.io", ISS_DEV_CMS_DOMAIN: "https://digitalisscms.dev.safelite.io",
CASH_PARENT_ACCOUNT_NUMBER: 167132
}; };
export { applicationConfig }; export { applicationConfig };

View file

@ -2,7 +2,7 @@ const damageCustomLabels = Object.freeze({
MATCH: 'match', MATCH: 'match',
REAR_WINDOW: 'rear window', REAR_WINDOW: 'rear window',
SIDE_WINDOW: 'side window', SIDE_WINDOW: 'side window',
WINDSHIELD: 'windshield', WINDSHIELD: 'windshield'
}); });
export default damageCustomLabels; export default damageCustomLabels;

View file

@ -3,7 +3,7 @@ const damageLocationsCms = {
SIDEDOOR: "SIDEDOOR", SIDEDOOR: "SIDEDOOR",
REARWINDOW: "REARWINDOW", REARWINDOW: "REARWINDOW",
DRIVERSIDE: "DRIVERSIDE", DRIVERSIDE: "DRIVERSIDE",
PASSENGERSIDE: "PASSENGERSIDE", PASSENGERSIDE: "PASSENGERSIDE"
}; };
export { damageLocationsCms }; export { damageLocationsCms };

View file

@ -15,7 +15,7 @@ const damageLocationsSelected = {
DRIVERSIDE: "DriverSide", DRIVERSIDE: "DriverSide",
PASSENGERSIDE: "PassengerSide", PASSENGERSIDE: "PassengerSide",
STATIONARY: "Stationary", STATIONARY: "Stationary",
SLIDER: "Slider", SLIDER: "Slider"
}; };
export { damageLocationsSelected }; export { damageLocationsSelected };

View file

@ -2,7 +2,8 @@ const dynamicStrings = {
GLOBAL_STATE: "globalState", GLOBAL_STATE: "globalState",
CUSTOM: "custom", CUSTOM: "custom",
ROUTER_LINK: "routerLink:", ROUTER_LINK: "routerLink:",
MODAL_LINK: "modalLink" MODAL_LINK: "modalLink",
TEXT_LINK: 'textLink'
}; };
export { dynamicStrings }; export { dynamicStrings };

View file

@ -18,8 +18,8 @@ const customMappings = {
{ key: "Passenger Back", transformedValue: "passenger side back door" }, { key: "Passenger Back", transformedValue: "passenger side back door" },
{ key: "Passenger Vent", transformedValue: "passenger side vent glass" }, { key: "Passenger Vent", transformedValue: "passenger side vent glass" },
{ key: "Passenger Quarter", transformedValue: "passenger side quarter panel" }, { key: "Passenger Quarter", transformedValue: "passenger side quarter panel" },
{ key: "Passenger SlideDoor", transformedValue: "passenger side sliding door" }, { key: "Passenger SlideDoor", transformedValue: "passenger side sliding door" }
], ]
}; };
// Gets an instance of a string where the dynamic portion of the text {custom:KeyName} // Gets an instance of a string where the dynamic portion of the text {custom:KeyName}

View file

@ -39,6 +39,10 @@ const endpoints = {
url: "/parts/api/v1/parts/parts", url: "/parts/api/v1/parts/parts",
method: "POST", method: "POST",
}, },
GetPriceOrderItems: {
url: '/price/api/v1/price/order-items',
method: 'GET'
},
GetCapabilityQuestions: { GetCapabilityQuestions: {
url: "/parts/api/v1/parts/capability-questions", url: "/parts/api/v1/parts/capability-questions",
method: "GET", method: "GET",
@ -46,7 +50,19 @@ const endpoints = {
GetPartFromCapabilityAnswer: { GetPartFromCapabilityAnswer: {
url: "/parts/api/v1/parts/part-from-capability-answer", url: "/parts/api/v1/parts/part-from-capability-answer",
method: "POST", method: "POST",
}, },
GetWipers: {
url: '/parts/api/v1/parts/wipers',
method: 'GET'
},
GetRainDefense: {
url: '/parts/api/v1/parts/rain-defense',
method: 'GET'
},
GetSupportingItems: {
url: '/parts/api/v1/parts/supporting-items',
method: 'POST'
},
GetVehicle: { GetVehicle: {
url: "/vehicle/api/v1/vehicle/lookup", url: "/vehicle/api/v1/vehicle/lookup",
method: "GET", method: "GET",

View file

@ -36,7 +36,7 @@ const errorMessages = {
DAMAGE_OPTION_REQUIRED: "Please select an option", DAMAGE_OPTION_REQUIRED: "Please select an option",
POLICYHOLDER_FIRST_NAME_REQUIRED: "Please enter the policyholder first name", POLICYHOLDER_FIRST_NAME_REQUIRED: "Please enter the policyholder first name",
POLICYHOLDER_LAST_NAME_REQUIRED: "Please enter the policyholder last name", POLICYHOLDER_LAST_NAME_REQUIRED: "Please enter the policyholder last name"
}; };

View file

@ -1,17 +1,17 @@
const globalEvents = { const globalEvents = {
Categories: { Categories: {
GLOBAL_ALERT: "GLOBAL_ALERT", GLOBAL_ALERT: "GLOBAL_ALERT"
}, },
SubCategories: { SubCategories: {
PAGE_NOT_FOUND: "PAGE_NOT_FOUND", PAGE_NOT_FOUND: "PAGE_NOT_FOUND"
}, }
}; };
const globalEventTypes = { const globalEventTypes = {
Success: "alert-success", Success: "alert-success",
Warning: "alert-warning", Warning: "alert-warning",
Info: "alert-info", Info: "alert-info",
Danger: "alert-danger", Danger: "alert-danger"
}; };
export { globalEvents, globalEventTypes }; export { globalEvents, globalEventTypes };

View file

@ -1,14 +1,14 @@
const experimentUniverses = { const experimentUniverses = {
ISS_FUNNEL: "ISSFunnel", ISS_FUNNEL: "ISSFunnel"
}; };
const experimentSettings = { const experimentSettings = {
GOOGLE_CUSTOM_DIMENSION_INDEX: "Google Custom Dimension Index", GOOGLE_CUSTOM_DIMENSION_INDEX: "Google Custom Dimension Index"
}; };
const experimentTriggers = { const experimentTriggers = {
SITE_ENTRY: "SiteEntry", SITE_ENTRY: "SiteEntry",
PAGE_ENTRY: "PageEntry", PAGE_ENTRY: "PageEntry"
}; };
export { experimentUniverses, experimentSettings, experimentTriggers }; export { experimentUniverses, experimentSettings, experimentTriggers };

View file

@ -1,3 +1,3 @@
export const headerKeys = { export const headerKeys = {
EXPERIMENT: "X-Experiment-Data", EXPERIMENT: "X-Experiment-Data"
}; };

View file

@ -3,8 +3,8 @@
const endpoints = { const endpoints = {
GetRouteInfo: { GetRouteInfo: {
url: "https://mockey.qa.sagaws.net/service/ISS/Content/RouteInfo", url: "https://mockey.qa.sagaws.net/service/ISS/Content/RouteInfo",
method: "GET", method: "GET"
}, }
}; };

View file

@ -0,0 +1,8 @@
const partTypeStrings = {
FRONT_WIPER: 'FRONT WIPER',
REAR_WIPER: 'REAR WIPER',
RAIN_DEFENSE: 'RAIN DEFENSE',
RECALIBRATION: 'RECALIBRATION'
};
export { partTypeStrings };

View file

@ -49,5 +49,5 @@ export const states = {
WA: "Washington", WA: "Washington",
WV: "West Virginia", WV: "West Virginia",
WI: "Wisconsin", WI: "Wisconsin",
WY: "Wyoming", WY: "Wyoming"
}; };

View file

@ -34,7 +34,7 @@ const tintMap = {
{ name: "gray tint privacy", src: "Glass-NoShade-GrayTint.svg" }, { name: "gray tint privacy", src: "Glass-NoShade-GrayTint.svg" },
// No shade or tint // No shade or tint
{ name: "clear", src: "Glass-NoShade-NoTint.svg" }, { name: "clear", src: "Glass-NoShade-NoTint.svg" }
], ],
windshield: [ windshield: [
@ -69,8 +69,8 @@ const tintMap = {
{ name: "gray tint privacy", src: "Windshield-NoShade-GrayTint.svg" }, { name: "gray tint privacy", src: "Windshield-NoShade-GrayTint.svg" },
// No shade or tint // No shade or tint
{ name: "clear", src: "Windshield-NoShade-NoTint.svg" }, { name: "clear", src: "Windshield-NoShade-NoTint.svg" }
], ]
}; };
// Gets the tint image source string given the glass location, and the tint description (like 'Green Tint') // Gets the tint image source string given the glass location, and the tint description (like 'Green Tint')

View file

@ -5,7 +5,7 @@ const vehicleCategories = {
COMMERCIALVAN: "COMMERCIAL VAN", COMMERCIALVAN: "COMMERCIAL VAN",
SUV: "SUV", SUV: "SUV",
MOTORHOME: "MOTOR HOME", MOTORHOME: "MOTOR HOME",
SEMI: "SEMI", SEMI: "SEMI"
}; };
export { vehicleCategories }; export { vehicleCategories };

View file

@ -1,7 +1,7 @@
const vinLookupMethodSelections = Object.freeze({ const vinLookupMethodSelections = Object.freeze({
MANUALVIN: 'ManualVin', MANUALVIN: 'ManualVin',
LICENSEPLATE: 'LicensePlate', LICENSEPLATE: 'LicensePlate',
HOMEADDRESS: 'HomeAddress', HOMEADDRESS: 'HomeAddress'
}); });
export {vinLookupMethodSelections}; export {vinLookupMethodSelections};

View file

@ -37,7 +37,7 @@
:buttonLabel="answer.buttonLabel" :buttonLabel="answer.buttonLabel"
:buttonLabelSubCopy="answer.buttonLabelSubCopy" :buttonLabelSubCopy="answer.buttonLabelSubCopy"
:buttonBodyCopy="answer.buttonBodyCopy" :buttonBodyCopy="answer.buttonBodyCopy"
:buttonAuxillaryCopy="answer.buttonAuxillaryCopy" :buttonAuxiliaryCopy="answer.buttonAuxiliaryCopy"
:buttonFooterCopy="answer.buttonFooterCopy" :buttonFooterCopy="answer.buttonFooterCopy"
:buttonImage="answer.buttonImage" :buttonImage="answer.buttonImage"
:buttonImageId="answer.buttonImageId" :buttonImageId="answer.buttonImageId"
@ -194,7 +194,7 @@ export default {
altText: answer.altText ?? (answer.Name ? answer.Name : answer), altText: answer.altText ?? (answer.Name ? answer.Name : answer),
buttonLabelSubCopy: answer.buttonLabelSubCopy ?? answer.SubText, buttonLabelSubCopy: answer.buttonLabelSubCopy ?? answer.SubText,
buttonBodyCopy: answer.buttonBodyCopy ?? answer.buttonBodyCopy, buttonBodyCopy: answer.buttonBodyCopy ?? answer.buttonBodyCopy,
buttonAuxillaryCopy: answer.buttonAuxillaryCopy ?? answer.buttonAuxillaryCopy, buttonAuxiliaryCopy: answer.buttonAuxiliaryCopy ?? answer.buttonAuxiliaryCopy,
buttonFooterCopy: answer.buttonFooterCopy ?? answer.buttonFooterCopy, buttonFooterCopy: answer.buttonFooterCopy ?? answer.buttonFooterCopy,
buttonImage: answer.buttonImage ?? answer.AnswerImageUrl, buttonImage: answer.buttonImage ?? answer.AnswerImageUrl,
buttonImageId: answer.buttonImageId ?? answer.ImageId, buttonImageId: answer.buttonImageId ?? answer.ImageId,

View file

@ -1,4 +1,4 @@
import { dynamicStrings } from "@/constants/dynamic-strings"; import { dynamicStrings } from '@/constants/dynamic-strings';
import { useMainStore } from '@/store'; import { useMainStore } from '@/store';
export function fetchCmsContentForPage(issPage) { export function fetchCmsContentForPage(issPage) {
@ -18,7 +18,7 @@ export function fetchCmsContentForPage(issPage) {
} }
else { else {
// Else get the client override page. // Else get the client override page.
const pageName = issPage + "_" + clientName.toLowerCase().replace(/ /g, ""); const pageName = issPage + '_' + clientName.toLowerCase().replace(/ /g, '');
return store.getPageData(pageName) return store.getPageData(pageName)
.then( .then(
@ -27,6 +27,7 @@ export function fetchCmsContentForPage(issPage) {
return processPageData(baseResponse, clientResponse); return processPageData(baseResponse, clientResponse);
}, },
(error) => { (error) => {
console.error(error);
// Process the just the base if no client override exists. // Process the just the base if no client override exists.
return processPageData(baseResponse, null); return processPageData(baseResponse, null);
} }
@ -44,8 +45,11 @@ function processPageData(baseResponse, clientResponse) {
const pageDataFromCms = {}; const pageDataFromCms = {};
let widgets = []; let widgets = [];
if ( clientResponse === null ) if (!baseResponse?.data?.Result) {
{ console.error('No result data found'); // Something has gone terribly wrong.
return {}
}
if (!clientResponse?.data?.Result) {
widgets = baseResponse.data.Result; widgets = baseResponse.data.Result;
} }
else else
@ -89,7 +93,7 @@ function processPageData(baseResponse, clientResponse) {
widgets.forEach((widget) => { widgets.forEach((widget) => {
// Global state value replacement. // Global state value replacement.
let widgetWithReplacements = findAndReplaceGlobalStateValues( const widgetWithReplacements = findAndReplaceGlobalStateValues(
widget.Model, widget.Model,
widget.Name widget.Name
); );
@ -103,7 +107,7 @@ function processPageData(baseResponse, clientResponse) {
} }
pageDataFromCms[widgetWithReplacements.Name] = [ pageDataFromCms[widgetWithReplacements.Name] = [
widgetWithReplacements.Model, widgetWithReplacements.Model
]; ];
}); });
@ -121,7 +125,7 @@ function processPageData(baseResponse, clientResponse) {
function findAndReplaceGlobalStateValues(widgetModel, widgetName) { function findAndReplaceGlobalStateValues(widgetModel, widgetName) {
const objWithReplacements = { const objWithReplacements = {
Name: widgetName, Name: widgetName,
Model: {}, Model: {}
}; };
Object.keys(widgetModel).forEach((key) => { Object.keys(widgetModel).forEach((key) => {
@ -140,7 +144,7 @@ function findAndReplaceGlobalStateValues(widgetModel, widgetName) {
// This is a recursive function, it will call itself until it runs out of items to iterate on given the object. // 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) { function processWidgetItemForReplacement(widgetModel, key) {
// If we have a string, and it needs to be replaced. // If we have a string, and it needs to be replaced.
if (typeof widgetModel[key] === "string") { if (typeof widgetModel[key] === 'string') {
widgetModel[key] = processIfStatements( widgetModel[key] = processIfStatements(
widgetModel[key], widgetModel[key],
dynamicStrings.GLOBAL_STATE, dynamicStrings.GLOBAL_STATE,
@ -158,7 +162,7 @@ function processWidgetItemForReplacement(widgetModel, key) {
// If we have an object. array, etc // If we have an object. array, etc
if ( if (
typeof widgetModel[key] === "object" && typeof widgetModel[key] === 'object' &&
Object.keys(widgetModel[key]).length Object.keys(widgetModel[key]).length
) { ) {
Object.keys(widgetModel[key]).forEach((item) => { Object.keys(widgetModel[key]).forEach((item) => {
@ -173,47 +177,43 @@ function processWidgetItemForReplacement(widgetModel, key) {
} }
function mapStringToModal(str) { function mapStringToModal(str) {
let startIndex = str.indexOf("{" + dynamicStrings.MODAL_LINK); const startIndex = str.indexOf('{' + dynamicStrings.MODAL_LINK);
let linkToReplace = str.substring(startIndex, str.length); const linkToReplace = str.substring(startIndex, str.length);
linkToReplace = linkToReplace.substring(0, linkToReplace.indexOf("}") + 1); linkToReplace = linkToReplace.substring(0, linkToReplace.indexOf('}') + 1);
let params = linkToReplace.substring((dynamicStrings.MODAL_LINK).length + 2, linkToReplace.length -1); const params = linkToReplace.substring((dynamicStrings.MODAL_LINK).length + 2, linkToReplace.length -1)
let splitParams = params.split(","); const splitParams = params.split(',');
const bodyText = '<a modalTarget="' + splitParams[0] + '" class="modal-text" aria-label="Modal window">' + splitParams[1] + '</a>';
let bodyText = '<a modalTarget="' + splitParams[0] + '" class="modal-text" aria-label="Modal window">' + splitParams[1] + '</a>';
let returnVal = str.replace(linkToReplace, bodyText); let returnVal = str.replace(linkToReplace, bodyText);
if (returnVal.includes(dynamicStrings.MODAL_LINK)) { if (returnVal.includes(dynamicStrings.MODAL_LINK)) {
returnVal = mapStringToModal(returnVal); returnVal = mapStringToModal(returnVal)
} }
return returnVal; return returnVal
} }
// Function to convert a string, into a matching global state item. // Function to convert a string, into a matching global state item.
function mapStringToState(str) { function mapStringToState(str) {
// Pull all matches out of the string. // Pull all matches out of the string.
const regexExp = new RegExp("{(.*?):(.*?)}", "g"); const regexExp = new RegExp('{([^{}]*?):([^{}]*?)}', 'g');
const regexMatches = [...str.matchAll(regexExp)]; const regexMatches = [...str.matchAll(regexExp)];
const globalStateMatches = regexMatches.filter(match => { const globalStateMatches = regexMatches.filter(match => {
return match[1] === dynamicStrings.GLOBAL_STATE; return match[1] === dynamicStrings.GLOBAL_STATE;
}); });
// Our final string value that will be built from the matches. // Our final string value that will be built from the matches.
let stringBuilder = ""; let stringBuilder = '';
for (const match of globalStateMatches) { for (const match of globalStateMatches) {
// Reset store state for each match. // Reset store state for each match.
let storeState = useMainStore(); const valueFromStore = getStoreValueFromString(match[2]);
if (!valueFromStore) {
for (const s of match[2].split(".")) { console.warning('Unable to resolve global state data.');
if (storeState[s] != undefined) { return '' // if we can't map our string to state data, return an empty string.
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], valueFromStore);
const stringWithReplacement = str.replace(match[0], storeState);
// If we still have values we need to substitute, call this function again. // If we still have values we need to substitute, call this function again.
if (stringWithReplacement.includes(dynamicStrings.GLOBAL_STATE)) { if (stringWithReplacement.includes(dynamicStrings.GLOBAL_STATE)) {
@ -227,18 +227,19 @@ function mapStringToState(str) {
return stringBuilder.trimStart(); return stringBuilder.trimStart();
} }
function getStoreValueFromString(str) { function getStoreValueFromString(str) {
if (!str) return '';
let storeOrStateObject = useMainStore(); let storeOrStateObject = useMainStore();
for (const s of str.split('.')) { for (const s of str.split('.')) {
if (s === 'getters') continue; if (s === 'getters') continue; //For backward compatability
if (storeOrStateObject[s] != undefined) { if (storeOrStateObject[s] != undefined) {
storeOrStateObject = storeOrStateObject[s]; storeOrStateObject = storeOrStateObject[s];
} else { } else {
return '' break;
} }
} }
return storeOrStateObject; return storeOrStateObject ?? '';
} }
/////////////////////////////////// ///////////////////////////////////
@ -246,19 +247,21 @@ function getStoreValueFromString(str) {
/////////////////////////////////// ///////////////////////////////////
/** /**
* Recursive function - replaces all instances of if statements from the CMS that utilize the specified ifConditionKeyword * Recursive function - replaces all instances of if statements from the CMS that utilize the specified ifConditionKeyword
* @param {*} str string - Input string to be processed * @param {*} str string - Input string to be processed
* @param {*} ifConditionKeyword string - Defines which if statements to process ex: 'globalState' * @param {*} ifConditionKeyword string - Defines which if statements to process ex: 'globalState'
* @param {*} replacePlaceholderCallback function - Callback to replace CMS placeholder values * @param {*} replacePlaceholderCallback function - Callback to replace CMS placeholder values
* @returns The processed string * @returns The processed string
*/ */
export function processIfStatements(str, ifConditionKeyword, replacePlaceholderCallback) { export function processIfStatements(str, ifConditionKeyword, replacePlaceholderCallback) {
const containsRelevantIfStatement = new RegExp('{if:' + ifConditionKeyword + ':.+?}', 'g').test( const containsRelevantIfStatement = new RegExp('{if:' + ifConditionKeyword + ':.+?}', 'g').test(
str str
); );
//str = str.replace(/\r?\n|\r/g, '');
const hasEmbeddedCrLf = /\r?\n|\r/g.test(str); const hasEmbeddedCrLf = /\r?\n|\r/g.test(str);
if (hasEmbeddedCrLf) {
console.warning('Processing of conditional string was skipped. String has embedded carriage return/linefeed.');
}
if (!containsRelevantIfStatement || hasEmbeddedCrLf) { if (!containsRelevantIfStatement || hasEmbeddedCrLf) {
return str; return str;
} else { } else {
@ -413,6 +416,10 @@ function getIfStatementRegexExpression() {
// End of If Statement Processing Logic // // End of If Statement Processing Logic //
////////////////////////////////////////// //////////////////////////////////////////
export function doesCopyContainTextLink(copy) {
return copy.includes(dynamicStrings.TEXT_LINK);
}
export function setupModalLinks(context) { export function setupModalLinks(context) {
context.$nextTick(() => { context.$nextTick(() => {
const elements = document.getElementsByClassName("modal-text") const elements = document.getElementsByClassName("modal-text")
@ -430,23 +437,35 @@ export function doesCopyContainRouterLink(copy) {
return copy.includes(this.dynamicStrings.ROUTER_LINK); return copy.includes(this.dynamicStrings.ROUTER_LINK);
} }
/**
* splits copy on { ... } such as {routerlink: ...}
* @returns array of strings
*/
export function splitCopyOnCMSPlaceHolder(copy) { export function splitCopyOnCMSPlaceHolder(copy) {
// splits copy on { ... } such as {routerlink: ...} // splits copy on { ... } such as {routerlink: ...}
return copy.split(/{(.*?)}/g); return copy.split(/{(.*?)}/g);
} }
/**
* Returns string2 of input following this pattern: {string1:string2,string3}
* @returns string
*/
export function getRouterLinkRouteFromCopy(copy) { export function getRouterLinkRouteFromCopy(copy) {
// sample input: {routerLink:estimate,provide your VIN} // sample input: {routerLink:estimate,provide your VIN}
// first split would return 'estimate,provide your VIN' // first split would return 'estimate,provide your VIN'
// second split would return 'estimate' // second split would return 'estimate'
return copy.split(":")[1].split(",")[0]; return copy.split(':')[1].split(',')[0];
} }
/**
* Returns string3 of input following this pattern: { string1: string2, string3 }
* @returns string
*/
export function getRouterLinkDisplayTextFromCopy(copy) { export function getRouterLinkDisplayTextFromCopy(copy) {
// sample input: {routerLink:estimate,provide your VIN} // sample input: {routerLink:estimate,provide your VIN}
// first split would return 'estimate,provide your VIN' // first split would return 'estimate,provide your VIN'
// second split would return 'provide your VIN' // second split would return 'provide your VIN'
return copy.split(":")[1].split(",")[1]; return copy.split(':')[1].split(',')[1];
} }
// Copy returned from the CMS that has newlines will return blocks wrapped in // Copy returned from the CMS that has newlines will return blocks wrapped in
@ -455,5 +474,5 @@ export function getRouterLinkDisplayTextFromCopy(copy) {
// attributes present // attributes present
export function splitCMSCopyOnParagraphTag(copy) { export function splitCMSCopyOnParagraphTag(copy) {
// filter removes empty strings that are a result of string.split with regex // filter removes empty strings that are a result of string.split with regex
return copy.split(/(?:<p(?:.*?)>)|(?:<\/p>)/g).filter((paragraph) => paragraph !== ""); return copy.split(/(?:<p(?:.*?)>)|(?:<\/p>)/g).filter((paragraph) => paragraph !== '');
} }

View file

@ -3,7 +3,7 @@
<img id="siteFooterImage" :src="footerImageURL" /> <img id="siteFooterImage" :src="footerImageURL" />
</div> </div>
<footer class="footer container-fluid fixed-bottom g-5 bg-light py-4" id="infoBox"> <footer class="footer container-fluid fixed-bottom g-5 bg-light py-4" id="infoBox">
<div class="row d-flex flex-row-reverse align-items-center vw-100"> <div class="row d-flex flex-row-reverse align-items-center vw-100 mx-0">
<div class="col button-col d-flex" id="stacked" > <div class="col button-col d-flex" id="stacked" >
<buttonMain <buttonMain
v-if="!isForwardButtonHidden" v-if="!isForwardButtonHidden"

View file

@ -30,13 +30,13 @@ export default({
isDismissible: false, isDismissible: false,
messageCopy: "", messageCopy: "",
messageHeadline: "", messageHeadline: "",
type: "", type: ""
}, },
headerAnswers: null headerAnswers: null
}; };
}, },
props: { props: {
cmsWidgetName: String, cmsWidgetName: String
}, },
computed: { computed: {
imageSrc() imageSrc()
@ -51,7 +51,7 @@ export default({
return { return {
"background-color": this.headerAnswers ? this.headerAnswers.HexCode : "#FFFFFF" "background-color": this.headerAnswers ? this.headerAnswers.HexCode : "#FFFFFF"
}; };
}, }
}, },
mounted() { mounted() {
const answers = this.getCmsContent(this.cmsWidgetName, "Answers"); const answers = this.getCmsContent(this.cmsWidgetName, "Answers");

View file

@ -14,10 +14,13 @@ describe("site sub header", () => {
it("should contain the cms content", () => { it("should contain the cms content", () => {
const wrapper = shallowMount(siteSubHeader, { const wrapper = shallowMount(siteSubHeader, {
propsData: {
justification: '',
issContainingPage: ''
},
mixins: [mockMixin] mixins: [mockMixin]
}); });
wrapper.getCmsContent = jest.fn();
const actual = wrapper.find("span"); const actual = wrapper.find("span");
expect(actual.html()).toContain(subHeaderText); expect(actual.html()).toContain(subHeaderText);
}); });

View file

@ -12,8 +12,8 @@
/> />
</h5> </h5>
</div> </div>
<div class="d-flex align-items-center justify-content-center container-fluid overflow-hidden"> <div class="d-flex align-items-center container-fluid overflow-hidden" :class="justifySubheader">
<p class="text-center small fw-normal mb-0 subheader-secondary"> <p class="text-center fw-normal mb-0 subheader-secondary" :class="alternateFormatting">
<span> <span>
{{ subText }} {{ subText }}
</span> </span>
@ -31,23 +31,33 @@ import buttonBack from "@/iss-components/site-sub-header/button-back/button-back
props: { props: {
cmsWidgetName: String, cmsWidgetName: String,
hasBackButton: Boolean, hasBackButton: Boolean,
justification: String,
issContainingPage: String
}, },
computed: { computed: {
content() content() {
{
return this.getCmsContent(this.cmsWidgetName, "SubHeaderText") return this.getCmsContent(this.cmsWidgetName, "SubHeaderText")
}, },
subText() subText() {
{ const subText = this.getCmsContent(this.cmsWidgetName, "SecondaryText");
return this.getCmsContent(this.cmsWidgetName, "SecondaryText") return subText ?? '';
}, },
backButtonAccessibleText() backButtonAccessibleText() {
{
return this.getCmsContent(this.cmsWidgetName, "BackButtonAccessibleText") return this.getCmsContent(this.cmsWidgetName, "BackButtonAccessibleText")
}, },
headerColor() { headerColor() {
return this.subText ? "dark-header" : "light-header"; return this.subText ? "dark-header" : "light-header";
}, },
justifySubheader() {
return (this.justification?.toLowerCase() === 'left') ?
'justify-content-left' :
'justify-content-center';
},
alternateFormatting() {
return (this.issContainingPage?.toLowerCase() === 'service-packages') ?
'service-packages-subtext mt-4 mb-2 px-5' :
'small';
}
}, },
methods: { methods: {
clickEvent() { clickEvent() {
@ -60,22 +70,27 @@ import buttonBack from "@/iss-components/site-sub-header/button-back/button-back
<style lang="scss" scoped> <style lang="scss" scoped>
.dark-header { .dark-header {
color: $black; color: $black;
} }
.light-header { .light-header {
color: $gray-550; color: $gray-550;
} }
h5 { h5 {
line-height: 32px; line-height: 32px;
button { button {
color: inherit; color: inherit;
} }
} }
p.small { p.small {
color: $gray-550; color: $gray-550;
} }
p.service-packages-subtext {
font-weight: 500 !important;
line-height: 24px;
}
</style> </style>

View file

@ -0,0 +1,355 @@
<template>
<buttonQuestion ref="buttonQuestion"
:answers="servicePackageAnswers"
:groupName="groupName"
buttonTypeString="servicePackageRadio"
:buttonTypeObject="servicePackageRadio"
v-model="selectedPackageName"
:validationRules="validationRules"
:isRequired="isRequired" />
</template>
<script>
import buttonQuestion from '@/digital-components/button-question/button-question';
import { processIfStatements } from '@/helpers/cms-content-helper';
import { damageLocationsSelected as glassLocations } from '@/constants/damage-locations-selected';
import servicePackageRadio from './service-package-radio/service-package-radio';
import { partTypeStrings } from '@/constants/part-type-strings';
import { useMainStore } from '@/store';
const packageNames = {
TIER_ONE: 'TierOne',
TIER_TWO: 'TierTwo',
TIER_THREE: 'TierThree',
};
export default {
name: 'servicePackageQuestion',
props: {
cmsWidgetName: String,
groupName: String,
validationRules: String,
isRequired: Boolean,
availableLineItems: []
},
data() {
return {
servicePackageRadio: servicePackageRadio,
selectedPackageName: null
};
},
watch: {
availableLineItems() {
const store = useMainStore();
if (this.allGlassPartsAndSupportingItemsHavePrices(store.order.lineItems)) {
this.selectDefaultPackage();
}
},
selectedPackageName(newValue) {
const VapsProductsInSelectedPackage = this.getVapsLineItemsForSelectedPackage(newValue);
this.$emit('vapsItemsSelected', VapsProductsInSelectedPackage);
}
},
computed: {
nullSafeAvailableLineItems() {
return this.availableLineItems ?? [];
},
servicePackageAnswers() {
if (!this.cmsWidgetName) return {};
const cmsAnswersContent = [
{
Name: 'TierOne',
cmsWidgetName: 'EconomyServicePackage'
},
{
Name: 'TierTwo',
cmsWidgetName: 'StandardServicePackage'
},
{
Name: 'TierThree',
cmsWidgetName: 'PremiumServicePackage'
}
];
//if cms content has not yet loaded, skip
if (this.getCmsContent(cmsAnswersContent[0].cmsWidgetName, 'HeaderText') == '') {
return {};
}
const modifiedAnswers = cmsAnswersContent.map((answer) => ({
value: answer.Name,
buttonLabel: this.getHeaderTextFromCms(answer.cmsWidgetName),
buttonLabelSubCopy: this.getSubheaderTextFromCms(answer.cmsWidgetName),
buttonBodyCopy: this.getBodyTextFromCms(answer.cmsWidgetName),
buttonAuxiliaryCopy: this.getPackagePriceString(answer.Name),
buttonFooterCopy: this.getFooterTextFromCms(answer.cmsWidgetName)
}
));
return modifiedAnswers;
},
frontWipersApplicableForTierTwo() {
const store = useMainStore();
const frontWipersAreAvailable = this.lineItemsContainsPartType(
partTypeStrings.FRONT_WIPER
);
const isRepair = store.order.damage.isRepair;
const glassToReplaceContainsWindshield = this.glassToReplaceContainsGlassLocation(
glassLocations.WINDSHIELD
);
if (frontWipersAreAvailable) {
if (isRepair) {
return true;
} else {
if (glassToReplaceContainsWindshield) {
return true;
} else {
return false;
}
}
} else {
return false;
}
},
rearWiperApplicableForTierTwo() {
const rearWiperIsAvailable = this.lineItemsContainsPartType(partTypeStrings.REAR_WIPER);
return (
this.glassToReplaceContainsGlassLocation(glassLocations.REAR) &&
rearWiperIsAvailable
);
},
frontWipersApplicableForTierThree() {
const frontWipersAreAvailable = this.lineItemsContainsPartType(partTypeStrings.FRONT_WIPER);
return frontWipersAreAvailable;
},
rearWiperApplicableForTierThree() {
const rearWiperIsAvailable = this.lineItemsContainsPartType(partTypeStrings.REAR_WIPER);
const frontWipersAreAvailable = this.lineItemsContainsPartType(partTypeStrings.FRONT_WIPER);
return (
rearWiperIsAvailable &&
(this.glassToReplaceContainsGlassLocation(glassLocations.REAR) ||
!frontWipersAreAvailable)
);
},
rainDefenseApplicableForTierThree() {
if (
this.rearWiperApplicableForTierTwo &&
!this.frontWipersApplicableForTierTwo &&
this.frontWipersApplicableForTierThree
) {
return false;
} else {
return true;
}
},
shouldDisplayTierTwoPackage() {
return this.frontWipersApplicableForTierTwo || this.rearWiperApplicableForTierTwo;
}
},
methods: {
processIfStatements,
getHeaderTextFromCms(cmsWidgetName) {
return this.getCmsContent(cmsWidgetName, 'HeaderText');
},
getSubheaderTextFromCms(cmsWidgetName) {
return this.getCmsContent(cmsWidgetName, 'SubheaderText');
},
getBodyTextFromCms(cmsWidgetName) {
const bodyText = this.getCmsContent(cmsWidgetName, "BodyText");
return this.processIfStatements(bodyText, "custom", this.getCustomValueFromString);
},
getFooterTextFromCms(cmsWidgetName) {
const footerText = this.getCmsContent(cmsWidgetName, "FooterText");
return this.processIfStatements(footerText, "custom", this.getCustomValueFromString);
},
getPackagePriceString(packageName) {
const formattedPriceFloat = parseFloat(this.getPackagePrice(packageName)).toFixed(2);
return '$' + formattedPriceFloat;
},
getPackagePrice(packageName) {
let priceFloat = 0;
if (packageName === packageNames.TIER_TWO) {
priceFloat += this.getTierTwoPackageVapsPrice();
} else if (packageName === packageNames.TIER_THREE) {
priceFloat += this.getTierThreePackageVapsPrice();
}
return priceFloat;
},
getTierTwoPackageVapsPrice() {
let vapsPrice = 0;
const priceFrontWipers = this.frontWipersApplicableForTierTwo;
const priceRearWipers = this.rearWiperApplicableForTierTwo;
this.nullSafeAvailableLineItems.forEach((item) => {
if (
(priceFrontWipers &&
item.partType.toUpperCase() === partTypeStrings.FRONT_WIPER) ||
(priceRearWipers && item.partType.toUpperCase() === partTypeStrings.REAR_WIPER)
) {
vapsPrice += this.getTotalLineItemPrice(item);
}
});
return vapsPrice;
},
getTierThreePackageVapsPrice() {
let vapsPrice = 0;
const priceFrontWipers = this.frontWipersApplicableForTierThree;
const priceRearWipers = this.rearWiperApplicableForTierThree;
const priceRainDefense = this.rainDefenseApplicableForTierThree;
this.nullSafeAvailableLineItems.forEach((item) => {
if (
(priceFrontWipers &&
item.partType.toUpperCase() === partTypeStrings.FRONT_WIPER) ||
(priceRearWipers &&
item.partType.toUpperCase() === partTypeStrings.REAR_WIPER) ||
(priceRainDefense &&
item.partType.toUpperCase() === partTypeStrings.RAIN_DEFENSE)
) {
vapsPrice += this.getTotalLineItemPrice(item);
}
});
return vapsPrice;
},
selectDefaultPackage() {
const store = useMainStore();
const vapsFromStore = store.lineItems.vaps;
let lowestTierForPackage = packageNames.TIER_ONE;
if (vapsFromStore?.length > 0) {
vapsFromStore.every((vapsItem) => {
let lowestTierForThisItem = this.getLowestTierForThisItem(vapsItem);
if (lowestTierForThisItem === packageNames.TIER_THREE) {
lowestTierForPackage = packageNames.TIER_THREE;
return false;
} else if (lowestTierForThisItem === packageNames.TIER_TWO) {
lowestTierForPackage = packageNames.TIER_TWO;
return true;
} else {
return true;
}
});
}
this.selectedPackageName = lowestTierForPackage;
},
allGlassPartsAndSupportingItemsHavePrices(lineItems) {
if (lineItems?.glassParts) {
for (let i = 0; i < lineItems.glassParts.length; i++) {
if (this.priceIsNullOrZero(lineItems.glassParts[i])) {
return false;
}
}
}
if (lineItems?.supportingItems) {
for (let i = 0; i < lineItems.supportingItems.length; i++) {
if (this.priceIsNullOrZero(lineItems.supportingItems[i])) {
return false;
}
}
}
return true;
},
priceIsNullOrZero(lineItem) {
return (
(lineItem.kitPrice == null || lineItem.kitPrice == 0) &&
(lineItem.laborAmount == null || lineItem.laborAmount == 0) &&
(lineItem.sellingPrice == null || lineItem.sellingPrice == 0)
);
},
getLowestTierForThisItem(vapsItem) {
let lowestTierForThisItem = null;
switch (vapsItem.partType) {
case partTypeStrings.FRONT_WIPER:
if (this.frontWipersApplicableForTierThree) {
lowestTierForThisItem = packageNames.TIER_THREE;
}
if (this.frontWipersApplicableForTierTwo) {
lowestTierForThisItem = packageNames.TIER_TWO;
}
break;
case partTypeStrings.REAR_WIPER:
if (this.rearWiperApplicableForTierThree) {
lowestTierForThisItem = packageNames.TIER_THREE;
}
if (this.rearWiperApplicableForTierTwo) {
lowestTierForThisItem = packageNames.TIER_TWO;
}
break;
case partTypeStrings.RAIN_DEFENSE:
if (this.rainDefenseApplicableForTierThree) {
lowestTierForThisItem = packageNames.TIER_THREE;
}
break;
}
return lowestTierForThisItem;
},
getVapsLineItemsForSelectedPackage(packageName) {
const vapsLineItemsForSelectedPackage = [];
if (packageName === packageNames.TIER_TWO) {
if (this.frontWipersApplicableForTierTwo) {
vapsLineItemsForSelectedPackage.push(
...this.getLineItemsContainingPartType(partTypeStrings.FRONT_WIPER)
);
}
if (this.rearWiperApplicableForTierTwo) {
vapsLineItemsForSelectedPackage.push(
...this.getLineItemsContainingPartType(partTypeStrings.REAR_WIPER)
);
}
} else if (packageName === packageNames.TIER_THREE) {
if (this.frontWipersApplicableForTierThree) {
vapsLineItemsForSelectedPackage.push(
...this.getLineItemsContainingPartType(partTypeStrings.FRONT_WIPER)
);
}
if (this.rearWiperApplicableForTierThree) {
vapsLineItemsForSelectedPackage.push(
...this.getLineItemsContainingPartType(partTypeStrings.REAR_WIPER)
);
}
if (this.rainDefenseApplicableForTierThree) {
vapsLineItemsForSelectedPackage.push(
...this.getLineItemsContainingPartType(partTypeStrings.RAIN_DEFENSE)
);
}
}
return vapsLineItemsForSelectedPackage;
},
getCustomValueFromString(str) {
switch (str) {
case 'isRecalibrationOnOrder':
return this.isRecalibrationOnOrder;
case 'frontWipersApplicableForTierTwo':
return this.frontWipersApplicableForTierTwo;
case 'rearWiperApplicableForTierTwo':
return this.rearWiperApplicableForTierTwo;
case 'frontWipersApplicableForTierThree':
return this.frontWipersApplicableForTierThree;
case 'rearWiperApplicableForTierThree':
return this.rearWiperApplicableForTierThree;
case 'rainDefenseApplicableForTierThree':
return this.rainDefenseApplicableForTierThree;
default:
return null;
}
},
getLineItemsContainingPartType(partType) {
const partTypeMatches = this.nullSafeAvailableLineItems.filter(
(lineItem) => lineItem.partType.toUpperCase() === partType
);
return partTypeMatches;
},
lineItemsContainsPartType(partType) {
const partTypeMatches = this.getLineItemsContainingPartType(partType);
return !!partTypeMatches.length;
},
glassToReplaceContainsGlassLocation(glassLocation) {
const store = useMainStore();
const glassLocationMatches =
store.order.damage.glassToReplace?.filter(
(glassToReplace) => glassToReplace.glassLocation === glassLocation
) ?? [];
return !!glassLocationMatches.length;
},
getTotalLineItemPrice(lineItem) {
return lineItem.kitPrice + lineItem.laborAmount + lineItem.sellingPrice
}
},
components: {
buttonQuestion
}
};
</script>

View file

@ -0,0 +1,127 @@
import { mount } from "@vue/test-utils"
import servicePackageRadio from "./service-package-radio"
import inputButtonWrapperMixin from "@/mixins/input-button-wrapper-mixin"
describe("service-package-radio.vue", () => {
it("Should include buttonLabel in html", async () => {
// Arrange
let { wrapper } = setupMocks({
mountOptionsMockData: {
propsData: mockProps,
},
})
// Act
const outputHtml = wrapper.html()
// Assert
expect(outputHtml).toEqual(expect.stringContaining(mockProps["buttonLabel"]))
})
it("Should include buttonLabelAuxillaryCopy in html", async () => {
// Arrange
let { wrapper } = setupMocks({
mountOptionsMockData: {
propsData: mockProps,
},
})
// Act
const outputHtml = wrapper.html()
// Assert
expect(outputHtml).toEqual(expect.stringContaining(mockProps["buttonLabelAuxillaryCopy"]))
})
it("Should include buttonLabelSubCopy in html", async () => {
// Arrange
let { wrapper } = setupMocks({
mountOptionsMockData: {
propsData: mockProps,
},
})
// Act
const outputHtml = wrapper.html()
// Assert
expect(outputHtml).toEqual(expect.stringContaining(mockProps["buttonLabelSubCopy"]))
})
it("Should include buttonFooterCopy in html", async () => {
// Arrange
let { wrapper } = setupMocks({
mountOptionsMockData: {
propsData: mockProps,
},
})
// Act
const outputHtml = wrapper.html()
// Assert
expect(outputHtml).toEqual(expect.stringContaining(mockProps["buttonFooterCopy"]))
})
it("Should get 5 strings from getArrayOfListItemsFromRawCmsCopy when provided with a dashed (x5) buttonBodyCopy", async () => {
// Arrange
let { wrapper } = setupMocks({
mountOptionsMockData: {
propsData: mockProps,
},
})
// Act
const results = wrapper.vm.getArrayOfListItemsFromRawCmsCopy(wrapper.vm.buttonBodyCopy)
// Assert
expect(results.length).toBe(5)
})
it("Should get strings from getArrayOfListItemsFromRawCmsCopy without dashes when provided with a dashed buttonBodyCopy", async () => {
// Arrange
let { wrapper } = setupMocks({
mountOptionsMockData: {
propsData: mockProps,
},
})
// Act
const results = wrapper.vm.getArrayOfListItemsFromRawCmsCopy(wrapper.vm.buttonBodyCopy)
// Assert
const fileredResults = results.filter((result) => {
return result.includes(" -");
})
expect(fileredResults.length).toBe(0)
})
it("Should get 5 strings from getArrayOfListItemsFromRawCmsCopy when buttonBodyCopy has 6 total dashes, but one is empty ", async () => {
// Arrange
const moddedProps = mockProps
moddedProps["buttonBodyCopy"] = "- buttonBodyCopy test copy - 2 - 3 - 4 - 5 -"
let { wrapper } = setupMocks({
mountOptionsMockData: {
propsData: moddedProps,
},
})
// Act
const results = wrapper.vm.getArrayOfListItemsFromRawCmsCopy(wrapper.vm.buttonBodyCopy)
// Assert
expect(results.length).toBe(5)
})
})
const mockProps = {
buttonLabel: 'buttonLabel test copy',
buttonLabelAuxillaryCopy: 'buttonLabelAuxillaryCopy test copy',
buttonLabelSubCopy: 'buttonLabelSubCopy test copy',
buttonBodyCopy: '- buttonBodyCopy test copy - 2 - 3 - 4 - 5',
buttonFooterCopy: 'buttonFooterCopy test copy'
}
function setupMocks({ mountOptionsMockData = {} }) {
const wrapper = mount(servicePackageRadio, {
...mountOptionsMockData,
mixins: [inputButtonWrapperMixin]
})
return { wrapper }
}

View file

@ -0,0 +1,265 @@
<template>
<baseInputButton v-bind="$props" @buttonClicked="handleAnswerChange" v-model="selectedValue">
<div class="package-label mb-4"
:class="[this.buttonLabelSubCopy ? 'has-subheader' : '']"
for="testradio">
<div class="package-specs">
<p class="m-0">
<span v-html="this.buttonLabel"></span>
<span class="pricing-info" v-html="this.buttonAuxiliaryCopy"></span>
</p>
<p class="sub-label m-0"
v-if="this.buttonLabelSubCopy"
v-html="this.buttonLabelSubCopy"></p>
<div>
<ul >
<li v-for="listItem in this.arrayOfListItemsFromBodyText" :key="listItem" class="mb-0">
<!-- no textLink -->
<span v-if="!doesCopyContainTextLink(listItem)"
v-html="listItem"></span>
<!-- with textLink -->
<template v-else
v-for="copy in splitCopyOnCMSPlaceHolder(listItem)"
:key="copy">
<span v-if="!doesCopyContainTextLink(copy)" v-html="copy"></span>
<span v-else>
<textLink linkType="text"
:text="getRouterLinkDisplayTextFromCopy(copy)"
href="#!"
@click-event="
$emit('buttonEvent', {
eventName: 'openModal',
args: getRouterLinkRouteFromCopy(copy),
})
"
:data-bs-target="'#' + getRouterLinkRouteFromCopy(copy)"
aria-label="Modal window" />
</span>
</template>
</li>
</ul>
<!-- End of body text parsing -->
<!--ms-n6-->
<div class="package-footer fw-bold caption mt-4 ml-n4 mr-3"
v-if="this.buttonFooterCopy"
v-html="this.buttonFooterCopy"></div>
</div>
</div>
</div>
</baseInputButton>
</template>
<script>
import baseInputButton from '@/digital-components/base-input-button/base-input-button';
import textLink from '@/ux-components/text-link/text-link';
import inputButtonWrapperMixin from '@/mixins/input-button-wrapper-mixin';
import {
getRouterLinkDisplayTextFromCopy,
getRouterLinkRouteFromCopy,
splitCopyOnCMSPlaceHolder,
doesCopyContainTextLink,
} from '@/helpers/cms-content-helper';
export default {
name: 'servicePackageRadio',
mixins: [inputButtonWrapperMixin],
components: {
baseInputButton,
textLink,
},
computed: {
arrayOfListItemsFromBodyText() {
return this.getArrayOfListItemsFromRawCmsCopy(this.buttonBodyCopy);
},
},
methods: {
getRouterLinkDisplayTextFromCopy,
getRouterLinkRouteFromCopy,
splitCopyOnCMSPlaceHolder,
doesCopyContainTextLink,
stripUlTagFromCopy(copy) {
return copy;
},
getArrayOfListItemsFromRawCmsCopy(copy) {
if (copy) {
return copy
.split('- ') //At some point we'll want a better delimiter
.filter((lineItem) => lineItem);
}
}
},
};
</script>
<style lang="scss" scoped>
.ml-n4 {
margin-left: -$spacer * 2;
}
.mr-3 {
margin-right: $spacer * 1.5;
}
.package-main {
.package-wrapper {
margin: 0.5rem 0;
label {
display: block;
}
input[type="radio"] {
opacity: 0;
position: absolute;
left: -9999px;
+ .package-label {
display: flex;
align-items: flex-start;
position: relative;
cursor: pointer;
width: 100%;
padding: 1rem;
border: 1px solid $gray-300;
box-shadow: 0px 4px 8px -4px rgba(0, 0, 0, 0.15), 0px 4px 24px -8px rgba(0, 0, 0, 0.2);
border-radius: 0.5rem;
overflow: hidden;
min-height: 60px;
&.has-subheader {
min-height: 80px;
}
&:before {
content: "";
position: relative;
top: 5px;
margin-right: 1rem;
border-radius: 50%;
border: 1px solid $gray-500;
width: 16px;
height: 16px;
min-width: 16px;
}
&:after {
content: "";
position: absolute;
left: 19px;
top: 24px;
border-radius: 50%;
width: 10px;
height: 10px;
min-width: 10px;
}
}
&:hover {
+ .package-label {
&:before {
border: 1px solid #8e9292;
box-shadow: 0px 0px 0px 4px #9fcee6, 0px 1px 4px rgba(0, 0, 0, 0.2);
}
}
}
&:checked {
+ .package-label {
.package-specs {
max-height: 1000px;
}
}
+ .package-label {
.package-specs {
.hide-when-closed {
display: block;
}
}
}
+ .package-label {
background-color: $blue-100;
border: 1px solid $blue;
max-height: 500px;
}
+ .package-label {
&:before {
box-shadow: 0px 0px 0px 1px $blue;
}
}
+ .package-label {
&:after {
background: $blue;
}
}
}
&:focus {
+ .package-label {
&:before {
border: 2px solid $blue;
}
}
}
}
.package-footer {
color: $red;
}
.package-specs {
display: flex;
flex-direction: column;
width: 100%;
max-height: 1000px;
transition: all 0.5s ease;
p {
font-weight: 500;
display: flex;
justify-content: space-between;
span {
&.pricing-info {
color: $green;
font-size: 0.875rem;
}
}
&.sub-label {
color: $green;
text-transform: uppercase;
font-size: 0.75rem;
}
}
ul {
margin: 1rem 0 0 -.6rem;
padding: 0;
li {
margin-bottom: 0.5rem;
font-size: 0.875rem;
line-height: 1.714;
a {
line-height: 1.714;
padding: 0;
}
}
}
@keyframes slideaway {
from {
display: block;
}
to {
transform: translateY(40px);
opacity: 0;
}
}
}
}
}
</style>

View file

@ -0,0 +1,150 @@
<template>
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }">
<div class="page-container-grouped-styles">
<loadingModal ref="loadingModal" />
<siteHeader cmsWidgetName="SiteHeaderWidget" />
<siteSubHeader cmsWidgetName="SiteSubHeaderWidget"
justification="left"
issContainingPage="service-packages"/>
<div class="fade-on-route-transition sub-container make-tall">
<servicePackageQuestion ref="servicePackage"
cmsWidgetName="ServicePackage"
groupName="ServicePackageQuestion"
:availableLineItems="availableLineItems"
@vapsItemsSelected="vapsItemsSelectedAction"
v-on="{ 'buttonEvent.openModal': openModalAction }"
validationRules="option-required"
isRequired />
<textBlock cmsWidgetName="PriceDisclaimerWidget"
justifyText="left"
typeStyle="caption"
style="margin-bottom: 6rem;"
class="mt-2 mx-6" />
<contentGroupModal ref="RainDefenseModal" cmsWidgetName="RainDefenseModal" />
<contentGroupModal ref="FrontWiperModal" cmsWidgetName="FrontWiperModal" />
<contentGroupModal ref="RearWiperModal" cmsWidgetName="RearWiperModal" />
<contentGroupModal ref="RecalModal" cmsWidgetName="RecalModal" />
<siteFooter cmsWidgetName="SiteFooterWidget"
:isForwardActionDisabled="!meta.valid"
@back-clicked="backButtonAction"
@ForwardClicked="forwardButtonAction" />
</div>
</div>
</Form>
</template>
<script>
// Components
import siteHeader from '@/iss-components/site-header/site-header';
import siteFooter from '@/iss-components/site-footer/site-footer';
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header';
import servicePackageQuestion from './service-package-question/service-package-question';
import textBlock from '@/digital-components/text-block/text-block';
import contentGroupModal from '@/iss-components/content-group-modal/content-group-modal';
import loadingModal from '@/iss-components/loading-modal/loading-modal.vue';
import { settleAllPromises } from '@/helpers/layout-helper';
import { useMainStore } from "@/store";
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import { required } from '@/helpers/validation-rules';
import { errorMessages } from '@/constants/error-messages';
import { Form, defineRule } from 'vee-validate';
defineRule('option-required', required(errorMessages.OPTION_REQUIRED));
export default {
name: 'service-packages',
async beforeRouteEnter(to, from, next) {
const store = useMainStore();
// Call APIs
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
const wipersPromise = await store.getWipers();
const rainDefensePromise = await store.getRainDefense();
const supportingItemsPromise = await store.getSupportingItems();
const promiseResultMap = [
{
resultKey: 'cmsContent',
promise: cmsContentPromise,
},
{
resultKey: 'wipers',
promise: wipersPromise,
},
{
resultKey: 'rainDefense',
promise: rainDefensePromise,
},
{
resultKey: 'supportingItems',
promise: supportingItemsPromise,
},
];
const resultMap = await settleAllPromises(promiseResultMap);
const clonedGlassParts = store.order.lineItems.glassParts
? JSON.parse(JSON.stringify(store.order.lineItems.glassParts))
: [];
const availableLineItems = [
resultMap.rainDefense,
...resultMap.supportingItems,
...resultMap.wipers,
...clonedGlassParts,
];
const pricingResults = await store.getPriceOrderItems(availableLineItems);
// Call the "next" function to complete the transition to this page.
next((vm) => {
vm.setCmsContent(resultMap.cmsContent);
vm.pricedGlassParts = clonedGlassParts;
vm.supportingItems = resultMap.supportingItems;
vm.availableLineItems = pricingResults;
});
},
data() {
return {
selectedVaps: null,
availableLineItems: null,
supportingItems: null,
pricedGlassParts: null
};
},
methods: {
openModalAction(modalName) {
this.$refs[modalName].openModal();
},
arePagePrerequisitesValid() {
const store = useMainStore();
return (
store.order.serviceLocation.zipCode &&
store.order.serviceLocation.zipCodeCtu &&
(store.order.damage.isRepair ||
(store.order.lineItems?.glassParts != null &&
store.order.lineItems.glassParts.length > 0)) &&
store.order.referralNumber?.length !== 6
);
},
vapsItemsSelectedAction(vapsItemsSelected) {
this.selectedVaps = vapsItemsSelected;
},
backButtonAction() {
this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route);
},
forwardButtonAction() {
//TODO: save items
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD, this.$route);
}
},
components: {
siteHeader,
siteFooter,
siteSubHeader,
Form, /* eslint-disable-line */
textBlock,
servicePackageQuestion,
loadingModal,
contentGroupModal
}
};
</script>

View file

@ -22,6 +22,12 @@ const vueApp = createApp(App);
*/ */
vueApp.config.unwrapInjectedRef = true; vueApp.config.unwrapInjectedRef = true;
vueApp.config.compilerOptions.isCustomElement = (tag) => {
return (tag === 'siteSubHeader' ||
tag === 'ServicePackages' ||
tag === 'servicePackageQuestion');
}
// Pinia // Pinia
const pinia = createPinia(); const pinia = createPinia();
vueApp.use(pinia); vueApp.use(pinia);

View file

@ -10,7 +10,7 @@ export default {
buttonLabel: [Number, String], buttonLabel: [Number, String],
buttonLabelSubCopy: String, buttonLabelSubCopy: String,
buttonBodyCopy: String, buttonBodyCopy: String,
buttonAuxillaryCopy: String, buttonAuxiliaryCopy: String,
buttonFooterCopy: String, buttonFooterCopy: String,
buttonImage: String, buttonImage: String,
buttonImageId: String, buttonImageId: String,

View file

@ -285,8 +285,7 @@ describe("vehicle-questions-mixin", () => {
const testCases = [ const testCases = [
[issPageValues.PART_QUESTIONS, issPageValues.VEHICLE_PARTS, true], [issPageValues.PART_QUESTIONS, issPageValues.VEHICLE_PARTS, true],
[issPageValues.VEHICLE_PARTS, issPageValues.VEHICLE_PARTS, false], [issPageValues.VEHICLE_PARTS, issPageValues.VEHICLE_PARTS, false],
[issPageValues.QUOTE, issPageValues.VEHICLE_PARTS, false], [issPageValues.VEHICLE_PARTS, issPageValues.REVEAL, false],
[issPageValues.QUOTE, issPageValues.QUOTE, false],
[issPageValues.VEHICLE_PARTS, issPageValues.PART_QUESTIONS, false], [issPageValues.VEHICLE_PARTS, issPageValues.PART_QUESTIONS, false],
[issPageValues.PART_QUESTIONS, issPageValues.CAPABILITY_QUESTIONS, true], [issPageValues.PART_QUESTIONS, issPageValues.CAPABILITY_QUESTIONS, true],
[issPageValues.MOLDING_QUESTIONS, issPageValues.CAPABILITY_QUESTIONS, true], [issPageValues.MOLDING_QUESTIONS, issPageValues.CAPABILITY_QUESTIONS, true],
@ -310,8 +309,7 @@ describe("vehicle-questions-mixin", () => {
const testCases = [ const testCases = [
[issPageValues.PART_QUESTIONS, issPageValues.VEHICLE_PARTS, false], [issPageValues.PART_QUESTIONS, issPageValues.VEHICLE_PARTS, false],
[issPageValues.VEHICLE_PARTS, issPageValues.VEHICLE_PARTS, false], [issPageValues.VEHICLE_PARTS, issPageValues.VEHICLE_PARTS, false],
[issPageValues.QUOTE, issPageValues.VEHICLE_PARTS, true], [issPageValues.VEHICLE_PARTS, issPageValues.SERVICE_LOCATION, true],
[issPageValues.QUOTE, issPageValues.QUOTE, false],
[issPageValues.VEHICLE_PARTS, issPageValues.PART_QUESTIONS, true], [issPageValues.VEHICLE_PARTS, issPageValues.PART_QUESTIONS, true],
[issPageValues.PART_QUESTIONS, issPageValues.CAPABILITY_QUESTIONS, false], [issPageValues.PART_QUESTIONS, issPageValues.CAPABILITY_QUESTIONS, false],
[issPageValues.MOLDING_QUESTIONS, issPageValues.CAPABILITY_QUESTIONS, false], [issPageValues.MOLDING_QUESTIONS, issPageValues.CAPABILITY_QUESTIONS, false],
@ -2079,188 +2077,9 @@ describe("vehicle-questions-mixin", () => {
); );
}); });
}); });
// TODO KO UNSKIP FOR QUOTE MVP
describe.skip("should go to quote page", () => {
test("single glass location selected, has no part questions and has one part => go to heritage funnel", async () => {
// Arrange
const partsOrQuestions = [
{
glassName: "Single",
glassLocation: "Windshield",
parts: [
{
partNumber: "FW04186GTYN",
description: "solar, soundproofing, lane keep assist",
color: "Green Tint",
requiresRecalibration: true,
requiresCapabilityQuestions: false,
childParts: [
{
partNumber: "GGG 3563 KIT",
partType: "MOULDING",
description: "Kit, Top & Sides ",
},
],
},
],
partQuestions: null,
},
];
const { wrapper } = setupMocks({
partsOrQuestions: partsOrQuestions,
});
// Act
await wrapper.vm.navigateForward(partsOrQuestions);
// Assert
expect(wrapper.vm.$router.navigate).toHaveBeenCalledTimes(1);
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS,
{ query: { issPage: "vin-lookup" } }
);
});
test("multiple glass locations selected, each has one part and no part questions => go to heritage funnel", async () => {
// Arrange
const partsOrQuestions = [
{
glassName: "Single",
glassLocation: "Windshield",
parts: [
{
partNumber: "FW04186GTYN",
description: "solar, soundproofing, lane keep assist",
color: "Green Tint",
requiresRecalibration: true,
requiresCapabilityQuestions: false,
childParts: [
{
partNumber: "GGG 3563 KIT",
partType: "MOULDING",
description: "Kit, Top & Sides ",
},
],
},
],
partQuestions: null,
},
{
glassName: "Back",
glassLocation: "Driver",
parts: [
{
partNumber: "FD25457GTYN",
description: "solar, driver side, rear",
color: "Green Tint",
requiresRecalibration: false,
requiresCapabilityQuestions: false,
childParts: null,
},
],
partQuestions: null,
},
{
glassName: "Front",
glassLocation: "Driver",
parts: [
{
partNumber: "FD27090GTYN",
description: "solar, driver side, front",
color: "Green Tint",
requiresRecalibration: false,
requiresCapabilityQuestions: false,
childParts: null,
},
],
partQuestions: null,
},
{
glassName: "Vent",
glassLocation: "Driver",
parts: [
{
partNumber: "FV25459GTNN",
description: "solar, driver side, rear",
color: "Green Tint",
requiresRecalibration: false,
requiresCapabilityQuestions: false,
childParts: null,
},
],
partQuestions: null,
},
{
glassName: "Stationary",
glassLocation: "Rear",
parts: [
{
partNumber: "FB25460GTYN",
description: "heated glass, solar",
color: "Green Tint",
requiresRecalibration: false,
requiresCapabilityQuestions: false,
childParts: null,
},
],
partQuestions: null,
},
];
const { wrapper } = setupMocks({
partsOrQuestions: partsOrQuestions,
});
// Act
await wrapper.vm.navigateForward(partsOrQuestions);
// Assert
expect(useMainStore.updateGlassParts).toHaveBeenCalledTimes(1);
expect(wrapper.vm.$router.navigate).toHaveBeenCalledTimes(1);
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS,
{ query: { issPage: "vin-lookup" } }
);
});
});
}); });
describe("navigateBack", () => { describe("navigateBack", () => {
test("current page is quote and there are capability questions => go to capability questions", () => {
// Arrange
const { wrapper } = setupMocks({ issPage: issPageValues.QUOTE });
wrapper.vm.hasCapabilityQuestions = jest.fn().mockReturnValue(true);
// Act
wrapper.vm.navigateBack();
// Assert
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
navigationScenarios.CLICKED_BACK_WITH_CAPABILITY_QUESTIONS,
{ query: { issPage: issPageValues.QUOTE } }
);
});
test("current page is quote and there are part questions and molding questions => go to molding questions", () => {
// Arrange
const { wrapper } = setupMocks({ issPage: issPageValues.QUOTE });
wrapper.vm.hasPartQuestions = jest.fn().mockReturnValue(true);
wrapper.vm.hasChildPartQuestions = jest.fn().mockReturnValue(true);
// Act
wrapper.vm.navigateBack();
// Assert
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
navigationScenarios.CLICKED_BACK_WITH_MOLDING_QUESTIONS,
{ query: { issPage: issPageValues.QUOTE } }
);
});
test("current page is molding questions and there are part questions, multiple parts to choose, and capability questions => go to vehicle-parts", () => { test("current page is molding questions and there are part questions, multiple parts to choose, and capability questions => go to vehicle-parts", () => {
// Arrange // Arrange
const { wrapper } = setupMocks({ issPage: issPageValues.MOLDING_QUESTIONS }); const { wrapper } = setupMocks({ issPage: issPageValues.MOLDING_QUESTIONS });

View file

@ -68,6 +68,7 @@ const routes = [
console.log(error); console.log(error);
GoToStartOn404(next); GoToStartOn404(next);
} }
return null;
} }
}]; }];
@ -77,10 +78,10 @@ const router = createRouter({
scrollBehavior(to, from, savedPosition) { scrollBehavior(to, from, savedPosition) {
// always scroll to top // always scroll to top
return { top: 0 } return { top: 0 }
}, }
}); });
router.afterEach((to, from) => { router.afterEach((to, from) => { /*eslint-disable-line*/
const store = useMainStore(); const store = useMainStore();
// Update lastPageVisited in the store // Update lastPageVisited in the store
@ -110,12 +111,12 @@ async function GetRouteInfoFromPageName(pageName) {
routeData.push({ routeData.push({
path: "/", path: "/",
name: `${key}`, name: `${key}`,
component: lazyLoadComponent(jsonFromResponse[key].LayoutName), component: lazyLoadComponent(jsonFromResponse[key].LayoutName)
}); });
}); });
return routeData; return routeData;
}; }
//Use this navigation when you need to call next() explicitly. beforeRouteEnter is a good example. //Use this navigation when you need to call next() explicitly. beforeRouteEnter is a good example.
router.overrideNavigation = ( router.overrideNavigation = (
@ -145,7 +146,7 @@ router.navigate = (scenario, currentRoute, optionalQuery = {}, optionalParams =
} }
// Navigate to the next route, depending on the scenario. // Navigate to the next route, depending on the scenario.
function navigate (scenario, currentRoute, optionalQuery = {}, optionalParams = {}, optionalPageData = {}) { function navigate (scenario, currentRoute, optionalQuery = {}, optionalParams = {}, optionalPageData = {}) { /*eslint-disable-line*/
if (!scenario) { if (!scenario) {
console.error("No scenario provided. Please review the routing table."); console.error("No scenario provided. Please review the routing table.");
return; return;
@ -174,7 +175,7 @@ function navigate (scenario, currentRoute, optionalQuery = {}, optionalParams =
router.push({ router.push({
name: "root", name: "root",
query: Object.assign(optionalQuery, { query: Object.assign(optionalQuery, {
issPage: matchingScenarioMap.destinationIssPageValue, issPage: matchingScenarioMap.destinationIssPageValue
}), }),
params: optionalParams params: optionalParams
}); });
@ -186,7 +187,7 @@ function navigate (scenario, currentRoute, optionalQuery = {}, optionalParams =
// Navigate to an external url. // Navigate to an external url.
function navigateToUrl(url, optionalQuery = {}) { function navigateToUrl(url, optionalQuery = {}) {
// possibly show some loading screen in the future here. // possibly show some loading screen in the future here.
let externalUrl = new URL(url); const externalUrl = new URL(url);
for (const queryKey in optionalQuery) { for (const queryKey in optionalQuery) {
externalUrl.searchParams.append(queryKey, optionalQuery[queryKey]); externalUrl.searchParams.append(queryKey, optionalQuery[queryKey]);
@ -223,7 +224,7 @@ function GoToStartOn404(next) {
router.addRoute({ router.addRoute({
path: "/", path: "/",
name: errorPageName, name: errorPageName,
component: lazyLoadComponent(errorPageName), component: lazyLoadComponent(errorPageName)
}); });
// Put item on the bus // Put item on the bus
@ -234,13 +235,13 @@ function GoToStartOn404(next) {
isDismissible: true, isDismissible: true,
messageCopy: "You can get a quote by starting on this page.", messageCopy: "You can get a quote by starting on this page.",
messageHeadline: "We're sorry, something went wrong.", messageHeadline: "We're sorry, something went wrong.",
type: globalEventTypes.Danger, type: globalEventTypes.Danger
} }
); );
next({ next({
name: errorPageName, name: errorPageName,
query: {issPage: errorPageName }, query: {issPage: errorPageName }
}); });
}; };
@ -253,14 +254,14 @@ async function runExperiments(nextPage) {
await store.runExperimentsForTrigger({ await store.runExperimentsForTrigger({
userId: getDeviceIdValue(), userId: getDeviceIdValue(),
triggerEvent: experimentTriggers.SITE_ENTRY, triggerEvent: experimentTriggers.SITE_ENTRY,
triggerValue: applicationConfig.SITE_ENTRY_TRIGGER_VALUE, triggerValue: applicationConfig.SITE_ENTRY_TRIGGER_VALUE
}); });
} }
await store.runExperimentsForTrigger({ await store.runExperimentsForTrigger({
userId: getDeviceIdValue(), userId: getDeviceIdValue(),
triggerEvent: experimentTriggers.PAGE_ENTRY, triggerEvent: experimentTriggers.PAGE_ENTRY,
triggerValue: nextPage, triggerValue: nextPage
}); });
} }

View file

@ -1,31 +1,28 @@
export const issPageValues = { export const issPageValues = {
ENTRY_PAGE: "entry-page", ENTRY_PAGE: 'entry-page',
WELCOME_PAGE: "welcome-page", WELCOME_PAGE: 'welcome-page',
POLICY_HOLDER_DETAILS: "policy-holder-details",
VEHICLE_MAKE: "vehicle-make", ADDRESS_LOOKUP: 'address-lookup',
VEHICLE_YEAR: "vehicle-year", ADDRESS_VEHICLES: 'address-vehicles',
VEHICLE_MODEL: "vehicle-model", CAPABILITY_QUESTIONS: 'capability-questions',
VEHICLE_STYLE: "vehicle-style", ESTIMATE: 'estimate',
VEHICLE_DAMAGE: "vehicle-damage", COVERAGE_STATEMENT: 'coverage-statement',
VEHICLE_LOOKUP: "vehicle-lookup", LICENSE_PLATE_LOOKUP: 'license-plate-lookup',
ADDRESS_LOOKUP: "address-lookup", MOLDING_QUESTIONS: 'molding-questions',
ADDRESS_VEHICLES: "address-vehicles", PART_QUESTIONS: 'part-questions',
LICENSE_PLATE_LOOKUP: "license-plate-lookup", POLICY_HOLDER_DETAILS: 'policy-holder-details',
VIN_LOOKUP: "vin-lookup", PROVIDER_PREFERENCE: 'provider-preference',
VEHICLE_PARTS: "vehicle-parts", REVEAL: 'reveal',
PART_QUESTIONS: "part-questions", REVIEW_ORDER: 'review-order',
MOLDING_QUESTIONS: "molding-questions", SERVICE_LOCATION: 'service-location',
CAPABILITY_QUESTIONS: "capability-questions", SERVICE_PACKAGE: 'service-package',
COVERAGE_STATEMENT: "coverage-statement", VEHICLE_DAMAGE: 'vehicle-damage',
PROVIDER_PREFERENCE: "provider-preference", VEHICLE_LOOKUP: 'vehicle-lookup',
SERVICE_LOCATION: "service-location", VEHICLE_MAKE: 'vehicle-make',
SCHEDULE_PAGE: "schedule-page", VEHICLE_MODEL: 'vehicle-model',
CONTACT_DETAILS: "contact-details", VEHICLE_PARTS: 'vehicle-parts',
PAYMENT_PAGE: "payment-page", VEHICLE_STYLE: 'vehicle-style',
REVEAL: "reveal", VEHICLE_YEAR: 'vehicle-year',
ESTIMATE: "estimate", VIN_LOOKUP: 'vin-lookup'
ADDRESS_VEHICLES: "address-vehicles",
QUOTE: "quote",
HERITAGE: "heritage",
}; };

View file

@ -1,5 +1,5 @@
import { issPageValues } from "@/router/router-constants/issPage-values"; import { issPageValues } from '@/router/router-constants/issPage-values';
import { navigationScenarios } from "@/router/router-constants/navigation-scenarios"; import { navigationScenarios } from '@/router/router-constants/navigation-scenarios';
// Get store from router/index.js instead of importing it here to get updated values // Get store from router/index.js instead of importing it here to get updated values
const routingTable = function(store) { const routingTable = function(store) {
@ -14,8 +14,8 @@ const routingTable = function(store) {
{ {
scenario: navigationScenarios.SELECTED_YEAR, scenario: navigationScenarios.SELECTED_YEAR,
destinationIssPageValue: issPageValues.VEHICLE_MAKE destinationIssPageValue: issPageValues.VEHICLE_MAKE
}, }
], ]
}, },
{ {
issPageValue: issPageValues.VEHICLE_MAKE, issPageValue: issPageValues.VEHICLE_MAKE,
@ -27,19 +27,19 @@ const routingTable = function(store) {
{ {
scenario: navigationScenarios.SELECTED_MAKE, scenario: navigationScenarios.SELECTED_MAKE,
destinationIssPageValue: issPageValues.VEHICLE_MODEL destinationIssPageValue: issPageValues.VEHICLE_MODEL
}, }
], ]
}, },
{ {
issPageValue: issPageValues.VEHICLE_MODEL, issPageValue: issPageValues.VEHICLE_MODEL,
maps: [ maps: [
{ {
scenario: navigationScenarios.CLICKED_BACK, scenario: navigationScenarios.CLICKED_BACK,
destinationIssPageValue: issPageValues.VEHICLE_MAKE, destinationIssPageValue: issPageValues.VEHICLE_MAKE
}, },
{ {
scenario: navigationScenarios.SELECTED_MODEL, scenario: navigationScenarios.SELECTED_MODEL,
destinationIssPageValue: issPageValues.VEHICLE_STYLE, destinationIssPageValue: issPageValues.VEHICLE_STYLE
} }
] ]
}, },
@ -48,11 +48,11 @@ const routingTable = function(store) {
maps: [ maps: [
{ {
scenario: navigationScenarios.CLICKED_BACK, scenario: navigationScenarios.CLICKED_BACK,
destinationIssPageValue: issPageValues.VEHICLE_MODEL, destinationIssPageValue: issPageValues.VEHICLE_MODEL
}, },
{ {
scenario: navigationScenarios.SELECTED_STYLE, scenario: navigationScenarios.SELECTED_STYLE,
destinationIssPageValue: issPageValues.VEHICLE_DAMAGE, destinationIssPageValue: issPageValues.VEHICLE_DAMAGE
} }
] ]
}, },
@ -61,298 +61,298 @@ const routingTable = function(store) {
maps: [ maps: [
{ {
scenario: navigationScenarios.CLICKED_BACK, scenario: navigationScenarios.CLICKED_BACK,
destinationIssPageValue: issPageValues.VEHICLE_STYLE, destinationIssPageValue: issPageValues.VEHICLE_STYLE
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_REPAIR, scenario: navigationScenarios.CLICKED_FORWARD_WITH_REPAIR,
destinationIssPageValue: issPageValues.COVERAGE_STATEMENT, destinationIssPageValue: issPageValues.COVERAGE_STATEMENT
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_VIN, scenario: navigationScenarios.CLICKED_FORWARD_WITH_VIN,
destinationIssPageValue: issPageValues.VEHICLE_LOOKUP, destinationIssPageValue: issPageValues.VEHICLE_LOOKUP
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITHOUT_VIN, scenario: navigationScenarios.CLICKED_FORWARD_WITHOUT_VIN,
destinationIssPageValue: issPageValues.VEHICLE_LOOKUP, destinationIssPageValue: issPageValues.VEHICLE_LOOKUP
}, }
], ]
}, },
{ {
issPageValue: issPageValues.VEHICLE_LOOKUP, issPageValue: issPageValues.VEHICLE_LOOKUP,
maps: [ maps: [
{ {
scenario: navigationScenarios.CLICKED_BACK, scenario: navigationScenarios.CLICKED_BACK,
destinationIssPageValue: issPageValues.VEHICLE_DAMAGE, destinationIssPageValue: issPageValues.VEHICLE_DAMAGE
}, },
{ {
scenario: navigationScenarios.SELECTED_MANUAL_VIN, scenario: navigationScenarios.SELECTED_MANUAL_VIN,
destinationIssPageValue: issPageValues.VIN_LOOKUP, destinationIssPageValue: issPageValues.VIN_LOOKUP
}, },
{ {
scenario: navigationScenarios.SELECTED_LICENSE_PLATE, scenario: navigationScenarios.SELECTED_LICENSE_PLATE,
destinationIssPageValue: issPageValues.LICENSE_PLATE_LOOKUP, destinationIssPageValue: issPageValues.LICENSE_PLATE_LOOKUP
}, },
{ {
scenario: navigationScenarios.SELECTED_HOME_ADDRESS, scenario: navigationScenarios.SELECTED_HOME_ADDRESS,
destinationIssPageValue: issPageValues.ADDRESS_LOOKUP, destinationIssPageValue: issPageValues.ADDRESS_LOOKUP
}, }
], ]
}, },
{ {
issPageValue: issPageValues.VIN_LOOKUP, issPageValue: issPageValues.VIN_LOOKUP,
maps: [ maps: [
{ {
scenario: navigationScenarios.CLICKED_BACK, scenario: navigationScenarios.CLICKED_BACK,
destinationIssPageValue: issPageValues.VEHICLE_LOOKUP, destinationIssPageValue: issPageValues.VEHICLE_LOOKUP
}, },
{ {
scenario: navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS, scenario: navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
destinationIssPageValue: issPageValues.VEHICLE_DAMAGE, destinationIssPageValue: issPageValues.VEHICLE_DAMAGE
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_PART_QUESTIONS, scenario: navigationScenarios.CLICKED_FORWARD_WITH_PART_QUESTIONS,
destinationIssPageValue: issPageValues.PART_QUESTIONS, destinationIssPageValue: issPageValues.PART_QUESTIONS
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_PARTS_TO_CHOOSE, scenario: navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_PARTS_TO_CHOOSE,
destinationIssPageValue: issPageValues.VEHICLE_PARTS, destinationIssPageValue: issPageValues.VEHICLE_PARTS
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_MOLDING_QUESTIONS, scenario: navigationScenarios.CLICKED_FORWARD_WITH_MOLDING_QUESTIONS,
destinationIssPageValue: issPageValues.MOLDING_QUESTIONS, destinationIssPageValue: issPageValues.MOLDING_QUESTIONS
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_CAPABILITY_QUESTIONS, scenario: navigationScenarios.CLICKED_FORWARD_WITH_CAPABILITY_QUESTIONS,
destinationIssPageValue: issPageValues.CAPABILITY_QUESTIONS, destinationIssPageValue: issPageValues.CAPABILITY_QUESTIONS
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS, scenario: navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS,
destinationIssPageValue: issPageValues.COVERAGE_STATEMENT, destinationIssPageValue: issPageValues.COVERAGE_STATEMENT
}, }
], ]
}, },
{ {
issPageValue: issPageValues.LICENSE_PLATE_LOOKUP, issPageValue: issPageValues.LICENSE_PLATE_LOOKUP,
maps: [ maps: [
{ {
scenario: navigationScenarios.CLICKED_BACK, scenario: navigationScenarios.CLICKED_BACK,
destinationIssPageValue: issPageValues.VEHICLE_LOOKUP, destinationIssPageValue: issPageValues.VEHICLE_LOOKUP
}, },
{ {
scenario: navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS, scenario: navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
destinationIssPageValue: issPageValues.VEHICLE_DAMAGE, destinationIssPageValue: issPageValues.VEHICLE_DAMAGE
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS, scenario: navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS,
destinationIssPageValue: issPageValues.COVERAGE_STATEMENT, destinationIssPageValue: issPageValues.COVERAGE_STATEMENT
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_PART_QUESTIONS, scenario: navigationScenarios.CLICKED_FORWARD_WITH_PART_QUESTIONS,
destinationIssPageValue: issPageValues.PART_QUESTIONS, destinationIssPageValue: issPageValues.PART_QUESTIONS
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_PARTS_TO_CHOOSE, scenario: navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_PARTS_TO_CHOOSE,
destinationIssPageValue: issPageValues.VEHICLE_PARTS, destinationIssPageValue: issPageValues.VEHICLE_PARTS
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_MOLDING_QUESTIONS, scenario: navigationScenarios.CLICKED_FORWARD_WITH_MOLDING_QUESTIONS,
destinationIssPageValue: issPageValues.MOLDING_QUESTIONS, destinationIssPageValue: issPageValues.MOLDING_QUESTIONS
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_CAPABILITY_QUESTIONS, scenario: navigationScenarios.CLICKED_FORWARD_WITH_CAPABILITY_QUESTIONS,
destinationIssPageValue: issPageValues.CAPABILITY_QUESTIONS, destinationIssPageValue: issPageValues.CAPABILITY_QUESTIONS
}, }
], ]
}, },
{ {
issPageValue: issPageValues.PART_QUESTIONS, issPageValue: issPageValues.PART_QUESTIONS,
maps: [ maps: [
{ {
scenario: navigationScenarios.CLICKED_BACK_WITH_VIN_AND_NO_MORE_QUESTIONS, scenario: navigationScenarios.CLICKED_BACK_WITH_VIN_AND_NO_MORE_QUESTIONS,
destinationIssPageValue: issPageValues.VIN_LOOKUP, destinationIssPageValue: issPageValues.VIN_LOOKUP
}, },
{ {
scenario: navigationScenarios.CLICKED_BACK_WITH_NO_VIN_NOR_QUESTIONS, scenario: navigationScenarios.CLICKED_BACK_WITH_NO_VIN_NOR_QUESTIONS,
destinationIssPageValue: issPageValues.VEHICLE_LOOKUP, destinationIssPageValue: issPageValues.VEHICLE_LOOKUP
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_PARTS_TO_CHOOSE, scenario: navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_PARTS_TO_CHOOSE,
destinationIssPageValue: issPageValues.VEHICLE_PARTS, destinationIssPageValue: issPageValues.VEHICLE_PARTS
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_MOLDING_QUESTIONS, scenario: navigationScenarios.CLICKED_FORWARD_WITH_MOLDING_QUESTIONS,
destinationIssPageValue: issPageValues.MOLDING_QUESTIONS, destinationIssPageValue: issPageValues.MOLDING_QUESTIONS
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_CAPABILITY_QUESTIONS, scenario: navigationScenarios.CLICKED_FORWARD_WITH_CAPABILITY_QUESTIONS,
destinationIssPageValue: issPageValues.CAPABILITY_QUESTIONS, destinationIssPageValue: issPageValues.CAPABILITY_QUESTIONS
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS, scenario: navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS,
destinationIssPageValue: issPageValues.COVERAGE_STATEMENT, destinationIssPageValue: issPageValues.COVERAGE_STATEMENT
}, }
], ]
}, },
{ {
issPageValue: issPageValues.VEHICLE_PARTS, issPageValue: issPageValues.VEHICLE_PARTS,
maps: [ maps: [
{ {
scenario: navigationScenarios.CLICKED_FORWARD, scenario: navigationScenarios.CLICKED_FORWARD,
destinationIssPageValue: issPageValues.REVEAL, destinationIssPageValue: issPageValues.REVEAL
}, },
{ {
scenario: navigationScenarios.CLICKED_BACK_WITH_PART_QUESTIONS, scenario: navigationScenarios.CLICKED_BACK_WITH_PART_QUESTIONS,
destinationIssPageValue: issPageValues.PART_QUESTIONS, destinationIssPageValue: issPageValues.PART_QUESTIONS
}, },
{ {
scenario: navigationScenarios.CLICKED_BACK_WITH_VIN_AND_NO_MORE_QUESTIONS, scenario: navigationScenarios.CLICKED_BACK_WITH_VIN_AND_NO_MORE_QUESTIONS,
destinationIssPageValue: issPageValues.VIN_LOOKUP, destinationIssPageValue: issPageValues.VIN_LOOKUP
}, },
{ {
scenario: navigationScenarios.CLICKED_BACK_WITH_NO_VIN_NOR_QUESTIONS, scenario: navigationScenarios.CLICKED_BACK_WITH_NO_VIN_NOR_QUESTIONS,
destinationIssPageValue: issPageValues.VEHICLE_LOOKUP, destinationIssPageValue: issPageValues.VEHICLE_LOOKUP
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_MOLDING_QUESTIONS, scenario: navigationScenarios.CLICKED_FORWARD_WITH_MOLDING_QUESTIONS,
destinationIssPageValue: issPageValues.MOLDING_QUESTIONS, destinationIssPageValue: issPageValues.MOLDING_QUESTIONS
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_CAPABILITY_QUESTIONS, scenario: navigationScenarios.CLICKED_FORWARD_WITH_CAPABILITY_QUESTIONS,
destinationIssPageValue: issPageValues.CAPABILITY_QUESTIONS, destinationIssPageValue: issPageValues.CAPABILITY_QUESTIONS
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS, scenario: navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS,
destinationIssPageValue: issPageValues.COVERAGE_STATEMENT, destinationIssPageValue: issPageValues.COVERAGE_STATEMENT
}, }
], ]
}, },
{ {
issPageValue: issPageValues.MOLDING_QUESTIONS, issPageValue: issPageValues.MOLDING_QUESTIONS,
maps: [ maps: [
{ {
scenario: navigationScenarios.CLICKED_BACK_WITH_VIN_AND_NO_MORE_QUESTIONS, scenario: navigationScenarios.CLICKED_BACK_WITH_VIN_AND_NO_MORE_QUESTIONS,
destinationIssPageValue: issPageValues.VIN_LOOKUP, destinationIssPageValue: issPageValues.VIN_LOOKUP
}, },
{ {
scenario: navigationScenarios.CLICKED_BACK_WITH_NO_VIN_NOR_QUESTIONS, scenario: navigationScenarios.CLICKED_BACK_WITH_NO_VIN_NOR_QUESTIONS,
destinationIssPageValue: issPageValues.VEHICLE_LOOKUP, destinationIssPageValue: issPageValues.VEHICLE_LOOKUP
}, },
{ {
scenario: navigationScenarios.CLICKED_BACK_WITH_PART_QUESTIONS, scenario: navigationScenarios.CLICKED_BACK_WITH_PART_QUESTIONS,
destinationIssPageValue: issPageValues.PART_QUESTIONS, destinationIssPageValue: issPageValues.PART_QUESTIONS
}, },
{ {
scenario: navigationScenarios.CLICKED_BACK_WITH_MULTIPLE_PARTS_TO_CHOOSE, scenario: navigationScenarios.CLICKED_BACK_WITH_MULTIPLE_PARTS_TO_CHOOSE,
destinationIssPageValue: issPageValues.VEHICLE_PARTS, destinationIssPageValue: issPageValues.VEHICLE_PARTS
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_CAPABILITY_QUESTIONS, scenario: navigationScenarios.CLICKED_FORWARD_WITH_CAPABILITY_QUESTIONS,
destinationIssPageValue: issPageValues.CAPABILITY_QUESTIONS, destinationIssPageValue: issPageValues.CAPABILITY_QUESTIONS
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS, scenario: navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS,
destinationIssPageValue: issPageValues.COVERAGE_STATEMENT, destinationIssPageValue: issPageValues.COVERAGE_STATEMENT
}, }
], ]
}, },
{ {
issPageValue: issPageValues.CAPABILITY_QUESTIONS, issPageValue: issPageValues.CAPABILITY_QUESTIONS,
maps: [ maps: [
{ {
scenario: navigationScenarios.CLICKED_BACK_WITH_VIN_AND_NO_MORE_QUESTIONS, scenario: navigationScenarios.CLICKED_BACK_WITH_VIN_AND_NO_MORE_QUESTIONS,
destinationIssPageValue: issPageValues.VIN_LOOKUP, destinationIssPageValue: issPageValues.VIN_LOOKUP
}, },
{ {
scenario: navigationScenarios.CLICKED_BACK_WITH_NO_VIN_NOR_QUESTIONS, scenario: navigationScenarios.CLICKED_BACK_WITH_NO_VIN_NOR_QUESTIONS,
destinationIssPageValue: issPageValues.VEHICLE_LOOKUP, destinationIssPageValue: issPageValues.VEHICLE_LOOKUP
}, },
{ {
scenario: navigationScenarios.CLICKED_BACK_WITH_PART_QUESTIONS, scenario: navigationScenarios.CLICKED_BACK_WITH_PART_QUESTIONS,
destinationIssPageValue: issPageValues.PART_QUESTIONS, destinationIssPageValue: issPageValues.PART_QUESTIONS
}, },
{ {
scenario: navigationScenarios.CLICKED_BACK_WITH_MULTIPLE_PARTS_TO_CHOOSE, scenario: navigationScenarios.CLICKED_BACK_WITH_MULTIPLE_PARTS_TO_CHOOSE,
destinationIssPageValue: issPageValues.VEHICLE_PARTS, destinationIssPageValue: issPageValues.VEHICLE_PARTS
}, },
{ {
scenario: navigationScenarios.CLICKED_BACK_WITH_MOLDING_QUESTIONS, scenario: navigationScenarios.CLICKED_BACK_WITH_MOLDING_QUESTIONS,
destinationIssPageValue: issPageValues.MOLDING_QUESTIONS, destinationIssPageValue: issPageValues.MOLDING_QUESTIONS
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS, scenario: navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS,
destinationIssPageValue: issPageValues.COVERAGE_STATEMENT, destinationIssPageValue: issPageValues.COVERAGE_STATEMENT
}, }
], ]
}, },
{ {
issPageValue: issPageValues.ADDRESS_LOOKUP, issPageValue: issPageValues.ADDRESS_LOOKUP,
maps: [ maps: [
{ {
scenario: navigationScenarios.CLICKED_BACK, scenario: navigationScenarios.CLICKED_BACK,
destinationIssPageValue: issPageValues.VEHICLE_LOOKUP, destinationIssPageValue: issPageValues.VEHICLE_LOOKUP
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_VEHICLES, scenario: navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_VEHICLES,
destinationIssPageValue: issPageValues.ADDRESS_VEHICLES, destinationIssPageValue: issPageValues.ADDRESS_VEHICLES
}, },
{ {
scenario: navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS, scenario: navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
destinationIssPageValue: issPageValues.VEHICLE_DAMAGE, destinationIssPageValue: issPageValues.VEHICLE_DAMAGE
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_PART_QUESTIONS, scenario: navigationScenarios.CLICKED_FORWARD_WITH_PART_QUESTIONS,
destinationIssPageValue: issPageValues.PART_QUESTIONS, destinationIssPageValue: issPageValues.PART_QUESTIONS
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_PARTS_TO_CHOOSE, scenario: navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_PARTS_TO_CHOOSE,
destinationIssPageValue: issPageValues.VEHICLE_PARTS, destinationIssPageValue: issPageValues.VEHICLE_PARTS
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_MOLDING_QUESTIONS, scenario: navigationScenarios.CLICKED_FORWARD_WITH_MOLDING_QUESTIONS,
destinationIssPageValue: issPageValues.MOLDING_QUESTIONS, destinationIssPageValue: issPageValues.MOLDING_QUESTIONS
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_CAPABILITY_QUESTIONS, scenario: navigationScenarios.CLICKED_FORWARD_WITH_CAPABILITY_QUESTIONS,
destinationIssPageValue: issPageValues.CAPABILITY_QUESTIONS, destinationIssPageValue: issPageValues.CAPABILITY_QUESTIONS
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS, scenario: navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS,
destinationIssPageValue: issPageValues.COVERAGE_STATEMENT, destinationIssPageValue: issPageValues.COVERAGE_STATEMENT
}, }
], ]
}, },
{ {
issPageValue: issPageValues.ADDRESS_VEHICLES, issPageValue: issPageValues.ADDRESS_VEHICLES,
maps: [ maps: [
{ {
scenario: navigationScenarios.CLICKED_BACK, scenario: navigationScenarios.CLICKED_BACK,
destinationIssPageValue: issPageValues.ADDRESS_LOOKUP, destinationIssPageValue: issPageValues.ADDRESS_LOOKUP
}, },
{ {
scenario: navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS, scenario: navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
destinationIssPageValue: issPageValues.VEHICLE_DAMAGE, destinationIssPageValue: issPageValues.VEHICLE_DAMAGE
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_PART_QUESTIONS, scenario: navigationScenarios.CLICKED_FORWARD_WITH_PART_QUESTIONS,
destinationIssPageValue: issPageValues.PART_QUESTIONS, destinationIssPageValue: issPageValues.PART_QUESTIONS
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_PARTS_TO_CHOOSE, scenario: navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_PARTS_TO_CHOOSE,
destinationIssPageValue: issPageValues.VEHICLE_PARTS, destinationIssPageValue: issPageValues.VEHICLE_PARTS
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_MOLDING_QUESTIONS, scenario: navigationScenarios.CLICKED_FORWARD_WITH_MOLDING_QUESTIONS,
destinationIssPageValue: issPageValues.MOLDING_QUESTIONS, destinationIssPageValue: issPageValues.MOLDING_QUESTIONS
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_CAPABILITY_QUESTIONS, scenario: navigationScenarios.CLICKED_FORWARD_WITH_CAPABILITY_QUESTIONS,
destinationIssPageValue: issPageValues.CAPABILITY_QUESTIONS, destinationIssPageValue: issPageValues.CAPABILITY_QUESTIONS
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS, scenario: navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS,
destinationIssPageValue: issPageValues.COVERAGE_STATEMENT, destinationIssPageValue: issPageValues.COVERAGE_STATEMENT
}, }
], ]
}, },
{ {
issPageValue: issPageValues.ENTRY_PAGE, issPageValue: issPageValues.ENTRY_PAGE,
@ -364,8 +364,8 @@ const routingTable = function(store) {
{ {
scenario: navigationScenarios.MOVE_FORWARD_ENTRY_PAGE, scenario: navigationScenarios.MOVE_FORWARD_ENTRY_PAGE,
destinationIssPageValue: issPageValues.WELCOME_PAGE destinationIssPageValue: issPageValues.WELCOME_PAGE
}, }
], ]
}, },
{ {
issPageValue: issPageValues.WELCOME_PAGE, issPageValue: issPageValues.WELCOME_PAGE,
@ -377,8 +377,8 @@ const routingTable = function(store) {
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WELCOME_PAGE, scenario: navigationScenarios.CLICKED_FORWARD_WELCOME_PAGE,
destinationIssPageValue: issPageValues.POLICY_HOLDER_DETAILS destinationIssPageValue: issPageValues.POLICY_HOLDER_DETAILS
}, }
], ]
}, },
{ {
issPageValue: issPageValues.POLICY_HOLDER_DETAILS, issPageValue: issPageValues.POLICY_HOLDER_DETAILS,
@ -390,55 +390,54 @@ const routingTable = function(store) {
{ {
scenario: navigationScenarios.CLICKED_FORWARD_POLICY_HOLDER_DETAILS, scenario: navigationScenarios.CLICKED_FORWARD_POLICY_HOLDER_DETAILS,
destinationIssPageValue: issPageValues.VEHICLE_YEAR destinationIssPageValue: issPageValues.VEHICLE_YEAR
}, }
], ]
}, },
{ {
issPageValue: issPageValues.COVERAGE_STATEMENT, issPageValue: issPageValues.COVERAGE_STATEMENT,
maps: [ maps: [
{ {
scenario: navigationScenarios.CLICKED_BACK_WITH_VIN_AND_NO_MORE_QUESTIONS, scenario: navigationScenarios.CLICKED_BACK_WITH_VIN_AND_NO_MORE_QUESTIONS,
destinationIssPageValue: issPageValues.VIN_LOOKUP, destinationIssPageValue: issPageValues.VIN_LOOKUP
}, },
{ {
scenario: navigationScenarios.CLICKED_BACK_WITH_NO_VIN_NOR_QUESTIONS, scenario: navigationScenarios.CLICKED_BACK_WITH_NO_VIN_NOR_QUESTIONS,
destinationIssPageValue: issPageValues.VEHICLE_LOOKUP, destinationIssPageValue: issPageValues.VEHICLE_LOOKUP
}, },
{ {
scenario: navigationScenarios.CLICKED_BACK_WITH_PART_QUESTIONS, scenario: navigationScenarios.CLICKED_BACK_WITH_PART_QUESTIONS,
destinationIssPageValue: issPageValues.PART_QUESTIONS, destinationIssPageValue: issPageValues.PART_QUESTIONS
}, },
{ {
scenario: navigationScenarios.CLICKED_BACK_WITH_MULTIPLE_PARTS_TO_CHOOSE, scenario: navigationScenarios.CLICKED_BACK_WITH_MULTIPLE_PARTS_TO_CHOOSE,
destinationIssPageValue: issPageValues.VEHICLE_PARTS, destinationIssPageValue: issPageValues.VEHICLE_PARTS
}, },
{ {
scenario: navigationScenarios.CLICKED_BACK_WITH_MOLDING_QUESTIONS, scenario: navigationScenarios.CLICKED_BACK_WITH_MOLDING_QUESTIONS,
destinationIssPageValue: issPageValues.MOLDING_QUESTIONS, destinationIssPageValue: issPageValues.MOLDING_QUESTIONS
}, },
{ {
scenario: navigationScenarios.CLICKED_BACK_WITH_CAPABILITY_QUESTIONS, scenario: navigationScenarios.CLICKED_BACK_WITH_CAPABILITY_QUESTIONS,
destinationIssPageValue: issPageValues.CAPABILITY_QUESTIONS, destinationIssPageValue: issPageValues.CAPABILITY_QUESTIONS
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_COVERAGE_STATEMENT, scenario: navigationScenarios.CLICKED_FORWARD_COVERAGE_STATEMENT,
destinationIssPageValue: issPageValues.PROVIDER_PREFERENCE, destinationIssPageValue: issPageValues.PROVIDER_PREFERENCE
}, }
], ]
}, },
{ {
issPageValue: issPageValues.PROVIDER_PREFERENCE, issPageValue: issPageValues.PROVIDER_PREFERENCE,
maps: [ maps: [
{ {
scenario: navigationScenarios.CLICKED_BACK, scenario: navigationScenarios.CLICKED_BACK,
destinationIssPageValue: issPageValues.COVERAGE_STATEMENT, destinationIssPageValue: issPageValues.COVERAGE_STATEMENT
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE, scenario: navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE,
destinationIssPageValue: issPageValues.SERVICE_LOCATION, destinationIssPageValue: issPageValues.SERVICE_LOCATION
}, }
], ]
}, },
{ {
issPageValue: issPageValues.SERVICE_LOCATION, issPageValue: issPageValues.SERVICE_LOCATION,
@ -447,40 +446,52 @@ const routingTable = function(store) {
scenario: navigationScenarios.CLICKED_BACK, scenario: navigationScenarios.CLICKED_BACK,
destinationIssPageValue: issPageValues.PROVIDER_PREFERENCE, destinationIssPageValue: issPageValues.PROVIDER_PREFERENCE,
}, },
{
], scenario: navigationScenarios.CLICKED_FORWARD,
destinationIssPageValue: issPageValues.SERVICE_PACKAGES
}
]
}, },
{ {
issPageValue: issPageValues.SCHEDULE_PAGE, issPageValue: issPageValues.SCHEDULE_PAGE,
maps: [ maps: [
{ {
scenario: navigationScenarios.CLICKED_BACK, scenario: navigationScenarios.CLICKED_BACK,
destinationIssPageValue: issPageValues.SERVICE_LOCATION, destinationIssPageValue: issPageValues.SERVICE_LOCATION
}, }
]
],
}, },
{ {
issPageValue: issPageValues.CONTACT_DETAILS, issPageValue: issPageValues.CONTACT_DETAILS,
maps: [ maps: [
{ {
scenario: navigationScenarios.CLICKED_BACK, scenario: navigationScenarios.CLICKED_BACK,
destinationIssPageValue: issPageValues.SCHEDULE_PAGE, destinationIssPageValue: issPageValues.SCHEDULE_PAGE
}
]
}, },
{
], issPageValue: issPageValues.SERVICE_PACKAGE,
maps: [
{
scenario: navigationScenarios.CLICKED_BACK,
destinationIssPageValue: issPageValues.SERVICE_LOCATION
},
{
scenario: navigationScenarios.CLICKED_FORWARD,
destinationIssPageValue: issPageValues.REVIEW_ORDER
}
]
}, },
{ {
issPageValue: issPageValues.PAYMENT_PAGE, issPageValue: issPageValues.PAYMENT_PAGE,
maps: [ maps: [
{ {
scenario: navigationScenarios.CLICKED_BACK, scenario: navigationScenarios.CLICKED_BACK,
destinationIssPageValue: issPageValues.REVIEW_PAGE, destinationIssPageValue: issPageValues.REVIEW_PAGE
}, }
]
], }
},
]; ];
}; };

View file

@ -30,8 +30,8 @@ const getDefaultState = () => {
state: null, state: null,
zipCode: null, zipCode: null,
firstName: null, firstName: null,
lastName: null, lastName: null
}, }
}, },
damage: { damage: {
isRepair: null, isRepair: null,
@ -39,7 +39,7 @@ const getDefaultState = () => {
glassToReplace: null, glassToReplace: null,
partQuestionAnswers: null, partQuestionAnswers: null,
moldingQuestionAnswers: null, moldingQuestionAnswers: null,
capabilityQuestionAnswers: null, capabilityQuestionAnswers: null
}, },
policy: { policy: {
policyNumber: null, policyNumber: null,
@ -47,7 +47,7 @@ const getDefaultState = () => {
damageCause: null, damageCause: null,
damageState: null, damageState: null,
damageCity: null, damageCity: null,
isDamageGlassOnly: null, isDamageGlassOnly: null
}, },
customer: { customer: {
address: { address: {
@ -55,12 +55,12 @@ const getDefaultState = () => {
streetAddress2: null, streetAddress2: null,
city: null, city: null,
state: null, state: null,
zipCode: null, zipCode: null
}, },
firstName: null, firstName: null,
lastName: null, lastName: null,
emailAddress: null, emailAddress: null,
phoneNumber: null, phoneNumber: null
}, },
serviceLocation: { serviceLocation: {
address: null, address: null,
@ -78,16 +78,14 @@ const getDefaultState = () => {
payment: { payment: {
isInsurance: true, isInsurance: true,
insuranceCoverage: { insuranceCoverage: {
isVerified: false, isVerified: false
}, }
}, },
referralNumber: null, referralNumber: null,
referralDate: null, referralDate: null
}, },
applicationUser: { applicationUser: {
lastPageVisited: null,
experiments: [], experiments: [],
triggeredSiteEntry: false,
eventBus: [], eventBus: [],
pageData: {}, pageData: {},
savedSessionTimeout: getDateForSavedSessionTimeout(), savedSessionTimeout: getDateForSavedSessionTimeout(),
@ -95,7 +93,7 @@ const getDefaultState = () => {
savedSessionId: null, savedSessionId: null,
crmCustomerId: null, crmCustomerId: null,
lastPageVisited: null, lastPageVisited: null,
triggeredSiteEntry: false, triggeredSiteEntry: false
}, },
issConfig: { issConfig: {
clientName: "Generic Insurance", // this is the default and will be overriden by the client's name clientName: "Generic Insurance", // this is the default and will be overriden by the client's name
@ -106,7 +104,7 @@ const getDefaultState = () => {
isAuthenticated: false, // Indicates if user is authenticated or not. isAuthenticated: false, // Indicates if user is authenticated or not.
enableTPAFlow: false, // Indicates if the TPA flow is supported for this client. enableTPAFlow: false, // Indicates if the TPA flow is supported for this client.
returnURL: null, returnURL: null,
returnURL2: null, returnURL2: null
} }
}; };
}; };
@ -120,6 +118,7 @@ export const useMainStore = defineStore({
vehicle: (state) => state.order.vehicle, vehicle: (state) => state.order.vehicle,
damage: (state) => state.order.damage, damage: (state) => state.order.damage,
lineItems: (state) => state.order.lineItems, lineItems: (state) => state.order.lineItems,
hasAnyNonWindshieldGlassParts: (state) => !state.order.policy.isDamageGlassOnly,
eventBusItem: (state) => ( eventCategory, eventSubCategory) => { eventBusItem: (state) => ( eventCategory, eventSubCategory) => {
const matchedEvent = state.applicationUser.eventBus.find( const matchedEvent = state.applicationUser.eventBus.find(
@ -235,8 +234,8 @@ export const useMainStore = defineStore({
licenseLastName: licenseLastName, licenseLastName: licenseLastName,
licenseStreetAddress: licenseStreetAddress, licenseStreetAddress: licenseStreetAddress,
licenseZip: licenseZip, licenseZip: licenseZip,
licenseState: licenseState, licenseState: licenseState
}, }
}); });
}, },
@ -245,14 +244,14 @@ export const useMainStore = defineStore({
method: endpoints.GetRouteInfo.method, method: endpoints.GetRouteInfo.method,
endpoint: endpoints.GetRouteInfo.url(applicationConfig.APPLICATION_ABBREVIATION), endpoint: endpoints.GetRouteInfo.url(applicationConfig.APPLICATION_ABBREVIATION),
payload: { payload: {
pageName: pageName, pageName: pageName
}, },
}); });
}, },
getHomepageName() { getHomepageName() {
return globalMethods.callHttpClient({ return globalMethods.callHttpClient({
method: endpoints.GetHomepageInfo.method, method: endpoints.GetHomepageInfo.method,
endpoint: endpoints.GetHomepageInfo.url(applicationConfig.APPLICATION_ABBREVIATION), endpoint: endpoints.GetHomepageInfo.url(applicationConfig.APPLICATION_ABBREVIATION)
}); });
}, },
@ -260,7 +259,7 @@ export const useMainStore = defineStore({
return globalMethods.callHttpClient({ return globalMethods.callHttpClient({
method: endpoints.GetPageData.method, method: endpoints.GetPageData.method,
endpoint: endpoints.GetPageData.url(applicationConfig.APPLICATION_ABBREVIATION, pageName), endpoint: endpoints.GetPageData.url(applicationConfig.APPLICATION_ABBREVIATION, pageName),
payload: {}, payload: {}
}); });
}, },
@ -269,7 +268,7 @@ export const useMainStore = defineStore({
return globalMethods.callHttpClient({ return globalMethods.callHttpClient({
method: endpoints.GetVehicleYears.method, method: endpoints.GetVehicleYears.method,
endpoint: endpoints.GetVehicleYears.url, endpoint: endpoints.GetVehicleYears.url,
payload: {}, payload: {}
}); });
}, },
@ -277,7 +276,7 @@ export const useMainStore = defineStore({
return globalMethods.callHttpClient({ return globalMethods.callHttpClient({
method: endpoints.GetVehicleMakes.method, method: endpoints.GetVehicleMakes.method,
endpoint: endpoints.GetVehicleMakes.url + this.order.vehicle.year, endpoint: endpoints.GetVehicleMakes.url + this.order.vehicle.year,
payload: {}, payload: {}
}); });
}, },
@ -285,7 +284,7 @@ export const useMainStore = defineStore({
return globalMethods.callHttpClient({ return globalMethods.callHttpClient({
method: endpoints.GetVehicleModels.method, method: endpoints.GetVehicleModels.method,
endpoint: `${endpoints.GetVehicleModels.url}/${this.order.vehicle.year}/${this.order.vehicle.make}`, endpoint: `${endpoints.GetVehicleModels.url}/${this.order.vehicle.year}/${this.order.vehicle.make}`,
payload: {}, payload: {}
}); });
}, },
@ -293,7 +292,7 @@ export const useMainStore = defineStore({
return globalMethods.callHttpClient({ return globalMethods.callHttpClient({
method: endpoints.GetVehicleStyles.method, method: endpoints.GetVehicleStyles.method,
endpoint: `${endpoints.GetVehicleStyles.url}/${this.order.vehicle.year}/${this.order.vehicle.make}/${this.order.vehicle.model}`, endpoint: `${endpoints.GetVehicleStyles.url}/${this.order.vehicle.year}/${this.order.vehicle.make}/${this.order.vehicle.model}`,
payload: {}, payload: {}
}); });
}, },
@ -301,7 +300,7 @@ export const useMainStore = defineStore({
return globalMethods.callHttpClient({ return globalMethods.callHttpClient({
methods: endpoints.GetDamageOptions.method, methods: endpoints.GetDamageOptions.method,
endpoint: `${endpoints.GetDamageOptions.url}/${carId}`, endpoint: `${endpoints.GetDamageOptions.url}/${carId}`,
payload: {}, payload: {}
}); });
}, },
getIsVinbyAddressPermissible(){ getIsVinbyAddressPermissible(){
@ -309,14 +308,14 @@ export const useMainStore = defineStore({
const response = globalMethods.callHttpClient({ const response = globalMethods.callHttpClient({
method:endpoints.IsVinbyAddressPermissible.method, method:endpoints.IsVinbyAddressPermissible.method,
endpoint:`${endpoints.IsVinbyAddressPermissible.url}?state=${this.order.customer.address.state}`, endpoint:`${endpoints.IsVinbyAddressPermissible.url}?state=${this.order.customer.address.state}`,
payload: {}, payload: {}
}); });
return response; return response;
} catch (responseError) { } catch (responseError) {
return { return {
error: { error: {
status: responseError.status, status: responseError.status
}, }
}; };
} }
}, },
@ -327,16 +326,16 @@ export const useMainStore = defineStore({
endpoint: endpoints.LookupVinByPlate.url, endpoint: endpoints.LookupVinByPlate.url,
payload: { payload: {
licensePlate: licensePlate, licensePlate: licensePlate,
licenseState: licenseState, licenseState: licenseState
}, }
}); });
return response; return response;
} catch (responseError) { } catch (responseError) {
return { return {
error: { error: {
status: responseError.status, status: responseError.status
}, }
}; };
} }
}, },
@ -363,8 +362,8 @@ export const useMainStore = defineStore({
carId: carId, carId: carId,
glassPieces: glassArrayForPayload, glassPieces: glassArrayForPayload,
zip: zipCode, zip: zipCode,
vin: vin, vin: vin
}, }
}); });
// Flatten location and name properties // Flatten location and name properties
@ -398,8 +397,8 @@ export const useMainStore = defineStore({
glassPieces: glassArrayForPayload, glassPieces: glassArrayForPayload,
answerResults: resultsArrayForPayload, answerResults: resultsArrayForPayload,
zip: zipCode, zip: zipCode,
vin: vin, vin: vin
}, }
}); });
// Flatten location and name properties // Flatten location and name properties
@ -413,7 +412,7 @@ export const useMainStore = defineStore({
getCapabilityQuestions(carId, partNumber) { getCapabilityQuestions(carId, partNumber) {
return globalMethods.callHttpClient({ return globalMethods.callHttpClient({
method: endpoints.GetCapabilityQuestions.method, method: endpoints.GetCapabilityQuestions.method,
endpoint: `${endpoints.GetCapabilityQuestions.url}/${carId}/${partNumber}`, endpoint: `${endpoints.GetCapabilityQuestions.url}/${carId}/${partNumber}`
}); });
}, },
@ -432,10 +431,100 @@ export const useMainStore = defineStore({
endpoint: endpoints.GetPartFromCapabilityAnswer.url, endpoint: endpoints.GetPartFromCapabilityAnswer.url,
payload: { payload: {
part, part,
capabilityAnswerResults: capabilityQuestionAnswersForPart, capabilityAnswerResults: capabilityQuestionAnswersForPart
}, }
}); });
}, },
async getWipers() {
const carId = this.order.vehicle.carId;
///WARNING
///TODO: this is temp test code until serviceLocation is complete.
//const serviceZipCode = this.order.serviceLocation.zipCode;
const serviceZipCode = '44902';
return globalMethods
.callHttpClient({
method: endpoints.GetWipers.method,
endpoint: `${endpoints.GetWipers.url}/${carId}/${serviceZipCode}`
})
.catch((error) => {
// The wiper service sometimes returns 500s on legitimate carId/zipCode combination - return empty array instead of breaking flow
console.error(error);
return [];
});
},
async getRainDefense() {
return globalMethods
.callHttpClient({
method: endpoints.GetRainDefense.method,
endpoint: `${endpoints.GetRainDefense.url}`
})
.catch((error) => {
// The wiper service sometimes returns 500s on legitimate carId/zipCode combination - return empty array instead of breaking flow
console.error(error);
return [];
});
},
async getSupportingItems() {
const glassPartsArray = this.order.lineItems.glassParts ?? [];
const carId = this.order.vehicle.carId;
const isRepair = this.order.damage.isRepair;
const numberOfChips = this.order.damage.numberOfChips;
return globalMethods
.callHttpClient({
method: endpoints.GetSupportingItems.method,
endpoint: endpoints.GetSupportingItems.url,
payload: {
carId: carId,
serviceType: isRepair ? 'Repair' : 'Replace',
parentAccountNumber: applicationConfig.CASH_PARENT_ACCOUNT_NUMBER,
parts: glassPartsArray,
numberOfRepairChips: isRepair ? numberOfChips : 0
}
});
},
async getPriceOrderItems(availableLineItems) {
let zipCodeToUse = this.order.serviceLocation.zipCode;
let ctuToUse = this.order.serviceLocation.zipCodeCtu;
const availableLineItemsFormattedForRequest =
getLineItemQueryStringForPricing(availableLineItems);
const vehicle = this.order.vehicle;
///WARNING
///TODO: this is temp test code until serviceLocation is complete.
/// and ctu is available. Also, EON may need to be implemented.
zipCodeToUse = "44902"
ctuToUse = "01820"
let queryString =
`ParentAccountNumber=${applicationConfig.CASH_PARENT_ACCOUNT_NUMBER}` +
`&CTU=${ctuToUse}` +
`&CarId=${vehicle.carId}` +
`&Make=${vehicle.make}` +
`&Model=${vehicle.model}` +
`&Year=${vehicle.year}` +
`&EON=0` +
`&ZipCode=${zipCodeToUse}` +
`${availableLineItemsFormattedForRequest}`;
const response = await globalMethods
.callHttpClient({
method: endpoints.GetPriceOrderItems.method,
endpoint: `${endpoints.GetPriceOrderItems.url}?${queryString}`
}).catch((error) => {
console.error(error);
return [];
});
availableLineItems = addPricesToLineItems(availableLineItems, response.data.lineItems)
return availableLineItems;
},
lookupVehicleByVin(vin) { lookupVehicleByVin(vin) {
return globalMethods.callHttpClient({ return globalMethods.callHttpClient({
method: endpoints.LookupVehicleByVin.method, method: endpoints.LookupVehicleByVin.method,
@ -451,7 +540,7 @@ export const useMainStore = defineStore({
.callHttpClient({ .callHttpClient({
methods: endpoints.GetVehicle.method, methods: endpoints.GetVehicle.method,
endpoint: `${endpoints.GetVehicle.url}/${this.order.vehicle.year}/${this.order.vehicle.make}/${this.order.vehicle.model}/${this.order.vehicle.style}`, endpoint: `${endpoints.GetVehicle.url}/${this.order.vehicle.year}/${this.order.vehicle.make}/${this.order.vehicle.model}/${this.order.vehicle.style}`,
payload: {}, payload: {}
}) })
.then((response) => { .then((response) => {
this.updateVehicle(response.data); this.updateVehicle(response.data);
@ -775,7 +864,7 @@ export const useMainStore = defineStore({
this.updateCapabilityQuestionAnswers(null); this.updateCapabilityQuestionAnswers(null);
this.updatePageData({ this.updatePageData({
page: issPageValues.CAPABILITY_QUESTIONS, page: issPageValues.CAPABILITY_QUESTIONS,
data: null, data: null
}); });
} }
@ -850,9 +939,9 @@ export const useMainStore = defineStore({
userPartitionNumber: experiment.userPartitionNumber, userPartitionNumber: experiment.userPartitionNumber,
assignmentId: experiment.assignmentId, assignmentId: experiment.assignmentId,
sessionKey: sessionKey, sessionKey: sessionKey,
pageName: pageName, pageName: pageName
}, }
}, }
}); });
}, },
logPageView({ userId, sessionKey, pageName, sessionId, action, event, shouldUseSessionId, experimentsForUser }) logPageView({ userId, sessionKey, pageName, sessionId, action, event, shouldUseSessionId, experimentsForUser })
@ -873,7 +962,7 @@ export const useMainStore = defineStore({
method: endpoints.LogPageView.method, method: endpoints.LogPageView.method,
endpoint: endpoints.LogPageView.url, endpoint: endpoints.LogPageView.url,
payload: payload, payload: payload,
logApiCall: false, logApiCall: false
}); });
}, },
logCustomEvent({ userId, sessionKey, pageName, sessionId, category, action, label, value, shouldUseSessionId, experimentsForUser}) logCustomEvent({ userId, sessionKey, pageName, sessionId, category, action, label, value, shouldUseSessionId, experimentsForUser})
@ -892,14 +981,14 @@ export const useMainStore = defineStore({
label: label, label: label,
value: value, value: value,
shouldUseSessionId: shouldUseSessionId, shouldUseSessionId: shouldUseSessionId,
experimentsForUser: experimentsForUser, experimentsForUser: experimentsForUser
}; };
return globalMethods.callHttpClient({ return globalMethods.callHttpClient({
method: endpoints.LogCustomEvent.method, method: endpoints.LogCustomEvent.method,
endpoint: endpoints.LogCustomEvent.url, endpoint: endpoints.LogCustomEvent.url,
payload: payload, payload: payload,
logApiCall: false, logApiCall: false
}); });
}, },
initializeSession({ userId, sessionId, userAgent, referrer }) { initializeSession({ userId, sessionId, userAgent, referrer }) {
@ -911,14 +1000,14 @@ export const useMainStore = defineStore({
userAgent: userAgent, userAgent: userAgent,
operatorId: "WEB", operatorId: "WEB",
userName: "SafeliteISS", userName: "SafeliteISS",
referrer: referrer, referrer: referrer
}; };
return globalMethods.callHttpClient({ return globalMethods.callHttpClient({
method: endpoints.InitializeSession.method, method: endpoints.InitializeSession.method,
endpoint: endpoints.InitializeSession.url, endpoint: endpoints.InitializeSession.url,
payload: payload, payload: payload,
logApiCall: false, logApiCall: false
}); });
}, },
@ -937,7 +1026,7 @@ export const useMainStore = defineStore({
return globalMethods.callHttpClient({ return globalMethods.callHttpClient({
method: endpoints.GetExperimentsByUser.method, method: endpoints.GetExperimentsByUser.method,
endpoint: `${endpoints.GetExperimentsByUser.url}/${userId}`, endpoint: `${endpoints.GetExperimentsByUser.url}/${userId}`,
payload: {}, payload: {}
}); });
}, },
@ -951,13 +1040,13 @@ export const useMainStore = defineStore({
userId: userId, userId: userId,
triggerEvent: triggerEvent, triggerEvent: triggerEvent,
triggerValue: triggerValue, triggerValue: triggerValue,
experimentOrder: this.experimentOrder, experimentOrder: this.experimentOrder
}; };
const response = await globalMethods.callHttpClient({ const response = await globalMethods.callHttpClient({
method: endpoints.RunExperimentsForTrigger.method, method: endpoints.RunExperimentsForTrigger.method,
endpoint: endpoints.RunExperimentsForTrigger.url, endpoint: endpoints.RunExperimentsForTrigger.url,
payload: payload, payload: payload
}); });
this.updateExperiments(response.data.experiments); this.updateExperiments(response.data.experiments);
@ -966,14 +1055,14 @@ export const useMainStore = defineStore({
async validateZip({ zip }) { async validateZip({ zip }) {
return await globalMethods.callHttpClient({ return await globalMethods.callHttpClient({
methods: endpoints.ValidateZip.method, methods: endpoints.ValidateZip.method,
endpoint: `${endpoints.ValidateZip.url}/${zip}`, endpoint: `${endpoints.ValidateZip.url}/${zip}`
}); });
}, },
async validateClientTag(clientTag) { async validateClientTag(clientTag) {
return await globalMethods.callHttpClient({ return await globalMethods.callHttpClient({
methods: endpoints.ValidateClientTag.method, methods: endpoints.ValidateClientTag.method,
endpoint: `${endpoints.ValidateClientTag.url}/${clientTag}`, endpoint: `${endpoints.ValidateClientTag.url}/${clientTag}`
}); });
}, },
@ -1124,7 +1213,7 @@ function convertGlassPieceNamingForApi(glassArray) {
glassArray.forEach((glass) => { glassArray.forEach((glass) => {
converted.push({ converted.push({
location: glass.glassLocation, location: glass.glassLocation,
name: glass.glassName, name: glass.glassName
}); });
}); });
return converted; return converted;
@ -1137,7 +1226,7 @@ function convertResultsForApi(resultsArray) {
converted.push({ converted.push({
location: answer.glassLocation, location: answer.glassLocation,
name: answer.glassName, name: answer.glassName,
result: answer.result, result: answer.result
}); });
}); });
return converted; return converted;
@ -1164,3 +1253,31 @@ function getAllPartNumbers(partsOrQuestions) {
.join(",") .join(",")
: []; : [];
} }
function addPricesToLineItems(lineItems, pricingLineItems) {
lineItems.forEach((lineItem) => {
const lineItemIndex = pricingLineItems.findIndex(
(pricingLineItem) => pricingLineItem.partNumber === lineItem.partNumber
)
if (lineItem.childParts) {
addPricesToLineItems(lineItem.childParts, pricingLineItems)
}
const pricedLineItem = pricingLineItems.splice(lineItemIndex, 1)[0]
lineItem.laborAmount = pricedLineItem.laborAmount
lineItem.sellingPrice = pricedLineItem.sellingPrice
lineItem.kitPrice = pricedLineItem.kitPrice
});
return lineItems;
}
function getLineItemQueryStringForPricing(lineItems) {
return lineItems
.map((lineItem) => {
let queryStringSnippet = `&LineItems=${lineItem.partNumber}`;
if (lineItem.childParts) {
queryStringSnippet += getLineItemQueryStringForPricing(lineItem.childParts);
}
return queryStringSnippet;
})
.join('');
}

View file

@ -3,7 +3,6 @@ process.env.VUE_APP_CURRENT_ENVIRONMENT = "Localhost";
process.env.VUE_APP_GOOGLE_PLACES_API_KEY = process.env.VUE_APP_GOOGLE_PLACES_API_KEY =
"AIzaSyCuLhQcDdZTTb4JzpUFms1OCch2dk5lHF0"; "AIzaSyCuLhQcDdZTTb4JzpUFms1OCch2dk5lHF0";
// GA & GTM // GA & GTM
// NOTE: Using the old ISS site GTM Cotnainer ID for now, will create a new one soon. // NOTE: Using the old ISS site GTM Cotnainer ID for now, will create a new one soon.
process.env.VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY = "(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','GTM-KKNWZ3');"; process.env.VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY = "(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','GTM-KKNWZ3');";
@ -27,6 +26,6 @@ module.exports = {
}, },
}, },
configureWebpack: { configureWebpack: {
devtool: 'source-map' devtool: 'source-map',
}, },
}; };