CSR-343 Fix reloading/repopulating and CSS
This commit is contained in:
parent
06335ba625
commit
8fe1dd8d7b
6 changed files with 110 additions and 114 deletions
|
|
@ -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);
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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],
|
||||
// // };
|
||||
// // }
|
||||
// // });
|
||||
// });
|
||||
});
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ const fmgPageValues = {
|
|||
REVEAL: "reveal",
|
||||
ESTIMATE: "estimate",
|
||||
ADDRESS_VEHICLES: "address-vehicles",
|
||||
QUOTE: "quote"
|
||||
};
|
||||
|
||||
export { fmgPageValues };
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue