/************************************************************************ * This file is part of EspoCRM. * * EspoCRM - Open Source CRM application. * Copyright (C) 2014-2023 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko * Website: https://www.espocrm.com * * EspoCRM is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * EspoCRM is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with EspoCRM. If not, see http://www.gnu.org/licenses/. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU General Public License version 3. * * In accordance with Section 7(b) of the GNU General Public License version 3, * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ /** @module ui */ import {marked} from 'marked'; import DOMPurify from 'dompurify'; import $ from 'jquery'; /** * Dialog parameters. * * @typedef {Object} module:ui.Dialog~Params * * @property {string} [className='dialog'] A class-name or multiple space separated. * @property {'static'|true|false} [backdrop='static'] A backdrop. * @property {boolean} [closeButton=true] A close button. * @property {boolean} [collapseButton=false] A collapse button. * @property {string|null} [header] A header HTML. * @property {string} [body] A body HTML. * @property {number|null} [width] A width. * @property {boolean} [removeOnClose=true] To remove on close. * @property {boolean} [draggable=false] Is draggable. * @property {function (): void} [onRemove] An on-remove callback. * @property {function (): void} [onClose] An on-close callback. * @property {function (): void} [onBackdropClick] An on-backdrop-click callback. * @property {string} [container='body'] A container selector. * @property {boolean} [keyboard=true] Enable a keyboard control. The `Esc` key closes a dialog. * @property {boolean} [footerAtTheTop=false] To display a footer at the top. * @property {module:ui.Dialog~Button[]} [buttonList] Buttons. * @property {module:ui.Dialog~Button[]} [dropdownItemList] Dropdown action items. * @property {boolean} [fullHeight] Deprecated. * @property {Number} [bodyDiffHeight] * @property {Number} [screenWidthXs] */ /** * A button or dropdown action item. * * @typedef {Object} module:ui.Dialog~Button * * @property {string} name A name. * @property {boolean} [pullLeft=false] Deprecated. Use the `position` property. * @property {'left'|'right'} [position='left'] A position. * @property {string} [html] HTML. * @property {string} [text] A text. * @property {boolean} [disabled=false] Disabled. * @property {boolean} [hidden=false] Hidden. * @property {'default'|'danger'|'success'|'warning'} [style='default'] A style. * @property {function(Espo.Ui.Dialog, JQueryEventObject): void} [onClick] An on-click callback. * @property {string} [className] An additional class name. * @property {string} [title] A title. */ /** * @alias Espo.Ui.Dialog */ class Dialog { height fitHeight onRemove onClose onBackdropClick buttons screenWidthXs /** * @param {module:ui.Dialog~Params} options Options. */ constructor(options) { options = options || {}; /** @private */ this.className = 'dialog'; /** @private */ this.backdrop = 'static'; /** @private */ this.closeButton = true; /** @private */ this.collapseButton = false; /** @private */ this.header = null; /** @private */ this.body = ''; /** @private */ this.width = null; /** * @private * @type {module:ui.Dialog~Button[]} */ this.buttonList = []; /** * @private * @type {module:ui.Dialog~Button[]} */ this.dropdownItemList = []; /** @private */ this.removeOnClose = true; /** @private */ this.draggable = false; /** @private */ this.container = 'body'; /** @private */ this.options = options; /** @private */ this.keyboard = true; this.activeElement = document.activeElement; let params = [ 'className', 'backdrop', 'keyboard', 'closeButton', 'collapseButton', 'header', 'body', 'width', 'height', 'fitHeight', 'buttons', 'buttonList', 'dropdownItemList', 'removeOnClose', 'draggable', 'container', 'onRemove', 'onClose', 'onBackdropClick', ]; params.forEach(param => { if (param in options) { this[param] = options[param]; } }); /** @private */ this.onCloseIsCalled = false; if (this.buttons && this.buttons.length) { /** * @private * @type {module:ui.Dialog~Button[]} */ this.buttonList = this.buttons; } this.id = 'dialog-' + Math.floor((Math.random() * 100000)); if (typeof this.backdrop === 'undefined') { /** @private */ this.backdrop = 'static'; } let $header = this.getHeader(); let $footer = this.getFooter(); let $body = $('