More intelligent updating to avoid having to re-do a whole week when one event is added

This commit is contained in:
Nathan Gray 2016-01-14 15:46:55 +00:00
parent 3eaca151a3
commit 6b78eb9d36
3 changed files with 158 additions and 100 deletions

View File

@ -895,7 +895,7 @@ class calendar_uiforms extends calendar_ui
}
$response = egw_json_response::get();
if($response && $update_type == 'update')
if($response && $update_type != 'delete')
{
// Directly update stored data. If event is still visible, it will
// be notified & update itself.
@ -1007,6 +1007,19 @@ class calendar_uiforms extends calendar_ui
{
$msg .= ($msg ? "\n" : '').implode("\n", $notification_errors);
}
// New event, send data before updating so it's there
$response = egw_json_response::get();
if($response && !$content['id'])
{
// Directly update stored data.
// Make sure we have the whole event, not just form data
$event = $this->bo->read($event['id']);
// Copy, so as to not change things for subsequent processing
$converted = $event;
$this->to_client($converted);
$response->call('egw.dataStoreUID','calendar::'.$converted['row_id'],$converted);
}
if (in_array($button,array('cancel','save','delete','delete_exceptions','delete_keep_exceptions')) && $noerror)
{
if ($content['lock_token']) // remove an existing lock
@ -2851,6 +2864,7 @@ class calendar_uiforms extends calendar_ui
// Directly update stored data. If event is still visible, it will
// be notified & update itself.
$this->to_client($event);
error_log(__METHOD__ . ':' . __LINE__ . ' updated calendar::'.$converted['id']);
$response->call('egw.dataStoreUID','calendar::'.$event['id'].($date?':'.$date:''),$event);
}
else

View File

@ -271,42 +271,17 @@ app.classes.calendar = AppJS.extend(
{
event = egw.dataGetUIDdata('calendar::'+_id);
}
if(_type != 'edit' && event && event.data && event.data.date &&
// Cannot handle adding recurring events easily
!(_type == 'add' && event.data.recur_type)
)
if(event && event.data && event.data.date || _type === 'delete')
{
var multiple_owner = typeof this.state.owner != 'string' &&
this.state.owner.length > 1 &&
(this.state.view == 'day' && this.state.owner.length < parseInt(this.egw.preference('day_consolidate','calendar')) ||
this.state.view == 'week' && this.state.owner.length < parseInt(this.egw.preference('week_consolidate','calendar')));
// Make sure it's a string
if(_id) _id = ''+_id;
for(var i = 0; i < this.state.owner.length; i++)
{
var owner = multiple_owner ? this.state.owner[i] : this.state.owner
var new_cache_id = app.classes.calendar._daywise_cache_id(event.data.date, owner)
var daywise = egw.dataGetUIDdata(new_cache_id);
daywise = daywise && daywise.data != null ? daywise.data : [];
if(daywise.indexOf(_id) >= 0 && (_type === 'delete' ||
// Make sure we only update the calendars of those actually in the event
multiple_owner && typeof event.data.participants[owner] == 'undefined'))
{
daywise.splice(daywise.indexOf(_id),1);
}
else if (daywise.indexOf(_id) < 0 && (
!multiple_owner || typeof event.data.participants[owner] !== 'undefined'))
{
daywise.push(_id);
}
// Intelligent refresh without reloading everything
if(_type === 'delete')
{
egw.dataStoreUID('calendar::'+_id, null);
}
egw.dataStoreUID(new_cache_id,daywise);
if(!multiple_owner) break;
// Updates are handled by events themselves through egw.data
else if (_type !== 'update')
{
this._update_events(this.state, ['calendar::'+_id]);
}
return false;
}
@ -2741,17 +2716,59 @@ app.classes.calendar = AppJS.extend(
}
}
}
if(data.order && data.total)
{
this._update_events(state, data.order);
}
// More rows?
if(data.order.length + start < data.total)
{
// Wait a bit, let UI do something.
window.setTimeout( function() {
app.calendar._fetch_data(state, instance, start + data.order.length);
}, 100);
}
// Hide AJAX loader
framework.applications.calendar.sidemenuEntry.hideAjaxLoader();
}, this,null
);
},
/**
* We have a list of calendar UIDs of events that need updating.
*
* The event data should already be in the egw.data cache, we just need to
* figure out where they need to go, and update the needed parent objects.
*
* Already existing events will have already been updated by egw.data
* callbacks.
*
* @param {Object} state Current state for update, used to determine what to update
*
*/
_update_events: function(state, data) {
var updated_days = {};
// Events can span for longer than we are showing
var first = new Date(state.first);
var last = new Date(state.last);
var bounds = {
first: ''+first.getUTCFullYear() + sprintf('%02d',first.getUTCMonth()+1) + sprintf('%02d',first.getUTCDate()),
last: ''+last.getUTCFullYear() + sprintf('%02d',last.getUTCMonth()+1) + sprintf('%02d',last.getUTCDate())
};
// Seperate owners, or consolidated?
var multiple_owner = typeof state.owner != 'string' &&
state.owner.length > 1 &&
(state.view == 'day' && state.owner.length < parseInt(this.egw.preference('day_consolidate','calendar')) ||
state.view == 'week' && state.owner.length < parseInt(this.egw.preference('week_consolidate','calendar')));
for(var i = 0; i < data.order.length && data.total; i++)
for(var i = 0; i < data.length; i++)
{
var record = this.egw.dataGetUIDdata(data.order[i]);
var record = this.egw.dataGetUIDdata(data[i]);
if(record && record.data)
{
if(typeof updated_days[record.data.date] === 'undefined')
@ -2805,24 +2822,35 @@ app.classes.calendar = AppJS.extend(
}
}
}
// Now we know which days changed, so we pass it on
for(var day in updated_days)
{
this.egw.dataStoreUID(app.classes.calendar._daywise_cache_id(day, state.owner), updated_days[day]);
}
// More rows?
if(data.order.length + start < data.total)
// Might be split by user, so we have to check that too
for(var i = 0; i < state.owner.length; i++)
{
// Wait a bit, let UI do something.
window.setTimeout( function() {
app.calendar._fetch_data(state, instance, start + data.order.length);
}, 100);
var owner = multiple_owner ? state.owner[i] : state.owner;
var cache_id = app.classes.calendar._daywise_cache_id(day, owner);
if(egw.dataHasUID(cache_id))
{
// Don't lose any existing data, just append
var c = egw.dataGetUIDdata(cache_id);
if(c.data && c.data !== null)
{
// Avoid duplicates
var data = c.data.concat(updated_days[day]).filter(function(value, index, self) {
return self.indexOf(value) === index;
});
this.egw.dataStoreUID(cache_id,data);
}
}
else
{
this.egw.dataStoreUID(cache_id, updated_days[day]);
}
if(!multiple_owner) break;
}
}
// Hide AJAX loader
framework.applications.calendar.sidemenuEntry.hideAjaxLoader();
}, this,null
);
},
/**

View File

@ -637,6 +637,22 @@ var et2_calendar_event = et2_valueWidget.extend([et2_IDetachedDOM],
return false;
}
// Also check participants against owner
if(event.participants && this._parent.options.owner)
{
var match = false;
for(var id in event.participants)
{
if(this._parent.options.owner == id ||
this._parent.options.owner.indexOf &&
this._parent.options.owner.indexOf(id) >= 0)
{
match = true;
}
}
if(!match) return false;
}
// Simple, same day
if(this.options.value.date && event.date == this.options.value.date)
{