mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-22 16:03:47 +01:00
Et2Tree now only binds on eventhandler for contextmenu and one for default instead of binding one for every item
-- EgwPopupActionImplementation now only binds one Handler iff FindActionTarget is implemented and actionObjectInterface has attribute tree set. This is only the case for EgwDragDropShoelaceTree
This commit is contained in:
parent
d5ffc615af
commit
6271f71a12
@ -134,9 +134,10 @@ export class EgwAction {
|
|||||||
* @param {string} _iconUrl
|
* @param {string} _iconUrl
|
||||||
* @param {(string|function)} _onExecute
|
* @param {(string|function)} _onExecute
|
||||||
* @param {boolean} _allowOnMultiple
|
* @param {boolean} _allowOnMultiple
|
||||||
* @returns {EgwAction}
|
* @returns EgwAction
|
||||||
**/
|
**/
|
||||||
constructor(_parent: EgwAction, _id: string, _caption: string = "", _iconUrl: string = "", _onExecute: string | Function = null, _allowOnMultiple: boolean = true) {
|
constructor(_parent: EgwAction, _id: string, _caption: string = "", _iconUrl: string = "", _onExecute: string | Function = null, _allowOnMultiple: boolean = true)
|
||||||
|
{
|
||||||
if (_parent && (typeof _id != "string" || !_id) && _parent.type !== "actionManager") {
|
if (_parent && (typeof _id != "string" || !_id) && _parent.type !== "actionManager") {
|
||||||
throw "EgwAction _id must be a non-empty string!";
|
throw "EgwAction _id must be a non-empty string!";
|
||||||
}
|
}
|
||||||
@ -294,10 +295,12 @@ export class EgwAction {
|
|||||||
if (typeof elem.icon == "undefined") elem.icon = this.defaultIcons[elem.id]; // only works if default Icon is available
|
if (typeof elem.icon == "undefined") elem.icon = this.defaultIcons[elem.id]; // only works if default Icon is available
|
||||||
if (typeof elem.icon != "undefined") {
|
if (typeof elem.icon != "undefined") {
|
||||||
elem.iconUrl = localEgw.image(elem.icon);
|
elem.iconUrl = localEgw.image(elem.icon);
|
||||||
}
|
} else //elem.icon and elem.iconUrl is still undefined
|
||||||
|
{
|
||||||
//if there is no icon and none can be found remove icon tag from the object
|
//if there is no icon and none can be found remove icon tag from the object
|
||||||
delete elem.icon;
|
delete elem.icon;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// always add shortcut for delete
|
// always add shortcut for delete
|
||||||
if (elem.id == "delete" && typeof elem.shortcut == "undefined") {
|
if (elem.id == "delete" && typeof elem.shortcut == "undefined") {
|
||||||
|
@ -17,20 +17,46 @@ import {EgwActionImplementation} from "./EgwActionImplementation";
|
|||||||
import {EgwActionObject} from "./EgwActionObject";
|
import {EgwActionObject} from "./EgwActionObject";
|
||||||
import {EgwPopupAction} from "./EgwPopupAction";
|
import {EgwPopupAction} from "./EgwPopupAction";
|
||||||
import {egw} from "../jsapi/egw_global";
|
import {egw} from "../jsapi/egw_global";
|
||||||
|
import {Et2Tree} from "../etemplate/Et2Tree/Et2Tree";
|
||||||
|
import {FindActionTarget} from "../etemplate/FindActionTarget";
|
||||||
|
|
||||||
export class EgwPopupActionImplementation implements EgwActionImplementation {
|
export class EgwPopupActionImplementation implements EgwActionImplementation {
|
||||||
type = "popup";
|
type = "popup";
|
||||||
auto_paste = true;
|
auto_paste = true;
|
||||||
|
parent?: FindActionTarget //currently only implemented by Et2Tree
|
||||||
|
|
||||||
registerAction = (_aoi, _callback, _context) => {
|
registerAction = (_aoi, _callback, _context) => {
|
||||||
|
const parent = _aoi.tree; // maybe expand this to aoi.?? for other actionObjectInterfaces
|
||||||
|
let isNew = parent?.findActionTarget != null
|
||||||
const node = _aoi.getDOMNode();
|
const node = _aoi.getDOMNode();
|
||||||
|
if (node == this.parent) return true //Event Listener already bound on parent
|
||||||
|
if (isNew)
|
||||||
|
{
|
||||||
|
if (this.parent && this.parent == parent)
|
||||||
|
{
|
||||||
|
return true // already added Event Listener on parent no need to register on children
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
|
||||||
if (node) {
|
this.parent = parent // this only exists for the EgwDragDropShoelaceTree ActionObjectInterface atm
|
||||||
|
|
||||||
|
//if a parent is available the context menu Event-listener will only be bound once on the parent
|
||||||
|
this._registerDefault(parent, _callback, _context);
|
||||||
|
this._registerContext(parent, _callback, _context);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
this._registerDefault(node, _callback, _context);
|
this._registerDefault(node, _callback, _context);
|
||||||
this._registerContext(node, _callback, _context);
|
this._registerContext(node, _callback, _context);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
unregisterAction = function (_aoi) {
|
unregisterAction = function (_aoi) {
|
||||||
@ -94,12 +120,24 @@ export class EgwPopupActionImplementation implements EgwActionImplementation {
|
|||||||
*/
|
*/
|
||||||
private _registerDefault = (_node, _callback, _context)=> {
|
private _registerDefault = (_node, _callback, _context)=> {
|
||||||
const defaultHandler = (e)=> {
|
const defaultHandler = (e)=> {
|
||||||
|
const x = _node
|
||||||
|
//use different node and context for callback if event happens on parent
|
||||||
|
let nodeToUse;
|
||||||
|
let contextToUse;
|
||||||
|
if (x.findActionTarget)
|
||||||
|
{
|
||||||
|
const y = x.findActionTarget(e);
|
||||||
|
nodeToUse = y?.target;
|
||||||
|
contextToUse = y?.action;
|
||||||
|
e.originalEvent = e;
|
||||||
|
|
||||||
|
}
|
||||||
//allow bubbling of the expand folder event
|
//allow bubbling of the expand folder event
|
||||||
//do not stop bubbling of events if the event is supposed to be handled by the et2-tree
|
//do not stop bubbling of events if the event is supposed to be handled by the et2-tree
|
||||||
if (window.egwIsMobile() && e.currentTarget.tagName == "SL-TREE-ITEM") return true;
|
if (window.egwIsMobile() && (nodeToUse || e.currentTarget).tagName == "SL-TREE-ITEM") return true;
|
||||||
// a tag should be handled by default event
|
// a tag should be handled by default event
|
||||||
// Prevent bubbling bound event on <a> tag, on touch devices
|
// Prevent bubbling bound event on <a> tag, on touch devices
|
||||||
if (window.egwIsMobile() && e.target.tagName == "A") return true;
|
if (window.egwIsMobile() && (nodeToUse || e.target).tagName == "A") return true;
|
||||||
|
|
||||||
|
|
||||||
if (typeof document["selection"] != "undefined" && typeof document["selection"].empty != "undefined") {
|
if (typeof document["selection"] != "undefined" && typeof document["selection"].empty != "undefined") {
|
||||||
@ -109,9 +147,13 @@ export class EgwPopupActionImplementation implements EgwActionImplementation {
|
|||||||
sel.removeAllRanges();
|
sel.removeAllRanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(_context.manager.getActionsByAttr('singleClick', true).length > 0 &&
|
if (!
|
||||||
e.target.classList.contains('et2_clickable'))) {
|
((contextToUse || _context).manager.getActionsByAttr('singleClick', true).length > 0 &&
|
||||||
_callback.call(_context, "default", this);
|
(nodeToUse || e.target).classList.contains('et2_clickable')
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_callback.call(contextToUse || _context, "default", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop action from bubbling up to parents
|
// Stop action from bubbling up to parents
|
||||||
@ -240,8 +282,19 @@ export class EgwPopupActionImplementation implements EgwActionImplementation {
|
|||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
private _registerContext = (_node, _callback, _context) => {
|
private _registerContext = (_node, _callback, _context) => {
|
||||||
const contextHandler = (e) => {
|
|
||||||
|
|
||||||
|
const contextHandler = (e) => {
|
||||||
|
const x = _node
|
||||||
|
//use different node and context for callback if event happens on parent
|
||||||
|
let nodeToUse;
|
||||||
|
let contextToUse;
|
||||||
|
if (x.findActionTarget)
|
||||||
|
{
|
||||||
|
const y = x.findActionTarget(e);
|
||||||
|
nodeToUse = y?.target;
|
||||||
|
contextToUse = y?.action;
|
||||||
|
e.originalEvent = e;
|
||||||
|
}
|
||||||
//Obtain the event object, this should not happen at any point
|
//Obtain the event object, this should not happen at any point
|
||||||
if (!e) {
|
if (!e) {
|
||||||
e = window.event;
|
e = window.event;
|
||||||
@ -250,25 +303,35 @@ export class EgwPopupActionImplementation implements EgwActionImplementation {
|
|||||||
// Close any open tooltip so they don't get in the way
|
// Close any open tooltip so they don't get in the way
|
||||||
egw(window).tooltipCancel();
|
egw(window).tooltipCancel();
|
||||||
|
|
||||||
if (_egw_active_menu) {
|
if (_egw_active_menu)
|
||||||
|
{
|
||||||
_egw_active_menu.hide();
|
_egw_active_menu.hide();
|
||||||
} else if (!e.ctrlKey && e.which == 3 || e.which === 0 || e.type === 'tapandhold') // tap event indicates by 0
|
} else if (!e.ctrlKey && e.which == 3 || e.which === 0 || e.type === 'tapandhold') // tap event indicates by 0
|
||||||
{
|
{
|
||||||
const _xy = this._getPageXY(e);
|
const _xy = this._getPageXY(e);
|
||||||
const _implContext = {event: e, posx: _xy.posx, posy: _xy.posy};
|
const _implContext = {
|
||||||
_callback.call(_context, _implContext, this);
|
event: e, posx: _xy.posx,
|
||||||
|
posy: _xy.posy,
|
||||||
|
innerText: nodeToUse.innerText || _node.innerText,//nodeToUse only exists on widgets that define findActionTarget
|
||||||
|
target: nodeToUse.target || _node,
|
||||||
|
};
|
||||||
|
_callback.call(contextToUse || _context, _implContext, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
e.cancelBubble = !e.ctrlKey || e.which == 1;
|
e.cancelBubble = !e.ctrlKey || e.which == 1;
|
||||||
if (e.stopPropagation && e.cancelBubble) {
|
if (e.stopPropagation && e.cancelBubble) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
e.preventDefault()
|
||||||
}
|
}
|
||||||
return !e.cancelBubble;
|
return !e.cancelBubble;
|
||||||
};
|
};
|
||||||
// Safari still needs the taphold to trigger contextmenu
|
// Safari still needs the taphold to trigger contextmenu
|
||||||
// Chrome has default event on touch and hold which acts like right click
|
// Chrome has default event on touch and hold which acts like right click
|
||||||
this._handleTapHold(_node, contextHandler);
|
this._handleTapHold(_node, contextHandler);
|
||||||
if (!window.egwIsMobile()) jQuery(_node).on('contextmenu', contextHandler);
|
if (!window.egwIsMobile())
|
||||||
|
{
|
||||||
|
_node.addEventListener('contextmenu', contextHandler);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -512,7 +575,7 @@ export class EgwPopupActionImplementation implements EgwActionImplementation {
|
|||||||
offset: {top: 0, left: 0}
|
offset: {top: 0, left: 0}
|
||||||
};
|
};
|
||||||
if (this._context.event) {
|
if (this._context.event) {
|
||||||
const event = this._context.event.originalEvent;
|
const event = this._context.event.originalEvent || this._context.event;
|
||||||
ui.position = {top: event.pageY, left: event.pageX};
|
ui.position = {top: event.pageY, left: event.pageX};
|
||||||
ui.offset = {top: event.offsetY, left: event.offsetX};
|
ui.offset = {top: event.offsetY, left: event.offsetX};
|
||||||
}
|
}
|
||||||
@ -598,9 +661,9 @@ export class EgwPopupActionImplementation implements EgwActionImplementation {
|
|||||||
}
|
}
|
||||||
let os_clipboard_caption = "";
|
let os_clipboard_caption = "";
|
||||||
if (this._context.event) {
|
if (this._context.event) {
|
||||||
os_clipboard_caption = this._context.event.originalEvent.target.innerText.trim();
|
os_clipboard_caption = this._context.innerText.trim();
|
||||||
clipboard_action.set_caption(window.egw.lang('Copy "%1"', os_clipboard_caption.length > 20 ? os_clipboard_caption.substring(0, 20) + '...' : os_clipboard_caption));
|
clipboard_action.set_caption(window.egw.lang('Copy "%1"', os_clipboard_caption.length > 20 ? os_clipboard_caption.substring(0, 20) + '...' : os_clipboard_caption));
|
||||||
clipboard_action.data.target = this._context.event.originalEvent.target;
|
clipboard_action.data.target = this._context.target;
|
||||||
}
|
}
|
||||||
jQuery(clipboard_action.data.target).off('copy').on('copy', function (event) {
|
jQuery(clipboard_action.data.target).off('copy').on('copy', function (event) {
|
||||||
try {
|
try {
|
||||||
|
@ -12,6 +12,7 @@ import {et2_action_object_impl} from "../et2_core_DOMWidget";
|
|||||||
import {EgwActionObject} from "../../egw_action/EgwActionObject";
|
import {EgwActionObject} from "../../egw_action/EgwActionObject";
|
||||||
import {EgwAction} from "../../egw_action/EgwAction";
|
import {EgwAction} from "../../egw_action/EgwAction";
|
||||||
import {EgwDragDropShoelaceTree} from "../../egw_action/EgwDragDropShoelaceTree";
|
import {EgwDragDropShoelaceTree} from "../../egw_action/EgwDragDropShoelaceTree";
|
||||||
|
import {FindActionTarget} from "../FindActionTarget";
|
||||||
|
|
||||||
export type TreeItemData = SelectOption & {
|
export type TreeItemData = SelectOption & {
|
||||||
focused?: boolean;
|
focused?: boolean;
|
||||||
@ -73,7 +74,7 @@ export const composedPathContains = (_ev: any, tag?: string, className?: string)
|
|||||||
* //TODO add for other events
|
* //TODO add for other events
|
||||||
* @since 23.1.x
|
* @since 23.1.x
|
||||||
*/
|
*/
|
||||||
export class Et2Tree extends Et2WidgetWithSelectMixin(LitElement)
|
export class Et2Tree extends Et2WidgetWithSelectMixin(LitElement) implements FindActionTarget
|
||||||
{
|
{
|
||||||
//does not work because it would need to be run on the shadow root
|
//does not work because it would need to be run on the shadow root
|
||||||
//@query("sl-tree-item[selected]") selected: SlTreeItem;
|
//@query("sl-tree-item[selected]") selected: SlTreeItem;
|
||||||
@ -131,6 +132,7 @@ export class Et2Tree extends Et2WidgetWithSelectMixin(LitElement)
|
|||||||
selectedNodes: SlTreeItem[]
|
selectedNodes: SlTreeItem[]
|
||||||
|
|
||||||
private _actionManager: EgwAction;
|
private _actionManager: EgwAction;
|
||||||
|
widget_object: EgwActionObject;
|
||||||
|
|
||||||
private get _tree() { return this.shadowRoot.querySelector('sl-tree') ?? null};
|
private get _tree() { return this.shadowRoot.querySelector('sl-tree') ?? null};
|
||||||
|
|
||||||
@ -462,7 +464,7 @@ export class Et2Tree extends Et2WidgetWithSelectMixin(LitElement)
|
|||||||
return this._currentSlTreeItem
|
return this._currentSlTreeItem
|
||||||
}
|
}
|
||||||
|
|
||||||
getDomNode(_id): SlTreeItem|null
|
getDomNode(_id: string): SlTreeItem | null
|
||||||
{
|
{
|
||||||
return this.shadowRoot.querySelector('sl-tree-item[id="' + _id.replace(/"/g, '\\"') + '"');
|
return this.shadowRoot.querySelector('sl-tree-item[id="' + _id.replace(/"/g, '\\"') + '"');
|
||||||
}
|
}
|
||||||
@ -576,7 +578,7 @@ export class Et2Tree extends Et2WidgetWithSelectMixin(LitElement)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* getTreeNodeOpenItems TODO
|
* getTreeNodeOpenItems
|
||||||
*
|
*
|
||||||
* @param {string} _nodeID the nodeID where to start from (initial node) 0 means for all items
|
* @param {string} _nodeID the nodeID where to start from (initial node) 0 means for all items
|
||||||
* @param {string} mode the mode to run in: "forced" fakes the initial node openState to be open
|
* @param {string} mode the mode to run in: "forced" fakes the initial node openState to be open
|
||||||
@ -584,9 +586,6 @@ export class Et2Tree extends Et2WidgetWithSelectMixin(LitElement)
|
|||||||
*/
|
*/
|
||||||
getTreeNodeOpenItems(_nodeID: string | 0, mode?: string)
|
getTreeNodeOpenItems(_nodeID: string | 0, mode?: string)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
//let z:string[] = this.input.getSubItems(_nodeID).split(this.input.dlmtr);
|
|
||||||
let subItems =
|
let subItems =
|
||||||
(_nodeID == 0) ?
|
(_nodeID == 0) ?
|
||||||
this._selectOptions.map(option => this.getDomNode(option.id)) ://NodeID == 0 means that we want all tree Items
|
this._selectOptions.map(option => this.getDomNode(option.id)) ://NodeID == 0 means that we want all tree Items
|
||||||
@ -595,7 +594,6 @@ export class Et2Tree extends Et2WidgetWithSelectMixin(LitElement)
|
|||||||
let PoS: 0 | 1 | -1;
|
let PoS: 0 | 1 | -1;
|
||||||
let rv: string[];
|
let rv: string[];
|
||||||
let returnValue = (_nodeID == 0) ? [] : [_nodeID]; // do not keep 0 in the return value...
|
let returnValue = (_nodeID == 0) ? [] : [_nodeID]; // do not keep 0 in the return value...
|
||||||
// it is not needed and only throws a php warning later TODO check with ralf what happens in mail_ui.inc.php with ajax_setFolderStatus
|
|
||||||
let modetorun = "none";
|
let modetorun = "none";
|
||||||
if (mode)
|
if (mode)
|
||||||
{
|
{
|
||||||
@ -817,6 +815,7 @@ export class Et2Tree extends Et2WidgetWithSelectMixin(LitElement)
|
|||||||
const parentNode = selectOption ?? this.getNode(selectOption.id) ?? this.optionSearch(selectOption.id, this._selectOptions, 'id', 'item');
|
const parentNode = selectOption ?? this.getNode(selectOption.id) ?? this.optionSearch(selectOption.id, this._selectOptions, 'id', 'item');
|
||||||
parentNode.item = [...result.item]
|
parentNode.item = [...result.item]
|
||||||
this.requestUpdate("_selectOptions")
|
this.requestUpdate("_selectOptions")
|
||||||
|
this._link_actions(this.actions)
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -933,7 +932,7 @@ export class Et2Tree extends Et2WidgetWithSelectMixin(LitElement)
|
|||||||
{
|
{
|
||||||
this.onopenend(event.detail.id, this, -1)
|
this.onopenend(event.detail.id, this, -1)
|
||||||
}
|
}
|
||||||
this._link_actions(this.actions)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -976,12 +975,12 @@ export class Et2Tree extends Et2WidgetWithSelectMixin(LitElement)
|
|||||||
}
|
}
|
||||||
// Get the top level element for the tree
|
// Get the top level element for the tree
|
||||||
let objectManager = egw_getAppObjectManager(true);
|
let objectManager = egw_getAppObjectManager(true);
|
||||||
let widget_object = objectManager.getObjectById(this.id);
|
this.widget_object = objectManager.getObjectById(this.id);
|
||||||
if (widget_object == null)
|
if (this.widget_object == null)
|
||||||
{
|
{
|
||||||
// Add a new container to the object manager which will hold the widget
|
// Add a new container to the object manager which will hold the widget
|
||||||
// objects
|
// objects
|
||||||
widget_object = objectManager.insertObject(false, new EgwActionObject(
|
this.widget_object = objectManager.insertObject(false, new EgwActionObject(
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
this.id, objectManager, (new et2_action_object_impl(this, this)).getAOI(),
|
this.id, objectManager, (new et2_action_object_impl(this, this)).getAOI(),
|
||||||
this._actionManager || objectManager.manager.getActionById(this.id) || objectManager.manager
|
this._actionManager || objectManager.manager.getActionById(this.id) || objectManager.manager
|
||||||
@ -989,12 +988,12 @@ export class Et2Tree extends Et2WidgetWithSelectMixin(LitElement)
|
|||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
widget_object.setAOI((new et2_action_object_impl(this, this)).getAOI());
|
this.widget_object.setAOI((new et2_action_object_impl(this, this)).getAOI());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete all old objects
|
// Delete all old objects
|
||||||
widget_object.clear();
|
this.widget_object.clear();
|
||||||
widget_object.unregisterActions();
|
this.widget_object.unregisterActions();
|
||||||
|
|
||||||
// Go over the widget & add links - this is where we decide which actions are
|
// Go over the widget & add links - this is where we decide which actions are
|
||||||
// 'allowed' for this widget at this time
|
// 'allowed' for this widget at this time
|
||||||
@ -1006,7 +1005,7 @@ export class Et2Tree extends Et2WidgetWithSelectMixin(LitElement)
|
|||||||
// Iterate over the options (leaves) and add action to each one
|
// Iterate over the options (leaves) and add action to each one
|
||||||
let apply_actions = function (treeObj: EgwActionObject, option: TreeItemData) {
|
let apply_actions = function (treeObj: EgwActionObject, option: TreeItemData) {
|
||||||
// Add a new action object to the object manager
|
// Add a new action object to the object manager
|
||||||
let id = option.value ?? (typeof option.value == 'number' ? String(option.id) : option.id);
|
let id = option.value ?? (typeof option.id == 'number' ? String(option.id) : option.id);
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
let obj : EgwActionObject = treeObj.addObject(id, new EgwDragDropShoelaceTree(self, id));
|
let obj : EgwActionObject = treeObj.addObject(id, new EgwDragDropShoelaceTree(self, id));
|
||||||
obj.updateActionLinks(action_links);
|
obj.updateActionLinks(action_links);
|
||||||
@ -1020,12 +1019,12 @@ export class Et2Tree extends Et2WidgetWithSelectMixin(LitElement)
|
|||||||
for (const selectOption of this._selectOptions)
|
for (const selectOption of this._selectOptions)
|
||||||
{
|
{
|
||||||
|
|
||||||
apply_actions.call(this, widget_object, selectOption)
|
apply_actions.call(this, this.widget_object, selectOption)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
widget_object.updateActionLinks(action_links);
|
this.widget_object.updateActionLinks(action_links);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1116,6 +1115,23 @@ export class Et2Tree extends Et2WidgetWithSelectMixin(LitElement)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the closest SlItem to the click position, and the corresponding EgwActionObject
|
||||||
|
* @param _event the click event
|
||||||
|
* @returns { target:SlTreeItem, action:EgwActionObject }
|
||||||
|
*/
|
||||||
|
findActionTarget(_event): { target: SlTreeItem, action: EgwActionObject }
|
||||||
|
{
|
||||||
|
let e = _event.composedPath ? _event : _event.originalEvent;
|
||||||
|
let target = e.composedPath().find(element => {
|
||||||
|
return element.tagName == "SL-TREE-ITEM"
|
||||||
|
})
|
||||||
|
let action: EgwActionObject = this.widget_object.children.find(elem => {
|
||||||
|
return elem.id == target.id
|
||||||
|
})
|
||||||
|
return {target: target, action: action}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("et2-tree", Et2Tree);
|
customElements.define("et2-tree", Et2Tree);
|
11
api/js/etemplate/FindActionTarget.ts
Normal file
11
api/js/etemplate/FindActionTarget.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import {EgwActionObject} from "../egw_action/EgwActionObject";
|
||||||
|
|
||||||
|
export interface FindActionTarget
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* returns the closest Item to the click position, and the corresponding EgwActionObject
|
||||||
|
* @param _event the click event
|
||||||
|
* @returns { target:HTMLElement, action:EgwActionObject }
|
||||||
|
*/
|
||||||
|
findActionTarget(_event): { target: HTMLElement, action: EgwActionObject };
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user