2022-05-31 21:40:31 +02:00
|
|
|
/**
|
|
|
|
* EGroupware eTemplate2 - Search & select link entry WebComponent
|
|
|
|
*
|
|
|
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
|
|
|
* @package api
|
|
|
|
* @link https://www.egroupware.org
|
|
|
|
* @author Nathan Gray
|
|
|
|
*/
|
|
|
|
|
2023-09-13 19:55:33 +02:00
|
|
|
import {css} from "lit";
|
2022-05-31 21:40:31 +02:00
|
|
|
import {Et2Select} from "../Et2Select/Et2Select";
|
|
|
|
import {Et2LinkAppSelect} from "./Et2LinkAppSelect";
|
2022-06-01 21:30:31 +02:00
|
|
|
import {Et2Link} from "./Et2Link";
|
2022-05-31 21:40:31 +02:00
|
|
|
|
|
|
|
export class Et2LinkSearch 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;
|
|
|
|
}
|
|
|
|
`
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static get properties()
|
|
|
|
{
|
|
|
|
return {
|
|
|
|
...super.properties,
|
|
|
|
app: {type: String, reflect: true}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
constructor()
|
|
|
|
{
|
|
|
|
super();
|
|
|
|
this.search = true;
|
|
|
|
this.searchUrl = "EGroupware\\Api\\Etemplate\\Widget\\Link::ajax_link_search";
|
2022-06-01 17:23:07 +02:00
|
|
|
this.clearable = true;
|
2022-06-02 19:52:27 +02:00
|
|
|
this.hoist = true;
|
2022-10-13 17:18:49 +02:00
|
|
|
this.placeholder = this.getAttribute("placeholder") || this.egw().lang("search");
|
2022-05-31 21:40:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
get _appNode() : Et2LinkAppSelect
|
|
|
|
{
|
2023-07-25 16:48:10 +02:00
|
|
|
return this.parentNode?.querySelector("et2-link-apps");
|
2022-05-31 21:40:31 +02:00
|
|
|
}
|
|
|
|
|
2022-07-20 23:05:05 +02:00
|
|
|
/**
|
|
|
|
* Override parent to do nothing - option is often not in select options
|
|
|
|
*
|
|
|
|
*/
|
2022-10-13 17:18:49 +02:00
|
|
|
protected fix_bad_value()
|
2022-07-20 23:05:05 +02:00
|
|
|
{}
|
|
|
|
|
2022-05-31 21:40:31 +02:00
|
|
|
protected remoteQuery(search : string, options : object)
|
|
|
|
{
|
2023-07-25 16:48:10 +02:00
|
|
|
let request = this.egw().request(this.searchUrl, [this._appNode?.value ?? options.app, '', search, options]);
|
2022-05-31 21:40:31 +02:00
|
|
|
if(this.query && typeof this.query == "function")
|
|
|
|
{
|
|
|
|
if(!this.query(request, this))
|
|
|
|
{
|
2023-07-25 17:14:13 +02:00
|
|
|
return Promise.resolve([]);
|
2022-05-31 21:40:31 +02:00
|
|
|
}
|
|
|
|
}
|
2022-09-16 18:20:47 +02:00
|
|
|
return request.then((result) =>
|
2022-05-31 21:40:31 +02:00
|
|
|
{
|
2023-11-16 23:05:38 +01:00
|
|
|
return this._processResultCount(result);
|
2022-05-31 21:40:31 +02:00
|
|
|
});
|
|
|
|
}
|
2022-06-01 21:30:31 +02:00
|
|
|
|
|
|
|
updated(changedProperties)
|
|
|
|
{
|
|
|
|
super.updated(changedProperties);
|
|
|
|
|
|
|
|
// Set a value we don't have as an option? That's OK, we'll just add it
|
2023-09-13 19:55:33 +02:00
|
|
|
if(changedProperties.has("value") && this.value && this.value.length > 0 && (
|
2023-09-19 16:46:41 +02:00
|
|
|
this.select_options.length == 0 ||
|
|
|
|
this.select_options.filter && this.select_options.filter(item => this.getValueAsArray().includes(item.value)).length == 0
|
2022-06-01 21:30:31 +02:00
|
|
|
))
|
|
|
|
{
|
|
|
|
this._missingOption(this.value)
|
|
|
|
}
|
2022-06-17 22:06:12 +02:00
|
|
|
if(changedProperties.has("readonly"))
|
|
|
|
{
|
|
|
|
this.clearable = !this.readonly;
|
|
|
|
}
|
2022-06-01 21:30:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The set value requires an option we don't have.
|
|
|
|
* Add it in, asking server for title if needed
|
|
|
|
*
|
|
|
|
* @param value
|
|
|
|
* @protected
|
|
|
|
*/
|
|
|
|
protected _missingOption(value : string)
|
|
|
|
{
|
|
|
|
let option = {
|
|
|
|
value: value,
|
|
|
|
label: Et2Link.MISSING_TITLE,
|
|
|
|
class: "loading"
|
|
|
|
}
|
2023-11-30 19:56:14 +01:00
|
|
|
|
2022-06-01 21:30:31 +02:00
|
|
|
// Weird call instead of just unshift() to make sure to trigger setter
|
|
|
|
this.select_options = Object.assign([option], this.__select_options);
|
|
|
|
this.egw()?.link_title(this.app, option.value, true).then(title =>
|
|
|
|
{
|
2022-08-05 00:25:44 +02:00
|
|
|
option.label = title || Et2Link.MISSING_TITLE;
|
2022-06-01 21:30:31 +02:00
|
|
|
option.class = "";
|
2022-06-02 18:18:46 +02:00
|
|
|
// It's probably already been rendered, find the item
|
2023-11-30 19:56:14 +01:00
|
|
|
let item = this.select?.querySelector('[value="' + option.value + '"]');
|
2022-06-02 18:18:46 +02:00
|
|
|
if(item)
|
|
|
|
{
|
2023-12-05 01:06:26 +01:00
|
|
|
this.requestUpdate();
|
2023-11-30 19:56:14 +01:00
|
|
|
this.select.requestUpdate("value");
|
|
|
|
|
2022-06-02 18:18:46 +02:00
|
|
|
item.classList.remove("loading");
|
2022-07-18 23:27:31 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Not already rendered, update the select option
|
|
|
|
this.requestUpdate("select_options");
|
2022-06-02 18:18:46 +02:00
|
|
|
}
|
2022-06-01 21:30:31 +02:00
|
|
|
});
|
|
|
|
}
|
2023-01-13 19:28:02 +01:00
|
|
|
|
|
|
|
public validate()
|
|
|
|
{
|
|
|
|
// Do not validate
|
|
|
|
}
|
2022-05-31 21:40:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// @ts-ignore TypeScript is not recognizing that this widget is a LitElement
|
|
|
|
customElements.define("et2-link-search", Et2LinkSearch);
|