IDEMPIERE-6105 Implement recently access menu items (#2311)
This commit is contained in:
parent
e4e27f4ee5
commit
0eabdd9d08
|
|
@ -219,6 +219,7 @@ public class SystemIDs
|
||||||
public final static int WINDOW_LOT = 257;
|
public final static int WINDOW_LOT = 257;
|
||||||
public final static int WINDOW_MATERIAL_RECEIPT = 184;
|
public final static int WINDOW_MATERIAL_RECEIPT = 184;
|
||||||
public final static int WINDOW_MATERIALTRANSACTIONS_INDIRECTUSER = 223;
|
public final static int WINDOW_MATERIALTRANSACTIONS_INDIRECTUSER = 223;
|
||||||
|
public final static int WINDOW_MENU = 105;
|
||||||
public final static int WINDOW_MY_REQUESTS = 237;
|
public final static int WINDOW_MY_REQUESTS = 237;
|
||||||
public final static int WINDOW_NOTICE = 193;
|
public final static int WINDOW_NOTICE = 193;
|
||||||
public final static int WINDOW_PAYMENTS_INTO_BATCH = 200031;
|
public final static int WINDOW_PAYMENTS_INTO_BATCH = 200031;
|
||||||
|
|
|
||||||
|
|
@ -101,8 +101,9 @@ public class GlobalSearch extends Div implements EventListener<Event> {
|
||||||
bandbox.setCtrlKeys("#up#down");
|
bandbox.setCtrlKeys("#up#down");
|
||||||
bandbox.addEventListener(Events.ON_CTRL_KEY, this);
|
bandbox.addEventListener(Events.ON_CTRL_KEY, this);
|
||||||
bandbox.addEventListener(Events.ON_FOCUS, e -> {
|
bandbox.addEventListener(Events.ON_FOCUS, e -> {
|
||||||
if (!bandbox.isOpen())
|
bandbox.setOpen(true);
|
||||||
bandbox.setOpen(true);
|
if (Util.isEmpty(bandbox.getValue(), true) && tabbox.getSelectedIndex() == 0)
|
||||||
|
menuController.updateRecentItems();
|
||||||
});
|
});
|
||||||
|
|
||||||
Bandpopup popup = new Bandpopup();
|
Bandpopup popup = new Bandpopup();
|
||||||
|
|
@ -224,6 +225,8 @@ public class GlobalSearch extends Div implements EventListener<Event> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (event.getName().equals(Events.ON_SELECT)) {
|
} else if (event.getName().equals(Events.ON_SELECT)) {
|
||||||
|
if (tabbox.getSelectedIndex() == 0)
|
||||||
|
menuController.updateRecentItems();
|
||||||
String value = (String) bandbox.getAttribute(LAST_ONCHANGING_ATTR);
|
String value = (String) bandbox.getAttribute(LAST_ONCHANGING_ATTR);
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
value = bandbox.getValue();
|
value = bandbox.getValue();
|
||||||
|
|
@ -254,7 +257,7 @@ public class GlobalSearch extends Div implements EventListener<Event> {
|
||||||
* Handle client info event from browser.
|
* Handle client info event from browser.
|
||||||
*/
|
*/
|
||||||
public void onClientInfo() {
|
public void onClientInfo() {
|
||||||
ZKUpdateUtil.setWindowHeightX(bandbox.getDropdown(), ClientInfo.get().desktopHeight-50);
|
ZKUpdateUtil.setWindowHeightX(bandbox.getDropdown(), ClientInfo.get().desktopHeight-100);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,11 @@ import org.adempiere.webui.util.TreeNodeAction;
|
||||||
import org.adempiere.webui.util.TreeUtils;
|
import org.adempiere.webui.util.TreeUtils;
|
||||||
import org.adempiere.webui.util.ZKUpdateUtil;
|
import org.adempiere.webui.util.ZKUpdateUtil;
|
||||||
import org.compiere.model.MMenu;
|
import org.compiere.model.MMenu;
|
||||||
|
import org.compiere.model.MPreference;
|
||||||
import org.compiere.model.MToolBarButtonRestrict;
|
import org.compiere.model.MToolBarButtonRestrict;
|
||||||
import org.compiere.model.MTreeNode;
|
import org.compiere.model.MTreeNode;
|
||||||
|
import org.compiere.model.Query;
|
||||||
|
import org.compiere.model.SystemIDs;
|
||||||
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;
|
||||||
|
|
@ -68,6 +71,9 @@ import org.zkoss.zul.impl.LabelImageElement;
|
||||||
*/
|
*/
|
||||||
public class MenuSearchController implements EventListener<Event>{
|
public class MenuSearchController implements EventListener<Event>{
|
||||||
|
|
||||||
|
/** Initial number of menu items loaded into listbox */
|
||||||
|
private static final int INITIAL_LOADING_SIZE = 50;
|
||||||
|
|
||||||
/** Component attribute to hold reference of {@link MTreeNode} **/
|
/** Component attribute to hold reference of {@link MTreeNode} **/
|
||||||
public static final String M_TREE_NODE_ATTR = "MTreeNode";
|
public static final String M_TREE_NODE_ATTR = "MTreeNode";
|
||||||
|
|
||||||
|
|
@ -77,7 +83,7 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
private static final String Z_ICON_STAR = "z-icon-star";
|
private static final String Z_ICON_STAR = "z-icon-star";
|
||||||
/** Event echo from {@link #search(String)} to initiate search action **/
|
/** Event echo from {@link #search(String)} to initiate search action **/
|
||||||
private static final String ON_SEARCH_ECHO_EVENT = "onSearchEcho";
|
private static final String ON_SEARCH_ECHO_EVENT = "onSearchEcho";
|
||||||
/** Event to load all menu items into {@link #listbox}. Default is to load the first 50 only. **/
|
/** Event to load all menu items into {@link #listbox}. Default is to load the first {@link #INITIAL_LOADING_SIZE} only. **/
|
||||||
private static final String ON_LOAD_MORE_EVENT = "onLoadMore";
|
private static final String ON_LOAD_MORE_EVENT = "onLoadMore";
|
||||||
/** {@link Listitem} attribute to store the last timestamp of ON_CLICK or ON_SELECT event **/
|
/** {@link Listitem} attribute to store the last timestamp of ON_CLICK or ON_SELECT event **/
|
||||||
private static final String ONSELECT_TIMESTAMP_ATTR = "onselect.timestamp";
|
private static final String ONSELECT_TIMESTAMP_ATTR = "onselect.timestamp";
|
||||||
|
|
@ -100,20 +106,58 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
|
|
||||||
private String highlightText = null;
|
private String highlightText = null;
|
||||||
|
|
||||||
|
/** List of recently access menu items (AD_Menu_ID) */
|
||||||
|
private List<String> recentMenuItemIds = new ArrayList<>();
|
||||||
|
|
||||||
/** Event post from {@link #selectTreeitem(Object, Boolean)} **/
|
/** Event post from {@link #selectTreeitem(Object, Boolean)} **/
|
||||||
private static final String ON_POST_SELECT_TREEITEM_EVENT = "onPostSelectTreeitem";
|
private static final String ON_POST_SELECT_TREEITEM_EVENT = "onPostSelectTreeitem";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param tree
|
* @param tree usually the tree instance from {@link}
|
||||||
*/
|
*/
|
||||||
public MenuSearchController(Tree tree) {
|
public MenuSearchController(Tree tree) {
|
||||||
this.tree = tree;
|
this.tree = tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load recently access menu items
|
||||||
|
*/
|
||||||
|
private List<String> loadRecentItems() {
|
||||||
|
List<String> recents = new ArrayList<String>();
|
||||||
|
int AD_User_ID = Env.getAD_User_ID(Env.getCtx());
|
||||||
|
int AD_Role_ID = Env.getAD_Role_ID(Env.getCtx());
|
||||||
|
int AD_Org_ID = 0;
|
||||||
|
String attribute = AD_Role_ID+"|RecentMenuItems";
|
||||||
|
Query query = new Query(Env.getCtx(), MPreference.Table_Name, "PreferenceFor=? AND Attribute=? AND AD_Org_ID=? AND AD_User_ID=? AND AD_Window_ID=?", null);
|
||||||
|
MPreference preference = query.setClient_ID().setParameters("W", attribute, AD_Org_ID, AD_User_ID, SystemIDs.WINDOW_MENU).first();
|
||||||
|
if (preference != null) {
|
||||||
|
String[] recentItems = preference.getValue().split("[,]");
|
||||||
|
for (String recentItem : recentItems) {
|
||||||
|
recents.add(recentItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return recents;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If there are changes in the recent menu items for user, reload and update menu items model
|
||||||
|
*/
|
||||||
|
public void updateRecentItems() {
|
||||||
|
List<String> recents = loadRecentItems();
|
||||||
|
if (!recents.equals(recentMenuItemIds)) {
|
||||||
|
recentMenuItemIds = recents;
|
||||||
|
sortMenuItemModel();
|
||||||
|
moveRecentItems();
|
||||||
|
if (fullModel != null)
|
||||||
|
updateListboxModel(model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Populate {@link #model} from {@link #tree}
|
* Populate {@link #model} from {@link #tree}
|
||||||
*/
|
*/
|
||||||
public void refreshModel() {
|
public void refreshModel() {
|
||||||
|
recentMenuItemIds = loadRecentItems();
|
||||||
final List<MenuItem> list = new ArrayList<MenuItem>();
|
final List<MenuItem> list = new ArrayList<MenuItem>();
|
||||||
if (tree.getModel() == null) {
|
if (tree.getModel() == null) {
|
||||||
TreeUtils.traverse(tree, new TreeItemAction() {
|
TreeUtils.traverse(tree, new TreeItemAction() {
|
||||||
|
|
@ -130,8 +174,15 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
model = new ListModelList<MenuItem>(list, true);
|
model = new ListModelList<MenuItem>(list, true);
|
||||||
model.sort(new Comparator<MenuItem>() {
|
sortMenuItemModel();
|
||||||
|
moveRecentItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort menu items model in alphabetical order
|
||||||
|
*/
|
||||||
|
private void sortMenuItemModel() {
|
||||||
|
model.sort(new Comparator<MenuItem>() {
|
||||||
@Override
|
@Override
|
||||||
public int compare(MenuItem o1, MenuItem o2) {
|
public int compare(MenuItem o1, MenuItem o2) {
|
||||||
return o1.getLabel().compareTo(o2.getLabel());
|
return o1.getLabel().compareTo(o2.getLabel());
|
||||||
|
|
@ -139,6 +190,35 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move the 7 most recently access menu items to the top of menu items model
|
||||||
|
*/
|
||||||
|
private void moveRecentItems() {
|
||||||
|
if (recentMenuItemIds.size() > 0) {
|
||||||
|
List<MenuItem> recents = new ArrayList<MenuItem>();
|
||||||
|
for(String id : recentMenuItemIds) {
|
||||||
|
for(int i = 0; i < model.getSize(); i++) {
|
||||||
|
if (model.get(i).getData() instanceof Treeitem ti) {
|
||||||
|
if (ti.getValue() instanceof String tis) {
|
||||||
|
if (tis.equals(id)) {
|
||||||
|
recents.add(model.get(i));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (recents.size() > 0) {
|
||||||
|
for (MenuItem mi : recents) {
|
||||||
|
model.remove(mi);
|
||||||
|
}
|
||||||
|
for(int i = recents.size()-1; i >= 0; i--) {
|
||||||
|
model.add(0, recents.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add treeNode to list
|
* Add treeNode to list
|
||||||
* @param list
|
* @param list
|
||||||
|
|
@ -373,16 +453,16 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load {@link #fullModel} to {@link #listbox}.
|
* Load {@link #fullModel} to {@link #listbox}.
|
||||||
* Only first 50 loaded to {@link #listbox} initially.
|
* Only first {@link #INITIAL_LOADING_SIZE} loaded to {@link #listbox} initially.
|
||||||
*/
|
*/
|
||||||
private void loadMore() {
|
private void loadMore() {
|
||||||
ListModel<MenuItem> listModel = listbox.getModel();
|
ListModel<MenuItem> listModel = listbox.getModel();
|
||||||
ListModelList<MenuItem> lml = (ListModelList<MenuItem>) listModel;
|
ListModelList<MenuItem> lml = (ListModelList<MenuItem>) listModel;
|
||||||
lml.remove(lml.size()-1);
|
lml.remove(lml.size()-1);
|
||||||
List<MenuItem> subList = fullModel.subList(50, fullModel.size());
|
List<MenuItem> subList = fullModel.subList(INITIAL_LOADING_SIZE, fullModel.size());
|
||||||
lml.addAll(subList);
|
lml.addAll(subList);
|
||||||
fullModel = null;
|
fullModel = null;
|
||||||
listbox.setSelectedIndex(50);
|
listbox.setSelectedIndex(INITIAL_LOADING_SIZE);
|
||||||
Clients.scrollIntoView(listbox.getSelectedItem());
|
Clients.scrollIntoView(listbox.getSelectedItem());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -430,8 +510,8 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle {@link #ON_POST_SELECT_TREEITEM_EVENT} event.
|
* Handle {@link #ON_POST_SELECT_TREEITEM_EVENT} event.<br/>
|
||||||
* Post ON_CLICK event to link ({@link A} or {@link Treerow}).
|
* Post ON_CLICK event to link ({@link A} or {@link Treerow}, handle in {@link AbstractMenuPanel}).
|
||||||
* @param newRecord
|
* @param newRecord
|
||||||
*/
|
*/
|
||||||
private void onPostSelectTreeitem(Boolean newRecord) {
|
private void onPostSelectTreeitem(Boolean newRecord) {
|
||||||
|
|
@ -441,9 +521,10 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
event = new Event(Events.ON_CLICK, tree.getSelectedItem().getTreerow().getFirstChild().getFirstChild(), newRecord);
|
event = new Event(Events.ON_CLICK, tree.getSelectedItem().getTreerow().getFirstChild().getFirstChild(), newRecord);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
event = new Event(Events.ON_CLICK, tree.getSelectedItem().getTreerow(), newRecord);
|
event = new Event(Events.ON_CLICK, tree.getSelectedItem().getTreerow(), newRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
Events.postEvent(event);
|
Events.postEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -474,15 +555,15 @@ public class MenuSearchController implements EventListener<Event>{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update {@link #listbox} with newModel.
|
* Update {@link #listbox} with newModel.
|
||||||
* If newModel has > 50 items, only first 50 is loaded into {@link #listbox}.
|
* If newModel has > {@link #INITIAL_LOADING_SIZE} items, only first {@link #INITIAL_LOADING_SIZE} is loaded into {@link #listbox}.
|
||||||
* User has to click the load more link (...) to load the rest of the items into {@link #listbox}.
|
* User has to click the load more link (...) to load the rest of the items into {@link #listbox}.
|
||||||
* @param newModel
|
* @param newModel
|
||||||
*/
|
*/
|
||||||
private void updateListboxModel(ListModelList<MenuItem> newModel) {
|
private void updateListboxModel(ListModelList<MenuItem> newModel) {
|
||||||
fullModel = null;
|
fullModel = null;
|
||||||
if (newModel.size() > 50) {
|
if (newModel.size() > INITIAL_LOADING_SIZE) {
|
||||||
List<MenuItem> list = newModel.getInnerList();
|
List<MenuItem> list = newModel.getInnerList();
|
||||||
List<MenuItem> subList = list.subList(0, 50);
|
List<MenuItem> subList = list.subList(0, INITIAL_LOADING_SIZE);
|
||||||
fullModel = newModel;
|
fullModel = newModel;
|
||||||
newModel = new ListModelList<MenuItem>(subList.toArray(new MenuItem[0]));
|
newModel = new ListModelList<MenuItem>(subList.toArray(new MenuItem[0]));
|
||||||
MenuItem more = new MenuItem();
|
MenuItem more = new MenuItem();
|
||||||
|
|
|
||||||
|
|
@ -15,19 +15,12 @@ import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import org.adempiere.util.Callback;
|
|
||||||
import org.adempiere.webui.ClientInfo;
|
import org.adempiere.webui.ClientInfo;
|
||||||
import org.adempiere.webui.adwindow.ADTabpanel;
|
|
||||||
import org.adempiere.webui.adwindow.ADWindow;
|
|
||||||
import org.adempiere.webui.desktop.AbstractDesktop;
|
|
||||||
import org.adempiere.webui.desktop.FavouriteController;
|
import org.adempiere.webui.desktop.FavouriteController;
|
||||||
import org.adempiere.webui.desktop.IDesktop;
|
|
||||||
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;
|
||||||
import org.compiere.model.MMenu;
|
import org.compiere.model.MMenu;
|
||||||
import org.compiere.model.MQuery;
|
|
||||||
import org.compiere.model.MTable;
|
|
||||||
import org.compiere.model.MToolBarButtonRestrict;
|
import org.compiere.model.MToolBarButtonRestrict;
|
||||||
import org.compiere.model.MTreeNode;
|
import org.compiere.model.MTreeNode;
|
||||||
import org.compiere.util.CLogger;
|
import org.compiere.util.CLogger;
|
||||||
|
|
@ -331,27 +324,7 @@ public class FavoriteSimpleTreeModel extends SimpleTreeModel implements EventLis
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MMenu menu = (MMenu) MTable.get(Env.getCtx(), MMenu.Table_ID).getPO(menuID, null);
|
SessionManager.getAppDesktop().onNewRecord(menuID);
|
||||||
IDesktop desktop = SessionManager.getAppDesktop();
|
|
||||||
if (desktop instanceof AbstractDesktop)
|
|
||||||
((AbstractDesktop)desktop).setPredefinedContextVariables(menu.getPredefinedContextVariables());
|
|
||||||
|
|
||||||
MQuery query = new MQuery("");
|
|
||||||
query.addRestriction("1=2");
|
|
||||||
query.setRecordCount(0);
|
|
||||||
|
|
||||||
SessionManager.getAppDesktop().openWindow(menu.getAD_Window_ID(), query, new Callback<ADWindow>() {
|
|
||||||
@Override
|
|
||||||
public void onCallback(ADWindow result)
|
|
||||||
{
|
|
||||||
if (result == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
result.getADWindowContent().onNew();
|
|
||||||
ADTabpanel adtabpanel = (ADTabpanel) result.getADWindowContent().getADTab().getSelectedTabpanel();
|
|
||||||
adtabpanel.focusToFirstEditor(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -16,15 +16,24 @@ package org.adempiere.webui.desktop;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.adempiere.util.Callback;
|
||||||
import org.adempiere.webui.AdempiereWebUI;
|
import org.adempiere.webui.AdempiereWebUI;
|
||||||
import org.adempiere.webui.ClientInfo;
|
import org.adempiere.webui.ClientInfo;
|
||||||
import org.adempiere.webui.LayoutUtils;
|
import org.adempiere.webui.LayoutUtils;
|
||||||
|
import org.adempiere.webui.adwindow.ADTabpanel;
|
||||||
|
import org.adempiere.webui.adwindow.ADWindow;
|
||||||
import org.adempiere.webui.component.Window;
|
import org.adempiere.webui.component.Window;
|
||||||
import org.adempiere.webui.event.DialogEvents;
|
import org.adempiere.webui.event.DialogEvents;
|
||||||
import org.adempiere.webui.exception.ApplicationException;
|
import org.adempiere.webui.exception.ApplicationException;
|
||||||
import org.adempiere.webui.part.AbstractUIPart;
|
import org.adempiere.webui.part.AbstractUIPart;
|
||||||
|
import org.adempiere.webui.session.SessionManager;
|
||||||
import org.compiere.model.MMenu;
|
import org.compiere.model.MMenu;
|
||||||
|
import org.compiere.model.MPreference;
|
||||||
|
import org.compiere.model.MQuery;
|
||||||
|
import org.compiere.model.Query;
|
||||||
|
import org.compiere.model.SystemIDs;
|
||||||
import org.compiere.util.CLogger;
|
import org.compiere.util.CLogger;
|
||||||
import org.compiere.util.Env;
|
import org.compiere.util.Env;
|
||||||
import org.zkoss.zk.ui.Component;
|
import org.zkoss.zk.ui.Component;
|
||||||
|
|
@ -58,8 +67,8 @@ public abstract class AbstractDesktop extends AbstractUIPart implements IDesktop
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event listener for menu item selection.<br/>
|
* Event listener for menu item selection.<br/>
|
||||||
* Identifies the action associated with the selected
|
* Identifies the action associated with the selected menu item and acts accordingly.<br/>
|
||||||
* menu item and acts accordingly.
|
* Event from favourite panel, global search and application menu tree will be routed here.
|
||||||
*
|
*
|
||||||
* @param menuId Identifier for the selected menu item
|
* @param menuId Identifier for the selected menu item
|
||||||
*
|
*
|
||||||
|
|
@ -110,8 +119,78 @@ public abstract class AbstractDesktop extends AbstractUIPart implements IDesktop
|
||||||
{
|
{
|
||||||
setPredefinedContextVariables(null);
|
setPredefinedContextVariables(null);
|
||||||
}
|
}
|
||||||
|
updateRecentMenuItem(menuId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open AD window in new record mode.<br/>
|
||||||
|
* Call by global search, application menu tree and favourite panel.
|
||||||
|
* @param menuId
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onNewRecord(int menuId) {
|
||||||
|
MMenu menu = new MMenu(Env.getCtx(), menuId, null);
|
||||||
|
setPredefinedContextVariables(menu.getPredefinedContextVariables());
|
||||||
|
|
||||||
|
MQuery query = new MQuery("");
|
||||||
|
query.addRestriction("1=2");
|
||||||
|
query.setRecordCount(0);
|
||||||
|
|
||||||
|
SessionManager.getAppDesktop().openWindow(menu.getAD_Window_ID(), query, new Callback<ADWindow>() {
|
||||||
|
@Override
|
||||||
|
public void onCallback(ADWindow result) {
|
||||||
|
if(result == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
result.getADWindowContent().onNew();
|
||||||
|
ADTabpanel adtabpanel = (ADTabpanel) result.getADWindowContent().getADTab().getSelectedTabpanel();
|
||||||
|
adtabpanel.focusToFirstEditor(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
updateRecentMenuItem(menuId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform asynchronous update of recent menu items preference for user
|
||||||
|
* @param menuId
|
||||||
|
*/
|
||||||
|
protected void updateRecentMenuItem(int menuId) {
|
||||||
|
Runnable runnable = () -> {
|
||||||
|
int AD_User_ID = Env.getAD_User_ID(Env.getCtx());
|
||||||
|
int AD_Role_ID = Env.getAD_Role_ID(Env.getCtx());
|
||||||
|
int AD_Org_ID = 0;
|
||||||
|
String attribute = AD_Role_ID+"|RecentMenuItems";
|
||||||
|
Query query = new Query(Env.getCtx(), MPreference.Table_Name, "PreferenceFor=? AND Attribute=? AND AD_Org_ID=? AND AD_User_ID=? AND AD_Window_ID=?", null);
|
||||||
|
MPreference preference = query.setClient_ID().setParameters("W", attribute, AD_Org_ID, AD_User_ID, SystemIDs.WINDOW_MENU).first();
|
||||||
|
if (preference == null) {
|
||||||
|
preference = new MPreference(Env.getCtx(), 0, null);
|
||||||
|
preference.setAD_Org_ID(AD_Org_ID);
|
||||||
|
preference.setPreferenceFor("W");
|
||||||
|
preference.setAttribute(attribute);
|
||||||
|
preference.setAD_User_ID(AD_User_ID);
|
||||||
|
preference.setValue(Integer.toString(menuId));
|
||||||
|
preference.setAD_Window_ID(SystemIDs.WINDOW_MENU);
|
||||||
|
preference.saveEx();
|
||||||
|
} else {
|
||||||
|
String recentItemValue = preference.getValue();
|
||||||
|
List<String> itemList = new ArrayList<String>();
|
||||||
|
String[] recentItemValues = recentItemValue.split("[,]");
|
||||||
|
String menuIdValue = Integer.toString(menuId);
|
||||||
|
itemList.add(menuIdValue);
|
||||||
|
for (int i = 0; itemList.size() < 7 && i < recentItemValues.length; i++) {
|
||||||
|
if (!recentItemValues[i].equals(menuIdValue))
|
||||||
|
itemList.add(recentItemValues[i]);
|
||||||
|
}
|
||||||
|
recentItemValue = itemList.stream().collect(Collectors.joining(","));
|
||||||
|
preference.setValue(recentItemValue);
|
||||||
|
preference.saveEx();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Executions.schedule(getComponent().getDesktop(), e -> {
|
||||||
|
runnable.run();
|
||||||
|
}, new Event("onUpdateRecentMenuItem"));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {@link ClientInfo}
|
* @return {@link ClientInfo}
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -49,11 +49,17 @@ public interface IDesktop extends UIPart {
|
||||||
public ClientInfo getClientInfo();
|
public ClientInfo getClientInfo();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Launch menu item
|
||||||
* @param nodeId
|
* @param nodeId
|
||||||
*/
|
*/
|
||||||
public void onMenuSelected(int nodeId);
|
public void onMenuSelected(int nodeId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Launch AD Window in new record mode
|
||||||
|
* @param menuId
|
||||||
|
*/
|
||||||
|
public void onNewRecord(int menuId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param window
|
* @param window
|
||||||
|
|
|
||||||
|
|
@ -20,18 +20,12 @@ import java.util.Collection;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.adempiere.util.Callback;
|
|
||||||
import org.adempiere.webui.adwindow.ADTabpanel;
|
|
||||||
import org.adempiere.webui.adwindow.ADWindow;
|
|
||||||
import org.adempiere.webui.apps.MenuSearchController;
|
import org.adempiere.webui.apps.MenuSearchController;
|
||||||
import org.adempiere.webui.desktop.AbstractDesktop;
|
|
||||||
import org.adempiere.webui.desktop.IDesktop;
|
|
||||||
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;
|
||||||
import org.adempiere.webui.util.ZKUpdateUtil;
|
import org.adempiere.webui.util.ZKUpdateUtil;
|
||||||
import org.compiere.model.MMenu;
|
import org.compiere.model.MMenu;
|
||||||
import org.compiere.model.MQuery;
|
|
||||||
import org.compiere.model.MToolBarButtonRestrict;
|
import org.compiere.model.MToolBarButtonRestrict;
|
||||||
import org.compiere.model.MTree;
|
import org.compiere.model.MTree;
|
||||||
import org.compiere.model.MTreeNode;
|
import org.compiere.model.MTreeNode;
|
||||||
|
|
@ -291,7 +285,8 @@ public abstract class AbstractMenuPanel extends Panel implements EventListener<E
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle onClick and onOk event
|
* Handle onClick and onOk event for menu tree item.<br/>
|
||||||
|
* The event from global search and application menu tree will be routed to here.
|
||||||
* @param comp
|
* @param comp
|
||||||
* @param eventData
|
* @param eventData
|
||||||
*/
|
*/
|
||||||
|
|
@ -361,31 +356,11 @@ public abstract class AbstractMenuPanel extends Panel implements EventListener<E
|
||||||
private void onNewRecord(Treeitem selectedItem) {
|
private void onNewRecord(Treeitem selectedItem) {
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (getParent() instanceof Popup) {
|
||||||
|
((Popup)getParent()).close();
|
||||||
|
}
|
||||||
int menuId = Integer.parseInt((String)selectedItem.getValue());
|
int menuId = Integer.parseInt((String)selectedItem.getValue());
|
||||||
MMenu menu = new MMenu(Env.getCtx(), menuId, null);
|
SessionManager.getAppDesktop().onNewRecord(menuId);
|
||||||
IDesktop desktop = SessionManager.getAppDesktop();
|
|
||||||
if (desktop instanceof AbstractDesktop)
|
|
||||||
((AbstractDesktop)desktop).setPredefinedContextVariables(menu.getPredefinedContextVariables());
|
|
||||||
|
|
||||||
MQuery query = new MQuery("");
|
|
||||||
query.addRestriction("1=2");
|
|
||||||
query.setRecordCount(0);
|
|
||||||
|
|
||||||
if (getParent() instanceof Popup) {
|
|
||||||
((Popup)getParent()).close();
|
|
||||||
}
|
|
||||||
|
|
||||||
SessionManager.getAppDesktop().openWindow(menu.getAD_Window_ID(), query, new Callback<ADWindow>() {
|
|
||||||
@Override
|
|
||||||
public void onCallback(ADWindow result) {
|
|
||||||
if(result == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
result.getADWindowContent().onNew();
|
|
||||||
ADTabpanel adtabpanel = (ADTabpanel) result.getADWindowContent().getADTab().getSelectedTabpanel();
|
|
||||||
adtabpanel.focusToFirstEditor(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue