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.application.Application;
9 import org.kuali.student.common.ui.client.configurable.mvc.FieldDescriptor;
10 import org.kuali.student.common.ui.client.configurable.mvc.WidgetConfigInfo;
11 import org.kuali.student.common.ui.client.configurable.mvc.binding.HasDataValueBinding;
12 import org.kuali.student.common.ui.client.configurable.mvc.binding.ModelWidgetBindingSupport;
13 import org.kuali.student.common.ui.client.configurable.mvc.sections.Section;
14 import org.kuali.student.common.ui.client.configurable.mvc.sections.VerticalSection;
15 import org.kuali.student.common.ui.client.configurable.mvc.views.VerticalSectionView;
16 import org.kuali.student.common.ui.client.mvc.Callback;
17 import org.kuali.student.common.ui.client.mvc.DataModel;
18 import org.kuali.student.common.ui.client.mvc.DataModelDefinition;
19 import org.kuali.student.common.ui.client.mvc.HasDataValue;
20 import org.kuali.student.common.ui.client.widgets.KSDropDown;
21 import org.kuali.student.common.ui.client.widgets.KSItemLabel;
22 import org.kuali.student.common.ui.client.widgets.KSLabel;
23 import org.kuali.student.common.ui.client.widgets.field.layout.element.MessageKeyInfo;
24 import org.kuali.student.common.ui.client.widgets.layout.VerticalFlowPanel;
25 import org.kuali.student.common.ui.client.widgets.list.KSSelectedList;
26 import org.kuali.student.common.ui.client.widgets.list.SelectionChangeEvent;
27 import org.kuali.student.common.ui.client.widgets.list.SelectionChangeHandler;
28 import org.kuali.student.common.ui.client.widgets.list.impl.SimpleListItems;
29 import org.kuali.student.common.ui.client.widgets.menus.KSListPanel;
30 import org.kuali.student.common.ui.client.widgets.progress.BlockingTask;
31 import org.kuali.student.common.ui.client.widgets.progress.KSBlockingProgressIndicator;
32 import org.kuali.student.common.ui.client.widgets.search.KSPicker;
33 import org.kuali.student.r1.common.assembly.data.Data;
34 import org.kuali.student.r1.common.assembly.data.Data.DataValue;
35 import org.kuali.student.r1.common.assembly.data.Data.Value;
36 import org.kuali.student.r1.common.assembly.data.LookupMetadata;
37 import org.kuali.student.r1.common.assembly.data.LookupParamMetadata;
38 import org.kuali.student.r1.common.assembly.data.Metadata;
39 import org.kuali.student.r1.common.assembly.data.QueryPath;
40 import org.kuali.student.r2.core.search.dto.SearchParamInfo;
41 import org.kuali.student.r2.core.search.dto.SearchRequestInfo;
42 import org.kuali.student.r2.lum.clu.dto.MembershipQueryInfo;
43
44 import com.google.gwt.core.client.GWT;
45 import com.google.gwt.dom.client.Style;
46 import com.google.gwt.event.dom.client.ClickEvent;
47 import com.google.gwt.event.dom.client.ClickHandler;
48 import com.google.gwt.event.logical.shared.CloseEvent;
49 import com.google.gwt.event.logical.shared.CloseHandler;
50 import com.google.gwt.event.shared.HandlerRegistration;
51 import com.google.gwt.user.client.Timer;
52 import com.google.gwt.user.client.ui.HTML;
53 import com.google.gwt.user.client.ui.Panel;
54 import com.google.gwt.user.client.ui.Widget;
55
56 public class CluSetEditorWidget extends VerticalSectionView {
57
58 private List<KSSelectedListPanelPair> selectedListPanelPairs = new ArrayList<KSSelectedListPanelPair>();
59 private DataModelDefinition modelDefinition;
60
61 private final Map<String, HandlerRegistration> showCluRangeDetailsHandlerRegs = new HashMap<String, HandlerRegistration>();
62 private List<KSItemLabelPanelPair> itemLabelPanelPairs = new ArrayList<KSItemLabelPanelPair>();
63 protected static String cluSetType;
64 private String metadataId;
65 private static Map<String, DataModelDefinition> modelDefinitionCache = new HashMap<String, DataModelDefinition>();
66 private BlockingTask initializeTask = new BlockingTask("Initializing");
67 protected static boolean singularCluOnly;
68 private KSSelectedList approvedClusSelection;
69
70 private enum CluSetManagementField {
71 APPROVED, PROPOSED, CLUSETS, RANGE
72 }
73
74 public CluSetEditorWidget() {
75 super();
76 }
77
78 public CluSetEditorWidget(CluSetRetriever cluSetRetriever, Enum<?> viewEnum,
79 String name, String modelId, boolean showTitle,
80 final Callback<Boolean> onReady, String cluSetType, boolean singularCluOnly) {
81 super(viewEnum, name, modelId, showTitle);
82 CluSetEditorWidget.cluSetType = cluSetType;
83 CluSetEditorWidget.singularCluOnly = singularCluOnly;
84 if (cluSetType != null && cluSetType.equals("kuali.cluSet.type.Program")) {
85 this.metadataId = "programSet";
86 } else {
87 this.metadataId = "courseSet";
88 }
89 KSBlockingProgressIndicator.addTask(initializeTask);
90 if (modelDefinitionCache.get(metadataId) == null) {
91 cluSetRetriever.getMetadata(metadataId, new Callback<Metadata>(){
92 @Override
93 public void exec(Metadata result) {
94 DataModelDefinition def = new DataModelDefinition(result);
95 modelDefinitionCache.put(metadataId, def);
96 setDef(def);
97 setupEditor();
98 if (onReady != null) {
99 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
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
142
143
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
154
155
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
182
183
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
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
219
220
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
244
245
246
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
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
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
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
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
709 searchRequest.setParams(searchParams);
710 searchRequest.setSortColumn(lookupMetadata.getResultSortKey());
711
712
713
714
715
716
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 }