Changed modal to work like the other modals which fixed CSR-1510
This commit is contained in:
parent
c0a54345b2
commit
de717b10e9
3 changed files with 71 additions and 32 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue