From 38f7ef333985184d923404c6b9150e35a7f38bbb Mon Sep 17 00:00:00 2001 From: hiteshkumar87 Date: Mon, 28 Aug 2023 12:20:59 +0530 Subject: [PATCH 01/73] CSR-1618 added FirstAvailableAppointment GA event --- src/helpers/date-helper.js | 10 ++++++++++ src/store/index.js | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 src/helpers/date-helper.js diff --git a/src/helpers/date-helper.js b/src/helpers/date-helper.js new file mode 100644 index 000000000..dce497231 --- /dev/null +++ b/src/helpers/date-helper.js @@ -0,0 +1,10 @@ +export function getDateDifferenceInDays(startDate, endDate) { + var date1 = new Date(endDate); + date1.setHours(0, 0, 0, 0); + var date2 = new Date(startDate); + date2.setHours(0, 0, 0, 0); + // To calculate the time difference of two dates + var Difference_In_Time = date1.getTime() - date2.getTime(); + // To calculate the no. of days between two dates + return Difference_In_Time / (1000 * 3600 * 24); +} diff --git a/src/store/index.js b/src/store/index.js index 9b52e08a4..403e784c1 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -15,6 +15,7 @@ import { deepEqual } from "@/helpers/object-helper"; import { AppointmentTypeStrings, PREMIUM_FEE_PART_TYPE } from "@/constants/schedule-constants"; import { getQuerystringParameter } from "@/helpers/querystring-helper"; import { queryStrings } from "@/constants/query-strings"; +import { getDateDifferenceInDays } from "@/helpers/date-helper"; // Export State const getDefaultState = () => { return { @@ -605,8 +606,24 @@ function getNonFalseValuesOfPropertyInArrayOfObjects(array, propertyName) { return (array ?? []).map((x) => x[propertyName]).filter((x) => x); } -function provisionalTriggersToString(provisionalTriggers) { - return "ProvisionalTriggers:" + provisionalTriggers.join(","); +function FirstAvailableAppointment( + provisionalTriggers, + zipCode, + firstAvailableAppointmentDateString, + shopAppointmentType +) { + var numberOfDays = null; + if (firstAvailableAppointmentDateString) + numberOfDays = getDateDifferenceInDays(new Date(), firstAvailableAppointmentDateString); + + if (shopAppointmentType) + return `FirstAvailableAppointment:${numberOfDays},Zip:${zipCode},ShopAppointmentType:${shopAppointmentType},ProvisionalTriggers:${provisionalTriggers.join( + "," + )}`; + else + return `FirstAvailableAppointment:${numberOfDays},Zip:${zipCode},ProvisionalTriggers:${provisionalTriggers.join( + "," + )}`; } // Export Actions @@ -1297,7 +1314,12 @@ export const actions = { endpoint: endpoints.GetShopTimeSlots.url, payload: payload, additionalSuccessEventDataHandler: (response) => - provisionalTriggersToString(response.data.provisionalTriggers), + FirstAvailableAppointment( + response.data.provisionalTriggers, + order.serviceLocation.zipCode, + response.data.days?.[0]?.date, + shopAppointmentType + ), }); }, @@ -1354,7 +1376,11 @@ export const actions = { endpoint: endpoints.GetMobileTimeSlots.url, payload: payload, additionalSuccessEventDataHandler: (response) => - provisionalTriggersToString(response.data.provisionalTriggers), + FirstAvailableAppointment( + response.data.provisionalTriggers, + order.serviceLocation.zipCode, + response.data.days?.[0]?.date + ), }); }, From 8dfa5d80a6944713d267326ef97a8d92491c2223 Mon Sep 17 00:00:00 2001 From: hiteshkumar87 Date: Thu, 31 Aug 2023 18:40:05 +0530 Subject: [PATCH 02/73] Update index.js rename the method FirstAvailableAppointment to getTimeSlotsAdditionalEventData --- src/store/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/store/index.js b/src/store/index.js index 403e784c1..5ab4f971a 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -606,7 +606,7 @@ function getNonFalseValuesOfPropertyInArrayOfObjects(array, propertyName) { return (array ?? []).map((x) => x[propertyName]).filter((x) => x); } -function FirstAvailableAppointment( +function getTimeSlotsAdditionalEventData( provisionalTriggers, zipCode, firstAvailableAppointmentDateString, @@ -1314,7 +1314,7 @@ export const actions = { endpoint: endpoints.GetShopTimeSlots.url, payload: payload, additionalSuccessEventDataHandler: (response) => - FirstAvailableAppointment( + getTimeSlotsAdditionalEventData( response.data.provisionalTriggers, order.serviceLocation.zipCode, response.data.days?.[0]?.date, @@ -1376,7 +1376,7 @@ export const actions = { endpoint: endpoints.GetMobileTimeSlots.url, payload: payload, additionalSuccessEventDataHandler: (response) => - FirstAvailableAppointment( + getTimeSlotsAdditionalEventData( response.data.provisionalTriggers, order.serviceLocation.zipCode, response.data.days?.[0]?.date From 52b54d44dcfd40d688d4cfb45b42f53505eefef4 Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Fri, 1 Sep 2023 10:24:47 -0400 Subject: [PATCH 03/73] CSR-1617 | Save quote defect (skip vin-lookup) --- src/helpers/heritage-integration/navigation-helper.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/helpers/heritage-integration/navigation-helper.js b/src/helpers/heritage-integration/navigation-helper.js index db7881527..3d1115000 100644 --- a/src/helpers/heritage-integration/navigation-helper.js +++ b/src/helpers/heritage-integration/navigation-helper.js @@ -68,12 +68,14 @@ export async function navigateToHeritageFunnel({ shouldSaveSession = true, loadi } export async function skipVinLookup() { + if (store.getters.damage.isRepair) { + return true; + } const isVinOptionalVehicle = store.getters.order.vehicle.make ? await store.dispatch(storeActions.IS_VIN_OPTIONAL_VEHICLE) : false; return ( - store.getters.damage.isRepair || isVinOptionalVehicle || !includesWindshieldReplacement() || experimentMixin.methods.hasSettingEqualTo(experimentSettings.SUPPRESS_VIN_CAPTURE, "true") From b14119278e4f7e17a5c342bcc479d6483f852f95 Mon Sep 17 00:00:00 2001 From: CarlNation <32103961+CarlNation@users.noreply.github.com> Date: Fri, 1 Sep 2023 10:58:07 -0400 Subject: [PATCH 04/73] CSR-1623 persist promo code and pass to heritage --- src/constants/query-strings.js | 1 + .../heritage-integration/navigation-helper.js | 13 +++++++++++-- src/router/index.js | 16 ++++++++-------- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/constants/query-strings.js b/src/constants/query-strings.js index 5ff1f636c..a0009bae0 100644 --- a/src/constants/query-strings.js +++ b/src/constants/query-strings.js @@ -2,6 +2,7 @@ const queryStrings = { FMG_PAGE: "fmgPage", START_TYPE: "start_type", ZIP_CODE: "zipcode", + PROMO: "promo", }; export { queryStrings }; diff --git a/src/helpers/heritage-integration/navigation-helper.js b/src/helpers/heritage-integration/navigation-helper.js index db7881527..ff651aab5 100644 --- a/src/helpers/heritage-integration/navigation-helper.js +++ b/src/helpers/heritage-integration/navigation-helper.js @@ -1,4 +1,5 @@ import { queryStrings } from "@/constants/query-strings"; +import { getQuerystringParameter } from "@/helpers/querystring-helper"; import { externalUrls } from "@/router/router-constants/externalUrl-values"; import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js"; import { saveSession } from "@/helpers/heritage-integration/order-helper.js"; @@ -59,12 +60,20 @@ export async function navigateToHeritageFunnel({ shouldSaveSession = true, loadi loadingModal.showModal(); } - router.navigateToExternalUrl(externalUrls.HERITAGE_FUNNEL, { + var heritageParms = { corid: store.getters.order.referralCorrelationId, src: "concept-funnel", conceptsqid: store.getters.applicationUser.savedSessionId, isInsurance: store.getters.payment.isInsurance, - }); + }; + + const promo = getQuerystringParameter(queryStrings.PROMO) + + if (promo) { + heritageParms["promo"] = promo; + } + + router.navigateToExternalUrl(externalUrls.HERITAGE_FUNNEL, heritageParms); } export async function skipVinLookup() { diff --git a/src/router/index.js b/src/router/index.js index 11efa6080..424d09dcd 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -6,6 +6,7 @@ import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js" import { routingTable } from "@/router/router-constants/routing-table.js"; import { globalEvents, globalEventTypes } from "@/constants/events"; import { queryStrings } from "@/constants/query-strings"; +import { getQuerystringParameter } from "@/helpers/querystring-helper"; import { getDeviceIdValue } from "@/helpers/heritage-integration/cookie-helper"; // Heritage integration @@ -277,14 +278,9 @@ async function navigate( fmgPage: destinationFmgPageValue, }; - const queryString = window.location.search; - const urlParams = new URLSearchParams(queryString); - const lowerCaseParams = new URLSearchParams(); - for (const [name, value] of urlParams) { - lowerCaseParams.append(name.toLowerCase(), value); - } - const hasZip = lowerCaseParams.has(queryStrings.ZIP_CODE); - const zip = lowerCaseParams.get(queryStrings.ZIP_CODE); + const hasZip = getQuerystringParameter(queryStrings.ZIP_CODE) + const zip = getQuerystringParameter(queryStrings.ZIP_CODE) + const promo = getQuerystringParameter(queryStrings.PROMO) if ( hasZip && @@ -296,6 +292,10 @@ async function navigate( queryStringsObject[queryStrings.ZIP_CODE] = zip; } + if (promo) { + queryStringsObject[queryStrings.PROMO] = promo; + } + router.push({ name: "root", query: Object.assign(optionalQuery, queryStringsObject), From c18bdec2abfd5b5e427e110fe26d0a52470e11eb Mon Sep 17 00:00:00 2001 From: CarlNation Date: Fri, 1 Sep 2023 11:04:48 -0400 Subject: [PATCH 05/73] CSR-1623 missed semi-colons prettier --- src/helpers/heritage-integration/navigation-helper.js | 2 +- src/router/index.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/helpers/heritage-integration/navigation-helper.js b/src/helpers/heritage-integration/navigation-helper.js index ff651aab5..1769bfa4e 100644 --- a/src/helpers/heritage-integration/navigation-helper.js +++ b/src/helpers/heritage-integration/navigation-helper.js @@ -67,7 +67,7 @@ export async function navigateToHeritageFunnel({ shouldSaveSession = true, loadi isInsurance: store.getters.payment.isInsurance, }; - const promo = getQuerystringParameter(queryStrings.PROMO) + const promo = getQuerystringParameter(queryStrings.PROMO); if (promo) { heritageParms["promo"] = promo; diff --git a/src/router/index.js b/src/router/index.js index 424d09dcd..58a3059b5 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -278,9 +278,9 @@ async function navigate( fmgPage: destinationFmgPageValue, }; - const hasZip = getQuerystringParameter(queryStrings.ZIP_CODE) - const zip = getQuerystringParameter(queryStrings.ZIP_CODE) - const promo = getQuerystringParameter(queryStrings.PROMO) + const hasZip = getQuerystringParameter(queryStrings.ZIP_CODE); + const zip = getQuerystringParameter(queryStrings.ZIP_CODE); + const promo = getQuerystringParameter(queryStrings.PROMO); if ( hasZip && From 29d3c08b365a255b3b6a87fb32f6f97108b6e650 Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Tue, 5 Sep 2023 10:18:47 -0400 Subject: [PATCH 06/73] CSR-1617 | Defect fix - IsVinOptionalNotRepair --- src/helpers/heritage-integration/navigation-helper.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/helpers/heritage-integration/navigation-helper.js b/src/helpers/heritage-integration/navigation-helper.js index 3d1115000..b9207e04b 100644 --- a/src/helpers/heritage-integration/navigation-helper.js +++ b/src/helpers/heritage-integration/navigation-helper.js @@ -83,18 +83,21 @@ export async function skipVinLookup() { } export async function skipVinLookupNotRepair() { + if (store.getters.damage.isRepair) { + return false; + } + const isVinOptionalVehicle = store.getters.order.vehicle.make ? await store.dispatch(storeActions.IS_VIN_OPTIONAL_VEHICLE) : false; return ( - !store.getters.damage.isRepair && - (isVinOptionalVehicle || + isVinOptionalVehicle || !includesWindshieldReplacement() || experimentMixin.methods.hasSettingEqualTo( experimentSettings.SUPPRESS_VIN_CAPTURE, "true" - )) + ) ); } From a6e40db17c7b20f56ac99de65d138beba3ae5cb8 Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Tue, 5 Sep 2023 10:19:31 -0400 Subject: [PATCH 07/73] CSR-1617 | Formatting --- src/helpers/heritage-integration/navigation-helper.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/helpers/heritage-integration/navigation-helper.js b/src/helpers/heritage-integration/navigation-helper.js index b9207e04b..c52cef86d 100644 --- a/src/helpers/heritage-integration/navigation-helper.js +++ b/src/helpers/heritage-integration/navigation-helper.js @@ -93,11 +93,8 @@ export async function skipVinLookupNotRepair() { return ( isVinOptionalVehicle || - !includesWindshieldReplacement() || - experimentMixin.methods.hasSettingEqualTo( - experimentSettings.SUPPRESS_VIN_CAPTURE, - "true" - ) + !includesWindshieldReplacement() || + experimentMixin.methods.hasSettingEqualTo(experimentSettings.SUPPRESS_VIN_CAPTURE, "true") ); } From a3dff865ea696d3ca8c03154a413b6768f29172c Mon Sep 17 00:00:00 2001 From: CarlNation <32103961+CarlNation@users.noreply.github.com> Date: Fri, 8 Sep 2023 08:25:44 -0400 Subject: [PATCH 08/73] CSR-1625 router/index.js assumes a load-session successful response should always go to heritage. This may have been true in the initial version of NextGen but now we can load and direct it to the correct page. The incorrect routing to heritage was also failing here for returning users that already had a NextGen cookie. The error caused us to route to the beginning. Fixed that error by removing the default true in the navigateToHeritageFunnel and changing all calls to pass a true or false. --- .../heritage-integration/navigation-helper.js | 13 ++---- .../navigation-helper.spec.js | 42 ++++++------------- src/layouts/estimate/estimate.vue | 5 ++- src/layouts/quote/quote.vue | 5 ++- src/layouts/schedule/schedule.vue | 5 ++- src/mixins/vehicle-questions-mixin.js | 10 ++++- src/router/index.js | 12 +----- 7 files changed, 37 insertions(+), 55 deletions(-) diff --git a/src/helpers/heritage-integration/navigation-helper.js b/src/helpers/heritage-integration/navigation-helper.js index 8d22ee901..78080479e 100644 --- a/src/helpers/heritage-integration/navigation-helper.js +++ b/src/helpers/heritage-integration/navigation-helper.js @@ -17,15 +17,11 @@ import router from "@/router"; drop them so they don't start at the beginning again. This method will return 'heritage' if the user has an existing order and they come back in from the Safelite.com CTA. */ -export async function getPageToRouteExistingOrderTo(toRoute = {}, existingHeritageOrder = false) { +export async function getPageToRouteExistingOrderTo(toRoute = {}) { // If the user is coming in via the Safelite.Com CTA if (toRoute.query[queryStrings.START_TYPE] === "fmg") { - // If they have an existing order, return 'heritage' for the page name. - if (existingHeritageOrder) { - return fmgPageValues.HERITAGE; - } - - return await getLatestPageForRedirection(); + const latestPageRoute = await getLatestPageForRedirection(); + return latestPageRoute; } // If navigating to a specific page, and that page is not part of the vin pages. @@ -42,7 +38,6 @@ export async function getPageToRouteExistingOrderTo(toRoute = {}, existingHerita // If this is not a direct link to a page using fmgPage, not from Safelite.com CTA or this is a vin related page. // Get the latest page for redirection. const latestPageRoute = await getLatestPageForRedirection(); - return latestPageRoute; } @@ -50,7 +45,7 @@ export async function getPageToRouteExistingOrderTo(toRoute = {}, existingHerita Used to navigate to the heritage funnel with the correct query string and url. */ -export async function navigateToHeritageFunnel({ shouldSaveSession = true, loadingModal }) { +export async function navigateToHeritageFunnel({ shouldSaveSession, loadingModal }) { // Create the order (or save existing order) when navigating to Heritage Funnel. if (shouldSaveSession) { await saveSession({ shouldAwaitSaveSessionQueue: true }); diff --git a/src/helpers/heritage-integration/navigation-helper.spec.js b/src/helpers/heritage-integration/navigation-helper.spec.js index d08ce92ec..c3bafc2da 100644 --- a/src/helpers/heritage-integration/navigation-helper.spec.js +++ b/src/helpers/heritage-integration/navigation-helper.spec.js @@ -35,7 +35,7 @@ describe("getPageToRouteExistingOrderTo", () => { }); // Act - const result = await getPageToRouteExistingOrderTo(toRoute, false); + const result = await getPageToRouteExistingOrderTo(toRoute); //Assert expect(result).toBe(fmgPageValues.VEHICLE_YEAR); @@ -57,7 +57,7 @@ describe("getPageToRouteExistingOrderTo", () => { }); // Act - const result = await getPageToRouteExistingOrderTo(toRoute, false); + const result = await getPageToRouteExistingOrderTo(toRoute); //Assert expect(result).toBe(fmgPageValues.VEHICLE_MAKE); @@ -80,7 +80,7 @@ describe("getPageToRouteExistingOrderTo", () => { }); // Act - const result = await getPageToRouteExistingOrderTo(toRoute, false); + const result = await getPageToRouteExistingOrderTo(toRoute); //Assert expect(result).toBe(fmgPageValues.VEHICLE_MODEL); @@ -104,7 +104,7 @@ describe("getPageToRouteExistingOrderTo", () => { }); // Act - const result = await getPageToRouteExistingOrderTo(toRoute, false); + const result = await getPageToRouteExistingOrderTo(toRoute); //Assert expect(result).toBe(fmgPageValues.VEHICLE_STYLE); @@ -129,7 +129,7 @@ describe("getPageToRouteExistingOrderTo", () => { }); // Act - const result = await getPageToRouteExistingOrderTo(toRoute, false); + const result = await getPageToRouteExistingOrderTo(toRoute); //Assert expect(result).toBe(fmgPageValues.VEHICLE_DAMAGE); @@ -169,7 +169,7 @@ describe("getPageToRouteExistingOrderTo", () => { }); // Act - const result = await getPageToRouteExistingOrderTo(toRoute, false); + const result = await getPageToRouteExistingOrderTo(toRoute); //Assert expect(result).toBe(fmgPageValues.ESTIMATE); @@ -199,7 +199,7 @@ describe("getPageToRouteExistingOrderTo", () => { }); // Act - const result = await getPageToRouteExistingOrderTo(toRoute, false); + const result = await getPageToRouteExistingOrderTo(toRoute); //Assert expect(result).toBe(fmgPageValues.ESTIMATE); @@ -229,7 +229,7 @@ describe("getPageToRouteExistingOrderTo", () => { }); // Act - const result = await getPageToRouteExistingOrderTo(toRoute, false); + const result = await getPageToRouteExistingOrderTo(toRoute); //Assert expect(result).toBe(fmgPageValues.CAPABILITY_QUESTIONS); @@ -259,7 +259,7 @@ describe("getPageToRouteExistingOrderTo", () => { }); // Act - const result = await getPageToRouteExistingOrderTo(toRoute, false); + const result = await getPageToRouteExistingOrderTo(toRoute); //Assert expect(result).toBe(fmgPageValues.MOLDING_QUESTIONS); @@ -289,7 +289,7 @@ describe("getPageToRouteExistingOrderTo", () => { }); // Act - const result = await getPageToRouteExistingOrderTo(toRoute, false); + const result = await getPageToRouteExistingOrderTo(toRoute); //Assert expect(result).toBe(fmgPageValues.VEHICLE_PARTS); @@ -319,29 +319,11 @@ describe("getPageToRouteExistingOrderTo", () => { }); // Act - const result = await getPageToRouteExistingOrderTo(toRoute, false); + const result = await getPageToRouteExistingOrderTo(toRoute); //Assert expect(result).toBe(fmgPageValues.PART_QUESTIONS); }); - - test("existing order > should return heritage", async () => { - // Arrange - const toRoute = { - query: { - [queryStrings.START_TYPE]: "fmg", - }, - }; - - store.commit(storeMutations.UPDATE_IS_REPAIR, false); - store.commit(storeMutations.UPDATE_MAKE, "acura"); - - // Act - const result = await getPageToRouteExistingOrderTo(toRoute, true); - - // Assert - expect(result).toBe(fmgPageValues.HERITAGE); - }); }); describe("navigateToHeritageFunnel", () => { @@ -377,7 +359,7 @@ describe("navigateToHeritageFunnel", () => { router.navigateToExternalUrl = jest.fn(); // Act - await navigateToHeritageFunnel({}); + await navigateToHeritageFunnel({loadingModal:null, shouldSaveSession:true}); // Assert expect(saveSessionFunction).toHaveBeenCalled(); diff --git a/src/layouts/estimate/estimate.vue b/src/layouts/estimate/estimate.vue index d18af242c..5ae10cb9c 100644 --- a/src/layouts/estimate/estimate.vue +++ b/src/layouts/estimate/estimate.vue @@ -255,7 +255,10 @@ export default { const vehicleChangedDuringPolicyLookupInHeritage = payment.isInsurance && payment.insuranceCoverage.coverageStatus; if (vehicleChangedDuringPolicyLookupInHeritage) { - navigateToHeritageFunnel({ loadingModal: this.$refs.loadingModal }); + navigateToHeritageFunnel({ + shouldSaveSession: true, + loadingModal: this.$refs.loadingModal, + }); } else if (this.$store.getters.order.referralNumber?.length === 6) { await this.navigateForwardWithSingleCarMatch(); } else if (this.isRepair) { diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue index 99d824af5..30d15ba4c 100644 --- a/src/layouts/quote/quote.vue +++ b/src/layouts/quote/quote.vue @@ -216,7 +216,10 @@ export default { const payment = this.$store.getters.payment; if (payment.isInsurance) { - navigateToHeritageFunnel({ loadingModal: this.$refs.loadingModal }); + navigateToHeritageFunnel({ + shouldSaveSession: true, + loadingModal: this.$refs.loadingModal, + }); } else { this.$router.navigateWithSaving( this.navigationScenarios.CLICKED_FORWARD_WITH_CASH, diff --git a/src/layouts/schedule/schedule.vue b/src/layouts/schedule/schedule.vue index 1ff1c18e7..3fda3d7e0 100644 --- a/src/layouts/schedule/schedule.vue +++ b/src/layouts/schedule/schedule.vue @@ -418,7 +418,10 @@ export default { this.appointmentDateAndTime, false ); - navigateToHeritageFunnel({ loadingModal: this.$refs.loadingModal }); + navigateToHeritageFunnel({ + shouldSaveSession: true, + loadingModal: this.$refs.loadingModal, + }); }, updateSupportingItems() { diff --git a/src/mixins/vehicle-questions-mixin.js b/src/mixins/vehicle-questions-mixin.js index 4b05067ea..fb54c059f 100644 --- a/src/mixins/vehicle-questions-mixin.js +++ b/src/mixins/vehicle-questions-mixin.js @@ -447,9 +447,15 @@ export default { const payment = store.getters.payment; if (store.getters.order.referralNumber?.length === 6) { - navigateToHeritageFunnel({ loadingModal: self.$refs.loadingModal }); + navigateToHeritageFunnel({ + shouldSaveSession: true, + loadingModal: self.$refs.loadingModal, + }); } else if (payment.isInsurance && payment.insuranceCoverage.isVerified) { - navigateToHeritageFunnel({ loadingModal: self.$refs.loadingModal }); + navigateToHeritageFunnel({ + shouldSaveSession: true, + loadingModal: self.$refs.loadingModal, + }); } else { self.$router.navigateWithSaving( self.navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS, diff --git a/src/router/index.js b/src/router/index.js index 58a3059b5..76892f76c 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -68,17 +68,7 @@ const routes = [ : null ); - const pageToRedirectTo = await getPageToRouteExistingOrderTo( - to, - loadSessionResponse - ); - - // If getPageToRouteExistingOrderTo determines that the return user needs to - // go back to heritage funnel, send them there and stop our current navigation. - if (pageToRedirectTo === "heritage") { - await navigateToHeritageFunnel(); - return next(false); - } + const pageToRedirectTo = await getPageToRouteExistingOrderTo(to); // Assign our fmgPage so it will load normally like the other pages. to.query.fmgPage = pageToRedirectTo; From 9e3e2a820bf6cad64f3b6225a7f1d067030a61cd Mon Sep 17 00:00:00 2001 From: CarlNation Date: Fri, 8 Sep 2023 08:29:47 -0400 Subject: [PATCH 09/73] CSR-1625 prettier --- src/helpers/heritage-integration/navigation-helper.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helpers/heritage-integration/navigation-helper.spec.js b/src/helpers/heritage-integration/navigation-helper.spec.js index c3bafc2da..145258c75 100644 --- a/src/helpers/heritage-integration/navigation-helper.spec.js +++ b/src/helpers/heritage-integration/navigation-helper.spec.js @@ -359,7 +359,7 @@ describe("navigateToHeritageFunnel", () => { router.navigateToExternalUrl = jest.fn(); // Act - await navigateToHeritageFunnel({loadingModal:null, shouldSaveSession:true}); + await navigateToHeritageFunnel({ loadingModal: null, shouldSaveSession: true }); // Assert expect(saveSessionFunction).toHaveBeenCalled(); From adaa964a4cc7c2481685d1ef30e0cdcae57aa9cd Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Fri, 8 Sep 2023 16:43:19 -0400 Subject: [PATCH 10/73] CSR-1635 | Move supportingItems save to store to Quote page load --- src/layouts/quote/quote.vue | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue index 30d15ba4c..61287610b 100644 --- a/src/layouts/quote/quote.vue +++ b/src/layouts/quote/quote.vue @@ -121,6 +121,12 @@ export default { false ); + baseMixin.methods.dispatchStoreAction( + storeActions.SAVE_SUPPORTING_ITEMS, + resultMap.supportingItems, + false + ); + // Call the "next" function to complete the transition to this page. next((vm) => { vm.setCmsContent(resultMap.cmsContent); @@ -206,12 +212,6 @@ export default { ); } - this.dispatchStoreAction( - this.storeActions.SAVE_SUPPORTING_ITEMS, - this.supportingItems, - false - ); - this.dispatchStoreAction(this.storeActions.SAVE_VAPS, this.selectedVaps, false); const payment = this.$store.getters.payment; From 2da09b11b7bf07c99233a9e5892057d06ace9f4f Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Tue, 12 Sep 2023 11:20:13 -0400 Subject: [PATCH 11/73] CSR-1642 | Mobile fee not being saved to supporting items fix --- .../service-location/service-location.vue | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/layouts/service-location/service-location.vue b/src/layouts/service-location/service-location.vue index 2c0e0619b..c25826121 100644 --- a/src/layouts/service-location/service-location.vue +++ b/src/layouts/service-location/service-location.vue @@ -116,6 +116,8 @@ import store from "@/store"; import { defineRule } from "vee-validate"; import { errorMessages } from "@/constants/error-messages"; +const MOBILE_FEE_PART_TYPE = "MOBILE FEE"; + // DEFINE VALIDATION RULES defineRule("mobile-location-required", (value) => { if ( @@ -375,6 +377,49 @@ export default { backButtonAction() { this.$router.navigateWithoutSaving(this.navigationScenarios.CLICKED_BACK, this.$route); }, + updateAndSaveSupportingItems() { + const supportingItems = store.getters.lineItems.supportingItems; + // if we have a mobile fee, then save/update supporting items + if ( + this.selectedAppointmentType == "Mobile" + ) { + const mobileFeeIndex = supportingItems.findIndex( + (item) => item.partType == MOBILE_FEE_PART_TYPE + ); + // If it already exists, update the price with latest data + if (mobileFeeIndex >= 0) { + supportingItems[mobileFeeIndex].laborAmount = + this.mobileFeePart.laborAmount; + supportingItems[mobileFeeIndex].selingPrice = + this.mobileFeePart.selingPrice; + supportingItems[mobileFeeIndex].kitPrice = + this.mobileFeePart.kitPrice; + } else { + supportingItems.push(this.mobileFeePart); + } + + this.dispatchStoreAction( + this.storeActions.SAVE_SUPPORTING_ITEMS_SUPPRESSING_STATE_RESETTING, + supportingItems, + false + ); + } else { + + // if it's not a mobile, then make sure we remove any that may have been added + const removeMobileFeeIndex = supportingItems.findIndex( + (item) => item.partType == MOBILE_FEE_PART_TYPE + ); + + if (removeMobileFeeIndex >= 0) { + supportingItems.splice(removeMobileFeeIndex, 1); + this.dispatchStoreAction( + this.storeActions.SAVE_SUPPORTING_ITEMS_SUPPRESSING_STATE_RESETTING, + supportingItems, + false + ); + } + } + }, async forwardButtonAction() { await this.dispatchStoreAction( this.storeActions.SAVE_SERVICE_LOCATION, @@ -401,6 +446,8 @@ export default { false ); + this.updateAndSaveSupportingItems(); + this.$router.navigateWithSaving( this.navigationScenarios.SELECTED_LOCATION, this.$route From b73abadebd2e5dfb623069303c5f0876e039cba3 Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Tue, 12 Sep 2023 11:22:00 -0400 Subject: [PATCH 12/73] CSR-1614 | Formatting --- src/layouts/service-location/service-location.vue | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/layouts/service-location/service-location.vue b/src/layouts/service-location/service-location.vue index c25826121..0eaaffbd4 100644 --- a/src/layouts/service-location/service-location.vue +++ b/src/layouts/service-location/service-location.vue @@ -380,20 +380,15 @@ export default { updateAndSaveSupportingItems() { const supportingItems = store.getters.lineItems.supportingItems; // if we have a mobile fee, then save/update supporting items - if ( - this.selectedAppointmentType == "Mobile" - ) { + if (this.selectedAppointmentType == "Mobile") { const mobileFeeIndex = supportingItems.findIndex( (item) => item.partType == MOBILE_FEE_PART_TYPE ); // If it already exists, update the price with latest data if (mobileFeeIndex >= 0) { - supportingItems[mobileFeeIndex].laborAmount = - this.mobileFeePart.laborAmount; - supportingItems[mobileFeeIndex].selingPrice = - this.mobileFeePart.selingPrice; - supportingItems[mobileFeeIndex].kitPrice = - this.mobileFeePart.kitPrice; + supportingItems[mobileFeeIndex].laborAmount = this.mobileFeePart.laborAmount; + supportingItems[mobileFeeIndex].selingPrice = this.mobileFeePart.selingPrice; + supportingItems[mobileFeeIndex].kitPrice = this.mobileFeePart.kitPrice; } else { supportingItems.push(this.mobileFeePart); } @@ -404,7 +399,6 @@ export default { false ); } else { - // if it's not a mobile, then make sure we remove any that may have been added const removeMobileFeeIndex = supportingItems.findIndex( (item) => item.partType == MOBILE_FEE_PART_TYPE From ad4b53a4b752a105cefeb07f18ab4afa97a7472a Mon Sep 17 00:00:00 2001 From: CarlNation <32103961+CarlNation@users.noreply.github.com> Date: Wed, 13 Sep 2023 10:38:32 -0400 Subject: [PATCH 13/73] CSR-1654 only save customer name on address lookup if it's not already in the store --- src/layouts/address-lookup/address-lookup.vue | 2 +- src/store/index.js | 29 ++++++++++++++----- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/layouts/address-lookup/address-lookup.vue b/src/layouts/address-lookup/address-lookup.vue index 48ab0dd08..f0bf91325 100644 --- a/src/layouts/address-lookup/address-lookup.vue +++ b/src/layouts/address-lookup/address-lookup.vue @@ -320,7 +320,7 @@ export default { Object.keys(vehicleInfoToCommit).length === 0 ? this.$store.getters.vehicle : vehicleInfoToCommit, - registrationInfo: { + customerInfo: { firstName: this.customerQuestions.firstName, lastName: this.customerQuestions.lastName, }, diff --git a/src/store/index.js b/src/store/index.js index 976ef0d2e..95a028aae 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -234,8 +234,6 @@ export const mutations = { }, updateRegistration(state, registrationInfo) { state.order.vehicle.registration.licensePlate = registrationInfo?.licensePlate; - state.order.customer.firstName = registrationInfo?.firstName; - state.order.customer.lastName = registrationInfo?.lastName; }, updateServiceZip(state, serviceZipInfo) { state.order.serviceLocation.state = serviceZipInfo.state; @@ -1662,15 +1660,25 @@ export const actions = { context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES); } - //Save new values context.commit(storeMutations.UPDATE_VEHICLE, vehicleInfo); - context.commit(storeMutations.UPDATE_REGISTRATION, registrationInfo); + + if (registrationInfo) { + context.commit(storeMutations.UPDATE_REGISTRATION, registrationInfo); + + // only update name information if there isn't a value in state already + if (!context.getters.order.customer.firstName) { + context.commit(storeMutations.UPDATE_CUSTOMER_DETAILS, { + firstName: registrationInfo.firstName, + lastName: registrationInfo.lastName, + }); + } + } } }, saveRegistrationAddressLookup( context, - { isSelectedGlassAvailableForVehicle, vehicleInfo, registrationInfo } + { isSelectedGlassAvailableForVehicle, vehicleInfo, customerInfo } ) { //Reset dependent state when changing if (vehicleInfo.vin !== context.state.order.vehicle.vin) { @@ -1681,9 +1689,14 @@ export const actions = { } } - if (registrationInfo) { - context.commit(storeMutations.UPDATE_VEHICLE, vehicleInfo); - context.commit(storeMutations.UPDATE_REGISTRATION, registrationInfo); + context.commit(storeMutations.UPDATE_VEHICLE, vehicleInfo); + + // only update name information if there isn't a value in state already + if (!context.getters.order.customer.firstName && customerInfo) { + context.commit(storeMutations.UPDATE_CUSTOMER_DETAILS, { + firstName: customerInfo.firstName, + lastName: customerInfo.lastName, + }); } }, From cd1354bc6dbada3a684e62ccd70d89a0e03b818d Mon Sep 17 00:00:00 2001 From: CarlNation Date: Wed, 13 Sep 2023 13:37:51 -0400 Subject: [PATCH 14/73] CSR-1564 tests --- src/store/store.spec.js | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/store/store.spec.js b/src/store/store.spec.js index ded194ba8..947299ff8 100644 --- a/src/store/store.spec.js +++ b/src/store/store.spec.js @@ -1492,9 +1492,18 @@ describe("Actions", () => { licensePlate: "ABC123", }, }, + customer: { + firstName: "test", + lastName: "test", + }, }, }; + context.getters = { + ...getters, + order: getters.order(context), + }; + const commit = jest.fn(); const dispatch = jest.fn(); @@ -1538,9 +1547,18 @@ describe("Actions", () => { address: "123 Main St", }, }, + customer: { + firstName: "test", + lastName: "test", + }, }, }; + context.getters = { + ...getters, + order: getters.order(context), + }; + const commit = jest.fn(); const dispatch = jest.fn(); @@ -1552,7 +1570,7 @@ describe("Actions", () => { isCarIdDifferent: true, isSelectedGlassAvailableForVehicle: false, vehicleInfo: { carId: "C010101", vin: "XXXXX" }, - registrationInfo: { firstName: "abc", lastName: "123" }, + customerInfo: { firstName: "abc", lastName: "123" }, serviceLocationInfo: { state: "CO" }, customerEmail: "test@safelite.com", }; @@ -1570,7 +1588,6 @@ describe("Actions", () => { ); expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE, payload.vehicleInfo); - expect(commit).toBeCalledWith(storeMutations.UPDATE_REGISTRATION, payload.registrationInfo); }); it("saveVehicle, should save vehicle info", () => { From 73f0a808df9b6e76130c58689579cbeeefc06e30 Mon Sep 17 00:00:00 2001 From: sheena Date: Thu, 14 Sep 2023 14:21:54 +0530 Subject: [PATCH 15/73] CSR-1631 Fixed the margin to 24px --- src/layouts/vehicle/vehicle.vue | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/layouts/vehicle/vehicle.vue b/src/layouts/vehicle/vehicle.vue index 8cc3f8e88..82e7ac8a4 100644 --- a/src/layouts/vehicle/vehicle.vue +++ b/src/layouts/vehicle/vehicle.vue @@ -3,7 +3,6 @@
-
@@ -67,8 +66,7 @@ ref="funnelFooter" />
-
-
+
@@ -402,10 +400,6 @@ export default { + const payment = this.$store.getters.payment; + if (payment.isInsurance) { + navigateToHeritageFunnel({ + shouldSaveSession: true, + loadingModal: this.$refs.loadingModal, + }); + } else { + this.$router.navigateWithSaving( + this.navigationScenarios.CLICKED_FORWARD_WITH_CASH, + this.$route + ); + } + }, + }, + components: { + funnelHeader, + navbar, + vehicleBanner, + funnelSubHeader, + Form, + textBlock, + cashOrInsuranceQuestion, + servicePackageQuestion, + contentGroupModal, + loadingModal, + }, + }; + + diff --git a/src/layouts/review/review.vue b/src/layouts/review/review.vue index 2fb033ea3..592654db1 100644 --- a/src/layouts/review/review.vue +++ b/src/layouts/review/review.vue @@ -1,105 +1,116 @@ diff --git a/src/layouts/service-location/service-location.vue b/src/layouts/service-location/service-location.vue index e49cd295c..b5ceb81dd 100644 --- a/src/layouts/service-location/service-location.vue +++ b/src/layouts/service-location/service-location.vue @@ -1,87 +1,109 @@ @@ -95,7 +117,7 @@ import appointmentTypeQuestion from "@/layouts/service-location/appointment-type import shopQuestion from "@/layouts/service-location/shop-question/shop-question"; import funnelHeader from "@/fmg-components/funnel-header/funnel-header"; -import funnelFooter from "@/fmg-components/funnel-footer/funnel-footer"; +import navbar from "@/fmg-components/nav-bar/nav-bar"; import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-header"; import loadingModal from "@/fmg-components/loading-modal/loading-modal.vue"; import { Form } from "vee-validate"; @@ -240,7 +262,7 @@ export default { set: function (newValue) { this.streetAddress = newValue.addressQuestions.streetAddress; this.apartmentNumberOrBusinessName = - newValue.addressQuestions.apartmentNumberOrBusinessName; + newValue.addressQuestions.apartmentNumberOrBusinessName; this.city = newValue.addressQuestions.city; this.state = newValue.addressQuestions.state; this.zipCode = newValue.addressQuestions.zipCode; @@ -369,10 +391,10 @@ export default { setServiceabilityDetails(serviceabilityDetails) { this.isGlassServiceableInshop = serviceabilityDetails.isGlassServiceableInshop; this.isRecalibrationServiceableInshop = - serviceabilityDetails.isRecalibrationServiceableInshop; + serviceabilityDetails.isRecalibrationServiceableInshop; this.isGlassServiceableMobile = serviceabilityDetails.isGlassServiceableMobile; this.isRecalibrationServiceableMobile = - serviceabilityDetails.isRecalibrationServiceableMobile; + serviceabilityDetails.isRecalibrationServiceableMobile; }, backButtonAction() { this.$router.navigateWithoutSaving(this.navigationScenarios.CLICKED_BACK, this.$route); @@ -456,7 +478,7 @@ export default { appointmentTypeQuestion, mobileLocationModalQuestions, funnelHeader, - funnelFooter, + navbar, funnelSubHeader, Form, loadingModal, diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue index c03fabda1..e27d398a4 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.vue +++ b/src/layouts/vehicle-damage/vehicle-damage.vue @@ -1,65 +1,81 @@ - + const payment = this.$store.getters.payment; + if (payment.isInsurance) { + navigateToHeritageFunnel({ + shouldSaveSession: true, + loadingModal: this.$refs.loadingModal, + }); + } else { + this.$router.navigateWithSaving( + this.navigationScenarios.CLICKED_FORWARD_WITH_CASH, + this.$route + ); + } + }, + }, + components: { + funnelHeader, + navbar, + vehicleBanner, + funnelSubHeader, + Form, + textBlock, + cashOrInsuranceQuestion, + servicePackageQuestion, + contentGroupModal, + loadingModal, + }, +}; + + diff --git a/src/layouts/review/review.vue b/src/layouts/review/review.vue index 592654db1..c7112fb00 100644 --- a/src/layouts/review/review.vue +++ b/src/layouts/review/review.vue @@ -8,7 +8,7 @@
-
 
+
 
- -
-
 
+
 
+ diff --git a/src/layouts/schedule/schedule.vue b/src/layouts/schedule/schedule.vue index 23564a4c7..59d8e932a 100644 --- a/src/layouts/schedule/schedule.vue +++ b/src/layouts/schedule/schedule.vue @@ -1,63 +1,66 @@ diff --git a/src/layouts/service-location/service-location.vue b/src/layouts/service-location/service-location.vue index b5ceb81dd..aed00e644 100644 --- a/src/layouts/service-location/service-location.vue +++ b/src/layouts/service-location/service-location.vue @@ -8,101 +8,100 @@
-
 
+
 
+ v-model="serviceZipCodeQuestion" + ref="serviceZipCodeQuestion" + :mobileFeePart="mobileFeePart" + @updated-mobile-fee-part="setMobileFeePart" + @updated-serviceability="setServiceabilityDetails" + @updated-contains-military-base="setContainsMilitaryBase" + linkWidgetName="ServiceZipLinkWidget" + modalWidgetName="ServiceZipModalWidget" + :onZipUpdateCallback="reloadShopData" /> + ref="alertMilitaryBaseZip" + class="my-5" + cmsWidgetName="AlertMilitaryBaseZipWidget" + v-if="displayMilitaryZipAlert" + alertClass="alert-warning" /> + ref="alertMobileOnly" + class="my-5" + cmsWidgetName="AlertMobileOnlyWidget" + v-if="displayServiceableMobileOnly" + alertClass="alert-warning" /> + ref="alertRecalNoMobile" + class="my-5" + cmsWidgetName="AlertRecalNoMobileWidget" + v-if="displayRecalibrationWarning" + @text-link-clicked="openModalAction" + alertClass="alert-warning" /> + ref="alertInshopOnly" + class="my-5" + cmsWidgetName="AlertInshopOnlyWidget" + v-if="displayServiceableInshopOnly" + alertClass="alert-warning" /> + ref="alertNoShops" + class="my-5" + cmsWidgetName="AlertNoShopsWidget" + v-if="displayNoShopsAlert" + alertClass="alert-warning" /> + v-model="selectedAppointmentType" + v-show="isAppointmentTypeDisplayed" + :isServiceableMobile="isServiceableMobile" + :isServiceableInshop="isServiceableInshop" + :isDisplayed="isAppointmentTypeDisplayed" + ref="appointmentTypeQuestion" + groupName="appointmentTypeQuestion" + cmsWidgetName="AppointmentTypeQuestionWidget" + validationRules="option-required" /> + customComponentId="mobileLocationQuestions" + v-if="selectedAppointmentType === 'Mobile'" + v-model="mobileLocationQuestions" + :mobileFeePart="mobileFeePart" + @updated-mobile-fee-part="setMobileFeePart" + @updated-serviceability="setServiceabilityDetails" + @updated-contains-military-base="setContainsMilitaryBase" + validationRules="mobile-location-required" + ref="mobileLocationQuestions" + linkWidgetName="MobileLocationLinkWidget" + modalWidgetName="MobileLocationModalWidget" + :onZipUpdateCallback="reloadShopData" /> + ref="shopQuestion" + v-show="isShopQuestionDisplayed" + v-model="selectedProvider" + :selectedAppointmentType="selectedAppointmentType" + :isDisplayed="isShopQuestionDisplayed" + cmsWidgetName="ShopQuestionWidget" /> - + cmsWidgetName="FunnelFooterWidget" + ref="navbar" + :isForwardActionDisabled="!meta.valid || displayNoShopsAlert" + @back-clicked="backButtonAction" + @ForwardClicked="forwardButtonAction" />
-
 
+
 
@@ -262,7 +261,7 @@ export default { set: function (newValue) { this.streetAddress = newValue.addressQuestions.streetAddress; this.apartmentNumberOrBusinessName = - newValue.addressQuestions.apartmentNumberOrBusinessName; + newValue.addressQuestions.apartmentNumberOrBusinessName; this.city = newValue.addressQuestions.city; this.state = newValue.addressQuestions.state; this.zipCode = newValue.addressQuestions.zipCode; @@ -391,10 +390,10 @@ export default { setServiceabilityDetails(serviceabilityDetails) { this.isGlassServiceableInshop = serviceabilityDetails.isGlassServiceableInshop; this.isRecalibrationServiceableInshop = - serviceabilityDetails.isRecalibrationServiceableInshop; + serviceabilityDetails.isRecalibrationServiceableInshop; this.isGlassServiceableMobile = serviceabilityDetails.isGlassServiceableMobile; this.isRecalibrationServiceableMobile = - serviceabilityDetails.isRecalibrationServiceableMobile; + serviceabilityDetails.isRecalibrationServiceableMobile; }, backButtonAction() { this.$router.navigateWithoutSaving(this.navigationScenarios.CLICKED_BACK, this.$route); diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue index e27d398a4..9670ec48c 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.vue +++ b/src/layouts/vehicle-damage/vehicle-damage.vue @@ -6,16 +6,16 @@ -
-
 
-
- +
 
+
+ - + - - - - - - - -
-
 
+
 
+ @@ -235,7 +235,7 @@ export default { }) ) { windShieldOptions.selectedWindshieldDamageType = - damageLocationsSelected.REPLACE; + damageLocationsSelected.REPLACE; windShieldOptions.selectedWindshieldReplaceOptions.push( damageLocationsSelected.SINGLE ); @@ -250,7 +250,7 @@ export default { }) ) { windShieldOptions.selectedWindshieldDamageType = - damageLocationsSelected.REPLACE; + damageLocationsSelected.REPLACE; windShieldOptions.selectedWindshieldReplaceOptions.push( damageLocationsSelected.DRIVER ); @@ -265,7 +265,7 @@ export default { }) ) { windShieldOptions.selectedWindshieldDamageType = - damageLocationsSelected.REPLACE; + damageLocationsSelected.REPLACE; windShieldOptions.selectedWindshieldReplaceOptions.push( damageLocationsSelected.PASSENGER ); @@ -335,7 +335,7 @@ export default { isWindshieldRepair: this.isWindshieldRepair, selectedGlassToReplace: this.selectedGlassToReplace(), selectedWindshieldChipCount: - this.selectedWindshieldOptions.selectedWindshieldChipCount, + this.selectedWindshieldOptions.selectedWindshieldChipCount, }, false ); @@ -358,9 +358,9 @@ export default { const payment = this.$store.getters.payment; const vehicleChangedDuringPolicyLookupInHeritage = - payment.isInsurance && - payment.insuranceCoverage.coverageStatus && - payment.insuranceCoverage.coverageStatus !== ""; + payment.isInsurance && + payment.insuranceCoverage.coverageStatus && + payment.insuranceCoverage.coverageStatus !== ""; if (vehicleChangedDuringPolicyLookupInHeritage) { if (store.getters.damage.isRepair) { this.$router.navigateWithSaving( @@ -370,7 +370,7 @@ export default { } else { this.$router.navigateWithSaving( this.navigationScenarios - .CLICKED_FORWARD_WITH_REPLACE_AND_VERIFIED_INSURANCE, + .CLICKED_FORWARD_WITH_REPLACE_AND_VERIFIED_INSURANCE, this.$route ); } @@ -452,7 +452,7 @@ export default { return ( this.isWindshieldDamageLocation && this.selectedWindshieldOptions.selectedWindshieldDamageType === - damageLocationsSelected.REPAIR + damageLocationsSelected.REPAIR ); }, isDriverSideReplace() { @@ -480,10 +480,10 @@ export default { if ( !this.selectedDamageLocations?.includes("Windshield") || this.selectedWindshieldOptions.selectedWindshieldDamageType === - damageLocationsSelected.REPAIR || + damageLocationsSelected.REPAIR || !this.selectedWindshieldOptions.selectedWindshieldReplaceOptions ) - return false; + return false; return ( this.selectedWindshieldOptions.selectedWindshieldReplaceOptions?.some( @@ -502,14 +502,14 @@ export default { ); } ) || - this.selectedWindshieldOptions.selectedWindshieldReplaceOptions?.some( - (selectedPassengerWindshield) => { - return ( - selectedPassengerWindshield.toUpperCase() === - damageLocationsSelected.PASSENGER.toUpperCase() - ); - } - )) + this.selectedWindshieldOptions.selectedWindshieldReplaceOptions?.some( + (selectedPassengerWindshield) => { + return ( + selectedPassengerWindshield.toUpperCase() === + damageLocationsSelected.PASSENGER.toUpperCase() + ); + } + )) ); }, shouldDisplayVehicleChangeAlert() { diff --git a/src/layouts/vehicle-parts/vehicle-parts.vue b/src/layouts/vehicle-parts/vehicle-parts.vue index c34223b88..5ad44d3e0 100644 --- a/src/layouts/vehicle-parts/vehicle-parts.vue +++ b/src/layouts/vehicle-parts/vehicle-parts.vue @@ -9,44 +9,48 @@
-
 
+
 
- -
-
-
- -
+ +
+
+
+
-
- -
- -
- +
+
+ +
+ +
+
-
 
+
 
diff --git a/src/layouts/vehicle/vehicle.vue b/src/layouts/vehicle/vehicle.vue index 92f1e7ea6..8743ef284 100644 --- a/src/layouts/vehicle/vehicle.vue +++ b/src/layouts/vehicle/vehicle.vue @@ -7,7 +7,7 @@
-
 
+
 
-
 
+
 
diff --git a/src/layouts/vin-lookup/vin-lookup.vue b/src/layouts/vin-lookup/vin-lookup.vue index dfb254dc9..fe25fa403 100644 --- a/src/layouts/vin-lookup/vin-lookup.vue +++ b/src/layouts/vin-lookup/vin-lookup.vue @@ -8,126 +8,122 @@
-
 
+
 
+ cmsWidgetName="VehicleBannerWidget" + :displayGenericVehicleImage="false" /> + cmsWidgetName="VinNumberQuestionWidget" + v-model="vin" + customInputId="vin" + isRequired + :validationRules="!vinPopulatedOnPageLoad ? 'vin-required|vin-format' : ''" + :isDisabled="vinPopulatedOnPageLoad" + maxLength="17" + :mask="vinMask" + includeImageQuestion + :imageQuestionSubmitHandler="getVinFromImage" + :maxFileSize="imageUploadMaxFileSize" + @image-lookup-error="displayVinScanAlert" + @image-validity-error="displayVinScanAlert" + data-test="vin-lookup-field" + ref="vinLookupQuestion" /> + cmsWidgetName="AlertVinScanFailed" + v-if="displayVinScanFailedAlert" + alertClass="alert-danger" /> + cmsWidgetName="ServiceZipQuestionWidget" + v-model="serviceZipCode" + customInputId="serviceZipCode" + mask="#####" + isRequired + validationRules="zip-required|zip-format" /> + cmsWidgetName="EmailAddressQuestionWidget" + v-model="emailAddress" + customInputId="emailAddress" + isRequired + validationRules="email-address-required|email-address-format" /> + ref="alertInvalidZip" + v-if="displayInvalidZipAlert" + class="my-4" + cmsWidgetName="AlertInvalidZipWidget" + alertClass="alert-danger" + v-bind:isDismissible="false" /> + class="my-4" + :manualHeadline="AlertPerfectMatchInsuranceVerifiedHeader" + :manualCopy="AlertPerfectMatchInsuranceVerifiedBody" + v-model="customAlertData" + v-if=" + vinPopulatedOnPageLoad && + isInsuranceVerified && + !displayInvalidZipAlert && + !displayNonServiceableZipAlert + " + alertClass="alert-success" /> + class="my-4" + :manualHeadline="AlertMatchedDifferentVehicleHeader" + :manualCopy="AlertMatchedDifferentVehicleBody" + v-model="customAlertData" + v-if="displayMatchedDifferentVehicleAlert" + alertClass="alert-warning" /> + class="my-4" + :manualHeadline="AlertNonServiceableZipHeader" + :manualCopy="AlertNonServiceableZipBody" + v-model="customAlertData" + v-if="displayNonServiceableZipAlert" + alertClass="alert-danger" /> + class="my-4" + v-model="customAlertData" + v-if="displayVinNotFoundAlert" + alertClass="alert-danger" + cmsWidgetName="AlertVinNotFoundWidget" /> + class="my-4" + :manualHeadline="AlertPerfectMatchInsuranceNotVerifiedHeader" + :manualCopy="AlertPerfectMatchInsuranceNotVerifiedBody" + v-model="customAlertData" + v-if=" + vinPopulatedOnPageLoad && + !isInsuranceVerified && + !displayInvalidZipAlert && + !displayNonServiceableZipAlert + " + alertClass="alert-success" /> - + cmsWidgetName="FunnelFooterWidget" + ref="navbar" + :isForwardActionDisabled="!meta.valid" + @back-clicked="backButtonAction" + @ForwardClicked="forwardButtonAction" />
-
 
+
 
- @@ -300,7 +296,7 @@ export default { // Check if the CarId is different from the lookup vs what is in state currently. this.isCarIdDifferent = - resultMap.vehicleLookupResponse.carId !== this.$store.getters.vehicle.carId; + resultMap.vehicleLookupResponse.carId !== this.$store.getters.vehicle.carId; if ( this.isCarIdDifferent && @@ -400,16 +396,16 @@ export default { getVinFromImage(image) { return new Promise((resolve, reject) => { this.dispatchStoreAction(storeActions.LOOKUP_VIN_BY_IMAGE, image) - .then((response) => { - if (response.data.length > 0) { - resolve(response.data[0]); - } else { - reject("No VINs detected."); - } - }) - .catch(() => { - reject("An error occurred during the lookup."); - }); + .then((response) => { + if (response.data.length > 0) { + resolve(response.data[0]); + } else { + reject("No VINs detected."); + } + }) + .catch(() => { + reject("An error occurred during the lookup."); + }); }); }, resetAlerts() { @@ -432,10 +428,10 @@ export default { }, AlertMatchedDifferentVehicleBody() { return this.getCmsContent("AlertMatchedDifferentVehicleWidget", "BodyText") - .replaceAll("{custom:damage}", getDamageString()) - .replaceAll("{custom:vinlookupYear}", this.customAlertData?.vehicleInfo?.year) - .replaceAll("{custom:vinlookupMake}", this.customAlertData?.vehicleInfo?.make) - .replaceAll("{custom:vinlookupModel}", this.customAlertData?.vehicleInfo?.model); + .replaceAll("{custom:damage}", getDamageString()) + .replaceAll("{custom:vinlookupYear}", this.customAlertData?.vehicleInfo?.year) + .replaceAll("{custom:vinlookupMake}", this.customAlertData?.vehicleInfo?.make) + .replaceAll("{custom:vinlookupModel}", this.customAlertData?.vehicleInfo?.model); }, AlertNonServiceableZipHeader() { return this.getCmsContent("AlertNonServiceableZipWidget", "HeadlineText").replaceAll( From efd0edc1e9f451ee821536fbc4ecde99834c5358 Mon Sep 17 00:00:00 2001 From: Bryan Mauger Date: Tue, 19 Sep 2023 11:16:32 -0400 Subject: [PATCH 29/73] WIP grid tweaks for list-card. --- .../button-question/button-question.vue | 4 +- src/layouts/vehicle-damage/vehicle-damage.vue | 116 +++++++++--------- 2 files changed, 60 insertions(+), 60 deletions(-) diff --git a/src/digital-components/button-question/button-question.vue b/src/digital-components/button-question/button-question.vue index 13c81f815..9636d1d25 100644 --- a/src/digital-components/button-question/button-question.vue +++ b/src/digital-components/button-question/button-question.vue @@ -192,9 +192,9 @@ export default { classes = "d-flex flex-row p-0"; break; case "listCard": - classes = "row g-2 justify-content-center mb-1"; + classes = "row g-2 g-md-5 justify-content-center mb-1"; if (this.isWide) { - classes += " flex-column"; + classes += "flex-column"; } break; case "radio": diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue index 9670ec48c..e5583d986 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.vue +++ b/src/layouts/vehicle-damage/vehicle-damage.vue @@ -10,61 +10,61 @@
 
+ cmsWidgetName="VehicleBannerWidget" + :displayGenericVehicleImage="false" /> + ref="vehicleChangeAlert" + v-if="shouldDisplayVehicleChangeAlert" + class="mt-5 mb-0" + cmsWidgetName="VehicleChangeAlert" + alertClass="alert-warning" + :isDismissible="false" /> + ref="damageLocation" + cmsWidgetName="DamageLocationQuestion" + v-model="selectedDamageLocations" + groupName="DamageLocationQuestion" /> + ref="windshieldOptions" + v-model="selectedWindshieldOptions" + :hasRepairReplaceConflict="hasRepairReplaceConflict" + :hasSplitSingleConflict="hasSplitSingleConflict" + :selectedDamageLocations="selectedDamageLocations" /> + v-if="hasRepairReplaceConflict" + class="my-5" + cmsWidgetName="HasReplacementConflict" + alertClass="alert-danger" + :isDismissible="false" /> + ref="sideDoorOptions" + cmsWidgetName="SideDoorSideQuestion" + groupName="SideDoorSideQuestion" + v-model="sideDoorOptionsData" + v-show="!hasRepairReplaceConflict" + :selectedDamageLocations="selectedDamageLocations" /> + ref="backGlassOptions" + cmsWidgetName="RearReplaceOptionsQuestion" + :isAvailable="isRearWindowDamageLocation && !hasRepairReplaceConflict" + v-model="selectedRearReplaceOptions" + groupName="BackGlassReplaceOptionsQuestion" + validationRules="replace-options-required" /> + cmsWidgetName="FunnelFooterWidget" + :isForwardActionDisabled="!meta.valid" + :isBackButtonHidden="shouldHideBackButton" + @back-clicked="backButtonAction" + @ForwardClicked="forwardButtonAction" />
 
@@ -235,7 +235,7 @@ export default { }) ) { windShieldOptions.selectedWindshieldDamageType = - damageLocationsSelected.REPLACE; + damageLocationsSelected.REPLACE; windShieldOptions.selectedWindshieldReplaceOptions.push( damageLocationsSelected.SINGLE ); @@ -250,7 +250,7 @@ export default { }) ) { windShieldOptions.selectedWindshieldDamageType = - damageLocationsSelected.REPLACE; + damageLocationsSelected.REPLACE; windShieldOptions.selectedWindshieldReplaceOptions.push( damageLocationsSelected.DRIVER ); @@ -265,7 +265,7 @@ export default { }) ) { windShieldOptions.selectedWindshieldDamageType = - damageLocationsSelected.REPLACE; + damageLocationsSelected.REPLACE; windShieldOptions.selectedWindshieldReplaceOptions.push( damageLocationsSelected.PASSENGER ); @@ -335,7 +335,7 @@ export default { isWindshieldRepair: this.isWindshieldRepair, selectedGlassToReplace: this.selectedGlassToReplace(), selectedWindshieldChipCount: - this.selectedWindshieldOptions.selectedWindshieldChipCount, + this.selectedWindshieldOptions.selectedWindshieldChipCount, }, false ); @@ -358,9 +358,9 @@ export default { const payment = this.$store.getters.payment; const vehicleChangedDuringPolicyLookupInHeritage = - payment.isInsurance && - payment.insuranceCoverage.coverageStatus && - payment.insuranceCoverage.coverageStatus !== ""; + payment.isInsurance && + payment.insuranceCoverage.coverageStatus && + payment.insuranceCoverage.coverageStatus !== ""; if (vehicleChangedDuringPolicyLookupInHeritage) { if (store.getters.damage.isRepair) { this.$router.navigateWithSaving( @@ -370,7 +370,7 @@ export default { } else { this.$router.navigateWithSaving( this.navigationScenarios - .CLICKED_FORWARD_WITH_REPLACE_AND_VERIFIED_INSURANCE, + .CLICKED_FORWARD_WITH_REPLACE_AND_VERIFIED_INSURANCE, this.$route ); } @@ -452,7 +452,7 @@ export default { return ( this.isWindshieldDamageLocation && this.selectedWindshieldOptions.selectedWindshieldDamageType === - damageLocationsSelected.REPAIR + damageLocationsSelected.REPAIR ); }, isDriverSideReplace() { @@ -480,10 +480,10 @@ export default { if ( !this.selectedDamageLocations?.includes("Windshield") || this.selectedWindshieldOptions.selectedWindshieldDamageType === - damageLocationsSelected.REPAIR || + damageLocationsSelected.REPAIR || !this.selectedWindshieldOptions.selectedWindshieldReplaceOptions ) - return false; + return false; return ( this.selectedWindshieldOptions.selectedWindshieldReplaceOptions?.some( @@ -502,14 +502,14 @@ export default { ); } ) || - this.selectedWindshieldOptions.selectedWindshieldReplaceOptions?.some( - (selectedPassengerWindshield) => { - return ( - selectedPassengerWindshield.toUpperCase() === - damageLocationsSelected.PASSENGER.toUpperCase() - ); - } - )) + this.selectedWindshieldOptions.selectedWindshieldReplaceOptions?.some( + (selectedPassengerWindshield) => { + return ( + selectedPassengerWindshield.toUpperCase() === + damageLocationsSelected.PASSENGER.toUpperCase() + ); + } + )) ); }, shouldDisplayVehicleChangeAlert() { From 5ff14add7bbaa0a815737b28411ea6fb30dd0179 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Tue, 19 Sep 2023 12:22:56 -0400 Subject: [PATCH 30/73] Lookup Pages --- src/helpers/damage-helper.js | 7 ++--- src/helpers/damage-helper.spec.js | 11 ++++++-- src/helpers/unit-test-helper.js | 21 +++++++++++++++ .../address-lookup/address-lookup.spec.js | 13 +++++++--- src/layouts/address-lookup/address-lookup.vue | 26 +++++++++++++------ .../address-vehicles/address-vehicles.vue | 13 +++++++--- .../license-plate-lookup.spec.js | 14 +++++----- .../license-plate-lookup.vue | 21 ++++++++++----- src/layouts/vin-lookup/vin-lookup.vue | 14 +++++++--- src/mixins/base-mixin.js | 7 +++-- src/store/index.js | 25 ++++++++++++++---- src/store/store.spec.js | 19 +++++++++++--- 12 files changed, 141 insertions(+), 50 deletions(-) diff --git a/src/helpers/damage-helper.js b/src/helpers/damage-helper.js index 727825d9d..13defa5df 100644 --- a/src/helpers/damage-helper.js +++ b/src/helpers/damage-helper.js @@ -54,10 +54,11 @@ export function includesWindshieldReplacement() { return windshieldMatches.length > 0; } -export async function isGlassAvailableForCarId(carId) { - const newGlassOptions = await baseMixin.methods.dispatchStoreAction( +export async function isGlassAvailableForCarId(carId, pageNameToLog) { + const newGlassOptions = await baseMixin.methods.dispatchStoreActionWithLogging( storeActions.GET_DAMAGE_OPTIONS, - { carId: carId } + { carId: carId }, + pageNameToLog ); const currentGlassOptions = store.getters.damage.glassToReplace; diff --git a/src/helpers/damage-helper.spec.js b/src/helpers/damage-helper.spec.js index 73215b9c7..1b4bd9261 100644 --- a/src/helpers/damage-helper.spec.js +++ b/src/helpers/damage-helper.spec.js @@ -11,6 +11,13 @@ jest.mock("@/mixins/base-mixin.js", () => ({ }, }; }), + dispatchStoreActionWithLogging: jest.fn().mockImplementation(() => { + return { + data: { + windshieldOptions: { availableReplacementOptions: ["windshield"] }, + }, + }; + }), }, })); @@ -77,7 +84,7 @@ describe("damage-helper.js", () => { ]; // Act - const isGlassAvailable = await isGlassAvailableForCarId(); + const isGlassAvailable = await isGlassAvailableForCarId("id", "testName"); // Assert expect(isGlassAvailable).toEqual(true); @@ -91,7 +98,7 @@ describe("damage-helper.js", () => { { glassLocation: "Windshield", glassName: "sideWindow" }, ]; - const isGlassAvailable = await isGlassAvailableForCarId(); + const isGlassAvailable = await isGlassAvailableForCarId("id", "testName"); // Assert expect(isGlassAvailable).toEqual(false); diff --git a/src/helpers/unit-test-helper.js b/src/helpers/unit-test-helper.js index 1210f119c..467b38c2b 100644 --- a/src/helpers/unit-test-helper.js +++ b/src/helpers/unit-test-helper.js @@ -44,6 +44,16 @@ export function getMountOptions(mockData) { }); } }); + mocks.dispatchStoreActionWithLogging = jest.fn(); + mocks.dispatchStoreActionWithLogging.mockImplementation((actionName) => { + let actionFilterResult = mockData.actionList?.filter((x) => x.actionName == actionName); + + if (actionFilterResult?.length === 1) { + return Promise.resolve({ + data: actionFilterResult[0].data, + }); + } + }); // Mock const files mocks.storeActions = storeActions; @@ -141,5 +151,16 @@ function setupBaseMixinDispatchStoreAction(mockData) { }); } }); + + baseMixin.methods.dispatchStoreActionWithLogging = jest.fn(); + baseMixin.methods.dispatchStoreActionWithLogging.mockImplementation((actionName) => { + let actionFilterResult = mockData.actionList.filter((x) => x.actionName == actionName); + + if (actionFilterResult.length > 0 && actionFilterResult.length === 1) { + return Promise.resolve({ + data: actionFilterResult[0].data, + }); + } + }); } } diff --git a/src/layouts/address-lookup/address-lookup.spec.js b/src/layouts/address-lookup/address-lookup.spec.js index 63847588b..624fb175b 100644 --- a/src/layouts/address-lookup/address-lookup.spec.js +++ b/src/layouts/address-lookup/address-lookup.spec.js @@ -471,7 +471,7 @@ describe("address-lookup.vue", () => { await wrapper.vm.forwardButtonAction(); // Assert - expect(wrapper.vm.dispatchStoreAction).toHaveBeenCalledWith( + expect(wrapper.vm.dispatchStoreActionWithLogging).toHaveBeenCalledWith( "lookupVinByAddress", { licenseLastName: undefined, @@ -479,12 +479,17 @@ describe("address-lookup.vue", () => { licenseStreetAddress: "1234 Main St", licenseZip: "43215", }, + "address-lookup", false ); - expect(wrapper.vm.dispatchStoreAction).toHaveBeenCalledWith("validateZip", { - zip: "43215", - }); + expect(wrapper.vm.dispatchStoreActionWithLogging).toHaveBeenCalledWith( + "validateZip", + { + zip: "43215", + }, + "address-lookup" + ); }); }); diff --git a/src/layouts/address-lookup/address-lookup.vue b/src/layouts/address-lookup/address-lookup.vue index f0bf91325..b95be8e83 100644 --- a/src/layouts/address-lookup/address-lookup.vue +++ b/src/layouts/address-lookup/address-lookup.vue @@ -207,7 +207,7 @@ export default { // Vehicle info change in the flow, use a variable to keep track and commit to state at the end. let vehicleInfoToCommit = {}; - const vinLookupResponse = this.dispatchStoreAction( + const vinLookupResponse = this.dispatchStoreActionWithLogging( storeActions.LOOKUP_VIN_BY_ADDRESS, { licenseLastName: this.customerQuestions.lastName, @@ -215,6 +215,7 @@ export default { licenseZip: this.customerQuestions.addressQuestions.zipCode, licenseState: this.customerQuestions.addressQuestions.state, }, + "address-lookup", false ); @@ -227,12 +228,20 @@ export default { { resultKey: "serviceZipValidationResponse", promise: this.serviceZipCode - ? this.dispatchStoreAction(storeActions.VALIDATE_ZIP, { - zip: this.serviceZipCode, - }) - : this.dispatchStoreAction(storeActions.VALIDATE_ZIP, { - zip: this.customerQuestions.addressQuestions.zipCode, - }), + ? this.dispatchStoreActionWithLogging( + storeActions.VALIDATE_ZIP, + { + zip: this.serviceZipCode, + }, + "address-lookup" + ) + : this.dispatchStoreActionWithLogging( + storeActions.VALIDATE_ZIP, + { + zip: this.customerQuestions.addressQuestions.zipCode, + }, + "address-lookup" + ), }, ]; @@ -267,7 +276,8 @@ export default { this.displayMatchedDifferentVehicleAlert = true; this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId( - carFound.carId + carFound.carId, + "address-lookup" ); // Update button "Continue with..." diff --git a/src/layouts/address-vehicles/address-vehicles.vue b/src/layouts/address-vehicles/address-vehicles.vue index de1fa9999..f7af34ec9 100644 --- a/src/layouts/address-vehicles/address-vehicles.vue +++ b/src/layouts/address-vehicles/address-vehicles.vue @@ -162,9 +162,13 @@ export default { this.$router.navigateWithoutSaving(this.navigationScenarios.CLICKED_BACK, this.$route); }, async forwardButtonAction() { - const vinLookup = await this.dispatchStoreAction(storeActions.LOOKUP_VEHICLE_BY_VIN, { - vin: this.selectedVehicle.vin, - }).catch(() => { + const vinLookup = await this.dispatchStoreActionWithLogging( + storeActions.LOOKUP_VEHICLE_BY_VIN, + { + vin: this.selectedVehicle.vin, + }, + "address-vehicles" + ).catch(() => { this.$refs.funnelFooter.removeLoader(); }); @@ -173,7 +177,8 @@ export default { } this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId( - vinLookup.data.carId + vinLookup.data.carId, + "address-vehicles" ); await this.dispatchStoreAction( diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.spec.js b/src/layouts/license-plate-lookup/license-plate-lookup.spec.js index bf5751637..2fa11b776 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.spec.js +++ b/src/layouts/license-plate-lookup/license-plate-lookup.spec.js @@ -120,7 +120,7 @@ describe("license-plate-lookup.vue", () => { wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => ""); wrapper.vm.navigateForward = jest.fn(); - wrapper.vm.dispatchStoreAction = jest.fn().mockImplementation(() => + wrapper.vm.dispatchStoreActionWithLogging = jest.fn().mockImplementation(() => Promise.resolve({ data: { vehicle: { @@ -157,7 +157,7 @@ describe("license-plate-lookup.vue", () => { }); // Mock store action call - wrapper.vm.dispatchStoreAction = jest.fn().mockImplementation(() => + wrapper.vm.dispatchStoreActionWithLogging = jest.fn().mockImplementation(() => Promise.resolve({ data: { vehicle: { @@ -201,7 +201,7 @@ describe("license-plate-lookup.vue", () => { wrapper.vm.navigateForward = jest.fn(); // Mock store action call - wrapper.vm.dispatchStoreAction = jest.fn().mockImplementation(() => + wrapper.vm.dispatchStoreActionWithLogging = jest.fn().mockImplementation(() => Promise.resolve({ data: { vehicle: { @@ -242,7 +242,7 @@ describe("license-plate-lookup.vue", () => { wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => { return ""; }); - wrapper.vm.dispatchStoreAction = jest.fn(); + wrapper.vm.dispatchStoreActionWithLogging = jest.fn(); await wrapper.vm.navigateForward(); @@ -379,7 +379,7 @@ describe("license-plate-lookup.vue", () => { return { data: { vehicle: { carId: "C00000" } } }; }); - wrapper.vm.dispatchStoreAction = jest.fn().mockImplementation(() => + wrapper.vm.dispatchStoreActionWithLogging = jest.fn().mockImplementation(() => Promise.resolve({ data: { vehicle: { @@ -417,7 +417,7 @@ describe("license-plate-lookup.vue", () => { await wrapper.setData({ registrationZip: "00000" }); navigateToHeritage.navigateToHeritageFunnel = jest.fn(); - wrapper.vm.dispatchStoreAction = jest.fn().mockImplementation(() => + wrapper.vm.dispatchStoreActionWithLogging = jest.fn().mockImplementation(() => Promise.resolve({ data: { vehicle: { @@ -449,7 +449,7 @@ describe("license-plate-lookup.vue", () => { await wrapper.setData({ registrationZipCode: "00000" }); navigateToHeritage.navigateToHeritageFunnel = jest.fn(); - wrapper.vm.dispatchStoreAction = jest.fn().mockImplementation(() => + wrapper.vm.dispatchStoreActionWithLogging = jest.fn().mockImplementation(() => Promise.resolve({ data: { vehicle: { diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.vue b/src/layouts/license-plate-lookup/license-plate-lookup.vue index 326215243..abd49c91a 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.vue +++ b/src/layouts/license-plate-lookup/license-plate-lookup.vue @@ -199,9 +199,10 @@ export default { async forwardButtonAction() { this.resetWarningsAndErrors(); - const registrationZipValidationResponse = this.dispatchStoreAction( + const registrationZipValidationResponse = this.dispatchStoreActionWithLogging( storeActions.VALIDATE_ZIP, - { zip: this.registrationZipCode } + { zip: this.registrationZipCode }, + "license-plate-lookup" ); // Settle promises and get results @@ -214,9 +215,13 @@ export default { // If serviceZipCode is not set, then sets the response to the registrationZipValidationResponse. Calls VALIDATE_ZIP if the serviceZipCode is set. resultKey: "serviceZipValidationResponse", promise: this.serviceZipCode - ? this.dispatchStoreAction(storeActions.VALIDATE_ZIP, { - zip: this.serviceZipCode, - }) + ? this.dispatchStoreActionWithLogging( + storeActions.VALIDATE_ZIP, + { + zip: this.serviceZipCode, + }, + "license-plate-lookup" + ) : registrationZipValidationResponse, }, ]; @@ -260,7 +265,8 @@ export default { this.displayMatchedDifferentVehicleAlert = true; this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId( - vinLookup.data.vehicle.carId + vinLookup.data.vehicle.carId, + "license-plate-lookup" ); // Update button "Continue with..." @@ -312,9 +318,10 @@ export default { return await this.navigateForward(); }, lookupVin(plate, state) { - return this.dispatchStoreAction( + return this.dispatchStoreActionWithLogging( storeActions.LOOKUP_VIN_BY_PLATE, { licensePlate: plate, licenseState: state }, + "license-plate-lookup", false ); }, diff --git a/src/layouts/vin-lookup/vin-lookup.vue b/src/layouts/vin-lookup/vin-lookup.vue index c0b1f1788..3103ac4e1 100644 --- a/src/layouts/vin-lookup/vin-lookup.vue +++ b/src/layouts/vin-lookup/vin-lookup.vue @@ -255,9 +255,10 @@ export default { // If this is a new VIN Lookup, do both a Vehicle Lookup and a Zip Validation if (!this.vinPopulatedOnPageLoad) { - const vehicleLookupResponse = this.dispatchStoreAction( + const vehicleLookupResponse = this.dispatchStoreActionWithLogging( storeActions.LOOKUP_VEHICLE_BY_VIN, - { vin: this.vin } + { vin: this.vin }, + "vin-lookup" ); // Settle promises and get results @@ -311,7 +312,8 @@ export default { this.displayMatchedDifferentVehicleAlert = true; this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId( - resultMap.vehicleLookupResponse.carId + resultMap.vehicleLookupResponse.carId, + "vin-lookup" ); // Update button "Continue with..." @@ -399,7 +401,11 @@ export default { }, getVinFromImage(image) { return new Promise((resolve, reject) => { - this.dispatchStoreAction(storeActions.LOOKUP_VIN_BY_IMAGE, image) + this.dispatchStoreActionWithLogging( + storeActions.LOOKUP_VIN_BY_IMAGE, + image, + "vin-lookup" + ) .then((response) => { if (response.data.length > 0) { resolve(response.data[0]); diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js index 6ad522fc8..c38836dfb 100644 --- a/src/mixins/base-mixin.js +++ b/src/mixins/base-mixin.js @@ -64,9 +64,12 @@ export default { return footerInfoBox ? footerInfoBox.offsetHeight : 0; }, async getZipCodeData(zipCode) { - const serviceZipValidationResponse = await this.dispatchStoreAction( + const pageName = this.$options?.name; + + const serviceZipValidationResponse = await this.dispatchStoreActionWithLogging( storeActions.VALIDATE_ZIP, - { zip: zipCode } + { zip: zipCode }, + pageName ); return { diff --git a/src/store/index.js b/src/store/index.js index 87c6b95cd..a8cfe77fd 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -661,17 +661,19 @@ export const actions = { }); }, - lookupVehicleByVin(context, { vin }) { + lookupVehicleByVin(context, { payload: { vin }, pageNameToLog }) { return globalMethods.callHttpClient({ method: endpoints.LookupVehicleByVin.method, endpoint: endpoints.LookupVehicleByVin.url, payload: { vin: vin, // EX "1J4GW58S4XC541166" }, + logApiCall: true, + pageNameToLog: pageNameToLog, }); }, - lookupVinByPlate(context, { licensePlate, licenseState }) { + lookupVinByPlate(context, { payload: { licensePlate, licenseState }, pageNameToLog }) { return globalMethods.callHttpClient({ method: endpoints.LookupVinByPlate.method, endpoint: endpoints.LookupVinByPlate.url, @@ -679,12 +681,17 @@ export const actions = { licensePlate: licensePlate, licenseState: licenseState, }, + logApiCall: true, + pageNameToLog: pageNameToLog, }); }, lookupVinByAddress( context, - { licenseLastName, licenseStreetAddress, licenseZip, licenseState } + { + payload: { licenseLastName, licenseStreetAddress, licenseZip, licenseState }, + pageNameToLog, + } ) { return globalMethods.callHttpClient({ method: endpoints.LookupVinByAddress.method, @@ -695,10 +702,14 @@ export const actions = { licenseZip: licenseZip, licenseState: licenseState, }, + logApiCall: true, + pageNameToLog: pageNameToLog, }); }, - lookupVinByImage(context, image) { + lookupVinByImage(context, { payload, pageNameToLog }) { + const image = payload; + return new Promise((resolve, reject) => { let reader = new FileReader(); reader.onload = (e) => { @@ -720,6 +731,8 @@ export const actions = { method: endpoints.LookupVinByImage.method, endpoint: endpoints.LookupVinByImage.url, payload: data, + logApiCall: true, + pageNameToLog: pageNameToLog, }); }); }, @@ -790,10 +803,12 @@ export const actions = { }); }, - validateZip(context, { zip }) { + validateZip(context, { payload: { zip }, pageNameToLog }) { return globalMethods.callHttpClient({ methods: endpoints.ValidateZip.method, endpoint: `${endpoints.ValidateZip.url}/${zip}`, + logApiCall: true, + pageNameToLog: pageNameToLog, }); }, diff --git a/src/store/store.spec.js b/src/store/store.spec.js index 75ebacc51..a0491f47c 100644 --- a/src/store/store.spec.js +++ b/src/store/store.spec.js @@ -428,7 +428,10 @@ describe("Actions", () => { }); // Assert - const response = await actions.lookupVinByPlate(context, "12345678901234567"); + const response = await actions.lookupVinByPlate(context, { + payload: { licensePlate: "12345678901234567", licenseState: "OH" }, + pageNameToLog: "test", + }); expect(response.data).toEqual({ carId: "C00000001" }); }); @@ -445,7 +448,10 @@ describe("Actions", () => { }); // Act - const response = await actions.lookupVinByImage(context, image); + const response = await actions.lookupVinByImage(context, { + payload: image, + pageNameToLog: "test", + }); // Assert expect(response.data).toEqual(["1C6JJTAG3NL134044"]); @@ -465,7 +471,9 @@ describe("Actions", () => { // Act // Assert - await expect(actions.lookupVinByImage(context, image)).rejects.toEqual("An error occurred"); + await expect( + actions.lookupVinByImage(context, { payload: image, pageNameToLog: "test" }) + ).rejects.toEqual("An error occurred"); }); it("getVehicleMakes action, should return makes list", async () => { @@ -574,7 +582,10 @@ describe("Actions", () => { }); }); - const response = await actions.validateZip(context, "43212"); + const response = await actions.validateZip(context, { + payload: { zip: "43212" }, + pageNameToLog: "test", + }); // Assert expect(response.data).toEqual({ From e4d98521d8cbb9155e0d25e45fb9fb4e470b9d77 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Tue, 19 Sep 2023 12:49:51 -0400 Subject: [PATCH 31/73] Test fix --- src/mixins/base-mixin.spec.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mixins/base-mixin.spec.js b/src/mixins/base-mixin.spec.js index b768b67d5..2ef76315e 100644 --- a/src/mixins/base-mixin.spec.js +++ b/src/mixins/base-mixin.spec.js @@ -101,8 +101,8 @@ describe("baseMixin.js", () => { test("getZipCodeData calls dispatch", () => { const mixIn = getMixInInstance({}); - mixIn.methods.dispatchStoreAction = jest.fn(); - mixIn.methods.dispatchStoreAction.mockReturnValue({ + mixIn.methods.dispatchStoreActionWithLogging = jest.fn(); + mixIn.methods.dispatchStoreActionWithLogging.mockReturnValue({ data: { isValid: true, isServiceable: true, state: "OH" }, }); const type = ""; @@ -118,7 +118,7 @@ describe("baseMixin.js", () => { mixIn.methods.getZipCodeData(type, payload); - expect(mixIn.methods.dispatchStoreAction).toBeCalled(); + expect(mixIn.methods.dispatchStoreActionWithLogging).toBeCalled(); }); }); From 7aa61e89982438931a984e00e8bca2ce8bbe740f Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Tue, 19 Sep 2023 12:50:09 -0400 Subject: [PATCH 32/73] Runexperiments --- src/router/index.js | 28 ++++++++++++++++++---------- src/store/index.js | 7 ++++++- src/store/store.spec.js | 10 ++++++++-- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/router/index.js b/src/router/index.js index e8fbf4d26..b49b38d9f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -394,18 +394,26 @@ function arePagePrerequisitesValid(component) { // Run SiteEntry and PageEntry triggers for experiments async function runExperiments(nextPage) { if (!store.getters.applicationUser.triggeredSiteEntry) { - await baseMixin.methods.dispatchStoreAction(storeActions.RUN_EXPERIMENTS_FOR_TRIGGER, { - userId: getDeviceIdValue(), - triggerEvent: experimentTriggers.SITE_ENTRY, - triggerValue: applicationConfig.SITE_ENTRY_TRIGGER_VALUE, - }); + await baseMixin.methods.dispatchStoreActionWithLogging( + storeActions.RUN_EXPERIMENTS_FOR_TRIGGER, + { + userId: getDeviceIdValue(), + triggerEvent: experimentTriggers.SITE_ENTRY, + triggerValue: applicationConfig.SITE_ENTRY_TRIGGER_VALUE, + }, + nextPage + ); } - await baseMixin.methods.dispatchStoreAction(storeActions.RUN_EXPERIMENTS_FOR_TRIGGER, { - userId: getDeviceIdValue(), - triggerEvent: experimentTriggers.PAGE_ENTRY, - triggerValue: nextPage, - }); + await baseMixin.methods.dispatchStoreActionWithLogging( + storeActions.RUN_EXPERIMENTS_FOR_TRIGGER, + { + userId: getDeviceIdValue(), + triggerEvent: experimentTriggers.PAGE_ENTRY, + triggerValue: nextPage, + }, + nextPage + ); } export default router; diff --git a/src/store/index.js b/src/store/index.js index a8cfe77fd..50124bee7 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1083,7 +1083,10 @@ export const actions = { }); }, - async runExperimentsForTrigger(context, { userId, triggerEvent, triggerValue }) { + async runExperimentsForTrigger( + context, + { payload: { userId, triggerEvent, triggerValue }, pageNameToLog } + ) { if (triggerEvent == experimentTriggers.SITE_ENTRY) { context.commit(storeMutations.UPDATE_TRIGGERED_SITE_ENTRY, true); } @@ -1100,6 +1103,8 @@ export const actions = { method: endpoints.RunExperimentsForTrigger.method, endpoint: endpoints.RunExperimentsForTrigger.url, payload: payload, + logApiCall: true, + pageNameToLog: pageNameToLog, }); context.commit(storeMutations.UPDATE_EXPERIMENTS, response.data.experiments); diff --git a/src/store/store.spec.js b/src/store/store.spec.js index a0491f47c..611341aa7 100644 --- a/src/store/store.spec.js +++ b/src/store/store.spec.js @@ -1751,7 +1751,10 @@ describe("Actions", () => { // Act await actions.runExperimentsForTrigger(context, { - triggerEvent: experimentTriggers.SITE_ENTRY, + payload: { + triggerEvent: experimentTriggers.SITE_ENTRY, + }, + pageNameToLog: "test", }); // Assert @@ -1785,7 +1788,10 @@ describe("Actions", () => { // Act await actions.runExperimentsForTrigger(context, { - triggerEvent: "NotSiteEntry", + payload: { + triggerEvent: "NotSiteEntry", + }, + pageNameToLog: "test", }); // Assert From c5162483f423213aed030c0f62ddd401f1f4f10a Mon Sep 17 00:00:00 2001 From: Bryan Mauger Date: Tue, 19 Sep 2023 14:33:44 -0400 Subject: [PATCH 33/73] WIP grid and style updates. --- src/layouts/address-lookup/address-lookup.vue | 6 ++---- .../customer-details/customer-details.vue | 6 ++---- src/layouts/estimate/estimate.vue | 6 ++---- .../license-plate-lookup.vue | 6 ++---- src/layouts/quote/quote.vue | 6 ++---- src/layouts/review/review.vue | 6 ++---- src/layouts/schedule/schedule.vue | 6 ++---- .../service-location/service-location.vue | 6 ++---- src/layouts/vehicle-damage/vehicle-damage.vue | 16 ++++++++++++---- src/layouts/vehicle-parts/vehicle-parts.vue | 16 ++++++++++++---- src/layouts/vehicle/vehicle.vue | 6 ++---- src/layouts/vin-lookup/vin-lookup.vue | 6 ++---- 12 files changed, 44 insertions(+), 48 deletions(-) diff --git a/src/layouts/address-lookup/address-lookup.vue b/src/layouts/address-lookup/address-lookup.vue index faae41388..34b111d15 100644 --- a/src/layouts/address-lookup/address-lookup.vue +++ b/src/layouts/address-lookup/address-lookup.vue @@ -7,9 +7,8 @@ -
-
 
-
+
+
-
 
diff --git a/src/layouts/customer-details/customer-details.vue b/src/layouts/customer-details/customer-details.vue index ebdd4c7a6..03de9ff97 100644 --- a/src/layouts/customer-details/customer-details.vue +++ b/src/layouts/customer-details/customer-details.vue @@ -6,9 +6,8 @@
-
-
 
-
+
+
-
 
diff --git a/src/layouts/estimate/estimate.vue b/src/layouts/estimate/estimate.vue index d6308f444..f27f833a0 100644 --- a/src/layouts/estimate/estimate.vue +++ b/src/layouts/estimate/estimate.vue @@ -7,9 +7,8 @@
-
-
 
-
+
+
@@ -80,7 +79,6 @@ @ForwardClicked="forwardButtonAction" />
-
 
diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.vue b/src/layouts/license-plate-lookup/license-plate-lookup.vue index c9e3d248e..31ca3fec7 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.vue +++ b/src/layouts/license-plate-lookup/license-plate-lookup.vue @@ -6,9 +6,8 @@
-
-
 
-
+
+
@@ -85,7 +84,6 @@ @back-clicked="backButtonAction" @ForwardClicked="forwardButtonAction" />
-
 
diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue index 357bd7c14..46f573144 100644 --- a/src/layouts/quote/quote.vue +++ b/src/layouts/quote/quote.vue @@ -7,9 +7,8 @@
-
-
 
-
+
+
@@ -52,7 +51,6 @@ @back-clicked="backButtonAction" @ForwardClicked="forwardButtonAction" />
-
 
diff --git a/src/layouts/review/review.vue b/src/layouts/review/review.vue index c7112fb00..639fd0fd5 100644 --- a/src/layouts/review/review.vue +++ b/src/layouts/review/review.vue @@ -7,9 +7,8 @@
-
-
 
-
+
+
@@ -101,7 +100,6 @@ @back-clicked="backButtonAction" @ForwardClicked="forwardButtonAction" />
-
 
diff --git a/src/layouts/schedule/schedule.vue b/src/layouts/schedule/schedule.vue index 59d8e932a..f276ea1cd 100644 --- a/src/layouts/schedule/schedule.vue +++ b/src/layouts/schedule/schedule.vue @@ -7,9 +7,8 @@
-
-
 
-
+
+