add to calendar setup
This commit is contained in:
parent
ab0e286c21
commit
5c9416e989
2 changed files with 314 additions and 0 deletions
|
|
@ -0,0 +1,313 @@
|
||||||
|
<template>
|
||||||
|
<div class="calendar-section">
|
||||||
|
<div class="add-to-calendar">
|
||||||
|
<button @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"
|
||||||
|
v-model="selectedCalendarOption"
|
||||||
|
customComponentId="calendarModalQuestion"
|
||||||
|
cmsWidgetName="CalendarModalQuestion"
|
||||||
|
:calendarOptionsData="calendarValues"
|
||||||
|
@calendarModalClosed="calendarModalClosed">
|
||||||
|
</calendarModalQuestion>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { getDateFormat,
|
||||||
|
calculateDuration,
|
||||||
|
combineDateAndTime,
|
||||||
|
shortTimeString,
|
||||||
|
addMinutes } from '@/helpers/date-helper.js';
|
||||||
|
import calendarModalQuestion from '@/layouts/order-confirmation/add-to-calendar/calendar-modal-question/calendar-modal-question.vue';
|
||||||
|
import { AppointmentTypeStrings, RouteCodeFlags } from '@/constants/schedule-constants';
|
||||||
|
import store from '@/store';
|
||||||
|
import calendarOptions from '@/constants/calendar-options';
|
||||||
|
import calendarStatus from '@/constants/calendar-status';
|
||||||
|
import { getCalendarFile, download } from '@/helpers/add-to-calendar-helper';
|
||||||
|
import serviceType from '@/constants/service-type';
|
||||||
|
import applicationConfig from '@/constants/application-config.js';
|
||||||
|
|
||||||
|
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() {
|
||||||
|
const obj = [];
|
||||||
|
const options = Object.values(calendarOptions);
|
||||||
|
for (let 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.submittedOrder.referralNumber?.toString();
|
||||||
|
},
|
||||||
|
ServiceType() {
|
||||||
|
const { isRepair } = store.getters.submittedOrder.damage;
|
||||||
|
const funnelHasRecalibrationPart = store.getters.isRecalibrationOnSubmittedOrder;
|
||||||
|
if (!isRepair) {
|
||||||
|
if (funnelHasRecalibrationPart) {
|
||||||
|
return serviceType.REPLACEMENT_AND_RECALIBRATION;
|
||||||
|
}
|
||||||
|
return serviceType.REPLACEMENT;
|
||||||
|
}
|
||||||
|
return serviceType.REPAIR;
|
||||||
|
},
|
||||||
|
RouteCode() {
|
||||||
|
return store.getters.submittedOrder.schedule.routeCode;
|
||||||
|
},
|
||||||
|
Appointment() {
|
||||||
|
let subject = '';
|
||||||
|
let location = '';
|
||||||
|
const startDateTime = combineDateAndTime(this.scheduleDate, this.scheduleStartTime);
|
||||||
|
let endDateTime = combineDateAndTime(this.scheduleDate, this.scheduleEndTime);
|
||||||
|
let body = '';
|
||||||
|
const isHTML = false;
|
||||||
|
let 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)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line brace-style
|
||||||
|
} // 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 === calendarOptions.ICAL
|
||||||
|
|| calendarOption.name === 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) {
|
||||||
|
let URL = '';
|
||||||
|
const dateFormat = 'yyyyMMddTHHmmss';
|
||||||
|
const outlookComTimeSpanFormat = 'yyyy-MM-ddTHH:mm:ss';
|
||||||
|
if (type === calendarOptions.OUTLOOKCOM) {
|
||||||
|
URL = `${applicationConfig.OUTLOOK_CALENDAR}&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 = `${applicationConfig.GOOGLE_CALENDAR}&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 = `${applicationConfig.YAHOO_CALENDAR}&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,
|
||||||
|
// eslint-disable-next-line import/no-dynamic-require, global-require
|
||||||
|
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
|
||||||
|
};
|
||||||
|
const 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>
|
||||||
|
|
@ -29,6 +29,7 @@ import { defineRule, useField } from 'vee-validate';
|
||||||
import errorMessages from '@/constants/error-messages.js';
|
import errorMessages from '@/constants/error-messages.js';
|
||||||
import { required } from '@/helpers/validation-rules';
|
import { required } from '@/helpers/validation-rules';
|
||||||
import { deepClone } from '@/helpers/object-helper';
|
import { deepClone } from '@/helpers/object-helper';
|
||||||
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
import calendarModalListButton from './calendar-modal-list-button/calendar-modal-list-button.vue';
|
import calendarModalListButton from './calendar-modal-list-button/calendar-modal-list-button.vue';
|
||||||
// Validation for the modal button
|
// Validation for the modal button
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue