From b6f70b9b868386533f0bcd587c2500bda396e696 Mon Sep 17 00:00:00 2001 From: Leah Schumann Date: Tue, 14 Feb 2023 07:46:29 -0500 Subject: [PATCH 01/17] Moved 'useForm' inside modal component --- src/digital-components/modal/modal.vue | 22 +++++----- .../mobile-location-modal-questions.vue | 43 +++++++------------ .../service-location/service-location.vue | 7 +-- .../service-zip-modal-question.vue | 7 --- 4 files changed, 32 insertions(+), 47 deletions(-) diff --git a/src/digital-components/modal/modal.vue b/src/digital-components/modal/modal.vue index 1bf7c3fce..0586b9f1a 100644 --- a/src/digital-components/modal/modal.vue +++ b/src/digital-components/modal/modal.vue @@ -43,7 +43,7 @@ From 4562f7679eec2c10f28b4be97c7a06b954e809e4 Mon Sep 17 00:00:00 2001 From: Leah Schumann Date: Fri, 17 Feb 2023 09:35:10 -0500 Subject: [PATCH 13/17] Added code to display invalid zip alert --- .../mobile-location-modal-questions.vue | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) 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 31378fc95..dc2df2e9a 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 @@ -36,7 +36,7 @@ ref="alertInvalidZip" v-if="displayInvalidZipAlert" class="my-4" - :cmsWidgetName="AlertInvalidZipWidget" + cmsWidgetName="AlertInvalidZipWidget" alertClass="alert-danger" v-bind:isDismissible="false" /> @@ -57,6 +57,7 @@ export default { data() { return { internalModel: this.copyModel(this.modelValue), + displayInvalidZipAlert: false, }; }, props: { @@ -162,11 +163,17 @@ export default { async setMobileLocation() { // TODO: Any lookups or actions to be taken before assigning the Mobile Location + const zipCodeData = await this.getZipCodeData(this.internalModel.addressQuestions.zipCode); - // Update the page level model - this.$emit("update:modelValue", this.internalModel); + if (!zipCodeData.isValid) { + this.displayInvalidZipAlert = true; + } else { + // Update the page level model + this.$emit("update:modelValue", this.internalModel); + + this.closeModal(); + } - this.closeModal(); }, }, watch: { From 487c83e3a0173b5ed2c9a94ff131ddd3bbcc0058 Mon Sep 17 00:00:00 2001 From: Leah Schumann Date: Fri, 17 Feb 2023 09:39:40 -0500 Subject: [PATCH 14/17] Resolving this issue: https://stackoverflow.com/questions/75179573/how-to-fix-loading-the-google-maps-javascript-api-without-a-callback-is-not-supp --- .../address-questions/address-questions.vue | 2 +- .../mobile-location-modal-questions.vue | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue b/src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue index 8a28ea669..c37e596ef 100644 --- a/src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue +++ b/src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue @@ -215,7 +215,7 @@ export default { const apiKey = applicationConfig.GOOGLE_PLACES_API_KEY; this.$loadScript( - `https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=places` + `https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=places&callback=Function.prototype` ) .then(() => { // Script is loaded, initialize the autocomplete textbox 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 dc2df2e9a..6a6e6cc56 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 @@ -163,7 +163,9 @@ export default { async setMobileLocation() { // TODO: Any lookups or actions to be taken before assigning the Mobile Location - const zipCodeData = await this.getZipCodeData(this.internalModel.addressQuestions.zipCode); + const zipCodeData = await this.getZipCodeData( + this.internalModel.addressQuestions.zipCode + ); if (!zipCodeData.isValid) { this.displayInvalidZipAlert = true; @@ -173,7 +175,6 @@ export default { this.closeModal(); } - }, }, watch: { From 4ddc9c41d0756161d51914771fc1f8365810255b Mon Sep 17 00:00:00 2001 From: Leah Schumann Date: Mon, 20 Feb 2023 09:22:22 -0500 Subject: [PATCH 15/17] Suggested changes from Mark regarding inputIDs for textboxQuestion and dropdownQuestion --- .../dropdown-question/dropdown-question.vue | 3 ++ .../text-block/text-block.vue | 4 ++ .../textbox-question/textbox-question.vue | 7 +++- .../mobile-location-modal-questions.vue | 29 ++++++++++++--- .../service-location/service-location.vue | 37 +++++++++++++++---- .../service-zip-modal-question.vue | 20 +++++++--- 6 files changed, 81 insertions(+), 19 deletions(-) diff --git a/src/digital-components/dropdown-question/dropdown-question.vue b/src/digital-components/dropdown-question/dropdown-question.vue index 3dfc82947..e122837c4 100644 --- a/src/digital-components/dropdown-question/dropdown-question.vue +++ b/src/digital-components/dropdown-question/dropdown-question.vue @@ -86,6 +86,9 @@ export default { errors, }; }, + mounted() { + this.$emit("dropdownQuestionEvent.inputIdAssigned", this.inputId); + }, computed: { questionText() { return this.getCmsContent(this.cmsWidgetName, "QuestionText"); diff --git a/src/digital-components/text-block/text-block.vue b/src/digital-components/text-block/text-block.vue index 33854e143..9e7df6312 100644 --- a/src/digital-components/text-block/text-block.vue +++ b/src/digital-components/text-block/text-block.vue @@ -9,6 +9,7 @@ export default { name: "textBlock", props: { + customText: String, // used to allow the insert of token values into textblock justifyText: String, // left, right, center typeStyle: String, // h1-h6, body, small, label, caption (see Figma or Confluence documentation) fontWeight: String, // bold=500, default is 400 @@ -16,6 +17,9 @@ export default { }, computed: { TextBlockCopy() { + if (this.customText) { + return this.customText; + } return this.getCmsContent(this.cmsWidgetName, "Text"); }, }, diff --git a/src/digital-components/textbox-question/textbox-question.vue b/src/digital-components/textbox-question/textbox-question.vue index 90aa33ddf..2b14aac6b 100644 --- a/src/digital-components/textbox-question/textbox-question.vue +++ b/src/digital-components/textbox-question/textbox-question.vue @@ -76,7 +76,9 @@ export default { includeSearchIcon: Boolean, }, setup(props) { - const inputId = !props.customInputId ? `input-${crypto.randomUUID()}` : props.customInputId; + const inputId = !props.customInputId + ? `input-${crypto.randomUUID()}` + : props.customInputId; const propsClone = Object.assign({}, props); const modelValue = propsClone.modelValue; @@ -126,6 +128,9 @@ export default { }, }, }, + mounted() { + this.$emit("textboxQuestionEvent.inputIdAssigned", this.inputId); + }, watch: { async value(newValue) { const result = await validate(newValue, this.validationRules); // do a test validation check, without triggering full validation 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 6a6e6cc56..bb768fa14 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 @@ -15,7 +15,10 @@ @click-event="openModal" aria-label="Modal window" /> - + + v-model="internalModel.zipCode" + v-on="{ 'textboxQuestionEvent.inputIdAssigned': onInputIdAssigned }" + :cmsWidgetName="textboxQuestionWidgetName" /> Date: Mon, 20 Feb 2023 10:39:06 -0500 Subject: [PATCH 16/17] Checking in before writing some unit tests --- src/constants/endpoints.js | 4 +++ src/constants/store-actions.js | 1 + .../textbox-question/textbox-question.vue | 4 +-- .../mobile-location-modal-questions.vue | 27 ++++++++++++++++--- src/store/index.js | 7 +++++ 5 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/constants/endpoints.js b/src/constants/endpoints.js index 9f4c60d61..19019477b 100644 --- a/src/constants/endpoints.js +++ b/src/constants/endpoints.js @@ -70,6 +70,10 @@ const endpoints = { url: "/parts/api/v1/parts/rain-defense", method: "GET", }, + GetMobileFeePart: { + url: "/parts/api/v1/parts/mobile-fee", + method: "GET", + }, GetSupportingItems: { url: "/parts/api/v1/parts/supporting-items", method: "POST", diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js index 428280d40..eb781b020 100644 --- a/src/constants/store-actions.js +++ b/src/constants/store-actions.js @@ -27,6 +27,7 @@ const storeActions = { GET_CAPABILITY_QUESTIONS: "getCapabilityQuestions", GET_PART_FROM_CAPABILITY_QUESTION_ANSWER: "getPartFromCapabilityQuestionAnswer", GET_MOLDING_QUESTIONS: "getMoldingQuestions", + GET_MOBILE_FEE_PART: "getMobileFeePart", SAVE_SESSION: "saveSession", LOAD_SESSION: "loadSession", UPDATE_STORE_WITH_SAVE_SESSION_RESPONSE: "updateStoreWithSaveSessionResponse", diff --git a/src/digital-components/textbox-question/textbox-question.vue b/src/digital-components/textbox-question/textbox-question.vue index 2b14aac6b..2766e2cd9 100644 --- a/src/digital-components/textbox-question/textbox-question.vue +++ b/src/digital-components/textbox-question/textbox-question.vue @@ -76,9 +76,7 @@ export default { includeSearchIcon: Boolean, }, setup(props) { - const inputId = !props.customInputId - ? `input-${crypto.randomUUID()}` - : props.customInputId; + const inputId = !props.customInputId ? `input-${crypto.randomUUID()}` : props.customInputId; const propsClone = Object.assign({}, props); const modelValue = propsClone.modelValue; 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 bb768fa14..9aeda710c 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 @@ -53,6 +53,8 @@ import alert from "@/ux-components/alert/alert"; import addressQuestions from "@/layouts/address-lookup/customer-questions/address-questions/address-questions"; import vehicleProtectedQuestion from "@/layouts/service-location/mobile-location-modal-questions/vehicle-protected-question/vehicle-protected-question"; import textBlock from "@/digital-components/text-block/text-block"; +import baseMixin from "@/mixins/base-mixin.js"; +import { storeActions } from "@/constants/store-actions"; export default { name: "mobile-location-modal-questions", @@ -61,7 +63,7 @@ export default { return { internalModel: this.copyModel(this.modelValue), displayInvalidZipAlert: false, - mobileFee: this.getMobileFee(), + mobileFee: "" }; }, props: { @@ -88,6 +90,9 @@ export default { alertNonServiceableZipWidgetName: String, alertInvalidZipWidgetName: String, }, + async mounted() { + this.mobileFee = await this.getMobileFee(); + }, computed: { mobileFeeText() { const cmsContentText = this.getCmsContent("MobileFeeDisclaimerWidget", "Text"); @@ -142,10 +147,24 @@ export default { isZipServiceableInShop: modelToCopy.isZipServiceableInShop, }; }, + + async getMobileFee() { + // Get the Mobile Fee Part + const mobileFeePart = await baseMixin.methods.dispatchStoreAction( + storeActions.GET_MOBILE_FEE_PART, + null, + false + ); + + // Get the Mobile Fee Part Price + const pricingResults = await baseMixin.methods.dispatchStoreAction( + storeActions.PRICE_ORDER_ITEMS, + [ mobileFeePart.data ], + false + ); + + return await baseMixin.methods.getTotalLineItemPrice(pricingResults[0]); - getMobileFee() { - // TODO: Call new service endpoint to get the Mobile Fee price - return "34.99"; }, openModal() { diff --git a/src/store/index.js b/src/store/index.js index 93a3e5a25..10cf7d797 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -907,6 +907,13 @@ export const actions = { }); }, + getMobileFeePart(context) { + return globalMethods.callMockHttpClient({ + method: endpoints.GetMobileFeePart.method, + endpoint: "https://run.mocky.io/v3/795de4cb-d014-48b4-9338-dab33261adce", //TODO: Remove Mocky Endpoint + }); + }, + getSupportingItems(context) { const glassPartsArray = context.getters.lineItems.glassParts ?? []; const carId = context.getters.vehicle.carId; From 023a521ec11c834f386151032916ad7c3389fed5 Mon Sep 17 00:00:00 2001 From: Leah Schumann Date: Mon, 20 Feb 2023 13:14:51 -0500 Subject: [PATCH 17/17] Now retrieving the actual mobile fee but we're mocking the part call --- src/constants/endpoints.js | 2 +- .../mobile-location-modal-questions.vue | 9 ++++----- src/store/index.js | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/constants/endpoints.js b/src/constants/endpoints.js index 19019477b..6b1e69609 100644 --- a/src/constants/endpoints.js +++ b/src/constants/endpoints.js @@ -70,7 +70,7 @@ const endpoints = { url: "/parts/api/v1/parts/rain-defense", method: "GET", }, - GetMobileFeePart: { + GetMobileFeePart: { url: "/parts/api/v1/parts/mobile-fee", method: "GET", }, 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 9aeda710c..d1aa4dd4b 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 @@ -63,7 +63,7 @@ export default { return { internalModel: this.copyModel(this.modelValue), displayInvalidZipAlert: false, - mobileFee: "" + mobileFee: "", }; }, props: { @@ -147,24 +147,23 @@ export default { isZipServiceableInShop: modelToCopy.isZipServiceableInShop, }; }, - + async getMobileFee() { // Get the Mobile Fee Part const mobileFeePart = await baseMixin.methods.dispatchStoreAction( storeActions.GET_MOBILE_FEE_PART, - null, + null, false ); // Get the Mobile Fee Part Price const pricingResults = await baseMixin.methods.dispatchStoreAction( storeActions.PRICE_ORDER_ITEMS, - [ mobileFeePart.data ], + [mobileFeePart.data], false ); return await baseMixin.methods.getTotalLineItemPrice(pricingResults[0]); - }, openModal() { diff --git a/src/store/index.js b/src/store/index.js index 10cf7d797..5f4d7c1f5 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -912,7 +912,7 @@ export const actions = { method: endpoints.GetMobileFeePart.method, endpoint: "https://run.mocky.io/v3/795de4cb-d014-48b4-9338-dab33261adce", //TODO: Remove Mocky Endpoint }); - }, + }, getSupportingItems(context) { const glassPartsArray = context.getters.lineItems.glassParts ?? [];