Merge branch 'develop' into feature/CSR-1144

This commit is contained in:
CarlNation 2023-05-23 08:04:50 -04:00
commit 433ab4aa21
11 changed files with 129 additions and 90 deletions

View file

@ -52,7 +52,7 @@ https://safelite.atlassian.net/wiki/spaces/DC/pages/76644418/Button+Question+Com
:isWide="isWide"
:validationRules="validationRules"
:textPosition="textPosition"
:additionalButtonStyling="additionalButtonStyling"
:additionalButtonData="additionalButtonData"
:lastValuePushedToGa="lastValuePushedToGa"
:setLastValuePushedToGa="setLastValuePushedToGa"
:suppressError="suppressError"
@ -126,7 +126,7 @@ export default {
suppressError: Boolean,
useTextForValue: Boolean,
valueToLogType: String,
additionalButtonStyling: String,
additionalButtonData: Object,
isSmallQuestionText: Boolean,
customButtonQuestionId: String,
logDisplayedValuesEvent: {

View file

@ -72,6 +72,7 @@
<script>
// Supporting files
import loader from "@/ux-components/loader/loader";
import store from "@/store";
import { TIMINGFUNC_MAP, BUFFER_OFFSET, MONTHS_OF_YEAR } from "./mixins/constants";
import { selectableDaysOptions, requiredParameter, forceTwoDigitString } from "./mixins/helpers";
@ -244,7 +245,8 @@ export default {
let myPromise = new Promise((resolve, reject) => {
const response = config.customSelectableDatesCallback(
initialViewStartDate,
initialViewEndDate
initialViewEndDate,
store.getters.order.serviceLocation.appointmentType
);
resolve(response);
});
@ -523,7 +525,8 @@ export default {
async updateSelectableDates(monthStart, monthEnd) {
const moreSelectableDates = await this.customSelectableDatesCallback(
monthStart,
monthEnd
monthEnd,
this.$store.getters.order.serviceLocation.appointmentType
);
moreSelectableDates.days.forEach((selectableDate) => {
const index = this.selectableDatesData.findIndex(

View file

@ -5,7 +5,7 @@
:groupName="groupName"
buttonTypeString="listButtonHorizontal"
v-model="selectedValues"
additionalButtonStyling="listButtonHorizontalStrong"
:additionalButtonData="{ additionalButtonStyling: 'listButtonHorizontalStrong' }"
isRequired />
</div>
</template>

View file

@ -0,0 +1,53 @@
<template>
<alert
v-for="alert in prefixedAlertReasons"
:key="alert.cmsWidgetName"
:ref="alert.cmsWidgetName"
class="mt-2 mb-3"
:cmsWidgetName="alert.cmsWidgetName"
alertClass="alert-warning" />
</template>
<script>
import alert from "@/ux-components/alert/alert";
import { getAlertReasons } from "@/layouts/schedule/helpers/schedule-helper";
export default {
name: "locationAlerts",
data() {
return {
alertReasons: [],
};
},
props: {
cmsWidgetPrefix: {
type: String,
default: "",
},
},
computed: {
prefixedAlertReasons() {
return this.alertReasons.reduce((newObj, alert) => {
newObj.push({
cmsWidgetName: `${this.cmsWidgetPrefix}${alert}`,
alertReason: alert,
});
return newObj;
}, []);
},
},
methods: {
loadInitialData(zipCodeCtu) {
return getAlertReasons(zipCodeCtu);
},
initializeComponent(initialData) {
this.alertReasons = initialData;
},
cmsHeadlineTextFound(widgetName) {
return this.getCmsContent(widgetName, "HeadlineText") !== "";
},
},
components: {
alert,
},
};
</script>

View file

@ -18,17 +18,7 @@
<span v-else class="m-0 text-body" v-html="copy"></span>
</span>
</div>
<template v-if="displayWeatherAlert">
<alert
v-for="alert in weatherAlerts"
v-show="cmsHeadlineTextFound(alert.cmsWidgetName)"
:key="alert.cmsWidgetName"
:ref="alert.cmsWidgetName"
class="mt-2 mb-3"
:cmsWidgetName="alert.cmsWidgetName"
alertClass="alert-warning" />
</template>
<location-alerts cmsWidgetPrefix="LocationAlert-" ref="locationAlerts" />
<date-picker
selectableDatesSetting="custom"
ref="datePicker"
@ -62,13 +52,13 @@
<script>
// Components
import alert from "@/ux-components/alert/alert";
import funnelHeader from "@/fmg-components/funnel-header/funnel-header";
import funnelFooter from "@/fmg-components/funnel-footer/funnel-footer";
import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-header";
import loadingModal from "@/fmg-components/loading-modal/loading-modal.vue";
import { Form, defineRule } from "vee-validate";
import datePicker from "@/digital-components/date-picker/date-picker";
import locationAlerts from "@/layouts/schedule/location-alerts/location-alerts";
import timeSlotModalQuestion from "./time-slot-modal-question/time-slot-modal-question";
// Supporting files
@ -77,7 +67,6 @@ import baseMixin from "@/mixins/base-mixin.js";
import { storeActions } from "@/constants/store-actions";
import { settleAllPromises } from "@/helpers/layout-helper";
import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
import { getAlertReasons } from "@/layouts/schedule/helpers/schedule-helper";
import {
doesCopyContainRouterLink,
splitCopyOnCMSPlaceHolder,
@ -91,14 +80,14 @@ import store from "@/store";
defineRule("date-required", required(errorMessages.DATE_REQUIRED));
defineRule("time-slot-selection-required", required(errorMessages.DATE_REQUIRED));
const getAvailableDates = async (startDate, endDate) => {
const getAvailableDates = async (startDate, endDate, appointmentType) => {
// USING DATES PASSED, MAKE AN API CALL
const newShopTimeSlotsResponse = await baseMixin.methods.dispatchStoreAction(
storeActions.GET_SHOP_TIME_SLOTS,
{
startDate: startDate,
endDate: endDate,
shopAppointmentType: "mobile", // TODO - PASS THIS IN FROM PREVIOUS PAGE?
shopAppointmentType: appointmentType,
},
false
);
@ -125,7 +114,6 @@ export default {
selectedDate: null,
selectedTimeSlotId: null,
selectableDatesData: [],
weatherAlerts: [],
mobileEarlyBirdFee: null,
};
},
@ -167,7 +155,9 @@ export default {
const earlyBirdPromise = baseMixin.methods.dispatchStoreAction(
storeActions.GET_MOBILE_EARLY_BIRD_FEE
);
const alertReasonsPromise = getAlertReasons(store.getters.order.serviceLocation.zipCodeCtu);
const alertReasonsPromise = locationAlerts.methods.loadInitialData(
store.getters.order.serviceLocation.zipCodeCtu
);
// Settle promises and get results
const promiseResultMap = [
@ -198,8 +188,8 @@ export default {
// Call the "next" function to complete the transition to this page.
next((vm) => {
vm.setCmsContent(resultMap.cmsContent);
vm.setData(resultMap.alertReasons);
vm.$refs.datePicker.initializeComponent(resultMap.datePickerInitialData);
vm.$refs.locationAlerts.initializeComponent(resultMap.alertReasons);
vm.selectableDatesData = resultMap.datePickerInitialData.initialShopTimeSlotsResponse;
if (resultMap.earlyBird) {
vm.mobileEarlyBirdFee = resultMap.pricingResults[0];
@ -214,9 +204,6 @@ export default {
// Splits content when brackets are found in text so that text can be looped through and router-link can be injected when needed
return this.splitCopyOnCMSPlaceHolder(this.ChangeShopLinkText);
},
displayWeatherAlert() {
return this.weatherAlerts.length > 0;
},
appointmentType() {
return this.$store.getters.order.serviceLocation.appointmentType;
},
@ -257,41 +244,17 @@ export default {
// NEED TODO - WHAT ARE PAGE REQ'S FOR THIS PAGE?
},
async getAvailableDatesMethod(startDate, endDate) {
const newShopTimeSlots = await getAvailableDates(startDate, endDate);
const newShopTimeSlots = await getAvailableDates(
startDate,
endDate,
this.appointmentType
);
// ADD API CALL RESULTS TO EXISTING DATE DATA
this.selectableDatesData.days = this.selectableDatesData.days.concat(
newShopTimeSlots.days
);
return newShopTimeSlots;
},
setData(alertReasonsData) {
if (alertReasonsData) {
this.convertReasonsToCmsAlerts(alertReasonsData);
}
},
cmsHeadlineTextFound(widgetName) {
return this.getCmsContent(widgetName, "HeadlineText") !== "";
},
convertReasonsToCmsAlerts(data) {
this.weatherAlerts = data.reduce((newObj, alert) => {
newObj.push({
cmsWidgetName: `LocationAlert-${alert}`,
alertReason: alert,
});
return newObj;
}, []);
},
async getWeatherAlertReasons(ctu) {
await getAlertReasons(ctu)
.then((response) => {
if (response.data) {
this.convertReasonsToCmsAlerts(response.data);
}
})
.catch(() => {
console.log("error fetching alert reasons..");
});
},
getServiceZipCtuCodeFromStore() {
return store.getters.order.serviceLocation.zipCodeCtu;
},
@ -338,15 +301,14 @@ export default {
},
},
components: {
alert,
funnelHeader,
funnelFooter,
funnelSubHeader,
Form,
loadingModal,
datePicker,
locationAlerts,
timeSlotModalQuestion,
},
mounted() {},
};
</script>

View file

@ -8,8 +8,8 @@
:onModalClosedCallback="onModalClosed"
@footer-button-event="closeModal">
<textBlock
v-show="inshopAppointmentDurationTextWithTime"
:customText="inshopAppointmentDurationTextWithTime"
v-show="durationTextBlockCopy"
:customText="durationTextBlockCopy"
justifyText="center"
typeStyle="small"
class="duration-text-block" />
@ -90,13 +90,18 @@ export default {
watch: {
modelValue() {
this.selectedTimeSlot = this.modelValue;
// Run component validation that is used at parent level
this.handleChange(this.modelValue);
},
// dateAndTimeSlotData(newValue, oldValue) {
// const numberOfOptions = newValue?.timeSlots.length;
// console.log('running');
// if (numberOfOptions === 1) {
// this.selectedTimeSlot = newValue.timeSlots[0].id;
// }
// }
},
computed: {
appointmentDurationTextFromCms() {
return this.getCmsContent(this.cmsWidgetName, "SubheaderText");
},
supplementalInformationBlock() {
let appointmentTypeCmsWidgetName;
let cmsFieldName = "BodyText";
@ -127,6 +132,29 @@ export default {
dropoffDisclaimerText() {
return this.getCmsContent(this.dropoffCmsWidgetName, "FooterText");
},
dropOffDurationText() {
return this.getCmsContent(this.dropoffCmsWidgetName, "SubheaderText");
},
inshopDurationText() {
const inshopDurationTextWithoutTime = this.getCmsContent(
this.cmsWidgetName,
"SubheaderText"
);
const inshopDurationTime = this.getDisplayTextForDurationLength(
this.estimatedServiceMinutesMinimum,
this.estimatedServiceMinutesMaximum
);
return `${inshopDurationTextWithoutTime} ${inshopDurationTime}`;
},
durationTextBlockCopy() {
if (this.appointmentType === AppointmentTypeStrings.MOBILE) {
return null;
} else if (this.appointmentType === AppointmentTypeStrings.IN_SHOP) {
return this.inshopDurationText;
} else {
return this.dropOffDurationText;
}
},
shouldShowDropoffDisclaimerText() {
return this.appointmentType === AppointmentTypeStrings.DROP_OFF && !this.isSameDay;
},
@ -145,21 +173,6 @@ export default {
// Ex. Tuesday, April 23
return `${weekdayName}, ${month} ${numberDayOfMonth}`;
},
inshopAppointmentDurationTextWithTime() {
if (this.appointmentType === AppointmentTypeStrings.MOBILE) {
return null;
}
let durationSubHeaderText = this.appointmentDurationTextFromCms + " ";
if (this.appointmentType === AppointmentTypeStrings.DROP_OFF) {
durationSubHeaderText += "All day";
} else {
durationSubHeaderText += this.getDisplayTextForDurationLength(
this.estimatedServiceMinutesMinimum,
this.estimatedServiceMinutesMaximum
);
}
return durationSubHeaderText;
},
availableTimeSlots() {
if (this.dateAndTimeSlotData === null) {
return null;

View file

@ -246,25 +246,29 @@ export default {
<style lang="scss">
.shop-question {
margin-top: 1rem !important;
text-align: center !important;
margin-top: 1rem;
text-align: center;
.button-question {
.question-text {
margin-top: 0.5rem !important;
margin-top: 0.5rem;
}
}
}
.drop-off-alert {
background: url("data:image/svg+xml,%3Csvg viewBox='0 0 12 12' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cg clip-path='url(%23clip0_13957_112512)'%3E%3Cpath d='M5.99865 0C4.81147 4.82643e-07 3.65095 0.352111 2.66392 1.01179C1.67688 1.67146 0.907678 2.60907 0.45361 3.70599C-0.000459241 4.80291 -0.11899 6.00986 0.113013 7.17415C0.345015 8.33845 0.917126 9.40778 1.75697 10.2469C2.59682 11.086 3.66666 11.6571 4.83117 11.8881C5.99567 12.119 7.20251 11.9994 8.29902 11.5443C9.39553 11.0893 10.3324 10.3192 10.9912 9.33159C11.65 8.34396 12.0011 7.18313 12 5.99594C11.9971 4.40566 11.3638 2.88142 10.2388 1.75742C9.11375 0.633431 7.58894 0.00143011 5.99865 0V0ZM5.99865 11.2478C4.96135 11.2473 3.94748 10.9392 3.08518 10.3627C2.22288 9.7861 1.55085 8.96685 1.15401 8.00846C0.75718 7.05006 0.653353 5.99554 0.855656 4.97815C1.05796 3.96077 1.55731 3.02618 2.29061 2.29251C3.0239 1.55884 3.95823 1.059 4.97551 0.856176C5.99279 0.653349 7.04737 0.756633 8.00597 1.15297C8.96457 1.54931 9.78416 2.22092 10.3612 3.08293C10.9382 3.94493 11.2467 4.95864 11.2478 5.99594C11.2478 7.38835 10.6949 8.72377 9.71053 9.70861C8.7262 10.6934 7.39106 11.2471 5.99865 11.2478V11.2478Z' fill='%2306577C'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M6.22736 8.84695C6.30613 8.76818 6.35038 8.66135 6.35038 8.54996V5.30996C6.35038 5.19857 6.30613 5.09174 6.22736 5.01298C6.1486 4.93421 6.04177 4.88996 5.93038 4.88996C5.81899 4.88996 5.71216 4.93421 5.63339 5.01298C5.55463 5.09174 5.51038 5.19857 5.51038 5.30996V8.54996C5.51038 8.66135 5.55463 8.76818 5.63339 8.84695C5.71216 8.92571 5.81899 8.96996 5.93038 8.96996C6.04177 8.96996 6.1486 8.92571 6.22736 8.84695ZM5.69704 3.97918C5.76611 4.02533 5.84731 4.04996 5.93038 4.04996C5.98558 4.05012 6.04026 4.03936 6.09129 4.01831C6.14232 3.99726 6.18868 3.96633 6.22771 3.9273C6.26675 3.88827 6.29768 3.8419 6.31873 3.79088C6.33978 3.73985 6.35053 3.68516 6.35038 3.62996C6.35038 3.54689 6.32574 3.46569 6.27959 3.39662C6.23344 3.32755 6.16785 3.27372 6.0911 3.24193C6.01436 3.21014 5.92991 3.20183 5.84844 3.21803C5.76697 3.23424 5.69213 3.27424 5.63339 3.33298C5.57465 3.39171 5.53465 3.46655 5.51845 3.54802C5.50224 3.6295 5.51056 3.71394 5.54235 3.79069C5.57414 3.86743 5.62797 3.93303 5.69704 3.97918Z' fill='%2306577C'/%3E%3C/g%3E%3Cdefs%3E%3CclipPath id='clip0_13957_112512'%3E%3Crect width='12' height='12' fill='white'/%3E%3C/clipPath%3E%3C/defs%3E%3C/svg%3E%0A");
background-repeat: no-repeat;
background-size: 0.75rem;
background-position: 0.5rem 0.75rem;
.alert-heading {
text-align: left;
font-size: 0.75rem !important;
line-height: 1.25rem !important;
font-size: 0.75rem;
line-height: 1.25rem;
}
p {
padding-left: 0.5rem;
margin-bottom: 0;
}
margin-top: 0.5rem !important;
padding-left: 1.5rem !important;
padding-right: 0.5rem !important;
}
</style>

View file

@ -21,7 +21,7 @@ export default {
textPosition: String,
screenReaderOnlyText: String,
isWide: Boolean,
additionalButtonStyling: String,
additionalButtonData: Object,
},
computed: {
selectedValue: {

View file

@ -204,7 +204,7 @@ export default {
}
& p {
font-size: 0.875rem;
margin-bottom: 0.25rem !important;
margin-bottom: 0.25rem;
}
}
</style>

View file

@ -57,7 +57,9 @@ describe("list-button-horizontal.vue", () => {
const { wrapper } = setupMocks({
mockData: {
propsData: {
additionalButtonStyling: "listButtonHorizontalStrong",
additionalButtonData: {
additionalButtonStyling: "listButtonHorizontalStrong",
},
},
},
});

View file

@ -30,7 +30,9 @@ export default {
mixins: [inputButtonWrapperMixin],
computed: {
isStrongStyling() {
return this.additionalButtonStyling === "listButtonHorizontalStrong";
return (
this.additionalButtonData?.additionalButtonStyling === "listButtonHorizontalStrong"
);
},
},
components: {