diff --git a/calendar/inc/class.calendar_uilist.inc.php b/calendar/inc/class.calendar_uilist.inc.php index c6847284b1..4e5853ac83 100644 --- a/calendar/inc/class.calendar_uilist.inc.php +++ b/calendar/inc/class.calendar_uilist.inc.php @@ -454,7 +454,7 @@ class calendar_uilist extends calendar_ui elseif ($event['recur_type'] != MCAL_RECUR_NONE) { $event['edit_link'] = "edit_series({$event['id']}, {$event['start']});return false;"; - $event['app_id'] .= ':'.($event['recur_date'] ? $event['recur_date'] : $event['start']); + $event['app_id'] .= ':'.egw_time::to($event['recur_date'] ? $event['recur_date'] : $event['start'],'ts'); } else { diff --git a/calendar/js/app.js b/calendar/js/app.js index fd11d60074..088b5f325e 100644 --- a/calendar/js/app.js +++ b/calendar/js/app.js @@ -2998,6 +2998,9 @@ app.classes.calendar = AppJS.extend( var nm = _et2.widgetContainer.getWidgetById('nm'); if(nm) { + // Avoid unwanted refresh immediately after load + nm.controller._grid.doInvalidate = false; + nm.set_startdate = jQuery.proxy(function(date) { this.state.first = this.date.toString(new Date(date)); },this); diff --git a/calendar/js/et2_widget_event.js b/calendar/js/et2_widget_event.js index 05b297b167..eab6952afe 100644 --- a/calendar/js/et2_widget_event.js +++ b/calendar/js/et2_widget_event.js @@ -137,14 +137,11 @@ var et2_calendar_event = et2_valueWidget.extend([et2_IDetachedDOM], this.options.value = _value; // Register for updates - var app_id = this.options.value.id + (this.options.value.recur_type ? ':'+ - (this.options.value.recur_date ? this.options.value.recur_date : this.options.value.start) : ''); - egw.dataRegisterUID('calendar::'+app_id, function(event) { + var app_id = this.options.value.app_id; + egw.dataRegisterUID('calendar::'+app_id, function _UID_callback(event) { // Make sure id is a string - if(event.id) - { - event.id = ''+event.id; - } + this._values_check(event); + // Check for changing days in the grid view if(!this._sameday_check(event)) { @@ -155,7 +152,11 @@ var et2_calendar_event = et2_valueWidget.extend([et2_IDetachedDOM], // Copy to avoid changes, which may cause nm problems this.options.value = jQuery.extend({},event); - this.options.value.date = this._parent.options.date; + + if(this._parent.options.date) + { + this.options.value.date = this._parent.options.date; + } // Let parent position this._parent.position_event(this); @@ -487,7 +488,9 @@ var et2_calendar_event = et2_valueWidget.extend([et2_IDetachedDOM], } else { - var duration = event.end_m - event.start_m; + var duration = event.multiday ? + (event.end - event.start) / 60000 : + (event.end_m - event.start_m); if (event.end_m === 24*60-1) ++duration; duration = Math.floor(duration/60) + this.egw().lang('h')+(duration%60 ? duration%60 : ''); @@ -507,6 +510,47 @@ var et2_calendar_event = et2_valueWidget.extend([et2_IDetachedDOM], return timespan; }, + /** + * Make sure event data has all proper values, and format them as expected + * @param {Object} event + */ + _values_check: function _values_check(event) + { + // Make sure ID is a string + if(event.id) + { + event.id = ''+event.id; + } + + // Use dates as objects + if(typeof event.start !== 'object') + { + this._parent.date_helper.set_value(event.start); + event.start = new Date(this._parent.date_helper.getValue()); + } + if(typeof event.end !== 'object') + { + this._parent.date_helper.set_value(event.end); + event.end = new Date(this._parent.date_helper.getValue()); + } + + // We need minutes for durations + if(typeof event.start_m === 'undefined') + { + event.start_m = event.start.getUTCHours() * 60 + event.start.getUTCMinutes(); + event.end_m = event.end.getUTCHours() * 60 + event.end.getUTCMinutes(); + } + if(typeof event.multiday === 'undefined') + { + event.multiday = (event.start.getUTCFullYear() !== event.end.getUTCFullYear() || + event.start.getUTCMonth() !== event.end.getUTCMonth() || + event.start.getUTCDate() != event.end.getUTCDate()); + } + if(!event.start.getUTCHours() && !event.start.getUTCMinutes() && event.end.getUTCHours() == 23 && event.end.getUTCMinutes() == 59) + { + event.whole_day_on_top = (event.non_blocking && event.non_blocking != '0'); + } + }, _sameday_check: function(event) { // Event somehow got orphaned, or deleted @@ -536,17 +580,21 @@ var et2_calendar_event = et2_valueWidget.extend([et2_IDetachedDOM], // Update daywise caches var new_cache_id = app.classes.calendar._daywise_cache_id(event.date,this._parent.options.owner); - var old_cache_id = app.classes.calendar._daywise_cache_id(this.options.value.date,this._parent.options.owner); var new_daywise = egw.dataGetUIDdata(new_cache_id); - var old_daywise = egw.dataGetUIDdata(old_cache_id); new_daywise = new_daywise ? new_daywise.data : []; - old_daywise = old_daywise ? old_daywise.data : []; + var old_cache_id = false; + if(this.options.value && this.options.value.date) + { + old_cache_id = app.classes.calendar._daywise_cache_id(this.options.value.date,this._parent.options.owner); + var old_daywise = egw.dataGetUIDdata(old_cache_id); + old_daywise = old_daywise ? old_daywise.data : []; + old_daywise.splice(old_daywise.indexOf(this.options.value.id),1); + egw.dataStoreUID(old_cache_id,old_daywise); + } if (new_daywise.indexOf(event.id) < 0) { new_daywise.push(event.id); } - old_daywise.splice(old_daywise.indexOf(this.options.value.id),1); - egw.dataStoreUID(old_cache_id,old_daywise); egw.dataStoreUID(new_cache_id,new_daywise); return false; diff --git a/calendar/js/et2_widget_planner.js b/calendar/js/et2_widget_planner.js index e3fd36a686..b0687efb36 100644 --- a/calendar/js/et2_widget_planner.js +++ b/calendar/js/et2_widget_planner.js @@ -684,7 +684,7 @@ var et2_calendar_planner = et2_calendar_view.extend([et2_IDetachedDOM, et2_IResi invalidate: function(trigger) { // Busy - if(!this.doInvalidate || this.update_timer) return; + if(!this.doInvalidate) return; // Wait a bit to see if anything else changes, then re-draw the days if(this.update_timer !== null) diff --git a/calendar/js/et2_widget_planner_row.js b/calendar/js/et2_widget_planner_row.js index 1f59d07795..97c5963d70 100644 --- a/calendar/js/et2_widget_planner_row.js +++ b/calendar/js/et2_widget_planner_row.js @@ -291,7 +291,9 @@ var et2_calendar_planner_row = et2_valueWidget.extend([et2_IDetachedDOM], _spread_events: function() { // Keep it so we don't have to re-do it when the next event asks - if(this._cached_rows.length == this._children.length) + var cached_length = 0; + this._cached_rows.map(function(row) {cached_length+=row.length;}); + if(cached_length === this._children.length) { return this._cached_rows; } @@ -300,9 +302,13 @@ var et2_calendar_planner_row = et2_valueWidget.extend([et2_IDetachedDOM], var rows = []; var row_end = [0]; - var start = this.options.start_date; - var end = this.options.end_date; - + // Sort in chronological order, so earliest ones are at the top + this._children.sort(function(a,b) { + var start = new Date(a.options.value.start) - new Date(b.options.value.start); + var end = new Date(a.options.value.end) - new Date(b.options.value.end); + return start ? start : end; + }); + for(var n = 0; n < this._children.length; n++) { var event = this._children[n].options.value || false; @@ -318,7 +324,6 @@ var et2_calendar_planner_row = et2_valueWidget.extend([et2_IDetachedDOM], } if(typeof event['start_m'] === 'undefined') { - var day_start = event.start.valueOf() / 1000; var dst_check = new Date(event.start); dst_check.setUTCHours(12); @@ -343,6 +348,10 @@ var et2_calendar_planner_row = et2_valueWidget.extend([et2_IDetachedDOM], event['end_m'] = 24*60-1; event['multiday'] = true; } + if(!event.start.getUTCHours() && !event.start.getUTCMinutes() && event.end.getUTCHours() == 23 && event.end.getUTCMinutes() == 59) + { + event.whole_day_on_top = (event.non_blocking && event.non_blocking != '0'); + } } var event_start = new Date(event.start).valueOf();