diff --git a/api/js/etemplate/Et2Dialog/Et2Dialog.ts b/api/js/etemplate/Et2Dialog/Et2Dialog.ts index f2c7e8c8dd..d4c3fd73a7 100644 --- a/api/js/etemplate/Et2Dialog/Et2Dialog.ts +++ b/api/js/etemplate/Et2Dialog/Et2Dialog.ts @@ -477,7 +477,7 @@ export class Et2Dialog extends Et2Widget(SlotMixin(SlDialog)) */ close() { - this.hide(); + return this.hide(); } addOpenListeners() diff --git a/api/js/etemplate/etemplate2.ts b/api/js/etemplate/etemplate2.ts index e610d60218..812b4d040f 100644 --- a/api/js/etemplate/etemplate2.ts +++ b/api/js/etemplate/etemplate2.ts @@ -146,6 +146,7 @@ import './et2_extension_nextmatch'; import './et2_extension_customfields'; import './vfsSelectUI'; import {Et2Tabs} from "./Layout/Et2Tabs/Et2Tabs"; +import {Et2Dialog} from "./Et2Dialog/Et2Dialog"; /** @@ -317,7 +318,7 @@ export class etemplate2 */ public clear(_keep_app_object? : boolean, _keep_session? : boolean) { - jQuery(this._DOMContainer).trigger('clear'); + this.DOMContainer.dispatchEvent(new Event("clear", {bubbles: true})); // Remove any handlers on window (resize) if(this.uniqueId) @@ -1516,7 +1517,9 @@ export class etemplate2 // Check the parameters const data = _response.data; // window-close does NOT send data.DOMNodeID! - const dialog = document.querySelector('et2-dialog > form'+(data.DOMNodeID?'#'+data.DOMNodeID:'.dialog_content'))?.parentNode; + const dialog = document.querySelector('et2-dialog > form' + (data.DOMNodeID ? '#' + data.DOMNodeID : '.dialog_content'))?.parentNode ?? + // Reloaded into same container + (this?.DOMContainer?.parentNode instanceof Et2Dialog ? this.DOMContainer.parentNode : undefined); if (dialog) { @@ -1527,7 +1530,7 @@ export class etemplate2 // handle Api\Framework::refresh_opener() if(Array.isArray(data['refresh-opener'])) { - if(window.opener)// && typeof window.opener.egw_refresh == 'function') + if(window.opener || dialog)// && typeof window.opener.egw_refresh == 'function') { const egw = window.egw(dialog ? window : opener); egw.refresh.apply(egw, data['refresh-opener']); @@ -1564,9 +1567,7 @@ export class etemplate2 } if (dialog) { - dialog.close(); - dialog.parentNode.removeChild(dialog); - return Promise.resolve(); + return dialog.close(); } egw.close(); return true; @@ -1592,14 +1593,16 @@ export class etemplate2 // regular et2 re-load if(typeof data.url == "string" && typeof data.data === 'object') { + let load : Promise; // @ts-ignore if(this && typeof this.load == 'function') { // Called from etemplate // set id in case serverside returned a different template this._DOMContainer.id = this.uniqueId = data.DOMNodeID; + // @ts-ignore - return this.load(data.name, data.url, data.data); + load = this.load(data.name, data.url, data.data); } else { @@ -1623,20 +1626,30 @@ export class etemplate2 uniqueId = data.DOMNodeID.replace('.', '-') + '-' + data['open_target']; } const et2 = new etemplate2(node, data.data.menuaction, uniqueId); - return et2.load(data.name, data.url, data.data, null, null, null, data['fw-target']) - .then(() => - { - if(dialog) - { - dialog._adoptTemplateButtons(); - } - }); + load = et2.load(data.name, data.url, data.data, null, null, null, data['fw-target']); } else { egw.debug("error", "Could not find target node %s", data.DOMNodeId); } } + + // Extra handling for being loaded into a Et2Dialog + if(dialog) + { + load.then(() => + { + // Move footer type buttons into dialog footer + const buttons = dialog._adoptTemplateButtons(); + + // Make sure adopted buttons are removed on clear + dialog.addEventListener("clear", () => + { + buttons.forEach(n => n.remove()); + }); + }); + } + return load; } throw("Error while parsing et2_load response"); diff --git a/api/js/jsapi/egw_app.ts b/api/js/jsapi/egw_app.ts index 6492cd9a19..f603d03c70 100644 --- a/api/js/jsapi/egw_app.ts +++ b/api/js/jsapi/egw_app.ts @@ -751,25 +751,43 @@ export abstract class EgwApp /** * Opens _menuaction in an Et2Dialog * - * Equivalent to egw.openDialog, thought this one works in popups too. + * Equivalent to egw.openDialog, though this one works in popups too. * * @param _menuaction - * @return Promise + * @return Promise */ openDialog(_menuaction : string) { - return this.egw.json(_menuaction.match(/^([^.:]+)/)[0] + '.jdots_framework.ajax_exec.template.' + _menuaction, + let resolver; + let rejector; + const dialog_promise = new Promise((resolve, reject) => + { + resolver = value => resolve(value); + rejector = reason => reject(reason); + }); + let request = 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') + if(Array.isArray(_response) && typeof _response[0] === 'string') { - jQuery(_response[0]).appendTo(document.body); + let dialog = jQuery(_response[0]).appendTo(document.body); + if(dialog.length > 0 && dialog.get(0)) + { + resolver(dialog.get(0)); + } + else + { + console.log("Unable to add dialog with dialogExec('" + _menuaction + "')", _response); + rejector(new Error("Unable to add dialog")); + } } else { - console.log("Invalid response to dialogExec('"+_menuaction+"')", _response); + console.log("Invalid response to dialogExec('" + _menuaction + "')", _response); + rejector(new Error("Invalid response to dialogExec('" + _menuaction + "')")); } }).sendRequest(); + return dialog_promise; } /** diff --git a/api/js/jsapi/egw_open.js b/api/js/jsapi/egw_open.js index 63209bfda1..b3bdfe92fb 100644 --- a/api/js/jsapi/egw_open.js +++ b/api/js/jsapi/egw_open.js @@ -386,22 +386,40 @@ egw.extend('open', egw.MODULE_WND_LOCAL, function(_egw, _wnd) * 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 + * @return Promise */ openDialog: function(_menuaction) { - return this.json(_menuaction.match(/^([^.:]+)/)[0] + '.jdots_framework.ajax_exec.template.' + _menuaction, + let resolver; + let rejector; + const dialog_promise = new Promise((resolve, reject) => + { + resolver = value => resolve(value); + rejector = reason => reject(reason); + }); + let request = 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') { - jQuery(_response[0]).appendTo(_wnd.document.body); + let dialog = jQuery(_response[0]).appendTo(_wnd.document.body); + if (dialog.length > 0 && dialog.get(0)) + { + resolver(dialog.get(0)); + } + else + { + console.log("Unable to add dialog with dialogExec('" + _menuaction + "')", _response); + rejector(new Error("Unable to add dialog")); + } } else { - console.log("Invalid response to dialogExec('"+_menuaction+"')", _response); + console.log("Invalid response to dialogExec('" + _menuaction + "')", _response); + rejector(new Error("Invalid response to dialogExec('" + _menuaction + "')")); } }).sendRequest(); + return dialog_promise; }, /**