From 19bd3a03b05942640fb21f8977e08a6655ea8cf2 Mon Sep 17 00:00:00 2001 From: nathangray Date: Thu, 4 Mar 2021 13:53:52 -0700 Subject: [PATCH] Addressbook: Update CRM view contact info in sidebox if it's changed by push message --- addressbook/inc/class.addressbook_ui.inc.php | 6 ++- addressbook/js/app.js | 33 +++++++++++++++++ addressbook/js/app.ts | 39 +++++++++++++++++++- api/js/jsapi/egw_app.js | 5 ++- api/js/jsapi/egw_app.ts | 4 +- 5 files changed, 81 insertions(+), 6 deletions(-) diff --git a/addressbook/inc/class.addressbook_ui.inc.php b/addressbook/inc/class.addressbook_ui.inc.php index 59fe2f92c6..a6c209faed 100644 --- a/addressbook/inc/class.addressbook_ui.inc.php +++ b/addressbook/inc/class.addressbook_ui.inc.php @@ -3039,6 +3039,10 @@ class addressbook_ui extends addressbook_bo unset($contact_id); } break; + default: + // No button, probably a refresh + $content = $this->read($content['id']); + break; } } else @@ -3193,7 +3197,7 @@ class addressbook_ui extends addressbook_bo // Load CRM code Framework::includeJS('.','CRM','addressbook'); - $content['view_sidebox'] = addressbook_hooks::getViewDOMID($contact_id, $crm_list); + $content['view_sidebox'] = addressbook_hooks::getViewDOMID($content['id'], $crm_list); $this->tmpl->exec('addressbook.addressbook_ui.view',$content,$sel_options,$readonlys,array( 'id' => $content['id'], 'index' => $content['index'], diff --git a/addressbook/js/app.js b/addressbook/js/app.js index 2d3c91524e..a790fe26f5 100644 --- a/addressbook/js/app.js +++ b/addressbook/js/app.js @@ -161,6 +161,39 @@ var AddressbookApp = /** @class */ (function (_super) { } return true; }; + /** + * Handle a push notification about entry changes from the websocket + * + * Get's called for data of all apps, but should only handle data of apps it displays, + * which is by default only it's own, but can be for multiple apps eg. for calendar. + * + * @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: requires full reload for proper sorting + * @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 + */ + AddressbookApp.prototype.push = function (pushData) { + var _a, _b; + // don't care about other apps data + if (pushData.app !== this.appname) + return; + // Update the contact list + if (this.et2 && this.et2.getInstanceManager().name == "addressbook.index") { + return _super.prototype.push.call(this, pushData); + } + // Update CRM view (sidebox part), if open + var contact_id = ((_b = (_a = this.et2) === null || _a === void 0 ? void 0 : _a.getArrayMgr("content")) === null || _b === void 0 ? void 0 : _b.getEntry("id")) || 0; + if (this.et2 && contact_id && contact_id == pushData.id) { + this.et2.getInstanceManager().submit(); + } + }; /** * Change handler for contact / org selectbox * diff --git a/addressbook/js/app.ts b/addressbook/js/app.ts index 772d56e321..8709b1b352 100644 --- a/addressbook/js/app.ts +++ b/addressbook/js/app.ts @@ -17,7 +17,7 @@ import 'jqueryui'; import '../jsapi/egw_global'; import '../etemplate/et2_types'; -import {EgwApp} from '../../api/js/jsapi/egw_app'; +import {EgwApp, PushData} from '../../api/js/jsapi/egw_app'; import {etemplate2} from "../../api/js/etemplate/etemplate2"; /** @@ -183,6 +183,43 @@ class AddressbookApp extends EgwApp return true; } + /** + * Handle a push notification about entry changes from the websocket + * + * Get's called for data of all apps, but should only handle data of apps it displays, + * which is by default only it's own, but can be for multiple apps eg. for calendar. + * + * @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: requires full reload for proper sorting + * @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 : PushData) + { + // don't care about other apps data + if(pushData.app !== this.appname) return; + + // Update the contact list + if(this.et2 && this.et2.getInstanceManager().name == "addressbook.index") + { + return super.push(pushData); + } + + // Update CRM view (sidebox part), if open + let contact_id = this.et2?.getArrayMgr("content")?.getEntry("id") || 0; + if(this.et2 && contact_id && contact_id == pushData.id) + { + this.et2.getInstanceManager().submit(); + } + } + /** * Change handler for contact / org selectbox * diff --git a/api/js/jsapi/egw_app.js b/api/js/jsapi/egw_app.js index e4caf79833..566ab641f6 100644 --- a/api/js/jsapi/egw_app.js +++ b/api/js/jsapi/egw_app.js @@ -160,6 +160,7 @@ var EgwApp = /** @class */ (function () { * @param {number} pushData.account_id User that caused the notification */ EgwApp.prototype.push = function (pushData) { + var _a; // don't care about other apps data, reimplement if your app does care eg. calendar if (pushData.app !== this.appname) return; @@ -171,7 +172,7 @@ var EgwApp = /** @class */ (function () { // If we know about it and it's an update, just update. // This must be before all ACL checks, as responsible might have changed and entry need to be removed // (server responds then with null / no entry causing the entry to disappear) - if (pushData.type !== "add" && this.egw.dataHasUID(this.uid(pushData))) { + if (pushData.type !== "add" && this.egw.dataHasUID(this.uid(pushData)) && this.et2) { return this.et2.getInstanceManager().refresh("", pushData.app, pushData.id, pushData.type); } // Check grants to see if we know we aren't supposed to show it @@ -180,7 +181,7 @@ var EgwApp = /** @class */ (function () { return; } // Nextmatch does the hard part of updating. Try to find one. - var nm = this.et2.getDOMWidgetById('nm'); + var nm = (_a = this.et2) === null || _a === void 0 ? void 0 : _a.getDOMWidgetById('nm'); if (!nm) { return; } diff --git a/api/js/jsapi/egw_app.ts b/api/js/jsapi/egw_app.ts index 34c79a246a..a2dfd70bc8 100644 --- a/api/js/jsapi/egw_app.ts +++ b/api/js/jsapi/egw_app.ts @@ -285,7 +285,7 @@ export abstract class EgwApp // If we know about it and it's an update, just update. // This must be before all ACL checks, as responsible might have changed and entry need to be removed // (server responds then with null / no entry causing the entry to disappear) - if (pushData.type !== "add" && this.egw.dataHasUID(this.uid(pushData))) + if (pushData.type !== "add" && this.egw.dataHasUID(this.uid(pushData)) && this.et2) { return this.et2.getInstanceManager().refresh("", pushData.app, pushData.id, pushData.type); } @@ -299,7 +299,7 @@ export abstract class EgwApp } // Nextmatch does the hard part of updating. Try to find one. - let nm = this.et2.getDOMWidgetById('nm'); + let nm = this.et2?.getDOMWidgetById('nm'); if(!nm) { return;