Skip to content

Commit

Permalink
DAC-75 Create a search filter when assigning user access permissions
Browse files Browse the repository at this point in the history
  • Loading branch information
Bryan Holladay committed Apr 16, 2015
1 parent 852965b commit e6060d2
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 103 deletions.
1 change: 1 addition & 0 deletions delegatedaccess/tool/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/bin/
Original file line number Diff line number Diff line change
Expand Up @@ -197,4 +197,5 @@ roleRequired=Role is required.
filterBy=Filter By
hierarchyLevel=Hierarchy Level
filter=Filter
clear=Clear
clear=Clear
modificationsPending=There are unsaved modifications that will be removed, please save or continue with action.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
package org.sakaiproject.delegatedaccess.tool.pages;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.swing.tree.DefaultMutableTreeNode;
Expand Down Expand Up @@ -103,6 +105,21 @@ private void updateNodeAccessHelper(DefaultMutableTreeNode node, String userId,
}
}
}

public boolean anyNodesModified(DefaultMutableTreeNode node){
boolean modified = false;
if(((NodeModel) node.getUserObject()).isModified()){
return true;
}else{
for(int i = 0; i < node.getChildCount(); i++){
modified = modified || anyNodesModified((DefaultMutableTreeNode)node.getChildAt(i));
if(modified){
break;
}
}
return modified;
}
}

/**
* This collapses all empty folders in the tree. This helps the user know that they need to click on the folder
Expand Down Expand Up @@ -207,61 +224,33 @@ public void onClick(AjaxRequestTarget arg0) {

}

public void expandTreeToDepth(DefaultMutableTreeNode node, int depth, String userId, List<ListOptionSerialized> blankRestrictedTools, List<String> accessAdminNodeIds, boolean onlyAccessNodes, boolean shopping, boolean shoppingPeriodTool){
public void expandTreeToDepth(DefaultMutableTreeNode node, int depth, String userId, List<ListOptionSerialized> blankRestrictedTools, List<String> accessAdminNodeIds, boolean onlyAccessNodes, boolean shopping, boolean shoppingPeriodTool, String filterSearch){
projectLogic.addChildrenNodes(node, userId, blankRestrictedTools, onlyAccessNodes, accessAdminNodeIds, shopping, shoppingPeriodTool);
//set expand flag to true so to not look for children again:
((NodeModel) node.getUserObject()).setAddedDirectChildrenFlag(true);
getTree().getTreeState().expandNode(node);
if(depth > 0){
//recursive function stopper:
int newDepth = depth - 1;
for(int i = 0; i < node.getChildCount(); i++){
expandTreeToDepth((DefaultMutableTreeNode) node.getChildAt(i), newDepth, userId, blankRestrictedTools, accessAdminNodeIds, onlyAccessNodes, shopping, shoppingPeriodTool);
//count down backwards since we could be deleting these children nodes
for(int i = node.getChildCount() - 1; i >= 0; i--){
expandTreeToDepth((DefaultMutableTreeNode) node.getChildAt(i), newDepth, userId, blankRestrictedTools, accessAdminNodeIds, onlyAccessNodes, shopping, shoppingPeriodTool, filterSearch);
}
}else{
//make sure all children are collapsed:
for(int i = 0; i < node.getChildCount(); i++){
//make sure all children are collapsed and filter out the ones that need to be filtered
//count down backwards since we could be deleting these children nodes
for(int i = node.getChildCount() - 1; i >= 0; i--){
getTree().getTreeState().collapseNode(node.getChildAt(i));
}
}
}

public void populateTreeItemFilter(WebMarkupContainer arg0, String filterHierarchyLevel, String filterSearch){
if(arg0.getDefaultModelObject() instanceof DelegatedAccessMutableTreeNode){
DelegatedAccessMutableTreeNode treeNode = (DelegatedAccessMutableTreeNode) arg0.getDefaultModelObject();
Component treeComponent = getTree().getNodeComponent(treeNode);
if(treeComponent != null){
//check filters:
//make sure filter visibility is set properly:
if(filterHierarchyLevel != null && !"".equals(filterHierarchyLevel.trim())){
try{
Integer filterLevel = Integer.parseInt(filterHierarchyLevel) + 1;
//find this components level:
int depth = 0;
TreeNode parent = treeNode.getParent();
while(parent != null){
parent = parent.getParent();
depth++;
}

if(filterLevel != null && filterLevel.equals(depth)){
//this is the filter level, so check visibility
String nodeTitle = ((NodeModel) treeNode.getUserObject()).getNode().description.toLowerCase();
if(filterSearch != null && !"".equals(filterSearch.trim())){
if(!nodeTitle.contains(filterSearch.toLowerCase())){
//hide this component:
treeComponent.add(new AttributeModifier("style", true, Model.of("display: none;")));
}else{
//matched
treeComponent.add(new AttributeAppender("class", true, Model.of("filterMatch"), " "));
}
}
}
}catch(NumberFormatException e){
//number format exception, ignore
}catch(Exception e){
log.error(e.getMessage(), e);
}
String nodeTitle = ((NodeModel) ((DefaultMutableTreeNode) node.getChildAt(i)).getUserObject()).getNode().description.toLowerCase();
if(filterSearch != null && !"".equals(filterSearch.trim()) && !nodeTitle.contains(filterSearch.toLowerCase())){
//delete this child:
node.remove(i);
}
}
}
//check if all of the children have been removed (but don't delete root node)
if(node.getParent() != null && node.getChildCount() == 0){
((DefaultMutableTreeNode) node.getParent()).remove(node);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public class ShoppingEditPage extends BaseTreePage{
private SelectOption filterHierarchy;
private String filterSearch = "";
private List<ListOptionSerialized> blankRestrictedTools;
private boolean filterChanged = false;
private boolean modifiedAlert = false;

@Override
protected AbstractTree getTree() {
Expand Down Expand Up @@ -144,35 +144,66 @@ public void onClick() {

@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> arg1) {
filterChanged = true;
//now go through the tree and make sure its been loaded at every level:
DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode) getTree().getModelObject().getRoot();
Integer depth = null;
if(filterHierarchy != null && filterHierarchy.getValue() != null && !"".equals(filterHierarchy.getValue().trim())){
try{
depth = Integer.parseInt(filterHierarchy.getValue());
}catch(Exception e){
//number format exception, ignore
//check that no nodes have been modified
if(!modifiedAlert && anyNodesModified(rootNode)){
formFeedback.setDefaultModel(new ResourceModel("modificationsPending"));
formFeedback.add(new AttributeModifier("class", true, new Model("alertMessage")));
target.addComponent(formFeedback);
formFeedback2.setDefaultModel(new ResourceModel("modificationsPending"));
formFeedback2.add(new AttributeModifier("class", true, new Model("alertMessage")));
target.addComponent(formFeedback2);
modifiedAlert = true;
//call a js function to hide the message in 5 seconds
target.appendJavascript("hideFeedbackTimer('" + formFeedbackId + "');");
target.appendJavascript("hideFeedbackTimer('" + formFeedback2Id + "');");
}else{
//now go through the tree and make sure its been loaded at every level:
Integer depth = null;
if(filterHierarchy != null && filterHierarchy.getValue() != null && !"".equals(filterHierarchy.getValue().trim())){
try{
depth = Integer.parseInt(filterHierarchy.getValue());
}catch(Exception e){
//number format exception, ignore
}
}
if(depth != null && filterSearch != null && !"".equals(filterSearch.trim())){
expandTreeToDepth(rootNode, depth, DelegatedAccessConstants.SHOPPING_PERIOD_USER, blankRestrictedTools, null, false, true, false, filterSearch);
getTree().updateTree(target);
}
modifiedAlert = false;
}
if(depth != null){
expandTreeToDepth(rootNode, depth, DelegatedAccessConstants.SHOPPING_PERIOD_USER, blankRestrictedTools, null, false, true, false);
getTree().updateTree(target);
}
}
});
filterForm.add(new AjaxButton("filterClearButton", new StringResourceModel("clear", null)){

@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> arg1) {
filterChanged = true;
filterSearch = "";
filterHierarchy = null;
target.addComponent(filterSearchTextField);
target.addComponent(filterHierarchyDropDown);
DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode) getTree().getModelObject().getRoot();
//check that no nodes have been modified
if(!modifiedAlert && anyNodesModified(rootNode)){
formFeedback.setDefaultModel(new ResourceModel("modificationsPending"));
formFeedback.add(new AttributeModifier("class", true, new Model("alertMessage")));
target.addComponent(formFeedback);
formFeedback2.setDefaultModel(new ResourceModel("modificationsPending"));
formFeedback2.add(new AttributeModifier("class", true, new Model("alertMessage")));
target.addComponent(formFeedback2);
modifiedAlert = true;
//call a js function to hide the message in 5 seconds
target.appendJavascript("hideFeedbackTimer('" + formFeedbackId + "');");
target.appendJavascript("hideFeedbackTimer('" + formFeedback2Id + "');");
}else{
filterSearch = "";
filterHierarchy = null;
target.addComponent(filterSearchTextField);
target.addComponent(filterHierarchyDropDown);

getTree().getTreeState().collapseAll();
getTree().updateTree(target);
((NodeModel) rootNode.getUserObject()).setAddedDirectChildrenFlag(false);
rootNode.removeAllChildren();
getTree().getTreeState().collapseAll();
getTree().updateTree(target);
modifiedAlert = false;
}
}
});

Expand Down Expand Up @@ -281,14 +312,6 @@ protected MarkupContainer newNodeLink(MarkupContainer parent, String id, TreeNod
}
return super.newNodeLink(parent, id, node);
}

@Override
protected void populateTreeItem(WebMarkupContainer arg0, int arg1) {
super.populateTreeItem(arg0, arg1);
if(filterHierarchy != null){
populateTreeItemFilter(arg0, filterHierarchy.getValue(), filterSearch);
}
}
};
if(singleRoleOptions){
tree.add(new AttributeAppender("class", new Model("noRoles"), " "));
Expand Down Expand Up @@ -323,6 +346,7 @@ protected void onSubmit(AjaxRequestTarget target, Form arg1) {
//call a js function to hide the message in 5 seconds
target.appendJavascript("hideFeedbackTimer('" + formFeedbackId + "');");
target.appendJavascript("hideFeedbackTimer('" + formFeedback2Id + "');");
modifiedAlert = false;
}
@Override
public boolean isVisible() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public class UserEditPage extends BaseTreePage{
private SelectOption filterHierarchy;
private String filterSearch = "";
private List<ListOptionSerialized> blankRestrictedTools;
private boolean filterChanged = false;
private boolean modifiedAlert = false;

@Override
protected AbstractTree getTree() {
Expand Down Expand Up @@ -137,35 +137,66 @@ public UserEditPage(final String userId, final String displayName){

@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> arg1) {
filterChanged = true;
//now go through the tree and make sure its been loaded at every level:
DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode) getTree().getModelObject().getRoot();
Integer depth = null;
if(filterHierarchy != null && filterHierarchy.getValue() != null && !"".equals(filterHierarchy.getValue().trim())){
try{
depth = Integer.parseInt(filterHierarchy.getValue());
}catch(Exception e){
//number format exception, ignore
//check that no nodes have been modified
if(!modifiedAlert && anyNodesModified(rootNode)){
formFeedback.setDefaultModel(new ResourceModel("modificationsPending"));
formFeedback.add(new AttributeModifier("class", true, new Model("alertMessage")));
target.addComponent(formFeedback);
formFeedback2.setDefaultModel(new ResourceModel("modificationsPending"));
formFeedback2.add(new AttributeModifier("class", true, new Model("alertMessage")));
target.addComponent(formFeedback2);
modifiedAlert = true;
//call a js function to hide the message in 5 seconds
target.appendJavascript("hideFeedbackTimer('" + formFeedbackId + "');");
target.appendJavascript("hideFeedbackTimer('" + formFeedback2Id + "');");
}else{
//now go through the tree and make sure its been loaded at every level:
Integer depth = null;
if(filterHierarchy != null && filterHierarchy.getValue() != null && !"".equals(filterHierarchy.getValue().trim())){
try{
depth = Integer.parseInt(filterHierarchy.getValue());
}catch(Exception e){
//number format exception, ignore
}
}
if(depth != null && filterSearch != null && !"".equals(filterSearch.trim())){
expandTreeToDepth(rootNode, depth, userId, blankRestrictedTools, accessAdminNodeIds, false, false, false, filterSearch);
getTree().updateTree(target);
}
modifiedAlert = false;
}
if(depth != null){
expandTreeToDepth(rootNode, depth, userId, blankRestrictedTools, accessAdminNodeIds, false, false, false);
getTree().updateTree(target);
}
}
});
filterForm.add(new AjaxButton("filterClearButton", new StringResourceModel("clear", null)){

@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> arg1) {
filterChanged = true;
filterSearch = "";
filterHierarchy = null;
target.addComponent(filterSearchTextField);
target.addComponent(filterHierarchyDropDown);
DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode) getTree().getModelObject().getRoot();
//check that no nodes have been modified
if(!modifiedAlert && anyNodesModified(rootNode)){
formFeedback.setDefaultModel(new ResourceModel("modificationsPending"));
formFeedback.add(new AttributeModifier("class", true, new Model("alertMessage")));
target.addComponent(formFeedback);
formFeedback2.setDefaultModel(new ResourceModel("modificationsPending"));
formFeedback2.add(new AttributeModifier("class", true, new Model("alertMessage")));
target.addComponent(formFeedback2);
modifiedAlert = true;
//call a js function to hide the message in 5 seconds
target.appendJavascript("hideFeedbackTimer('" + formFeedbackId + "');");
target.appendJavascript("hideFeedbackTimer('" + formFeedback2Id + "');");
}else{
filterSearch = "";
filterHierarchy = null;
target.addComponent(filterSearchTextField);
target.addComponent(filterHierarchyDropDown);

getTree().getTreeState().collapseAll();
getTree().updateTree(target);
((NodeModel) rootNode.getUserObject()).setAddedDirectChildrenFlag(false);
rootNode.removeAllChildren();
getTree().getTreeState().collapseAll();
getTree().updateTree(target);
modifiedAlert = false;
}
}
});

Expand Down Expand Up @@ -269,15 +300,7 @@ protected void onJunctionLinkClicked(AjaxRequestTarget target, TreeNode node) {
@Override
protected boolean isForceRebuildOnSelectionChange() {
return true;
};

@Override
protected void populateTreeItem(WebMarkupContainer arg0, int arg1) {
super.populateTreeItem(arg0, arg1);
if(filterHierarchy != null){
populateTreeItemFilter(arg0, filterHierarchy.getValue(), filterSearch);
}
}
};

@Override
protected MarkupContainer newNodeLink(MarkupContainer parent, String id, TreeNode node) {
Expand Down Expand Up @@ -321,6 +344,7 @@ protected void onSubmit(AjaxRequestTarget target, Form arg1) {
//call a js function to hide the message in 5 seconds
target.appendJavascript("hideFeedbackTimer('" + formFeedbackId + "');");
target.appendJavascript("hideFeedbackTimer('" + formFeedback2Id + "');");
modifiedAlert = false;
}
};
form.add(updateButton);
Expand Down

0 comments on commit e6060d2

Please sign in to comment.