Merge branch 'develop' into feature/add-prettier-test-to-PR-check

This commit is contained in:
SujathaAnishetty 2025-02-25 10:54:46 -05:00 committed by GitHub
commit 6905f26d56
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 140 additions and 4 deletions

View file

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

View file

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

View file

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

View file

@ -1,5 +1,8 @@
<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-if="doesCopyContainRouterLink(copy)">
<textLink

View file

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

View file

@ -43,6 +43,8 @@
customComponentId="timeSlotModalQuestion"
v-model="selectedTimeSlotInfo"
cmsWidgetName="TimeSlotModalQuestion"
waitListLabelWidget="WaitListLabelWidget"
waitListQuestionWidget="WaitListQuestionWidget"
mobilePremiumCmsWidgetName="MobilePremiumTimeSlotModal"
mobileCmsWidgetName="MobileTimeSlotModal"
dropoffCmsWidgetName="DropOffTimeSlotModal"
@ -51,6 +53,7 @@
:selectedDate="selectedDate"
:appointmentType="appointmentType"
:premiumAppointmentFee="mobilePremiumAppointmentFee"
:displayWaitList="displayWaitList"
:timeSlotsForSelectedDate="timeSlotsForSelectedDate"
:estimatedServiceMinutesMinimum="
selectableDatesData.estimatedServiceMinutesMinimum
@ -58,6 +61,7 @@
:estimatedServiceMinutesMaximum="
selectableDatesData.estimatedServiceMinutesMaximum
"
@waitListRequested-emitted="handleWaitListRequested"
@time-slot-modal-closed="timeSlotModalClosed"
validationRules="time-slot-selection-required"
@TimeSlotSelected="forwardButtonAction" />
@ -217,6 +221,8 @@ export default {
selectedTimeSlotInfo: this.getSelectedTimeSlotInfo(),
selectableDatesData: [],
mobilePremiumAppointmentFee: null,
waitListRequested: null,
displayWaitList: null,
};
},
async beforeRouteEnter(to, from, next) {
@ -295,6 +301,7 @@ export default {
? resultMap.premiumFeeWithPrice[0]
: null;
vm.updateFooterButtonText(vm.selectedTimeSlotInfo);
vm.setDisplayWaitList();
});
},
computed: {
@ -469,6 +476,29 @@ export default {
forwardButtonAction() {
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) {
this.selectedTimeSlotInfo.timeSlot.jobMinMinutes =
this.selectableDatesData?.estimatedServiceMinutesMinimum?.toString();
@ -482,8 +512,39 @@ export default {
false
);
this.dispatchStoreAction(
this.storeActions.SAVE_WAITLIST_REQUESTED,
this.waitListRequested,
false
);
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() {
const supportingItems = this.getSupportingItems();
@ -532,6 +593,9 @@ export default {
}
}
},
handleWaitListRequested(value) {
this.waitListRequested = value;
},
},
watch: {
selectedDate(newValue, oldValue) {

View file

@ -26,7 +26,21 @@
isRequired
validationRules="time-slot-required" />
<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-html="supplementalInformationBlock"></div>
<textBlock
@ -44,7 +58,11 @@
import modal from "@/digital-components/modal/modal";
import textBlock from "@/digital-components/text-block/text-block";
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 experimentMixin from "@/mixins/experiment-mixin";
import { experimentSettings } from "@/constants/experiments";
import store from "@/store";
// Helpers
import { deepClone } from "@/helpers/object-helper";
@ -82,7 +100,7 @@ defineRule("time-slot-required", required(errorMessages.OPTION_REQUIRED));
export default {
name: "time-slot-modal-question",
emits: ["update:modelValue", "TimeSlotSelected"],
emits: ["update:modelValue", "TimeSlotSelected", "click-event"],
props: {
modelValue: {
type: Object,
@ -112,12 +130,14 @@ export default {
validationRules: String,
customComponentId: String,
selectedDate: String,
displayWaitList: Boolean,
},
data() {
return {
isModalOpened: false,
selectedRouteCode: this.getSelectedRouteCode(),
timeSlotModalListButton: timeSlotModalListButton,
waitListRequested: this.getWaitListRequestedFromStore(),
};
},
setup(props) {
@ -330,6 +350,15 @@ export default {
return this.getAvailableTimeSlotsForInshop(this.timeSlotsForSelectedDate.timeSlots);
}
},
hasWaitListExperiment() {
return experimentMixin.methods.hasSettingEqualTo(
experimentSettings.DISPLAY_WAITLIST,
"true"
);
},
displayWaitListFeature() {
return this.displayWaitList;
},
},
methods: {
openModal() {
@ -445,6 +474,9 @@ export default {
return selectedRouteCode;
},
getWaitListRequestedFromStore() {
return store.getters.order.customer?.waitListRequested;
},
autoSelectTimeSlotIfOnlyOneIsAvailable() {
const numberOfOptions = this.availableTimeSlots?.length;
if (numberOfOptions === 1) {
@ -493,6 +525,9 @@ export default {
isPremiumAppointment: null,
};
},
waitListChecked(event) {
this.$emit("waitListRequested-emitted", event.target.checked);
},
},
unmounted() {
if (this.isModalOpened) this.closeModal();
@ -515,6 +550,7 @@ export default {
modal,
textBlock,
buttonQuestion,
checkboxQuestion,
},
};
</script>
@ -538,5 +574,19 @@ export default {
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>

View file

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

View file

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