Merge pull request #561 from Safelite/feature/CSR-480

Feature/CSR-480
This commit is contained in:
AdamCaouetteSafelite 2022-06-15 11:13:32 -04:00 committed by GitHub
commit 1f450d1a0b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 159 additions and 17 deletions

View file

@ -23,6 +23,7 @@ module.exports = {
"!src/layouts/address-vehicles/address-vehicles-question/address-vehicles-question.vue",
"!src/ux-components/alert/alert.vue",
"!src/helpers/validation-rules.js",
"!src/common-components/question-chain/question-chain",
// END
], // ! means exclude from coverage.
testMatch: ["**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"],

View file

@ -112,7 +112,8 @@ describe("buttonQuestion.vue", () => {
const wrapper = shallowMount(buttonQuestion, setupMocks({}));
await wrapper.setProps({
answers: ["2022", "2021", "2020"],
isMultiSelect: false
isMultiSelect: false,
modelValue: []
});
const val = { checkValue: true, value: "2021", }
wrapper.vm.handleCheckedChanged(val);

View file

@ -36,6 +36,7 @@
data-test="button"
:validationRules="validationRules"
:class="[suppressError ? 'alertError' : '']"
:clearOnUnmount="clearOnUnmount"
/>
</div>
</fieldset>
@ -84,6 +85,10 @@ export default {
validationRules: String,
suppressError: Boolean,
useTextForValue: Boolean,
clearOnUnmount: {
type: Boolean,
default: true
}
},
computed: {
getFieldSetClasses() {
@ -133,17 +138,14 @@ export default {
return answer.Name ? answer.Name : answer;
},
handleCheckedChanged(val) {
if(this.isMultiSelect && this.selectedValues) {
// Add or remove item to array of data to emit
const newSelectedValues = this.selectedValues;
if(this.selectingInitiatesLoad) {
this.selectedValues = [val.value];
} else {
if(Array.isArray(this.selectedValues)) {
const newSelectedValues = this.selectedValues;
val.checkValue ? newSelectedValues.push(val.value) : newSelectedValues.splice(newSelectedValues.indexOf(val.value), 1);
this.selectedValues = newSelectedValues;
}
} else {
this.selectedValues = [val.value];
}
},
},

View file

@ -0,0 +1,119 @@
<template>
<div v-for="(q, i) in questions" :key="i">
<transition appear name="fade" mode="out-in">
<buttonQuestion
v-if="q.questionSequence === currentQuestion"
class="radioQuestion"
:questionText="q.questionText"
:answers="q.answers"
:groupName="`${questionData.glassName}-${questionData.glassLocation}-${i}`"
textPosition="text-start"
v-model="selectedValue"
isRequired=true
:validationRules="validationRules"
:clearOnUnmount=false
/>
</transition>
</div>
</template>
<script>
import buttonQuestion from "@/common-components/button-question/button-question";
export default {
name: "questionChain",
data() {
return {
models: Array,
currentQuestion: 1,
answeredQuestions: [],
};
},
props: {
questionData: Array,
validationRules: String,
modelValue: String,
},
computed: {
questions() {
const questions = this.questionData.partQuestions.map((q, i) => {
return {
questionText: q.questionText,
questionSequence: q.questionSequence,
answers: q.answers.map((a) => {
return {
Text: a.answerText,
// Name will either be nextQuestionSequence or answerResult
Name: a.nextQuestionSequence ? a.nextQuestionSequence : "answer-" + a.answerResult,
nextQuestionSequence: a.nextQuestionSequence,
answerResult: a.answerResult,
}
})
}
});
// add an empty item to be array[0] since we start with 1
questions.unshift({});
return questions;
},
selectedValue: {
get: function() {
return this.modelValue;
},
set: function(returnedAnswer) {
const isNewModelValueComplete = this.getNewModelValue(returnedAnswer);
if (isNewModelValueComplete) {
this.$emit("update:modelValue", isNewModelValueComplete);
}
}
}
},
methods: {
getNewModelValue(returnedAnswer) {
if (!returnedAnswer || !Array.isArray(returnedAnswer)) { return false }
const lastAnswer = returnedAnswer[returnedAnswer.length - 1];
const currentQuestion = this.questions[this.currentQuestion];
if (lastAnswer.indexOf("answer-") === 0) {
// if it is an answerResult
const finalAnswer = lastAnswer.slice(7);
const currentQuestionSelectedAnswer = currentQuestion.answers.find(
({ answerResult }) => answerResult === finalAnswer
);
// add current item to list of answered questions
this.answeredQuestions.push(
{
questionText: currentQuestion.questionText,
selectedAnswerText: currentQuestionSelectedAnswer.Text,
}
);
return {
answerResult: finalAnswer,
answeredQuestions: this.answeredQuestions,
};
} else {
const currentQuestionSelectedAnswer = currentQuestion.answers.find(
({ nextQuestionSequence }) => nextQuestionSequence === parseInt(lastAnswer)
);
// add current item to list of answered questions
this.answeredQuestions.push(
{
questionText: currentQuestion.questionText,
selectedAnswerText: currentQuestionSelectedAnswer.Text,
}
);
this.currentQuestion = parseInt(lastAnswer); // update count to display next question
return false;
}
}
},
components: {
buttonQuestion,
},
};
</script>

View file

@ -46,6 +46,7 @@ const routes = [
// If the saved session has timed out, clear the session, execute 404 logic.
if (getFunnelCookie() !== null && !isSavedSessionStillActive()) {
await baseMixin.methods.dispatchStoreAction(storeActions.RESET_STATE);
await GoToFunnelStartOn404(next);
}

View file

@ -78,6 +78,10 @@ export default {
validationRules: String,
selectedValues: [Array, String],
hasError: Boolean,
clearOnUnmount: {
type: Boolean,
default: true
}
},
data() {
return {
@ -92,9 +96,11 @@ export default {
: this.selectedValues[0];
}
},
unmounted() { // needed to clear this button's selectedValues if it is removed
this.checkValue = false;
this.handleCheckChange();
unmounted() { // needed to clear this button's selectedValues if it is removed to keep validation in sync
if (this.clearOnUnmount) {
this.checkValue = false;
this.handleCheckChange();
}
},
methods: {
displayLoader() {

View file

@ -78,6 +78,10 @@ export default {
validationRules: String,
selectedValues: [Array, String],
hasError: Boolean,
clearOnUnmount: {
type: Boolean,
default: true
}
},
data() {
return {
@ -92,9 +96,11 @@ export default {
: this.selectedValues[0];
}
},
unmounted() { // needed to clear this button's selectedValues if it is removed
this.checkValue = false;
this.handleCheckChange();
unmounted() { // needed to clear this button's selectedValues if it is removed to keep validation in sync
if (this.clearOnUnmount) {
this.checkValue = false;
this.handleCheckChange();
}
},
methods: {
displayLoader() {

View file

@ -86,6 +86,10 @@ export default {
selectedValues: [Array, String],
modelValue: Object,
hasError: Boolean,
clearOnUnmount: {
type: Boolean,
default: true
}
},
data() {
return {
@ -99,9 +103,11 @@ export default {
: this.selectedValues[0];
}
},
unmounted() { // needed to clear this button's selectedValues if it is removed
this.checkValue = false;
this.handleCheckChange();
unmounted() { // needed to clear this button's selectedValues if it is removed to keep validation in sync
if (this.clearOnUnmount) {
this.checkValue = false;
this.handleCheckChange();
}
},
computed: {
getLabelClasses() {