Newer
Older
const TIME_FORMAT = 'HH:mm';
const FLYING_TEAM_LABEL = 'Flying Team';
const FLYING_TEAM_BORDER_COLOR = "orange";
var overlaps = (function () {
function getPositions(elem) {
var pos, width, height;
pos = $(elem).position();
width = $(elem).width();
height = $(elem).height();
return [[pos.left, pos.left + width], [pos.top, pos.top + height]];
}
function comparePositions(p1, p2) {
var r1, r2;
r1 = p1[0] < p2[0] ? p1 : p2;
r2 = p1[0] < p2[0] ? p2 : p1;
return r1[1] > r2[0] || r1[0] === r2[0];
}
return function (x, y, element) {
var pos1 = [[x, x + 100], [y, y + 20]],
pos2 = getPositions(element);
console.log(x, y, element);
return comparePositions(pos1[0], pos2[0]) && comparePositions(pos1[1], pos2[1]);
};
})();
var eventsCleared = [];
var appointmentsCleared = [];
function add_event(event, color, subjectId, locationId, boxBody) {
var eventElement = $('<div class="fc-event ui-draggable ui-draggable-handle hidden-print">' + event.title +
'<span style="float:right;padding-right:5px;">' + event.duration + '</span></div>'
)
;
eventElement.removeData();
var constraintStart = $.fullCalendar.moment(event.appointment_start);
var borderColor;
var location = event.location;
if (location === FLYING_TEAM_LABEL) {
eventElement.css('border', '2px solid ' + FLYING_TEAM_BORDER_COLOR);
location = event.flying_team_location + ' (FT)';
borderColor = FLYING_TEAM_BORDER_COLOR;
var event_title = event.short_title;
if (event_title === undefined || event_title === "") {
event_title = event.title;
}
eventElement.data('event', {
appointment_start: event.appointment_start,
appointment_end: event.appointment_end,
title: event_title,
stick: true,
color: color + " !important",
duration: event.duration,
original_duration: event.duration,
subject: event.subject,
subject_id: subjectId,
location_id: locationId,
appointment_id: event.appointment_id,
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
link_id: event.link_id,
link_who: event.link_who,
link_when: event.link_when,
location: event.location,
flying_team_location: event.flying_team_location,
constraint: {
start: constraintStart,
end: $.fullCalendar.moment(event.appointment_end)
},
borderColor: borderColor
});
eventElement.draggable({
zIndex: 999,
revert: true,
revertDuration: 0,
start: function (event, ui) {
$(this).popover('disable');
}
});
eventElement.css('background-color', color);
eventElement.css('width', event.width);
boxBody.append(eventElement);
eventElement.popover({
container: 'body',
trigger: 'click',
content: location + ', appointment starts at ' + constraintStart.format(TIME_FORMAT)
});
}
function get_subjects_events(day) {
$.get('/api/events/' + day, function (data) {
$("#subjects").empty();
var availabilities = data.availabilities;
$.each(availabilities, function (index, event) {
event.backgroundColor = '#AAFFAA !important';
event.start = $.fullCalendar.moment(event.link_when);
event.end = $.fullCalendar.moment(event.link_end);
event.rendering = 'background';
event.resourceId = event.link_who.toString();
event.className = 'background-event';
$('#calendar').fullCalendar('renderEvent', event, true);
});
var holidays = data.holidays;
$.each(holidays, function (index, event) {
if(event.kind == 'H'){
event.backgroundColor = '#FFAAAA !important';
}else{
event.backgroundColor = '#AAFFAA !important';
}
event.start = $.fullCalendar.moment(event.link_when);
event.end = $.fullCalendar.moment(event.link_end);
event.rendering = 'background';
event.resourceId = event.link_who.toString();
event.className = 'background-event';
$('#calendar').fullCalendar('renderEvent', event, true);
});
var subjects = data.data;
$.each(subjects, function (index, subject) {
var divSubject = $("<div class='col-md-4 col-lg-3 col-sm-12 subjects-events'/>");
var boxSubject = $("<div class='box box-primary'/>").css('border-top-color', subject.color);
var boxBody = $("<div class='box-body' id='subject_" + subject.id + "'>");
var boxHeader = $("<div class='box-header with-border'/>");

Carlos Vega
committed
//flags
var flagTooltip = '';
if('flags' in subject){
for(i=0; i<subject.flags.length; i++){
var url = subject.flags[i];
flagTooltip+= `<img class='tooltip_image' src='${url}'/>`;
}
var title_subject = `<h4 class="subject_title" data-toggle="tooltip" data-html="true" title="${flagTooltip}">${subject.name} (${subject.start})</h4>`;
}else{
var title_subject = `<h4 class="subject_title">${subject.name} (${subject.start})</h4>`; //wrap content
}
title_subject = $(`${title_subject}
<span style='padding-right:5px;'>${subject.location}</span>
<span style='padding-right:5px;'>
<a title="Edit appointment" target="_blank" href="/appointments/edit/${subject.appointment_id}">
<i class="fa fa-pencil-square"></i>
</a>
</span>`);
title_subject.find('a[title]').tooltip();
$.each(subject.events, function (index_event, event) {
if (event.link_when) {
event.title = event.short_title;
event.color = subject.color + ' !important';
event.start = $.fullCalendar.moment(event.link_when);
event.end = $.fullCalendar.moment(event.link_end);
event.resourceId = event.link_who.toString();
event.subject_id = subject.id;
event.original_duration = event.duration;
event.constraint = {
start: $.fullCalendar.moment(event.appointment_start),
end: $.fullCalendar.moment(event.appointment_end)
};
if (event.start.valueOf() === event.end.valueOf()) {
event.end = $.fullCalendar.moment(event.start);
event.end.add(1, 'hour');
}
$('#calendar').fullCalendar('renderEvent', event, true);
} else {
add_event(event, subject.color, subject.id, undefined, boxBody);
}
});
boxSubject.append(boxHeader);
boxSubject.append(boxBody);
divSubject.append(boxSubject);
$("#subjects").append(divSubject);
divSubject.droppable({
drop: function (event, ui) {
}
});
});
var location_based_general_appointments = data.generic;

Carlos Vega
committed
$.each(location_based_general_appointments, function (index, location) { //Subject Appointment List
var divSubject = $("<div class='col-md-4 col-lg-3 col-sm-12 subjects-events'/>");
var boxSubject = $("<div class='box box-primary'/>").css('border-top-color', location.color);
var boxBody = $("<div class='box-body' id='location_" + location.id + "'>");
var boxHeader = $("<div class='box-header with-border'/>");

Carlos Vega
committed
var title_location = $(`<h4>${location.name}<span style='padding-right:5px;'>${location.location}</span></h4>
<span style='padding-right:5px;'>
<a title="Edit Appointment" target="_blank" href="/appointments/edit/${location.id}">
<i class="fa fa-pencil-square"></i>
</a>
</span>`);
boxHeader.append(title_location);
title_location.find('a[title]').tooltip();
$.each(location.events, function (index_event, event) {
if (event.link_who) {
event.title = event.short_title;
event.color = location.color + ' !important';
event.start = $.fullCalendar.moment(event.link_when);
event.end = $.fullCalendar.moment(event.link_end);
event.resourceId = event.link_who.toString();
event.location_id = location.id;
event.original_duration = event.duration;
event.constraint = {
start: $.fullCalendar.moment(event.appointment_start),
end: $.fullCalendar.moment(event.appointment_end)
};
if (event.start.valueOf() === event.end.valueOf()) {
event.end = $.fullCalendar.moment(event.start);
event.end.add(1, 'hour');
}
$('#calendar').fullCalendar('renderEvent', event, true);
} else {
add_event(event, location.color, undefined, location.id, boxBody);
}
});
boxSubject.append(boxHeader);
boxSubject.append(boxBody);
divSubject.append(boxSubject);
$("#subjects").append(divSubject);
divSubject.droppable({
drop: function (event, ui) {
}
});
});
function remove_event(event) {
$('#calendar').fullCalendar('removeEvents', event.id);
var selector;
if (event.subject_id !== undefined) {
selector = '#subject_' + event.subject_id;
} else {
selector = '#location_' + event.location_id;
}
var boxBody = $(selector);
event.duration = event.original_duration;
event.removed = true;
//remove !important
event.color = event.color.substring(0, 7);
if (event.link_id !== undefined) {
eventsCleared.push(event.link_id);
} else {
appointmentsCleared.push(event.appointment_id);
}
add_event(event, event.color, event.subject_id, event.location_id, boxBody);
$(document).ready(function () {
$('#calendar').fullCalendar({
schedulerLicenseKey: 'CC-Attribution-NonCommercial-NoDerivatives',
defaultView: 'agendaDay',
eventDurationEditable: false,
eventStartEditable: true,
editable: true,
selectable: true,
eventOverlap: function (stillEvent, movingEvent) {
if (stillEvent.rendering === "background") {
return true;
}
return false;
},
weekends: false,
scrollTime: '08:00',
slotDuration: '00:30',
snapDuration: '00:05',
displayEventTime: true,
resourceOrder: 'role',
resourceGroupField: 'role',
dragRevertDuration: 0,
minTime: "08:00:00",
maxTime: "19:00:00",
groupByResource: true,
datePickerButton: {
text: 'select',
click: function () {
var $btnCustom = $('.fc-datePickerButton-button');
if ($(".calendar-datepicker").length > 0) {
$(".calendar-datepicker").remove();
}
else {
$btnCustom.after('<div class="calendar-datepicker"/>');
$(".calendar-datepicker").datepicker().on('changeDate', function (ev) {
$('#calendar').fullCalendar('gotoDate', ev.date);
$(".calendar-datepicker").remove();
});
}
}
},
save: {
text: 'Save',
click: function () {
calendarEvents = $('#calendar').fullCalendar('clientEvents');
eventsToPersist = [];
var saveButton = $(".fc-save-button");
var currentBorder = saveButton.css('border-color');
$.each(calendarEvents, function (i, calendar_event) {
if (calendar_event.rendering !== "background") {
eventsToPersist.push({
'link_id': calendar_event.link_id,
'appointment_id': calendar_event.appointment_id,
'link_who': parseInt(calendar_event.resourceId),
'start': calendar_event.start.format()
});
if (calendar_event.link_id !== undefined) {
var index = eventsCleared.indexOf(calendar_event.link_id);
if (index > -1) {
eventsCleared.splice(index, 1);
}
} else {
var index = appointmentsCleared.indexOf(calendar_event.appointment_id);
if (index > -1) {
appointmentsCleared.splice(index, 1);
}
}
});
$.post({
url: events_url,
data: {
events_to_persist: JSON.stringify(eventsToPersist),
events_to_clear: JSON.stringify(eventsCleared),
appointments_to_clear: JSON.stringify(appointmentsCleared)
},
dataType: "json"
}).done(function (data) {
saveButton.css('border-color', 'green');
setTimeout(function () {
saveButton.css('border-color', currentBorder);
}, 200);
}).error(function (data) {
console.log(data);
saveButton.css('border-color', 'red');
showErrorInfo("There was an unexpected problem with saving data. " +
"Please contact administrators.");
setTimeout(function () {
saveButton.delay(200).css('border-color', currentBorder);
}, 200);
});
}
},
clear: {
text: 'Clear',
click: function () {
calendarEvents = $('#calendar').fullCalendar('clientEvents');
$.each(calendarEvents, function (i, calendar_event) {
remove_event(calendar_event);
});
}
},
toPdf: {
text: 'PDF',
click: function () {
var srcEl = document.getElementById("calendar");
var parent = srcEl.parentNode;
var container = document.createElement("div");
container.style.backgroundColor = "#FFFFFF";
container.style.width = "3840px";
document.body.appendChild(container);
container.appendChild(srcEl);
var pdf = new jsPDF('l', 'mm', [1485, 270]);
pdf.addHTML(container, function () {
pdf.save('daily-planning.pdf');
parent.appendChild(srcEl);
document.body.removeChild(container);
},
viewRender: function (view, element) {
var date = view.start.format('YYYY-MM-DD');
$('#calendar').fullCalendar('removeEvents');
get_subjects_events(date);
},
businessHours: {
start: '08:00',
end: '19:00'
},
header: {
left: 'prev,next today',
center: 'title, datePickerButton',
},
droppable: true,
resourceAreaWidth: '15%',
resourceLabelText: 'Workers',
refetchResourcesOnNavigate: true,
resourceOrder: '-availability',

Carlos Vega
committed
resourceRender: function(resourceObj, labelTds, bodyTds) { //Calendar Columns
var title = $(labelTds).text() //get content
$(labelTds).text('') //empty content
var flagTooltip = '';
if('flags' in resourceObj){
for(i=0; i<resourceObj.flags.length; i++){
var url = resourceObj.flags[i];
flagTooltip+= `<img class='tooltip_image' src='${url}'/>`;
}
$(labelTds).prepend(`<span class="column_title" data-toggle="tooltip" data-html="true" title="${flagTooltip}">${title}</span>`) //wrap content
}else{
$(labelTds).prepend(`<span class="column_title">${title}</span>`) //wrap content
}
//buttons
var worker_id = resourceObj.id;
var span = $(`<div style='display:block;'></div>`);
var add_extra_availability_link = `<a style="padding-right:5px;" title="Add Extra Availability or Holiday" target="_blank" href="/doctors/${worker_id}/holiday/add"><i class="fa fa-plus-square-o" aria-hidden="true"></i></a>`;
var edit_worker_link = `<a style="padding-right:5px;" title="Edit Worker" target="_blank" href="/doctors/edit/${worker_id}"><i class="fa fa-pencil-square" aria-hidden="true"></i></a>`;
$(span).append($(add_extra_availability_link));
$(span).append($(edit_worker_link));
$(labelTds).append(span);
$(labelTds).find('a[title]').tooltip();
},
resources: function(callback){
setTimeout(function(){
var view = $('#calendar').fullCalendar('getView');
$.ajax({
url: resources_url,
type: 'GET',
cache: false,
data: {
start_date: view.start.format('YYYY-MM-DD'),
}
}).then(function(resources){

Carlos Vega
committed
//Filter out roles
var checked_roles = $('.role_list_item > input:checked').map( (i,e) => e.value).toArray();
resources = resources.filter(resource => checked_roles.includes(resource.role));
callback(resources)
});
}, 0);
},
events: [],
eventRender: function (event, element) {
if (event.rendering !== 'background') {
var content =
element.popover({
title: event.short_title,
container: 'body',
placement: 'bottom',
trigger: 'click',
content: '<ul>' +
'<li>' + (event.subject !== undefined ? event.subject : 'NO SUBJECT') + '</li>' +
'<li>' + event.start.format(TIME_FORMAT) + ' - ' + event.end.format(TIME_FORMAT) + '</li>' +
(event.subject !== undefined ? '<li>Appointment starts: ' + event.constraint.start.format(TIME_FORMAT) + '</li>' : '') +
'<li>Location: ' + (event.location !== FLYING_TEAM_LABEL ? event.location : event.flying_team_location + ' (FT)') + '</li>' +
'</ul>',
html: true
});
} else {
}
},
selectAllow: function (selectInfo) {
return false;
},
eventDragStop: function (event, jsEvent, ui, view) {
// var x = isElemOverDiv(jsEvent.clientX, jsEvent.clientY, $('#subjects'));
$('.popover').popover('hide');
var x = overlaps(jsEvent.clientX, jsEvent.clientY, $('#subjects'));
if (x) {
remove_event(event);
}
},
eventDragStart: function (event, jsEvent, view) {
$('.popover').popover('hide');
},
selectHelper: true,
drop: function (date, jsEvent, ui, resourceId) {
$(this).remove();
},
eventAfterAllRender: function(view){
//RESIZE COLUMNS AND ENABLE HORIZONTAL SCROLL
window.onresize = function(event) {
resizeCalendarColumns();
};
setTimeout(function() {resizeCalendarColumns()}, 100);
;
//RESIZE COLUMNS AND ENABLE HORIZONTAL SCROLL
function resizeCalendarColumns(){
if($('.fc-resource-cell').width() <= 150){
$('.fc-view-container').width(200*$('.fc-resource-cell').length);
$('#calendar').css('overflow-x', 'scroll');
}
if($('#calendar').width() > 200*$('.fc-resource-cell').length){
$('.fc-view-container').width("100%");
$('#calendar').css('overflow-x', 'null');
}
}