diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js index ebffdebde..392e7b59e 100644 --- a/src/constants/store-actions.js +++ b/src/constants/store-actions.js @@ -54,6 +54,7 @@ const storeActions = { RESET_DAMAGE_STATE_AND_DEPENDENCIES: "resetDamageAndDependencies", RESET_REGISTRATION_STATE_AND_DEPENDENCIES: "resetRegistrationAndDependencies", RESET_PARTS_STATE_AND_DEPENDENCIES: "resetPartsAndDependencies", + RESET_SERVICE_LOCATION_STATE_AND_DEPENDENCIES: "resetServiceLocationAndDependencies", RESET_STATE: "resetState", // SAVE COMPONENT STATE diff --git a/src/fmg-components/funnel-header/menu-modal/menu-modal.vue b/src/fmg-components/funnel-header/menu-modal/menu-modal.vue index 55ff95c48..72fef029b 100644 --- a/src/fmg-components/funnel-header/menu-modal/menu-modal.vue +++ b/src/fmg-components/funnel-header/menu-modal/menu-modal.vue @@ -21,6 +21,19 @@ aria-hidden="true" v-on="{ 'show.bs.modal': show, 'hide.bs.modal': hide }" :style="`height: calc(100% - ${currentFooterAndHeaderHeight}px);`"> +
- Finding shops near you + Tidying up the shop . . .
- Looking for dates + Getting all the glass shined up . . .
- Searching for times + Planning your new view of the road . . . @@ -164,19 +164,19 @@ export default { transform: translateX(-600px); } 55% { - transform: translateX(-1110px); + transform: translateX(-1195px); } 66% { - transform: translateX(-1110px); + transform: translateX(-1195px); } 77% { - transform: translateX(-1600px); + transform: translateX(-1750px); } 88% { - transform: translateX(-1600px); + transform: translateX(-1750px); } 100% { - transform: translateX(-2050px); + transform: translateX(-2200px); } } diff --git a/src/global-methods.js b/src/global-methods.js index 45bbc467c..756b58dc8 100644 --- a/src/global-methods.js +++ b/src/global-methods.js @@ -1,13 +1,21 @@ import axios from "axios"; import analyticsMixIn from "@/mixins/analytics-mixin.js"; import store from "@/store"; +import router from "@/router"; import { applicationConfig } from "@/constants/application-config.js"; import { GaCategories, GaActions, GaLabels } from "@/constants/analytics"; import { headerKeys } from "@/constants/header-keys"; export default { - callHttpClient({ method, endpoint, payload, logApiCall = true, isFormData = false }) { + callHttpClient({ + method, + endpoint, + payload, + logApiCall = true, + isFormData = false, + additionalSuccessEventDataHandler, + }) { return new Promise((resolve, reject) => { const cfDistroUrl = applicationConfig.CONSUMER_CF_DISTRO; let payloadAndAnalyticsData = {}; @@ -31,10 +39,16 @@ export default { }).then( (response) => { if (logApiCall) { + let additionalEventData = ""; + if (additionalSuccessEventDataHandler) { + additionalEventData = "_" + additionalSuccessEventDataHandler(response); + } + const pageName = analyticsMixIn.methods.getPageName(); + const nextPageName = router.getNextPage() || pageName; analyticsMixIn.methods.pushEventToGA( GaCategories.API_RESPONSE, - GaActions.RESULT, - `${GaLabels.SUCCESS}_${endpoint}`, + `${nextPageName}_${endpoint}`, + `${GaLabels.SUCCESS}${additionalEventData}`, true ); } diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index 29eb76c3d..75f22edcb 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -23,6 +23,10 @@ import { applicationConfig } from "../constants/application-config"; export default { methods: { + getPageName() { + return getPageNameByQueryString(); + }, + logPageView(pageEvent) { const currentPageName = getPageNameByQueryString(); var payload = { diff --git a/src/router/index.js b/src/router/index.js index 15ba52647..1d410c3cb 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -222,6 +222,12 @@ router.overrideNavigation = ( next(); }; +router.getNextPage = () => nextPageName; + +// PRIVATE VARIABLES + +var nextPageName; + // PRIVATE FUNCTIONS // Navigate to the next route, depending on the scenario. @@ -245,6 +251,8 @@ async function navigate( if (destinationFmgPageValue !== undefined) { // We're always pushing the same path, just changing query strings. Make sure our optional query strings get combined with our fmgPage one. + nextPageName = destinationFmgPageValue; + // Update page data to the store for next page if provided. Otherwise, keep existing page data or set to empty object const existingPageDataForPage = store.getters.pageData(destinationFmgPageValue); baseMixin.methods.savePageDataToStore( diff --git a/src/store/index.js b/src/store/index.js index eac829543..6c95aa81b 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -341,14 +341,14 @@ export const mutations = { state.order.schedule.routeCode = null; state.order.schedule.jobMaxMinutes = null; - //early bird fee used on schedule page also needs reset when schedule is reset + //premium appointment fee used on schedule page also needs reset when schedule is reset const supportingItems = state.order.lineItems.supportingItems; - const removeEarlyBirdIndex = supportingItems?.findIndex( + const premiumAppointmentFeeIndex = supportingItems?.findIndex( (item) => item.partType == PREMIUM_FEE_PART_TYPE ); - if (removeEarlyBirdIndex >= 0) { - supportingItems.splice(removeEarlyBirdIndex, 1); + if (premiumAppointmentFeeIndex >= 0) { + supportingItems.splice(premiumAppointmentFeeIndex, 1); state.order.lineItems.supportingItems = supportingItems; } }, @@ -369,7 +369,6 @@ export const mutations = { state.order.serviceLocation.address2 = null; state.order.serviceLocation.city = null; state.order.serviceLocation.state = null; - state.order.serviceLocation.zipCode = null; state.order.serviceLocation.isVehicleProtected = null; }, // Misc Mutations @@ -712,20 +711,30 @@ export const actions = { // Dependency Actions resetDamageAndDependencies(context) { context.commit(storeMutations.RESET_DAMAGE_STATE); - context.commit(storeMutations.RESET_GLASS_PARTS_STATE); - context.commit(storeMutations.UPDATE_SUPPORTING_ITEMS, null); + + context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES); + context.commit(storeMutations.UPDATE_VAPS, null); }, resetRegistrationAndDependencies(context) { context.commit(storeMutations.RESET_REGISTRATION_STATE); - context.commit(storeMutations.RESET_GLASS_PARTS_STATE); - context.commit(storeMutations.UPDATE_SUPPORTING_ITEMS, null); + + context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES); }, resetPartsAndDependencies(context) { context.commit(storeMutations.RESET_GLASS_PARTS_STATE); context.commit(storeMutations.UPDATE_SUPPORTING_ITEMS, null); + + context.dispatch(storeActions.RESET_SERVICE_LOCATION_STATE_AND_DEPENDENCIES); + }, + + resetServiceLocationAndDependencies(context) { + context.commit(storeMutations.RESET_SERVICE_LOCATION_APPOINTMENT_TYPE); + context.commit(storeMutations.RESET_SERVICE_LOCATION_PROVIDER); + + context.commit(storeMutations.RESET_SCHEDULE); }, resetState(context) { @@ -1382,6 +1391,8 @@ export const actions = { eon: order.eon, }, }, + additionalSuccessEventDataHandler: (response) => + "Email provided: " + (order.customer.emailAddress ? "true" : "false"), }); }, @@ -1597,7 +1608,6 @@ export const actions = { if (!isSelectedGlassAvailableForVehicle) { context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES); - context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES); } //Save new values @@ -1623,7 +1633,6 @@ export const actions = { if (!isSelectedGlassAvailableForVehicle) { context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES); - context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES); } //Save new values @@ -1649,6 +1658,8 @@ export const actions = { ); if (havePartQuestionAnswersChanged) { + context.dispatch(storeActions.RESET_SERVICE_LOCATION_STATE_AND_DEPENDENCIES); + context.commit(storeMutations.UPDATE_GLASS_PARTS, null); context.commit(storeMutations.UPDATE_SUPPORTING_ITEMS, null); context.commit(storeMutations.UPDATE_MOLDING_QUESTION_ANSWERS, null); @@ -1696,6 +1707,8 @@ export const actions = { previouslySelectedPartNumbers !== currentlySelectedPartNumbers; if (haveSelectedVehiclePartsChanged) { + context.dispatch(storeActions.RESET_SERVICE_LOCATION_STATE_AND_DEPENDENCIES); + context.commit(storeMutations.UPDATE_GLASS_PARTS, null); context.commit(storeMutations.UPDATE_SUPPORTING_ITEMS, null); context.commit(storeMutations.UPDATE_MOLDING_QUESTION_ANSWERS, null); @@ -1727,6 +1740,8 @@ export const actions = { ); if (haveMoldingQuestionAnswersChanged) { + context.dispatch(storeActions.RESET_SERVICE_LOCATION_STATE_AND_DEPENDENCIES); + context.commit(storeMutations.UPDATE_GLASS_PARTS, null); context.commit(storeMutations.UPDATE_SUPPORTING_ITEMS, null); context.commit(storeMutations.UPDATE_CAPABILITY_QUESTION_ANSWERS, null); @@ -1756,6 +1771,8 @@ export const actions = { ); if (haveCapabilityQuestionAnswersChanged) { + context.dispatch(storeActions.RESET_SERVICE_LOCATION_STATE_AND_DEPENDENCIES); + context.commit(storeMutations.UPDATE_GLASS_PARTS, null); context.commit(storeMutations.UPDATE_SUPPORTING_ITEMS, null); } @@ -1777,8 +1794,7 @@ export const actions = { saveSupportingItems(context, supportingItems) { if (!deepEqual(supportingItems, context.state.order.lineItems.supportingItems)) { - context.commit(storeMutations.RESET_SERVICE_LOCATION_APPOINTMENT_TYPE); - context.commit(storeMutations.RESET_SERVICE_LOCATION_PROVIDER); + context.dispatch(storeActions.RESET_SERVICE_LOCATION_STATE_AND_DEPENDENCIES); } context.commit(storeMutations.UPDATE_SUPPORTING_ITEMS, supportingItems); @@ -1854,8 +1870,8 @@ export const actions = { context.state.order.serviceLocation && serviceZipCodeInfo.zipCode !== context.state.order.serviceLocation.zipCode ) { - context.commit(storeMutations.RESET_SERVICE_LOCATION_APPOINTMENT_TYPE); - context.commit(storeMutations.RESET_SERVICE_LOCATION_PROVIDER); + context.dispatch(storeActions.RESET_SERVICE_LOCATION_STATE_AND_DEPENDENCIES); + context.commit(storeMutations.RESET_SERVICE_LOCATION_MOBILE_ADDRESS); } @@ -1863,6 +1879,20 @@ export const actions = { }, saveServiceLocation(context, serviceLocationInfo) { + if (context.state.order.serviceLocation) { + if ( + serviceLocationInfo.zipCode !== context.state.order.serviceLocation.zipCode || + !deepEqual( + serviceLocationInfo.provider, + context.state.order.serviceLocation.provider + ) || + serviceLocationInfo.appointmentType !== + context.state.order.serviceLocation.appointmentType + ) { + context.commit(storeMutations.RESET_SCHEDULE); + } + } + context.commit(storeMutations.UPDATE_SERVICE_LOCATION, serviceLocationInfo); }, @@ -1875,7 +1905,6 @@ export const actions = { if (vehicleInfo.vin !== context.state.order.vehicle.vin) { if (!isSelectedGlassAvailableForVehicle) { context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES); - context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES); } //Save new values @@ -1885,8 +1914,7 @@ export const actions = { saveGlassParts(context, parts) { if (!deepEqual(parts, context.state.order.lineItems.glassParts)) { - context.commit(storeMutations.RESET_SERVICE_LOCATION_APPOINTMENT_TYPE); - context.commit(storeMutations.RESET_SERVICE_LOCATION_PROVIDER); + context.dispatch(storeActions.RESET_SERVICE_LOCATION_STATE_AND_DEPENDENCIES); } context.commit(storeMutations.UPDATE_GLASS_PARTS, parts); diff --git a/src/store/store.spec.js b/src/store/store.spec.js index 262cb263a..9d9cdfcf4 100644 --- a/src/store/store.spec.js +++ b/src/store/store.spec.js @@ -547,41 +547,48 @@ describe("Actions", () => { // Arrange const context = state; const commit = jest.fn(); + const dispatch = jest.fn(); context.commit = commit; + context.dispatch = dispatch; // Act await actions.resetDamageAndDependencies(context); expect(commit).toBeCalledWith(storeMutations.RESET_DAMAGE_STATE); - expect(commit).toBeCalledWith(storeMutations.RESET_GLASS_PARTS_STATE); + expect(dispatch).toBeCalledWith(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES); }); it("resetRegistrationAndDependencies action", async () => { // Arrange const context = state; const commit = jest.fn(); + const dispatch = jest.fn(); context.commit = commit; + context.dispatch = dispatch; // Act await actions.resetRegistrationAndDependencies(context); expect(commit).toBeCalledWith(storeMutations.RESET_REGISTRATION_STATE); - expect(commit).toBeCalledWith(storeMutations.RESET_GLASS_PARTS_STATE); + expect(dispatch).toBeCalledWith(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES); }); it("resetPartsAndDependencies action", async () => { // Arrange const context = state; const commit = jest.fn(); + const dispatch = jest.fn(); context.commit = commit; + context.dispatch = dispatch; // Act await actions.resetPartsAndDependencies(context); expect(commit).toBeCalledWith(storeMutations.RESET_GLASS_PARTS_STATE); + expect(dispatch).toBeCalledWith(storeActions.RESET_SERVICE_LOCATION_STATE_AND_DEPENDENCIES); }); it("resetState action", async () => { @@ -933,6 +940,90 @@ describe("Actions", () => { ); }); + it("saveServiceZipCodeInfo, should call mutation and save zip code to state", () => { + // Arrange + const context = state; + const commit = jest.fn(); + context.commit = commit; + + const serviceZipCodeInfo = { + zipCode: "43212", + }; + + // Act + actions.saveServiceLocation(context, serviceZipCodeInfo); + + // Assert + expect(commit).toBeCalledWith(storeMutations.UPDATE_SERVICE_LOCATION, serviceZipCodeInfo); + expect(state.order.serviceLocation.zipCode).toEqual("43212"); + }); + + it("saveServiceZipCodeInfo, should reset if zip code is different", () => { + // Arrange + const context = { + state: { + order: { + serviceLocation: { + zipCode: "43212", + }, + }, + }, + }; + + const commit = jest.fn(); + const dispatch = jest.fn(); + + context.commit = commit; + context.dispatch = dispatch; + + const serviceZipCodeInfo = { + zipCode: "43202", + }; + + // Act + actions.saveServiceZipCodeInfo(context, serviceZipCodeInfo); + + // Assert + expect(dispatch).toHaveBeenCalledWith( + storeActions.RESET_SERVICE_LOCATION_STATE_AND_DEPENDENCIES + ); + expect(commit).toHaveBeenCalledWith(storeMutations.RESET_SERVICE_LOCATION_MOBILE_ADDRESS); + }); + + it("saveServiceZipCodeInfo, should not reset if zip code is the same", () => { + // Arrange + const context = { + state: { + order: { + serviceLocation: { + zipCode: "43212", + }, + }, + }, + }; + + const commit = jest.fn(); + const dispatch = jest.fn(); + + context.commit = commit; + context.dispatch = dispatch; + + const serviceZipCodeInfo = { + zipCode: "43212", + }; + + // Act + actions.saveServiceZipCodeInfo(context, serviceZipCodeInfo); + + // Assert + expect(dispatch).not.toHaveBeenCalledWith( + storeActions.RESET_SERVICE_LOCATION_STATE_AND_DEPENDENCIES + ); + expect(commit).not.toHaveBeenCalledWith( + storeMutations.RESET_SERVICE_LOCATION_MOBILE_ADDRESS + ); + }); + it("saveServiceLocation, should call mutation and save service address to state", () => { // Arrange const context = state; @@ -959,6 +1050,242 @@ describe("Actions", () => { expect(state.order.serviceLocation.zipCodeCtu).toEqual("01820"); }); + it("saveServiceLocation, should reset if zipcode is different", () => { + // Arrange + const context = { + state: { + order: { + serviceLocation: { + address: "123 Test Lane", + city: "Columbus", + zipCode: "43212", + state: "OH", + zipCodeCtu: "01820", + appointmentType: "Mobile", + isVehicleProtected: true, + provider: { + providerNumber: "11111", + address: { + streetAddress: "123 Test Lane", + city: "Columbus", + state: "OH", + zip: "43212", + }, + }, + }, + }, + }, + }; + + const commit = jest.fn(); + const dispatch = jest.fn(); + + context.commit = commit; + context.dispatch = dispatch; + + const serviceLocation = { + address: "123 Test Lane", + city: "Columbus", + zipCode: "43202", + state: "OH", + zipCodeCtu: "01820", + appointmentType: "Mobile", + isVehicleProtected: true, + provider: { + providerNumber: "11111", + address: { + streetAddress: "123 Test Lane", + city: "Columbus", + state: "OH", + zip: "43212", + }, + }, + }; + + // Act + actions.saveServiceLocation(context, serviceLocation); + + // Assert + expect(commit).toHaveBeenCalledWith(storeMutations.RESET_SCHEDULE); + }); + + it("saveServiceLocation, should reset if provider is different", () => { + // Arrange + const context = { + state: { + order: { + serviceLocation: { + address: "123 Test Lane", + city: "Columbus", + zipCode: "43212", + state: "OH", + zipCodeCtu: "01820", + appointmentType: "Mobile", + isVehicleProtected: true, + provider: { + providerNumber: "11111", + address: { + streetAddress: "123 Test Lane", + city: "Columbus", + state: "OH", + zip: "43212", + }, + }, + }, + }, + }, + }; + + const commit = jest.fn(); + const dispatch = jest.fn(); + + context.commit = commit; + context.dispatch = dispatch; + + const serviceLocation = { + address: "123 Test Lane", + city: "Columbus", + zipCode: "43212", + state: "OH", + zipCodeCtu: "01820", + appointmentType: "Mobile", + isVehicleProtected: true, + provider: { + providerNumber: "22222", + address: { + streetAddress: "321 Test Lane", + city: "Columbus", + state: "OH", + zip: "43212", + }, + }, + }; + + // Act + actions.saveServiceLocation(context, serviceLocation); + + // Assert + expect(commit).toHaveBeenCalledWith(storeMutations.RESET_SCHEDULE); + }); + + it("saveServiceLocation, should reset if appointment type is different", () => { + // Arrange + const context = { + state: { + order: { + serviceLocation: { + address: "123 Test Lane", + city: "Columbus", + zipCode: "43212", + state: "OH", + zipCodeCtu: "01820", + appointmentType: "Mobile", + isVehicleProtected: true, + provider: { + providerNumber: "11111", + address: { + streetAddress: "123 Test Lane", + city: "Columbus", + state: "OH", + zip: "43212", + }, + }, + }, + }, + }, + }; + + const commit = jest.fn(); + const dispatch = jest.fn(); + + context.commit = commit; + context.dispatch = dispatch; + + const serviceLocation = { + address: "123 Test Lane", + city: "Columbus", + zipCode: "43212", + state: "OH", + zipCodeCtu: "01820", + appointmentType: "Inshop", + isVehicleProtected: true, + provider: { + providerNumber: "11111", + address: { + streetAddress: "123 Test Lane", + city: "Columbus", + state: "OH", + zip: "43212", + }, + }, + }; + + // Act + actions.saveServiceLocation(context, serviceLocation); + + // Assert + expect(commit).toHaveBeenCalledWith(storeMutations.RESET_SCHEDULE); + }); + + it("saveServiceLocation, should not reset if parameters are the same", () => { + // Arrange + const context = { + state: { + order: { + serviceLocation: { + address: "123 Test Lane", + city: "Columbus", + zipCode: "43212", + state: "OH", + zipCodeCtu: "01820", + appointmentType: "Mobile", + isVehicleProtected: true, + provider: { + providerNumber: "11111", + address: { + streetAddress: "123 Test Lane", + city: "Columbus", + state: "OH", + zip: "43212", + }, + }, + }, + }, + }, + }; + + const commit = jest.fn(); + const dispatch = jest.fn(); + + context.commit = commit; + context.dispatch = dispatch; + + const serviceLocation = { + address: "123 Test Lane", + city: "Columbus", + zipCode: "43212", + state: "OH", + zipCodeCtu: "01820", + appointmentType: "Mobile", + isVehicleProtected: true, + provider: { + providerNumber: "11111", + address: { + streetAddress: "123 Test Lane", + city: "Columbus", + state: "OH", + zip: "43212", + }, + }, + }; + + // Act + actions.saveServiceLocation(context, serviceLocation); + + // Assert + expect(commit).not.toHaveBeenCalledWith(storeMutations.RESET_SCHEDULE); + }); + it("saveGlassParts, should call mutation", () => { // Arrange const context = { @@ -966,14 +1293,88 @@ describe("Actions", () => { }; const commit = jest.fn(); + const dispatch = jest.fn(); context.commit = commit; + context.dispatch = dispatch; // Act actions.saveGlassParts(context, { glassParts: {} }); // Assert expect(commit).toBeCalledWith(storeMutations.UPDATE_GLASS_PARTS, { glassParts: {} }); + expect(dispatch).toBeCalledWith(storeActions.RESET_SERVICE_LOCATION_STATE_AND_DEPENDENCIES); + }); + + it("saveSupportingItems, should call mutations", () => { + // Arrange + const context = { + state: state, + }; + + const commit = jest.fn(); + const dispatch = jest.fn(); + + context.commit = commit; + context.dispatch = dispatch; + + // Act + actions.saveSupportingItems(context, []); + + // Assert + expect(commit).toBeCalledWith(storeMutations.UPDATE_SUPPORTING_ITEMS, []); + }); + + it("saveSupportingItems, should call reset logic when value is new", () => { + // Arrange + const context = { + state: { + order: { + lineItems: { + supportingItems: ["TestValue1", "TestValue2"], + }, + }, + }, + }; + + const commit = jest.fn(); + const dispatch = jest.fn(); + + context.commit = commit; + context.dispatch = dispatch; + + // Act + actions.saveSupportingItems(context, ["TestValue3", "TestValue4", "TestValue5"]); + + // Assert + expect(dispatch).toBeCalledWith(storeActions.RESET_SERVICE_LOCATION_STATE_AND_DEPENDENCIES); + }); + + it("saveSupportingItems, should not call reset logic when value is the same", () => { + // Arrange + const context = { + state: { + order: { + lineItems: { + supportingItems: ["TestValue1", "TestValue2"], + }, + }, + }, + }; + + const commit = jest.fn(); + const dispatch = jest.fn(); + + context.commit = commit; + context.dispatch = dispatch; + + // Act + actions.saveSupportingItems(context, ["TestValue1", "TestValue2"]); + + // Assert + expect(dispatch).not.toBeCalledWith( + storeActions.RESET_SERVICE_LOCATION_STATE_AND_DEPENDENCIES + ); }); it("clearVin, should call mutation", () => {