Merge branch 'develop' into rlsmerge/2025.02.27-to-develop

This commit is contained in:
CarlNation 2025-02-27 05:05:04 -05:00
commit ea9feb856b
18 changed files with 189 additions and 55 deletions

View file

@ -22,7 +22,8 @@ resources:
- container: awscli - container: awscli
image: packagerepository.sagaws.net:8082/safelite/awscli2-build:3.9 image: packagerepository.sagaws.net:8082/safelite/awscli2-build:3.9
- container: prettier-node - container: prettier-node
image: packagerepository.sagaws.net:8082/safelite/prettier-node-build:18 image: ghcr.io/safelite/prettier-node-build:23
endpoint: GitHub Docker
repositories: repositories:
- repository: AzureDevOps - repository: AzureDevOps
type: github type: github
@ -37,15 +38,15 @@ variables:
stages: stages:
# PR's # PR's
- ${{ if eq(variables['Build.Reason'], 'PullRequest') }}: - ${{ if eq(variables['Build.Reason'], 'PullRequest') }}:
# - stage: TestFormat - stage: TestFormat
# displayName: Test Code Format displayName: Test Code Format
# jobs: jobs:
# - job: checkFormatting - job: checkFormatting
# displayName: Check formatting displayName: Check formatting
# container: prettier-node container: prettier-node
# steps: steps:
# - bash: prettier --check "$(Build.SourcesDirectory)/src/**/*.(js|vue)" - bash: prettier --check "$(Build.SourcesDirectory)/src/**/*.(js|vue)"
# displayName: Run Prettier check displayName: Run Prettier check
- stage: TestPr - stage: TestPr
displayName: Run Unit Tests For PullRequest displayName: Run Unit Tests For PullRequest

View file

@ -18,6 +18,8 @@ const experimentSettings = {
INSURANCE_TAB_TO_DISPLAY_THRESHOLD_INTERNAL: "NextGen_InternalInsuranceTabDisplayThreshold", INSURANCE_TAB_TO_DISPLAY_THRESHOLD_INTERNAL: "NextGen_InternalInsuranceTabDisplayThreshold",
INSURANCE_TAB_TO_DISPLAY_THRESHOLD_EXTERNAL: "NextGen_ExternalInsuranceTabDisplayThreshold", INSURANCE_TAB_TO_DISPLAY_THRESHOLD_EXTERNAL: "NextGen_ExternalInsuranceTabDisplayThreshold",
DISPLAY_MSR: "DisplayMSR", DISPLAY_MSR: "DisplayMSR",
DISPLAY_WAITLIST: "DisplayWaitlist2.0",
WAITLIST_THRESHOLD_DAYS: "Waitlist_Threshold_Days",
PRICING_BY_DAY: "DisplayPricingByDay", PRICING_BY_DAY: "DisplayPricingByDay",
FOSTER_LOVE: "DisplayFosterLove", FOSTER_LOVE: "DisplayFosterLove",
}; };

View file

@ -2,6 +2,7 @@ const partNumberStrings = {
// Recalibration // Recalibration
MOBILE_STATIC_RECAL_FEE: "RECAL MOBILE", MOBILE_STATIC_RECAL_FEE: "RECAL MOBILE",
MOBILE_DUAL_RECAL_FEE: "RECAL MOBILEDUAL", MOBILE_DUAL_RECAL_FEE: "RECAL MOBILEDUAL",
DONATION: "DONATION",
}; };
export { partNumberStrings }; export { partNumberStrings };

View file

@ -79,6 +79,7 @@ const storeActions = {
SAVE_EMAIL: "saveEmail", SAVE_EMAIL: "saveEmail",
SAVE_PHONE_NUMBER: "savePhoneNumber", SAVE_PHONE_NUMBER: "savePhoneNumber",
SAVE_IS_SMS_OPT_IN: "saveIsSmsOptIn", SAVE_IS_SMS_OPT_IN: "saveIsSmsOptIn",
SAVE_WAITLIST_REQUESTED: "saveWaitListRequested",
SAVE_REGISTRATION_LICENSE_PLATE_LOOKUP: "saveRegistrationLicensePlateLookup", SAVE_REGISTRATION_LICENSE_PLATE_LOOKUP: "saveRegistrationLicensePlateLookup",
SAVE_VIN: "saveVin", SAVE_VIN: "saveVin",
SAVE_REGISTRATION_ADDRESS_LOOKUP: "saveRegistrationAddressLookup", SAVE_REGISTRATION_ADDRESS_LOOKUP: "saveRegistrationAddressLookup",

View file

@ -42,6 +42,7 @@ const storeMutations = {
UPDATE_CUSTOMER_PHONE_NUMBER: "updateCustomerPhoneNumber", UPDATE_CUSTOMER_PHONE_NUMBER: "updateCustomerPhoneNumber",
UPDATE_CUSTOMER_IS_SMS_OPT_IN: "updateCustomerIsSmsOptin", UPDATE_CUSTOMER_IS_SMS_OPT_IN: "updateCustomerIsSmsOptin",
UPDATE_CUSTOMER_DETAILS: "updateCustomerDetails", UPDATE_CUSTOMER_DETAILS: "updateCustomerDetails",
UPDATE_CUSTOMER_WAITLIST_REQUESTED: "updateCustomerWaitListRequested",
// ORDER MUTATIONS // ORDER MUTATIONS
UPDATE_REFERRAL_NUMBER: "updateReferralNumber", UPDATE_REFERRAL_NUMBER: "updateReferralNumber",

View file

@ -1,5 +1,8 @@
<template> <template>
<div class="text-block w-100" :class="[justifyText, typeStyle, fontWeight, marginTopClass]"> <div
class="text-block w-100"
:class="[justifyText, typeStyle, fontWeight, marginTopClass]"
:style="{ 'font-weight': fontWeight }">
<span v-for="copy in splitCopyOnCMSPlaceHolder(this.textBlockCopy)" :key="copy"> <span v-for="copy in splitCopyOnCMSPlaceHolder(this.textBlockCopy)" :key="copy">
<span v-if="doesCopyContainRouterLink(copy)"> <span v-if="doesCopyContainRouterLink(copy)">
<textLink <textLink

View file

@ -130,10 +130,6 @@ export default {
}, },
methods: { methods: {
handleDonationAction(submitEvent) { handleDonationAction(submitEvent) {
console.log(
"running handleDonationAction(), submitEvent.target.elements.amount.value: ",
submitEvent.target.elements.amount.value
);
this.selectedValue = submitEvent.target.elements.amount.value; this.selectedValue = submitEvent.target.elements.amount.value;
}, },
}, },

View file

@ -1,10 +1,9 @@
<template> <template>
<baseInputButton v-bind="$props" @buttonClicked="handleAnswerChange" v-model="selectedValue"> <baseInputButton v-bind="$props" @buttonClicked="handleAnswerChange" v-model="selectedValue">
<div <div
class="package-label" class="package-label pricing-by-day-pkg-lbl"
:class="[ :class="[
this.buttonLabelSubCopy ? 'has-subheader' : '', this.buttonLabelSubCopy ? 'has-subheader' : '',
this.isInsuranceSelected ? 'pricing-by-day-pkg-lbl-ins' : 'pricing-by-day-pkg-lbl',
!this.additionalButtonData.servicePackageDiscount ? 'adjust-top' : '', !this.additionalButtonData.servicePackageDiscount ? 'adjust-top' : '',
]" ]"
for="testradio"> for="testradio">
@ -21,9 +20,7 @@
</div> </div>
<span class="col md-6 service-package-discount-pricing-by-day"> <span class="col md-6 service-package-discount-pricing-by-day">
<div> <div>
<span v-if="!isInsuranceSelected" class="caption pricing-by-day"> <span class="caption pricing-by-day">as low as</span>
as low as
</span>
<div <div
class="strikethrough-discount-price" class="strikethrough-discount-price"
v-if="shouldDisplayStrikeThroughPrice" v-if="shouldDisplayStrikeThroughPrice"
@ -36,9 +33,7 @@
<p class="m-0"> <p class="m-0">
<span v-html="this.buttonLabel"></span> <span v-html="this.buttonLabel"></span>
<span class="pricing-info-pricing-by-day"> <span class="pricing-info-pricing-by-day">
<span v-if="!isInsuranceSelected" class="caption pricing-by-day"> <span class="caption pricing-by-day">as low as</span>
as low as
</span>
<span <span
class="strikethrough-price" class="strikethrough-price"
v-if="shouldDisplayStrikeThroughPrice" v-if="shouldDisplayStrikeThroughPrice"
@ -208,7 +203,7 @@ export default {
} }
@include media-breakpoint-up(lg) { @include media-breakpoint-up(lg) {
&:before { &:before {
top: .5rem; top: 0.5rem;
} }
&:after { &:after {
top: 1.4375rem; top: 1.4375rem;
@ -223,7 +218,7 @@ export default {
+ .package-label.pricing-by-day-pkg-lbl-ins { + .package-label.pricing-by-day-pkg-lbl-ins {
&:before { &:before {
top: .3125rem; top: 0.3125rem;
} }
&:after { &:after {
top: 1.25rem; top: 1.25rem;
@ -234,7 +229,7 @@ export default {
&:before { &:before {
top: 0.9375rem; top: 0.9375rem;
@include media-breakpoint-up(lg) { @include media-breakpoint-up(lg) {
top: .3125rem; top: 0.3125rem;
} }
} }
&:after { &:after {

View file

@ -14,6 +14,19 @@ import { experimentSettings } from "@/constants/experiments";
const mockExperimentSettings = experimentSettings; const mockExperimentSettings = experimentSettings;
jest.mock("@/mixins/experiment-mixin.js", () => ({
methods: {
getSettingValue(settingName) {
if (settingName === mockExperimentSettings.RECAL_PRICE_REMOVE) {
return true;
}
},
hasSettingEqualTo(settingName, settingValue) {
return true;
},
},
}));
// Mock our module for promises. // Mock our module for promises.
jest.mock("@/helpers/layout-helper.js", () => ({ jest.mock("@/helpers/layout-helper.js", () => ({
settleAllPromises: jest.fn(), settleAllPromises: jest.fn(),
@ -572,13 +585,6 @@ function setupMocks({ customMountOptions }) {
getCmsContent: jest.fn().mockImplementation(() => { getCmsContent: jest.fn().mockImplementation(() => {
return wordingText; return wordingText;
}), }),
getSettingValue: jest.fn((settingName) => {
if (settingName === experimentSettings.RECAL_PRICE_REMOVE) {
return "true";
}
return "false";
}),
}, },
}, },
]; ];

View file

@ -64,7 +64,7 @@
:isItac="isItac" :isItac="isItac"
:isNoComp="isNoComp" /> :isNoComp="isNoComp" />
<div class="mt-3" v-if="displayFosterLove"> <div class="mt-3" v-if="DisplayFosterLove">
<donationBlock <donationBlock
cmsWidgetName="DonationWidget" cmsWidgetName="DonationWidget"
v-model="donationAmount" v-model="donationAmount"
@ -73,10 +73,6 @@
:showDonationError="showDonationError" /> :showDonationError="showDonationError" />
</div> </div>
<!-- <button type="button" @click="addDonation(3)">
Add Donation of $3
</button> -->
<hr class="mb-5" /> <hr class="mb-5" />
<div class="emailtext" v-html="ConfirmationEmailText"></div> <div class="emailtext" v-html="ConfirmationEmailText"></div>
@ -122,6 +118,7 @@ import { partTypeStrings } from "@/constants/part-type-strings";
import { containsLineItemWithPartType } from "@/helpers/service-package-helper"; import { containsLineItemWithPartType } from "@/helpers/service-package-helper";
import { containsRecalParts } from "@/helpers/recal-helper.js"; import { containsRecalParts } from "@/helpers/recal-helper.js";
import donationBlock from "@/experiment-components/donation-block.vue"; import donationBlock from "@/experiment-components/donation-block.vue";
import { partNumberStrings } from "@/constants/part-number-strings";
export default { export default {
name: "confirmation", name: "confirmation",
@ -219,7 +216,7 @@ export default {
}; };
const donationItems = lineItemsFromSubmittedOrder.supportingItems?.filter( const donationItems = lineItemsFromSubmittedOrder.supportingItems?.filter(
(item) => item.partNumber === "DONATION" (item) => item.partNumber === partNumberStrings.DONATION
); );
const donationAmount = donationItems?.length > 0 ? donationItems[0].sellingPrice : 0; const donationAmount = donationItems?.length > 0 ? donationItems[0].sellingPrice : 0;
@ -532,13 +529,9 @@ export default {
"test", "test",
false false
).catch((error) => { ).catch((error) => {
// this.$refs.navbar.removeLoader();
console.error("Error!!! error: ", error);
return error; return error;
}); });
console.log("ran addDonation()... (*fake call*) donationResponse: ", donationResponse);
if (donationResponse?.status == "200") { if (donationResponse?.status == "200") {
this.showDonationSuccess = true; this.showDonationSuccess = true;
this.showDonationError = false; this.showDonationError = false;
@ -561,7 +554,6 @@ export default {
watch: { watch: {
donationAmount(newValue) { donationAmount(newValue) {
newValue = parseInt(newValue); newValue = parseInt(newValue);
console.log("WATCHED donationAmount changed: ", newValue);
// this.addDonation(newValue); // this.addDonation(newValue);
// TODO - when backend code is final, then remove the below and restore the line above // TODO - when backend code is final, then remove the below and restore the line above

View file

@ -35,7 +35,7 @@ jest.mock("@/mixins/experiment-mixin.js", () => ({
} }
}, },
hasSettingEqualTo(settingName, settingValue) { hasSettingEqualTo(settingName, settingValue) {
return true; return false;
}, },
}, },
})); }));

View file

@ -227,11 +227,9 @@ export default {
methods: { methods: {
processIfStatements, processIfStatements,
hasPricingByDay() { hasPricingByDay() {
return ( return experimentMixin.methods.hasSettingEqualTo(
experimentMixin.methods.hasSettingEqualTo( experimentSettings.PRICING_BY_DAY,
experimentSettings.PRICING_BY_DAY, "true"
"true"
) && !this.isInsuranceSelected
); );
}, },
getHeaderTextFromCms(cmsWidgetName) { getHeaderTextFromCms(cmsWidgetName) {
@ -264,6 +262,10 @@ export default {
servicePackageDiscount, servicePackageDiscount,
}) })
).toFixed(2); ).toFixed(2);
if (this.hasPricingByDay()) {
return "$" + formattedPriceFloat;
}
return (this.isInsuranceSelected ? "As little as $" : "$") + formattedPriceFloat; return (this.isInsuranceSelected ? "As little as $" : "$") + formattedPriceFloat;
}, },
getPackagePrice(packageName, { discountedPrice = false, servicePackageDiscount = false }) { getPackagePrice(packageName, { discountedPrice = false, servicePackageDiscount = false }) {

View file

@ -304,6 +304,7 @@ describe("schedule.vue...", () => {
days: [], days: [],
}; };
wrapper.vm.updateFooterButtonText = jest.fn(); wrapper.vm.updateFooterButtonText = jest.fn();
wrapper.vm.setDisplayWaitList = jest.fn();
const nextFunction = jest.fn((c) => { const nextFunction = jest.fn((c) => {
c(wrapper.vm); c(wrapper.vm);
}); });
@ -338,6 +339,7 @@ describe("schedule.vue...", () => {
}) })
); );
expect(wrapper.vm.updateFooterButtonText).toHaveBeenCalled(); expect(wrapper.vm.updateFooterButtonText).toHaveBeenCalled();
expect(wrapper.vm.setDisplayWaitList).toHaveBeenCalled();
}); });
}); });

View file

@ -43,6 +43,8 @@
customComponentId="timeSlotModalQuestion" customComponentId="timeSlotModalQuestion"
v-model="selectedTimeSlotInfo" v-model="selectedTimeSlotInfo"
cmsWidgetName="TimeSlotModalQuestion" cmsWidgetName="TimeSlotModalQuestion"
waitListLabelWidget="WaitListLabelWidget"
waitListQuestionWidget="WaitListQuestionWidget"
mobilePremiumCmsWidgetName="MobilePremiumTimeSlotModal" mobilePremiumCmsWidgetName="MobilePremiumTimeSlotModal"
mobileCmsWidgetName="MobileTimeSlotModal" mobileCmsWidgetName="MobileTimeSlotModal"
dropoffCmsWidgetName="DropOffTimeSlotModal" dropoffCmsWidgetName="DropOffTimeSlotModal"
@ -51,6 +53,7 @@
:selectedDate="selectedDate" :selectedDate="selectedDate"
:appointmentType="appointmentType" :appointmentType="appointmentType"
:premiumAppointmentFee="mobilePremiumAppointmentFee" :premiumAppointmentFee="mobilePremiumAppointmentFee"
:displayWaitList="displayWaitList"
:timeSlotsForSelectedDate="timeSlotsForSelectedDate" :timeSlotsForSelectedDate="timeSlotsForSelectedDate"
:estimatedServiceMinutesMinimum=" :estimatedServiceMinutesMinimum="
selectableDatesData.estimatedServiceMinutesMinimum selectableDatesData.estimatedServiceMinutesMinimum
@ -58,6 +61,7 @@
:estimatedServiceMinutesMaximum=" :estimatedServiceMinutesMaximum="
selectableDatesData.estimatedServiceMinutesMaximum selectableDatesData.estimatedServiceMinutesMaximum
" "
@waitListRequested-emitted="handleWaitListRequested"
@time-slot-modal-closed="timeSlotModalClosed" @time-slot-modal-closed="timeSlotModalClosed"
validationRules="time-slot-selection-required" validationRules="time-slot-selection-required"
@TimeSlotSelected="forwardButtonAction" /> @TimeSlotSelected="forwardButtonAction" />
@ -217,6 +221,8 @@ export default {
selectedTimeSlotInfo: this.getSelectedTimeSlotInfo(), selectedTimeSlotInfo: this.getSelectedTimeSlotInfo(),
selectableDatesData: [], selectableDatesData: [],
mobilePremiumAppointmentFee: null, mobilePremiumAppointmentFee: null,
waitListRequested: null,
displayWaitList: null,
}; };
}, },
async beforeRouteEnter(to, from, next) { async beforeRouteEnter(to, from, next) {
@ -295,6 +301,7 @@ export default {
? resultMap.premiumFeeWithPrice[0] ? resultMap.premiumFeeWithPrice[0]
: null; : null;
vm.updateFooterButtonText(vm.selectedTimeSlotInfo); vm.updateFooterButtonText(vm.selectedTimeSlotInfo);
vm.setDisplayWaitList();
}); });
}, },
computed: { computed: {
@ -469,6 +476,29 @@ export default {
forwardButtonAction() { forwardButtonAction() {
this.updateSupportingItems(); this.updateSupportingItems();
if (this.waitListRequested) {
var gaLabel = store.getters.isMobileAppointment
? "checked_mobile"
: "checked_inshop";
const currentDate = new Date();
const dateString = this.selectableDatesData.days[0].date;
const [year, month, day] = dateString.split("-").map(Number);
const appointmentDate = new Date(year, month - 1, day);
const timeDifference = appointmentDate - currentDate;
// Convert the time difference from milliseconds to days
const daysUntilAppointment = Math.ceil(timeDifference / (1000 * 60 * 60 * 24));
gaLabel +=
"_" +
daysUntilAppointment.toString() +
"_" +
store.getters.order.serviceLocation.zipCode +
"_" +
store.getters.order.serviceLocation.zipCodeCtu;
this.pushEventToGA("waitlist", "add_to_waitlist_check_box_status", gaLabel, true);
}
if (this.selectedTimeSlotInfo.timeSlot.jobMinMinutes == null) { if (this.selectedTimeSlotInfo.timeSlot.jobMinMinutes == null) {
this.selectedTimeSlotInfo.timeSlot.jobMinMinutes = this.selectedTimeSlotInfo.timeSlot.jobMinMinutes =
this.selectableDatesData?.estimatedServiceMinutesMinimum?.toString(); this.selectableDatesData?.estimatedServiceMinutesMinimum?.toString();
@ -482,8 +512,44 @@ export default {
false false
); );
this.dispatchStoreAction(
this.storeActions.SAVE_WAITLIST_REQUESTED,
this.waitListRequested,
false
);
this.$router.navigateWithSaving(this.navigationScenarios.CLICKED_FORWARD, this.$route); this.$router.navigateWithSaving(this.navigationScenarios.CLICKED_FORWARD, this.$route);
}, },
setDisplayWaitList() {
if (
experimentMixin.methods.hasSettingEqualTo(
experimentSettings.DISPLAY_WAITLIST,
"true"
)
) {
const dateString = this.selectableDatesData.days[0].date;
const [year, month, day] = dateString.split("-").map(Number);
const targetDate = new Date(year, month - 1, day);
const currentDate = new Date();
const futureDate = new Date(currentDate);
const experimentThresholdDays = experimentMixin.methods.hasSetting(
experimentSettings.WAITLIST_THRESHOLD_DAYS
)
? parseInt(
experimentMixin.methods.getSettingValue(
experimentSettings.WAITLIST_THRESHOLD_DAYS
)
)
: 0;
futureDate.setDate(currentDate.getDate() + experimentThresholdDays);
if (targetDate >= futureDate) {
this.displayWaitList = true;
} else {
this.displayWaitList = false;
}
}
},
updateSupportingItems() { updateSupportingItems() {
const supportingItems = this.getSupportingItems(); const supportingItems = this.getSupportingItems();
@ -532,6 +598,9 @@ export default {
} }
} }
}, },
handleWaitListRequested(value) {
this.waitListRequested = value;
},
}, },
watch: { watch: {
selectedDate(newValue, oldValue) { selectedDate(newValue, oldValue) {

View file

@ -26,7 +26,21 @@
isRequired isRequired
validationRules="time-slot-required" /> validationRules="time-slot-required" />
<div <div
class="mt-1 mb-2 supplemental-information" v-if="hasWaitListExperiment && displayWaitListFeature"
class="mt-5 bg-light rounded waitlist">
<textBlock
cmsWidgetName="WaitListLabelWidget"
typeStyle="medium"
fontWeight="600"
marginTopSizeOverride="0" />
<checkboxQuestion
class="mt-3"
cmsWidgetName="WaitListQuestionWidget"
v-model="waitListRequested"
@click="waitListChecked" />
</div>
<div
class="mt-5 mb-2 supplemental-information"
v-if="supplementalInformationBlock" v-if="supplementalInformationBlock"
v-html="supplementalInformationBlock"></div> v-html="supplementalInformationBlock"></div>
<textBlock <textBlock
@ -44,7 +58,11 @@
import modal from "@/digital-components/modal/modal"; import modal from "@/digital-components/modal/modal";
import textBlock from "@/digital-components/text-block/text-block"; import textBlock from "@/digital-components/text-block/text-block";
import buttonQuestion from "@/digital-components/button-question/button-question"; import buttonQuestion from "@/digital-components/button-question/button-question";
import checkboxQuestion from "@/digital-components/checkbox-question/checkbox-question";
import timeSlotModalListButton from "./time-slot-modal-list-button/time-slot-modal-list-button"; import timeSlotModalListButton from "./time-slot-modal-list-button/time-slot-modal-list-button";
import experimentMixin from "@/mixins/experiment-mixin";
import { experimentSettings } from "@/constants/experiments";
import store from "@/store";
// Helpers // Helpers
import { deepClone } from "@/helpers/object-helper"; import { deepClone } from "@/helpers/object-helper";
@ -82,7 +100,7 @@ defineRule("time-slot-required", required(errorMessages.OPTION_REQUIRED));
export default { export default {
name: "time-slot-modal-question", name: "time-slot-modal-question",
emits: ["update:modelValue", "TimeSlotSelected"], emits: ["update:modelValue", "TimeSlotSelected", "click-event"],
props: { props: {
modelValue: { modelValue: {
type: Object, type: Object,
@ -112,12 +130,14 @@ export default {
validationRules: String, validationRules: String,
customComponentId: String, customComponentId: String,
selectedDate: String, selectedDate: String,
displayWaitList: Boolean,
}, },
data() { data() {
return { return {
isModalOpened: false, isModalOpened: false,
selectedRouteCode: this.getSelectedRouteCode(), selectedRouteCode: this.getSelectedRouteCode(),
timeSlotModalListButton: timeSlotModalListButton, timeSlotModalListButton: timeSlotModalListButton,
waitListRequested: this.getWaitListRequestedFromStore(),
}; };
}, },
setup(props) { setup(props) {
@ -330,6 +350,15 @@ export default {
return this.getAvailableTimeSlotsForInshop(this.timeSlotsForSelectedDate.timeSlots); return this.getAvailableTimeSlotsForInshop(this.timeSlotsForSelectedDate.timeSlots);
} }
}, },
hasWaitListExperiment() {
return experimentMixin.methods.hasSettingEqualTo(
experimentSettings.DISPLAY_WAITLIST,
"true"
);
},
displayWaitListFeature() {
return this.displayWaitList;
},
}, },
methods: { methods: {
openModal() { openModal() {
@ -445,6 +474,9 @@ export default {
return selectedRouteCode; return selectedRouteCode;
}, },
getWaitListRequestedFromStore() {
return store.getters.order.customer?.waitListRequested;
},
autoSelectTimeSlotIfOnlyOneIsAvailable() { autoSelectTimeSlotIfOnlyOneIsAvailable() {
const numberOfOptions = this.availableTimeSlots?.length; const numberOfOptions = this.availableTimeSlots?.length;
if (numberOfOptions === 1) { if (numberOfOptions === 1) {
@ -493,6 +525,9 @@ export default {
isPremiumAppointment: null, isPremiumAppointment: null,
}; };
}, },
waitListChecked(event) {
this.$emit("waitListRequested-emitted", event.target.checked);
},
}, },
unmounted() { unmounted() {
if (this.isModalOpened) this.closeModal(); if (this.isModalOpened) this.closeModal();
@ -515,6 +550,7 @@ export default {
modal, modal,
textBlock, textBlock,
buttonQuestion, buttonQuestion,
checkboxQuestion,
}, },
}; };
</script> </script>
@ -538,5 +574,19 @@ export default {
margin-bottom: 8px; margin-bottom: 8px;
} }
} }
.waitlist {
box-shadow: 0px 1px 4px 0px #00000033;
border-radius: 8px;
font-size: $h6-font-size;
padding: 16px;
margin-top: 16px;
margin-bottom: -8px;
.ui-checkbox {
padding-left: 0px;
}
.form-check-input {
margin-left: 0px;
}
}
} }
</style> </style>

View file

@ -42,11 +42,16 @@ export default {
await this.validateSession(); await this.validateSession();
const submittedOrder = baseMixin.methods.getSubmittedOrder(); const submittedOrder = baseMixin.methods.getSubmittedOrder();
const hasSubmittedOrder = baseMixin.methods.hasSubmittedOrder();
const refSequenceNum = const refSequenceNum =
store.getters.order.referralSequenceNumber || store.getters.order.referralSequenceNumber ||
submittedOrder?.referralSequenceNumber; submittedOrder?.referralSequenceNumber;
const parentAccountNum = hasSubmittedOrder
? submittedOrder.payment.parentAccountNumber
: store.getters.order.payment.parentAccountNumber;
var payload = { var payload = {
userId: getUserIdValue(), userId: getUserIdValue(),
sessionKey: getSessionKeyValue(), sessionKey: getSessionKeyValue(),
@ -57,7 +62,7 @@ export default {
shouldUseSessionId: false, shouldUseSessionId: false,
experimentsForUser: store.getters.applicationUser.experiments, experimentsForUser: store.getters.applicationUser.experiments,
referralSequenceNumber: refSequenceNum, referralSequenceNumber: refSequenceNum,
parentAccountNumber: store.getters.order.payment.parentAccountNumber, parentAccountNumber: parentAccountNum,
}; };
await baseMixin.methods.dispatchStoreAction(storeActions.LOG_PAGE_VIEW, payload, false); await baseMixin.methods.dispatchStoreAction(storeActions.LOG_PAGE_VIEW, payload, false);

View file

@ -98,6 +98,7 @@ const getDefaultState = () => {
emailAddress: null, emailAddress: null,
phoneNumber: null, phoneNumber: null,
isSmsOptIn: null, isSmsOptIn: null,
waitListRequested: null,
}, },
damage: { damage: {
isRepair: null, isRepair: null,
@ -346,6 +347,9 @@ export const mutations = {
updateCustomerIsSmsOptin(state, isSmsOptIn) { updateCustomerIsSmsOptin(state, isSmsOptIn) {
state.order.customer.isSmsOptIn = isSmsOptIn; state.order.customer.isSmsOptIn = isSmsOptIn;
}, },
updateCustomerWaitListRequested(state, waitListRequested) {
state.order.customer.waitListRequested = waitListRequested;
},
updateVehicle(state, vehicleInfo) { updateVehicle(state, vehicleInfo) {
state.order.vehicle.year = vehicleInfo.year; state.order.vehicle.year = vehicleInfo.year;
state.order.vehicle.make = vehicleInfo.make; state.order.vehicle.make = vehicleInfo.make;
@ -3081,6 +3085,10 @@ export const actions = {
context.commit(storeMutations.UPDATE_CUSTOMER_IS_SMS_OPT_IN, isSmsOptIn); context.commit(storeMutations.UPDATE_CUSTOMER_IS_SMS_OPT_IN, isSmsOptIn);
}, },
saveWaitListRequested(context, waitListRequested) {
context.commit(storeMutations.UPDATE_CUSTOMER_WAITLIST_REQUESTED, waitListRequested);
},
savePageData(context, emailOrSms) { savePageData(context, emailOrSms) {
context.commit(storeMutations.UPDATE_PAGE_DATA, emailOrSms); context.commit(storeMutations.UPDATE_PAGE_DATA, emailOrSms);
}, },