.*?)' + // Match & Capture all chracters (lazy), can be empty
+ '(?=' +
+ anyLogicOperatorNonCapture +
+ '|$)'; // Looks ahead but does not capture the next logic operator
+ // Combine all matching patterns, separated by 'or' pipes
+ return new RegExp(
+ matchStartOfString +
+ '|' +
+ matchIfOperator +
+ '|' +
+ matchElseOperator +
+ '|' +
+ matchEndOperator,
+ 'g'
+ );
+}
+
+//////////////////////////////////////////
+// End of If Statement Processing Logic //
+//////////////////////////////////////////
+
export function doesCopyContainRouterLink(copy) {
return copy.includes(this.dynamicStrings.ROUTER_LINK);
}
@@ -229,14 +408,14 @@ export function getRouterLinkRouteFromCopy(copy) {
// sample input: {routerLink:estimate,provide your VIN}
// first split would return 'estimate,provide your VIN'
// second split would return 'estimate'
- return copy.split(":")[1].split(",")[0];
+ return copy.split(':')[1].split(',')[0];
}
export function getRouterLinkDisplayTextFromCopy(copy) {
// sample input: {routerLink:estimate,provide your VIN}
// first split would return 'estimate,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
@@ -245,5 +424,5 @@ export function getRouterLinkDisplayTextFromCopy(copy) {
// attributes present
export function splitCMSCopyOnParagraphTag(copy) {
// filter removes empty strings that are a result of string.split with regex
- return copy.split(/(?:)|(?:<\/p>)/g).filter((paragraph) => paragraph !== "");
+ return copy.split(/(?:
)|(?:<\/p>)/g).filter((paragraph) => paragraph !== '');
}
diff --git a/src/iss-components/site-header/site-header.vue b/src/iss-components/site-header/site-header.vue
index d9d485be..75a82bef 100644
--- a/src/iss-components/site-header/site-header.vue
+++ b/src/iss-components/site-header/site-header.vue
@@ -30,13 +30,13 @@ export default({
isDismissible: false,
messageCopy: "",
messageHeadline: "",
- type: "",
+ type: ""
},
headerAnswers: null
};
},
props: {
- cmsWidgetName: String,
+ cmsWidgetName: String
},
computed: {
imageSrc()
@@ -51,7 +51,7 @@ export default({
return {
"background-color": this.headerAnswers ? this.headerAnswers.HexCode : "#FFFFFF"
};
- },
+ }
},
mounted() {
const answers = this.getCmsContent(this.cmsWidgetName, "Answers");
diff --git a/src/layouts/service-packages/service-package-question/service-package-question.vue b/src/layouts/service-packages/service-package-question/service-package-question.vue
new file mode 100644
index 00000000..0b8b2f6e
--- /dev/null
+++ b/src/layouts/service-packages/service-package-question/service-package-question.vue
@@ -0,0 +1,361 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/layouts/service-packages/service-package-question/service-package-radio/service-package-radio.vue b/src/layouts/service-packages/service-package-question/service-package-radio/service-package-radio.vue
new file mode 100644
index 00000000..74c38517
--- /dev/null
+++ b/src/layouts/service-packages/service-package-question/service-package-radio/service-package-radio.vue
@@ -0,0 +1,267 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/layouts/service-packages/service-packages.vue b/src/layouts/service-packages/service-packages.vue
new file mode 100644
index 00000000..99d97a62
--- /dev/null
+++ b/src/layouts/service-packages/service-packages.vue
@@ -0,0 +1,151 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main.js b/src/main.js
index d7e9ef55..a7b26869 100644
--- a/src/main.js
+++ b/src/main.js
@@ -22,6 +22,12 @@ const vueApp = createApp(App);
*/
vueApp.config.unwrapInjectedRef = true;
+vueApp.config.compilerOptions.isCustomElement = (tag) => {
+ return (tag === 'siteSubHeader' ||
+ tag === 'ServicePackages' ||
+ tag === 'servicePackageQuestion');
+}
+
// Pinia
const pinia = createPinia();
vueApp.use(pinia);
diff --git a/src/mixins/input-button-wrapper-mixin.js b/src/mixins/input-button-wrapper-mixin.js
index 286c3f21..88ba973e 100644
--- a/src/mixins/input-button-wrapper-mixin.js
+++ b/src/mixins/input-button-wrapper-mixin.js
@@ -10,7 +10,7 @@ export default {
buttonLabel: [Number, String],
buttonLabelSubCopy: String,
buttonBodyCopy: String,
- buttonAuxillaryCopy: String,
+ buttonAuxiliaryCopy: String,
buttonFooterCopy: String,
buttonImage: String,
buttonImageId: String,
diff --git a/src/router/index.js b/src/router/index.js
index bc8579c6..16ea8cc4 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -54,6 +54,7 @@ const routes = [
router.addRoute({
path: routeData[0].path, // Always the same path, because we control it with query strings.
name: routeData[0].name,
+ query: to.query,
component: routeData[0].component,
});
@@ -68,15 +69,16 @@ const routes = [
console.log(error);
GoToStartOn404(next);
}
+ return null;
}
}];
const router = createRouter({
history: createWebHistory("/"),
- routes,
+ routes
});
-router.afterEach((to, from) => {
+router.afterEach((to, from) => { /*eslint-disable-line*/
const store = useMainStore();
// Update lastPageVisited in the store
@@ -106,12 +108,12 @@ async function GetRouteInfoFromPageName(pageName) {
routeData.push({
path: "/",
name: `${key}`,
- component: lazyLoadComponent(jsonFromResponse[key].LayoutName),
+ component: lazyLoadComponent(jsonFromResponse[key].LayoutName)
});
});
return routeData;
-};
+}
//Use this navigation when you need to call next() explicitly. beforeRouteEnter is a good example.
router.overrideNavigation = (
@@ -141,7 +143,7 @@ router.navigate = (scenario, currentRoute, optionalQuery = {}, optionalParams =
}
// 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) {
console.error("No scenario provided. Please review the routing table.");
return;
@@ -170,7 +172,7 @@ function navigate (scenario, currentRoute, optionalQuery = {}, optionalParams =
router.push({
name: "root",
query: Object.assign(optionalQuery, {
- issPage: matchingScenarioMap.destinationIssPageValue,
+ issPage: matchingScenarioMap.destinationIssPageValue
}),
params: optionalParams
});
@@ -182,7 +184,7 @@ function navigate (scenario, currentRoute, optionalQuery = {}, optionalParams =
// Navigate to an external url.
function navigateToUrl(url, optionalQuery = {}) {
// possibly show some loading screen in the future here.
- let externalUrl = new URL(url);
+ const externalUrl = new URL(url);
for (const queryKey in optionalQuery) {
externalUrl.searchParams.append(queryKey, optionalQuery[queryKey]);
@@ -219,7 +221,7 @@ function GoToStartOn404(next) {
router.addRoute({
path: "/",
name: errorPageName,
- component: lazyLoadComponent(errorPageName),
+ component: lazyLoadComponent(errorPageName)
});
// Put item on the bus
@@ -230,13 +232,13 @@ function GoToStartOn404(next) {
isDismissible: true,
messageCopy: "You can get a quote by starting on this page.",
messageHeadline: "We're sorry, something went wrong.",
- type: globalEventTypes.Danger,
+ type: globalEventTypes.Danger
}
);
next({
name: errorPageName,
- query: {issPage: errorPageName },
+ query: {issPage: errorPageName }
});
};
@@ -249,14 +251,14 @@ async function runExperiments(nextPage) {
await store.runExperimentsForTrigger({
userId: getDeviceIdValue(),
triggerEvent: experimentTriggers.SITE_ENTRY,
- triggerValue: applicationConfig.SITE_ENTRY_TRIGGER_VALUE,
+ triggerValue: applicationConfig.SITE_ENTRY_TRIGGER_VALUE
});
}
await store.runExperimentsForTrigger({
userId: getDeviceIdValue(),
triggerEvent: experimentTriggers.PAGE_ENTRY,
- triggerValue: nextPage,
+ triggerValue: nextPage
});
}
diff --git a/src/router/router-constants/issPage-values.js b/src/router/router-constants/issPage-values.js
index b660f98f..634039d4 100644
--- a/src/router/router-constants/issPage-values.js
+++ b/src/router/router-constants/issPage-values.js
@@ -1,28 +1,27 @@
export const issPageValues = {
- ENTRY_PAGE: "entry-page",
- WELCOME_PAGE: "welcome-page",
- POLICY_HOLDER_DETAILS: "policy-holder-details",
- VEHICLE_MAKE: "vehicle-make",
- VEHICLE_YEAR: "vehicle-year",
- VEHICLE_MODEL: "vehicle-model",
- VEHICLE_STYLE: "vehicle-style",
- VEHICLE_DAMAGE: "vehicle-damage",
- VEHICLE_LOOKUP: "vehicle-lookup",
- ADDRESS_LOOKUP: "address-lookup",
- ADDRESS_VEHICLES: "address-vehicles",
- LICENSE_PLATE_LOOKUP: "license-plate-lookup",
- VIN_LOOKUP: "vin-lookup",
- VEHICLE_PARTS: "vehicle-parts",
- PART_QUESTIONS: "part-questions",
- MOLDING_QUESTIONS: "molding-questions",
- CAPABILITY_QUESTIONS: "capability-questions",
- COVERAGE_STATEMENT: "coverage-statement",
- PROVIDER_PREFERENCE: "provider-preference",
- SERVICE_LOCATION: "service-location",
- REVEAL: "reveal",
- ESTIMATE: "estimate",
- ADDRESS_VEHICLES: "address-vehicles",
- QUOTE: "quote",
- HERITAGE: "heritage",
+ ENTRY_PAGE: 'entry-page',
+ WELCOME_PAGE: 'welcome-page',
+ POLICY_HOLDER_DETAILS: 'policy-holder-details',
+ VEHICLE_MAKE: 'vehicle-make',
+ VEHICLE_YEAR: 'vehicle-year',
+ VEHICLE_MODEL: 'vehicle-model',
+ VEHICLE_STYLE: 'vehicle-style',
+ VEHICLE_DAMAGE: 'vehicle-damage',
+ VEHICLE_LOOKUP: 'vehicle-lookup',
+ ADDRESS_LOOKUP: 'address-lookup',
+ ADDRESS_VEHICLES: 'address-vehicles',
+ LICENSE_PLATE_LOOKUP: 'license-plate-lookup',
+ VIN_LOOKUP: 'vin-lookup',
+ VEHICLE_PARTS: 'vehicle-parts',
+ PART_QUESTIONS: 'part-questions',
+ MOLDING_QUESTIONS: 'molding-questions',
+ CAPABILITY_QUESTIONS: 'capability-questions',
+ COVERAGE_STATEMENT: 'coverage-statement',
+ PROVIDER_PREFERENCE: 'provider-preference',
+ SERVICE_LOCATION: 'service-location',
+ REVEAL: 'reveal',
+ ESTIMATE: 'estimate',
+ ADDRESS_VEHICLES: 'address-vehicles',
+ SERVICE_PACKAGE: 'service-package',
};
\ No newline at end of file
diff --git a/src/store/index.js b/src/store/index.js
index 4b6ac5b6..6b40617c 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -118,6 +118,7 @@ export const useMainStore = defineStore({
vehicle: (state) => state.order.vehicle,
damage: (state) => state.order.damage,
lineItems: (state) => state.order.lineItems,
+ hasAnyNonWindshieldGlassParts: (state) => !state.order.policy.isDamageGlassOnly,
eventBusItem: (state) => ( eventCategory, eventSubCategory) => {
const matchedEvent = state.applicationUser.eventBus.find(
@@ -433,7 +434,58 @@ export const useMainStore = defineStore({
capabilityAnswerResults: capabilityQuestionAnswersForPart,
},
});
- },
+ },
+ getWipers() {
+ const carId = this.order.vehicle.carId;
+ ///WARNING WARNING DANGER WILL ROBINSON
+ ///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 [];
+ });
+ },
+
+ 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 [];
+ });
+
+ },
+
+ 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: 0,
+ parts: glassPartsArray,
+ numberOfRepairChips: isRepair ? numberOfChips : 0
+ }
+ });
+ },
+
lookupVehicleByVin(vin) {
return globalMethods.callHttpClient({
method: endpoints.LookupVehicleByVin.method,