move add-to-calendar within confirmation

move add-to-calendar within confirmation and pass cms widget as props
This commit is contained in:
hiteshkumar87 2023-10-20 18:01:55 +05:30
parent 6defb7ea9c
commit 10b1d941ef
7 changed files with 342 additions and 312 deletions

View file

@ -1,167 +0,0 @@
<template>
<div class="calendar-section">
<div class="add-to-calendar">
<button v-on:click="openCalendarModal">
<span class="add-to-calendar-span">
<img src="@/assets/img/icons/add-to-calendar.svg" class="add-to-calendar-img" />
<span class="add-to-calendar-text">Add to calendar</span></span
>
</button>
</div>
<calendarModalQuestion
ref="calendarModalQuestion"
customComponentId="calendarModalQuestion"
cmsWidgetName="CalendarModalQuestion"
@calendar-modal-closed="calendarModalClosed"
:calendarOptionsData="calendarValues"
v-model="selectedCalendarOption">
</calendarModalQuestion>
</div>
</template>
<script>
import { calendarOptions } from "@/constants/calendar-options";
import { calendarStatus } from "@/constants/calendar-status";
import calendarModalQuestion from "@/layouts/add-to-calendar/calendar-modal-question/calendar-modal-question";
import { getDateFormat } from "@/helpers/date-helper";
import { getCalendarFile, download } from "@/helpers/add-to-calendar-helper";
export default {
name: "add-to-calendar",
components: {
calendarModalQuestion,
},
props: {
appointment: Object,
},
data() {
return {
selectedCalendarOption: null,
};
},
computed: {
calendarValues: {
get: function () {
var obj = [];
const options = Object.values(calendarOptions);
for (var i = 0; i < options.length; i++) {
obj[i] = this.getCalendarData(options[i]);
}
return obj;
},
},
},
watch: {
selectedCalendarOption(newValue) {
if (newValue) {
this.setCalendarAppointment(newValue);
}
},
},
methods: {
setCalendarAppointment(calendarOption) {
if (
calendarOption.name.includes(calendarOptions.ICAL) ||
calendarOption.name.includes(calendarOptions.OUTLOOK)
) {
this.getAppointment();
} else {
window.open(calendarOption.url);
}
},
calendarModalClosed() {
// Clear the selectedOption if close the modal
this.selectedCalendarOption = null;
},
openCalendarModal() {
this.$refs["calendarModalQuestion"].openModal();
},
getCalendarData(type) {
var URL = "";
const dateFormat = "yyyyMMddTHHmmss";
const outlookComTimeSpanFormat = "yyyy-MM-ddTHH:mm:ss";
if (type == calendarOptions.OUTLOOKCOM) {
URL = `https://outlook.office.com/calendar/deeplink/compose?path=/calendar/action/compose&rru=addevent&startdt=${encodeURIComponent(
getDateFormat(this.appointment.StartDate, outlookComTimeSpanFormat)
)}&enddt=${encodeURIComponent(
getDateFormat(this.appointment.EndDate, outlookComTimeSpanFormat)
)}&subject=${encodeURIComponent(
this.appointment.Subject
)}&body=${encodeURIComponent(this.appointment.Body)}&location=${encodeURIComponent(
this.appointment.Location
)}`;
}
if (type == calendarOptions.GOOGLE) {
URL = `https://www.google.com/calendar/render?action=TEMPLATE&text=${encodeURIComponent(
this.appointment.Subject
)}&dates=${encodeURIComponent(
getDateFormat(this.appointment.StartDate, dateFormat)
)}/${encodeURIComponent(
getDateFormat(this.appointment.EndDate, dateFormat)
)}&details=${encodeURIComponent(
this.appointment.Body
)}&location=${encodeURIComponent(this.appointment.Location)}&sf=true&output=xml`;
}
if (type == calendarOptions.YAHOO) {
URL = `https://calendar.yahoo.com/?v=60&TITLE=${encodeURIComponent(
this.appointment.Subject
)}&DESC=${encodeURIComponent(this.appointment.Body)}&ST=${encodeURIComponent(
getDateFormat(this.appointment.StartDate, dateFormat)
)}&DUR=${this.appointment.Duration}&in_loc=${encodeURIComponent(
this.appointment.Location
)}`;
}
return {
url: URL,
name: type,
icon: require(`@/assets/img/icons/${type}.svg`),
};
},
getAppointment() {
let body = this.appointment.Body;
body = body.replace("|", "<").replace("~", ">");
const calFile = {
Location: this.appointment.Location,
Body: body,
IsHTML: this.appointment.IsHTML,
UniqueId: this.appointment.RefrrlSeqNum,
Subject: this.appointment.Subject,
StartDate: this.appointment.StartDate,
EndDate: this.appointment.EndDate,
Status: calendarStatus.BUSY,
};
var calBody = getCalendarFile(calFile);
download("SafeliteAppointment.ics", calBody);
},
},
};
</script>
<style scoped>
.add-to-calendar-text {
margin: 0 0 0 7px;
color: #1574a1;
vertical-align: middle;
font-weight: 500;
font-family: "Roboto";
}
.add-to-calendar button {
border: 0;
background-color: #fff;
}
.calendar-section {
display: table;
position: relative;
margin: 0 auto;
}
.calendar-section .add-to-calendar {
padding-top: 15px;
}
.calendar-section .add-to-calendar .add-to-calendar-span {
cursor: pointer;
}
.calendar-section .add-to-calendar .add-to-calendar-img {
display: inline;
width: 20px;
}
</style>

View file

@ -1,5 +1,5 @@
// Components
import addToCalendar from "@/layouts/add-to-calendar/add-to-calendar.vue";
import addToCalendar from "@/layouts/confirmation/add-to-calendar/add-to-calendar.vue";
import { calendarOptions } from "@/constants/calendar-options";
import { AppointmentTypeStrings, RouteCodeFlags } from "@/constants/schedule-constants";
@ -176,11 +176,20 @@ describe("Add-to-calendar methods...", () => {
});
});
var appointmentText = "Appointment content";
function setupMocks({ customMountOptions }) {
const mountOptions = getMountOptions({
...customMountOptions,
});
mountOptions.mixins = [
{
methods: {
getCmsContent: jest.fn().mockImplementation(() => {
return appointmentText;
}),
},
},
];
const wrapper = shallowMount(addToCalendar, mountOptions);
wrapper.vm.$refs.calendarModalQuestion.openModal = jest.fn();
return { wrapper };

View file

@ -0,0 +1,313 @@
<template>
<div class="calendar-section">
<div class="add-to-calendar">
<button v-on:click="openCalendarModal">
<span class="add-to-calendar-span">
<img src="@/assets/img/icons/add-to-calendar.svg" class="add-to-calendar-img" />
<span class="add-to-calendar-text">Add to calendar</span></span
>
</button>
</div>
<calendarModalQuestion
ref="calendarModalQuestion"
customComponentId="calendarModalQuestion"
cmsWidgetName="CalendarModalQuestion"
@calendar-modal-closed="calendarModalClosed"
:calendarOptionsData="calendarValues"
v-model="selectedCalendarOption">
</calendarModalQuestion>
</div>
</template>
<script>
import { calendarOptions } from "@/constants/calendar-options";
import { calendarStatus } from "@/constants/calendar-status";
import calendarModalQuestion from "@/layouts/confirmation/add-to-calendar/calendar-modal-question/calendar-modal-question";
import { getDateFormat } from "@/helpers/date-helper";
import { AppointmentTypeStrings, RouteCodeFlags } from "@/constants/schedule-constants";
import { getCalendarFile, download } from "@/helpers/add-to-calendar-helper";
import {
calculateDuration,
combineDateAndTime,
shortTimeString,
addMinutes,
} from "@/helpers/date-helper";
import store from "@/store";
import { serviceType } from "@/constants/service-type";
export default {
name: "add-to-calendar",
components: {
calendarModalQuestion,
},
props: {
mobileWidgetName: String,
inShopWidgetName: String,
dropOffWidgetName: String,
overnightDropOffWidgetName: String,
allDayDropOffWidgetName: String,
sameDayDropOffWidgetName: String,
serviceLocationFullAddress: String,
providerFullAddress: String,
appointmentType: String,
scheduleDate: String,
scheduleStartTime: String,
scheduleEndTime: String,
},
data() {
return {
selectedCalendarOption: null,
};
},
computed: {
calendarValues: {
get: function () {
var obj = [];
const options = Object.values(calendarOptions);
for (var i = 0; i < options.length; i++) {
obj[i] = this.getCalendarData(options[i]);
}
return obj;
},
},
IsSameDayDropOff() {
const todaysDate = new Date().toISOString().split("T")[0];
return this.scheduleDate === todaysDate;
},
AddToCalendar_Mobile_Subject() {
return this.getCmsContent(this.mobileWidgetName, "HeaderText");
},
AddToCalendar_Mobile_Body() {
return this.getCmsContent(this.mobileWidgetName, "BodyText");
},
AddToCalendar_InShop_Subject() {
return this.getCmsContent(this.inShopWidgetName, "HeaderText");
},
AddToCalendar_InShop_Body() {
return this.getCmsContent(this.inShopWidgetName, "BodyText");
},
AddToCalendar_DropOff_Subject() {
return this.getCmsContent(this.dropOffWidgetName, "HeaderText");
},
AddToCalendar_DropOff_Body() {
return this.getCmsContent(this.dropOffWidgetName, "BodyText");
},
AddToCalendar_OvernightDropOff_Subject() {
return this.getCmsContent(this.overnightDropOffWidgetName, "HeaderText");
},
AddToCalendar_OvernightDropOff_Body() {
return this.getCmsContent(this.overnightDropOffWidgetName, "BodyText");
},
AddToCalendar_AllDayDropOff_Subject() {
return this.getCmsContent(this.allDayDropOffWidgetName, "HeaderText");
},
AddToCalendar_AllDayDropOff_Body() {
return this.getCmsContent(this.allDayDropOffWidgetName, "BodyText");
},
AddToCalendar_SameDayDropOff_Subject() {
return this.getCmsContent(this.sameDayDropOffWidgetName, "HeaderText");
},
AddToCalendar_SameDayDropOff_Body() {
return this.getCmsContent(this.sameDayDropOffWidgetName, "BodyText");
},
UniqueId() {
return store.getters.order.referralNumber?.toString();
},
ServiceType() {
const isRepair = store.getters.order.damage.isRepair;
const funnelHasRecalibrationPart = store.getters.funnelHasRecalibrationPart;
if (!isRepair) {
if (funnelHasRecalibrationPart) {
return serviceType.REPLACEMENT_AND_RECALIBRATION;
} else {
return serviceType.REPLACEMENT;
}
}
return serviceType.REPAIR;
},
RouteCode() {
return store.getters.order.schedule.routeCode;
},
Appointment() {
var subject = "";
var location = "";
var startDateTime = combineDateAndTime(this.scheduleDate, this.scheduleStartTime);
var endDateTime = combineDateAndTime(this.scheduleDate, this.scheduleEndTime);
var body = "";
var isHTML = false;
var duration = "";
if (this.appointmentType === AppointmentTypeStrings.MOBILE) {
location = this.serviceLocationFullAddress?.replace("<br/>", "");
subject = this.AddToCalendar_Mobile_Subject?.replace(
"{custom:SERVICETYPE}",
this.ServiceType
);
body = this.AddToCalendar_Mobile_Body;
} else {
location = this.providerFullAddress?.replace("<br/>", "");
if (this.appointmentType === AppointmentTypeStrings.DROP_OFF) {
if (this.RouteCode.includes(RouteCodeFlags.OVERNIGHT_DROP_OFF)) {
subject = this.AddToCalendar_OvernightDropOff_Subject;
body = this.AddToCalendar_OvernightDropOff_Body;
} else if (this.RouteCode.includes(RouteCodeFlags.ALL_DAY_DROP_OFF)) {
if (this.IsSameDayDropOff) {
subject = this.AddToCalendar_SameDayDropOff_Subject;
endDateTime = addMinutes(startDateTime, 120);
body = this.AddToCalendar_SameDayDropOff_Body;
} else {
endDateTime = addMinutes(startDateTime, 120);
subject = this.AddToCalendar_AllDayDropOff_Subject?.replace(
"{custom:STARTDATETIME}",
shortTimeString(startDateTime)
).replace("{custom:ENDDATETIME}", shortTimeString(endDateTime));
body = this.AddToCalendar_AllDayDropOff_Body?.replace(
"{custom:ENDDATETIME}",
shortTimeString(endDateTime)
);
}
} //normal time slot
else {
subject = this.AddToCalendar_DropOff_Subject?.replace(
"{custom:SERVICETYPE}",
this.ServiceType
);
body = this.AddToCalendar_DropOff_Body?.replace(
"{custom:ADDRESS}",
location
);
}
} else {
subject = this.AddToCalendar_InShop_Subject?.replace(
"{custom:SERVICETYPE}",
this.ServiceType
);
body = this.AddToCalendar_InShop_Body?.replace("{custom:ADDRESS}", location);
}
duration = calculateDuration(startDateTime, endDateTime);
}
return {
Subject: subject,
Location: location,
StartDate: startDateTime,
EndDate: endDateTime,
RefrrlSeqNum: this.UniqueId,
Body: body,
IsHTML: isHTML,
Duration: duration,
};
},
},
watch: {
selectedCalendarOption(newValue) {
if (newValue) {
this.setCalendarAppointment(newValue);
}
},
},
methods: {
setCalendarAppointment(calendarOption) {
if (
calendarOption.name.includes(calendarOptions.ICAL) ||
calendarOption.name.includes(calendarOptions.OUTLOOK)
) {
this.getAppointment();
} else {
window.open(calendarOption.url);
}
},
calendarModalClosed() {
// Clear the selectedOption if close the modal
this.selectedCalendarOption = null;
},
openCalendarModal() {
this.$refs["calendarModalQuestion"].openModal();
},
getCalendarData(type) {
var URL = "";
const dateFormat = "yyyyMMddTHHmmss";
const outlookComTimeSpanFormat = "yyyy-MM-ddTHH:mm:ss";
if (type == calendarOptions.OUTLOOKCOM) {
URL = `https://outlook.office.com/calendar/deeplink/compose?path=/calendar/action/compose&rru=addevent&startdt=${encodeURIComponent(
getDateFormat(this.Appointment.StartDate, outlookComTimeSpanFormat)
)}&enddt=${encodeURIComponent(
getDateFormat(this.Appointment.EndDate, outlookComTimeSpanFormat)
)}&subject=${encodeURIComponent(
this.Appointment.Subject
)}&body=${encodeURIComponent(this.Appointment.Body)}&location=${encodeURIComponent(
this.Appointment.Location
)}`;
}
if (type == calendarOptions.GOOGLE) {
URL = `https://www.google.com/calendar/render?action=TEMPLATE&text=${encodeURIComponent(
this.Appointment.Subject
)}&dates=${encodeURIComponent(
getDateFormat(this.Appointment.StartDate, dateFormat)
)}/${encodeURIComponent(
getDateFormat(this.Appointment.EndDate, dateFormat)
)}&details=${encodeURIComponent(
this.Appointment.Body
)}&location=${encodeURIComponent(this.Appointment.Location)}&sf=true&output=xml`;
}
if (type == calendarOptions.YAHOO) {
URL = `https://calendar.yahoo.com/?v=60&TITLE=${encodeURIComponent(
this.Appointment.Subject
)}&DESC=${encodeURIComponent(this.Appointment.Body)}&ST=${encodeURIComponent(
getDateFormat(this.Appointment.StartDate, dateFormat)
)}&DUR=${this.Appointment.Duration}&in_loc=${encodeURIComponent(
this.Appointment.Location
)}`;
}
return {
url: URL,
name: type,
icon: require(`@/assets/img/icons/${type}.svg`),
};
},
getAppointment() {
let body = this.Appointment.Body;
body = body?.replace("|", "<").replace("~", ">");
const calFile = {
Location: this.Appointment.Location,
Body: body,
IsHTML: this.Appointment.IsHTML,
UniqueId: this.Appointment.RefrrlSeqNum,
Subject: this.Appointment.Subject,
StartDate: this.Appointment.StartDate,
EndDate: this.Appointment.EndDate,
Status: calendarStatus.BUSY,
};
var calBody = getCalendarFile(calFile);
download("SafeliteAppointment.ics", calBody);
},
},
};
</script>
<style scoped>
.add-to-calendar-text {
margin: 0 0 0 7px;
color: #1574a1;
vertical-align: middle;
font-weight: 500;
font-family: "Roboto";
}
.add-to-calendar button {
border: 0;
background-color: #fff;
}
.calendar-section {
display: table;
position: relative;
margin: 0 auto;
}
.calendar-section .add-to-calendar {
padding-top: 15px;
}
.calendar-section .add-to-calendar .add-to-calendar-span {
cursor: pointer;
}
.calendar-section .add-to-calendar .add-to-calendar-img {
display: inline;
width: 20px;
}
</style>

View file

@ -1,6 +1,6 @@
import { shallowMount } from "@vue/test-utils";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
import calendarModalQuestion from "@/layouts/add-to-calendar/calendar-modal-question/calendar-modal-question.vue";
import calendarModalQuestion from "@/layouts/confirmation/add-to-calendar/calendar-modal-question/calendar-modal-question.vue";
describe("calendar-modal-question.vue", () => {
test("When selected calendar option is changed, a correctly selectedCalendarOption should be emitted", async () => {

View file

@ -20,7 +20,19 @@
<p>{{ ScheduleDateFormatted }}</p>
<p>{{ ScheduleTimeFormatted }}</p>
</div>
<addToCalendar :appointment="this.AppointmentData" />
<addToCalendar
mobileWidgetName="AddToCalendar_Mobile"
inShopWidgetName="AddToCalendar_InShop"
dropOffWidgetName="AddToCalendar_DropOff"
overnightDropOffWidgetName="AddToCalendar_OvernightDropOff"
allDayDropOffWidgetName="AddToCalendar_AllDayDropOff"
sameDayDropOffWidgetName="AddToCalendar_SameDayDropOff"
:serviceLocationFullAddress="ServiceLocationFullAddress"
:providerFullAddress="ProviderFullAddress"
:appointmentType="AppointmentType"
:scheduleDate="ScheduleDate"
:scheduleStartTime="ScheduleStartTime"
:scheduleEndTime="ScheduleEndTime" />
<div class="appoinmenttext" v-html="AppointmentWordingText"></div>
</div>
@ -43,22 +55,17 @@
import funnelHeader from "@/fmg-components/funnel-header/funnel-header";
import vehicleBanner from "@/fmg-components/vehicle-banner/vehicle-banner";
import navbar from "@/fmg-components/nav-bar/nav-bar";
import addToCalendar from "@/layouts/add-to-calendar/add-to-calendar";
import addToCalendar from "@/layouts/confirmation/add-to-calendar/add-to-calendar";
//Supporting files
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { AppointmentTypeStrings, RouteCodeFlags } from "@/constants/schedule-constants";
import { AppointmentTypeStrings } from "@/constants/schedule-constants";
import { settleAllPromises } from "@/helpers/layout-helper";
import { applicationConfig } from "@/constants/application-config.js";
import { convertDateStringToDate } from "@/layouts/schedule/helpers/schedule-helper";
import {
calculateDuration,
combineDateAndTime,
shortTimeString,
addMinutes,
} from "@/helpers/date-helper";
import { Form } from "vee-validate";
import store from "@/store";
import { serviceType } from "@/constants/service-type";
import { get12HourTimeFormat, get12HourTimeMobileFormat } from "@/helpers/date-helper";
export default {
name: "confirmation",
@ -190,138 +197,6 @@ export default {
return `at ${get12HourTimeFormat(this.ScheduleStartTime)}`;
}
},
IsSameDayDropOff() {
const todaysDate = new Date().toISOString().split("T")[0];
return this.ScheduleDate === todaysDate;
},
Mobile_Appointment_Subject() {
return this.getCmsContent("Mobile_Appointment_Widget", "HeaderText");
},
Mobile_Appointment_Body() {
return this.getCmsContent("Mobile_Appointment_Widget", "BodyText");
},
InShop_Appointment_Subject() {
return this.getCmsContent("InShop_Appointment_Widget", "HeaderText");
},
InShop_Appointment_Body() {
return this.getCmsContent("InShop_Appointment_Widget", "BodyText");
},
Drop_Off_Appointment_Subject() {
return this.getCmsContent("Drop_Off_Appointment_Widget", "HeaderText");
},
Drop_Off_Appointment_Body() {
return this.getCmsContent("Drop_Off_Appointment_Widget", "BodyText");
},
Overnight_Drop_Off_Appointment_Subject() {
return this.getCmsContent("Drop_Off_Appointment_Widget", "HeaderText");
},
Overnight_Drop_Off_Appointment_Body() {
return this.getCmsContent("Drop_Off_Appointment_Widget", "BodyText");
},
All_Day_Drop_Off_Appointment_Subject() {
return this.getCmsContent("All_Day_Drop_Off_Appointment_Widget", "HeaderText");
},
All_Day_Drop_Off_Appointment_Body() {
return this.getCmsContent("All_Day_Drop_Off_Appointment_Widget", "BodyText");
},
Same_Day_Drop_Off_Appointment_Subject() {
return this.getCmsContent("Same_Day_Drop_Off_Appointment_Widget", "HeaderText");
},
Same_Day_Drop_Off_Appointment_Body() {
return this.getCmsContent("Same_Day_Drop_Off_Appointment_Widget", "BodyText");
},
UniqueId() {
return store.getters.order.referralNumber?.toString();
},
ServiceType() {
const isRepair = store.getters.order.damage.isRepair;
const funnelHasRecalibrationPart = store.getters.funnelHasRecalibrationPart;
if (!isRepair) {
if (funnelHasRecalibrationPart) {
return serviceType.REPLACEMENT_AND_RECALIBRATION;
} else {
return serviceType.REPLACEMENT;
}
}
return serviceType.REPAIR;
},
RouteCode() {
return store.getters.order.schedule.routeCode;
},
AppointmentData() {
var subject = "";
var location = "";
var startDateTime = combineDateAndTime(this.ScheduleDate, this.ScheduleStartTime);
var endDateTime = combineDateAndTime(this.ScheduleDate, this.ScheduleEndTime);
var body = "";
var isHTML = false;
var duration = "";
if (this.AppointmentType === AppointmentTypeStrings.MOBILE) {
location = this.ServiceLocationFullAddress?.replace("<br/>", "");
subject = this.Mobile_Appointment_Subject?.replace(
"{custom:SERVICETYPE}",
this.ServiceType
);
body = this.Mobile_Appointment_Body;
} else {
location = this.ProviderFullAddress?.replace("<br/>", "");
if (this.AppointmentType === AppointmentTypeStrings.DROP_OFF) {
if (this.RouteCode.includes(RouteCodeFlags.OVERNIGHT_DROP_OFF)) {
subject = this.Overnight_Drop_Off_Appointment_Subject;
body = this.Overnight_Drop_Off_Appointment_Body;
} else if (this.RouteCode.includes(RouteCodeFlags.ALL_DAY_DROP_OFF)) {
if (this.IsSameDayDropOff) {
subject = this.Same_Day_Drop_Off_Appointment_Subject;
endDateTime = addMinutes(startDateTime, 120);
body = this.Same_Day_Drop_Off_Appointment_Body;
} else {
endDateTime = addMinutes(startDateTime, 120);
subject = this.All_Day_Drop_Off_Appointment_Subject?.replace(
"{custom:STARTDATETIME}",
shortTimeString(startDateTime)
).replace("{custom:ENDDATETIME}", shortTimeString(endDateTime));
body = this.All_Day_Drop_Off_Appointment_Body?.replace(
"{custom:ENDDATETIME}",
shortTimeString(endDateTime)
);
}
} //normal time slot
else {
subject = this.Drop_Off_Appointment_Subject?.replace(
"{custom:SERVICETYPE}",
this.ServiceType
);
body = this.Drop_Off_Appointment_Body?.replace(
"{custom:ADDRESS}",
location
);
}
} else {
subject = this.InShop_Appointment_Subject?.replace(
"{custom:SERVICETYPE}",
this.ServiceType
);
body = this.InShop_Appointment_Body?.replace("{custom:ADDRESS}", location);
}
duration = calculateDuration(startDateTime, endDateTime);
}
return {
Subject: subject,
Location: location,
StartDate: startDateTime,
EndDate: endDateTime,
RefrrlSeqNum: this.UniqueId,
Body: body,
IsHTML: isHTML,
Duration: duration,
};
},
},
data() {
return {
workOrderNumber: store.getters.order.workOrderNumber,
};
},
methods: {
arePagePrerequisitesValid() {