mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-22 14:41:29 +01:00
* Calendar: Push updates
This commit is contained in:
parent
2c7b7052bc
commit
dc6a8e0977
@ -118,6 +118,7 @@ class calendar_boupdate extends calendar_bo
|
|||||||
*/
|
*/
|
||||||
function update(&$event,$ignore_conflicts=false,$touch_modified=true,$ignore_acl=false,$updateTS=true,&$messages=null, $skip_notification=false)
|
function update(&$event,$ignore_conflicts=false,$touch_modified=true,$ignore_acl=false,$updateTS=true,&$messages=null, $skip_notification=false)
|
||||||
{
|
{
|
||||||
|
$update_type = 'edit';
|
||||||
unset($updateTS); // ignored, as updating timestamps is required for sync!
|
unset($updateTS); // ignored, as updating timestamps is required for sync!
|
||||||
//error_log(__METHOD__."(".array2string($event).",$ignore_conflicts,$touch_modified,$ignore_acl)");
|
//error_log(__METHOD__."(".array2string($event).",$ignore_conflicts,$touch_modified,$ignore_acl)");
|
||||||
if (!is_array($messages)) $messages = $messages ? (array)$messages : array();
|
if (!is_array($messages)) $messages = $messages ? (array)$messages : array();
|
||||||
@ -150,6 +151,7 @@ class calendar_boupdate extends calendar_bo
|
|||||||
$status = calendar_so::combine_status($event['owner'] == $this->user ? 'A' : 'U', 1, 'CHAIR');
|
$status = calendar_so::combine_status($event['owner'] == $this->user ? 'A' : 'U', 1, 'CHAIR');
|
||||||
$event['participants'] = array($event['owner'] => $status);
|
$event['participants'] = array($event['owner'] => $status);
|
||||||
}
|
}
|
||||||
|
$update_type = 'add';
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if user has the permission to update / create the event
|
// check if user has the permission to update / create the event
|
||||||
@ -273,6 +275,7 @@ class calendar_boupdate extends calendar_bo
|
|||||||
{
|
{
|
||||||
// Restored, bring back links
|
// Restored, bring back links
|
||||||
Link::restore('calendar', $cal_id);
|
Link::restore('calendar', $cal_id);
|
||||||
|
$update_type = 'add';
|
||||||
}
|
}
|
||||||
if ($this->log_file)
|
if ($this->log_file)
|
||||||
{
|
{
|
||||||
@ -291,8 +294,8 @@ class calendar_boupdate extends calendar_bo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// notify the link-class about the update, as other apps may be subscribt to it
|
// notify the link-class about the update, as other apps may be subscribed to it
|
||||||
Link::notify_update('calendar',$cal_id,$event);
|
Link::notify_update('calendar',$cal_id,$event,$update_type);
|
||||||
|
|
||||||
return $cal_id;
|
return $cal_id;
|
||||||
}
|
}
|
||||||
@ -1777,7 +1780,10 @@ class calendar_boupdate extends calendar_bo
|
|||||||
{
|
{
|
||||||
$this->set_status($old_event, $userid, $status, $recur_date, true, false,$skip_notification);
|
$this->set_status($old_event, $userid, $status, $recur_date, true, false,$skip_notification);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// notify the link-class about the update, as other apps may be subscribed to it
|
||||||
|
Link::notify_update('calendar',$new_event['id'],$new_event,"update");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* deletes an event
|
* deletes an event
|
||||||
|
@ -68,6 +68,7 @@ class calendar_hooks
|
|||||||
'merge' => true,
|
'merge' => true,
|
||||||
'entry' => 'Event',
|
'entry' => 'Event',
|
||||||
'entries' => 'Events',
|
'entries' => 'Events',
|
||||||
|
'push_data' => ['id','owner','participants','start','end']
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -617,6 +617,22 @@ class calendar_ui
|
|||||||
$sidebox->exec('calendar.calendar_ui.sidebox_etemplate', $cont, $sel_options, $readonlys);
|
$sidebox->exec('calendar.calendar_ui.sidebox_etemplate', $cont, $sel_options, $readonlys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the data for the given event IDs in a format suitable for the client.
|
||||||
|
*
|
||||||
|
* Used to get new data when Push tells us. Push doesn't have the full event data,
|
||||||
|
* just the minimum, so the client needs to ask for it.
|
||||||
|
*
|
||||||
|
* @param string[] $event_ids
|
||||||
|
*/
|
||||||
|
public function ajax_get($event_ids)
|
||||||
|
{
|
||||||
|
foreach($event_ids as $id)
|
||||||
|
{
|
||||||
|
$this->update_client($id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send updated event information to the client via ajax
|
* Send updated event information to the client via ajax
|
||||||
*
|
*
|
||||||
|
@ -3200,9 +3200,8 @@ class calendar_uiforms extends calendar_ui
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Directly update stored data. If event is still visible, it will
|
// notify the link-class about the update, as other apps may be subscribed to it
|
||||||
// be notified & update itself.
|
Link::notify_update('calendar',$event['id'],$event,"update");
|
||||||
$this->update_client($eventId,$d);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -119,7 +119,8 @@ var CalendarApp = /** @class */ (function (_super) {
|
|||||||
egw.preference('defaultcalendar', 'calendar') || 'day',
|
egw.preference('defaultcalendar', 'calendar') || 'day',
|
||||||
owner: egw.user('account_id'),
|
owner: egw.user('account_id'),
|
||||||
keywords: '',
|
keywords: '',
|
||||||
last: undefined
|
last: undefined,
|
||||||
|
first: undefined
|
||||||
};
|
};
|
||||||
// If you are in one of these views and select a date in the sidebox, the view
|
// If you are in one of these views and select a date in the sidebox, the view
|
||||||
// will change as needed to show the date. Other views will only change the
|
// will change as needed to show the date. Other views will only change the
|
||||||
@ -513,6 +514,81 @@ var CalendarApp = /** @class */ (function (_super) {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* Handle a push notification about entry changes from the websocket
|
||||||
|
*
|
||||||
|
* @param pushData
|
||||||
|
* @param {string} pushData.app application name
|
||||||
|
* @param {(string|number)} pushData.id id of entry to refresh or null
|
||||||
|
* @param {string} pushData.type either 'update', 'edit', 'delete', 'add' or null
|
||||||
|
* - update: request just modified data from given rows. Sorting is not considered,
|
||||||
|
* so if the sort field is changed, the row will not be moved.
|
||||||
|
* - edit: rows changed, but sorting may be affected. Requires full reload.
|
||||||
|
* - delete: just delete the given rows clientside (no server interaction neccessary)
|
||||||
|
* - add: ask server for data, add in intelligently
|
||||||
|
* @param {object|null} pushData.acl Extra data for determining relevance. eg: owner or responsible to decide if update is necessary
|
||||||
|
* @param {number} pushData.account_id User that caused the notification
|
||||||
|
*/
|
||||||
|
CalendarApp.prototype.push = function (pushData) {
|
||||||
|
// Calendar cares about calendar & infolog
|
||||||
|
if (pushData.app !== this.appname && pushData.app !== 'infolog')
|
||||||
|
return;
|
||||||
|
// pushData does not contain everything, just the minimum. See calendar_hooks::search_link().
|
||||||
|
var event = pushData.acl || {};
|
||||||
|
if (pushData.type === 'delete') {
|
||||||
|
return _super.prototype.push.call(this, pushData);
|
||||||
|
}
|
||||||
|
switch (pushData.app) {
|
||||||
|
case "calendar":
|
||||||
|
return this.push_calendar(pushData);
|
||||||
|
case "infolog":
|
||||||
|
return this.push_infolog(pushData);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Handle a push about infolog
|
||||||
|
*
|
||||||
|
* @param pushData
|
||||||
|
*/
|
||||||
|
CalendarApp.prototype.push_infolog = function (pushData) {
|
||||||
|
// This isn't the most intelligent, but it refreshes
|
||||||
|
this.observer("", pushData.app, pushData.id, pushData.type, "", null);
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Handle a push from calendar
|
||||||
|
*
|
||||||
|
* @param pushData
|
||||||
|
*/
|
||||||
|
CalendarApp.prototype.push_calendar = function (pushData) {
|
||||||
|
// check visibility - grants is ID => permission of people we're allowed to see
|
||||||
|
var owners = [];
|
||||||
|
if (typeof this._grants === 'undefined') {
|
||||||
|
this._grants = egw.grants(this.appname);
|
||||||
|
}
|
||||||
|
// Filter what's allowed down to those we care about
|
||||||
|
var filtered = Object.keys(this._grants).filter(function (account) { return app.calendar.state.owner.indexOf(account) >= 0; });
|
||||||
|
// Check if we're interested in displaying by owner / participant
|
||||||
|
var owner_check = et2_widget_event_1.et2_calendar_event.owner_check(event, { options: { owner: filtered } });
|
||||||
|
if (!owner_check) {
|
||||||
|
// The owner is not in the list of what we're allowed / care about
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Check if we're interested by date?
|
||||||
|
if (event.end <= new Date(this.state.first).valueOf() / 1000 || event.start > new Date(this.state.last).valueOf() / 1000) {
|
||||||
|
// The event is outside our current view
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Ask for the real data
|
||||||
|
egw.json("calendar.calendar_ui.ajax_get", [[pushData.id]], function (data) {
|
||||||
|
var unknown = (typeof egw.dataGetUIDdata(data.uid) === "undefined");
|
||||||
|
// Store it, which will call all registered listeners
|
||||||
|
egw.dataStoreUID(data.uid, data.data);
|
||||||
|
// Any existing events were updated. Run this to catch new events or events moved into view
|
||||||
|
if (unknown) {
|
||||||
|
this._update_events(this.state, [data.uid]);
|
||||||
|
}
|
||||||
|
}.bind(this)).sendRequest(true);
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* Link hander for jDots template to just reload our iframe, instead of reloading whole admin app
|
* Link hander for jDots template to just reload our iframe, instead of reloading whole admin app
|
||||||
*
|
*
|
||||||
|
@ -80,7 +80,8 @@ class CalendarApp extends EgwApp
|
|||||||
egw.preference('defaultcalendar','calendar') || 'day',
|
egw.preference('defaultcalendar','calendar') || 'day',
|
||||||
owner: egw.user('account_id'),
|
owner: egw.user('account_id'),
|
||||||
keywords: '',
|
keywords: '',
|
||||||
last: undefined
|
last: undefined,
|
||||||
|
first: undefined
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -126,6 +127,8 @@ class CalendarApp extends EgwApp
|
|||||||
// Data for quick add dialog
|
// Data for quick add dialog
|
||||||
private quick_add: any;
|
private quick_add: any;
|
||||||
|
|
||||||
|
//
|
||||||
|
private _grants : any;
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
@ -438,6 +441,98 @@ class CalendarApp extends EgwApp
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Handle a push notification about entry changes from the websocket
|
||||||
|
*
|
||||||
|
* @param pushData
|
||||||
|
* @param {string} pushData.app application name
|
||||||
|
* @param {(string|number)} pushData.id id of entry to refresh or null
|
||||||
|
* @param {string} pushData.type either 'update', 'edit', 'delete', 'add' or null
|
||||||
|
* - update: request just modified data from given rows. Sorting is not considered,
|
||||||
|
* so if the sort field is changed, the row will not be moved.
|
||||||
|
* - edit: rows changed, but sorting may be affected. Requires full reload.
|
||||||
|
* - delete: just delete the given rows clientside (no server interaction neccessary)
|
||||||
|
* - add: ask server for data, add in intelligently
|
||||||
|
* @param {object|null} pushData.acl Extra data for determining relevance. eg: owner or responsible to decide if update is necessary
|
||||||
|
* @param {number} pushData.account_id User that caused the notification
|
||||||
|
*/
|
||||||
|
push(pushData)
|
||||||
|
{
|
||||||
|
// Calendar cares about calendar & infolog
|
||||||
|
if(pushData.app !== this.appname && pushData.app !== 'infolog') return;
|
||||||
|
|
||||||
|
// pushData does not contain everything, just the minimum. See calendar_hooks::search_link().
|
||||||
|
let event = pushData.acl || {};
|
||||||
|
|
||||||
|
if(pushData.type === 'delete')
|
||||||
|
{
|
||||||
|
return super.push(pushData);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (pushData.app)
|
||||||
|
{
|
||||||
|
case "calendar":
|
||||||
|
return this.push_calendar(pushData);
|
||||||
|
case "infolog":
|
||||||
|
return this.push_infolog(pushData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle a push about infolog
|
||||||
|
*
|
||||||
|
* @param pushData
|
||||||
|
*/
|
||||||
|
private push_infolog(pushData)
|
||||||
|
{
|
||||||
|
// This isn't the most intelligent, but it refreshes
|
||||||
|
this.observer("", pushData.app, pushData.id, pushData.type,"",null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle a push from calendar
|
||||||
|
*
|
||||||
|
* @param pushData
|
||||||
|
*/
|
||||||
|
private push_calendar(pushData)
|
||||||
|
{
|
||||||
|
// check visibility - grants is ID => permission of people we're allowed to see
|
||||||
|
let owners = [];
|
||||||
|
if(typeof this._grants === 'undefined')
|
||||||
|
{
|
||||||
|
this._grants = egw.grants(this.appname);
|
||||||
|
}
|
||||||
|
// Filter what's allowed down to those we care about
|
||||||
|
let filtered = Object.keys(this._grants).filter(account => app.calendar.state.owner.indexOf(account) >= 0);
|
||||||
|
|
||||||
|
// Check if we're interested in displaying by owner / participant
|
||||||
|
let owner_check = et2_calendar_event.owner_check(event, {options: {owner: filtered}});
|
||||||
|
if(!owner_check)
|
||||||
|
{
|
||||||
|
// The owner is not in the list of what we're allowed / care about
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we're interested by date?
|
||||||
|
if(event.end <= new Date(this.state.first).valueOf() /1000 || event.start > new Date(this.state.last).valueOf()/1000)
|
||||||
|
{
|
||||||
|
// The event is outside our current view
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ask for the real data
|
||||||
|
egw.json("calendar.calendar_ui.ajax_get", [[pushData.id]], function(data) {
|
||||||
|
let unknown = (typeof egw.dataGetUIDdata(data.uid) === "undefined");
|
||||||
|
// Store it, which will call all registered listeners
|
||||||
|
egw.dataStoreUID(data.uid, data.data);
|
||||||
|
|
||||||
|
// Any existing events were updated. Run this to catch new events or events moved into view
|
||||||
|
if(unknown)
|
||||||
|
{
|
||||||
|
this._update_events(this.state, [data.uid]);
|
||||||
|
}
|
||||||
|
}.bind(this)).sendRequest(true);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Link hander for jDots template to just reload our iframe, instead of reloading whole admin app
|
* Link hander for jDots template to just reload our iframe, instead of reloading whole admin app
|
||||||
|
Loading…
Reference in New Issue
Block a user