diff --git a/admin/templates/default/app.css b/admin/templates/default/app.css index 6d42a62f56..ca0a01b4ca 100644 --- a/admin/templates/default/app.css +++ b/admin/templates/default/app.css @@ -141,20 +141,29 @@ span#admin-mailaccount_acc_id { float: right; } #admin-mailaccount_acc_smtp_account_id { - padding-left: 5px; + padding-left: 5px; } + #admin-mailaccount_button\[multiple\] { - height: auto; - padding-left: 5px; - margin:2px; - width: 16px; - vertical-align: top; + height: auto; + padding-left: 5px; + margin: 2px; + width: 16px; + vertical-align: top; } + +#admin-mailaccount_button\[placeholders\] { + height: 16px; + padding-left: 5px; + align-self: center; +} + #admin-mailaccount_mailLocalAddress { - width: 98%; + width: 98%; } + select#admin-mailaccount_ident_id { - width: 95%; + width: 95%; } /** diff --git a/admin/templates/pixelegg/app.css b/admin/templates/pixelegg/app.css index 3ea72981bd..bbfbd24cfb 100755 --- a/admin/templates/pixelegg/app.css +++ b/admin/templates/pixelegg/app.css @@ -150,14 +150,21 @@ span#admin-mailaccount_acc_id { padding-left: 5px; } #admin-mailaccount_button\[multiple\] { - height: auto; - padding-left: 5px; - margin: 2px; - width: 16px; - vertical-align: top; + height: auto; + padding-left: 5px; + margin: 2px; + width: 16px; + vertical-align: top; } + +#admin-mailaccount_button\[placeholders\] { + height: 16px; + padding-left: 5px; + align-self: center; +} + #admin-mailaccount_mailLocalAddress { - width: 98%; + width: 98%; } select#admin-mailaccount_ident_id { width: 95%; diff --git a/api/etemplate.php b/api/etemplate.php index 6b4fc990fa..31e94bbdca 100644 --- a/api/etemplate.php +++ b/api/etemplate.php @@ -160,12 +160,7 @@ function send_template() // replace not set background_image attribute with new et2-button-image tag if (!empty($attrs['image']) && (empty($attrs['background_image']) || $attrs['background_image'] === 'false')) { - $tag = 'et2-button-image'; - if($attrs['label']) - { - $attrs['statustext'] = $attrs['label']; - unset($attrs['label']); - } + $tag = 'et2-image'; } // novalidation --> noValidation if (!empty($attrs['novalidation']) && in_array($attrs['novalidation'], ['true', '1'], true)) diff --git a/api/js/etemplate/Et2Box/Et2Box.ts b/api/js/etemplate/Et2Box/Et2Box.ts index 2dd7d3706b..60da1665dd 100644 --- a/api/js/etemplate/Et2Box/Et2Box.ts +++ b/api/js/etemplate/Et2Box/Et2Box.ts @@ -41,7 +41,7 @@ export class Et2Box extends Et2Widget(LitElement) implements et2_IDetachedDOM ::slotted(*) { flex: 1 0 auto; } - ::slotted(img) { + ::slotted(img),::slotted(et2-image) { /* Stop images from growing. In general we want them to stay */ flex-grow: 0; } diff --git a/api/js/etemplate/Et2Button/Et2ButtonImage.ts b/api/js/etemplate/Et2Button/Et2ButtonImage.ts deleted file mode 100644 index f81c5db292..0000000000 --- a/api/js/etemplate/Et2Button/Et2ButtonImage.ts +++ /dev/null @@ -1,49 +0,0 @@ -/** - * EGroupware eTemplate2 - Image only button widget - * - * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License - * @package etemplate - * @subpackage api - * @link https://www.egroupware.org - * @author Nathan Gray - */ - - -import {Et2Button} from "./Et2Button"; -import {css} from "@lion/core"; - -export class Et2ButtonImage extends Et2Button -{ - - public static styles = [ - ...Et2Button.styles, - css` - :host { - /* Important needed to override boxes trying to stretch children */ - flex: 0 0 !important; - } - ` - ]; - - /** - * Handle changes that have to happen based on changes to properties - * - */ - requestUpdate(name : PropertyKey, oldValue) - { - super.requestUpdate(name, oldValue); - - // image only don't have labels, but we'll set hover instead - if(name == 'label') - { - if(!this.statustext) - { - this.statustext = this.label; - } - this.__label = ""; - } - } -} - -// @ts-ignore TypeScript is not recognizing that Et2Button is a LitElement -customElements.define("et2-button-image", Et2ButtonImage); \ No newline at end of file diff --git a/api/js/etemplate/Et2Image/Et2Image.ts b/api/js/etemplate/Et2Image/Et2Image.ts new file mode 100644 index 0000000000..fffc37e39c --- /dev/null +++ b/api/js/etemplate/Et2Image/Et2Image.ts @@ -0,0 +1,183 @@ +/** + * EGroupware eTemplate2 - Image widget + * + * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License + * @package etemplate + * @subpackage api + * @link https://www.egroupware.org + * @author Nathan Gray + */ + + +import {css, html, LitElement} from "@lion/core"; +import {Et2Widget} from "../Et2Widget/Et2Widget"; +import {et2_IDetachedDOM} from "../et2_core_interfaces"; + +export class Et2Image extends Et2Widget(LitElement) implements et2_IDetachedDOM +{ + static get styles() + { + return [ + ...super.styles, + css` + :host { + display: inline-block; + } + img { + height: 100%; + width: 100%; + } + `, + ]; + } + + static get properties() + { + return { + + /** + * Image + * Displayed image + */ + src: {type: String}, + + /** + * Default image + * Image to use if src is not found + */ + default_src: {type: String}, + + /** + * Link Target + * Link URL, empty if you don't wan't to display a link. + */ + href: {type: String}, + + /** + * Link target + * Link target descriptor + */ + extra_link_target: {type: String}, + + /** + * Popup + * widthxheight, if popup should be used, eg. 640x480 + */ + extra_link_popup: {type: String}, + + /** + * Expose view + * Clicking on an image with href value would popup an expose view, and will show image referenced by href. + */ + expose_view: {type: Boolean}, + } + } + + constructor() + { + super(); + this.src = ""; + this.default_src = egw?.image("help"); + this.href = ""; + this.extra_link_target = "_self"; + this.extra_link_popup = ""; + this.expose_view = false; + } + + connectedCallback() + { + super.connectedCallback(); + this._handleClick = this._handleClick.bind(this); + } + + render() + { + return html` + ${this.label}`; + } + + /** + * Set image src + * + * @param {string} _value image, app/image or url + */ + set src(_value : string) + { + this.__src = _value; + + // allow url's too + if(_value[0] == '/' || _value.substr(0, 4) == 'http' || _value.substr(0, 5) == 'data:') + { + this.setAttribute('src', _value); + return; + } + let src = this.egw().image(_value); + if(src) + { + this.setAttribute('src', src); + } + } + + _handleClick(_ev : MouseEvent) : boolean + { + if(this.href) + { + this.egw().open_link(this.href, this.extra_link_target, this.extra_link_popup); + } + else + { + return super._handleClick(_ev); + } + } + + /** + * Handle changes that have to happen based on changes to properties + * + */ + requestUpdate(name : PropertyKey, oldValue) + { + super.requestUpdate(name, oldValue); + + // if there's an href, make it look clickable + if(name == 'href') + { + this.classList.toggle("et2_clickable", this.href) + } + } + + /** + * Code for implementing et2_IDetachedDOM + * + * Individual widgets are detected and handled by the grid, but the interface is needed for this to happen + * + * @param {array} _attrs array to add further attributes to + */ + getDetachedAttributes(_attrs) + { + _attrs.push('data'); + } + + getDetachedNodes() + { + return [this.getDOMNode()]; + } + + setDetachedAttributes(_nodes, _values) + { + if(_values.data) + { + var pairs = _values.data.split(/,/g); + for(var i = 0; i < pairs.length; ++i) + { + var name_value = pairs[i].split(':'); + jQuery(_nodes[0]).attr('data-' + name_value[0], name_value[1]); + } + } + } +} + +customElements.define("et2-image", Et2Image as any, {extends: 'img'}); \ No newline at end of file diff --git a/api/js/etemplate/etemplate2.ts b/api/js/etemplate/etemplate2.ts index f57ce40f3a..5c0f226fcf 100644 --- a/api/js/etemplate/etemplate2.ts +++ b/api/js/etemplate/etemplate2.ts @@ -25,7 +25,6 @@ import '../jsapi/egw_json.js'; import {egwIsMobile} from "../egw_action/egw_action_common.js"; import './Et2Box/Et2Box'; import './Et2Button/Et2Button'; -import './Et2Button/Et2ButtonImage'; import './Et2Date/Et2Date'; import './Et2Date/Et2DateDuration'; import './Et2Date/Et2DateDurationReadonly'; @@ -38,6 +37,7 @@ import './Et2Date/Et2DateTimeReadonly'; import './Et2Date/Et2DateTimeToday'; import './Et2Description/Et2Description'; import './Et2Dialog/Et2Dialog'; +import './Et2Image/Et2Image'; import './Et2Select/Et2Select'; import './Et2Select/Et2SelectAccount'; import './Et2Select/Et2SelectReadonly';