diff --git a/jest.config.js b/jest.config.js index 93249f226..0f45a8a97 100644 --- a/jest.config.js +++ b/jest.config.js @@ -31,5 +31,5 @@ module.exports = { }, }, // Uncomment this to avoid the massive amount of warnings we are getting for onSubmit and onInvalidSubmit - // silent: true, + silent: true, }; diff --git a/src/layouts/service-location/appointment-type-question/appointment-type-question.vue b/src/layouts/service-location/appointment-type-question/appointment-type-question.vue index 0a904da96..ca452ac01 100644 --- a/src/layouts/service-location/appointment-type-question/appointment-type-question.vue +++ b/src/layouts/service-location/appointment-type-question/appointment-type-question.vue @@ -8,7 +8,7 @@ :answers="answersToDisplay" :groupName="groupName" buttonTypeString="listCard" - v-model="selectedValues" + v-model="selectedValue" :suppressError="suppressError" :validationRules="validationRules" isRequired /> @@ -55,7 +55,7 @@ export default { }) : []; }, - selectedValues: { + selectedValue: { get: function () { return this.modelValue; }, diff --git a/src/layouts/service-location/classes/provider-address.js b/src/layouts/service-location/classes/provider-address.js new file mode 100644 index 000000000..52f24109a --- /dev/null +++ b/src/layouts/service-location/classes/provider-address.js @@ -0,0 +1,15 @@ +export class ProviderAddress { + constructor( + streetAddress = null, + city = null, + state = null, + zipCode = null, + zipCodeCtu = null + ) { + this.streetAddress = streetAddress; + this.city = city; + this.state = state; + this.zipCode = zipCode; + this.zipCodeCtu = zipCodeCtu; + } +} diff --git a/src/layouts/service-location/classes/provider.js b/src/layouts/service-location/classes/provider.js new file mode 100644 index 000000000..dd9c7cd8c --- /dev/null +++ b/src/layouts/service-location/classes/provider.js @@ -0,0 +1,8 @@ +import { ProviderAddress } from "./provider-address"; + +export class Provider { + constructor(providerNumber = null, address = null) { + this.providerNumber = providerNumber; + this.address = address ?? new ProviderAddress(); + } +} diff --git a/src/layouts/service-location/helpers/service-location-helper/service-location-helper.js b/src/layouts/service-location/helpers/service-location-helper/service-location-helper.js index 2298aa386..cb4c06100 100644 --- a/src/layouts/service-location/helpers/service-location-helper/service-location-helper.js +++ b/src/layouts/service-location/helpers/service-location-helper/service-location-helper.js @@ -1,5 +1,4 @@ import { storeActions } from "@/constants/store-actions"; -import store from "@/store"; import baseMixin from "@/mixins/base-mixin.js"; export async function getPricedMobileFeePart(serviceZipCode, pageNameToLog) { diff --git a/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.vue b/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.vue index 2c63bdf43..58420ce3a 100644 --- a/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.vue +++ b/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.vue @@ -314,9 +314,10 @@ export default { margin-top: 0em; } -#mobileLocationLinkPromptId { +.update-mobile-location-text-link { white-space: pre-line; } + .text-black { color: $black; } diff --git a/src/layouts/service-location/service-location.spec.js b/src/layouts/service-location/service-location.spec.js index 0073a9f65..6cd3bc2f1 100644 --- a/src/layouts/service-location/service-location.spec.js +++ b/src/layouts/service-location/service-location.spec.js @@ -7,7 +7,10 @@ import { getMountOptions } from "@/helpers/unit-test-helper"; import store from "@/store"; import baseMixin from "@/mixins/base-mixin"; -import { getServiceabilityDetails } from "@/layouts/service-location/helpers/service-location-helper/service-location-helper"; +import { + getServiceabilityDetails, + Provider, +} from "@/layouts/service-location/helpers/service-location-helper/service-location-helper"; // Define Mocks jest.mock("@/helpers/cms-content-helper", () => ({ @@ -16,6 +19,8 @@ jest.mock("@/helpers/cms-content-helper", () => ({ }), })); +jest.mock("./classes/provider"); + const mockGetPricedMobileFeePart = (mockServiceZipCode) => { let mobileFeePart = {}; @@ -397,6 +402,7 @@ describe("service-location.vue", () => { await wrapper.setData({ selectedAppointmentType: "Mobile", + providerData: { mobileProviderNumber: "01820" }, }); const mobileLocationQuestionsComponent = wrapper.findComponent({ @@ -448,6 +454,7 @@ describe("service-location.vue", () => { await wrapper.setData({ selectedAppointmentType: "Mobile", + providerData: { mobileProviderNumber: "01820" }, }); const mobileLocationQuestionsComponent = wrapper.findComponent({ @@ -511,6 +518,7 @@ describe("service-location.vue", () => { await wrapper.setData({ selectedAppointmentType: "Mobile", + providerData: { mobileProviderNumber: "01820" }, }); const mobileLocationQuestionsComponent = wrapper.findComponent({ diff --git a/src/layouts/service-location/service-location.vue b/src/layouts/service-location/service-location.vue index dc8b90f41..2ca24e353 100644 --- a/src/layouts/service-location/service-location.vue +++ b/src/layouts/service-location/service-location.vue @@ -95,6 +95,7 @@ v-model="selectedProvider" :selectedAppointmentType="selectedAppointmentType" :isDisplayed="isShopQuestionDisplayed" + @updated-shop-list="setUpdatedShopList" cmsWidgetName="ShopQuestionWidget" /> @@ -135,6 +136,9 @@ import { getPricedMobileFeePart, getServiceabilityDetails, } from "@/layouts/service-location/helpers/service-location-helper/service-location-helper"; + +import { Provider } from "@/layouts/service-location/classes/provider"; + import store from "@/store"; // Validation @@ -176,6 +180,7 @@ export default { mobileFeePart: null, zipContainsMilitaryBase: false, zipCodeCtu: null, + providerData: null, }; }, async beforeRouteEnter(to, from, next) { @@ -229,7 +234,12 @@ export default { resultMap.serviceabilityDetails, resultMap.mobileFeePart ); + + // Initialize the Shop Question component vm.$refs.shopQuestion.initializeComponent(resultMap.shopQuestionInitialData); + + // Initialize the page level shop data + vm.providerData = resultMap.shopQuestionInitialData; }); }, computed: { @@ -333,6 +343,9 @@ export default { displayNoShopsAlert() { return !this.isServiceableInshop && !this.isServiceableMobile; }, + recalibrationInformationModal() { + return this.$refs.recalibrationInformationModal; + }, }, methods: { arePagePrerequisitesValid() { @@ -403,6 +416,15 @@ export default { this.isRecalibrationServiceableMobile = serviceabilityDetails.isRecalibrationServiceableMobile; }, + async reloadShopData(zipCode) { + await this.$refs.shopQuestion.reloadShopData(zipCode); + }, + setUpdatedShopList(providerData) { + this.providerData = providerData; + }, + openRecalibrationInformationModal() { + this.recalibrationInformationModal.openModal(); + }, backButtonAction() { this.$router.navigateWithoutSaving(this.navigationScenarios.CLICKED_BACK, this.$route); }, @@ -472,11 +494,25 @@ export default { this.updateAndSaveSupportingItems(); this.$router.navigateWithSaving(this.navigationScenarios.CLICKED_FORWARD, this.$route); }, - openModalAction(modalName) { - this.$refs[modalName].openModal(); + }, + watch: { + selectedAppointmentType: { + handler(newValue) { + if (newValue === "Mobile") { + this.selectedProvider = new Provider(this.providerData.mobileProviderNumber); + } else { + this.selectedProvider = new Provider(); + } + }, }, - async reloadShopData() { - await this.$refs.shopQuestion.reloadShopData(this.zipCode); + providerData: { + handler(newValue) { + if (newValue === "Mobile") { + this.selectedProvider = new Provider(this.providerData.mobileProviderNumber); + } else { + this.selectedProvider = new Provider(); + } + }, }, }, components: { diff --git a/src/layouts/service-location/shop-question/shop-question.vue b/src/layouts/service-location/shop-question/shop-question.vue index 7a32baf90..c3f31c68d 100644 --- a/src/layouts/service-location/shop-question/shop-question.vue +++ b/src/layouts/service-location/shop-question/shop-question.vue @@ -54,6 +54,8 @@ import { nextTick } from "vue"; import { getAvailabilityRating } from "@/layouts/service-location/helpers/service-location-helper/service-location-helper"; +import { Provider } from "@/layouts/service-location/classes/provider"; + defineRule("option-required", required(errorMessages.OPTION_REQUIRED)); export default { @@ -136,6 +138,7 @@ export default { }, initializeComponent(shopQuestionInitialData) { this.shopProviders = shopQuestionInitialData.shopProviders; + this.$emit("updated-shop-list", shopQuestionInitialData); }, async getNextShopsFromList(numberToGet = 3) { const shopIterator = (array, n) => { @@ -206,9 +209,9 @@ export default { await this.getNextShopsFromList(); }, getSelectedProviderObject(providerNumber) { - const provider = this.shopProviders?.find( - (provider) => provider.providerNumber == providerNumber - ); + const provider = + this.shopProviders?.find((provider) => provider.providerNumber == providerNumber) ?? + new Provider(); return provider; }, @@ -222,18 +225,15 @@ export default { }, watch: { selectedAppointmentType: { - async handler(newValue) { + // Question: Does it matter if this fires when clicking Mobile? Ideally it should not, but it doesn't seem to effect anything + // What we DON'T want to do here is create a dependency by checking if the selectedAppointmentType is Mobile as that has + // nothing to do with this component. We could mitigate this by showing / hiding this component with v-if but that messes + // up the component initialization on page load. + async handler() { this.resetAnswers(); await nextTick(); - - this.selectedProviderNumber = null; - - await nextTick(); - - if (newValue !== "Mobile") { - this.getNextShopsFromList(); - } + this.getNextShopsFromList(); }, }, shopProviders: { diff --git a/src/store/index.js b/src/store/index.js index 80b12fdb5..431fce721 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1381,6 +1381,7 @@ export const actions = { ? convertGlassPieceToBackEndCompatibleFormat(order.damage.glassToReplace) : []; var payload = { + zipCode: order.serviceLocation.provider.zipCode, providerNumber: providerNumber, startDate: startDate, endDate: endDate,