Merge pull request #156 from Safelite/feature/digital/SSR-207
Feature/digital/ssr 207
This commit is contained in:
commit
2146c5e865
6 changed files with 682 additions and 43 deletions
|
|
@ -0,0 +1,77 @@
|
|||
import addressVehiclesQuestion from "@/layouts/address-vehicles/address-vehicles-question/address-vehicles-question.vue";
|
||||
import { shallowMount } from "@vue/test-utils";
|
||||
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||
|
||||
describe("address-vehicles-question.vue", () => {
|
||||
test("Selected vehicle is emitted upon selection", async () => {
|
||||
//Arrange
|
||||
const { wrapper } = setupMocks({ modelValueProp: "2020 Audi A6" });
|
||||
const vehicleToSelect = "2016 Jaguar F-Type";
|
||||
|
||||
//Act
|
||||
wrapper.setValue({ selectedVehicle: vehicleToSelect });
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
//Assert
|
||||
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([
|
||||
{ selectedVehicle: "2016 Jaguar F-Type" },
|
||||
]);
|
||||
});
|
||||
test("Should return content for differentVehicleAlertHeader", () => {
|
||||
// Arrange
|
||||
const wrapper = shallowMount(addressVehiclesQuestion, {
|
||||
mixins: [mockMixin],
|
||||
});
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.differentVehicleAlertHeader).toEqual("FoundWindshieldTestReturn");
|
||||
});
|
||||
test("Should return content for differentVehicleAlertBody", () => {
|
||||
// Arrange
|
||||
const wrapper = shallowMount(addressVehiclesQuestion, {
|
||||
mixins: [mockMixin],
|
||||
propsData: {
|
||||
vehicles: ["1", "2"],
|
||||
modelValue: ["1", "2"],
|
||||
},
|
||||
});
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.differentVehicleAlertBody).toEqual("FoundWindshieldTestReturn");
|
||||
});
|
||||
});
|
||||
|
||||
const mockMixin = {
|
||||
methods: {
|
||||
getCmsContent: jest.fn((contentName) => {
|
||||
if (contentName === "FoundWindshield") {
|
||||
return "FoundWindshieldTestReturn";
|
||||
}
|
||||
return null;
|
||||
}),
|
||||
vehicles: jest.fn(() => {
|
||||
return [{ vehicle: "test" }];
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
function setupMocks({
|
||||
modelValueProp = "TESTCAR",
|
||||
cmsQuestionText = "CMS text goes here",
|
||||
}) {
|
||||
|
||||
const mountOptions = getMountOptions();
|
||||
|
||||
//Mock props
|
||||
mountOptions.propsData = {
|
||||
modelValue: modelValueProp,
|
||||
};
|
||||
|
||||
const wrapper = shallowMount(addressVehiclesQuestion, mountOptions);
|
||||
|
||||
//Mock CMS content
|
||||
const cmsContent = {
|
||||
QuestionText: cmsQuestionText,
|
||||
};
|
||||
return { wrapper, cmsContent };
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
<template>
|
||||
<alert
|
||||
ref="differentVehicleAlert"
|
||||
v-if="isCarIdDifferent"
|
||||
class="my-4"
|
||||
cmsWidgetName="FoundWindshield"
|
||||
:manualHeadline="differentVehicleAlertHeader"
|
||||
:manualCopy="differentVehicleAlertBody"
|
||||
alertClass="alert-warning"
|
||||
v-bind:isDismissible="false"
|
||||
id="address-vehicles-question-alert" />
|
||||
<buttonQuestion
|
||||
class="address-vehicles-question"
|
||||
ref="addressVehiclesQuestion"
|
||||
buttonTypeString="listButton"
|
||||
groupName="ChooseAddressVehicle"
|
||||
:questionText="questionText"
|
||||
:answers="vehicles"
|
||||
v-model="selectedVehicleVin"
|
||||
isRequired
|
||||
:validation-rules="validationRules" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import buttonQuestion from "@/digital-components/button-question/button-question";
|
||||
import alert from "@/ux-components/alert/alert";
|
||||
// Supporting files
|
||||
import { getDamageString } from "@/helpers/damage-helper";
|
||||
export default {
|
||||
name: "address-vehicles-question",
|
||||
props: {
|
||||
vehicles: Array,
|
||||
modelValue: String,
|
||||
cmsWidgetName: String,
|
||||
validationRules: String,
|
||||
isCarIdDifferent: Boolean,
|
||||
},
|
||||
computed: {
|
||||
differentVehicleAlertHeader() {
|
||||
return this.getCmsContent("FoundWindshield", "HeadlineText").replaceAll(
|
||||
"{custom:damage}",
|
||||
getDamageString()
|
||||
);
|
||||
},
|
||||
differentVehicleAlertBody() {
|
||||
return this.getCmsContent("FoundWindshield", "BodyText")
|
||||
.replaceAll("{custom:damage}", getDamageString())
|
||||
.replaceAll("{custom:vinlookupYear}", this.selectedVehicle?.vehicle.year)
|
||||
.replaceAll("{custom:vinlookupMake}", this.selectedVehicle?.vehicle.make)
|
||||
.replaceAll("{custom:vinlookupModel}", this.selectedVehicle?.vehicle.model);
|
||||
},
|
||||
questionText() {
|
||||
return this.getCmsContent("VehicleConfirmationQuestion", "QuestionText");
|
||||
},
|
||||
selectedVehicleVin: {
|
||||
get: function () {
|
||||
return this.modelValue;
|
||||
},
|
||||
set: function (newValue) {
|
||||
this.$emit("update:modelValue", newValue);
|
||||
},
|
||||
},
|
||||
selectedVehicle() {
|
||||
// this computed is only needed for the computed differentVehicleAlertBody text above
|
||||
return this.vehicles.find(({ vin }) => vin === this.selectedVehicleVin);
|
||||
},
|
||||
},
|
||||
components: {
|
||||
buttonQuestion,
|
||||
alert,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.address-vehicles-question {
|
||||
.question-text {
|
||||
margin-bottom: 0.5rem;
|
||||
& > span {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
#address-vehicles-question-alert p {
|
||||
margin-bottom: 0 !important; // Overrides extra margin-bottom on alert body text
|
||||
}
|
||||
</style>
|
||||
252
src/layouts/address-vehicles/address-vehicles.spec.js
Normal file
252
src/layouts/address-vehicles/address-vehicles.spec.js
Normal file
|
|
@ -0,0 +1,252 @@
|
|||
import addressVehicles from "@/layouts/address-vehicles/address-vehicles";
|
||||
import { settleAllPromises } from "@/helpers/layout-helper.js";
|
||||
import { shallowMount } from "@vue/test-utils";
|
||||
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||
import { useMainStore } from "@/store";
|
||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||
|
||||
jest.mock("@/helpers/damage-helper", () => ({
|
||||
isGlassAvailableForCarId: jest.fn().mockImplementation(() => true),
|
||||
getDamageString: jest.fn(),
|
||||
}));
|
||||
|
||||
// Mock fetchCmsContentForPage
|
||||
jest.mock("@/helpers/cms-content-helper", () => ({
|
||||
fetchCmsContentForPage: jest.fn(),
|
||||
doesCopyContainRouterLink: jest.fn(),
|
||||
splitCopyOnCMSPlaceHolder: jest.fn().mockImplementation(() => "test"),
|
||||
getRouterLinkRouteFromCopy: jest.fn(),
|
||||
getRouterLinkDisplayTextFromCopy: jest.fn(),
|
||||
splitCMSCopyOnParagraphTag: jest.fn(),
|
||||
}));
|
||||
|
||||
// Mock our module for promises.
|
||||
jest.mock("@/helpers/layout-helper.js", () => ({
|
||||
settleAllPromises: jest.fn(),
|
||||
}));
|
||||
|
||||
describe("address-vehicles.vue", () => {
|
||||
test("Should navigate to CLICKED_BACK if backButtonAction is run", async () => {
|
||||
// Arrange
|
||||
const { wrapper } = setupMocks({});
|
||||
|
||||
// Act
|
||||
await wrapper.vm.backButtonAction();
|
||||
|
||||
//Assert
|
||||
expect(wrapper.vm.$router.navigate).toBeCalled();
|
||||
});
|
||||
|
||||
test("navigateForward should be called if forwardButtonAction is run", async () => {
|
||||
// Arrange
|
||||
const { wrapper } = setupMocks({});
|
||||
const lookupVinResponse = {
|
||||
data: {
|
||||
carId: "456"
|
||||
}
|
||||
}
|
||||
|
||||
wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
|
||||
wrapper.vm.$refs.siteFooter.removeLoader = jest.fn();
|
||||
wrapper.vm.lookupVin = jest.fn(() => Promise.resolve(lookupVinResponse));
|
||||
wrapper.vm.$router.navigate = jest.fn();
|
||||
wrapper.vm.saveVin = jest.fn().mockImplementation(() => {});
|
||||
wrapper.vm.navigateForward = jest.fn().mockImplementation(() => {});
|
||||
|
||||
// Act
|
||||
await wrapper.setData({
|
||||
selectedVehicleVin: "5NMS3CADXLH233004",
|
||||
});
|
||||
|
||||
await wrapper.vm.forwardButtonAction();
|
||||
wrapper.vm.$nextTick();
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.navigateForward).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test("Should return out of forwardButtonAction is lookupVin returns an error", async () => {
|
||||
// Arrange
|
||||
const { wrapper } = setupMocks({});
|
||||
wrapper.vm.navigateForwardWithSingleCarMatch = jest.fn();
|
||||
|
||||
const lookupVinResponse = {
|
||||
error: "there is an error",
|
||||
};
|
||||
|
||||
wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
|
||||
wrapper.vm.$refs.siteFooter.removeLoader = jest.fn();
|
||||
wrapper.vm.lookupVin = jest.fn(() => Promise.reject(lookupVinResponse));
|
||||
wrapper.vm.$router.navigate = jest.fn();
|
||||
wrapper.vm.saveVin = jest.fn().mockImplementation(() => {});
|
||||
|
||||
// Act
|
||||
await wrapper.setData({
|
||||
selectedVehicleVin: "5NMS3CADXLH233004",
|
||||
});
|
||||
|
||||
await wrapper.vm.forwardButtonAction();
|
||||
wrapper.vm.$nextTick();
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.forwardButtonAction).toReturn;
|
||||
});
|
||||
|
||||
test("Should navigate to CLICKED_FORWARD scenario if carId is different and selected glass not available for vehicle on navigateForward", async () => {
|
||||
// Arrange
|
||||
const { wrapper } = setupMocks({});
|
||||
wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
|
||||
wrapper.vm.$router.navigate = jest.fn();
|
||||
|
||||
// Act
|
||||
await wrapper.setData({
|
||||
selectedVehicleVin: "5NMS3CADXLH233004",
|
||||
isSelectedGlassAvailableForVehicle: false,
|
||||
isCarIdDifferent: true,
|
||||
});
|
||||
await wrapper.vm.navigateForward();
|
||||
|
||||
//Assert
|
||||
expect(wrapper.vm.$router.navigate).toBeCalledTimes(1);
|
||||
});
|
||||
|
||||
test("carId is not different on navigateForward (car was found) => Should handle navigating forward with car match", async () => {
|
||||
// Arrange
|
||||
const { wrapper } = setupMocks({});
|
||||
wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
|
||||
wrapper.vm.navigateForwardWithSingleCarMatch = jest.fn();
|
||||
|
||||
// Act
|
||||
await wrapper.setData({
|
||||
isCarIdDifferent: false,
|
||||
});
|
||||
await wrapper.vm.navigateForward();
|
||||
|
||||
//Assert
|
||||
expect(wrapper.vm.navigateForwardWithSingleCarMatch).toBeCalledTimes(1);
|
||||
|
||||
});
|
||||
|
||||
test("Should return true for valid page requisites if carId exists", async () => {
|
||||
// Arrange
|
||||
const { wrapper } = setupMocks({});
|
||||
useMainStore().order.vehicle.carId = "CR00000395";
|
||||
|
||||
// Act
|
||||
addressVehicles.beforeRouteEnter.call(
|
||||
wrapper.vm,
|
||||
{ query: { issPage: "address-vehicles" } },
|
||||
undefined,
|
||||
(c) => c(wrapper.vm)
|
||||
);
|
||||
|
||||
let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
||||
|
||||
// Assert
|
||||
expect(arePagePrerequisitesValid).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
function setupMocks({
|
||||
route = null,
|
||||
lookupVehicleByVinResponse,
|
||||
})
|
||||
{
|
||||
useMainStore().applicationUser = {
|
||||
pageData: {
|
||||
"address-vehicles":
|
||||
[
|
||||
{
|
||||
vehicle: {
|
||||
carId: "CR00069309",
|
||||
category: "SUV",
|
||||
imageUrl:
|
||||
"https://dbhdyzvm8lm25.cloudfront.net/color_0320_032/MY2020/13769/13769_cc0320_032_WW8.jpg",
|
||||
imageVifColor: "white",
|
||||
imageVifNumber: "13769",
|
||||
make: "Hyundai",
|
||||
model: "Santa Fe",
|
||||
style: "4 door utility",
|
||||
year: 2020,
|
||||
},
|
||||
vin: "5NMS3CADXLH233004",
|
||||
},
|
||||
],
|
||||
}
|
||||
};
|
||||
|
||||
useMainStore().lookupVehicleByVin = jest.fn().mockImplementation(() => {
|
||||
return Promise.resolve({
|
||||
data: lookupVehicleByVinResponse
|
||||
? lookupVehicleByVinResponse : {
|
||||
vehicle: {
|
||||
carId: "CARID"
|
||||
},
|
||||
},
|
||||
})
|
||||
});
|
||||
|
||||
const mountOptions = getMountOptions({
|
||||
route: route ? route : undefined,
|
||||
router: {
|
||||
navigate: jest.fn(),
|
||||
},
|
||||
mainStore: {
|
||||
order: {
|
||||
vehicle: {
|
||||
carId: "CR00069309",
|
||||
category: "SUV",
|
||||
imageUrl:
|
||||
"https://dbhdyzvm8lm25.cloudfront.net/color_0320_032/MY2020/13769/13769_cc0320_032_WW8.jpg",
|
||||
imageVifColor: "white",
|
||||
imageVifNumber: "13769",
|
||||
make: "Hyundai",
|
||||
model: "Santa Fe",
|
||||
style: "4 door utility",
|
||||
year: 2020,
|
||||
},
|
||||
vin: "5NMS3CADXLH233004",
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
const apiResponses = {
|
||||
cmsContent: {},
|
||||
};
|
||||
|
||||
settleAllPromises.mockImplementation(() => apiResponses);
|
||||
fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
|
||||
|
||||
|
||||
//Mock props
|
||||
const mockMixin = {
|
||||
methods: {
|
||||
getCmsContent: jest.fn((contentName) => {
|
||||
if (contentName === "FoundMultipleVehicles") {
|
||||
return "FoundMultipleVehiclesTestReturn";
|
||||
}
|
||||
if (contentName === "ProvideVinAlert") {
|
||||
return "ProvideVinAlertTestReturn";
|
||||
}
|
||||
return null;
|
||||
}),
|
||||
},
|
||||
computed: {
|
||||
dynamicStrings() {
|
||||
return { ROUTER_LINK: "routerLink:" };
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
mountOptions.mixins = [mockMixin];
|
||||
|
||||
const wrapper = shallowMount(addressVehicles, mountOptions);
|
||||
|
||||
wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => "");
|
||||
wrapper.vm.setCmsContent = jest.fn();
|
||||
wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
|
||||
wrapper.vm.$refs.siteFooter.removeLoader = jest.fn();
|
||||
|
||||
return { wrapper };
|
||||
}
|
||||
|
|
@ -2,66 +2,103 @@
|
|||
<Form
|
||||
@submit="onSubmit"
|
||||
@invalidSubmit="onInvalidSubmit"
|
||||
ref="theForm"
|
||||
v-slot="{ meta }"
|
||||
>
|
||||
<div class="page-container-grouped-styles overflow-auto">
|
||||
<siteHeader
|
||||
cmsWidgetName="SiteHeaderWidget"
|
||||
/>
|
||||
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
||||
<vehicleBanner
|
||||
cmsWidgetName="VehicleBannerWidget"
|
||||
:displayGenericVehicleImage="false"
|
||||
/>
|
||||
<siteSubHeader
|
||||
cmsWidgetName="SiteSubHeaderWidget"
|
||||
<siteSubHeader cmsWidgetName="SiteSubHeaderWidget" />
|
||||
<alert
|
||||
cmsWidgetName="FoundMultipleVehicles"
|
||||
ref="alertFoundMultipleVehicles"
|
||||
class="my-5"
|
||||
alertClass="alert-warning"
|
||||
:manualHeadline="AlertFoundMultipleVehiclesHeader"
|
||||
manualCopy=""
|
||||
v-bind:isDismissible="false"
|
||||
id="multiple-vehicles-alert"
|
||||
/>
|
||||
<div class="fade-on-route-transition sub-container make-tall mt-5">
|
||||
<p>Placeholder for address-vehicles page</p>
|
||||
|
||||
<siteFooter
|
||||
cmsWidgetName="SiteFooterWidget"
|
||||
:isForwardActionDisabled="!meta.valid"
|
||||
@backClicked="backButtonAction"
|
||||
@forwardClicked="forwardButtonAction"
|
||||
ref="siteFooter"
|
||||
/>
|
||||
<addressVehiclesQuestion
|
||||
ref="addressVehiclesQuestion"
|
||||
cmsWidgetName="VehicleConfirmationQuestion"
|
||||
:vehicles="VehiclesForQuestions"
|
||||
validationRules="vehicle-required"
|
||||
v-model="selectedVehicleVin"
|
||||
:isCarIdDifferent="isCarIdDifferent"
|
||||
/>
|
||||
<div
|
||||
class="alert-provide-vin my-3"
|
||||
v-if="splitAlertProvideVinBodyForLink.length"
|
||||
>
|
||||
<span v-for="copy in splitAlertProvideVinBodyForLink" :key="copy">
|
||||
<span v-if="doesCopyContainRouterLink(copy)" class="text-body">
|
||||
<router-link
|
||||
:to="{
|
||||
query: { issPage: `${getRouterLinkRouteFromCopy(copy)}` },
|
||||
name: 'root',
|
||||
}"
|
||||
>{{ getRouterLinkDisplayTextFromCopy(copy) }}</router-link
|
||||
>
|
||||
</span>
|
||||
<span v-else class="m-0 text-body" v-html="copy"></span>
|
||||
</span>
|
||||
</div>
|
||||
<siteFooter
|
||||
cmsWidgetName="SiteFooterWidget"
|
||||
:isForwardActionDisabled="!meta.valid"
|
||||
@backClicked="backButtonAction"
|
||||
@forwardClicked="forwardButtonAction"
|
||||
ref="siteFooter"
|
||||
/>
|
||||
</div>
|
||||
</Form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Import Supporting Files
|
||||
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
|
||||
import { settleAllPromises } from '@/helpers/layout-helper';
|
||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||
import { settleAllPromises } from "@/helpers/layout-helper";
|
||||
import { useMainStore } from "@/store";
|
||||
import { issPageValues } from "@/router/router-constants/issPage-values";
|
||||
import { errorMessages } from "@/constants/error-messages";
|
||||
import { required } from "@/helpers/validation-rules";
|
||||
import { Form, defineRule } from "vee-validate";
|
||||
import { isGlassAvailableForCarId } from "@/helpers/damage-helper";
|
||||
import {
|
||||
doesCopyContainRouterLink,
|
||||
splitCopyOnCMSPlaceHolder,
|
||||
getRouterLinkRouteFromCopy,
|
||||
getRouterLinkDisplayTextFromCopy,
|
||||
} from "@/helpers/cms-content-helper";
|
||||
import { routerParams } from "@/router/router-constants/router-params";
|
||||
import vinPagesMixin from "@/mixins/vin-pages-mixin";
|
||||
|
||||
// Import Component
|
||||
import baseFormMixin from '@/mixins/base-form-mixin';
|
||||
import { Form } from 'vee-validate';
|
||||
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
|
||||
import siteHeader from '@/iss-components/site-header/site-header.vue';
|
||||
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header.vue';
|
||||
import vehicleBanner from '@/iss-components/vehicle-banner/vehicle-banner.vue';
|
||||
import baseFormMixin from "@/mixins/base-form-mixin";
|
||||
import siteFooter from "@/iss-components/site-footer/site-footer.vue";
|
||||
import siteHeader from "@/iss-components/site-header/site-header.vue";
|
||||
import siteSubHeader from "@/iss-components/site-sub-header/site-sub-header.vue";
|
||||
import vehicleBanner from "@/iss-components/vehicle-banner/vehicle-banner.vue";
|
||||
import alert from "@/ux-components/alert/alert";
|
||||
import addressVehiclesQuestion from "@/layouts/address-vehicles/address-vehicles-question/address-vehicles-question";
|
||||
|
||||
// DEFINE VALIDATION RULES
|
||||
defineRule("vehicle-required", required(errorMessages.VEHICLE_REQUIRED));
|
||||
|
||||
export default {
|
||||
name: 'capability-questions',
|
||||
mixins: [baseFormMixin],
|
||||
components: {
|
||||
siteFooter,
|
||||
siteHeader,
|
||||
siteSubHeader,
|
||||
Form,
|
||||
vehicleBanner,
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
name: "address-vehicles",
|
||||
mixins: [baseFormMixin, vinPagesMixin],
|
||||
async beforeRouteEnter(to, from, next) {
|
||||
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
||||
|
||||
// Settle promises and get results
|
||||
const promiseResultMap = [
|
||||
{
|
||||
resultKey: 'cmsContent',
|
||||
resultKey: "cmsContent",
|
||||
promise: cmsContentPromise,
|
||||
},
|
||||
];
|
||||
|
|
@ -72,18 +109,159 @@ export default {
|
|||
vm.setCmsContent(resultMap.cmsContent);
|
||||
});
|
||||
},
|
||||
props: {
|
||||
validationRules: String,
|
||||
},
|
||||
setup() {
|
||||
const mainStore = useMainStore();
|
||||
|
||||
return { mainStore };
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectedVehicleVin: "",
|
||||
isCarIdDifferent: false,
|
||||
isSelectedGlassAvailableForVehicle: true,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
vehicleCount() {
|
||||
return this.VehiclesForQuestions.length;
|
||||
},
|
||||
AlertFoundMultipleVehiclesHeader() {
|
||||
return this.getCmsContent(
|
||||
"FoundMultipleVehicles",
|
||||
"HeadlineText"
|
||||
).replaceAll("{custom:vehicleCount}", this.vehicleCount);
|
||||
},
|
||||
AlertProvideVinBody() {
|
||||
return this.getCmsContent("ProvideVinAlert", "BodyText");
|
||||
},
|
||||
splitAlertProvideVinBodyForLink() {
|
||||
// Splits content when brackets are found in text so that text can be looped through and router-link can be injected when needed
|
||||
return this.splitCopyOnCMSPlaceHolder(this.AlertProvideVinBody);
|
||||
},
|
||||
VehiclesForQuestions() {
|
||||
// Map API result data, to address-vehicles data structure
|
||||
const mappedData = this.VehiclesFromApi.map((v) => {
|
||||
const maskSymbol = "X";
|
||||
const vinStart = maskSymbol.repeat(v.vin.length - 6);
|
||||
const vinEnd = v.vin.substring(v.vin.length - 6);
|
||||
return {
|
||||
vin: v.vin,
|
||||
vehicle: v.vehicle,
|
||||
Text: v.vehicle.year + " " + v.vehicle.make + " " + v.vehicle.model,
|
||||
Name: v.vin,
|
||||
SubText: "VIN " + vinStart + vinEnd,
|
||||
};
|
||||
});
|
||||
return mappedData;
|
||||
},
|
||||
VehiclesFromApi() {
|
||||
return useMainStore().pageData(issPageValues.ADDRESS_VEHICLES);
|
||||
},
|
||||
selectedVehicle() {
|
||||
return this.VehiclesForQuestions.find(
|
||||
({ vin }) => vin === this.selectedVehicleVin
|
||||
);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
arePagePrerequisiteValid() {
|
||||
return true;
|
||||
doesCopyContainRouterLink,
|
||||
splitCopyOnCMSPlaceHolder,
|
||||
getRouterLinkRouteFromCopy,
|
||||
getRouterLinkDisplayTextFromCopy,
|
||||
arePagePrerequisitesValid() {
|
||||
if (this.mainStore.order.vehicle.carId) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
backButtonAction() {
|
||||
/**
|
||||
* this.navigationScenarios comes from base-mixin
|
||||
*/
|
||||
this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route);
|
||||
},
|
||||
async forwardButtonAction() {},
|
||||
resetDependentState() {},
|
||||
async forwardButtonAction() {
|
||||
const vinLookup = await useMainStore()
|
||||
.lookupVehicleByVin(this.selectedVehicle.vin)
|
||||
.catch(() => {
|
||||
this.$refs.siteFooter.removeLoader();
|
||||
});
|
||||
if (!vinLookup) {
|
||||
return;
|
||||
}
|
||||
this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId(
|
||||
vinLookup.data.carId
|
||||
);
|
||||
await useMainStore().saveVin(
|
||||
{
|
||||
vehicleInfo: Object.assign(this.selectedVehicle.vehicle, {
|
||||
vin: this.selectedVehicle.vin,
|
||||
}),
|
||||
isSelectedGlassAvailableForVehicle:
|
||||
this.isSelectedGlassAvailableForVehicle,
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
return await this.navigateForward();
|
||||
},
|
||||
async navigateForward() {
|
||||
// If the vehicle selected on this page is different from the one originally entered and the selected glass is not available
|
||||
// for that vehicle, then navigate back to "vehicle-damage" and display vehicle changed alert on that page.
|
||||
if (this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle) {
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
|
||||
this.$route,
|
||||
{},
|
||||
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true }
|
||||
);
|
||||
} else {
|
||||
await this.navigateForwardWithSingleCarMatch();
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
selectedVehicleVin: {
|
||||
handler() {
|
||||
// does this vehicle match the previously selected carId?
|
||||
this.isCarIdDifferent =
|
||||
this.selectedVehicle?.vehicle.carId !== useMainStore().vehicle.carId;
|
||||
if (this.isCarIdDifferent) {
|
||||
this.$refs.siteFooter.updateButtonText(
|
||||
`Continue with ${this.selectedVehicle.vehicle.year} ${this.selectedVehicle.vehicle.make} ${this.selectedVehicle.vehicle.model}`
|
||||
);
|
||||
} else {
|
||||
this.$refs.siteFooter.updateButtonText(
|
||||
this.getCmsContent("SiteFooterWidget", "ForwardButtonText")
|
||||
);
|
||||
}
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
siteFooter,
|
||||
siteHeader,
|
||||
siteSubHeader,
|
||||
Form,
|
||||
vehicleBanner,
|
||||
alert,
|
||||
addressVehiclesQuestion,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.alert-provide-vin {
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.4;
|
||||
a {
|
||||
text-underline-offset: 4px; //Per Devyn. This can't be documented in Figma so there is a comment with the Prototype mocks on the Quote page in Figma
|
||||
line-height: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
#multiple-vehicles-alert p {
|
||||
margin-bottom: 0 !important; // Overrides extra margin-bottom on alert body text
|
||||
}
|
||||
</style>
|
||||
|
|
@ -321,6 +321,39 @@ const routingTable = function(store) {
|
|||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
issPageValue: issPageValues.ADDRESS_VEHICLES,
|
||||
maps: [
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_BACK,
|
||||
destinationIssPageValue: issPageValues.ADDRESS_LOOKUP,
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
|
||||
destinationIssPageValue: issPageValues.VEHICLE_DAMAGE,
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_FORWARD_WITH_PART_QUESTIONS,
|
||||
destinationIssPageValue: issPageValues.PART_QUESTIONS,
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_PARTS_TO_CHOOSE,
|
||||
destinationIssPageValue: issPageValues.VEHICLE_PARTS,
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_FORWARD_WITH_MOLDING_QUESTIONS,
|
||||
destinationIssPageValue: issPageValues.MOLDING_QUESTIONS,
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_FORWARD_WITH_CAPABILITY_QUESTIONS,
|
||||
destinationIssPageValue: issPageValues.CAPABILITY_QUESTIONS,
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS,
|
||||
destinationIssPageValue: issPageValues.COVERAGE_STATEMENT,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
issPageValue: issPageValues.WELCOME_PAGE,
|
||||
maps: [
|
||||
|
|
|
|||
|
|
@ -893,7 +893,20 @@ export const useMainStore = defineStore({
|
|||
this.updateRegistration(registrationInfo);
|
||||
}
|
||||
},
|
||||
saveVin({ isSelectedGlassAvailableForVehicle, vehicleInfo }) {
|
||||
//Reset dependent state when changing
|
||||
if (vehicleInfo.vin !== this.order.vehicle.vin) {
|
||||
this.resetRegistrationAndDependencies();
|
||||
|
||||
if (!isSelectedGlassAvailableForVehicle) {
|
||||
this.resetDamageAndDependencies();
|
||||
this.resetPartsAndDependencies();
|
||||
}
|
||||
|
||||
//Save new values
|
||||
this.updateVehicle(vehicleInfo);
|
||||
}
|
||||
},
|
||||
saveRegistrationLicensePlateLookup({ isSelectedGlassAvailableForVehicle, vehicleInfo, registrationInfo }) {
|
||||
//Reset dependent state when changing
|
||||
if
|
||||
|
|
|
|||
Loading…
Reference in a new issue