IDEMPIERE-3328 Trees : Ability to force loading of all nodes

This commit is contained in:
Nicolas Micoud 2017-05-03 18:19:26 +02:00
parent ab23c91233
commit 0107f87a3a
8 changed files with 215 additions and 6 deletions

View File

@ -0,0 +1,42 @@
SET SQLBLANKLINES ON
SET DEFINE OFF
-- IDEMPIERE-3328
-- Apr 3, 2017 5:18:40 PM CEST
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,Description,PrintName,EntityType,AD_Element_UU) VALUES (203064,0,0,'Y',TO_DATE('2017-04-03 17:18:40','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2017-04-03 17:18:40','YYYY-MM-DD HH24:MI:SS'),100,'IsLoadAllNodesImmediately','Loads directly all nodes','If checked, all nodes are loaded before tree is displayed','Loads directly all nodes','D','decd8ab6-f0dd-441a-8842-25d9cb9e3b3f')
;
-- Apr 3, 2017 5:19:13 PM CEST
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,AD_Table_ID,ColumnName,DefaultValue,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure) VALUES (212971,0,'Loads directly all nodes','If checked, all nodes are loaded before tree is displayed',288,'IsLoadAllNodesImmediately','N',1,'N','N','Y','N','N',0,'N',20,0,0,'Y',TO_DATE('2017-04-03 17:19:13','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2017-04-03 17:19:13','YYYY-MM-DD HH24:MI:SS'),100,203064,'Y','N','D','N','N','N','Y','692e44f6-4653-4a06-b68e-05fa3382202d','N',0,'N','N')
;
-- Apr 3, 2017 5:19:18 PM CEST
ALTER TABLE AD_Tree MODIFY IsLoadAllNodesImmediately CHAR(1) DEFAULT 'N'
;
-- Apr 3, 2017 5:19:18 PM CEST
UPDATE AD_Tree SET IsLoadAllNodesImmediately='N' WHERE IsLoadAllNodesImmediately IS NULL
;
-- Apr 3, 2017 5:19:47 PM CEST
INSERT INTO AD_Field (AD_Field_ID,Name,Description,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan) VALUES (204379,'Loads directly all nodes','If checked, all nodes are loaded before tree is displayed',243,212971,'Y',1,110,'N','N','N','N',0,0,'Y',TO_DATE('2017-04-03 17:19:46','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2017-04-03 17:19:46','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','c66c870e-2b9a-41cb-86f8-74c7b9e4b538','Y',110,2,2)
;
-- Apr 3, 2017 5:20:08 PM CEST
UPDATE AD_Field SET SeqNo=80, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-04-03 17:20:08','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=203826
;
-- Apr 3, 2017 5:20:08 PM CEST
UPDATE AD_Field SET SeqNo=90, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-04-03 17:20:08','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=5228
;
-- Apr 3, 2017 5:20:08 PM CEST
UPDATE AD_Field SET SeqNo=100, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-04-03 17:20:08','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=12421
;
-- Apr 3, 2017 5:20:09 PM CEST
UPDATE AD_Field SET SeqNo=120, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-04-03 17:20:09','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=8371
;
SELECT register_migration_script('201704031723_IDEMPIERE-3328.sql') FROM dual
;

View File

@ -0,0 +1,39 @@
-- IDEMPIERE-3328
-- Apr 3, 2017 5:18:41 PM CEST
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,Description,PrintName,EntityType,AD_Element_UU) VALUES (203064,0,0,'Y',TO_TIMESTAMP('2017-04-03 17:18:40','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2017-04-03 17:18:40','YYYY-MM-DD HH24:MI:SS'),100,'IsLoadAllNodesImmediately','Loads directly all nodes','If checked, all nodes are loaded before tree is displayed','Loads directly all nodes','D','decd8ab6-f0dd-441a-8842-25d9cb9e3b3f')
;
-- Apr 3, 2017 5:19:13 PM CEST
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,AD_Table_ID,ColumnName,DefaultValue,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure) VALUES (212971,0,'Loads directly all nodes','If checked, all nodes are loaded before tree is displayed',288,'IsLoadAllNodesImmediately','N',1,'N','N','Y','N','N',0,'N',20,0,0,'Y',TO_TIMESTAMP('2017-04-03 17:19:13','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2017-04-03 17:19:13','YYYY-MM-DD HH24:MI:SS'),100,203064,'Y','N','D','N','N','N','Y','692e44f6-4653-4a06-b68e-05fa3382202d','N',0,'N','N')
;
-- Apr 3, 2017 5:19:18 PM CEST
INSERT INTO t_alter_column values('ad_tree','IsLoadAllNodesImmediately','CHAR(1)',null,'N')
;
-- Apr 3, 2017 5:19:18 PM CEST
UPDATE AD_Tree SET IsLoadAllNodesImmediately='N' WHERE IsLoadAllNodesImmediately IS NULL
;
-- Apr 3, 2017 5:19:47 PM CEST
INSERT INTO AD_Field (AD_Field_ID,Name,Description,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan) VALUES (204379,'Loads directly all nodes','If checked, all nodes are loaded before tree is displayed',243,212971,'Y',1,110,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2017-04-03 17:19:46','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2017-04-03 17:19:46','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','c66c870e-2b9a-41cb-86f8-74c7b9e4b538','Y',110,2,2)
;
-- Apr 3, 2017 5:20:08 PM CEST
UPDATE AD_Field SET SeqNo=80, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-04-03 17:20:08','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=203826
;
-- Apr 3, 2017 5:20:08 PM CEST
UPDATE AD_Field SET SeqNo=90, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-04-03 17:20:08','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=5228
;
-- Apr 3, 2017 5:20:08 PM CEST
UPDATE AD_Field SET SeqNo=100, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-04-03 17:20:08','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=12421
;
-- Apr 3, 2017 5:20:09 PM CEST
UPDATE AD_Field SET SeqNo=120, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-04-03 17:20:09','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=8371
;
SELECT register_migration_script('201704031723_IDEMPIERE-3328.sql') FROM dual
;

View File

@ -167,6 +167,19 @@ public interface I_AD_Tree
*/ */
public boolean isDefault(); public boolean isDefault();
/** Column name IsLoadAllNodesImmediately */
public static final String COLUMNNAME_IsLoadAllNodesImmediately = "IsLoadAllNodesImmediately";
/** Set Loads directly all nodes.
* If checked, all nodes are loaded before tree is displayed
*/
public void setIsLoadAllNodesImmediately (boolean IsLoadAllNodesImmediately);
/** Get Loads directly all nodes.
* If checked, all nodes are loaded before tree is displayed
*/
public boolean isLoadAllNodesImmediately();
/** Column name IsTreeDrivenByValue */ /** Column name IsTreeDrivenByValue */
public static final String COLUMNNAME_IsTreeDrivenByValue = "IsTreeDrivenByValue"; public static final String COLUMNNAME_IsTreeDrivenByValue = "IsTreeDrivenByValue";

View File

@ -20,6 +20,7 @@ import java.sql.ResultSet;
import java.util.Properties; import java.util.Properties;
import org.compiere.util.CCache; import org.compiere.util.CCache;
import org.compiere.util.DB;
/** /**
* Base Tree Model. * Base Tree Model.
@ -330,7 +331,7 @@ public class MTree_Base extends X_AD_Tree
if ("M_Product".equals(tableName) || "C_BPartner".equals(tableName) if ("M_Product".equals(tableName) || "C_BPartner".equals(tableName)
|| "AD_Org".equals(tableName) || "C_Campaign".equals(tableName)) || "AD_Org".equals(tableName) || "C_Campaign".equals(tableName))
return "x.AD_PrintColor_ID"; return "x.AD_PrintColor_ID";
return "NULL"; return "NULL";
} // getSourceTableName } // getSourceTableName
@ -397,5 +398,10 @@ public class MTree_Base extends X_AD_Tree
return success; return success;
} // afterSave } // afterSave
/** Returns true if should load all tree nodes immediately */
public static boolean isLoadAllNodesImmediately(int treeID, String trxName) {
return DB.getSQLValueStringEx(trxName, "SELECT IsLoadAllNodesImmediately FROM AD_Tree WHERE AD_Tree_ID = ?", treeID).equals("Y");
}
} // MTree_Base } // MTree_Base

View File

@ -30,7 +30,7 @@ public class X_AD_Tree extends PO implements I_AD_Tree, I_Persistent
/** /**
* *
*/ */
private static final long serialVersionUID = 20161030L; private static final long serialVersionUID = 20170403L;
/** Standard Constructor */ /** Standard Constructor */
public X_AD_Tree (Properties ctx, int AD_Tree_ID, String trxName) public X_AD_Tree (Properties ctx, int AD_Tree_ID, String trxName)
@ -41,6 +41,8 @@ public class X_AD_Tree extends PO implements I_AD_Tree, I_Persistent
setAD_Tree_ID (0); setAD_Tree_ID (0);
setIsAllNodes (false); setIsAllNodes (false);
setIsDefault (false); setIsDefault (false);
// N
setIsLoadAllNodesImmediately (false);
// N // N
setIsTreeDrivenByValue (false); setIsTreeDrivenByValue (false);
// N // N
@ -207,6 +209,30 @@ public class X_AD_Tree extends PO implements I_AD_Tree, I_Persistent
return false; return false;
} }
/** Set Loads directly all nodes.
@param IsLoadAllNodesImmediately
If checked, all nodes are loaded before tree is displayed
*/
public void setIsLoadAllNodesImmediately (boolean IsLoadAllNodesImmediately)
{
set_Value (COLUMNNAME_IsLoadAllNodesImmediately, Boolean.valueOf(IsLoadAllNodesImmediately));
}
/** Get Loads directly all nodes.
@return If checked, all nodes are loaded before tree is displayed
*/
public boolean isLoadAllNodesImmediately ()
{
Object oo = get_Value(COLUMNNAME_IsLoadAllNodesImmediately);
if (oo != null)
{
if (oo instanceof Boolean)
return ((Boolean)oo).booleanValue();
return "Y".equals(oo);
}
return false;
}
/** Set Driven by Search Key. /** Set Driven by Search Key.
@param IsTreeDrivenByValue Driven by Search Key */ @param IsTreeDrivenByValue Driven by Search Key */
public void setIsTreeDrivenByValue (boolean IsTreeDrivenByValue) public void setIsTreeDrivenByValue (boolean IsTreeDrivenByValue)

View File

@ -20,6 +20,7 @@ import org.adempiere.webui.component.ToolBarButton;
import org.adempiere.webui.panel.TreeSearchPanel; import org.adempiere.webui.panel.TreeSearchPanel;
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.MTree_Base;
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;
@ -42,8 +43,7 @@ public class ADTreePanel extends Panel implements EventListener<Event>
/** /**
* *
*/ */
private static final long serialVersionUID = -6868506934553777046L; private static final long serialVersionUID = 164816320839461191L;
private static final String ON_EXPAND_MENU_EVENT = "onExpandMenu"; private static final String ON_EXPAND_MENU_EVENT = "onExpandMenu";
private TreeSearchPanel pnlSearch; private TreeSearchPanel pnlSearch;
private Tree tree; private Tree tree;
@ -75,6 +75,8 @@ public class ADTreePanel extends Panel implements EventListener<Event>
{ {
this.AD_Tree_ID = AD_Tree_ID; this.AD_Tree_ID = AD_Tree_ID;
SimpleTreeModel.initADTree(tree, AD_Tree_ID, windowNo); SimpleTreeModel.initADTree(tree, AD_Tree_ID, windowNo);
if (MTree_Base.isLoadAllNodesImmediately(AD_Tree_ID, null))
TreeUtils.collapseTree(tree, true);
pnlSearch.initialise(); pnlSearch.initialise();
return true; return true;
} }

View File

@ -34,11 +34,13 @@ import org.adempiere.webui.panel.CustomForm;
import org.adempiere.webui.panel.IFormController; import org.adempiere.webui.panel.IFormController;
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.TreeUtils;
import org.adempiere.webui.util.ZKUpdateUtil; import org.adempiere.webui.util.ZKUpdateUtil;
import org.adempiere.webui.window.FDialog; import org.adempiere.webui.window.FDialog;
import org.compiere.apps.form.TreeMaintenance; import org.compiere.apps.form.TreeMaintenance;
import org.compiere.model.MTree; import org.compiere.model.MTree;
import org.compiere.model.MTreeNode; import org.compiere.model.MTreeNode;
import org.compiere.model.MTree_Base;
import org.compiere.util.Env; import org.compiere.util.Env;
import org.compiere.util.KeyNamePair; import org.compiere.util.KeyNamePair;
import org.compiere.util.Msg; import org.compiere.util.Msg;
@ -322,8 +324,11 @@ public class WTreeMaintenance extends TreeMaintenance implements IFormController
centerTree.getTreefoot().detach(); centerTree.getTreefoot().detach();
if (centerTree.getTreechildren() != null) if (centerTree.getTreechildren() != null)
centerTree.getTreechildren().detach(); centerTree.getTreechildren().detach();
SimpleTreeModel.initADTree(centerTree, m_tree.getAD_Tree_ID(), m_WindowNo); SimpleTreeModel.initADTree(centerTree, m_tree.getAD_Tree_ID(), m_WindowNo);
if (MTree_Base.isLoadAllNodesImmediately(m_tree.getAD_Tree_ID(), null))
TreeUtils.collapseTree(centerTree, false);
} // action_fillTree } // action_fillTree
/** /**

View File

@ -13,11 +13,17 @@
*****************************************************************************/ *****************************************************************************/
package org.adempiere.webui.util; package org.adempiere.webui.util;
import java.util.Collection;
import java.util.Iterator;
import org.zkoss.zk.ui.Component;
import org.zkoss.zul.DefaultTreeNode; import org.zkoss.zul.DefaultTreeNode;
import org.zkoss.zul.Tree; import org.zkoss.zul.Tree;
import org.zkoss.zul.TreeModel; import org.zkoss.zul.TreeModel;
import org.zkoss.zul.TreeNode;
import org.zkoss.zul.Treechildren; import org.zkoss.zul.Treechildren;
import org.zkoss.zul.Treeitem; import org.zkoss.zul.Treeitem;
import org.zkoss.zul.ext.TreeOpenableModel;
/** /**
* *
@ -137,4 +143,74 @@ public class TreeUtils {
} }
return false; return false;
} }
/**
* travel all node of tree, at selected node, call callback function
* @param tree
* @param nodeModel
* @param isRootNode
* @param processNode
*/
static public void collapseTree (Component treeObject, boolean isOpen){
if (treeObject instanceof Tree) {
Tree tree = (Tree)treeObject;
if (tree.getModel() != null && tree.getModel() instanceof TreeOpenableModel){
collapseTreeModel ((TreeOpenableModel)tree.getModel(), isOpen, null);
return;
}
}
if (treeObject instanceof Treeitem) {// Tree also is Treeitem
Treeitem treeitem = (Treeitem) treeObject;
treeitem.setOpen(isOpen);
}
Collection<?> com = treeObject.getChildren();
if (com != null) {
for (Iterator<?> iterator = com.iterator(); iterator.hasNext();) {
collapseTree((Component) iterator.next(), isOpen);
}
}
}
static protected <T> void collapseTreeModel (TreeOpenableModel treeModelOpenable, boolean isOpen, T treeNode){
if (!isOpen){
treeModelOpenable.clearOpen();
return;//done, easy to close all node
}else{
if (!(treeModelOpenable instanceof TreeModel<?>)){
return;//model have to be a instance of TreeModel. because it provide method to add open object
}
if (treeNode != null && !(treeNode instanceof TreeNode<?>)){
return; //don't support, at least it's TreeNode to travel child node
}
@SuppressWarnings("unchecked")
TreeModel<T> treeModel = (TreeModel<T>)treeModelOpenable;
if (treeNode == null){// get from model
Object rootNode = treeModel.getRoot();
if (!(rootNode instanceof TreeNode<?>)){
return;//don't support, at least it's TreeNode to travel child node
}
@SuppressWarnings("unchecked")
TreeNode<T> node = (TreeNode<T>)rootNode;
collapseTreeModel (treeModelOpenable, isOpen, node);
}else{//child node
TreeNode<?> node = (TreeNode<?>)treeNode;
treeModelOpenable.addOpenPath(treeModel.getPath(treeNode));
if (node.getChildren() != null) {
for (TreeNode<?> childNode : node.getChildren()){
collapseTreeModel (treeModelOpenable, isOpen, childNode);
}
}
}
}
}
} }