From b0447586c51e8960b142bf7664dde8f1f3aff3ca Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Thu, 6 Oct 2022 15:12:03 -0400 Subject: [PATCH 01/11] CSR-803: remove obsolete code --- src/layouts/capability-questions/capability-questions.vue | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/layouts/capability-questions/capability-questions.vue b/src/layouts/capability-questions/capability-questions.vue index 39b96c361..2c132af9b 100644 --- a/src/layouts/capability-questions/capability-questions.vue +++ b/src/layouts/capability-questions/capability-questions.vue @@ -85,12 +85,6 @@ export default { AlertFewMoreQuestionsCopy() { return this.getCmsContent("AdditionalPartsQuestionsAlert", "BodyText"); }, - windshieldPart() { - return this.pageData.partsOrQuestions.find(x => x.glassLocation === damageLocationsSelected.WINDSHIELD); - }, - windshieldPartInfo() { - return this.windshieldPart.parts[0]; - }, pageData() { return this.$store.getters.pageData(fmgPageValues.CAPABILITY_QUESTIONS); } From e604bdb8e10b669e08357ff44c629a5a36c70643 Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Fri, 7 Oct 2022 16:04:43 -0400 Subject: [PATCH 02/11] CSR-803: move handleAnswerUpdates to shared mixin --- .../capability-questions.vue | 277 +----------------- .../molding-questions/molding-questions.vue | 268 +---------------- src/layouts/part-questions/part-questions.vue | 270 +---------------- src/mixins/vehicle-questions-mixin.js | 257 ++++++++++++++++ 4 files changed, 279 insertions(+), 793 deletions(-) diff --git a/src/layouts/capability-questions/capability-questions.vue b/src/layouts/capability-questions/capability-questions.vue index 2c132af9b..f9a15a6e8 100644 --- a/src/layouts/capability-questions/capability-questions.vue +++ b/src/layouts/capability-questions/capability-questions.vue @@ -9,7 +9,7 @@ -
+
x.capabilityQuestions).map((glass, i) => { + this.questionsData = this.pageData.partsOrQuestions.filter(x => x.capabilityQuestions).map((glass, i) => { // NOTE: questions for property "questions" can differ between layouts glass.questions = glass.capabilityQuestions; // reset selectedAnswers for this glass @@ -103,16 +101,16 @@ export default { }); }, methods: { - showThisQuestionChain(glass, i) { - if (!glass.capabilityQuestions || glass.capabilityQuestions?.length < 1 || glass.isSuppressedPart) { return false; } // return false if no capabilityQuestions or if suppressed - return this.currentQuestionChainIndex === i || glass.answerData?.answerResult?.length > 0; - }, arePagePrerequisitesValid() { const capabilityQuestionsPageData = store.getters.pageData(fmgPageValues.CAPABILITY_QUESTIONS); return capabilityQuestionsPageData && Object.keys(capabilityQuestionsPageData).length > 0; }, + showThisQuestionChain(glass, i) { + if (!glass.capabilityQuestions || glass.capabilityQuestions?.length < 1 || glass.isSuppressedPart) { return false; } // return false if no capabilityQuestions or if suppressed + return this.currentQuestionChainIndex === i || glass.answerData?.answerResult?.length > 0; + }, async forwardButtonAction() { - const capabilityQuestionsAnswersArray = this.capabilityQuestionsData.map((glass) => { + const capabilityQuestionsAnswersArray = this.questionsData.map((glass) => { const selectedAnswerResult2 = this.getCorrespondingAnswerResult2(glass.answerData.answerResult); return { @@ -127,7 +125,7 @@ export default { }); // clear out answerData for future page loads; must occur prior to store save - this.capabilityQuestionsData.forEach((glass) => { + this.questionsData.forEach((glass) => { glass.answerData = {}; }); @@ -138,270 +136,17 @@ export default { let partsOrQuestions = this.pageData.partsOrQuestions; for (let answer of capabilityQuestionsAnswersArray) { const correspondingPart = partsOrQuestions.find(partOrQuestion => partOrQuestion.glassLocation === answer.glassLocation); - const partFromCapabilityQuestionAnswer = (await this.dispatchStoreAction(storeActions.GET_PART_FROM_CAPABILITY_QUESTION_ANSWER, answer.glassLocation, false)).data; + const partFromCapabilityQuestionAnswer = (await this.dispatchStoreAction(this.storeActions.GET_PART_FROM_CAPABILITY_QUESTION_ANSWER, answer.glassLocation, false)).data; partsOrQuestions.find(partOrQuestion => partOrQuestion.glassLocation === answer.glassLocation).parts = partFromCapabilityQuestionAnswer; } this.navigateForward(partsOrQuestions); }, - handleAnswerUpdates(answer) { - // only runs when all questions in a question-chain have been answered - // when selectedAnswers updates, user has completed this part's question chain and has a final answer - // (does not get run for each invididual question's answer, only when - // all relevant questions for the current part have been answered) - - /* - answer example format: - { - "answerResult": "DD11132", - "answeredQuestions": [ - { - "questionText": "Is your Grand Cherokee the Laredo model?", - "selectedAnswerText": "Yes", - "questionNum": 1, - } - ], - "glassIndex": 0 - } - */ - - // collect a list of the answered questions' numbers, needed later below - const answeredQuestionIndexes = []; - const foundDuplicateQuestions = []; - - // if user has answered a question differently than anything that was preloaded, - // we need to clear out any preloaded answers - this.selectedAnswers = {}; - - // loop through every answered question on the currently answered glass part - answer.answeredQuestions?.forEach((aq) => { - - // keep track of this question number - answeredQuestionIndexes.push(aq.questionNum); - - const answeredQuestionText = aq.questionText.toUpperCase(); - const answeredQuestionAnswer = aq.selectedAnswerText.toUpperCase(); - - // HANDLE DUPLICATE QUESTIONS - - // loop through all glass parts data - this.capabilityQuestionsData.forEach((glass, gpIndex) => { - - // only look for duplicates forward... to parts that follow after the currently being answered part - if (gpIndex > answer.glass) { - - let suppressUntil; - // reset this glass part, in case user is changing their previous answers - glass.answerData = null; - glass.isSuppressedPart = null; - - // loop through this glass part's part questions, looking for a questionText match - glass.capabilityQuestions.forEach((pq, pqIndex) => { - - // clear out any previously set answers - pq.answerSelected = null; - - // clear or set suppressQuestion property for each question - if (suppressUntil) { - // if suppressUntil has been set, then suppress this question if before it - if (pqIndex + 1 < suppressUntil) { - pq.suppressQuestion = true; - } else { - pq.suppressQuestion = null; - } - } else { - pq.suppressQuestion = null; - } - - // if these match then we have a duplicate question - if (pq.questionText.toUpperCase() === answeredQuestionText) { - - const thisAnsweredCapabilityQuestion = glass.capabilityQuestions[pqIndex]; - let matchedAnswer; - let rejectedAnswers = []; // set as an array, in case we ever have questions with more than 2 answers... - - // which one of this capabilityQuestions' answers matches our answer? - pq.answers.forEach((ans) => { - if (ans.answerText.toUpperCase() === answeredQuestionAnswer) { - matchedAnswer = ans; - ans.selected = true; - } else { - rejectedAnswers.push(ans); - ans.selected = null; - } - }); - - // 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(); - - // handle suppressing downstream in this question chain - - if (matchedAnswer.nextQuestionSequence) { - // ensure that the question that the accepted answer has set to be next is NOT suppressed - glass.capabilityQuestions[matchedAnswer.nextQuestionSequence - 1].suppressQuestion = null; - // if the duplicate is the 1ST question, then set suppressUntil var to lowest nextQuestion number - if (pqIndex === 0) { - if (!suppressUntil) { suppressUntil = matchedAnswer.nextQuestionSequence } - if (matchedAnswer.nextQuestionSequence < suppressUntil) { suppressUntil = matchedAnswer.nextQuestionSequence } - } - } - - // handle suppressing upstream in this question chain - glass.capabilityQuestions.forEach((q) => { - q.answers.forEach((thisAns) => { - // restore any of the answers that formerly led to the duplicated question - if (thisAns.originalNextQuestionSequence === pq.questionSequence) { - // restore original nextQuestionSequence - thisAns.nextQuestionSequence = thisAns.originalNextQuestionSequence; - this.originalNextQuestionSequence = null; - // restore original answerResult - if (thisAns.originalAnswerResult) { - thisAns.answerResult = thisAns.originalAnswerResult; - thisAns.originalAnswerResult = null; - } - } - // search for any answers that lead to the duplicated question - if (thisAns.nextQuestionSequence === pq.questionSequence) { - // update either the nextQuestionSequence or the answerResult - if (matchedAnswer.nextQuestionSequence) { - thisAns.originalNextQuestionSequence = thisAns.nextQuestionSequence; - thisAns.nextQuestionSequence = matchedAnswer.nextQuestionSequence; - } else { - thisAns.originalNextQuestionSequence = thisAns.nextQuestionSequence; - thisAns.nextQuestionSequence = null; - thisAns.originalAnswerResult = thisAns.originalAnswerResult || thisAns.answerResult; - thisAns.answerResult = matchedAnswer.answerResult; - } - } - }); - }); - - // suppress current question - thisAnsweredCapabilityQuestion.suppressQuestion = true; - - const thisGlassPart = "glass" + gpIndex; - if (foundDuplicateQuestions[thisGlassPart]) { - if (!foundDuplicateQuestions[thisGlassPart].includes(thisAnsweredCapabilityQuestion.questionSequence)) { - foundDuplicateQuestions[thisGlassPart].push(thisAnsweredCapabilityQuestion.questionSequence); - } - } else { - foundDuplicateQuestions[thisGlassPart] = [thisAnsweredCapabilityQuestion.questionSequence]; - } - - // are there any questions left that are not suppressed? - const remainingQuestions = glass.capabilityQuestions.filter((q) => { - return !q.suppressQuestion; - }); - - if (remainingQuestions.length < 1) { - // this is the final answer for this glass part - - // mark this part as completely answered by adding answerData - const answeredQuestionObj = { - questionText: pq.questionText, - selectedAnswerText: matchedAnswer.answerText, - questionNum: pq.questionSequence, - suppressQuestion: pq.suppressQuestion, - }; - // set the answerData as 'already answered' - glass.answerData = { - answerResult: matchedAnswer.nextQuestionSequence ? matchedAnswer.nextQuestionSequence : matchedAnswer.answerResult, - answeredQuestions: [answeredQuestionObj], - }; - - // suppress this glass because it has an answer - glass.isSuppressedPart = true; - } - - } - - }); - - // 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(); - - } - }); - }); - - // DETERMINE ANSWERED QUESTIONS LIST FOR THIS GLASS PART - - // look through all (this part's) part questions for any duplicates that were suppressed; - // add them to the list of answered questions if found - - // EX answeredQuestionIndexes: [1,5,11,13] - - // EX foundDuplicateQuestions = { - // "glassPart1": [1], - // "glassPart2": [7, 10] - // }; - - const thisPartsDupes = foundDuplicateQuestions["glass" + answer.glassIndex]; - const completeAnsweredQuestions = answer.answeredQuestions ? [...answer.answeredQuestions] : []; - const glassPartAnswered = this.capabilityQuestionsData[answer.glassIndex]; - - thisPartsDupes?.forEach((dupe) => { - // dupe is a single integer - const dupeQuestion = glassPartAnswered.capabilityQuestions[dupe - 1]; - const dupeQuestionAnswer = dupeQuestion.answers.find((q) => q.selected === true); - - glassPartAnswered.capabilityQuestions.forEach((q) => { - let includeThisDupeInAnsweredQuestions = false; - - // did one of the answers of this question point to the duplicated question? - q.answers.forEach((a) => { - if ((dupe === a.originalNextQuestionSequence) && - (answeredQuestionIndexes.includes(q.questionSequence)) && - (a.answerText.toUpperCase() === dupeQuestionAnswer.answerText.toUpperCase())) { - includeThisDupeInAnsweredQuestions = true; - } - }); - - // is this q.questionSequence listed as the duplicated question's nextQuestionSequence? - if ((q.questionSequence === dupeQuestionAnswer.nextQuestionSequence) && (answeredQuestionIndexes.includes(q.questionSequence))) { - includeThisDupeInAnsweredQuestions = true; - } - - if (includeThisDupeInAnsweredQuestions) { - completeAnsweredQuestions.push({ - questionNum: dupeQuestion.questionSequence, - questionText: dupeQuestion.questionText, - selectedAnswerText: dupeQuestionAnswer.answerText, - suppressQuestion: dupeQuestion.suppressQuestion, - }); - } - }); - }); - - // make sure there are no duplicated dupes in the list... - const foundInCompleteAnsweredQuestions = new Set(); - let filteredCompleteAnsweredQuestions = completeAnsweredQuestions.filter(el => { - const duplicate = foundInCompleteAnsweredQuestions.has(el.questionText); - foundInCompleteAnsweredQuestions.add(el.questionText); - return !duplicate; - }); - filteredCompleteAnsweredQuestions = filteredCompleteAnsweredQuestions.sort((a, b) => a.questionNum - b.questionNum); - - // set final answer data for the current answered glass part - glassPartAnswered.answerData = { - answerResult: answer.answerResult, - answeredQuestions: filteredCompleteAnsweredQuestions, - } - - // this part has been fully answered, so advance to next part's question chain - for (let i = answer.glassIndex + 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?.answerResult) { - this.currentQuestionChainIndex = i; - break; - } - } - }, // 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 getCorrespondingAnswerResult2(answerResult1) { - return this.capabilityQuestionsData + return this.questionsData .find(part => part.capabilityQuestions.some(question => question.answers.some(answer => answer.answerResult == answerResult1))) // found part .capabilityQuestions.find(question => question.answers.some(answer => answer.answerResult == answerResult1)) // found question .answers.find(answer => answer.answerResult == answerResult1) diff --git a/src/layouts/molding-questions/molding-questions.vue b/src/layouts/molding-questions/molding-questions.vue index 50cfe42c2..b60e4dd5f 100644 --- a/src/layouts/molding-questions/molding-questions.vue +++ b/src/layouts/molding-questions/molding-questions.vue @@ -20,7 +20,7 @@ :manualCopy="AlertFewMoreQuestionsCopy" v-bind:isDismissible="false" /> -
+
x.parts[0].childPartQuestions.length).map((glass, i) => { + this.questionsData = this.pageData.partsOrQuestions.filter(x => x.parts[0].childPartQuestions.length).map((glass, i) => { // NOTE: questions for property "questions" can differ between layouts glass.questions = glass.parts[0].childPartQuestions; // reset selectedAnswers for this glass @@ -130,7 +128,7 @@ export default { return this.currentGlassIndex === i || glass.answerData?.answerResult?.length > 0; }, async forwardButtonAction() { - const questionAnswersArray = this.moldingQuestionsData.map((glass) => { + const questionAnswersArray = this.questionsData.map((glass) => { return { glassLocation: glass.glassLocation, glassName: glass.glassName, @@ -141,7 +139,7 @@ export default { }); // clear out answerData for future page loads; must occur prior to store save - this.moldingQuestionsData.forEach((glass) => { + this.questionsData.forEach((glass) => { glass.answerData = {}; }); @@ -162,262 +160,6 @@ export default { this.navigateForward(partsOrQuestions); }, - handleAnswerUpdates(answer) { - // only runs when all questions in a question-chain have been answered - // when selectedAnswers updates, user has completed this part's question chain and has a final answer - // (does not get run for each invididual question's answer, only when - // all relevant questions for the current part have been answered) - - /* - answer example format: - { - "answerResult": "DD11132", - "answeredQuestions": [ - { - "questionText": "Is your Grand Cherokee the Laredo model?", - "selectedAnswerText": "Yes", - "questionNum": 1, - } - ], - "glassIndex": 0 - } - */ - - // collect a list of the answered questions' numbers, needed later below - const answeredQuestionIndexes = []; - const foundDuplicateQuestions = []; - - // if user has answered a question differently than anything that was preloaded, - // we need to clear out any preloaded answers - this.selectedAnswers = {}; - - // loop through every answered question on the currently answered glass part - answer.answeredQuestions?.forEach((aq) => { - - // keep track of this question number - answeredQuestionIndexes.push(aq.questionNum); - - const answeredQuestionText = aq.questionText.toUpperCase(); - const answeredQuestionAnswer = aq.selectedAnswerText.toUpperCase(); - - // HANDLE DUPLICATE QUESTIONS - - // loop through all glass parts data - this.moldingQuestionsData.forEach((glass, gpIndex) => { - - // only look for duplicates forward... to parts that follow after the currently being answered part - if (gpIndex > answer.glassIndex) { - - let suppressUntil; - // reset this glass part, in case user is changing their previous answers - glass.answerData = null; - glass.isSuppressedPart = null; - - // loop through this glass part's part questions, looking for a questionText match - glass.questions.forEach((pq, pqIndex) => { - - // clear out any previously set answers - pq.answerSelected = null; - - // clear or set suppressQuestion property for each question - if (suppressUntil) { - // if suppressUntil has been set, then suppress this question if before it - if (pqIndex + 1 < suppressUntil) { - pq.suppressQuestion = true; - } else { - pq.suppressQuestion = null; - } - } else { - pq.suppressQuestion = null; - } - - // if these match then we have a duplicate question - if (pq.questionText.toUpperCase() === answeredQuestionText) { - - const thisAnsweredPartQuestion = glass.questions[pqIndex]; - let matchedAnswer; - let rejectedAnswers = []; // set as an array, in case we ever have questions with more than 2 answers... - - // which one of this questions' answers matches our answer? - pq.answers.forEach((ans) => { - if (ans.answerText.toUpperCase() === answeredQuestionAnswer) { - matchedAnswer = ans; - ans.selected = true; - } else { - rejectedAnswers.push(ans); - ans.selected = null; - } - }); - - // Update the key to re-render this part's question-chain component - this.moldingQuestionsData[gpIndex].key = this.moldingQuestionsData[gpIndex].glassLocation + this.moldingQuestionsData[gpIndex].glassName + Date.now().toString(); - - // handle suppressing downstream in this question chain - - if (matchedAnswer.nextQuestionSequence) { - // ensure that the question that the accepted answer has set to be next is NOT suppressed - glass.questions[matchedAnswer.nextQuestionSequence - 1].suppressQuestion = null; - // if the duplicate is the 1ST question, then set suppressUntil var to lowest nextQuestion number - if (pqIndex === 0) { - if (!suppressUntil) { suppressUntil = matchedAnswer.nextQuestionSequence } - if (matchedAnswer.nextQuestionSequence < suppressUntil) { suppressUntil = matchedAnswer.nextQuestionSequence} - } - } - - // handle suppressing upstream in this question chain - glass.questions.forEach((q) => { - q.answers.forEach((thisAns) => { - // restore any of the answers that formerly led to the duplicated question - if (thisAns.originalNextQuestionSequence === pq.questionSequence) { - // restore original nextQuestionSequence - thisAns.nextQuestionSequence = thisAns.originalNextQuestionSequence; - this.originalNextQuestionSequence = null; - // restore original answerResult - if (thisAns.originalAnswerResult) { - thisAns.answerResult = thisAns.originalAnswerResult; - thisAns.originalAnswerResult = null; - } - } - // search for any answers that lead to the duplicated question - if (thisAns.nextQuestionSequence === pq.questionSequence) { - // update either the nextQuestionSequence or the answerResult - if (matchedAnswer.nextQuestionSequence) { - thisAns.originalNextQuestionSequence = thisAns.nextQuestionSequence; - thisAns.nextQuestionSequence = matchedAnswer.nextQuestionSequence; - } else { - thisAns.originalNextQuestionSequence = thisAns.nextQuestionSequence; - thisAns.nextQuestionSequence = null; - thisAns.originalAnswerResult = thisAns.originalAnswerResult || thisAns.answerResult; - thisAns.answerResult = matchedAnswer.answerResult; - } - } - }); - }); - - // suppress current question - thisAnsweredPartQuestion.suppressQuestion = true; - - const thisGlassPart = "glass" + gpIndex; - if (foundDuplicateQuestions[thisGlassPart]) { - if (!foundDuplicateQuestions[thisGlassPart].includes(thisAnsweredPartQuestion.questionSequence)) { - foundDuplicateQuestions[thisGlassPart].push(thisAnsweredPartQuestion.questionSequence); - } - } else { - foundDuplicateQuestions[thisGlassPart] = [thisAnsweredPartQuestion.questionSequence]; - } - - // are there any questions left that are not suppressed? - const remainingQuestions = glass.questions.filter((q) => { - return !q.suppressQuestion; - }); - - if (remainingQuestions.length < 1) { - // this is the final answer for this glass part - - // mark this part as completely answered by adding answerData - const answeredQuestionObj = { - questionText: pq.questionText, - selectedAnswerText: matchedAnswer.answerText, - questionNum: pq.questionSequence, - suppressQuestion: pq.suppressQuestion, - }; - // set the answerData as 'already answered' - glass.answerData = { - answerResult: matchedAnswer.nextQuestionSequence ? matchedAnswer.nextQuestionSequence : matchedAnswer.answerResult, - answeredQuestions: [answeredQuestionObj], - }; - - // suppress this glass because it has an answer - glass.isSuppressedPart = true; - } - - } - - }); - - // Update the key to re-render this part's question-chain component - this.moldingQuestionsData[gpIndex].key = this.moldingQuestionsData[gpIndex].glassLocation + this.moldingQuestionsData[gpIndex].glassName + Date.now().toString(); - - } - - }); - - }); - - // DETERMINE ANSWERED QUESTIONS LIST FOR THIS GLASS PART - - // look through all (this part's) part questions for any duplicates that were suppressed; - // add them to the list of answered questions if found - - // EX answeredQuestionIndexes: [1,5,11,13] - - // EX foundDuplicateQuestions = { - // "glassPart1": [1], - // "glassPart2": [7, 10] - // }; - - const thisPartsDupes = foundDuplicateQuestions["glass" + answer.glassIndex]; - const completeAnsweredQuestions = answer.answeredQuestions ? [...answer.answeredQuestions] : []; - const glassPartAnswered = this.moldingQuestionsData[answer.glassIndex]; - - thisPartsDupes?.forEach((dupe) => { - // dupe is a single integer - const dupeQuestion = glassPartAnswered.questions[dupe - 1]; - const dupeQuestionAnswer = dupeQuestion.answers.find((q) => q.selected === true); - - glassPartAnswered.questions.forEach((q) => { - let includeThisDupeInAnsweredQuestions = false; - - // did one of the answers of this question point to the duplicated question? - q.answers.forEach((a) => { - if ((dupe === a.originalNextQuestionSequence) && - (answeredQuestionIndexes.includes(q.questionSequence)) && - (a.answerText.toUpperCase() === dupeQuestionAnswer.answerText.toUpperCase())) { - includeThisDupeInAnsweredQuestions = true; - } - }); - - // is this q.questionSequence listed as the duplicated question's nextQuestionSequence? - if ((q.questionSequence === dupeQuestionAnswer.nextQuestionSequence) && (answeredQuestionIndexes.includes(q.questionSequence))) { - includeThisDupeInAnsweredQuestions = true; - } - - if (includeThisDupeInAnsweredQuestions) { - completeAnsweredQuestions.push({ - questionNum: dupeQuestion.questionSequence, - questionText: dupeQuestion.questionText, - selectedAnswerText: dupeQuestionAnswer.answerText, - suppressQuestion: dupeQuestion.suppressQuestion, - }); - } - }); - }); - - // make sure there are no duplicated dupes in the list... - const foundInCompleteAnsweredQuestions = new Set(); - let filteredCompleteAnsweredQuestions = completeAnsweredQuestions.filter(el => { - const duplicate = foundInCompleteAnsweredQuestions.has(el.questionText); - foundInCompleteAnsweredQuestions.add(el.questionText); - return !duplicate; - }); - filteredCompleteAnsweredQuestions = filteredCompleteAnsweredQuestions.sort((a,b) => a.questionNum - b.questionNum); - - // set final answer data for the current answered glass part - glassPartAnswered.answerData = { - answerResult: answer.answerResult, - answeredQuestions: filteredCompleteAnsweredQuestions, - } - - // this part has been fully answered, so advance to next molding question chain - for (let i = answer.glassIndex + 1; i < this.moldingQuestionsData.length; i++) { - // if this part has not yet been fully answered, then make it the current part - if (!this.moldingQuestionsData[i].answerData?.answerResult) { - this.currentGlassIndex = i; - break; - } - } - - }, }, components: { funnelHeader, diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue index 131a70f44..d5e79540b 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" /> -
+
x.partQuestions).map((glass, i) => { + this.questionsData = this.pageData.partsOrQuestions.filter(x => x.partQuestions).map((glass, i) => { // NOTE: questions for property "questions" can differ between layouts glass.questions = glass.partQuestions; // reset selectedAnswers for this glass @@ -130,7 +128,7 @@ export default { return this.currentGlassIndex === i || glass.answerData?.answerResult?.length > 0; }, async forwardButtonAction() { - const questionAnswersArray = this.partsQuestionsData.map((glass) => { + const questionAnswersArray = this.questionsData.map((glass) => { return { glassLocation: glass.glassLocation, glassName: glass.glassName, @@ -141,7 +139,7 @@ export default { }); // clear out answerData for future page loads; must occur prior to store save - this.partsQuestionsData.forEach((glass) => { + this.questionsData.forEach((glass) => { glass.answerData = {}; }); @@ -149,7 +147,7 @@ export default { await this.dispatchStoreAction(this.storeActions.SAVE_PART_QUESTION_ANSWERS, questionAnswersArray, false); // call API parts method - const partsLookup = await this.dispatchStoreAction(storeActions.GET_PARTS) + const partsLookup = await this.dispatchStoreAction(this.storeActions.GET_PARTS) .catch(() => { return this.$refs.funnelFooter.removeLoader(); }); @@ -158,262 +156,6 @@ export default { this.navigateForward(glassNameAndPartsForStore); }, - handleAnswerUpdates(answer) { - // only runs when all questions in a question-chain have been answered - // when selectedAnswers updates, user has completed this part's question chain and has a final answer - // (does not get run for each invididual question's answer, only when - // all relevant questions for the current part have been answered) - - /* - answer example format: - { - "answerResult": "DD11132", - "answeredQuestions": [ - { - "questionText": "Is your Grand Cherokee the Laredo model?", - "selectedAnswerText": "Yes", - "questionNum": 1, - } - ], - "glassIndex": 0 - } - */ - - // collect a list of the answered questions' numbers, needed later below - const answeredQuestionIndexes = []; - const foundDuplicateQuestions = []; - - // if user has answered a question differently than anything that was preloaded, - // we need to clear out any preloaded answers - this.selectedAnswers = {}; - - // loop through every answered question on the currently answered glass part - answer.answeredQuestions?.forEach((aq) => { - - // keep track of this question number - answeredQuestionIndexes.push(aq.questionNum); - - const answeredQuestionText = aq.questionText.toUpperCase(); - const answeredQuestionAnswer = aq.selectedAnswerText.toUpperCase(); - - // HANDLE DUPLICATE QUESTIONS - - // loop through all glass parts data - this.partsQuestionsData.forEach((glass, gpIndex) => { - - // only look for duplicates forward... to parts that follow after the currently being answered part - if (gpIndex > answer.glassIndex) { - - let suppressUntil; - // reset this glass part, in case user is changing their previous answers - glass.answerData = null; - glass.isSuppressedPart = null; - - // loop through this glass part's questions, looking for a questionText match - glass.questions.forEach((pq, pqIndex) => { - - // clear out any previously set answers - pq.answerSelected = null; - - // clear or set suppressQuestion property for each question - if (suppressUntil) { - // if suppressUntil has been set, then suppress this question if before it - if (pqIndex + 1 < suppressUntil) { - pq.suppressQuestion = true; - } else { - pq.suppressQuestion = null; - } - } else { - pq.suppressQuestion = null; - } - - // if these match then we have a duplicate question - if (pq.questionText.toUpperCase() === answeredQuestionText) { - - const thisAnsweredQuestion = glass.questions[pqIndex]; - let matchedAnswer; - let rejectedAnswers = []; // set as an array, in case we ever have questions with more than 2 answers... - - // which one of this questions' answers matches our answer? - pq.answers.forEach((ans) => { - if (ans.answerText.toUpperCase() === answeredQuestionAnswer) { - matchedAnswer = ans; - ans.selected = true; - } else { - rejectedAnswers.push(ans); - ans.selected = null; - } - }); - - // Update the key to re-render this part's question-chain component - this.partsQuestionsData[gpIndex].key = this.partsQuestionsData[gpIndex].glassLocation + this.partsQuestionsData[gpIndex].glassName + Date.now().toString(); - - // handle suppressing downstream in this question chain - - if (matchedAnswer.nextQuestionSequence) { - // ensure that the question that the accepted answer has set to be next is NOT suppressed - glass.questions[matchedAnswer.nextQuestionSequence - 1].suppressQuestion = null; - // if the duplicate is the 1ST question, then set suppressUntil var to lowest nextQuestion number - if (pqIndex === 0) { - if (!suppressUntil) { suppressUntil = matchedAnswer.nextQuestionSequence } - if (matchedAnswer.nextQuestionSequence < suppressUntil) { suppressUntil = matchedAnswer.nextQuestionSequence} - } - } - - // handle suppressing upstream in this question chain - glass.questions.forEach((q) => { - q.answers.forEach((thisAns) => { - // restore any of the answers that formerly led to the duplicated question - if (thisAns.originalNextQuestionSequence === pq.questionSequence) { - // restore original nextQuestionSequence - thisAns.nextQuestionSequence = thisAns.originalNextQuestionSequence; - this.originalNextQuestionSequence = null; - // restore original answerResult - if (thisAns.originalAnswerResult) { - thisAns.answerResult = thisAns.originalAnswerResult; - thisAns.originalAnswerResult = null; - } - } - // search for any answers that lead to the duplicated question - if (thisAns.nextQuestionSequence === pq.questionSequence) { - // update either the nextQuestionSequence or the answerResult - if (matchedAnswer.nextQuestionSequence) { - thisAns.originalNextQuestionSequence = thisAns.nextQuestionSequence; - thisAns.nextQuestionSequence = matchedAnswer.nextQuestionSequence; - } else { - thisAns.originalNextQuestionSequence = thisAns.nextQuestionSequence; - thisAns.nextQuestionSequence = null; - thisAns.originalAnswerResult = thisAns.originalAnswerResult || thisAns.answerResult; - thisAns.answerResult = matchedAnswer.answerResult; - } - } - }); - }); - - // suppress current question - thisAnsweredQuestion.suppressQuestion = true; - - const thisGlassPart = "glass" + gpIndex; - if (foundDuplicateQuestions[thisGlassPart]) { - if (!foundDuplicateQuestions[thisGlassPart].includes(thisAnsweredQuestion.questionSequence)) { - foundDuplicateQuestions[thisGlassPart].push(thisAnsweredQuestion.questionSequence); - } - } else { - foundDuplicateQuestions[thisGlassPart] = [thisAnsweredQuestion.questionSequence]; - } - - // are there any questions left that are not suppressed? - const remainingQuestions = glass.questions.filter((q) => { - return !q.suppressQuestion; - }); - - if (remainingQuestions.length < 1) { - // this is the final answer for this glass part - - // mark this part as completely answered by adding answerData - const answeredQuestionObj = { - questionText: pq.questionText, - selectedAnswerText: matchedAnswer.answerText, - questionNum: pq.questionSequence, - suppressQuestion: pq.suppressQuestion, - }; - // set the answerData as 'already answered' - glass.answerData = { - answerResult: matchedAnswer.nextQuestionSequence ? matchedAnswer.nextQuestionSequence : matchedAnswer.answerResult, - answeredQuestions: [answeredQuestionObj], - }; - - // suppress this glass because it has an answer - glass.isSuppressedPart = true; - } - - } - - }); - - // Update the key to re-render this part's question-chain component - this.partsQuestionsData[gpIndex].key = this.partsQuestionsData[gpIndex].glassLocation + this.partsQuestionsData[gpIndex].glassName + Date.now().toString(); - - } - - }); - - }); - - // DETERMINE ANSWERED QUESTIONS LIST FOR THIS GLASS PART - - // look through all (this part's) part questions for any duplicates that were suppressed; - // add them to the list of answered questions if found - - // EX answeredQuestionIndexes: [1,5,11,13] - - // EX foundDuplicateQuestions = { - // "glassPart1": [1], - // "glassPart2": [7, 10] - // }; - - const thisPartsDupes = foundDuplicateQuestions["glass" + answer.glassIndex]; - const completeAnsweredQuestions = answer.answeredQuestions ? [...answer.answeredQuestions] : []; - const glassPartAnswered = this.partsQuestionsData[answer.glassIndex]; - - thisPartsDupes?.forEach((dupe) => { - // dupe is a single integer - const dupeQuestion = glassPartAnswered.questions[dupe - 1]; - const dupeQuestionAnswer = dupeQuestion.answers.find((q) => q.selected === true); - - glassPartAnswered.questions.forEach((q) => { - let includeThisDupeInAnsweredQuestions = false; - - // did one of the answers of this question point to the duplicated question? - q.answers.forEach((a) => { - if ((dupe === a.originalNextQuestionSequence) && - (answeredQuestionIndexes.includes(q.questionSequence)) && - (a.answerText.toUpperCase() === dupeQuestionAnswer.answerText.toUpperCase())) { - includeThisDupeInAnsweredQuestions = true; - } - }); - - // is this q.questionSequence listed as the duplicated question's nextQuestionSequence? - if ((q.questionSequence === dupeQuestionAnswer.nextQuestionSequence) && (answeredQuestionIndexes.includes(q.questionSequence))) { - includeThisDupeInAnsweredQuestions = true; - } - - if (includeThisDupeInAnsweredQuestions) { - completeAnsweredQuestions.push({ - questionNum: dupeQuestion.questionSequence, - questionText: dupeQuestion.questionText, - selectedAnswerText: dupeQuestionAnswer.answerText, - suppressQuestion: dupeQuestion.suppressQuestion, - }); - } - }); - }); - - // make sure there are no duplicated dupes in the list... - const foundInCompleteAnsweredQuestions = new Set(); - let filteredCompleteAnsweredQuestions = completeAnsweredQuestions.filter(el => { - const duplicate = foundInCompleteAnsweredQuestions.has(el.questionText); - foundInCompleteAnsweredQuestions.add(el.questionText); - return !duplicate; - }); - filteredCompleteAnsweredQuestions = filteredCompleteAnsweredQuestions.sort((a,b) => a.questionNum - b.questionNum); - - // set final answer data for the current answered glass part - glassPartAnswered.answerData = { - answerResult: answer.answerResult, - answeredQuestions: filteredCompleteAnsweredQuestions, - } - - // this part has been fully answered, so advance to next part's question chain - for (let i = answer.glassIndex + 1; i < this.partsQuestionsData.length; i++) { - // if this part has not yet been fully answered, then make it the current part - if (!this.partsQuestionsData[i].answerData?.answerResult) { - this.currentGlassIndex = i; - break; - } - } - - }, }, components: { funnelHeader, diff --git a/src/mixins/vehicle-questions-mixin.js b/src/mixins/vehicle-questions-mixin.js index 415fa1e6d..a34107970 100644 --- a/src/mixins/vehicle-questions-mixin.js +++ b/src/mixins/vehicle-questions-mixin.js @@ -126,6 +126,263 @@ export default { return glass; }, + handleAnswerUpdates(answer, vm) { + // only runs when all questions in a question-chain have been answered + // when selectedAnswers updates, user has completed this part's question chain and has a final answer + // (does not get run for each invididual question's answer, only when + // all relevant questions for the current part have been answered) + + /* answer example format: + { + "answerResult": "DD11132", + "answeredQuestions": [ + { + "questionText": "Is your Grand Cherokee the Laredo model?", + "selectedAnswerText": "Yes", + "questionNum": 1, + } + ], + "glassIndex": 0 + } + */ + + const self = vm ?? this; + + // collect a list of the answered questions' numbers, needed later below + const answeredQuestionIndexes = []; + const foundDuplicateQuestions = []; + + // if user has answered a question differently than anything that was preloaded, + // we need to clear out any preloaded answers + self.selectedAnswers = {}; + + // loop through every answered question on the currently answered glass part + answer.answeredQuestions?.forEach((aq) => { + + // keep track of this question number + answeredQuestionIndexes.push(aq.questionNum); + + const answeredQuestionText = aq.questionText.toUpperCase(); + const answeredQuestionAnswer = aq.selectedAnswerText.toUpperCase(); + + // HANDLE DUPLICATE QUESTIONS + + // loop through all glass parts data + self.questionsData.forEach((glass, gpIndex) => { + + // only look for duplicates forward... to parts that follow after the currently being answered part + if (gpIndex > answer.glassIndex) { + + let suppressUntil; + // reset this glass part, in case user is changing their previous answers + glass.answerData = null; + glass.isSuppressedPart = null; + + // loop through this glass part's questions, looking for a questionText match + glass.questions.forEach((pq, pqIndex) => { + + // clear out any previously set answers + pq.answerSelected = null; + + // clear or set suppressQuestion property for each question + if (suppressUntil) { + // if suppressUntil has been set, then suppress this question if before it + if (pqIndex + 1 < suppressUntil) { + pq.suppressQuestion = true; + } else { + pq.suppressQuestion = null; + } + } else { + pq.suppressQuestion = null; + } + + // if these match then we have a duplicate question + if (pq.questionText.toUpperCase() === answeredQuestionText) { + + const thisAnsweredQuestion = glass.questions[pqIndex]; + let matchedAnswer; + let rejectedAnswers = []; // set as an array, in case we ever have questions with more than 2 answers... + + // which one of this questions' answers matches our answer? + pq.answers.forEach((ans) => { + if (ans.answerText.toUpperCase() === answeredQuestionAnswer) { + matchedAnswer = ans; + ans.selected = true; + } else { + rejectedAnswers.push(ans); + ans.selected = null; + } + }); + + // Update the key to re-render this part's question-chain component + self.questionsData[gpIndex].key = self.questionsData[gpIndex].glassLocation + self.questionsData[gpIndex].glassName + Date.now().toString(); + + // handle suppressing downstream in this question chain + + if (matchedAnswer.nextQuestionSequence) { + // ensure that the question that the accepted answer has set to be next is NOT suppressed + glass.questions[matchedAnswer.nextQuestionSequence - 1].suppressQuestion = null; + // if the duplicate is the 1ST question, then set suppressUntil var to lowest nextQuestion number + if (pqIndex === 0) { + if (!suppressUntil) { suppressUntil = matchedAnswer.nextQuestionSequence } + if (matchedAnswer.nextQuestionSequence < suppressUntil) { suppressUntil = matchedAnswer.nextQuestionSequence} + } + } + + // handle suppressing upstream in this question chain + glass.questions.forEach((q) => { + q.answers.forEach((thisAns) => { + // restore any of the answers that formerly led to the duplicated question + if (thisAns.originalNextQuestionSequence === pq.questionSequence) { + // restore original nextQuestionSequence + thisAns.nextQuestionSequence = thisAns.originalNextQuestionSequence; + self.originalNextQuestionSequence = null; + // restore original answerResult + if (thisAns.originalAnswerResult) { + thisAns.answerResult = thisAns.originalAnswerResult; + thisAns.originalAnswerResult = null; + } + } + // search for any answers that lead to the duplicated question + if (thisAns.nextQuestionSequence === pq.questionSequence) { + // update either the nextQuestionSequence or the answerResult + if (matchedAnswer.nextQuestionSequence) { + thisAns.originalNextQuestionSequence = thisAns.nextQuestionSequence; + thisAns.nextQuestionSequence = matchedAnswer.nextQuestionSequence; + } else { + thisAns.originalNextQuestionSequence = thisAns.nextQuestionSequence; + thisAns.nextQuestionSequence = null; + thisAns.originalAnswerResult = thisAns.originalAnswerResult || thisAns.answerResult; + thisAns.answerResult = matchedAnswer.answerResult; + } + } + }); + }); + + // suppress current question + thisAnsweredQuestion.suppressQuestion = true; + + const thisGlassPart = "glass" + gpIndex; + if (foundDuplicateQuestions[thisGlassPart]) { + if (!foundDuplicateQuestions[thisGlassPart].includes(thisAnsweredQuestion.questionSequence)) { + foundDuplicateQuestions[thisGlassPart].push(thisAnsweredQuestion.questionSequence); + } + } else { + foundDuplicateQuestions[thisGlassPart] = [thisAnsweredQuestion.questionSequence]; + } + + // are there any questions left that are not suppressed? + const remainingQuestions = glass.questions.filter((q) => { + return !q.suppressQuestion; + }); + + if (remainingQuestions.length < 1) { + // this is the final answer for this glass part + + // mark this part as completely answered by adding answerData + const answeredQuestionObj = { + questionText: pq.questionText, + selectedAnswerText: matchedAnswer.answerText, + questionNum: pq.questionSequence, + suppressQuestion: pq.suppressQuestion, + }; + // set the answerData as 'already answered' + glass.answerData = { + answerResult: matchedAnswer.nextQuestionSequence ? matchedAnswer.nextQuestionSequence : matchedAnswer.answerResult, + answeredQuestions: [answeredQuestionObj], + }; + + // suppress this glass because it has an answer + glass.isSuppressedPart = true; + } + + } + + }); + + // Update the key to re-render this part's question-chain component + self.questionsData[gpIndex].key = self.questionsData[gpIndex].glassLocation + self.questionsData[gpIndex].glassName + Date.now().toString(); + + } + + }); + + }); + + // DETERMINE ANSWERED QUESTIONS LIST FOR THIS GLASS PART + + // look through all (this part's) part questions for any duplicates that were suppressed; + // add them to the list of answered questions if found + + // EX answeredQuestionIndexes: [1,5,11,13] + + // EX foundDuplicateQuestions = { + // "glassPart1": [1], + // "glassPart2": [7, 10] + // }; + + const thisPartsDupes = foundDuplicateQuestions["glass" + answer.glassIndex]; + const completeAnsweredQuestions = answer.answeredQuestions ? [...answer.answeredQuestions] : []; + const glassPartAnswered = self.questionsData[answer.glassIndex]; + + thisPartsDupes?.forEach((dupe) => { + // dupe is a single integer + const dupeQuestion = glassPartAnswered.questions[dupe - 1]; + const dupeQuestionAnswer = dupeQuestion.answers.find((q) => q.selected === true); + + glassPartAnswered.questions.forEach((q) => { + let includeThisDupeInAnsweredQuestions = false; + + // did one of the answers of this question point to the duplicated question? + q.answers.forEach((a) => { + if ((dupe === a.originalNextQuestionSequence) && + (answeredQuestionIndexes.includes(q.questionSequence)) && + (a.answerText.toUpperCase() === dupeQuestionAnswer.answerText.toUpperCase())) { + includeThisDupeInAnsweredQuestions = true; + } + }); + + // is this q.questionSequence listed as the duplicated question's nextQuestionSequence? + if ((q.questionSequence === dupeQuestionAnswer.nextQuestionSequence) && (answeredQuestionIndexes.includes(q.questionSequence))) { + includeThisDupeInAnsweredQuestions = true; + } + + if (includeThisDupeInAnsweredQuestions) { + completeAnsweredQuestions.push({ + questionNum: dupeQuestion.questionSequence, + questionText: dupeQuestion.questionText, + selectedAnswerText: dupeQuestionAnswer.answerText, + suppressQuestion: dupeQuestion.suppressQuestion, + }); + } + }); + }); + + // make sure there are no duplicated dupes in the list... + const foundInCompleteAnsweredQuestions = new Set(); + let filteredCompleteAnsweredQuestions = completeAnsweredQuestions.filter(el => { + const duplicate = foundInCompleteAnsweredQuestions.has(el.questionText); + foundInCompleteAnsweredQuestions.add(el.questionText); + return !duplicate; + }); + filteredCompleteAnsweredQuestions = filteredCompleteAnsweredQuestions.sort((a,b) => a.questionNum - b.questionNum); + + // set final answer data for the current answered glass part + glassPartAnswered.answerData = { + answerResult: answer.answerResult, + answeredQuestions: filteredCompleteAnsweredQuestions, + } + + // this part has been fully answered, so advance to next part's question chain + for (let i = answer.glassIndex + 1; i < self.questionsData.length; i++) { + // if this part has not yet been fully answered, then make it the current part + if (!self.questionsData[i].answerData?.answerResult) { + self.currentGlassIndex = i; + break; + } + } + + }, // Can't use `this` because navigateForward is also called from vin-pages-mixin async navigateForward(partsOrQuestions, vm) { const self = vm ?? this; From fbbbf377beefb03ed69ae08c22bf2560c415f779 Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Mon, 10 Oct 2022 13:24:56 -0400 Subject: [PATCH 03/11] CSR-803 standardize naming across questions pages --- .../capability-questions/capability-questions.vue | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/layouts/capability-questions/capability-questions.vue b/src/layouts/capability-questions/capability-questions.vue index f9a15a6e8..cb0d0d656 100644 --- a/src/layouts/capability-questions/capability-questions.vue +++ b/src/layouts/capability-questions/capability-questions.vue @@ -12,7 +12,7 @@
@@ -106,11 +106,11 @@ export default { return capabilityQuestionsPageData && Object.keys(capabilityQuestionsPageData).length > 0; }, showThisQuestionChain(glass, i) { - if (!glass.capabilityQuestions || glass.capabilityQuestions?.length < 1 || glass.isSuppressedPart) { return false; } // return false if no capabilityQuestions or if suppressed + if (!glass.questions || glass.questions?.length < 1 || glass.isSuppressedPart) { return false; } // return false if no capabilityQuestions or if suppressed return this.currentQuestionChainIndex === i || glass.answerData?.answerResult?.length > 0; }, async forwardButtonAction() { - const capabilityQuestionsAnswersArray = this.questionsData.map((glass) => { + const questionAnswersArray = this.questionsData.map((glass) => { const selectedAnswerResult2 = this.getCorrespondingAnswerResult2(glass.answerData.answerResult); return { @@ -130,11 +130,11 @@ export default { }); // save to vuex store as order.damage.capabilityQuestionAnswers (array) - await this.dispatchStoreAction(this.storeActions.SAVE_CAPABILITY_QUESTION_ANSWERS, capabilityQuestionsAnswersArray, false); + await this.dispatchStoreAction(this.storeActions.SAVE_CAPABILITY_QUESTION_ANSWERS, questionAnswersArray, false); // get parts from the capabilityQuestionAnswers let partsOrQuestions = this.pageData.partsOrQuestions; - for (let answer of capabilityQuestionsAnswersArray) { + for (let answer of questionAnswersArray) { const correspondingPart = partsOrQuestions.find(partOrQuestion => partOrQuestion.glassLocation === answer.glassLocation); const partFromCapabilityQuestionAnswer = (await this.dispatchStoreAction(this.storeActions.GET_PART_FROM_CAPABILITY_QUESTION_ANSWER, answer.glassLocation, false)).data; From 4324f0ee5fba57eb084172290125ba1ed9b5420e Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Mon, 31 Oct 2022 14:25:13 -0400 Subject: [PATCH 04/11] CSR-803: merge --- src/global-methods.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/global-methods.js b/src/global-methods.js index 14e5cca0e..30eeffb65 100644 --- a/src/global-methods.js +++ b/src/global-methods.js @@ -7,6 +7,7 @@ import { GaCategories, GaActions, GaLabels } from "@/constants/analytics"; import { headerKeys } from "@/constants/header-keys"; export default { +<<<<<<< Updated upstream callHttpClient({ method, endpoint, payload, logApiCall = true }) { return new Promise((resolve, reject) => { const cfDistroUrl = applicationConfig.CONSUMER_CF_DISTRO; @@ -14,6 +15,21 @@ export default { const headers = { [headerKeys.EXPERIMENT]: JSON.stringify(store.getters.experimentSettings), }; +======= + callHttpClient({ method, endpoint, payload, logApiCall = true }) { + return new Promise((resolve, reject) => { + let cfDistroUrl = applicationConfig.CONSUMER_CF_DISTRO; + if (endpoint.includes("/order/")) { + cfDistroUrl = "https://localhost:5001"; + } + if (endpoint.includes("/parts/")) { + cfDistroUrl = "https://localhost:5003"; + } + const payloadAndAnalyticsData = Object.assign({}, payload, { AppName: "FixMyGlass" }); + const headers = { + [headerKeys.EXPERIMENT]: JSON.stringify(store.getters.experimentSettings) + } +>>>>>>> Stashed changes axios({ method: method, From a1c20e41a275245e3037ec615f72d58055ebfced Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Sat, 5 Nov 2022 16:13:50 -0400 Subject: [PATCH 05/11] CSR-803: bulk of refactoring --- .../question-chain/question-chain.vue | 8 +- .../questions-page/questions-page.vue | 106 +++ src/global-methods.js | 16 - .../capability-questions.vue | 141 ++- .../molding-questions/molding-questions.vue | 108 +-- src/layouts/part-questions/part-questions.vue | 106 +-- src/mixins/vehicle-questions-mixin.js | 311 +++---- src/mixins/vehicle-questions-mixin.spec.js | 821 +++++++++++++++++- 8 files changed, 1165 insertions(+), 452 deletions(-) create mode 100644 src/common-components/questions-page/questions-page.vue diff --git a/src/common-components/question-chain/question-chain.vue b/src/common-components/question-chain/question-chain.vue index 6121cbd25..7c9767d47 100644 --- a/src/common-components/question-chain/question-chain.vue +++ b/src/common-components/question-chain/question-chain.vue @@ -31,8 +31,9 @@ export default { props: { questionData: Object, validationRules: String, - modelValue: Array, + modelValue: Object, glassIndex: Number, + answerKey: String, }, async created() { // do a test validation check upon create to prevent out of sync / incorrect valid states @@ -65,7 +66,7 @@ export default { }), answerSelected: q.answerSelected || "", }; - if (!q.suppressQuestion) { + if (!q.suppressThisQuestion) { this.questions.push(question); } }); @@ -81,7 +82,6 @@ export default { }, methods: { handleAnswer(question, returnedAnswer) { - question.answerSelected = returnedAnswer; /* returnedAnswer example format: { @@ -90,6 +90,8 @@ export default { "buttonId": "Driver-Front-1-1|answer|DD11132|Yes" } */ + + question.answerSelected = returnedAnswer; const isQuestionChainComplete = this.getQuestionChainAnswerIfComplete(returnedAnswer); if (isQuestionChainComplete) { diff --git a/src/common-components/questions-page/questions-page.vue b/src/common-components/questions-page/questions-page.vue new file mode 100644 index 000000000..3d04f804d --- /dev/null +++ b/src/common-components/questions-page/questions-page.vue @@ -0,0 +1,106 @@ + + + + + diff --git a/src/global-methods.js b/src/global-methods.js index 30eeffb65..14e5cca0e 100644 --- a/src/global-methods.js +++ b/src/global-methods.js @@ -7,7 +7,6 @@ import { GaCategories, GaActions, GaLabels } from "@/constants/analytics"; import { headerKeys } from "@/constants/header-keys"; export default { -<<<<<<< Updated upstream callHttpClient({ method, endpoint, payload, logApiCall = true }) { return new Promise((resolve, reject) => { const cfDistroUrl = applicationConfig.CONSUMER_CF_DISTRO; @@ -15,21 +14,6 @@ export default { const headers = { [headerKeys.EXPERIMENT]: JSON.stringify(store.getters.experimentSettings), }; -======= - callHttpClient({ method, endpoint, payload, logApiCall = true }) { - return new Promise((resolve, reject) => { - let cfDistroUrl = applicationConfig.CONSUMER_CF_DISTRO; - if (endpoint.includes("/order/")) { - cfDistroUrl = "https://localhost:5001"; - } - if (endpoint.includes("/parts/")) { - cfDistroUrl = "https://localhost:5003"; - } - const payloadAndAnalyticsData = Object.assign({}, payload, { AppName: "FixMyGlass" }); - const headers = { - [headerKeys.EXPERIMENT]: JSON.stringify(store.getters.experimentSettings) - } ->>>>>>> Stashed changes axios({ method: method, diff --git a/src/layouts/capability-questions/capability-questions.vue b/src/layouts/capability-questions/capability-questions.vue index c46aa353a..0f7a0e57e 100644 --- a/src/layouts/capability-questions/capability-questions.vue +++ b/src/layouts/capability-questions/capability-questions.vue @@ -1,47 +1,28 @@ - - diff --git a/src/layouts/molding-questions/molding-questions.vue b/src/layouts/molding-questions/molding-questions.vue index 336ee1096..9f0362b44 100644 --- a/src/layouts/molding-questions/molding-questions.vue +++ b/src/layouts/molding-questions/molding-questions.vue @@ -1,51 +1,28 @@ - - diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue index 7b389158d..02200585f 100644 --- a/src/layouts/part-questions/part-questions.vue +++ b/src/layouts/part-questions/part-questions.vue @@ -1,51 +1,28 @@ - diff --git a/src/mixins/vehicle-questions-mixin.js b/src/mixins/vehicle-questions-mixin.js index 627874abd..a362ec2c6 100644 --- a/src/mixins/vehicle-questions-mixin.js +++ b/src/mixins/vehicle-questions-mixin.js @@ -1,6 +1,5 @@ import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; import { storeMutations } from "@/constants/store-mutations.js"; -import { damageLocationsSelected } from "@/constants/damage-locations-selected"; import { navigationScenarios } from "../router/router-constants/navigation-scenarios"; import { storeActions } from "@/constants/store-actions"; import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper"; @@ -68,8 +67,8 @@ export default { return this.comparePageIndices(currentPage, fmgPage) > 0; }, setupInitialData(glass, i, alreadyAnsweredQuestions, vm) { - glass.key = glass.glassLocation + "-" + glass.glassName; const self = vm ?? this; + // clear answerData if no questions are already answered if (!alreadyAnsweredQuestions) { glass.answerData = null; @@ -82,9 +81,7 @@ export default { !answeredGlass.glassName || !answeredGlass.answeredQuestions || (!answeredGlass.result && !answeredGlass.partNum) - ) { - return; - } + ) { return } // test if glass parts match if ( @@ -94,33 +91,33 @@ export default { let answerString = ""; // loop through answeredQuestions for matches - answeredGlass.answeredQuestions.forEach((aq) => { - if (!aq.questionNum || !aq.selectedAnswerText) { + answeredGlass.answeredQuestions.forEach((answeredQuestion) => { + if (!answeredQuestion.questionNum || !answeredQuestion.selectedAnswerText) { return; } // determine which answer was previously chosen - const chosenAns = glass.questions[aq.questionNum - 1].answers.find((a) => { + const chosenAns = glass.questions[answeredQuestion.questionNum - 1].answers.find((a) => { return ( - a.answerText.toUpperCase() === aq.selectedAnswerText.toUpperCase() + a.answerText.toUpperCase() === answeredQuestion.selectedAnswerText.toUpperCase() ); }); // set the answerString to use for answerSelected if (chosenAns.nextQuestionSequence) { - answerString = `${aq.questionNum}|nextQuestion|${chosenAns.nextQuestionSequence}|${chosenAns.answerText}`; + answerString = `${answeredQuestion.questionNum}|nextQuestion|${chosenAns.nextQuestionSequence}|${chosenAns.answerText}`; } else { - answerString = `${aq.questionNum}|answer|${chosenAns.answerResult}|${chosenAns.answerText}`; + answerString = `${answeredQuestion.questionNum}|answer|${chosenAns.answerResult}|${chosenAns.answerText}`; } // mark this question as answered (question-chain will read this) - glass.questions[aq.questionNum - 1].answerSelected = answerString; + glass.questions[answeredQuestion.questionNum - 1].answerSelected = answerString; // mark this question as suppressed if needed (question-chain uses this) - if (aq.suppressQuestion) { - glass.questions[aq.questionNum - 1].suppressQuestion = true; + if (answeredQuestion.suppressThisQuestion) { + glass.questions[answeredQuestion.questionNum - 1].suppressThisQuestion = true; } }); - // advance the currentGlassIndex - self.currentGlassIndex = i; + // advance the currentGlassPieceIndex + self.currentGlassPieceIndex = i; const answerResult = answeredGlass.partNum ? answeredGlass.partNum @@ -135,21 +132,9 @@ export default { } }); - // Set up watch for each set of glass questions - // (updated when all questions for a glass have been answered in question-chain) - self.$watch( - "selectedAnswers." + glass.glassLocation + "-" + glass.glassName, - (newValue) => { - if (newValue) { - self.handleAnswerUpdates(newValue); - } - }, - { deep: true } - ); - return glass; }, - handleAnswerUpdates(answer, vm) { + handleAnswerUpdates(answer, glassKey, vm) { // only runs when all questions in a question-chain have been answered // when selectedAnswers updates, user has completed this part's question chain and has a final answer // (does not get run for each invididual question's answer, only when @@ -171,236 +156,183 @@ export default { const self = vm ?? this; - // collect a list of the answered questions' numbers, needed later below - const answeredQuestionIndexes = []; - const foundDuplicateQuestions = []; - - // if user has answered a question differently than anything that was preloaded, - // we need to clear out any preloaded answers + // clear out any preloaded answers self.selectedAnswers = {}; // loop through every answered question on the currently answered glass part - answer.answeredQuestions?.forEach((aq) => { + answer.answeredQuestions?.forEach((answeredQuestion) => { - // keep track of this question number - answeredQuestionIndexes.push(aq.questionNum); + /* answeredQuestion example format: + { + "questionText": "Is your Grand Cherokee the Laredo model?", + "selectedAnswerText": "Yes", + "questionNum": 1, + } + */ - const answeredQuestionText = aq.questionText.toUpperCase(); - const answeredQuestionAnswer = aq.selectedAnswerText.toUpperCase(); + const answeredQuestionText = answeredQuestion.questionText.toUpperCase(); + const answeredQuestionAnswer = answeredQuestion.selectedAnswerText.toUpperCase(); // HANDLE DUPLICATE QUESTIONS - // loop through all glass parts data - self.questionsData.forEach((glass, gpIndex) => { + // loop through all glass pieces data + self.questionsData.forEach((glassPiece, pieceIndex) => { + + /* glassPiece example format: + { + "glassName": "Single", + "glassLocation": "Windshield", + "parts": null, + "questions": [ + { + "questionSequence": 1, + "questionText": "Is your vehicle equipped with a black dotted pattern behind the rear view mirror, known as a third visor frit?", + "answers": [ + { + "answerResult": "DW01537", + "answerText": "Yes", + "nextQuestionSequence": null + }, + { + "answerResult": "DW01537b", + "answerText": "No", + "nextQuestionSequence": null + } + ] + } + ], + "answerKey": "Windshield-Single", + "answerData": null + } + */ - // only look for duplicates forward... to parts that follow after the currently being answered part - if (gpIndex > answer.glassIndex) { + // limit duplicate search to glass pieces that follow after the currently being answered glass piece + if (pieceIndex > answer.glassIndex) { - let suppressUntil; - // reset this glass part, in case user is changing their previous answers - glass.answerData = null; - glass.isSuppressedPart = null; + let indexToSuppressTo; + // reset this glass piece, in case user is changing their previous answers + glassPiece.answerData = null; + glassPiece.isSuppressedPart = null; - // loop through this glass part's questions, looking for a questionText match - glass.questions.forEach((pq, pqIndex) => { + // loop through this glass piece's questions, looking for a questionText match + glassPiece.questions.forEach((question, questionIndex) => { // clear out any previously set answers - pq.answerSelected = null; + question.answerSelected = null; - // clear or set suppressQuestion property for each question - if (suppressUntil) { - // if suppressUntil has been set, then suppress this question if before it - if (pqIndex + 1 < suppressUntil) { - pq.suppressQuestion = true; - } else { - pq.suppressQuestion = null; - } + // clear or set suppressThisQuestion property for each question + if (indexToSuppressTo && questionIndex + 1 < indexToSuppressTo) { + question.suppressThisQuestion = true; } else { - pq.suppressQuestion = null; + question.suppressThisQuestion = null; } - // if these match then we have a duplicate question - if (pq.questionText.toUpperCase() === answeredQuestionText) { - - const thisAnsweredQuestion = glass.questions[pqIndex]; + // handle duplicate questions + if (question.questionText.toUpperCase() === answeredQuestionText) { let matchedAnswer; - let rejectedAnswers = []; // set as an array, in case we ever have questions with more than 2 answers... - // which one of this questions' answers matches our answer? - pq.answers.forEach((ans) => { + // handle matching answer in duplicated question + question.answers.forEach((ans) => { if (ans.answerText.toUpperCase() === answeredQuestionAnswer) { matchedAnswer = ans; ans.selected = true; } else { - rejectedAnswers.push(ans); ans.selected = null; } }); - // Update the key to re-render this part's question-chain component - self.questionsData[gpIndex].key = self.questionsData[gpIndex].glassLocation + self.questionsData[gpIndex].glassName + Date.now().toString(); - - // handle suppressing downstream in this question chain - + // handle duplicate's nextQuestion logic on other related questions if (matchedAnswer.nextQuestionSequence) { - // ensure that the question that the accepted answer has set to be next is NOT suppressed - glass.questions[matchedAnswer.nextQuestionSequence - 1].suppressQuestion = null; - // if the duplicate is the 1ST question, then set suppressUntil var to lowest nextQuestion number - if (pqIndex === 0) { - if (!suppressUntil) { suppressUntil = matchedAnswer.nextQuestionSequence } - if (matchedAnswer.nextQuestionSequence < suppressUntil) { suppressUntil = matchedAnswer.nextQuestionSequence} + // clear any suppression on the nextQuestion + glassPiece.questions[matchedAnswer.nextQuestionSequence - 1].suppressThisQuestion = null; + // if the duplicate is 1ST question in array, set indexToSuppressTo + if (questionIndex === 0) { + if (!indexToSuppressTo || matchedAnswer.nextQuestionSequence < indexToSuppressTo) { indexToSuppressTo = matchedAnswer.nextQuestionSequence} } } - // handle suppressing upstream in this question chain - glass.questions.forEach((q) => { - q.answers.forEach((thisAns) => { - // restore any of the answers that formerly led to the duplicated question - if (thisAns.originalNextQuestionSequence === pq.questionSequence) { + // update answers in this glass piece's questions with duplication logic modifications + glassPiece.questions.forEach((q) => { + q.answers.forEach((a) => { + // revert any previously set nextQuestion logic modifications + if (a.originalNextQuestionSequence === question.questionSequence) { // restore original nextQuestionSequence - thisAns.nextQuestionSequence = thisAns.originalNextQuestionSequence; + a.nextQuestionSequence = a.originalNextQuestionSequence; self.originalNextQuestionSequence = null; // restore original answerResult - if (thisAns.originalAnswerResult) { - thisAns.answerResult = thisAns.originalAnswerResult; - thisAns.originalAnswerResult = null; + if (a.originalAnswerResult) { + a.answerResult = a.originalAnswerResult; + a.originalAnswerResult = null; } } - // search for any answers that lead to the duplicated question - if (thisAns.nextQuestionSequence === pq.questionSequence) { - // update either the nextQuestionSequence or the answerResult + // modify logic on any related questions + if (a.nextQuestionSequence === question.questionSequence) { + // update either nextQuestionSequence or answerResult + + // update questions that lead to duplicated question if (matchedAnswer.nextQuestionSequence) { - thisAns.originalNextQuestionSequence = thisAns.nextQuestionSequence; - thisAns.nextQuestionSequence = matchedAnswer.nextQuestionSequence; + a.originalNextQuestionSequence = a.nextQuestionSequence; + a.nextQuestionSequence = matchedAnswer.nextQuestionSequence; } else { - thisAns.originalNextQuestionSequence = thisAns.nextQuestionSequence; - thisAns.nextQuestionSequence = null; - thisAns.originalAnswerResult = thisAns.originalAnswerResult || thisAns.answerResult; - thisAns.answerResult = matchedAnswer.answerResult; + a.originalNextQuestionSequence = a.nextQuestionSequence; + a.nextQuestionSequence = null; + a.originalAnswerResult = a.originalAnswerResult || a.answerResult; + a.answerResult = matchedAnswer.answerResult; } } }); }); // suppress current question - thisAnsweredQuestion.suppressQuestion = true; - - const thisGlassPart = "glass" + gpIndex; - if (foundDuplicateQuestions[thisGlassPart]) { - if (!foundDuplicateQuestions[thisGlassPart].includes(thisAnsweredQuestion.questionSequence)) { - foundDuplicateQuestions[thisGlassPart].push(thisAnsweredQuestion.questionSequence); - } - } else { - foundDuplicateQuestions[thisGlassPart] = [thisAnsweredQuestion.questionSequence]; - } + question.suppressThisQuestion = true; // are there any questions left that are not suppressed? - const remainingQuestions = glass.questions.filter((q) => { - return !q.suppressQuestion; + const remainingQuestions = glassPiece.questions.filter((q) => { + return !q.suppressThisQuestion; }); if (remainingQuestions.length < 1) { - // this is the final answer for this glass part + // this is the final answer for this glass piece - // mark this part as completely answered by adding answerData + // mark this glass piece as completely answered by adding answerData const answeredQuestionObj = { - questionText: pq.questionText, + questionText: question.questionText, selectedAnswerText: matchedAnswer.answerText, - questionNum: pq.questionSequence, - suppressQuestion: pq.suppressQuestion, + questionNum: question.questionSequence, + suppressThisQuestion: question.suppressThisQuestion, }; - // set the answerData as 'already answered' - glass.answerData = { + // set the answerData (used as indicator that it has been already answered) + glassPiece.answerData = { answerResult: matchedAnswer.nextQuestionSequence ? matchedAnswer.nextQuestionSequence : matchedAnswer.answerResult, answeredQuestions: [answeredQuestionObj], }; - // suppress this glass because it has an answer - glass.isSuppressedPart = true; + // suppress this glass piece because it has an answer + glassPiece.isSuppressedPart = true; } } - }); - // Update the key to re-render this part's question-chain component - self.questionsData[gpIndex].key = self.questionsData[gpIndex].glassLocation + self.questionsData[gpIndex].glassName + Date.now().toString(); - + // Update key to force re-render of glass piece with duplicate question in case user changes previous related answer in the chain + self.questionsData[pieceIndex].key = self.questionsData[pieceIndex].key + Date.now().toString(); } }); }); - // DETERMINE ANSWERED QUESTIONS LIST FOR THIS GLASS PART - - // look through all (this part's) part questions for any duplicates that were suppressed; - // add them to the list of answered questions if found - - // EX answeredQuestionIndexes: [1,5,11,13] - - // EX foundDuplicateQuestions = { - // "glassPart1": [1], - // "glassPart2": [7, 10] - // }; - - const thisPartsDupes = foundDuplicateQuestions["glass" + answer.glassIndex]; - const completeAnsweredQuestions = answer.answeredQuestions ? [...answer.answeredQuestions] : []; - const glassPartAnswered = self.questionsData[answer.glassIndex]; - - thisPartsDupes?.forEach((dupe) => { - // dupe is a single integer - const dupeQuestion = glassPartAnswered.questions[dupe - 1]; - const dupeQuestionAnswer = dupeQuestion.answers.find((q) => q.selected === true); - - glassPartAnswered.questions.forEach((q) => { - let includeThisDupeInAnsweredQuestions = false; - - // did one of the answers of this question point to the duplicated question? - q.answers.forEach((a) => { - if ((dupe === a.originalNextQuestionSequence) && - (answeredQuestionIndexes.includes(q.questionSequence)) && - (a.answerText.toUpperCase() === dupeQuestionAnswer.answerText.toUpperCase())) { - includeThisDupeInAnsweredQuestions = true; - } - }); - - // is this q.questionSequence listed as the duplicated question's nextQuestionSequence? - if ((q.questionSequence === dupeQuestionAnswer.nextQuestionSequence) && (answeredQuestionIndexes.includes(q.questionSequence))) { - includeThisDupeInAnsweredQuestions = true; - } - - if (includeThisDupeInAnsweredQuestions) { - completeAnsweredQuestions.push({ - questionNum: dupeQuestion.questionSequence, - questionText: dupeQuestion.questionText, - selectedAnswerText: dupeQuestionAnswer.answerText, - suppressQuestion: dupeQuestion.suppressQuestion, - }); - } - }); - }); - - // make sure there are no duplicated dupes in the list... - const foundInCompleteAnsweredQuestions = new Set(); - let filteredCompleteAnsweredQuestions = completeAnsweredQuestions.filter(el => { - const duplicate = foundInCompleteAnsweredQuestions.has(el.questionText); - foundInCompleteAnsweredQuestions.add(el.questionText); - return !duplicate; - }); - filteredCompleteAnsweredQuestions = filteredCompleteAnsweredQuestions.sort((a,b) => a.questionNum - b.questionNum); - // set final answer data for the current answered glass part - glassPartAnswered.answerData = { + self.questionsData[answer.glassIndex].answerData = { answerResult: answer.answerResult, - answeredQuestions: filteredCompleteAnsweredQuestions, + answeredQuestions: answer.answeredQuestions, } // this part has been fully answered, so advance to next part's question chain - for (let i = answer.glassIndex + 1; i < self.questionsData.length; i++) { + for (let i = answer.glassIndex + 1; i < this.questionsData.length; i++) { // if this part has not yet been fully answered, then make it the current part - if (!self.questionsData[i].answerData?.answerResult) { - self.currentGlassIndex = i; + if (!this.questionsData[i].answerData?.answerResult) { + this.currentGlassPieceIndex = i; break; } } @@ -495,12 +427,19 @@ export default { { partsOrQuestions } ); } else { + // if single parts only const collectedGlassParts = this.reducedGlassPartsArray(partsOrQuestions); + // save to store lineItems.glassParts self.$store.commit(storeMutations.UPDATE_GLASS_PARTS, collectedGlassParts); - self.$refs.loadingModal.showModal(); + if (self.$refs.questionsPage) { + self.$refs.questionsPage.showLoadingModal(); + } else if (self.$refs.loadingModal) { + self.$refs.loadingModal.showModal(); + } + navigateToHeritageFunnel(); } }, diff --git a/src/mixins/vehicle-questions-mixin.spec.js b/src/mixins/vehicle-questions-mixin.spec.js index 6f14cebdd..41ddc8ea2 100644 --- a/src/mixins/vehicle-questions-mixin.spec.js +++ b/src/mixins/vehicle-questions-mixin.spec.js @@ -337,24 +337,6 @@ describe("vehicle-questions-mixin", () => { }); describe("setupInitialData", () => { - describe("should always", () => { - test("return glass with new key attribute", async () => { - // Arrange - const { wrapper } = setupMocks({}); - const glass = { - glassName: "Single", - glassLocation: "Windshield", - }; - const i = 0; - - // Act - const returnedGlass = await wrapper.vm.setupInitialData(glass, i); - - // Assert - expect(returnedGlass).toMatchObject({ key: "Windshield-Single" }); - }); - }); - describe("if no alreadyAnsweredQuestions", () => { test("should return glass with answerData of null", async () => { // Arrange @@ -382,8 +364,7 @@ describe("vehicle-questions-mixin", () => { questions: [ { questionSequence: 1, - questionText: - "Does the rubber seal around your windshield have a chrome strip running through it?", + questionText: "Does the rubber seal around your windshield have a chrome strip running through it?", answers: [ { answerResult: "WKT D1106 C", @@ -407,8 +388,7 @@ describe("vehicle-questions-mixin", () => { partNum: "WKT D1106 C", answeredQuestions: [ { - questionText: - "Does the rubber seal around your windshield have a chrome strip running through it?", + questionText: "Does the rubber seal around your windshield have a chrome strip running through it?", selectedAnswerText: "Yes", questionNum: 1, }, @@ -430,6 +410,803 @@ describe("vehicle-questions-mixin", () => { }); }); + describe("handleAnswerUpdates", () => { + describe("selectedAnswers", () => { + test("should be cleared to be empty", () => { + // Arrange + const answer = { + "answerResult": "DD11132", + "answeredQuestions": [ + { + "questionText": "Test duplicate question 1?", + "selectedAnswerText": "Yes", + "questionNum": 1, + } + ], + "glassIndex": 0 + }; + const { wrapper } = setupMocks({}); + + wrapper.vm.selectedAnswers = { "test": "mockSelectedAnswers" }; + wrapper.vm.questionsData = [ + { + "glassLocation": "Windshield", + "glassName": "Single", + "questions": [], + "answerData": "testAnswerData1" + } + ]; + + // Act + wrapper.vm.handleAnswerUpdates(answer, '', wrapper.vm); + + // Assert + expect(wrapper.vm.selectedAnswers).toMatchObject({}); + }); + }); + + describe("questions in glass parts that are after the answered glass", () => { + test("should have answerData cleared", () => { + // Arrange + const answer = { + "answerResult": "DD11132", + "answeredQuestions": [ + { + "questionText": "Test duplicate question 1?", + "selectedAnswerText": "Yes", + "questionNum": 1, + } + ], + "glassIndex": 0 + }; + const { wrapper } = setupMocks({}); + + wrapper.vm.questionsData = [ + { + "glassLocation": "Windshield", + "glassName": "Single", + "questions": [], + "answerData": "testAnswerData1" + }, + { + "glassLocation": "Driver", + "glassName": "Front", + "questions": [], + "answerData": "testAnswerData2" + } + ]; + + // Act + wrapper.vm.handleAnswerUpdates(answer, '', wrapper.vm); + + // Assert + expect(wrapper.vm.questionsData[1].answerData).toEqual(null); + }); + test("should have isSuppressedPart cleared", () => { + // Arrange + const answer = { + "answerResult": "DD11132", + "answeredQuestions": [ + { + "questionText": "Test duplicate question 1?", + "selectedAnswerText": "Yes", + "questionNum": 1, + } + ], + "glassIndex": 0 + }; + const { wrapper } = setupMocks({}); + + wrapper.vm.questionsData = [ + { + "glassLocation": "Windshield", + "glassName": "Single", + "questions": [], + "answerData": "testAnswerData1" + }, + { + "glassLocation": "Driver", + "glassName": "Front", + "questions": [], + "answerData": "testAnswerData2", + isSuppressedPart: true + } + ]; + + // Act + wrapper.vm.handleAnswerUpdates(answer, '', wrapper.vm); + + // Assert + expect(wrapper.vm.questionsData[1].isSuppressedPart).toEqual(null); + }); + test("should set answerSelected for each glass part question to null ", () => { + // Arrange + const answer = { + "answerResult": "DD11132", + "answeredQuestions": [ + { + "questionText": "Test duplicate question 1?", + "selectedAnswerText": "Yes", + "questionNum": 1, + } + ], + "glassIndex": 0 + }; + const { wrapper } = setupMocks({}); + + wrapper.vm.questionsData = [ + { + "glassLocation": "Windshield", + "glassName": "Single", + "questions": [], + "answerData": "testAnswerData1" + }, + { + "glassLocation": "Driver", + "glassName": "Front", + "questions": [ + { + "questionSequence": 1, + "questionText": "Is your vehicle equipped with the Panoramic Sunroof which can be identified by having a glass panel over the rear seats?", + "answers": [ + { + "answerResult": "", + "answerText": "Yes", + "nextQuestionSequence": 2 + }, + { + "answerResult": "", + "answerText": "No", + "nextQuestionSequence": 3 + } + ], + "answerSelected": "456" + }, + { + "questionSequence": 2, + "questionText": "Is your vehicle equipped with a heated windshield that melts snow and ice from underneath the windshield wiper blades?", + "answers": [ + { + "answerResult": "FW04848", + "answerText": "Yes", + "nextQuestionSequence": null + }, + { + "answerResult": "FW04846", + "answerText": "No", + "nextQuestionSequence": null + } + ], + "answerSelected": "789" + } + ], + "answerData": "testAnswerData2" + } + ]; + + // Act + wrapper.vm.handleAnswerUpdates(answer, '', wrapper.vm); + + // Assert + expect(wrapper.vm.questionsData[1].questions[0].answerSelected).toEqual(null); + expect(wrapper.vm.questionsData[1].questions[1].answerSelected).toEqual(null); + }); + }); + + describe("if there is a duplicate question", () => { + + test("then the glass piece's key should be updated", () => { + // Arrange + const answerNo = { + "answerResult": "456", + "answeredQuestions": [ + { + "questionText": "Test duplicate question 1?", + "selectedAnswerText": "No", + "questionNum": 1, + } + ], + "glassIndex": 0 + }; + const { wrapper } = setupMocks({}); + + wrapper.vm.questionsData = [ + { + "glassLocation": "Windshield", + "glassName": "Single", + "key": "testkey1", + "questions": [ + { + "questionSequence": 1, + "questionText": "Test duplicate question 1?", + "answers": [ + { + "answerResult": "123", + "answerText": "Yes", + "nextQuestionSequence": null + }, + { + "answerResult": "456", + "answerText": "No", + "nextQuestionSequence": null + } + ] + }, + ] + }, + { + "glassLocation": "Driver", + "glassName": "Front", + "key": "testkey2", + "questions": [ + { + "questionSequence": 1, + "questionText": "Test duplicate question 1?", + "answers": [ + { + "answerResult": "123", + "answerText": "Yes", + "nextQuestionSequence": null + }, + { + "answerResult": "234", + "answerText": "No", + "nextQuestionSequence": null + } + ] + } + ] + } + ]; + + // Act + wrapper.vm.handleAnswerUpdates(answerNo, '', wrapper.vm); + const glassPieceWithDuplicate = wrapper.vm.questionsData[1]; + + // Assert + expect(glassPieceWithDuplicate.key).not.toBe("testkey2"); + }); + + test("then that question should be supressed", () => { + // Arrange + const answerNo = { + "answerResult": "456", + "answeredQuestions": [ + { + "questionText": "Test duplicate question 1?", + "selectedAnswerText": "No", + "questionNum": 1, + } + ], + "glassIndex": 0 + }; + const { wrapper } = setupMocks({}); + + wrapper.vm.questionsData = [ + { + "glassLocation": "Windshield", + "glassName": "Single", + "questions": [ + { + "questionSequence": 1, + "questionText": "Test duplicate question 1?", + "answers": [ + { + "answerResult": "123", + "answerText": "Yes", + "nextQuestionSequence": null + }, + { + "answerResult": "456", + "answerText": "No", + "nextQuestionSequence": null + } + ] + }, + ] + }, + { + "glassLocation": "Driver", + "glassName": "Front", + "questions": [ + { + "questionSequence": 1, + "questionText": "Test duplicate question 1?", + "answers": [ + { + "answerResult": "123", + "answerText": "Yes", + "nextQuestionSequence": null + }, + { + "answerResult": "234", + "answerText": "No", + "nextQuestionSequence": null + } + ] + } + ] + } + ]; + + // Act + wrapper.vm.handleAnswerUpdates(answerNo, '', wrapper.vm); + const duplicateQuestion = wrapper.vm.questionsData[1].questions[0]; + + // Assert + expect(duplicateQuestion.suppressThisQuestion).toBeTruthy(); + }); + + describe("and the duplicate has a nextQuestionSequence value", () => { + + test("then the question set as nextQuestionSequence should not be suppressed", () => { + // Arrange + const answerNo = { + "answerResult": "456", + "answeredQuestions": [ + { + "questionText": "Test duplicate question 1?", + "selectedAnswerText": "No", + "questionNum": 1, + } + ], + "glassIndex": 0 + }; + const { wrapper } = setupMocks({}); + + wrapper.vm.questionsData = [ + { + "glassLocation": "Windshield", + "glassName": "Single", + "questions": [ + { + "questionSequence": 1, + "questionText": "Test duplicate question 1?", + "answers": [ + { + "answerResult": "123", + "answerText": "Yes", + "nextQuestionSequence": null + }, + { + "answerResult": "456", + "answerText": "No", + "nextQuestionSequence": null + } + ] + }, + ] + }, + { + "glassLocation": "Driver", + "glassName": "Front", + "questions": [ + { + "questionSequence": 1, + "questionText": "ZZZTest duplicate question 1?", + "answers": [ + { + "answerResult": "", + "answerText": "Yes", + "nextQuestionSequence": 2 + }, + { + "answerResult": "", + "answerText": "No", + "nextQuestionSequence": 3 + } + ] + }, + { + "questionSequence": 2, + "questionText": "Test question 2?", + "answers": [ + { + "answerResult": "123", + "answerText": "Yes", + "nextQuestionSequence": null + }, + { + "answerResult": "234", + "answerText": "No", + "nextQuestionSequence": null + } + ] + }, + { + "questionSequence": 3, + "questionText": "Test question 3?", + "answers": [ + { + "answerResult": "345", + "answerText": "Yes", + "nextQuestionSequence": null + }, + { + "answerResult": "456", + "answerText": "No", + "nextQuestionSequence": null + } + ], + "suppressThisQuestion": true + } + ] + } + ]; + + // Act + wrapper.vm.handleAnswerUpdates(answerNo, '', wrapper.vm); + const nextQuestionAfterDuplicate = wrapper.vm.questionsData[1].questions[2]; + + // Assert + expect(nextQuestionAfterDuplicate.suppressThisQuestion).not.toBeTruthy(); + }); + + test("then the nextQuestionSequence should be updated and the original value saved", () => { + // Arrange + const answerNo = { + "answerResult": "456", + "answeredQuestions": [ + { + "questionText": "Test question 3?", + "selectedAnswerText": "No", + "questionNum": 1, + } + ], + "glassIndex": 0 + }; + const { wrapper } = setupMocks({}); + + wrapper.vm.questionsData = [ + { + "glassLocation": "Windshield", + "glassName": "Single", + "questions": [ + { + "questionSequence": 1, + "questionText": "Test question 3?", + "answers": [ + { + "answerResult": "123", + "answerText": "Yes", + "nextQuestionSequence": null + }, + { + "answerResult": "456", + "answerText": "No", + "nextQuestionSequence": null + } + ] + }, + ] + }, + { + "glassLocation": "Driver", + "glassName": "Front", + "questions": [ + { + "questionSequence": 1, + "questionText": "Test question 1?", + "answers": [ + { + "answerResult": "", + "answerText": "Yes", + "nextQuestionSequence": 2 + }, + { + "answerResult": "", + "answerText": "No", + "nextQuestionSequence": 3 + } + ] + }, + { + "questionSequence": 2, + "questionText": "Test question 2?", + "answers": [ + { + "answerResult": "123", + "answerText": "Yes", + "nextQuestionSequence": null + }, + { + "answerResult": "234", + "answerText": "No", + "nextQuestionSequence": null + } + ] + }, + { + "questionSequence": 3, + "questionText": "Test question 3?", + "answers": [ + { + "answerResult": "", + "answerText": "Yes", + "nextQuestionSequence": 4 + }, + { + "answerResult": "", + "answerText": "No", + "nextQuestionSequence": 5 + } + ] + }, + { + "questionSequence": 4, + "questionText": "Test question 4?", + "answers": [ + { + "answerResult": "567", + "answerText": "Yes", + "nextQuestionSequence": null + }, + { + "answerResult": "678", + "answerText": "No", + "nextQuestionSequence": null + } + ] + }, + { + "questionSequence": 5, + "questionText": "Test question 5?", + "answers": [ + { + "answerResult": "789", + "answerText": "Yes", + "nextQuestionSequence": null + }, + { + "answerResult": "890", + "answerText": "No", + "nextQuestionSequence": null + } + ] + } + ] + } + ]; + + // Act + wrapper.vm.handleAnswerUpdates(answerNo, '', wrapper.vm); + const duplicatedQuestion = wrapper.vm.questionsData[1].questions[2]; + const duplicatedQuestionAnswer = duplicatedQuestion.answers.filter(a => { + return a.selected; + }) + const answerToTest = wrapper.vm.questionsData[1].questions[0].answers.filter(a => { + return a.originalNextQuestionSequence; + }); + + // Assert + expect(answerToTest[0].originalNextQuestionSequence).toEqual(duplicatedQuestion.questionSequence); + expect(answerToTest[0].nextQuestionSequence).toEqual(duplicatedQuestionAnswer[0].nextQuestionSequence); + }); + + describe("and the duplicate was the first question for that part", () => { + + test("then any questions up to the nextQuestionSequence value should be marked as suppressed", () => { + // Arrange + const answerNo = { + "answerResult": "456", + "answeredQuestions": [ + { + "questionText": "Test duplicate question 1?", + "selectedAnswerText": "No", + "questionNum": 1, + } + ], + "glassIndex": 0 + }; + const { wrapper } = setupMocks({}); + + wrapper.vm.questionsData = [ + { + "glassLocation": "Windshield", + "glassName": "Single", + "questions": [ + { + "questionSequence": 1, + "questionText": "Test duplicate question 1?", + "answers": [ + { + "answerResult": "123", + "answerText": "Yes", + "nextQuestionSequence": null + }, + { + "answerResult": "456", + "answerText": "No", + "nextQuestionSequence": null + } + ] + }, + ] + }, + { + "glassLocation": "Driver", + "glassName": "Front", + "questions": [ + { + "questionSequence": 1, + "questionText": "Test duplicate question 1?", + "answers": [ + { + "answerResult": "", + "answerText": "Yes", + "nextQuestionSequence": 2 + }, + { + "answerResult": "", + "answerText": "No", + "nextQuestionSequence": 3 + } + ] + }, + { + "questionSequence": 2, + "questionText": "Test question 2?", + "answers": [ + { + "answerResult": "123", + "answerText": "Yes", + "nextQuestionSequence": null + }, + { + "answerResult": "234", + "answerText": "No", + "nextQuestionSequence": null + } + ] + }, + { + "questionSequence": 3, + "questionText": "Test question 3?", + "answers": [ + { + "answerResult": "345", + "answerText": "Yes", + "nextQuestionSequence": null + }, + { + "answerResult": "456", + "answerText": "No", + "nextQuestionSequence": null + } + ] + } + ] + } + ]; + + // Act + wrapper.vm.handleAnswerUpdates(answerNo, '', wrapper.vm); + + // Assert + expect(wrapper.vm.questionsData[1].questions[0].suppressThisQuestion).toBeTruthy(); + expect(wrapper.vm.questionsData[1].questions[1].suppressThisQuestion).toBeTruthy(); + expect(wrapper.vm.questionsData[1].questions[2].suppressThisQuestion).toBeFalsy(); + }); + + }); + + }); + + describe("and the duplicate has an answerResult", () => { + test("then any questions in the same glass piece that lead to the duplicate should be modified to just provide the duplicate's answerResult", async () => { + // Arrange + const answerNo = { + "answerResult": "456", + "answeredQuestions": [ + { + "questionText": "Test question 3?", + "selectedAnswerText": "No", + "questionNum": 1, + } + ], + "glassIndex": 0 + }; + const { wrapper } = setupMocks({}); + + wrapper.vm.questionsData = [ + { + "glassLocation": "Windshield", + "glassName": "Single", + "questions": [ + { + "questionSequence": 1, + "questionText": "Test question 3?", + "answers": [ + { + "answerResult": "123", + "answerText": "Yes", + "nextQuestionSequence": null + }, + { + "answerResult": "456", + "answerText": "No", + "nextQuestionSequence": null + } + ] + }, + ] + }, + { + "glassLocation": "Driver", + "glassName": "Front", + "questions": [ + { + "questionSequence": 1, + "questionText": "Test question 1?", + "answers": [ + { + "answerResult": "", + "answerText": "Yes", + "nextQuestionSequence": 2 + }, + { + "answerResult": "", + "answerText": "No", + "nextQuestionSequence": 3 + } + ] + }, + { + "questionSequence": 2, + "questionText": "Test question 2?", + "answers": [ + { + "answerResult": "123", + "answerText": "Yes", + "nextQuestionSequence": null + }, + { + "answerResult": "234", + "answerText": "No", + "nextQuestionSequence": null + } + ] + }, + { + "questionSequence": 3, + "questionText": "Test question 3?", + "answers": [ + { + "answerResult": "345", + "answerText": "Yes", + "nextQuestionSequence": null + }, + { + "answerResult": "456", + "answerText": "No", + "nextQuestionSequence": null + } + ] + }, + ] + } + ]; + + // Act + await wrapper.vm.handleAnswerUpdates(answerNo, '', wrapper.vm); + + const questionsToTest = wrapper.vm.questionsData[1].questions; + const answerLeadingToDuplicate = questionsToTest[0].answers[1]; + const duplicateQuestion = questionsToTest[2]; + const answerInDuplicateQuestion = duplicateQuestion.answers.filter(a => { + return a.selected; + }) + + // Assert + expect(answerLeadingToDuplicate.answerResult).toEqual(answerInDuplicateQuestion[0].answerResult); + expect(answerLeadingToDuplicate.originalAnswerResult).toBeFalsy(); + expect(answerLeadingToDuplicate.nextQuestionSequence).toEqual(null); + expect(answerLeadingToDuplicate.originalNextQuestionSequence).toEqual(duplicateQuestion.questionSequence); + }); + }); + }); + }); + describe("navigateForward", () => { describe("should go to parts-questions", () => { test("single glass location has part question => go to parts-questions", async () => { From e6b27f2098c453514cbe52bc645f61b38cb62310 Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Sat, 5 Nov 2022 20:28:08 -0400 Subject: [PATCH 06/11] CSR-803: prettify formatting changes --- .../question-chain/question-chain.vue | 2 +- .../capability-questions.vue | 59 +- .../molding-questions/molding-questions.vue | 47 +- src/layouts/part-questions/part-questions.vue | 59 +- src/mixins/vehicle-questions-mixin.js | 72 +- src/mixins/vehicle-questions-mixin.spec.js | 983 +++++++++--------- 6 files changed, 627 insertions(+), 595 deletions(-) diff --git a/src/common-components/question-chain/question-chain.vue b/src/common-components/question-chain/question-chain.vue index 7c9767d47..bc707f239 100644 --- a/src/common-components/question-chain/question-chain.vue +++ b/src/common-components/question-chain/question-chain.vue @@ -90,7 +90,7 @@ export default { "buttonId": "Driver-Front-1-1|answer|DD11132|Yes" } */ - + question.answerSelected = returnedAnswer; const isQuestionChainComplete = this.getQuestionChainAnswerIfComplete(returnedAnswer); diff --git a/src/layouts/capability-questions/capability-questions.vue b/src/layouts/capability-questions/capability-questions.vue index 0f7a0e57e..98ecc31f6 100644 --- a/src/layouts/capability-questions/capability-questions.vue +++ b/src/layouts/capability-questions/capability-questions.vue @@ -1,22 +1,16 @@ @@ -81,25 +75,30 @@ export default { // are there alreadyAnsweredQuestions? const alreadyAnsweredQuestions = store.getters.damage.capabilityQuestionAnswers; - this.questionsData = this.pageData.partsOrQuestions.filter((x) => x.capabilityQuestions).map((glass, i) => { - // NOTE: questions for property "questions" can differ between layouts - glass.questions = glass.capabilityQuestions; - glass.answerKey = glass.glassLocation + "-" + glass.glassName; - // reset selectedAnswers for this glass - this.selectedAnswers2[glass.answerKey] = []; + this.questionsData = this.pageData.partsOrQuestions + .filter((x) => x.capabilityQuestions) + .map((glass, i) => { + // NOTE: questions for property "questions" can differ between layouts + glass.questions = glass.capabilityQuestions; + glass.answerKey = glass.glassLocation + "-" + glass.glassName; + // reset selectedAnswers for this glass + this.selectedAnswers2[glass.answerKey] = []; - const updatedGlass = this.setupInitialData(glass, i, alreadyAnsweredQuestions); + const updatedGlass = this.setupInitialData(glass, i, alreadyAnsweredQuestions); - // Set up watch for each set of glass questions - this.$watch("selectedAnswers2." + glass.answerKey, (newValue) => { - if (newValue && Object.keys(newValue).length > 0) { - this.handleAnswerUpdates(newValue, glass.answerKey); - } - }, { deep: true }); - - return updatedGlass; - }); + // Set up watch for each set of glass questions + this.$watch( + "selectedAnswers2." + glass.answerKey, + (newValue) => { + if (newValue && Object.keys(newValue).length > 0) { + this.handleAnswerUpdates(newValue, glass.answerKey); + } + }, + { deep: true } + ); + return updatedGlass; + }); }, methods: { arePagePrerequisitesValid() { @@ -114,9 +113,13 @@ export default { const questionAnswersArray = this.questionsData.map((glass) => { // get answerResult2 of returned answer let selectedAnswerResult2; - glass.questions.forEach(q => { - const idx = q.answers.findIndex(a => a.answerResult === glass.answerData.answerResult); - if (idx !== -1) { selectedAnswerResult2 = q.answers[idx].answerResult2 } + glass.questions.forEach((q) => { + const idx = q.answers.findIndex( + (a) => a.answerResult === glass.answerData.answerResult + ); + if (idx !== -1) { + selectedAnswerResult2 = q.answers[idx].answerResult2; + } }); return { diff --git a/src/layouts/molding-questions/molding-questions.vue b/src/layouts/molding-questions/molding-questions.vue index 9f0362b44..3670f9cc1 100644 --- a/src/layouts/molding-questions/molding-questions.vue +++ b/src/layouts/molding-questions/molding-questions.vue @@ -1,22 +1,16 @@ @@ -81,24 +75,29 @@ export default { // are there alreadyAnsweredQuestions? const alreadyAnsweredQuestions = store.getters.damage.moldingQuestionAnswers; - this.questionsData = this.pageData.partsOrQuestions.filter(x => x.parts[0].childPartQuestions.length).map((glass, i) => { - // NOTE: questions for property "questions" can differ between layouts - glass.questions = glass.parts[0].childPartQuestions; - glass.answerKey = glass.glassLocation + "-" + glass.glassName; - // reset selectedAnswers for this glass - this.selectedAnswers2[glass.answerKey] = []; + this.questionsData = this.pageData.partsOrQuestions + .filter((x) => x.parts[0].childPartQuestions.length) + .map((glass, i) => { + // NOTE: questions for property "questions" can differ between layouts + glass.questions = glass.parts[0].childPartQuestions; + glass.answerKey = glass.glassLocation + "-" + glass.glassName; + // reset selectedAnswers for this glass + this.selectedAnswers2[glass.answerKey] = []; - const updatedGlass = this.setupInitialData(glass, i, alreadyAnsweredQuestions); + const updatedGlass = this.setupInitialData(glass, i, alreadyAnsweredQuestions); - this.$watch("selectedAnswers2." + glass.answerKey, (newValue) => { - if (newValue && Object.keys(newValue).length > 0) { - this.handleAnswerUpdates(newValue, glass.answerKey); - } - }, { deep: true }); - - return updatedGlass; - }); + this.$watch( + "selectedAnswers2." + glass.answerKey, + (newValue) => { + if (newValue && Object.keys(newValue).length > 0) { + this.handleAnswerUpdates(newValue, glass.answerKey); + } + }, + { deep: true } + ); + return updatedGlass; + }); }, methods: { arePagePrerequisitesValid() { diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue index 02200585f..961fa825d 100644 --- a/src/layouts/part-questions/part-questions.vue +++ b/src/layouts/part-questions/part-questions.vue @@ -1,22 +1,16 @@ @@ -81,25 +75,30 @@ export default { // are there alreadyAnsweredQuestions? const alreadyAnsweredQuestions = store.getters.damage.partQuestionAnswers; - this.questionsData = this.pageData.partsOrQuestions.filter(x => x.partQuestions).map((glass, i) => { - // NOTE: questions for property "questions" can differ between layouts - glass.questions = glass.partQuestions; - glass.answerKey = glass.glassLocation + "-" + glass.glassName; - // reset selectedAnswers for this glass - this.selectedAnswers[glass.answerKey] = []; + this.questionsData = this.pageData.partsOrQuestions + .filter((x) => x.partQuestions) + .map((glass, i) => { + // NOTE: questions for property "questions" can differ between layouts + glass.questions = glass.partQuestions; + glass.answerKey = glass.glassLocation + "-" + glass.glassName; + // reset selectedAnswers for this glass + this.selectedAnswers[glass.answerKey] = []; - const updatedGlass = this.setupInitialData(glass, i, alreadyAnsweredQuestions); + const updatedGlass = this.setupInitialData(glass, i, alreadyAnsweredQuestions); - // Set up watch for each set of glass questions - this.$watch("selectedAnswers." + glass.answerKey, (newValue) => { - if (newValue && Object.keys(newValue).length > 0) { - this.handleAnswerUpdates(newValue, glass.answerKey); - } - }, {deep: true}); - - return updatedGlass; - }); + // Set up watch for each set of glass questions + this.$watch( + "selectedAnswers." + glass.answerKey, + (newValue) => { + if (newValue && Object.keys(newValue).length > 0) { + this.handleAnswerUpdates(newValue, glass.answerKey); + } + }, + { deep: true } + ); + return updatedGlass; + }); }, methods: { arePagePrerequisitesValid() { @@ -130,10 +129,11 @@ export default { ); // call API parts method - const partsLookup = await this.dispatchStoreAction(this.storeActions.GET_PARTS) - .catch(() => { + const partsLookup = await this.dispatchStoreAction(this.storeActions.GET_PARTS).catch( + () => { return this.$refs.funnelFooter.removeLoader(); - }); + } + ); const glassPiecePartsForStore = partsLookup.data.glassPieceParts; @@ -146,4 +146,3 @@ export default { }, }; - diff --git a/src/mixins/vehicle-questions-mixin.js b/src/mixins/vehicle-questions-mixin.js index a362ec2c6..2d16dd2e4 100644 --- a/src/mixins/vehicle-questions-mixin.js +++ b/src/mixins/vehicle-questions-mixin.js @@ -81,7 +81,9 @@ export default { !answeredGlass.glassName || !answeredGlass.answeredQuestions || (!answeredGlass.result && !answeredGlass.partNum) - ) { return } + ) { + return; + } // test if glass parts match if ( @@ -96,9 +98,12 @@ export default { return; } // determine which answer was previously chosen - const chosenAns = glass.questions[answeredQuestion.questionNum - 1].answers.find((a) => { + const chosenAns = glass.questions[ + answeredQuestion.questionNum - 1 + ].answers.find((a) => { return ( - a.answerText.toUpperCase() === answeredQuestion.selectedAnswerText.toUpperCase() + a.answerText.toUpperCase() === + answeredQuestion.selectedAnswerText.toUpperCase() ); }); // set the answerString to use for answerSelected @@ -109,10 +114,13 @@ export default { } // mark this question as answered (question-chain will read this) - glass.questions[answeredQuestion.questionNum - 1].answerSelected = answerString; + glass.questions[answeredQuestion.questionNum - 1].answerSelected = + answerString; // mark this question as suppressed if needed (question-chain uses this) if (answeredQuestion.suppressThisQuestion) { - glass.questions[answeredQuestion.questionNum - 1].suppressThisQuestion = true; + glass.questions[ + answeredQuestion.questionNum - 1 + ].suppressThisQuestion = true; } }); @@ -137,10 +145,10 @@ export default { handleAnswerUpdates(answer, glassKey, vm) { // only runs when all questions in a question-chain have been answered // when selectedAnswers updates, user has completed this part's question chain and has a final answer - // (does not get run for each invididual question's answer, only when + // (does not get run for each invididual question's answer, only when // all relevant questions for the current part have been answered) - /* answer example format: + /* answer example format: { "answerResult": "DD11132", "answeredQuestions": [ @@ -161,7 +169,6 @@ export default { // loop through every answered question on the currently answered glass part answer.answeredQuestions?.forEach((answeredQuestion) => { - /* answeredQuestion example format: { "questionText": "Is your Grand Cherokee the Laredo model?", @@ -177,7 +184,6 @@ export default { // loop through all glass pieces data self.questionsData.forEach((glassPiece, pieceIndex) => { - /* glassPiece example format: { "glassName": "Single", @@ -205,10 +211,9 @@ export default { "answerData": null } */ - + // limit duplicate search to glass pieces that follow after the currently being answered glass piece if (pieceIndex > answer.glassIndex) { - let indexToSuppressTo; // reset this glass piece, in case user is changing their previous answers glassPiece.answerData = null; @@ -216,7 +221,6 @@ export default { // loop through this glass piece's questions, looking for a questionText match glassPiece.questions.forEach((question, questionIndex) => { - // clear out any previously set answers question.answerSelected = null; @@ -244,10 +248,17 @@ export default { // handle duplicate's nextQuestion logic on other related questions if (matchedAnswer.nextQuestionSequence) { // clear any suppression on the nextQuestion - glassPiece.questions[matchedAnswer.nextQuestionSequence - 1].suppressThisQuestion = null; + glassPiece.questions[ + matchedAnswer.nextQuestionSequence - 1 + ].suppressThisQuestion = null; // if the duplicate is 1ST question in array, set indexToSuppressTo if (questionIndex === 0) { - if (!indexToSuppressTo || matchedAnswer.nextQuestionSequence < indexToSuppressTo) { indexToSuppressTo = matchedAnswer.nextQuestionSequence} + if ( + !indexToSuppressTo || + matchedAnswer.nextQuestionSequence < indexToSuppressTo + ) { + indexToSuppressTo = matchedAnswer.nextQuestionSequence; + } } } @@ -255,7 +266,10 @@ export default { glassPiece.questions.forEach((q) => { q.answers.forEach((a) => { // revert any previously set nextQuestion logic modifications - if (a.originalNextQuestionSequence === question.questionSequence) { + if ( + a.originalNextQuestionSequence === + question.questionSequence + ) { // restore original nextQuestionSequence a.nextQuestionSequence = a.originalNextQuestionSequence; self.originalNextQuestionSequence = null; @@ -271,18 +285,22 @@ export default { // update questions that lead to duplicated question if (matchedAnswer.nextQuestionSequence) { - a.originalNextQuestionSequence = a.nextQuestionSequence; - a.nextQuestionSequence = matchedAnswer.nextQuestionSequence; + a.originalNextQuestionSequence = + a.nextQuestionSequence; + a.nextQuestionSequence = + matchedAnswer.nextQuestionSequence; } else { - a.originalNextQuestionSequence = a.nextQuestionSequence; + a.originalNextQuestionSequence = + a.nextQuestionSequence; a.nextQuestionSequence = null; - a.originalAnswerResult = a.originalAnswerResult || a.answerResult; + a.originalAnswerResult = + a.originalAnswerResult || a.answerResult; a.answerResult = matchedAnswer.answerResult; } } }); }); - + // suppress current question question.suppressThisQuestion = true; @@ -303,30 +321,30 @@ export default { }; // set the answerData (used as indicator that it has been already answered) glassPiece.answerData = { - answerResult: matchedAnswer.nextQuestionSequence ? matchedAnswer.nextQuestionSequence : matchedAnswer.answerResult, + answerResult: matchedAnswer.nextQuestionSequence + ? matchedAnswer.nextQuestionSequence + : matchedAnswer.answerResult, answeredQuestions: [answeredQuestionObj], }; // suppress this glass piece because it has an answer glassPiece.isSuppressedPart = true; } - } }); // Update key to force re-render of glass piece with duplicate question in case user changes previous related answer in the chain - self.questionsData[pieceIndex].key = self.questionsData[pieceIndex].key + Date.now().toString(); + self.questionsData[pieceIndex].key = + self.questionsData[pieceIndex].key + Date.now().toString(); } - }); - }); // set final answer data for the current answered glass part self.questionsData[answer.glassIndex].answerData = { answerResult: answer.answerResult, answeredQuestions: answer.answeredQuestions, - } + }; // this part has been fully answered, so advance to next part's question chain for (let i = answer.glassIndex + 1; i < this.questionsData.length; i++) { @@ -336,7 +354,6 @@ export default { break; } } - }, // Can't use `this` because navigateForward is also called from vin-pages-mixin async navigateForward(partsOrQuestions, vm) { @@ -427,7 +444,6 @@ export default { { partsOrQuestions } ); } else { - // if single parts only const collectedGlassParts = this.reducedGlassPartsArray(partsOrQuestions); diff --git a/src/mixins/vehicle-questions-mixin.spec.js b/src/mixins/vehicle-questions-mixin.spec.js index 41ddc8ea2..4be7dec0f 100644 --- a/src/mixins/vehicle-questions-mixin.spec.js +++ b/src/mixins/vehicle-questions-mixin.spec.js @@ -364,7 +364,8 @@ describe("vehicle-questions-mixin", () => { questions: [ { questionSequence: 1, - questionText: "Does the rubber seal around your windshield have a chrome strip running through it?", + questionText: + "Does the rubber seal around your windshield have a chrome strip running through it?", answers: [ { answerResult: "WKT D1106 C", @@ -388,7 +389,8 @@ describe("vehicle-questions-mixin", () => { partNum: "WKT D1106 C", answeredQuestions: [ { - questionText: "Does the rubber seal around your windshield have a chrome strip running through it?", + questionText: + "Does the rubber seal around your windshield have a chrome strip running through it?", selectedAnswerText: "Yes", questionNum: 1, }, @@ -415,30 +417,30 @@ describe("vehicle-questions-mixin", () => { test("should be cleared to be empty", () => { // Arrange const answer = { - "answerResult": "DD11132", - "answeredQuestions": [ + answerResult: "DD11132", + answeredQuestions: [ { - "questionText": "Test duplicate question 1?", - "selectedAnswerText": "Yes", - "questionNum": 1, - } + questionText: "Test duplicate question 1?", + selectedAnswerText: "Yes", + questionNum: 1, + }, ], - "glassIndex": 0 + glassIndex: 0, }; const { wrapper } = setupMocks({}); - wrapper.vm.selectedAnswers = { "test": "mockSelectedAnswers" }; + wrapper.vm.selectedAnswers = { test: "mockSelectedAnswers" }; wrapper.vm.questionsData = [ { - "glassLocation": "Windshield", - "glassName": "Single", - "questions": [], - "answerData": "testAnswerData1" - } + glassLocation: "Windshield", + glassName: "Single", + questions: [], + answerData: "testAnswerData1", + }, ]; // Act - wrapper.vm.handleAnswerUpdates(answer, '', wrapper.vm); + wrapper.vm.handleAnswerUpdates(answer, "", wrapper.vm); // Assert expect(wrapper.vm.selectedAnswers).toMatchObject({}); @@ -449,35 +451,35 @@ describe("vehicle-questions-mixin", () => { test("should have answerData cleared", () => { // Arrange const answer = { - "answerResult": "DD11132", - "answeredQuestions": [ + answerResult: "DD11132", + answeredQuestions: [ { - "questionText": "Test duplicate question 1?", - "selectedAnswerText": "Yes", - "questionNum": 1, - } + questionText: "Test duplicate question 1?", + selectedAnswerText: "Yes", + questionNum: 1, + }, ], - "glassIndex": 0 + glassIndex: 0, }; const { wrapper } = setupMocks({}); wrapper.vm.questionsData = [ { - "glassLocation": "Windshield", - "glassName": "Single", - "questions": [], - "answerData": "testAnswerData1" + glassLocation: "Windshield", + glassName: "Single", + questions: [], + answerData: "testAnswerData1", }, { - "glassLocation": "Driver", - "glassName": "Front", - "questions": [], - "answerData": "testAnswerData2" - } + glassLocation: "Driver", + glassName: "Front", + questions: [], + answerData: "testAnswerData2", + }, ]; // Act - wrapper.vm.handleAnswerUpdates(answer, '', wrapper.vm); + wrapper.vm.handleAnswerUpdates(answer, "", wrapper.vm); // Assert expect(wrapper.vm.questionsData[1].answerData).toEqual(null); @@ -485,36 +487,36 @@ describe("vehicle-questions-mixin", () => { test("should have isSuppressedPart cleared", () => { // Arrange const answer = { - "answerResult": "DD11132", - "answeredQuestions": [ + answerResult: "DD11132", + answeredQuestions: [ { - "questionText": "Test duplicate question 1?", - "selectedAnswerText": "Yes", - "questionNum": 1, - } + questionText: "Test duplicate question 1?", + selectedAnswerText: "Yes", + questionNum: 1, + }, ], - "glassIndex": 0 + glassIndex: 0, }; const { wrapper } = setupMocks({}); wrapper.vm.questionsData = [ { - "glassLocation": "Windshield", - "glassName": "Single", - "questions": [], - "answerData": "testAnswerData1" + glassLocation: "Windshield", + glassName: "Single", + questions: [], + answerData: "testAnswerData1", }, { - "glassLocation": "Driver", - "glassName": "Front", - "questions": [], - "answerData": "testAnswerData2", - isSuppressedPart: true - } + glassLocation: "Driver", + glassName: "Front", + questions: [], + answerData: "testAnswerData2", + isSuppressedPart: true, + }, ]; // Act - wrapper.vm.handleAnswerUpdates(answer, '', wrapper.vm); + wrapper.vm.handleAnswerUpdates(answer, "", wrapper.vm); // Assert expect(wrapper.vm.questionsData[1].isSuppressedPart).toEqual(null); @@ -522,70 +524,72 @@ describe("vehicle-questions-mixin", () => { test("should set answerSelected for each glass part question to null ", () => { // Arrange const answer = { - "answerResult": "DD11132", - "answeredQuestions": [ + answerResult: "DD11132", + answeredQuestions: [ { - "questionText": "Test duplicate question 1?", - "selectedAnswerText": "Yes", - "questionNum": 1, - } + questionText: "Test duplicate question 1?", + selectedAnswerText: "Yes", + questionNum: 1, + }, ], - "glassIndex": 0 + glassIndex: 0, }; const { wrapper } = setupMocks({}); wrapper.vm.questionsData = [ { - "glassLocation": "Windshield", - "glassName": "Single", - "questions": [], - "answerData": "testAnswerData1" + glassLocation: "Windshield", + glassName: "Single", + questions: [], + answerData: "testAnswerData1", }, { - "glassLocation": "Driver", - "glassName": "Front", - "questions": [ + glassLocation: "Driver", + glassName: "Front", + questions: [ { - "questionSequence": 1, - "questionText": "Is your vehicle equipped with the Panoramic Sunroof which can be identified by having a glass panel over the rear seats?", - "answers": [ + questionSequence: 1, + questionText: + "Is your vehicle equipped with the Panoramic Sunroof which can be identified by having a glass panel over the rear seats?", + answers: [ { - "answerResult": "", - "answerText": "Yes", - "nextQuestionSequence": 2 + answerResult: "", + answerText: "Yes", + nextQuestionSequence: 2, }, { - "answerResult": "", - "answerText": "No", - "nextQuestionSequence": 3 - } + answerResult: "", + answerText: "No", + nextQuestionSequence: 3, + }, ], - "answerSelected": "456" + answerSelected: "456", }, { - "questionSequence": 2, - "questionText": "Is your vehicle equipped with a heated windshield that melts snow and ice from underneath the windshield wiper blades?", - "answers": [ + questionSequence: 2, + questionText: + "Is your vehicle equipped with a heated windshield that melts snow and ice from underneath the windshield wiper blades?", + answers: [ { - "answerResult": "FW04848", - "answerText": "Yes", - "nextQuestionSequence": null + answerResult: "FW04848", + answerText: "Yes", + nextQuestionSequence: null, }, { - "answerResult": "FW04846", - "answerText": "No", - "nextQuestionSequence": null - } + answerResult: "FW04846", + answerText: "No", + nextQuestionSequence: null, + }, ], - "answerSelected": "789" - } + answerSelected: "789", + }, ], - "answerData": "testAnswerData2" - } + answerData: "testAnswerData2", + }, ]; // Act - wrapper.vm.handleAnswerUpdates(answer, '', wrapper.vm); + wrapper.vm.handleAnswerUpdates(answer, "", wrapper.vm); // Assert expect(wrapper.vm.questionsData[1].questions[0].answerSelected).toEqual(null); @@ -594,250 +598,248 @@ describe("vehicle-questions-mixin", () => { }); describe("if there is a duplicate question", () => { - test("then the glass piece's key should be updated", () => { // Arrange const answerNo = { - "answerResult": "456", - "answeredQuestions": [ + answerResult: "456", + answeredQuestions: [ { - "questionText": "Test duplicate question 1?", - "selectedAnswerText": "No", - "questionNum": 1, - } + questionText: "Test duplicate question 1?", + selectedAnswerText: "No", + questionNum: 1, + }, ], - "glassIndex": 0 + glassIndex: 0, }; const { wrapper } = setupMocks({}); wrapper.vm.questionsData = [ { - "glassLocation": "Windshield", - "glassName": "Single", - "key": "testkey1", - "questions": [ + glassLocation: "Windshield", + glassName: "Single", + key: "testkey1", + questions: [ { - "questionSequence": 1, - "questionText": "Test duplicate question 1?", - "answers": [ + questionSequence: 1, + questionText: "Test duplicate question 1?", + answers: [ { - "answerResult": "123", - "answerText": "Yes", - "nextQuestionSequence": null + answerResult: "123", + answerText: "Yes", + nextQuestionSequence: null, }, { - "answerResult": "456", - "answerText": "No", - "nextQuestionSequence": null - } - ] + answerResult: "456", + answerText: "No", + nextQuestionSequence: null, + }, + ], }, - ] + ], }, { - "glassLocation": "Driver", - "glassName": "Front", - "key": "testkey2", - "questions": [ + glassLocation: "Driver", + glassName: "Front", + key: "testkey2", + questions: [ { - "questionSequence": 1, - "questionText": "Test duplicate question 1?", - "answers": [ + questionSequence: 1, + questionText: "Test duplicate question 1?", + answers: [ { - "answerResult": "123", - "answerText": "Yes", - "nextQuestionSequence": null + answerResult: "123", + answerText: "Yes", + nextQuestionSequence: null, }, { - "answerResult": "234", - "answerText": "No", - "nextQuestionSequence": null - } - ] - } - ] - } + answerResult: "234", + answerText: "No", + nextQuestionSequence: null, + }, + ], + }, + ], + }, ]; // Act - wrapper.vm.handleAnswerUpdates(answerNo, '', wrapper.vm); + wrapper.vm.handleAnswerUpdates(answerNo, "", wrapper.vm); const glassPieceWithDuplicate = wrapper.vm.questionsData[1]; // Assert expect(glassPieceWithDuplicate.key).not.toBe("testkey2"); }); - + test("then that question should be supressed", () => { // Arrange const answerNo = { - "answerResult": "456", - "answeredQuestions": [ + answerResult: "456", + answeredQuestions: [ { - "questionText": "Test duplicate question 1?", - "selectedAnswerText": "No", - "questionNum": 1, - } + questionText: "Test duplicate question 1?", + selectedAnswerText: "No", + questionNum: 1, + }, ], - "glassIndex": 0 + glassIndex: 0, }; const { wrapper } = setupMocks({}); wrapper.vm.questionsData = [ { - "glassLocation": "Windshield", - "glassName": "Single", - "questions": [ + glassLocation: "Windshield", + glassName: "Single", + questions: [ { - "questionSequence": 1, - "questionText": "Test duplicate question 1?", - "answers": [ + questionSequence: 1, + questionText: "Test duplicate question 1?", + answers: [ { - "answerResult": "123", - "answerText": "Yes", - "nextQuestionSequence": null + answerResult: "123", + answerText: "Yes", + nextQuestionSequence: null, }, { - "answerResult": "456", - "answerText": "No", - "nextQuestionSequence": null - } - ] + answerResult: "456", + answerText: "No", + nextQuestionSequence: null, + }, + ], }, - ] + ], }, { - "glassLocation": "Driver", - "glassName": "Front", - "questions": [ + glassLocation: "Driver", + glassName: "Front", + questions: [ { - "questionSequence": 1, - "questionText": "Test duplicate question 1?", - "answers": [ + questionSequence: 1, + questionText: "Test duplicate question 1?", + answers: [ { - "answerResult": "123", - "answerText": "Yes", - "nextQuestionSequence": null + answerResult: "123", + answerText: "Yes", + nextQuestionSequence: null, }, { - "answerResult": "234", - "answerText": "No", - "nextQuestionSequence": null - } - ] - } - ] - } + answerResult: "234", + answerText: "No", + nextQuestionSequence: null, + }, + ], + }, + ], + }, ]; // Act - wrapper.vm.handleAnswerUpdates(answerNo, '', wrapper.vm); + wrapper.vm.handleAnswerUpdates(answerNo, "", wrapper.vm); const duplicateQuestion = wrapper.vm.questionsData[1].questions[0]; // Assert expect(duplicateQuestion.suppressThisQuestion).toBeTruthy(); }); - + describe("and the duplicate has a nextQuestionSequence value", () => { - test("then the question set as nextQuestionSequence should not be suppressed", () => { // Arrange const answerNo = { - "answerResult": "456", - "answeredQuestions": [ + answerResult: "456", + answeredQuestions: [ { - "questionText": "Test duplicate question 1?", - "selectedAnswerText": "No", - "questionNum": 1, - } + questionText: "Test duplicate question 1?", + selectedAnswerText: "No", + questionNum: 1, + }, ], - "glassIndex": 0 + glassIndex: 0, }; const { wrapper } = setupMocks({}); - + wrapper.vm.questionsData = [ { - "glassLocation": "Windshield", - "glassName": "Single", - "questions": [ + glassLocation: "Windshield", + glassName: "Single", + questions: [ { - "questionSequence": 1, - "questionText": "Test duplicate question 1?", - "answers": [ + questionSequence: 1, + questionText: "Test duplicate question 1?", + answers: [ { - "answerResult": "123", - "answerText": "Yes", - "nextQuestionSequence": null + answerResult: "123", + answerText: "Yes", + nextQuestionSequence: null, }, { - "answerResult": "456", - "answerText": "No", - "nextQuestionSequence": null - } - ] + answerResult: "456", + answerText: "No", + nextQuestionSequence: null, + }, + ], }, - ] + ], }, { - "glassLocation": "Driver", - "glassName": "Front", - "questions": [ + glassLocation: "Driver", + glassName: "Front", + questions: [ { - "questionSequence": 1, - "questionText": "ZZZTest duplicate question 1?", - "answers": [ + questionSequence: 1, + questionText: "ZZZTest duplicate question 1?", + answers: [ { - "answerResult": "", - "answerText": "Yes", - "nextQuestionSequence": 2 + answerResult: "", + answerText: "Yes", + nextQuestionSequence: 2, }, { - "answerResult": "", - "answerText": "No", - "nextQuestionSequence": 3 - } - ] - }, - { - "questionSequence": 2, - "questionText": "Test question 2?", - "answers": [ - { - "answerResult": "123", - "answerText": "Yes", - "nextQuestionSequence": null + answerResult: "", + answerText: "No", + nextQuestionSequence: 3, }, - { - "answerResult": "234", - "answerText": "No", - "nextQuestionSequence": null - } - ] - }, - { - "questionSequence": 3, - "questionText": "Test question 3?", - "answers": [ - { - "answerResult": "345", - "answerText": "Yes", - "nextQuestionSequence": null - }, - { - "answerResult": "456", - "answerText": "No", - "nextQuestionSequence": null - } ], - "suppressThisQuestion": true - } - ] - } + }, + { + questionSequence: 2, + questionText: "Test question 2?", + answers: [ + { + answerResult: "123", + answerText: "Yes", + nextQuestionSequence: null, + }, + { + answerResult: "234", + answerText: "No", + nextQuestionSequence: null, + }, + ], + }, + { + questionSequence: 3, + questionText: "Test question 3?", + answers: [ + { + answerResult: "345", + answerText: "Yes", + nextQuestionSequence: null, + }, + { + answerResult: "456", + answerText: "No", + nextQuestionSequence: null, + }, + ], + suppressThisQuestion: true, + }, + ], + }, ]; - + // Act - wrapper.vm.handleAnswerUpdates(answerNo, '', wrapper.vm); + wrapper.vm.handleAnswerUpdates(answerNo, "", wrapper.vm); const nextQuestionAfterDuplicate = wrapper.vm.questionsData[1].questions[2]; - + // Assert expect(nextQuestionAfterDuplicate.suppressThisQuestion).not.toBeTruthy(); }); @@ -845,363 +847,376 @@ describe("vehicle-questions-mixin", () => { test("then the nextQuestionSequence should be updated and the original value saved", () => { // Arrange const answerNo = { - "answerResult": "456", - "answeredQuestions": [ + answerResult: "456", + answeredQuestions: [ { - "questionText": "Test question 3?", - "selectedAnswerText": "No", - "questionNum": 1, - } + questionText: "Test question 3?", + selectedAnswerText: "No", + questionNum: 1, + }, ], - "glassIndex": 0 + glassIndex: 0, }; const { wrapper } = setupMocks({}); - + wrapper.vm.questionsData = [ { - "glassLocation": "Windshield", - "glassName": "Single", - "questions": [ + glassLocation: "Windshield", + glassName: "Single", + questions: [ { - "questionSequence": 1, - "questionText": "Test question 3?", - "answers": [ + questionSequence: 1, + questionText: "Test question 3?", + answers: [ { - "answerResult": "123", - "answerText": "Yes", - "nextQuestionSequence": null + answerResult: "123", + answerText: "Yes", + nextQuestionSequence: null, }, { - "answerResult": "456", - "answerText": "No", - "nextQuestionSequence": null - } - ] + answerResult: "456", + answerText: "No", + nextQuestionSequence: null, + }, + ], }, - ] + ], }, { - "glassLocation": "Driver", - "glassName": "Front", - "questions": [ + glassLocation: "Driver", + glassName: "Front", + questions: [ { - "questionSequence": 1, - "questionText": "Test question 1?", - "answers": [ + questionSequence: 1, + questionText: "Test question 1?", + answers: [ { - "answerResult": "", - "answerText": "Yes", - "nextQuestionSequence": 2 + answerResult: "", + answerText: "Yes", + nextQuestionSequence: 2, }, { - "answerResult": "", - "answerText": "No", - "nextQuestionSequence": 3 - } - ] + answerResult: "", + answerText: "No", + nextQuestionSequence: 3, + }, + ], }, { - "questionSequence": 2, - "questionText": "Test question 2?", - "answers": [ + questionSequence: 2, + questionText: "Test question 2?", + answers: [ { - "answerResult": "123", - "answerText": "Yes", - "nextQuestionSequence": null + answerResult: "123", + answerText: "Yes", + nextQuestionSequence: null, }, { - "answerResult": "234", - "answerText": "No", - "nextQuestionSequence": null - } - ] + answerResult: "234", + answerText: "No", + nextQuestionSequence: null, + }, + ], }, { - "questionSequence": 3, - "questionText": "Test question 3?", - "answers": [ + questionSequence: 3, + questionText: "Test question 3?", + answers: [ { - "answerResult": "", - "answerText": "Yes", - "nextQuestionSequence": 4 + answerResult: "", + answerText: "Yes", + nextQuestionSequence: 4, }, { - "answerResult": "", - "answerText": "No", - "nextQuestionSequence": 5 - } - ] + answerResult: "", + answerText: "No", + nextQuestionSequence: 5, + }, + ], }, { - "questionSequence": 4, - "questionText": "Test question 4?", - "answers": [ + questionSequence: 4, + questionText: "Test question 4?", + answers: [ { - "answerResult": "567", - "answerText": "Yes", - "nextQuestionSequence": null + answerResult: "567", + answerText: "Yes", + nextQuestionSequence: null, }, { - "answerResult": "678", - "answerText": "No", - "nextQuestionSequence": null - } - ] + answerResult: "678", + answerText: "No", + nextQuestionSequence: null, + }, + ], }, { - "questionSequence": 5, - "questionText": "Test question 5?", - "answers": [ + questionSequence: 5, + questionText: "Test question 5?", + answers: [ { - "answerResult": "789", - "answerText": "Yes", - "nextQuestionSequence": null + answerResult: "789", + answerText: "Yes", + nextQuestionSequence: null, }, { - "answerResult": "890", - "answerText": "No", - "nextQuestionSequence": null - } - ] - } - ] - } + answerResult: "890", + answerText: "No", + nextQuestionSequence: null, + }, + ], + }, + ], + }, ]; - + // Act - wrapper.vm.handleAnswerUpdates(answerNo, '', wrapper.vm); + wrapper.vm.handleAnswerUpdates(answerNo, "", wrapper.vm); const duplicatedQuestion = wrapper.vm.questionsData[1].questions[2]; - const duplicatedQuestionAnswer = duplicatedQuestion.answers.filter(a => { + const duplicatedQuestionAnswer = duplicatedQuestion.answers.filter((a) => { return a.selected; - }) - const answerToTest = wrapper.vm.questionsData[1].questions[0].answers.filter(a => { - return a.originalNextQuestionSequence; }); - + const answerToTest = wrapper.vm.questionsData[1].questions[0].answers.filter( + (a) => { + return a.originalNextQuestionSequence; + } + ); + // Assert - expect(answerToTest[0].originalNextQuestionSequence).toEqual(duplicatedQuestion.questionSequence); - expect(answerToTest[0].nextQuestionSequence).toEqual(duplicatedQuestionAnswer[0].nextQuestionSequence); + expect(answerToTest[0].originalNextQuestionSequence).toEqual( + duplicatedQuestion.questionSequence + ); + expect(answerToTest[0].nextQuestionSequence).toEqual( + duplicatedQuestionAnswer[0].nextQuestionSequence + ); }); describe("and the duplicate was the first question for that part", () => { - test("then any questions up to the nextQuestionSequence value should be marked as suppressed", () => { // Arrange const answerNo = { - "answerResult": "456", - "answeredQuestions": [ + answerResult: "456", + answeredQuestions: [ { - "questionText": "Test duplicate question 1?", - "selectedAnswerText": "No", - "questionNum": 1, - } + questionText: "Test duplicate question 1?", + selectedAnswerText: "No", + questionNum: 1, + }, ], - "glassIndex": 0 + glassIndex: 0, }; const { wrapper } = setupMocks({}); - + wrapper.vm.questionsData = [ { - "glassLocation": "Windshield", - "glassName": "Single", - "questions": [ + glassLocation: "Windshield", + glassName: "Single", + questions: [ { - "questionSequence": 1, - "questionText": "Test duplicate question 1?", - "answers": [ + questionSequence: 1, + questionText: "Test duplicate question 1?", + answers: [ { - "answerResult": "123", - "answerText": "Yes", - "nextQuestionSequence": null + answerResult: "123", + answerText: "Yes", + nextQuestionSequence: null, }, { - "answerResult": "456", - "answerText": "No", - "nextQuestionSequence": null - } - ] + answerResult: "456", + answerText: "No", + nextQuestionSequence: null, + }, + ], }, - ] + ], }, { - "glassLocation": "Driver", - "glassName": "Front", - "questions": [ + glassLocation: "Driver", + glassName: "Front", + questions: [ { - "questionSequence": 1, - "questionText": "Test duplicate question 1?", - "answers": [ + questionSequence: 1, + questionText: "Test duplicate question 1?", + answers: [ { - "answerResult": "", - "answerText": "Yes", - "nextQuestionSequence": 2 + answerResult: "", + answerText: "Yes", + nextQuestionSequence: 2, }, { - "answerResult": "", - "answerText": "No", - "nextQuestionSequence": 3 - } - ] + answerResult: "", + answerText: "No", + nextQuestionSequence: 3, + }, + ], }, { - "questionSequence": 2, - "questionText": "Test question 2?", - "answers": [ + questionSequence: 2, + questionText: "Test question 2?", + answers: [ { - "answerResult": "123", - "answerText": "Yes", - "nextQuestionSequence": null + answerResult: "123", + answerText: "Yes", + nextQuestionSequence: null, }, { - "answerResult": "234", - "answerText": "No", - "nextQuestionSequence": null - } - ] + answerResult: "234", + answerText: "No", + nextQuestionSequence: null, + }, + ], }, { - "questionSequence": 3, - "questionText": "Test question 3?", - "answers": [ + questionSequence: 3, + questionText: "Test question 3?", + answers: [ { - "answerResult": "345", - "answerText": "Yes", - "nextQuestionSequence": null + answerResult: "345", + answerText: "Yes", + nextQuestionSequence: null, }, { - "answerResult": "456", - "answerText": "No", - "nextQuestionSequence": null - } - ] - } - ] - } + answerResult: "456", + answerText: "No", + nextQuestionSequence: null, + }, + ], + }, + ], + }, ]; - + // Act - wrapper.vm.handleAnswerUpdates(answerNo, '', wrapper.vm); - + wrapper.vm.handleAnswerUpdates(answerNo, "", wrapper.vm); + // Assert - expect(wrapper.vm.questionsData[1].questions[0].suppressThisQuestion).toBeTruthy(); - expect(wrapper.vm.questionsData[1].questions[1].suppressThisQuestion).toBeTruthy(); - expect(wrapper.vm.questionsData[1].questions[2].suppressThisQuestion).toBeFalsy(); + expect( + wrapper.vm.questionsData[1].questions[0].suppressThisQuestion + ).toBeTruthy(); + expect( + wrapper.vm.questionsData[1].questions[1].suppressThisQuestion + ).toBeTruthy(); + expect( + wrapper.vm.questionsData[1].questions[2].suppressThisQuestion + ).toBeFalsy(); }); - }); - }); describe("and the duplicate has an answerResult", () => { test("then any questions in the same glass piece that lead to the duplicate should be modified to just provide the duplicate's answerResult", async () => { // Arrange const answerNo = { - "answerResult": "456", - "answeredQuestions": [ + answerResult: "456", + answeredQuestions: [ { - "questionText": "Test question 3?", - "selectedAnswerText": "No", - "questionNum": 1, - } + questionText: "Test question 3?", + selectedAnswerText: "No", + questionNum: 1, + }, ], - "glassIndex": 0 + glassIndex: 0, }; const { wrapper } = setupMocks({}); - + wrapper.vm.questionsData = [ { - "glassLocation": "Windshield", - "glassName": "Single", - "questions": [ + glassLocation: "Windshield", + glassName: "Single", + questions: [ { - "questionSequence": 1, - "questionText": "Test question 3?", - "answers": [ + questionSequence: 1, + questionText: "Test question 3?", + answers: [ { - "answerResult": "123", - "answerText": "Yes", - "nextQuestionSequence": null + answerResult: "123", + answerText: "Yes", + nextQuestionSequence: null, }, { - "answerResult": "456", - "answerText": "No", - "nextQuestionSequence": null - } - ] + answerResult: "456", + answerText: "No", + nextQuestionSequence: null, + }, + ], }, - ] + ], }, { - "glassLocation": "Driver", - "glassName": "Front", - "questions": [ + glassLocation: "Driver", + glassName: "Front", + questions: [ { - "questionSequence": 1, - "questionText": "Test question 1?", - "answers": [ + questionSequence: 1, + questionText: "Test question 1?", + answers: [ { - "answerResult": "", - "answerText": "Yes", - "nextQuestionSequence": 2 + answerResult: "", + answerText: "Yes", + nextQuestionSequence: 2, }, { - "answerResult": "", - "answerText": "No", - "nextQuestionSequence": 3 - } - ] + answerResult: "", + answerText: "No", + nextQuestionSequence: 3, + }, + ], }, { - "questionSequence": 2, - "questionText": "Test question 2?", - "answers": [ + questionSequence: 2, + questionText: "Test question 2?", + answers: [ { - "answerResult": "123", - "answerText": "Yes", - "nextQuestionSequence": null + answerResult: "123", + answerText: "Yes", + nextQuestionSequence: null, }, { - "answerResult": "234", - "answerText": "No", - "nextQuestionSequence": null - } - ] + answerResult: "234", + answerText: "No", + nextQuestionSequence: null, + }, + ], }, { - "questionSequence": 3, - "questionText": "Test question 3?", - "answers": [ + questionSequence: 3, + questionText: "Test question 3?", + answers: [ { - "answerResult": "345", - "answerText": "Yes", - "nextQuestionSequence": null + answerResult: "345", + answerText: "Yes", + nextQuestionSequence: null, }, { - "answerResult": "456", - "answerText": "No", - "nextQuestionSequence": null - } - ] + answerResult: "456", + answerText: "No", + nextQuestionSequence: null, + }, + ], }, - ] - } + ], + }, ]; - + // Act - await wrapper.vm.handleAnswerUpdates(answerNo, '', wrapper.vm); - + await wrapper.vm.handleAnswerUpdates(answerNo, "", wrapper.vm); + const questionsToTest = wrapper.vm.questionsData[1].questions; const answerLeadingToDuplicate = questionsToTest[0].answers[1]; const duplicateQuestion = questionsToTest[2]; - const answerInDuplicateQuestion = duplicateQuestion.answers.filter(a => { + const answerInDuplicateQuestion = duplicateQuestion.answers.filter((a) => { return a.selected; - }) - + }); + // Assert - expect(answerLeadingToDuplicate.answerResult).toEqual(answerInDuplicateQuestion[0].answerResult); + expect(answerLeadingToDuplicate.answerResult).toEqual( + answerInDuplicateQuestion[0].answerResult + ); expect(answerLeadingToDuplicate.originalAnswerResult).toBeFalsy(); expect(answerLeadingToDuplicate.nextQuestionSequence).toEqual(null); - expect(answerLeadingToDuplicate.originalNextQuestionSequence).toEqual(duplicateQuestion.questionSequence); + expect(answerLeadingToDuplicate.originalNextQuestionSequence).toEqual( + duplicateQuestion.questionSequence + ); }); }); }); From 9d38856241a2d5c21dec162b5e4f74d22301caec Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Mon, 7 Nov 2022 11:15:15 -0500 Subject: [PATCH 07/11] CSR-803: correction and tweaking of names --- .../question-chain/question-chain.vue | 6 +++--- .../questions-page/questions-page.vue | 14 ++++++------- .../capability-questions.vue | 8 ++++---- .../molding-questions/molding-questions.vue | 8 ++++---- src/mixins/vehicle-questions-mixin.js | 8 ++++---- src/mixins/vehicle-questions-mixin.spec.js | 20 +++++++++---------- 6 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/common-components/question-chain/question-chain.vue b/src/common-components/question-chain/question-chain.vue index bc707f239..a5e2e8bbf 100644 --- a/src/common-components/question-chain/question-chain.vue +++ b/src/common-components/question-chain/question-chain.vue @@ -7,7 +7,7 @@ :class="q.questionSequence === currentQuestionNum && 'current-question'" :questionText="q.questionText" :answers="q.answers" - :groupName="`question-${glassIndex}-${q.questionSequence}`" + :groupName="`question-${glassPieceIndex}-${q.questionSequence}`" :modelValue="q.answerSelected" @update:modelValue="handleAnswer(q, $event)" isRequired @@ -32,7 +32,7 @@ export default { questionData: Object, validationRules: String, modelValue: Object, - glassIndex: Number, + glassPieceIndex: Number, answerKey: String, }, async created() { @@ -155,7 +155,7 @@ export default { return { answerResult: questionAnswer, answeredQuestions: answeredQuestions, - glassIndex: this.glassIndex, + glassPieceIndex: this.glassPieceIndex, }; } }, diff --git a/src/common-components/questions-page/questions-page.vue b/src/common-components/questions-page/questions-page.vue index 3d04f804d..42e1930b6 100644 --- a/src/common-components/questions-page/questions-page.vue +++ b/src/common-components/questions-page/questions-page.vue @@ -13,14 +13,14 @@ :manualHeadline="alertFewMoreQuestionsHeader" :manualCopy="alertFewMoreQuestionsCopy" v-bind:isDismissible="false" /> -
+
@@ -56,7 +56,7 @@ export default { data() { return { questionsData: [], - selectedAnswers2: {}, + selectedAnswers: {}, currentGlassPieceIndex: 0, }; }, @@ -82,13 +82,13 @@ export default { glass.questions = glass.capabilityQuestions; glass.answerKey = glass.glassLocation + "-" + glass.glassName; // reset selectedAnswers for this glass - this.selectedAnswers2[glass.answerKey] = []; + this.selectedAnswers[glass.answerKey] = []; const updatedGlass = this.setupInitialData(glass, i, alreadyAnsweredQuestions); // Set up watch for each set of glass questions this.$watch( - "selectedAnswers2." + glass.answerKey, + "selectedAnswers." + glass.answerKey, (newValue) => { if (newValue && Object.keys(newValue).length > 0) { this.handleAnswerUpdates(newValue, glass.answerKey); diff --git a/src/layouts/molding-questions/molding-questions.vue b/src/layouts/molding-questions/molding-questions.vue index 3670f9cc1..72e3f62ad 100644 --- a/src/layouts/molding-questions/molding-questions.vue +++ b/src/layouts/molding-questions/molding-questions.vue @@ -7,7 +7,7 @@ :alertFewMoreQuestionsCopy="AlertFewMoreQuestionsCopy" :questionsData="questionsData" :validationRules="questions - required" - v-model="selectedAnswers2" + v-model="selectedAnswers" @forwardButtonAction="forwardButtonAction" @backButtonAction="backButtonAction" :currentGlassPieceIndex="currentGlassPieceIndex" /> @@ -56,7 +56,7 @@ export default { data() { return { questionsData: [], - selectedAnswers2: {}, + selectedAnswers: {}, currentGlassPieceIndex: 0, }; }, @@ -82,12 +82,12 @@ export default { glass.questions = glass.parts[0].childPartQuestions; glass.answerKey = glass.glassLocation + "-" + glass.glassName; // reset selectedAnswers for this glass - this.selectedAnswers2[glass.answerKey] = []; + this.selectedAnswers[glass.answerKey] = []; const updatedGlass = this.setupInitialData(glass, i, alreadyAnsweredQuestions); this.$watch( - "selectedAnswers2." + glass.answerKey, + "selectedAnswers." + glass.answerKey, (newValue) => { if (newValue && Object.keys(newValue).length > 0) { this.handleAnswerUpdates(newValue, glass.answerKey); diff --git a/src/mixins/vehicle-questions-mixin.js b/src/mixins/vehicle-questions-mixin.js index 2d16dd2e4..2a8a1f891 100644 --- a/src/mixins/vehicle-questions-mixin.js +++ b/src/mixins/vehicle-questions-mixin.js @@ -158,7 +158,7 @@ export default { "questionNum": 1, } ], - "glassIndex": 0 + "glassPieceIndex": 0 } */ @@ -213,7 +213,7 @@ export default { */ // limit duplicate search to glass pieces that follow after the currently being answered glass piece - if (pieceIndex > answer.glassIndex) { + if (pieceIndex > answer.glassPieceIndex) { let indexToSuppressTo; // reset this glass piece, in case user is changing their previous answers glassPiece.answerData = null; @@ -341,13 +341,13 @@ export default { }); // set final answer data for the current answered glass part - self.questionsData[answer.glassIndex].answerData = { + self.questionsData[answer.glassPieceIndex].answerData = { answerResult: answer.answerResult, answeredQuestions: answer.answeredQuestions, }; // this part has been fully answered, so advance to next part's question chain - for (let i = answer.glassIndex + 1; i < this.questionsData.length; i++) { + for (let i = answer.glassPieceIndex + 1; i < this.questionsData.length; i++) { // if this part has not yet been fully answered, then make it the current part if (!this.questionsData[i].answerData?.answerResult) { this.currentGlassPieceIndex = i; diff --git a/src/mixins/vehicle-questions-mixin.spec.js b/src/mixins/vehicle-questions-mixin.spec.js index 4be7dec0f..dbbe3c64f 100644 --- a/src/mixins/vehicle-questions-mixin.spec.js +++ b/src/mixins/vehicle-questions-mixin.spec.js @@ -425,7 +425,7 @@ describe("vehicle-questions-mixin", () => { questionNum: 1, }, ], - glassIndex: 0, + glassPieceIndex: 0, }; const { wrapper } = setupMocks({}); @@ -459,7 +459,7 @@ describe("vehicle-questions-mixin", () => { questionNum: 1, }, ], - glassIndex: 0, + glassPieceIndex: 0, }; const { wrapper } = setupMocks({}); @@ -495,7 +495,7 @@ describe("vehicle-questions-mixin", () => { questionNum: 1, }, ], - glassIndex: 0, + glassPieceIndex: 0, }; const { wrapper } = setupMocks({}); @@ -532,7 +532,7 @@ describe("vehicle-questions-mixin", () => { questionNum: 1, }, ], - glassIndex: 0, + glassPieceIndex: 0, }; const { wrapper } = setupMocks({}); @@ -609,7 +609,7 @@ describe("vehicle-questions-mixin", () => { questionNum: 1, }, ], - glassIndex: 0, + glassPieceIndex: 0, }; const { wrapper } = setupMocks({}); @@ -681,7 +681,7 @@ describe("vehicle-questions-mixin", () => { questionNum: 1, }, ], - glassIndex: 0, + glassPieceIndex: 0, }; const { wrapper } = setupMocks({}); @@ -752,7 +752,7 @@ describe("vehicle-questions-mixin", () => { questionNum: 1, }, ], - glassIndex: 0, + glassPieceIndex: 0, }; const { wrapper } = setupMocks({}); @@ -855,7 +855,7 @@ describe("vehicle-questions-mixin", () => { questionNum: 1, }, ], - glassIndex: 0, + glassPieceIndex: 0, }; const { wrapper } = setupMocks({}); @@ -1003,7 +1003,7 @@ describe("vehicle-questions-mixin", () => { questionNum: 1, }, ], - glassIndex: 0, + glassPieceIndex: 0, }; const { wrapper } = setupMocks({}); @@ -1115,7 +1115,7 @@ describe("vehicle-questions-mixin", () => { questionNum: 1, }, ], - glassIndex: 0, + glassPieceIndex: 0, }; const { wrapper } = setupMocks({}); From d907080bf6cec5e5b5d1e11f5c6e8a8d40133611 Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Mon, 7 Nov 2022 11:37:53 -0500 Subject: [PATCH 08/11] CSR-803: rename tweaking, again --- .../question-chain/question-chain.vue | 2 +- .../questions-page/questions-page.vue | 10 +++++----- .../capability-questions.vue | 18 ++++++++--------- .../molding-questions/molding-questions.vue | 18 ++++++++--------- src/layouts/part-questions/part-questions.vue | 18 ++++++++--------- src/mixins/vehicle-questions-mixin.js | 8 ++++---- src/mixins/vehicle-questions-mixin.spec.js | 20 +++++++++---------- 7 files changed, 47 insertions(+), 47 deletions(-) diff --git a/src/common-components/question-chain/question-chain.vue b/src/common-components/question-chain/question-chain.vue index a5e2e8bbf..3f77a87be 100644 --- a/src/common-components/question-chain/question-chain.vue +++ b/src/common-components/question-chain/question-chain.vue @@ -155,7 +155,7 @@ export default { return { answerResult: questionAnswer, answeredQuestions: answeredQuestions, - glassPieceIndex: this.glassPieceIndex, + index: this.glassPieceIndex, }; } }, diff --git a/src/common-components/questions-page/questions-page.vue b/src/common-components/questions-page/questions-page.vue index 42e1930b6..de58727f6 100644 --- a/src/common-components/questions-page/questions-page.vue +++ b/src/common-components/questions-page/questions-page.vue @@ -13,14 +13,14 @@ :manualHeadline="alertFewMoreQuestionsHeader" :manualCopy="alertFewMoreQuestionsCopy" v-bind:isDismissible="false" /> -
+
x.capabilityQuestions) - .map((glass, i) => { + .map((glassPiece, i) => { // NOTE: questions for property "questions" can differ between layouts - glass.questions = glass.capabilityQuestions; - glass.answerKey = glass.glassLocation + "-" + glass.glassName; - // reset selectedAnswers for this glass - this.selectedAnswers[glass.answerKey] = []; + glassPiece.questions = glassPiece.capabilityQuestions; + glassPiece.answerKey = glassPiece.glassLocation + "-" + glassPiece.glassName; + // reset selectedAnswers for this glassPiece + this.selectedAnswers[glassPiece.answerKey] = []; - const updatedGlass = this.setupInitialData(glass, i, alreadyAnsweredQuestions); + const updatedGlassPiece = this.setupInitialData(glass, i, alreadyAnsweredQuestions); // Set up watch for each set of glass questions this.$watch( - "selectedAnswers." + glass.answerKey, + "selectedAnswers." + glassPiece.answerKey, (newValue) => { if (newValue && Object.keys(newValue).length > 0) { - this.handleAnswerUpdates(newValue, glass.answerKey); + this.handleAnswerUpdates(newValue, glassPiece.answerKey); } }, { deep: true } ); - return updatedGlass; + return updatedGlassPiece; }); }, methods: { diff --git a/src/layouts/molding-questions/molding-questions.vue b/src/layouts/molding-questions/molding-questions.vue index 72e3f62ad..d0e85e244 100644 --- a/src/layouts/molding-questions/molding-questions.vue +++ b/src/layouts/molding-questions/molding-questions.vue @@ -77,26 +77,26 @@ export default { this.questionsData = this.pageData.partsOrQuestions .filter((x) => x.parts[0].childPartQuestions.length) - .map((glass, i) => { + .map((glassPiece, i) => { // NOTE: questions for property "questions" can differ between layouts - glass.questions = glass.parts[0].childPartQuestions; - glass.answerKey = glass.glassLocation + "-" + glass.glassName; - // reset selectedAnswers for this glass - this.selectedAnswers[glass.answerKey] = []; + glassPiece.questions = glassPiece.parts[0].childPartQuestions; + glassPiece.answerKey = glassPiece.glassLocation + "-" + glassPiece.glassName; + // reset selectedAnswers for this glassPiece + this.selectedAnswers[glassPiece.answerKey] = []; - const updatedGlass = this.setupInitialData(glass, i, alreadyAnsweredQuestions); + const updatedGlassPiece = this.setupInitialData(glass, i, alreadyAnsweredQuestions); this.$watch( - "selectedAnswers." + glass.answerKey, + "selectedAnswers." + glassPiece.answerKey, (newValue) => { if (newValue && Object.keys(newValue).length > 0) { - this.handleAnswerUpdates(newValue, glass.answerKey); + this.handleAnswerUpdates(newValue, glassPiece.answerKey); } }, { deep: true } ); - return updatedGlass; + return updatedGlassPiece; }); }, methods: { diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue index 961fa825d..6034986a4 100644 --- a/src/layouts/part-questions/part-questions.vue +++ b/src/layouts/part-questions/part-questions.vue @@ -77,27 +77,27 @@ export default { this.questionsData = this.pageData.partsOrQuestions .filter((x) => x.partQuestions) - .map((glass, i) => { + .map((glassPiece, i) => { // NOTE: questions for property "questions" can differ between layouts - glass.questions = glass.partQuestions; - glass.answerKey = glass.glassLocation + "-" + glass.glassName; - // reset selectedAnswers for this glass - this.selectedAnswers[glass.answerKey] = []; + glassPiece.questions = glassPiece.partQuestions; + glassPiece.answerKey = glassPiece.glassLocation + "-" + glassPiece.glassName; + // reset selectedAnswers for this glassPiece + this.selectedAnswers[glassPiece.answerKey] = []; - const updatedGlass = this.setupInitialData(glass, i, alreadyAnsweredQuestions); + const updatedGlassPiece = this.setupInitialData(glass, i, alreadyAnsweredQuestions); // Set up watch for each set of glass questions this.$watch( - "selectedAnswers." + glass.answerKey, + "selectedAnswers." + glassPiece.answerKey, (newValue) => { if (newValue && Object.keys(newValue).length > 0) { - this.handleAnswerUpdates(newValue, glass.answerKey); + this.handleAnswerUpdates(newValue, glassPiece.answerKey); } }, { deep: true } ); - return updatedGlass; + return updatedGlassPiece; }); }, methods: { diff --git a/src/mixins/vehicle-questions-mixin.js b/src/mixins/vehicle-questions-mixin.js index 2a8a1f891..f54b462ee 100644 --- a/src/mixins/vehicle-questions-mixin.js +++ b/src/mixins/vehicle-questions-mixin.js @@ -158,7 +158,7 @@ export default { "questionNum": 1, } ], - "glassPieceIndex": 0 + "index": 0 } */ @@ -213,7 +213,7 @@ export default { */ // limit duplicate search to glass pieces that follow after the currently being answered glass piece - if (pieceIndex > answer.glassPieceIndex) { + if (pieceIndex > answer.index) { let indexToSuppressTo; // reset this glass piece, in case user is changing their previous answers glassPiece.answerData = null; @@ -341,13 +341,13 @@ export default { }); // set final answer data for the current answered glass part - self.questionsData[answer.glassPieceIndex].answerData = { + self.questionsData[answer.index].answerData = { answerResult: answer.answerResult, answeredQuestions: answer.answeredQuestions, }; // this part has been fully answered, so advance to next part's question chain - for (let i = answer.glassPieceIndex + 1; i < this.questionsData.length; i++) { + for (let i = answer.index + 1; i < this.questionsData.length; i++) { // if this part has not yet been fully answered, then make it the current part if (!this.questionsData[i].answerData?.answerResult) { this.currentGlassPieceIndex = i; diff --git a/src/mixins/vehicle-questions-mixin.spec.js b/src/mixins/vehicle-questions-mixin.spec.js index dbbe3c64f..6fb8f33d8 100644 --- a/src/mixins/vehicle-questions-mixin.spec.js +++ b/src/mixins/vehicle-questions-mixin.spec.js @@ -425,7 +425,7 @@ describe("vehicle-questions-mixin", () => { questionNum: 1, }, ], - glassPieceIndex: 0, + index: 0, }; const { wrapper } = setupMocks({}); @@ -459,7 +459,7 @@ describe("vehicle-questions-mixin", () => { questionNum: 1, }, ], - glassPieceIndex: 0, + index: 0, }; const { wrapper } = setupMocks({}); @@ -495,7 +495,7 @@ describe("vehicle-questions-mixin", () => { questionNum: 1, }, ], - glassPieceIndex: 0, + index: 0, }; const { wrapper } = setupMocks({}); @@ -532,7 +532,7 @@ describe("vehicle-questions-mixin", () => { questionNum: 1, }, ], - glassPieceIndex: 0, + index: 0, }; const { wrapper } = setupMocks({}); @@ -609,7 +609,7 @@ describe("vehicle-questions-mixin", () => { questionNum: 1, }, ], - glassPieceIndex: 0, + index: 0, }; const { wrapper } = setupMocks({}); @@ -681,7 +681,7 @@ describe("vehicle-questions-mixin", () => { questionNum: 1, }, ], - glassPieceIndex: 0, + index: 0, }; const { wrapper } = setupMocks({}); @@ -752,7 +752,7 @@ describe("vehicle-questions-mixin", () => { questionNum: 1, }, ], - glassPieceIndex: 0, + index: 0, }; const { wrapper } = setupMocks({}); @@ -855,7 +855,7 @@ describe("vehicle-questions-mixin", () => { questionNum: 1, }, ], - glassPieceIndex: 0, + index: 0, }; const { wrapper } = setupMocks({}); @@ -1003,7 +1003,7 @@ describe("vehicle-questions-mixin", () => { questionNum: 1, }, ], - glassPieceIndex: 0, + index: 0, }; const { wrapper } = setupMocks({}); @@ -1115,7 +1115,7 @@ describe("vehicle-questions-mixin", () => { questionNum: 1, }, ], - glassPieceIndex: 0, + index: 0, }; const { wrapper } = setupMocks({}); From 262980bfa355d3cb3135da624ad7ebca069c25d0 Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Mon, 7 Nov 2022 14:13:54 -0500 Subject: [PATCH 09/11] CSR-803: correct missing reference --- src/layouts/capability-questions/capability-questions.vue | 2 +- src/layouts/molding-questions/molding-questions.vue | 2 +- src/layouts/part-questions/part-questions.vue | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/layouts/capability-questions/capability-questions.vue b/src/layouts/capability-questions/capability-questions.vue index d90c2f777..c916cf99d 100644 --- a/src/layouts/capability-questions/capability-questions.vue +++ b/src/layouts/capability-questions/capability-questions.vue @@ -84,7 +84,7 @@ export default { // reset selectedAnswers for this glassPiece this.selectedAnswers[glassPiece.answerKey] = []; - const updatedGlassPiece = this.setupInitialData(glass, i, alreadyAnsweredQuestions); + const updatedGlassPiece = this.setupInitialData(glassPiece, i, alreadyAnsweredQuestions); // Set up watch for each set of glass questions this.$watch( diff --git a/src/layouts/molding-questions/molding-questions.vue b/src/layouts/molding-questions/molding-questions.vue index d0e85e244..9b0b39d81 100644 --- a/src/layouts/molding-questions/molding-questions.vue +++ b/src/layouts/molding-questions/molding-questions.vue @@ -84,7 +84,7 @@ export default { // reset selectedAnswers for this glassPiece this.selectedAnswers[glassPiece.answerKey] = []; - const updatedGlassPiece = this.setupInitialData(glass, i, alreadyAnsweredQuestions); + const updatedGlassPiece = this.setupInitialData(glassPiece, i, alreadyAnsweredQuestions); this.$watch( "selectedAnswers." + glassPiece.answerKey, diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue index 6034986a4..6b1ebb87f 100644 --- a/src/layouts/part-questions/part-questions.vue +++ b/src/layouts/part-questions/part-questions.vue @@ -84,7 +84,7 @@ export default { // reset selectedAnswers for this glassPiece this.selectedAnswers[glassPiece.answerKey] = []; - const updatedGlassPiece = this.setupInitialData(glass, i, alreadyAnsweredQuestions); + const updatedGlassPiece = this.setupInitialData(glassPiece, i, alreadyAnsweredQuestions); // Set up watch for each set of glass questions this.$watch( From b98f38e84d0210d3fe7c4c0c80a93bf1ff98a0bf Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Tue, 8 Nov 2022 09:24:43 -0500 Subject: [PATCH 10/11] CSR-803: prettier changes --- src/layouts/capability-questions/capability-questions.vue | 6 +++++- src/layouts/molding-questions/molding-questions.vue | 6 +++++- src/layouts/part-questions/part-questions.vue | 6 +++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/layouts/capability-questions/capability-questions.vue b/src/layouts/capability-questions/capability-questions.vue index c916cf99d..2f6fa4f74 100644 --- a/src/layouts/capability-questions/capability-questions.vue +++ b/src/layouts/capability-questions/capability-questions.vue @@ -84,7 +84,11 @@ export default { // reset selectedAnswers for this glassPiece this.selectedAnswers[glassPiece.answerKey] = []; - const updatedGlassPiece = this.setupInitialData(glassPiece, i, alreadyAnsweredQuestions); + const updatedGlassPiece = this.setupInitialData( + glassPiece, + i, + alreadyAnsweredQuestions + ); // Set up watch for each set of glass questions this.$watch( diff --git a/src/layouts/molding-questions/molding-questions.vue b/src/layouts/molding-questions/molding-questions.vue index 9b0b39d81..d0b7c93c4 100644 --- a/src/layouts/molding-questions/molding-questions.vue +++ b/src/layouts/molding-questions/molding-questions.vue @@ -84,7 +84,11 @@ export default { // reset selectedAnswers for this glassPiece this.selectedAnswers[glassPiece.answerKey] = []; - const updatedGlassPiece = this.setupInitialData(glassPiece, i, alreadyAnsweredQuestions); + const updatedGlassPiece = this.setupInitialData( + glassPiece, + i, + alreadyAnsweredQuestions + ); this.$watch( "selectedAnswers." + glassPiece.answerKey, diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue index 6b1ebb87f..6be2e8028 100644 --- a/src/layouts/part-questions/part-questions.vue +++ b/src/layouts/part-questions/part-questions.vue @@ -84,7 +84,11 @@ export default { // reset selectedAnswers for this glassPiece this.selectedAnswers[glassPiece.answerKey] = []; - const updatedGlassPiece = this.setupInitialData(glassPiece, i, alreadyAnsweredQuestions); + const updatedGlassPiece = this.setupInitialData( + glassPiece, + i, + alreadyAnsweredQuestions + ); // Set up watch for each set of glass questions this.$watch( From 2812c9e51134646b2e6ac830224931da6344df4f Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Wed, 9 Nov 2022 14:58:22 -0500 Subject: [PATCH 11/11] CSR-803: PR refactoring --- .../question-chain/question-chain.vue | 6 +-- .../questions-page-layout.vue} | 6 +-- .../capability-questions.vue | 34 +++++++--------- .../molding-questions/molding-questions.vue | 34 +++++++--------- src/layouts/part-questions/part-questions.vue | 40 +++++++++---------- src/mixins/vehicle-questions-mixin.js | 36 ++++++++--------- src/mixins/vehicle-questions-mixin.spec.js | 4 +- 7 files changed, 75 insertions(+), 85 deletions(-) rename src/common-components/{questions-page/questions-page.vue => questions-page-layout/questions-page-layout.vue} (95%) diff --git a/src/common-components/question-chain/question-chain.vue b/src/common-components/question-chain/question-chain.vue index 3f77a87be..432fd2eca 100644 --- a/src/common-components/question-chain/question-chain.vue +++ b/src/common-components/question-chain/question-chain.vue @@ -7,7 +7,7 @@ :class="q.questionSequence === currentQuestionNum && 'current-question'" :questionText="q.questionText" :answers="q.answers" - :groupName="`question-${glassPieceIndex}-${q.questionSequence}`" + :groupName="`question-${index}-${q.questionSequence}`" :modelValue="q.answerSelected" @update:modelValue="handleAnswer(q, $event)" isRequired @@ -32,7 +32,7 @@ export default { questionData: Object, validationRules: String, modelValue: Object, - glassPieceIndex: Number, + index: Number, answerKey: String, }, async created() { @@ -155,7 +155,7 @@ export default { return { answerResult: questionAnswer, answeredQuestions: answeredQuestions, - index: this.glassPieceIndex, + index: this.index, }; } }, diff --git a/src/common-components/questions-page/questions-page.vue b/src/common-components/questions-page-layout/questions-page-layout.vue similarity index 95% rename from src/common-components/questions-page/questions-page.vue rename to src/common-components/questions-page-layout/questions-page-layout.vue index de58727f6..85ccd33ad 100644 --- a/src/common-components/questions-page/questions-page.vue +++ b/src/common-components/questions-page-layout/questions-page-layout.vue @@ -18,7 +18,7 @@ ref="questionChain" v-model="selectedAnswers[questionsDatum.answerKey]" :questionData="questionsDatum.questions" - :glassPieceIndex="i" + :index="i" v-if="showThisQuestionChain(questionsDatum, i)" :answerKey="questionsDatum.answerKey" :validationRules="validationRules" /> @@ -52,7 +52,7 @@ export default { questionsData: Array, validationRules: String, modelValue: Array, - currentGlassPieceIndex: Number, + index: Number, }, computed: { selectedAnswers: { @@ -69,7 +69,7 @@ export default { if (!glass.questions || glass.questions?.length < 1 || glass.isSuppressedPart) { return false; } // return false if no questions or if suppressed - return this.currentGlassPieceIndex === i || glass.answerData?.answerResult?.length > 0; + return this.index === i || glass.answerData?.answerResult?.length > 0; }, handleForwardButtonAction() { this.$emit("forwardButtonAction"); diff --git a/src/layouts/capability-questions/capability-questions.vue b/src/layouts/capability-questions/capability-questions.vue index 2f6fa4f74..67b95a707 100644 --- a/src/layouts/capability-questions/capability-questions.vue +++ b/src/layouts/capability-questions/capability-questions.vue @@ -1,7 +1,7 @@ diff --git a/src/layouts/molding-questions/molding-questions.vue b/src/layouts/molding-questions/molding-questions.vue index d0b7c93c4..cfae7af71 100644 --- a/src/layouts/molding-questions/molding-questions.vue +++ b/src/layouts/molding-questions/molding-questions.vue @@ -1,7 +1,7 @@ diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue index 6be2e8028..9d1b54c66 100644 --- a/src/layouts/part-questions/part-questions.vue +++ b/src/layouts/part-questions/part-questions.vue @@ -1,7 +1,7 @@ diff --git a/src/mixins/vehicle-questions-mixin.js b/src/mixins/vehicle-questions-mixin.js index f54b462ee..a50a85755 100644 --- a/src/mixins/vehicle-questions-mixin.js +++ b/src/mixins/vehicle-questions-mixin.js @@ -66,7 +66,7 @@ export default { currentPageComesAfterPage(currentPage = this.$route.query.fmgPage, fmgPage) { return this.comparePageIndices(currentPage, fmgPage) > 0; }, - setupInitialData(glass, i, alreadyAnsweredQuestions, vm) { + setupInitialData(glass, index, alreadyAnsweredQuestions, vm) { const self = vm ?? this; // clear answerData if no questions are already answered @@ -124,8 +124,8 @@ export default { } }); - // advance the currentGlassPieceIndex - self.currentGlassPieceIndex = i; + // advance the currentGlassIndex + self.currentGlassIndex = index; const answerResult = answeredGlass.partNum ? answeredGlass.partNum @@ -182,9 +182,9 @@ export default { // HANDLE DUPLICATE QUESTIONS - // loop through all glass pieces data - self.questionsData.forEach((glassPiece, pieceIndex) => { - /* glassPiece example format: + // loop through all glass data + self.questionsData.forEach((glass, glassIndex) => { + /* glass example format: { "glassName": "Single", "glassLocation": "Windshield", @@ -213,14 +213,14 @@ export default { */ // limit duplicate search to glass pieces that follow after the currently being answered glass piece - if (pieceIndex > answer.index) { + if (glassIndex > answer.index) { let indexToSuppressTo; // reset this glass piece, in case user is changing their previous answers - glassPiece.answerData = null; - glassPiece.isSuppressedPart = null; + glass.answerData = null; + glass.isSuppressedPart = null; // loop through this glass piece's questions, looking for a questionText match - glassPiece.questions.forEach((question, questionIndex) => { + glass.questions.forEach((question, questionIndex) => { // clear out any previously set answers question.answerSelected = null; @@ -248,7 +248,7 @@ export default { // handle duplicate's nextQuestion logic on other related questions if (matchedAnswer.nextQuestionSequence) { // clear any suppression on the nextQuestion - glassPiece.questions[ + glass.questions[ matchedAnswer.nextQuestionSequence - 1 ].suppressThisQuestion = null; // if the duplicate is 1ST question in array, set indexToSuppressTo @@ -263,7 +263,7 @@ export default { } // update answers in this glass piece's questions with duplication logic modifications - glassPiece.questions.forEach((q) => { + glass.questions.forEach((q) => { q.answers.forEach((a) => { // revert any previously set nextQuestion logic modifications if ( @@ -305,7 +305,7 @@ export default { question.suppressThisQuestion = true; // are there any questions left that are not suppressed? - const remainingQuestions = glassPiece.questions.filter((q) => { + const remainingQuestions = glass.questions.filter((q) => { return !q.suppressThisQuestion; }); @@ -320,7 +320,7 @@ export default { suppressThisQuestion: question.suppressThisQuestion, }; // set the answerData (used as indicator that it has been already answered) - glassPiece.answerData = { + glass.answerData = { answerResult: matchedAnswer.nextQuestionSequence ? matchedAnswer.nextQuestionSequence : matchedAnswer.answerResult, @@ -328,14 +328,14 @@ export default { }; // suppress this glass piece because it has an answer - glassPiece.isSuppressedPart = true; + glass.isSuppressedPart = true; } } }); // Update key to force re-render of glass piece with duplicate question in case user changes previous related answer in the chain - self.questionsData[pieceIndex].key = - self.questionsData[pieceIndex].key + Date.now().toString(); + self.questionsData[glassIndex].key = + self.questionsData[glassIndex].key + Date.now().toString(); } }); }); @@ -350,7 +350,7 @@ export default { for (let i = answer.index + 1; i < this.questionsData.length; i++) { // if this part has not yet been fully answered, then make it the current part if (!this.questionsData[i].answerData?.answerResult) { - this.currentGlassPieceIndex = i; + this.currentGlassIndex = i; break; } } diff --git a/src/mixins/vehicle-questions-mixin.spec.js b/src/mixins/vehicle-questions-mixin.spec.js index 6fb8f33d8..873614fc4 100644 --- a/src/mixins/vehicle-questions-mixin.spec.js +++ b/src/mixins/vehicle-questions-mixin.spec.js @@ -664,10 +664,10 @@ describe("vehicle-questions-mixin", () => { // Act wrapper.vm.handleAnswerUpdates(answerNo, "", wrapper.vm); - const glassPieceWithDuplicate = wrapper.vm.questionsData[1]; + const glassWithDuplicate = wrapper.vm.questionsData[1]; // Assert - expect(glassPieceWithDuplicate.key).not.toBe("testkey2"); + expect(glassWithDuplicate.key).not.toBe("testkey2"); }); test("then that question should be supressed", () => {