View Javadoc

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