This commit is contained in:
Kulbhushan Kaushik 2022-11-10 08:03:43 -05:00
parent 7e1eb15d3f
commit 120369c5bc
9 changed files with 966 additions and 33 deletions

View file

@ -0,0 +1,9 @@
const damageLocationsCms = {
WINDSHIELD: "WINDSHIELD",
SIDEDOOR: "SIDEDOOR",
REARWINDOW: "REARWINDOW",
DRIVERSIDE: "DRIVERSIDE",
PASSENGERSIDE: "PASSENGERSIDE",
};
export { damageLocationsCms };

View file

@ -0,0 +1,21 @@
const damageLocationsSelected = {
WINDSHIELD: "Windshield",
SIDEDOOR: "SideDoor",
REARWINDOW: "RearWindow",
REPAIR: "Repair",
REPLACE: "Replace",
DRIVER: "Driver",
PASSENGER: "Passenger",
FRONT: "Front",
REAR: "Rear",
BACK: "Back",
QUARTER: "Quarter",
VENT: "Vent",
SINGLE: "Single",
DRIVERSIDE: "DriverSide",
PASSENGERSIDE: "PassengerSide",
STATIONARY: "Stationary",
SLIDER: "Slider",
};
export { damageLocationsSelected };

View file

@ -14,7 +14,6 @@
<script>
import buttonQuestion from "@/common-components/button-question/button-question";
import { useMainStore } from '@/store';
import { defineRule } from "vee-validate";
import { required } from "@/helpers/validation-rules";
import { errorMessages } from "@/constants/error-messages";
@ -68,7 +67,7 @@ export default {
? this.answersFromCms.filter((ans) => {
const name = ans.Name.split("-");
return (
name[0].toUpperCase() === useMainStore().getters.vehicle.category &&
name[0].toUpperCase() === this.mainStore.getters.vehicle.category &&
this.damageOptionsMap[name[1]]
);
})

View file

@ -22,7 +22,6 @@
<script>
import buttonQuestion from "@/common-components/button-question/button-question";
import { useMainStore } from '@/store';
export default {
name: "replaceOptionsQuestion",
@ -75,7 +74,7 @@ export default {
? this.answersFromCms.filter((ans) => {
const name = ans.Name.split("-");
return this.filterByVehicleCategory
? name[0].toUpperCase() === useMainStore().getters.vehicle.category &&
? name[0].toUpperCase() === this.mainStore.getters.vehicle.category &&
this.replaceOptions.includes(name[1])
: this.replaceOptions.includes(ans.Name);
})

View file

@ -0,0 +1,168 @@
<template>
<div class="side-door-options">
<transition name="fade" mode="out-in">
<div
class="side-doors"
v-if="selectedDamageLocations.includes('SideDoor')"
aria-live="polite">
<buttonQuestion
:questionText="questionText"
isMultiSelect
:answers="answersToDisplay"
:groupName="groupName"
buttonTypeString="listCard"
v-model="selectedDoorSidesValues"
validationRules="damage-side-required"
isRequired />
</div>
</transition>
<replaceOptionsQuestion
ref="driverSideOptions"
cmsWidgetName="DriverSideReplaceOptionsQuestion"
:isAvailable="isDriverSideReplaceOptionsQuestionAvailable"
groupName="driverSideOptions"
isMultiSelect
filterByVehicleCategory
v-model="selectedDriverSideReplaceOptionsValues"
validationRules="driver-side-options-required"
isRequired />
<replaceOptionsQuestion
ref="passengerSideOptions"
cmsWidgetName="PassengerSideReplaceOptionsQuestion"
:isAvailable="isPassengerSideReplaceOptionsQuestionAvailable"
groupName="passengerSideOptions"
isMultiSelect
filterByVehicleCategory
v-model="selectedPassengerSideReplaceOptionsValues"
validationRules="passenger-side-options-required"
isRequired />
</div>
</template>
<script>
import buttonQuestion from "@/common-components/button-question/button-question";
import replaceOptionsQuestion from "@/layouts/vehicle-damage/replace-options-question/replace-options-question";
import { useMainStore } from '@/store';
import { defineRule } from "vee-validate";
import { required } from "@/helpers/validation-rules";
import { errorMessages } from "@/constants/error-messages";
import { damageLocationsSelected } from "@/constants/damage-locations-selected";
// DEFINE VALIDATION RULES
defineRule("damage-side-required", required(errorMessages.DAMAGE_SIDE_REQUIRED));
defineRule("driver-side-options-required", required(errorMessages.DRIVER_SIDE_OPTIONS_REQUIRED));
defineRule("passenger-side-options-required",required(errorMessages.PASSENGER_SIDE_OPTIONS_REQUIRED));
export default {
name: "sideDoorOptions",
props: {
groupName: String,
modelValue: Object,
selectedDamageLocations: Array,
cmsWidgetName: String,
},
methods: {
initializeComponent(driverSideOptions, passengerSideOptions) {
this.$refs.driverSideOptions.initializeComponent(driverSideOptions);
this.$refs.passengerSideOptions.initializeComponent(passengerSideOptions);
},
getSideDoorReplacementOptions(
selectedDoorSides,
selectedDriverSideReplaceOptions,
selectedPassengerSideReplaceOptions
) {
return {
selectedDoorSides: selectedDoorSides,
selectedDriverSideReplaceOptions: selectedDriverSideReplaceOptions,
selectedPassengerSideReplaceOptions: selectedPassengerSideReplaceOptions,
};
},
},
computed: {
questionText() {
return this.getCmsContent(this.cmsWidgetName, "QuestionText");
},
answersFromCms() {
return this.getCmsContent(this.cmsWidgetName, "Answers");
},
selectedValues: {
get: function () {
return this.modelValue;
},
set: function (newValue) {
this.$emit("update:modelValue", newValue);
},
},
selectedDoorSidesValues: {
get: function () {
return this.selectedValues.selectedDoorSides;
},
set: function (newValue) {
this.selectedValues = this.getSideDoorReplacementOptions(
newValue,
this.selectedValues.selectedDriverSideReplaceOptions,
this.selectedValues.selectedPassengerSideReplaceOptions
);
},
},
selectedDriverSideReplaceOptionsValues: {
get: function () {
return this.selectedValues.selectedDriverSideReplaceOptions;
},
set: function (newValue) {
this.selectedValues = this.getSideDoorReplacementOptions(
this.selectedValues.selectedDoorSides,
newValue,
this.selectedValues.selectedPassengerSideReplaceOptions
);
},
},
selectedPassengerSideReplaceOptionsValues: {
get: function () {
return this.selectedValues.selectedPassengerSideReplaceOptions;
},
set: function (newValue) {
this.selectedValues = this.getSideDoorReplacementOptions(
this.selectedValues.selectedDoorSides,
this.selectedValues.selectedDriverSideReplaceOptions,
newValue
);
},
},
answersToDisplay() {
const filteredAnswers = Array.isArray(this.answersFromCms)
? this.answersFromCms.filter((ans) => {
const name = ans.Name.split("-");
return name[0].toUpperCase() === store.getters.vehicle.category;
})
: [];
return filteredAnswers.map((ans) => {
const newName = ans.Name.includes("-") ? ans.Name.split("-")[1] : ans.Name;
ans.Name = newName;
return ans;
});
},
isDriverSideReplaceOptionsQuestionAvailable() {
return (
Array.isArray(this.selectedDoorSidesValues) &&
this.selectedDoorSidesValues.includes(damageLocationsSelected.DRIVERSIDE) &&
Array.isArray(this.selectedDamageLocations) &&
this.selectedDamageLocations.includes(damageLocationsSelected.SIDEDOOR)
);
},
isPassengerSideReplaceOptionsQuestionAvailable() {
return (
Array.isArray(this.selectedDoorSidesValues) &&
this.selectedDoorSidesValues.includes(damageLocationsSelected.PASSENGERSIDE) &&
Array.isArray(this.selectedDamageLocations) &&
this.selectedDamageLocations.includes(damageLocationsSelected.SIDEDOOR)
);
},
},
components: {
buttonQuestion,
replaceOptionsQuestion,
},
};
</script>

View file

@ -0,0 +1,490 @@
<template>
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }">
<div class="page-container-grouped-styles">
<siteHeader cmsWidgetName="SiteHeaderWidget" />
<vehicleBanner
cmsWidgetName="VehicleBannerWidget"
:displayGenericVehicleImage="false" />
<siteSubHeader cmsWidgetName="SiteSubHeaderWidget" />
<div class="fade-on-route-transition sub-container make-tall">
<alert
ref="vehicleChangeAlert"
v-if="shouldDisplayVehicleChangeAlert"
class="mt-5 mb-0"
cmsWidgetName="VehicleChangeAlert"
alertClass="alert-warning"
:isDismissible="false" />
<damageLocationQuestion
ref="damageLocation"
cmsWidgetName="DamageLocationQuestion"
v-model="selectedDamageLocations"
groupName="DamageLocationQuestion" />
<windshieldOptions
ref="windshieldOptions"
v-model="selectedWindshieldOptions"
:hasRepairReplaceConflict="hasRepairReplaceConflict"
:hasSplitSingleConflict="hasSplitSingleConflict"
:selectedDamageLocations="selectedDamageLocations" />
<alert
v-if="hasRepairReplaceConflict"
class="my-5"
cmsWidgetName="HasReplacementConflict"
alertClass="alert-danger"
:isDismissible="false" />
<sideDoorOptions
ref="sideDoorOptions"
cmsWidgetName="SideDoorSideQuestion"
groupName="SideDoorSideQuestion"
v-model="sideDoorOptionsData"
v-show="!hasRepairReplaceConflict"
:selectedDamageLocations="selectedDamageLocations" />
<replaceOptionsQuestion
ref="backGlassOptions"
cmsWidgetName="RearReplaceOptionsQuestion"
:isAvailable="isRearWindowDamageLocation && !hasRepairReplaceConflict"
v-model="selectedRearReplaceOptions"
groupName="BackGlassReplaceOptionsQuestion"
validationRules="replace-options-required" />
<site-footer
cmsWidgetName="SiteFooterWidget"
:isForwardActionDisabled="!meta.valid"
:isBackButtonHidden="shouldHideBackButton"
@back-clicked="backButtonAction"
@ForwardClicked="forwardButtonAction" />
</div>
</div>
</Form>
</template>
<script>
// Components
import siteHeader from "@/common-components/site-header/site-header";
import siteFooter from "@/common-components/site-footer/site-footer";
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
import siteSubHeader from "@/common-components/site-sub-header/site-sub-header";
import sideDoorOptions from "@/layouts/vehicle-damage/side-door-options/side-door-options";
import damageLocationQuestion from "@/layouts/vehicle-damage/damage-location-question/damage-location-question";
import windshieldOptions from "@/layouts/vehicle-damage/windshield-options/windshield-options";
import replaceOptionsQuestion from "@/layouts/vehicle-damage/replace-options-question/replace-options-question";
import alert from "@/ux-components/alert/alert";
// Supporting files
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { settleAllPromises } from "@/helpers/layout-helper";
import { storeActions } from "@/constants/store-actions";
import { Form, defineRule } from "vee-validate";
import { required } from "@/helpers/validation-rules";
import { errorMessages } from "@/constants/error-messages";
import { damageLocationsCms } from "@/constants/damage-locations-cms.js";
import { damageLocationsSelected } from "@/constants/damage-locations-selected.js";
import store from "@/store";
import baseMixin from "@/mixins/base-mixin";
// DEFINE VALIDATION RULES
defineRule("replace-options-required", required(errorMessages.REPLACE_OPTIONS_REQUIRED));
export default {
name: "vehicle-damage",
async beforeRouteEnter(to, from, next) {
// Call APIs
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
const damageOptionsPromise = baseMixin.methods.dispatchStoreAction(
storeActions.GET_DAMAGE_OPTIONS,
{ carId: store.getters.vehicle.carId }
);
// Settle promises and get results
const promiseResultMap = [
{
resultKey: "cmsContent",
promise: cmsContentPromise,
},
{
resultKey: "damageOptions",
promise: damageOptionsPromise,
},
];
const resultMap = await settleAllPromises(promiseResultMap);
// Call the "next" function to complete the transition to this page.
next((vm) => {
vm.setCmsContent(resultMap.cmsContent);
vm.$refs.damageLocation.initializeComponent(resultMap.damageOptions);
vm.$refs.sideDoorOptions.initializeComponent(
resultMap.damageOptions.driverSideOptions.availableReplacementOptions,
resultMap.damageOptions.passengerSideOptions.availableReplacementOptions
);
vm.$refs.windshieldOptions.initializeComponent(
resultMap.damageOptions.windshieldOptions.availableReplacementOptions
);
vm.$refs.backGlassOptions.initializeComponent(
resultMap.damageOptions.backGlassOptions.availableReplacementOptions
);
});
},
data() {
return {
selectedDamageLocations: this.getDamageLocationsFromStore(),
sideDoorOptionsData: {
selectedDoorSides: this.getDoorSidesFromStore(),
selectedDriverSideReplaceOptions: this.getDriverSideReplaceOptionsFromStore(),
selectedPassengerSideReplaceOptions: this.getPassengerSideReplaceOptionsFromStore(),
},
selectedWindshieldOptions: this.getWindshieldOptionsFromStore(),
selectedRearReplaceOptions: this.getRearReplaceOptionsFromStore(),
};
},
mounted() {
this.attachCustomEvents();
},
methods: {
arePagePrerequisitesValid() {
if (store.getters.vehicle.carId) {
return true;
}
return false;
},
attachCustomEvents() {
if (this.$store.getters.vehicle.imageVifNumber) {
this.pushEventToGA(
this.GaCategories.EVOX,
`${this.GaActions.VIF}_${this.$store.getters.vehicle.imageVifNumber}`,
this.$store.getters.vehicle.carId,
true
);
}
},
backButtonAction() {
// route to move backwards
this.$router.navigateWithoutSaving(this.navigationScenarios.CLICKED_BACK, this.$route);
},
getDamageLocationsFromStore() {
var glassSelections = [];
if (
store.getters.damage.glassToReplace?.some((glass) => {
return glass.glassLocation === damageLocationsSelected.WINDSHIELD;
}) ||
store.getters.damage.isRepair
) {
glassSelections.push(damageLocationsSelected.WINDSHIELD);
}
if (
store.getters.damage.glassToReplace?.some((glass) => {
return (
glass.glassLocation === damageLocationsSelected.DRIVER ||
glass.glassLocation === damageLocationsSelected.PASSENGER
);
})
) {
glassSelections.push(damageLocationsSelected.SIDEDOOR);
}
if (
store.getters.damage.glassToReplace?.some((glass) => {
return glass.glassLocation === damageLocationsSelected.REAR;
})
) {
glassSelections.push(damageLocationsSelected.REARWINDOW);
}
return glassSelections;
},
getWindshieldOptionsFromStore() {
var windShieldOptions = {
selectedWindshieldDamageType: "",
selectedWindshieldChipCount: null,
selectedWindshieldReplaceOptions: [],
};
if (store.getters.damage.isRepair === undefined) return windshieldOptions;
if (store.getters.damage.isRepair) {
windShieldOptions.selectedWindshieldDamageType = damageLocationsSelected.REPAIR;
windShieldOptions.selectedWindshieldChipCount = store.getters.damage.numberOfChips;
} else {
if (
store.getters.damage.glassToReplace?.some((glass) => {
return (
glass.glassLocation === damageLocationsSelected.WINDSHIELD &&
glass.glassName === damageLocationsSelected.SINGLE
);
})
) {
windShieldOptions.selectedWindshieldDamageType =
damageLocationsSelected.REPLACE;
windShieldOptions.selectedWindshieldReplaceOptions.push(
damageLocationsSelected.SINGLE
);
}
if (
store.getters.damage.glassToReplace?.some((glass) => {
return (
glass.glassLocation === damageLocationsSelected.WINDSHIELD &&
glass.glassName === damageLocationsSelected.DRIVER
);
})
) {
windShieldOptions.selectedWindshieldDamageType =
damageLocationsSelected.REPLACE;
windShieldOptions.selectedWindshieldReplaceOptions.push(
damageLocationsSelected.DRIVER
);
}
if (
store.getters.damage.glassToReplace?.some((glass) => {
return (
glass.glassLocation === damageLocationsSelected.WINDSHIELD &&
glass.glassName === damageLocationsSelected.PASSENGER
);
})
) {
windShieldOptions.selectedWindshieldDamageType =
damageLocationsSelected.REPLACE;
windShieldOptions.selectedWindshieldReplaceOptions.push(
damageLocationsSelected.PASSENGER
);
}
}
return windShieldOptions;
},
getDoorSidesFromStore() {
var doorSides = [];
if (
store.getters.damage.glassToReplace?.some((glass) => {
return glass.glassLocation === damageLocationsSelected.DRIVER;
})
) {
doorSides.push(damageLocationsSelected.DRIVERSIDE);
}
if (
store.getters.damage.glassToReplace?.some((glass) => {
return glass.glassLocation === damageLocationsSelected.PASSENGER;
})
) {
doorSides.push(damageLocationsSelected.PASSENGERSIDE);
}
return doorSides;
},
getDriverSideReplaceOptionsFromStore() {
var driverSideReplaceOptions = [];
store.getters.damage.glassToReplace?.forEach((glass) => {
if (glass.glassLocation === damageLocationsSelected.DRIVER) {
driverSideReplaceOptions.push(glass.glassName);
}
});
return driverSideReplaceOptions;
},
getPassengerSideReplaceOptionsFromStore() {
var passengerSideReplaceOptions = [];
store.getters.damage.glassToReplace?.forEach((glass) => {
if (glass.glassLocation === damageLocationsSelected.PASSENGER) {
passengerSideReplaceOptions.push(glass.glassName);
}
});
return passengerSideReplaceOptions;
},
getRearReplaceOptionsFromStore() {
var rearReplaceOptions = store.getters.damage.glassToReplace?.filter(
(glass) => glass.glassLocation === damageLocationsSelected.REAR
)[0]?.glassName;
return rearReplaceOptions;
},
async forwardButtonAction() {
await this.dispatchStoreAction(
this.storeActions.SAVE_VEHICLE_DAMAGE,
{
isWindshieldRepair: this.isWindshieldRepair,
selectedGlassToReplace: this.selectedGlassToReplace(),
selectedWindshieldChipCount:
this.selectedWindshieldOptions.selectedWindshieldChipCount,
},
false
);
return this.navigateForward();
},
navigateForward() {
// If vin already exists, navigate directly to vin-lookup
if (store.getters.vehicle.vin) {
this.$router.navigateWithSaving(
this.navigationScenarios.CLICKED_FORWARD_WITH_VIN,
this.$route
);
} else {
this.$router.navigateWithSaving(
this.navigationScenarios.CLICKED_FORWARD_WITHOUT_VIN,
this.$route
);
}
},
selectedGlassToReplace() {
const selectedGlassToReplace = [];
if (this.isWindshieldDamageLocation && !this.isWindshieldRepair) {
this.selectedWindshieldOptions.selectedWindshieldReplaceOptions.forEach(
(wsItem) => {
selectedGlassToReplace.push({
glassLocation: damageLocationsSelected.WINDSHIELD,
glassName: wsItem,
});
}
);
}
if (this.isDriverSideReplace) {
this.sideDoorOptionsData.selectedDriverSideReplaceOptions.forEach((driverItem) => {
selectedGlassToReplace.push({
glassLocation: damageLocationsSelected.DRIVER,
glassName: driverItem,
});
});
}
if (this.isPassengerSideReplace) {
this.sideDoorOptionsData.selectedPassengerSideReplaceOptions.forEach(
(passengerItem) => {
selectedGlassToReplace.push({
glassLocation: damageLocationsSelected.PASSENGER,
glassName: passengerItem,
});
}
);
}
if (this.isRearWindowDamageLocation) {
selectedGlassToReplace.push({
glassLocation: damageLocationsSelected.REAR,
glassName: this.selectedRearReplaceOptions,
});
}
return selectedGlassToReplace;
},
},
computed: {
isWindshieldDamageLocation() {
return this.selectedDamageLocations.some((selectedDamages) => {
return selectedDamages.toUpperCase() === damageLocationsCms.WINDSHIELD;
});
},
isSideDoorDamageLocation() {
return this.selectedDamageLocations.some((selectedDamages) => {
return selectedDamages.toUpperCase() === damageLocationsCms.SIDEDOOR;
});
},
isRearWindowDamageLocation() {
return this.selectedDamageLocations.some((selectedDamages) => {
return selectedDamages.toUpperCase() === damageLocationsCms.REARWINDOW;
});
},
isWindshieldRepair() {
return (
this.isWindshieldDamageLocation &&
this.selectedWindshieldOptions.selectedWindshieldDamageType ===
damageLocationsSelected.REPAIR
);
},
isDriverSideReplace() {
if (!this.isSideDoorDamageLocation) return false;
return this.sideDoorOptionsData.selectedDoorSides.some((selectedDriverSide) => {
return selectedDriverSide.toUpperCase() === damageLocationsCms.DRIVERSIDE;
});
},
isPassengerSideReplace() {
if (!this.isSideDoorDamageLocation) return false;
return this.sideDoorOptionsData.selectedDoorSides.some((selectedPassengerSide) => {
return selectedPassengerSide.toUpperCase() === damageLocationsCms.PASSENGERSIDE;
});
},
hasRepairReplaceConflict() {
return (
this.isWindshieldDamageLocation &&
this.selectedDamageLocations.length > 1 &&
this.isWindshieldRepair
);
},
hasSplitSingleConflict() {
if (
!this.selectedDamageLocations?.includes("Windshield") ||
this.selectedWindshieldOptions.selectedWindshieldDamageType ===
damageLocationsSelected.REPAIR ||
!this.selectedWindshieldOptions.selectedWindshieldReplaceOptions
)
return false;
return (
this.selectedWindshieldOptions.selectedWindshieldReplaceOptions?.some(
(selectedSingleWindshield) => {
return (
selectedSingleWindshield.toUpperCase() ===
damageLocationsSelected.SINGLE.toUpperCase()
);
}
) &&
(this.selectedWindshieldOptions.selectedWindshieldReplaceOptions?.some(
(selectedDriverWindshield) => {
return (
selectedDriverWindshield.toUpperCase() ===
damageLocationsSelected.DRIVER.toUpperCase()
);
}
) ||
this.selectedWindshieldOptions.selectedWindshieldReplaceOptions?.some(
(selectedPassengerWindshield) => {
return (
selectedPassengerWindshield.toUpperCase() ===
damageLocationsSelected.PASSENGER.toUpperCase()
);
}
))
);
},
shouldDisplayVehicleChangeAlert() {
return this.$route.params[this.routerParams.DISPLAY_VEHICLE_CHANGE_ALERT];
},
shouldHideBackButton() {
return (
this.$store.getters.payment.insuranceCoverage.isVerified
);
},
},
components: {
siteHeader,
siteFooter,
vehicleBanner,
siteSubHeader,
sideDoorOptions,
damageLocationQuestion,
windshieldOptions,
replaceOptionsQuestion,
Form,
alert,
},
};
</script>

View file

@ -0,0 +1,50 @@
<template>
<transition name="fade" mode="out-in">
<div class="windshield-damage-type-question" v-if="isAvailable" aria-live="polite">
<buttonQuestion
:questionText="questionText"
:answers="answersFromCms"
:groupName="groupName"
buttonTypeString="listCard"
v-model="selectedValues"
:suppressError="suppressError"
:validationRules="validationRules"
isRequired />
</div>
</transition>
</template>
<script>
import buttonQuestion from "@/common-components/button-question/button-question";
export default {
name: "windshieldDamageTypeQuestion",
props: {
modelValue: String,
groupName: String,
isAvailable: Boolean,
suppressError: Boolean,
validationRules: String,
cmsWidgetName: String,
},
computed: {
questionText() {
return this.getCmsContent(this.cmsWidgetName, "QuestionText");
},
answersFromCms() {
return this.getCmsContent(this.cmsWidgetName, "Answers");
},
selectedValues: {
get: function () {
return this.modelValue;
},
set: function (newValue) {
this.$emit("update:modelValue", newValue);
},
},
},
components: {
buttonQuestion,
},
};
</script>

View file

@ -1,39 +1,139 @@
<template>
<transition name="fade" mode="out-in">
<div class="windshield-damage-type-question" v-if="isAvailable" aria-live="polite">
<buttonQuestion
:questionText="questionText"
:answers="answersFromCms"
:groupName="groupName"
buttonTypeString="listCard"
v-model="selectedValues"
:suppressError="suppressError"
:validationRules="validationRules"
isRequired />
</div>
</transition>
<div class="windshield-options">
<windshieldDamageTypeQuestion
cmsWidgetName="WindshieldDamageTypeQuestion"
:isAvailable="isWindshieldDamageLocation"
:suppressError="hasRepairReplaceConflict || showNoReplacementAvailableError"
groupName="WindshieldDamageTypeQuestion"
v-model="selectedWindshieldDamageTypeValue"
:validationRules="windshieldDamageTypeQuestionValidationRules" />
<alert
v-if="showNoReplacementAvailableError"
class="my-3"
cmsWidgetName="NoReplacementAvailableError"
alertClass="alert-danger"
:isDismissible="false" />
<windshieldChipCountQuestion
cmsWidgetName="WindshieldChipCountQuestion"
:isAvailable="isRepairOptionSelected && !hasRepairReplaceConflict"
groupName="WindshieldChipCountQuestion"
v-model="selectedWindshieldChipCountValues"
validationRules="windshield-chip-count-required" />
<replaceOptionsQuestion
ref="replaceOptionsQuestion"
cmsWidgetName="WindshieldReplaceOptionsQuestion"
:isAvailable="isReplaceOptionSelected"
isMultiSelect
groupName="WindshieldReplaceOptions"
v-model="selectedWindshieldReplaceOptionsValues"
validationRules="windshield-replace-options-required|prevent-split-and-single-together"
:suppressError="hasSplitSingleConflict"
isRequired />
<alert
v-if="hasSplitSingleConflict"
class="mt-5"
cmsWidgetName="SplitSingleConflict"
alertClass="alert-danger"
:isDismissible="false" />
</div>
</template>
<script>
import buttonQuestion from "@/common-components/button-question/button-question";
import windshieldDamageTypeQuestion from "@/layouts/vehicle-damage/windshield-options/windshield-damage-type-question/windshield-damage-type-question";
import windshieldChipCountQuestion from "@/layouts/vehicle-damage/windshield-options/windshield-chip-count-question/windshield-chip-count-question";
import replaceOptionsQuestion from "@/layouts/vehicle-damage/replace-options-question/replace-options-question";
import alert from "@/ux-components/alert/alert";
import { defineRule } from "vee-validate";
import { required } from "@/helpers/validation-rules";
import { errorMessages } from "@/constants/error-messages";
import { damageLocationsSelected } from "@/constants/damage-locations-selected.js";
// DEFINE VALIDATION RULES
defineRule(
"windshield-damage-type-required",
required(errorMessages.WINDSHIELD_DAMAGE_TYPE_REQUIRED)
);
defineRule(
"windshield-chip-count-required",
required(errorMessages.WINDSHIELD_CHIP_COUNT_REQUIRED)
);
defineRule(
"windshield-replace-options-required",
required(errorMessages.WINSHIELD_REPLACE_OPTIONS_REQUIRED)
);
defineRule(
"check-for-repair-and-replace",
(selectedWindshieldDamageType, selectedDamageLocations) => {
return (
selectedWindshieldDamageType.toString() != damageLocationsSelected.REPAIR ||
(!selectedDamageLocations.includes(damageLocationsSelected.WINDSHIELD) &&
!selectedDamageLocations[0]?.includes(damageLocationsSelected.WINDSHIELD)) ||
selectedDamageLocations[0].length === 1
);
}
);
defineRule("repair-only", (value) => {
return value.toString() === damageLocationsSelected.REPAIR;
});
defineRule("prevent-split-and-single-together", (value) => {
if (
value.toString().toUpperCase().includes(damageLocationsSelected.SINGLE.toUpperCase()) &&
(value.toString().toUpperCase().includes(damageLocationsSelected.DRIVER.toUpperCase()) ||
value
.toString()
.toUpperCase()
.includes(damageLocationsSelected.PASSENGER.toUpperCase()))
) {
return false;
}
return true;
});
export default {
name: "windshieldDamageTypeQuestion",
name: "windshieldOptions",
data() {
return {
windshieldAvailableReplacementOptions: Object,
};
},
props: {
modelValue: String,
groupName: String,
isAvailable: Boolean,
suppressError: Boolean,
validationRules: String,
cmsWidgetName: String,
modelValue: Object,
selectedDamageLocations: Array,
hasRepairReplaceConflict: Boolean,
hasSplitSingleConflict: Boolean,
},
methods: {
initializeComponent(windshieldAvailableReplacementOptions) {
this.windshieldAvailableReplacementOptions = windshieldAvailableReplacementOptions;
this.$refs.replaceOptionsQuestion.initializeComponent(
windshieldAvailableReplacementOptions
);
},
getWindshieldOptions(
selectedWindshieldDamageType,
selectedWindshieldChipCount,
selectedWindshieldReplaceOptions
) {
// ONLY UPDATE THE NEW VALUE IF IT IS TRUTHY (NOT NULL)
return {
selectedWindshieldDamageType: selectedWindshieldDamageType
? selectedWindshieldDamageType
: this.selectedValues.selectedWindshieldDamageType,
selectedWindshieldChipCount: selectedWindshieldChipCount
? selectedWindshieldChipCount
: this.selectedValues.selectedWindshieldChipCount,
selectedWindshieldReplaceOptions: selectedWindshieldReplaceOptions
? selectedWindshieldReplaceOptions
: this.selectedValues.selectedWindshieldReplaceOptions,
};
},
},
computed: {
questionText() {
return this.getCmsContent(this.cmsWidgetName, "QuestionText");
},
answersFromCms() {
return this.getCmsContent(this.cmsWidgetName, "Answers");
},
selectedValues: {
get: function () {
return this.modelValue;
@ -42,9 +142,97 @@ export default {
this.$emit("update:modelValue", newValue);
},
},
selectedWindshieldDamageTypeValue: {
get: function () {
return this.selectedDamageLocations.includes(damageLocationsSelected.WINDSHIELD)
? this.selectedValues.selectedWindshieldDamageType
: null;
},
set: function (newValue) {
this.selectedValues = this.getWindshieldOptions(newValue, null, null);
},
},
selectedWindshieldChipCountValues: {
get: function () {
return this.selectedValues.selectedWindshieldChipCount;
},
set: function (newValue) {
this.selectedValues = this.getWindshieldOptions(
this.selectedWindshieldDamageTypeValue,
newValue,
null
);
},
},
selectedWindshieldReplaceOptionsValues: {
get: function () {
return this.selectedValues.selectedWindshieldReplaceOptions;
},
set: function (newValue) {
this.selectedValues = this.getWindshieldOptions(
this.selectedWindshieldDamageTypeValue,
null,
newValue
);
},
},
isWindshieldDamageLocation() {
return this.selectedDamageLocations.some(
(selectedDamageLocation) =>
selectedDamageLocation === damageLocationsSelected.WINDSHIELD
);
},
isRepairOptionSelected() {
if (!this.selectedWindshieldDamageTypeValue) return false;
return (
this.selectedWindshieldDamageTypeValue === damageLocationsSelected.REPAIR &&
this.isWindshieldDamageLocation
);
},
isReplaceOptionSelected() {
if (!this.selectedWindshieldDamageTypeValue) return false;
return (
this.selectedWindshieldDamageTypeValue === damageLocationsSelected.REPLACE &&
this.isWindshieldDamageLocation
);
},
isWindshieldReplaceAvailable() {
return !(
Array.isArray(this.windshieldAvailableReplacementOptions) &&
this.windshieldAvailableReplacementOptions.length < 1
);
},
isSplitWindshieldOption() {
const options = this.windshieldAvailableReplacementOptions.toString().toUpperCase();
if (options.includes("DRIVER") && options.includes("PASSENGER")) {
return true;
}
return false;
},
showNoReplacementAvailableError() {
if (this.isReplaceOptionSelected && !this.isWindshieldReplaceAvailable) {
return true;
}
return false;
},
windshieldDamageTypeQuestionValidationRules() {
// Note: the validation rules string is not dynamic (it cannot be changed once component has been created)
let validationRules =
"windshield-damage-type-required|check-for-repair-and-replace:@DamageLocationQuestion";
// if vehicle has no windshield replacement option
if (!this.isWindshieldReplaceAvailable) {
validationRules = validationRules.concat("|repair-only");
}
return validationRules;
},
},
components: {
buttonQuestion,
windshieldDamageTypeQuestion,
windshieldChipCountQuestion,
replaceOptionsQuestion,
alert,
},
};
</script>

View file

@ -29,6 +29,14 @@ const getDefaultState = () => {
lastName: null,
},
},
damage: {
isRepair: null,
numberOfChips: null,
glassToReplace: null,
partQuestionAnswers: null,
moldingQuestionAnswers: null,
capabilityQuestionAnswers: null,
},
referralNumber: null,
referralDate: null,
accountNumber: 0,
@ -49,7 +57,8 @@ export const useMainStore = defineStore({
id: storeId,
state: () => state,
getters: {
vehicle: this.order.vehicle,
vehicle: (state) => state.order.vehicle,
damage: (state) => state.order.damage,
eventBusItem: (state) => ( eventCategory, eventSubCategory) => {
const matchedEvent = state.applicationUser.eventBus.find(