diff --git a/api/js/etemplate/et2_extension_nextmatch.ts b/api/js/etemplate/et2_extension_nextmatch.ts index 421dfb6c33..0089fb75bf 100644 --- a/api/js/etemplate/et2_extension_nextmatch.ts +++ b/api/js/etemplate/et2_extension_nextmatch.ts @@ -2898,238 +2898,241 @@ export class et2_nextmatch extends et2_DOMWidget implements et2_IResizeable, et2 const total = this.controller._grid.getTotalCount(); // Defer the printing to ask about columns & rows - const defer = jQuery.Deferred(); - - - let pref = this.options.settings.columnselection_pref; - if(pref.indexOf('nextmatch') == 0) + return new Promise((resolve, reject) => { - pref = 'nextmatch-' + pref; - } - const app = this.getInstanceManager().app; - - const columns = {}; - const columnMgr = this.dataview.getColumnMgr(); - pref += '_print'; - const columns_selected = []; - - // Get column names - for(let i = 0; i < columnMgr.columns.length; i++) - { - const col = columnMgr.columns[i]; - const widget = this.columns[i].widget; - let colName = this._getColumnName(widget); - - if(col.caption && col.visibility !== et2_dataview_column.ET2_COL_VISIBILITY_ALWAYS_NOSELECT && - col.visibility !== et2_dataview_column.ET2_COL_VISIBILITY_DISABLED) + let pref = this.options.settings.columnselection_pref; + if (pref.indexOf('nextmatch') == 0) { - columns[colName] = col.caption; - if(col.visibility === et2_dataview_column.ET2_COL_VISIBILITY_VISIBLE) columns_selected.push(colName); + pref = 'nextmatch-' + pref; } - // Custom fields get listed separately - if(widget.instanceOf(et2_nextmatch_customfields)) + const app = this.getInstanceManager().app; + + const columns = {}; + const columnMgr = this.dataview.getColumnMgr(); + pref += '_print'; + const columns_selected = []; + + // Get column names + for (let i = 0; i < columnMgr.columns.length; i++) { - delete (columns[colName]); - colName = widget.id; - if(col.visibility === et2_dataview_column.ET2_COL_VISIBILITY_VISIBLE && ! - jQuery.isEmptyObject((widget).customfields) - ) + const col = columnMgr.columns[i]; + const widget = this.columns[i].widget; + let colName = this._getColumnName(widget); + + if (col.caption && col.visibility !== et2_dataview_column.ET2_COL_VISIBILITY_ALWAYS_NOSELECT && + col.visibility !== et2_dataview_column.ET2_COL_VISIBILITY_DISABLED) { columns[colName] = col.caption; - for(let field_name in (widget).customfields) - { - columns[et2_nextmatch_customfields.PREFIX + field_name] = " - " + (widget).customfields[field_name].label; - if(widget.options.fields[field_name] && columns_selected.indexOf(colName) >= 0) - { - columns_selected.push(et2_nextmatch_customfields.PREFIX + field_name); - } - } + if (col.visibility === et2_dataview_column.ET2_COL_VISIBILITY_VISIBLE) columns_selected.push(colName); } - } - } - - // Preference exists? Set it now - if(this.egw().preference(pref, app)) - { - this.set_columns(jQuery.extend([], this.egw().preference(pref, app))); - } - - const callback = function(button, value) - { - if(button === Et2Dialog.CANCEL_BUTTON) - { - // Give dialog a chance to close, or it will be in the print - window.setTimeout(function() + // Custom fields get listed separately + if (widget.instanceOf(et2_nextmatch_customfields)) { - defer.reject(); - }, 0); - return; - } - - // Set CSS for orientation - this.div.addClass(value.orientation); - this.egw().set_preference(app, pref + '_orientation', value.orientation); - - - // Try to tell browser about orientation - const css = '@page { size: ' + value.orientation + '; }', - head = document.head || document.getElementsByTagName('head')[0], - style = document.createElement('style'); - - style.type = 'text/css'; - style.media = 'print'; - - // @ts-ignore - if(style.styleSheet) - { - // @ts-ignore - style.styleSheet.cssText = css; - } - else - { - style.appendChild(document.createTextNode(css)); - } - - head.appendChild(style); - this.print.orientation_style = style; - - // Trigger resize, so we can fit on a page - this.dynheight.outerNode.css('max-width', this.div.css('max-width')); - - // Handle columns - this.set_columns(value.columns); - this.egw().set_preference(app, pref, value.columns); - - let rows = parseInt(value.row_count); - if(rows > total) - { - rows = total; - } - - // If they want the whole thing, style it as all - if(button === Et2Dialog.OK_BUTTON && rows == this.controller._grid.getTotalCount()) - { - // Add the class, gives more reliable sizing - this.div.addClass('print'); - // Show it all - jQuery('.egwGridView_scrollarea', this.div).css('height', 'auto'); - } - // We need more rows - if(button === 'dialog[all]' || rows > loaded_count) - { - let count = 0; - let fetchedCount = 0; - let cancel = false; - const nm = this; - const dialog = Et2Dialog.show_dialog( - // Abort the long task if they canceled the data load - function() + delete (columns[colName]); + colName = widget.id; + if (col.visibility === et2_dataview_column.ET2_COL_VISIBILITY_VISIBLE && ! + jQuery.isEmptyObject((widget).customfields) + ) { - count = total; - cancel = true; - window.setTimeout(function() + columns[colName] = col.caption; + for (let field_name in (widget).customfields) { - defer.reject(); - }, 0); - }, - egw.lang('Loading'), egw.lang('please wait...'), {}, [ - {"button_id": Et2Dialog.CANCEL_BUTTON, label: 'cancel', id: 'dialog[cancel]', image: 'cancel'} - ] - ); - - // dataFetch() is asynchronous, so all these requests just get fired off... - // 200 rows chosen arbitrarily to reduce requests. - do - { - const ctx = { - "self": this.controller, - "start": count, - "count": Math.min(rows, 200), - "lastModification": this.controller._lastModification - }; - if(nm.controller.dataStorePrefix) - { - // @ts-ignore - ctx.prefix = nm.controller.dataStorePrefix; - } - nm.controller.dataFetch({start: count, num_rows: Math.min(rows, 200)}, function(data) - { - // Keep track - if(data && data.order) - { - fetchedCount += data.order.length; - } - nm.controller._fetchCallback.apply(this, arguments); - - if(fetchedCount >= rows) - { - if(cancel) + columns[et2_nextmatch_customfields.PREFIX + field_name] = " - " + (widget).customfields[field_name].label; + if (widget.options.fields[field_name] && columns_selected.indexOf(colName) >= 0) { - dialog.destroy(); - defer.reject(); - return; + columns_selected.push(et2_nextmatch_customfields.PREFIX + field_name); } - // Use CSS to hide all but the requested rows - // Prevents us from showing more than requested, if actual height was less than average - nm.print.row_selector = ".egwGridView_grid > tbody > tr:not(:nth-child(-n+" + rows + "))"; - egw.css(nm.print.row_selector, 'display: none'); - - // No scrollbar in print view - jQuery('.egwGridView_scrollarea', this.div).css('overflow-y', 'hidden'); - // Show it all - jQuery('.egwGridView_scrollarea', this.div).css('height', 'auto'); - - // Grid needs to redraw before it can be printed, so wait - window.setTimeout(function() - { - dialog.close(); - - // Should be OK to print now - defer.resolve(); - }.bind(nm), et2_dataview_grid.ET2_GRID_INVALIDATE_TIMEOUT); - } - - }, ctx); - count += 200; + } } - while(count < rows); - nm.controller._grid.setScrollHeight(nm.controller._grid.getAverageHeight() * (rows + 1)); } - else + + // Preference exists? Set it now + if (this.egw().preference(pref, app)) { - // Don't need more rows, limit to requested and finish + this.set_columns(jQuery.extend([], this.egw().preference(pref, app))); + } - // Show it all - jQuery('.egwGridView_scrollarea', this.div).css('height', 'auto'); - - // Use CSS to hide all but the requested rows - // Prevents us from showing more than requested, if actual height was less than average - this.print.row_selector = ".egwGridView_grid > tbody > tr:not(:nth-child(-n+" + rows + "))"; - egw.css(this.print.row_selector, 'display: none'); - - // No scrollbar in print view - jQuery('.egwGridView_scrollarea', this.div).css('overflow-y', 'hidden'); - // Give dialog a chance to close, or it will be in the print - window.setTimeout(function() + const callback = function (button, value) + { + if (button === Et2Dialog.CANCEL_BUTTON) { - defer.resolve(); - }, 0); - } - }.bind(this); - var value = { - content: { - row_count: Math.min(100, total), - columns: this.egw().preference(pref, app) || columns_selected, - orientation: this.egw().preference(pref + '_orientation', app) - }, - sel_options: { - columns: columns - } - }; - this._create_print_dialog.call(this, value, callback); + // Give dialog a chance to close, or it will be in the print + window.setTimeout(function () + { + reject(); + }, 0); + return; + } - return defer; + // Set CSS for orientation + this.div.addClass(value.orientation); + this.egw().set_preference(app, pref + '_orientation', value.orientation); + + + // Try to tell browser about orientation + const css = '@page { size: ' + value.orientation + '; }', + head = document.head || document.getElementsByTagName('head')[0], + style = document.createElement('style'); + + style.type = 'text/css'; + style.media = 'print'; + + // @ts-ignore + if (style.styleSheet) + { + // @ts-ignore + style.styleSheet.cssText = css; + } + else + { + style.appendChild(document.createTextNode(css)); + } + + head.appendChild(style); + this.print.orientation_style = style; + + // Trigger resize, so we can fit on a page + this.dynheight.outerNode.css('max-width', this.div.css('max-width')); + + // Handle columns + this.set_columns(value.columns); + this.egw().set_preference(app, pref, value.columns); + + let rows = parseInt(value.row_count); + if (rows > total) + { + rows = total; + } + + // If they want the whole thing, style it as all + if (button === Et2Dialog.OK_BUTTON && rows == this.controller._grid.getTotalCount()) + { + // Add the class, gives more reliable sizing + this.div.addClass('print'); + // Show it all + jQuery('.egwGridView_scrollarea', this.div).css('height', 'auto'); + } + // We need more rows + if (button === 'dialog[all]' || rows > loaded_count) + { + let count = 0; + let fetchedCount = 0; + let cancel = false; + const nm = this; + const dialog = Et2Dialog.show_dialog( + // Abort the long task if they canceled the data load + function () + { + count = total; + cancel = true; + window.setTimeout(function () + { + reject(); + }, 0); + }, + egw.lang('Loading'), egw.lang('please wait...'), {}, [ + { + "button_id": Et2Dialog.CANCEL_BUTTON, + label: 'cancel', + id: 'dialog[cancel]', + image: 'cancel' + } + ] + ); + + // dataFetch() is asynchronous, so all these requests just get fired off... + // 200 rows chosen arbitrarily to reduce requests. + do + { + const ctx = { + "self": this.controller, + "start": count, + "count": Math.min(rows, 200), + "lastModification": this.controller._lastModification + }; + if (nm.controller.dataStorePrefix) + { + // @ts-ignore + ctx.prefix = nm.controller.dataStorePrefix; + } + nm.controller.dataFetch({start: count, num_rows: Math.min(rows, 200)}, function (data) + { + // Keep track + if (data && data.order) + { + fetchedCount += data.order.length; + } + nm.controller._fetchCallback.apply(this, arguments); + + if (fetchedCount >= rows) + { + if (cancel) + { + dialog.destroy(); + reject(); + return; + } + // Use CSS to hide all but the requested rows + // Prevents us from showing more than requested, if actual height was less than average + nm.print.row_selector = ".egwGridView_grid > tbody > tr:not(:nth-child(-n+" + rows + "))"; + egw.css(nm.print.row_selector, 'display: none'); + + // No scrollbar in print view + jQuery('.egwGridView_scrollarea', this.div).css('overflow-y', 'hidden'); + // Show it all + jQuery('.egwGridView_scrollarea', this.div).css('height', 'auto'); + + // Grid needs to redraw before it can be printed, so wait + window.setTimeout(function () + { + dialog.close(); + + // Should be OK to print now + resolve(); + }.bind(nm), et2_dataview_grid.ET2_GRID_INVALIDATE_TIMEOUT); + + } + + }, ctx); + count += 200; + } + while (count < rows); + nm.controller._grid.setScrollHeight(nm.controller._grid.getAverageHeight() * (rows + 1)); + } + else + { + // Don't need more rows, limit to requested and finish + + // Show it all + jQuery('.egwGridView_scrollarea', this.div).css('height', 'auto'); + + // Use CSS to hide all but the requested rows + // Prevents us from showing more than requested, if actual height was less than average + this.print.row_selector = ".egwGridView_grid > tbody > tr:not(:nth-child(-n+" + rows + "))"; + egw.css(this.print.row_selector, 'display: none'); + + // No scrollbar in print view + jQuery('.egwGridView_scrollarea', this.div).css('overflow-y', 'hidden'); + // Give dialog a chance to close, or it will be in the print + window.setTimeout(function () + { + resolve(); + }, 0); + } + }.bind(this); + var value = { + content: { + row_count: Math.min(100, total), + columns: this.egw().preference(pref, app) || columns_selected, + orientation: this.egw().preference(pref + '_orientation', app) + }, + sel_options: { + columns: columns + } + }; + this._create_print_dialog.call(this, value, callback); + }); } /** @@ -3592,7 +3595,7 @@ export class et2_nextmatch_header_bar extends et2_DOMWidget implements et2_INext header.loadingFinished(deferred); // Wait until all child widgets are loaded, then bind - jQuery.when.apply(jQuery, deferred).then(function() + Promise.all(deferred).then(() => { // fix order in DOM by reattaching templates in correct position switch(id) diff --git a/api/js/etemplate/et2_widget_description.ts b/api/js/etemplate/et2_widget_description.ts index b68e8d9f1c..d77bc271bb 100644 --- a/api/js/etemplate/et2_widget_description.ts +++ b/api/js/etemplate/et2_widget_description.ts @@ -180,18 +180,19 @@ export class et2_description extends expose(class et2_description extends et2_ba else { // Target widget is not done yet, need to wait - var tab_deferred = jQuery.Deferred(); - window.setTimeout(function() { - for_id = for_widget.dom_id; - if(for_widget.instanceOf(et2_inputWidget) && for_widget.getInputNode() && for_widget.dom_id !== for_widget.getInputNode()?.id) + return new Promise((resolve) => + { + window.setTimeout(() => { - for_id = for_widget.getInputNode().id; - } - this.span.attr("for", for_id); - tab_deferred.resolve(); - }.bind(this),0); - - return tab_deferred.promise(); + for_id = for_widget.dom_id; + if (for_widget.instanceOf(et2_inputWidget) && for_widget.getInputNode() && for_widget.dom_id !== for_widget.getInputNode()?.id) + { + for_id = for_widget.getInputNode().id; + } + this.span.attr("for", for_id); + resolve(); + }, 0); + }); } } return true; @@ -199,7 +200,7 @@ export class et2_description extends expose(class et2_description extends et2_ba set_label(_value) { - // Abort if ther was no change in the label + // Abort if there was no change in the label if (_value == this.label) { return; @@ -443,4 +444,4 @@ export class et2_description extends expose(class et2_description extends et2_ba }); } }){}; -et2_register_widget(et2_description, ["description", "label"]); +et2_register_widget(et2_description, ["description", "label"]); \ No newline at end of file diff --git a/api/js/etemplate/et2_widget_split.ts b/api/js/etemplate/et2_widget_split.ts index aa52aca726..565cbf719d 100644 --- a/api/js/etemplate/et2_widget_split.ts +++ b/api/js/etemplate/et2_widget_split.ts @@ -96,9 +96,6 @@ export class et2_split extends et2_DOMWidget implements et2_IResizeable, et2_IPr this.left = jQuery("
Top / Left
").appendTo(this.div); this.right = jQuery("
Bottom / Right
").appendTo(this.div); - // Deferred object so we can wait for children - this.loading = jQuery.Deferred(); - // Flag to temporarily ignore resizing this.stop_resize = false; } @@ -163,21 +160,18 @@ export class et2_split extends et2_DOMWidget implements et2_IResizeable, et2_IPr { super.doLoadingFinished(); - // Use a timeout to give the children a chance to finish - var self = this; - window.setTimeout(function() { - self._init_splitter(); - },1); - // Not done yet, but widget will let you know - return this.loading.promise(); + return new Promise((resolve) => { + // Use a timeout to give the children a chance to finish + window.setTimeout(() => this._init_splitter(resolve),1); + }); } /** * Initialize the splitter UI * Internal. */ - private _init_splitter() + private _init_splitter(resolve? : Function) { if(!this.isAttached()) return; @@ -299,10 +293,10 @@ export class et2_split extends et2_DOMWidget implements et2_IResizeable, et2_IPr // Ok, update children self.iterateOver(function(widget) { // Extra resize would cause stalling chrome - // as resize might confilict with bottom download bar + // as resize might conflict with bottom download bar // in chrome which does a window resize, so better to not // trigger second resize and leave that to an application - // if it is neccessary. + // if it is necessary. // Above forcing is not enough for Firefox, defer window.setTimeout(jQuery.proxy(function() {this.resize();}, widget),200); @@ -310,7 +304,7 @@ export class et2_split extends et2_DOMWidget implements et2_IResizeable, et2_IPr }); } - this.loading.resolve(); + if (resolve) resolve(); } /** @@ -459,5 +453,4 @@ export class et2_split extends et2_DOMWidget implements et2_IResizeable, et2_IPr this.stop_resize = false; } } -et2_register_widget(et2_split, ["split"]); - +et2_register_widget(et2_split, ["split"]); \ No newline at end of file