mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-01-03 04:29:28 +01:00
Smarter updates for recurring events, to avoid refreshing more than needed.
This commit is contained in:
parent
c4cfb8a8c0
commit
72991fc007
@ -673,10 +673,62 @@ class calendar_ui
|
|||||||
$sidebox->exec('calendar.calendar_ui.sidebox_etemplate', $content, $sel_options, $readonlys);
|
$sidebox->exec('calendar.calendar_ui.sidebox_etemplate', $content, $sel_options, $readonlys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send updated event information to the client via ajax
|
||||||
|
*
|
||||||
|
* This allows to pass only changed information for a single (recurring) event
|
||||||
|
* and update the UI without a refreshing any more than needed. If adding,
|
||||||
|
* a notification via egw_framework::refresh_opener() is still needed but
|
||||||
|
* edits, updates and deletes will be automatic.
|
||||||
|
* If the event is recurring, we send the next month's worth of recurrences
|
||||||
|
* for lack of a better way to determine how much to send.
|
||||||
|
*
|
||||||
|
* @param int $event_id
|
||||||
|
* @param egw_time $recurrence_date
|
||||||
|
*/
|
||||||
|
public function update_client($event_id, egw_time $recurrence_date = null)
|
||||||
|
{
|
||||||
|
// Directly update stored data.
|
||||||
|
// Make sure we have the whole event
|
||||||
|
$event = $this->bo->read($event_id, $recurrence_date);
|
||||||
|
$response = egw_json_response::get();
|
||||||
|
|
||||||
|
if(!$event)
|
||||||
|
{
|
||||||
|
// Sending null will trigger a removal
|
||||||
|
$response->call('egw.dataStoreUID','calendar::'.$event_id,null);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$event['recur_type'] || $recurrence_date)
|
||||||
|
{
|
||||||
|
$this->to_client($event);
|
||||||
|
$response->call('egw.dataStoreUID','calendar::'.$event['row_id'],$event);
|
||||||
|
}
|
||||||
|
// If it's recurring, try to send the next month or so
|
||||||
|
else if($event['recur_type'] )
|
||||||
|
{
|
||||||
|
$this_month = new egw_time('next month');
|
||||||
|
$rrule = calendar_rrule::event2rrule($event, true);
|
||||||
|
$rrule->rewind();
|
||||||
|
do
|
||||||
|
{
|
||||||
|
$occurrence = $rrule->current();
|
||||||
|
$converted = $this->bo->read($event['id'], $occurrence);
|
||||||
|
$this->to_client($converted);
|
||||||
|
$response->call('egw.dataStoreUID','calendar::'.$converted['row_id'],$converted);
|
||||||
|
$rrule->next();
|
||||||
|
}
|
||||||
|
while ($rrule->valid() && $occurrence <= $this_month );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare an array of event information for sending to the client
|
* Prepare an array of event information for sending to the client
|
||||||
*
|
*
|
||||||
* This involves changing timestamps into strings with timezone
|
* This involves changing timestamps into strings with timezone so javascript
|
||||||
|
* does not change them, and making sure we have everything the client needs
|
||||||
|
* for proper display.
|
||||||
*
|
*
|
||||||
* @param type $event
|
* @param type $event
|
||||||
*/
|
*/
|
||||||
|
@ -1013,14 +1013,7 @@ class calendar_uiforms extends calendar_ui
|
|||||||
$response = egw_json_response::get();
|
$response = egw_json_response::get();
|
||||||
if($response && !$content['id'] && $event['id'])
|
if($response && !$content['id'] && $event['id'])
|
||||||
{
|
{
|
||||||
// Directly update stored data.
|
$this->update_client($event['id']);
|
||||||
// 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 (in_array($button,array('cancel','save','delete','delete_exceptions','delete_keep_exceptions')) && $noerror)
|
||||||
{
|
{
|
||||||
@ -2843,24 +2836,14 @@ class calendar_uiforms extends calendar_ui
|
|||||||
$message = false;
|
$message = false;
|
||||||
$conflicts=$this->bo->update($event,false, true, false, true, $message);
|
$conflicts=$this->bo->update($event,false, true, false, true, $message);
|
||||||
|
|
||||||
|
$this->update_client($event['id'],$d);
|
||||||
$response = egw_json_response::get();
|
$response = egw_json_response::get();
|
||||||
if(!is_array($conflicts) && $conflicts)
|
if(!is_array($conflicts) && $conflicts)
|
||||||
{
|
{
|
||||||
if(is_int($conflicts))
|
if(is_int($conflicts))
|
||||||
{
|
{
|
||||||
$event['id'] = $conflicts;
|
$event['id'] = $conflicts;
|
||||||
}
|
$response->call('egw.refresh', '','calendar',$event['id'],'add');
|
||||||
if(!$event['recur_type'] && !$old_event['recur_type'])
|
|
||||||
{
|
|
||||||
// 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
|
|
||||||
{
|
|
||||||
$response->call('egw.refresh', '','calendar',$event['id'],'edit');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ($conflicts)
|
else if ($conflicts)
|
||||||
@ -2879,6 +2862,7 @@ class calendar_uiforms extends calendar_ui
|
|||||||
{
|
{
|
||||||
$response->call('egw.message', implode('<br />', $message));
|
$response->call('egw.message', implode('<br />', $message));
|
||||||
}
|
}
|
||||||
|
if($event['id'] != $eventId ) $this->update_client($_eventId);
|
||||||
if ($status_reset_to_unknown)
|
if ($status_reset_to_unknown)
|
||||||
{
|
{
|
||||||
foreach((array)$event['participants'] as $uid => $status)
|
foreach((array)$event['participants'] as $uid => $status)
|
||||||
@ -2931,8 +2915,7 @@ class calendar_uiforms extends calendar_ui
|
|||||||
|
|
||||||
// Directly update stored data. If event is still visible, it will
|
// Directly update stored data. If event is still visible, it will
|
||||||
// be notified & update itself.
|
// be notified & update itself.
|
||||||
$this->to_client($event);
|
$this->update_client($_eventId);
|
||||||
egw_json_response::get()->call('egw.dataStoreUID','calendar::'.$event['id'].($date?':'.$date:''),$event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2940,8 +2923,8 @@ class calendar_uiforms extends calendar_ui
|
|||||||
*/
|
*/
|
||||||
public function ajax_delete($eventId)
|
public function ajax_delete($eventId)
|
||||||
{
|
{
|
||||||
list($eventId, $date) = explode(':',$eventId);
|
list($id, $date) = explode(':',$eventId);
|
||||||
$event=$this->bo->read($eventId);
|
$event=$this->bo->read($id);
|
||||||
$response = egw_json_response::get();
|
$response = egw_json_response::get();
|
||||||
|
|
||||||
if ($this->bo->delete($event['id'], (int)$date))
|
if ($this->bo->delete($event['id'], (int)$date))
|
||||||
@ -2958,7 +2941,7 @@ class calendar_uiforms extends calendar_ui
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$response->apply('egw.message', lang('Error'),'error');
|
$response->apply('egw.message', Array(lang('Error')),'error');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,14 +274,22 @@ app.classes.calendar = AppJS.extend(
|
|||||||
if(event && event.data && event.data.date || _type === 'delete')
|
if(event && event.data && event.data.date || _type === 'delete')
|
||||||
{
|
{
|
||||||
// Intelligent refresh without reloading everything
|
// Intelligent refresh without reloading everything
|
||||||
|
var recurrences = Object.keys(egw.dataSearchUIDs(new RegExp('^calendar::'+_id+':')))
|
||||||
|
var ids = event && event.data.recur_type && typeof _id === 'string' && _id.indexOf(':') < 0 || recurrences.length ?
|
||||||
|
recurrences :
|
||||||
|
['calendar::'+_id];
|
||||||
|
|
||||||
if(_type === 'delete')
|
if(_type === 'delete')
|
||||||
{
|
{
|
||||||
egw.dataStoreUID('calendar::'+_id, null);
|
for(var i in ids)
|
||||||
|
{
|
||||||
|
egw.dataStoreUID(ids[i], null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Updates are handled by events themselves through egw.data
|
// Updates are handled by events themselves through egw.data
|
||||||
else if (_type !== 'update')
|
else if (_type !== 'update')
|
||||||
{
|
{
|
||||||
this._update_events(this.state, ['calendar::'+_id]);
|
this._update_events(this.state, ids);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -796,15 +796,15 @@ var et2_calendar_event = et2_valueWidget.extend([et2_IDetachedDOM],
|
|||||||
// Get the top level element - timegrid or so
|
// Get the top level element - timegrid or so
|
||||||
var objectManager = this.getParent().getParent()._actionObject ||
|
var objectManager = this.getParent().getParent()._actionObject ||
|
||||||
egw_getAppObjectManager(true).getObjectById(this._parent._parent._parent.id) || egw_getAppObjectManager(true);
|
egw_getAppObjectManager(true).getObjectById(this._parent._parent._parent.id) || egw_getAppObjectManager(true);
|
||||||
this._actionObject = objectManager.getObjectById('calendar::'+this.options.value.id);
|
this._actionObject = objectManager.getObjectById('calendar::'+this.options.value.row_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._actionObject == null) {
|
if (this._actionObject == null) {
|
||||||
// Add a new container to the object manager which will hold the widget
|
// Add a new container to the object manager which will hold the widget
|
||||||
// objects
|
// objects
|
||||||
this._actionObject = objectManager.insertObject(false, new egwActionObject(
|
this._actionObject = objectManager.insertObject(false, new egwActionObject(
|
||||||
'calendar::'+this.options.value.id, objectManager, new et2_event_action_object_impl(this,this.getDOMNode()),
|
'calendar::'+this.options.value.row_id, objectManager, new et2_event_action_object_impl(this,this.getDOMNode()),
|
||||||
this._actionManager || objectManager.manager.getActionById(this.options.value.id) || objectManager.manager
|
this._actionManager || objectManager.manager.getActionById(this.options.value.row_id) || objectManager.manager
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user