Fixing merge conflicts

This commit is contained in:
brydon1 2023-06-28 14:55:03 -04:00
commit 6df4b1400c
27 changed files with 431 additions and 386 deletions

View file

@ -175,17 +175,11 @@ stages:
indexDeployVariables: indexDeployVariables:
__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__: $(__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__) __VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__: $(__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__)
__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__: $(__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__) __VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__: $(__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__)
- template: templates/digital/invalidate-cloudfront-cache.yml@AzureDevOps
parameters:
awsCliContainer: awscli
distributionId: $(apiCfDistributionId)
paths: /*
awsProfile: $(qaDeploymentProfile)
- template: templates/digital/invalidate-cloudfront-cache.yml@AzureDevOps - template: templates/digital/invalidate-cloudfront-cache.yml@AzureDevOps
parameters: parameters:
awsCliContainer: awscli awsCliContainer: awscli
distributionId: $(cfDistributionId) distributionId: $(cfDistributionId)
paths: /iss/* paths: /*
awsProfile: $(qaDeploymentProfile) awsProfile: $(qaDeploymentProfile)
# Prod Build/Deploy # Prod Build/Deploy
@ -230,17 +224,11 @@ stages:
indexDeployVariables: indexDeployVariables:
__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__: $(__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__) __VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__: $(__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__)
__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__: $(__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__) __VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__: $(__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__)
- template: templates/digital/invalidate-cloudfront-cache.yml@AzureDevOps
parameters:
awsCliContainer: awscli
distributionId: $(apiCfDistributionId)
paths: /*
awsProfile: $(prodDeploymentProfile)
- template: templates/digital/invalidate-cloudfront-cache.yml@AzureDevOps - template: templates/digital/invalidate-cloudfront-cache.yml@AzureDevOps
parameters: parameters:
awsCliContainer: awscli awsCliContainer: awscli
distributionId: $(cfDistributionId) distributionId: $(cfDistributionId)
paths: /iss/* paths: /*
awsProfile: $(prodDeploymentProfile) awsProfile: $(prodDeploymentProfile)
- template: templates/digital/auto-tag.yml@AzureDevOps - template: templates/digital/auto-tag.yml@AzureDevOps
parameters: parameters:

View file

@ -14,7 +14,7 @@
]"> ]">
<input <input
class="form-control" class="form-control"
v-model.trim="value" v-model.trim.lazy="value"
v-maska="mask" v-maska="mask"
:type="type" :type="type"
:ref="inputId" :ref="inputId"

View file

@ -16,7 +16,7 @@
alertClass="alert-warning" alertClass="alert-warning"
:manualHeadline="alertFewMoreQuestionsHeader" :manualHeadline="alertFewMoreQuestionsHeader"
:manualCopy="alertFewMoreQuestionsCopy" :manualCopy="alertFewMoreQuestionsCopy"
v-bind:isDismissible="false" v-bind:isDismissible="false"
class="mt-5"/> class="mt-5"/>
<div v-for="(questionsDatum, i) in questionsData" :key="questionsDatum.key"> <div v-for="(questionsDatum, i) in questionsData" :key="questionsDatum.key">
<questionChain <questionChain
@ -29,6 +29,7 @@
:validationRules="validationRules" /> :validationRules="validationRules" />
</div> </div>
<siteFooter <siteFooter
class="mt-3"
ref="siteFooter" ref="siteFooter"
cmsWidgetName="SiteFooterWidget" cmsWidgetName="SiteFooterWidget"
:isForwardActionDisabled="!isMetaValid" :isForwardActionDisabled="!isMetaValid"

View file

@ -1,9 +1,9 @@
<template> <template>
<div>
<footer class="footer container-fluid g-5 px-0 py-3 " id="infoBox"> <footer class="footer container-fluid g-5 px-0" id="infoBox">
<div class="row d-flex flex-row-reverse align-items-center vw-100 mx-0"> <div class="row d-flex flex-row-reverse align-items-center vw-100 mx-0">
<div class="col button-col d-flex px-0" id="stacked" > <div class="col button-col d-flex px-0" id="stacked" >
<buttonMain <buttonMain
v-if="!isForwardButtonHidden" v-if="!isForwardButtonHidden"
ref="buttonMain" ref="buttonMain"
isPrimary isPrimary
@ -16,9 +16,9 @@
data-bs-target="#footerModal" data-bs-target="#footerModal"
data-bs-dismiss="modal" data-bs-dismiss="modal"
data-test-id="site-footer-main-button" /> data-test-id="site-footer-main-button" />
</div> </div>
<div v-if="!isBackButtonHidden" class="col-auto link-col py-1 px-0 text-break"> <div v-if="!isBackButtonHidden" class="col-auto link-col py-1 px-0 text-break">
<textLink <textLink
linkType="navigation" linkType="navigation"
:text="backLink" :text="backLink"
@click-event="linkClick" @click-event="linkClick"
@ -26,11 +26,12 @@
data-bs-target="#footerModal" data-bs-target="#footerModal"
data-bs-dismiss="modal" data-bs-dismiss="modal"
data-test-id="site-footer-back-button" /> data-test-id="site-footer-back-button" />
</div>
</div> </div>
</footer>
<div class="footerImage" id="imgCity" v-if="footerImageURL" >
<img id="siteFooterImage" :src="footerImageURL" />
</div> </div>
</footer>
<div class="footerImage" id="imgCity" v-if="footerImageURL" >
<img id="siteFooterImage" :src="footerImageURL" />
</div> </div>
</template> </template>
@ -77,8 +78,8 @@ export default {
}, },
buttonText() { buttonText() {
return this.customButtontext return this.customButtontext
? this.customButtontext ? this.customButtontext
: this.getCmsContent(this.cmsWidgetName, "ForwardButtonText"); : this.getCmsContent(this.cmsWidgetName, "ForwardButtonText");
}, },
footerImageURL() footerImageURL()
{ {
@ -126,6 +127,7 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.footer { .footer {
display: flex; display: flex;
overflow: visible;
a { a {
display: flex; display: flex;
justify-content: center; justify-content: center;

View file

@ -1,13 +1,13 @@
<template> <template>
<div class="menu-modal-container"> <div class="menu-modal-container">
<button class="menu-button" type="button" :class="[isActive ? 'active' : '']" data-bs-toggle="modal" data-bs-target="#footerModal" aria-label="Hamburger Menu (modal window)"> <button class="menu-button" type="button" :class="[isActive ? 'active' : '']" aria-label="Hamburger Menu (modal window)" @click="toggle()">
<div class="bar1"></div> <div class="bar1"></div>
<div class="bar2"></div> <div class="bar2"></div>
<div class="bar3"></div> <div class="bar3"></div>
</button> </button>
</div> </div>
<!-- Modal --> <!-- Modal -->
<div class="modal menu-modal fade" data-bs-backdrop="false" id="footerModal" tabindex="-1" aria-labelledby="footerModalLabel" aria-hidden="true" v-on="{ 'show.bs.modal' : show, 'hide.bs.modal' : hide }"> <div class="modal menu-modal fade" data-bs-backdrop="false" id="footerModal" tabindex="-1" aria-labelledby="footerModalLabel" aria-hidden="true">
<div class="modal-dialog modal-fullscreen"> <div class="modal-dialog modal-fullscreen">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header visually-hidden"> <div class="modal-header visually-hidden">
@ -53,6 +53,8 @@
<script> <script>
import textLink from "@/ux-components/text-link/text-link"; import textLink from "@/ux-components/text-link/text-link";
import { Modal } from "bootstrap";
export default { export default {
name: 'menuModal', name: 'menuModal',
data() { data() {
@ -62,17 +64,25 @@ export default {
}; };
}, },
methods: { methods: {
show() { toggle() {
this.currentFooterAndHeaderHeight = this.getFooterInfoBoxHeight() + 56; if(this.isActive){
this.isActive = true; //hide modal
document.querySelector('.fade-on-route-transition').scrollTo({ this.isActive = false;
top: 0, behavior: 'instant' const modal = Modal.getInstance(document.getElementById("footerModal"));
}); modal?.hide();
}, }
hide() { else
var self = this; {
self.isActive = false; //show modal
}, this.currentFooterAndHeaderHeight = this.getFooterInfoBoxHeight() + 56;
this.isActive = true;
const modal = Modal.getOrCreateInstance(document.getElementById("footerModal"));
modal?.show();
document.querySelector('.fade-on-route-transition').scrollTo({
top: 0, behavior: 'instant'
});
}
}
}, },
components: { components: {
textLink, textLink,
@ -127,6 +137,7 @@ export default {
border-top: 1px solid $gray-300; border-top: 1px solid $gray-300;
overflow-x: visible; overflow-x: visible;
overflow-y: visible; overflow-y: visible;
z-index: 2;
.modal-body { .modal-body {
padding: 2rem; padding: 2rem;
.ccpa-icon { .ccpa-icon {

View file

@ -96,6 +96,7 @@ export default({
<style lang="scss" scoped> <style lang="scss" scoped>
.site-header { .site-header {
height: 56px; height: 56px;
position: relative;
} }
.alert { .alert {
left: 0; left: 0;

View file

@ -31,7 +31,8 @@ import buttonBack from "@/iss-components/site-sub-header/button-back/button-back
cmsWidgetName: String, cmsWidgetName: String,
hasBackButton: Boolean, hasBackButton: Boolean,
justification: String, justification: String,
issContainingPage: String issContainingPage: String,
darkGraySubText: Boolean,
}, },
computed: { computed: {
content() { content() {
@ -53,9 +54,15 @@ import buttonBack from "@/iss-components/site-sub-header/button-back/button-back
'justify-content-center'; 'justify-content-center';
}, },
alternateFormatting() { alternateFormatting() {
return (this.issContainingPage?.toLowerCase() === 'service-packages') ? //override for service-packages unique style
'service-packages-subtext mt-4 mb-2 px-5' : if (this.issContainingPage?.toLowerCase() === 'service-packages')
'small'; {
return 'service-packages-subtext mt-4 mb-2 px-5';
}
else
{
return this.darkGraySubText ? "dark-gray" : "light-gray";
}
} }
}, },
methods: { methods: {
@ -84,9 +91,14 @@ import buttonBack from "@/iss-components/site-sub-header/button-back/button-back
color: inherit; color: inherit;
} }
} }
p.small { p.light-gray {
color: $gray-550; color: $gray-550;
} }
p.dark-gray {
color: $darker-gray;
}
p.service-packages-subtext { p.service-packages-subtext {
font-weight: 500 !important; font-weight: 500 !important;
line-height: 24px; line-height: 24px;

View file

@ -41,14 +41,13 @@
<alert <alert
ref="alertVinLookupsByHomeAddressNotAllowed" ref="alertVinLookupsByHomeAddressNotAllowed"
v-if="displayVinLookupByHomeAddressNotAllowedAlert" v-if="displayVinLookupByHomeAddressNotAllowedAlert"
class="mb-4 mt-4" class="mt-4"
cmsWidgetName="AlertVinLookupsByHomeAddressNotAllowedWidget" cmsWidgetName="AlertVinLookupsByHomeAddressNotAllowedWidget"
alertClass="alert-danger" alertClass="alert-danger"
v-bind:isDismissible="false" /> v-bind:isDismissible="false" />
<customerQuestions ref="customerQuestions" v-model="customerQuestions" /> <customerQuestions ref="customerQuestions" v-model="customerQuestions" />
<siteFooter <siteFooter
class="mt-5"
cmsWidgetName="SiteFooterWidget" cmsWidgetName="SiteFooterWidget"
ref="siteFooter" ref="siteFooter"
:isDisabled="!meta.valid" :isDisabled="!meta.valid"
@ -234,7 +233,7 @@ export default {
isSelectedGlassAvailableForVehicle: this.isSelectedGlassAvailableForVehicle, isSelectedGlassAvailableForVehicle: this.isSelectedGlassAvailableForVehicle,
vehicleInfo: vehicleInfo:
Object.keys(vehicleInfoToCommit).length === 0 Object.keys(vehicleInfoToCommit).length === 0
? useMainStore().order.vehicle ? null
: vehicleInfoToCommit, : vehicleInfoToCommit,
registrationInfo: { registrationInfo: {
firstName: this.customerQuestions.firstName, firstName: this.customerQuestions.firstName,

View file

@ -53,6 +53,7 @@
validationRules="state-required" validationRules="state-required"
class="mt-4 mb-2"/> class="mt-4 mb-2"/>
<siteFooter <siteFooter
class="mt-5"
:isForwardActionDisabled="!meta.valid" :isForwardActionDisabled="!meta.valid"
cms-widget-name="SiteFooterWidget" cms-widget-name="SiteFooterWidget"
@back-clicked="backButtonAction" @back-clicked="backButtonAction"

View file

@ -28,6 +28,7 @@
</div> </div>
</div> </div>
<siteFooter <siteFooter
class="mt-5"
cmsWidgetName="SiteFooterWidget" cmsWidgetName="SiteFooterWidget"
ref="siteFooter" ref="siteFooter"
:isForwardActionDisabled="!meta.valid" :isForwardActionDisabled="!meta.valid"
@ -66,7 +67,7 @@ export default {
data() { data() {
return { return {
customerQuestions: this.getPolicyHolderDetailsFromStore(), customerQuestions: this.getPolicyHolderDetailsFromStore(),
vehiclesFound: [], vehiclesFound: [],
}; };
}, },
setup() { setup() {
@ -91,8 +92,8 @@ export default {
next((vm) => { next((vm) => {
vm.setCmsContent(resultMap.cmsContent); vm.setCmsContent(resultMap.cmsContent);
}); });
}, },
methods: methods:
{ {
@ -101,8 +102,8 @@ export default {
}, },
async forwardButtonAction() async forwardButtonAction()
{ {
this.mainStore.updatePolicyHolderDetails(this.customerQuestions); this.mainStore.updatePolicyHolderDetails(this.customerQuestions);
return this.navigateForward(); return this.navigateForward();
}, },
@ -114,7 +115,7 @@ export default {
{}, {},
{}, {},
this.vehiclesFound this.vehiclesFound
); );
else else
this.$router.navigate( this.$router.navigate(
this.navigationScenarios.CLICKED_FORWARD_POLICY_UNVERIFIED, this.navigationScenarios.CLICKED_FORWARD_POLICY_UNVERIFIED,
@ -135,7 +136,7 @@ export default {
firstName : this.mainStore.order.customer.firstName, firstName : this.mainStore.order.customer.firstName,
lastName : this.mainStore.order.customer.lastName, lastName : this.mainStore.order.customer.lastName,
} }
}, },
}, },
computed:{ computed:{
isCoverageEnabled(){ isCoverageEnabled(){
@ -143,7 +144,7 @@ export default {
}, },
vehiclesCount(){ vehiclesCount(){
return this.vehiclesFound.length; return this.vehiclesFound.length;
} }
}, },
components: { components: {
siteHeader, siteHeader,

View file

@ -1,43 +1,34 @@
import policyVehicles from "@/layouts/policy-vehicles/policy-vehicles"; import policyVehicles from '@/layouts/policy-vehicles/policy-vehicles.vue';
import { settleAllPromises } from "@/helpers/layout-helper.js"; import { settleAllPromises } from '@/helpers/layout-helper';
import { shallowMount } from "@vue/test-utils"; import { shallowMount } from '@vue/test-utils';
import { getMountOptions } from "@/helpers/unit-test-helper.js"; import { getMountOptions } from '@/helpers/unit-test-helper';
import { useMainStore } from "@/store"; import { useMainStore } from '@/store';
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
import {vehicleSelectionOptions} from "@/constants/vehicle-selection-options"; import { navigationScenarios } from '@/router/router-constants/navigation-scenarios';
import { navigationScenarios } from "@/router/router-constants/navigation-scenarios"; import baseMixin from '@/mixins/base-mixin';
import baseMixin from "@/mixins/base-mixin"; import { getRandomString, getRandomInt } from '@/helpers/data-generation';
import { getRandomString, getRandomInt } from '@/helpers/data-generation.js'; import { endorsementOptions } from '@/constants/endorsement-options';
import { endorsementOptions } from '@/constants/endorsement-options.js';
import { createTestingPinia } from '@pinia/testing'; import { createTestingPinia } from '@pinia/testing';
import { issPageValues } from "@/router/router-constants/issPage-values";
import { vehicleSelectionOptions } from "@/constants/vehicle-selection-options";
// Mock fetchCmsContentForPage // Mock fetchCmsContentForPage
jest.mock("@/helpers/cms-content-helper", () => ({ jest.mock('@/helpers/cms-content-helper', () => ({
fetchCmsContentForPage: jest.fn(), fetchCmsContentForPage: jest.fn(),
doesCopyContainRouterLink: jest.fn(), doesCopyContainRouterLink: jest.fn(),
splitCopyOnCMSPlaceHolder: jest.fn().mockImplementation(() => "test"), splitCopyOnCMSPlaceHolder: jest.fn().mockImplementation(() => 'test'),
getRouterLinkRouteFromCopy: jest.fn(), getRouterLinkRouteFromCopy: jest.fn(),
getRouterLinkDisplayTextFromCopy: jest.fn(), getRouterLinkDisplayTextFromCopy: jest.fn(),
splitCMSCopyOnParagraphTag: jest.fn(), splitCMSCopyOnParagraphTag: jest.fn(),
})); }));
// Mock our module for promises. // Mock our module for promises.
jest.mock("@/helpers/layout-helper.js", () => ({ jest.mock('@/helpers/layout-helper.js', () => ({
settleAllPromises: jest.fn(), settleAllPromises: jest.fn(),
})); }));
describe("policy-vehicles.vue", () => { describe('policy-vehicles.vue', () => {
test("Should navigate to CLICKED_BACK if backButtonAction is run", async () => { 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("Should navigate to CLICKED_BACK if backButtonAction is run", async () => {
// Arrange // Arrange
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({});
@ -48,9 +39,9 @@ describe("policy-vehicles.vue", () => {
expect(wrapper.vm.$router.navigate).toBeCalled(); expect(wrapper.vm.$router.navigate).toBeCalled();
}); });
describe("forwardButtonAction", () => { describe('forwardButtonAction', () => {
test("Selected VIN matches vehicle listed in system => update vehicle and navigate forward with CLICKED_FORWARD_LISTED_VEHICLE scenario.", async () => { test('Selected VIN matches vehicle listed in system => update vehicle and navigate forward with CLICKED_FORWARD_LISTED_VEHICLE scenario.', async () => {
//Arrange //Arrange
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({});
@ -94,10 +85,10 @@ describe("policy-vehicles.vue", () => {
); );
}); });
test("Error in lookupVehicleByVin call => bailout true and navigate forward with CLICKED_FORWARD_WITH_BAILOUT scenario.", async () => { test('Error in lookupVehicleByVin call => bailout true and navigate forward with CLICKED_FORWARD_WITH_BAILOUT scenario.', async () => {
//Arrange //Arrange
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({});
const vin = getRandomString(17,17); const vin = getRandomString(17,17);
await wrapper.setData({ await wrapper.setData({
selectedVehicleVin: vin, selectedVehicleVin: vin,
@ -120,7 +111,7 @@ describe("policy-vehicles.vue", () => {
); );
}); });
test("vehicle not listed => navigate forward with CLICKED_FORWARD_NON_LISTED_VEHICLE scenario.", async () => { test('vehicle not listed => navigate forward with CLICKED_FORWARD_NON_LISTED_VEHICLE scenario.', async () => {
// Arrange // Arrange
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({});
@ -141,8 +132,8 @@ describe("policy-vehicles.vue", () => {
}); });
}) })
describe("noCompensationForSelectedVehicle computed property", () => { describe('noCompensationForSelectedVehicle computed property', () => {
it("No vehicle match => returns true", async () => { it('No vehicle match => returns true', async () => {
// Arrange // Arrange
const selectedVin = getRandomString(17,17); const selectedVin = getRandomString(17,17);
const otherVin = getRandomString(17,17); const otherVin = getRandomString(17,17);
@ -162,7 +153,7 @@ describe("policy-vehicles.vue", () => {
expect(result).toBeTruthy(); expect(result).toBeTruthy();
}); });
it("Coverages list empty => true", () => { it('Coverages list empty => true', () => {
// Arrange // Arrange
const vin = getRandomString(17,17); const vin = getRandomString(17,17);
const testValues = { const testValues = {
@ -182,7 +173,7 @@ describe("policy-vehicles.vue", () => {
expect(result).toBeTruthy(); expect(result).toBeTruthy();
}); });
it("Coverages list non-empty => false", () => { it('Coverages list non-empty => false', () => {
// Arrange // Arrange
const vin = getRandomString(17,17); const vin = getRandomString(17,17);
const testValues = { const testValues = {
@ -207,9 +198,9 @@ describe("policy-vehicles.vue", () => {
}); });
}) })
describe("deductibleForSelectedVehicle computed property", () => { describe('deductibleForSelectedVehicle computed property', () => {
it("No vehicle match => undefined returned", () => { it('No vehicle match => undefined returned', () => {
// Arrange // Arrange
const selectedVin = getRandomString(17,17); const selectedVin = getRandomString(17,17);
const otherVin = getRandomString(17,17); const otherVin = getRandomString(17,17);
@ -229,7 +220,7 @@ describe("policy-vehicles.vue", () => {
expect(result).toBe(undefined); expect(result).toBe(undefined);
}); });
it("Vehicle match with empty coverages list => 0 returned", () => { it('Vehicle match with empty coverages list => 0 returned', () => {
// Arrange // Arrange
const vin = getRandomString(17,17); const vin = getRandomString(17,17);
const testValues = { const testValues = {
@ -249,7 +240,7 @@ describe("policy-vehicles.vue", () => {
expect(result).toBe(0); expect(result).toBe(0);
}); });
it("Coverages list non empty => deductible from first coverage returned", () => { it('Coverages list non empty => deductible from first coverage returned', () => {
// Arrange // Arrange
const vin = getRandomString(17,17); const vin = getRandomString(17,17);
const firstDeductible = getRandomInt(1,1000); const firstDeductible = getRandomInt(1,1000);
@ -277,11 +268,11 @@ describe("policy-vehicles.vue", () => {
// Assert // Assert
expect(result).toBe(firstDeductible); expect(result).toBe(firstDeductible);
}); });
}) });
describe("repairWaivedForSelectedVehicle computed property", () => { describe('repairWaivedForSelectedVehicle computed property', () => {
it("No vehicle match => false returned", () => { it('No vehicle match => false returned', () => {
// Arrange // Arrange
const selectedVin = getRandomString(17,17); const selectedVin = getRandomString(17,17);
const otherVin = getRandomString(17,17); const otherVin = getRandomString(17,17);
@ -301,7 +292,7 @@ describe("policy-vehicles.vue", () => {
expect(result).toBe(false); expect(result).toBe(false);
}); });
it("Endorsements list empty => false returned", () => { it('Endorsements list empty => false returned', () => {
// Arrange // Arrange
const vin = getRandomString(17,17); const vin = getRandomString(17,17);
const testValues = { const testValues = {
@ -321,7 +312,7 @@ describe("policy-vehicles.vue", () => {
expect(result).toBe(false); expect(result).toBe(false);
}); });
it("Endorsements list non-empty, not containing repair waived => false returned", () => { it('Endorsements list non-empty, not containing repair waived => false returned', () => {
// Arrange // Arrange
const vin = getRandomString(17,17); const vin = getRandomString(17,17);
const testValues = { const testValues = {
@ -341,7 +332,7 @@ describe("policy-vehicles.vue", () => {
expect(result).toBe(false); expect(result).toBe(false);
}); });
it("Endorsements list contains repair waived => true returned", () => { it('Endorsements list contains repair waived => true returned', () => {
// Arrange // Arrange
const vin = getRandomString(17,17); const vin = getRandomString(17,17);
const testValues = { const testValues = {
@ -364,7 +355,25 @@ describe("policy-vehicles.vue", () => {
// Assert // Assert
expect(result).toBe(true); expect(result).toBe(true);
}); });
}) });
test('first vehicle is auto-selected if only one vehicle on policy', async () => {
// Arrange
const vin = getRandomString(17,17);
useMainStore().applicationUser = {
pageData: {
[issPageValues.POLICY_VEHICLES]: [ { vin: vin } ],
}
};
const { wrapper } = setupMocks();
// Act
await wrapper.vm.$nextTick();
// Assert
expect(wrapper.vm.selectedVehicleVin).toBe(vin);
});
}); });
const mockMixin = { const mockMixin = {
@ -373,7 +382,7 @@ const mockMixin = {
}, },
computed: { computed: {
dynamicStrings() { dynamicStrings() {
return { ROUTER_LINK: "routerLink:" }; return { ROUTER_LINK: 'routerLink:' };
}, },
}, },
}; };
@ -408,7 +417,7 @@ function setupMocks()
fetchCmsContentForPage.mockImplementation(() => Promise.resolve()); fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
const wrapper = shallowMount(policyVehicles, mountOptions); const wrapper = shallowMount(policyVehicles, mountOptions);
wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => ""); wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => '');
wrapper.vm.setCmsContent = jest.fn(); wrapper.vm.setCmsContent = jest.fn();
wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent; wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent;
wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn(); wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();

View file

@ -8,7 +8,7 @@
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<div class="select-car-form rounded text-center"> <div class="select-car-form rounded text-center">
<vehicleBanner cmsWidgetName="VehicleBannerWidget" :displayGenericVehicleImage="true" class="mt-2 mb-4" /> <vehicleBanner cmsWidgetName="VehicleBannerWidget" :displayGenericVehicleImage="displayGeneric" class="mt-2 mb-4" />
<policyVehiclesQuestion <policyVehiclesQuestion
class="px-4" class="px-4"
cmsWidgetName="PolicyVehiclesQuestion" cmsWidgetName="PolicyVehiclesQuestion"
@ -53,12 +53,16 @@ export default {
const policyVehicles = useMainStore().pageData(issPageValues.POLICY_VEHICLES); const policyVehicles = useMainStore().pageData(issPageValues.POLICY_VEHICLES);
return { return {
policyVehicles: policyVehicles, policyVehicles: policyVehicles,
selectedVehicleVin: (policyVehicles?.length ?? 0) == 0 selectedVehicleVin: (policyVehicles?.length ?? 0) == 1
? "" ? policyVehicles[0].vin
: policyVehicles[0].vin, : "",
displayGeneric: true,
bailout: false bailout: false
} }
}, },
// mounted() {
// this.autoSelectIfOneVehicle();
// },
async beforeRouteEnter(to, from, next) async beforeRouteEnter(to, from, next)
{ {
// Call APIs // Call APIs
@ -133,8 +137,13 @@ export default {
error: true, error: true,
}; };
} }
}, },
// autoSelectIfOneVehicle() {
// if (this.policyVehicles.length == 1) {
// this.selectedVehicleVin = this.policyVehicles[0].vin;
// }
// }
}, },
computed:{ computed:{
VehiclesForQuestions() { VehiclesForQuestions() {
@ -171,8 +180,58 @@ export default {
repairWaivedForSelectedVehicle() { repairWaivedForSelectedVehicle() {
const vehicle = this.policyVehicles.find((vehicle) => { return vehicle.vin == this.selectedVehicleVin; }); const vehicle = this.policyVehicles.find((vehicle) => { return vehicle.vin == this.selectedVehicleVin; });
return vehicle?.endorsements?.includes(endorsementOptions.REPAIR_WAIVED) ?? false; return vehicle?.endorsements?.includes(endorsementOptions.REPAIR_WAIVED) ?? false;
} },
VehiclesFromApi() {
return useMainStore().pageData(issPageValues.POLICY_VEHICLES);
},
selectedVehicle() {
const vehicle = this.mainStore.lookupVehicleByVin(this.selectedVehicleVin);
return vehicle;
},
}, },
watch: {
async selectedVehicleVin(value) {
if (value === vehicleSelectionOptions.VEHICLE_NOT_LISTED) {
// clear previously selected vehicle and image
this.mainStore.resetVehicleState();
this.displayGeneric = true;
}
else {
// get vehicle details from selected VIN
const vehicle = await this.lookupVehicleByVin(value);
// handle error in case vehicle info doesn't come back for selected VIN
if (vehicle?.error ?? true) {
this.mainStore.resetVehicleState();
this.displayGeneric = true;
return;
}
// save selected vehicle to the store
this.mainStore.updateVehicle(vehicle.data);
this.displayGeneric = true;
// get the style(s) associated with the selected YMM
const styleOptions = await this.mainStore.getVehicleStyles(
vehicle.data.year,
vehicle.data.make,
vehicle.data.model
)
// if there is more than 1 style for the selected vehicle, display generic/blurred image
this.displayGeneric = styleOptions?.data?.length > 1;
// if (styleOptions?.data?.length > 1) {
// = true;
// }
// else {
// // display clear image of vehicle
// this.displayGeneric = false;
// }
}
}
},
components: { components: {
siteHeader, siteHeader,
siteFooter, siteFooter,

View file

@ -16,6 +16,7 @@
class="mx-5" /> class="mx-5" />
<div class="px-5"> <div class="px-5">
<siteFooter <siteFooter
class="mt-5"
cmsWidgetName="SiteFooterWidget" cmsWidgetName="SiteFooterWidget"
:isForwardActionDisabled="isForwardActionDisabled" :isForwardActionDisabled="isForwardActionDisabled"
@backClicked="backButtonAction" @backClicked="backButtonAction"
@ -26,16 +27,16 @@
</div> </div>
<recalModal ref="recalModal" cmsWidgetName="RecalModal" /> <recalModal ref="recalModal" cmsWidgetName="RecalModal" />
<steeringModal cmsWidgetName="StateSteeringModal" ref="StateSteeringModal" /> <steeringModal cmsWidgetName="StateSteeringModal" ref="StateSteeringModal" />
<shopPreferenceModal <shopPreferenceModal
cmsWidgetName="ShopPreferenceDrawer" cmsWidgetName="ShopPreferenceDrawer"
ref="ShopPreferenceDrawer" ref="ShopPreferenceDrawer"
@openSteering="openStateSteeringModal" @openSteering="openStateSteeringModal"
:showSteeringLink="showSteeringLink"/> :showSteeringLink="showSteeringLink"/>
<tpaRecalModal cmsWidgetName="TPARecalModal" <tpaRecalModal cmsWidgetName="TPARecalModal"
ref="TPARecalModal" ref="TPARecalModal"
:ackError="ackError" :ackError="ackError"
@buttonClick="navigateWithTPAAck" @buttonClick="navigateWithTPAAck"
/> />
</Form> </Form>
</template> </template>
@ -159,12 +160,12 @@ export default {
this.$router.navigate(scenario, this.$route); this.$router.navigate(scenario, this.$route);
}, },
navigateWithTPAAck() { navigateWithTPAAck() {
this.mainStore.saveProviderPreferenceData({selectedProvider: this.selectedProvider, tpaAcknowledgement: this.tpaAcknowledgement}); this.mainStore.saveProviderPreferenceData({selectedProvider: this.selectedProvider, tpaAcknowledgement: this.tpaAcknowledgement});
this.navigateForward(this.navigationScenarios.CLICKED_FORWARD_WITH_TPA_ENABLED); this.navigateForward(this.navigationScenarios.CLICKED_FORWARD_WITH_TPA_ENABLED);
}, },
forwardButtonAction() { forwardButtonAction() {
if(this.selectedProvider) { if(this.selectedProvider) {
let scenario = null; let scenario = null;
switch (this.selectedProvider) { switch (this.selectedProvider) {
case options.SAFELITE: case options.SAFELITE:
scenario = this.navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE; scenario = this.navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE;
@ -186,7 +187,7 @@ export default {
break; break;
}; };
this.navigateForward(scenario); this.navigateForward(scenario);
this.mainStore.saveProviderPreferenceData({selectedProvider: this.selectedProvider, tpaAcknowledgement: this.tpaAcknowledgement}); this.mainStore.saveProviderPreferenceData({selectedProvider: this.selectedProvider, tpaAcknowledgement: this.tpaAcknowledgement});
} }
}, },
openStateSteeringModal() { openStateSteeringModal() {

View file

@ -6,6 +6,7 @@
<div class="container-fluid pb-2"> <div class="container-fluid pb-2">
<p>Placeholder for schedule page</p> <p>Placeholder for schedule page</p>
<siteFooter <siteFooter
class="mt-5"
cmsWidgetName="SiteFooterWidget" cmsWidgetName="SiteFooterWidget"
ref="siteFooter" ref="siteFooter"
:isForwardActionDisabled="!meta.valid" :isForwardActionDisabled="!meta.valid"

View file

@ -31,11 +31,12 @@
validationRules="selection-required" validationRules="selection-required"
class="service-location-button-question mb-1"/> class="service-location-button-question mb-1"/>
<div class="select-car"> <div class="select-car">
<div class="container-fluid pb-2"> <div class="container-fluid pb-2 g-0">
<div class="row"> <div class="row">
<div class="col px-0"> <div class="col px-0">
<div class="select-car-form rounded"> <div class="select-car-form rounded">
<siteFooter <siteFooter
class="mt-4"
cmsWidgetName="SiteFooterWidget" cmsWidgetName="SiteFooterWidget"
:isForwardActionDisabled="!meta.valid" :isForwardActionDisabled="!meta.valid"
@backClicked="backButtonAction" @backClicked="backButtonAction"
@ -89,7 +90,7 @@ export default {
const zipCodeData = getZipCodeData(serviceZipCode); const zipCodeData = getZipCodeData(serviceZipCode);
const serviceabilityDetailsPromise = getServiceabilityDetails(serviceZipCode); const serviceabilityDetailsPromise = getServiceabilityDetails(serviceZipCode);
// Settle promises and get results // Settle promises and get results
const promiseResultMap = [ const promiseResultMap = [
{ {
@ -107,7 +108,7 @@ export default {
]; ];
const resultMap = await settleAllPromises(promiseResultMap); const resultMap = await settleAllPromises(promiseResultMap);
next((vm) => { next((vm) => {
vm.setCmsContent(resultMap.cmsContent); vm.setCmsContent(resultMap.cmsContent);
vm.setData( vm.setData(
@ -161,7 +162,7 @@ export default {
}, },
displayMilitaryZipAlert() { displayMilitaryZipAlert() {
return this.zipContainsMilitaryBase && this.isServiceableMobile; return this.zipContainsMilitaryBase && this.isServiceableMobile;
} }
}, },
methods: { methods: {
arePagePrerequisiteValid() { arePagePrerequisiteValid() {
@ -258,11 +259,11 @@ export default {
.service-location-button-question { .service-location-button-question {
.question-text { .question-text {
margin-top: 1.5rem; margin-top: 1.5rem;
span { span {
text-align: center; text-align: center;
} }
} }
} }
</style> </style>

View file

@ -51,6 +51,7 @@
groupName="BackGlassReplaceOptionsQuestion" groupName="BackGlassReplaceOptionsQuestion"
validationRules="replace-options-required" /> validationRules="replace-options-required" />
<site-footer <site-footer
class="mt-5"
cmsWidgetName="SiteFooterWidget" cmsWidgetName="SiteFooterWidget"
:isForwardActionDisabled="!meta.valid" :isForwardActionDisabled="!meta.valid"
@backClicked="backButtonAction" @backClicked="backButtonAction"

View file

@ -11,7 +11,7 @@
<VehicleBanner class="mt-2 mb-4" cms-widget-name="VehicleBannerWidget" :display-generic-vehicle-image="false" /> <VehicleBanner class="mt-2 mb-4" cms-widget-name="VehicleBannerWidget" :display-generic-vehicle-image="false" />
<SiteSubHeader cms-widget-name="SiteSubHeaderWidget" class="mt-5 mb-2" /> <SiteSubHeader cms-widget-name="SiteSubHeaderWidget" class="mt-5 mb-2" />
<VinLookupMethods v-model="selectedVinLookupMethod" cms-widget-name="VINLookupMethod" group-name="VinLookupMethods" ref="VinLookupMethods" /> <VinLookupMethods v-model="selectedVinLookupMethod" cms-widget-name="VINLookupMethod" group-name="VinLookupMethods" ref="VinLookupMethods" />
<SiteFooter cms-widget-name="SiteFooterWidget" :is-forward-action-disabled="isForwardActionDisabled" @back-clicked="backButtonAction" @forward-clicked="forwardButtonAction" /> <SiteFooter cms-widget-name="SiteFooterWidget" :is-forward-action-disabled="isForwardActionDisabled" @back-clicked="backButtonAction" @forward-clicked="forwardButtonAction" class="mt-3"/>
</div> </div>
</div> </div>
</div> </div>

View file

@ -181,12 +181,12 @@ export default {
}, },
AutoSelectIfSinglePart() { AutoSelectIfSinglePart() {
if (this.partsForSelectedTint?.length > 0) if (this.partsForSelectedTint?.length > 0)
{ {
// Check if only a single part is present for the tint and set the v-model if it is. // Check if only a single part is present for the tint and set the v-model if it is.
if (this.partsForSelectedTint?.length == 1) { if (this.partsForSelectedTint?.length == 1) {
this.selectedPartNumber = { value: this.partsForSelectedTint[0].partNumber }; this.selectedPartNumber = { value: this.partsForSelectedTint[0].partNumber };
// //select element with matching partNumber // //select element with matching partNumber
this.$nextTick(() => { this.$nextTick(() => {
const radioInput = document.querySelector('input[value=' + this.selectedPartNumber + ']'); const radioInput = document.querySelector('input[value=' + this.selectedPartNumber + ']');
@ -199,7 +199,7 @@ export default {
} }
} }
}, },
// Loads the preselected values from the store. // Loads the preselected values from the store.
LoadPreselectedValues() { LoadPreselectedValues() {
this.$nextTick(() => { this.$nextTick(() => {
@ -208,7 +208,7 @@ export default {
{ {
this.selectedTint = this.modelValue.color; this.selectedTint = this.modelValue.color;
} }
}); });
}, },
}, },
watch: { watch: {

View file

@ -1,5 +1,5 @@
<template> <template>
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }" > <Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }" >
<div class="page-container-grouped-styles position-relative"> <div class="page-container-grouped-styles position-relative">
<div class="fade-on-route-transition position-relative"> <div class="fade-on-route-transition position-relative">
<siteHeader cmsWidgetName="SiteHeaderWidget" /> <siteHeader cmsWidgetName="SiteHeaderWidget" />
@ -8,57 +8,59 @@
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<div class="select-car-form rounded"> <div class="select-car-form rounded">
<siteSubHeader <siteSubHeader
cmsWidgetName="SiteSubHeaderWidget" cmsWidgetName="SiteSubHeaderWidget"
class="siteSubHeader" class="siteSubHeader"
justification="left" justification="center"
darkGraySubText
/> />
<vehicleQuestion <vehicleQuestion
ref="vehicleYearQuestion" ref="vehicleYearQuestion"
class="mb-2 mt-4" class="mb-2 mt-4"
v-model="selectedYear" v-model="selectedYear"
cmsWidgetName="VehicleYearQuestion" cmsWidgetName="VehicleYearQuestion"
:updateValues="updateYearValues" :updateValues="updateYearValues"
validationRules="year-required" validationRules="year-required"
inputId="yearQuestionField" inputId="yearQuestionField"
/> />
<vehicleQuestion <vehicleQuestion
ref="vehicleMakeQuestion" ref="vehicleMakeQuestion"
class="mb-2 mt-4" class="mb-2 mt-4"
v-model="selectedMake" v-model="selectedMake"
cmsWidgetName="VehicleMakeQuestion" cmsWidgetName="VehicleMakeQuestion"
:updateValues="updateMakeValues" :updateValues="updateMakeValues"
validationRules="make-required" validationRules="make-required"
inputId="makeQuestionField" inputId="makeQuestionField"
/> />
<vehicleQuestion <vehicleQuestion
ref="vehicleModelQuestion" ref="vehicleModelQuestion"
class="mb-2 mt-4" class="mb-2 mt-4"
v-model="selectedModel" v-model="selectedModel"
cmsWidgetName="VehicleModelQuestion" cmsWidgetName="VehicleModelQuestion"
:updateValues="updateModelValues" :updateValues="updateModelValues"
validationRules="model-required" validationRules="model-required"
inputId="modelQuestionField" inputId="modelQuestionField"
/> />
<vehicleQuestion <vehicleQuestion
ref="vehicleStyleQuestion" ref="vehicleStyleQuestion"
class="mb-2 mt-4" class="mb-2 mt-4"
v-model="selectedStyle" v-model="selectedStyle"
cmsWidgetName="VehicleStyleQuestion" cmsWidgetName="VehicleStyleQuestion"
:updateValues="updateStyleValues" :updateValues="updateStyleValues"
validationRules="style-required" validationRules="style-required"
inputId="styleQuestionField" inputId="styleQuestionField"
/> />
<vehicleBanner <vehicleBanner
cmsWidgetName="VehicleBannerWidget" cmsWidgetName="VehicleBannerWidget"
:displayGenericVehicleImage="displayGeneric" :displayGenericVehicleImage="displayGeneric"
class="mt-5 mb-3" class="mt-5 mb-3"
ref="banner" ref="banner"
/> />
<siteFooter <siteFooter
class="mt-5"
cmsWidgetName="SiteFooterWidget" cmsWidgetName="SiteFooterWidget"
@ForwardClicked="forwardButtonAction" @ForwardClicked="forwardButtonAction"
:isForwardActionDisabled="!meta.valid" :isForwardActionDisabled="!meta.valid"
@ -106,33 +108,33 @@ export default {
selectedYear: null, selectedYear: null,
selectedMake: null, selectedMake: null,
selectedModel: null, selectedModel: null,
selectedStyle: null, selectedStyle: null,
}; };
}, },
props:{ props:{
cmsWidgetName:String, cmsWidgetName:String,
validationRules:String, validationRules:String,
}, },
mounted(){ mounted(){
this.$refs["vehicleYearQuestion"].getNewValues(); this.$refs["vehicleYearQuestion"].getNewValues();
}, },
async beforeRouteEnter(to, from, next) { async beforeRouteEnter(to, from, next) {
// Call APIs // Call APIs
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage); const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
// Settle promises and get results // Settle promises and get results
const promiseResultMap = [ const promiseResultMap = [
{ {
resultKey: "cmsContent", resultKey: "cmsContent",
promise: cmsContentPromise, promise: cmsContentPromise,
}, },
]; ];
let resultMap = await settleAllPromises(promiseResultMap); let resultMap = await settleAllPromises(promiseResultMap);
// Call the "next" function to complete the transition to this page. // Call the "next" function to complete the transition to this page.
next((vm) => { next((vm) => {
vm.setCmsContent(resultMap.cmsContent); vm.setCmsContent(resultMap.cmsContent);
}); });
}, },
@ -140,33 +142,28 @@ export default {
watch: { watch: {
selectedYear(value) { selectedYear(value) {
this.mainStore.updateVehicleYear(value); this.mainStore.updateVehicleYear(value);
this.$refs["vehicleMakeQuestion"].clearValues();
if(value) if(value)
{ {
this.$refs["vehicleMakeQuestion"].getNewValues(); this.$refs["vehicleMakeQuestion"].getNewValues();
} }
else{
this.$refs["vehicleMakeQuestion"].clearValues();
}
}, },
selectedMake(value) { selectedMake(value) {
this.mainStore.updateVehicleMake(value); this.mainStore.updateVehicleMake(value);
this.$refs["vehicleModelQuestion"].clearValues();
if(value) if(value)
{ {
this.$refs["vehicleModelQuestion"].getNewValues(); this.$refs["vehicleModelQuestion"].getNewValues();
} }
else{
this.$refs["vehicleModelQuestion"].clearValues();
}
}, },
selectedModel(value) { selectedModel(value) {
this.mainStore.updateVehicleModel(value); this.mainStore.updateVehicleModel(value);
this.$refs["vehicleStyleQuestion"].clearValues();
if(value) if(value)
{ {
this.$refs["vehicleStyleQuestion"].getNewValues(); this.$refs["vehicleStyleQuestion"].getNewValues();
} }
else{
this.$refs["vehicleStyleQuestion"].clearValues();
}
}, },
selectedStyle(value) { selectedStyle(value) {
this.mainStore.updateVehicleStyle(value); this.mainStore.updateVehicleStyle(value);
@ -191,7 +188,7 @@ export default {
this.$route this.$route
); );
}); });
}, },
async updateYearValues() { async updateYearValues() {
return await useMainStore().getVehicleYears(); return await useMainStore().getVehicleYears();
}, },
@ -232,6 +229,6 @@ export default {
.subheader-secondary { .subheader-secondary {
margin-top: .5rem; margin-top: .5rem;
padding: 0px; padding: 0px;
} }
</style> </style>

View file

@ -119,6 +119,11 @@ const vehicleWithNoAdditionalPartsOrQuestionsMockResponse = {
}, },
}; };
jest.mock("bootstrap", () => ({
getInstance: jest.fn(),
getOrCreateInstance: jest.fn(),
}));
const mockRoute = { const mockRoute = {
query: { query: {
// Needed inside vehicle-questions-mixin // Needed inside vehicle-questions-mixin

View file

@ -13,7 +13,7 @@
<vinLookupAlerts class="mt-5" :activeAlertType="activeVehicleLookupAlertType" /> <vinLookupAlerts class="mt-5" :activeAlertType="activeVehicleLookupAlertType" />
<vinQuestion v-model="vin" :mask="vinMask" :isDisabled="vinPopulatedOnPageLoad" textPosition="left" /> <vinQuestion v-model="vin" :mask="vinMask" :isDisabled="vinPopulatedOnPageLoad" textPosition="left" />
<vinLocationInformation /> <vinLocationInformation />
<siteFooter cmsWidgetName="SiteFooterWidget" :isForwardActionDisabled="!meta.valid" @backClicked="backButtonAction" @forwardClicked="forwardButtonAction" ref="siteFooter" /> <siteFooter cmsWidgetName="SiteFooterWidget" :isForwardActionDisabled="!meta.valid" @backClicked="backButtonAction" @forwardClicked="forwardButtonAction" ref="siteFooter" class="mt-5" />
</div> </div>
</div> </div>
</div> </div>
@ -152,7 +152,7 @@ export default {
this.bailout=true this.bailout=true
} }
if(this.bailout){ if(this.bailout){
return this.$router.navigate( return this.$router.navigate(
this.navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT, this.navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT,
this.$route); this.$route);
@ -188,6 +188,7 @@ export default {
// navigate back to vehicle-damage // navigate back to vehicle-damage
if (this.isCarIdDifferentFromTheStore && !isSelectedGlassAvailableForVehicle) { if (this.isCarIdDifferentFromTheStore && !isSelectedGlassAvailableForVehicle) {
this.mainStore.updateVehicle(this.vehicleFromLookup); this.mainStore.updateVehicle(this.vehicleFromLookup);
this.mainStore.resetDamageState();
this.$router.navigate( this.$router.navigate(
this.navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS, this.navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
this.$route, this.$route,

View file

@ -140,7 +140,8 @@
</div> </div>
<div class="row position-sticky top-100" id="welcomeFooter"> <div class="row position-sticky top-100" id="welcomeFooter">
<div class="col"> <div class="col">
<site-footer <siteFooter
class="mt-3"
cmsWidgetName="SiteFooterWidget" cmsWidgetName="SiteFooterWidget"
:isForwardActionDisabled="!meta.valid" :isForwardActionDisabled="!meta.valid"
@back-clicked="backButtonAction" @back-clicked="backButtonAction"
@ -259,12 +260,12 @@ export default {
const policyLookupResultMap = await settleAllPromises(promisePolicyLookupResultMap); const policyLookupResultMap = await settleAllPromises(promisePolicyLookupResultMap);
const policyInfo = policyLookupResultMap.policyLookupResponse; const policyInfo = policyLookupResultMap.policyLookupResponse;
// if policy lookup fails, navigate directly to policy-holder-details page // if policy lookup fails, navigate directly to policy-holder-details page
if (!policyInfo) { if (!policyInfo) {
this.navigateForward(); this.navigateForward();
} }
const policy = policyInfo.policies?.[0]; const policy = policyInfo.policies?.[0];
if (policy) { if (policy) {
//populate policy holder details from policy lookup //populate policy holder details from policy lookup
@ -274,8 +275,8 @@ export default {
this.mainStore.order.customer.address.zipCode = policy.insureds?.[0]?.zipCode; this.mainStore.order.customer.address.zipCode = policy.insureds?.[0]?.zipCode;
this.mainStore.order.customer.firstName = policy.insureds?.[0]?.firstName; this.mainStore.order.customer.firstName = policy.insureds?.[0]?.firstName;
this.mainStore.order.customer.lastName = policy.insureds?.[0]?.lastName; this.mainStore.order.customer.lastName = policy.insureds?.[0]?.lastName;
//populate vehicles //populate vehicles
this.vehiclesFound = policy.vehicles; this.vehiclesFound = policy.vehicles;
} }
return this.navigateForward(policy); return this.navigateForward(policy);
@ -289,7 +290,7 @@ export default {
// if policy lookup is successful and vehicles are found, navigate to policy-vehicles page // if policy lookup is successful and vehicles are found, navigate to policy-vehicles page
this.$router.navigate( this.$router.navigate(
this.navigationScenarios.CLICKED_FORWARD_POLICY_VERIFIED_WITH_VEHICLES, this.navigationScenarios.CLICKED_FORWARD_POLICY_VERIFIED_WITH_VEHICLES,
this.$route, this.$route,
{}, {},
{}, {},
this.vehiclesFound this.vehiclesFound
@ -312,7 +313,7 @@ export default {
); );
} }
}, },
getWelcomePageModelFromStore() { getWelcomePageModelFromStore() {
return { return {
policyNumber: this.mainStore.order.policy.policyNumber, policyNumber: this.mainStore.order.policy.policyNumber,

View file

@ -24,11 +24,7 @@ export const issPageValues = {
SCHEDULE_PAGE: 'schedule-page', SCHEDULE_PAGE: 'schedule-page',
VEHICLE_DAMAGE: 'vehicle-damage', VEHICLE_DAMAGE: 'vehicle-damage',
VEHICLE_LOOKUP: 'vehicle-lookup', VEHICLE_LOOKUP: 'vehicle-lookup',
VEHICLE_MAKE: 'vehicle-make',
VEHICLE_MODEL: 'vehicle-model',
VEHICLE_PARTS: 'vehicle-parts', VEHICLE_PARTS: 'vehicle-parts',
VEHICLE_STYLE: 'vehicle-style',
VEHICLE_YEAR: 'vehicle-year',
VEHICLE_SELECTION: 'vehicle-selection', VEHICLE_SELECTION: 'vehicle-selection',
VIN_LOOKUP: 'vin-lookup', VIN_LOOKUP: 'vin-lookup',
TPA_SUBMIT: 'tpa-submit', TPA_SUBMIT: 'tpa-submit',

View file

@ -17,58 +17,6 @@ const routingTable = function(store) {
} }
] ]
}, },
{
issPageValue: issPageValues.VEHICLE_YEAR,
maps: [
{
scenario: navigationScenarios.CLICKED_BACK,
destinationIssPageValue: issPageValues.POLICY_HOLDER_DETAILS
},
{
scenario: navigationScenarios.SELECTED_YEAR,
destinationIssPageValue: issPageValues.VEHICLE_MAKE
}
]
},
{
issPageValue: issPageValues.VEHICLE_MAKE,
maps: [
{
scenario: navigationScenarios.CLICKED_BACK,
destinationIssPageValue: issPageValues.VEHICLE_YEAR
},
{
scenario: navigationScenarios.SELECTED_MAKE,
destinationIssPageValue: issPageValues.VEHICLE_MODEL
}
]
},
{
issPageValue: issPageValues.VEHICLE_MODEL,
maps: [
{
scenario: navigationScenarios.CLICKED_BACK,
destinationIssPageValue: issPageValues.VEHICLE_MAKE
},
{
scenario: navigationScenarios.SELECTED_MODEL,
destinationIssPageValue: issPageValues.VEHICLE_STYLE
}
]
},
{
issPageValue: issPageValues.VEHICLE_STYLE,
maps: [
{
scenario: navigationScenarios.CLICKED_BACK,
destinationIssPageValue: issPageValues.VEHICLE_MODEL
},
{
scenario: navigationScenarios.SELECTED_STYLE,
destinationIssPageValue: issPageValues.VEHICLE_DAMAGE
}
]
},
{ {
issPageValue: issPageValues.VEHICLE_DAMAGE, issPageValue: issPageValues.VEHICLE_DAMAGE,
maps: [ maps: [

View file

@ -988,7 +988,8 @@ export const useMainStore = defineStore({
); );
if (haveMoldingQuestionAnswersChanged) { if (haveMoldingQuestionAnswersChanged) {
this.resetPartsAndDependencies(); this.updateGlassParts(null);
this.updateSupportingItems(null);
this.updateCapabilityQuestionAnswers(null); this.updateCapabilityQuestionAnswers(null);
this.updatePageData({ page: issPageValues.CAPABILITY_QUESTIONS, data: null }); this.updatePageData({ page: issPageValues.CAPABILITY_QUESTIONS, data: null });
} }
@ -1013,7 +1014,8 @@ export const useMainStore = defineStore({
); );
if (haveCapabilityQuestionAnswersChanged) { if (haveCapabilityQuestionAnswersChanged) {
this.resetPartsAndDependencies(); this.updateGlassParts(null);
this.updateSupportingItems(null);
} }
// Save new values // Save new values
@ -1236,9 +1238,7 @@ export const useMainStore = defineStore({
registrationInfo?.firstName !== this.order.vehicle.registration?.firstName || registrationInfo?.firstName !== this.order.vehicle.registration?.firstName ||
registrationInfo?.lastName !== this.order.vehicle.registration?.lastName registrationInfo?.lastName !== this.order.vehicle.registration?.lastName
) )
{ {
this.resetRegistrationAndDependencies();
if (!isSelectedGlassAvailableForVehicle) { if (!isSelectedGlassAvailableForVehicle) {
this.resetDamageState(); this.resetDamageState();
this.resetGlassPartsState(); this.resetGlassPartsState();
@ -1248,7 +1248,11 @@ export const useMainStore = defineStore({
this.updateRegistration(registrationInfo); this.updateRegistration(registrationInfo);
}; };
this.updateVehicle(vehicleInfo); if(vehicleInfo)
{
this.updateVehicle(vehicleInfo);
}
}, },
saveVin({ isSelectedGlassAvailableForVehicle, vehicleInfo }) { saveVin({ isSelectedGlassAvailableForVehicle, vehicleInfo }) {
//Reset dependent state when changing //Reset dependent state when changing

View file

@ -11,11 +11,11 @@ describe("Store", () => {
let store; let store;
const vueApp = createApp(App); const vueApp = createApp(App);
const pinia = createPinia();
vueApp.use(pinia);
beforeEach(() => { beforeEach(() => {
setActivePinia(createPinia()); const pinia = createPinia();
setActivePinia(pinia);
vueApp.use(pinia);
store = useMainStore(); store = useMainStore();
store.applicationUser.eventBus = []; store.applicationUser.eventBus = [];
jest.resetAllMocks(); jest.resetAllMocks();

View file

@ -1,139 +1,144 @@
<template> <template>
<!-- Checkbox groups MUST be wrapped in a <fieldset> and <legend> tag and must contain tabindex --> <!-- Checkbox groups MUST be wrapped in a <fieldset> and <legend> tag and must contain tabindex -->
<div class="ui-radio form-check" :class="[(errors.length > 0 || hasError) ? 'has-error' : '']"> <div class="ui-radio form-check" :class="[(errors.length > 0 || hasError) ? 'has-error' : '']">
<input <label class="d-inline-flex align-items-start form-check-label" :for="buttonID">
type="radio" <input
class="form-check-input" type="radio"
aria-checked="false" class="form-check-input"
:name="groupName" aria-checked="false"
:id="buttonID" :name="groupName"
:aria-required="isRequired" :id="buttonID"
:value="value" :aria-required="isRequired"
:v-model="checkValue" :value="value"
@change="handleCheckChange" :v-model="checkValue"
:checked="checkValue" @change="handleCheckChange"
:validationRules="validationRules" :checked="checkValue"
/> :validationRules="validationRules"
<label class="d-flex align-items-start form-check-label" :for="buttonID"> />
<p v-if="buttonLabel" class="m-0">{{ buttonLabel }}</p> <p v-if="buttonLabel" class="m-0">{{ buttonLabel }}</p>
<span v-if="screenReaderOnlyText" class="sr-only">{{ <span v-if="screenReaderOnlyText" class="sr-only">{{
screenReaderOnlyText screenReaderOnlyText
}}</span> }}</span>
</label> </label>
</div> </div>
</template> </template>
<script> <script>
import { useField } from "vee-validate"; import { useField } from "vee-validate";
export default { export default {
name: "radio", name: "radio",
props: { props: {
groupName: String, groupName: String,
buttonLabel: String, buttonLabel: String,
buttonID: String, buttonID: String,
isRequired: Boolean, isRequired: Boolean,
value: { value: {
type: [String, Number], type: [String, Number],
default: "", default: "",
}, },
screenReaderOnlyText: String, screenReaderOnlyText: String,
selectedValues: String, selectedValues: String,
hasError: Boolean, hasError: Boolean,
validationRules: String, validationRules: String,
valueToLogType: String, valueToLogType: String,
}, },
data() { data() {
return { return {
checkValue: Boolean, checkValue: Boolean,
}; };
}, },
created() { created() {
if (this.selectedValues) { if (this.selectedValues) {
this.checkValue = this.selectedValues === this.value; this.checkValue = this.selectedValues === this.value;
this.handleCheckChange(); this.handleCheckChange();
} else{ } else{
this.checkValue = false; this.checkValue = false;
} }
}, },
methods: { methods: {
handleCheckChange() { handleCheckChange() {
this.handleChange(this.value); this.handleChange(this.value);
const emitEvent = { const emitEvent = {
checkValue: this.checkValue, checkValue: this.checkValue,
value: this.value.toString(), value: this.value.toString(),
buttonID: this.buttonID && this.buttonID.toString(), buttonID: this.buttonID && this.buttonID.toString(),
}; };
this.$emit("isCheckedChanged", emitEvent); this.$emit("isCheckedChanged", emitEvent);
this.$emit("update:modelValue", emitEvent); this.$emit("update:modelValue", emitEvent);
}, },
}, },
setup(props) { setup(props) {
const inputType = "radio"; const inputType = "radio";
const { const {
value: inputValue, value: inputValue,
handleChange, handleChange,
errors, errors,
} = useField(props.groupName, props.validationRules, } = useField(props.groupName, props.validationRules,
{ {
type: inputType, type: inputType,
checkedValue: props.value, checkedValue: props.value,
}); });
return { return {
handleChange, handleChange,
errors, errors,
}; };
}, },
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.form-check { .form-check {
position: relative; position: relative;
.form-check-input { label {
border: 1px solid $gray-500; &:hover {
border-radius: 50%; cursor: pointer;
margin-right: 0.5rem; }
}
&:checked {
background-color: $white; .form-check-input {
background-size: 71%; border: 1px solid $gray-500;
background-position: center; border-radius: 50%;
border: 1px solid $blue; margin-right: 0.5rem;
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 50 50' xml:space='preserve'%3e%3ccircle cx='25' cy='25' r='25' fill='%231574A1'/%3e%3c/svg%3e");
+ label { &:checked {
p { background-color: $white;
font-weight: 500; background-size: 71%;
font-size: .875rem; background-position: center;
color: $black; border: 1px solid $blue;
} background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 50 50' xml:space='preserve'%3e%3ccircle cx='25' cy='25' r='25' fill='%231574A1'/%3e%3c/svg%3e");
+ label {
p {
font-weight: 500;
font-size: .875rem;
color: $black;
}
}
}
&:focus {
box-shadow: 0 0 0 2.5px $blue;
}
&, & + label {
margin-top: 0;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
}
&:hover {
.form-check-input {
box-shadow: 0 0 0 4px $blue-300;
}
}
p {
font-weight: 400;
font-size: .875rem;
color: $gray-600;
} }
}
&:focus {
box-shadow: 0 0 0 2.5px $blue;
}
&, & + label {
margin-top: 0;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
} }
</style>
&:hover {
.form-check-input {
box-shadow: 0 0 0 4px $blue-300;
}
}
p {
font-weight: 400;
font-size: .875rem;
color: $gray-600;
}
}
</style>