mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-22 16:03:47 +01:00
Implement actions on Et2Widget
This commit is contained in:
parent
eef04636db
commit
49a706ec50
81
api/js/egw_action/EgwEt2WidgetObject.ts
Normal file
81
api/js/egw_action/EgwEt2WidgetObject.ts
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
import {EgwActionObjectInterface} from "./EgwActionObjectInterface";
|
||||||
|
import {Element} from "parse5";
|
||||||
|
import {Function} from "estree";
|
||||||
|
import {EGW_AO_STATE_NORMAL, EGW_AO_STATE_VISIBLE} from "./egw_action_constants";
|
||||||
|
import {Et2Widget} from "../etemplate/Et2Widget/Et2Widget";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic interface object so any webComponent can participate in action system.
|
||||||
|
* This interface can be extended if special handling is needed, but it should work
|
||||||
|
* for any widget.
|
||||||
|
*/
|
||||||
|
export class EgwEt2WidgetObject implements EgwActionObjectInterface
|
||||||
|
{
|
||||||
|
node = null;
|
||||||
|
|
||||||
|
constructor(node)
|
||||||
|
{
|
||||||
|
this.node = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
_state : number = EGW_AO_STATE_NORMAL || EGW_AO_STATE_VISIBLE;
|
||||||
|
handlers : { [p : string] : any };
|
||||||
|
|
||||||
|
reconnectActionsCallback(p0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
reconnectActionsContext : any;
|
||||||
|
|
||||||
|
stateChangeCallback(p0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
stateChangeContext : any;
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
getDOMNode() : Element
|
||||||
|
{
|
||||||
|
return this.node;
|
||||||
|
}
|
||||||
|
|
||||||
|
getWidget() : typeof Et2Widget
|
||||||
|
{
|
||||||
|
return this.node
|
||||||
|
}
|
||||||
|
|
||||||
|
getState() : number
|
||||||
|
{
|
||||||
|
return this._state;
|
||||||
|
}
|
||||||
|
|
||||||
|
makeVisible() : void
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
reconnectActions() : void
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
setReconnectActionsCallback(_callback : Function, _context : any) : void
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
setState(_state : any) : void
|
||||||
|
{
|
||||||
|
this._state = _state
|
||||||
|
}
|
||||||
|
|
||||||
|
setStateChangeCallback(_callback : Function, _context : any) : void
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
triggerEvent(_event : any, _data : any) : boolean
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateState(_stateBit : number, _set : boolean, _shiftState : boolean) : void
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@ -13,6 +13,12 @@ import {dedupeMixin} from "@open-wc/dedupe-mixin";
|
|||||||
import type {et2_container} from "../et2_core_baseWidget";
|
import type {et2_container} from "../et2_core_baseWidget";
|
||||||
import type {et2_DOMWidget} from "../et2_core_DOMWidget";
|
import type {et2_DOMWidget} from "../et2_core_DOMWidget";
|
||||||
import bootstrapIcons from "../Styles/bootstrap-icons";
|
import bootstrapIcons from "../Styles/bootstrap-icons";
|
||||||
|
import {EgwAction} from "../../egw_action/EgwAction";
|
||||||
|
import {property} from "lit/decorators/property.js";
|
||||||
|
import {egw_getActionManager, egw_getAppObjectManager} from "../../egw_action/egw_action";
|
||||||
|
import {EgwEt2WidgetObject} from "../../egw_action/EgwEt2WidgetObject";
|
||||||
|
import {EgwActionObject} from "../../egw_action/EgwActionObject";
|
||||||
|
import {EgwActionObjectInterface} from "../../egw_action/EgwActionObjectInterface";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This mixin will allow any LitElement to become an Et2Widget
|
* This mixin will allow any LitElement to become an Et2Widget
|
||||||
@ -101,6 +107,8 @@ const Et2WidgetMixin = <T extends Constructor>(superClass : T) =>
|
|||||||
*/
|
*/
|
||||||
protected _deferred_properties : { [key : string] : string } = {};
|
protected _deferred_properties : { [key : string] : string } = {};
|
||||||
|
|
||||||
|
protected _actionManager : EgwAction = null;
|
||||||
|
|
||||||
|
|
||||||
/** WebComponent **/
|
/** WebComponent **/
|
||||||
static get styles()
|
static get styles()
|
||||||
@ -267,6 +275,10 @@ const Et2WidgetMixin = <T extends Constructor>(superClass : T) =>
|
|||||||
data: {
|
data: {
|
||||||
type: String,
|
type: String,
|
||||||
reflect: false
|
reflect: false
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
type: Object
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -498,6 +510,148 @@ const Et2WidgetMixin = <T extends Constructor>(superClass : T) =>
|
|||||||
return data.join(",");
|
return data.join(",");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Actions on the widget
|
||||||
|
*
|
||||||
|
* Each action is defined as an object:
|
||||||
|
*
|
||||||
|
* move: {
|
||||||
|
* type: "drop",
|
||||||
|
* acceptedTypes: "mail",
|
||||||
|
* icon: "move",
|
||||||
|
* caption: "Move to"
|
||||||
|
* onExecute: javascript:mail_move"
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* This will turn the widget into a drop target for "mail" drag types. When "mail" drag types are dropped,
|
||||||
|
* the global function mail_move(egwAction action, egwActionObject sender) will be called. The ID of the
|
||||||
|
* dragged "mail" will be in sender.id, some information about the sender will be in sender.context. The
|
||||||
|
* etemplate2 widget involved can typically be found in action.parent.data.widget, so your handler
|
||||||
|
* can operate in the widget context easily. The location varies depending on your action though. It
|
||||||
|
* might be action.parent.parent.data.widget
|
||||||
|
*
|
||||||
|
* To customise how the actions are handled for a particular widget, override _link_actions(). It handles
|
||||||
|
* the more widget-specific parts.
|
||||||
|
*
|
||||||
|
* @param {object} actions {ID: {attributes..}+} map of egw action information
|
||||||
|
* @see api/src/Etemplate/Widget/Nextmatch.php egw_actions() method
|
||||||
|
*/
|
||||||
|
@property({type: Object})
|
||||||
|
set actions(actions : EgwAction[] | { [id : string] : object })
|
||||||
|
{
|
||||||
|
if(this.id == "" || typeof this.id == "undefined")
|
||||||
|
{
|
||||||
|
this.egw().debug("warn", "Widget should have an ID if you want actions", this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the action manager and add some actions to it
|
||||||
|
if(this._actionManager == null)
|
||||||
|
{
|
||||||
|
// Find the apropriate parent action manager
|
||||||
|
let parent_am = null;
|
||||||
|
let widget = <Et2WidgetClass | et2_widget>this;
|
||||||
|
while(widget.getParent() && !parent_am)
|
||||||
|
{
|
||||||
|
// @ts-ignore
|
||||||
|
if(widget._actionManager)
|
||||||
|
{
|
||||||
|
// @ts-ignore
|
||||||
|
parent_am = widget._actionManager;
|
||||||
|
}
|
||||||
|
widget = widget.getParent();
|
||||||
|
}
|
||||||
|
if(!parent_am)
|
||||||
|
{
|
||||||
|
// Only look 1 level deep
|
||||||
|
parent_am = egw_getActionManager(this.egw().appName, true, 1);
|
||||||
|
}
|
||||||
|
if(parent_am.getActionById(this.getInstanceManager().uniqueId, 1) !== null)
|
||||||
|
{
|
||||||
|
parent_am = parent_am.getActionById(this.getInstanceManager().uniqueId, 1);
|
||||||
|
}
|
||||||
|
if(parent_am.getActionById(this.id, 1) != null)
|
||||||
|
{
|
||||||
|
this._actionManager = parent_am.getActionById(this.id, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this._actionManager = parent_am.addAction("actionManager", this.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this._actionManager.updateActions(actions, this.egw().appName);
|
||||||
|
|
||||||
|
// 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};
|
||||||
|
|
||||||
|
// Link the actions to the DOM
|
||||||
|
this._link_actions(actions);
|
||||||
|
}
|
||||||
|
|
||||||
|
get actions()
|
||||||
|
{
|
||||||
|
return this._actionManager?.children || {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all action-links / id's of 1.-level actions from a given action object
|
||||||
|
*
|
||||||
|
* This can be overwritten to not allow all actions, by not returning them here.
|
||||||
|
*
|
||||||
|
* @param actions
|
||||||
|
* @returns {Array}
|
||||||
|
*/
|
||||||
|
protected _get_action_links(actions)
|
||||||
|
{
|
||||||
|
const action_links = [];
|
||||||
|
for(let i in actions)
|
||||||
|
{
|
||||||
|
let action = actions[i];
|
||||||
|
action_links.push(typeof action.id != 'undefined' ? action.id : i);
|
||||||
|
}
|
||||||
|
return action_links;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Link the actions to the DOM nodes / widget bits.
|
||||||
|
*
|
||||||
|
* @param {object} actions {ID: {attributes..}+} map of egw action information
|
||||||
|
*/
|
||||||
|
protected _link_actions(actions)
|
||||||
|
{
|
||||||
|
// Get the top level element for the tree
|
||||||
|
let objectManager = egw_getAppObjectManager(true);
|
||||||
|
let widget_object = objectManager.getObjectById(this.id);
|
||||||
|
|
||||||
|
if(widget_object == null)
|
||||||
|
{
|
||||||
|
// Add a new container to the object manager which will hold the widget
|
||||||
|
// objects
|
||||||
|
widget_object = objectManager.insertObject(false, new EgwActionObject(
|
||||||
|
this.id, objectManager, this.createWidgetObjectInterface(),
|
||||||
|
this._actionManager || objectManager.manager.getActionById(this.id) || objectManager.manager
|
||||||
|
));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
widget_object.setAOI(this.createWidgetObjectInterface());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete all old objects
|
||||||
|
widget_object.clear();
|
||||||
|
widget_object.unregisterActions();
|
||||||
|
|
||||||
|
// Go over the widget & add links - this is where we decide which actions are
|
||||||
|
// 'allowed' for this widget at this time
|
||||||
|
widget_object.updateActionLinks(this._get_action_links(actions));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected createWidgetObjectInterface() : EgwActionObjectInterface
|
||||||
|
{
|
||||||
|
return <EgwActionObjectInterface><unknown>(new EgwEt2WidgetObject(this));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A property has changed, and we want to make adjustments to other things
|
* A property has changed, and we want to make adjustments to other things
|
||||||
* based on that
|
* based on that
|
||||||
|
Loading…
Reference in New Issue
Block a user