From 2544954f8f15dcae5918a904fafbf3df4370be0e Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Tue, 14 Jun 2022 16:49:24 -0400 Subject: [PATCH 001/132] CSR-652 | Add CSS class to each alert That matches CMS --- .../funnel-header/funnel-header.vue | 5 ++-- src/layouts/address-lookup/address-lookup.vue | 18 ++++++++----- .../address-questions/address-questions.vue | 6 +++-- .../address-vehicles-question.vue | 6 ++--- .../address-vehicles/address-vehicles.vue | 11 ++++---- src/layouts/estimate/estimate.vue | 9 +++---- .../license-plate-lookup.vue | 14 ++++++---- src/layouts/vehicle-damage/vehicle-damage.vue | 7 +++-- .../windshield-options/windshield-options.vue | 4 +-- src/layouts/vehicle-parts/vehicle-parts.vue | 2 +- src/layouts/vin-lookup/vin-lookup.vue | 26 +++++++++---------- src/ux-components/alert/alert.vue | 17 +++++++++--- 12 files changed, 71 insertions(+), 54 deletions(-) diff --git a/src/common-components/funnel-header/funnel-header.vue b/src/common-components/funnel-header/funnel-header.vue index 1fa13094f..dcc997c5f 100644 --- a/src/common-components/funnel-header/funnel-header.vue +++ b/src/common-components/funnel-header/funnel-header.vue @@ -7,11 +7,12 @@ diff --git a/src/layouts/address-lookup/address-lookup.vue b/src/layouts/address-lookup/address-lookup.vue index 2e13299de..f171d571b 100644 --- a/src/layouts/address-lookup/address-lookup.vue +++ b/src/layouts/address-lookup/address-lookup.vue @@ -12,27 +12,33 @@
- - - -
- - - diff --git a/src/layouts/address-vehicles/address-vehicles.vue b/src/layouts/address-vehicles/address-vehicles.vue index faf71e1fb..9d818628d 100644 --- a/src/layouts/address-vehicles/address-vehicles.vue +++ b/src/layouts/address-vehicles/address-vehicles.vue @@ -10,16 +10,15 @@ - -
+ class="vinLookupMethodHeading" + cmsWidgetName="AlertVinLookupQuestion" + alertClass="" + />
@@ -58,14 +59,17 @@ />
- -
- @@ -32,9 +31,9 @@ :selectedDamageLocations="selectedDamageLocations" /> diff --git a/src/layouts/vehicle-damage/windshield-options/windshield-options.vue b/src/layouts/vehicle-damage/windshield-options/windshield-options.vue index bdbe25195..fd1254228 100644 --- a/src/layouts/vehicle-damage/windshield-options/windshield-options.vue +++ b/src/layouts/vehicle-damage/windshield-options/windshield-options.vue @@ -8,9 +8,9 @@ :validationRules="windshieldDamageTypeQuestionValidationRules" /> @@ -30,9 +30,9 @@ isRequired /> diff --git a/src/layouts/vehicle-parts/vehicle-parts.vue b/src/layouts/vehicle-parts/vehicle-parts.vue index 842cc0720..67f594cc0 100644 --- a/src/layouts/vehicle-parts/vehicle-parts.vue +++ b/src/layouts/vehicle-parts/vehicle-parts.vue @@ -9,8 +9,8 @@
diff --git a/src/layouts/vin-lookup/vin-lookup.vue b/src/layouts/vin-lookup/vin-lookup.vue index 9dc81f719..736396bde 100644 --- a/src/layouts/vin-lookup/vin-lookup.vue +++ b/src/layouts/vin-lookup/vin-lookup.vue @@ -60,49 +60,47 @@

{{ alertHeadline }}

diff --git a/src/mixins/vin-pages-mixin.js b/src/mixins/vin-pages-mixin.js index fce96c980..196a21e63 100644 --- a/src/mixins/vin-pages-mixin.js +++ b/src/mixins/vin-pages-mixin.js @@ -7,10 +7,14 @@ export default { methods: { async navigateForwardWithSingleCarMatch() { const result = await this.dispatchStoreAction(storeActions.GET_PARTS_OR_QUESTIONS); - const partsOrQuestions = result.data.partsOrQuestions; const hasPartsQuestions = partsOrQuestions.some(pq => pq.partQuestions?.length > 0); const hasGlassLocationWithMultipleParts = partsOrQuestions.some(pq => pq.parts?.length > 1); + const hasChildPartQuestions = partsOrQuestions.some(pq => { + return pq.parts?.some(part => part.childPartQuestions?.length > 0); + }); + + // TODO - ADD CHECK FOR CAPABILITY QUESTIONS TO SEE IF NAVIGATE TO CAPABILITY-QUESTIONS if (hasPartsQuestions) { this.$router.navigate(this.navigationScenarios.SELECTED_VIN_WITH_PART_QUESTIONS, this.$route, {}, {}, result.data); @@ -18,6 +22,9 @@ export default { else if (hasGlassLocationWithMultipleParts) { this.$router.navigate(this.navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS, this.$route, {}, {}, result.data); } + else if (hasChildPartQuestions) { + this.$router.navigate(this.navigationScenarios.SELECTED_VIN_WITH_MOLDING_QUESTIONS, this.$route, {}, {}, result.data); + } else { store.commit(storeMutations.UPDATE_GLASS_PARTS, result.data); this.$refs.loadingModal.showModal(); diff --git a/src/router/router-constants/fmgPage-values.js b/src/router/router-constants/fmgPage-values.js index d067895ee..7a38c6b40 100644 --- a/src/router/router-constants/fmgPage-values.js +++ b/src/router/router-constants/fmgPage-values.js @@ -8,6 +8,7 @@ const fmgPageValues = { VIN_LOOKUP: "vin-lookup", VEHICLE_PARTS: "vehicle-parts", PART_QUESTIONS: "part-questions", + MOLDING_QUESTIONS: "molding-questions", LICENSE_PLATE_LOOKUP: "license-plate-lookup", REVEAL: "reveal", ESTIMATE: "estimate", diff --git a/src/router/router-constants/navigation-scenarios.js b/src/router/router-constants/navigation-scenarios.js index 5768c55de..ab1772de3 100644 --- a/src/router/router-constants/navigation-scenarios.js +++ b/src/router/router-constants/navigation-scenarios.js @@ -10,6 +10,7 @@ const navigationScenarios = { SELECTED_PARTS: "SELECTED_PARTS", SELECTED_VIN_WITH_PART_QUESTIONS: "SELECTED_VIN_WITH_PART_QUESTIONS", SELECTED_VIN_WITH_MULTIPLE_PARTS: "SELECTED_VIN_WITH_MULTIPLE_PARTS", + SELECTED_VIN_WITH_MOLDING_QUESTIONS: "SELECTED_VIN_WITH_MOLDING_QUESTIONS", CONTINUING_WITH_SINGLE_PART: "CONTINUING_WITH_SINGLE_PART", CONTINUING_WITH_MULTIPLE_VEHICLES: "CONTINUING_WITH_MULTIPLE_VEHICLES", SELECTED_VIN_HAS_MISMATCHED_GLASS: "SELECTED_VIN_HAS_MISMATCHED_GLASS", @@ -19,6 +20,7 @@ const navigationScenarios = { SELECTED_HOME_ADDRESS: "SELECTED_HOME_ADDRESS", ANSWERED_QUESTIONS_WITH_SINGLE_PART: "ANSWERED_QUESTIONS_WITH_SINGLE_PART", ANSWERED_QUESTIONS_WITH_MULTIPLE_PARTS: "ANSWERED_QUESTIONS_WITH_MULTIPLE_PARTS", + HAS_MOLDING_QUESTIONS: "HAS_MOLDING_QUESTIONS", SELECTED_PROVIDE_VIN_DIFFERENT_WAY: "SELECTED_PROVIDE_VIN_DIFFERENT_WAY" }; diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index 3f81e99ad..82bb59ff6 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -79,8 +79,8 @@ const routingTable = [ destinationFmgPageValue: fmgPageValues.QUOTE, }, { - scenario: navigationScenarios.CLICKED_FORWARD, - destinationFmgPageValue: fmgPageValues.REVEAL, + scenario: navigationScenarios.HAS_MOLDING_QUESTIONS, + destinationFmgPageValue: fmgPageValues.MOLDING_QUESTIONS }, ], }, @@ -119,6 +119,10 @@ const routingTable = [ { scenario: navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS, destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS + }, + { + scenario: navigationScenarios.SELECTED_VIN_WITH_MOLDING_QUESTIONS, + destinationFmgPageValue: fmgPageValues.MOLDING_QUESTIONS } ], }, @@ -140,6 +144,10 @@ const routingTable = [ { scenario: navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS, destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS + }, + { + scenario: navigationScenarios.SELECTED_VIN_WITH_MOLDING_QUESTIONS, + destinationFmgPageValue: fmgPageValues.MOLDING_QUESTIONS } ], }, @@ -165,6 +173,10 @@ const routingTable = [ { scenario: navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS, destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS + }, + { + scenario: navigationScenarios.SELECTED_VIN_WITH_MOLDING_QUESTIONS, + destinationFmgPageValue: fmgPageValues.MOLDING_QUESTIONS } ], }, @@ -225,12 +237,25 @@ const routingTable = [ scenario: navigationScenarios.ANSWERED_QUESTIONS_WITH_MULTIPLE_PARTS, destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS }, + { + scenario: navigationScenarios.HAS_MOLDING_QUESTIONS, + destinationFmgPageValue: fmgPageValues.MOLDING_QUESTIONS, + }, { scenario: navigationScenarios.ANSWERED_QUESTIONS_WITH_SINGLE_PART, destinationFmgPageValue: fmgPageValues.QUOTE, }, ] }, + { + fmgPageValue: fmgPageValues.MOLDING_QUESTIONS, + maps: [ + { + scenario: navigationScenarios.CLICKED_BACK, + destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS + }, + ] + }, ]; export { routingTable }; From c55ee6a15d174699488b4c78bdc70ffe955b5113 Mon Sep 17 00:00:00 2001 From: Bryan Mauger Date: Wed, 20 Jul 2022 15:28:05 -0400 Subject: [PATCH 037/132] WIP --- .../radio-service-package.vue | 306 ++++++++++-------- 1 file changed, 174 insertions(+), 132 deletions(-) diff --git a/src/ux-components/radio-service-package/radio-service-package.vue b/src/ux-components/radio-service-package/radio-service-package.vue index 2f06d0600..0654a2c14 100644 --- a/src/ux-components/radio-service-package/radio-service-package.vue +++ b/src/ux-components/radio-service-package/radio-service-package.vue @@ -1,160 +1,202 @@ diff --git a/src/layouts/molding-questions/molding-questions.vue b/src/layouts/molding-questions/molding-questions.vue index 0ffaae411..a0fa5e96d 100644 --- a/src/layouts/molding-questions/molding-questions.vue +++ b/src/layouts/molding-questions/molding-questions.vue @@ -60,6 +60,7 @@ import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; import { Form, defineRule } from "vee-validate"; import { required } from "@/helpers/validation-rules"; import { errorMessages } from "@/constants/error-messages"; +import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin"; // DEFINE VALIDATION RULES defineRule("questions-required", required(errorMessages.OPTION_REQUIRED)); @@ -108,9 +109,10 @@ export default { return this.getCmsContent("AlertPartsQuestions", "BodyText"); }, }, + mixins: [vehicleQuestionsMixin], methods: { arePagePrerequisitesValid() { - return true; + return true; // TODO - DO TRUE TEST OF PAGEDATA // return Object.keys(store.getters.pageData(fmgPageValues.MOLDING_QUESTIONS)).length > 0; }, showThisPartQuestionChain(part, i) { @@ -146,111 +148,20 @@ export default { const glassNameAndPartsForStore = partsLookup.data.glassNameAndPartsForStore; - console.log("glassNameAndPartsForStore: ", glassNameAndPartsForStore); + const hasCapabilityQuestions = this.hasCapabilityQuestions(glassNameAndPartsForStore); - // HARD CODE RESPONSE FOR NOW... - - this.glassNameAndPartsForStore = [ - { - "glassName": "Single", - "glassLocation": "Windshield", - "parts": [ - { - "partNumber": "FW03861GTYN", - "description": "rain sensor, heated glass, auto dimming mirror, solar, 3rd visor band, condensation sensor", - "color": "Green Tint", - "requiresRecalibration": false, - "requiresCapabilityQuestions": false, - "recalibrationType": null, - "childParts": null, - "childPartQuestions": [ - { - "questionSequence": 1, - "questionText": "Does the rubber seal around your windshield have a chrome strip running through it?", - "answers": [ - { - "answerResult": "WKT D1106 C", - "answerText": "Yes", - "nextQuestionSequence": null - }, - { - "answerResult": "WKT D1106 B", - "answerText": "No", - "nextQuestionSequence": null - } - ] - } - ] - } - ] - }, - { - "glassName": "Stationary", - "glassLocation": "Rear", - "parts": [ - { - "partNumber": "FB25992GTNN", - "description": "heated glass, solar", - "color": "Green Tint", - "requiresRecalibration": false, - "requiresCapabilityQuestions": false, - "recalibrationType": null, - "childParts": null, - "childPartQuestions": [] - } - ] - } - ]; - - - - - - - // test response data for multiple parts - const hasMultipleParts = glassNameAndPartsForStore.some((glass) => glass.parts?.length > 1); - - // loop through all glass items - const collectedGlassParts = []; - glassNameAndPartsForStore.forEach((glass) => { - if (Array.isArray(glass.parts) && glass.parts.length === 1) { - const singlePart = glass.parts[0]; - collectedGlassParts.push({ - "partNumber": singlePart.partNumber, - "description": singlePart.description, - "color": singlePart.color, - "requiresRecalibration": singlePart.requiresRecalibration, - "childParts": singlePart.childParts, - "price": singlePart.price, - }); - // check for and collect any molding questions - if (Array.isArray(singlePart.childPartQuestions) && singlePart.childPartQuestions.length > 0) { - this.moldingQuestionsForStore.push({ - "glassName": glass.glassName, - "glassLocation": glass.glassLocation, - "childPartQuestions": singlePart.childPartQuestions, - }); - } - } - }); - if (!hasMultipleParts) { - this.$store.commit(storeMutations.UPDATE_GLASS_PARTS, collectedGlassParts); - } - this.navigateForward(hasMultipleParts, glassNameAndPartsForStore); - }, - navigateForward(hasMultipleParts, glassNameAndPartsForStore) { - if (hasMultipleParts) { - // if multiple parts on any glass - // go to vehicle-parts page and pass the partsData - this.$router.navigate(this.navigationScenarios.ANSWERED_QUESTIONS_WITH_MULTIPLE_PARTS,this.$route,{},{},{partsOrQuestions: glassNameAndPartsForStore}); + if (hasCapabilityQuestions) { + // if has capability questions + // go to capability-questions page + this.$router.navigate(this.navigationScenarios.HAS_CAPABILITY_QUESTIONS,this.$route,{},{},{partsOrQuestions: glassNameAndPartsForStore}); } else { // if single parts only + const collectedGlassParts = this.reduceGlassPartsArray(glassNameAndPartsForStore); + // save to store lineItems.glassParts + this.$store.commit(storeMutations.UPDATE_GLASS_PARTS, collectedGlassParts); // go to quote page this.$router.navigate(this.navigationScenarios.ANSWERED_QUESTIONS_WITH_SINGLE_PART,this.$route); } - - // TODO - ADD CHECK FOR CAPABILITY QUESTIONS TO SEE IF NAVIGATE TO CAPABILITY-QUESTIONS - }, }, watch: { diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue index 856b8a099..b22c30ba6 100644 --- a/src/layouts/part-questions/part-questions.vue +++ b/src/layouts/part-questions/part-questions.vue @@ -60,6 +60,7 @@ import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; import { Form, defineRule } from "vee-validate"; import { required } from "@/helpers/validation-rules"; import { errorMessages } from "@/constants/error-messages"; +import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin"; // DEFINE VALIDATION RULES defineRule("questions-required", required(errorMessages.OPTION_REQUIRED)); @@ -108,6 +109,7 @@ export default { return this.getCmsContent("AlertPartsQuestions", "BodyText"); }, }, + mixins: [vehicleQuestionsMixin], methods: { showThisPartQuestionChain(part, i) { if (part.partQuestions?.length < 1) { return false; } // return false if only one partQuestion @@ -137,59 +139,36 @@ export default { // call API parts method const partsLookup = await this.dispatchStoreAction(storeActions.GET_PARTS) .catch(() => { - this.$refs.funnelFooter.removeLoader(); + return this.$refs.funnelFooter.removeLoader(); }); - if (!partsLookup) { return } + const glassNameAndPartsForStore = partsLookup.data.glassNameAndParts; - const glassNameAndPartsForStore = partsLookup.data.glassNameAndPartsForStore; + const hasGlassLocationWithMultipleParts = this.hasGlassLocationWithMultipleParts(glassNameAndPartsForStore); + const hasChildPartQuestions = this.hasChildPartQuestions(glassNameAndPartsForStore); + const hasCapabilityQuestions = this.hasCapabilityQuestions(glassNameAndPartsForStore); - // test response data for multiple parts - const hasMultipleParts = glassNameAndPartsForStore.some((glass) => glass.parts?.length > 1); - - // loop through all glass items - const collectedGlassParts = []; - glassNameAndPartsForStore.forEach((glass) => { - if (Array.isArray(glass.parts) && glass.parts.length === 1) { - const singlePart = glass.parts[0]; - collectedGlassParts.push({ - "partNumber": singlePart.partNumber, - "description": singlePart.description, - "color": singlePart.color, - "requiresRecalibration": singlePart.requiresRecalibration, - "childParts": singlePart.childParts, - "price": singlePart.price, - }); - // check for and collect any molding questions - if (Array.isArray(singlePart.childPartQuestions) && singlePart.childPartQuestions.length > 0) { - this.moldingQuestionsForStore.push({ - "glassName": glass.glassName, - "glassLocation": glass.glassLocation, - "childPartQuestions": singlePart.childPartQuestions, - }); - } - } - }); - if (!hasMultipleParts) { - store.commit(storeMutations.UPDATE_GLASS_PARTS, collectedGlassParts); - } - this.navigateForward(hasMultipleParts, glassNameAndPartsForStore); - }, - async navigateForward(hasMultipleParts, glassNameAndPartsForStore) { - if (hasMultipleParts) { + // NAVIGATE FORWARD + if (hasGlassLocationWithMultipleParts) { // if multiple parts on any glass // go to vehicle-parts page and pass the partsData this.$router.navigate(this.navigationScenarios.ANSWERED_QUESTIONS_WITH_MULTIPLE_PARTS,this.$route,{},{},{partsOrQuestions: glassNameAndPartsForStore}); + } else if (hasChildPartQuestions) { + // if any childpart questions + // go to molding-questions page and pass the partsData + this.$router.navigate(this.navigationScenarios.HAS_MOLDING_QUESTIONS,this.$route,{},{},{partsOrQuestions: glassNameAndPartsForStore}); + } else if (hasCapabilityQuestions) { + // if has capability questions + // go to capability-questions page and pass the partsData + this.$router.navigate(this.navigationScenarios.HAS_CAPABILITY_QUESTIONS,this.$route,{},{},{partsOrQuestions: glassNameAndPartsForStore}); } else { // if single parts only + const collectedGlassParts = this.reduceGlassPartsArray(glassNameAndPartsForStore); + // save to store lineItems.glassParts + this.$store.commit(storeMutations.UPDATE_GLASS_PARTS, collectedGlassParts); // go to quote page this.$router.navigate(this.navigationScenarios.ANSWERED_QUESTIONS_WITH_SINGLE_PART,this.$route); } - - // TODO - ADD CHECK FOR CAPABILITY QUESTIONS TO SEE IF NAVIGATE TO CAPABILITY-QUESTIONS - - - }, arePagePrerequisitesValid() { return Object.keys(store.getters.pageData(fmgPageValues.PART_QUESTIONS)).length > 0; diff --git a/src/layouts/vehicle-parts/vehicle-parts.vue b/src/layouts/vehicle-parts/vehicle-parts.vue index d0af557b0..3cbc07e6f 100644 --- a/src/layouts/vehicle-parts/vehicle-parts.vue +++ b/src/layouts/vehicle-parts/vehicle-parts.vue @@ -60,9 +60,10 @@ import alert from "@/ux-components/alert/alert"; import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; import { settleAllPromises } from "@/helpers/layout-helper"; import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; -import store from "@/store"; import { Form } from "vee-validate"; -import { storeActions } from "@/constants/store-actions"; +import store from "@/store"; +import { storeMutations } from "@/constants/store-mutations.js"; +import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin"; export default { name: "vehicle-parts", @@ -95,7 +96,6 @@ export default { data() { return { glassParts: {}, - matchedParts: [], alertWidgetData: Object, alreadyPopulatedPartsData: {}, }; @@ -141,13 +141,14 @@ export default { }, PartsFromApi() { - return store.getters.pageData(fmgPageValues.VEHICLE_PARTS); + return this.$store.getters.pageData(fmgPageValues.VEHICLE_PARTS); }, RefPrefix() { return "partQuestion"; }, }, + mixins: [vehicleQuestionsMixin], methods: { arePagePrerequisitesValid() { // Check if isRepair is populated and if the pageData we need is here (Parts data) @@ -160,7 +161,7 @@ export default { this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route); }, async forwardButtonAction() { - let isMoldingQuestions = false; + const matchedParts = []; // Match them to the parts from the API. for (let [key, value] of Object.entries( @@ -175,47 +176,54 @@ export default { ); if (isMatched) { - this.matchedParts.push(currentPart); - // check if there are childPartQuestions (for molding-questions) - if (Array.isArray(currentPart.childPartQuestions) && currentPart.childPartQuestions.length > 0) { - isMoldingQuestions = true - } + matchedParts.push({ + "glassLocation": value.glassLocation, + "glassName": value.glassName, + "parts": [currentPart] + }); } } } - // If no parts could be matched, throw an error (isForwardActionDisabled is based off of this.matchedParts) + const hasChildPartQuestions = this.hasChildPartQuestions(matchedParts); + const hasCapabilityQuestions = this.hasCapabilityQuestions(matchedParts); + + // If no parts could be matched, throw an error (isForwardActionDisabled is based off of matchedParts) if (this.isForwardActionDisabled) { this.$refs.funnelFooter.removeLoader(); throw new Error("Could not match any parts to the selected parts"); } // Navigate to the next page - if (isMoldingQuestions) { + if (hasChildPartQuestions) { this.$router.navigate( this.navigationScenarios.HAS_MOLDING_QUESTIONS, this.$route, {}, {}, - this.moldingQuestionsForStore + {partsOrQuestions: matchedParts} ); - } - else { - // Save parts to the store - await this.dispatchStoreAction( - storeActions.SAVE_GLASS_PARTS, - this.matchedParts, - false + } else if (hasCapabilityQuestions) { + this.$router.navigate( + this.navigationScenarios.HAS_CAPABILITY_QUESTIONS, + this.$route, + {}, + {}, + {partsOrQuestions: matchedParts} ); + + } else { + // if single parts only + const collectedGlassParts = this.reduceGlassPartsArray(matchedParts); + // save to store lineItems.glassParts + this.$store.commit(storeMutations.UPDATE_GLASS_PARTS, collectedGlassParts); + // Navigate to the quote page this.$router.navigate( this.navigationScenarios.SELECTED_PARTS, this.$route ); } - - // TODO - ADD CHECK FOR CAPABILITY QUESTIONS TO SEE IF NAVIGATE TO CAPABILITY-QUESTIONS - }, LoadInitialPartsData() { diff --git a/src/mixins/vehicle-questions-mixin.js b/src/mixins/vehicle-questions-mixin.js new file mode 100644 index 000000000..5490ea7bf --- /dev/null +++ b/src/mixins/vehicle-questions-mixin.js @@ -0,0 +1,43 @@ +export default { + + methods: { + hasPartQuestions(partsOrQuestions) { + return partsOrQuestions.some(pq => pq.partQuestions?.length > 0); + }, + hasGlassLocationWithMultipleParts(partsOrQuestions) { + return partsOrQuestions.some(pq => pq.parts?.length > 1); + }, + hasChildPartQuestions(partsOrQuestions) { + return partsOrQuestions.some(pq => { + return pq.parts?.some(part => part.childPartQuestions?.length > 0); + }); + }, + hasCapabilityQuestions(partsOrQuestions) { + return partsOrQuestions.some(pq => { + return pq.parts?.some(part => part.requiresCapabilityQuestions === true); + }); + }, + // method to only include keys listed for lineItems.glassParts in + // https://safelite.atlassian.net/wiki/spaces/DC/pages/17137665/Catalog+Front-End+State#glassParts + reduceGlassPartsArray(glassParts) { + const reducedGlassParts = []; + glassParts.forEach((glass) => { + if (Array.isArray(glass.parts) && glass.parts.length === 1) { + const singlePart = glass.parts[0]; + reducedGlassParts.push({ + "partNumber": singlePart.partNumber, + "description": singlePart.description, + "color": singlePart.color, + "requiresRecalibration": singlePart.requiresRecalibration, + "requiresCapabilityQuestions": singlePart.requiresCapabilityQuestions, + "recalibrationType": singlePart.recalibrationType, + "childParts": singlePart.childParts, + "price": singlePart.price, + }); + } + }); + return reducedGlassParts; + } + } + +} \ No newline at end of file diff --git a/src/mixins/vin-pages-mixin.js b/src/mixins/vin-pages-mixin.js index 196a21e63..b9d652223 100644 --- a/src/mixins/vin-pages-mixin.js +++ b/src/mixins/vin-pages-mixin.js @@ -1,18 +1,20 @@ -import store from "@/store"; import { storeActions } from "@/constants/store-actions.js"; import { storeMutations } from "@/constants/store-mutations.js"; import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper"; +import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin"; export default { + mixins: [vehicleQuestionsMixin], methods: { async navigateForwardWithSingleCarMatch() { const result = await this.dispatchStoreAction(storeActions.GET_PARTS_OR_QUESTIONS); + const partsOrQuestions = result.data.partsOrQuestions; - const hasPartsQuestions = partsOrQuestions.some(pq => pq.partQuestions?.length > 0); - const hasGlassLocationWithMultipleParts = partsOrQuestions.some(pq => pq.parts?.length > 1); - const hasChildPartQuestions = partsOrQuestions.some(pq => { - return pq.parts?.some(part => part.childPartQuestions?.length > 0); - }); + + const hasPartsQuestions = this.hasPartQuestions(partsOrQuestions); + const hasGlassLocationWithMultipleParts = this.hasGlassLocationWithMultipleParts(partsOrQuestions); + const hasChildPartQuestions = this.hasChildPartQuestions(partsOrQuestions); + const hasCapabilityQuestions = this.hasCapabilityQuestions(partsOrQuestions); // TODO - ADD CHECK FOR CAPABILITY QUESTIONS TO SEE IF NAVIGATE TO CAPABILITY-QUESTIONS @@ -25,8 +27,17 @@ export default { else if (hasChildPartQuestions) { this.$router.navigate(this.navigationScenarios.SELECTED_VIN_WITH_MOLDING_QUESTIONS, this.$route, {}, {}, result.data); } + else if (hasCapabilityQuestions) { + this.$router.navigate(this.navigationScenarios.SELECTED_VIN_WITH_CAPABILITY_QUESTIONS, this.$route, {}, {}, result.data); + } else { - store.commit(storeMutations.UPDATE_GLASS_PARTS, result.data); + // if single parts only + const collectedGlassParts = this.reduceGlassPartsArray(result.data.partsOrQuestions); + // save to store lineItems.glassParts + this.$store.commit(storeMutations.UPDATE_GLASS_PARTS, collectedGlassParts); + + // go to quote page + this.$router.navigate(this.navigationScenarios.ANSWERED_QUESTIONS_WITH_SINGLE_PART,this.$route); this.$refs.loadingModal.showModal(); navigateToHeritageFunnel(); } diff --git a/src/mixins/vin-pages-mixin.spec.js b/src/mixins/vin-pages-mixin.spec.js index 0ef66226f..49503d9dc 100644 --- a/src/mixins/vin-pages-mixin.spec.js +++ b/src/mixins/vin-pages-mixin.spec.js @@ -864,14 +864,17 @@ describe("vin-pages-mixin", () => { partsOrQuestions: partsOrQuestions }); - store.commit = jest.fn(); + wrapper.vm.$store.commit = jest.fn(); + + const collectedGlassParts = wrapper.vm.reduceGlassPartsArray(partsOrQuestions); // Act await wrapper.vm.navigateForwardWithSingleCarMatch(); + // Assert - expect(store.commit).toHaveBeenCalledTimes(1); - expect(store.commit).toHaveBeenCalledWith(storeMutations.UPDATE_GLASS_PARTS, { partsOrQuestions }) + expect(wrapper.vm.$store.commit).toHaveBeenCalledTimes(1); + expect(wrapper.vm.$store.commit).toHaveBeenCalledWith(storeMutations.UPDATE_GLASS_PARTS, collectedGlassParts) expect(wrapper.vm.$refs.loadingModal.showModal).toHaveBeenCalledTimes(1); expect(navigateToHeritageFunnel).toHaveBeenCalledTimes(1); }); @@ -895,6 +898,9 @@ function setupMocks({ partsOrQuestions = [] }) { router: { navigate: jest.fn() }, + store: { + commit: jest.fn() + } }); const mockVinComponent = { diff --git a/src/router/router-constants/fmgPage-values.js b/src/router/router-constants/fmgPage-values.js index 7a38c6b40..404a89de9 100644 --- a/src/router/router-constants/fmgPage-values.js +++ b/src/router/router-constants/fmgPage-values.js @@ -9,6 +9,7 @@ const fmgPageValues = { VEHICLE_PARTS: "vehicle-parts", PART_QUESTIONS: "part-questions", MOLDING_QUESTIONS: "molding-questions", + CAPABILITY_QUESTIONS: "capability-questions", LICENSE_PLATE_LOOKUP: "license-plate-lookup", REVEAL: "reveal", ESTIMATE: "estimate", diff --git a/src/router/router-constants/navigation-scenarios.js b/src/router/router-constants/navigation-scenarios.js index ab1772de3..c252a3d0f 100644 --- a/src/router/router-constants/navigation-scenarios.js +++ b/src/router/router-constants/navigation-scenarios.js @@ -11,6 +11,7 @@ const navigationScenarios = { SELECTED_VIN_WITH_PART_QUESTIONS: "SELECTED_VIN_WITH_PART_QUESTIONS", SELECTED_VIN_WITH_MULTIPLE_PARTS: "SELECTED_VIN_WITH_MULTIPLE_PARTS", SELECTED_VIN_WITH_MOLDING_QUESTIONS: "SELECTED_VIN_WITH_MOLDING_QUESTIONS", + SELECTED_VIN_WITH_CAPABILITY_QUESTIONS: "SELECTED_VIN_WITH_CAPABILITY_QUESTIONS", CONTINUING_WITH_SINGLE_PART: "CONTINUING_WITH_SINGLE_PART", CONTINUING_WITH_MULTIPLE_VEHICLES: "CONTINUING_WITH_MULTIPLE_VEHICLES", SELECTED_VIN_HAS_MISMATCHED_GLASS: "SELECTED_VIN_HAS_MISMATCHED_GLASS", @@ -21,6 +22,7 @@ const navigationScenarios = { ANSWERED_QUESTIONS_WITH_SINGLE_PART: "ANSWERED_QUESTIONS_WITH_SINGLE_PART", ANSWERED_QUESTIONS_WITH_MULTIPLE_PARTS: "ANSWERED_QUESTIONS_WITH_MULTIPLE_PARTS", HAS_MOLDING_QUESTIONS: "HAS_MOLDING_QUESTIONS", + HAS_CAPABILITY_QUESTIONS: "HAS_CAPABILITY_QUESTIONS", SELECTED_PROVIDE_VIN_DIFFERENT_WAY: "SELECTED_PROVIDE_VIN_DIFFERENT_WAY" }; diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index 51ac52efa..73b501493 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -135,6 +135,10 @@ const routingTable = function(store) { { scenario: navigationScenarios.SELECTED_VIN_WITH_MOLDING_QUESTIONS, destinationFmgPageValue: fmgPageValues.MOLDING_QUESTIONS + }, + { + scenario: navigationScenarios.SELECTED_VIN_WITH_CAPABILITY_QUESTIONS, + destinationFmgPageValue: fmgPageValues.CAPABILITY_QUESTIONS } ], }, @@ -160,6 +164,10 @@ const routingTable = function(store) { { scenario: navigationScenarios.SELECTED_VIN_WITH_MOLDING_QUESTIONS, destinationFmgPageValue: fmgPageValues.MOLDING_QUESTIONS + }, + { + scenario: navigationScenarios.SELECTED_VIN_WITH_CAPABILITY_QUESTIONS, + destinationFmgPageValue: fmgPageValues.CAPABILITY_QUESTIONS } ], }, @@ -189,6 +197,10 @@ const routingTable = function(store) { { scenario: navigationScenarios.SELECTED_VIN_WITH_MOLDING_QUESTIONS, destinationFmgPageValue: fmgPageValues.MOLDING_QUESTIONS + }, + { + scenario: navigationScenarios.SELECTED_VIN_WITH_CAPABILITY_QUESTIONS, + destinationFmgPageValue: fmgPageValues.CAPABILITY_QUESTIONS } ], }, @@ -211,10 +223,18 @@ const routingTable = function(store) { scenario: navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS, destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS }, + { + scenario: navigationScenarios.SELECTED_VIN_WITH_MOLDING_QUESTIONS, + destinationFmgPageValue: fmgPageValues.MOLDING_QUESTIONS + }, + { + scenario: navigationScenarios.SELECTED_VIN_WITH_CAPABILITY_QUESTIONS, + destinationFmgPageValue: fmgPageValues.CAPABILITY_QUESTIONS + }, { scenario: navigationScenarios.SELECTED_PROVIDE_VIN_DIFFERENT_WAY, destinationFmgPageValue: fmgPageValues.ESTIMATE - } + } ], }, { @@ -253,6 +273,10 @@ const routingTable = function(store) { scenario: navigationScenarios.HAS_MOLDING_QUESTIONS, destinationFmgPageValue: fmgPageValues.MOLDING_QUESTIONS, }, + { + scenario: navigationScenarios.HAS_CAPABILITY_QUESTIONS, + destinationFmgPageValue: fmgPageValues.CAPABILITY_QUESTIONS, + }, { scenario: navigationScenarios.ANSWERED_QUESTIONS_WITH_SINGLE_PART, destinationFmgPageValue: fmgPageValues.QUOTE, @@ -261,6 +285,19 @@ const routingTable = function(store) { }, { fmgPageValue: fmgPageValues.MOLDING_QUESTIONS, + maps: [ + { + scenario: navigationScenarios.CLICKED_BACK, + destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS + }, + { + scenario: navigationScenarios.HAS_CAPABILITY_QUESTIONS, + destinationFmgPageValue: fmgPageValues.CAPABILITY_QUESTIONS, + }, + ] + }, + { + fmgPageValue: fmgPageValues.CAPABILITY_QUESTIONS, maps: [ { scenario: navigationScenarios.CLICKED_BACK, From 6a8409cd345863d01037856714a6e72d1d52952b Mon Sep 17 00:00:00 2001 From: Katie Date: Tue, 26 Jul 2022 15:03:40 -0400 Subject: [PATCH 045/132] CSR-702 Add basic routing for part-questions --- .../button-question/button-question.vue | 2 +- src/layouts/part-questions/part-questions.vue | 2 +- .../side-door-options/side-door-options.vue | 2 +- .../glass-part-question.vue | 3 ++- src/layouts/vehicle-parts/vehicle-parts.vue | 19 +++++++++---------- src/mixins/vehicle-questions-mixin.js | 10 ++++++++++ src/mixins/vehicle-questions-mixin.spec.js | 0 src/mixins/vin-pages-mixin.js | 8 +++++--- src/router/index.js | 7 +++++-- .../router-constants/navigation-scenarios.js | 4 +++- src/router/router-constants/routing-table.js | 12 ++++++++---- src/store/index.js | 7 ++++++- .../list-button-horizontal.vue | 8 ++++---- src/ux-components/list-button/list-button.vue | 8 ++++---- src/ux-components/list-card/list-card.vue | 6 +----- 15 files changed, 60 insertions(+), 38 deletions(-) create mode 100644 src/mixins/vehicle-questions-mixin.js create mode 100644 src/mixins/vehicle-questions-mixin.spec.js diff --git a/src/common-components/button-question/button-question.vue b/src/common-components/button-question/button-question.vue index ee9ecdbad..6848285b8 100644 --- a/src/common-components/button-question/button-question.vue +++ b/src/common-components/button-question/button-question.vue @@ -89,7 +89,7 @@ export default { modelValue: [Array, String], validationRules: String, suppressError: Boolean, - useTextForValue: Boolean + useTextForValue: Boolean, }, computed: { formattedGroupName() { diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue index f5ec4841d..ee1d81c09 100644 --- a/src/layouts/part-questions/part-questions.vue +++ b/src/layouts/part-questions/part-questions.vue @@ -88,7 +88,7 @@ export default { data() { return { selectedModel: [], - partsQuestionsData: this.$store.getters.pageData(fmgPageValues.PART_QUESTIONS).partsOrQuestions.filter((p) => { + partsQuestionsData: store.getters.pageData(fmgPageValues.PART_QUESTIONS)?.partsOrQuestions.filter((p) => { if (Array.isArray(p.partQuestions) && p.partQuestions.length > 0) { return { glassName: p.glassName, diff --git a/src/layouts/vehicle-damage/side-door-options/side-door-options.vue b/src/layouts/vehicle-damage/side-door-options/side-door-options.vue index b4df1121e..284c3eee6 100644 --- a/src/layouts/vehicle-damage/side-door-options/side-door-options.vue +++ b/src/layouts/vehicle-damage/side-door-options/side-door-options.vue @@ -112,7 +112,7 @@ export default ({ this.selectedValues = this.getSideDoorReplacementOptions(this.selectedValues.selectedDoorSides, this.selectedValues.selectedDriverSideReplaceOptions, newValue); } }, - answersToDisplay(){ + answersToDisplay(){ const filteredAnswers = Array.isArray(this.answersFromCms) ? this.answersFromCms.filter(ans => { diff --git a/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue b/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue index 608cf55cb..b46a2f9bc 100644 --- a/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue +++ b/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue @@ -48,6 +48,7 @@ import { getCustomTransformValue } from "@/constants/dynamictext-mapper"; import { defineRule } from "vee-validate"; import { required } from "@/helpers/validation-rules"; import { errorMessages } from "@/constants/error-messages"; +import store from "@/store"; export default { name: "glass-part-question", @@ -152,7 +153,7 @@ export default { }, PartDataFromApi() { - return this.$store.getters.pageData(this.$route.query.fmgPage) ?? {}; + return store.getters.pageData(this.$route.query.fmgPage) ?? {}; }, }, methods: { diff --git a/src/layouts/vehicle-parts/vehicle-parts.vue b/src/layouts/vehicle-parts/vehicle-parts.vue index ce5727ce3..c35699c4e 100644 --- a/src/layouts/vehicle-parts/vehicle-parts.vue +++ b/src/layouts/vehicle-parts/vehicle-parts.vue @@ -63,9 +63,11 @@ import store from "@/store"; import { Form } from "vee-validate"; import { storeActions } from "@/constants/store-actions"; + import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin"; export default { name: "vehicle-parts", + mixins: [vehicleQuestionsMixin], async beforeRouteEnter(to, from, next) { // Call APIs const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage); @@ -173,19 +175,16 @@ methods: { arePagePrerequisitesValid() { // Check if isRepair is populated and if the pageData we need is here (Parts data) - if ( - store.getters.damage.isRepair != null && - Object.keys(store.getters.pageData(fmgPageValues.VEHICLE_PARTS)) - .length !== 0 - ) { - return true; - } - - return false; + return store.getters.damage.isRepair != null && + Object.keys(store.getters.pageData(fmgPageValues.VEHICLE_PARTS)).length !== 0; }, backButtonAction() { + console.log(this.$store.getters.pageData(fmgPageValues.PART_QUESTIONS)) + const hasPartQuestions = this.hasPartQuestions(this.$store.getters.pageData(fmgPageValues.PART_QUESTIONS).partsOrQuestions); + const backNavigationScenario = hasPartQuestions ? this.navigationScenarios.CLICKED_BACK_WITH_PART_QUESTION_ANSWERS : this.navigationScenarios.CLICKED_BACK_WITHOUT_PART_QUESTION_ANSWERS; + this.$router.navigate( - this.navigationScenarios.CLICKED_BACK, + backNavigationScenario, this.$route ); }, diff --git a/src/mixins/vehicle-questions-mixin.js b/src/mixins/vehicle-questions-mixin.js new file mode 100644 index 000000000..7a8f3832f --- /dev/null +++ b/src/mixins/vehicle-questions-mixin.js @@ -0,0 +1,10 @@ +export default { + methods: { + hasPartQuestions(partsOrQuestions) { + return partsOrQuestions.some(pq => pq.partQuestions?.length > 0); + }, + hasGlassLocationWithMultipleParts(partsOrQuestions) { + return partsOrQuestions.some(pq => pq.parts?.length > 1); + } + } +} \ No newline at end of file diff --git a/src/mixins/vehicle-questions-mixin.spec.js b/src/mixins/vehicle-questions-mixin.spec.js new file mode 100644 index 000000000..e69de29bb diff --git a/src/mixins/vin-pages-mixin.js b/src/mixins/vin-pages-mixin.js index fce96c980..31fa44cf7 100644 --- a/src/mixins/vin-pages-mixin.js +++ b/src/mixins/vin-pages-mixin.js @@ -2,15 +2,17 @@ import store from "@/store"; import { storeActions } from "@/constants/store-actions.js"; import { storeMutations } from "@/constants/store-mutations.js"; import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper"; +import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin"; export default { + mixins: [vehicleQuestionsMixin], methods: { async navigateForwardWithSingleCarMatch() { const result = await this.dispatchStoreAction(storeActions.GET_PARTS_OR_QUESTIONS); const partsOrQuestions = result.data.partsOrQuestions; - const hasPartsQuestions = partsOrQuestions.some(pq => pq.partQuestions?.length > 0); - const hasGlassLocationWithMultipleParts = partsOrQuestions.some(pq => pq.parts?.length > 1); + const hasPartsQuestions = this.hasPartQuestions(partsOrQuestions); + const hasGlassLocationWithMultipleParts = this.hasGlassLocationWithMultipleParts(partsOrQuestions); if (hasPartsQuestions) { this.$router.navigate(this.navigationScenarios.SELECTED_VIN_WITH_PART_QUESTIONS, this.$route, {}, {}, result.data); @@ -23,6 +25,6 @@ export default { this.$refs.loadingModal.showModal(); navigateToHeritageFunnel(); } - } + }, } } \ No newline at end of file diff --git a/src/router/index.js b/src/router/index.js index d2a5ee154..d086cc89a 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -173,8 +173,11 @@ async function navigate(scenario, currentRoute, optionalQuery = {}, optionalPara if (destinationFmgPageValue !== undefined) { // We're always pushing the same path, just changing query strings. Make sure our optional query strings get combined with our fmgPage one. - // Append page data to the store for the NEXT page, if any. It will be an empty object if none is provided. - baseMixin.methods.savePageDataToStore(destinationFmgPageValue, optionalPageData); + // Update page data to the store for next page if provided. Otherwise, use existing page data or override with empty object + const existingPageData = store.getters.pageData(destinationFmgPageValue) ?? {}; + if (Object.keys(optionalPageData).length > 0 && Object.keys(existingPageData).length === 0) { + baseMixin.methods.savePageDataToStore(destinationFmgPageValue, optionalPageData); + } // if cookie and referralNumber/Date exists OR an emailAddress has been saved if ((getFunnelCookie()?.ReferralNumber && getFunnelCookie()?.ReferralDate) || store.getters.order.customer?.emailAddress) { diff --git a/src/router/router-constants/navigation-scenarios.js b/src/router/router-constants/navigation-scenarios.js index 5768c55de..61de8147f 100644 --- a/src/router/router-constants/navigation-scenarios.js +++ b/src/router/router-constants/navigation-scenarios.js @@ -19,7 +19,9 @@ const navigationScenarios = { SELECTED_HOME_ADDRESS: "SELECTED_HOME_ADDRESS", ANSWERED_QUESTIONS_WITH_SINGLE_PART: "ANSWERED_QUESTIONS_WITH_SINGLE_PART", ANSWERED_QUESTIONS_WITH_MULTIPLE_PARTS: "ANSWERED_QUESTIONS_WITH_MULTIPLE_PARTS", - SELECTED_PROVIDE_VIN_DIFFERENT_WAY: "SELECTED_PROVIDE_VIN_DIFFERENT_WAY" + SELECTED_PROVIDE_VIN_DIFFERENT_WAY: "SELECTED_PROVIDE_VIN_DIFFERENT_WAY", + CLICKED_BACK_WITH_PART_QUESTION_ANSWERS: "CLICKED_BACK_WITH_PART_QUESTION_ANSWERS", + CLICKED_BACK_WITHOUT_PART_QUESTION_ANSWERS: "CLICKED_BACK_WITHOUT_PART_QUESTION_ANSWERS" }; export { navigationScenarios }; diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index 25463bd8b..0c729607f 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -82,10 +82,6 @@ const routingTable = function(store) { { fmgPageValue: fmgPageValues.VEHICLE_PARTS, maps: [ - { - scenario: navigationScenarios.CLICKED_BACK, - destinationFmgPageValue: fmgPageValues.VIN_LOOKUP, - }, { scenario: navigationScenarios.SELECTED_PARTS, destinationFmgPageValue: fmgPageValues.QUOTE, @@ -94,6 +90,14 @@ const routingTable = function(store) { scenario: navigationScenarios.CLICKED_FORWARD, destinationFmgPageValue: fmgPageValues.REVEAL, }, + { + scenario: navigationScenarios.CLICKED_BACK_WITH_PART_QUESTION_ANSWERS, + destinationFmgPageValue: fmgPageValues.PART_QUESTIONS, + }, + { + scenario: navigationScenarios.CLICKED_BACK_WITHOUT_PART_QUESTION_ANSWERS, + destinationFmgPageValue: fmgPageValues.VIN_LOOKUP, + }, ], }, { diff --git a/src/store/index.js b/src/store/index.js index 90932c8bb..200389734 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -5,6 +5,7 @@ import { getDateForSavedSessionTimeout } from "@/helpers/heritage-integration/se import createPersistedState from "vuex-persistedstate"; import globalMethods from "@/global-methods"; import { storeActions } from "../constants/store-actions"; +import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; // Export State const getDefaultState = () => { @@ -264,7 +265,10 @@ export const mutations = { state.order.vehicle.registration.lastName = null; }, resetGlassPartsState(state) { + console.log("resetGlassPartsState") state.order.lineItems.glassParts = null; + state.order.damage.partQuestionAnswers = null; + state.applicationUser.pageData[fmgPageValues.PART_QUESTIONS] = null; }, resetState(state) { Object.assign(state, getDefaultState()); @@ -701,7 +705,7 @@ export const actions = { accountNumber: accountNumber?.toString() }, }).then((response) => { - context.commit(storeMutations.RESET_STATE); + // context.commit(storeMutations.RESET_STATE); context.commit(storeMutations.UPDATE_STATE_WITH_ORDER_INFORMATION, response.data); return response; }); @@ -854,6 +858,7 @@ export const actions = { }, savePartQuestionAnswers(context, partQuestionAnswersArray) { //Save new values + // context.dispatch(storeActions.SAVE_GLASS_PARTS, null); context.commit(storeMutations.UPDATE_PART_QUESTION_ANSWERS, partQuestionAnswersArray); }, diff --git a/src/ux-components/list-button-horizontal/list-button-horizontal.vue b/src/ux-components/list-button-horizontal/list-button-horizontal.vue index 2fef5119f..5bcfcc706 100644 --- a/src/ux-components/list-button-horizontal/list-button-horizontal.vue +++ b/src/ux-components/list-button-horizontal/list-button-horizontal.vue @@ -92,10 +92,10 @@ export default { : this.selectedValues[0]; } }, - unmounted() { // needed to clear this button's selectedValues if it is removed - this.checkValue = false; - this.handleCheckChange(); - }, + // unmounted() { // needed to clear this button's selectedValues if it is removed + // this.checkValue = false; + // this.handleCheckChange(); + // }, methods: { displayLoader() { this.isLoaderDisplayed = true; diff --git a/src/ux-components/list-button/list-button.vue b/src/ux-components/list-button/list-button.vue index 34b6f92e0..cef450bb6 100644 --- a/src/ux-components/list-button/list-button.vue +++ b/src/ux-components/list-button/list-button.vue @@ -92,10 +92,10 @@ export default { : this.selectedValues[0]; } }, - unmounted() { // needed to clear this button's selectedValues if it is removed - this.checkValue = false; - this.handleCheckChange(); - }, + // unmounted() { // needed to clear this button's selectedValues if it is removed + // this.checkValue = false; + // this.handleCheckChange(); + // }, methods: { displayLoader() { this.isLoaderDisplayed = true; diff --git a/src/ux-components/list-card/list-card.vue b/src/ux-components/list-card/list-card.vue index a4ef7eac8..002fb14ac 100644 --- a/src/ux-components/list-card/list-card.vue +++ b/src/ux-components/list-card/list-card.vue @@ -110,10 +110,6 @@ export default { this.checkValue = this.selectedValues == this.value || this.modelValue == this.value; } }, - unmounted() { // needed to clear this button's selectedValues if it is removed - this.checkValue = false; - this.handleCheckChange(); - }, computed: { getLabelClasses() { if (this.isWide) { @@ -185,7 +181,7 @@ export default { const fieldOptions = { type: inputType, - checkedValue: props.value, // EX: "Single" or "Passenger" + // checkedValue: props.value, // EX: "Single" or "Passenger" potentialInitialValue: props.selectedValues, }; From 7e5fb4c906903f2c657553327b50e091e10add72 Mon Sep 17 00:00:00 2001 From: Katie Date: Tue, 26 Jul 2022 15:31:20 -0400 Subject: [PATCH 046/132] CSR-702 Cleanup --- src/layouts/part-questions/part-questions.vue | 2 +- src/layouts/vehicle-parts/vehicle-parts.vue | 3 --- src/store/index.js | 2 -- .../list-button-horizontal/list-button-horizontal.vue | 4 ---- src/ux-components/list-button/list-button.vue | 4 ---- src/ux-components/list-card/list-card.vue | 2 +- 6 files changed, 2 insertions(+), 15 deletions(-) diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue index 3f779ace8..ff5f494c1 100644 --- a/src/layouts/part-questions/part-questions.vue +++ b/src/layouts/part-questions/part-questions.vue @@ -142,7 +142,7 @@ export default { if (!partsLookup) { return } - const glassNameAndPartsForStore = partsLookup.data.glassNameAndPartsForStore; + const glassNameAndPartsForStore = partsLookup.data.glassNameAndParts; // test response data for multiple parts const hasMultipleParts = glassNameAndPartsForStore.some((glass) => glass.parts?.length > 1); diff --git a/src/layouts/vehicle-parts/vehicle-parts.vue b/src/layouts/vehicle-parts/vehicle-parts.vue index 75ba3df7f..80cdf8a97 100644 --- a/src/layouts/vehicle-parts/vehicle-parts.vue +++ b/src/layouts/vehicle-parts/vehicle-parts.vue @@ -157,7 +157,6 @@ export default { Object.keys(store.getters.pageData(fmgPageValues.VEHICLE_PARTS)).length !== 0; }, backButtonAction() { - console.log(this.$store.getters.pageData(fmgPageValues.PART_QUESTIONS)) const hasPartQuestions = this.hasPartQuestions(this.$store.getters.pageData(fmgPageValues.PART_QUESTIONS).partsOrQuestions); const backNavigationScenario = hasPartQuestions ? this.navigationScenarios.CLICKED_BACK_WITH_PART_QUESTION_ANSWERS : this.navigationScenarios.CLICKED_BACK_WITHOUT_PART_QUESTION_ANSWERS; @@ -167,8 +166,6 @@ export default { ); }, async forwardButtonAction() { - const selectedGlassPartNumbers = []; - const matchedParts = []; let isMoldingQuestions = false; // Match them to the parts from the API. diff --git a/src/store/index.js b/src/store/index.js index d6c09b22c..f3e3cf96a 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -265,7 +265,6 @@ export const mutations = { state.order.vehicle.registration.lastName = null; }, resetGlassPartsState(state) { - console.log("resetGlassPartsState") state.order.lineItems.glassParts = null; state.order.damage.partQuestionAnswers = null; state.applicationUser.pageData[fmgPageValues.PART_QUESTIONS] = null; @@ -866,7 +865,6 @@ export const actions = { }, savePartQuestionAnswers(context, partQuestionAnswersArray) { //Save new values - // context.dispatch(storeActions.SAVE_GLASS_PARTS, null); context.commit(storeMutations.UPDATE_PART_QUESTION_ANSWERS, partQuestionAnswersArray); }, diff --git a/src/ux-components/list-button-horizontal/list-button-horizontal.vue b/src/ux-components/list-button-horizontal/list-button-horizontal.vue index 5bcfcc706..4c9670097 100644 --- a/src/ux-components/list-button-horizontal/list-button-horizontal.vue +++ b/src/ux-components/list-button-horizontal/list-button-horizontal.vue @@ -92,10 +92,6 @@ export default { : this.selectedValues[0]; } }, - // unmounted() { // needed to clear this button's selectedValues if it is removed - // this.checkValue = false; - // this.handleCheckChange(); - // }, methods: { displayLoader() { this.isLoaderDisplayed = true; diff --git a/src/ux-components/list-button/list-button.vue b/src/ux-components/list-button/list-button.vue index cef450bb6..aabb06ae5 100644 --- a/src/ux-components/list-button/list-button.vue +++ b/src/ux-components/list-button/list-button.vue @@ -92,10 +92,6 @@ export default { : this.selectedValues[0]; } }, - // unmounted() { // needed to clear this button's selectedValues if it is removed - // this.checkValue = false; - // this.handleCheckChange(); - // }, methods: { displayLoader() { this.isLoaderDisplayed = true; diff --git a/src/ux-components/list-card/list-card.vue b/src/ux-components/list-card/list-card.vue index 002fb14ac..a1c95157f 100644 --- a/src/ux-components/list-card/list-card.vue +++ b/src/ux-components/list-card/list-card.vue @@ -181,7 +181,7 @@ export default { const fieldOptions = { type: inputType, - // checkedValue: props.value, // EX: "Single" or "Passenger" + checkedValue: props.value, // EX: "Single" or "Passenger" potentialInitialValue: props.selectedValues, }; From 18524de9a6fe74b3f2bc4a142861a2db1173c4d4 Mon Sep 17 00:00:00 2001 From: Katie Date: Tue, 26 Jul 2022 16:02:53 -0400 Subject: [PATCH 047/132] CSR-702 Add vehicle-questions-mixin tests --- src/layouts/part-questions/part-questions.vue | 2 +- .../glass-part-question.vue | 3 +- src/mixins/vehicle-questions-mixin.spec.js | 161 ++++++++++++++++++ 3 files changed, 163 insertions(+), 3 deletions(-) diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue index ff5f494c1..6f18408b7 100644 --- a/src/layouts/part-questions/part-questions.vue +++ b/src/layouts/part-questions/part-questions.vue @@ -88,7 +88,7 @@ export default { data() { return { selectedModel: [], - partsQuestionsData: store.getters.pageData(fmgPageValues.PART_QUESTIONS)?.partsOrQuestions.filter((p) => { + partsQuestionsData: this.$store.getters.pageData(fmgPageValues.PART_QUESTIONS)?.partsOrQuestions.filter((p) => { if (Array.isArray(p.partQuestions) && p.partQuestions.length > 0) { return { glassName: p.glassName, diff --git a/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue b/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue index b46a2f9bc..608cf55cb 100644 --- a/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue +++ b/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue @@ -48,7 +48,6 @@ import { getCustomTransformValue } from "@/constants/dynamictext-mapper"; import { defineRule } from "vee-validate"; import { required } from "@/helpers/validation-rules"; import { errorMessages } from "@/constants/error-messages"; -import store from "@/store"; export default { name: "glass-part-question", @@ -153,7 +152,7 @@ export default { }, PartDataFromApi() { - return store.getters.pageData(this.$route.query.fmgPage) ?? {}; + return this.$store.getters.pageData(this.$route.query.fmgPage) ?? {}; }, }, methods: { diff --git a/src/mixins/vehicle-questions-mixin.spec.js b/src/mixins/vehicle-questions-mixin.spec.js index e69de29bb..01d41b9c8 100644 --- a/src/mixins/vehicle-questions-mixin.spec.js +++ b/src/mixins/vehicle-questions-mixin.spec.js @@ -0,0 +1,161 @@ +import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin"; +import { shallowMount } from "@vue/test-utils"; +import { setupMocksForJsFiles, getMountOptions } from "@/helpers/unit-test-helper.js"; + +describe("vehicle-questions-mixin", () => { + describe("hasPartQuestions", () => { + test("has no part questions => return false", () => { + // Arrange + const { wrapper } = setupMocks({}); + + // Act + const hasPartQuestions = wrapper.vm.hasPartQuestions([ + { + partQuestions: [] + } + ]) + + // Assert + expect(hasPartQuestions).toBe(false); + }); + + test("has undefined part questions => return false", () => { + // Arrange + const { wrapper } = setupMocks({}); + + // Act + const hasPartQuestions = wrapper.vm.hasPartQuestions([]) + + // Assert + expect(hasPartQuestions).toBe(false); + }); + + test("has part questions => return true", () => { + // Arrange + const { wrapper } = setupMocks({}); + + // Act + const hasPartQuestions = wrapper.vm.hasPartQuestions([ + { + partQuestions: [{ + testProperty: "some value" + }] + } + ]) + + // Assert + expect(hasPartQuestions).toBe(true); + }); + }); + + describe("hasGlassLocationWithMultipleParts", () => { + test("has one part for one glass location => return false", () => { + // Arrange + const { wrapper } = setupMocks({}); + + // Act + const hasGlassLocationWithMultipleParts = wrapper.vm.hasGlassLocationWithMultipleParts([ + { + glassName: "Something", + glassLocation: "somewhere", + parts: [{ + partNumber: "1234567" + }] + } + ]) + + // Assert + expect(hasGlassLocationWithMultipleParts).toBe(false); + }); + + test("has one part for every glass location => return false", () => { + // Arrange + const { wrapper } = setupMocks({}); + + // Act + const hasGlassLocationWithMultipleParts = wrapper.vm.hasGlassLocationWithMultipleParts([ + { + glassName: "Something", + glassLocation: "somewhere", + parts: [{ + partNumber: "1234567" + }] + }, + { + glassName: "Another glass", + glassLocation: "somewhere else", + parts: [{ + partNumber: "1234568" + }] + }, + { + glassName: "Special glass", + glassLocation: "Another where", + parts: [{ + partNumber: "1234569" + }] + } + ]) + + // Assert + expect(hasGlassLocationWithMultipleParts).toBe(false); + }); + + test("has multiple parts for one glass location => return true", () => { + // Arrange + const { wrapper } = setupMocks({}); + + // Act + const hasGlassLocationWithMultipleParts = wrapper.vm.hasGlassLocationWithMultipleParts([ + { + glassName: "Something", + glassLocation: "somewhere", + parts: [{ + partNumber: "1234567" + }] + }, + { + glassName: "Another glass", + glassLocation: "somewhere else", + parts: [{ + partNumber: "1234568" + }] + }, + { + glassName: "Special glass", + glassLocation: "Another where", + parts: [ + { + partNumber: "1234569" + }, + { + partNumber: "1234560" + } + ] + } + ]) + + // Assert + expect(hasGlassLocationWithMultipleParts).toBe(true); + }); + }); +}); + +function setupMocks({}) { + const baseMixin = setupMocksForJsFiles({}); + + const mocks = getMountOptions({ + router: { + navigate: jest.fn() + }, + }); + + const mockVehicleQuestionComponent = { + template: '
', + mixins: [vehicleQuestionsMixin, baseMixin.baseMixin] + }; + + const wrapper = shallowMount(mockVehicleQuestionComponent, mocks); + + return { wrapper }; +} \ No newline at end of file From 149adc97929bd7b1f83c464c99f18aed876818bd Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Tue, 26 Jul 2022 16:21:13 -0400 Subject: [PATCH 048/132] CSR-110: restored navigation to go back to heritage funnel --- .../capability-questions/capability-questions.vue | 3 +++ src/layouts/molding-questions/molding-questions.vue | 8 ++++++-- src/layouts/part-questions/part-questions.vue | 9 +++++++-- src/layouts/vehicle-parts/vehicle-parts.vue | 11 ++++++----- src/mixins/vin-pages-mixin.js | 3 +-- 5 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/layouts/capability-questions/capability-questions.vue b/src/layouts/capability-questions/capability-questions.vue index 025e5aa20..69fc8aad5 100644 --- a/src/layouts/capability-questions/capability-questions.vue +++ b/src/layouts/capability-questions/capability-questions.vue @@ -6,6 +6,7 @@ v-slot="{ meta }" >
+ @@ -49,6 +50,7 @@ import alert from "@/ux-components/alert/alert"; import questionChain from "@/common-components/question-chain/question-chain"; import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header"; import funnelFooter from "@/common-components/funnel-footer/funnel-footer"; +import loadingModal from '@/common-components/loading-modal/loading-modal.vue'; // Supporting Files import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; @@ -145,6 +147,7 @@ export default { questionChain, funnelSubHeader, funnelFooter, + loadingModal, Form, }, }; diff --git a/src/layouts/molding-questions/molding-questions.vue b/src/layouts/molding-questions/molding-questions.vue index a0fa5e96d..c489dc500 100644 --- a/src/layouts/molding-questions/molding-questions.vue +++ b/src/layouts/molding-questions/molding-questions.vue @@ -6,6 +6,7 @@ v-slot="{ meta }" >
+ @@ -49,6 +50,7 @@ import alert from "@/ux-components/alert/alert"; import questionChain from "@/common-components/question-chain/question-chain"; import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header"; import funnelFooter from "@/common-components/funnel-footer/funnel-footer"; +import loadingModal from '@/common-components/loading-modal/loading-modal.vue'; // Supporting Files import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; @@ -159,8 +161,9 @@ export default { const collectedGlassParts = this.reduceGlassPartsArray(glassNameAndPartsForStore); // save to store lineItems.glassParts this.$store.commit(storeMutations.UPDATE_GLASS_PARTS, collectedGlassParts); - // go to quote page - this.$router.navigate(this.navigationScenarios.ANSWERED_QUESTIONS_WITH_SINGLE_PART,this.$route); + // go to heritage quote page + this.$refs.loadingModal.showModal(); + navigateToHeritageFunnel(); } }, }, @@ -180,6 +183,7 @@ export default { questionChain, funnelSubHeader, funnelFooter, + loadingModal, Form, }, }; diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue index b22c30ba6..dcefad7c0 100644 --- a/src/layouts/part-questions/part-questions.vue +++ b/src/layouts/part-questions/part-questions.vue @@ -6,6 +6,7 @@ v-slot="{ meta }" >
+ @@ -49,6 +50,7 @@ import alert from "@/ux-components/alert/alert"; import questionChain from "@/common-components/question-chain/question-chain"; import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header"; import funnelFooter from "@/common-components/funnel-footer/funnel-footer"; +import loadingModal from '@/common-components/loading-modal/loading-modal.vue'; // Supporting Files import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; @@ -61,6 +63,7 @@ import { Form, defineRule } from "vee-validate"; import { required } from "@/helpers/validation-rules"; import { errorMessages } from "@/constants/error-messages"; import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin"; +import loadingModal from '@/common-components/loading-modal/loading-modal.vue'; // DEFINE VALIDATION RULES defineRule("questions-required", required(errorMessages.OPTION_REQUIRED)); @@ -166,8 +169,9 @@ export default { const collectedGlassParts = this.reduceGlassPartsArray(glassNameAndPartsForStore); // save to store lineItems.glassParts this.$store.commit(storeMutations.UPDATE_GLASS_PARTS, collectedGlassParts); - // go to quote page - this.$router.navigate(this.navigationScenarios.ANSWERED_QUESTIONS_WITH_SINGLE_PART,this.$route); + // go to heritage quote page + this.$refs.loadingModal.showModal(); + navigateToHeritageFunnel(); } }, arePagePrerequisitesValid() { @@ -190,6 +194,7 @@ export default { questionChain, funnelSubHeader, funnelFooter, + loadingModal, Form, }, }; diff --git a/src/layouts/vehicle-parts/vehicle-parts.vue b/src/layouts/vehicle-parts/vehicle-parts.vue index 3cbc07e6f..832d4bb94 100644 --- a/src/layouts/vehicle-parts/vehicle-parts.vue +++ b/src/layouts/vehicle-parts/vehicle-parts.vue @@ -1,6 +1,7 @@