2022-06-10 18:11:34 +02:00
|
|
|
/**
|
|
|
|
* EGroupware eTemplate2 - Email-selection WebComponent
|
|
|
|
*
|
|
|
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
|
|
|
* @package api
|
|
|
|
* @link https://www.egroupware.org
|
|
|
|
* @author Nathan Gray
|
|
|
|
*/
|
|
|
|
|
|
|
|
import {Et2Select} from "./Et2Select";
|
2022-06-10 22:11:57 +02:00
|
|
|
import {css} from "@lion/core";
|
2022-06-10 18:11:34 +02:00
|
|
|
import {IsEmail} from "../Validators/IsEmail";
|
2022-06-21 16:21:23 +02:00
|
|
|
import interact from "@interactjs/interact";
|
2022-06-10 18:11:34 +02:00
|
|
|
|
|
|
|
export class Et2SelectEmail extends Et2Select
|
|
|
|
{
|
|
|
|
static get styles()
|
|
|
|
{
|
|
|
|
return [
|
|
|
|
...super.styles,
|
|
|
|
css`
|
|
|
|
:host {
|
|
|
|
display: block;
|
|
|
|
flex: 1 1 auto;
|
|
|
|
min-width: 200px;
|
|
|
|
}
|
|
|
|
::part(icon), .select__icon {
|
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
::slotted(sl-icon[slot="suffix"]) {
|
|
|
|
display: none;
|
|
|
|
}
|
2022-06-16 00:43:39 +02:00
|
|
|
|
|
|
|
/* Hide selected options from the dropdown */
|
|
|
|
::slotted([checked])
|
|
|
|
{
|
|
|
|
display: none;
|
|
|
|
}
|
2022-06-10 18:11:34 +02:00
|
|
|
`
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
2022-06-21 16:21:23 +02:00
|
|
|
static get properties()
|
|
|
|
{
|
|
|
|
return {
|
|
|
|
...super.properties,
|
|
|
|
|
|
|
|
/**
|
2022-07-19 21:18:51 +02:00
|
|
|
* Allow drag and drop tags between two or more Et2SelectEmail widgets
|
2022-06-21 16:21:23 +02:00
|
|
|
*/
|
2022-07-19 21:18:51 +02:00
|
|
|
allowDragAndDrop: {type: Boolean},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Show the full, original value email address under all circumstances, rather than the contact name for known contacts
|
|
|
|
*/
|
|
|
|
full_email: {type: Boolean}
|
2022-06-21 16:21:23 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-10 18:11:34 +02:00
|
|
|
constructor(...args : any[])
|
|
|
|
{
|
|
|
|
super(...args);
|
|
|
|
this.search = true;
|
|
|
|
this.searchUrl = "EGroupware\\Api\\Etemplate\\Widget\\Taglist::ajax_email";
|
|
|
|
this.allowFreeEntries = true;
|
|
|
|
this.editModeEnabled = true;
|
2022-06-21 16:21:23 +02:00
|
|
|
this.allowDragAndDrop = false;
|
2022-06-10 18:11:34 +02:00
|
|
|
this.multiple = true;
|
2022-07-19 21:18:51 +02:00
|
|
|
this.full_email = false;
|
2022-06-10 18:11:34 +02:00
|
|
|
this.defaultValidators.push(new IsEmail());
|
|
|
|
}
|
|
|
|
|
|
|
|
connectedCallback()
|
|
|
|
{
|
|
|
|
super.connectedCallback();
|
|
|
|
}
|
|
|
|
|
2022-06-22 22:36:38 +02:00
|
|
|
|
|
|
|
protected _bindListeners()
|
|
|
|
{
|
|
|
|
super._bindListeners();
|
|
|
|
if(!this.multiple)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
interact(this).dropzone({
|
|
|
|
accept: `.et2-select-draggable`,
|
|
|
|
ondrop: function(e)
|
|
|
|
{
|
|
|
|
e.target.createFreeEntry(e.draggable.target.value);
|
|
|
|
e.target.classList.remove('et2_toolbarDropArea');
|
|
|
|
|
|
|
|
// remove the dragged value from its origin source
|
|
|
|
e.draggable.parent_node.value = e.draggable.parent_node.value.filter(_item => {return e.draggable.target.value !== _item;})
|
|
|
|
|
|
|
|
// set value for newly dropped target
|
|
|
|
e.target.value.push(e.draggable.target.value);
|
|
|
|
},
|
|
|
|
ondragenter: function(e)
|
|
|
|
{
|
|
|
|
e.target.classList.add('et2_dropZone');
|
|
|
|
},
|
|
|
|
ondragleave: function(e)
|
|
|
|
{
|
|
|
|
e.target.classList.remove('et2_dropZone');
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-06-10 18:11:34 +02:00
|
|
|
/**
|
|
|
|
* Actually query the server.
|
|
|
|
*
|
|
|
|
* Overridden to change request to match server
|
|
|
|
*
|
|
|
|
* @param {string} search
|
|
|
|
* @param {object} options
|
|
|
|
* @returns {any}
|
|
|
|
* @protected
|
|
|
|
*/
|
|
|
|
protected remoteQuery(search : string, options : object)
|
|
|
|
{
|
|
|
|
return this.egw().json(this.searchUrl, [search]).sendRequest().then((result) =>
|
|
|
|
{
|
|
|
|
this.processRemoteResults(result);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add in remote results
|
|
|
|
*
|
|
|
|
* Overridden to get results in a format parent expects.
|
|
|
|
* Current server-side gives {
|
|
|
|
* icon: "/egroupware/api/avatar.php?contact_id=5&etag=1"
|
|
|
|
* id: "ng@egroupware.org"
|
|
|
|
* label: "ng@egroupware.org"
|
|
|
|
* name: ""
|
|
|
|
* title: "ng@egroupware.org"
|
|
|
|
* }
|
|
|
|
* Parent expects value instead of id
|
|
|
|
*
|
|
|
|
* @param results
|
|
|
|
* @protected
|
|
|
|
*/
|
|
|
|
protected processRemoteResults(results)
|
|
|
|
{
|
|
|
|
results.forEach(r => r.value = r.id);
|
|
|
|
super.processRemoteResults(results);
|
|
|
|
}
|
2022-06-21 16:21:23 +02:00
|
|
|
|
2022-06-24 20:10:10 +02:00
|
|
|
/**
|
|
|
|
* Use a custom tag for when multiple=true
|
|
|
|
*
|
|
|
|
* @returns {string}
|
|
|
|
*/
|
|
|
|
get tagTag() : string
|
|
|
|
{
|
|
|
|
return "et2-email-tag";
|
|
|
|
}
|
|
|
|
|
2022-06-21 16:21:23 +02:00
|
|
|
/**
|
|
|
|
* override tag creation in order to add DND functionality
|
|
|
|
* @param item
|
|
|
|
* @protected
|
|
|
|
*/
|
|
|
|
protected _createTagNode(item)
|
|
|
|
{
|
|
|
|
let tag = super._createTagNode(item);
|
2022-07-19 21:18:51 +02:00
|
|
|
tag.full_email = this.full_email;
|
2022-06-24 20:10:10 +02:00
|
|
|
if(!this.readonly && this.allowFreeEntries && this.allowDragAndDrop)
|
2022-06-21 16:21:23 +02:00
|
|
|
{
|
|
|
|
let dragTranslate = {x:0,y:0};
|
|
|
|
tag.class = item.classList.value + " et2-select-draggable";
|
|
|
|
let draggable = interact(tag).draggable({
|
|
|
|
startAxis: 'xy',
|
|
|
|
listeners: {
|
|
|
|
start: function(e)
|
|
|
|
{
|
|
|
|
let dragPosition = {x:e.page.x, y:e.page.y};
|
|
|
|
e.target.setAttribute('style', `width:${e.target.clientWidth}px !important`);
|
|
|
|
e.target.style.position = 'fixed';
|
|
|
|
e.target.style.transform =
|
|
|
|
`translate(${dragPosition.x}px, ${dragPosition.y}px)`;
|
|
|
|
},
|
|
|
|
move : function(e)
|
|
|
|
{
|
|
|
|
dragTranslate.x += e.delta.x;
|
|
|
|
dragTranslate.y += e.delta.y;
|
|
|
|
e.target.style.transform =
|
|
|
|
`translate(${dragTranslate.x}px, ${dragTranslate.y}px)`;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
// set parent_node with widget context in order to make it accessible after drop
|
|
|
|
draggable.parent_node = this;
|
|
|
|
}
|
|
|
|
return tag;
|
|
|
|
}
|
2022-06-10 18:11:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// @ts-ignore TypeScript is not recognizing that this widget is a LitElement
|
|
|
|
customElements.define("et2-select-email", Et2SelectEmail);
|