From be45bb9ff72ba376360e856dfd28420f22a3070b Mon Sep 17 00:00:00 2001 From: Katie Date: Fri, 15 Jul 2022 11:46:01 -0400 Subject: [PATCH 01/42] CSR-514 Initial implementation for runExperimentsForTrigger --- src/constants/application-config.js | 4 +- src/constants/endpoints.js | 4 ++ src/constants/experiments.js | 7 +++- src/constants/store-actions.js | 1 + src/constants/store-mutations.js | 4 ++ src/router/index.js | 10 +++++ src/store/index.js | 60 +++++++++++++++++++++++++++-- 7 files changed, 85 insertions(+), 5 deletions(-) diff --git a/src/constants/application-config.js b/src/constants/application-config.js index 0d173db19..3f1979f83 100644 --- a/src/constants/application-config.js +++ b/src/constants/application-config.js @@ -5,7 +5,9 @@ const applicationConfig = { ANALYTICS_SESSION_TIMEOUT_MINUTES: 30, SAVED_SESSION_TIMEOUT_DAYS: 45, COOKIE_PATH: "/", - CURRENT_ENVIRONMENT: process.env.VUE_APP_CURRENT_ENVIRONMENT // "Localhost", "Dev", "QA", and "Prod" + CURRENT_ENVIRONMENT: process.env.VUE_APP_CURRENT_ENVIRONMENT, // "Localhost", "Dev", "QA", and "Prod" + APPLICATION_NAME: "SafeliteDotCom", + SITE_ENTRY_TRIGGER_VALUE: "FixMyGlass" }; export { applicationConfig }; \ No newline at end of file diff --git a/src/constants/endpoints.js b/src/constants/endpoints.js index e7f856f40..3b3bc8bde 100644 --- a/src/constants/endpoints.js +++ b/src/constants/endpoints.js @@ -90,6 +90,10 @@ const endpoints = { GetExperimentsByUser: { url: "/analytics/api/v1/analytics/get-experiments", method: "GET", + }, + RunExperimentsForTrigger: { + url: "/experiments/api/v1/experiments/run", + method: "POST" } }; diff --git a/src/constants/experiments.js b/src/constants/experiments.js index cd2325a24..fdfa7acac 100644 --- a/src/constants/experiments.js +++ b/src/constants/experiments.js @@ -5,6 +5,11 @@ const experimentUniverses = { const experimentSettings = { GOOGLE_CUSTOM_DIMENSION_INDEX: 'Google Custom Dimension Index' } + +const experimentTriggers = { + SITE_ENTRY: "SiteEntry", + PAGE_ENTRY: "PageEntry" +}; -export { experimentUniverses, experimentSettings}; +export { experimentUniverses, experimentSettings, experimentTriggers }; \ No newline at end of file diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js index 87331daea..6d0fb1f6b 100644 --- a/src/constants/store-actions.js +++ b/src/constants/store-actions.js @@ -30,6 +30,7 @@ const storeActions = { LOG_CUSTOM_EVENT: "logCustomEvent", INITIALIZE_SESSION: "initializeSession", GET_EXPERIMENTS_BY_USER: "GetExperimentsByUser", + RUN_EXPERIMENTS_FOR_TRIGGER: "runExperimentsForTrigger", CLEAR_VIN: "clearVin", // DEPENDENCY MUTATIONS diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js index 80697cc46..28dbb17bf 100644 --- a/src/constants/store-mutations.js +++ b/src/constants/store-mutations.js @@ -58,6 +58,10 @@ const storeMutations = { UPDATE_STATE_WITH_ORDER_INFORMATION: "updateStateWithOrderInformation", UPDATE_SAVE_ORDER_PROMISE: "updateSaveOrderPromise", UPDATE_LAST_PAGE_VISITED: "updateLastPageVisited", + + // EXPERIMENT MUTATIONS + UPDATE_EXPERIMENTS: "updateExperiments", + UPDATE_TRIGGERED_SITE_ENTRY: "updateTriggeredSiteEntry" }; export { storeMutations }; diff --git a/src/router/index.js b/src/router/index.js index b09f734a2..02ec313b8 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -18,6 +18,8 @@ import baseMixin from "@/mixins/base-mixin"; import eventBus from "@/helpers/event-bus/event-bus"; import store from "@/store"; import analyticsMixin from "@/mixins/analytics-mixin"; +import { experimentTriggers } from "../constants/experiments"; +import { applicationConfig } from "../constants/application-config"; const routes = [ { @@ -35,6 +37,14 @@ const routes = [ return next(false); } + 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 + }); + } + // If the saved session has timed out, clear the session, execute 404 logic. if (getFunnelCookie() !== null && !isSavedSessionStillActive()) { await baseMixin.methods.dispatchStoreAction(storeActions.RESET_STATE); diff --git a/src/store/index.js b/src/store/index.js index bac95e3cf..0e766f3c3 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -5,6 +5,8 @@ import { getDateForSavedSessionTimeout } from "@/helpers/heritage-integration/se import createPersistedState from "vuex-persistedstate"; import globalMethods from "@/global-methods"; import { storeActions } from "../constants/store-actions"; +import { applicationConfig } from "../constants/application-config"; +import { experimentTriggers } from "../constants/experiments"; // Export State const getDefaultState = () => { @@ -69,6 +71,8 @@ const getDefaultState = () => { saveQuoteId: null, crmCustomerId: null, lastPageVisited: null, + experiments: {}, + triggeredSiteEntry: false }, } }; @@ -313,6 +317,12 @@ export const mutations = { state.order.customer.emailAddress = orderInformation.customer.emailAddress; }, + updateExperiments(state, experiments) { + state.applicationUser.experiments = experiments; + }, + updateTriggeredSiteEntry(state, wasSiteEntryTriggered) { + state.applicationUser.triggeredSiteEntry = wasSiteEntryTriggered; + } } // Export Getters @@ -333,6 +343,30 @@ export const getters = { applicationUser: (state) => state.applicationUser, order: (state) => state.order, payment: (state) => state.order.payment, + experimentOrder: (state) => { + return { + vehicleYear: state.order.vehicle.year, + vehicleMake: state.order.vehicle.make, + vehicleModel: state.order.vehicle.model, + vehicleStyle: state.order.vehicle.style, + isRepair: state.order.damage.isRepair, + numberOfChips: state.order.damage.numberOfChips, + carId: state.order.vehicle.carId, + serviceCity: state.order.serviceLocation.city, + serviceState: state.order.serviceLocation.state, + serviceZipCode: state.order.serviceLocation.zipCode, + parentAccountNumber: state.order.accountNumber, + isCoverageVerified: state.order.payment.insuranceCoverage.isVerified, + orderPartNumbers: [...Object.values(state.order.lineItems.glassParts), ...Object.values(state.order.lineItems.otherParts)], + orderPartTypes: [...Object.keys(state.order.lineItems.glassParts), ...Object.keys(state.order.lineItems.otherParts)], + hasRecalibrationPart: Object.values(state.order.lineItems.glassParts).filter(x => x.requiresRecalibration)?.length > 0, + selectedMultiGlass: state.order.damage.glassToReplace.length > 1, + selectedWindshieldGlass: Object.keys(state.order.damage.glassToReplace).map(x => x.split("-")[0]).includes(damageLocationsSelected.WINDSHIELD), + selectedBackGlass: Object.keys(state.order.damage.glassToReplace).map(x => x.split("-")[0]).includes(damageLocationsSelected.BACK), + selectedDriverSideGlass: Object.keys(state.order.damage.glassToReplace).map(x => x.split("-")[0]).includes(damageLocationsSelected.DRIVER), + selectedPassengerSideGlass: Object.keys(state.order.damage.glassToReplace).map(x => x.split("-")[0]).includes(damageLocationsSelected.PASSENGER) + } + } } // Export Actions @@ -510,7 +544,7 @@ export const actions = { sessionKey: sessionKey, sessionId: sessionId, pageName: pageName, - applicationName: 'SafeliteDotCom', + applicationName: applicationConfig.APPLICATION_NAME, action: action, event: event, shouldUseSessionId: shouldUseSessionId @@ -529,7 +563,7 @@ export const actions = { sessionKey: sessionKey, sessionId: sessionId, pageName: pageName, - applicationName: 'SafeliteDotCom', + applicationName: applicationConfig.APPLICATION_NAME, category: category, action: action, label: label, @@ -546,7 +580,7 @@ export const actions = { }, initializeSession(context, { userId, sessionId, userAgent, referrer }) { var payload = { - applicationName: 'SafeliteDotCom', + applicationName: applicationConfig.APPLICATION_NAME, userId: userId, deviceId: userId, sessionId: sessionId, @@ -579,6 +613,26 @@ export const actions = { }); }, + runExperimentsForTrigger(context, { userId, triggerEvent, triggerValue }) { + if (triggerValue == experimentTriggers.SITE_ENTRY) { + context.commit(storeMutations.UPDATE_TRIGGERED_SITE_ENTRY, true); + } + + var payload = { + applicationName: applicationConfig.APPLICATION_NAME, + userId: userId, + triggerEvent: triggerEvent, + triggerValue: triggerValue, + experimentOrder: context.getters.experimentOrder + }; + + return globalMethods.callHttpClient({ + method: endpoints.RunExperimentsForTrigger.method, + endpoint: endpoints.RunExperimentsForTrigger.url, + payload: payload, + }); + }, + getEvoxImage(context, { relativeUrl }) { return globalMethods.callHttpClient({ method: endpoints.GetPageData.method, From a750a20e61fe587c189800eeae93477464ab6905 Mon Sep 17 00:00:00 2001 From: Katie Date: Mon, 18 Jul 2022 08:52:49 -0400 Subject: [PATCH 02/42] CSR-514 Add import --- src/store/index.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/store/index.js b/src/store/index.js index 0e766f3c3..3544622af 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -4,9 +4,10 @@ import { storeMutations } from "@/constants/store-mutations"; import { getDateForSavedSessionTimeout } from "@/helpers/heritage-integration/session-helper"; import createPersistedState from "vuex-persistedstate"; import globalMethods from "@/global-methods"; -import { storeActions } from "../constants/store-actions"; -import { applicationConfig } from "../constants/application-config"; -import { experimentTriggers } from "../constants/experiments"; +import { storeActions } from "@/constants/store-actions"; +import { applicationConfig } from "@/constants/application-config"; +import { experimentTriggers } from "@/constants/experiments"; +import { damageLocationsSelected } from "@/constants/damage-locations-selected"; // Export State const getDefaultState = () => { From 635913934242d928c32248a5931fc10ecea30abd Mon Sep 17 00:00:00 2001 From: Katie Date: Tue, 2 Aug 2022 12:17:35 -0400 Subject: [PATCH 03/42] CSR-690 Implement navigation to and from heritage --- src/constants/store-mutations.js | 1 + src/global-methods.js | 7 +++- .../heritage-integration/cookie-helper.js | 3 +- .../heritage-integration/navigation-helper.js | 42 ++++++++++++++----- .../heritage-integration/session-helper.js | 25 +++++++---- .../capability-questions.vue | 2 +- src/layouts/estimate/estimate.vue | 5 +-- .../molding-questions/molding-questions.vue | 2 +- src/layouts/vehicle-damage/vehicle-damage.vue | 5 +-- src/layouts/vehicle-make/vehicle-make.vue | 5 ++- src/layouts/vehicle-parts/vehicle-parts.vue | 11 +++-- src/mixins/vehicle-questions-mixin.js | 8 ++-- src/router/index.js | 2 + src/router/router-constants/fmgPage-values.js | 3 +- src/store/index.js | 22 +++++++--- 15 files changed, 95 insertions(+), 48 deletions(-) diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js index 508f59bf7..44e43ff3e 100644 --- a/src/constants/store-mutations.js +++ b/src/constants/store-mutations.js @@ -39,6 +39,7 @@ const storeMutations = { UPDATE_REFERRAL_DATE: "updateReferralDate", UPDATE_REFERRAL_CORRELATION_ID: "updateReferralCorrelationId", UPDATE_PARENT_ACCT_NUMBER: "updateParentAcctNumber", + UPDATE_EON: "updateEON", UPDATE_SAVED_SESSION_ID: "updateSavedSessionId", UPDATE_CRM_CUSTOMER_ID: "updateCrmCustomerId", diff --git a/src/global-methods.js b/src/global-methods.js index ffda1e77f..4a2026764 100644 --- a/src/global-methods.js +++ b/src/global-methods.js @@ -9,7 +9,12 @@ import { headerKeys } from "@/constants/header-keys"; export default { callHttpClient({ method, endpoint, payload, logApiCall = true }) { return new Promise((resolve, reject) => { - const cfDistroUrl = applicationConfig.CONSUMER_CF_DISTRO; + // const cfDistroUrl = applicationConfig.CONSUMER_CF_DISTRO; + + let cfDistroUrl = applicationConfig.CONSUMER_CF_DISTRO; + if (endpoint.includes("/order/")) + cfDistroUrl = "https://localhost:44346" + const payloadAndAnalyticsData = Object.assign({}, payload, { AppName: "FixMyGlass" }); const headers = { [headerKeys.EXPERIMENT]: JSON.stringify(store.getters.experimentSettings) diff --git a/src/helpers/heritage-integration/cookie-helper.js b/src/helpers/heritage-integration/cookie-helper.js index 775a64fec..fa475beff 100644 --- a/src/helpers/heritage-integration/cookie-helper.js +++ b/src/helpers/heritage-integration/cookie-helper.js @@ -1,6 +1,7 @@ import { cookieNames } from "@/constants/cookie-names"; import store from "@/store"; import { applicationConfig } from "@/constants/application-config"; +// import { getDateForSavedSessionTimeout } from "@/helpers/heritage-integration/session-helper"; /* Will update the cookie if present, or create a new one if not. @@ -15,7 +16,7 @@ export function updateOrCreateFunnelCookie() { // Set up cookie with all the props. setFunnelCookieProperties({ LastTouched: new Date().toUTCString(), - SavedSessionTimeoutDate: store.getters.applicationUser.savedSessionTimeout, + // SavedSessionTimeoutDate: getDateForSavedSessionTimeout(), DidHeritageFunnelUpdateLast: false, ShouldResetState: false, ReferralNumber: store.getters.order.referralNumber, diff --git a/src/helpers/heritage-integration/navigation-helper.js b/src/helpers/heritage-integration/navigation-helper.js index 3ebb7ded8..c3ec9445a 100644 --- a/src/helpers/heritage-integration/navigation-helper.js +++ b/src/helpers/heritage-integration/navigation-helper.js @@ -16,7 +16,7 @@ export async function getPageToRouteExistingOrderTo(toRoute = {}, existingHerita if (toRoute.query[queryStrings.START_TYPE] === 'fmg') { // If they have an existing order, return 'heritage' for the page name. if (existingHeritageOrder) { - return 'heritage'; + return fmgPageValues.HERITAGE; } return await getLatestPageForRedirection(); @@ -61,11 +61,16 @@ async function getLatestPageForRedirection() { // If this is a non-CTA navigation, determine where to send the user based on page prerequisites. // This also works if a user has a 'fmg' start_type query string but no current order. // That shouldn't happen, but it's possible. - const vehicleMakeComponent = (await lazyLoadComponent('vehicle-make')()).default; - const vehicleModelComponent = (await lazyLoadComponent('vehicle-model')()).default; - const vehicleStyleComponent = (await lazyLoadComponent('vehicle-style')()).default; - const vehicleDamageComponent = (await lazyLoadComponent('vehicle-damage')()).default; - + const vehicleMakeComponent = await getLazyLoadedComponent(fmgPageValues.VEHICLE_MAKE);//(await lazyLoadComponent('vehicle-make')()).default; + const vehicleModelComponent = await getLazyLoadedComponent(fmgPageValues.VEHICLE_MODEL);//(await lazyLoadComponent('vehicle-model')()).default; + const vehicleStyleComponent = await getLazyLoadedComponent(fmgPageValues.VEHICLE_STYLE);//(await lazyLoadComponent('vehicle-style')()).default; + const vehicleDamageComponent = await getLazyLoadedComponent(fmgPageValues.VEHICLE_DAMAGE);//(await lazyLoadComponent('vehicle-damage')()).default; + const estimateComponent = await getLazyLoadedComponent(fmgPageValues.ESTIMATE); + const vinLookupComponent = await getLazyLoadedComponent(fmgPageValues.VIN_LOOKUP); + const partQuestionsComponent = await getLazyLoadedComponent(fmgPageValues.PART_QUESTIONS);//(await lazyLoadComponent('part-questions')()).default; + const vehiclePartsComponent = await getLazyLoadedComponent(fmgPageValues.VEHICLE_PARTS); + const moldingQuestionsComponent = await getLazyLoadedComponent(fmgPageValues.MOLDING_QUESTIONS); + const capabilityQuestionsComponent = await getLazyLoadedComponent(fmgPageValues.CAPABILITY_QUESTIONS);//(await lazyLoadComponent('capability-questions')()).default if (!vehicleMakeComponent.methods.arePagePrerequisitesValid()) { return fmgPageValues.VEHICLE_YEAR; @@ -75,15 +80,28 @@ async function getLatestPageForRedirection() { return fmgPageValues.VEHICLE_MODEL; } else if (!vehicleDamageComponent.methods.arePagePrerequisitesValid()) { return fmgPageValues.VEHICLE_STYLE; - } else if (store.getters.damage.isRepair == null || !store.getters.vehicle.carId) { + } else if (!estimateComponent.methods.arePagePrerequisitesValid()) { return fmgPageValues.VEHICLE_DAMAGE; } else { - if (store.getters.vehicle.vin) { + if (capabilityQuestionsComponent.methods.arePagePrerequisitesValid()) { + return fmgPageValues.CAPABILITY_QUESTIONS; + } + else if (moldingQuestionsComponent.methods.arePagePrerequisitesValid()) { + return fmgPageValues.MOLDING_QUESTIONS; + } + else if (vehiclePartsComponent.methods.arePagePrerequisitesValid()) { + return fmgPageValues.VEHICLE_PARTS; + } + else if (partQuestionsComponent.methods.arePagePrerequisitesValid()) { + return fmgPageValues.PART_QUESTIONS; + } + else if (store.getters.vehicle.vin) { return fmgPageValues.VIN_LOOKUP; - } else { + } + else { return fmgPageValues.ESTIMATE; } - } + } } /* @@ -126,4 +144,8 @@ function isVinRelatedPage(toRoute) { fmgPageValue === fmgPageValues.ADDRESS_LOOKUP || fmgPageValue === fmgPageValues.ADDRESS_VEHICLES || fmgPageValue === fmgPageValues.ESTIMATE; +} + +async function getLazyLoadedComponent(pageName) { + return (await lazyLoadComponent(pageName)()).default; } \ No newline at end of file diff --git a/src/helpers/heritage-integration/session-helper.js b/src/helpers/heritage-integration/session-helper.js index ca50a4e7b..c03288b42 100644 --- a/src/helpers/heritage-integration/session-helper.js +++ b/src/helpers/heritage-integration/session-helper.js @@ -28,23 +28,34 @@ export function isAnalyticsSessionStillActive() { */ export function isSavedSessionStillActive() { if (getFunnelCookie() !== null) { - const savedSessionTimeStamp = new Date(getFunnelCookie().SavedSessionTimeoutDate); + const savedSessionTimeStamp = new Date(getSavedSessionTimeoutDate()); const isSavedSessionTimedOut = (new Date(new Date().toUTCString()) > savedSessionTimeStamp); - if (isSavedSessionTimedOut) { - return false; - } - - return true; + return !isSavedSessionTimedOut; } } /* -Function to get the date for the saved session timeout. +Function to calculate the date for the saved session timeout. */ export function getDateForSavedSessionTimeout() { const currentDate = new Date(new Date().toUTCString()) currentDate.setDate(currentDate.getDate() + applicationConfig.SAVED_SESSION_TIMEOUT_DAYS) return currentDate.toUTCString(); +} + +/** Function to get saved session timeout date based on values in the cookie */ +function getSavedSessionTimeoutDate() { + console.log("getFunnelCookie()?.LastTouched: ", getFunnelCookie()?.LastTouched) + let lastTouched = new Date(getFunnelCookie()?.LastTouched); + lastTouched = lastTouched ? lastTouched : new Date().toUTCString(); + let savedSessionTimeoutDate = lastTouched; + savedSessionTimeoutDate.setDate(savedSessionTimeoutDate.getDate() + applicationConfig.SAVED_SESSION_TIMEOUT_DAYS); + + // const test = lastTouched + // ? lastTouched.setDate(lastTouched.getDate() + applicationConfig.SAVED_SESSION_TIMEOUT_DAYS) + // : getDateForSavedSessionTimeout(); + + return savedSessionTimeoutDate; } \ No newline at end of file diff --git a/src/layouts/capability-questions/capability-questions.vue b/src/layouts/capability-questions/capability-questions.vue index 69fc8aad5..a29aa3779 100644 --- a/src/layouts/capability-questions/capability-questions.vue +++ b/src/layouts/capability-questions/capability-questions.vue @@ -112,7 +112,7 @@ export default { }, methods: { arePagePrerequisitesValid() { - return true; // TODO - DO TRUE TEST OF PAGEDATA + return false; // TODO - DO TRUE TEST OF PAGEDATA // return Object.keys(store.getters.pageData(fmgPageValues.CAPABILITY_QUESTIONS)).length > 0; }, showThisPartQuestionChain(part, i) { diff --git a/src/layouts/estimate/estimate.vue b/src/layouts/estimate/estimate.vue index 3949d4c41..3cc6b1149 100644 --- a/src/layouts/estimate/estimate.vue +++ b/src/layouts/estimate/estimate.vue @@ -80,10 +80,7 @@ export default { }, methods: { arePagePrerequisitesValid() { - if(store.getters.damage.isRepair!=null){ - return true; - } - return false; + return store.getters.damage.isRepair != null; }, backButtonAction() { // route to move backwards diff --git a/src/layouts/molding-questions/molding-questions.vue b/src/layouts/molding-questions/molding-questions.vue index d2b469a36..f575c9240 100644 --- a/src/layouts/molding-questions/molding-questions.vue +++ b/src/layouts/molding-questions/molding-questions.vue @@ -115,7 +115,7 @@ export default { }, methods: { arePagePrerequisitesValid() { - return true; // TODO - DO TRUE TEST OF PAGEDATA + return false; // TODO - DO TRUE TEST OF PAGEDATA // return Object.keys(store.getters.pageData(fmgPageValues.MOLDING_QUESTIONS)).length > 0; }, showThisPartQuestionChain(part, i) { diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue index 7d61814f8..a00c91a85 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.vue +++ b/src/layouts/vehicle-damage/vehicle-damage.vue @@ -155,10 +155,7 @@ export default { }, methods: { arePagePrerequisitesValid() { - if(store.getters.vehicle.carId){ - return true; - } - return false; + return store.getters.vehicle.carId; }, attachCustomEvents(){ diff --git a/src/layouts/vehicle-make/vehicle-make.vue b/src/layouts/vehicle-make/vehicle-make.vue index 8cd77c545..4a2eff8f9 100644 --- a/src/layouts/vehicle-make/vehicle-make.vue +++ b/src/layouts/vehicle-make/vehicle-make.vue @@ -76,9 +76,10 @@ export default { ); }, arePagePrerequisitesValid() { - if (store.getters.vehicle.year){ - return true; + if (store.getters.vehicle.year){ + return true; } + return false; }, }, diff --git a/src/layouts/vehicle-parts/vehicle-parts.vue b/src/layouts/vehicle-parts/vehicle-parts.vue index 290910217..103af885b 100644 --- a/src/layouts/vehicle-parts/vehicle-parts.vue +++ b/src/layouts/vehicle-parts/vehicle-parts.vue @@ -155,11 +155,11 @@ export default { methods: { arePagePrerequisitesValid() { // Check if isRepair is populated and if the pageData we need is here (Parts data) - return store.getters.damage.isRepair != null && + return store.getters.damage.isRepair != null && store.getters.pageData(fmgPageValues.VEHICLE_PARTS) && Object.keys(store.getters.pageData(fmgPageValues.VEHICLE_PARTS)).length !== 0; }, backButtonAction() { - const hasPartQuestions = this.hasPartQuestions(this.$store.getters.pageData(fmgPageValues.PART_QUESTIONS).partsOrQuestions); + const hasPartQuestions = this.hasPartQuestions(this.$store.getters.pageData(fmgPageValues.PART_QUESTIONS)?.partsOrQuestions); const backNavigationScenario = hasPartQuestions ? this.navigationScenarios.CLICKED_BACK_WITH_PART_QUESTION_ANSWERS : this.navigationScenarios.CLICKED_BACK_WITHOUT_PART_QUESTION_ANSWERS; this.$router.navigate( @@ -175,7 +175,6 @@ export default { this.PartsFromApi.partsOrQuestions )) { for (let [partKey, partValue] of Object.entries(value.parts)) { - const currentPart = this.PartsFromApi.partsOrQuestions[key].parts[partKey]; const isMatched = this.selectedGlassPartNumbers.some( @@ -184,9 +183,9 @@ export default { if (isMatched) { matchedParts.push({ - "glassLocation": value.glassLocation, - "glassName": value.glassName, - "parts": [currentPart] + glassLocation: value.glassLocation, + glassName: value.glassName, + parts: [currentPart] }); } } diff --git a/src/mixins/vehicle-questions-mixin.js b/src/mixins/vehicle-questions-mixin.js index 7a86066a8..1a28fe028 100644 --- a/src/mixins/vehicle-questions-mixin.js +++ b/src/mixins/vehicle-questions-mixin.js @@ -2,18 +2,18 @@ export default { methods: { hasPartQuestions(partsOrQuestions) { - return partsOrQuestions.some(pq => pq.partQuestions?.length > 0); + return partsOrQuestions?.some(pq => pq.partQuestions?.length > 0); }, hasGlassLocationWithMultipleParts(partsOrQuestions) { - return partsOrQuestions.some(pq => pq.parts?.length > 1); + return partsOrQuestions?.some(pq => pq.parts?.length > 1); }, hasChildPartQuestions(partsOrQuestions) { - return partsOrQuestions.some(pq => { + return partsOrQuestions?.some(pq => { return pq.parts?.some(part => part.childPartQuestions?.length > 0); }); }, hasCapabilityQuestions(partsOrQuestions) { - return partsOrQuestions.some(pq => { + return partsOrQuestions?.some(pq => { return pq.parts?.some(part => part.requiresCapabilityQuestions === true); }); }, diff --git a/src/router/index.js b/src/router/index.js index 767b9ab18..4295ae491 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -224,6 +224,8 @@ function navigateToUrl(url, optionalQuery = {}) { externalUrl.searchParams.append(queryKey, optionalQuery[queryKey]); } + externalUrl.searchParams.append("experiments", "ConceptFunnel=ConceptFunnel_V1=ConceptFunnel_TEST=true"); + window.location.assign(externalUrl); } diff --git a/src/router/router-constants/fmgPage-values.js b/src/router/router-constants/fmgPage-values.js index 404a89de9..d924e30de 100644 --- a/src/router/router-constants/fmgPage-values.js +++ b/src/router/router-constants/fmgPage-values.js @@ -14,7 +14,8 @@ const fmgPageValues = { REVEAL: "reveal", ESTIMATE: "estimate", ADDRESS_VEHICLES: "address-vehicles", - QUOTE: "quote" + QUOTE: "quote", + HERITAGE: "heritage" }; export { fmgPageValues }; diff --git a/src/store/index.js b/src/store/index.js index 44dfccfcc..28d231316 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -60,11 +60,12 @@ const getDefaultState = () => { referralDate: null, referralCorrelationId: null, accountNumber: 0, + eon: null }, applicationUser: { eventBus: [], pageData: {}, - savedSessionTimeout: getDateForSavedSessionTimeout(), + // savedSessionTimeout: getDateForSavedSessionTimeout(), saveOrderPromise: null, savedSessionId: null, crmCustomerId: null, @@ -139,6 +140,9 @@ export const mutations = { updateParentAcctNumber(state, parentAcctNumber) { state.order.accountNumber = parentAcctNumber; }, + updateEON(state, eon) { + state.order.eon = eon; + }, updateIsInsurance(state, isInsurance) { state.order.payment.isInsurance = isInsurance; }, @@ -279,6 +283,7 @@ export const mutations = { state.order.referralNumber = orderInformation.referralNumber; state.order.referralDate = orderInformation.referralDate; state.order.referralCorrelationId = orderInformation.referralCorrelationId; + state.order.eon = orderInformation.eon; state.order.vehicle = Object.assign(state.order.vehicle, { year: orderInformation.vehicle?.year, @@ -504,10 +509,11 @@ export const actions = { }, // Misc Actions - updateStoreWithSaveOrderResponse(context, { referralNumber, referralDate, referralCorrelationId, accountNumber, savedSessionId, crmCustomerId }) { + updateStoreWithSaveOrderResponse(context, { referralNumber, referralDate, referralCorrelationId, eon, accountNumber, savedSessionId, crmCustomerId }) { context.commit(storeMutations.UPDATE_REFERRAL_NUMBER, referralNumber); context.commit(storeMutations.UPDATE_REFERRAL_DATE, referralDate); context.commit(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, referralCorrelationId); + context.commit(storeMutations.UPDATE_EON, eon); context.commit(storeMutations.UPDATE_PARENT_ACCT_NUMBER, accountNumber); context.commit(storeMutations.UPDATE_SAVED_SESSION_ID, savedSessionId); context.commit(storeMutations.UPDATE_CRM_CUSTOMER_ID, crmCustomerId); @@ -574,10 +580,11 @@ export const actions = { }, // Misc Actions - setReferralInformation(context, { referralNumber, referralDate, referralCorrelationId }) { + setReferralInformation(context, { referralNumber, referralDate, referralCorrelationId, eon }) { context.commit(storeMutations.UPDATE_REFERRAL_NUMBER, referralNumber); context.commit(storeMutations.UPDATE_REFERRAL_DATE, referralDate); context.commit(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, referralCorrelationId); + context.commit(storeMutations.UPDATE_EON, eon); }, GetExperimentsByUser(context, { userId }) { @@ -650,6 +657,7 @@ export const actions = { const damage = context.getters.damage; const order = context.state.order; const applicationUser = context.getters.applicationUser; + const lineItems = context.state.order.lineItems; return globalMethods.callHttpClient({ method: endpoints.SaveOrder.method, @@ -680,6 +688,9 @@ export const actions = { customer: { emailAddress: order.customer.emailAddress, }, + lineItems: { + glassParts: lineItems.glassParts + }, serviceLocation: { streetAddress: order.serviceLocation.address, city: order.serviceLocation.city, @@ -693,7 +704,6 @@ export const actions = { lastPage: applicationUser.lastPageVisited, crmCustomerId: applicationUser.crmCustomerId, savedSessionId: applicationUser.savedSessionId, - }, }); }, @@ -708,8 +718,8 @@ export const actions = { accountNumber: accountNumber?.toString() }, }).then((response) => { - // clear the state if the existing referral number does not equal what is returned from loadOrder - if (context.state.order.referralNumber != response.data.referralNumber) { + // clear the state if the existing EON does not equal what is returned from loadOrder + if (context.state.order.eon && context.state.order.eon != response.data.eon) { context.commit(storeMutations.RESET_STATE); } context.commit(storeMutations.UPDATE_STATE_WITH_ORDER_INFORMATION, response.data); From 7d7896a0121a74308028d8159733e7e0b03025d0 Mon Sep 17 00:00:00 2001 From: Katie Date: Tue, 2 Aug 2022 15:32:11 -0400 Subject: [PATCH 04/42] CSR-690 Fix issue with part-questions back --- src/helpers/heritage-integration/session-helper.js | 1 - src/layouts/part-questions/part-questions.vue | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/helpers/heritage-integration/session-helper.js b/src/helpers/heritage-integration/session-helper.js index c03288b42..cf58846f0 100644 --- a/src/helpers/heritage-integration/session-helper.js +++ b/src/helpers/heritage-integration/session-helper.js @@ -47,7 +47,6 @@ export function getDateForSavedSessionTimeout() { /** Function to get saved session timeout date based on values in the cookie */ function getSavedSessionTimeoutDate() { - console.log("getFunnelCookie()?.LastTouched: ", getFunnelCookie()?.LastTouched) let lastTouched = new Date(getFunnelCookie()?.LastTouched); lastTouched = lastTouched ? lastTouched : new Date().toUTCString(); let savedSessionTimeoutDate = lastTouched; diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue index db237ce2b..a4ccaff48 100644 --- a/src/layouts/part-questions/part-questions.vue +++ b/src/layouts/part-questions/part-questions.vue @@ -175,7 +175,8 @@ export default { } }, arePagePrerequisitesValid() { - return Object.keys(store.getters.pageData(fmgPageValues.PART_QUESTIONS)).length > 0; + const partQuestionsFromPageData = store.getters.pageData(fmgPageValues.PART_QUESTIONS); + return partQuestionsFromPageData && Object.keys(partQuestionsFromPageData).length > 0; }, }, watch: { From 9248a5b3b2817f8db0251e309a03161c02af2b30 Mon Sep 17 00:00:00 2001 From: Katie Date: Wed, 3 Aug 2022 12:01:43 -0400 Subject: [PATCH 05/42] CSR-690 --- src/helpers/heritage-integration/cookie-helper.js | 4 ++-- src/layouts/vehicle-damage/vehicle-damage.vue | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/helpers/heritage-integration/cookie-helper.js b/src/helpers/heritage-integration/cookie-helper.js index fa475beff..4af74bb80 100644 --- a/src/helpers/heritage-integration/cookie-helper.js +++ b/src/helpers/heritage-integration/cookie-helper.js @@ -1,7 +1,7 @@ import { cookieNames } from "@/constants/cookie-names"; import store from "@/store"; import { applicationConfig } from "@/constants/application-config"; -// import { getDateForSavedSessionTimeout } from "@/helpers/heritage-integration/session-helper"; +import { getDateForSavedSessionTimeout } from "@/helpers/heritage-integration/session-helper"; /* Will update the cookie if present, or create a new one if not. @@ -16,7 +16,7 @@ export function updateOrCreateFunnelCookie() { // Set up cookie with all the props. setFunnelCookieProperties({ LastTouched: new Date().toUTCString(), - // SavedSessionTimeoutDate: getDateForSavedSessionTimeout(), + SavedSessionTimeoutDate: getDateForSavedSessionTimeout(), DidHeritageFunnelUpdateLast: false, ShouldResetState: false, ReferralNumber: store.getters.order.referralNumber, diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue index a00c91a85..42e150c90 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.vue +++ b/src/layouts/vehicle-damage/vehicle-damage.vue @@ -155,7 +155,7 @@ export default { }, methods: { arePagePrerequisitesValid() { - return store.getters.vehicle.carId; + return store.getters.vehicle.carId != null; }, attachCustomEvents(){ From ef42c6553aaacbd70a94c775a01f066eed8a23b6 Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Thu, 4 Aug 2022 09:43:37 -0400 Subject: [PATCH 06/42] Defect | Change hardcoded value to prod image Used to be -dev --- src/layouts/vin-lookup/vin-information/vin-information.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layouts/vin-lookup/vin-information/vin-information.vue b/src/layouts/vin-lookup/vin-information/vin-information.vue index 91cee616f..6eee66970 100644 --- a/src/layouts/vin-lookup/vin-information/vin-information.vue +++ b/src/layouts/vin-lookup/vin-information/vin-information.vue @@ -23,7 +23,7 @@ export default { isActive: false, HeadlineText: "Where can I find my VIN?", BodyText: "

You can find your VIN in a few places:

  1. Driver side windshield
  2. Driver side doorjamb
  3. Vehicle registration card
  4. Auto insurance card or app
", - OptionalImage: "https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/vin_location.svg?sfvrsn=63a9a2cf_3", + OptionalImage: "https://digitalconsumercms.safelite.com/images/default-source/default-album/vin_location.svg?sfvrsn=63a9a2cf_3", }; }, methods: { From 74b86c80d2af35a6dbc81e1d034a25aa3765c078 Mon Sep 17 00:00:00 2001 From: Katie Date: Fri, 5 Aug 2022 08:36:23 -0400 Subject: [PATCH 07/42] CSR-690 Add savedSessionTimeoutDate stuff back --- .../heritage-integration/cookie-helper.js | 4 ++-- .../heritage-integration/session-helper.js | 22 +++++++++---------- src/store/index.js | 13 ++++++++++- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/helpers/heritage-integration/cookie-helper.js b/src/helpers/heritage-integration/cookie-helper.js index 4af74bb80..f466bb9b8 100644 --- a/src/helpers/heritage-integration/cookie-helper.js +++ b/src/helpers/heritage-integration/cookie-helper.js @@ -1,7 +1,7 @@ import { cookieNames } from "@/constants/cookie-names"; import store from "@/store"; import { applicationConfig } from "@/constants/application-config"; -import { getDateForSavedSessionTimeout } from "@/helpers/heritage-integration/session-helper"; +// import { getDateForSavedSessionTimeout } from "@/helpers/heritage-integration/session-helper"; /* Will update the cookie if present, or create a new one if not. @@ -16,7 +16,7 @@ export function updateOrCreateFunnelCookie() { // Set up cookie with all the props. setFunnelCookieProperties({ LastTouched: new Date().toUTCString(), - SavedSessionTimeoutDate: getDateForSavedSessionTimeout(), + SavedSessionTimeoutDate: store.getters.applicationUser.savedSessionTimeout, DidHeritageFunnelUpdateLast: false, ShouldResetState: false, ReferralNumber: store.getters.order.referralNumber, diff --git a/src/helpers/heritage-integration/session-helper.js b/src/helpers/heritage-integration/session-helper.js index cf58846f0..a5118a21d 100644 --- a/src/helpers/heritage-integration/session-helper.js +++ b/src/helpers/heritage-integration/session-helper.js @@ -28,7 +28,7 @@ export function isAnalyticsSessionStillActive() { */ export function isSavedSessionStillActive() { if (getFunnelCookie() !== null) { - const savedSessionTimeStamp = new Date(getSavedSessionTimeoutDate()); + const savedSessionTimeStamp = new Date(getFunnelCookie().SavedSessionTimeoutDate); const isSavedSessionTimedOut = (new Date(new Date().toUTCString()) > savedSessionTimeStamp); return !isSavedSessionTimedOut; @@ -46,15 +46,15 @@ export function getDateForSavedSessionTimeout() { } /** Function to get saved session timeout date based on values in the cookie */ -function getSavedSessionTimeoutDate() { - let lastTouched = new Date(getFunnelCookie()?.LastTouched); - lastTouched = lastTouched ? lastTouched : new Date().toUTCString(); - let savedSessionTimeoutDate = lastTouched; - savedSessionTimeoutDate.setDate(savedSessionTimeoutDate.getDate() + applicationConfig.SAVED_SESSION_TIMEOUT_DAYS); +// function getSavedSessionTimeoutDate() { +// let lastTouched = new Date(getFunnelCookie()?.LastTouched); +// lastTouched = lastTouched ? lastTouched : new Date().toUTCString(); +// let savedSessionTimeoutDate = lastTouched; +// savedSessionTimeoutDate.setDate(savedSessionTimeoutDate.getDate() + applicationConfig.SAVED_SESSION_TIMEOUT_DAYS); - // const test = lastTouched - // ? lastTouched.setDate(lastTouched.getDate() + applicationConfig.SAVED_SESSION_TIMEOUT_DAYS) - // : getDateForSavedSessionTimeout(); +// // const test = lastTouched +// // ? lastTouched.setDate(lastTouched.getDate() + applicationConfig.SAVED_SESSION_TIMEOUT_DAYS) +// // : getDateForSavedSessionTimeout(); - return savedSessionTimeoutDate; -} \ No newline at end of file +// return savedSessionTimeoutDate; +// } \ No newline at end of file diff --git a/src/store/index.js b/src/store/index.js index 28d231316..7db358c1e 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -65,7 +65,7 @@ const getDefaultState = () => { applicationUser: { eventBus: [], pageData: {}, - // savedSessionTimeout: getDateForSavedSessionTimeout(), + savedSessionTimeout: getDateForSavedSessionTimeout(), saveOrderPromise: null, savedSessionId: null, crmCustomerId: null, @@ -271,6 +271,9 @@ export const mutations = { state.order.lineItems.glassParts = null; state.order.damage.partQuestionAnswers = null; state.applicationUser.pageData[fmgPageValues.PART_QUESTIONS] = null; + state.applicationUser.pageData[fmgPageValues.VEHICLE_PARTS] = null; + state.applicationUser.pageData[fmgPageValues.MOLDING_QUESTIONS] = null; + state.applicationUser.pageData[fmgPageValues.CAPABILITY_QUESTIONS] = null; }, resetState(state) { Object.assign(state, getDefaultState()); @@ -746,6 +749,7 @@ export const actions = { context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES); context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES); + context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES); //Save new values context.commit(storeMutations.UPDATE_YEAR, year); @@ -766,6 +770,7 @@ export const actions = { context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES); context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES); + context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES); //Save new values context.commit(storeMutations.UPDATE_MAKE, make); @@ -785,6 +790,7 @@ export const actions = { context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES); context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES); + context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES); //Save new values context.commit(storeMutations.UPDATE_MODEL, model); @@ -802,6 +808,7 @@ export const actions = { context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES); context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES); + context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES); //Save new values context.commit(storeMutations.UPDATE_STYLE, style); @@ -832,6 +839,7 @@ export const actions = { //Reset dependent state when changing if (vehicleInfo.vin !== context.state.order.vehicle.vin) { context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES); + context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES); if (!isSelectedGlassAvailableForVehicle) { context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES); @@ -850,6 +858,7 @@ export const actions = { if (!isSelectedGlassAvailableForVehicle) { context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES); + context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES); } //Save new values @@ -865,6 +874,7 @@ export const actions = { if (!isSelectedGlassAvailableForVehicle) { context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES); + context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES); } //Save new values @@ -890,6 +900,7 @@ export const actions = { if (!isSelectedGlassAvailableForVehicle) { context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES); + context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES); } //Save new values From ae6c242f2d087c83cc8b3fd3556c7d2632c0e4ee Mon Sep 17 00:00:00 2001 From: CarlNation Date: Fri, 5 Aug 2022 15:31:07 -0400 Subject: [PATCH 08/42] CSR-658 skip style page when only 1 style --- src/layouts/vehicle-style/vehicle-style.vue | 28 ++++++++++++++++----- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/layouts/vehicle-style/vehicle-style.vue b/src/layouts/vehicle-style/vehicle-style.vue index c7589d32d..50f1b35f5 100644 --- a/src/layouts/vehicle-style/vehicle-style.vue +++ b/src/layouts/vehicle-style/vehicle-style.vue @@ -1,5 +1,5 @@