| 1 |  |   | 
  | 2 |  |   | 
  | 3 |  |   | 
  | 4 |  |   | 
  | 5 |  |   | 
  | 6 |  |   | 
  | 7 |  |   | 
  | 8 |  |   | 
  | 9 |  |   | 
  | 10 |  |   | 
  | 11 |  |   | 
  | 12 |  |   | 
  | 13 |  |   | 
  | 14 |  |   | 
  | 15 |  |   | 
  | 16 |  |  package org.kuali.student.lum.lu.ui.tools.client.configuration; | 
  | 17 |  |   | 
  | 18 |  |  import java.util.ArrayList; | 
  | 19 |  |  import java.util.HashMap; | 
  | 20 |  |  import java.util.List; | 
  | 21 |  |  import java.util.Map; | 
  | 22 |  |   | 
  | 23 |  |  import org.kuali.student.common.ui.client.application.Application; | 
  | 24 |  |  import org.kuali.student.common.ui.client.configurable.mvc.FieldDescriptor; | 
  | 25 |  |  import org.kuali.student.common.ui.client.configurable.mvc.LayoutController; | 
  | 26 |  |  import org.kuali.student.common.ui.client.configurable.mvc.SectionTitle; | 
  | 27 |  |  import org.kuali.student.common.ui.client.configurable.mvc.multiplicity.DisplayMultiplicityComposite; | 
  | 28 |  |  import org.kuali.student.common.ui.client.configurable.mvc.sections.GroupSection; | 
  | 29 |  |  import org.kuali.student.common.ui.client.configurable.mvc.sections.Section; | 
  | 30 |  |  import org.kuali.student.common.ui.client.configurable.mvc.sections.SwapSection; | 
  | 31 |  |  import org.kuali.student.common.ui.client.configurable.mvc.sections.VerticalSection; | 
  | 32 |  |  import org.kuali.student.common.ui.client.configurable.mvc.views.SectionView; | 
  | 33 |  |  import org.kuali.student.common.ui.client.configurable.mvc.views.VerticalSectionView; | 
  | 34 |  |  import org.kuali.student.common.ui.client.mvc.Callback; | 
  | 35 |  |  import org.kuali.student.common.ui.client.mvc.DataModel; | 
  | 36 |  |  import org.kuali.student.common.ui.client.mvc.DataModelDefinition; | 
  | 37 |  |  import org.kuali.student.common.ui.client.mvc.ModelRequestCallback; | 
  | 38 |  |  import org.kuali.student.common.ui.client.widgets.KSDatePicker; | 
  | 39 |  |  import org.kuali.student.common.ui.client.widgets.KSItemLabel; | 
  | 40 |  |  import org.kuali.student.common.ui.client.widgets.KSLabel; | 
  | 41 |  |  import org.kuali.student.common.ui.client.widgets.KSTextArea; | 
  | 42 |  |  import org.kuali.student.common.ui.client.widgets.dialog.ConfirmationDialog; | 
  | 43 |  |  import org.kuali.student.common.ui.client.widgets.field.layout.element.MessageKeyInfo; | 
  | 44 |  |  import org.kuali.student.common.ui.client.widgets.list.KSCheckBoxList; | 
  | 45 |  |  import org.kuali.student.common.ui.client.widgets.list.impl.SimpleListItems; | 
  | 46 |  |  import org.kuali.student.common.ui.client.widgets.search.KSPicker; | 
  | 47 |  |  import org.kuali.student.common.ui.client.widgets.search.SelectedResults; | 
  | 48 |  |  import org.kuali.student.core.assembly.data.Data; | 
  | 49 |  |  import org.kuali.student.core.assembly.data.LookupMetadata; | 
  | 50 |  |  import org.kuali.student.core.assembly.data.Metadata; | 
  | 51 |  |  import org.kuali.student.core.assembly.data.QueryPath; | 
  | 52 |  |  import org.kuali.student.core.assembly.data.Data.DataValue; | 
  | 53 |  |  import org.kuali.student.core.search.dto.SearchRequest; | 
  | 54 |  |  import org.kuali.student.lum.common.client.lu.LUUIConstants; | 
  | 55 |  |  import org.kuali.student.lum.common.client.widgets.CluSetRangeDataHelper; | 
  | 56 |  |  import org.kuali.student.lum.common.client.widgets.CluSetRangeModelUtil; | 
  | 57 |  |  import org.kuali.student.lum.lu.assembly.data.client.constants.orch.CreditCourseConstants; | 
  | 58 |  |  import org.kuali.student.lum.lu.dto.MembershipQueryInfo; | 
  | 59 |  |   | 
  | 60 |  |  import com.google.gwt.core.client.GWT; | 
  | 61 |  |  import com.google.gwt.user.client.ui.Widget; | 
  | 62 |  |   | 
  | 63 | 0 |  public class CluSetsConfigurer { | 
  | 64 |  |   | 
  | 65 | 0 |      private boolean WITH_DIVIDER = true; | 
  | 66 |  |   | 
  | 67 |  |      public static final String CREATE_CLUSET_MGT_MODEL = "createCluSetManagementModel"; | 
  | 68 |  |      public static final String EDIT_CLUSET_MGT_MODEL = "editCluSetManagementModel"; | 
  | 69 |  |      public static final String VIEW_CLUSET_MGT_MODEL = "viewCluSetManagerModel"; | 
  | 70 |  |      public static final String EDIT_SEARCH_CLUSET_MGT_MODEL = "editSearchCluSetManagementModel"; | 
  | 71 |  |      public static final String VIEW_SEARCH_CLUSET_MGT_MODEL = "viewSearchCluSetManagementModel"; | 
  | 72 | 0 |      private String editSearchCluSetId = null; | 
  | 73 | 0 |      private String viewSearchCluSetId = null; | 
  | 74 | 0 |      private Map<String, CluSetEditOptionList> cluSetEditOptionsMap = | 
  | 75 |  |          new HashMap<String, CluSetEditOptionList>(); | 
  | 76 |  |   | 
  | 77 |  |   | 
  | 78 |  |      private DataModelDefinition modelDefinition; | 
  | 79 |  |   | 
  | 80 | 0 |      public enum CluSetSections{ | 
  | 81 | 0 |          CREATE_CLU_SET, EDIT_CLU_SET, VIEW_CLU_SET | 
  | 82 |  |      } | 
  | 83 |  |   | 
  | 84 |  |      public void setModelDefinition(DataModelDefinition modelDefinition){ | 
  | 85 | 0 |              this.modelDefinition = modelDefinition; | 
  | 86 | 0 |      } | 
  | 87 |  |   | 
  | 88 |  |   | 
  | 89 |  |   | 
  | 90 |  |   | 
  | 91 |  |   | 
  | 92 |  |   | 
  | 93 |  |   | 
  | 94 |  |   | 
  | 95 |  |   | 
  | 96 |  |   | 
  | 97 |  |   | 
  | 98 |  |   | 
  | 99 |  |   | 
  | 100 |  |   | 
  | 101 |  |   | 
  | 102 |  |   | 
  | 103 |  |   | 
  | 104 |  |   | 
  | 105 |  |   | 
  | 106 |  |   | 
  | 107 |  |      private void addClusetDetailsSections(SectionView parentView, final String modelId) { | 
  | 108 | 0 |          VerticalSection defineCluSet = initSection(getH3Title(ToolsConstants.NEW_CLU_SET_INFO), WITH_DIVIDER); | 
  | 109 | 0 |          CluSetEditOptionList cluSetEditOptions = new CluSetEditOptionList(); | 
  | 110 | 0 |          cluSetEditOptionsMap.put(modelId, cluSetEditOptions); | 
  | 111 | 0 |          SwapSection clusetDetails = new SwapSection( | 
  | 112 |  |                  cluSetEditOptions, | 
  | 113 |  |                  new ConfirmationDialog("Delete Clu Set Details", | 
  | 114 |  |                          "You are about to delete clu set details.  Continue?") | 
  | 115 |  |                  ); | 
  | 116 |  |           | 
  | 117 | 0 |          ModelIdPlaceHolder modelIdObj = new ModelIdPlaceHolder(modelId); | 
  | 118 |  |   | 
  | 119 |  |           | 
  | 120 | 0 |          Section approvedClusSection = new VerticalSection(); | 
  | 121 | 0 |          addField(approvedClusSection, ToolsConstants.CLU_SET_APPROVED_CLUS_FIELD, generateMessageInfo(ToolsConstants.NEW_CLU_SET_CONTENT_APPROVED_COURSE)).setModelId(modelId); | 
  | 122 | 0 |          clusetDetails.addSection(approvedClusSection, ToolsConstants.CLU_SET_SWAP_APPROVED_CLUS); | 
  | 123 |  |           | 
  | 124 |  |   | 
  | 125 |  |           | 
  | 126 | 0 |          Section proposedClusSection = new VerticalSection(); | 
  | 127 | 0 |          addField(proposedClusSection, ToolsConstants.CLU_SET_PROPOSED_CLUS_FIELD, generateMessageInfo(ToolsConstants.NEW_CLU_SET_CONTENT_PROPOSED_COURSE)).setModelId(modelId); | 
  | 128 | 0 |          clusetDetails.addSection(proposedClusSection, ToolsConstants.CLU_SET_SWAP_PROPOSED_CLUS); | 
  | 129 |  |           | 
  | 130 |  |   | 
  | 131 |  |           | 
  | 132 |  |           | 
  | 133 | 0 |          Section cluRangeSection = new VerticalSection(); | 
  | 134 | 0 |          final Picker cluSetRangePicker = configureSearch(ToolsConstants.CLU_SET_CLU_SET_RANGE_EDIT_FIELD); | 
  | 135 | 0 |          final FieldDescriptor cluRangeFieldEditDescriptor = addField(cluRangeSection, ToolsConstants.CLU_SET_CLU_SET_RANGE_EDIT_FIELD, generateMessageInfo(ToolsConstants.NEW_CLU_SET_CONTENT_RANGE), cluSetRangePicker); | 
  | 136 | 0 |          final CluSetRangeDataHelper clusetRangeModelHelper = new CluSetRangeDataHelper(); | 
  | 137 | 0 |          final KSItemLabel clusetRangeLabel = new KSItemLabel(true, clusetRangeModelHelper); | 
  | 138 | 0 |          clusetRangeLabel.getElement().getStyle().setProperty("border", "solid 1px #cdcdcd"); | 
  | 139 | 0 |          final FieldDescriptor cluRangeFieldDescriptor = addField(cluRangeSection, ToolsConstants.CLU_SET_CLU_SET_RANGE_FIELD, null, clusetRangeLabel); | 
  | 140 | 0 |          cluSetRangePicker.getSearchWindow().addActionCompleteCallback(new Callback<Boolean>() { | 
  | 141 |  |           | 
  | 142 |  |              @Override | 
  | 143 |  |              public void exec(Boolean result) { | 
  | 144 | 0 |                  cluSetRangePicker.getSearchWindow().hide(); | 
  | 145 | 0 |                  final LayoutController parent = LayoutController.findParentLayout(cluSetRangePicker); | 
  | 146 | 0 |                  if(parent != null){ | 
  | 147 | 0 |                      parent.requestModel(modelId, new ModelRequestCallback<DataModel>() { | 
  | 148 |  |                          @Override | 
  | 149 |  |                          public void onModelReady(DataModel model) { | 
  | 150 |  |   | 
  | 151 |  |   | 
  | 152 |  |   | 
  | 153 | 0 |                              SearchRequest searchRequest = cluSetRangePicker.getSearchWindow() | 
  | 154 |  |                                  .getSearchRequest(); | 
  | 155 | 0 |                              String selectedLookupName = cluSetRangePicker.getSearchWindow() | 
  | 156 |  |                                  .getSelectedLookupName(); | 
  | 157 | 0 |                              Data searchRequestData = CluSetRangeModelUtil.INSTANCE. | 
  | 158 |  |                                  toData(searchRequest, null); | 
  | 159 | 0 |                              DataValue dataValue = new DataValue(searchRequestData); | 
  | 160 | 0 |                              LookupMetadata lookupMetadata = null; | 
  | 161 |  |                               | 
  | 162 |  |                               | 
  | 163 | 0 |                              List<LookupMetadata> lookupMDs = new ArrayList<LookupMetadata>(); | 
  | 164 | 0 |                              lookupMDs.add(cluSetRangePicker.getInitLookupMetadata()); | 
  | 165 | 0 |                              lookupMetadata = findLookupMetadata(selectedLookupName,  | 
  | 166 |  |                                      lookupMDs); | 
  | 167 | 0 |                              if (lookupMetadata == null ||  | 
  | 168 |  |                                      !nullSafeEquals(lookupMetadata.getName(),  | 
  | 169 |  |                                              selectedLookupName)) { | 
  | 170 | 0 |                                  lookupMetadata = findLookupMetadata(selectedLookupName,  | 
  | 171 |  |                                          cluSetRangePicker.getAdditionalLookupMetadata()); | 
  | 172 |  |                              } | 
  | 173 |  |                               | 
  | 174 | 0 |                              clusetRangeModelHelper.setLookupMetadata(lookupMetadata); | 
  | 175 | 0 |                              clusetRangeLabel.setValue(dataValue); | 
  | 176 | 0 |                          } | 
  | 177 |  |   | 
  | 178 |  |                          @Override | 
  | 179 |  |                          public void onRequestFail(Throwable cause) { | 
  | 180 | 0 |                              GWT.log("Unable to retrieve model" + cluRangeFieldDescriptor.getFieldKey(), null); | 
  | 181 | 0 |                          } | 
  | 182 |  |                           | 
  | 183 |  |                      }); | 
  | 184 |  |                  } | 
  | 185 | 0 |              } | 
  | 186 |  |          }); | 
  | 187 | 0 |          clusetDetails.addSection(cluRangeSection, ToolsConstants.CLU_SET_SWAP_CLU_SET_RANGE); | 
  | 188 |  |           | 
  | 189 |  |           | 
  | 190 | 0 |          Section cluSetSection = new VerticalSection(); | 
  | 191 | 0 |          addField(cluSetSection, ToolsConstants.CLU_SET_CLU_SETS_FIELD, generateMessageInfo(ToolsConstants.NEW_CLU_SET_CONTENT_CLUSET)).setModelId(modelId); | 
  | 192 | 0 |          clusetDetails.addSection(cluSetSection, ToolsConstants.CLU_SET_SWAP_CLU_SETS); | 
  | 193 |  |           | 
  | 194 |  |           | 
  | 195 | 0 |          addField(modelIdObj, defineCluSet, ToolsConstants.CLU_SET_TYPE_FIELD); | 
  | 196 | 0 |          addField(modelIdObj, defineCluSet, ToolsConstants.CLU_SET_ORGANIZATION_FIELD, generateMessageInfo(ToolsConstants.ORGANIZATION)); | 
  | 197 | 0 |          addField(modelIdObj, defineCluSet, ToolsConstants.CLU_SET_NAME_FIELD, generateMessageInfo(ToolsConstants.TITLE)); | 
  | 198 | 0 |          addField(modelIdObj, defineCluSet, ToolsConstants.CLU_SET_DESCRIPTION_FIELD, generateMessageInfo(ToolsConstants.DESCRIPTION), new KSTextArea()); | 
  | 199 | 0 |          addField(modelIdObj, defineCluSet, ToolsConstants.CLU_SET_EFF_DATE_FIELD, generateMessageInfo(ToolsConstants.EFFECTIVE_DATE), new KSDatePicker()); | 
  | 200 | 0 |          addField(modelIdObj, defineCluSet, ToolsConstants.CLU_SET_EXP_DATE_FIELD, generateMessageInfo(ToolsConstants.EXPIRATION_DATE), new KSDatePicker()); | 
  | 201 |  |           | 
  | 202 | 0 |          parentView.addWidget(cluSetEditOptions); | 
  | 203 | 0 |          parentView.addSection(clusetDetails); | 
  | 204 | 0 |          parentView.addSection(defineCluSet); | 
  | 205 | 0 |      } | 
  | 206 |  |       | 
  | 207 |  |      private static boolean nullSafeEquals(Object obj1, Object obj2) { | 
  | 208 | 0 |          return (obj1 == null && obj2 == null || | 
  | 209 |  |                  obj1 != null && obj2 != null && obj1.equals(obj2)); | 
  | 210 |  |      } | 
  | 211 |  |       | 
  | 212 |  |      private static LookupMetadata findLookupMetadata(String selectedLookupName,  | 
  | 213 |  |              List<LookupMetadata> lookupMetadatas) { | 
  | 214 | 0 |          LookupMetadata result = null; | 
  | 215 | 0 |          if (lookupMetadatas != null) { | 
  | 216 | 0 |              for (LookupMetadata lookupMetadata : lookupMetadatas) { | 
  | 217 | 0 |                  if (nullSafeEquals(lookupMetadata.getName(), selectedLookupName)) { | 
  | 218 | 0 |                      result = lookupMetadata; | 
  | 219 |  |                  } | 
  | 220 |  |              } | 
  | 221 |  |          } | 
  | 222 | 0 |          return result; | 
  | 223 |  |      } | 
  | 224 |  |   | 
  | 225 |  |      private SectionView createCluSetSection() { | 
  | 226 |  |           | 
  | 227 | 0 |          VerticalSectionView section = initNestedSectionView(CluSetSections.CREATE_CLU_SET, ToolsConstants.NEW_CLU_SET, CREATE_CLUSET_MGT_MODEL); | 
  | 228 | 0 |          addClusetDetailsSections(section, CluSetsConfigurer.CREATE_CLUSET_MGT_MODEL); | 
  | 229 | 0 |          return section; | 
  | 230 |  |          } | 
  | 231 |  |   | 
  | 232 |  |      private boolean hasCluSetRange(Data cluSetRangeData) { | 
  | 233 | 0 |          boolean hasCluSetRange = false; | 
  | 234 | 0 |          MembershipQueryInfo membershipQueryInfo =  | 
  | 235 |  |              CluSetRangeModelUtil.INSTANCE.toMembershipQueryInfo(cluSetRangeData); | 
  | 236 | 0 |          if (membershipQueryInfo != null) { | 
  | 237 | 0 |              hasCluSetRange = true; | 
  | 238 |  |          } | 
  | 239 | 0 |          return hasCluSetRange; | 
  | 240 |  |      } | 
  | 241 |  |       | 
  | 242 |  |      private boolean hasClus(Data clusData) { | 
  | 243 | 0 |          boolean clusExist = false; | 
  | 244 | 0 |          if (clusData != null) { | 
  | 245 | 0 |              for (Data.Property p : clusData) { | 
  | 246 | 0 |                  if(!"_runtimeData".equals(p.getKey())){ | 
  | 247 | 0 |                      String cluId = p.getValue(); | 
  | 248 | 0 |                      if (cluId != null && !cluId.trim().isEmpty()) { | 
  | 249 | 0 |                          clusExist = true; | 
  | 250 | 0 |                          break; | 
  | 251 |  |                      } | 
  | 252 | 0 |                  } | 
  | 253 |  |              } | 
  | 254 |  |          } | 
  | 255 | 0 |          return clusExist; | 
  | 256 |  |      } | 
  | 257 |  |       | 
  | 258 |  |      private boolean hasCluSets(Data clusetData) { | 
  | 259 | 0 |          boolean cluSetsExist = false; | 
  | 260 | 0 |          if (clusetData != null) { | 
  | 261 | 0 |              for (Data.Property p : clusetData) { | 
  | 262 | 0 |                  if(!"_runtimeData".equals(p.getKey())){ | 
  | 263 | 0 |                      String cluSetId = p.getValue(); | 
  | 264 | 0 |                      if (cluSetId != null && !cluSetId.trim().isEmpty()) { | 
  | 265 | 0 |                          cluSetsExist = true; | 
  | 266 | 0 |                          break; | 
  | 267 |  |                      } | 
  | 268 | 0 |                  } | 
  | 269 |  |              } | 
  | 270 |  |          } | 
  | 271 | 0 |          return cluSetsExist; | 
  | 272 |  |      } | 
  | 273 |  |       | 
  | 274 |  |      private boolean hasData(String queryPath, Data queryData) { | 
  | 275 | 0 |          boolean hasData = false; | 
  | 276 | 0 |          if (queryPath != null && (queryPath.equals(ToolsConstants.CLU_SET_APPROVED_CLUS_FIELD) || | 
  | 277 |  |                  queryPath.equals(ToolsConstants.CLU_SET_PROPOSED_CLUS_FIELD))) { | 
  | 278 | 0 |              hasData = hasClus(queryData); | 
  | 279 | 0 |          } else if (queryPath != null && queryPath.equals(ToolsConstants.CLU_SET_CLU_SETS_FIELD)) { | 
  | 280 | 0 |              hasData = hasCluSets(queryData); | 
  | 281 | 0 |          } else if (queryPath != null && queryPath.equals(ToolsConstants.CLU_SET_CLU_SET_RANGE_FIELD)) { | 
  | 282 | 0 |              hasData = hasCluSetRange(queryData); | 
  | 283 |  |          } else { | 
  | 284 | 0 |              throw new IllegalArgumentException("Unexpected queryPath: " + queryPath); | 
  | 285 |  |          } | 
  | 286 | 0 |          return hasData; | 
  | 287 |  |      } | 
  | 288 |  |       | 
  | 289 |  |      private void selectCluSetOptionList(DataModel model, CluSetEditOptionList cluSetEditOptions) { | 
  | 290 | 0 |          selectCluSetOption(model, cluSetEditOptions, ToolsConstants.CLU_SET_APPROVED_CLUS_FIELD, | 
  | 291 |  |                  ToolsConstants.CLU_SET_SWAP_APPROVED_CLUS); | 
  | 292 | 0 |          selectCluSetOption(model, cluSetEditOptions, ToolsConstants.CLU_SET_PROPOSED_CLUS_FIELD,  | 
  | 293 |  |                  ToolsConstants.CLU_SET_SWAP_PROPOSED_CLUS); | 
  | 294 | 0 |          selectCluSetOption(model, cluSetEditOptions, ToolsConstants.CLU_SET_CLU_SET_RANGE_FIELD,  | 
  | 295 |  |                  ToolsConstants.CLU_SET_SWAP_CLU_SET_RANGE); | 
  | 296 | 0 |          selectCluSetOption(model, cluSetEditOptions, ToolsConstants.CLU_SET_CLU_SETS_FIELD, | 
  | 297 |  |                  ToolsConstants.CLU_SET_SWAP_CLU_SETS); | 
  | 298 | 0 |      } | 
  | 299 |  |       | 
  | 300 |  |      private void selectCluSetOption(DataModel model, CluSetEditOptionList cluSetEditOptions, | 
  | 301 |  |              String queryPath, String selectionId) { | 
  | 302 | 0 |          final QueryPath qPath = QueryPath.parse(queryPath); | 
  | 303 | 0 |          Data queryData = model.get(qPath); | 
  | 304 | 0 |          if (hasData(queryPath, queryData)) { | 
  | 305 | 0 |              cluSetEditOptions.selectItem(selectionId); | 
  | 306 |  |          } else { | 
  | 307 | 0 |              cluSetEditOptions.deSelectItem(selectionId); | 
  | 308 |  |          } | 
  | 309 | 0 |      } | 
  | 310 |  |       | 
  | 311 |  |      private SectionView editCluSetSection() { | 
  | 312 |  |           | 
  | 313 | 0 |          ModelIdPlaceHolder modelIdObj = new ModelIdPlaceHolder(CluSetsConfigurer.EDIT_CLUSET_MGT_MODEL); | 
  | 314 | 0 |          final VerticalSectionView section = initNestedSectionView(CluSetSections.EDIT_CLU_SET, ToolsConstants.EDIT_CLU_SET, EDIT_CLUSET_MGT_MODEL); | 
  | 315 | 0 |          VerticalSection oversight = initSection(getH3Title(""), WITH_DIVIDER); | 
  | 316 | 0 |          Picker cluSetPicker = configureSearch(ToolsConstants.SEARCH_CLU_SET); | 
  | 317 | 0 |          cluSetPicker.addBasicSelectionCompletedCallback(new Callback<SelectedResults>() { | 
  | 318 |  |              @Override | 
  | 319 |  |              public void exec(SelectedResults result) { | 
  | 320 | 0 |                  if (result != null && result.getReturnKey() != null && result.getReturnKey().trim().length() > 0) { | 
  | 321 | 0 |                      editSearchCluSetId = result.getReturnKey(); | 
  | 322 | 0 |                      final CluSetEditOptionList cluSetEditOptions =  | 
  | 323 |  |                          cluSetEditOptionsMap.get(CluSetsConfigurer.EDIT_CLUSET_MGT_MODEL); | 
  | 324 |  |                       | 
  | 325 | 0 |                      final LayoutController parent = LayoutController.findParentLayout(section); | 
  | 326 | 0 |                      if(parent != null){ | 
  | 327 | 0 |                          parent.requestModel(CluSetsConfigurer.EDIT_SEARCH_CLUSET_MGT_MODEL, new ModelRequestCallback<DataModel>() { | 
  | 328 |  |                              @Override | 
  | 329 |  |                              public void onModelReady(DataModel model) { | 
  | 330 | 0 |                                  selectCluSetOptionList(model, cluSetEditOptions); | 
  | 331 | 0 |                                  section.updateWidgetData(model); | 
  | 332 | 0 |                              } | 
  | 333 |  |   | 
  | 334 |  |                              @Override | 
  | 335 |  |                              public void onRequestFail(Throwable cause) { | 
  | 336 | 0 |                                  GWT.log("Unable to retrieve model" + EDIT_SEARCH_CLUSET_MGT_MODEL.toString(), null); | 
  | 337 | 0 |                              } | 
  | 338 |  |   | 
  | 339 |  |                          }); | 
  | 340 |  |                      } | 
  | 341 |  |                  } | 
  | 342 | 0 |              } | 
  | 343 |  |          }); | 
  | 344 |  |           | 
  | 345 | 0 |          addField(modelIdObj, oversight, ToolsConstants.SEARCH_CLU_SET, generateMessageInfo("Search Clu Set"), cluSetPicker); | 
  | 346 |  |           | 
  | 347 | 0 |          section.addSection(oversight); | 
  | 348 | 0 |          addClusetDetailsSections(section, CluSetsConfigurer.EDIT_CLUSET_MGT_MODEL); | 
  | 349 | 0 |          return section; | 
  | 350 |  |          } | 
  | 351 |  |   | 
  | 352 |  |      private SectionView viewCluSetSection() { | 
  | 353 | 0 |          final VerticalSectionView sectionView = initVerticalSectionView(CluSetSections.VIEW_CLU_SET, ToolsConstants.VIEW_CLU_SET, VIEW_CLUSET_MGT_MODEL); | 
  | 354 |  |   | 
  | 355 |  |   | 
  | 356 | 0 |          Picker cluSetPicker = configureSearch(ToolsConstants.SEARCH_CLU_SET); | 
  | 357 | 0 |          cluSetPicker.addBasicSelectionCompletedCallback(new Callback<SelectedResults>() { | 
  | 358 |  |              @Override | 
  | 359 |  |              public void exec(SelectedResults result) { | 
  | 360 | 0 |                  if (result != null && result.getReturnKey() != null && result.getReturnKey().trim().length() > 0) { | 
  | 361 | 0 |                      viewSearchCluSetId = result.getReturnKey(); | 
  | 362 |  |                       | 
  | 363 | 0 |                      final LayoutController parent = LayoutController.findParentLayout(sectionView); | 
  | 364 | 0 |                      if(parent != null){ | 
  | 365 | 0 |                          parent.requestModel(CluSetsConfigurer.VIEW_SEARCH_CLUSET_MGT_MODEL, new ModelRequestCallback<DataModel>() { | 
  | 366 |  |                              @Override | 
  | 367 |  |                              public void onModelReady(DataModel model) { | 
  | 368 | 0 |                                  sectionView.updateWidgetData(model); | 
  | 369 |  |                                   | 
  | 370 |  |                                   | 
  | 371 |  |                                   | 
  | 372 | 0 |                              } | 
  | 373 |  |   | 
  | 374 |  |                              @Override | 
  | 375 |  |                              public void onRequestFail(Throwable cause) { | 
  | 376 | 0 |                                  GWT.log("Unable to retrieve model" + VIEW_SEARCH_CLUSET_MGT_MODEL.toString(), null); | 
  | 377 | 0 |                              } | 
  | 378 |  |   | 
  | 379 |  |                          }); | 
  | 380 |  |                      } | 
  | 381 |  |                  } | 
  | 382 | 0 |              } | 
  | 383 |  |          }); | 
  | 384 | 0 |          addField(sectionView, ToolsConstants.SEARCH_CLU_SET, generateMessageInfo(""), cluSetPicker); | 
  | 385 |  |   | 
  | 386 | 0 |          VerticalSection nameSection = initSection(null, !WITH_DIVIDER); | 
  | 387 | 0 |          nameSection.addStyleName(LUUIConstants.STYLE_BOTTOM_DIVIDER); | 
  | 388 | 0 |          addField(nameSection, ToolsConstants.CLU_SET_NAME_FIELD, generateMessageInfo(ToolsConstants.CLU_SET_NAME), new KSLabel()); | 
  | 389 | 0 |          sectionView.addSection(nameSection); | 
  | 390 |  |   | 
  | 391 | 0 |          VerticalSection descriptionSection = initSection(null, !WITH_DIVIDER); | 
  | 392 | 0 |          descriptionSection.addStyleName(LUUIConstants.STYLE_BOTTOM_DIVIDER); | 
  | 393 | 0 |          addField(descriptionSection, ToolsConstants.CLU_SET_DESCRIPTION_FIELD, generateMessageInfo("Description"), new KSLabel()); | 
  | 394 | 0 |          sectionView.addSection(descriptionSection); | 
  | 395 |  |           | 
  | 396 | 0 |          VerticalSection expirationDateSection = initSection(null, !WITH_DIVIDER); | 
  | 397 | 0 |          expirationDateSection.addStyleName(LUUIConstants.STYLE_BOTTOM_DIVIDER); | 
  | 398 | 0 |          addField(expirationDateSection, ToolsConstants.CLU_SET_EXP_DATE_FIELD, generateMessageInfo(ToolsConstants.EFFECTIVE_DATE), new KSLabel()); | 
  | 399 | 0 |          sectionView.addSection(expirationDateSection); | 
  | 400 |  |           | 
  | 401 | 0 |          VerticalSection clusSection = initSection(null, !WITH_DIVIDER); | 
  | 402 | 0 |          clusSection.addStyleName(LUUIConstants.STYLE_BOTTOM_DIVIDER); | 
  | 403 | 0 |          addField(clusSection, ToolsConstants.CLU_SET_ALL_CLUS_FIELD,  | 
  | 404 |  |                  generateMessageInfo("Individual Courses"), | 
  | 405 |  |                  new TranslatedStringList(ToolsConstants.CLU_SET_ALL_CLUS_FIELD)); | 
  | 406 | 0 |          sectionView.addSection(clusSection); | 
  | 407 |  |           | 
  | 408 | 0 |          VerticalSection cluSetsSection = initSection(null, !WITH_DIVIDER); | 
  | 409 | 0 |          cluSetsSection.addStyleName(LUUIConstants.STYLE_BOTTOM_DIVIDER); | 
  | 410 | 0 |          addField(cluSetsSection, ToolsConstants.CLU_SET_CLU_SETS_FIELD,  | 
  | 411 |  |                  generateMessageInfo("CLU Sets"), | 
  | 412 |  |                  new TranslatedStringList(ToolsConstants.CLU_SET_CLU_SETS_FIELD)); | 
  | 413 | 0 |          sectionView.addSection(cluSetsSection); | 
  | 414 |  |           | 
  | 415 | 0 |          VerticalSection cluRangeDetailsSection = initSection(null, !WITH_DIVIDER); | 
  | 416 | 0 |          cluRangeDetailsSection.addStyleName(LUUIConstants.STYLE_BOTTOM_DIVIDER); | 
  | 417 | 0 |          addField(cluRangeDetailsSection, ToolsConstants.CLU_SET_CLUSET_RANGE_VIEW_DETAILS_FIELD,  | 
  | 418 |  |                  generateMessageInfo("Course Range"), | 
  | 419 |  |                  new TranslatedStringList(ToolsConstants.CLU_SET_CLUSET_RANGE_VIEW_DETAILS_FIELD)); | 
  | 420 | 0 |          sectionView.addSection(cluRangeDetailsSection); | 
  | 421 |  |   | 
  | 422 | 0 |          return sectionView; | 
  | 423 |  |      } | 
  | 424 |  |   | 
  | 425 |  |      private class TranslatedStringList extends DisplayMultiplicityComposite { | 
  | 426 |  |          private final String parentPath; | 
  | 427 | 0 |          public TranslatedStringList(String parentPath){ | 
  | 428 | 0 |              this.parentPath = parentPath; | 
  | 429 | 0 |          } | 
  | 430 |  |          @Override | 
  | 431 |  |          public Widget createItem() { | 
  | 432 | 0 |              String path = QueryPath.concat(parentPath, CreditCourseConstants._RUNTIME_DATA, String.valueOf(itemCount-1)).toString(); | 
  | 433 | 0 |              GroupSection ns = new GroupSection(); | 
  | 434 | 0 |              addField(ns, "id-translation", null, new KSLabel(), path); | 
  | 435 |  |   | 
  | 436 | 0 |              return ns; | 
  | 437 |  |          } | 
  | 438 |  |      } | 
  | 439 |  |   | 
  | 440 |  |      private VerticalSectionView initVerticalSectionView(Enum<?> viewEnum, String labelKey, String modelId) { | 
  | 441 | 0 |          VerticalSectionView section = new VerticalSectionView(viewEnum, getLabel(labelKey), modelId); | 
  | 442 | 0 |          section.addStyleName(LUUIConstants.STYLE_SECTION); | 
  | 443 |  |           | 
  | 444 |  |   | 
  | 445 | 0 |          return section; | 
  | 446 |  |      } | 
  | 447 |  |   | 
  | 448 |  |      private VerticalSectionView initNestedSectionView (Enum<?> viewEnum, String labelKey, String modelId) { | 
  | 449 | 0 |          VerticalSectionView section = new VerticalSectionView(viewEnum, getLabel(labelKey), modelId); | 
  | 450 | 0 |          section.addStyleName(LUUIConstants.STYLE_SECTION); | 
  | 451 |  |           | 
  | 452 |  |   | 
  | 453 | 0 |          return section; | 
  | 454 |  |      } | 
  | 455 |  |   | 
  | 456 |  |      private static VerticalSection initSection(SectionTitle title, boolean withDivider) { | 
  | 457 | 0 |          VerticalSection section = new VerticalSection(title); | 
  | 458 | 0 |          section.addStyleName(LUUIConstants.STYLE_SECTION); | 
  | 459 | 0 |          if (withDivider) | 
  | 460 | 0 |              section.addStyleName(LUUIConstants.STYLE_SECTION_DIVIDER); | 
  | 461 | 0 |          return section; | 
  | 462 |  |      } | 
  | 463 |  |   | 
  | 464 |  |      private String getLabel(String labelKey) { | 
  | 465 | 0 |          return Application.getApplicationContext().getUILabel("clusetmanagement", "clusetmanagement", "draft", labelKey); | 
  | 466 |  |      } | 
  | 467 |  |   | 
  | 468 |  |      private SectionTitle getH3Title(String labelKey) { | 
  | 469 | 0 |          return SectionTitle.generateH3Title(getLabel(labelKey)); | 
  | 470 |  |      } | 
  | 471 |  |   | 
  | 472 |  |      private Picker configureSearch(String fieldKey) { | 
  | 473 | 0 |          QueryPath path = QueryPath.concat(null, fieldKey); | 
  | 474 | 0 |          Metadata metaData = modelDefinition.getMetadata(path); | 
  | 475 | 0 |          Picker picker = new Picker(metaData.getInitialLookup(), metaData.getAdditionalLookups()); | 
  | 476 | 0 |          return picker; | 
  | 477 |  |      } | 
  | 478 |  |   | 
  | 479 |  |   | 
  | 480 |  |   | 
  | 481 |  |   | 
  | 482 |  |   | 
  | 483 |  |   | 
  | 484 |  |   | 
  | 485 |  |   | 
  | 486 |  |   | 
  | 487 |  |   | 
  | 488 |  |   | 
  | 489 |  |   | 
  | 490 |  |   | 
  | 491 |  |   | 
  | 492 |  |   | 
  | 493 |  |   | 
  | 494 |  |   | 
  | 495 |  |   | 
  | 496 |  |   | 
  | 497 |  |      public static class Picker extends KSPicker { | 
  | 498 |  |   | 
  | 499 |  |          private String name; | 
  | 500 |  |          private LookupMetadata initLookupMetadata; | 
  | 501 |  |          private List<LookupMetadata> additionalLookupMetadata; | 
  | 502 |  |   | 
  | 503 |  |          public Picker(LookupMetadata inLookupMetadata, List<LookupMetadata> additionalLookupMetadata) { | 
  | 504 | 0 |              super(inLookupMetadata, additionalLookupMetadata); | 
  | 505 | 0 |              this.initLookupMetadata = inLookupMetadata; | 
  | 506 | 0 |              this.additionalLookupMetadata = additionalLookupMetadata; | 
  | 507 | 0 |          } | 
  | 508 |  |   | 
  | 509 |  |          public String getName() { | 
  | 510 | 0 |              return name; | 
  | 511 |  |          } | 
  | 512 |  |   | 
  | 513 |  |          public void setName(String name) { | 
  | 514 | 0 |              this.name = name; | 
  | 515 | 0 |          } | 
  | 516 |  |   | 
  | 517 |  |          public LookupMetadata getInitLookupMetadata() { | 
  | 518 | 0 |              return initLookupMetadata; | 
  | 519 |  |          } | 
  | 520 |  |   | 
  | 521 |  |          public void setInitLookupMetadata(LookupMetadata initLookupMetadata) { | 
  | 522 | 0 |              this.initLookupMetadata = initLookupMetadata; | 
  | 523 | 0 |          } | 
  | 524 |  |   | 
  | 525 |  |          public List<LookupMetadata> getAdditionalLookupMetadata() { | 
  | 526 | 0 |              return additionalLookupMetadata; | 
  | 527 |  |          } | 
  | 528 |  |   | 
  | 529 |  |          public void setAdditionalLookupMetadata(List<LookupMetadata> additionalLookupMetadata) { | 
  | 530 | 0 |              this.additionalLookupMetadata = additionalLookupMetadata; | 
  | 531 | 0 |          } | 
  | 532 |  |           | 
  | 533 |  |      } | 
  | 534 |  |      private FieldDescriptor addField(ModelIdPlaceHolder modelIdObj, Section section, String fieldKey) { | 
  | 535 | 0 |              return addField(modelIdObj, section, fieldKey, null, null, null); | 
  | 536 |  |      } | 
  | 537 |  |      private FieldDescriptor addField(ModelIdPlaceHolder modelIdObj, Section section, String fieldKey, MessageKeyInfo messageKey) { | 
  | 538 | 0 |              return addField(modelIdObj, section, fieldKey, messageKey, null, null); | 
  | 539 |  |      } | 
  | 540 |  |      private FieldDescriptor addField(ModelIdPlaceHolder modelIdObj, Section section, String fieldKey, MessageKeyInfo messageKey, Widget widget) { | 
  | 541 | 0 |              return addField(modelIdObj, section, fieldKey, messageKey, widget, null); | 
  | 542 |  |      } | 
  | 543 |  |   | 
  | 544 |  |       | 
  | 545 |  |       | 
  | 546 |  |       | 
  | 547 |  |       | 
  | 548 |  |      protected FieldDescriptor addField(Section section, String fieldKey) { | 
  | 549 | 0 |              return addField(null, section, fieldKey, null, null, null); | 
  | 550 |  |      }     | 
  | 551 |  |      protected FieldDescriptor addField(Section section, String fieldKey, MessageKeyInfo messageKey) { | 
  | 552 | 0 |              return addField(null, section, fieldKey, messageKey, null, null); | 
  | 553 |  |      } | 
  | 554 |  |      protected FieldDescriptor addField(Section section, String fieldKey, MessageKeyInfo messageKey, Widget widget) { | 
  | 555 | 0 |              return addField(null, section, fieldKey, messageKey, widget, null); | 
  | 556 |  |      } | 
  | 557 |  |      protected FieldDescriptor addField(Section section, String fieldKey, MessageKeyInfo messageKey, String parentPath) { | 
  | 558 | 0 |          return addField(null, section, fieldKey, messageKey, null, parentPath); | 
  | 559 |  |      } | 
  | 560 |  |      protected FieldDescriptor addField(Section section, String fieldKey, MessageKeyInfo messageKey, Widget widget, String parentPath) { | 
  | 561 | 0 |          return addField(null, section, fieldKey, messageKey, widget, parentPath); | 
  | 562 |  |      } | 
  | 563 |  |      private FieldDescriptor addField(ModelIdPlaceHolder modelId, Section section, String fieldKey, MessageKeyInfo messageKey, Widget widget, String parentPath) { | 
  | 564 | 0 |          QueryPath path = QueryPath.concat(parentPath, fieldKey); | 
  | 565 | 0 |              Metadata meta = modelDefinition.getMetadata(path); | 
  | 566 |  |              FieldDescriptor fd; | 
  | 567 | 0 |              if (widget != null) { | 
  | 568 | 0 |                      fd = new FieldDescriptor(path.toString(), messageKey, meta, widget); | 
  | 569 |  |              } | 
  | 570 |  |              else{ | 
  | 571 | 0 |                      fd = new FieldDescriptor(path.toString(), messageKey, meta); | 
  | 572 |  |              } | 
  | 573 | 0 |              if (modelId != null) { | 
  | 574 | 0 |                      fd.setModelId(modelId.getModelId()); | 
  | 575 |  |              } | 
  | 576 | 0 |              section.addField(fd); | 
  | 577 | 0 |              return fd; | 
  | 578 |  |      } | 
  | 579 |  |   | 
  | 580 |  |      public String getEditSearchCluSetId() { | 
  | 581 | 0 |          return editSearchCluSetId; | 
  | 582 |  |      } | 
  | 583 |  |   | 
  | 584 |  |      public void setEditSearchCluSetId(String searchCluSetId) { | 
  | 585 | 0 |          this.editSearchCluSetId = searchCluSetId; | 
  | 586 | 0 |      } | 
  | 587 |  |   | 
  | 588 |  |      public String getViewSearchCluSetId() { | 
  | 589 | 0 |          return viewSearchCluSetId; | 
  | 590 |  |      } | 
  | 591 |  |   | 
  | 592 |  |      public void setViewSearchCluSetId(String viewSearchCluSetId) { | 
  | 593 | 0 |          this.viewSearchCluSetId = viewSearchCluSetId; | 
  | 594 | 0 |      } | 
  | 595 |  |       | 
  | 596 |  |      protected MessageKeyInfo generateMessageInfo(String labelKey) { | 
  | 597 | 0 |          return new MessageKeyInfo("clusetmanagement", "clusetmanagement", "draft", labelKey); | 
  | 598 |  |      } | 
  | 599 |  |       | 
  | 600 |  |      class ModelIdPlaceHolder { | 
  | 601 |  |              private String modelId; | 
  | 602 |  |               | 
  | 603 | 0 |              public ModelIdPlaceHolder(String modelId) { | 
  | 604 | 0 |                      setModelId(modelId); | 
  | 605 | 0 |              } | 
  | 606 |  |               | 
  | 607 |  |                  public String getModelId() { | 
  | 608 | 0 |                          return modelId; | 
  | 609 |  |                  } | 
  | 610 |  |   | 
  | 611 |  |                  public void setModelId(String modelId) { | 
  | 612 | 0 |                          this.modelId = modelId; | 
  | 613 | 0 |                  } | 
  | 614 |  |      } | 
  | 615 |  |   | 
  | 616 | 0 |      public class CluSetEditOptionList extends KSCheckBoxList{ | 
  | 617 | 0 |          public CluSetEditOptionList(){ | 
  | 618 | 0 |              SimpleListItems editOptions = new SimpleListItems(); | 
  | 619 |  |   | 
  | 620 | 0 |              editOptions.addItem(ToolsConstants.CLU_SET_SWAP_APPROVED_CLUS, "Approved Courses"); | 
  | 621 | 0 |              editOptions.addItem(ToolsConstants.CLU_SET_SWAP_PROPOSED_CLUS, "Proposed Courses"); | 
  | 622 | 0 |              editOptions.addItem(ToolsConstants.CLU_SET_SWAP_CLU_SETS, "CLU Sets"); | 
  | 623 | 0 |              editOptions.addItem(ToolsConstants.CLU_SET_SWAP_CLU_SET_RANGE, "Course Ranges (Course numbers, common learning objectives, etc)"); | 
  | 624 |  |   | 
  | 625 | 0 |              super.setListItems(editOptions); | 
  | 626 | 0 |          } | 
  | 627 |  |      } | 
  | 628 |  |   | 
  | 629 |  |  } |