CSR-111 Get part from capability question, save, reset answers when part question answer result changes

This commit is contained in:
Katie 2022-08-16 14:44:32 -04:00
parent 7584968143
commit d3f7ad68f2
9 changed files with 108 additions and 77 deletions

View file

@ -63,6 +63,10 @@ const endpoints = {
url: "/parts/api/v1/parts/capability-questions", url: "/parts/api/v1/parts/capability-questions",
method: "GET" method: "GET"
}, },
ApplyCapabilityAnswerToPart: {
url: "/parts/api/v1/parts/apply-capability-answer-to-part",
method: "POST"
},
SaveOrder: { SaveOrder: {
url: "/order/api/v1/order/save", url: "/order/api/v1/order/save",
method: "POST", method: "POST",

View file

@ -22,6 +22,7 @@ const storeActions = {
GET_PARTS_OR_QUESTIONS: "getPartsOrQuestions", GET_PARTS_OR_QUESTIONS: "getPartsOrQuestions",
GET_PARTS: "getParts", GET_PARTS: "getParts",
GET_CAPABILITY_QUESTIONS: "getCapabilityQuestions", GET_CAPABILITY_QUESTIONS: "getCapabilityQuestions",
GET_PART_FROM_CAPABILITY_QUESTION_ANSWER: "getPartFromCapabilityQuestionAnswer",
SAVE_ORDER: "saveOrder", SAVE_ORDER: "saveOrder",
LOAD_ORDER: "loadOrder", LOAD_ORDER: "loadOrder",
UPDATE_STORE_WITH_SAVE_ORDER_RESPONSE: "updateStoreWithSaveOrderResponse", UPDATE_STORE_WITH_SAVE_ORDER_RESPONSE: "updateStoreWithSaveOrderResponse",
@ -56,6 +57,7 @@ const storeActions = {
SAVE_REGISTRATION_ADDRESS_LOOKUP: "saveRegistrationAddressLookup", SAVE_REGISTRATION_ADDRESS_LOOKUP: "saveRegistrationAddressLookup",
SAVE_GLASS_PARTS: "saveGlassParts", SAVE_GLASS_PARTS: "saveGlassParts",
SAVE_PART_QUESTION_ANSWERS: "savePartQuestionAnswers", SAVE_PART_QUESTION_ANSWERS: "savePartQuestionAnswers",
SAVE_CAPABILITY_QUESTION_ANSWERS: "saveCapabilityQuestionAnswers"
}; };
export { storeActions }; export { storeActions };

View file

@ -17,6 +17,7 @@ const storeMutations = {
UPDATE_NUMBER_OF_CHIPS: "updateNumberOfChips", UPDATE_NUMBER_OF_CHIPS: "updateNumberOfChips",
UPDATE_GLASS_TO_REPLACE: "updateGlassToReplace", UPDATE_GLASS_TO_REPLACE: "updateGlassToReplace",
UPDATE_PART_QUESTION_ANSWERS: "updatePartQuestionAnswers", UPDATE_PART_QUESTION_ANSWERS: "updatePartQuestionAnswers",
UPDATE_CAPABILITY_QUESTION_ANSWERS: "updateCapabilityQuestionAnswers",
UPDATE_GLASS_PARTS: "updateGlassParts", UPDATE_GLASS_PARTS: "updateGlassParts",
UPDATE_OTHER_PARTS: "updateOtherParts", UPDATE_OTHER_PARTS: "updateOtherParts",

View file

@ -6,13 +6,10 @@
v-slot="{ meta }" v-slot="{ meta }"
> >
<div class="page-container-grouped-styles capability-questions"> <div class="page-container-grouped-styles capability-questions">
<loadingModal ref="loadingModal"/>
<funnelHeader cmsWidgetName="FunnelHeaderWidget" /> <funnelHeader cmsWidgetName="FunnelHeaderWidget" />
<vehicleBanner cmsWidgetName="VehicleBannerWidget" :displayGenericVehicleImage=false /> <vehicleBanner cmsWidgetName="VehicleBannerWidget" :displayGenericVehicleImage=false />
<funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" /> <funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" />
<div class="fade-on-route-transition sub-container make-tall"> <div class="fade-on-route-transition sub-container make-tall">
<h1>CAPABILITY QUESTIONS TEMPORARY PLACEHOLDER</h1>
CQD: {{ capabilityQuestionsData }}
<alert <alert
ref="alertFewMoreQuestions" ref="alertFewMoreQuestions"
class="my-5" class="my-5"
@ -21,15 +18,13 @@
:manualCopy="AlertFewMoreQuestionsCopy" :manualCopy="AlertFewMoreQuestionsCopy"
v-bind:isDismissible="false" v-bind:isDismissible="false"
/> />
<!-- <div v-for="(question, i) in capabilityQuestionsData" :key="i"> --> <questionChain
<questionChain ref="questionChain"
ref="questionChain" v-model="selectedAnswer"
v-model="selectedModel" :questionData="capabilityQuestionsData"
:questionData="capabilityQuestionsData" :partIndex="i"
:partIndex="i" validationRules="questions-required"
validationRules="questions-required" />
/>
<!-- </div> -->
<funnel-footer <funnel-footer
ref="funnelFooter" ref="funnelFooter"
cmsWidgetName="FunnelFooterWidget" cmsWidgetName="FunnelFooterWidget"
@ -63,6 +58,7 @@ import { Form, defineRule } from "vee-validate";
import { required } from "@/helpers/validation-rules"; import { required } from "@/helpers/validation-rules";
import { errorMessages } from "@/constants/error-messages"; import { errorMessages } from "@/constants/error-messages";
import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin"; import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin";
import { damageLocationsSelected } from "@/constants/damage-locations-selected";
// DEFINE VALIDATION RULES // DEFINE VALIDATION RULES
defineRule("questions-required", required(errorMessages.OPTION_REQUIRED)); defineRule("questions-required", required(errorMessages.OPTION_REQUIRED));
@ -73,7 +69,6 @@ export default {
async beforeRouteEnter(to, from, next) { async beforeRouteEnter(to, from, next) {
// Call APIs // Call APIs
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage); const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
const getCapabilityQuestions = store.dispatch(storeActions.GET_CAPABILITY_QUESTIONS, store.getters.pageData(fmgPageValues.CAPABILITY_QUESTIONS));
// Settle promises and get results // Settle promises and get results
const promiseResultMap = [ const promiseResultMap = [
@ -81,10 +76,6 @@ export default {
resultKey: "cmsContent", resultKey: "cmsContent",
promise: cmsContentPromise, promise: cmsContentPromise,
}, },
{
resultKey: "capabilityQuestions",
promise: getCapabilityQuestions,
},
]; ];
const resultMap = await settleAllPromises(promiseResultMap); const resultMap = await settleAllPromises(promiseResultMap);
@ -92,72 +83,57 @@ export default {
// Call the "next" function to complete the transition to this page. // Call the "next" function to complete the transition to this page.
next((vm) => { next((vm) => {
vm.setCmsContent(resultMap.cmsContent); vm.setCmsContent(resultMap.cmsContent);
resultMap.capabilityQuestions.forEach(question => {
console.log(question.answers)
question.answers = question.answers.map(answer => {
return {
...answer,
answerResult: answer.answerResult1
}
})
// question.answers = question.answers
})
vm.capabilityQuestionsData = {
partQuestions: resultMap.capabilityQuestions
};
console.log("CQ: ", resultMap.capabilityQuestions)
}); });
}, },
data() { data() {
return { return {
selectedModel: [], selectedAnswer: [],
capabilityQuestionsData: [], // TODO This shouldn't be an object with property `partQuestions`
currentPartNum: 0, capabilityQuestionsData: {
partQuestions: store.getters.pageData(fmgPageValues.CAPABILITY_QUESTIONS).capabilityQuestions
}
}; };
}, },
computed: { computed: {
AlertFewMoreQuestionsHeader() { AlertFewMoreQuestionsHeader() {
return this.getCmsContent("AlertPartsQuestions", "HeadlineText"); return this.getCmsContent("AdditionalPartsQuestionsAlert", "HeadlineText");
}, },
AlertFewMoreQuestionsCopy() { AlertFewMoreQuestionsCopy() {
return this.getCmsContent("AlertPartsQuestions", "BodyText"); 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);
}
}, },
methods: { methods: {
arePagePrerequisitesValid() { arePagePrerequisitesValid() {
const capabilityQuestionsPageData = store.getters.pageData(fmgPageValues.CAPABILITY_QUESTIONS); const capabilityQuestionsPageData = store.getters.pageData(fmgPageValues.CAPABILITY_QUESTIONS);
return capabilityQuestionsPageData && Object.keys(capabilityQuestionsPageData).length > 0; return capabilityQuestionsPageData && Object.keys(capabilityQuestionsPageData).length > 0;
}, },
showThisPartQuestionChain(part, i) {
if (part.partQuestions?.length < 1) { return false; } // return false if only one partQuestion
if (this.currentPartNum === i || part.answerData?.answerResult.length > 0) { return true; }
return false;
},
// backButtonAction() {
// // route to move backwards
// this.$router.navigate(
// this.navigationScenarios.CLICKED_BACK,
// this.$route
// );
// },
async forwardButtonAction() { async forwardButtonAction() {
// TODO: TO COME console.log(this.windshieldPartInfo);
// if questions are answered: console.log(this.selectedAnswer)
const selectedAnswerResult1 = this.selectedAnswer.answerResult;
const selectedAnswerResult2 = this.pageData.capabilityQuestions[0].answers.find(x => x.answerResult1 === selectedAnswerResult1).answerResult2;
this.$router.navigate( this.dispatchStoreAction(storeActions.SAVE_CAPABILITY_QUESTION_ANSWERS, {
this.navigationScenarios.CLICKED_FORWARD, glassName: this.windshieldPart.glassName,
this.$route glassLocation: this.windshieldPart.glassLocation,
); result1: selectedAnswerResult1,
}, result2: selectedAnswerResult2
}, });
watch: {
selectedModel(model) { const partFromCapabilityQuestionAnswer = (await this.dispatchStoreAction(storeActions.GET_PART_FROM_CAPABILITY_QUESTION_ANSWER)).data;
this.capabilityQuestionsData[model.partIndex].answerData = { let partsOrQuestions = this.pageData.partsOrQuestions;
answerResult: model.answerResult, partsOrQuestions.find(partOrQuestion => partOrQuestion.glassLocation === damageLocationsSelected.WINDSHIELD).parts = partFromCapabilityQuestionAnswer;
answeredQuestions: model.answeredQuestions,
} this.navigateForward(partsOrQuestions);
this.currentPartNum = model.partIndex + 1;
}, },
}, },
components: { components: {

View file

@ -3,6 +3,8 @@ import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigat
import { storeMutations } from "@/constants/store-mutations.js"; import { storeMutations } from "@/constants/store-mutations.js";
import { damageLocationsSelected } from "@/constants/damage-locations-selected"; import { damageLocationsSelected } from "@/constants/damage-locations-selected";
import { navigationScenarios } from "../router/router-constants/navigation-scenarios"; import { navigationScenarios } from "../router/router-constants/navigation-scenarios";
import { storeActions } from "@/constants/store-actions";
import store from "@/store";
export default { export default {
methods: { methods: {
@ -22,6 +24,7 @@ export default {
return pq.parts?.some(part => part.requiresCapabilityQuestions === true); return pq.parts?.some(part => part.requiresCapabilityQuestions === true);
}); });
}, },
// method to only include keys listed for lineItems.glassParts in // method to only include keys listed for lineItems.glassParts in
// https://safelite.atlassian.net/wiki/spaces/DC/pages/17137665/Catalog+Front-End+State#glassParts // https://safelite.atlassian.net/wiki/spaces/DC/pages/17137665/Catalog+Front-End+State#glassParts
reducedGlassPartsArray(glassParts) { reducedGlassPartsArray(glassParts) {
@ -63,7 +66,7 @@ export default {
return this.comparePageIndices(currentPage, fmgPage) > 0; return this.comparePageIndices(currentPage, fmgPage) > 0;
}, },
// Can't use `this` because navigateForward is also called from vin-pages-mixin // Can't use `this` because navigateForward is also called from vin-pages-mixin
navigateForward(partsOrQuestions, vm) { async navigateForward(partsOrQuestions, vm) {
const self = vm ?? this; const self = vm ?? this;
const currentPage = self.$route.query.fmgPage; const currentPage = self.$route.query.fmgPage;
@ -86,18 +89,30 @@ export default {
} else if (hasCapabilityQuestions && this.currentPageComesBeforePage(currentPage, fmgPageValues.CAPABILITY_QUESTIONS)) { } else if (hasCapabilityQuestions && this.currentPageComesBeforePage(currentPage, fmgPageValues.CAPABILITY_QUESTIONS)) {
// if has capability questions // if has capability questions
// go to capability-questions page and pass the partsData // go to capability-questions page and pass the partsData
self.$router.navigate(self.navigationScenarios.HAS_CAPABILITY_QUESTIONS, self.$route, {}, {}, {
carId: self.$store.getters.vehicle.carId, const windshieldPart = partsOrQuestions.filter(x => x.glassLocation === damageLocationsSelected.WINDSHIELD)[0].parts[0];
partNumber: partsOrQuestions.filter(x => x.glassLocation === damageLocationsSelected.WINDSHIELD)[0].parts[0].partNumber let capabilityQuestions = (await store.dispatch(storeActions.GET_CAPABILITY_QUESTIONS, {
carId: store.getters.vehicle.carId,
partNumber: windshieldPart.partNumber
})).data;
capabilityQuestions.forEach(question => {
question.answers = question.answers.map(answer => {
return {
...answer,
answerResult: answer.answerResult1
}
})
}); });
self.$router.navigate(self.navigationScenarios.HAS_CAPABILITY_QUESTIONS, self.$route, {}, {}, { partsOrQuestions, capabilityQuestions });
} else { } else {
// if single parts only // if single parts only
const collectedGlassParts = this.reducedGlassPartsArray(partsOrQuestions); const collectedGlassParts = this.reducedGlassPartsArray(partsOrQuestions);
// save to store lineItems.glassParts // save to store lineItems.glassParts
self.$store.commit(storeMutations.UPDATE_GLASS_PARTS, collectedGlassParts); self.$store.commit(storeMutations.UPDATE_GLASS_PARTS, collectedGlassParts);
// go to heritage quote page
self.$refs.loadingModal.showModal(); self.$router.navigate(self.navigationScenarios.ANSWERED_ALL_QUESTIONS, self.$route);
navigateToHeritageFunnel();
} }
}, },
backButtonAction() { backButtonAction() {

View file

@ -4,7 +4,6 @@ import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigat
import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin"; import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin";
export default { export default {
mixins: [vehicleQuestionsMixin],
methods: { methods: {
async navigateForwardWithSingleCarMatch() { async navigateForwardWithSingleCarMatch() {
const result = await this.dispatchStoreAction(storeActions.GET_PARTS_OR_QUESTIONS); const result = await this.dispatchStoreAction(storeActions.GET_PARTS_OR_QUESTIONS);

View file

@ -24,6 +24,7 @@ const navigationScenarios = {
SELECTED_PROVIDE_VIN_DIFFERENT_WAY: "SELECTED_PROVIDE_VIN_DIFFERENT_WAY", SELECTED_PROVIDE_VIN_DIFFERENT_WAY: "SELECTED_PROVIDE_VIN_DIFFERENT_WAY",
CLICKED_BACK_WITH_PART_QUESTION_ANSWERS: "CLICKED_BACK_WITH_PART_QUESTION_ANSWERS", CLICKED_BACK_WITH_PART_QUESTION_ANSWERS: "CLICKED_BACK_WITH_PART_QUESTION_ANSWERS",
CLICKED_BACK_WITHOUT_PART_QUESTION_ANSWERS: "CLICKED_BACK_WITHOUT_PART_QUESTION_ANSWERS", CLICKED_BACK_WITHOUT_PART_QUESTION_ANSWERS: "CLICKED_BACK_WITHOUT_PART_QUESTION_ANSWERS",
ANSWERED_ALL_QUESTIONS: "ANSWERED_ALL_QUESTIONS",
HAS_PART_QUESTIONS: "HAS_PART_QUESTIONS", HAS_PART_QUESTIONS: "HAS_PART_QUESTIONS",
HAS_MULTIPLE_PARTS_TO_CHOOSE: "HAS_MULTIPLE_PARTS_TO_CHOOSE", HAS_MULTIPLE_PARTS_TO_CHOOSE: "HAS_MULTIPLE_PARTS_TO_CHOOSE",
HAS_MOLDING_QUESTIONS: "HAS_MOLDING_QUESTIONS", HAS_MOLDING_QUESTIONS: "HAS_MOLDING_QUESTIONS",

View file

@ -251,7 +251,7 @@ const routingTable = function(store) {
destinationFmgPageValue: fmgPageValues.CAPABILITY_QUESTIONS, destinationFmgPageValue: fmgPageValues.CAPABILITY_QUESTIONS,
}, },
{ {
scenario: navigationScenarios.ANSWERED_QUESTIONS_WITH_SINGLE_PART, scenario: navigationScenarios.ANSWERED_ALL_QUESTIONS,
destinationFmgPageValue: fmgPageValues.QUOTE, destinationFmgPageValue: fmgPageValues.QUOTE,
}, },
] ]
@ -284,7 +284,7 @@ const routingTable = function(store) {
destinationFmgPageValue: fmgPageValues.CAPABILITY_QUESTIONS, destinationFmgPageValue: fmgPageValues.CAPABILITY_QUESTIONS,
}, },
{ {
scenario: navigationScenarios.ANSWERED_QUESTIONS_WITH_SINGLE_PART, scenario: navigationScenarios.ANSWERED_ALL_QUESTIONS,
destinationFmgPageValue: fmgPageValues.QUOTE, destinationFmgPageValue: fmgPageValues.QUOTE,
}, },
], ],
@ -309,7 +309,7 @@ const routingTable = function(store) {
destinationFmgPageValue: fmgPageValues.CAPABILITY_QUESTIONS, destinationFmgPageValue: fmgPageValues.CAPABILITY_QUESTIONS,
}, },
{ {
scenario: navigationScenarios.ANSWERED_QUESTIONS_WITH_SINGLE_PART, scenario: navigationScenarios.ANSWERED_ALL_QUESTIONS,
destinationFmgPageValue: fmgPageValues.QUOTE, destinationFmgPageValue: fmgPageValues.QUOTE,
} }
] ]
@ -334,7 +334,7 @@ const routingTable = function(store) {
destinationFmgPageValue: fmgPageValues.MOLDING_QUESTIONS destinationFmgPageValue: fmgPageValues.MOLDING_QUESTIONS
}, },
{ {
scenario: navigationScenarios.CLICKED_FORWARD, scenario: navigationScenarios.ANSWERED_ALL_QUESTIONS,
destinationFmgPageValue: fmgPageValues.QUOTE destinationFmgPageValue: fmgPageValues.QUOTE
}, },
] ]

View file

@ -49,6 +49,7 @@ const getDefaultState = () => {
numberOfChips: null, numberOfChips: null,
glassToReplace: null, glassToReplace: null,
partQuestionAnswers: null, partQuestionAnswers: null,
capabilityQuestionAnswers: null
}, },
lineItems: { lineItems: {
glassParts: null glassParts: null
@ -126,6 +127,9 @@ export const mutations = {
updatePartQuestionAnswers(state, answersArray) { updatePartQuestionAnswers(state, answersArray) {
state.order.damage.partQuestionAnswers = answersArray; state.order.damage.partQuestionAnswers = answersArray;
}, },
updateCapabilityQuestionAnswers(state, answersArray) {
state.order.damage.capabilityQuestionAnswers = answersArray;
},
updateGlassParts(state, partsData) { updateGlassParts(state, partsData) {
state.order.lineItems.glassParts = partsData; state.order.lineItems.glassParts = partsData;
}, },
@ -277,6 +281,7 @@ export const mutations = {
resetGlassPartsState(state) { resetGlassPartsState(state) {
state.order.lineItems.glassParts = null; state.order.lineItems.glassParts = null;
state.order.damage.partQuestionAnswers = null; state.order.damage.partQuestionAnswers = null;
state.order.damage.capabilityQuestionAnswers = null;
state.applicationUser.pageData[fmgPageValues.PART_QUESTIONS] = null; state.applicationUser.pageData[fmgPageValues.PART_QUESTIONS] = null;
state.applicationUser.pageData[fmgPageValues.VEHICLE_PARTS] = null; state.applicationUser.pageData[fmgPageValues.VEHICLE_PARTS] = null;
state.applicationUser.pageData[fmgPageValues.MOLDING_QUESTIONS] = null; state.applicationUser.pageData[fmgPageValues.MOLDING_QUESTIONS] = null;
@ -729,6 +734,22 @@ export const actions = {
}) })
}, },
getPartFromCapabilityQuestionAnswer(context, selectedAnswerResult1) {
const pageData = context.getters.pageData(fmgPageValues.CAPABILITY_QUESTIONS);
const part = pageData.partsOrQuestions.find(x => x.glassLocation === damageLocationsSelected.WINDSHIELD).parts[0];
const capabilityQuestionAnswers = context.getters.damage.capabilityQuestionAnswers;
return globalMethods.callHttpClient({
method: endpoints.ApplyCapabilityAnswerToPart.method,
endpoint: endpoints.ApplyCapabilityAnswerToPart.url,
payload: {
part,
capabilityAnswerResults: capabilityQuestionAnswers
}
})
},
// Order API Actions // Order API Actions
saveOrder(context) { saveOrder(context) {
const vehicle = context.getters.vehicle; const vehicle = context.getters.vehicle;
@ -958,10 +979,22 @@ export const actions = {
} }
}, },
savePartQuestionAnswers(context, partQuestionAnswersArray) { savePartQuestionAnswers(context, partQuestionAnswersArray) {
// if part question answers have changed, reset subsequent question answers
const previousResultsArray = context.getters.damage.partQuestionAnswers;
const havePartQuestionAnswersChanged = previousResultsArray.length !== partQuestionAnswersArray.length ||
!previousResultsArray.every((x, i) => x.result === partQuestionAnswersArray[i].result);
if (havePartQuestionAnswersChanged) {
context.commit(storeMutations.UPDATE_CAPABILITY_QUESTION_ANSWERS, null);
}
//Save new values //Save new values
context.commit(storeMutations.UPDATE_PART_QUESTION_ANSWERS, partQuestionAnswersArray); context.commit(storeMutations.UPDATE_PART_QUESTION_ANSWERS, partQuestionAnswersArray);
}, },
saveCapabilityQuestionAnswers(context, capabilityQuestionAnswers) {
//Save new values
context.commit(storeMutations.UPDATE_CAPABILITY_QUESTION_ANSWERS, capabilityQuestionAnswers);
},
// Misc order actions // Misc order actions
saveServiceLocation(context, serviceLocationInfo) { saveServiceLocation(context, serviceLocationInfo) {
context.commit(storeMutations.UPDATE_SERVICE_LOCATION, serviceLocationInfo); context.commit(storeMutations.UPDATE_SERVICE_LOCATION, serviceLocationInfo);