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.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.core.assembly.data.Data;
034 import org.kuali.student.core.assembly.data.LookupMetadata;
035 import org.kuali.student.core.assembly.data.LookupParamMetadata;
036 import org.kuali.student.core.assembly.data.Metadata;
037 import org.kuali.student.core.assembly.data.QueryPath;
038 import org.kuali.student.core.assembly.data.Data.DataValue;
039 import org.kuali.student.core.assembly.data.Data.Value;
040 import org.kuali.student.core.search.dto.SearchParam;
041 import org.kuali.student.core.search.dto.SearchRequest;
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 }