idea-toolbox
Version:
IDEA's utility functions
245 lines (244 loc) • 10.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AppointmentNotificationUnitsOfTime = exports.AppointmentNotificationMethods = exports.AppointmentNotification = exports.AppointmentAttendance = exports.AppointmentAttendee = exports.AppointmentLinkedObjectTypes = exports.AppointmentLinkedObject = exports.AppointmentKeys = exports.Appointment = void 0;
const resource_model_1 = require("./resource.model");
/**
* Represents an appointment (event) of a calendar.
*
* Table: `idea_appointments`.
*
* Indexes:
* - calendarId-startTime-index (LSI, all)
* - calendarId-masterAppointmentId-index (LSI, keys); to manage occurences
* - internalNotificationFiresOn-internalNotificationFiresAt-index (GSI); includes:
* internalNotificationProject, internalNotificationTeamId, internalNotificationUserId,
* notifications, title, startTime, endTime
*/
class Appointment extends resource_model_1.Resource {
load(x) {
super.load(x);
this.appointmentId = this.clean(x.appointmentId, String);
this.calendarId = this.clean(x.calendarId, String);
this.iCalUID = this.clean(x.iCalUID, String);
if (x.masterAppointmentId)
this.masterAppointmentId = this.clean(x.masterAppointmentId, String);
this.title = this.clean(x.title, String);
this.location = this.clean(x.location, String);
this.description = this.clean(x.description, String);
this.startTime = this.clean(x.startTime, d => new Date(d).getTime());
this.endTime = this.clean(x.endTime, d => new Date(d).getTime());
this.allDay = this.clean(x.allDay, Boolean);
this.fixAllDayTime();
this.timezone = this.clean(x.timezone, String, Intl.DateTimeFormat().resolvedOptions().timeZone);
if (x.linkToOrigin)
this.linkToOrigin = this.clean(x.linkToOrigin, String);
this.notifications = this.cleanArray(x.notifications, n => new AppointmentNotification(n));
if (!this.linkToOrigin && this.notifications.length) {
// appointment comes from an internal calendar, notifications will fire
this.internalNotificationProject = this.clean(x.internalNotificationProject, String);
this.internalNotificationTeamId = this.clean(x.internalNotificationTeamId, String);
this.internalNotificationUserId = this.clean(x.internalNotificationUserId, String);
this.removeDuplicateNotifications();
this.calculateFiringTime();
}
if (x.linkedTo)
this.linkedTo = this.cleanArray(x.linkedTo, o => new AppointmentLinkedObject(o));
this.attendees = this.cleanArray(x.attendees, a => new AppointmentAttendee(a));
}
/**
* Set a default start/end day for all-day events, to be compatible with external services.
*/
fixAllDayTime() {
if (this.allDay) {
const start = new Date(this.startTime);
start.setHours(0, 0, 0);
this.startTime = start.getTime();
const end = new Date(this.endTime);
end.setHours(13, 0, 0);
this.endTime = end.getTime();
}
}
safeLoad(newData, safeData) {
super.safeLoad(newData, safeData);
this.appointmentId = safeData.appointmentId;
this.calendarId = safeData.calendarId;
this.iCalUID = safeData.iCalUID;
if (safeData.masterAppointmentId)
this.masterAppointmentId = safeData.masterAppointmentId;
if (safeData.linkedTo)
this.linkedTo = safeData.linkedTo;
if (!this.linkToOrigin)
if (this.notifications.length) {
this.internalNotificationProject = safeData.internalNotificationProject;
this.internalNotificationTeamId = safeData.internalNotificationTeamId;
this.internalNotificationUserId = safeData.internalNotificationUserId;
this.removeDuplicateNotifications();
this.calculateFiringTime();
}
else {
delete this.internalNotificationProject;
delete this.internalNotificationTeamId;
delete this.internalNotificationUserId;
delete this.internalNotificationFiresAt;
delete this.internalNotificationFiresOn;
}
}
validate() {
const e = super.validate();
if (this.iE(this.title))
e.push('title');
if (this.iE(this.startTime))
e.push('startTime');
if (this.iE(this.endTime))
e.push('endTime');
if (this.iE(this.timezone))
e.push('timezone');
return e;
}
/**
* Helper to remove duplicates notifications for the same appointment.
*/
removeDuplicateNotifications() {
this.notifications = this.notifications.filter((n, index, self) => index === self.findIndex(t => t.method === n.method && t.minutes === n.minutes));
}
/**
* Calculate the firing time for internal appointments.
*/
calculateFiringTime() {
// find the first notification to fire (max number of minutes to substract from the start time)
const maxNumMinutes = Math.max.apply(null, this.notifications.map(n => n.minutes));
// prepare the support firing attributes
const at = new Date(this.startTime);
at.setMinutes(at.getMinutes() - maxNumMinutes);
this.internalNotificationFiresOn = String(at.getFullYear()).concat(('00' + String(at.getMonth() + 1)).slice(-2), ('00' + String(at.getDate())).slice(-2), ('00' + String(at.getHours())).slice(-2));
this.internalNotificationFiresAt = at.getMinutes();
}
/**
* Get the information on an attendee.
* The latter can be identified by email or, by default, as the attendee marked as `self`.
*/
getAttendee(email) {
return this.attendees.find(a => (email ? a.email === email : a.self));
}
/**
* Get the attendance of the desired attendee.
* The latter can be identified by email or, by default, as the attendee marked as `self`.
*/
getAttendance(email) {
const attendee = this.getAttendee(email);
return attendee ? attendee.attendance : undefined;
}
/**
* Whether the user is the organizer of the event.
* The user can be identified by email or, by default, as the attendee marked as `self`.
*/
isOrganizer(email) {
// if the array is empty, the event is owned by the current user (there aren't other attendees)
if (!this.attendees.length)
return true;
// otherwise, check whether the user is the organizer
const attendee = this.getAttendee(email);
return attendee ? attendee.organizer : false;
}
}
exports.Appointment = Appointment;
/**
* A brief view of the appointment, composed by only its keys.
*/
class AppointmentKeys extends resource_model_1.Resource {
load(x) {
super.load(x);
this.appointmentId = this.clean(x.appointmentId, String);
this.calendarId = this.clean(x.calendarId, String);
if (x.teamId)
this.teamId = this.clean(x.teamId, String);
}
validate() {
const e = super.validate();
if (this.iE(this.appointmentId))
e.push('appointmentId');
if (this.iE(this.calendarId))
e.push('calendarId');
return e;
}
}
exports.AppointmentKeys = AppointmentKeys;
/**
* A generic structure to reference to a linked object.
*/
class AppointmentLinkedObject extends resource_model_1.Resource {
load(x) {
super.load(x);
this.type = this.clean(x.type, Number);
this.id = this.clean(x.id, String);
}
validate() {
const e = super.validate();
if (!(this.type in AppointmentLinkedObjectTypes))
e.push('type');
if (this.iE(this.id))
e.push('id');
return e;
}
}
exports.AppointmentLinkedObject = AppointmentLinkedObject;
/**
* The linked object types.
*/
var AppointmentLinkedObjectTypes;
(function (AppointmentLinkedObjectTypes) {
AppointmentLinkedObjectTypes[AppointmentLinkedObjectTypes["SCARLETT_ACTIVITY"] = 100] = "SCARLETT_ACTIVITY";
AppointmentLinkedObjectTypes[AppointmentLinkedObjectTypes["ARTHUR_ACTIVITY"] = 200] = "ARTHUR_ACTIVITY";
})(AppointmentLinkedObjectTypes || (exports.AppointmentLinkedObjectTypes = AppointmentLinkedObjectTypes = {}));
/**
* The info about the attendee to an appointment.
*/
class AppointmentAttendee extends resource_model_1.Resource {
load(x) {
super.load(x);
this.email = this.clean(x.email, String);
this.organizer = this.clean(x.organizer, Boolean);
this.self = this.clean(x.self, Boolean);
this.attendance = this.clean(x.attendance, Number, AppointmentAttendance.NEEDS_ACTION);
}
}
exports.AppointmentAttendee = AppointmentAttendee;
/**
* Possible attendance status for the appointment.
*/
var AppointmentAttendance;
(function (AppointmentAttendance) {
AppointmentAttendance[AppointmentAttendance["DECLINED"] = -1] = "DECLINED";
AppointmentAttendance[AppointmentAttendance["NEEDS_ACTION"] = 0] = "NEEDS_ACTION";
AppointmentAttendance[AppointmentAttendance["TENTATIVE"] = 1] = "TENTATIVE";
AppointmentAttendance[AppointmentAttendance["ACCEPTED"] = 2] = "ACCEPTED";
})(AppointmentAttendance || (exports.AppointmentAttendance = AppointmentAttendance = {}));
/**
* The info about the appointment notification.
*/
class AppointmentNotification extends resource_model_1.Resource {
load(x) {
super.load(x);
this.method = this.clean(x.method, String);
this.minutes = this.clean(x.minutes, Number, 0);
}
}
exports.AppointmentNotification = AppointmentNotification;
/**
* Possible notification methods (currently supported for Google Calendars and internal calendars).
*/
var AppointmentNotificationMethods;
(function (AppointmentNotificationMethods) {
AppointmentNotificationMethods["PUSH"] = "PUSH";
AppointmentNotificationMethods["EMAIL"] = "EMAIL";
})(AppointmentNotificationMethods || (exports.AppointmentNotificationMethods = AppointmentNotificationMethods = {}));
/**
* Possible notification units of time.
*/
var AppointmentNotificationUnitsOfTime;
(function (AppointmentNotificationUnitsOfTime) {
AppointmentNotificationUnitsOfTime["MINUTES"] = "MINUTES";
AppointmentNotificationUnitsOfTime["HOURS"] = "HOURS";
AppointmentNotificationUnitsOfTime["DAYS"] = "DAYS";
AppointmentNotificationUnitsOfTime["WEEKS"] = "WEEKS";
})(AppointmentNotificationUnitsOfTime || (exports.AppointmentNotificationUnitsOfTime = AppointmentNotificationUnitsOfTime = {}));