+
+${{ wipersModal.totalRearPrice }}
@@ -62,12 +56,17 @@
import buttonQuestion from "@/digital-components/button-question/button-question";
import addVapsButton from "./add-vaps-button/add-vaps-button";
import contentGroupModal from "@/fmg-components/content-group-modal/content-group-modal";
-import checkboxQuestion from "@/digital-components/checkbox-question/checkbox-question";
// SUPPORTING
import { partTypeStrings } from "@/constants/part-type-strings";
+import { defineRule } from "vee-validate";
+import { required } from "@/helpers/validation-rules";
+import { errorMessages } from "@/constants/error-messages";
-const wipersToDisplayStrings = {
+// DEFINE VALIDATION RULES
+defineRule("checkbox-required", required(errorMessages.OPTION_REQUIRED));
+
+const wipersOfferedStrings = {
FRONT: "FRONT",
REAR: "REAR",
BOTH: "BOTH",
@@ -83,15 +82,22 @@ export default {
data() {
return {
addVapsButton: addVapsButton,
- selectedFrontWipers: false,
- selectedRearWipers: false,
- wipersToDisplay: null,
+ wipersToAddToCart: [],
+ wipersOffered: null,
+ isModalOpened: false,
+ selectedWipers: this.getSelectedWipers(),
};
},
methods: {
openModal(modalName) {
this.$refs[modalName].openModal();
},
+ closeModal(modalName) {
+ this.$refs[modalName].closeModal();
+ },
+ formatString(str) {
+ return String(str).replaceAll(" ", "-");
+ },
addRainDefenseToCart(modalName, part) {
const alreadyInCart = this.currentCartItems.vaps.some((item) => {
return item.partType === part.partType;
@@ -99,9 +105,11 @@ export default {
if (!alreadyInCart) {
this.currentCartItems.vaps.push(part);
}
- this.$refs[modalName].closeModal();
+ this.closeModal(modalName);
},
addWipersToCart(modalName, part) {
+ const itemsForCart = [];
+
const frontWipersAlreadyInCart = this.currentCartItems.vaps.some((item) => {
return item.partType === part.frontWiperLineItems[0].partType;
});
@@ -109,36 +117,43 @@ export default {
return item.partType === part.rearWiperLineItems[0]?.partType;
});
- if (this.wipersToDisplay === wipersToDisplayStrings.FRONT) {
- this.selectedFrontWipers = true; // set as true if front wipers is only option
+ if (this.wipersOffered === wipersOfferedStrings.BOTH) {
+ this.selectedWipers.forEach((wiper) => {
+ itemsForCart.push(wiper);
+ });
+ } else {
+ if (
+ !frontWipersAlreadyInCart &&
+ this.wipersOffered === wipersOfferedStrings.FRONT
+ ) {
+ itemsForCart.push(wipersOfferedStrings.FRONT);
+ }
+ if (!rearWipersAlreadyInCart && this.wipersOffered === wipersOfferedStrings.REAR) {
+ itemsForCart.push(wipersOfferedStrings.REAR);
+ }
}
- if (this.wipersToDisplay === wipersToDisplayStrings.REAR) {
- this.selectedRearWipers = true; // set as true if rear wipers is only option
- }
- if (!frontWipersAlreadyInCart && this.selectedFrontWipers) {
- if (part.frontWiperLineItems) {
- // for wipers, a "combined" part (frontWiperLineItems)
+
+ itemsForCart.forEach((type) => {
+ if (type === wipersOfferedStrings.FRONT) {
part.frontWiperLineItems.forEach((part) => {
this.currentCartItems.vaps.push(part);
});
}
- }
- if (!rearWipersAlreadyInCart && this.selectedRearWipers) {
- if (part.rearWiperLineItems) {
+ if (type === wipersOfferedStrings.REAR) {
part.rearWiperLineItems.forEach((part) => {
this.currentCartItems.vaps.push(part);
});
}
- }
- this.$refs[modalName].closeModal();
+ });
- if (this.wipersToDisplay === wipersToDisplayStrings.BOTH) {
- this.selectedFrontWipers = false; // set as false if both options are given
- this.selectedRearWipers = false; // set as false if both options are given
- }
+ this.closeModal(modalName);
+ this.selectedWipers;
},
- updateWipersToDisplay(value) {
- this.wipersToDisplay = value;
+ updateWipersOffered(value) {
+ this.wipersOffered = value;
+ },
+ getSelectedWipers() {
+ return null;
},
},
computed: {
@@ -229,31 +244,72 @@ export default {
];
prices.sort((a, b) => a - b);
modalData.SubText = "+$" + prices[0] + " - $" + prices[prices.length - 1];
- this.updateWipersToDisplay(wipersToDisplayStrings.BOTH);
+ this.updateWipersOffered(wipersOfferedStrings.BOTH);
buttons.push(modalData);
} else {
// NO FRONT WIPERS IN CART; SHOW ONLY FRONT WIPERS BUTTON
modalData.SubText = "+$" + this.wipersModal?.totalFrontPrice;
- this.updateWipersToDisplay(wipersToDisplayStrings.FRONT);
+ this.updateWipersOffered(wipersOfferedStrings.FRONT);
buttons.push(modalData);
}
} else if (!rearWipersInCart && this.wipersModal?.rearWiperLineItems.length > 0) {
// NO REAR WIPERS IN CART; SHOW ONLY REAR WIPERS BUTTON
modalData.SubText = "+$" + this.wipersModal?.totalRearPrice;
- this.updateWipersToDisplay(wipersToDisplayStrings.REAR);
+ this.updateWipersOffered(wipersOfferedStrings.REAR);
buttons.push(modalData);
}
return buttons;
},
- wipersToDisplayStrings() {
- return wipersToDisplayStrings;
+ wipersOfferedStrings() {
+ return wipersOfferedStrings;
+ },
+ wipersOptions() {
+ const wipersOptions = [];
+ const wipersFrontCopy = this.getCmsContent(
+ "AddFrontBladesQuestionWidget",
+ "QuestionText"
+ );
+ const wipersRearCopy = this.getCmsContent(
+ "AddRearBladesQuestionWidget",
+ "QuestionText"
+ );
+ const frontWipersLineItems = this.wipersModal.frontWiperLineItems;
+ const rearWipersLineItems = this.wipersModal.rearWiperLineItems;
+
+ if (frontWipersLineItems) {
+ const wipersOption = {
+ buttonLabel: wipersFrontCopy,
+ groupName: "wipers-options",
+ value: wipersOfferedStrings.FRONT,
+ buttonLabelSubCopy: "buttonLabelSubCopy",
+ buttonBodyCopy: "buttonBodyCopy",
+ buttonAuxillaryCopy: "buttonAuxillaryCopy",
+ buttonFooterCopy: "buttonFooterCopy",
+ additionalButtonData: "+$" + this.wipersModal.totalFrontPrice,
+ };
+ wipersOptions.push(wipersOption);
+ }
+ if (rearWipersLineItems) {
+ const wipersOption = {
+ buttonLabel: wipersRearCopy,
+ groupName: "wipers-options",
+ value: wipersOfferedStrings.REAR,
+ buttonLabelSubCopy: "buttonLabelSubCopy",
+ buttonBodyCopy: "buttonBodyCopy",
+ buttonAuxillaryCopy: "buttonAuxillaryCopy",
+ buttonFooterCopy: "buttonFooterCopy",
+ additionalButtonData: "+$" + this.wipersModal.totalRearPrice,
+ };
+ wipersOptions.push(wipersOption);
+ }
+
+ return wipersOptions;
},
},
components: {
buttonQuestion,
contentGroupModal,
- checkboxQuestion,
},
};
@@ -286,26 +342,31 @@ export default {
text-align: center;
}
.wiper-options {
- & > div {
- display: flex;
- justify-content: space-between;
- margin-bottom: 1rem;
+ .ui-checkbox {
+ display: block;
- &:last-child {
- margin-bottom: 0;
+ & > div.col {
+ margin-bottom: 1rem;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
}
+ .checkbox {
+ display: flex;
+ justify-content: space-between;
- .form-check {
- margin-bottom: 0;
+ .additional-button-data {
+ font-size: 0.875rem;
+ line-height: 1.75;
+ padding-left: 0.5rem;
+ color: $green;
+ }
}
}
p {
margin-bottom: 0;
- }
- p.price {
- font-size: 0.875rem;
- padding-left: 0.5rem;
- color: $green;
+ line-height: 1.75;
}
}
}
diff --git a/src/ux-components/checkbox/checkbox.spec.js b/src/ux-components/checkbox/checkbox.spec.js
new file mode 100644
index 000000000..7aa72b718
--- /dev/null
+++ b/src/ux-components/checkbox/checkbox.spec.js
@@ -0,0 +1,66 @@
+import { mount } from "@vue/test-utils";
+import checkbox from "./checkbox";
+import { getMountOptions } from "@/helpers/unit-test-helper.js";
+import inputButtonWrapperMixin from "@/mixins/input-button-wrapper-mixin";
+
+describe("checkbox.vue", () => {
+ it("Should have correct group name", async () => {
+ // Arrange
+ let { wrapper } = setupMocks({
+ mountOptionsMockData: {
+ propsData: {
+ groupName: "checkbox-button-test",
+ value: "test value",
+ },
+ },
+ });
+
+ // Act
+ const input = wrapper.find("input");
+
+ // Assert
+ expect(input.attributes().name).toEqual("checkbox-button-test");
+ });
+
+ it("Should have correct label text", async () => {
+ // Act
+ let { wrapper } = setupMocks({
+ mountOptionsMockData: {
+ propsData: {
+ buttonLabel: "label text",
+ value: "test value",
+ },
+ },
+ });
+
+ // Arrange
+ const paragraph = wrapper.find("p");
+
+ // Assert
+ expect(paragraph.text()).toEqual("label text");
+ });
+
+ it("Should have correct screenreader-only text", async () => {
+ // Act
+ let { wrapper } = setupMocks({});
+
+ // Arrange
+ await wrapper.setProps({
+ screenReaderOnlyText: "screenreader text",
+ value: "test value",
+ });
+ const paragraph = wrapper.find(".sr-only");
+
+ // Assert
+ expect(paragraph.text()).toEqual("screenreader text");
+ });
+});
+
+function setupMocks({ mountOptionsMockData = {} }) {
+ const wrapper = mount(checkbox, {
+ ...mountOptionsMockData,
+ mixins: [inputButtonWrapperMixin],
+ });
+
+ return { wrapper };
+}
diff --git a/src/ux-components/checkbox/checkbox.vue b/src/ux-components/checkbox/checkbox.vue
new file mode 100644
index 000000000..9c02b7b99
--- /dev/null
+++ b/src/ux-components/checkbox/checkbox.vue
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+
+