From f266fce3f54e531e877562dd3ee87cdedf54e691 Mon Sep 17 00:00:00 2001 From: Katie Date: Wed, 24 Aug 2022 10:56:31 -0400 Subject: [PATCH 01/10] CSR-111 WIP --- .../question-chain/question-chain.vue | 7 +- .../capability-questions.vue | 493 ++++++++++++++++-- src/mixins/vehicle-questions-mixin.js | 201 ++++++- src/store/index.js | 7 +- 4 files changed, 630 insertions(+), 78 deletions(-) diff --git a/src/common-components/question-chain/question-chain.vue b/src/common-components/question-chain/question-chain.vue index dee5d1f32..950c06e7e 100644 --- a/src/common-components/question-chain/question-chain.vue +++ b/src/common-components/question-chain/question-chain.vue @@ -1,5 +1,7 @@ diff --git a/src/mixins/vehicle-questions-mixin.js b/src/mixins/vehicle-questions-mixin.js index 380805751..77ce21f23 100644 --- a/src/mixins/vehicle-questions-mixin.js +++ b/src/mixins/vehicle-questions-mixin.js @@ -68,42 +68,205 @@ export default { async navigateForward(partsOrQuestions, vm) { const self = vm ?? this; const currentPage = self.$route.query.fmgPage; - + const hasPartQuestions = this.hasPartQuestions(partsOrQuestions) const hasGlassLocationWithMultipleParts = this.hasGlassLocationWithMultipleParts(partsOrQuestions); const hasChildPartQuestions = this.hasChildPartQuestions(partsOrQuestions); - const hasCapabilityQuestions = this.hasCapabilityQuestions(partsOrQuestions); + + // TODO REMOVE + const hasCapabilityQuestions = true //this.hasCapabilityQuestions(partsOrQuestions); if (hasPartQuestions && this.currentPageComesBeforePage(currentPage, fmgPageValues.PART_QUESTIONS)) { - self.$router.navigateWithSaving(self.navigationScenarios.HAS_PART_QUESTIONS, self.$route, {}, {}, {partsOrQuestions: partsOrQuestions}); + self.$router.navigateWithSaving(self.navigationScenarios.HAS_PART_QUESTIONS, self.$route, {}, {}, { partsOrQuestions: partsOrQuestions }); } else if (hasGlassLocationWithMultipleParts && this.currentPageComesBeforePage(currentPage, fmgPageValues.VEHICLE_PARTS)) { // if multiple parts on any glass // go to vehicle-parts page and pass the partsData - self.$router.navigateWithSaving(self.navigationScenarios.HAS_MULTIPLE_PARTS_TO_CHOOSE,self.$route,{},{},{partsOrQuestions: partsOrQuestions}); + self.$router.navigateWithSaving(self.navigationScenarios.HAS_MULTIPLE_PARTS_TO_CHOOSE, self.$route, {}, {}, { partsOrQuestions: partsOrQuestions }); } else if (hasChildPartQuestions && this.currentPageComesBeforePage(currentPage, fmgPageValues.MOLDING_QUESTIONS)) { // if any childpart questions // go to molding-questions page and pass the partsData - self.$router.navigateWithSaving(self.navigationScenarios.HAS_MOLDING_QUESTIONS,self.$route,{},{},{partsOrQuestions: partsOrQuestions}); + self.$router.navigateWithSaving(self.navigationScenarios.HAS_MOLDING_QUESTIONS, self.$route, {}, {}, { partsOrQuestions: partsOrQuestions }); } else if (hasCapabilityQuestions && this.currentPageComesBeforePage(currentPage, fmgPageValues.CAPABILITY_QUESTIONS)) { // if has capability questions // go to capability-questions page and pass the partsData - const windshieldPart = partsOrQuestions.filter(x => x.glassLocation === damageLocationsSelected.WINDSHIELD)[0].parts[0]; - let capabilityQuestions = (await baseMixin.methods.dispatchStoreAction(storeActions.GET_CAPABILITY_QUESTIONS, { - carId: store.getters.vehicle.carId, - partNumber: windshieldPart.partNumber - })).data; - capabilityQuestions.forEach(question => { - question.answers = question.answers.map(answer => { - return { - ...answer, - answerResult: answer.answerResult1 + partsOrQuestions = [ + { + "glassName": "Single", + "glassLocation": "Windshield", + "parts": [ + { + "partNumber": "A", + "description": "rain sensor, solar, 3rd visor band, soundproofing, high beam sensor", + "color": "Green Tint, Blue Shade", + "requiresRecalibration": true, + "requiresCapabilityQuestions": true, + "recalibrationType": null, + "childParts": null, + "childPartQuestions": [] + }, + ], + "partQuestions": null + }, + { + "glassName": "Front", + "glassLocation": "Driver", + "parts": [ + { + "partNumber": "B", + "description": "rain sensor, solar, 3rd visor band, soundproofing, high beam sensor", + "color": "Green Tint, Blue Shade", + "requiresRecalibration": true, + "requiresCapabilityQuestions": true, + "recalibrationType": null, + "childParts": null, + "childPartQuestions": [] + }, + ], + "partQuestions": null + }, + { + "glassName": "Rear", + "glassLocation": "Driver", + "parts": [ + + { + "partNumber": "C", + "description": "rain sensor, solar, 3rd visor band, soundproofing, high beam sensor", + "color": "Green Tint, Blue Shade", + "requiresRecalibration": true, + "requiresCapabilityQuestions": false, + "recalibrationType": null, + "childParts": null, + "childPartQuestions": [] + }, + ], + "partQuestions": null + } + ] + + partsOrQuestions = [ + { + "glassName": "Single", + "glassLocation": "Windshield", + "parts": [ + { + "partNumber": "A", + "description": "rain sensor, solar, 3rd visor band, soundproofing, high beam sensor", + "color": "Green Tint, Blue Shade", + "requiresRecalibration": true, + "requiresCapabilityQuestions": true, + "recalibrationType": null, + "childParts": null, + "childPartQuestions": [] } - }) - }); + ], + "partQuestions": null, + "capabilityQuestions": [ + { + "questionSequence": 1, + "questionText": "Is this the first question?", + "answers": [ + { + "answerResult1": "DYNAMIC", + "answerResult2": "1", + "answerText": "Yes", + "nextQuestionSequence": null, + "answerResult": "DYNAMIC" + }, + { + "answerResult1": "Unknown", + "answerResult2": "0", + "answerText": "No", + "nextQuestionSequence": null, + "answerResult": "Unknown" + } + ] + } + ] + }, + { + "glassName": "Front", + "glassLocation": "Driver", + "parts": [ + { + "partNumber": "B", + "description": "rain sensor, solar, 3rd visor band, soundproofing, high beam sensor", + "color": "Green Tint, Blue Shade", + "requiresRecalibration": true, + "requiresCapabilityQuestions": true, + "recalibrationType": null, + "childParts": null, + "childPartQuestions": [] + } + ], + "partQuestions": null, + "capabilityQuestions": [ + { + "questionSequence": 1, + "questionText": "Is this the second question?", + "answers": [ + { + "answerResult1": "Oh yeah", + "answerResult2": "1", + "answerText": "Yes", + "nextQuestionSequence": null, + "answerResult": "Oh yeah" + }, + { + "answerResult1": "Maybe", + "answerResult2": "0", + "answerText": "No", + "nextQuestionSequence": null, + "answerResult": "Maybe" + } + ] + } + ] + }, + { + "glassName": "Rear", + "glassLocation": "Driver", + "parts": [ + { + "partNumber": "C", + "description": "rain sensor, solar, 3rd visor band, soundproofing, high beam sensor", + "color": "Green Tint, Blue Shade", + "requiresRecalibration": true, + "requiresCapabilityQuestions": false, + "recalibrationType": null, + "childParts": null, + "childPartQuestions": [] + } + ], + "partQuestions": null + } + ] + + for (let partOrQuestion of partsOrQuestions) { + if (this.hasCapabilityQuestions([partOrQuestion])) { + let capabilityQuestionsForGlassLocation = (await baseMixin.methods.dispatchStoreAction(storeActions.GET_CAPABILITY_QUESTIONS, { + carId: "CR00064847", // store.getters.vehicle.carId, + partNumber: "DW01929GBYN" // glassLocationWithCapabilityQuestion.parts[0].partNumber + })).data; + + capabilityQuestionsForGlassLocation.forEach(question => { + question.answers = question.answers.map(answer => { + return { + ...answer, + answerResult: answer.answerResult1 + } + }) + }) + + partOrQuestion.capabilityQuestions = capabilityQuestionsForGlassLocation; + } + } + - self.$router.navigateWithSaving(self.navigationScenarios.HAS_CAPABILITY_QUESTIONS, self.$route, {}, {}, { partsOrQuestions, capabilityQuestions }); + + self.$router.navigateWithSaving(self.navigationScenarios.HAS_CAPABILITY_QUESTIONS, self.$route, {}, {}, { partsOrQuestions }); } else { // if single parts only const collectedGlassParts = this.reducedGlassPartsArray(partsOrQuestions); @@ -112,7 +275,7 @@ export default { self.$refs.loadingModal.showModal(); navigateToHeritageFunnel(); - + // For quote pages MVP release // self.$router.navigate(self.navigationScenarios.HAS_NO_MORE_QUESTIONS, self.$route); } diff --git a/src/store/index.js b/src/store/index.js index 359d9cb3b..62e0625cb 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -749,18 +749,19 @@ export const actions = { }) }, - getPartFromCapabilityQuestionAnswer(context, selectedAnswerResult1) { + getPartFromCapabilityQuestionAnswer(context, glassLocation) { const pageData = context.getters.pageData(fmgPageValues.CAPABILITY_QUESTIONS); - const part = pageData.partsOrQuestions.find(x => x.glassLocation === damageLocationsSelected.WINDSHIELD).parts[0]; + const part = pageData.partsOrQuestions.find(x => x.glassLocation === glassLocation).parts[0]; const capabilityQuestionAnswers = context.getters.damage.capabilityQuestionAnswers; + const capabilityQuestionAnswersForPart = capabilityQuestionAnswers.find(x => x.glassLocation === glassLocation); return globalMethods.callHttpClient({ method: endpoints.ApplyCapabilityAnswerToPart.method, endpoint: endpoints.ApplyCapabilityAnswerToPart.url, payload: { part, - capabilityAnswerResults: capabilityQuestionAnswers + capabilityAnswerResults: capabilityQuestionAnswersForPart } }) }, From 9c40093144172e15f66d98d22f26e9bb3541fd2b Mon Sep 17 00:00:00 2001 From: Katie Date: Wed, 24 Aug 2022 15:30:11 -0400 Subject: [PATCH 02/10] CSR-111 Fix answer change issue --- .../question-chain/question-chain.vue | 160 +++++---- .../capability-questions.vue | 40 ++- src/layouts/part-questions/part-questions.vue | 2 +- src/mixins/vehicle-questions-mixin.js | 326 ++++++++++++------ src/ux-components/list-button/list-button.vue | 8 + 5 files changed, 342 insertions(+), 194 deletions(-) diff --git a/src/common-components/question-chain/question-chain.vue b/src/common-components/question-chain/question-chain.vue index 950c06e7e..c0192aa7d 100644 --- a/src/common-components/question-chain/question-chain.vue +++ b/src/common-components/question-chain/question-chain.vue @@ -1,23 +1,18 @@ diff --git a/src/layouts/capability-questions/capability-questions.vue b/src/layouts/capability-questions/capability-questions.vue index 2fcb76975..a78eefde3 100644 --- a/src/layouts/capability-questions/capability-questions.vue +++ b/src/layouts/capability-questions/capability-questions.vue @@ -9,13 +9,12 @@ -
- {{ part.capabilityQuestions }}

- {{ showThisPartQuestionChain(part, i) }} +
+ v-if="showThisPartQuestionChain(part, i)" + validationRules="questions-required" />
partOrQuestion.glassLocation === answer.glassLocation); const partFromCapabilityQuestionAnswer = (await this.dispatchStoreAction(storeActions.GET_PART_FROM_CAPABILITY_QUESTION_ANSWER, answer.glassLocation, false)).data; - partsOrQuestions.find(partOrQuestion => partOrQuestion.glassLocation === damageLocationsSelected.WINDSHIELD).parts = partFromCapabilityQuestionAnswer; + partsOrQuestions.find(partOrQuestion => partOrQuestion.glassLocation === answer.glassLocation).parts = partFromCapabilityQuestionAnswer; } console.log(partsOrQuestions) @@ -171,7 +170,7 @@ export default { // let partsOrQuestions = this.pageData.partsOrQuestions; // partsOrQuestions.find(partOrQuestion => partOrQuestion.glassLocation === damageLocationsSelected.WINDSHIELD).parts = partFromCapabilityQuestionAnswer; - // this.navigateForward(partsOrQuestions); + this.navigateForward(partsOrQuestions); }, handleAnswerUpdates(answer) { // only runs when all questions in a question-chain have been answered @@ -292,6 +291,7 @@ export default { // restore original answerResult if (thisAns.originalAnswerResult) { thisAns.answerResult = thisAns.originalAnswerResult; + thisAns.answerResult1 = thisAns.originalAnswerResult; thisAns.originalAnswerResult = null; } } @@ -306,6 +306,7 @@ export default { thisAns.nextQuestionSequence = null; thisAns.originalAnswerResult = thisAns.originalAnswerResult || thisAns.answerResult; thisAns.answerResult = matchedAnswer.answerResult; + thisAns.answerResult1 = matchedAnswer.answerResult; } } }); @@ -341,6 +342,7 @@ export default { // set the answerData as 'already answered' glassPart.answerData = { answerResult: matchedAnswer.nextQuestionSequence ? matchedAnswer.nextQuestionSequence : matchedAnswer.answerResult, + answerResult1: matchedAnswer.nextQuestionSequence ? matchedAnswer.nextQuestionSequence : matchedAnswer.answerResult, answeredQuestions: [answeredQuestionObj], }; @@ -354,13 +356,22 @@ export default { // Update the key to re-render this part's question-chain component this.capabilityQuestionsData[gpIndex].key = this.capabilityQuestionsData[gpIndex].glassLocation + this.capabilityQuestionsData[gpIndex].glassName + Date.now().toString(); - + console.log("rerendering") + console.log(this.capabilityQuestionsData[gpIndex]) + } - }); - }); + // Need to clear questions for subsequent glassParts as well + console.log(this.capabilityQuestionsData) + // for (let i = currentQuestionChainIndex; i < this.capabilityQuestionsData.length; i++) { + // this.capabilityQuestionsData.map(data => ({ + // ...data, + + // })) + // } + // DETERMINE ANSWERED QUESTIONS LIST FOR THIS GLASS PART // look through all (this part's) part questions for any duplicates that were suppressed; @@ -410,6 +421,7 @@ export default { }); }); + console.log(this.capabilityQuestionsData[1].capabilityQuestions[0].answerSelected) // make sure there are no duplicated dupes in the list... const foundInCompleteAnsweredQuestions = new Set(); let filteredCompleteAnsweredQuestions = completeAnsweredQuestions.filter(el => { @@ -430,15 +442,17 @@ export default { answeredQuestions: filteredCompleteAnsweredQuestions, } + console.log(this.capabilityQuestionsData[1].capabilityQuestions[0].answerSelected) + // this part has been fully answered, so advance to next part's question chain for (let i = answer.partIndex + 1; i < this.capabilityQuestionsData.length; i++) { // if this part has not yet been fully answered, then make it the current part - if (!this.capabilityQuestionsData[i].answerData?.answerSelected) { + if (!this.capabilityQuestionsData[i].answerData?.answerResult) { this.currentQuestionChainIndex = i; break; } } - + console.log(this.capabilityQuestionsData[1].capabilityQuestions[0].answerSelected) }, // TODO I'm sure there's a better/simplier way to do this that I'm missing but my brain's fried // Find the part that has some answer that has an answerResult matching the selected answerResult, then get the corresponding answerResult2 @@ -450,7 +464,6 @@ export default { .answerResult2; }, loadInitialCapabilityQuestionsData() { - // are there alreadyAnsweredQuestions? const alreadyAnsweredQuestions = store.getters.damage.capabilityQuestionAnswers; @@ -486,6 +499,7 @@ export default { // mark this partQuestion as answered (question-chain will read this) part.capabilityQuestions[aq.questionNum - 1].answerSelected = answerString; + console.log("answerSelected set") // mark this partQuestion as duplicate if it is (question-chain will read this) if (aq.suppressQuestion) { part.capabilityQuestions[aq.questionNum - 1].suppressQuestion = true; @@ -506,6 +520,8 @@ export default { }); + console.log("AHHHHH", this.capabilityQuestionsData[1].capabilityQuestions[0].answerSelected) + // Set up watch for each set of part questions, which gets updated when all questions for a part have been answered this.$watch("selectedAnswers." + part.key, (newValue) => { if (newValue) { diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue index 881eaf90b..7de6eb5a2 100644 --- a/src/layouts/part-questions/part-questions.vue +++ b/src/layouts/part-questions/part-questions.vue @@ -20,7 +20,7 @@ :manualCopy="AlertFewMoreQuestionsCopy" v-bind:isDismissible="false" /> -
+
Date: Wed, 24 Aug 2022 15:36:21 -0400 Subject: [PATCH 03/10] CSR-111 EXAMPLE of multiple capability questions --- .../question-chain/question-chain.vue | 153 ++++++++---------- 1 file changed, 68 insertions(+), 85 deletions(-) diff --git a/src/common-components/question-chain/question-chain.vue b/src/common-components/question-chain/question-chain.vue index c0192aa7d..6f52d8e70 100644 --- a/src/common-components/question-chain/question-chain.vue +++ b/src/common-components/question-chain/question-chain.vue @@ -1,16 +1,18 @@ @@ -20,76 +22,65 @@ import buttonQuestion from "@/common-components/button-question/button-question" import { useValidateForm } from "vee-validate"; export default { - name: "questionChain", - data() { - return { - currentQuestionNum: 0, - questions: [], - }; - }, - props: { - questionData: Object, - validationRules: String, - modelValue: Array, - partIndex: Number, - keyString: String, - }, - async created() { - await this.setupQuestionChain(); - }, - methods: { - async setupQuestionChain(validate = true) { - // validate form upon create to prevent out of sync / persistent valid states - if (validate) - await useValidateForm(); // do a test validation check, without triggering full validation + name: "questionChain", + data() { + return { + currentQuestionNum: 0, + questions: [], + }; + }, + props: { + questionData: Object, + validationRules: String, + modelValue: Array, + partIndex: Number, + keyString: String, + }, + async created() { + // validate form upon create to prevent out of sync / persistent valid states + await useValidateForm(); // do a test validation check, without triggering full validation - this.questionData.map((q, i) => { - let answerPair = []; - const question = { - questionText: q.questionText, - questionSequence: q.questionSequence, - answers: q.answers.map((a) => { - answerPair.push(a.nextQuestionSequence ? a.nextQuestionSequence : a.answerResult); - return { - Text: a.answerText, - // Name will either be nextQuestionSequence or answerResult - // Name will be used by list-button as the input value. - // It must be a single string or number, so concatenating together a string with - // 4 pieces of data separated by pipe characters: - // question number|type of answer|answer value|answer text - Name: a.nextQuestionSequence ? - q.questionSequence + "|nextQuestion|" + a.nextQuestionSequence + "|" + a.answerText : - q.questionSequence + "|answer|" + a.answerResult + "|" + a.answerText, - nextQuestionSequence: a.nextQuestionSequence, - answerResult: a.answerResult, - questionSequence: q.questionSequence, - questionType: a.nextQuestionSequence ? "nextQuestion" : "answer", - } - }), - answerSelected: q.answerSelected || "", - }; - console.log("answerSelected set") - question.answerPair = answerPair; - if (!q.suppressQuestion) { - this.questions.push(question); - } - - this.$watch("questions", (newValue, oldValue) => { - console.log("QUESTIONS CHANGED") - console.log("newValues: ", newValue) - console.log("oldValue: ", oldValue) - }, { deep: true }) - }); - - if (!this.modelValue?.length > 0) { - // set this.currentQuestionNum to first valid question - this.currentQuestionNum = this.questions[0]?.questionSequence ?? 0; - // scroll the next question into view - this.$nextTick(() => { - document.querySelector('.current-question').scrollIntoView({ behavior: "smooth" }); - }) + this.questionData.map((q, i) => { + let answerPair = []; + const question = { + questionText: q.questionText, + questionSequence: q.questionSequence, + answers: q.answers.map((a) => { + answerPair.push(a.nextQuestionSequence ? a.nextQuestionSequence : a.answerResult); + return { + Text: a.answerText, + // Name will either be nextQuestionSequence or answerResult + // Name will be used by list-button as the input value. + // It must be a single string or number, so concatenating together a string with + // 4 pieces of data separated by pipe characters: + // question number|type of answer|answer value|answer text + Name: a.nextQuestionSequence ? + q.questionSequence + "|nextQuestion|" + a.nextQuestionSequence + "|" + a.answerText : + q.questionSequence + "|answer|" + a.answerResult + "|" + a.answerText, + nextQuestionSequence: a.nextQuestionSequence, + answerResult: a.answerResult, + questionSequence: q.questionSequence, + questionType: a.nextQuestionSequence ? "nextQuestion" : "answer", } - }, + }), + answerSelected: q.answerSelected || "", + }; + question.answerPair = answerPair; + if (!q.suppressQuestion) { + this.questions.push(question); + } + }); + + if (!this.modelValue?.length > 0) { + // set this.currentQuestionNum to first valid question + this.currentQuestionNum = this.questions[0].questionSequence; + // scroll the next question into view + this.$nextTick(() => { + document.querySelector('.current-question').scrollIntoView({behavior: "smooth"}); + }) + } + }, + methods: { handleAnswer(returnedAnswer) { /* returnedAnswer example format: @@ -119,21 +110,16 @@ export default { const questionAnswerText = returnedAnswerArray[3]; const answeredQuestions = []; - console.log(questionAnswerText) - console.log(returnedAnswerArray) - this.questions.forEach((q) => { // find this question and mark it as "answered" by populating answerSelected if (q.questionSequence === questionNum) { - // q.answerSelected = returnedAnswer; - console.log("answerSelected set") + q.answerSelected = returnedAnswer; q.answerNumber = questionNum; q.selectedAnswerText = questionAnswerText; } // remove all answers AFTER this question... // (needed in case user is changing previously answered questions) if ((q.questionSequence > questionNum)) { - console.log("deleting answerSelected") delete q.answerSelected; } if (q.answerSelected) { @@ -152,7 +138,7 @@ export default { this.currentQuestionNum = parseInt(questionAnswer); // update count to display next question // scroll the next question into view this.$nextTick(() => { - document.querySelector('.current-question').scrollIntoView({ behavior: "smooth" }); + document.querySelector('.current-question').scrollIntoView({behavior: "smooth"}); }) return false; @@ -160,7 +146,7 @@ export default { // reset current question index (removes .current-question class) this.currentQuestionNum = 0; // reset count - + // return an object with the part answer, all the answered questions, and the part index return { answerResult: questionAnswer, @@ -174,8 +160,5 @@ export default { components: { buttonQuestion, }, - watch: { - - } }; From 76077d7793cdcecdc2f062cfb24f1e613886c8bc Mon Sep 17 00:00:00 2001 From: Katie Date: Wed, 24 Aug 2022 15:39:47 -0400 Subject: [PATCH 04/10] CSR-111 Cleanup --- .../capability-questions.vue | 41 ----------- src/mixins/vehicle-questions-mixin.js | 72 +------------------ src/ux-components/list-button/list-button.vue | 7 -- 3 files changed, 3 insertions(+), 117 deletions(-) diff --git a/src/layouts/capability-questions/capability-questions.vue b/src/layouts/capability-questions/capability-questions.vue index a78eefde3..f107356e6 100644 --- a/src/layouts/capability-questions/capability-questions.vue +++ b/src/layouts/capability-questions/capability-questions.vue @@ -147,29 +147,6 @@ export default { partsOrQuestions.find(partOrQuestion => partOrQuestion.glassLocation === answer.glassLocation).parts = partFromCapabilityQuestionAnswer; } - console.log(partsOrQuestions) - - - - - // const glassNameAndPartsForStore = partsLookup.data.glassNameAndParts; - // this.navigateForward(glassNameAndPartsForStore); - - - // const selectedAnswerResult1 = this.selectedAnswer.answerResult; - // const selectedAnswerResult2 = this.pageData.capabilityQuestions[0].answers.find(x => x.answerResult1 === selectedAnswerResult1).answerResult2; - - // this.dispatchStoreAction(storeActions.SAVE_CAPABILITY_QUESTION_ANSWERS, { - // glassName: this.windshieldPart.glassName, - // glassLocation: this.windshieldPart.glassLocation, - // result1: selectedAnswerResult1, - // result2: selectedAnswerResult2 - // }); - - // const partFromCapabilityQuestionAnswer = (await this.dispatchStoreAction(storeActions.GET_PART_FROM_CAPABILITY_QUESTION_ANSWER)).data; - // let partsOrQuestions = this.pageData.partsOrQuestions; - // partsOrQuestions.find(partOrQuestion => partOrQuestion.glassLocation === damageLocationsSelected.WINDSHIELD).parts = partFromCapabilityQuestionAnswer; - this.navigateForward(partsOrQuestions); }, handleAnswerUpdates(answer) { @@ -356,22 +333,11 @@ export default { // Update the key to re-render this part's question-chain component this.capabilityQuestionsData[gpIndex].key = this.capabilityQuestionsData[gpIndex].glassLocation + this.capabilityQuestionsData[gpIndex].glassName + Date.now().toString(); - console.log("rerendering") - console.log(this.capabilityQuestionsData[gpIndex]) } }); }); - // Need to clear questions for subsequent glassParts as well - console.log(this.capabilityQuestionsData) - // for (let i = currentQuestionChainIndex; i < this.capabilityQuestionsData.length; i++) { - // this.capabilityQuestionsData.map(data => ({ - // ...data, - - // })) - // } - // DETERMINE ANSWERED QUESTIONS LIST FOR THIS GLASS PART // look through all (this part's) part questions for any duplicates that were suppressed; @@ -421,7 +387,6 @@ export default { }); }); - console.log(this.capabilityQuestionsData[1].capabilityQuestions[0].answerSelected) // make sure there are no duplicated dupes in the list... const foundInCompleteAnsweredQuestions = new Set(); let filteredCompleteAnsweredQuestions = completeAnsweredQuestions.filter(el => { @@ -442,8 +407,6 @@ export default { answeredQuestions: filteredCompleteAnsweredQuestions, } - console.log(this.capabilityQuestionsData[1].capabilityQuestions[0].answerSelected) - // this part has been fully answered, so advance to next part's question chain for (let i = answer.partIndex + 1; i < this.capabilityQuestionsData.length; i++) { // if this part has not yet been fully answered, then make it the current part @@ -452,7 +415,6 @@ export default { break; } } - console.log(this.capabilityQuestionsData[1].capabilityQuestions[0].answerSelected) }, // TODO I'm sure there's a better/simplier way to do this that I'm missing but my brain's fried // Find the part that has some answer that has an answerResult matching the selected answerResult, then get the corresponding answerResult2 @@ -499,7 +461,6 @@ export default { // mark this partQuestion as answered (question-chain will read this) part.capabilityQuestions[aq.questionNum - 1].answerSelected = answerString; - console.log("answerSelected set") // mark this partQuestion as duplicate if it is (question-chain will read this) if (aq.suppressQuestion) { part.capabilityQuestions[aq.questionNum - 1].suppressQuestion = true; @@ -520,8 +481,6 @@ export default { }); - console.log("AHHHHH", this.capabilityQuestionsData[1].capabilityQuestions[0].answerSelected) - // Set up watch for each set of part questions, which gets updated when all questions for a part have been answered this.$watch("selectedAnswers." + part.key, (newValue) => { if (newValue) { diff --git a/src/mixins/vehicle-questions-mixin.js b/src/mixins/vehicle-questions-mixin.js index aee95c5d3..7e4542a13 100644 --- a/src/mixins/vehicle-questions-mixin.js +++ b/src/mixins/vehicle-questions-mixin.js @@ -90,62 +90,6 @@ export default { } else if (hasCapabilityQuestions && this.currentPageComesBeforePage(currentPage, fmgPageValues.CAPABILITY_QUESTIONS)) { // if has capability questions // go to capability-questions page and pass the partsData - - // partsOrQuestions = [ - // { - // "glassName": "Single", - // "glassLocation": "Windshield", - // "parts": [ - // { - // "partNumber": "A", - // "description": "rain sensor, solar, 3rd visor band, soundproofing, high beam sensor", - // "color": "Green Tint, Blue Shade", - // "requiresRecalibration": true, - // "requiresCapabilityQuestions": true, - // "recalibrationType": null, - // "childParts": null, - // "childPartQuestions": [] - // }, - // ], - // "partQuestions": null - // }, - // { - // "glassName": "Front", - // "glassLocation": "Driver", - // "parts": [ - // { - // "partNumber": "B", - // "description": "rain sensor, solar, 3rd visor band, soundproofing, high beam sensor", - // "color": "Green Tint, Blue Shade", - // "requiresRecalibration": true, - // "requiresCapabilityQuestions": true, - // "recalibrationType": null, - // "childParts": null, - // "childPartQuestions": [] - // }, - // ], - // "partQuestions": null - // }, - // { - // "glassName": "Rear", - // "glassLocation": "Driver", - // "parts": [ - - // { - // "partNumber": "C", - // "description": "rain sensor, solar, 3rd visor band, soundproofing, high beam sensor", - // "color": "Green Tint, Blue Shade", - // "requiresRecalibration": true, - // "requiresCapabilityQuestions": false, - // "recalibrationType": null, - // "childParts": null, - // "childPartQuestions": [] - // }, - // ], - // "partQuestions": null - // } - // ] - partsOrQuestions = [ { "glassName": "Single", @@ -243,7 +187,7 @@ export default { "partQuestions": null } ] - + for (let partOrQuestion of partsOrQuestions) { if (this.hasCapabilityQuestions([partOrQuestion])) { let capabilityQuestionsForGlassLocation = (await baseMixin.methods.dispatchStoreAction(storeActions.GET_CAPABILITY_QUESTIONS, { @@ -264,8 +208,6 @@ export default { } } - - partsOrQuestions = [ { "glassName": "Single", @@ -371,11 +313,6 @@ export default { }], }) - - - - - self.$router.navigateWithSaving(self.navigationScenarios.HAS_CAPABILITY_QUESTIONS, self.$route, {}, {}, { partsOrQuestions }); } else { // if single parts only @@ -383,11 +320,8 @@ export default { // save to store lineItems.glassParts self.$store.commit(storeMutations.UPDATE_GLASS_PARTS, collectedGlassParts); - // self.$refs.loadingModal.showModal(); - // navigateToHeritageFunnel(); - - // For quote pages MVP release - // self.$router.navigate(self.navigationScenarios.HAS_NO_MORE_QUESTIONS, self.$route); + self.$refs.loadingModal.showModal(); + navigateToHeritageFunnel(); } }, backButtonAction() { diff --git a/src/ux-components/list-button/list-button.vue b/src/ux-components/list-button/list-button.vue index b9915a5a5..e51d5cc77 100644 --- a/src/ux-components/list-button/list-button.vue +++ b/src/ux-components/list-button/list-button.vue @@ -91,7 +91,6 @@ export default { }, mounted() { if (Array.isArray(this.validateValue)) { - console.log("LB mounted array") this.checkValue = this.isValueSelectedByArray(this.selectedValues); const isSelectedByValidator = this.isValueSelectedByArray(this.validateValue); @@ -100,10 +99,7 @@ export default { } } else { - console.log("LB mounted NOT ") - console.log("selectedValues: ", this.selectedValues) this.checkValue = this.selectedValues == this.value; - console.log(this.checkValue) } }, methods: { @@ -139,9 +135,6 @@ export default { buttonId: this.buttonID && this.buttonID.toString(), }; - console.log("handleCheckChange: ", emitEvent) - console.log("selectedValues: ", this.selectedValues) - this.handleChange(this.value); this.$emit("isCheckedChanged", emitEvent); this.$emit("update:modelValue", emitEvent); From ec7bc77e675c82f09a482e701a938d1f5600d8f2 Mon Sep 17 00:00:00 2001 From: Katie Date: Wed, 24 Aug 2022 15:49:32 -0400 Subject: [PATCH 05/10] CSR-111 Remove multiple questions example, tested with heritage --- src/mixins/vehicle-questions-mixin.js | 203 +------------------------- src/router/index.js | 2 +- 2 files changed, 2 insertions(+), 203 deletions(-) diff --git a/src/mixins/vehicle-questions-mixin.js b/src/mixins/vehicle-questions-mixin.js index 7e4542a13..6c0c56dad 100644 --- a/src/mixins/vehicle-questions-mixin.js +++ b/src/mixins/vehicle-questions-mixin.js @@ -90,104 +90,8 @@ export default { } else if (hasCapabilityQuestions && this.currentPageComesBeforePage(currentPage, fmgPageValues.CAPABILITY_QUESTIONS)) { // if has capability questions // go to capability-questions page and pass the partsData - partsOrQuestions = [ - { - "glassName": "Single", - "glassLocation": "Windshield", - "parts": [ - { - "partNumber": "A", - "description": "rain sensor, solar, 3rd visor band, soundproofing, high beam sensor", - "color": "Green Tint, Blue Shade", - "requiresRecalibration": true, - "requiresCapabilityQuestions": true, - "recalibrationType": null, - "childParts": null, - "childPartQuestions": [] - } - ], - "partQuestions": null, - "capabilityQuestions": [ - { - "questionSequence": 1, - "questionText": "Is this the first question?", - "answers": [ - { - "answerResult1": "DYNAMIC", - "answerResult2": "1", - "answerText": "Yes", - "nextQuestionSequence": null, - "answerResult": "DYNAMIC" - }, - { - "answerResult1": "Unknown", - "answerResult2": "0", - "answerText": "No", - "nextQuestionSequence": null, - "answerResult": "Unknown" - } - ] - } - ] - }, - { - "glassName": "Front", - "glassLocation": "Driver", - "parts": [ - { - "partNumber": "B", - "description": "rain sensor, solar, 3rd visor band, soundproofing, high beam sensor", - "color": "Green Tint, Blue Shade", - "requiresRecalibration": true, - "requiresCapabilityQuestions": true, - "recalibrationType": null, - "childParts": null, - "childPartQuestions": [] - } - ], - "partQuestions": null, - "capabilityQuestions": [ - { - "questionSequence": 1, - "questionText": "Is this the second question?", - "answers": [ - { - "answerResult1": "Oh yeah", - "answerResult2": "1", - "answerText": "Yes", - "nextQuestionSequence": null, - "answerResult": "Oh yeah" - }, - { - "answerResult1": "Maybe", - "answerResult2": "0", - "answerText": "No", - "nextQuestionSequence": null, - "answerResult": "Maybe" - } - ] - } - ] - }, - { - "glassName": "Rear", - "glassLocation": "Driver", - "parts": [ - { - "partNumber": "C", - "description": "rain sensor, solar, 3rd visor band, soundproofing, high beam sensor", - "color": "Green Tint, Blue Shade", - "requiresRecalibration": true, - "requiresCapabilityQuestions": false, - "recalibrationType": null, - "childParts": null, - "childPartQuestions": [] - } - ], - "partQuestions": null - } - ] + // mimic part-questions page data for consistency for (let partOrQuestion of partsOrQuestions) { if (this.hasCapabilityQuestions([partOrQuestion])) { let capabilityQuestionsForGlassLocation = (await baseMixin.methods.dispatchStoreAction(storeActions.GET_CAPABILITY_QUESTIONS, { @@ -208,111 +112,6 @@ export default { } } - partsOrQuestions = [ - { - "glassName": "Single", - "glassLocation": "Windshield", - "parts": [ - { - "partNumber": "A", - "description": "rain sensor, solar, 3rd visor band, soundproofing, high beam sensor", - "color": "Green Tint, Blue Shade", - "requiresRecalibration": true, - "requiresCapabilityQuestions": true, - "recalibrationType": null, - "childParts": null, - "childPartQuestions": [] - } - ], - "partQuestions": null, - "capabilityQuestions": [ - { - "questionSequence": 1, - "questionText": "Is this the first question?", - "answers": [ - { - "answerResult1": "DYNAMIC", - "answerResult2": "1", - "answerText": "Yes", - "nextQuestionSequence": null, - "answerResult": "DYNAMIC" - }, - { - "answerResult1": "Unknown", - "answerResult2": "0", - "answerText": "No", - "nextQuestionSequence": null, - "answerResult": "Unknown" - } - ] - } - ] - }, - { - "glassName": "Front", - "glassLocation": "Driver", - "parts": [ - { - "partNumber": "B", - "description": "rain sensor, solar, 3rd visor band, soundproofing, high beam sensor", - "color": "Green Tint, Blue Shade", - "requiresRecalibration": true, - "requiresCapabilityQuestions": true, - "recalibrationType": null, - "childParts": null, - "childPartQuestions": [] - } - ], - "partQuestions": null, - "capabilityQuestions": [ - { - "questionSequence": 1, - "questionText": "Is this the second question?", - "answers": [ - { - "answerResult1": "Oh yeah", - "answerResult2": "1", - "answerText": "Yes", - "nextQuestionSequence": null, - "answerResult": "Oh yeah" - }, - { - "answerResult1": "Maybe", - "answerResult2": "0", - "answerText": "No", - "nextQuestionSequence": null, - "answerResult": "Maybe" - } - ] - } - ] - }, - { - "glassName": "Rear", - "glassLocation": "Driver", - "parts": [ - { - "partNumber": "C", - "description": "rain sensor, solar, 3rd visor band, soundproofing, high beam sensor", - "color": "Green Tint, Blue Shade", - "requiresRecalibration": true, - "requiresCapabilityQuestions": false, - "recalibrationType": null, - "childParts": null, - "childPartQuestions": [] - } - ], - "partQuestions": null - } - ] - - store.commit(storeMutations.UPDATE_PAGE_DATA, { - page: "capability-questions", - data: [{ - partsOrQuestions: partsOrQuestions - }], - }) - self.$router.navigateWithSaving(self.navigationScenarios.HAS_CAPABILITY_QUESTIONS, self.$route, {}, {}, { partsOrQuestions }); } else { // if single parts only diff --git a/src/router/index.js b/src/router/index.js index 5c4b6ca75..b45e0b403 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -224,7 +224,7 @@ function navigateToUrl(url, optionalQuery = {}) { for (const queryKey in optionalQuery) { externalUrl.searchParams.append(queryKey, optionalQuery[queryKey]); } - + window.location.assign(externalUrl); } From e6dfb8a25f53aa1e61b337309c9b8586368730f3 Mon Sep 17 00:00:00 2001 From: Katie Date: Wed, 24 Aug 2022 15:53:13 -0400 Subject: [PATCH 06/10] CSR-111 Cleanup --- src/layouts/capability-questions/capability-questions.vue | 8 ++------ src/mixins/vehicle-questions-mixin.js | 4 +--- src/router/index.js | 2 +- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/layouts/capability-questions/capability-questions.vue b/src/layouts/capability-questions/capability-questions.vue index f107356e6..be43f0db2 100644 --- a/src/layouts/capability-questions/capability-questions.vue +++ b/src/layouts/capability-questions/capability-questions.vue @@ -74,7 +74,6 @@ export default { data() { return { selectedAnswer: [], - // TODO This shouldn't be an object with property `capabilityQuestions` capabilityQuestionsData: store.getters.pageData(fmgPageValues.CAPABILITY_QUESTIONS).partsOrQuestions, selectedAnswers: {}, currentQuestionChainIndex: 0, @@ -108,11 +107,8 @@ export default { return this.currentQuestionChainIndex === i || part.answerData?.answerResult?.length > 0 }, arePagePrerequisitesValid() { - return true; - - // TODO UNCOMMENT - // const capabilityQuestionsPageData = store.getters.pageData(fmgPageValues.CAPABILITY_QUESTIONS); - // return capabilityQuestionsPageData && Object.keys(capabilityQuestionsPageData).length > 0; + const capabilityQuestionsPageData = store.getters.pageData(fmgPageValues.CAPABILITY_QUESTIONS); + return capabilityQuestionsPageData && Object.keys(capabilityQuestionsPageData).length > 0; }, async forwardButtonAction() { const capabilityQuestionsAnswersArray = this.capabilityQuestionsData.map((item) => { diff --git a/src/mixins/vehicle-questions-mixin.js b/src/mixins/vehicle-questions-mixin.js index 6c0c56dad..cdfc5f261 100644 --- a/src/mixins/vehicle-questions-mixin.js +++ b/src/mixins/vehicle-questions-mixin.js @@ -72,9 +72,7 @@ export default { const hasPartQuestions = this.hasPartQuestions(partsOrQuestions) const hasGlassLocationWithMultipleParts = this.hasGlassLocationWithMultipleParts(partsOrQuestions); const hasChildPartQuestions = this.hasChildPartQuestions(partsOrQuestions); - - // TODO REMOVE - const hasCapabilityQuestions = true //this.hasCapabilityQuestions(partsOrQuestions); + const hasCapabilityQuestions = this.hasCapabilityQuestions(partsOrQuestions); if (hasPartQuestions && this.currentPageComesBeforePage(currentPage, fmgPageValues.PART_QUESTIONS)) { self.$router.navigateWithSaving(self.navigationScenarios.HAS_PART_QUESTIONS, self.$route, {}, {}, { partsOrQuestions: partsOrQuestions }); diff --git a/src/router/index.js b/src/router/index.js index b45e0b403..5c4b6ca75 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -224,7 +224,7 @@ function navigateToUrl(url, optionalQuery = {}) { for (const queryKey in optionalQuery) { externalUrl.searchParams.append(queryKey, optionalQuery[queryKey]); } - + window.location.assign(externalUrl); } From 5f3f647fb803f0cb1331f98e2a1d349d50f173cc Mon Sep 17 00:00:00 2001 From: Katie Date: Thu, 25 Aug 2022 08:25:36 -0400 Subject: [PATCH 07/10] CSR-111 Tested with dynamic values --- src/mixins/vehicle-questions-mixin.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mixins/vehicle-questions-mixin.js b/src/mixins/vehicle-questions-mixin.js index cdfc5f261..06776174f 100644 --- a/src/mixins/vehicle-questions-mixin.js +++ b/src/mixins/vehicle-questions-mixin.js @@ -93,8 +93,8 @@ export default { for (let partOrQuestion of partsOrQuestions) { if (this.hasCapabilityQuestions([partOrQuestion])) { let capabilityQuestionsForGlassLocation = (await baseMixin.methods.dispatchStoreAction(storeActions.GET_CAPABILITY_QUESTIONS, { - carId: "CR00064847", // store.getters.vehicle.carId, - partNumber: "DW01929GBYN" // glassLocationWithCapabilityQuestion.parts[0].partNumber + carId: store.getters.vehicle.carId, + partNumber: partOrQuestion.parts[0].partNumber })).data; capabilityQuestionsForGlassLocation.forEach(question => { From 73bc3f594506e08826ca46d80abc85395e71e8e4 Mon Sep 17 00:00:00 2001 From: Katie Date: Thu, 25 Aug 2022 08:51:15 -0400 Subject: [PATCH 08/10] CSR-111 Fix tests --- src/mixins/vehicle-questions-mixin.spec.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mixins/vehicle-questions-mixin.spec.js b/src/mixins/vehicle-questions-mixin.spec.js index 954349c53..05d019da5 100644 --- a/src/mixins/vehicle-questions-mixin.spec.js +++ b/src/mixins/vehicle-questions-mixin.spec.js @@ -944,6 +944,7 @@ describe("vehicle-questions-mixin", () => { "childPartQuestions": null } ], + "capabilityQuestions": [], "partQuestions": null } ]; @@ -957,7 +958,7 @@ describe("vehicle-questions-mixin", () => { // Assert expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledTimes(1); - expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledWith(navigationScenarios.HAS_CAPABILITY_QUESTIONS, wrapper.vm.$route, {}, {}, { partsOrQuestions, capabilityQuestions: [] }); + expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledWith(navigationScenarios.HAS_CAPABILITY_QUESTIONS, wrapper.vm.$route, {}, {}, { partsOrQuestions }); }); }); From 9ed3c0fa84b2ae2ddd72e82fc683498c0b00c10e Mon Sep 17 00:00:00 2001 From: Katie Date: Thu, 25 Aug 2022 09:08:00 -0400 Subject: [PATCH 09/10] CSR-111 Add experimentMixin to components --- src/main.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main.js b/src/main.js index 6a81170db..01aa5406d 100644 --- a/src/main.js +++ b/src/main.js @@ -6,6 +6,7 @@ import router from "./router"; import store from "@/store"; import baseMixin from "@/mixins/base-mixin.js"; import analyticsMixin from "@/mixins/analytics-mixin.js"; +import experimentMixin from "@/mixins/experiment-mixin.js"; import "../node_modules/bootstrap/dist/js/bootstrap.js"; // Vue App Setup @@ -17,5 +18,6 @@ vueApp.use(LoadScript); vueApp.use(Maska); vueApp.mixin(baseMixin); vueApp.mixin(analyticsMixin); +vueApp.mixin(experimentMixin); vueApp.mount("#app"); From bb8a8cc2f4d236e83c799aab885b95f697833490 Mon Sep 17 00:00:00 2001 From: Katie Date: Thu, 25 Aug 2022 11:49:10 -0400 Subject: [PATCH 10/10] CSR-804 Change endpoint name --- src/constants/endpoints.js | 4 ++-- src/store/index.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/constants/endpoints.js b/src/constants/endpoints.js index 9cf0b6856..d0e05919b 100644 --- a/src/constants/endpoints.js +++ b/src/constants/endpoints.js @@ -63,8 +63,8 @@ const endpoints = { url: "/parts/api/v1/parts/capability-questions", method: "GET" }, - ApplyCapabilityAnswerToPart: { - url: "/parts/api/v1/parts/apply-capability-answer-to-part", + GetPartFromCapabilityAnswer: { + url: "/parts/api/v1/parts/part-from-capability-answer", method: "POST" }, SaveOrder: { diff --git a/src/store/index.js b/src/store/index.js index 62e0625cb..9c81b88e0 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -757,8 +757,8 @@ export const actions = { const capabilityQuestionAnswersForPart = capabilityQuestionAnswers.find(x => x.glassLocation === glassLocation); return globalMethods.callHttpClient({ - method: endpoints.ApplyCapabilityAnswerToPart.method, - endpoint: endpoints.ApplyCapabilityAnswerToPart.url, + method: endpoints.GetPartFromCapabilityAnswer.method, + endpoint: endpoints.GetPartFromCapabilityAnswer.url, payload: { part, capabilityAnswerResults: capabilityQuestionAnswersForPart