From 58ae23c74c144b18d01c6568fbbfacf7540faee4 Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Thu, 4 Mar 2021 11:49:45 +0200 Subject: [PATCH] allow "app.." in link registry and use it to open CRM view --- .../inc/class.addressbook_hooks.inc.php | 7 +- addressbook/js/app.js | 65 ++++++++++---- addressbook/js/app.ts | 87 ++++++++++++++----- api/js/jsapi/egw_app.js | 36 -------- api/js/jsapi/egw_app.ts | 41 --------- api/js/jsapi/egw_json.js | 2 +- api/js/jsapi/egw_open.js | 10 ++- api/src/Contacts.php | 26 ++---- infolog/inc/class.infolog_ui.inc.php | 2 +- infolog/js/app.js | 2 +- infolog/js/app.ts | 2 +- 11 files changed, 136 insertions(+), 144 deletions(-) diff --git a/addressbook/inc/class.addressbook_hooks.inc.php b/addressbook/inc/class.addressbook_hooks.inc.php index f19d95a555..599d694276 100644 --- a/addressbook/inc/class.addressbook_hooks.inc.php +++ b/addressbook/inc/class.addressbook_hooks.inc.php @@ -361,12 +361,7 @@ class addressbook_hooks 'query' => 'api.EGroupware\\Api\\Contacts.link_query', 'title' => 'api.EGroupware\\Api\\Contacts.link_title', 'titles' => 'api.EGroupware\\Api\\Contacts.link_titles', - 'view' => array( - 'menuaction' => 'addressbook.addressbook_ui.view', - 'ajax' => 'true', - 'target' => 'tab', - 'crm_list' => 'infolog' - ), + 'view' => 'app.addressbook.openCRMview', 'view_id' => 'contact_id', 'list' => array( 'menuaction' => 'addressbook.addressbook_ui.index', diff --git a/addressbook/js/app.js b/addressbook/js/app.js index 03a373124e..2d3c91524e 100644 --- a/addressbook/js/app.js +++ b/addressbook/js/app.js @@ -194,16 +194,15 @@ var AddressbookApp = /** @class */ (function (_super) { return !promise; }; /** - * Open CRM view + * Open CRM view from addressbook index itself * * @param _action * @param _senders */ AddressbookApp.prototype.view = function (_action, _senders) { - var index = _senders[0]._index; - var id = _senders[0].id.split('::').pop(); var extras = { - index: index + contact_id: _senders[0].id.split('::').pop(), + index: _senders[0]._index }; var data = egw.dataGetUIDdata(_senders[0].id)['data']; // CRM list @@ -212,21 +211,55 @@ var AddressbookApp = /** @class */ (function (_super) { } if (!extras.crm_list) extras.crm_list = egw.preference('crm_list', 'addressbook'); - this.egw.openTab(id, 'addressbook', 'view', extras, { - displayName: (_action.id.match(/\-organisation/) && data.org_name != "") ? data.org_name - : data.n_fn + " (" + egw.lang(extras.crm_list) + ")", - icon: data.photo, - refreshCallback: this.view_refresh, - id: id + '-' + extras.crm_list, - }); + extras.title = (_action.id.match(/\-organisation/) && data.org_name != "") ? data.org_name + : data.n_fn + " (" + egw.lang(extras.crm_list) + ")"; + extras.icon = data.photo; + return this.openCRMview(extras); }; /** - * callback for refreshing relative crm view list + * Open a CRM view for a contact: callback for link-registry / egw.open / other apps + * + * @param {CrmParams} _params object with attribute "contact_id" and optional "title", "crm_list", "icon" + * @param {object} _senders use egw.dataGetUIDdata to get contact_id */ - AddressbookApp.prototype.view_refresh = function () { - var et2 = etemplate2_1.etemplate2.getById("addressbook-view-" + this.appName); - if (et2) { - et2.app_obj.addressbook.view_set_list(); + AddressbookApp.prototype.openCRMview = function (_params, _senders) { + var contact_id = typeof _params === 'object' ? _params.contact_id : _params; + if (typeof _senders === 'object') { + var data = egw.dataGetUIDdata(_senders[0].id); + contact_id = data.data.contact_id; + } + if (typeof contact_id !== 'undefined') { + var crm_list_1 = _params.crm_list || egw.preference('crm_list', 'addressbook'); + if (!crm_list_1 || crm_list_1 === '~edit~') + crm_list_1 = 'infolog'; + var url_1 = this.egw.link('/index.php', { + menuaction: 'addressbook.addressbook_ui.view', + ajax: 'true', + contact_id: contact_id, + crm_list: crm_list_1 + }); + // no framework, just open the url + if (typeof this.egw.window.framework === 'undefined') { + return this.egw.open_link(url_1); + } + var open_1 = function (_title) { + var title = _title || this.egw.link_title('addressbook', contact_id, open_1); + if (title) { + this.egw.window.framework.tabLinkHandler(url_1, { + displayName: title, + icon: _params.icon || this.egw.link('/api/avatar.php', { + contact_id: contact_id, + etag: (new Date).valueOf() / 86400 | 0 // cache for a day, better then no invalidation + }), + refreshCallback: function () { + var _a; + (_a = etemplate2_1.etemplate2.getById("addressbook-view-" + this.appName)) === null || _a === void 0 ? void 0 : _a.app_obj.addressbook.view_set_list(); + }, + id: contact_id + '-' + crm_list_1 + }); + } + }.bind(this); + open_1(_params.title); } }; /** diff --git a/addressbook/js/app.ts b/addressbook/js/app.ts index 3b9bd8d259..772d56e321 100644 --- a/addressbook/js/app.ts +++ b/addressbook/js/app.ts @@ -20,6 +20,17 @@ import '../etemplate/et2_types'; import {EgwApp} from '../../api/js/jsapi/egw_app'; import {etemplate2} from "../../api/js/etemplate/etemplate2"; +/** + * Object to call app.addressbook.openCRMview with + */ +export interface CrmParams { + contact_id: number|string; + crm_list?: "infolog"|"tracker"|"infolog-organisation"; // default: use preference + title?: string; // default: link-title of contact_id + icon?: string; // default: avatar for contact_id + index?: number; +} + /** * UI for Addressbook * @@ -212,44 +223,80 @@ class AddressbookApp extends EgwApp } return !promise; } + /** - * Open CRM view + * Open CRM view from addressbook index itself * * @param _action * @param _senders */ view(_action, _senders) { - var index = _senders[0]._index; - var id = _senders[0].id.split('::').pop(); - var extras : any = { - index: index + let extras : CrmParams = { + contact_id: _senders[0].id.split('::').pop(), + index: _senders[0]._index }; - var data = egw.dataGetUIDdata(_senders[0].id)['data']; + let data = egw.dataGetUIDdata(_senders[0].id)['data']; // CRM list - if(_action.id != 'view') + if (_action.id != 'view') { extras.crm_list = _action.id.replace('view-',''); } - if (!extras.crm_list) extras.crm_list = egw.preference('crm_list', 'addressbook'); - this.egw.openTab(id, 'addressbook', 'view', extras, { - displayName: (_action.id.match(/\-organisation/) && data.org_name != "") ? data.org_name - : data.n_fn+" ("+egw.lang(extras.crm_list)+")", - icon: data.photo, - refreshCallback: this.view_refresh, - id: id+'-'+extras.crm_list, - }); + if (!extras.crm_list) extras.crm_list = egw.preference('crm_list', 'addressbook'); + extras.title = (_action.id.match(/\-organisation/) && data.org_name != "") ? data.org_name + : data.n_fn+" ("+egw.lang(extras.crm_list)+")"; + extras.icon = data.photo; + return this.openCRMview(extras); } /** - * callback for refreshing relative crm view list + * Open a CRM view for a contact: callback for link-registry / egw.open / other apps + * + * @param {CrmParams} _params object with attribute "contact_id" and optional "title", "crm_list", "icon" + * @param {object} _senders use egw.dataGetUIDdata to get contact_id */ - view_refresh() + openCRMview(_params: CrmParams, _senders?: object) { - let et2 = etemplate2.getById("addressbook-view-"+this.appName); - if (et2) + let contact_id = typeof _params === 'object' ? _params.contact_id : _params; + if (typeof _senders === 'object') { - et2.app_obj.addressbook.view_set_list(); + let data = egw.dataGetUIDdata(_senders[0].id); + contact_id = data.data.contact_id; + } + if (typeof contact_id !== 'undefined') + { + let crm_list = _params.crm_list || egw.preference('crm_list', 'addressbook'); + if (!crm_list || crm_list === '~edit~') crm_list = 'infolog'; + let url = this.egw.link('/index.php', { + menuaction: 'addressbook.addressbook_ui.view', + ajax: 'true', + contact_id: contact_id, + crm_list: crm_list + }); + // no framework, just open the url + if (typeof this.egw.window.framework === 'undefined') + { + return this.egw.open_link(url); + } + let open = function(_title) + { + let title = _title || this.egw.link_title('addressbook', contact_id, open); + if (title) + { + this.egw.window.framework.tabLinkHandler(url, { + displayName: title, + icon: _params.icon || this.egw.link('/api/avatar.php', { + contact_id: contact_id, + etag: (new Date).valueOf()/86400|0 // cache for a day, better then no invalidation + }), + refreshCallback: function() { + etemplate2.getById("addressbook-view-"+this.appName)?.app_obj.addressbook.view_set_list(); + }, + id: contact_id + '-'+crm_list + }); + } + }.bind(this); + open(_params.title); } } diff --git a/api/js/jsapi/egw_app.js b/api/js/jsapi/egw_app.js index d2ee386509..e2ad66c0e6 100644 --- a/api/js/jsapi/egw_app.js +++ b/api/js/jsapi/egw_app.js @@ -300,42 +300,6 @@ var EgwApp = /** @class */ (function () { var id_app = _senders[0].id.split('::'); egw.open(id_app[1], this.appname); }; - /** - * Open a CRM view for a contact - * - * @param _action - * @param _senders - * @param _contact_id default: use contact_id from data of _senders[0].id - */ - EgwApp.prototype.openCRMview = function (_action, _senders) { - var contact_id = _senders; - if (typeof _senders === 'object') { - var data = egw.dataGetUIDdata(_senders[0].id); - contact_id = data.data.contact_id; - } - if (typeof contact_id !== 'undefined') { - var crm_list_1 = egw.preference('crm_list', 'addressbook'); - if (!crm_list_1 || crm_list_1 === '~edit~') - crm_list_1 = 'infolog'; - var open_1 = function (_title) { - var title = _title || this.egw.link_title('addressbook', contact_id, open_1); - if (title) { - this.egw.openTab(contact_id, 'addressbook', 'view', { - crm_list: crm_list_1 - }, { - displayName: title, - icon: this.egw.link('/api/avatar.php', { - contact_id: contact_id, - etag: (new Date).valueOf() / 86400 | 0 // cache for a day, better then no invalidation - }), - refreshCallback: 'app.addressbook.view_refresh', - id: contact_id + '-' + crm_list_1 - }); - } - }.bind(this); - open_1(); - } - }; EgwApp.prototype._do_action = function (action_id, selected) { }; /** diff --git a/api/js/jsapi/egw_app.ts b/api/js/jsapi/egw_app.ts index 44eb7a0adb..de729a71b2 100644 --- a/api/js/jsapi/egw_app.ts +++ b/api/js/jsapi/egw_app.ts @@ -436,47 +436,6 @@ export abstract class EgwApp egw.open(id_app[1], this.appname); } - /** - * Open a CRM view for a contact - * - * @param _action - * @param _senders - * @param _contact_id default: use contact_id from data of _senders[0].id - */ - openCRMview(_action, _senders) - { - let contact_id = _senders; - if (typeof _senders === 'object') - { - let data = egw.dataGetUIDdata(_senders[0].id); - contact_id = data.data.contact_id; - } - if (typeof contact_id !== 'undefined') - { - let crm_list = egw.preference('crm_list', 'addressbook'); - if (!crm_list || crm_list === '~edit~') crm_list = 'infolog'; - let open = function(_title) - { - let title = _title || this.egw.link_title('addressbook', contact_id, open); - if (title) - { - this.egw.openTab(contact_id,'addressbook', 'view', { - crm_list: crm_list - }, { - displayName: title, - icon: this.egw.link('/api/avatar.php', { - contact_id: contact_id, - etag: (new Date).valueOf()/86400|0 // cache for a day, better then no invalidation - }), - refreshCallback: 'app.addressbook.view_refresh', - id: contact_id + '-'+crm_list - }); - } - }.bind(this); - open(); - } - } - _do_action(action_id : string, selected : []) { } diff --git a/api/js/jsapi/egw_json.js b/api/js/jsapi/egw_json.js index ff13ade1b3..3020ccf2df 100644 --- a/api/js/jsapi/egw_json.js +++ b/api/js/jsapi/egw_json.js @@ -524,7 +524,7 @@ egw.extend('json', egw.MODULE_WND_LOCAL, function(_app, _wnd) { self.includeJS('/'+parts[1]+'/js/app.js', function () { - resolve(self.apply(_func, args)); + resolve(self.applyFunc(_func, args)); }, self, self.webserverUrl); }); } diff --git a/api/js/jsapi/egw_open.js b/api/js/jsapi/egw_open.js index 95dc25c079..0dd044f30a 100644 --- a/api/js/jsapi/egw_open.js +++ b/api/js/jsapi/egw_open.js @@ -187,7 +187,8 @@ egw.extend('open', egw.MODULE_WND_LOCAL, function(_egw, _wnd) // Copy, not get a reference, or we'll change the registry params = jQuery.extend({},app_registry[type]); } - else if (typeof app_registry[type] === 'string' && app_registry[type].indexOf('javascript:') === 0) + else if (typeof app_registry[type] === 'string' && + (app_registry[type].substr(0, 11) === 'javascript:' || app_registry[type].substr(0, 4) === 'app.')) { // JavaScript, just pass it on url = app_registry[type]; @@ -214,11 +215,16 @@ egw.extend('open', egw.MODULE_WND_LOCAL, function(_egw, _wnd) } popup = app_registry[type+'_popup']; } - if(url.indexOf('javascript:') === 0) + if (url.substr(0, 11) === 'javascript:') { // Add parameters into javascript url = 'javascript:var params = '+ JSON.stringify(params) + '; '+ url.substr(11); } + // app..: call app method direct with parameter object as first parameter + else if (url.substr(0, 4) === 'app.') + { + return this.callFunc(url, params); + } else { url = this.link(url, params); diff --git a/api/src/Contacts.php b/api/src/Contacts.php index 212eda4761..c568916d9a 100755 --- a/api/src/Contacts.php +++ b/api/src/Contacts.php @@ -2921,27 +2921,15 @@ class Contacts extends Contacts\Storage { $crm_list = 'infolog-organisation'; } - $extras = [ - //'index': ToDo: what's that used for? + $push->call($func='app.addressbook.openCRMview', $arg=[ + 'contact_id' => (int)$contact['id'], 'crm_list' => $crm_list, - ]; - $params = [(int)$contact['id'], 'addressbook', 'view', $extras, [ - 'displayName' => count($found) > 1 && $contact['org_name'] ? + 'title' => count($found) > 1 && $contact['org_name'] ? $contact['org_name'] : $contact['n_fn'].' ('.lang($extras['crm_list']).')', 'icon' => $contact['photo'], - 'refreshCallback' => 'app.addressbook.view_refresh', - 'id' => $contact['id'].'-'.$extras['crm_list'], - ]]; - /* ToDo: allow refreshCallback to be a "app.." string resolving also private / non-global apps - $push->apply('egw.openTab', $params); - */ - $params = str_replace('"app.addressbook.view_refresh"', 'function(){ - let et2 = etemplate2.getById("addressbook-view-"+this.appName); - if (et2) et2.app_obj.addressbook.view_set_list(); -}', json_encode($params, JSON_UNESCAPED_SLASHES)); - $push->script('egw.openTab.apply(egw, '.$params.')'); - if (!is_string($params)) $params = json_encode($params, JSON_UNESCAPED_SLASHES); - error_log("crm.php: calling push(#$this->user)->apply('egw.openTab', $params)"); - return "calling push(#$this->user)->apply('egw.openTab', $params)"; + ]); + $arg = json_encode($arg, JSON_UNESCAPED_SLASHES); + error_log("crm.php: calling push(#$this->user)->call('$func', $arg)"); + return "calling push(#$this->user)->call('$func', $arg)"; } } diff --git a/infolog/inc/class.infolog_ui.inc.php b/infolog/inc/class.infolog_ui.inc.php index 8c85d89bdb..5983ccb54d 100644 --- a/infolog/inc/class.infolog_ui.inc.php +++ b/infolog/inc/class.infolog_ui.inc.php @@ -2280,7 +2280,7 @@ class infolog_ui } if ($GLOBALS['egw_info']['user']['apps']['stylite'] && !$GLOBALS['egw_info']['server']['disable_pgp_encryption']) { - $content['encryption_ts'] = filemtime(EGW_SERVER_ROOT.'/stylite/js/infolog-encryption.js'); + $content['encryption_ts'] = filemtime(EGW_SERVER_ROOT.'/stylite/js/app.js'); } elseif ($GLOBALS['egw_info']['server']['disable_pgp_encryption']) { diff --git a/infolog/js/app.js b/infolog/js/app.js index ff36f22b74..21a3a0f6f6 100644 --- a/infolog/js/app.js +++ b/infolog/js/app.js @@ -739,7 +739,7 @@ var InfologApp = /** @class */ (function (_super) { var app = this.et2.getInstanceManager().app_obj; if (!app.stylite) { var self = this; - egw_LAB.script('stylite/js/infolog-encryption.js?' + this.et2.getArrayMgr('content').data.encryption_ts).wait(function () { + egw_LAB.script('stylite/js/app.js?' + this.et2.getArrayMgr('content').getEntry('encryption_ts')).wait(function () { app.stylite = new app.classes.stylite; app.stylite.et2 = self.et2; if (callback) { diff --git a/infolog/js/app.ts b/infolog/js/app.ts index 3e238a7e8b..48bdbd6bef 100644 --- a/infolog/js/app.ts +++ b/infolog/js/app.ts @@ -875,7 +875,7 @@ class InfologApp extends EgwApp if (!app.stylite) { var self = this; - egw_LAB.script('stylite/js/infolog-encryption.js?'+this.et2.getArrayMgr('content').data.encryption_ts).wait(function() + egw_LAB.script('stylite/js/app.js?'+this.et2.getArrayMgr('content').getEntry('encryption_ts')).wait(function() { app.stylite = new app.classes.stylite; app.stylite.et2 = self.et2;