Coverage Report - org.kuali.student.common.ui.client.widgets.rules.RulePreviewWidget
 
Classes in this File Line Coverage Branch Coverage Complexity
RulePreviewWidget
0%
0/122
0%
0/42
1.913
RulePreviewWidget$1
0%
0/6
N/A
1.913
RulePreviewWidget$2
0%
0/5
N/A
1.913
RulePreviewWidget$2$1
0%
0/5
N/A
1.913
RulePreviewWidget$SubRuleInfo
0%
0/7
N/A
1.913
 
 1  
 package org.kuali.student.common.ui.client.widgets.rules;
 2  
 
 3  
 import java.util.ArrayList;
 4  
 import java.util.List;
 5  
 import java.util.Map;
 6  
 
 7  
 import org.kuali.student.common.ui.client.configurable.mvc.SectionTitle;
 8  
 import org.kuali.student.common.ui.client.mvc.Callback;
 9  
 import org.kuali.student.common.ui.client.widgets.KSButton;
 10  
 import org.kuali.student.common.ui.client.widgets.KSButtonAbstract;
 11  
 import org.kuali.student.common.ui.client.widgets.KSLabel;
 12  
 import org.kuali.student.common.ui.client.widgets.dialog.ConfirmationDialog;
 13  
 import org.kuali.student.common.ui.client.widgets.field.layout.element.SpanPanel;
 14  
 import org.kuali.student.core.statement.dto.StatementOperatorTypeKey;
 15  
 import org.kuali.student.core.statement.dto.StatementTreeViewInfo;
 16  
 
 17  
 import com.google.gwt.event.dom.client.ClickEvent;
 18  
 import com.google.gwt.event.dom.client.ClickHandler;
 19  
 import com.google.gwt.user.client.ui.FlowPanel;
 20  
 import com.google.gwt.user.client.ui.Widget;
 21  
 
 22  0
 public class RulePreviewWidget extends FlowPanel {
 23  
 
 24  
     //Widgets
 25  0
     private SpanPanel rulePanel = new SpanPanel();
 26  0
     private KSButton editButton = new KSButton("Edit", KSButtonAbstract.ButtonStyle.DEFAULT_ANCHOR);
 27  0
     private SpanPanel separator = new SpanPanel(" | ");
 28  0
     private KSButton deleteButton = new KSButton("Delete", KSButtonAbstract.ButtonStyle.DEFAULT_ANCHOR);
 29  0
     private KSButton addSubRuleBtn = new KSButton("Add a Rule", KSButtonAbstract.ButtonStyle.FORM_SMALL);
 30  0
     private List<SubrulePreviewWidget> subRulePreviewWidgets = new ArrayList<SubrulePreviewWidget>();
 31  
     private Map<String, Widget> clusetWidgets;
 32  0
     private SectionTitle progReqHeader = SectionTitle.generateH4Title("");
 33  0
     private KSLabel ruleDescLabel = new KSLabel();
 34  0
     private SpanPanel actions = new SpanPanel();
 35  
 
 36  
     //data
 37  
     private StatementTreeViewInfo stmtTreeInfo;     //program rule e.g. program completion rule
 38  
     private boolean isReadOnly;
 39  0
     private boolean addRuleOperator = false;        //first subrule does not have operator following it
 40  
     private Integer internalProgReqID;
 41  
 
 42  
     private Callback<SubRuleInfo> editSubRuleCallback;
 43  
     private Callback<Integer> deleteSubRuleCallback;
 44  
 
 45  
     public RulePreviewWidget(Integer internalProgReqID, String ruleName, String ruleCreditsText, String ruleDesc, StatementTreeViewInfo stmtTreeInfo,
 46  
                              Boolean isReadOnly,  Map<String, Widget> clusetWidgets) {
 47  0
         super();
 48  0
         this.internalProgReqID = internalProgReqID;
 49  0
         this.stmtTreeInfo = stmtTreeInfo;
 50  0
         this.isReadOnly = isReadOnly;
 51  0
         this.clusetWidgets = clusetWidgets;
 52  
 
 53  
         //prepare widgets
 54  0
         this.addStyleName("KS-Rule-Preview-Box");
 55  0
         progReqHeader.setStyleName("KS-Rule-Preview-header");
 56  0
         ruleDescLabel.addStyleName("KS-Rule-Preview-Desc");
 57  0
         if (!isReadOnly) {
 58  0
             buildEditActionsWidget();
 59  
         }
 60  0
         updateProgInfoFields(ruleName, ruleCreditsText, ruleDesc);
 61  
 
 62  0
         displayRule();
 63  0
     }
 64  
 
 65  
     public void updateProgInfoFields(String ruleName, String ruleCreditsText, String ruleDesc) {
 66  0
         progReqHeader.clear();
 67  0
         progReqHeader.setHTML("<b>" + ruleName + "</b>" + "  " + ruleCreditsText);
 68  
         //do not show edit,delete etc. if user is only viewing the rule in non-edit mode
 69  0
         if (!isReadOnly) {
 70  0
             progReqHeader.add(actions);
 71  
         }
 72  0
         ruleDescLabel.setText(ruleDesc);
 73  0
     }
 74  
 
 75  
     private void displayRule() {
 76  
         //start with a header for the entire rule
 77  0
         buildRuleHeader();
 78  
 
 79  
         //show sub-rules if we have any
 80  0
         if (stmtTreeInfo == null) {
 81  0
             displayNoRule();
 82  
         }
 83  
 
 84  0
         if ((stmtTreeInfo.getStatements() == null) || (stmtTreeInfo.getStatements().isEmpty())) {
 85  0
             if ((stmtTreeInfo.getReqComponents() == null) || (stmtTreeInfo.getReqComponents().isEmpty())) {
 86  0
                 displayNoRule();
 87  
             } else {
 88  0
                 addSubRule(stmtTreeInfo);
 89  
             }
 90  
         } else {
 91  0
             for (final StatementTreeViewInfo subTree : stmtTreeInfo.getStatements()) {
 92  0
                 addSubRule(subTree);
 93  
             }
 94  
         }
 95  
 
 96  
         //button below has to be spaced
 97  0
         SpanPanel spacer = new SpanPanel();
 98  0
         spacer.addStyleName("KS-Rule-Last-Preview-Spacer");
 99  0
         rulePanel.add(spacer);
 100  
 
 101  
         //add a button for user to add additional subrule
 102  0
         if (!isReadOnly) {
 103  0
             addSubRuleBtn.addStyleName("KS-Rule-Preview-Add-Subrule");
 104  0
             rulePanel.add(addSubRuleBtn);
 105  
         }
 106  
 
 107  0
         this.add(rulePanel);
 108  0
     }
 109  
 
 110  
     private void displayNoRule() {
 111  0
         KSLabel noRulesAddedYet = new KSLabel("No rules have been added yet.");
 112  0
         noRulesAddedYet.addStyleName("KS-Rule-Preview-NoRule");
 113  0
         rulePanel.add(noRulesAddedYet);
 114  0
     }
 115  
 
 116  
     private void addSubRule(final StatementTreeViewInfo subTree) {
 117  
         //display AND/OR operator between subrules
 118  0
         if (addRuleOperator) {
 119  0
             buildANDOperator(stmtTreeInfo.getOperator());
 120  
         }
 121  
 
 122  0
         final SubrulePreviewWidget newSubRuleWidget = new SubrulePreviewWidget(subTree, isReadOnly, clusetWidgets);        
 123  0
         subRulePreviewWidgets.add(newSubRuleWidget);
 124  
 
 125  0
         newSubRuleWidget.addEditButtonClickHandler(new ClickHandler(){
 126  
             public void onClick(ClickEvent event) {
 127  0
                 SubRuleInfo subRuleInfo = new SubRuleInfo();
 128  0
                 subRuleInfo.setSubrule(subTree);
 129  0
                 subRuleInfo.setInternalProgReqID(internalProgReqID);
 130  0
                 editSubRuleCallback.exec(subRuleInfo);
 131  0
             }
 132  
         });
 133  
 
 134  0
         newSubRuleWidget.addDeleteButtonClickHandler(new ClickHandler(){
 135  
             public void onClick(ClickEvent event) {
 136  0
                 final ConfirmationDialog dialog = new ConfirmationDialog("Delete Rule", "Are you sure you want to delete this rule?"); //TODO app context for labels
 137  0
                 dialog.getConfirmButton().addClickHandler(new ClickHandler(){
 138  
                     @Override
 139  
                     public void onClick(ClickEvent event) {
 140  0
                         removeSubRule(newSubRuleWidget, subTree);
 141  0
                         dialog.hide();
 142  0
                         deleteSubRuleCallback.exec(internalProgReqID);
 143  0
                     }
 144  
                 });
 145  0
                 dialog.show();
 146  0
             }
 147  
         });
 148  
 
 149  0
         rulePanel.add(newSubRuleWidget);
 150  0
         addRuleOperator = true;
 151  0
     }
 152  
 
 153  
     //user selected to delete this particular requirement
 154  
     public void removeSubRule(SubrulePreviewWidget subRuleWidget, StatementTreeViewInfo subTree) {
 155  
         //update data
 156  0
         List<StatementTreeViewInfo> statements = stmtTreeInfo.getStatements();
 157  0
         statements.remove(subTree);
 158  0
         subRulePreviewWidgets.remove(subRuleWidget);
 159  
 
 160  
         //update display
 161  0
         rulePanel.remove(subRuleWidget);
 162  
 
 163  
         //remove unnecessary operators
 164  0
         int numberOfOperators = 0;
 165  0
         boolean lastWidgetIsSubRule = true;
 166  0
         boolean foundSubRule = false;
 167  0
         int counter = 0;
 168  0
         Widget widget = null;
 169  0
         Widget widgetToRemove = null;
 170  0
         Widget lastOperatorWidget = null;
 171  0
         for (Object aRulePanel : rulePanel) {
 172  0
             counter++;
 173  0
             widget = (Widget) aRulePanel;
 174  0
             if (widget instanceof KSLabel) {
 175  0
                 if (((KSLabel) widget).getText().equals("AND") || ((KSLabel) widget).getText().equals("OR")) {
 176  0
                     lastWidgetIsSubRule = false;
 177  0
                     lastOperatorWidget = widget;
 178  0
                     numberOfOperators++;
 179  
                     //remove 'AND' above the first sub-rule or two repeated instances
 180  0
                     if ((numberOfOperators > 1) || (counter == 1) || !foundSubRule) {
 181  0
                         widgetToRemove = widget;
 182  0
                         numberOfOperators--;
 183  
                     }
 184  
                 }
 185  0
             } else if (widget instanceof SubrulePreviewWidget) {
 186  0
                 foundSubRule = true;
 187  0
                 lastWidgetIsSubRule = true;
 188  0
                 numberOfOperators = 0;
 189  
             }
 190  
         }
 191  
         
 192  0
         if (!lastWidgetIsSubRule) {
 193  0
             rulePanel.remove(lastOperatorWidget);
 194  
         }
 195  0
         if (widgetToRemove != null) {
 196  0
             rulePanel.remove(widgetToRemove);
 197  
         }
 198  0
     }
 199  
 
 200  
     private void buildRuleHeader() {
 201  0
         rulePanel.clear();
 202  0
         rulePanel.addStyleName("KS-Rule-Preview-Box1");
 203  0
         rulePanel.add(progReqHeader);
 204  0
         rulePanel.add(ruleDescLabel);
 205  
 
 206  
         //build subheading
 207  0
         SectionTitle header = SectionTitle.generateH6Title("");
 208  0
         header.setHTML("Must meet <b>all of the following</b> rules");
 209  0
         header.setStyleName("KS-Rule-Preview-header-Subrule");
 210  0
         header.getElement().setAttribute("style", "font-weight: normal");        
 211  0
         rulePanel.add(header);
 212  0
     }
 213  
 
 214  
     private void buildEditActionsWidget() {       
 215  0
         actions.add(editButton);
 216  0
         actions.add(separator);
 217  0
         actions.add(deleteButton);
 218  0
         actions.addStyleName("KS-Rule-Preview-header-action");
 219  0
     }
 220  
 
 221  
     private void buildANDOperator(StatementOperatorTypeKey operator) {
 222  0
         KSLabel andLabel = new KSLabel((operator == StatementOperatorTypeKey.AND ? "AND" : "OR"));
 223  0
         andLabel.addStyleName("KS-Rule-Preview-Operator");
 224  0
         rulePanel.add(andLabel);        
 225  0
     }
 226  
 
 227  
     public void addProgReqEditButtonClickHandler(ClickHandler handler) {
 228  0
         editButton.addClickHandler(handler);
 229  0
     }
 230  
 
 231  
     public void addProgReqDeleteButtonClickHandler(ClickHandler handler) {
 232  0
         deleteButton.addClickHandler(handler);
 233  0
     }
 234  
 
 235  
     public void addSubRuleAddButtonClickHandler(ClickHandler handler) {
 236  0
         addSubRuleBtn.addClickHandler(handler);
 237  0
     }
 238  
 
 239  
     public void addSubRuleEditButtonClickHandler(Callback<SubRuleInfo> callback) {
 240  0
         this.editSubRuleCallback = callback;
 241  0
     }
 242  
 
 243  
     public void addSubRuleDeleteCallback(Callback<Integer> callback) {
 244  0
         this.deleteSubRuleCallback = callback;
 245  0
     }
 246  
 
 247  
     public StatementTreeViewInfo getStatementTreeViewInfo() {
 248  0
         return  stmtTreeInfo;
 249  
     }
 250  
 
 251  
     public Integer getInternalProgReqID() {
 252  0
         return internalProgReqID;
 253  
     }
 254  
 
 255  0
     public class SubRuleInfo {
 256  
         private StatementTreeViewInfo subrule;
 257  
 
 258  
         private Integer internalProgReqID;
 259  
 
 260  
         public StatementTreeViewInfo getSubrule() {
 261  0
             return subrule;
 262  
         }
 263  
 
 264  
         public void setSubrule(StatementTreeViewInfo subrule) {
 265  0
             this.subrule = subrule;
 266  0
         }
 267  
 
 268  
         public Integer getInternalProgReqID() {
 269  0
             return internalProgReqID;
 270  
         }
 271  
 
 272  
         public void setInternalProgReqID(Integer internalProgReqID) {
 273  0
             this.internalProgReqID = internalProgReqID;
 274  0
         }
 275  
     }
 276  
 }