View Javadoc

1   package org.kuali.student.lum.lu.ui.tools.client.configuration;
2   
3   import java.util.Date;
4   import java.util.List;
5   
6   import org.kuali.student.common.ui.client.application.Application;
7   import org.kuali.student.common.ui.client.application.KSAsyncCallback;
8   import org.kuali.student.common.ui.client.configurable.mvc.FieldDescriptor;
9   import org.kuali.student.common.ui.client.configurable.mvc.FieldDescriptorReadOnly;
10  import org.kuali.student.common.ui.client.configurable.mvc.SectionTitle;
11  import org.kuali.student.common.ui.client.configurable.mvc.binding.ModelWidgetBinding;
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.Controller;
18  import org.kuali.student.common.ui.client.mvc.DataModel;
19  import org.kuali.student.common.ui.client.mvc.DataModelDefinition;
20  import org.kuali.student.common.ui.client.mvc.history.HistoryManager;
21  import org.kuali.student.common.ui.client.widgets.KSDatePicker;
22  import org.kuali.student.common.ui.client.widgets.KSLabel;
23  import org.kuali.student.common.ui.client.widgets.KSTextArea;
24  import org.kuali.student.common.ui.client.widgets.field.layout.element.MessageKeyInfo;
25  import org.kuali.student.common.ui.client.widgets.headers.KSDocumentHeader;
26  import org.kuali.student.common.ui.client.widgets.search.KSPicker;
27  import org.kuali.student.common.ui.client.widgets.search.SelectedResults;
28  import org.kuali.student.common.ui.client.widgets.table.summary.SummaryTableFieldBlock;
29  import org.kuali.student.common.ui.client.widgets.table.summary.SummaryTableFieldRow;
30  import org.kuali.student.common.ui.client.widgets.table.summary.SummaryTableSection;
31  import org.kuali.student.lum.common.client.lu.LUUIConstants;
32  import org.kuali.student.lum.common.client.widgets.CluSetDetailsWidget;
33  import org.kuali.student.lum.common.client.widgets.CluSetEditorWidget;
34  import org.kuali.student.lum.common.client.widgets.CluSetManagementRpcService;
35  import org.kuali.student.lum.common.client.widgets.CluSetManagementRpcServiceAsync;
36  import org.kuali.student.lum.common.client.widgets.CluSetRetriever;
37  import org.kuali.student.lum.common.client.widgets.CluSetRetrieverImpl;
38  import org.kuali.student.r1.common.assembly.data.LookupMetadata;
39  import org.kuali.student.r1.common.assembly.data.Metadata;
40  import org.kuali.student.r1.common.assembly.data.QueryPath;
41  
42  import com.google.gwt.core.client.GWT;
43  import com.google.gwt.dom.client.Style;
44  import com.google.gwt.event.dom.client.ClickEvent;
45  import com.google.gwt.event.dom.client.ClickHandler;
46  import com.google.gwt.i18n.client.DateTimeFormat;
47  import com.google.gwt.user.client.Window;
48  import com.google.gwt.user.client.rpc.AsyncCallback;
49  import com.google.gwt.user.client.ui.Anchor;
50  import com.google.gwt.user.client.ui.HasText;
51  import com.google.gwt.user.client.ui.SimplePanel;
52  import com.google.gwt.user.client.ui.Widget;
53  
54  public class ClusetView extends VerticalSectionView {
55  
56      protected CluSetManagementRpcServiceAsync cluSetManagementRpcServiceAsync = GWT.create(CluSetManagementRpcService.class);
57      protected CluSetRetriever cluSetRetriever = new CluSetRetrieverImpl();
58      protected DataModelDefinition modelDefinition;
59      protected DataModelDefinition searchDefinition;
60      protected String selectedCluSetId;
61      protected CluSetsManagementViews viewEnum;
62      protected SimplePanel cluSetDisplay = new SimplePanel();
63      protected CluSetEditorWidget cluSetEditor;
64      protected String cluSetType;
65  
66      protected KSLabel titleLabel = new KSLabel();
67  
68      public void afterModelIsLoaded(DataModel cluSetModel) {
69          titleLabel.setText(cluSetModel.<String>get("name"));
70      }
71  
72      public enum CluSetsManagementViews {
73          MAIN,
74          CREATE,
75          EDIT,
76          VIEW
77      }
78  
79      public ClusetView() {
80          super();
81      }
82  
83      public ClusetView(Enum<?> viewEnum, String name, String modelId,
84              boolean showTitle) {
85          super(viewEnum, name, modelId, showTitle);
86      }
87  
88      public ClusetView(Enum<?> viewEnum, String name, String modelId,
89              Widget titleWidget) {
90          super(viewEnum, name, modelId, titleWidget);
91      }
92  
93      public ClusetView(Enum<?> viewEnum, String name, String modelId) {
94          super(viewEnum, name, modelId);
95      }
96  
97      public void init(CluSetsManagementViews clusetViewEnum, String name, String modelId, final Callback<Boolean> onReady) {
98          init(clusetViewEnum, name, modelId, false, onReady);
99      }
100 
101     public void init(final CluSetsManagementViews clusetViewEnum, String name,
102             String clusetMgtModel, boolean showTitle, final Callback<Boolean> onReady) {
103         super.init(clusetViewEnum, name, modelId, showTitle);
104         cluSetType = "kuali.cluSet.type.CreditCourse";
105         if (clusetViewEnum == CluSetsManagementViews.CREATE ||
106                 clusetViewEnum == CluSetsManagementViews.EDIT) {
107             cluSetEditor = new CluSetEditorWidget(
108                     new CluSetRetrieverImpl(),
109                     clusetViewEnum, name, modelId, true, null,
110                     cluSetType, false);
111         }
112         viewEnum = clusetViewEnum;
113         cluSetManagementRpcServiceAsync.getMetadata("courseSet", null, new KSAsyncCallback<Metadata>() {
114             @Override
115             public void handleFailure(Throwable caught) {
116                 Window.alert("Failed to retrieve cluset definition");
117             }
118 
119             @Override
120             public void onSuccess(Metadata result) {
121                 DataModelDefinition def = new DataModelDefinition(result);
122                 setModelDefinition(def);
123                 cluSetManagementRpcServiceAsync.getMetadata("search", null, new AsyncCallback<Metadata>() {
124                     @Override
125                     public void onFailure(Throwable caught) {
126                         Window.alert("Failed to retrieve searchDefinition");
127                     }
128 
129                     @Override
130                     public void onSuccess(Metadata result) {
131                         setSearchDefinition(new DataModelDefinition(result));
132                         setupView(clusetViewEnum);
133                         if (onReady != null) {
134                             onReady.exec(new Boolean(true));
135                         }
136                     }
137                 });
138             }
139         });
140         setStyles();
141     }
142 
143     private void setStyles() {
144         titleLabel.addStyleName("cluSetTitle");
145     }
146 
147     private void setModelDefinition(DataModelDefinition modelDefinition) {
148         this.modelDefinition = modelDefinition;
149     }
150 
151     private void setSearchDefinition(DataModelDefinition searchDefinition) {
152         this.searchDefinition = searchDefinition;
153     }
154 
155     @Override
156     public void beforeShow(Callback<Boolean> onReadyCallback) {
157         super.beforeShow(onReadyCallback);
158         if (viewEnum == CluSetsManagementViews.VIEW) {
159             refreshCluSetDisplay();
160         }
161     }
162 
163     private void refreshCluSetDisplay() {
164         if (this.selectedCluSetId != null) {
165             CluSetDetailsWidget clusetDetailsWidget =
166                     new CluSetDetailsWidget(selectedCluSetId, cluSetRetriever);
167             cluSetDisplay.clear();
168             cluSetDisplay.setWidget(clusetDetailsWidget);
169         }
170     }
171 
172     private void setupView(CluSetsManagementViews clusetViewEnum) {
173         if (clusetViewEnum == CluSetsManagementViews.CREATE ||
174                 clusetViewEnum == CluSetsManagementViews.EDIT) {
175             setupCreateEditClusetView();
176         } else if (clusetViewEnum == CluSetsManagementViews.MAIN) {
177             setupMainView();
178         } else if (clusetViewEnum == CluSetsManagementViews.VIEW) {
179             setupViewClusetView();
180         }
181     }
182 
183     @Override
184     public void onHistoryEvent(String historyStack) {
185         super.onHistoryEvent(historyStack);
186         CluSetsManagementController cluSetsManagementController =
187                 (CluSetsManagementController) getController();
188         selectedCluSetId = HistoryManager.getTokenMap(historyStack).get("docId");
189         cluSetsManagementController.getMainView().setSelectedCluSetId(selectedCluSetId);
190         cluSetsManagementController.showView(CluSetsManagementViews.VIEW);
191     }
192 
193     protected void setupViewClusetView() {
194         Anchor editCluSet = new Anchor("Edit Course Set");
195         editCluSet.addClickHandler(new ClickHandler() {
196             @Override
197             public void onClick(ClickEvent event) {
198                 Controller parentController = getController();
199                 parentController.showView(CluSetsManagementViews.EDIT);
200             }
201         });
202         addWidget(titleLabel);
203         this.addWidget(editCluSet);
204         Section generalClusInfoSection = new VerticalSection();
205         KSLabel cluSetTitle = new KSLabel();
206         cluSetTitle.getElement().getStyle().setProperty("fontWeight", "bold");
207         cluSetTitle.getElement().getStyle().setProperty("fontSize", "16px");
208         cluSetTitle.getElement().getStyle().setProperty("borderBotton", "1px solid #D8D8D8");
209 
210         addField(generalClusInfoSection,
211                 ToolsConstants.CLU_SET_NAME_FIELD,
212                 null,
213                 cluSetTitle,
214                 null);
215 //        addField(generalClusInfoSection, 
216 //                ToolsConstants.CLU_SET_DESCRIPTION_FIELD, 
217 //                generateMessageInfo(ToolsConstants.DESCRIPTION),
218 //                new KSLabel(),
219 //                null);
220 //        addField(generalClusInfoSection, 
221 //                ToolsConstants.CLU_SET_EXP_DATE_FIELD, 
222 //                generateMessageInfo(ToolsConstants.EXPIRATION_DATE),
223 //                new KSLabel(),
224 //                null);
225         this.addSection(setupGeneralClusInfoSection());
226 //        this.addSection(generalClusInfoSection);
227         this.addWidget(new KSLabel("Items in this Course Set"));
228         this.addWidget(cluSetDisplay);
229         this.setStyleName("standard-content-padding");
230     }
231 
232     protected SummaryTableSection setupGeneralClusInfoSection() {
233         SummaryTableSection result = GWT.create(SummaryTableSection.class);
234         result.init(getController());
235         result.setEditable(false);
236 
237         SummaryTableFieldBlock block = new SummaryTableFieldBlock();
238 //        block.addEditingHandler(new EditHandler(CourseSections.COURSE_INFO));
239 //        block.setTitle(getLabel(LUConstants.INFORMATION_LABEL_KEY));
240         block.addSummaryTableFieldRow(getFieldRow(ToolsConstants.CLU_SET_DESCRIPTION_FIELD, generateMessageInfo(ToolsConstants.DESCRIPTION)));
241         SummaryTableFieldRow expDateRow = getFieldRow(ToolsConstants.CLU_SET_EXP_DATE_FIELD,
242                 generateMessageInfo(ToolsConstants.EXPIRATION_DATE), null, null, null,
243                 new ModelWidgetBindingSupport<HasText>() {
244                     public String dateToString(Date date) {
245                         String result = null;
246                         DateTimeFormat format = DateTimeFormat.getFormat("MM/dd/yyyy");
247                         result = format.format(date);
248 
249                         return result;
250                     }
251 
252                     @Override
253                     public void setModelValue(HasText widget, DataModel model, String path) {
254                         // not implementing here since this value should not be edited through this widget
255                     }
256 
257                     @Override
258                     public void setWidgetValue(HasText widget, DataModel model, String path) {
259                         try {
260                             QueryPath qPath = QueryPath.parse(path);
261 
262                             Object value = null;
263                             if (model != null) {
264                                 value = model.get(qPath);
265                             }
266 
267                             if (value != null && widget != null) {
268                                 if (value instanceof Date) {
269                                     widget.setText(dateToString((Date) value));
270                                 } else {
271                                     widget.setText(value.toString());
272                                 }
273                             } else if (value == null && widget != null) {
274                                 widget.setText("");
275                             }
276                         } catch (Exception e) {
277                             GWT.log("Error setting widget value for: " + path, e);
278                         }
279                     }
280 
281                 }
282                 , false);
283         block.addSummaryTableFieldRow(expDateRow);
284 
285         result.addSummaryTableFieldBlock(block);
286         return result;
287     }
288 
289     protected SummaryTableFieldRow getFieldRow(String fieldKey, MessageKeyInfo messageKey) {
290         return getFieldRow(fieldKey, messageKey, null, null, null, null, false);
291     }
292 
293     protected SummaryTableFieldRow getFieldRow(String fieldKey, MessageKeyInfo messageKey, boolean optional) {
294         return getFieldRow(fieldKey, messageKey, null, null, null, null, optional);
295     }
296 
297     protected SummaryTableFieldRow getFieldRow(String fieldKey, MessageKeyInfo messageKey, Widget widget, Widget widget2, String parentPath, ModelWidgetBinding<?> binding, boolean optional) {
298         QueryPath path = QueryPath.concat(parentPath, fieldKey);
299         Metadata meta = modelDefinition.getMetadata(path);
300 
301         FieldDescriptorReadOnly fd = new FieldDescriptorReadOnly(path.toString(), messageKey, meta);
302         if (widget != null) {
303             fd.setFieldWidget(widget);
304         }
305         if (binding != null) {
306             fd.setWidgetBinding(binding);
307         }
308         fd.setOptional(optional);
309 
310         FieldDescriptorReadOnly fd2 = new FieldDescriptorReadOnly(path.toString(), messageKey, meta);
311         if (widget2 != null) {
312             fd2.setFieldWidget(widget2);
313         }
314         if (binding != null) {
315             fd2.setWidgetBinding(binding);
316         }
317         fd2.setOptional(optional);
318 
319         SummaryTableFieldRow fieldRow = new SummaryTableFieldRow(fd, fd2);
320 
321         return fieldRow;
322     }
323 
324     private void setupMainView() {
325         this.addStyleName("blockLayout");
326         KSDocumentHeader header = new KSDocumentHeader();
327         header.setTitle("Course Set Management");
328         this.addWidget(header);
329 
330         Anchor createCluSet = new Anchor("<h2 class=\"contentBlock-title\">Create Course Set</h2>", true);
331         createCluSet.addClickHandler(new ClickHandler() {
332             @Override
333             public void onClick(ClickEvent event) {
334                 getController().showView(CluSetsManagementViews.CREATE);
335             }
336         });
337         this.addWidget(createCluSet);
338         this.addWidget(new KSLabel("Build a new Course set from courses, Course Sets, " +
339                 "or specific criteria."));
340 
341         Picker cluSetPicker = configureSearch(ToolsConstants.SEARCH_COURSE_SET);
342         cluSetPicker.addBasicSelectionCompletedCallback(new Callback<SelectedResults>() {
343             @Override
344             public void exec(SelectedResults result) {
345                 if (result != null && result.getReturnKey() != null && result.getReturnKey().trim().length() > 0) {
346                     selectedCluSetId = result.getReturnKey();
347                     Controller parentController = getController();
348                     parentController.showView(CluSetsManagementViews.VIEW);
349                 }
350             }
351         });
352         SectionTitle modifyCluSetTitle = SectionTitle.generateH2Title("View or Modify Course Sets");
353         modifyCluSetTitle.addStyleName("contentBlock-title");
354         modifyCluSetTitle.getElement().getStyle().setPaddingTop(40, Style.Unit.PX);
355         this.addWidget(modifyCluSetTitle);
356         this.addWidget(cluSetPicker);
357     }
358 
359     public String getSelectedCluSetId() {
360         return selectedCluSetId;
361     }
362 
363     public void setSelectedCluSetId(String selectedCluSetId) {
364         this.selectedCluSetId = selectedCluSetId;
365     }
366 
367     protected void setupCreateEditClusetView() {
368         String contextName = (cluSetType != null && cluSetType.equals("kuali.cluSet.type.Program")) ?
369                 "Program" : "Course";
370         VerticalSection defineCluSet = initSection(getH3Title(ToolsConstants.DEFINE_CLUSET + contextName), true);
371         
372         addFields(defineCluSet,contextName);
373 
374         KSLabel spacer = new KSLabel();
375         spacer.setHeight("20px");
376         this.addSection(cluSetEditor);
377         this.addWidget(spacer);
378         this.addSection(defineCluSet);
379         this.setStyleName("standard-content-padding");
380     }
381     
382     protected void addFields(VerticalSection defineCluSet, String contextName) {
383         addField(defineCluSet, ToolsConstants.CLU_SET_ORGANIZATION_FIELD, generateMessageInfo(ToolsConstants.ORGANIZATION), null, null);
384         addField(defineCluSet, ToolsConstants.CLU_SET_NAME_FIELD, generateMessageInfo(ToolsConstants.TITLE + contextName), null, null);
385         addField(defineCluSet, ToolsConstants.CLU_SET_DESCRIPTION_FIELD, generateMessageInfo(ToolsConstants.DESCRIPTION), new KSTextArea(), null);
386         addField(defineCluSet, ToolsConstants.CLU_SET_EFF_DATE_FIELD, generateMessageInfo(ToolsConstants.EFFECTIVE_DATE), new KSDatePicker(), null);
387         addField(defineCluSet, ToolsConstants.CLU_SET_EXP_DATE_FIELD, generateMessageInfo(ToolsConstants.EXPIRATION_DATE), new KSDatePicker(), null);
388     }
389 
390     protected static VerticalSection initSection(SectionTitle title, boolean withDivider) {
391         VerticalSection section = new VerticalSection(title);
392         section.addStyleName(LUUIConstants.STYLE_SECTION);
393         if (withDivider)
394             section.addStyleName(LUUIConstants.STYLE_SECTION_DIVIDER);
395         return section;
396     }
397 
398     private String getLabel(String labelKey) {
399         return Application.getApplicationContext().getUILabel("clusetmanagement", "clusetmanagement", "draft", labelKey);
400     }
401 
402     protected SectionTitle getH3Title(String labelKey) {
403         return SectionTitle.generateH3Title(getLabel(labelKey));
404     }
405 
406     protected MessageKeyInfo generateMessageInfo(String labelKey) {
407         return new MessageKeyInfo("clusetmanagement", "clusetmanagement", "draft", labelKey);
408     }
409 
410     private FieldDescriptor getFieldDescriptor(
411             String fieldKey,
412             MessageKeyInfo messageKey,
413             Widget widget,
414             String parentPath) {
415         QueryPath path = QueryPath.concat(parentPath, fieldKey);
416         Metadata meta = modelDefinition.getMetadata(path);
417         FieldDescriptor fd;
418         if (widget != null) {
419             fd = new FieldDescriptor(path.toString(), messageKey, meta, widget);
420         } else {
421             fd = new FieldDescriptor(path.toString(), messageKey, meta);
422         }
423         return fd;
424     }
425 
426     protected FieldDescriptor addField(Section section,
427                                      String fieldKey,
428                                      MessageKeyInfo messageKey,
429                                      Widget widget,
430                                      String parentPath) {
431         FieldDescriptor fd = getFieldDescriptor(fieldKey, messageKey, widget, parentPath);
432         section.addField(fd);
433         return fd;
434     }
435 
436     private Picker configureSearch(String fieldKey) {
437         QueryPath path = QueryPath.concat(null, fieldKey);
438         Metadata metaData = searchDefinition.getMetadata(path);
439         Picker picker = new Picker(metaData.getInitialLookup(), metaData.getAdditionalLookups());
440         return picker;
441     }
442 
443     public static class Picker extends KSPicker {
444 
445         private String name;
446         private LookupMetadata initLookupMetadata;
447         private List<LookupMetadata> additionalLookupMetadata;
448 
449         public Picker(LookupMetadata inLookupMetadata, List<LookupMetadata> additionalLookupMetadata) {
450             super.init(inLookupMetadata, additionalLookupMetadata);
451             this.initLookupMetadata = inLookupMetadata;
452             this.additionalLookupMetadata = additionalLookupMetadata;
453         }
454 
455         public String getName() {
456             return name;
457         }
458 
459         public void setName(String name) {
460             this.name = name;
461         }
462 
463         public LookupMetadata getInitLookupMetadata() {
464             return initLookupMetadata;
465         }
466 
467         public void setInitLookupMetadata(LookupMetadata initLookupMetadata) {
468             this.initLookupMetadata = initLookupMetadata;
469         }
470 
471         public List<LookupMetadata> getAdditionalLookupMetadata() {
472             return additionalLookupMetadata;
473         }
474 
475         public void setAdditionalLookupMetadata(List<LookupMetadata> additionalLookupMetadata) {
476             this.additionalLookupMetadata = additionalLookupMetadata;
477         }
478 
479     }
480 
481     @Override
482     public void setController(Controller controller) {
483         super.setController(controller);
484         if (cluSetEditor != null) {
485             cluSetEditor.setController(controller);
486         }
487     }
488 
489 }