From e9b054b025b873470459725cdcfc3eb0419a4f23 Mon Sep 17 00:00:00 2001 From: ralf Date: Thu, 13 Jul 2023 15:22:21 +0200 Subject: [PATCH] WIP Mail REST API: change calendar to use new egw.openDialog(): - renamed app.dialogExec() to app.openDialog() or egw.openDialog() - the later is the nicer place, but fails for lost window context with popups :( --- api/js/etemplate/etemplate2.ts | 2 +- api/js/jsapi/egw_app.ts | 11 +- api/js/jsapi/egw_open.js | 28 +++- api/src/Framework/Ajax.php | 30 ++-- calendar/inc/class.calendar_uiforms.inc.php | 14 +- calendar/js/app.ts | 164 +------------------- calendar/templates/default/add.xet | 6 +- 7 files changed, 65 insertions(+), 190 deletions(-) diff --git a/api/js/etemplate/etemplate2.ts b/api/js/etemplate/etemplate2.ts index dff553d428..3bf9a623a7 100644 --- a/api/js/etemplate/etemplate2.ts +++ b/api/js/etemplate/etemplate2.ts @@ -1573,7 +1573,7 @@ export class etemplate2 } // handle framework.setSidebox calls - if(window.framework && jQuery.isArray(data.setSidebox)) + if(!dialog && window.framework && Array.isArray(data.setSidebox)) { if(data['fw-target']) { diff --git a/api/js/jsapi/egw_app.ts b/api/js/jsapi/egw_app.ts index ca53177945..d6ef68e55e 100644 --- a/api/js/jsapi/egw_app.ts +++ b/api/js/jsapi/egw_app.ts @@ -750,13 +750,15 @@ export abstract class EgwApp /** * Opens _menuaction in an Et2Dialog * + * Equivalent to egw.openDialog, thought this one works in popups too. + * * @param _menuaction * @return Promise */ - dialogExec(_menuaction : string) + openDialog(_menuaction : string) { - const ajax = this.egw.json(_menuaction.match(/^([^.:]+)/)[0] + '.jdots_framework.ajax_exec.template.' + _menuaction, - ['index.php?menuaction=' + _menuaction], _response => + return this.egw.json(_menuaction.match(/^([^.:]+)/)[0] + '.jdots_framework.ajax_exec.template.' + _menuaction, + ['index.php?menuaction=' + _menuaction, true], _response => { if (Array.isArray(_response) && typeof _response[0] === 'string') { @@ -766,8 +768,7 @@ export abstract class EgwApp { console.log("Invalid response to dialogExec('"+_menuaction+"')", _response); } - }); - return ajax.sendRequest(); + }).sendRequest(); } /** diff --git a/api/js/jsapi/egw_open.js b/api/js/jsapi/egw_open.js index 909c320186..63209bfda1 100644 --- a/api/js/jsapi/egw_open.js +++ b/api/js/jsapi/egw_open.js @@ -378,6 +378,32 @@ egw.extend('open', egw.MODULE_WND_LOCAL, function(_egw, _wnd) } }, + /** + * Opens a menuaction in an Et2Dialog instead of a popup + * + * Please note: + * This method does NOT (yet) work in popups, only in the main EGroupware window! + * For popups you have to use the app.ts method openDialog(), which creates the dialog in the correct window / popup. + * + * @param string _menuaction + * @return Promise + */ + openDialog: function(_menuaction) + { + return this.json(_menuaction.match(/^([^.:]+)/)[0] + '.jdots_framework.ajax_exec.template.' + _menuaction, + ['index.php?menuaction=' + _menuaction, true], _response => + { + if (Array.isArray(_response) && typeof _response[0] === 'string') + { + jQuery(_response[0]).appendTo(_wnd.document.body); + } + else + { + console.log("Invalid response to dialogExec('"+_menuaction+"')", _response); + } + }).sendRequest(); + }, + /** * Open a (centered) popup window with given size and url * @@ -690,4 +716,4 @@ try { } } catch (e) {} }); -*/ +*/ \ No newline at end of file diff --git a/api/src/Framework/Ajax.php b/api/src/Framework/Ajax.php index 63aae4c89c..b2ce428ffa 100755 --- a/api/src/Framework/Ajax.php +++ b/api/src/Framework/Ajax.php @@ -1083,11 +1083,12 @@ abstract class Ajax extends Api\Framework /** * Run a link via ajax, returning content via egw_json_response->data() * - * This behavies like /index.php, but returns the content via json. + * This behaves like /index.php, but returns the content via json. * * @param string $link + * @param bool $dialog=false true ajax_exec is called to execute a popup in a dialog */ - public static function ajax_exec($link) + public static function ajax_exec($link, bool $dialog=false) { $parts = parse_url($link); $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] = $parts['path']; @@ -1130,20 +1131,23 @@ abstract class Ajax extends Api\Framework // dont send header and footer self::$header_done = self::$footer_done = true; - // flag to indicate target of output e.g. _tab - if ($_GET['fw_target']) + if (!$dialog) { - Api\Cache::unsetSession(__CLASS__,'sidebox_md5'); // sideboxes need to be send again - $GLOBALS['egw']->framework->set_extra('fw','target',$_GET['fw_target']); + // flag to indicate target of output e.g. _tab + if ($_GET['fw_target']) + { + Api\Cache::unsetSession(__CLASS__,'sidebox_md5'); // sideboxes need to be send again + $GLOBALS['egw']->framework->set_extra('fw','target',$_GET['fw_target']); + } + + // need to call do_sidebox, as header() with $header_done does NOT! + $GLOBALS['egw']->framework->do_sidebox(); + + // send Api\Preferences, so we dont need to request them in a second ajax request + $GLOBALS['egw']->framework->response->call('egw.set_preferences', + (array)$GLOBALS['egw_info']['user']['preferences'][$app], $app); } - // need to call do_sidebox, as header() with $header_done does NOT! - $GLOBALS['egw']->framework->do_sidebox(); - - // send Api\Preferences, so we dont need to request them in a second ajax request - $GLOBALS['egw']->framework->response->call('egw.set_preferences', - (array)$GLOBALS['egw_info']['user']['preferences'][$app], $app); - // call application menuaction ob_start(); $obj->$method(); diff --git a/calendar/inc/class.calendar_uiforms.inc.php b/calendar/inc/class.calendar_uiforms.inc.php index b8625e4fb0..37ee762108 100644 --- a/calendar/inc/class.calendar_uiforms.inc.php +++ b/calendar/inc/class.calendar_uiforms.inc.php @@ -671,10 +671,13 @@ class calendar_uiforms extends calendar_ui case 'exception': // create an exception in a recuring event $msg = $this->_create_exception($event,$preserv); break; + case 'edit': // Going from add dialog to full edit dialog unset($preserv['template']); unset($event['template']); + Api\Json\Response::get()->call('egw.open', '', 'calendar', 'edit', $event); + Framework::window_close(); break; case 'copy': // create new event with copied content, some content need to be unset to make a "new" event @@ -1151,12 +1154,7 @@ class calendar_uiforms extends calendar_ui $button == 'save' && $client_updated ? ($content['id'] ? $update_type : 'add') : 'delete' ); } - // Don't try to close quick add, it's not in a popup - if($content['template'] !== 'calendar.add') - { - Framework::window_close(); - } - exit(); + Framework::window_close(); } unset($event['no_notifications']); return $this->edit($event,$preserv,$msg,$event['id'] ? $event['id'] : $content['link_to']['to_id']); @@ -1562,8 +1560,8 @@ class calendar_uiforms extends calendar_ui if (!is_array($event)) { $preserv = array( - 'no_popup' => isset($_GET['no_popup']), - 'template' => isset($_GET['template']) ? $_GET['template'] : (isset($_REQUEST['print']) ? 'calendar.print' : 'calendar.edit'), + 'no_popup' => !empty($_GET['no_popup']), + 'template' => $_GET['template'] ?? (isset($_REQUEST['print']) ? 'calendar.print' : 'calendar.edit'), ); if(!isset($_REQUEST['print']) && !empty($preserv['template']) && $this->cal_prefs['new_event_dialog'] == 'edit') { diff --git a/calendar/js/app.ts b/calendar/js/app.ts index f26f0b1929..05a22c9e15 100644 --- a/calendar/js/app.ts +++ b/calendar/js/app.ts @@ -2057,170 +2057,16 @@ export class CalendarApp extends EgwApp //options.template = 'calendar.add'; return this.egw.open(null, 'calendar', 'edit', options, '_blank', 'calendar'); } - // Hold on to options, may have to pass them into edit (rather than all, just send what the programmer wanted) - this.quick_add = options; - - // Open dialog to use as target - let add_dialog; - - // Call the server, get it into the dialog - options = jQuery.extend({menuaction: 'calendar.calendar_uiforms.ajax_add', template: 'calendar.add'}, options); - this.egw.json( - this.egw.link('/json.php', options), - [options], - (data) => - { - if(Array.isArray(data) && typeof data[0] === 'string') - { - jQuery(data[0]).appendTo(document.body); - } - add_dialog = document.body.querySelector("et2-dialog"); - add_dialog.id = "quick-add"; - } - ).sendRequest(); - - add_dialog.addEventListener("close", (ev) => + let menuaction = 'calendar.calendar_uiforms.edit&template=calendar.add'; + for(const name in options) { - // Wait a bit to make sure etemplate button finishes processing, or it will error - window.setTimeout(function() - { - if(event && event.destroy) - { - event.destroy(); - } - let template = etemplate2.getById('calendar-add'); - if(template && template.name === 'calendar.add') - { - template.clear(); - delete app.calendar.quick_add; - } - else if(template || (template = etemplate2.getById("calendar-conflicts"))) - { - // Open conflicts - var data = jQuery.extend( - {menuaction: 'calendar.calendar_uiforms.ajax_conflicts'}, - template.widgetContainer.getArrayMgr('content').data, - app.calendar.quick_add - ); - - egw.openPopup( - egw.link( - '/index.php', - data - ), - 850, 300, - 'conflicts', 'calendar' - ); - - delete app.calendar.quick_add; - - // Do not submit this etemplate - return false; - } - - }.bind({dialog: add_dialog, event: ev}), 1000); - }); - } - - /** - * Callback for save button in add dialog - * - * @param {Event} event - * @param {et2_button} widget - * @returns {Boolean} - */ - add_dialog_save(event, widget) - { - // Include all sent values so we can pass on things that we don't have UI widgets for - this.quick_add = this._add_dialog_values(widget); - widget.getInstanceManager().isInvalid().then((invalid) => - { - if(invalid.filter((widget) => widget).length == 0) - { - // Close the dialog, if everything is OK - (document.querySelector('et2-dialog')).hide(); - } - }); - - // Mess with opener so update opener in response works - window.opener = window; - window.setTimeout(function() {window.opener = null;}, 1000); - - // Proceed with submit, though it will fail if something is invalid - return true; - } - - - /** - * Callback for edit button in add dialog - * - * @param {Event} event - * @param {et2_button} widget - * @returns {Boolean} - */ - add_dialog_edit(event, widget) - { - var title=widget.getRoot().getWidgetById('title'); - let options = jQuery.extend(this.quick_add, this._add_dialog_values(widget)); - - // Open regular edit - egw.open(null,'calendar','edit',options); - - // Close the dialog - (document.querySelector('et2-dialog#quick_add')).close() - - // Do not submit this etemplate - return false; - } - - /** - * Include some additional values so we can pass on things that we don't have - * UI widgets for in the add template - * - * @param {et2_widget} widget - * @returns {Object} - */ - _add_dialog_values(widget) - { - // Some select things to pass on, since not everything will fit - var mgr = widget.getRoot().getArrayMgr('content'); - var values : any = { - owner: typeof mgr.getEntry('owner') == 'object' ? mgr.getEntry('owner') : (mgr.getEntry('owner')+'').split(','), - participants: [], - whole_day: mgr.getEntry('whole_day') - }; - if(mgr.getEntry('link_to') && typeof mgr.getEntry('link_to').to_id === 'object') - { - var links = mgr.getEntry('link_to').to_id; - - values.link_app = []; - values.link_id = []; - for( var id in links) - { - values.link_app.push(links[id].app); - values.link_id.push(links[id].id); - } + menuaction += '&'+name+'='+encodeURIComponent(options[name]); } - for(var id in mgr.getEntry('participants')) - { - var participant = mgr.getEntry('participants')[id]; - if (participant && participant.uid) - { - values.participants.push(participant.uid); - } - } - let send = jQuery.extend( - values, - widget.getInstanceManager().getValues(widget.getRoot()) - ); - // Don't need the checkbox - delete send.new_event_dialog; - - return send; + return this.egw.openDialog(menuaction); } /** - * Open calendar entry, taking into accout the calendar integration of other apps + * Open calendar entry, taking into account the calendar integration of other apps * * calendar_uilist::get_rows sets var js_calendar_integration object * diff --git a/calendar/templates/default/add.xet b/calendar/templates/default/add.xet index 17951b0b45..29fac64885 100644 --- a/calendar/templates/default/add.xet +++ b/calendar/templates/default/add.xet @@ -24,9 +24,9 @@ - - - + + + \ No newline at end of file