diff --git a/api/js/etemplate/et2_widget_dialog.ts b/api/js/etemplate/et2_widget_dialog.ts
index f0de722f2b..d303ae65fd 100644
--- a/api/js/etemplate/et2_widget_dialog.ts
+++ b/api/js/etemplate/et2_widget_dialog.ts
@@ -8,902 +8,12 @@
* @copyright Nathan Gray 2013
*/
-/*egw:uses
- et2_core_widget;
- /vendor/bower-asset/jquery-ui/jquery-ui.js;
-*/
-
-import {et2_createWidget, et2_register_widget, et2_widget, WidgetConfig} from "./et2_core_widget";
-import {et2_button} from "./et2_widget_button";
-import {ClassWithAttributes} from "./et2_core_inheritance";
-import {etemplate2} from "./etemplate2";
-import {egw, IegwAppLocal} from "../jsapi/egw_global";
-import {et2_no_init} from "./et2_core_common";
+import {Et2Dialog} from "./Et2Dialog/Et2Dialog";
/**
- * A common dialog widget that makes it easy to imform users or prompt for information.
- *
- * It is possible to have a custom dialog by using a template, but you can also use
- * the static method et2_dialog.show_dialog(). At its simplest, you can just use:
- *
- * et2_dialog.show_dialog(false, "Operation completed");
- *
- * Or a more complete example:
- *
- * var callback = function (button_id)
- * {
- * if(button_id == et2_dialog.YES_BUTTON)
- * {
- * // Do stuff
- * }
- * else if (button_id == et2_dialog.NO_BUTTON)
- * {
- * // Other stuff
- * }
- * else if (button_id == et2_dialog.CANCEL_BUTTON)
- * {
- * // Abort
- * }
- * }.
- * var dialog = et2_dialog.show_dialog(
- * callback, "Erase the entire database?","Break things", {} // value
- * et2_dialog.BUTTONS_YES_NO_CANCEL, et2_dialog.WARNING_MESSAGE
- * );
- *
- *
- *
- * The parameters for the above are all optional, except callback and message:
- * callback - function called when the dialog closes, or false/null.
- * The ID of the button will be passed. Button ID will be one of the et2_dialog.*_BUTTON constants.
- * The callback is _not_ called if the user closes the dialog with the X in the corner, or presses ESC.
- * message - (plain) text to display
- * title - Dialog title
- * value (for prompt)
- * buttons - et2_dialog BUTTONS_* constant, or an array of button settings
- * dialog_type - et2_dialog *_MESSAGE constant
- * icon - URL of icon
- *
- * Note that these methods will _not_ block program flow while waiting for user input.
- * The user's input will be provided to the callback.
- *
- * You can also use the standard et2_createWidget() to create a custom dialog using an etemplate, even setting all
- * the buttons yourself.
- *
- * var dialog = et2_createWidget("dialog",{
- * // If you use a template, the second parameter will be the value of the template, as if it were submitted.
- * callback: function(button_id, value) {...}, // return false to prevent dialog closing
- * buttons: [
- * // These ones will use the callback, just like normal
- * {text: egw.lang("OK"),id:"OK", class="ui-priority-primary", default: true},
- * {text: egw.lang("Yes"),id:"Yes"},
- * {text: egw.lang("Sure"),id:"Sure"},
- * {text: egw.lang("Maybe"),click: function() {
- * // If you override, 'this' will be the dialog DOMNode.
- * // Things get more complicated.
- * // Do what you like, but don't forget this line:
- * jQuery(this).dialog("close")
- * }, class="ui-state-error"},
- *
- * ],
- * title: 'Why would you want to do this?',
- * template:"/egroupware/addressbook/templates/default/edit.xet",
- * value: { content: {...default values}, sel_options: {...}...}
- * });
- *
- * @augments et2_widget
- * @see http://api.jqueryui.com/dialog/
+ * Just a stub that wraps Et2Dialog
+ * @deprecated
*/
-export class et2_dialog extends et2_widget {
- static readonly _attributes: any = {
- callback: {
- name: "Callback",
- type: "js",
- description: "Callback function is called with the value when the dialog is closed",
- "default": function (button_id) {
- egw.debug("log", "Button ID: %d", button_id);
- }
- },
- beforeClose: {
- name: "before close callback",
- type: "js",
- description: "Callback function before dialog is closed, return false to prevent that",
- "default": function () {
- }
- },
- message: {
- name: "Message",
- type: "string",
- description: "Dialog message (plain text, no html)",
- "default": "Somebody forgot to set this..."
- },
- dialog_type: {
- name: "Dialog type",
- type: "integer",
- description: "To use a pre-defined dialog style, use et2_dialog.ERROR_MESSAGE, INFORMATION_MESSAGE,WARNING_MESSAGE,QUESTION_MESSAGE,PLAIN_MESSAGE constants. Default is et2_dialog.PLAIN_MESSAGE",
- "default": 0 //this.PLAIN_MESSAGE
- },
- buttons: {
- name: "Buttons",
- type: "any",
- "default": 0, //this.BUTTONS_OK,
- description: "Buttons that appear at the bottom of the dialog. You can use the constants et2_dialog.BUTTONS_OK, BUTTONS_YES_NO, BUTTONS_YES_NO_CANCEL, BUTTONS_OK_CANCEL, or pass in an array for full control"
- },
- icon: {
- name: "Icon",
- type: "string",
- description: "URL of an icon for the dialog. If omitted, an icon based on dialog_type will be used.",
- "default": ""
- },
- title: {
- name: "Title",
- type: "string",
- description: "Title for the dialog box (plain text, no html)",
- "default": ""
- },
- modal: {
- name: "Modal",
- type: "boolean",
- description: "Prevent the user from interacting with the page",
- "default": true
- },
- resizable: {
- name: "Resizable",
- type: "boolean",
- description: "Allow the user to resize the dialog",
- "default": true
- },
- value: {
- "name": "Value",
- "description": "The (default) value of the dialog. Use with template.",
- "type": "any",
- "default": et2_no_init
- },
- template: {
- "name": "Template",
- "description": "Instead of displaying a simple message, a full template can be loaded instead. Set defaults with value.",
- "type": "string",
- "default": et2_no_init
- },
- minWidth: {
- name: "minimum width",
- type: "integer",
- description: "Define minimum width of dialog",
- "default": 0
- },
- minHeight: {
- name: "minimum height",
- type: "integer",
- description: "Define minimum height of dialog",
- "default": 0
- },
- width: {
- name: "width",
- type: "string",
- description: "Define width of dialog, the default is auto",
- "default": et2_no_init
- },
- height: {
- name: "height",
- type: "string",
- description: "Define width of dialog, the default is auto",
- "default": 'auto'
- },
- position: {
- name: "position",
- type: "string",
- description: "Define position of dialog in the main window",
- default: "center"
- },
- appendTo: {
- name: "appendTo",
- type: "string",
- description: "Defines the dialog parent context",
- default: ''
- },
- draggable: {
- name: "Draggable",
- type: "boolean",
- description: "Allow the user to drag the dialog",
- default: true
- },
- closeOnEscape: {
- name: "close on escape",
- type: "boolean",
- description: "Allow the user to close the dialog by hiting escape",
- default: true
- },
- dialogClass: {
- name: "dialog class",
- type: "string",
- description: "Add css classed into dialog container",
- default: ''
- }
- };
-
- /**
- * Details for dialog type options
- */
- private readonly _dialog_types: any = [
- //PLAIN_MESSAGE: 0
- "",
- //INFORMATION_MESSAGE: 1,
- "dialog_info",
- //QUESTION_MESSAGE: 2,
- "dialog_help",
- //WARNING_MESSAGE: 3,
- "dialog_warning",
- //ERROR_MESSAGE: 4,
- "dialog_error"
- ];
-
- private readonly _buttons: any = [
- /*
- Pre-defined Button combos
- - button ids copied from et2_dialog static, since the constants are not defined yet
- - image get replaced by 'style="background-image: url('+egw.image(image)+')' for an image prefixing text
- */
- //BUTTONS_OK: 0,
- [{"button_id": 1, "text": 'ok', id: 'dialog[ok]', image: 'check', "default": true}],
- //BUTTONS_OK_CANCEL: 1,
- [
- {"button_id": 1, "text": 'ok', id: 'dialog[ok]', image: 'check', "default": true},
- {"button_id": 0, "text": 'cancel', id: 'dialog[cancel]', image: 'cancel'}
- ],
- //BUTTONS_YES_NO: 2,
- [
- {"button_id": 2, "text": 'yes', id: 'dialog[yes]', image: 'check', "default": true},
- {"button_id": 3, "text": 'no', id: 'dialog[no]', image: 'cancelled'}
- ],
- //BUTTONS_YES_NO_CANCEL: 3,
- [
- {"button_id": 2, "text": 'yes', id: 'dialog[yes]', image: 'check', "default": true},
- {"button_id": 3, "text": 'no', id: 'dialog[no]', image: 'cancelled'},
- {"button_id": 0, "text": 'cancel', id: 'dialog[cancel]', image: 'cancel'}
- ]
- ];
-
- /**
- * Types
- * @constant
- */
- public static PLAIN_MESSAGE: number = 0;
- public static INFORMATION_MESSAGE: number = 1;
- public static QUESTION_MESSAGE: number = 2;
- public static WARNING_MESSAGE: number = 3;
- public static ERROR_MESSAGE: number = 4;
-
- /* Pre-defined Button combos */
- public static BUTTONS_OK: number = 0;
- public static BUTTONS_OK_CANCEL: number = 1;
- public static BUTTONS_YES_NO: number = 2;
- public static BUTTONS_YES_NO_CANCEL: number = 3;
-
- /* Button constants */
- public static CANCEL_BUTTON: number = 0;
- public static OK_BUTTON: number = 1;
- public static YES_BUTTON: number = 2;
- public static NO_BUTTON: number = 3;
-
- div: JQuery = null;
- template: etemplate2 = null;
-
- constructor(_parent?, _attrs? : WidgetConfig, _child? : object) {
- super(_parent, _attrs, ClassWithAttributes.extendAttributes(et2_dialog._attributes, _child || {}));
-
- // Define this as null to avoid breaking any hierarchies (eg: destroy())
- if (this.getParent() != null) this.getParent().removeChild(this);
-
- // Button callbacks need a reference to this
- let self = this;
- for (let i = 0; i < this._buttons.length; i++) {
- for (let j = 0; j < this._buttons[i].length; j++) {
- this._buttons[i][j].click = (function (id) {
- return function (event) {
- self.click(event.target, id);
- };
- })(this._buttons[i][j].button_id);
- // translate button texts, as translations are not available before
- this._buttons[i][j].text = egw.lang(this._buttons[i][j].text);
- }
- }
-
- this.div = jQuery(document.createElement("div"));
-
- this._createDialog();
- }
-
- /**
- * Clean up dialog
- */
- destroy() {
- if (this.div != null) {
- // Un-dialog the dialog
- this.div.dialog("destroy");
-
- if (this.template) {
- // if the dialog has an etemplate_exec_id, like the vfs select dialog, we must NOT delete the server-side
- // et2 session, as the exec-id is NOT from the dialog, but some other template
- this.template.clear(true, true);
- this.template = null;
- }
-
- this.div = null;
- }
-
- // Call the inherited constructor
- super.destroy();
- }
-
- /**
- * Internal callback registered on all standard buttons.
- * The provided callback is called after the dialog is closed.
- *
- * @param target DOMNode The clicked button
- * @param button_id integer The ID of the clicked button
- */
- click(target: HTMLElement, button_id: number) {
- if (this.options.callback) {
- if (this.options.callback.call(this, button_id, this.get_value()) === false) return;
- }
- // Triggers destroy too
- this.div.dialog("close");
- }
-
- /**
- * Returns the values of any widgets in the dialog. This does not include
- * the buttons, which are only supplied for the callback.
- */
- get_value() {
- var value = this.options.value;
- if (this.template) {
- value = this.template.getValues(this.template.widgetContainer);
- }
- return value;
- }
-
- /**
- * Set the displayed prompt message
- *
- * @param {string} message New message for the dialog
- */
- set_message(message) {
- this.options.message = message;
-
- this.div.empty()
- .append("")
- .append(jQuery('
').text(message));
- }
-
- /**
- * Set the dialog type to a pre-defined type
- *
- * @param {integer} type constant from et2_dialog
- */
- set_dialog_type(type) {
- if (this.options.dialog_type != type && typeof this._dialog_types[type] == "string") {
- this.options.dialog_type = type;
- }
- this.set_icon(this._dialog_types[type] ? egw.image(this._dialog_types[type]) : "");
- }
-
- /**
- * Set the icon for the dialog
- *
- * @param {string} icon_url
- */
- set_icon(icon_url) {
- if (icon_url == "") {
- jQuery("img.dialog_icon", this.div).hide();
- } else {
- jQuery("img.dialog_icon", this.div).show().attr("src", icon_url);
- }
- }
-
- /**
- * Set the dialog buttons
- *
- * Use either the pre-defined options in et2_dialog, or an array
- * @see http://api.jqueryui.com/dialog/#option-buttons
- * @param {array} buttons
- */
- set_buttons(buttons) {
- this.options.buttons = buttons;
- if (buttons instanceof Array) {
- for (var i = 0; i < buttons.length; i++) {
- var button = buttons[i];
- if (!button.click) {
- button.click = jQuery.proxy(this.click, this, null, button.id);
- }
- // set a default background image and css class based on buttons id
- if (button.id && typeof button.class == 'undefined') {
- for (var name in et2_button.default_classes) {
- if (button.id.match(et2_button.default_classes[name])) {
- button.class = (typeof button.class == 'undefined' ? '' : button.class + ' ') + name;
- break;
- }
- }
- }
- if (button.id && typeof button.image == 'undefined' && typeof button.style == 'undefined') {
- for (var name in et2_button.default_background_images) {
- if (button.id.match(et2_button.default_background_images[name])) {
- button.image = name;
- break;
- }
- }
- }
- if (button.image) {
- button.style = 'background-image: url(' +
- (button.image.match('^http|\/') ?
- button.image : this.egw().image(button.image, 'api'))
- + ')';
- delete button.image;
- }
- }
- }
-
- // If dialog already created, update buttons
- if (this.div.data('ui-dialog')) {
- this.div.dialog("option", "buttons", buttons);
-
- // Focus default button so enter works
- jQuery('.ui-dialog-buttonpane button[default]', this.div.parent()).focus();
- }
- }
-
- /**
- * Set the dialog title
- *
- * @param {string} title New title for the dialog
- */
- set_title(title) {
- this.options.title = title;
- this.div.dialog("option", "title", title);
- }
-
- /**
- * Block interaction with the page behind the dialog
- *
- * @param {boolean} modal Block page behind dialog
- */
- set_modal(modal) {
- this.options.modal = modal;
- this.div.dialog("option", "modal", modal);
- }
-
- /**
- * Load an etemplate into the dialog
- *
- * @param template String etemplate file name
- */
- set_template(template) {
- if (this.template && this.options.template != template) {
- this.template.clear();
- }
-
- this.template = new etemplate2(this.div[0]);
- if (template.indexOf('.xet') > 0) {
- // File name provided, fetch from server
- this.template.load("", template, this.options.value || {content: {}}, jQuery.proxy(function () {
- // Set focus to the first input
- jQuery('input', this.div).first().focus();
- }, this));
- } else {
- // Just template name, it better be loaded already
- this.template.load(template, '', this.options.value || {},
- // true: do NOT call et2_ready, as it would overwrite this.et2 in app.js
- undefined, undefined, true);
- }
-
- // Don't let dialog closing destroy the parent session
- if(this.template.etemplate_exec_id && this.template.app)
- {
- for(let et of etemplate2.getByApplication(this.template.app))
- {
- if(et !== this.template && et.etemplate_exec_id === this.template.etemplate_exec_id)
- {
- // Found another template using that exec_id, don't destroy when dialog closes.
- this.template.unbind_unload();
- break;
- }
- }
- }
- // set template-name as id, to allow to style dialogs
- this.div.children().attr('id', template.replace(/^(.*\/)?([^/]+)(\.xet)?$/, '$2').replace(/\./g, '-'));
- }
-
- /**
- * Actually create and display the dialog
- */
- _createDialog() {
- if (this.options.template) {
- this.set_template(this.options.template);
- } else {
- this.set_message(this.options.message);
- this.set_dialog_type(this.options.dialog_type);
- }
- this.set_buttons(typeof this.options.buttons == "number" ? this._buttons[this.options.buttons] : this.options.buttons);
- let position_my, position_at = '';
- if (this.options.position)
- {
- let positions = this.options.position.split(',');
- position_my = positions[0] ? positions[0].trim() : 'center';
- position_at = positions[1] ? positions[1].trim() : position_my;
- }
- let options = {
- // Pass the internal object, not the option
- buttons: this.options.buttons,
- modal: this.options.modal,
- resizable: this.options.resizable,
- minWidth: this.options.minWidth,
- minHeight: this.options.minHeight,
- maxWidth: 640,
- height: this.options.height,
- title: this.options.title,
- open: function () {
- // Focus default button so enter works
- jQuery(this).parents('.ui-dialog-buttonpane button[default]').focus();
- window.setTimeout(function () {
- jQuery(this).dialog('option', 'position', {
- my: position_my,
- at: position_at,
- of: window
- });
- }.bind(this), 0);
- },
- close: jQuery.proxy(function () {
- this.destroy();
- }, this),
- beforeClose: this.options.beforeClose,
- closeText: this.egw().lang('close'),
- position: {my: "center", at: "center", of: window},
- appendTo: this.options.appendTo,
- draggable: this.options.draggable,
- closeOnEscape: this.options.closeOnEscape,
- dialogClass: this.options.dialogClass,
- };
- // Leaving width unset lets it size itself according to contents
- if (this.options.width) {
- options['width'] = this.options.width;
- }
-
- this.div.dialog(options);
-
- // Make sure dialog is wide enough for the title
- // Arbitrary numbers that seem to work nicely.
- let title_width = 20 + 10 * this.options.title.length;
- if (this.div.width() < title_width && this.options.title.trim()) {
- // Auto-sizing chopped the title
- this.div.dialog('option', 'width', title_width);
- }
- }
-
- /**
- * Create a parent to inject application specific egw object with loaded translations into et2_dialog
- *
- * @param {string|egw} _egw_or_appname egw object with already loaded translations or application name to load translations for
- */
- static _create_parent(_egw_or_appname? : string | IegwAppLocal) {
- if (typeof _egw_or_appname == 'undefined') {
- // @ts-ignore
- _egw_or_appname = egw_appName;
- }
- // create a dummy parent with a correct reference to an application specific egw object
- let parent = new et2_widget();
- // if egw object is passed in because called from et2, just use it
- if (typeof _egw_or_appname != 'string') {
- parent.setApiInstance(_egw_or_appname);
- }
- // otherwise use given appname to create app-specific egw instance and load default translations
- else {
- parent.setApiInstance(egw(_egw_or_appname));
- parent.egw().langRequireApp(parent.egw().window, _egw_or_appname);
- }
- return parent;
- }
-
- /**
- * Show a confirmation dialog
- *
- * @param {function} _callback Function called when the user clicks a button. The context will be the et2_dialog widget, and the button constant is passed in.
- * @param {string} _message Message to be place in the dialog.
- * @param {string} _title Text in the top bar of the dialog.
- * @param _value passed unchanged to callback as 2. parameter
- * @param {integer|array} _buttons One of the BUTTONS_ constants defining the set of buttons at the bottom of the box
- * @param {integer} _type One of the message constants. This defines the style of the message.
- * @param {string} _icon URL of an icon to display. If not provided, a type-specific icon will be used.
- * @param {string|egw} _egw_or_appname egw object with already laoded translations or application name to load translations for
- */
- static show_dialog(_callback? : Function, _message? : string, _title? : string, _value? : object, _buttons?, _type? : number, _icon? : string, _egw_or_appname? : string | IegwAppLocal)
- {
- let parent = et2_dialog._create_parent(_egw_or_appname);
-
- // Just pass them along, widget handles defaults & missing
- return et2_createWidget("dialog", {
- callback: _callback || function () {
- },
- message: _message,
- title: _title || parent.egw().lang('Confirmation required'),
- buttons: typeof _buttons != 'undefined' ? _buttons : et2_dialog.BUTTONS_YES_NO,
- dialog_type: typeof _type != 'undefined' ? _type : et2_dialog.QUESTION_MESSAGE,
- icon: _icon,
- value: _value,
- width: 'auto'
- }, parent);
- };
-
- /**
- * Show an alert message with OK button
- *
- * @param {string} _message Message to be place in the dialog.
- * @param {string} _title Text in the top bar of the dialog.
- * @param {integer} _type One of the message constants. This defines the style of the message.
- */
- static alert(_message? : string, _title? : string, _type?)
- {
- let parent = et2_dialog._create_parent(et2_dialog._create_parent().egw());
- et2_createWidget("dialog", {
- callback: function () {
- },
- message: _message,
- title: _title,
- buttons: et2_dialog.BUTTONS_OK,
- dialog_type: _type || et2_dialog.INFORMATION_MESSAGE
- }, parent);
- }
-
- /**
- * Show a prompt dialog
- *
- * @param {function} _callback Function called when the user clicks a button. The context will be the et2_dialog widget, and the button constant is passed in.
- * @param {string} _message Message to be place in the dialog.
- * @param {string} _title Text in the top bar of the dialog.
- * @param {string} _value for prompt, passed to callback as 2. parameter
- * @param {integer|array} _buttons One of the BUTTONS_ constants defining the set of buttons at the bottom of the box
- * @param {string|egw} _egw_or_appname egw object with already laoded translations or application name to load translations for
- */
- static show_prompt(_callback, _message, _title?, _value?, _buttons?, _egw_or_appname?) {
- var callback = _callback;
- // Just pass them along, widget handles defaults & missing
- return et2_createWidget("dialog", {
- callback: function (_button_id, _value) {
- if (typeof callback == "function") {
- callback.call(this, _button_id, _value.value);
- }
- },
- title: _title || egw.lang('Input required'),
- buttons: _buttons || et2_dialog.BUTTONS_OK_CANCEL,
- value: {
- content: {
- value: _value,
- message: _message
- }
- },
- template: egw.webserverUrl + '/api/templates/default/prompt.xet',
- class: "et2_prompt"
- }, et2_dialog._create_parent(_egw_or_appname));
- }
-
- /**
- * Method to build a confirmation dialog only with
- * YES OR NO buttons and submit content back to server
- *
- * @param {widget} _senders widget that has been clicked
- * @param {String} _dialogMsg message shows in dialog box
- * @param {String} _titleMsg message shows as a title of the dialog box
- * @param {Bool} _postSubmit true: use postSubmit instead of submit
- *
- * @description submit the form contents including the button that has been pressed
- */
- static confirm(_senders, _dialogMsg, _titleMsg, _postSubmit) {
- var senders = _senders;
- var buttonId = _senders.id;
- var dialogMsg = (typeof _dialogMsg != "undefined") ? _dialogMsg : '';
- var titleMsg = (typeof _titleMsg != "undefined") ? _titleMsg : '';
- var egw = _senders instanceof et2_widget ? _senders.egw() : et2_dialog._create_parent().egw();
- var callbackDialog = function (button_id) {
- if (button_id == et2_dialog.YES_BUTTON) {
- if (_postSubmit)
- {
- senders.getRoot().getInstanceManager().postSubmit(buttonId);
- }
- else if (senders.instanceOf(et2_button) && senders.getType() !== "buttononly")
- {
- senders.clicked = true;
- senders.getInstanceManager().submit(senders, false, senders.options.novalidate);
- senders.clicked = false;
- }
- else
- {
- senders.getRoot().getInstanceManager().submit(buttonId);
- }
- }
- };
- et2_dialog.show_dialog(callbackDialog, egw.lang(dialogMsg), egw.lang(titleMsg), {},
- et2_dialog.BUTTONS_YES_NO, et2_dialog.WARNING_MESSAGE, undefined, egw);
- };
-
-
- /**
- * Show a dialog for a long-running, multi-part task
- *
- * Given a server url and a list of parameters, this will open a dialog with
- * a progress bar, asynchronously call the url with each parameter, and update
- * the progress bar.
- * Any output from the server will be displayed in a box.
- *
- * When all tasks are done, the callback will be called with boolean true. It will
- * also be called if the user clicks a button (OK or CANCEL), so be sure to
- * check to avoid executing more than intended.
- *
- * @param {function} _callback Function called when the user clicks a button,
- * or when the list is done processing. The context will be the et2_dialog
- * widget, and the button constant is passed in.
- * @param {string} _message Message to be place in the dialog. Usually just
- * text, but DOM nodes will work too.
- * @param {string} _title Text in the top bar of the dialog.
- * @param {string} _menuaction the menuaction function which should be called and
- * which handles the actual request. If the menuaction is a full featured
- * url, this one will be used instead.
- * @param {Array[]} _list - List of parameters, one for each call to the
- * address. Multiple parameters are allowed, in an array.
- * @param {string|egw} _egw_or_appname egw object with already laoded translations or application name to load translations for
- *
- * @return {et2_dialog}
- */
- static long_task(_callback, _message, _title, _menuaction, _list, _egw_or_appname)
- {
- let parent = et2_dialog._create_parent(_egw_or_appname);
- let egw = parent.egw();
-
- // Special action for cancel
- let buttons = [
- {"button_id": et2_dialog.OK_BUTTON, "text": egw.lang('ok'), "default": true, "disabled": true},
- {
- "button_id": et2_dialog.CANCEL_BUTTON, "text": egw.lang('cancel'), click: function () {
- // Cancel run
- cancel = true;
- jQuery("button[button_id=" + et2_dialog.CANCEL_BUTTON + "]", dialog.div.parent()).button("disable");
- update.call(_list.length, '');
- }
- }
- ];
- let dialog = et2_createWidget("dialog", {
- template: egw.webserverUrl + '/api/templates/default/long_task.xet',
- value: {
- content: {
- message: _message
- }
- },
- callback: function (_button_id, _value) {
- if (_button_id == et2_dialog.CANCEL_BUTTON) {
- cancel = true;
- }
- if (typeof _callback == "function") {
- _callback.call(this, _button_id, _value.value);
- }
- },
- title: _title || egw.lang('please wait...'),
- buttons: buttons
- }, parent);
-
- // OK starts disabled
- jQuery("button[button_id=" + et2_dialog.OK_BUTTON + "]", dialog.div.parent()).button("disable");
-
- let log = null;
- let progressbar = null;
- let cancel = false;
- let totals = {
- success: 0,
- skipped: 0,
- failed: 0,
- widget: null
- };
-
- // Updates progressbar & log, calls next step
- let update = function (response) {
- // context is index
- let index = this || 0;
-
- progressbar.set_value(100 * (index / _list.length));
- progressbar.set_label(index + ' / ' + _list.length);
-
- // Display response information
- switch (response.type) {
- case 'error':
- jQuery("")
- .text(response.data)
- .appendTo(log);
-
- totals.failed++;
-
- // Ask to retry / ignore / abort
- et2_createWidget("dialog", {
- callback: function (button) {
- switch (button) {
- case 'dialog[cancel]':
- cancel = true;
- return update.call(index, '');
- case 'dialog[skip]':
- // Continue with next index
- totals.skipped++;
- return update.call(index, '');
- default:
- // Try again with previous index
- return update.call(index - 1, '');
- }
-
- },
- message: response.data,
- title: '',
- buttons: [
- // These ones will use the callback, just like normal
- {text: egw.lang("Abort"), id: 'dialog[cancel]'},
- {text: egw.lang("Retry"), id: 'dialog[retry]'},
- {text: egw.lang("Skip"), id: 'dialog[skip]', class: "ui-priority-primary", default: true}
- ],
- dialog_type: et2_dialog.ERROR_MESSAGE
- }, parent);
- // Early exit
- return;
- default:
- if (response && typeof response === "string") {
- totals.success++;
- jQuery("")
- .text(response)
- .appendTo(log);
- }
- else
- {
- jQuery("")
- .text(JSON.stringify(response))
- .appendTo(log);
- }
- }
- // Scroll to bottom
- let height = log[0].scrollHeight;
- log.scrollTop(height);
-
- // Update totals
- totals.widget.set_value(egw.lang(
- "Total: %1 Successful: %2 Failed: %3 Skipped: %4",
- _list.length, totals.success, totals.failed, totals.skipped
- ));
-
- // Fire next step
- if (!cancel && index < _list.length) {
- var parameters = _list[index];
- if (typeof parameters != 'object') parameters = [parameters];
-
- // Async request, we'll take the next step in the callback
- // We can't pass index = 0, it looks like false and causes issues
- egw.json(_menuaction, parameters, update, index + 1, true, index + 1).sendRequest();
- } else {
- // All done
- if (!cancel) progressbar.set_value(100);
- jQuery("button[button_id=" + et2_dialog.CANCEL_BUTTON + "]", dialog.div.parent()).button("disable");
- jQuery("button[button_id=" + et2_dialog.OK_BUTTON + "]", dialog.div.parent()).button("enable");
- if (!cancel && typeof _callback == "function") {
- _callback.call(dialog, true, response);
- }
- }
- };
-
- jQuery(dialog.template.DOMContainer).on('load', function () {
- // Get access to template widgets
- log = jQuery(dialog.template.widgetContainer.getWidgetById('log').getDOMNode());
- progressbar = dialog.template.widgetContainer.getWidgetById('progressbar');
- progressbar.set_label('0 / ' + _list.length);
- totals.widget = dialog.template.widgetContainer.getWidgetById('totals');
-
- // Start
- window.setTimeout(function () {
- update.call(0, '');
- }, 0);
- });
-
- return dialog;
- }
-}
-// make et2_dialog publicly available as we need to call it from templates
-//if (typeof window.et2_dialog === 'undefined') window['et2_dialog'] = et2_dialog;
-et2_register_widget(et2_dialog, ["dialog"]);
\ No newline at end of file
+export class et2_dialog extends Et2Dialog
+{
+}
\ No newline at end of file