-
+
@@ -26,14 +65,27 @@ import funnelFooter from "@/common-components/funnel-footer/funnel-footer";
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header";
import customerQuestions from "@/layouts/address-lookup/customer-questions/customer-questions";
+import alert from "@/ux-components/alert/alert";
+import textboxQuestion from "@/common-components/textbox-question/textbox-question";
+
import { Form } from "vee-validate";
+import { defineRule } from "vee-validate";
+import { required } from "@/helpers/validation-rules";
+import { regex } from "@/helpers/validation-rules";
+import { errorMessages } from "@/constants/error-messages";
// Supporting files
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { settleAllPromises } from "@/helpers/layout-helper";
-import { storeActions } from "@/constants/store-actions";
import store from "@/store";
+import { storeActions } from "@/constants/store-actions";
+import { storeMutations } from "@/constants/store-mutations";
+import baseMixin from "@/mixins/base-mixin";
+import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
+import { getDamageString, isGlassAvailableForCarId } from "@/helpers/damage-helper";
+defineRule("service-zip-required", required(errorMessages.SERVICE_ZIP_REQUIRED));
+defineRule("service-zip-format", regex(/(^\d{5}$)|(^\d{5}-\d{4}$)/, errorMessages.SERVICE_ZIP_FORMAT));
export default {
name: "address-lookup",
@@ -53,46 +105,29 @@ export default {
// Call the "next" function to complete the transition to this page.
next((vm) => {
- vm.$refs.funnelHeader.initializeComponent(
- resultMap.cmsContent.FunnelHeaderWidget
- );
- vm.$refs.vehicleBanner.initializeComponent(
- resultMap.cmsContent.VehicleBannerWidget
- );
- vm.$refs.funnelSubHeader.initializeComponent(
- resultMap.cmsContent.FunnelSubHeaderWidget
- );
- vm.$refs.funnelFooter.initializeComponent(
- resultMap.cmsContent.FunnelFooterWidget
- );
- vm.$refs.customerQuestions.initializeComponent([
- resultMap.cmsContent.StreetAddressQuestionWidget,
- resultMap.cmsContent.CityQuestionWidget,
- resultMap.cmsContent.StateQuestionWidget,
- resultMap.cmsContent.ZipQuestionWidget,
- resultMap.cmsContent.AlertVerificationWarningWidget,
- resultMap.cmsContent.AlertNoMatchWarningWidget,
- resultMap.cmsContent.FirstNameQuestionWidget,
- resultMap.cmsContent.LastNameQuestionWidget,
- resultMap.cmsContent.EmailAddressQuestionWidget,
-
- ]
- );
+ vm.setCmsContent(resultMap.cmsContent);
});
},
data() {
return {
customerQuestions: {
addressQuestions: {
- streetAddress: "",
- city: "",
- state: "",
- zip: "",
+ streetAddress: this.getRegistrationAddressFromStore(),
+ city: this.getRegistrationCityFromStore(),
+ state: this.getRegistrationStateFromStore(),
+ zip: this.getRegistrationZipFromStore(),
},
- firstName: "",
- lastName: "",
- emailAddress: "",
- }
+ firstName: this.getRegistrationFirstNameFromStore(),
+ lastName: this.getRegistrationLastNameFromStore(),
+ emailAddress: this.getEmailFromStore(),
+ },
+ serviceZip: this.getServiceZipFromStore(),
+ displayNonServiceableZipAlert: false,
+ displayVinNotFoundAlert: false,
+ displayMatchedDifferentVehicleAlert: false,
+ displayVinLookupByHomeAddressNotAllowedAlert: false,
+ previousCarIdFound: "",
+ customAlertData: {},
}
},
methods: {
@@ -100,9 +135,220 @@ export default {
return store.getters.vehicle.carId !== null;
},
resetDependentState() {
- // Invokes
+ store.commit(storeMutations.UPDATE_REGISTRATION_LICENSE_PLATE, null);
+ store.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES);
+ },
+ backButtonAction() {
+ // route to move backwards
+ this.$router.navigate(
+ this.navigationScenarios.CLICKED_BACK,
+ this.$route
+ );
+ },
+ getRegistrationAddressFromStore() {
+ return store.getters.vehicle.registration.address;
+ },
+ getRegistrationCityFromStore() {
+ return store.getters.vehicle.registration.city;
+ },
+ getRegistrationStateFromStore() {
+ return store.getters.vehicle.registration.state;
+ },
+ getRegistrationZipFromStore() {
+ return store.getters.vehicle.registration.zipCode;
+ },
+ getRegistrationFirstNameFromStore() {
+ return store.getters.vehicle.registration.firstName;
+ },
+ getRegistrationLastNameFromStore() {
+ return store.getters.vehicle.registration.lastName;
+ },
+ getEmailFromStore() {
+ return store.getters.order.customer.emailAddress;
+ },
+ getServiceZipFromStore() {
+ return store.getters.order.serviceLocation.zip;
+ },
+ async forwardButtonAction() {
+ this.resetWarningsAndErrors();
+
+ // Lookup VIN(s) with the provided address
+ const vinLookup = await this.lookupVin(
+ this.customerQuestions.lastName,
+ this.customerQuestions.addressQuestions.streetAddress,
+ this.customerQuestions.addressQuestions.zip,
+ this.customerQuestions.addressQuestions.state
+ );
+
+ if (!vinLookup.data.isStatePermissible) {
+ // State Restrictions forbid lookup by address
+ this.displayVinLookupByHomeAddressNotAllowedAlert = true;
+ this.$refs.funnelFooter.removeLoader();
+ return;
+ }
+
+ // Validate if the original or service zip provided is serviceable
+ const zipValidation = this.serviceZip ? await this.validateZip(this.serviceZip) : await this.validateZip(this.customerQuestions.addressQuestions.zip);
+ if (!zipValidation.data.isServiceable) {
+ this.displayNonServiceableZipAlert = true;
+ this.showServiceZipField = true;
+ this.$refs.funnelFooter.removeLoader();
+ }
+
+ const carEntered = store.getters.vehicle;
+ const carsFound = vinLookup.data.vinVehicles;
+ if (carsFound.length == 0) {
+ // No VINs found
+ this.displayVinNotFoundAlert = true;
+ this.$refs.funnelFooter.removeLoader();
+ return;
+ } else if (carsFound.length == 1) {
+ var carFound = carsFound[0].vehicle;
+
+ if (carEntered.carId == carFound.carId || carFound.carId == this.previousCarIdFound) {
+ // update data
+ this.updateVehicleInfo(carFound.vin, carFound);
+ this.updateCustomerInfo();
+
+ // navigate forward
+ this.navigateForward(carEntered, carsFound);
+ } else {
+ // Display Alert
+ this.customAlertData.vehicleInfo = carFound;
+ this.displayMatchedDifferentVehicleAlert = true;
+
+ // Update button "Continue with..."
+ this.$refs.funnelFooter.updateButtonText(`Continue with ${carFound.year} ${carFound.make} ${carFound.model}`);
+ this.$refs.funnelFooter.removeLoader();
+ }
+
+ this.previousCarIdFound = carFound.carId;
+
+ } else if (vinLookup.data.vinVehicles.length > 1) {
+ this.updateCustomerInfo();
+
+ // navigate forward
+ this.navigateForward(carEntered, carsFound);
+ }
+
},
+ resetWarningsAndErrors() {
+ this.displayVinNotFoundAlert = false;
+ this.displayNonServiceableZipAlert = false;
+ this.displayMatchedDifferentVehicleAlert = false;
+ this.displayVinLookupByHomeAddressNotAllowedAlert = false;
+ },
+ async navigateForward(carEntered, carsFound) {
+ if (carsFound.length == 1) {
+ // get the damage options for the car that was found
+ const carFound = carsFound[0].vehicle;
+ const glassOptions = await baseMixin.methods.dispatchStoreAction(
+ storeActions.GET_DAMAGE_OPTIONS,
+ { carId: carFound.carId }
+ );
+
+ // if the car entered is the same as the car found OR the glass options for the found car match the users damage selections
+ if (carEntered.carId == carFound.carId || isGlassAvailableForCarId(carFound.carId)) {
+ navigateAfterSaveToHeritageFunnel(this.$route);
+ } else {
+ // if not then navigate to the "vehicle-damage" page
+ this.$router.navigateAfterSave(this.navigationScenarios.CLICKED_FORWARD, this.$route, {}, { displayVehicleChangeAlert: true }, {});
+ }
+ } else if (carsFound.length > 1) {
+ // if multiple cars were found
+ if (carsFound.find(car => car.carId === carEntered.carId)) {
+ // and one of them matches the car id entered
+ navigateAfterSaveToHeritageFunnel(this.$route);
+ } else {
+ // and there is no match, navigate to "address-vehicle" page
+ this.$router.navigateAfterSave(this.navigationScenarios.CONTINUING_WITH_MULTIPLE_VEHICLES, this.$route, {}, {}, carsFound);
+ }
+ }
+
+ },
+ validateZip(zip) {
+ return baseMixin.methods.dispatchStoreAction(
+ storeActions.VALIDATE_ZIP,
+ { zip });
+ },
+ lookupVin(lastName, streetAddress, zip, state) {
+ return baseMixin.methods.dispatchStoreAction(
+ storeActions.LOOKUP_VIN_BY_ADDRESS,
+ {
+ licenseLastName: lastName,
+ licenseStreetAddress: streetAddress,
+ licenseZip: zip,
+ licenseState: state
+ }, false
+ );
+ },
+ updateVehicleInfo(vin, vehicleInfo) {
+ store.commit(storeMutations.UPDATE_VEHICLE_VIN, vin);
+ store.commit(storeMutations.UPDATE_YEAR, vehicleInfo.year);
+ store.commit(storeMutations.UPDATE_MAKE, vehicleInfo.make);
+ store.commit(storeMutations.UPDATE_MODEL, vehicleInfo.model);
+ store.commit(storeMutations.UPDATE_STYLE, vehicleInfo.style);
+ store.commit(storeMutations.UPDATE_CAR_ID, vehicleInfo.carId);
+ store.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, vehicleInfo.category);
+ store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, vehicleInfo.imageUrl);
+ store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, vehicleInfo.imageVifNumber);
+ store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, vehicleInfo.imageColor);
+ },
+ updateCustomerInfo() {
+ store.commit(storeMutations.UPDATE_REGISTRATION_ADDRESS, this.customerQuestions.addressQuestions.streetAddress);
+ store.commit(storeMutations.UPDATE_REGISTRATION_CITY, this.customerQuestions.addressQuestions.city);
+ store.commit(storeMutations.UPDATE_REGISTRATION_STATE, this.customerQuestions.addressQuestions.state);
+ store.commit(storeMutations.UPDATE_REGISTRATION_ZIP_CODE, this.customerQuestions.addressQuestions.zipCode);
+ store.commit(storeMutations.UPDATE_REGISTRATION_FIRST_NAME, this.customerQuestions.firstName);
+ store.commit(storeMutations.UPDATE_REGISTRATION_LAST_NAME, this.customerQuestions.lastName);
+ store.commit(storeMutations.UPDATE_SERVICE_LOCATION_ZIP, this.serviceZip);
+ store.commit(storeMutations.UPDATE_CUSTOMER_EMAIL_ADDRESS, this.customerQuestions.email);
+ },
+
+ },
+ computed: {
+ AlertNonServiceableZipHeader(){
+ let zip = this.serviceZip ? this.serviceZip : this.customerQuestions.addressQuestions.zip;
+ let text = this.getCmsContent("AlertNonServiceableZipWidget", "HeadlineText").replaceAll("{custom:serviceZip}", zip);
+ return text;
+ },
+ AlertNonServiceableZipBody(){
+ return this.getCmsContent("AlertNonServiceableZipWidget", "BodyText");
+ },
+ AlertMatchedDifferentVehicleHeader(){
+ let text = this.getCmsContent("AlertMatchedDifferentVehicleWidget", "HeadlineText").replaceAll("{custom:glassText}", getDamageString());
+ return text;
+ },
+ AlertMatchedDifferentVehicleBody(){
+ let content = this.getCmsContent("AlertMatchedDifferentVehicleWidget", "BodyText");
+ content = content.replaceAll("{custom:glassText}", getDamageString());
+ let vinYmmFound = `${this.customAlertData?.vehicleInfo?.year} ${this.customAlertData?.vehicleInfo?.make} ${this.customAlertData?.vehicleInfo?.model}`;
+ let vinYmmExpected = `${store.getters.vehicle.year} ${store.getters.vehicle.make} ${store.getters.vehicle.model}`;
+
+ content = content.replaceAll("{custom:vinYmmFound}", vinYmmFound);
+ content = content.replaceAll("{custom:vinYmmExpected}", vinYmmExpected);
+
+ return content;
+ },
+ },
+ watch: {
+ customerQuestions: {
+ handler(newValue) {
+ // if they modify one of the lookup fields (address, city, state, zip, or lastName), then modify the button text back to “Get my personalized quote”
+ this.$refs.funnelFooter.updateButtonText(this.getCmsContent("FunnelFooterWidget", "ForwardButtonText"));
+ this.showServiceZipField = false;
+ this.resetWarningsAndErrors();
+ },
+ deep: true
+ },
+ serviceZip: {
+ handler(newValue) {
+ // if they modify the service zip, then hide the error message”
+ this.displayNonServiceableZipAlert = false;
+ },
+ }
+
},
components: {
funnelHeader,
@@ -110,6 +356,8 @@ export default {
vehicleBanner,
funnelSubHeader,
customerQuestions,
+ textboxQuestion,
+ alert,
Form
},
};
diff --git a/src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue b/src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue
index 0954caf34..4a772e468 100644
--- a/src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue
+++ b/src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue
@@ -1,36 +1,34 @@
-
-
-
-
-
+
+
+
+
@@ -41,17 +39,17 @@ import textboxQuestion from "@/common-components/textbox-question/textbox-questi
import dropdownQuestion from "@/common-components/dropdown-question/dropdown-question";
import alert from "@/ux-components/alert/alert";
import { applicationConfig } from "@/constants/application-config.js";
-import { computed } from 'vue';
import { defineRule } from "vee-validate";
import { required } from "@/helpers/validation-rules";
+import { regex } from "@/helpers/validation-rules";
import { errorMessages } from "@/constants/error-messages";
-//import store from "@/store";
// DEFINE VALIDATION RULES
defineRule("street-address-required", required(errorMessages.STREET_ADDRESS_REQUIRED));
defineRule("city-required", required(errorMessages.CITY_REQUIRED));
defineRule("state-required", required(errorMessages.STATE_REQUIRED));
defineRule("zip-required", required(errorMessages.ZIP_REQUIRED));
+defineRule("zip-format", regex(/(^\d{5}$)|(^\d{5}-\d{4}$)/, errorMessages.ZIP_FORMAT));
export default ({
name: "address-questions",
@@ -67,19 +65,7 @@ export default ({
}),
},
validationRules: String,
- },
- setup(props, { emit }) {
- // Please do not modify, this "computed" is used to track and report
- // this object's property changes to the parent component
- const addressModel = computed({ // Use computed to wrap the object
- get: () => props.modelValue,
- set: (value) => emit('update:modelValue', value),
- });
-
- return {
- addressModel,
- };
- },
+ },
data() {
return {
showAddressFields: false,
@@ -148,128 +134,130 @@ export default ({
'WY': 'Wyoming',
}
}
- }
+ },
+ addressModel: {
+ get: function() {
+ return this.modelValue;
+ },
+ set: function(newValue) {
+ this.$emit("update:modelValue", newValue);
+ }
+ },
},
methods: {
- initializeComponent(cmsContent) {
- this.$refs.autocomplete.initializeComponent(cmsContent[0].QuestionText);
- this.$refs.city.initializeComponent(cmsContent[1].QuestionText);
- this.$refs.state.initializeComponent(cmsContent[2].QuestionText);
- this.$refs.zip.initializeComponent(cmsContent[3].QuestionText);
+ setupAddressLookup() {
+ const addressField1 = document.getElementById("autocomplete");
+ const self = this;
- // assign alert texts to this component
- this.alertHeadlineVerificationWarning = cmsContent[4].HeadlineText;
- this.alertCopyVerificationWarning = cmsContent[4].BodyText;
+ const apiKey = applicationConfig.GOOGLE_PLACES_API_KEY;
- this.alertHeadlineNoMatchWarning = cmsContent[5].HeadlineText;
- this.alertCopyNoMatchWarning = cmsContent[5].BodyText;
+ this.$loadScript(`https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=places`)
+ .then(() => {
+ // Script is loaded, initialize the autocomplete textbox
+ const autocomplete = new window.google.maps.places.Autocomplete(
+ addressField1,
+ {
+ componentRestrictions: { country: ["us"] },
+ fields: ["address_components"],
+ types: ["geocode"],
+ }
+ );
+
+ // Standard place_changed event handling
+ autocomplete.addListener('place_changed', fillInAddress);
+
+ addressField1.onblur = function() {
+ const hover = document.querySelector(".pac-container .pac-item:hover");
+ // if an item has been clicked, do nothing, otherwise get first solution and use Geocoder to get the place
+ if (hover === null) {
+ const item = document.querySelector(".pac-container .pac-item");
+ if (item != null) {
+ const firstResult = item.textContent;
+ const geocoder = new window.google.maps.Geocoder();
+ geocoder.geocode({
+ address: firstResult
+ }, function (results, status) {
+ if (status === window.google.maps.GeocoderStatus.OK) {
+ fillInAddress(results[0]);
+ self.displayVerificationWarning = true;
+ self.displayNoMatchWarning = false;
+ }
+ });
+ }
+ else {
+ self.addressModel.city = "";
+ self.addressModel.state = "";
+ self.addressModel.zip = "";
+ self.showAddressFields = true;
+ self.displayVerificationWarning = false;
+ self.displayNoMatchWarning = true;
+ }
+ }
+ };
+
+ function fillInAddress(place) {
+ if (!place) {
+ place = autocomplete.getPlace();
+ }
+
+ if (place && place.address_components) {
+ self.addressModel.streetAddress= "";
+ self.showAddressFields = true;
+
+ for (const component of place.address_components) {
+ const componentType = component.types[0];
+
+ switch (componentType) {
+ case "street_number": {
+ self.addressModel.streetAddress = component.long_name;
+ break;
+ }
+ case "route": {
+ self.addressModel.streetAddress += ' ' + component.short_name;
+ break;
+ }
+ case "locality": {
+ self.addressModel.city = component.long_name;
+ break;
+ }
+ case "administrative_area_level_1": {
+ self.addressModel.state = component.short_name;
+ break;
+ }
+ case "postal_code": {
+ self.addressModel.zip = component.long_name;
+ break;
+ }
+
+ }
+ }
+
+ self.displayVerificationWarning = false;
+ self.displayNoMatchWarning = false;
+ }
+ else {
+ self.displayVerificationWarning = true;
+ self.displayNoMatchWarning = false;
+ }
+ }
+ })
+ .catch(() => {
+ // Failed to fetch script
+ console.log("Unable to load Google Places API script");
+ });
}
},
mounted() {
-
- const addressField1 = document.getElementById("autocomplete");
- const self = this;
-
- const apiKey = applicationConfig.GOOGLE_PLACES_API_KEY;
-
- this.$loadScript(`https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=places`)
- .then(() => {
- // Script is loaded, initialize the autocomplete textbox
- const autocomplete = new window.google.maps.places.Autocomplete(
- addressField1,
- {
- componentRestrictions: { country: ["us"] },
- fields: ["address_components"],
- types: ["address"],
- }
- );
-
- // Standard place_changed event handling
- autocomplete.addListener('place_changed', fillInAddress);
-
- addressField1.onblur = function() {
- const hover = document.querySelector(".pac-container .pac-item:hover");
-
- // if an item has been clicked, do nothing, otherwise get first solution and use Geocoder to get the place
- if (hover === null) {
- const item = document.querySelector(".pac-container .pac-item");
- if (item != null) {
- const firstResult = item.textContent;
- const geocoder = new window.google.maps.Geocoder();
- geocoder.geocode({
- address: firstResult
- }, function (results, status) {
- if (status === window.google.maps.GeocoderStatus.OK) {
- fillInAddress(results[0]);
- self.displayVerificationWarning = true;
- self.displayNoMatchWarning = false;
- }
- });
- }
- else {
- self.addressModel.city = "";
- self.addressModel.state = "";
- self.addressModel.zip = "";
- self.showAddressFields = true;
- self.displayVerificationWarning = false;
- self.displayNoMatchWarning = true;
- }
-
-
- }
- };
-
- function fillInAddress(place) {
- if (!place) {
- place = autocomplete.getPlace();
- }
-
- if (place && place.address_components) {
- self.addressModel.streetAddress= "";
- self.showAddressFields = true;
-
- for (const component of place.address_components) {
- const componentType = component.types[0];
-
- switch (componentType) {
- case "street_number": {
- self.addressModel.streetAddress = component.long_name;
- break;
- }
- case "route": {
- self.addressModel.streetAddress += ' ' + component.short_name;
- break;
- }
- case "locality": {
- self.addressModel.city = component.long_name;
- break;
- }
- case "administrative_area_level_1": {
- self.addressModel.state = component.short_name;
- break;
- }
- case "postal_code": {
- self.addressModel.zip = component.long_name;
- break;
- }
-
- }
- }
-
- self.displayVerificationWarning = false;
- self.displayNoMatchWarning = false;
- }
- else {
- self.displayVerificationWarning = true;
- self.displayNoMatchWarning = false;
- }
- }
- })
- .catch(() => {
- // Failed to fetch script
- console.log("Unable to load Google Places API script");
- });
+ this.setupAddressLookup();
},
+ watch: {
+ addressModel: {
+ handler(newValue){
+ this.displayNoMatchWarning = false;
+ },
+ deep: true
+ }
+ },
components: {
textboxQuestion,
dropdownQuestion,
diff --git a/src/layouts/address-lookup/customer-questions/customer-questions.vue b/src/layouts/address-lookup/customer-questions/customer-questions.vue
index 7fa324f91..e1c505c9e 100644
--- a/src/layouts/address-lookup/customer-questions/customer-questions.vue
+++ b/src/layouts/address-lookup/customer-questions/customer-questions.vue
@@ -1,18 +1,18 @@
-
+
@@ -20,12 +20,10 @@
+
\ No newline at end of file
diff --git a/src/layouts/vehicle-damage/damage-location-question/damage-location-question.vue b/src/layouts/vehicle-damage/damage-location-question/damage-location-question.vue
index 690e7df78..16d67b3ee 100644
--- a/src/layouts/vehicle-damage/damage-location-question/damage-location-question.vue
+++ b/src/layouts/vehicle-damage/damage-location-question/damage-location-question.vue
@@ -6,6 +6,7 @@
:answers="answersToDisplay"
:groupName="groupName"
buttonType="listCard"
+ isRequired
v-model="selectedValues"
validationRules="damage-location-required"
/>
@@ -30,11 +31,7 @@ export default ({
}
},
props: {
- isMultiSelect: Boolean,
modelValue: Array,
- isAvailable: Boolean,
- filterByVehicleCategory: Boolean,
- name: String,
groupName: String,
cmsWidgetName: String,
},
diff --git a/src/layouts/vehicle-damage/replace-options-question/replace-options-question.vue b/src/layouts/vehicle-damage/replace-options-question/replace-options-question.vue
index e2a6bb426..53ef1e2fa 100644
--- a/src/layouts/vehicle-damage/replace-options-question/replace-options-question.vue
+++ b/src/layouts/vehicle-damage/replace-options-question/replace-options-question.vue
@@ -11,6 +11,7 @@
v-model="selectedValues"
:validationRules="validationRules"
:suppressError="suppressError"
+ :isRequired=isRequired
/>
@@ -36,6 +37,7 @@ export default ({
validationRules: String,
suppressError: Boolean,
cmsWidgetName: String,
+ isRequired: Boolean,
},
methods: {
initializeComponent(replaceOptions){
diff --git a/src/layouts/vehicle-damage/side-door-options/side-door-options.vue b/src/layouts/vehicle-damage/side-door-options/side-door-options.vue
index a79cdf49f..b4df1121e 100644
--- a/src/layouts/vehicle-damage/side-door-options/side-door-options.vue
+++ b/src/layouts/vehicle-damage/side-door-options/side-door-options.vue
@@ -10,6 +10,7 @@
buttonType="listCard"
v-model="selectedDoorSidesValues"
validationRules="damage-side-required"
+ isRequired
/>
@@ -22,6 +23,7 @@
filterByVehicleCategory
v-model="selectedDriverSideReplaceOptionsValues"
validationRules="driver-side-options-required"
+ isRequired
/>
diff --git a/src/layouts/vehicle-damage/vehicle-damage.spec.js b/src/layouts/vehicle-damage/vehicle-damage.spec.js
index 7b28e4bb5..9a9f7e6d7 100644
--- a/src/layouts/vehicle-damage/vehicle-damage.spec.js
+++ b/src/layouts/vehicle-damage/vehicle-damage.spec.js
@@ -17,6 +17,7 @@ import { storeMutations } from "@/constants/store-mutations";
import store from "@/store";
import { validate } from "vee-validate";
import { damageLocationsSelected } from "@/constants/damage-locations-selected.js";
+import { routerParams } from "@/router/router-constants/router-params";
// Mock our module for promises.
jest.mock("@/helpers/layout-helper.js", () => ({
@@ -703,6 +704,57 @@ describe("vehicle-damage.vue", () => {
});
});
+describe("vehicle-damage.vue", () => {
+ test("when displayVehicleChangeAlert router params is true, the alert: 'vehicleChangeAlert' should be visible", () => {
+ // Arrange & Act
+ const { wrapper } = setupMocks({
+ mountOptionsMockData: {
+ route: {
+ params: {
+ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true
+ }
+ }
+ }
+ });
+ // Assert
+ expect(wrapper.findComponent({ref: 'vehicleChangeAlert'}).isVisible()).toBe(true);
+ })
+});
+
+describe("vehicle-damage.vue", () => {
+ test("when displayVehicleChangeAlert router params is false, the alert: 'vehicleChangeAlert' should not be visible", () => {
+ // Arrange & Act
+ const { wrapper } = setupMocks({
+ mountOptionsMockData: {
+ route: {
+ params: {
+ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: false
+ }
+ }
+ }
+ });
+ // Assert
+ expect(wrapper.findComponent({ref: 'vehicleChangeAlert'}).isVisible()).toBe(false);
+ })
+});
+
+describe("vehicle-damage.vue", () => {
+ test("when displayVehicleChangeAlert router params is undefined, the alert: 'vehicleChangeAlert' should not be visible", () => {
+ // Arrange & Act
+ const { wrapper } = setupMocks({
+ mountOptionsMockData: {
+ route: {
+ params: {
+ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: undefined
+ }
+ }
+ }
+ });
+ // Assert
+ expect(wrapper.findComponent({ref: 'vehicleChangeAlert'}).isVisible()).toBe(false);
+ })
+});
+
// THE FOLLOWING TEST IS NOT NECESSARILY REQUIRED FOR COVERAGE
// BUT KEEP FOR AN EXAMPLE OF A VALIDATION TEST
//
@@ -734,32 +786,41 @@ describe("vehicle-damage.vue", () => {
});
-function setupMocks({
- pageHeaderWidgetHeaderText = {},
- mountOptionsMockData = {
+function setupMocks({pageHeaderWidgetHeaderText, mountOptionsMockData}) {
+ var pageHeaderWidgetHeaderTextDefault = {};
+ var mountOptionsMockDataDefault = {
router: {
navigate: jest.fn(),
},
+ route: {
+ params: {
+ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: false
+ }
+ },
store: {
getters: {
vehicle: {},
- payment: { insuranceCoverage: { isVerified: false } },
+ payment: {
+ insuranceCoverage: {
+ isVerified: false
+ }
+ },
},
},
- },
-}) {
+ };
+ // Combine parameters with default values
+ pageHeaderWidgetHeaderText = Object.assign(pageHeaderWidgetHeaderTextDefault, pageHeaderWidgetHeaderText);
+ mountOptionsMockData = Object.assign(mountOptionsMockDataDefault, mountOptionsMockData);
//Mock api responses
- baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn();
+ baseMixin.methods.dispatchStoreAction = jest.fn();
const apiResponses = {
cmsContent: {
FunnelSubHeaderWidget: pageHeaderWidgetHeaderText,
VehicleBannerWidget: {
- GenericVehicleImage:
- "https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/blurred-image.jpg?sfvrsn=a6ce3034_3",
+ GenericVehicleImage: "https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/blurred-image.jpg?sfvrsn=a6ce3034_3",
},
FunnelHeaderWidget: {
- LogoImage:
- "https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/safelite-logo.svg?sfvrsn=45e7ed06_3",
+ LogoImage: "https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/safelite-logo.svg?sfvrsn=45e7ed06_3",
},
},
damageOptions: {
diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue
index 543a02bef..862abaced 100644
--- a/src/layouts/vehicle-damage/vehicle-damage.vue
+++ b/src/layouts/vehicle-damage/vehicle-damage.vue
@@ -9,49 +9,57 @@