From 231b135b1bff3fd03600856afbfc24166792d93f Mon Sep 17 00:00:00 2001 From: nathangray Date: Tue, 9 Mar 2021 16:42:34 -0700 Subject: [PATCH] Calendar: handle push updates for integrated apps --- calendar/inc/class.calendar_so.inc.php | 8 +++- calendar/inc/class.calendar_uilist.inc.php | 6 ++- calendar/js/app.js | 48 ++++++++++++-------- calendar/js/app.ts | 53 +++++++++++++--------- 4 files changed, 71 insertions(+), 44 deletions(-) diff --git a/calendar/inc/class.calendar_so.inc.php b/calendar/inc/class.calendar_so.inc.php index bf7da13dcb..67ac746d3a 100644 --- a/calendar/inc/class.calendar_so.inc.php +++ b/calendar/inc/class.calendar_so.inc.php @@ -777,6 +777,12 @@ class calendar_so $private_filter = '(cal_public=1 OR cal_public=0 AND '.$this->db->expression($this->cal_table, array('cal_owner' => $params['private_grants'])) . ')'; $where[] = $private_filter; } + if($params['sql_filter']['cal_id']) + { + $params['query']['cal_id'] = $params['sql_filter']['cal_id']; + $where[] = $this->db->column_data_implode(", ", [$this->cal_table.'.cal_id' => $params['sql_filter']['cal_id']], True, False); + unset($params['sql_filter']['cal_id']); + } if (!empty($params['sql_filter'])) { if (is_string($params['sql_filter'])) @@ -1287,7 +1293,7 @@ class calendar_so } if (isset($app_cols[$col])) { - $return_cols[] = $app_cols[$col]; + $return_cols[] = $app_cols[$col] . " AS $col"; } else { diff --git a/calendar/inc/class.calendar_uilist.inc.php b/calendar/inc/class.calendar_uilist.inc.php index 6e72fc4cc1..3cc679ab3e 100644 --- a/calendar/inc/class.calendar_uilist.inc.php +++ b/calendar/inc/class.calendar_uilist.inc.php @@ -412,6 +412,10 @@ class calendar_uilist extends calendar_ui { $col_filter[$name] = $val; } + else if ( $name == 'row_id' && (string)$val !== '') + { + $col_filter['cal_id'] = $val; + } } } $rows = $js_integration_data = array(); @@ -427,7 +431,7 @@ class calendar_uilist extends calendar_ui foreach((array) $this->bo->search($search_params, !empty($col_filter) ? $col_filter : null) as $event) { - if ($params['csv_export']) + if ($params['csv_export'] && $params['csv_export'] !== "refresh") { $event['participants'] = implode(",\n",$this->bo->participants($event,true)); } diff --git a/calendar/js/app.js b/calendar/js/app.js index b72a978783..eed9ecdce4 100644 --- a/calendar/js/app.js +++ b/calendar/js/app.js @@ -545,9 +545,18 @@ var CalendarApp = /** @class */ (function (_super) { if (pushData.app == "infolog") { return this.push_infolog(pushData); } - // Other integration here - // TODO - debugger; + else { + // Modify the pushData so it looks like one of ours + var integrated_pushData = jQuery.extend(pushData, { + id: pushData.app + pushData.id, + app: this.appname + }); + if (integrated_pushData.type == "delete" || egw.dataHasUID(this.uid(integrated_pushData))) { + return _super.prototype.push.call(this, integrated_pushData); + } + // Ask for the real data, we don't have it + this._fetch_data(this.state, undefined, 0, [integrated_pushData.id]); + } } } }; @@ -602,12 +611,9 @@ var CalendarApp = /** @class */ (function (_super) { if (pushData.type === 'delete') { return this.egw.dataStoreUID(info_uid, null); } - // We could try to be a little smarter, but this will work - // Discard cache - this._clear_cache(); // Calendar is the current application, refresh now if (framework.activeApp.appName === this.appname) { - this.setState({ state: this.state }); + this._fetch_data(this.state, undefined, 0, [pushData.app + pushData.id]); } // Bind once to trigger a refresh when tab is activated again else if (framework.applications.calendar && framework.applications.calendar.tab && @@ -817,15 +823,7 @@ var CalendarApp = /** @class */ (function (_super) { integration_preference.splice(index, 1); } // Clear any events from that app - var events = egw.dataKnownUIDs('calendar'); - for (var i = 0; i < events.length; i++) { - var event_data = egw.dataGetUIDdata("calendar::" + events[i]).data || { app: "calendar" }; - if (event_data && event_data.app === app) { - // Remove entry, then delete it from the cache - egw.dataStoreUID("calendar::" + events[i], null); - egw.dataDeleteUID('calendar::' + events[i]); - } - } + this._clear_cache(app); } egw.set_preference("calendar", "integration_toggle", integration_preference, callback); }; @@ -2934,12 +2932,21 @@ var CalendarApp = /** @class */ (function (_super) { /** * Clear all calendar data from egw.data cache */ - CalendarApp.prototype._clear_cache = function () { + CalendarApp.prototype._clear_cache = function (integration_app) { // Full refresh, clear the caches var events = egw.dataKnownUIDs('calendar'); for (var i = 0; i < events.length; i++) { - egw.dataDeleteUID('calendar::' + events[i]); + var event_data = egw.dataGetUIDdata("calendar::" + events[i]).data || { app: "calendar" }; + if (!integration_app || integration_app && event_data && event_data.app === integration_app) { + // Remove entry + egw.dataStoreUID("calendar::" + events[i], null); + // Delete from cache + egw.dataDeleteUID('calendar::' + events[i]); + } } + // If just removing one app, leave the columns alone + if (integration_app) + return; var daywise = egw.dataKnownUIDs(CalendarApp.DAYWISE_CACHE_ID); for (var i = 0; i < daywise.length; i++) { // Empty to clear existing widgets @@ -3020,8 +3027,9 @@ var CalendarApp = /** @class */ (function (_super) { * @param {etemplate2} [instance] If the full calendar app isn't loaded * (home app), pass a different instance to use it to get the data * @param {number} [start] Result offset. Internal use only + * @param {string[]} [specific_ids] Only request the given IDs */ - CalendarApp.prototype._fetch_data = function (state, instance, start) { + CalendarApp.prototype._fetch_data = function (state, instance, start, specific_ids) { if (!this.sidebox_et2 && !instance) { return; } @@ -3067,7 +3075,7 @@ var CalendarApp = /** @class */ (function (_super) { } this._queries_in_progress.push(query_string); this.egw.dataFetch(instance ? instance.etemplate_exec_id : - this.sidebox_et2.getInstanceManager().etemplate_exec_id, { start: start, num_rows: 400 }, query, this.appname, function calendar_handleResponse(data) { + this.sidebox_et2.getInstanceManager().etemplate_exec_id, specific_ids ? { refresh: specific_ids } : { start: start, num_rows: 400 }, query, this.appname, function calendar_handleResponse(data) { var idx = this._queries_in_progress.indexOf(query_string); if (idx >= 0) { this._queries_in_progress.splice(idx, 1); diff --git a/calendar/js/app.ts b/calendar/js/app.ts index b83193716e..320532e8ee 100644 --- a/calendar/js/app.ts +++ b/calendar/js/app.ts @@ -480,9 +480,20 @@ class CalendarApp extends EgwApp { return this.push_infolog(pushData); } - // Other integration here - // TODO - debugger; + else + { + // Modify the pushData so it looks like one of ours + let integrated_pushData = jQuery.extend(pushData, { + id: pushData.app+pushData.id, + app: this.appname + }); + if(integrated_pushData.type == "delete" || egw.dataHasUID(this.uid(integrated_pushData))) + { + return super.push(integrated_pushData); + } + // Ask for the real data, we don't have it + this._fetch_data(this.state,undefined,0,[integrated_pushData.id]); + } } } } @@ -554,14 +565,11 @@ class CalendarApp extends EgwApp { return this.egw.dataStoreUID(info_uid, null); } - // We could try to be a little smarter, but this will work - // Discard cache - this._clear_cache(); // Calendar is the current application, refresh now if(framework.activeApp.appName === this.appname) { - this.setState({state: this.state}); + this._fetch_data(this.state,undefined,0,[pushData.app+pushData.id]); } // Bind once to trigger a refresh when tab is activated again else if(framework.applications.calendar && framework.applications.calendar.tab && @@ -818,17 +826,7 @@ class CalendarApp extends EgwApp } // Clear any events from that app - let events = egw.dataKnownUIDs('calendar'); - for(let i = 0; i < events.length; i++) - { - let event_data = egw.dataGetUIDdata("calendar::" + events[i]).data || {app: "calendar"}; - if(event_data && event_data.app === app) - { - // Remove entry, then delete it from the cache - egw.dataStoreUID("calendar::"+events[i], null); - egw.dataDeleteUID('calendar::' + events[i]); - } - } + this._clear_cache(app); } egw.set_preference("calendar","integration_toggle",integration_preference, callback); } @@ -3435,14 +3433,24 @@ class CalendarApp extends EgwApp /** * Clear all calendar data from egw.data cache */ - _clear_cache( ) + _clear_cache( integration_app?:string ) { // Full refresh, clear the caches var events = egw.dataKnownUIDs('calendar'); for(var i = 0; i < events.length; i++) { - egw.dataDeleteUID('calendar::' + events[i]); + let event_data = egw.dataGetUIDdata("calendar::" + events[i]).data || {app: "calendar"}; + if(!integration_app || integration_app && event_data && event_data.app === integration_app) + { + // Remove entry + egw.dataStoreUID("calendar::" + events[i], null); + // Delete from cache + egw.dataDeleteUID('calendar::' + events[i]); + } } + // If just removing one app, leave the columns alone + if(integration_app) return; + var daywise = egw.dataKnownUIDs(CalendarApp.DAYWISE_CACHE_ID); for(var i = 0; i < daywise.length; i++) { @@ -3552,8 +3560,9 @@ class CalendarApp extends EgwApp * @param {etemplate2} [instance] If the full calendar app isn't loaded * (home app), pass a different instance to use it to get the data * @param {number} [start] Result offset. Internal use only + * @param {string[]} [specific_ids] Only request the given IDs */ - _fetch_data(state, instance, start?) + _fetch_data(state, instance, start?, specific_ids?) { if(!this.sidebox_et2 && !instance) { @@ -3613,7 +3622,7 @@ class CalendarApp extends EgwApp this.egw.dataFetch( instance ? instance.etemplate_exec_id : this.sidebox_et2.getInstanceManager().etemplate_exec_id, - {start: start, num_rows:400}, + specific_ids ? {refresh: specific_ids} : {start: start, num_rows:400}, query, this.appname, function calendar_handleResponse(data) {