diff --git a/src/common-components/button-question/button-question.vue b/src/common-components/button-question/button-question.vue index f2f87931e..b46d933c0 100644 --- a/src/common-components/button-question/button-question.vue +++ b/src/common-components/button-question/button-question.vue @@ -37,8 +37,8 @@ -
- +
+
@@ -133,9 +133,10 @@ export default { if(this.isMultiSelect && this.selectedValues) { // Add or remove item to array of data to emit const newSelectedValues = this.selectedValues; + if(Array.isArray(this.selectedValues)) { val.checkValue ? newSelectedValues.push(val.value) : newSelectedValues.splice(newSelectedValues.indexOf(val.value), 1); - this.selectedValues = newSelectedValues; + this.selectedValues = newSelectedValues; } } else { this.selectedValues = [val.value]; @@ -154,11 +155,11 @@ export default { diff --git a/src/layouts/vehicle-damage/windshield-options/windshield-options.vue b/src/layouts/vehicle-damage/windshield-options/windshield-options.vue index 1d483f269..30f8c15d7 100644 --- a/src/layouts/vehicle-damage/windshield-options/windshield-options.vue +++ b/src/layouts/vehicle-damage/windshield-options/windshield-options.vue @@ -1,12 +1,20 @@ @@ -27,18 +44,40 @@ 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("checkForRepairAndReplace", (value, [other]) => { - if (value.toString().toUpperCase().includes("REPAIR") && other.toString().toUpperCase().includes("WINDSHIELD") && other.length > 1) { - return "checkForRepairAndReplace error" +defineRule("checkForRepairAndReplace", (value, [otherFieldValue]) => { + if (value.toString().toUpperCase().includes(damageLocationsSelected.REPAIR.toUpperCase()) && + otherFieldValue.toString().toUpperCase().includes(damageLocationsSelected.WINDSHIELD.toUpperCase()) && + Array.isArray(otherFieldValue) && + otherFieldValue.length > 1) + { + return false; + } + return true; +}); +defineRule("repairOnly", (value) => { + if (value.toString().toUpperCase() === damageLocationsSelected.REPAIR.toUpperCase()) { + return true; + } + return false; +}); +defineRule("preventSplitAndSingleTogether", (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; }); @@ -46,10 +85,17 @@ defineRule("checkForRepairAndReplace", (value, [other]) => { export default ({ name: "windshieldOptions", + data(){ + return { + windshieldAvailableReplacementOptions: Object, + } + }, + props: { modelValue: Array, selectedDamageLocations: Array, - hasRepairReplaceConflict: Boolean + hasRepairReplaceConflict: Boolean, + hasSplitSingleConflict: Boolean, }, methods: { @@ -59,12 +105,15 @@ export default ({ this.$refs.windshieldDamageTypeQuestion.initializeComponent(windshieldDamageTypeQuestionFromCms); this.$refs.windshieldChipCountQuestion.initializeComponent(windshieldChipCountQuestionFromCms); this.$refs.replaceOptionsQuestion.initializeComponent(windshieldReplaceOptionsQuestionFromCms, windshieldAvailableReplacementOptions); + + this.windshieldAvailableReplacementOptions = windshieldAvailableReplacementOptions; }, getWindshieldOptions(selectedWindshieldDamageType, selectedWindshieldChipCount, selectedWindshieldReplaceOptions){ + // ONLY UPDATE THE NEW VALUE IF IT IS TRUTHY (NOT NULL) return { - selectedWindshieldDamageType: selectedWindshieldDamageType, - selectedWindshieldChipCount: selectedWindshieldChipCount, - selectedWindshieldReplaceOptions: selectedWindshieldReplaceOptions + selectedWindshieldDamageType: selectedWindshieldDamageType ? selectedWindshieldDamageType : this.selectedValues.selectedWindshieldDamageType, + selectedWindshieldChipCount: selectedWindshieldChipCount ? selectedWindshieldChipCount : this.selectedValues.selectedWindshieldChipCount, + selectedWindshieldReplaceOptions: selectedWindshieldReplaceOptions ? selectedWindshieldReplaceOptions : this.selectedValues.selectedWindshieldReplaceOptions, } }, }, @@ -102,7 +151,7 @@ export default ({ } }, isWindshieldDamageLocation() { - return this.selectedDamageLocations.some(selectedDamages => + return this.selectedDamageLocations.some(selectedDamages => { return Boolean(selectedDamages.toUpperCase() === "WINDSHIELD"); }); @@ -117,11 +166,37 @@ export default ({ return this.selectedWindshieldDamageTypeValues.some(val => val.toUpperCase() === "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|checkForRepairAndReplace:@DamageLocationQuestion"; + // if vehicle has no windshield replacement option + if (!this.isWindshieldReplaceAvailable) { + validationRules = validationRules.concat('|repairOnly'); + } + return validationRules; + } }, components: { windshieldDamageTypeQuestion, windshieldChipCountQuestion, - replaceOptionsQuestion + replaceOptionsQuestion, + alert, }, }) \ No newline at end of file diff --git a/src/layouts/vin-lookup/vin-lookup.spec.js b/src/layouts/vin-lookup/vin-lookup.spec.js new file mode 100644 index 000000000..3d0843e10 --- /dev/null +++ b/src/layouts/vin-lookup/vin-lookup.spec.js @@ -0,0 +1 @@ +test.todo("some test to be written in the future"); diff --git a/src/layouts/vin-lookup/vin-lookup.vue b/src/layouts/vin-lookup/vin-lookup.vue new file mode 100644 index 000000000..aa179439a --- /dev/null +++ b/src/layouts/vin-lookup/vin-lookup.vue @@ -0,0 +1,102 @@ + + + + + diff --git a/src/router/router-constants/fmgPage-values.js b/src/router/router-constants/fmgPage-values.js index 770c1f7b6..b648ae047 100644 --- a/src/router/router-constants/fmgPage-values.js +++ b/src/router/router-constants/fmgPage-values.js @@ -4,9 +4,10 @@ const fmgPageValues = { VEHICLE_MODEL: "vehicle-model", VEHICLE_STYLE: "vehicle-style", VEHICLE_DAMAGE: "vehicle-damage", + VIN_LOOKUP: "vin-lookup", VEHICLE_PARTS: "vehicle-parts", PART_QUESTIONS: "part-questions", REVEAL : "reveal", }; -export { fmgPageValues }; \ No newline at end of file +export { fmgPageValues }; diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index e4c657a1d..70e47c832 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -94,6 +94,19 @@ const routingTable = [ }, ], }, + { + fmgPageValue: fmgPageValues.REVEAL, + maps: [ + { + scenario: navigationScenarios.CLICKED_BACK, + destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE, + }, + { + scenario: navigationScenarios.SELECTED_PARTS, + destinationFmgPageValue: fmgPageValues.VIN_LOOKUP, + }, + ], + }, ]; export { routingTable }; diff --git a/src/store/index.js b/src/store/index.js index 8e5e801c5..f453aa340 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -128,11 +128,7 @@ export const mutations = { resetDamageState(state) { state.order.damage.isRepair = null; state.order.damage.numberOfChips = null; - state.order.damage.windshieldGlassToReplace = null; - state.order.damage.driverSideGlassToReplace = null; - state.order.damage.passengerSideGlassToReplace = null; - state.order.damage.rearGlassToReplace = null; - + state.order.damage.glassToReplace = null; }, resetRegistrationState(state) { diff --git a/src/store/store.spec.js b/src/store/store.spec.js index ccb715e50..a3f8a5cb5 100644 --- a/src/store/store.spec.js +++ b/src/store/store.spec.js @@ -139,19 +139,13 @@ describe("Mutations", () => { storeState.order.damage = { isRepair: true, numberOfChips: 2, - windshieldGlassToReplace: "Front", - driverSideGlassToReplace: "Rear", - passengerSideGlassToReplace: "Rear", - rearGlassToReplace: "Slider" + glassToReplace: [{location: 'Rear', name: 'Stationary'}] } // Expect expect(storeState.order.damage.isRepair).toEqual(true); expect(storeState.order.damage.numberOfChips).toEqual(2); - expect(storeState.order.damage.windshieldGlassToReplace).toEqual("Front"); - expect(storeState.order.damage.driverSideGlassToReplace).toEqual("Rear"); - expect(storeState.order.damage.passengerSideGlassToReplace).toEqual("Rear"); - expect(storeState.order.damage.rearGlassToReplace).toEqual("Slider"); + expect(storeState.order.damage.glassToReplace).toStrictEqual([{location: 'Rear', name: 'Stationary'}]); // Act mutations.resetDamageState(storeState); @@ -159,11 +153,7 @@ describe("Mutations", () => { // Expect expect(storeState.order.damage.isRepair).toEqual(null); expect(storeState.order.damage.numberOfChips).toEqual(null); - expect(storeState.order.damage.windshieldGlassToReplace).toEqual(null); - expect(storeState.order.damage.driverSideGlassToReplace).toEqual(null); - expect(storeState.order.damage.passengerSideGlassToReplace).toEqual(null); - expect(storeState.order.damage.rearGlassToReplace).toEqual(null); - + expect(storeState.order.damage.glassToReplace).toEqual(null); }); it("Updates number of chips in state", () => { diff --git a/src/styles/common-styles.scss b/src/styles/common-styles.scss index 47ea0815d..8425a3021 100644 --- a/src/styles/common-styles.scss +++ b/src/styles/common-styles.scss @@ -3,6 +3,7 @@ body { font-size: 16px; background-color: #fff; + color: #4D5151; .container-fluid { max-width: 576px; //Remove once desktop app is complete &.container-shadow { @@ -22,7 +23,7 @@ body { } .container, .container-fluid { - overflow-x: hidden; + overflow-x: hidden !important; } .sr-only { @@ -34,4 +35,3 @@ body { overflow: hidden; } } -// Hide horizontal scrollbar diff --git a/src/styles/ux-variables.scss b/src/styles/ux-variables.scss index 83dadd34a..88d95030e 100644 --- a/src/styles/ux-variables.scss +++ b/src/styles/ux-variables.scss @@ -107,6 +107,9 @@ $theme-colors: ( "dark": $dark ); +//Default font color +$body-color: $gray-600; + //Fonts $font-family-sans-serif: Roboto, Arial, Helvetica, sans-serif; $font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;