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