001 package org.kuali.student.lum.common.client.widgets; 002 003 import java.util.ArrayList; 004 import java.util.HashMap; 005 import java.util.List; 006 import java.util.Map; 007 008 import org.kuali.student.common.ui.client.application.Application; 009 import org.kuali.student.common.ui.client.configurable.mvc.FieldDescriptor; 010 import org.kuali.student.common.ui.client.configurable.mvc.WidgetConfigInfo; 011 import org.kuali.student.common.ui.client.configurable.mvc.binding.HasDataValueBinding; 012 import org.kuali.student.common.ui.client.configurable.mvc.binding.ModelWidgetBindingSupport; 013 import org.kuali.student.common.ui.client.configurable.mvc.sections.Section; 014 import org.kuali.student.common.ui.client.configurable.mvc.sections.VerticalSection; 015 import org.kuali.student.common.ui.client.configurable.mvc.views.VerticalSectionView; 016 import org.kuali.student.common.ui.client.mvc.Callback; 017 import org.kuali.student.common.ui.client.mvc.DataModel; 018 import org.kuali.student.common.ui.client.mvc.DataModelDefinition; 019 import org.kuali.student.common.ui.client.mvc.HasDataValue; 020 import org.kuali.student.common.ui.client.widgets.KSDropDown; 021 import org.kuali.student.common.ui.client.widgets.KSItemLabel; 022 import org.kuali.student.common.ui.client.widgets.KSLabel; 023 import org.kuali.student.common.ui.client.widgets.field.layout.element.MessageKeyInfo; 024 import org.kuali.student.common.ui.client.widgets.layout.VerticalFlowPanel; 025 import org.kuali.student.common.ui.client.widgets.list.KSSelectedList; 026 import org.kuali.student.common.ui.client.widgets.list.SelectionChangeEvent; 027 import org.kuali.student.common.ui.client.widgets.list.SelectionChangeHandler; 028 import org.kuali.student.common.ui.client.widgets.list.impl.SimpleListItems; 029 import org.kuali.student.common.ui.client.widgets.menus.KSListPanel; 030 import org.kuali.student.common.ui.client.widgets.progress.BlockingTask; 031 import org.kuali.student.common.ui.client.widgets.progress.KSBlockingProgressIndicator; 032 import org.kuali.student.common.ui.client.widgets.search.KSPicker; 033 import org.kuali.student.r1.common.assembly.data.Data; 034 import org.kuali.student.r1.common.assembly.data.Data.DataValue; 035 import org.kuali.student.r1.common.assembly.data.Data.Value; 036 import org.kuali.student.r1.common.assembly.data.LookupMetadata; 037 import org.kuali.student.r1.common.assembly.data.LookupParamMetadata; 038 import org.kuali.student.r1.common.assembly.data.Metadata; 039 import org.kuali.student.r1.common.assembly.data.QueryPath; 040 import org.kuali.student.r2.core.search.dto.SearchParamInfo; 041 import org.kuali.student.r2.core.search.dto.SearchRequestInfo; 042 import org.kuali.student.r2.lum.clu.dto.MembershipQueryInfo; 043 044 import com.google.gwt.core.client.GWT; 045 import com.google.gwt.dom.client.Style; 046 import com.google.gwt.event.dom.client.ClickEvent; 047 import com.google.gwt.event.dom.client.ClickHandler; 048 import com.google.gwt.event.logical.shared.CloseEvent; 049 import com.google.gwt.event.logical.shared.CloseHandler; 050 import com.google.gwt.event.shared.HandlerRegistration; 051 import com.google.gwt.user.client.Timer; 052 import com.google.gwt.user.client.ui.HTML; 053 import com.google.gwt.user.client.ui.Panel; 054 import com.google.gwt.user.client.ui.Widget; 055 056 public class CluSetEditorWidget extends VerticalSectionView { 057 058 private List<KSSelectedListPanelPair> selectedListPanelPairs = new ArrayList<KSSelectedListPanelPair>(); 059 private DataModelDefinition modelDefinition; 060 // private final List<HandlerRegistration> showClusetDetailsHandlerRegs = new ArrayList<HandlerRegistration>(); 061 private final Map<String, HandlerRegistration> showCluRangeDetailsHandlerRegs = new HashMap<String, HandlerRegistration>(); 062 private List<KSItemLabelPanelPair> itemLabelPanelPairs = new ArrayList<KSItemLabelPanelPair>(); 063 protected static String cluSetType; 064 private String metadataId; 065 private static Map<String, DataModelDefinition> modelDefinitionCache = new HashMap<String, DataModelDefinition>(); 066 private BlockingTask initializeTask = new BlockingTask("Initializing"); 067 protected static boolean singularCluOnly; 068 private KSSelectedList approvedClusSelection; 069 070 private enum CluSetManagementField { 071 APPROVED, PROPOSED, CLUSETS, RANGE 072 } 073 074 public CluSetEditorWidget() { 075 super(); 076 } 077 078 public CluSetEditorWidget(CluSetRetriever cluSetRetriever, Enum<?> viewEnum, 079 String name, String modelId, boolean showTitle, 080 final Callback<Boolean> onReady, String cluSetType, boolean singularCluOnly) { 081 super(viewEnum, name, modelId, showTitle); 082 CluSetEditorWidget.cluSetType = cluSetType; 083 CluSetEditorWidget.singularCluOnly = singularCluOnly; 084 if (cluSetType != null && cluSetType.equals("kuali.cluSet.type.Program")) { 085 this.metadataId = "programSet"; 086 } else { 087 this.metadataId = "courseSet"; 088 } 089 KSBlockingProgressIndicator.addTask(initializeTask); 090 if (modelDefinitionCache.get(metadataId) == null) { 091 cluSetRetriever.getMetadata(metadataId, new Callback<Metadata>(){ 092 @Override 093 public void exec(Metadata result) { 094 DataModelDefinition def = new DataModelDefinition(result); 095 modelDefinitionCache.put(metadataId, def); 096 setDef(def); 097 setupEditor(); 098 if (onReady != null) { 099 onReady.exec(new Boolean(true)); 100 } 101 KSBlockingProgressIndicator.removeTask(initializeTask); 102 } 103 }); 104 } else { 105 DataModelDefinition def = modelDefinitionCache.get(metadataId); 106 setDef(def); 107 setupEditor(); 108 if (onReady != null) { 109 onReady.exec(new Boolean(true)); 110 } 111 KSBlockingProgressIndicator.removeTask(initializeTask); 112 } 113 } 114 115 private void setDef(DataModelDefinition def) { 116 this.modelDefinition = def; 117 } 118 119 public void setupEditor() { 120 String labelType = null; 121 if (cluSetType == null || !cluSetType.equals("kuali.cluSet.type.Program")) { 122 labelType = "Course"; 123 } else { 124 labelType = "Program"; 125 } 126 final CluSetEditOptionDropdown chooser = GWT.create(CluSetEditOptionDropdown.class); 127 SwitchSection clusetDetails = new SwitchSection( 128 chooser, 129 null); 130 clusetDetails.enableConfirmation(false); 131 // ****** Add Approved Clus ******* 132 Section approvedClusSection = new VerticalSection(); 133 FieldDescriptor approvedClusFd = addField(approvedClusSection, 134 CommonWidgetConstants.CLU_SET_APPROVED_CLUS_FIELD, 135 generateMessageInfo(CommonWidgetConstants.NEW_CLU_SET_CONTENT_APPROVED + labelType), 136 null, 137 null); 138 approvedClusSelection = (KSSelectedList) approvedClusFd.getFieldWidget(); 139 KSListPanel approvedClusListPanel = approvedClusSelection.separateValuesPanel(); 140 clusetDetails.addSection(approvedClusSection, CommonWidgetConstants.CLU_SET_SWAP_APPROVED_CLUS); 141 // END OF items related to Add Approved Clus 142 143 // ****** Add Proposed Clus ******* 144 Section proposedClusSection = new VerticalSection(); 145 FieldDescriptor proposedClusFd = addField(proposedClusSection, 146 CommonWidgetConstants.CLU_SET_PROPOSED_CLUS_FIELD, 147 generateMessageInfo(CommonWidgetConstants.NEW_CLU_SET_CONTENT_PROPOSED + labelType), 148 null, 149 null); 150 final KSSelectedList proposedClusSelection = (KSSelectedList) proposedClusFd.getFieldWidget(); 151 KSListPanel proposedClusListPanel = proposedClusSelection.separateValuesPanel(); 152 clusetDetails.addSection(proposedClusSection, CommonWidgetConstants.CLU_SET_SWAP_PROPOSED_CLUS); 153 // END OF items related to Add Approved Clus 154 155 // ****** Add Clu Range ******* 156 KSItemLabel clusetRangeLabel = null; 157 if (displayField(CluSetManagementField.RANGE)) { 158 Section cluRangeSection = new VerticalSection(); 159 final Picker cluSetRangePicker = configureSearch(CommonWidgetConstants.CLU_SET_CLU_SET_RANGE_EDIT_FIELD); 160 addField(cluRangeSection, 161 CommonWidgetConstants.CLU_SET_CLU_SET_RANGE_EDIT_FIELD, 162 generateMessageInfo(CommonWidgetConstants.NEW_CLU_SET_CONTENT_RANGE + labelType), 163 cluSetRangePicker, 164 null); 165 final CluSetRangeDataHelper clusetRangeModelHelper = new CluSetRangeDataHelper(); 166 clusetRangeLabel = new KSItemLabel(true, true, clusetRangeModelHelper); 167 final KSItemLabel theClusetRangeLabel = clusetRangeLabel; 168 clusetRangeLabel.getElement().getStyle().setProperty("border", "solid 1px #cdcdcd"); 169 clusetRangeLabel.getElement().getStyle().setProperty("width", "354px"); 170 final FieldDescriptor cluRangeFieldDescriptor = addField( 171 cluRangeSection, 172 CommonWidgetConstants.CLU_SET_CLU_SET_RANGE_FIELD, 173 null, 174 clusetRangeLabel, 175 null); 176 cluRangeFieldDescriptor.setWidgetBinding(new CluSetRangeBinding(clusetRangeModelHelper)); 177 cluSetRangePicker.getSearchWindow().addActionCompleteCallback(new Callback<Boolean>() { 178 @Override 179 public void exec(Boolean result) { 180 cluSetRangePicker.getSearchWindow().hide(); 181 // ((ModelWidgetBinding)cluRangeFieldDescriptor.getModelWidgetBinding()).setWidgetValue(widget, model, path) 182 // CluSetHelper cluSetHelper = CluSetHelper.wrap(model.getRoot()); 183 // cluSetHelper.setCluRangeParams(value) 184 final SearchRequestInfo searchRequest = cluSetRangePicker.getSearchWindow().getSearchRequest(); 185 String selectedSearchKey = searchRequest.getSearchKey(); 186 Data searchRequestData = CluSetRangeModelUtil.INSTANCE.toData(searchRequest, null); 187 LookupMetadata lookupMetadata = null; 188 189 // look for the lookupMetaData corresponding to the searchRequest 190 List<LookupMetadata> lookupMDs = new ArrayList<LookupMetadata>(); 191 lookupMDs.add(cluSetRangePicker.getInitLookupMetadata()); 192 lookupMetadata = findLookupMetadataByLookupId(selectedSearchKey, 193 lookupMDs, searchRequest.getParams()); 194 if (lookupMetadata == null || 195 !nullSafeEquals(lookupMetadata.getSearchTypeId(), 196 selectedSearchKey)) { 197 lookupMetadata = findLookupMetadataByLookupId(selectedSearchKey, 198 cluSetRangePicker.getAdditionalLookupMetadata(), 199 searchRequest.getParams()); 200 } 201 202 addClusetItemViewHandler(clusetRangeModelHelper, 203 theClusetRangeLabel, 204 lookupMetadata, 205 searchRequestData, 206 searchRequest); 207 theClusetRangeLabel.setHighlighted(true); 208 new Timer() { 209 @Override 210 public void run() { 211 theClusetRangeLabel.setHighlighted(false); 212 } 213 }.schedule(5000); 214 } 215 }); 216 clusetDetails.addSection(cluRangeSection, CommonWidgetConstants.CLU_SET_SWAP_CLU_SET_RANGE); 217 } 218 // END OF items related to Add Clu Range 219 220 // ****** Add cluSets ******* 221 KSListPanel cluSetsListPanel = null; 222 KSSelectedList cluSetsSelection = null; 223 if (displayField(CluSetManagementField.CLUSETS)) { 224 Section cluSetSection = new VerticalSection(); 225 FieldDescriptor cluSetsTempFd = getFieldDescriptor( 226 CommonWidgetConstants.CLU_SET_CLU_SETS_FIELD, 227 generateMessageInfo(CommonWidgetConstants.NEW_CLU_SET_CONTENT_CLUSET + labelType), 228 null, 229 null); 230 KSSelectedList tempCluSetsSelection = (KSSelectedList) cluSetsTempFd.getFieldWidget(); 231 WidgetConfigInfo config = tempCluSetsSelection.getConfig(); 232 cluSetsSelection = new KSSelectedList(config, false); 233 cluSetsListPanel = cluSetsSelection.separateValuesPanel(); 234 final FieldDescriptor cluSetsFd = addField( 235 cluSetSection, 236 CommonWidgetConstants.CLU_SET_CLU_SETS_FIELD, 237 generateMessageInfo(CommonWidgetConstants.NEW_CLU_SET_CONTENT_CLUSET + labelType), 238 cluSetsSelection, 239 null); 240 cluSetsFd.setWidgetBinding(new CluSetBinding()); 241 clusetDetails.addSection(cluSetSection, CommonWidgetConstants.CLU_SET_SWAP_CLU_SETS); 242 } 243 // END OF items related to Add CluSets 244 245 // display item type title if the list selected items is populated 246 // hide if the list becomes empty (thus the close listeners for each item 247 String contextName = (cluSetType != null && cluSetType.equals("kuali.cluSet.type.Program"))? 248 "PROGRAMS" : "COURSES"; 249 VerticalFlowPanel selectedValuesPanel = new VerticalFlowPanel(); 250 selectedValuesPanel.getElement().getStyle().setPaddingTop(20, Style.Unit.PX); 251 VerticalFlowPanel approvedClusPanel = prepareValuesPanel(approvedClusListPanel, "APPROVED " + contextName); 252 approvedClusPanel.getElement().getStyle().setPaddingTop(15, Style.Unit.PX); 253 VerticalFlowPanel proposedClusPanel = prepareValuesPanel(proposedClusListPanel, "PROPOSED " + contextName); 254 proposedClusPanel.getElement().getStyle().setPaddingTop(15, Style.Unit.PX); 255 VerticalFlowPanel rangePanel = null; 256 if (displayField(CluSetManagementField.RANGE)) { 257 rangePanel = prepareValuesPanel(clusetRangeLabel, contextName + " RANGE"); 258 rangePanel.getElement().getStyle().setPaddingTop(15, Style.Unit.PX); 259 } 260 VerticalFlowPanel cluSetsPanel = null; 261 if (displayField(CluSetManagementField.CLUSETS)) { 262 cluSetsPanel = prepareValuesPanel(cluSetsListPanel, contextName + " SETS"); 263 cluSetsPanel.getElement().getStyle().setPaddingTop(15, Style.Unit.PX); 264 } 265 266 selectedValuesPanel.add(approvedClusPanel); 267 selectedValuesPanel.add(proposedClusPanel); 268 if (displayField(CluSetManagementField.RANGE)) { 269 selectedValuesPanel.add(rangePanel); 270 } 271 if (displayField(CluSetManagementField.CLUSETS)) { 272 selectedValuesPanel.add(cluSetsPanel); 273 } 274 275 addVisibilityHandlers(approvedClusSelection, approvedClusPanel); 276 addVisibilityHandlers(proposedClusSelection, proposedClusPanel); 277 if (displayField(CluSetManagementField.RANGE)) { 278 addVisibilityHandlers(clusetRangeLabel, rangePanel); 279 } 280 if (displayField(CluSetManagementField.CLUSETS)) { 281 addVisibilityHandlers(cluSetsSelection, cluSetsPanel); 282 } 283 284 selectedListPanelPairs.add(new KSSelectedListPanelPair(approvedClusSelection, approvedClusPanel)); 285 selectedListPanelPairs.add(new KSSelectedListPanelPair(proposedClusSelection, proposedClusPanel)); 286 if (displayField(CluSetManagementField.CLUSETS)) { 287 selectedListPanelPairs.add(new KSSelectedListPanelPair(cluSetsSelection, cluSetsPanel)); 288 } 289 if (displayField(CluSetManagementField.RANGE)) { 290 itemLabelPanelPairs.add(new KSItemLabelPanelPair(clusetRangeLabel, rangePanel)); 291 } 292 293 final VerticalSection choosingSection = new VerticalSection(); 294 HTML prompt; 295 if(cluSetType.equals("kuali.cluSet.type.Program")){ 296 choosingSection.addWidget(new HTML(Application 297 .getApplicationContext().getMessage(CommonWidgetConstants.CLU_SET_ADD_PROGRAM_LABEL))); 298 prompt = new HTML(Application 299 .getApplicationContext().getMessage(CommonWidgetConstants.CLU_SET_MANAGEMENT_PROGRAM_INSTRUCTIONS)); 300 } 301 else{ 302 choosingSection.addWidget(new HTML(Application 303 .getApplicationContext().getMessage(CommonWidgetConstants.CLU_SET_ADD_COURSE_LABEL))); 304 prompt = new HTML(Application 305 .getApplicationContext().getMessage(CommonWidgetConstants.CLU_SET_MANAGEMENT_COURSE_INSTRUCTIONS)); 306 } 307 choosingSection.addWidget(chooser); 308 choosingSection.addSection(clusetDetails); 309 chooser.addSelectionChangeHandler(new SelectionChangeHandler() { 310 @Override 311 public void onSelectionChange(SelectionChangeEvent event) { 312 if (chooser.getSelectedItem() != null && 313 !chooser.getSelectedItem().trim().isEmpty()) { 314 choosingSection.setStyleName("KS-CluSetManagement-chooser"); 315 } else { 316 choosingSection.setStyleName("KS-CluSetManagement-chooser-unselected"); 317 } 318 } 319 }); 320 321 this.addWidget(prompt); 322 this.addSection(choosingSection); 323 this.addWidget(selectedValuesPanel); 324 } 325 326 private boolean displayField(CluSetManagementField field) { 327 boolean result = false; 328 switch(field) { 329 case APPROVED: 330 case PROPOSED: 331 result = true; 332 break; 333 case RANGE: 334 if (!singularCluOnly && (cluSetType == null || !cluSetType.equals("kuali.cluSet.type.Program"))) { 335 result = true; 336 } else { 337 result = false; 338 } 339 break; 340 case CLUSETS: 341 if (!singularCluOnly) { 342 result = true; 343 } else { 344 result = false; 345 } 346 break; 347 } 348 return result; 349 } 350 351 private void addClusetItemViewHandler(CluSetRangeDataHelper clusetRangeModelHelper, 352 KSItemLabel clusetRangeLabel, 353 final LookupMetadata lookupMetadata, 354 Data searchRequestData, 355 final SearchRequestInfo searchRequest) { 356 clusetRangeModelHelper.setLookupMetadata(lookupMetadata); 357 clusetRangeLabel.setValue(new DataValue(searchRequestData)); 358 if (showCluRangeDetailsHandlerRegs != null && 359 showCluRangeDetailsHandlerRegs.get(Integer.toString(clusetRangeLabel.instanceId)) != null) { 360 ((HandlerRegistration)showCluRangeDetailsHandlerRegs.get(Integer.toString(clusetRangeLabel.instanceId))).removeHandler(); 361 } 362 showCluRangeDetailsHandlerRegs.put(Integer.toString(clusetRangeLabel.instanceId), 363 clusetRangeLabel.addShowDetailsHandler(new ClickHandler() { 364 @Override 365 public void onClick(ClickEvent event) { 366 SearchResultsLightBox srLightBox = new SearchResultsLightBox("View Course Range", 367 searchRequest, lookupMetadata); 368 srLightBox.show(); 369 } 370 })); 371 } 372 373 protected MessageKeyInfo generateMessageInfo(String labelKey) { 374 return new MessageKeyInfo("clusetmanagement", "clusetmanagement", "draft", labelKey); 375 } 376 377 private FieldDescriptor getFieldDescriptor( 378 String fieldKey, 379 MessageKeyInfo messageKey, 380 Widget widget, 381 String parentPath) { 382 QueryPath path = QueryPath.concat(parentPath, fieldKey); 383 Metadata meta = modelDefinition.getMetadata(path); 384 FieldDescriptor fd; 385 if (widget != null) { 386 fd = new FieldDescriptor(path.toString(), messageKey, meta, widget); 387 } 388 else{ 389 fd = new FieldDescriptor(path.toString(), messageKey, meta); 390 } 391 return fd; 392 } 393 394 private FieldDescriptor addField(Section section, 395 String fieldKey, 396 MessageKeyInfo messageKey, 397 Widget widget, 398 String parentPath) { 399 FieldDescriptor fd = getFieldDescriptor(fieldKey, messageKey, widget, parentPath); 400 section.addField(fd); 401 return fd; 402 } 403 404 private static boolean nullSafeEquals(Object obj1, Object obj2) { 405 return (obj1 == null && obj2 == null || 406 obj1 != null && obj2 != null && obj1.equals(obj2)); 407 } 408 409 private VerticalFlowPanel prepareValuesPanel(Widget widget, String title) { 410 final VerticalFlowPanel valuesPanel = new VerticalFlowPanel(); 411 valuesPanel.add(new KSLabel(title)); 412 valuesPanel.add(widget); 413 valuesPanel.setVisible(false); 414 return valuesPanel; 415 } 416 417 @Override 418 public void updateWidgetData(DataModel model) { 419 super.updateWidgetData(model); 420 // this is to refresh the lists and item labels. 421 if (selectedListPanelPairs != null) { 422 for (KSSelectedListPanelPair selectedListPanelPair : selectedListPanelPairs) { 423 handleSelectedListVisibility(selectedListPanelPair.getKsSelectedList(), 424 selectedListPanelPair.getPanel()); 425 } 426 } 427 if (itemLabelPanelPairs != null) { 428 for (KSItemLabelPanelPair itemLabelPanelPair : itemLabelPanelPairs) { 429 handleListItemVisibility(itemLabelPanelPair.getKsItemLabel(), 430 itemLabelPanelPair.getPanel()); 431 } 432 } 433 } 434 435 private void addVisibilityHandlers(final KSItemLabel listItem, 436 final Panel selectionPanel) { 437 listItem.addValueChangeCallback(new Callback<Value>() { 438 @Override 439 public void exec(Value result) { 440 handleListItemVisibility(listItem, selectionPanel); 441 } 442 }); 443 } 444 445 private void handleListItemVisibility(KSItemLabel listItem, Panel selectionPanel) { 446 String displayText = listItem.getDisplayText(); 447 if (displayText == null || displayText.equals("")) { 448 selectionPanel.setVisible(false); 449 } else { 450 selectionPanel.setVisible(true); 451 } 452 } 453 454 private void addVisibilityHandlers(final KSSelectedList selectionList, 455 final Panel selectionPanel) { 456 selectionList.addSelectionChangeHandler( 457 new SelectionChangeHandler() { 458 @Override 459 public void onSelectionChange(SelectionChangeEvent event) { 460 handleSelectedListVisibility(selectionList, selectionPanel); 461 } 462 } 463 ); 464 } 465 466 private void handleSelectedListVisibility(final KSSelectedList selectionList, final Panel selectionPanel) { 467 List<KSItemLabel> selectedItems = selectionList.getSelectedItems(); 468 if (selectedItems != null && !selectedItems.isEmpty()) { 469 // show item type title 470 selectionPanel.setVisible(true); 471 for (KSItemLabel selectedItem : selectedItems) { 472 selectedItem.addCloseHandler(new CloseHandler<KSItemLabel>() { 473 @Override 474 public void onClose(CloseEvent<KSItemLabel> event) { 475 List<KSItemLabel> newSelectedItems = 476 selectionList.getSelectedItems(); 477 int numNewSelectedItems = (newSelectedItems == null)? 0 : 478 newSelectedItems.size(); 479 if (numNewSelectedItems == 0) { 480 //hide item type title 481 selectionPanel.setVisible(false); 482 } 483 } 484 }); 485 } 486 } 487 } 488 489 private Picker configureSearch(String fieldKey) { 490 QueryPath path = QueryPath.concat(null, fieldKey); 491 Metadata metaData = modelDefinition.getMetadata(path); 492 Picker picker = new Picker(metaData.getInitialLookup(), metaData.getAdditionalLookups()); 493 return picker; 494 } 495 496 private static LookupMetadata findLookupMetadataByLookupId(String searchTypeId, 497 List<LookupMetadata> lookupMetadatas, 498 List<SearchParamInfo> searchParams) { 499 LookupMetadata result = null; 500 if (lookupMetadatas != null) { 501 for (LookupMetadata lookupMetadata : lookupMetadatas) { 502 if (nullSafeEquals(lookupMetadata.getSearchTypeId(), searchTypeId)) { 503 // search Type id matches now add up all the params meta found to the result 504 List<LookupParamMetadata> paramMetas = lookupMetadata.getParams(); 505 List<LookupParamMetadata> resultParamMetas = null; 506 result = (result == null)? new LookupMetadata() : result; 507 result.setDesc(lookupMetadata.getDesc()); 508 result.setId(lookupMetadata.getId()); 509 result.setName(""); 510 resultParamMetas = result.getParams(); 511 if (resultParamMetas == null) { 512 resultParamMetas = new ArrayList<LookupParamMetadata>(); 513 } 514 if (paramMetas != null) { 515 for (LookupParamMetadata paramMeta : paramMetas) { 516 boolean resultParamMetaFound = false; 517 for (LookupParamMetadata resultParamMeta : resultParamMetas) { 518 if (paramMeta.getKey().equals(resultParamMeta)) { 519 resultParamMetaFound = true; 520 break; 521 } 522 } 523 if (!resultParamMetaFound) { 524 resultParamMetas.add(paramMeta); 525 } 526 } 527 } 528 result.setParams(resultParamMetas); 529 result.setQosMetadata(lookupMetadata.getQosMetadata()); 530 result.setResultDisplayKey(lookupMetadata.getResultDisplayKey()); 531 result.setResultReturnKey(lookupMetadata.getResultReturnKey()); 532 result.setResults(lookupMetadata.getResults()); 533 result.setResultSortKey(lookupMetadata.getResultSortKey()); 534 } 535 } 536 } 537 return result; 538 } 539 540 @Override 541 public void updateModel() { 542 543 super.updateModel(); 544 } 545 546 547 548 public static class CluSetEditOptionDropdown extends KSDropDown { 549 public CluSetEditOptionDropdown(){ 550 SimpleListItems editOptions = new SimpleListItems(); 551 552 if (cluSetType != null && cluSetType.equals("kuali.cluSet.type.Program")) { 553 editOptions.addItem(CommonWidgetConstants.CLU_SET_SWAP_APPROVED_CLUS, "Approved Programs"); 554 editOptions.addItem(CommonWidgetConstants.CLU_SET_SWAP_PROPOSED_CLUS, "Proposed Programs"); 555 if (!singularCluOnly) { 556 editOptions.addItem(CommonWidgetConstants.CLU_SET_SWAP_CLU_SETS, "Program Sets"); 557 } 558 } else { 559 editOptions.addItem(CommonWidgetConstants.CLU_SET_SWAP_APPROVED_CLUS, Application 560 .getApplicationContext().getMessage("clusetmanagement", 561 CommonWidgetConstants.CLU_SET_APPROVED_COURSE)); 562 editOptions.addItem(CommonWidgetConstants.CLU_SET_SWAP_PROPOSED_CLUS, Application 563 .getApplicationContext().getMessage("clusetmanagement", 564 CommonWidgetConstants.CLU_SET_PROPOSED_COURSE)); 565 if (!singularCluOnly) { 566 editOptions.addItem(CommonWidgetConstants.CLU_SET_SWAP_CLU_SETS, "Course Sets"); 567 editOptions.addItem(CommonWidgetConstants.CLU_SET_SWAP_CLU_SET_RANGE, "Course Ranges (Course numbers, common learning objectives, etc)"); 568 } 569 } 570 super.setListItems(editOptions); 571 } 572 } 573 574 class KSSelectedListPanelPair { 575 private KSSelectedList ksSelectedList; 576 private Panel panel; 577 public KSSelectedListPanelPair(KSSelectedList ksSelectedList, Panel panel) { 578 setKsSelectedList(ksSelectedList); 579 setPanel(panel); 580 } 581 public KSSelectedList getKsSelectedList() { 582 return ksSelectedList; 583 } 584 public void setKsSelectedList(KSSelectedList ksSelectedList) { 585 this.ksSelectedList = ksSelectedList; 586 } 587 public Panel getPanel() { 588 return panel; 589 } 590 public void setPanel(Panel panel) { 591 this.panel = panel; 592 } 593 } 594 595 class KSItemLabelPanelPair { 596 private KSItemLabel ksItemLabel; 597 private Panel panel; 598 public KSItemLabelPanelPair(KSItemLabel ksItemLabel, Panel panel) { 599 setKsItemLabel(ksItemLabel); 600 setPanel(panel); 601 } 602 public KSItemLabel getKsItemLabel() { 603 return ksItemLabel; 604 } 605 public void setKsItemLabel(KSItemLabel ksItemLabel) { 606 this.ksItemLabel = ksItemLabel; 607 } 608 public Panel getPanel() { 609 return panel; 610 } 611 public void setPanel(Panel panel) { 612 this.panel = panel; 613 } 614 } 615 616 public static class Picker extends KSPicker { 617 618 private String name; 619 private LookupMetadata initLookupMetadata; 620 private List<LookupMetadata> additionalLookupMetadata; 621 622 public Picker(LookupMetadata inLookupMetadata, List<LookupMetadata> additionalLookupMetadata) { 623 super.init(inLookupMetadata, additionalLookupMetadata); 624 this.initLookupMetadata = inLookupMetadata; 625 this.additionalLookupMetadata = additionalLookupMetadata; 626 } 627 628 public String getName() { 629 return name; 630 } 631 632 public void setName(String name) { 633 this.name = name; 634 } 635 636 public LookupMetadata getInitLookupMetadata() { 637 return initLookupMetadata; 638 } 639 640 public void setInitLookupMetadata(LookupMetadata initLookupMetadata) { 641 this.initLookupMetadata = initLookupMetadata; 642 } 643 644 public List<LookupMetadata> getAdditionalLookupMetadata() { 645 return additionalLookupMetadata; 646 } 647 648 public void setAdditionalLookupMetadata(List<LookupMetadata> additionalLookupMetadata) { 649 this.additionalLookupMetadata = additionalLookupMetadata; 650 } 651 652 } 653 654 public class CluSetBinding extends ModelWidgetBindingSupport<HasDataValue> { 655 private HasDataValueBinding binding = HasDataValueBinding.INSTANCE; 656 657 @Override 658 public void setModelValue(HasDataValue widget, DataModel model, String path) { 659 binding.setModelValue(widget, model, path); 660 } 661 662 @Override 663 public void setWidgetValue(HasDataValue widget, DataModel model, String path) { 664 binding.setWidgetValue(widget, model, path); 665 } 666 } 667 668 public class CluSetRangeBinding extends ModelWidgetBindingSupport<HasDataValue> { 669 private HasDataValueBinding binding = HasDataValueBinding.INSTANCE; 670 private CluSetRangeDataHelper clusetRangeModelHelper = null; 671 672 public CluSetRangeBinding(CluSetRangeDataHelper clusetRangeModelHelper) { 673 this.clusetRangeModelHelper = clusetRangeModelHelper; 674 } 675 676 @Override 677 public void setModelValue(HasDataValue widget, DataModel model, String path) { 678 binding.setModelValue(widget, model, path); 679 } 680 681 @Override 682 public void setWidgetValue(final HasDataValue widget, DataModel model, String path) { 683 DataModel middleManModel = new DataModel(); 684 if (model != null && model.getRoot() != null) { 685 middleManModel = new DataModel(model.getDefinition(), model.getRoot().copy()); 686 } 687 Metadata rangeEditMetaData = model.getMetadata( 688 QueryPath.parse(CommonWidgetConstants.CLU_SET_CLU_SET_RANGE_EDIT_FIELD)); 689 Data membershipQueryData = (Data)model.get(path); 690 MembershipQueryInfo membershipQueryInfo = (membershipQueryData == null)? 691 null : CluSetRangeModelUtil.INSTANCE.toMembershipQueryInfo(membershipQueryData); 692 if (membershipQueryInfo != null) { 693 String selectedSearchTypeKey = membershipQueryInfo.getSearchTypeKey(); 694 List<LookupMetadata> lookupMDs = new ArrayList<LookupMetadata>(); 695 List<SearchParamInfo> searchParams = membershipQueryInfo.getQueryParamValues(); 696 lookupMDs.add(rangeEditMetaData.getInitialLookup()); 697 LookupMetadata lookupMetadata = findLookupMetadataByLookupId(selectedSearchTypeKey, 698 lookupMDs, searchParams); 699 if (lookupMetadata == null || 700 !nullSafeEquals(lookupMetadata.getName(), 701 selectedSearchTypeKey)) { 702 lookupMetadata = findLookupMetadataByLookupId(selectedSearchTypeKey, 703 rangeEditMetaData.getAdditionalLookups(), searchParams); 704 } 705 706 SearchRequestInfo searchRequest = new SearchRequestInfo(); 707 searchRequest.setSearchKey(selectedSearchTypeKey); 708 // if () 709 searchRequest.setParams(searchParams); 710 searchRequest.setSortColumn(lookupMetadata.getResultSortKey()); 711 712 // if (showCluRangeDetailsHandlerRegs != null) { 713 // for (HandlerRegistration showCluRangeDetailsHandlerReg : showCluRangeDetailsHandlerRegs) { 714 // showCluRangeDetailsHandlerReg.removeHandler(); 715 // } 716 // showCluRangeDetailsHandlerRegs.clear(); 717 // } 718 addClusetItemViewHandler(clusetRangeModelHelper, 719 (KSItemLabel)widget, 720 lookupMetadata, 721 membershipQueryData, 722 searchRequest); 723 ((KSItemLabel)widget).setHighlighted(true); 724 new Timer() { 725 @Override 726 public void run() { 727 ((KSItemLabel)widget).setHighlighted(false); 728 } 729 }.schedule(5000); 730 } 731 binding.setWidgetValue(widget, middleManModel, path); 732 } 733 } 734 }