Merge branch 'develop' into feature/CSR-1112
This commit is contained in:
commit
1bc9050113
16 changed files with 145 additions and 46 deletions
|
|
@ -19,6 +19,7 @@ const GaActions = {
|
|||
CLICKED: "Clicked",
|
||||
VIF: "vif",
|
||||
SUBMITTED: "Submitted",
|
||||
DISPLAYED: "Displayed",
|
||||
};
|
||||
|
||||
const GaLabels = {
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ import listButtonHorizontal from "@/ux-components/list-button-horizontal/list-bu
|
|||
import listCard from "@/ux-components/list-card/list-card";
|
||||
import radio from "@/ux-components/radio/radio";
|
||||
import { useField, ErrorMessage } from "vee-validate";
|
||||
import { queryStrings } from "@/constants/query-strings";
|
||||
|
||||
export default {
|
||||
name: "buttonQuestion",
|
||||
|
|
@ -130,6 +131,10 @@ export default {
|
|||
isSmallQuestionText: Boolean,
|
||||
availability: String,
|
||||
customButtonQuestionId: String,
|
||||
logDisplayedValuesEvent: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const propsClone = Object.assign({}, props);
|
||||
|
|
@ -254,6 +259,29 @@ export default {
|
|||
modelValue() {
|
||||
this.resetField();
|
||||
},
|
||||
answers() {
|
||||
//once we get the answers to display from parent, see if we need a GA event to log what we showed
|
||||
if (this.logDisplayedValuesEvent && this.answers.length > 0) {
|
||||
var eventLabel = "";
|
||||
//build comma separated list of all items in button list that we are going to display on page
|
||||
this.answers.forEach((item) => {
|
||||
if (item.Name) {
|
||||
eventLabel += item.Name + ",";
|
||||
}
|
||||
if (item.buttonLabel) {
|
||||
eventLabel += item.buttonLabel + ",";
|
||||
}
|
||||
});
|
||||
|
||||
eventLabel = eventLabel.slice(0, -1); //remove the last comma
|
||||
this.pushEventToGA(
|
||||
this.$route.query[queryStrings.FMG_PAGE],
|
||||
this.GaActions.DISPLAYED,
|
||||
eventLabel,
|
||||
true
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
components: {
|
||||
listButton,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import store from "@/store";
|
||||
import baseMixin from "@/mixins/base-mixin.js";
|
||||
import { storeActions } from "@/constants/store-actions";
|
||||
import { damageLocationsSelected as glassLocations } from "@/constants/damage-locations-selected";
|
||||
|
||||
export function getDamageString() {
|
||||
// If it's a repair it's always a windshield.
|
||||
|
|
@ -45,6 +46,14 @@ export function getIsWindshieldOnly() {
|
|||
return returnString;
|
||||
}
|
||||
|
||||
export function includesWindshieldReplacement() {
|
||||
const windshieldMatches =
|
||||
store.getters.order.damage.glassToReplace?.filter(
|
||||
(glassToReplace) => glassToReplace.glassLocation === glassLocations.WINDSHIELD
|
||||
) ?? [];
|
||||
return windshieldMatches.length > 0;
|
||||
}
|
||||
|
||||
export async function isGlassAvailableForCarId(carId) {
|
||||
const newGlassOptions = await baseMixin.methods.dispatchStoreAction(
|
||||
storeActions.GET_DAMAGE_OPTIONS,
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { storeActions } from "@/constants/store-actions.js";
|
|||
import { settleAllPromises } from "@/helpers/layout-helper";
|
||||
import experimentMixin from "@/mixins/experiment-mixin";
|
||||
import { experimentSettings } from "@/constants/experiments";
|
||||
import { includesWindshieldReplacement } from "@/helpers/damage-helper";
|
||||
import store from "@/store";
|
||||
import router from "@/router";
|
||||
|
||||
|
|
@ -73,6 +74,7 @@ export async function skipVinLookup() {
|
|||
return (
|
||||
store.getters.damage.isRepair ||
|
||||
isVinOptionalVehicle ||
|
||||
!includesWindshieldReplacement() ||
|
||||
experimentMixin.methods.hasSettingEqualTo(experimentSettings.SUPPRESS_VIN_CAPTURE, "true")
|
||||
);
|
||||
}
|
||||
|
|
@ -85,6 +87,7 @@ export async function skipVinLookupNotRepair() {
|
|||
return (
|
||||
!store.getters.damage.isRepair &&
|
||||
(isVinOptionalVehicle ||
|
||||
!includesWindshieldReplacement() ||
|
||||
experimentMixin.methods.hasSettingEqualTo(
|
||||
experimentSettings.SUPPRESS_VIN_CAPTURE,
|
||||
"true"
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ describe("getPageToRouteExistingOrderTo", () => {
|
|||
expect(result).toBe(fmgPageValues.VEHICLE_DAMAGE);
|
||||
});
|
||||
|
||||
test("user has YMMS and no vehicle questions > should return vin-lookup", async () => {
|
||||
test("user has YMMS and no vehicle questions > should return estimate", async () => {
|
||||
// Arrange
|
||||
const toRoute = {
|
||||
query: {},
|
||||
|
|
@ -172,7 +172,7 @@ describe("getPageToRouteExistingOrderTo", () => {
|
|||
const result = await getPageToRouteExistingOrderTo(toRoute, false);
|
||||
|
||||
//Assert
|
||||
expect(result).toBe(fmgPageValues.VIN_LOOKUP);
|
||||
expect(result).toBe(fmgPageValues.ESTIMATE);
|
||||
});
|
||||
|
||||
test("user has YMMS but no questions or carId > should return estimate", async () => {
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
<div class="row mb-4" v-show="showAddressFields" aria-live="polite">
|
||||
<div class="col">
|
||||
<dropdownQuestion
|
||||
customInputId="state"
|
||||
customDropdownId="state"
|
||||
cmsWidgetName="StateQuestionWidget"
|
||||
v-model="addressModel.state"
|
||||
ref="state"
|
||||
|
|
@ -115,6 +115,10 @@ export default {
|
|||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
preserveCityAndStateOnReset: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
@ -390,8 +394,10 @@ export default {
|
|||
this.displayNoMatchWarning = true;
|
||||
|
||||
this.addressModel.city = "";
|
||||
this.addressModel.state = "";
|
||||
this.addressModel.zipCode = "";
|
||||
if (!this.preserveCityAndStateOnReset) {
|
||||
this.addressModel.state = "";
|
||||
this.addressModel.zipCode = "";
|
||||
}
|
||||
this.showAddressFields = true;
|
||||
this.displayVerificationWarning = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -101,6 +101,9 @@ describe("estimate.vue", () => {
|
|||
//Arrange
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
delete window.location;
|
||||
window.location = { search: "?fmgPage=estimate&zipcode=43015" };
|
||||
|
||||
//Act
|
||||
estimate.beforeRouteEnter.call(
|
||||
wrapper.vm,
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@
|
|||
buttonTypeString="listButton"
|
||||
v-model="selectedVinLookupMethod"
|
||||
isRequired
|
||||
validationRules="option-required" />
|
||||
validationRules="option-required"
|
||||
:logDisplayedValuesEvent="true" />
|
||||
</div>
|
||||
<div v-else>
|
||||
<alert
|
||||
|
|
@ -147,11 +148,17 @@ export default {
|
|||
|
||||
const queryString = window.location.search;
|
||||
const urlParams = new URLSearchParams(queryString);
|
||||
const hasZip = urlParams.has(queryStrings.ZIP_CODE);
|
||||
const zip = urlParams.get(queryStrings.ZIP_CODE);
|
||||
const lowerCaseParams = new URLSearchParams();
|
||||
for (const [name, value] of urlParams) {
|
||||
lowerCaseParams.append(name.toLowerCase(), value);
|
||||
}
|
||||
|
||||
const zip = lowerCaseParams.get(queryStrings.ZIP_CODE)
|
||||
? lowerCaseParams.get(queryStrings.ZIP_CODE)
|
||||
: store.getters.order.serviceLocation.zipCode;
|
||||
|
||||
var vinByAddressPromise;
|
||||
if (hasZip) {
|
||||
if (zip) {
|
||||
vinByAddressPromise = baseMixin.methods.dispatchStoreAction(
|
||||
storeActions.IS_VIN_BY_ADDRESS_PERMISSIBLE,
|
||||
zip,
|
||||
|
|
@ -191,7 +198,7 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
if (zip && resultMap.vinByAddress === false) {
|
||||
if (!zip || resultMap.vinByAddress === false) {
|
||||
var indexToRemove = resultMap.cmsContent.VinLookupMethod.Answers.findIndex(
|
||||
(answer) => answer.Name === "HomeAddress"
|
||||
);
|
||||
|
|
@ -199,6 +206,7 @@ export default {
|
|||
resultMap.cmsContent.VinLookupMethod.Answers.splice(indexToRemove, 1);
|
||||
}
|
||||
}
|
||||
|
||||
vm.setCmsContent(resultMap.cmsContent);
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
:displayGenericVehicleImage="false" />
|
||||
<funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" />
|
||||
<div class="fade-on-route-transition sub-container make-tall">
|
||||
<div class="row my-2">
|
||||
<div class="row mt-2 mb-4">
|
||||
<div class="col">
|
||||
<textboxQuestion
|
||||
cmsWidgetName="LicensePlateNumberQuestionWidget"
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
validationRules="license-plate-required" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-2">
|
||||
<div class="row mt-0 mb-4">
|
||||
<div class="col">
|
||||
<textboxQuestion
|
||||
cmsWidgetName="RegistrationZipQuestionWidget"
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
validationRules="zip-required|zip-format" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-2">
|
||||
<div class="row mt-0">
|
||||
<div class="col">
|
||||
<textboxQuestion
|
||||
cmsWidgetName="EmailAddressQuestionWidget"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@
|
|||
:buttonTypeObject="servicePackageRadio"
|
||||
v-model="selectedPackageName"
|
||||
:validationRules="validationRules"
|
||||
:isRequired="isRequired" />
|
||||
:isRequired="isRequired"
|
||||
:logDisplayedValuesEvent="true" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
|
|||
|
|
@ -66,6 +66,18 @@ export default {
|
|||
},
|
||||
},
|
||||
watch: {
|
||||
answersToDisplay: {
|
||||
handler(newValue) {
|
||||
// If there is only one option to display and that option is 'Mobile' then select it
|
||||
if (
|
||||
newValue.length == 1 &&
|
||||
newValue.findIndex((answer) => answer.Name == "Mobile") != -1
|
||||
) {
|
||||
this.selectedValues = "Mobile";
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
isMobileOnly: {
|
||||
handler(newValue) {
|
||||
if (newValue) {
|
||||
|
|
|
|||
|
|
@ -17,15 +17,15 @@
|
|||
@click-event="openModal"
|
||||
aria-label="Modal window" />
|
||||
</div>
|
||||
<textBlock
|
||||
:customText="mobileFeeText"
|
||||
cmsWidgetName="MobileFeeDisclaimerWidget"
|
||||
typeStyle="caption" />
|
||||
<div v-show="errorMessage" class="row my-1 form-test-error">
|
||||
<span class="d-inline-flex small mt-0 center-error-message" role="alert">
|
||||
{{ errorMessage }}
|
||||
</span>
|
||||
</div>
|
||||
<textBlock
|
||||
:customText="mobileFeeText"
|
||||
cmsWidgetName="MobileFeeDisclaimerWidget"
|
||||
typeStyle="caption" />
|
||||
</div>
|
||||
<modal
|
||||
:ref="modalName"
|
||||
|
|
@ -37,7 +37,8 @@
|
|||
<addressQuestions
|
||||
ref="addressQuestions"
|
||||
v-model="internalModel.addressQuestions"
|
||||
captureApartmentNumberOrBusinessName="true" />
|
||||
captureApartmentNumberOrBusinessName="true"
|
||||
preserveCityAndStateOnReset="true" />
|
||||
<vehicleProtectedQuestion
|
||||
ref="vehicleProtectedQuestion"
|
||||
v-model="internalModel.isVehicleProtected"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="vin-information">
|
||||
<div class="vin-toggle mt-2" :class="[isActive ? 'active' : '']" @click="toggleClass()">
|
||||
<div class="vin-toggle" :class="[isActive ? 'active' : '']" @click="toggleClass()">
|
||||
<textLink linkType="text" href="#!" :text="WhereCanIFindMyVINHeadline" />
|
||||
</div>
|
||||
<div class="vin-info">
|
||||
|
|
|
|||
|
|
@ -36,12 +36,12 @@
|
|||
alertClass="alert-danger" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<vinInformation />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-2">
|
||||
<div class="row mb-0 mt-4">
|
||||
<div class="col">
|
||||
<textboxQuestion
|
||||
cmsWidgetName="ServiceZipQuestionWidget"
|
||||
|
|
@ -52,7 +52,7 @@
|
|||
validationRules="zip-required|zip-format" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-2">
|
||||
<div class="row mt-4">
|
||||
<div class="col">
|
||||
<textboxQuestion
|
||||
cmsWidgetName="EmailAddressQuestionWidget"
|
||||
|
|
|
|||
|
|
@ -143,18 +143,18 @@ export default {
|
|||
false
|
||||
);
|
||||
|
||||
if (response.data) {
|
||||
if (response.data.sessionKey && skey === 0) {
|
||||
if (response?.data) {
|
||||
if (response?.data.sessionKey && skey === 0) {
|
||||
setCookieProperties(
|
||||
{ [cookieNames.SESSION_KEY]: response.data.sessionKey },
|
||||
{ [cookieNames.SESSION_KEY]: response?.data.sessionKey },
|
||||
{
|
||||
useDefaultFunnelCookieAttributes: false,
|
||||
}
|
||||
);
|
||||
}
|
||||
if (response.data.sessionId && sid === "00000000-0000-0000-0000-000000000000") {
|
||||
if (response?.data.sessionId && sid === "00000000-0000-0000-0000-000000000000") {
|
||||
setCookieProperties(
|
||||
{ [cookieNames.SESSION_ID]: response.data.sessionId },
|
||||
{ [cookieNames.SESSION_ID]: response?.data.sessionId },
|
||||
{
|
||||
maxAge: 60 * 30, // 30 minutes
|
||||
}
|
||||
|
|
|
|||
|
|
@ -727,12 +727,21 @@ export const actions = {
|
|||
experimentsForUser: experimentsForUser,
|
||||
};
|
||||
|
||||
return globalMethods.callHttpClient({
|
||||
method: endpoints.LogPageView.method,
|
||||
endpoint: endpoints.LogPageView.url,
|
||||
payload: payload,
|
||||
logApiCall: false,
|
||||
});
|
||||
return globalMethods
|
||||
.callHttpClient({
|
||||
method: endpoints.LogPageView.method,
|
||||
endpoint: endpoints.LogPageView.url,
|
||||
payload: payload,
|
||||
logApiCall: false,
|
||||
})
|
||||
.then(
|
||||
(response) => {
|
||||
return response;
|
||||
},
|
||||
(error) => {
|
||||
console.log("Analytics Service Error: " + error.data);
|
||||
}
|
||||
);
|
||||
},
|
||||
logCustomEvent(
|
||||
context,
|
||||
|
|
@ -763,12 +772,21 @@ export const actions = {
|
|||
experimentsForUser: experimentsForUser,
|
||||
};
|
||||
|
||||
return globalMethods.callHttpClient({
|
||||
method: endpoints.LogCustomEvent.method,
|
||||
endpoint: endpoints.LogCustomEvent.url,
|
||||
payload: payload,
|
||||
logApiCall: false,
|
||||
});
|
||||
return globalMethods
|
||||
.callHttpClient({
|
||||
method: endpoints.LogCustomEvent.method,
|
||||
endpoint: endpoints.LogCustomEvent.url,
|
||||
payload: payload,
|
||||
logApiCall: false,
|
||||
})
|
||||
.then(
|
||||
(response) => {
|
||||
return response;
|
||||
},
|
||||
(error) => {
|
||||
console.log("Analytics Service Error: " + error.data);
|
||||
}
|
||||
);
|
||||
},
|
||||
initializeSession(context, { userId, sessionId, userAgent, referrer }) {
|
||||
var payload = {
|
||||
|
|
@ -782,12 +800,21 @@ export const actions = {
|
|||
referrer: referrer,
|
||||
};
|
||||
|
||||
return globalMethods.callHttpClient({
|
||||
method: endpoints.InitializeSession.method,
|
||||
endpoint: endpoints.InitializeSession.url,
|
||||
payload: payload,
|
||||
logApiCall: false,
|
||||
});
|
||||
return globalMethods
|
||||
.callHttpClient({
|
||||
method: endpoints.InitializeSession.method,
|
||||
endpoint: endpoints.InitializeSession.url,
|
||||
payload: payload,
|
||||
logApiCall: false,
|
||||
})
|
||||
.then(
|
||||
(response) => {
|
||||
return response;
|
||||
},
|
||||
(error) => {
|
||||
console.log("Analytics Service Error: " + error.data);
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
// Misc Actions
|
||||
|
|
|
|||
Loading…
Reference in a new issue