2015-11-06 21:12:24 +01:00
|
|
|
/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
|
|
|
|
(function() {
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
/*
|
|
|
|
* sgDraggableCalendarBlock - Make an element draggable
|
|
|
|
* @memberof SOGo.SchedulerUI
|
|
|
|
* @restrict class or attribute
|
|
|
|
*
|
|
|
|
* @example:
|
|
|
|
|
|
|
|
<div class="sg-draggable-calendar-block"/>
|
|
|
|
*/
|
2016-01-26 13:20:02 +01:00
|
|
|
sgDraggableCalendarBlock.$inject = ['$rootScope', '$timeout', '$log', 'Preferences', 'Calendar', 'CalendarSettings', 'Component'];
|
|
|
|
function sgDraggableCalendarBlock($rootScope, $timeout, $log, Preferences, Calendar, CalendarSettings, Component) {
|
2015-11-06 21:12:24 +01:00
|
|
|
return {
|
|
|
|
restrict: 'CA',
|
|
|
|
require: '^sgCalendarDay',
|
|
|
|
link: link
|
|
|
|
};
|
|
|
|
|
|
|
|
function link(scope, element, attrs, calendarDayCtrl) {
|
2015-11-26 19:31:26 +01:00
|
|
|
if (scope.block) {
|
2016-08-04 20:25:29 +02:00
|
|
|
if (scope.block.component.editable && !scope.block.userState) {
|
2015-11-26 19:31:26 +01:00
|
|
|
// Add dragging grips to existing event block
|
|
|
|
initGrips();
|
2015-12-10 02:13:19 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
element.removeClass('sg-draggable-calendar-block');
|
2015-11-26 19:31:26 +01:00
|
|
|
return;
|
2015-12-10 02:13:19 +01:00
|
|
|
}
|
2015-11-26 19:31:26 +01:00
|
|
|
}
|
2015-11-06 21:12:24 +01:00
|
|
|
|
|
|
|
// Start dragging on mousedown
|
2015-11-09 18:15:16 +01:00
|
|
|
element.on('mousedown', onDragDetect);
|
2015-11-06 21:12:24 +01:00
|
|
|
|
2015-11-09 18:15:16 +01:00
|
|
|
// Deregister listeners when removing the element from the DOM
|
2015-11-06 21:12:24 +01:00
|
|
|
scope.$on('$destroy', function() {
|
2015-11-09 18:15:16 +01:00
|
|
|
element.off('mousedown', onDragDetect);
|
|
|
|
element.off('mousemove', onDrag);
|
2015-11-06 21:12:24 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
function initGrips() {
|
2016-05-06 20:14:45 +02:00
|
|
|
var component, dayIndex, blockIndex, isFirstBlock, isLastBlock,
|
2015-11-06 21:12:24 +01:00
|
|
|
dragGrip, leftGrip, rightGrip, topGrip, bottomGrip;
|
|
|
|
|
2016-09-30 15:31:01 +02:00
|
|
|
// Don't show grips for blocks of less than 45 minutes
|
|
|
|
if (scope.block.length < 3) return;
|
|
|
|
|
2015-11-06 21:12:24 +01:00
|
|
|
component = scope.block.component;
|
2016-05-06 20:14:45 +02:00
|
|
|
dayIndex = scope.block.dayIndex;
|
|
|
|
blockIndex = _.findIndex(component.blocks, ['dayIndex', dayIndex]);
|
2015-11-06 21:12:24 +01:00
|
|
|
isFirstBlock = (blockIndex === 0);
|
|
|
|
isLastBlock = (blockIndex === component.blocks.length - 1);
|
|
|
|
|
|
|
|
dragGrip = angular.element('<div class="dragGrip"></div>');
|
|
|
|
dragGrip.addClass('bdr-folder' + component.pid);
|
|
|
|
|
2015-11-20 19:30:26 +01:00
|
|
|
if (component.c_isallday ||
|
|
|
|
element[0].parentNode.tagName === 'SG-CALENDAR-MONTH-DAY') {
|
2015-11-06 21:12:24 +01:00
|
|
|
if (isFirstBlock) {
|
|
|
|
leftGrip = angular.element('<div class="dragGrip-left"></div>').append(dragGrip);
|
|
|
|
element.append(leftGrip);
|
|
|
|
}
|
|
|
|
if (isLastBlock) {
|
|
|
|
rightGrip = angular.element('<div class="dragGrip-right"></div>').append(dragGrip.clone());
|
|
|
|
element.append(rightGrip);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (isFirstBlock) {
|
|
|
|
topGrip = angular.element('<div class="dragGrip-top"></div>').append(dragGrip);
|
|
|
|
element.append(topGrip);
|
|
|
|
}
|
|
|
|
if (isLastBlock) {
|
|
|
|
bottomGrip = angular.element('<div class="dragGrip-bottom"></div>').append(dragGrip.clone());
|
|
|
|
element.append(bottomGrip);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-09 18:15:16 +01:00
|
|
|
function onDragDetect(ev) {
|
2017-03-10 21:05:46 +01:00
|
|
|
var dragMode, pointerHandler, hasVerticalScrollbar, rect, scrollableZone;
|
2015-11-06 21:12:24 +01:00
|
|
|
|
2015-11-20 21:36:24 +01:00
|
|
|
ev.stopPropagation();
|
|
|
|
|
2017-01-30 21:52:07 +01:00
|
|
|
hasVerticalScrollbar = ev.target.scrollHeight > ev.target.clientHeight + 1;
|
|
|
|
|
|
|
|
if (hasVerticalScrollbar) {
|
|
|
|
// Check if mouse click is inside scrollbar
|
|
|
|
rect = ev.target.getBoundingClientRect();
|
|
|
|
scrollableZone = rect.left + rect.width - 18;
|
|
|
|
if (ev.pageX > scrollableZone)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-11-06 21:12:24 +01:00
|
|
|
dragMode = 'move-event';
|
2016-05-06 20:14:45 +02:00
|
|
|
|
2015-11-06 21:12:24 +01:00
|
|
|
if (scope.block && scope.block.component) {
|
|
|
|
// Move or resize existing component
|
|
|
|
if (ev.target.className == 'dragGrip-top' ||
|
|
|
|
ev.target.className == 'dragGrip-left')
|
|
|
|
dragMode = 'change-start';
|
|
|
|
else if (ev.target.className == 'dragGrip-bottom' ||
|
|
|
|
ev.target.className == 'dragGrip-right' )
|
|
|
|
dragMode = 'change-end';
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Create new component from dragging
|
|
|
|
dragMode = 'change-end';
|
2015-11-09 18:15:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Initialize pointer handler
|
|
|
|
pointerHandler = new SOGoEventDragPointerHandler(dragMode);
|
|
|
|
pointerHandler.initFromEvent(ev);
|
|
|
|
|
|
|
|
// Update Component.$ghost
|
|
|
|
Component.$ghost.pointerHandler = pointerHandler;
|
|
|
|
|
|
|
|
// Stop dragging on the next "mouseup"
|
|
|
|
angular.element(document).one('mouseup', onDragEnd);
|
|
|
|
|
|
|
|
// Listen to mousemove and start dragging when mouse has moved from at least 3 pixels
|
|
|
|
angular.element(document).on('mousemove', onDrag);
|
|
|
|
}
|
|
|
|
|
|
|
|
function dragStart(ev) {
|
2016-03-09 15:18:21 +01:00
|
|
|
var block, eventType, isHourCell, isMonthly, startDate, newData, newComponent, pointerHandler, calendarData;
|
2015-11-09 18:15:16 +01:00
|
|
|
|
2015-11-20 21:36:24 +01:00
|
|
|
isHourCell = element.hasClass('clickableHourCell');
|
|
|
|
isMonthly = (element[0].parentNode.tagName == 'SG-CALENDAR-MONTH-DAY') ||
|
|
|
|
element.hasClass('clickableDayCell');
|
2015-11-09 18:15:16 +01:00
|
|
|
|
2015-12-16 04:55:02 +01:00
|
|
|
calendarData = calendarDayCtrl.calendarData();
|
|
|
|
|
2015-11-09 18:15:16 +01:00
|
|
|
if (scope.block && scope.block.component) {
|
|
|
|
// Move or resize existing component
|
|
|
|
block = scope.block;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Create new component from dragging
|
2016-01-26 13:20:02 +01:00
|
|
|
startDate = calendarDayCtrl.dayString.parseDate(Preferences.$mdDateLocaleProvider, '%Y-%m-%e');
|
2015-11-06 21:12:24 +01:00
|
|
|
newData = {
|
|
|
|
type: 'appointment',
|
2015-12-16 04:55:02 +01:00
|
|
|
pid: calendarData? calendarData.pid : Calendar.$defaultCalendar(),
|
2016-02-03 20:37:53 +01:00
|
|
|
summary: l('New Event'),
|
2015-11-20 21:36:24 +01:00
|
|
|
startDate: startDate,
|
|
|
|
isAllDay: isHourCell? 0 : 1
|
2015-11-06 21:12:24 +01:00
|
|
|
};
|
|
|
|
newComponent = new Component(newData);
|
|
|
|
block = {
|
|
|
|
component: newComponent,
|
2015-11-20 21:36:24 +01:00
|
|
|
dayNumber: calendarDayCtrl.dayNumber,
|
2015-11-06 21:12:24 +01:00
|
|
|
length: 0
|
|
|
|
};
|
|
|
|
block.component.blocks = [block];
|
|
|
|
}
|
|
|
|
|
2015-11-20 21:36:24 +01:00
|
|
|
// Determine event type
|
|
|
|
eventType = 'multiday';
|
|
|
|
if (isMonthly)
|
|
|
|
eventType = 'monthly';
|
|
|
|
else if (block.component.c_isallday)
|
|
|
|
eventType = 'multiday-allday';
|
|
|
|
|
2015-11-06 21:12:24 +01:00
|
|
|
// Mark all blocks as being dragged
|
|
|
|
_.forEach(block.component.blocks, function(b) {
|
|
|
|
b.dragging = true;
|
|
|
|
});
|
|
|
|
|
2015-11-09 18:15:16 +01:00
|
|
|
// Update pointer handler
|
|
|
|
pointerHandler = Component.$ghost.pointerHandler;
|
2015-11-06 21:12:24 +01:00
|
|
|
pointerHandler.prepareWithEventType(eventType);
|
|
|
|
pointerHandler.initFromBlock(block);
|
2015-12-16 04:55:02 +01:00
|
|
|
if (calendarData)
|
|
|
|
// When the day is associated to a calendar, the day number becomes the calendar index
|
|
|
|
// among the active calendars
|
|
|
|
pointerHandler.initFromCalendar(calendarData);
|
2015-11-06 21:12:24 +01:00
|
|
|
|
|
|
|
// Update Component.$ghost
|
|
|
|
Component.$ghost.component = block.component;
|
|
|
|
|
2016-03-09 15:18:21 +01:00
|
|
|
$log.debug('emit calendar:dragstart ' + eventType);
|
2015-11-09 18:15:16 +01:00
|
|
|
$rootScope.$emit('calendar:dragstart');
|
2015-11-06 21:12:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function onDrag(ev) {
|
|
|
|
var pointerHandler = Component.$ghost.pointerHandler;
|
|
|
|
|
|
|
|
// Update
|
|
|
|
// - currentCoordinates
|
|
|
|
// - currentViewCoordinates
|
|
|
|
// - currentEventCoordinates
|
|
|
|
$timeout(function() {
|
|
|
|
pointerHandler.updateFromEvent(ev);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function onDragEnd(ev) {
|
|
|
|
var block, pointer;
|
|
|
|
|
|
|
|
block = scope.block;
|
|
|
|
pointer = Component.$ghost.pointerHandler;
|
|
|
|
|
|
|
|
// Deregister mouse events
|
|
|
|
angular.element(document).off('mousemove', onDrag);
|
|
|
|
|
|
|
|
if (pointer.dragHasStarted) {
|
|
|
|
$rootScope.$emit('calendar:dragend');
|
|
|
|
pointer.dragHasStarted = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Unmark all blocks as being dragged
|
2015-12-16 04:55:02 +01:00
|
|
|
if (block && block.component)
|
2015-11-06 21:12:24 +01:00
|
|
|
_.forEach(block.component.blocks, function(b) {
|
|
|
|
b.dragging = false;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* SOGoCoordinates
|
|
|
|
*/
|
|
|
|
function SOGoCoordinates() {
|
|
|
|
}
|
|
|
|
|
|
|
|
SOGoCoordinates.prototype = {
|
|
|
|
x: -1,
|
|
|
|
y: -1,
|
|
|
|
|
|
|
|
getDelta: function SC_getDelta(otherCoordinates) {
|
|
|
|
var delta = new SOGoCoordinates();
|
|
|
|
delta.x = this.x - otherCoordinates.x;
|
|
|
|
delta.y = this.y - otherCoordinates.y;
|
|
|
|
|
2016-05-06 20:14:45 +02:00
|
|
|
if (Calendar.$view) {
|
|
|
|
delta.days = Calendar.$view.dayNumbers[this.x] - Calendar.$view.dayNumbers[otherCoordinates.x];
|
|
|
|
}
|
|
|
|
|
2015-11-06 21:12:24 +01:00
|
|
|
return delta;
|
|
|
|
},
|
|
|
|
|
|
|
|
getDistance: function SC_getDistance(otherCoordinates) {
|
|
|
|
var delta = this.getDelta(otherCoordinates);
|
|
|
|
|
|
|
|
return Math.sqrt(delta.x * delta.x + delta.y * delta.y);
|
|
|
|
},
|
|
|
|
|
|
|
|
clone: function SC_clone() {
|
|
|
|
var coordinates = new SOGoCoordinates();
|
|
|
|
coordinates.x = this.x;
|
|
|
|
coordinates.y = this.y;
|
|
|
|
|
|
|
|
return coordinates;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* SOGoEventDragEventCoordinates
|
|
|
|
*/
|
2015-11-20 19:30:26 +01:00
|
|
|
function SOGoEventDragEventCoordinates(eventType) {
|
|
|
|
this.setEventType(eventType);
|
2015-11-06 21:12:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
SOGoEventDragEventCoordinates.prototype = {
|
|
|
|
dayNumber: -1,
|
2016-05-06 20:14:45 +02:00
|
|
|
weekDay: -1,
|
2015-11-06 21:12:24 +01:00
|
|
|
start: -1,
|
|
|
|
duration: -1,
|
|
|
|
|
|
|
|
eventType: null,
|
|
|
|
|
|
|
|
setEventType: function(eventType) {
|
|
|
|
this.eventType = eventType;
|
|
|
|
},
|
|
|
|
|
|
|
|
initFromBlock: function(block) {
|
2016-05-06 20:14:45 +02:00
|
|
|
var prevDayNumber = -1;
|
|
|
|
|
2015-11-20 21:36:24 +01:00
|
|
|
if (this.eventType === 'monthly') {
|
2015-11-20 19:30:26 +01:00
|
|
|
this.start = 0;
|
2016-05-06 20:14:45 +02:00
|
|
|
this.duration = block.component.blocks.length * CalendarSettings.EventDragDayLength;
|
2015-11-20 21:36:24 +01:00
|
|
|
}
|
|
|
|
else {
|
2015-11-20 19:30:26 +01:00
|
|
|
// Get the start (first quarter) from the event's first block
|
2015-11-20 21:36:24 +01:00
|
|
|
// Compute overall length
|
2015-11-20 19:30:26 +01:00
|
|
|
this.start = block.component.blocks[0].start;
|
2016-03-09 15:18:21 +01:00
|
|
|
this.duration = _.sumBy(block.component.blocks, function(b) {
|
2016-05-06 20:14:45 +02:00
|
|
|
var delta, currentDayNumber;
|
|
|
|
|
|
|
|
currentDayNumber = b.dayNumber;
|
|
|
|
if (prevDayNumber < 0)
|
|
|
|
delta = 0;
|
|
|
|
else
|
|
|
|
delta = currentDayNumber - prevDayNumber - 1;
|
|
|
|
prevDayNumber = currentDayNumber;
|
|
|
|
|
|
|
|
return b.length + delta * CalendarSettings.EventDragDayLength;
|
2015-11-20 19:30:26 +01:00
|
|
|
});
|
2015-11-20 21:36:24 +01:00
|
|
|
}
|
2015-11-06 21:12:24 +01:00
|
|
|
},
|
|
|
|
|
2015-12-16 04:55:02 +01:00
|
|
|
initFromCalendar: function(calendarNumber) {
|
|
|
|
this.dayNumber = calendarNumber;
|
|
|
|
},
|
|
|
|
|
2015-11-06 21:12:24 +01:00
|
|
|
getDelta: function(otherCoordinates) {
|
|
|
|
var delta = new SOGoEventDragEventCoordinates();
|
|
|
|
delta.dayNumber = (this.dayNumber - otherCoordinates.dayNumber);
|
|
|
|
delta.start = (this.start - otherCoordinates.start);
|
|
|
|
delta.duration = (this.duration - otherCoordinates.duration);
|
|
|
|
|
|
|
|
return delta;
|
|
|
|
},
|
|
|
|
|
|
|
|
_quartersToHM: function(quarters) {
|
|
|
|
var minutes = quarters * 15;
|
|
|
|
var hours = Math.floor(minutes / 60);
|
|
|
|
if (hours < 10)
|
|
|
|
hours = "0" + hours;
|
|
|
|
var mins = minutes % 60;
|
|
|
|
if (mins < 10)
|
|
|
|
mins = "0" + mins;
|
|
|
|
|
|
|
|
return "" + hours + ":" + mins;
|
|
|
|
},
|
|
|
|
|
|
|
|
getStartTime: function() {
|
|
|
|
return this._quartersToHM(this.start);
|
|
|
|
},
|
|
|
|
|
|
|
|
getEndTime: function() {
|
|
|
|
var end = (this.start + this.duration) % CalendarSettings.EventDragDayLength;
|
|
|
|
return this._quartersToHM(end);
|
|
|
|
},
|
|
|
|
|
|
|
|
clone: function() {
|
|
|
|
var coordinates = new SOGoEventDragEventCoordinates();
|
|
|
|
coordinates.dayNumber = this.dayNumber;
|
|
|
|
coordinates.start = this.start;
|
|
|
|
coordinates.duration = this.duration;
|
|
|
|
|
|
|
|
return coordinates;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* SOGoEventDragPointerHandler
|
|
|
|
*/
|
|
|
|
function SOGoEventDragPointerHandler(dragMode) {
|
|
|
|
this.dragMode = dragMode;
|
|
|
|
}
|
|
|
|
|
|
|
|
SOGoEventDragPointerHandler.prototype = {
|
|
|
|
// Pointer absolute xy coordinates within page
|
|
|
|
originalCoordinates: null,
|
|
|
|
currentCoordinates: null,
|
|
|
|
|
2015-11-20 19:30:26 +01:00
|
|
|
// Pointer relative xy coordinates within view (row-column)
|
2015-11-06 21:12:24 +01:00
|
|
|
originalViewCoordinates: null,
|
|
|
|
currentViewCoordinates: null,
|
|
|
|
|
|
|
|
// Event start-duration coordinates
|
|
|
|
originalEventCoordinates: null,
|
|
|
|
currentEventCoordinates: null,
|
|
|
|
|
2015-12-16 04:55:02 +01:00
|
|
|
originalCalendar: null,
|
|
|
|
|
2015-11-06 21:12:24 +01:00
|
|
|
dragHasStarted: false,
|
|
|
|
|
|
|
|
// Function to return the day and quarter coordinates of the pointer cursor
|
|
|
|
// within the day view
|
|
|
|
getEventViewCoordinates: null,
|
|
|
|
|
|
|
|
initFromBlock: function SEDPH_initFromBlock(block) {
|
2015-11-20 19:30:26 +01:00
|
|
|
this.currentEventCoordinates = new SOGoEventDragEventCoordinates(this.eventType);
|
|
|
|
this.originalEventCoordinates = new SOGoEventDragEventCoordinates(this.eventType);
|
2015-11-06 21:12:24 +01:00
|
|
|
this.originalEventCoordinates.initFromBlock(block);
|
|
|
|
},
|
|
|
|
|
2015-11-09 18:15:16 +01:00
|
|
|
initFromEvent: function SEDPH_initFromEvent(event) {
|
|
|
|
this.currentCoordinates = new SOGoCoordinates();
|
|
|
|
this.updateFromEvent(event);
|
|
|
|
this.originalCoordinates = this.currentCoordinates.clone();
|
|
|
|
},
|
|
|
|
|
2015-12-16 04:55:02 +01:00
|
|
|
initFromCalendar: function SEDPH_initFromCalendar(calendarData) {
|
|
|
|
this.originalCalendar = calendarData;
|
|
|
|
this.currentEventCoordinates.initFromCalendar(calendarData.index);
|
|
|
|
this.originalEventCoordinates.initFromCalendar(calendarData.index);
|
|
|
|
},
|
|
|
|
|
2015-11-06 21:12:24 +01:00
|
|
|
// Method continuously called while dragging
|
|
|
|
updateFromEvent: function SEDPH_updateFromEvent(event) {
|
|
|
|
// Event here is a DOM event, not a calendar event!
|
|
|
|
this.currentCoordinates.x = event.pageX;
|
|
|
|
this.currentCoordinates.y = event.pageY;
|
|
|
|
|
|
|
|
// From SOGoEventDragGhostController.updateFromPointerHandler
|
|
|
|
if (this.dragHasStarted && Calendar.$view) {
|
|
|
|
var newEventCoordinates = this.getEventViewCoordinates(Calendar.$view);
|
|
|
|
if (!this.originalViewCoordinates) {
|
|
|
|
this.originalViewCoordinates = this.getEventViewCoordinates(Calendar.$view, this.originalCoordinates);
|
2015-11-09 18:15:16 +01:00
|
|
|
if (Component.$ghost.component.isNew) {
|
|
|
|
this.setTimeFromQuarters(Component.$ghost.component.start, this.originalViewCoordinates.y);
|
|
|
|
$log.debug('new event start date ' + Component.$ghost.component.start);
|
|
|
|
}
|
2015-11-06 21:12:24 +01:00
|
|
|
}
|
|
|
|
if (!this.currentViewCoordinates ||
|
|
|
|
!newEventCoordinates ||
|
|
|
|
newEventCoordinates.x != this.currentViewCoordinates.x ||
|
|
|
|
newEventCoordinates.y != this.currentViewCoordinates.y) {
|
|
|
|
this.currentViewCoordinates = newEventCoordinates;
|
|
|
|
if (this.originalViewCoordinates) {
|
|
|
|
if (!newEventCoordinates) {
|
|
|
|
this.currentViewCoordinates = this.originalViewCoordinates.clone();
|
|
|
|
}
|
|
|
|
this.updateEventCoordinates();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (this.originalCoordinates &&
|
|
|
|
this.currentCoordinates &&
|
|
|
|
!this.dragHasStarted) {
|
|
|
|
var distance = this.getDistance();
|
|
|
|
if (distance > 3) {
|
|
|
|
this.dragHasStarted = true;
|
2015-11-09 18:15:16 +01:00
|
|
|
dragStart(event);
|
2015-11-06 21:12:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
// SOGoEventDragGhostController._updateCoordinates
|
|
|
|
// Extend this.currentCoordinates with start, dayNumber and duration
|
|
|
|
updateEventCoordinates: function SEDGC__updateCoordinates() {
|
|
|
|
var newDuration;
|
|
|
|
|
|
|
|
// Compute delta wrt to position of mouse at dragstart on the day/quarter grid
|
|
|
|
var delta = this.currentViewCoordinates.getDelta(this.originalViewCoordinates);
|
2016-05-06 20:14:45 +02:00
|
|
|
var deltaQuarters = delta.days * CalendarSettings.EventDragDayLength + delta.y;
|
2015-11-06 21:12:24 +01:00
|
|
|
$log.debug('quarters delta ' + deltaQuarters);
|
|
|
|
|
2015-11-20 19:30:26 +01:00
|
|
|
if (angular.isUndefined(this.originalEventCoordinates.start)) {
|
2016-05-06 20:14:45 +02:00
|
|
|
// Creating new appointment from DnD
|
|
|
|
this.originalEventCoordinates.dayNumber = Calendar.$view.dayNumbers[this.originalViewCoordinates.x];
|
2015-11-09 18:15:16 +01:00
|
|
|
this.originalEventCoordinates.start = this.originalViewCoordinates.y;
|
|
|
|
}
|
2016-05-06 20:14:45 +02:00
|
|
|
else if (this.originalEventCoordinates.dayNumber < 0) {
|
|
|
|
this.originalEventCoordinates.dayNumber = Calendar.$view.dayNumbers[scope.block.component.blocks[0].dayIndex];
|
|
|
|
}
|
2015-11-06 21:12:24 +01:00
|
|
|
// if (currentView == "multicolumndayview")
|
|
|
|
// this._updateMulticolumnViewDayNumber_SEDGC();
|
|
|
|
// else
|
|
|
|
this.currentEventCoordinates.dayNumber = this.originalEventCoordinates.dayNumber;
|
|
|
|
|
|
|
|
if (this.dragMode == "move-event") {
|
|
|
|
this.currentEventCoordinates.start = this.originalEventCoordinates.start + deltaQuarters;
|
|
|
|
this.currentEventCoordinates.duration = this.originalEventCoordinates.duration;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (this.dragMode == "change-start") {
|
|
|
|
newDuration = this.originalEventCoordinates.duration - deltaQuarters;
|
|
|
|
if (newDuration > 0) {
|
|
|
|
this.currentEventCoordinates.start = this.originalEventCoordinates.start + deltaQuarters;
|
|
|
|
this.currentEventCoordinates.duration = newDuration;
|
|
|
|
}
|
|
|
|
else if (newDuration < 0) {
|
|
|
|
this.currentEventCoordinates.start = (this.originalEventCoordinates.start + this.originalEventCoordinates.duration);
|
|
|
|
this.currentEventCoordinates.duration = -newDuration;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (this.dragMode == "change-end") {
|
|
|
|
newDuration = this.originalEventCoordinates.duration + deltaQuarters;
|
|
|
|
if (newDuration > 0) {
|
|
|
|
this.currentEventCoordinates.start = this.originalEventCoordinates.start;
|
|
|
|
this.currentEventCoordinates.duration = newDuration;
|
|
|
|
}
|
|
|
|
else if (newDuration < 0) {
|
|
|
|
this.currentEventCoordinates.start = this.originalEventCoordinates.start + newDuration;
|
|
|
|
this.currentEventCoordinates.duration = -newDuration;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var deltaDays;
|
|
|
|
if (this.currentEventCoordinates.start < 0) {
|
|
|
|
deltaDays = Math.ceil(-this.currentEventCoordinates.start / CalendarSettings.EventDragDayLength);
|
|
|
|
this.currentEventCoordinates.start += deltaDays * CalendarSettings.EventDragDayLength;
|
|
|
|
this.currentEventCoordinates.dayNumber -= deltaDays;
|
|
|
|
}
|
|
|
|
else if (this.currentEventCoordinates.start >= CalendarSettings.EventDragDayLength) {
|
|
|
|
deltaDays = Math.floor(this.currentEventCoordinates.start / CalendarSettings.EventDragDayLength);
|
|
|
|
this.currentEventCoordinates.start -= deltaDays * CalendarSettings.EventDragDayLength;
|
|
|
|
this.currentEventCoordinates.dayNumber += deltaDays;
|
|
|
|
}
|
2016-05-06 20:14:45 +02:00
|
|
|
|
2015-11-06 21:12:24 +01:00
|
|
|
$log.debug('event coordinates ' + JSON.stringify(this.currentEventCoordinates));
|
|
|
|
$rootScope.$emit('calendar:drag');
|
|
|
|
},
|
|
|
|
|
|
|
|
// SOGoEventDragPointerHandler.getContainerBasedCoordinates
|
|
|
|
getContainerBasedCoordinates: function SEDPH_getCBC(view, pointerCoordinates) {
|
|
|
|
var currentCoordinates = pointerCoordinates || this.currentCoordinates;
|
|
|
|
var coordinates = currentCoordinates.getDelta(view.coordinates);
|
|
|
|
var container = view.element;
|
|
|
|
|
|
|
|
if (coordinates.x < view.daysOffset || coordinates.x > container.clientWidth ||
|
|
|
|
coordinates.y < 0 || coordinates.y > container.clientHeight)
|
|
|
|
coordinates = null;
|
|
|
|
|
|
|
|
return coordinates;
|
|
|
|
},
|
|
|
|
|
|
|
|
prepareWithEventType: function SEDPH_prepareWithEventType(eventType) {
|
|
|
|
var methods = { "multiday": this.getEventMultiDayViewCoordinates,
|
|
|
|
"multiday-allday": this.getEventMultiDayAllDayViewCoordinates,
|
|
|
|
"monthly": this.getEventMonthlyViewCoordinates,
|
|
|
|
"unknown": null };
|
|
|
|
var method = methods[eventType];
|
|
|
|
this.eventType = eventType;
|
|
|
|
this.getEventViewCoordinates = method;
|
|
|
|
},
|
|
|
|
|
|
|
|
getEventMultiDayViewCoordinates: function SEDPH_gEMultiDayViewC(view, pointerCoordinates) {
|
|
|
|
/* x = day; y = quarter */
|
|
|
|
var coordinates = this.getEventMultiDayAllDayViewCoordinates(view, pointerCoordinates); // get the x coordinate
|
|
|
|
if (coordinates) {
|
|
|
|
var quarterHeight = view.quarterHeight;
|
|
|
|
var pxCoordinates = this.getContainerBasedCoordinates(view, pointerCoordinates);
|
|
|
|
pxCoordinates.y += view.element.scrollTop;
|
|
|
|
|
|
|
|
coordinates.y = Math.floor((pxCoordinates.y - CalendarSettings.EventDragHorizontalOffset) / quarterHeight);
|
|
|
|
var maxY = CalendarSettings.EventDragDayLength - 1;
|
|
|
|
if (coordinates.y < 0)
|
|
|
|
coordinates.y = 0;
|
|
|
|
else if (coordinates.y > maxY)
|
|
|
|
coordinates.y = maxY;
|
|
|
|
}
|
|
|
|
|
|
|
|
return coordinates;
|
|
|
|
},
|
|
|
|
getEventMultiDayAllDayViewCoordinates: function SEDPH_gEMultiDayADVC(view, pointerCoordinates) {
|
|
|
|
/* x = day; y = quarter */
|
|
|
|
var coordinates;
|
|
|
|
|
|
|
|
var pxCoordinates = this.getContainerBasedCoordinates(view, pointerCoordinates);
|
|
|
|
if (pxCoordinates) {
|
|
|
|
coordinates = new SOGoCoordinates();
|
|
|
|
|
|
|
|
var dayWidth = view.dayWidth;
|
|
|
|
var daysOffset = view.daysOffset;
|
|
|
|
|
|
|
|
coordinates.x = Math.floor((pxCoordinates.x - daysOffset) / dayWidth);
|
2015-12-16 04:55:02 +01:00
|
|
|
var minX = 0;
|
2015-11-06 21:12:24 +01:00
|
|
|
var maxX = Calendar.$view.maxX;
|
2015-12-16 04:55:02 +01:00
|
|
|
if (this.dragMode != 'move-event') {
|
|
|
|
var calendarData = calendarDayCtrl.calendarData();
|
|
|
|
if (calendarData)
|
|
|
|
// Resizing an event can't span a different day when in multicolumn view
|
|
|
|
minX = maxX = calendarData.index;
|
|
|
|
}
|
|
|
|
if (coordinates.x < minX)
|
|
|
|
coordinates.x = minX;
|
2015-11-06 21:12:24 +01:00
|
|
|
else if (coordinates.x > maxX)
|
|
|
|
coordinates.x = maxX;
|
|
|
|
coordinates.y = 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
coordinates = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return coordinates;
|
|
|
|
},
|
2015-11-20 19:30:26 +01:00
|
|
|
getEventMonthlyViewCoordinates: function SEDPH_gEMonthlyViewC(view, pointerCoordinates) {
|
|
|
|
/* x = day; y = quarter */
|
|
|
|
var coordinates;
|
|
|
|
|
|
|
|
var pxCoordinates = this.getContainerBasedCoordinates(view, pointerCoordinates);
|
|
|
|
if (pxCoordinates) {
|
|
|
|
coordinates = new SOGoCoordinates();
|
|
|
|
|
2016-05-06 21:45:42 +02:00
|
|
|
var maxX = view.maxX;
|
2015-11-20 19:30:26 +01:00
|
|
|
var daysTopOffset = 0;
|
|
|
|
var dayWidth = view.dayWidth;
|
|
|
|
var daysOffset = view.daysOffset;
|
|
|
|
var dayHeight = view.dayHeight;
|
|
|
|
var daysY = Math.floor((pxCoordinates.y - daysTopOffset) / dayHeight);
|
|
|
|
if (daysY < 0)
|
|
|
|
daysY = 0;
|
|
|
|
|
|
|
|
coordinates.x = Math.floor((pxCoordinates.x - daysOffset) / dayWidth);
|
|
|
|
if (coordinates.x < 0)
|
|
|
|
coordinates.x = 0;
|
2016-05-06 21:45:42 +02:00
|
|
|
else if (coordinates.x > maxX)
|
|
|
|
coordinates.x = maxX;
|
|
|
|
coordinates.x += (maxX + 1) * daysY;
|
2015-11-20 19:30:26 +01:00
|
|
|
coordinates.y = 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
coordinates = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return coordinates;
|
|
|
|
},
|
2015-11-06 21:12:24 +01:00
|
|
|
|
|
|
|
getDistance: function SEDPH_getDistance() {
|
|
|
|
return this.currentCoordinates.getDistance(this.originalCoordinates);
|
2015-11-09 18:15:16 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
setTimeFromQuarters: function SEDPH_setTimeFromQuarters(date, quarters) {
|
|
|
|
var hours, minutes;
|
|
|
|
hours = Math.floor(quarters / 4);
|
|
|
|
minutes = (quarters % 4) * 15;
|
|
|
|
date.setHours(hours, minutes);
|
2015-11-06 21:12:24 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
angular
|
|
|
|
.module('SOGo.SchedulerUI')
|
|
|
|
.directive('sgDraggableCalendarBlock', sgDraggableCalendarBlock);
|
|
|
|
})();
|
|
|
|
|