Changed modal to work like the other modals which fixed CSR-1510

This commit is contained in:
Leah Schumann 2023-07-24 09:06:29 -04:00
parent c0a54345b2
commit de717b10e9
3 changed files with 71 additions and 32 deletions

View file

@ -84,6 +84,9 @@ import {
} from "@/layouts/schedule/helpers/schedule-helper";
import { useField, ErrorMessage } from "vee-validate";
import { deepClone } from "@/helpers/object-helper";
import { v4 as uuidv4 } from "uuid";
export default {
name: "datePicker",
data() {
@ -96,6 +99,7 @@ export default {
};
},
props: {
customComponentId: String,
selectableDatesSetting: {
type: String,
validator(value) {
@ -123,18 +127,24 @@ export default {
},
},
setup(props) {
const propsClone = Object.assign({}, props);
const modelValue = propsClone.modelValue;
const uuid = uuidv4();
const componentId = !props.customComponentId
? `component-${uuid}`
: props.customComponentId;
const modelValue = deepClone(props).modelValue;
const initialValue = modelValue;
const fieldOptions = {
value: modelValue,
initialValue: modelValue,
initialValue: initialValue,
};
const { errorMessage, handleBlur, handleChange, meta, validate, errors, resetField } =
useField("date-of-month", props.validationRules, fieldOptions);
useField(componentId, props.validationRules, fieldOptions);
return {
componentId,
errorMessage,
handleBlur,
handleChange,

View file

@ -13,6 +13,7 @@
</template>
<locationAlerts cmsWidgetPrefix="LocationAlert-" ref="locationAlerts" />
<datePicker
customComponentId="dateQuestion"
selectableDatesSetting="custom"
ref="datePicker"
v-model="selectedDate"
@ -30,11 +31,13 @@
sameDayDropOffCmsWidgetName="SameDayDropOffTimeSlotModal"
overnightDropOffCmsWidgetName="OvernightDropOffTimeSlotModal"
v-model="selectedTimeSlot"
:selectedDate="selectedDate"
:appointmentType="appointmentType"
:premiumAppointmentFee="mobilePremiumAppointmentFee"
:dateAndTimeSlotData="timeSlotsForSelectedDate"
:estimatedServiceMinutesMinimum="selectableDatesData.estimatedServiceMinutesMinimum"
:estimatedServiceMinutesMaximum="selectableDatesData.estimatedServiceMinutesMaximum"
@time-slot-modal-closed="timeSlotModalClosed"
validationRules="time-slot-selection-required" />
<funnel-footer
cmsWidgetName="FunnelFooterWidget"
@ -75,14 +78,12 @@ import { errorMessages } from "@/constants/error-messages";
import { required } from "@/helpers/validation-rules";
import store from "@/store";
defineRule("date-required", required(errorMessages.DATE_REQUIRED));
// DEFINE VALIDATION RULES
defineRule("date-required", required(errorMessages.DATE_REQUIRED));
defineRule("time-slot-selection-required", (value) => {
if (
value.date == null ||
value.startTime == null ||
value.endTime == null ||
value.routeCode == null ||
value.estimatedServiceMinutesMaximum
) {
@ -339,6 +340,12 @@ export default {
(lineItem) => lineItem.partType === PREMIUM_FEE_PART_TYPE
).length;
},
timeSlotModalClosed() {
// Clear the selectedDate if no timeSlot has been selected
if (this.selectedTimeSlot.routeCode == null) {
this.selectedDate = null;
}
},
updateFooterButtonText(timeSlot) {
let funnelFooterButtonText;
if (!timeSlot || !timeSlot.date) {
@ -438,6 +445,18 @@ export default {
},
},
watch: {
selectedDate(newValue, oldValue) {
// Clear time slot selection if date selected changes
if (newValue !== oldValue) {
this.selectedTimeSlot = {
date: null,
routeCode: null,
startTime: null,
endTime: null,
jobMaxMinutes: null,
};
}
},
selectedTimeSlot(newValue) {
this.updateFooterButtonText(newValue);
},

View file

@ -3,10 +3,9 @@
:ref="modalName"
:headerText="dateSelectedReadableDate"
:footerButtonText="footerCloseButtonText"
:onModalOpenedCallback="onModalOpened"
:onModalClosedCallback="onModalClosed"
@isModalOpened="setModalStatus"
@footer-button-event="setTimeSlot"
@footer-button-event="setSelectedTimeSlot"
class="time-slots-modal">
<template v-if="isModalOpened">
<textBlock
@ -104,11 +103,12 @@ export default {
estimatedServiceMinutesMaximum: Number,
validationRules: String,
customComponentId: String,
selectedDate: String,
},
data() {
return {
internalModel: deepClone(this.modelValue),
isModalOpened: false,
selectedValue: null,
timeSlotModalListButton: timeSlotModalListButton,
};
},
@ -145,17 +145,9 @@ export default {
modalName() {
return "timeSlots";
},
selectedValue: {
get: function () {
return this.modelValue;
},
set: function (newValue) {
this.$emit("update:modelValue", newValue);
},
},
selectedTimeSlotId: {
get: function () {
return this.selectedValue?.routeCode;
return this.modelValue?.routeCode;
},
set: function (newValue) {
// Button Question only supports Number, or String data types so we must get the full object to emit
@ -324,6 +316,7 @@ export default {
if (!this.dateAndTimeSlotData) {
return null;
}
if (this.appointmentType === AppointmentTypeStrings.DROP_OFF) {
return this.getAvailableTimeSlotsForDropOff(this.dateAndTimeSlotData.timeSlots);
} else if (this.appointmentType === AppointmentTypeStrings.MOBILE) {
@ -340,9 +333,6 @@ export default {
openModal() {
this.modal.openModal();
},
onModalOpened() {
this.internalModel = deepClone(this.modelValue);
},
setModalStatus(isOpened) {
this.isModalOpened = isOpened;
},
@ -350,10 +340,10 @@ export default {
this.modal.closeModal();
},
onModalClosed() {
this.internalModel = deepClone(this.modelValue);
this.$emit("time-slot-modal-closed");
},
setTimeSlot() {
this.$emit("update:modelValue", this.internalModel);
async setSelectedTimeSlot() {
this.$emit("update:modelValue", this.selectedValue);
this.closeModal();
},
getDisplayTextForMilitaryTime(militaryTimeInput) {
@ -361,9 +351,11 @@ export default {
let hours = parseInt(militaryTimeInput.split(":")[0]);
const minutes = militaryTimeInput.split(":")[1];
const meridianNotation = hours > 11 ? "PM" : "AM";
if (hours > 12) {
hours -= 12;
}
return `${hours}:${minutes} ${meridianNotation}`;
},
getDisplayTextForDurationLength(durationMinimum, durationMaximum) {
@ -375,6 +367,7 @@ export default {
} else {
displayTextForDurationLength = `${durationMinimum} - ${durationMaximum} minutes`;
}
return displayTextForDurationLength;
},
getRelevantDropOffCmsWidgetNameForSelectedTimeSlot(
@ -408,11 +401,13 @@ export default {
} else {
buttonLabelValue = this.dropoffButtonText;
}
return {
value: timeSlot.id,
buttonLabel: buttonLabelValue,
};
});
return availableTimeSlots;
},
getAvailableTimeSlotsForMobile(timeSlotsForSelectedDate) {
@ -463,25 +458,40 @@ export default {
return timeSlotId.substring(0, timeSlotId.length - PREMIUM_TIME_SLOT_ID_FLAG.length);
},
getSelectedTimeSlotObject(timeSlotId) {
const timeSlot = this.dateAndTimeSlotData.timeSlots?.find(
const timeSlot = this.dateAndTimeSlotData?.timeSlots?.find(
(timeSlot) => timeSlot.id == timeSlotId
);
if (timeSlot) {
return {
date: this.dateAndTimeSlotData.date,
routeCode: timeSlot.id,
startTime: timeSlot.startTime,
endTime: timeSlot.endTime,
jobMaxMinutes: this.estimatedServiceMinutesMaximum.toString(),
};
}
return {
date: this.dateAndTimeSlotData.date,
startTime: timeSlot.startTime,
endTime: timeSlot.endTime,
routeCode: timeSlot.id,
jobMaxMinutes: this.estimatedServiceMinutesMaximum.toString(),
date: null,
startTime: null,
endTime: null,
routeCode: null,
jobMaxMinutes: null,
};
},
},
watch: {
modelValue: {
handler(newValue) {
this.internalModel = deepClone(newValue);
this.handleChange(newValue);
},
deep: true,
},
selectedDate: {
handler() {
this.selectedTimeSlotId = null;
},
},
availableTimeSlots(newValue) {
this.autoSelectTimeSlotIfOnlyOneIsAvailable(newValue);