IDEMPIERE-3528 Add to Favorite for Menu Search Panel
This commit is contained in:
parent
ffdc57cbe8
commit
c036ed2e57
|
@ -0,0 +1,23 @@
|
||||||
|
SET SQLBLANKLINES ON
|
||||||
|
SET DEFINE OFF
|
||||||
|
|
||||||
|
-- IDEMPIERE-3528 Add to Favorite for Menu Search Panel
|
||||||
|
-- Oct 23, 2017 11:59:39 PM GMT+08:00
|
||||||
|
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Add To Favourite',0,0,'Y',TO_DATE('2017-10-23 23:59:38','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2017-10-23 23:59:38','YYYY-MM-DD HH24:MI:SS'),100,200435,'AddToFavourite','D','ddbf357f-3f1c-49dd-9ce7-3d8f0cc3b30a')
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Oct 24, 2017 12:00:05 AM GMT+08:00
|
||||||
|
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Remove From Favourite',0,0,'Y',TO_DATE('2017-10-24 00:00:05','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2017-10-24 00:00:05','YYYY-MM-DD HH24:MI:SS'),100,200436,'RemoveFromFavourite','D','36985206-17fb-4bf2-a339-3aac5e2601f3')
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Oct 24, 2017 12:00:51 AM GMT+08:00
|
||||||
|
UPDATE AD_Message SET MsgText='Add To Favourites', Value='AddToFavourites',Updated=TO_DATE('2017-10-24 00:00:51','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Message_ID=200435
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Oct 24, 2017 12:00:58 AM GMT+08:00
|
||||||
|
UPDATE AD_Message SET MsgText='Remove From Favourites', Value='RemoveFromFavourites',Updated=TO_DATE('2017-10-24 00:00:58','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Message_ID=200436
|
||||||
|
;
|
||||||
|
|
||||||
|
SELECT register_migration_script('201710232100_IDEMPIERE-3528.sql') FROM dual
|
||||||
|
;
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
-- IDEMPIERE-3528 Add to Favorite for Menu Search Panel
|
||||||
|
-- Oct 23, 2017 11:59:39 PM GMT+08:00
|
||||||
|
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Add To Favourite',0,0,'Y',TO_TIMESTAMP('2017-10-23 23:59:38','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2017-10-23 23:59:38','YYYY-MM-DD HH24:MI:SS'),100,200435,'AddToFavourite','D','ddbf357f-3f1c-49dd-9ce7-3d8f0cc3b30a')
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Oct 24, 2017 12:00:05 AM GMT+08:00
|
||||||
|
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Remove From Favourite',0,0,'Y',TO_TIMESTAMP('2017-10-24 00:00:05','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2017-10-24 00:00:05','YYYY-MM-DD HH24:MI:SS'),100,200436,'RemoveFromFavourite','D','36985206-17fb-4bf2-a339-3aac5e2601f3')
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Oct 24, 2017 12:00:51 AM GMT+08:00
|
||||||
|
UPDATE AD_Message SET MsgText='Add To Favourites', Value='AddToFavourites',Updated=TO_TIMESTAMP('2017-10-24 00:00:51','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Message_ID=200435
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Oct 24, 2017 12:00:58 AM GMT+08:00
|
||||||
|
UPDATE AD_Message SET MsgText='Remove From Favourites', Value='RemoveFromFavourites',Updated=TO_TIMESTAMP('2017-10-24 00:00:58','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Message_ID=200436
|
||||||
|
;
|
||||||
|
|
||||||
|
SELECT register_migration_script('201710232100_IDEMPIERE-3528.sql') FROM dual
|
||||||
|
;
|
||||||
|
|
|
@ -35,6 +35,7 @@ import org.adempiere.webui.component.DrillCommand;
|
||||||
import org.adempiere.webui.component.TokenCommand;
|
import org.adempiere.webui.component.TokenCommand;
|
||||||
import org.adempiere.webui.component.ZoomCommand;
|
import org.adempiere.webui.component.ZoomCommand;
|
||||||
import org.adempiere.webui.desktop.DefaultDesktop;
|
import org.adempiere.webui.desktop.DefaultDesktop;
|
||||||
|
import org.adempiere.webui.desktop.FavouriteController;
|
||||||
import org.adempiere.webui.desktop.IDesktop;
|
import org.adempiere.webui.desktop.IDesktop;
|
||||||
import org.adempiere.webui.session.SessionContextListener;
|
import org.adempiere.webui.session.SessionContextListener;
|
||||||
import org.adempiere.webui.session.SessionManager;
|
import org.adempiere.webui.session.SessionManager;
|
||||||
|
@ -281,6 +282,9 @@ public class AdempiereWebUI extends Window implements EventListener<Event>, IWeb
|
||||||
Env.setContext(ctx, "#LocalHttpAddr", localHttpAddr.toString());
|
Env.setContext(ctx, "#LocalHttpAddr", localHttpAddr.toString());
|
||||||
Clients.response(new AuScript("zAu.cmd0.clearBusy()"));
|
Clients.response(new AuScript("zAu.cmd0.clearBusy()"));
|
||||||
|
|
||||||
|
//init favorite
|
||||||
|
FavouriteController.getInstance(currSess);
|
||||||
|
|
||||||
processParameters();
|
processParameters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,8 @@ import java.util.List;
|
||||||
import org.adempiere.webui.component.ListHead;
|
import org.adempiere.webui.component.ListHead;
|
||||||
import org.adempiere.webui.component.ListItem;
|
import org.adempiere.webui.component.ListItem;
|
||||||
import org.adempiere.webui.component.Listbox;
|
import org.adempiere.webui.component.Listbox;
|
||||||
|
import org.adempiere.webui.component.ToolBarButton;
|
||||||
|
import org.adempiere.webui.desktop.FavouriteController;
|
||||||
import org.adempiere.webui.theme.ThemeManager;
|
import org.adempiere.webui.theme.ThemeManager;
|
||||||
import org.adempiere.webui.util.TreeItemAction;
|
import org.adempiere.webui.util.TreeItemAction;
|
||||||
import org.adempiere.webui.util.TreeNodeAction;
|
import org.adempiere.webui.util.TreeNodeAction;
|
||||||
|
@ -47,7 +49,6 @@ import org.zkoss.zul.Listitem;
|
||||||
import org.zkoss.zul.ListitemRenderer;
|
import org.zkoss.zul.ListitemRenderer;
|
||||||
import org.zkoss.zul.ListitemRendererExt;
|
import org.zkoss.zul.ListitemRendererExt;
|
||||||
import org.zkoss.zul.Textbox;
|
import org.zkoss.zul.Textbox;
|
||||||
import org.zkoss.zul.Toolbarbutton;
|
|
||||||
import org.zkoss.zul.Tree;
|
import org.zkoss.zul.Tree;
|
||||||
import org.zkoss.zul.Treechildren;
|
import org.zkoss.zul.Treechildren;
|
||||||
import org.zkoss.zul.Treeitem;
|
import org.zkoss.zul.Treeitem;
|
||||||
|
@ -61,14 +62,21 @@ import org.zkoss.zul.impl.LabelImageElement;
|
||||||
*/
|
*/
|
||||||
public class MenuSearchController implements EventListener<Event>{
|
public class MenuSearchController implements EventListener<Event>{
|
||||||
|
|
||||||
|
public static final String M_TREE_NODE_ATTR = "MTreeNode";
|
||||||
|
|
||||||
|
private static final String Z_ICON_STAR_O = "z-icon-star-o";
|
||||||
|
private static final String Z_ICON_STAR = "z-icon-star";
|
||||||
private static final String ON_SEARCH_ECHO = "onSearchEcho";
|
private static final String ON_SEARCH_ECHO = "onSearchEcho";
|
||||||
private static final String ON_LOAD_MORE = "onLoadMore";
|
private static final String ON_LOAD_MORE = "onLoadMore";
|
||||||
private static final String ONSELECT_TIMESTAMP = "onselect.timestamp";
|
private static final String ONSELECT_TIMESTAMP = "onselect.timestamp";
|
||||||
|
private static final String STAR_BUTTON_NAME = "Star";
|
||||||
|
private static final String NEW_BUTTON_NAME = "New";
|
||||||
private Tree tree;
|
private Tree tree;
|
||||||
private Listbox listbox;
|
private Listbox listbox;
|
||||||
private ListModelList<MenuItem> model;
|
private ListModelList<MenuItem> model;
|
||||||
private Vlayout layout;
|
private Vlayout layout;
|
||||||
private ListModelList<MenuItem> fullModel;
|
private ListModelList<MenuItem> fullModel;
|
||||||
|
private boolean inStarEvent;
|
||||||
|
|
||||||
private static final String ON_POST_SELECT_TREEITEM_EVENT = "onPostSelectTreeitem";
|
private static final String ON_POST_SELECT_TREEITEM_EVENT = "onPostSelectTreeitem";
|
||||||
|
|
||||||
|
@ -196,12 +204,21 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
Listheader listheader = new Listheader();
|
Listheader listheader = new Listheader();
|
||||||
listhead.appendChild(listheader);
|
listhead.appendChild(listheader);
|
||||||
listheader = new Listheader();
|
listheader = new Listheader();
|
||||||
ZKUpdateUtil.setWidth(listheader, "32px");
|
listheader.setAlign("center");
|
||||||
|
ZKUpdateUtil.setWidth(listheader, "28px");
|
||||||
|
listhead.appendChild(listheader);
|
||||||
|
listheader = new Listheader();
|
||||||
|
listheader.setAlign("center");
|
||||||
|
ZKUpdateUtil.setWidth(listheader, "28px");
|
||||||
listhead.appendChild(listheader);
|
listhead.appendChild(listheader);
|
||||||
|
|
||||||
layout.addEventListener(ON_SEARCH_ECHO, this);
|
layout.addEventListener(ON_SEARCH_ECHO, this);
|
||||||
layout.addEventListener(ON_LOAD_MORE, this);
|
layout.addEventListener(ON_LOAD_MORE, this);
|
||||||
updateListboxModel(model);
|
updateListboxModel(model);
|
||||||
|
|
||||||
|
FavouriteController controller = FavouriteController.getInstance(Executions.getCurrent().getSession());
|
||||||
|
controller.addDeletedCallback(t -> onDeletedCallback(t));
|
||||||
|
controller.addInsertedCallback(t -> onInsertedCallback(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -221,7 +238,9 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
} else if (System.currentTimeMillis() - onSelect.longValue() > 1000) {
|
} else if (System.currentTimeMillis() - onSelect.longValue() > 1000) {
|
||||||
onSelect(item, Boolean.FALSE);
|
onSelect(item, Boolean.FALSE);
|
||||||
}
|
}
|
||||||
} else if (event.getTarget() instanceof Toolbarbutton) {
|
} else if (event.getTarget() instanceof ToolBarButton) {
|
||||||
|
ToolBarButton btn = (ToolBarButton) event.getTarget();
|
||||||
|
if (NEW_BUTTON_NAME.equals(btn.getName())) {
|
||||||
ListItem item = null;
|
ListItem item = null;
|
||||||
Component parent = event.getTarget();
|
Component parent = event.getTarget();
|
||||||
while (parent != null) {
|
while (parent != null) {
|
||||||
|
@ -234,6 +253,20 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
if (item != null) {
|
if (item != null) {
|
||||||
onSelect(item, Boolean.TRUE);
|
onSelect(item, Boolean.TRUE);
|
||||||
}
|
}
|
||||||
|
} else if (STAR_BUTTON_NAME.equals(btn.getName())) {
|
||||||
|
inStarEvent = true;
|
||||||
|
FavouriteController controller = FavouriteController.getInstance(Executions.getCurrent().getSession());
|
||||||
|
if (Z_ICON_STAR_O.equals(btn.getIconSclass())) {
|
||||||
|
btn.setIconSclass(Z_ICON_STAR);
|
||||||
|
btn.setTooltiptext(Msg.getMsg(Env.getCtx(), "RemoveFromFavourites"));
|
||||||
|
controller.addNode((MTreeNode) btn.getAttribute(M_TREE_NODE_ATTR));
|
||||||
|
} else if (Z_ICON_STAR.equals(btn.getIconSclass())) {
|
||||||
|
btn.setIconSclass(Z_ICON_STAR_O);
|
||||||
|
btn.setTooltiptext(Msg.getMsg(Env.getCtx(), "AddToFavourites"));
|
||||||
|
controller.removeNode(((MTreeNode) btn.getAttribute(M_TREE_NODE_ATTR)).getNode_ID());
|
||||||
|
}
|
||||||
|
inStarEvent = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (event.getName().equals(ON_SEARCH_ECHO)) {
|
} else if (event.getName().equals(ON_SEARCH_ECHO)) {
|
||||||
onSearchEcho((String) event.getData());
|
onSearchEcho((String) event.getData());
|
||||||
|
@ -242,6 +275,20 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onInsertedCallback(MTreeNode node) {
|
||||||
|
if (inStarEvent) return;
|
||||||
|
ListModel<?> t = listbox.getModel();
|
||||||
|
listbox.setModel((ListModel<?>)null);
|
||||||
|
listbox.setModel(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onDeletedCallback(Integer nodeId) {
|
||||||
|
if (inStarEvent) return;
|
||||||
|
ListModel<?> t = listbox.getModel();
|
||||||
|
listbox.setModel((ListModel<?>)null);
|
||||||
|
listbox.setModel(t);
|
||||||
|
}
|
||||||
|
|
||||||
private void onSelect(ListItem selected, Boolean newRecord) {
|
private void onSelect(ListItem selected, Boolean newRecord) {
|
||||||
MenuItem item = selected.getValue();
|
MenuItem item = selected.getValue();
|
||||||
if (item == null) return;
|
if (item == null) return;
|
||||||
|
@ -438,6 +485,9 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
}
|
}
|
||||||
|
|
||||||
private class MenuItemRenderer implements ListitemRenderer<MenuItem>, ListitemRendererExt {
|
private class MenuItemRenderer implements ListitemRenderer<MenuItem>, ListitemRendererExt {
|
||||||
|
private static final String REMOVE_FROM_FAVOURITES_MSG = "RemoveFromFavourites";
|
||||||
|
private static final String ADD_TO_FAVOURITES_MSG = "AddToFavourites";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Listitem newListitem(org.zkoss.zul.Listbox listbox) {
|
public Listitem newListitem(org.zkoss.zul.Listbox listbox) {
|
||||||
return new ListItem();
|
return new ListItem();
|
||||||
|
@ -466,13 +516,41 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
item.appendChild(cell);
|
item.appendChild(cell);
|
||||||
boolean isWindow = data.getType() != null && data.getType().equals("window");
|
boolean isWindow = data.getType() != null && data.getType().equals("window");
|
||||||
if (isWindow) {
|
if (isWindow) {
|
||||||
Toolbarbutton newBtn = new Toolbarbutton(null, ThemeManager.getThemeResource("images/New16.png"));
|
ToolBarButton newBtn = new ToolBarButton();
|
||||||
|
newBtn.setImage(ThemeManager.getThemeResource("images/New16.png"));
|
||||||
newBtn.addEventListener(Events.ON_CLICK, MenuSearchController.this);
|
newBtn.addEventListener(Events.ON_CLICK, MenuSearchController.this);
|
||||||
newBtn.setSclass("fav-new-btn");
|
newBtn.setSclass("fav-new-btn");
|
||||||
newBtn.setTooltiptext(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "New")));
|
newBtn.setTooltiptext(Util.cleanAmp(Msg.getMsg(Env.getCtx(), NEW_BUTTON_NAME)));
|
||||||
|
newBtn.setName(NEW_BUTTON_NAME);
|
||||||
cell.appendChild(newBtn);
|
cell.appendChild(newBtn);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
cell = new Listcell();
|
||||||
|
item.appendChild(cell);
|
||||||
|
MTreeNode node = null;
|
||||||
|
if (data.getData() instanceof MTreeNode) {
|
||||||
|
node = (MTreeNode) data.getData();
|
||||||
|
} else if (data.getData() instanceof Treeitem) {
|
||||||
|
Treeitem value = (Treeitem) data.getData();
|
||||||
|
if (value != null) {
|
||||||
|
node = (MTreeNode) value.getAttribute(M_TREE_NODE_ATTR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (node != null) {
|
||||||
|
FavouriteController controller = FavouriteController.getInstance(Executions.getCurrent().getSession());
|
||||||
|
ToolBarButton starBtn = new ToolBarButton();
|
||||||
|
starBtn.setAttribute(M_TREE_NODE_ATTR, node);
|
||||||
|
starBtn.setName(STAR_BUTTON_NAME);
|
||||||
|
if (controller.hasNode(node.getNode_ID())) {
|
||||||
|
starBtn.setIconSclass(Z_ICON_STAR);
|
||||||
|
starBtn.setTooltiptext(Msg.getMsg(Env.getCtx(), REMOVE_FROM_FAVOURITES_MSG));
|
||||||
|
} else {
|
||||||
|
starBtn.setIconSclass(Z_ICON_STAR_O);
|
||||||
|
starBtn.setTooltiptext(Msg.getMsg(Env.getCtx(), ADD_TO_FAVOURITES_MSG));
|
||||||
|
}
|
||||||
|
cell.appendChild(starBtn);
|
||||||
|
starBtn.addEventListener(Events.ON_CLICK, MenuSearchController.this);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,13 +13,13 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
package org.adempiere.webui.dashboard;
|
package org.adempiere.webui.dashboard;
|
||||||
|
|
||||||
import static org.compiere.model.SystemIDs.TREE_MENUPRIMARY;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Enumeration;
|
|
||||||
|
|
||||||
import org.adempiere.util.Callback;
|
import org.adempiere.util.Callback;
|
||||||
import org.adempiere.webui.adwindow.ADTabpanel;
|
import org.adempiere.webui.adwindow.ADTabpanel;
|
||||||
import org.adempiere.webui.adwindow.ADWindow;
|
import org.adempiere.webui.adwindow.ADWindow;
|
||||||
|
import org.adempiere.webui.desktop.FavouriteController;
|
||||||
import org.adempiere.webui.exception.ApplicationException;
|
import org.adempiere.webui.exception.ApplicationException;
|
||||||
import org.adempiere.webui.session.SessionManager;
|
import org.adempiere.webui.session.SessionManager;
|
||||||
import org.adempiere.webui.theme.ITheme;
|
import org.adempiere.webui.theme.ITheme;
|
||||||
|
@ -27,13 +27,12 @@ import org.adempiere.webui.theme.ThemeManager;
|
||||||
import org.adempiere.webui.window.FDialog;
|
import org.adempiere.webui.window.FDialog;
|
||||||
import org.compiere.model.MMenu;
|
import org.compiere.model.MMenu;
|
||||||
import org.compiere.model.MQuery;
|
import org.compiere.model.MQuery;
|
||||||
import org.compiere.model.MTree;
|
|
||||||
import org.compiere.model.MTreeNode;
|
import org.compiere.model.MTreeNode;
|
||||||
import org.compiere.util.DB;
|
|
||||||
import org.compiere.util.Env;
|
import org.compiere.util.Env;
|
||||||
import org.compiere.util.Msg;
|
import org.compiere.util.Msg;
|
||||||
import org.compiere.util.Util;
|
import org.compiere.util.Util;
|
||||||
import org.zkoss.zk.ui.Component;
|
import org.zkoss.zk.ui.Component;
|
||||||
|
import org.zkoss.zk.ui.Executions;
|
||||||
import org.zkoss.zk.ui.event.DropEvent;
|
import org.zkoss.zk.ui.event.DropEvent;
|
||||||
import org.zkoss.zk.ui.event.Event;
|
import org.zkoss.zk.ui.event.Event;
|
||||||
import org.zkoss.zk.ui.event.EventListener;
|
import org.zkoss.zk.ui.event.EventListener;
|
||||||
|
@ -74,7 +73,9 @@ public class DPFavourites extends DashboardPanel implements EventListener<Event>
|
||||||
|
|
||||||
private Label lblMsg;
|
private Label lblMsg;
|
||||||
|
|
||||||
private int m_AD_Tree_ID;
|
private List<A> links = new ArrayList<>();
|
||||||
|
|
||||||
|
private boolean inCallingController;
|
||||||
|
|
||||||
public DPFavourites()
|
public DPFavourites()
|
||||||
{
|
{
|
||||||
|
@ -108,35 +109,44 @@ public class DPFavourites extends DashboardPanel implements EventListener<Event>
|
||||||
|
|
||||||
private void createFavouritesPanel()
|
private void createFavouritesPanel()
|
||||||
{
|
{
|
||||||
int AD_Role_ID = Env.getAD_Role_ID(Env.getCtx());
|
FavouriteController controller = FavouriteController.getInstance(Executions.getCurrent().getSession());
|
||||||
int AD_Tree_ID = DB.getSQLValue(null,
|
List<MTreeNode> favorites = controller.getFavourites();
|
||||||
"SELECT COALESCE(r.AD_Tree_Menu_ID, ci.AD_Tree_Menu_ID)"
|
for (MTreeNode nd : favorites)
|
||||||
+ "FROM AD_ClientInfo ci"
|
|
||||||
+ " INNER JOIN AD_Role r ON (ci.AD_Client_ID=r.AD_Client_ID) "
|
|
||||||
+ "WHERE AD_Role_ID=?", AD_Role_ID);
|
|
||||||
if (AD_Tree_ID <= 0)
|
|
||||||
AD_Tree_ID = TREE_MENUPRIMARY; // Menu
|
|
||||||
|
|
||||||
m_AD_Tree_ID = AD_Tree_ID;
|
|
||||||
|
|
||||||
MTree vTree = new MTree(Env.getCtx(), AD_Tree_ID, false, true, null);
|
|
||||||
MTreeNode m_root = vTree.getRoot();
|
|
||||||
Enumeration<?> enTop = m_root.children();
|
|
||||||
while(enTop.hasMoreElements())
|
|
||||||
{
|
{
|
||||||
MTreeNode ndTop = (MTreeNode)enTop.nextElement();
|
addNode(nd);
|
||||||
Enumeration<?> en = ndTop.preorderEnumeration();
|
|
||||||
while (en.hasMoreElements())
|
|
||||||
{
|
|
||||||
MTreeNode nd = (MTreeNode)en.nextElement();
|
|
||||||
if (nd.isOnBar()) {
|
|
||||||
addNode(nd.getNode_ID(), nd.toString().trim(), nd.getDescription(), getIconFile(nd), (nd.isWindow() && !nd.isForm()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lblMsg = new Label(Msg.getMsg(Env.getCtx(), "DropMenuItemHere"));
|
lblMsg = new Label(Msg.getMsg(Env.getCtx(), "DropMenuItemHere"));
|
||||||
if(bxFav.getChildren().isEmpty()) bxFav.appendChild(lblMsg);
|
if(bxFav.getChildren().isEmpty()) bxFav.appendChild(lblMsg);
|
||||||
|
|
||||||
|
controller.addInsertedCallback(t -> onInsertedCallback(t));
|
||||||
|
controller.addDeletedCallback(t -> onDeletedCallback(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addNode(MTreeNode nd) {
|
||||||
|
addNode(nd.getNode_ID(), nd.toString().trim(), nd.getDescription(), getIconFile(nd), (nd.isWindow() && !nd.isForm()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onDeletedCallback(Integer nodeId) {
|
||||||
|
if (inCallingController) return;
|
||||||
|
for (A link : links) {
|
||||||
|
String id = (String) link.getAttribute(NODE_ID_ATTR);
|
||||||
|
if (id.equals(nodeId.toString())) {
|
||||||
|
removeLinkFromUI(link);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onInsertedCallback(MTreeNode node) {
|
||||||
|
if (inCallingController) return;
|
||||||
|
for (A link : links) {
|
||||||
|
String id = (String) link.getAttribute(NODE_ID_ATTR);
|
||||||
|
if (id.equals(String.valueOf(node.getNode_ID()))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addNode(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void addNode(int nodeId, String label, String description, String imageSrc, boolean addNewBtn) {
|
protected void addNode(int nodeId, String label, String description, String imageSrc, boolean addNewBtn) {
|
||||||
|
@ -168,52 +178,7 @@ public class DPFavourites extends DashboardPanel implements EventListener<Event>
|
||||||
newBtn.setSclass("fav-new-btn");
|
newBtn.setSclass("fav-new-btn");
|
||||||
newBtn.setTooltiptext(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "New")));
|
newBtn.setTooltiptext(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "New")));
|
||||||
}
|
}
|
||||||
}
|
links.add(btnFavItem);
|
||||||
|
|
||||||
/**
|
|
||||||
* Make Bar add/remove persistent
|
|
||||||
* @param add true if add - otherwise remove
|
|
||||||
* @param Node_ID Node ID
|
|
||||||
* @return true if updated
|
|
||||||
*/
|
|
||||||
private boolean barDBupdate(boolean add, int Node_ID)
|
|
||||||
{
|
|
||||||
int AD_Client_ID = Env.getAD_Client_ID(Env.getCtx());
|
|
||||||
int AD_Org_ID = Env.getContextAsInt(Env.getCtx(), "#AD_Org_ID");
|
|
||||||
int AD_User_ID = Env.getContextAsInt(Env.getCtx(), "#AD_User_ID");
|
|
||||||
StringBuilder sql = new StringBuilder();
|
|
||||||
if (add) {
|
|
||||||
// If record already exist, we will only make an update
|
|
||||||
if (DB.getSQLValueEx(null, "SELECT 1 FROM AD_TreeBar WHERE AD_Tree_ID = ? AND AD_User_ID = ? AND Node_ID = ?", m_AD_Tree_ID, AD_User_ID, Node_ID) == 1) {
|
|
||||||
sql.append("UPDATE AD_TreeBar SET IsFavourite = 'Y', Updated = Sysdate, UpdatedBy = ").append(AD_User_ID).append(" WHERE AD_Tree_ID = ").append(m_AD_Tree_ID)
|
|
||||||
.append(" AND AD_User_ID=").append(AD_User_ID)
|
|
||||||
.append(" AND Node_ID=").append(Node_ID);
|
|
||||||
}
|
|
||||||
else // we will create the record
|
|
||||||
sql.append("INSERT INTO AD_TreeBar "
|
|
||||||
+ "(AD_Tree_ID,AD_User_ID,Node_ID, "
|
|
||||||
+ "AD_Client_ID,AD_Org_ID, "
|
|
||||||
+ "IsActive,Created,CreatedBy,Updated,UpdatedBy)VALUES (")
|
|
||||||
.append(m_AD_Tree_ID).append(",").append(AD_User_ID).append(",").append(Node_ID).append(",")
|
|
||||||
.append(AD_Client_ID).append(",").append(AD_Org_ID).append(",")
|
|
||||||
.append("'Y',SysDate,").append(AD_User_ID).append(",SysDate,").append(AD_User_ID).append(")");
|
|
||||||
// if already exist, will result in ORA-00001: unique constraint (ADEMPIERE.AD_TREEBAR_KEY)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// if the menu entry is opened at login, we will only remove it from favourites
|
|
||||||
if (DB.getSQLValueEx(null, "SELECT LoginOpenSeqNo FROM AD_TreeBar WHERE AD_Tree_ID = ? AND AD_User_ID = ? AND Node_ID = ?", m_AD_Tree_ID, AD_User_ID, Node_ID) > 0) {
|
|
||||||
|
|
||||||
sql.append("UPDATE AD_TreeBar SET IsFavourite = 'N', Updated = Sysdate, UpdatedBy = ").append(AD_User_ID).append(" WHERE AD_Tree_ID = ").append(m_AD_Tree_ID)
|
|
||||||
.append(" AND AD_User_ID=").append(AD_User_ID)
|
|
||||||
.append(" AND Node_ID=").append(Node_ID);
|
|
||||||
}
|
|
||||||
else // otherwise, we remove the record
|
|
||||||
sql.append("DELETE AD_TreeBar WHERE AD_Tree_ID=").append(m_AD_Tree_ID)
|
|
||||||
.append(" AND AD_User_ID=").append(AD_User_ID)
|
|
||||||
.append(" AND Node_ID=").append(Node_ID);
|
|
||||||
}
|
|
||||||
int no = DB.executeUpdate(sql.toString(), false, null);
|
|
||||||
return no == 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onEvent(Event event)
|
public void onEvent(Event event)
|
||||||
|
@ -318,18 +283,25 @@ public class DPFavourites extends DashboardPanel implements EventListener<Event>
|
||||||
if(value != null)
|
if(value != null)
|
||||||
{
|
{
|
||||||
int Node_ID = Integer.valueOf(value.toString());
|
int Node_ID = Integer.valueOf(value.toString());
|
||||||
if(barDBupdate(false, Node_ID))
|
FavouriteController controller = FavouriteController.getInstance(Executions.getCurrent().getSession());
|
||||||
|
inCallingController = true;
|
||||||
|
if(controller.removeNode(Node_ID))
|
||||||
{
|
{
|
||||||
|
removeLinkFromUI(btn);
|
||||||
|
}
|
||||||
|
inCallingController = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeLinkFromUI(A btn) {
|
||||||
if (btn.getParent() instanceof Hlayout)
|
if (btn.getParent() instanceof Hlayout)
|
||||||
bxFav.removeChild(btn.getParent());
|
bxFav.removeChild(btn.getParent());
|
||||||
// bxFav.removeChild(btn);
|
|
||||||
|
|
||||||
if(bxFav.getChildren().isEmpty())
|
if(bxFav.getChildren().isEmpty())
|
||||||
bxFav.appendChild(lblMsg);
|
bxFav.appendChild(lblMsg);
|
||||||
|
|
||||||
bxFav.invalidate();
|
bxFav.invalidate();
|
||||||
}
|
links.remove(btn);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -341,7 +313,9 @@ public class DPFavourites extends DashboardPanel implements EventListener<Event>
|
||||||
if(value != null)
|
if(value != null)
|
||||||
{
|
{
|
||||||
int Node_ID = Integer.valueOf(value.toString());
|
int Node_ID = Integer.valueOf(value.toString());
|
||||||
if(barDBupdate(true, Node_ID))
|
FavouriteController controller = FavouriteController.getInstance(Executions.getCurrent().getSession());
|
||||||
|
inCallingController = true;
|
||||||
|
if(controller.addNode(Node_ID))
|
||||||
{
|
{
|
||||||
String menuType = (String) treeitem.getAttribute("menu.type");
|
String menuType = (String) treeitem.getAttribute("menu.type");
|
||||||
boolean isWindow = menuType != null && menuType.equals("window");
|
boolean isWindow = menuType != null && menuType.equals("window");
|
||||||
|
@ -364,6 +338,7 @@ public class DPFavourites extends DashboardPanel implements EventListener<Event>
|
||||||
} else {
|
} else {
|
||||||
FDialog.error(0, this, "BookmarkExist", null);
|
FDialog.error(0, this, "BookmarkExist", null);
|
||||||
}
|
}
|
||||||
|
inCallingController = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,187 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.adempiere.webui.desktop;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.adempiere.util.Callback;
|
||||||
|
import org.compiere.model.MTree;
|
||||||
|
import org.compiere.model.MTreeNode;
|
||||||
|
import org.compiere.util.DB;
|
||||||
|
import org.compiere.util.Env;
|
||||||
|
import org.zkoss.zk.ui.Session;
|
||||||
|
|
||||||
|
import static org.compiere.model.SystemIDs.TREE_MENUPRIMARY;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hengsin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class FavouriteController {
|
||||||
|
|
||||||
|
private static final String DESKTOP_FAVOURITE_CONTROLLER = "desktop.FavouriteController";
|
||||||
|
private Map<Integer, MTreeNode> nodeMap;
|
||||||
|
private int m_AD_Tree_ID;
|
||||||
|
private MTreeNode rootNode;
|
||||||
|
private List<Callback<Integer>> deletedCallbacks;
|
||||||
|
private List<Callback<MTreeNode>> insertedCallbacks;
|
||||||
|
|
||||||
|
private FavouriteController() {
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
nodeMap = new LinkedHashMap<>();
|
||||||
|
deletedCallbacks = new ArrayList<>();
|
||||||
|
insertedCallbacks = new ArrayList<>();
|
||||||
|
int AD_Role_ID = Env.getAD_Role_ID(Env.getCtx());
|
||||||
|
int AD_Tree_ID = DB.getSQLValue(null,
|
||||||
|
"SELECT COALESCE(r.AD_Tree_Menu_ID, ci.AD_Tree_Menu_ID)"
|
||||||
|
+ "FROM AD_ClientInfo ci"
|
||||||
|
+ " INNER JOIN AD_Role r ON (ci.AD_Client_ID=r.AD_Client_ID) "
|
||||||
|
+ "WHERE AD_Role_ID=?", AD_Role_ID);
|
||||||
|
if (AD_Tree_ID <= 0)
|
||||||
|
AD_Tree_ID = TREE_MENUPRIMARY; // Menu
|
||||||
|
|
||||||
|
m_AD_Tree_ID = AD_Tree_ID;
|
||||||
|
|
||||||
|
MTree vTree = new MTree(Env.getCtx(), AD_Tree_ID, false, true, false, null);
|
||||||
|
rootNode = vTree.getRoot();
|
||||||
|
Enumeration<?> enTop = rootNode.children();
|
||||||
|
while(enTop.hasMoreElements())
|
||||||
|
{
|
||||||
|
MTreeNode ndTop = (MTreeNode)enTop.nextElement();
|
||||||
|
Enumeration<?> en = ndTop.preorderEnumeration();
|
||||||
|
while (en.hasMoreElements())
|
||||||
|
{
|
||||||
|
MTreeNode nd = (MTreeNode)en.nextElement();
|
||||||
|
if (nd.isOnBar()) {
|
||||||
|
nodeMap.put(nd.getNode_ID(), nd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get favourites controller instance for current session
|
||||||
|
* @param currSess
|
||||||
|
* @return FavouriteController session instance
|
||||||
|
*/
|
||||||
|
public static synchronized FavouriteController getInstance(Session currSess) {
|
||||||
|
FavouriteController controller = (FavouriteController) currSess.getAttribute(DESKTOP_FAVOURITE_CONTROLLER);
|
||||||
|
if (controller == null) {
|
||||||
|
controller = new FavouriteController();
|
||||||
|
currSess.setAttribute(DESKTOP_FAVOURITE_CONTROLLER, controller);
|
||||||
|
}
|
||||||
|
return controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean barDBupdate(boolean add, int Node_ID)
|
||||||
|
{
|
||||||
|
int AD_Client_ID = Env.getAD_Client_ID(Env.getCtx());
|
||||||
|
int AD_Org_ID = Env.getContextAsInt(Env.getCtx(), "#AD_Org_ID");
|
||||||
|
int AD_User_ID = Env.getContextAsInt(Env.getCtx(), "#AD_User_ID");
|
||||||
|
StringBuilder sql = new StringBuilder();
|
||||||
|
if (add)
|
||||||
|
sql.append("INSERT INTO AD_TreeBar "
|
||||||
|
+ "(AD_Tree_ID,AD_User_ID,Node_ID, "
|
||||||
|
+ "AD_Client_ID,AD_Org_ID, "
|
||||||
|
+ "IsActive,Created,CreatedBy,Updated,UpdatedBy)VALUES (")
|
||||||
|
.append(m_AD_Tree_ID).append(",").append(AD_User_ID).append(",").append(Node_ID).append(",")
|
||||||
|
.append(AD_Client_ID).append(",").append(AD_Org_ID).append(",")
|
||||||
|
.append("'Y',SysDate,").append(AD_User_ID).append(",SysDate,").append(AD_User_ID).append(")");
|
||||||
|
// if already exist, will result in ORA-00001: unique constraint (ADEMPIERE.AD_TREEBAR_KEY)
|
||||||
|
else
|
||||||
|
sql.append("DELETE AD_TreeBar WHERE AD_Tree_ID=").append(m_AD_Tree_ID)
|
||||||
|
.append(" AND AD_User_ID=").append(AD_User_ID)
|
||||||
|
.append(" AND Node_ID=").append(Node_ID);
|
||||||
|
int no = DB.executeUpdate(sql.toString(), false, null);
|
||||||
|
return no == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add node (by node id) to favourties
|
||||||
|
* @param nodeId
|
||||||
|
* @return true if successfully added
|
||||||
|
*/
|
||||||
|
public boolean addNode(int nodeId) {
|
||||||
|
MTreeNode node = rootNode.findNode(nodeId);
|
||||||
|
if (node != null) {
|
||||||
|
return addNode(node);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add tree node to favourites
|
||||||
|
* @param node
|
||||||
|
* @return true if successfully added
|
||||||
|
*/
|
||||||
|
public boolean addNode(MTreeNode node) {
|
||||||
|
if(barDBupdate(true, node.getNode_ID())) {
|
||||||
|
nodeMap.put(node.getNode_ID(), node);
|
||||||
|
for (Callback<MTreeNode> callback : insertedCallbacks) {
|
||||||
|
callback.onCallback(node);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove node (by node id) from favourites
|
||||||
|
* @param nodeId
|
||||||
|
* @return true if found and remove
|
||||||
|
*/
|
||||||
|
public boolean removeNode(int nodeId) {
|
||||||
|
if(barDBupdate(false, nodeId))
|
||||||
|
{
|
||||||
|
nodeMap.remove(nodeId);
|
||||||
|
for (Callback<Integer> callback : deletedCallbacks) {
|
||||||
|
callback.onCallback(nodeId);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param nodeId
|
||||||
|
* @return true if node id is in the current favourites list
|
||||||
|
*/
|
||||||
|
public boolean hasNode(int nodeId) {
|
||||||
|
return nodeMap.keySet().contains(nodeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return List of favourites node
|
||||||
|
*/
|
||||||
|
public List<MTreeNode> getFavourites() {
|
||||||
|
List<MTreeNode> list = new ArrayList<>();
|
||||||
|
for(int key : nodeMap.keySet()) {
|
||||||
|
list.add(nodeMap.get(key));
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add callback for after add node to favourites
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
public void addInsertedCallback(Callback<MTreeNode> callback) {
|
||||||
|
insertedCallbacks.add(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add callback for after remove node from favourites
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
public void addDeletedCallback(Callback<Integer> callback) {
|
||||||
|
deletedCallbacks.add(callback);
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,6 +23,7 @@ import java.util.Properties;
|
||||||
import org.adempiere.util.Callback;
|
import org.adempiere.util.Callback;
|
||||||
import org.adempiere.webui.adwindow.ADTabpanel;
|
import org.adempiere.webui.adwindow.ADTabpanel;
|
||||||
import org.adempiere.webui.adwindow.ADWindow;
|
import org.adempiere.webui.adwindow.ADWindow;
|
||||||
|
import org.adempiere.webui.apps.MenuSearchController;
|
||||||
import org.adempiere.webui.exception.ApplicationException;
|
import org.adempiere.webui.exception.ApplicationException;
|
||||||
import org.adempiere.webui.session.SessionManager;
|
import org.adempiere.webui.session.SessionManager;
|
||||||
import org.adempiere.webui.theme.ThemeManager;
|
import org.adempiere.webui.theme.ThemeManager;
|
||||||
|
@ -205,6 +206,7 @@ public abstract class AbstractMenuPanel extends Panel implements EventListener<E
|
||||||
link.setSclass("menu-href");
|
link.setSclass("menu-href");
|
||||||
|
|
||||||
treeitem.getTreerow().setDraggable("favourite"); // Elaine 2008/07/24
|
treeitem.getTreerow().setDraggable("favourite"); // Elaine 2008/07/24
|
||||||
|
treeitem.setAttribute(MenuSearchController.M_TREE_NODE_ATTR, mChildNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
.fav-new-btn {
|
.fav-new-btn {
|
||||||
margin-left: 4px;
|
|
||||||
margin-bottom: 3px;
|
|
||||||
padding-left: 1px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.fav-new-btn img {
|
.fav-new-btn img {
|
||||||
|
|
Loading…
Reference in New Issue