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 6fa81d45f..9f8ad36f6 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", RESET_SAVE_ORDER_PROMISE: "resetSaveOrderPromise", diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js index 44e43ff3e..968478932 100644 --- a/src/constants/store-mutations.js +++ b/src/constants/store-mutations.js @@ -53,13 +53,17 @@ const storeMutations = { RESET_REGISTRATION_STATE: "resetRegistrationState", RESET_GLASS_PARTS_STATE: "resetGlassPartsState", RESET_STATE: "resetState", + RESET_SAVE_ORDER_PROMISE: "resetSaveOrderPromise", // OTHER MUTATIONS UPDATE_PAGE_DATA: "updatePageData", UPDATE_STATE_WITH_ORDER_INFORMATION: "updateStateWithOrderInformation", UPDATE_SAVE_ORDER_PROMISE: "updateSaveOrderPromise", UPDATE_LAST_PAGE_VISITED: "updateLastPageVisited", - RESET_SAVE_ORDER_PROMISE: "resetSaveOrderPromise", + + // 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 ed01c158d..2e1bca1b1 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) { + 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 968837218..64d451f63 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -4,7 +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 { storeActions } from "@/constants/store-actions"; +import { applicationConfig } from "@/constants/application-config"; +import { experimentTriggers } from "@/constants/experiments"; +import { damageLocationsSelected } from "@/constants/damage-locations-selected"; import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; // Export State @@ -70,7 +73,8 @@ const getDefaultState = () => { savedSessionId: null, crmCustomerId: null, lastPageVisited: null, - experiments: [] + experiments: [], + triggeredSiteEntry: false }, } }; @@ -333,6 +337,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 @@ -353,9 +363,37 @@ 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: [...getAllValuesOfPropertyInArrayOfObjects(state.order.lineItems.glassParts, "partNumber"), ...getAllValuesOfPropertyInArrayOfObjects(state.order.lineItems.otherParts, "partNumber")], + orderPartTypes: [...getAllValuesOfPropertyInArrayOfObjects(state.order.lineItems.glassParts, "recalibrationType"), ...getAllValuesOfPropertyInArrayOfObjects(state.order.lineItems.otherParts, "recalibrationType")], + hasRecalibrationPart: (state.order.lineItems.glassParts ?? []).filter(x => x.requiresRecalibration)?.length > 0, + selectedMultiGlass: state.order.damage.glassToReplace?.length > 1, + selectedWindshieldGlass: getAllValuesOfPropertyInArrayOfObjects(state.order.damage.glassToReplace, "glassLocation").includes(damageLocationsSelected.WINDSHIELD), + selectedBackGlass: getAllValuesOfPropertyInArrayOfObjects(state.order.damage.glassToReplace, "glassLocation").includes(damageLocationsSelected.REAR), + selectedDriverSideGlass: getAllValuesOfPropertyInArrayOfObjects(state.order.damage.glassToReplace, "glassLocation").includes(damageLocationsSelected.DRIVER), + selectedPassengerSideGlass: getAllValuesOfPropertyInArrayOfObjects(state.order.damage.glassToReplace, "glassLocation").includes(damageLocationsSelected.PASSENGER) + } + }, experimentSettings: (state) => state.applicationUser.experiments.map(x => x.settings).reduce((r, c) => Object.assign(r, c), {}) } +function getAllValuesOfPropertyInArrayOfObjects(array, propertyName) { + return (array ?? []).map(x => x[propertyName]).filter(x => x); +} + // Export Actions export const actions = { @@ -535,7 +573,7 @@ export const actions = { sessionKey: sessionKey, sessionId: sessionId, pageName: pageName, - applicationName: 'SafeliteDotCom', + applicationName: applicationConfig.APPLICATION_NAME, action: action, event: event, shouldUseSessionId: shouldUseSessionId @@ -554,7 +592,7 @@ export const actions = { sessionKey: sessionKey, sessionId: sessionId, pageName: pageName, - applicationName: 'SafeliteDotCom', + applicationName: applicationConfig.APPLICATION_NAME, category: category, action: action, label: label, @@ -571,7 +609,7 @@ export const actions = { }, initializeSession(context, { userId, sessionId, userAgent, referrer }) { var payload = { - applicationName: 'SafeliteDotCom', + applicationName: applicationConfig.APPLICATION_NAME, userId: userId, deviceId: userId, sessionId: sessionId, @@ -605,6 +643,26 @@ export const actions = { }); }, + runExperimentsForTrigger(context, { userId, triggerEvent, triggerValue }) { + if (triggerEvent == 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 + }; + + globalMethods.callHttpClient({ + method: endpoints.RunExperimentsForTrigger.method, + endpoint: endpoints.RunExperimentsForTrigger.url, + payload: payload, + }); + }, + getEvoxImage(context, { relativeUrl }) { return globalMethods.callHttpClient({ method: endpoints.GetPageData.method,