diff --git a/UI/WebServerResources/js/Scheduler/sgCalendarDayBlockGhost.directive.js b/UI/WebServerResources/js/Scheduler/sgCalendarDayBlockGhost.directive.js new file mode 100644 index 000000000..e166e0413 --- /dev/null +++ b/UI/WebServerResources/js/Scheduler/sgCalendarDayBlockGhost.directive.js @@ -0,0 +1,205 @@ +/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ + +(function() { + 'use strict'; + + /* + * sgCalendarDayBlockGhost - An event ghost block to be displayed while dragging an event block. Each day of the + * calendar's view is associated to a ghost block. + * @memberof SOGo.SchedulerUI + * @restrict element + * + * @example: + + + */ + sgCalendarDayBlockGhost.$inject = ['$rootScope', '$timeout', 'CalendarSettings', 'Calendar', 'Component']; + function sgCalendarDayBlockGhost($rootScope, $timeout, CalendarSettings, Calendar, Component) { + return { + restrict: 'E', + require: ['^sgCalendarDay', '^sgCalendarScrollView'], + replace: true, + template: [ + '
', + '
', + '
{{ block.component.summary }}', + ' ', + // Component has an alarm + ' ', + // Component is confidential + ' ', + // Component is private + ' ', + ' ', + '
', + '
', + '
{{ startHour }}
', + '
{{ endHour }}
', + '
' + ].join(''), + link: link + }; + + function link(scope, iElement, attrs, ctrls) { + var domElement, calendarDayCtrl, scrollViewCtrl; + + domElement = iElement[0]; + calendarDayCtrl = ctrls[0]; + scrollViewCtrl = ctrls[1]; + + // Listen on drag gestures + var deregisterDragStart = $rootScope.$on('calendar:dragstart', initGhost); + var deregisterDrag = $rootScope.$on('calendar:drag', updateGhost); + var deregisterDragEnd = $rootScope.$on('calendar:dragend', hideGhost); + + // Deregister listeners on destroy + scope.$on('$destroy', function() { + deregisterDragStart(); + deregisterDrag(); + deregisterDragEnd(); + }); + + function initGhost() { + // Expose ghost block to the scope + scope.block = Component.$ghost; + // Set background color + iElement.addClass('bg-folder' + scope.block.component.pid); + } + + function hideGhost() { + // Remove background color + _.forEachRight(domElement.classList, function(c) { + if (/^bg-folder/.test(c)) + iElement.removeClass(c); + }); + // Hide ghost + iElement.addClass('ng-hide'); + } + + function updateGhost() { + // From SOGoEventDragGhostController._updateGhosts + var showGhost, isAllDay, originalDay, currentDay, wasOtherBlock, + start, duration, durationLeft, maxDuration, enableTransition; + + showGhost = false; + enableTransition = function() { + iElement.removeClass('sg-event--notransition'); + }; + + if (Calendar.$view && Calendar.$view.type == scrollViewCtrl.type) { + // The view of the dragging block is the scrolling view of this ghost block + + isAllDay = scope.block.component.c_isallday; + originalDay = scope.block.pointerHandler.originalEventCoordinates.dayNumber; + currentDay = scope.block.pointerHandler.currentEventCoordinates.dayNumber; + start = scope.block.pointerHandler.currentEventCoordinates.start; + durationLeft = scope.block.pointerHandler.currentEventCoordinates.duration; + maxDuration = CalendarSettings.EventDragDayLength - start; + + if (angular.isUndefined(durationLeft)) + return; + + duration = durationLeft; + if (duration > maxDuration) + duration = maxDuration; + + delete scope.startHour; + delete scope.endHour; + + if (currentDay > -1 && currentDay == calendarDayCtrl.dayNumber) { + // This ghost block (day) is the first of the dragging event + showGhost = true; + if (!isAllDay) { + // Show start hour and set the vertical position + scope.startHour = getStartTime(start); + wasOtherBlock = parseInt(iElement.css('top')) === 0; + if (wasOtherBlock) + iElement.addClass('sg-event--notransition'); + iElement.css('top', (start * Calendar.$view.quarterHeight) + 'px'); + iElement.css('height', (duration * Calendar.$view.quarterHeight) + 'px'); + if (wasOtherBlock) + $timeout(enableTransition); + } + iElement.removeClass('fg-folder' + scope.block.component.pid); + iElement.removeClass('sg-event--ghost--last'); + iElement.addClass('sg-event--ghost--first'); + } + + durationLeft -= duration; + currentDay++; + + // Search a subsequent block that matches the current ghost's day + while (!showGhost && durationLeft && currentDay <= calendarDayCtrl.dayNumber) { + duration = durationLeft; + if (duration > CalendarSettings.EventDragDayLength) + duration = CalendarSettings.EventDragDayLength; + if (currentDay > -1 && currentDay == calendarDayCtrl.dayNumber) { + // The dragging event overlaps this current ghost's day + showGhost = true; + if (!isAllDay) { + wasOtherBlock = parseInt(iElement.css('top')) !== 0; + if (wasOtherBlock) + iElement.addClass('sg-event--notransition'); + // Set the height + iElement.css('top', '0px'); + iElement.css('height', (duration * Calendar.$view.quarterHeight) + 'px'); + if (wasOtherBlock) + $timeout(enableTransition); + } + iElement.removeClass('sg-event--ghost--first'); + iElement.removeClass('sg-event--ghost--last'); + // Trick for all-day events: set the foreground color to the background color so the event's title + // is not visible but the div size remains identical. + iElement.addClass('fg-folder' + scope.block.component.pid); + } + durationLeft -= duration; + currentDay++; + start = 0; + } + if (!durationLeft) { + // Reached last ghost block + if (isAllDay) { + iElement.addClass('sg-event--ghost--last'); + } + else { + // Set the end date + scope.endHour = getEndTime(start, duration); + } + } + } + + if (showGhost) + iElement.removeClass('ng-hide'); + else + iElement.addClass('ng-hide'); + } + + function quartersToHM(quarters) { + var minutes, hours, mins; + + minutes = quarters * 15; + hours = Math.floor(minutes / 60); + if (hours < 10) + hours = "0" + hours; + mins = minutes % 60; + if (mins < 10) + mins = "0" + mins; + + return "" + hours + ":" + mins; + } + + function getStartTime(start) { + return quartersToHM(start); + } + + function getEndTime(start, duration) { + var end = (start + duration) % CalendarSettings.EventDragDayLength; + return quartersToHM(end); + } + } + } + + angular + .module('SOGo.SchedulerUI') + .directive('sgCalendarDayBlockGhost', sgCalendarDayBlockGhost); +})();