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