mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-29 19:33:54 +01:00
WIP sl-Tree
This commit is contained in:
parent
e3ca0bfacd
commit
aa228dad42
@ -1,12 +1,14 @@
|
|||||||
import {Et2InputWidget} from "../Et2InputWidget/Et2InputWidget";
|
import {Et2InputWidget} from "../Et2InputWidget/Et2InputWidget";
|
||||||
import {SlTree} from "@shoelace-style/shoelace";
|
import {SlTree} from "@shoelace-style/shoelace";
|
||||||
import {Et2Link} from "../Et2Link/Et2Link";
|
import {Et2Link} from "../Et2Link/Et2Link";
|
||||||
import {Et2widgetWithSelectMixin} from "../Et2Select/Et2WidgetWithSelectMixin";
|
|
||||||
import {et2_no_init} from "../et2_core_common";
|
import {et2_no_init} from "../et2_core_common";
|
||||||
import {egw, framework} from "../../jsapi/egw_global";
|
import {egw, framework} from "../../jsapi/egw_global";
|
||||||
import {SelectOption, find_select_options, cleanSelectOptions} from "../Et2Select/FindSelectOptions";
|
import {SelectOption, find_select_options, cleanSelectOptions} from "../Et2Select/FindSelectOptions";
|
||||||
import {html, TemplateResult} from "@lion/core";
|
|
||||||
import {egwIsMobile} from "../../egw_action/egw_action_common";
|
import {egwIsMobile} from "../../egw_action/egw_action_common";
|
||||||
|
import {Et2WidgetWithSelectMixin} from "../Et2Select/Et2WidgetWithSelectMixin";
|
||||||
|
import {LitElement, css, TemplateResult, html} from "lit";
|
||||||
|
import {repeat} from "lit/directives/repeat.js";
|
||||||
|
import shoelace from "../Styles/shoelace";
|
||||||
|
|
||||||
export type TreeItem = {
|
export type TreeItem = {
|
||||||
child: Boolean | 1,
|
child: Boolean | 1,
|
||||||
@ -25,17 +27,46 @@ export type TreeItem = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export class Et2Tree extends Et2widgetWithSelectMixin(SlTree) {
|
export class Et2Tree extends Et2WidgetWithSelectMixin(LitElement)
|
||||||
private input: any = null;
|
{
|
||||||
private div: JQuery;
|
static get styles()
|
||||||
private autoloading_url: any;
|
{
|
||||||
private selectOptions: TreeItem[];
|
|
||||||
|
|
||||||
constructor() {
|
return [
|
||||||
|
shoelace,
|
||||||
|
// @ts-ignore
|
||||||
|
...super.styles,
|
||||||
|
css`
|
||||||
|
|
||||||
|
`
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
private currentItem: TreeItem
|
||||||
|
private input: any = null;
|
||||||
|
private autoloading_url: any;
|
||||||
|
private selectOptions: TreeItem[] = [];
|
||||||
|
private needsLazyLoading: Boolean = true;
|
||||||
|
/**
|
||||||
|
* Limit server searches to 100 results, matches Link::DEFAULT_NUM_ROWS
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
static RESULT_LIMIT: number = 100;
|
||||||
|
|
||||||
|
constructor()
|
||||||
|
{
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
static get properties() {
|
public loadFromXML()
|
||||||
|
{
|
||||||
|
//if(this.id)
|
||||||
|
this.selectOptions = <TreeItem[]><unknown>find_select_options(this)[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
static get properties()
|
||||||
|
{
|
||||||
return {
|
return {
|
||||||
...super.properties,
|
...super.properties,
|
||||||
multiple: {
|
multiple: {
|
||||||
@ -123,46 +154,38 @@ export class Et2Tree extends Et2widgetWithSelectMixin(SlTree) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public set onOpenStart(_handler: Function) {
|
public set onOpenStart(_handler: Function)
|
||||||
|
{
|
||||||
this.installHandler("onOpenStart", _handler)
|
this.installHandler("onOpenStart", _handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
public set onChange(_handler: Function) {
|
public set onChange(_handler: Function)
|
||||||
|
{
|
||||||
this.installHandler("onChange", _handler)
|
this.installHandler("onChange", _handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
public set onClick(_handler: Function) {
|
public set onClick(_handler: Function)
|
||||||
|
{
|
||||||
this.installHandler("onClick", _handler)
|
this.installHandler("onClick", _handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
public set onSelect(_handler: Function) {
|
public set onSelect(_handler: Function)
|
||||||
|
{
|
||||||
this.installHandler("onSelect", _handler)
|
this.installHandler("onSelect", _handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
public set onOpenEnd(_handler: Function) {
|
public set onOpenEnd(_handler: Function)
|
||||||
|
{
|
||||||
this.installHandler("onOpenEnd", _handler)
|
this.installHandler("onOpenEnd", _handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
_optionTemplate() {
|
|
||||||
// @ts-ignore
|
|
||||||
this.selectOptions= find_select_options(this)[1];
|
|
||||||
//slot = expanded/collapsed instead of expand/collapse like it is in documentation
|
|
||||||
let result: TemplateResult<1> = html``
|
|
||||||
for (const selectOption of this.selectOptions) {
|
|
||||||
result = html`${result}
|
|
||||||
<sl-tree-item>
|
|
||||||
${this.recursivelyAddChildren(selectOption)}
|
|
||||||
</sl-tree-item>`
|
|
||||||
}
|
|
||||||
const h = html`${result}`
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated assign to onOpenStart
|
* @deprecated assign to onOpenStart
|
||||||
* @param _handler
|
* @param _handler
|
||||||
*/
|
*/
|
||||||
public set_onopenstart(_handler: Function) {
|
public set_onopenstart(_handler: Function)
|
||||||
|
{
|
||||||
this.installHandler("onOpenStart", _handler)
|
this.installHandler("onOpenStart", _handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,7 +193,8 @@ export class Et2Tree extends Et2widgetWithSelectMixin(SlTree) {
|
|||||||
* @deprecated assign to onChange
|
* @deprecated assign to onChange
|
||||||
* @param _handler
|
* @param _handler
|
||||||
*/
|
*/
|
||||||
public set_onchange(_handler: Function) {
|
public set_onchange(_handler: Function)
|
||||||
|
{
|
||||||
this.installHandler('onchange', _handler);
|
this.installHandler('onchange', _handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,7 +202,8 @@ export class Et2Tree extends Et2widgetWithSelectMixin(SlTree) {
|
|||||||
* @deprecated assign to onClick
|
* @deprecated assign to onClick
|
||||||
* @param _handler
|
* @param _handler
|
||||||
*/
|
*/
|
||||||
public set_onclick(_handler: Function) {
|
public set_onclick(_handler: Function)
|
||||||
|
{
|
||||||
this.installHandler('onclick', _handler);
|
this.installHandler('onclick', _handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,7 +211,8 @@ export class Et2Tree extends Et2widgetWithSelectMixin(SlTree) {
|
|||||||
* @deprecated assign to onSelect
|
* @deprecated assign to onSelect
|
||||||
* @param _handler
|
* @param _handler
|
||||||
*/
|
*/
|
||||||
public set_onselect(_handler: Function) {
|
public set_onselect(_handler: Function)
|
||||||
|
{
|
||||||
this.installHandler('onselect', _handler);
|
this.installHandler('onselect', _handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,36 +220,15 @@ export class Et2Tree extends Et2widgetWithSelectMixin(SlTree) {
|
|||||||
* @deprecated assign to onOpenEnd
|
* @deprecated assign to onOpenEnd
|
||||||
* @param _handler
|
* @param _handler
|
||||||
*/
|
*/
|
||||||
public set_onopenend(_handler: Function) {
|
public set_onopenend(_handler: Function)
|
||||||
|
{
|
||||||
this.installHandler('onOpenEnd', _handler);
|
this.installHandler('onOpenEnd', _handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
private recursivelyAddChildren(item: any): TemplateResult<1> {
|
|
||||||
let img:String =item.im0??item.im1??item.im2;
|
|
||||||
let attributes = ""
|
|
||||||
let res: TemplateResult<1> = html`${item.text}`;
|
|
||||||
if(img){
|
|
||||||
img = "api/templates/default/images/dhtmlxtree/"+img
|
|
||||||
//sl-icon images need to be svgs if there is a png try to find the corresponding svg
|
|
||||||
if(img.endsWith(".png"))img = img.replace(".png",".svg");
|
|
||||||
res = html`<sl-icon src=${img}></sl-icon>${res}`
|
|
||||||
}
|
|
||||||
if (item.item?.length > 0) // there are children available
|
|
||||||
{
|
|
||||||
for (const subItem of item.item) {
|
|
||||||
res = html`
|
|
||||||
${res}
|
|
||||||
<sl-tree-item lazy> ${this.recursivelyAddChildren(subItem)}</sl-tree-item>`
|
|
||||||
}
|
|
||||||
// }else if(item.child === 1){
|
|
||||||
// res = html``
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
private installHandler(_name: String, _handler: Function) {
|
private installHandler(_name: String, _handler: Function)
|
||||||
if (this.input == null) this.createTree(this);
|
{
|
||||||
|
if (this.input == null) this.createTree();
|
||||||
// automatic convert onChange event to oncheck or onSelect depending on multiple is used or not
|
// automatic convert onChange event to oncheck or onSelect depending on multiple is used or not
|
||||||
// if (_name == "onchange") {
|
// if (_name == "onchange") {
|
||||||
// _name = this.options.multiple ? "oncheck" : "onselect"
|
// _name = this.options.multiple ? "oncheck" : "onselect"
|
||||||
@ -240,17 +245,108 @@ export class Et2Tree extends Et2widgetWithSelectMixin(SlTree) {
|
|||||||
// });
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
private createTree(widget: this) {
|
private createTree()
|
||||||
widget.input = document.querySelector("et2-tree");
|
{
|
||||||
// Allow controlling icon size by CSS
|
// widget.input = document.querySelector("et2-tree");
|
||||||
widget.input.def_img_x = "";
|
// // Allow controlling icon size by CSS
|
||||||
widget.input.def_img_y = "";
|
// widget.input.def_img_x = "";
|
||||||
|
// widget.input.def_img_y = "";
|
||||||
|
//
|
||||||
|
// // to allow "," in value, eg. folder-names, IF value is specified as array
|
||||||
|
// widget.input.dlmtr = ':}-*(';
|
||||||
|
// @ts-ignore from static get properties
|
||||||
|
if (this.autoLoading)
|
||||||
|
{
|
||||||
|
// @ts-ignore from static get properties
|
||||||
|
let url = this.autoLoading;
|
||||||
|
|
||||||
// to allow "," in value, eg. folder-names, IF value is specified as array
|
if (url.charAt(0) != '/' && url.substr(0, 4) != 'http')
|
||||||
widget.input.dlmtr = ':}-*(';
|
{
|
||||||
|
url = '/json.php?menuaction=' + url;
|
||||||
|
}
|
||||||
|
this.autoloading_url = url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleLazyLoading(_item: TreeItem)
|
||||||
|
{
|
||||||
|
let sendOptions = {
|
||||||
|
num_rows: Et2Tree.RESULT_LIMIT,
|
||||||
|
}
|
||||||
|
return egw().request(egw().link(egw().ajaxUrl(egw().decodePath(this.autoloading_url)),
|
||||||
|
{
|
||||||
|
id: _item.id
|
||||||
|
}), [sendOptions])
|
||||||
|
.then((results) => {
|
||||||
|
|
||||||
|
// If results have a total included, pull it out.
|
||||||
|
// It will cause errors if left in the results
|
||||||
|
// this._total_result_count = results.length;
|
||||||
|
// if(typeof results.total !== "undefined")
|
||||||
|
// {
|
||||||
|
// this._total_result_count = results.total;
|
||||||
|
// delete results.total;
|
||||||
|
// }
|
||||||
|
// let entries = cleanSelectOptions(results);
|
||||||
|
// this.processRemoteResults(entries);
|
||||||
|
// return entries;
|
||||||
|
return results
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//this.selectOptions = find_select_options(this)[1];
|
||||||
|
_optionTemplate(selectOption: TreeItem)
|
||||||
|
{
|
||||||
|
// @ts-ignore
|
||||||
|
|
||||||
|
//slot = expanded/collapsed instead of expand/collapse like it is in documentation
|
||||||
|
//selectOption.child === 1
|
||||||
|
return html`
|
||||||
|
<sl-tree-item
|
||||||
|
.currentItem=${selectOption}
|
||||||
|
?lazy=${this.needsLazyLoading}
|
||||||
|
@sl-lazy-load=${() => this.handleLazyLoading(selectOption)}
|
||||||
|
>
|
||||||
|
${selectOption.text}
|
||||||
|
${repeat(selectOption.item, this._optionTemplate.bind(this))}
|
||||||
|
</sl-tree-item>`
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(): unknown
|
||||||
|
{
|
||||||
|
return html`
|
||||||
|
<sl-tree
|
||||||
|
|
||||||
|
>
|
||||||
|
${repeat(this.selectOptions, this._optionTemplate.bind(this))}
|
||||||
|
</sl-tree>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected remoteQuery(search: string, options: object): Promise<SelectOption[]>
|
||||||
|
{
|
||||||
|
// Include a limit, even if options don't, to avoid massive lists breaking the UI
|
||||||
|
let sendOptions = {
|
||||||
|
num_rows: Et2Tree.RESULT_LIMIT,
|
||||||
|
...options
|
||||||
|
}
|
||||||
|
return this.egw().request(this.egw().link(this.egw().ajaxUrl(this.egw().decodePath(this.searchUrl)),
|
||||||
|
{query: search, ...sendOptions}), [search, sendOptions]).then((results) => {
|
||||||
|
// If results have a total included, pull it out.
|
||||||
|
// It will cause errors if left in the results
|
||||||
|
this._total_result_count = results.length;
|
||||||
|
if (typeof results.total !== "undefined")
|
||||||
|
{
|
||||||
|
this._total_result_count = results.total;
|
||||||
|
delete results.total;
|
||||||
|
}
|
||||||
|
let entries = cleanSelectOptions(results);
|
||||||
|
this.processRemoteResults(entries);
|
||||||
|
return entries;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("et2-tree", Et2Tree);
|
customElements.define("et2-tree", Et2Tree);
|
||||||
const tree = new Et2Tree();
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user