mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-25 09:23:28 +01:00
Fix Et2TreeDropdown context menu actions & missing validation error
This commit is contained in:
parent
4234afd453
commit
762a18e711
@ -124,6 +124,9 @@ export class Et2Tree extends Et2WidgetWithSelectMixin(LitElement)
|
|||||||
this.requestUpdate("_selectOptions");
|
this.requestUpdate("_selectOptions");
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Actions can't be initialized without being connected to InstanceManager
|
||||||
|
this._initActions();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Sl-Trees handle their own onClick events
|
//Sl-Trees handle their own onClick events
|
||||||
@ -182,96 +185,6 @@ export class Et2Tree extends Et2WidgetWithSelectMixin(LitElement)
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
static get properties()
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
...super.properties,
|
|
||||||
// multiple: {
|
|
||||||
// name: "",
|
|
||||||
// type: Boolean,
|
|
||||||
// default: false,
|
|
||||||
// description: "Allow selecting multiple options"
|
|
||||||
// },
|
|
||||||
// selectOptions: {
|
|
||||||
// type: "any",
|
|
||||||
// name: "Select options",
|
|
||||||
// default: {},
|
|
||||||
// description: "Used to set the tree options."
|
|
||||||
// },
|
|
||||||
// onclick: {
|
|
||||||
// name: "onclick",
|
|
||||||
// type: "js",
|
|
||||||
// description: "JS code which gets executed when clicks on text of a node"
|
|
||||||
// },
|
|
||||||
// onSelect: {
|
|
||||||
// name: "onSelect",
|
|
||||||
// type: "js",
|
|
||||||
// default: et2_no_init,
|
|
||||||
// description: "Javascript executed when user selects a node"
|
|
||||||
//},
|
|
||||||
// onCheck: {
|
|
||||||
// name: "onCheck",
|
|
||||||
// type: "js",
|
|
||||||
// default: et2_no_init,
|
|
||||||
// description: "Javascript executed when user checks a node"
|
|
||||||
// },
|
|
||||||
// onOpenStart: {
|
|
||||||
// name: "onOpenStart",
|
|
||||||
// type: "js",
|
|
||||||
// default: et2_no_init,
|
|
||||||
// description: "Javascript function executed when user opens a node: function(_id, _widget, _hasChildren) returning true to allow opening!"
|
|
||||||
// },
|
|
||||||
// onOpenEnd: {
|
|
||||||
// name: "onOpenEnd",
|
|
||||||
// type: "js",
|
|
||||||
// default: et2_no_init,
|
|
||||||
// description: "Javascript function executed when opening a node is finished: function(_id, _widget, _hasChildren)"
|
|
||||||
// },
|
|
||||||
// imagePath: {
|
|
||||||
// name: "Image directory",
|
|
||||||
// type: String,
|
|
||||||
// default: egw().webserverUrl + "/api/templates/default/images/dhtmlxtree/",//TODO we will need a different path here! maybe just rename the path?
|
|
||||||
// description: "Directory for tree structure images, set on server-side to 'dhtmlx' subdir of templates image-directory"
|
|
||||||
// },
|
|
||||||
// value: {
|
|
||||||
// type: "any",
|
|
||||||
// default: {}
|
|
||||||
// },
|
|
||||||
// actions: {
|
|
||||||
// name: "Actions array",
|
|
||||||
// type: "any",
|
|
||||||
// default: et2_no_init,
|
|
||||||
// description: "List of egw actions that can be done on the tree. This includes context menu, drag and drop. TODO: Link to action documentation"
|
|
||||||
// },
|
|
||||||
// autoloading: {
|
|
||||||
// name: "Auto loading",
|
|
||||||
// type: String,
|
|
||||||
// default: "",
|
|
||||||
// description: "JSON URL or menuaction to be called for nodes marked with child=1, but not having children, GET parameter selected contains node-id"
|
|
||||||
// },
|
|
||||||
//only used once ever as "bullet" in admin/.../index.xet
|
|
||||||
stdImages: {
|
|
||||||
name: "Standard images",
|
|
||||||
type: String,
|
|
||||||
default: "",
|
|
||||||
description: "comma-separated names of icons for a leaf, closed and opened folder (default: leaf.png,folderClosed.png,folderOpen.png), images with extension get loaded from imagePath, just 'image' or 'appname/image' are allowed too"
|
|
||||||
},
|
|
||||||
//what is this used for only used as "strict in mail subscribe.xet and folder_management.xet
|
|
||||||
multiMarking: {
|
|
||||||
name: "multi marking",
|
|
||||||
type: "any",
|
|
||||||
default: false,
|
|
||||||
description: "Allow marking multiple nodes, default is false which means disabled multiselection, true or 'strict' activates it and 'strict' makes it strict to only same level marking"
|
|
||||||
},
|
|
||||||
// highlighting: {
|
|
||||||
// name: "highlighting",
|
|
||||||
// type: Boolean,
|
|
||||||
// default: false,
|
|
||||||
// description: "Add highlighting class on hovered over item, highlighting is disabled by default"
|
|
||||||
// },
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private _actions: object
|
private _actions: object
|
||||||
|
|
||||||
get actions()
|
get actions()
|
||||||
@ -310,40 +223,19 @@ export class Et2Tree extends Et2WidgetWithSelectMixin(LitElement)
|
|||||||
{
|
{
|
||||||
this._actions = actions
|
this._actions = actions
|
||||||
if (this.id == "" || typeof this.id == "undefined")
|
if (this.id == "" || typeof this.id == "undefined")
|
||||||
|
{
|
||||||
|
if(this.isConnected)
|
||||||
{
|
{
|
||||||
window.egw().debug("warn", "Widget should have an ID if you want actions", this);
|
window.egw().debug("warn", "Widget should have an ID if you want actions", this);
|
||||||
|
}
|
||||||
|
// No id because we're not done yet, try again later
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the action manager and add some actions to it
|
if(this.isConnected)
|
||||||
// Only look 1 level deep
|
|
||||||
// @ts-ignore exists from Et2Widget
|
|
||||||
var gam = egw_getActionManager(this.egw().appName, true, 1);
|
|
||||||
if (typeof this._actionManager != "object")
|
|
||||||
{
|
{
|
||||||
// @ts-ignore exists from Et2Widget
|
this._initActions();
|
||||||
if (gam.getActionById(this.getInstanceManager().uniqueId, 1) !== null)
|
|
||||||
{
|
|
||||||
// @ts-ignore exists from Et2Widget
|
|
||||||
gam = gam.getActionById(this.getInstanceManager().uniqueId, 1);
|
|
||||||
}
|
}
|
||||||
if (gam.getActionById(this.id, 1) != null)
|
|
||||||
{
|
|
||||||
this._actionManager = gam.getActionById(this.id, 1);
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
this._actionManager = gam.addAction("actionManager", this.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// @ts-ignore egw() exists on this
|
|
||||||
this._actionManager.updateActions(actions, this.egw().appName);
|
|
||||||
// @ts-ignore
|
|
||||||
if (this.options.default_execute) this._actionManager.setDefaultExecute(this.options.default_execute);
|
|
||||||
|
|
||||||
// Put a reference to the widget into the action stuff, so we can
|
|
||||||
// easily get back to widget context from the action handler
|
|
||||||
this._actionManager.data = {widget: this};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public loadFromXML()
|
public loadFromXML()
|
||||||
@ -360,6 +252,45 @@ export class Et2Tree extends Et2WidgetWithSelectMixin(LitElement)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the action manager and add some actions to it
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
private _initActions()
|
||||||
|
{
|
||||||
|
// Only look 1 level deep
|
||||||
|
// @ts-ignore exists from Et2Widget
|
||||||
|
var gam = egw_getActionManager(this.egw().appName, true, 1);
|
||||||
|
if(typeof this._actionManager != "object")
|
||||||
|
{
|
||||||
|
// @ts-ignore exists from Et2Widget
|
||||||
|
if(this.getInstanceManager() && gam.getActionById(this.getInstanceManager().uniqueId, 1) !== null)
|
||||||
|
{
|
||||||
|
// @ts-ignore exists from Et2Widget
|
||||||
|
gam = gam.getActionById(this.getInstanceManager().uniqueId, 1);
|
||||||
|
}
|
||||||
|
if(gam.getActionById(this.id, 1) != null)
|
||||||
|
{
|
||||||
|
this._actionManager = gam.getActionById(this.id, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this._actionManager = gam.addAction("actionManager", this.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// @ts-ignore egw() exists on this
|
||||||
|
this._actionManager.updateActions(this.actions, this.egw().appName);
|
||||||
|
// @ts-ignore
|
||||||
|
if(this.options.default_execute)
|
||||||
|
{
|
||||||
|
this._actionManager.setDefaultExecute(this.options.default_execute);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put a reference to the widget into the action stuff, so we can
|
||||||
|
// easily get back to widget context from the action handler
|
||||||
|
this._actionManager.data = {widget: this};
|
||||||
|
}
|
||||||
|
|
||||||
/** Sets focus on the control. */
|
/** Sets focus on the control. */
|
||||||
focus(options? : FocusOptions)
|
focus(options? : FocusOptions)
|
||||||
{
|
{
|
||||||
@ -457,7 +388,7 @@ export class Et2Tree extends Et2WidgetWithSelectMixin(LitElement)
|
|||||||
{
|
{
|
||||||
if(_id == undefined){debugger;}
|
if(_id == undefined){debugger;}
|
||||||
// TODO: Look into this._search(), find out why it doesn't always succeed
|
// TODO: Look into this._search(), find out why it doesn't always succeed
|
||||||
return this._search(_id, this._selectOptions) ?? this.optionSearch(_id, this._selectOptions, 'id', 'item')
|
return this._search(_id, this._selectOptions) ?? this.optionSearch(_id, this._selectOptions, 'value', 'children')
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -772,6 +703,11 @@ export class Et2Tree extends Et2WidgetWithSelectMixin(LitElement)
|
|||||||
*/
|
*/
|
||||||
_link_actions(actions)
|
_link_actions(actions)
|
||||||
{
|
{
|
||||||
|
if(this.actions && !this._actionManager)
|
||||||
|
{
|
||||||
|
// ActionManager creation was missed
|
||||||
|
this.actions = this._actions;
|
||||||
|
}
|
||||||
// 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);
|
let widget_object = objectManager.getObjectById(this.id);
|
||||||
@ -804,16 +740,15 @@ 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);
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
let obj: EgwActionObject = treeObj.addObject((typeof option.id == 'number' ? String(option.id) : option.id), new EgwDragDropShoelaceTree(self, option.id));
|
let obj : EgwActionObject = treeObj.addObject(id, new EgwDragDropShoelaceTree(self, id));
|
||||||
obj.updateActionLinks(action_links);
|
obj.updateActionLinks(action_links);
|
||||||
|
|
||||||
if (option.item && option.item.length > 0)
|
const children = option.children ?? option.item ?? [];
|
||||||
|
for(let i = 0; i < children.length; i++)
|
||||||
{
|
{
|
||||||
for (let i = 0; i < option.item.length; i++)
|
apply_actions.call(this, treeObj, children[i]);
|
||||||
{
|
|
||||||
apply_actions.call(this, treeObj, option.item[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
for (const selectOption of this._selectOptions)
|
for (const selectOption of this._selectOptions)
|
||||||
|
@ -69,6 +69,12 @@ export class Et2TreeDropdown extends SearchMixin<Constructor<any> & Et2InputWidg
|
|||||||
*/
|
*/
|
||||||
@property({type: Boolean, reflect: true}) open = false;
|
@property({type: Boolean, reflect: true}) open = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Actions (passed to the tree)
|
||||||
|
* @type {{}}
|
||||||
|
*/
|
||||||
|
@property({type: Object}) actions = {};
|
||||||
|
|
||||||
@state() currentTag : Et2Tag;
|
@state() currentTag : Et2Tag;
|
||||||
|
|
||||||
// We show search results in the same dropdown
|
// We show search results in the same dropdown
|
||||||
@ -615,6 +621,8 @@ export class Et2TreeDropdown extends SearchMixin<Constructor<any> & Et2InputWidg
|
|||||||
</div>
|
</div>
|
||||||
${this.searchResultsTemplate()}
|
${this.searchResultsTemplate()}
|
||||||
<et2-tree
|
<et2-tree
|
||||||
|
.id=${this.id + "_tree"}
|
||||||
|
._parent=${this}
|
||||||
class="tree-dropdown__tree"
|
class="tree-dropdown__tree"
|
||||||
?readonly=${this.readonly}
|
?readonly=${this.readonly}
|
||||||
?disabled=${this.disabled}
|
?disabled=${this.disabled}
|
||||||
@ -627,6 +635,14 @@ export class Et2TreeDropdown extends SearchMixin<Constructor<any> & Et2InputWidg
|
|||||||
</et2-tree>
|
</et2-tree>
|
||||||
</sl-popup>
|
</sl-popup>
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
part="form-control-help-text"
|
||||||
|
id="help-text"
|
||||||
|
class="form-control__help-text"
|
||||||
|
aria-hidden=${hasHelpText ? 'false' : 'true'}
|
||||||
|
>
|
||||||
|
<slot name="help-text">${this.helpText}</slot>
|
||||||
|
</div>
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user