From f503743956e54c9246642c9d473b2e5eeece95ef Mon Sep 17 00:00:00 2001 From: nathan Date: Fri, 27 Jan 2023 13:26:50 -0700 Subject: [PATCH] Use client-side Et2LAvatar instead of image for Et2SelectEmail options & tags Should now be only avatar.php image when provided --- api/js/etemplate/Et2Select/Et2SelectEmail.ts | 25 ++- api/js/etemplate/Et2Select/Tag/Et2EmailTag.ts | 162 +++++++++--------- api/js/etemplate/Et2Select/Tag/Et2Tag.ts | 12 +- 3 files changed, 109 insertions(+), 90 deletions(-) diff --git a/api/js/etemplate/Et2Select/Et2SelectEmail.ts b/api/js/etemplate/Et2Select/Et2SelectEmail.ts index 9a63f4e60a..9129fba0a1 100644 --- a/api/js/etemplate/Et2Select/Et2SelectEmail.ts +++ b/api/js/etemplate/Et2Select/Et2SelectEmail.ts @@ -8,7 +8,7 @@ */ import {Et2Select} from "./Et2Select"; -import {css} from "@lion/core"; +import {css, html, nothing} from "@lion/core"; import {IsEmail} from "../Validators/IsEmail"; import interact from "@interactjs/interact"; @@ -32,9 +32,6 @@ export class Et2SelectEmail extends Et2Select flex: 1 1 auto; min-width: 200px; } - ::part(icon), .select__icon { - display: none; - } ::slotted(sl-icon[slot="suffix"]) { display: none; } @@ -192,6 +189,26 @@ export class Et2SelectEmail extends Et2Select return tag; } + /** + * Override icon for the select option to use lavatar, same as Et2SelectAccount + * + * @param option + * @protected + */ + protected _iconTemplate(option) + { + // lavatar uses a size property, not a CSS variable + let style = getComputedStyle(this); + + return html` + + `; + } + /** * Override image to skip it, we add images in Et2EmailTag using CSS * @param item diff --git a/api/js/etemplate/Et2Select/Tag/Et2EmailTag.ts b/api/js/etemplate/Et2Select/Tag/Et2EmailTag.ts index e1a519c2c9..2662f38594 100644 --- a/api/js/etemplate/Et2Select/Tag/Et2EmailTag.ts +++ b/api/js/etemplate/Et2Select/Tag/Et2EmailTag.ts @@ -6,10 +6,9 @@ * @link https://www.egroupware.org * @author Nathan Gray */ -import {css, PropertyValues} from "@lion/core"; +import {classMap, css, html, nothing, PropertyValues, TemplateResult} from "@lion/core"; import shoelace from "../../Styles/shoelace"; import {Et2Tag} from "./Et2Tag"; -import {cssImage} from "../../Et2Widget/Et2Widget"; /** * Display a single email address @@ -30,43 +29,34 @@ export class Et2EmailTag extends Et2Tag super.styles, shoelace, css` .tag { - position: relative; + position: relative; } - .tag__prefix { - width: 20px; - height: 20px; - flex: 0 1 auto; - - background-color: initial; - background-repeat: no-repeat; - background-size: contain; - background-position-y: center; - - opacity: 30%; - cursor: pointer; + + .tag__prefix { + flex: 0 1 auto; + + opacity: 30%; + cursor: pointer; } - - .contact_plus .tag__prefix { - opacity: 100%; + + .tag__has_plus et2-button-icon { + visibility: visible; } - .tag__prefix.loading { - opacity: 100%; - background-image: ${cssImage("loading")}; - } - - .tag__prefix.contact_plus_add { - height: 80%; - background-image: ${cssImage("add")}; + + :host(:hover) .tag__has_plus { + opacity: 100%; } + /* Address is for a contact - always show */ - .tag__prefix.contact_plus_contact { - opacity: 100%; - background-image: ${cssImage("contact")}; + + .tag__prefix.tag__has_contact { + opacity: 100%; } + .tag__remove { - order: 3; + order: 3; } - `]; + `]; } static get properties() @@ -143,37 +133,6 @@ export class Et2EmailTag extends Et2Tag this.shadowRoot.querySelector(".tag").classList.remove("contact_plus"); } - /** - * We either have a contact ID, or false. If false, show the add button. - * @param {false | ContactInfo} data - */ - handleContactResponse(data : false | ContactInfo) - { - this._contactPlusNode.classList.remove("loading"); - if(data) - { - this._contactPlusNode.classList.add("contact_plus_contact"); - // Add name in if missing - if(!this.fullEmail && data.n_fn && !this.splitEmail(this.value).name) - { - // Append current value as email, data may have work & home email in it - this.textContent = data.n_fn + " <" + this.value + ">" - } - if(data.photo) - { - this._contactPlusNode.style.backgroundImage = "url(" + data.photo + ")"; - } - this._contactPlusNode.addEventListener("click", this.handleContactClick); - this.egw().tooltipBind(this._contactPlusNode, this.egw().lang("Open existing contact") + ":\n" + data.n_fn, false, {}); - } - else - { - this._contactPlusNode.classList.add("contact_plus_add"); - this._contactPlusNode.addEventListener("click", this.handleClick); - this.egw().tooltipBind(this._contactPlusNode, this.egw().lang("Add a new contact"), false, {}); - } - } - handleClick(e : MouseEvent) { e.stopPropagation(); @@ -216,37 +175,74 @@ export class Et2EmailTag extends Et2Tag // Send the request this.checkContact(this.value).then((result) => { - this.handleContactResponse(result); + this.requestUpdate(); }); } } - - /** - * Check the content for name . - * If there's a name, just show the name, otherwise show the email - * - * @param {string} new_content - */ - set textContent(new_content) + public _contentTemplate() : TemplateResult { - if(this.fullEmail) + let content = this.value; + // If there's a name, just show the name, otherwise show the email + if(Et2EmailTag.email_cache[this.value]) { - super.textContent = new_content; - return; + // Append current value as email, data may have work & home email in it + content = (Et2EmailTag.email_cache[this.value]?.n_fn || "") + " <" + this.value + ">" } - - const split = this.splitEmail(new_content); - super.textContent = split.name || split.email; - - // Show full email in tooltip. - // We could do better here for known contacts - this.egw().tooltipBind(this, new_content.trim(), false, {}); + if(!this.fullEmail) + { + const split = this.splitEmail(content); + content = split.name || split.email; + } + return html` + + ${content} + `; } - get textContent() + public _prefixTemplate() : TemplateResult { - return super.textContent; + let classes = { + "tag__prefix": true, + } + let button_or_avatar; + + // Show the lavatar for the contact + if(this.value && Et2EmailTag.email_cache[this.value]) + { + classes['tag__has_contact'] = true; + // lavatar uses a size property, not a CSS variable + let style = getComputedStyle(this); + const option = Et2EmailTag.email_cache[this.value]; + + button_or_avatar = html` + " + option.n_fn}" + > + `; + } + else + { + // Show a button to add as new contact + classes['tag__has_plus'] = true; + button_or_avatar = html` + + `; + } + + return html` + + + + ${button_or_avatar} + `; } /** diff --git a/api/js/etemplate/Et2Select/Tag/Et2Tag.ts b/api/js/etemplate/Et2Select/Tag/Et2Tag.ts index 37eb0ae2bf..d9e50c1d46 100644 --- a/api/js/etemplate/Et2Select/Tag/Et2Tag.ts +++ b/api/js/etemplate/Et2Select/Tag/Et2Tag.ts @@ -147,9 +147,7 @@ export class Et2Tag extends Et2Widget(SlTag) 'tag--removable': this.removable })} > - - - + ${this._prefixTemplate()} ${content} `; @@ -177,6 +175,14 @@ export class Et2Tag extends Et2Widget(SlTag) `; } + _prefixTemplate() : TemplateResult + { + return html` + + + `; + } + startEdit(event? : MouseEvent) { if(event)