CSR-343 Fix reloading/repopulating and CSS

This commit is contained in:
Katie 2022-06-28 17:46:05 -04:00
parent 06335ba625
commit 8fe1dd8d7b
6 changed files with 110 additions and 114 deletions

View file

@ -5,8 +5,8 @@
<span class="fs-5 fw-bold w-100">{{ questionText }}</span>
</div>
<div class="w-100 d-flex justify-content-center">
<fieldset class="w-100" :aria-required=isRequired :class="getFieldSetClasses" :role="isMultiSelect ? 'group' : 'radiogroup'" :aria-labelledby="groupName">
<legend class="sr-only" :data-focus-target="groupName" :id="groupName" tabindex="-1">
<fieldset class="w-100" :aria-required=isRequired :class="getFieldSetClasses" :role="isMultiSelect ? 'group' : 'radiogroup'" :aria-labelledby="formattedGroupName">
<legend class="sr-only" :data-focus-target="formattedGroupName" :id="formattedGroupName" tabindex="-1">
{{(isMultiSelect && answers && answers.length > 1) ? 'Select one or more options below.' : 'Select an option below.' }}
</legend>
<div :class="getComponentLoopWrapperClasses">
@ -14,13 +14,13 @@
<component
:is="buttonType"
@isCheckedChanged="handleCheckedChanged"
:buttonID="answer.Name ? groupName + '-' + answer.Name : groupName + '-' + answer"
:buttonID="answer.Name ? formattedGroupName + '-' + answer.Name : formattedGroupName + '-' + answer"
:value="getValues(answer)"
:buttonLabel="answer.Text ? answer.Text : answer"
:buttonLabelSubCopy="answer.SubText"
:textPosition="textPosition"
:isMultiSelect="isMultiSelect"
:groupName="groupName"
:groupName="formattedGroupName"
:selectingInitiatesLoad="selectingInitiatesLoad"
:loaderColor="loaderColor"
:loaderPosition="loaderPosition"
@ -48,7 +48,7 @@
</fieldset>
</div>
<div class="row form-test-error mt-1">
<error-message :name="groupName" v-if="!suppressError"></error-message>
<error-message :name="formattedGroupName" v-if="!suppressError"></error-message>
</div>
</div>
</template>
@ -97,6 +97,9 @@ export default {
},
},
computed: {
formattedGroupName() {
return this.groupName.replace(" ", "-");
},
getFieldSetClasses() {
if (this.isOverflowScrollable) {
return "container-fluid overflow-scroll position-absolute px-5 pt-1 py-0";
@ -175,6 +178,7 @@ export default {
}
}
this.$emit("change");
this.$emit("isCheckedChanged", val);
},
},

View file

@ -14,7 +14,7 @@
isRequired
:groupName="`${glassLocation}-${glassName}`"
@isCheckedChanged="ResetTintAndPartSelections"
validationRules="replace-options-required"
:validationRules="`${glassLocation}-${glassName}-tint-required`"
>
<div class="row my-2" aria-live="polite">
<div class="col">
@ -36,12 +36,6 @@
</div>
</div>
</div>
<div class="row form-test-error mt-1">
<!-- <error-message
:name="`${glassLocation}-${glassName}`"
v-if="!suppressError"
></error-message> -->
</div>
</template>
<script>
@ -54,11 +48,6 @@ import { getCustomTransformValue } from "@/constants/dynamictext-mapper";
import { defineRule } from "vee-validate";
import { required } from "@/helpers/validation-rules";
import { errorMessages } from "@/constants/error-messages";
// import { ErrorMessage } from "vee-validate";
defineRule("replace-options-required", required(errorMessages.OPTION_REQUIRED));
// defineRule("part-required", required(errorMessages.OPTION_REQUIRED));
defineRule(`${this.glassLocation}-${this.glassName}-part-required`, required(errorMessages.OPTION_REQUIRED));
export default {
name: "glass-part-question",
@ -75,15 +64,14 @@ export default {
glassLocation: String,
colorAnswers: Array,
modelValue: Object,
// validationRules: String,
alreadyPopulatedPartsData: Object
},
mounted() {
// this.setAllValidationRules();
this.setAllValidationRules();
this.LoadPreselectedValues();
},
components: {
buttonQuestion,
// ErrorMessage,
},
computed: {
colorQuestionText() {
@ -111,13 +99,9 @@ export default {
selectedPartNumber: {
get() {
console.log(this.modelValue)
return this.modelValue?.partNumber;
},
set(newValue) {
console.log("setting")
console.log(newValue)
this.$emit("update:modelValue", this.partsForSelectedTint.filter(part => part.partNumber == newValue)[0]);
},
},
@ -188,47 +172,15 @@ export default {
// Reset selections when tint changes for the same glass to ensure proper selection.
// Also checks if only a single part is present for the tint.
ResetTintAndPartSelections() {
console.log("Resetting!")
// this.selectedTint = "";
this.selectedPartNumber = null;
this.AutoSelectIfSinglePart();
},
// Check if only a single part is present for the tint and set the v-model if it is.
AutoSelectIfSinglePart() {
console.log("Autoselecting, my dear")
console.log(this.PartDataFromApi.partsOrQuestions)
console.log(this.glassName)
console.log(this.glassLocation)
console.log(this.selectedTint)
console.log(this.partsForSelectedTint)
if (this.partsForSelectedTint?.length == 1) {
console.log("One!")
this.selectedPartNumber = this.partsForSelectedTint[0].partNumber;
console.log(this.selectedPartNumber)
}
// this.$nextTick()
console.log(this.selectedPartNumber)
// Check if the selected tint only has a single feature
// Object.keys(this.PartDataFromApi.partsOrQuestions ?? {}).forEach(
// (key) => {
// const currentGlassSelection =
// this.PartDataFromApi.partsOrQuestions[key];
// if (
// currentGlassSelection.glassName === this.glassName &&
// currentGlassSelection.glassLocation ===
// this.glassLocation
// ) {
// if (currentGlassSelection.parts.length === 1) {
// this.selectedPartNumber = currentGlassSelection.parts[0].partNumber
// }
// }
// }
// );
},
// Loads the preselected values from the store.
@ -236,40 +188,18 @@ export default {
this.$nextTick(() => {
if (this.modelValue !== undefined) {
// Populate button-question model-value if parts data already exists in VueX
const alreadyPopulatedPartsData = this.$store.getters.lineItems.glassParts;
Object.keys(alreadyPopulatedPartsData).forEach((key) => {
const partNumber = alreadyPopulatedPartsData[key].partNumber;
const tintColor = alreadyPopulatedPartsData[key].color;
Object.keys(this.modelValue).forEach((key) => {
if (this.modelValue[key][0] === partNumber) {
this.selectedTint = tintColor;
// this.selectedTint[tintColor] = {
// buttonId: `${this.glassLocation}-${this.glassName}-${tintColor}`,
// checkValue: "",
// value: `${this.glassLocation}-${this.glassName}-${tintColor}`,
// };
}
});
});
this.selectedTint = this.alreadyPopulatedPartsData.filter(part => part.partNumber === this.selectedPartNumber)[0].color;
}
});
},
// setAllValidationRules() {
// console.log("SETTING VALIDATION RULES")
// console.log(this.PartDataFromApi.partsOrQuestions)
// this.PartDataFromApi.partsOrQuestions.forEach(part => {
// console.log(`${this.glassLocation}-${this.glassName}-${this.selectedTint}-part-required`)
// defineRule(`${this.glassLocation}-${this.glassName}-part-required`, required(errorMessages.OPTION_REQUIRED));
// })
// }
setAllValidationRules() {
defineRule(`${this.glassLocation}-${this.glassName}-tint-required`, required(errorMessages.OPTION_REQUIRED));
defineRule(`${this.glassLocation}-${this.glassName}-part-required`, required(errorMessages.OPTION_REQUIRED));
}
},
watch: {
selectedTint() {
console.log("watch me")
this.selectedPartNumber = null;
this.AutoSelectIfSinglePart()
this.AutoSelectIfSinglePart();
}
}
};

View file

@ -31,6 +31,7 @@
:glassLocation="item.glassLocation"
:glassName="item.glassName"
:colorAnswers="item.colorAnswers"
:alreadyPopulatedPartsData="alreadyPopulatedPartsData"
/>
</div>
<funnelFooter
@ -91,6 +92,7 @@ data() {
return {
glassParts: {},
alertWidgetData: Object,
alreadyPopulatedPartsData: {}
};
},
components: {
@ -163,34 +165,28 @@ methods: {
// Match them to the parts from the API.
this.PartsFromApi.partsOrQuestions.forEach(part => {
const selectedPartForGlassLocationAndName = this.glassParts[`${part.glassLocation}-${part.glassName}`];
console.log(part)
console.log(this.glassParts)
console.log(`${part.glassLocation}-${part.glassName}`)
console.log(selectedPartForGlassLocationAndName)
const selectedPartData = part.parts.filter(part => selectedPartForGlassLocationAndName && part.partNumber == selectedPartForGlassLocationAndName?.partNumber)[0];
if (selectedPartData)
matchedParts.push(selectedPartData);
})
console.log(matchedParts)
// If no parts could be matched, throw an error.
if (matchedParts.length !== this.PartsFromApi.length) {
if (Object.keys(matchedParts).length !== this.PartsFromApi.partsOrQuestions.length) {
this.$refs.funnelFooter.removeLoader();
throw new Error("Could not match any parts to the selected parts");
}
this.$refs.funnelFooter.removeLoader();
console.log(matchedParts)
// Save parts to the store.
store.commit(storeMutations.UPDATE_GLASS_PARTS, matchedParts);
// Navigate to the next page.
this.$router.navigateAfterSave(
this.navigationScenarios.SELECTED_PARTS,
this.$route
);
// this.$router.navigateAfterSave(
// this.navigationScenarios.SELECTED_PARTS,
// this.$route
// );
},
resetDependentState() {
@ -198,21 +194,48 @@ methods: {
},
LoadInitialPartsData() {
const partsData = this.PartsFromApi;
const alreadyPopulatedPartsData = this.$store.getters.lineItems.glassParts === null ? {} : this.$store.getters.lineItems.glassParts;
console.log("Loading in vehicle-parts")
this.alreadyPopulatedPartsData = this.$store.getters.lineItems.glassParts ?? [];
// MOCKKKK, real one is above
// console.log(this.PartsFromApi.partsOrQuestions[0])
// this.alreadyPopulatedPartsData = [this.PartsFromApi.partsOrQuestions[0].parts[0], this.PartsFromApi.partsOrQuestions[1].parts[0], this.PartsFromApi.partsOrQuestions[2].parts[0], this.PartsFromApi.partsOrQuestions[3].parts[0], this.PartsFromApi.partsOrQuestions[4].parts[0]];
// console.log("MOCK alreadyPopulatedPartsData")
// console.log(this.alreadyPopulatedPartsData)
const savedPartNumbers = this.alreadyPopulatedPartsData.map(part => part.partNumber)
console.log(savedPartNumbers)
// const allPartsForGlass = this.PartsFromApi.partsOrQuestions.filter(glass => glass.glassLocation == this.glassLocation && glass.glassName == this.glassName)[0].parts;
partsData.partsOrQuestions.map((g) => {
this.PartsFromApi.partsOrQuestions.forEach(glass => {
console.log("glass")
console.log(glass)
const savedPart = glass.parts.filter(part => savedPartNumbers.includes(part.partNumber))[0];
console.log('savedPart')
console.log(savedPart)
if (savedPart) {
this.glassParts[`${glass.glassLocation}-${glass.glassName}`.replace(" ", "-")] = savedPart;
}
console.log('glassParts')
console.log(this.glassParts)
// this.glassParts[`${glass.glassLocation}-${glass.glassName}`] =
// If the part is already populated, use the value from the store and populate the v-model.
Object.keys(alreadyPopulatedPartsData).forEach((key) => {
const partNumber = alreadyPopulatedPartsData[key].partNumber;
g.parts.forEach((p) => {
if (p.partNumber === partNumber) {
this.glassParts[g.glassLocation + "-" + g.glassName] = {
[g.glassLocation]: [partNumber],
};
}
});
});
// Object.keys(alreadyPopulatedPartsData).forEach(savedPart => {
// const savedPartNumber = savedPart.partNumber;
// let test = partFromApi.parts.filter(part => part.partNumber == savedPartNumber);
// console.log(test);
// // g.parts.forEach((p) => {
// // if (p.partNumber === partNumber) {
// // this.glassParts[g.glassLocation + "-" + g.glassName] = {
// // [g.glassLocation]: [partNumber],
// // };
// // }
// // });
// });
});
},
},

View file

@ -12,6 +12,7 @@ const fmgPageValues = {
REVEAL: "reveal",
ESTIMATE: "estimate",
ADDRESS_VEHICLES: "address-vehicles",
QUOTE: "quote"
};
export { fmgPageValues };

View file

@ -3,6 +3,7 @@
<div
class="list-card w-100 rounded-3 d-flex align-items-center"
:class="[
'h-100',
isWide ? 'horizontal' : '',
(errors.length > 0 || hasError) ? 'has-error' : '',
]"
@ -19,15 +20,16 @@
:value="value"
:aria-required="isRequired"
v-model="checkValue"
@change="handleInputChange()"
:checked="checkValue"
@change="handleInputChange"
/>
<label
tabindex="-1"
:for="buttonID"
:aria-labelledby="buttonID"
class="d-flex w-100 align-items-center px-2"
class="d-flex w-100 align-items-center px-2 h-100"
:class="getLabelClasses"
@mouseup="triggerButton()"
@mouseup="triggerButton"
>
<img
:id="buttonImageId"
@ -102,6 +104,12 @@ export default {
? this.selectedValues.includes(this.value)
: this.selectedValues[0];
}
else {
console.log("HI")
console.log(this.modelValue)
console.log(this.value)
this.checkValue = this.selectedValues == this.value || this.modelValue == this.value;
}
},
unmounted() { // needed to clear this button's selectedValues if it is removed to keep validation in sync
if (this.clearOnUnmount) {
@ -124,7 +132,9 @@ export default {
},
methods: {
handleInputChange() {
console.log("HI 1")
if(!this.selectingInitiatesLoad) {
console.log("HI 2")
this.handleCheckChange();
}
},
@ -164,6 +174,22 @@ export default {
this.checkValue = newVal.value;
}
},
selectedValues(newVal) {
// this.handleChange(newVal == this.value);
console.log("WATCH")
console.log(newVal)
console.log(typeof newVal)
console.log(typeof newVal === "string")
if (typeof newVal === "string") {
console.log(this.value)
// console.log(newVal == this.value)
this.handleChange(this.value);
this.checkValue = newVal == this.value;
}
else if (newVal !== undefined) {
this.checkValue = newVal.value;
}
},
},
setup(props) {
const inputType = props.isMultiSelect ? "checkbox" : "radio";

View file

@ -50,6 +50,7 @@ export default {
created() {
if (this.selectedValues) {
this.checkValue = this.selectedValues === this.value;
this.handleCheckChange();
} else{
this.checkValue = false;
}
@ -88,14 +89,17 @@ export default {
<style lang="scss" scoped>
.form-check {
position: relative;
.form-check-input {
border: 1px solid $gray-500;
border-radius: 100%;
border-radius: 50%;
margin-right: 0.5rem;
margin-top: 0.12rem;
&:checked {
background-color: $white;
background-size: 71%;
background-position: center;
border: 1px solid $blue;
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 50 50' xml:space='preserve'%3e%3ccircle cx='25' cy='25' r='25' fill='%231574A1'/%3e%3c/svg%3e");
+ label {
@ -109,7 +113,15 @@ export default {
&:focus {
box-shadow: 0 0 0 2.5px $blue;
}
&, & + label {
margin-top: 0;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
}
&:hover {
.form-check-input {
box-shadow: 0 0 0 4px $blue-300;