1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.student.lum.lu.ui.tools.client.configuration;
17
18 import java.util.List;
19
20 import org.kuali.student.common.ui.client.application.KSAsyncCallback;
21 import org.kuali.student.common.ui.client.configurable.mvc.layouts.BasicLayout;
22 import org.kuali.student.common.ui.client.configurable.mvc.sections.Section;
23 import org.kuali.student.common.ui.client.event.SaveActionEvent;
24 import org.kuali.student.common.ui.client.event.SaveActionHandler;
25 import org.kuali.student.common.ui.client.mvc.Callback;
26 import org.kuali.student.common.ui.client.mvc.Controller;
27 import org.kuali.student.common.ui.client.mvc.DataModel;
28 import org.kuali.student.common.ui.client.mvc.DataModelDefinition;
29 import org.kuali.student.common.ui.client.mvc.ModelProvider;
30 import org.kuali.student.common.ui.client.mvc.ModelRequestCallback;
31 import org.kuali.student.common.ui.client.mvc.View;
32 import org.kuali.student.common.ui.client.mvc.WorkQueue;
33 import org.kuali.student.common.ui.client.mvc.WorkQueue.WorkItem;
34 import org.kuali.student.common.ui.client.service.DataSaveResult;
35 import org.kuali.student.common.ui.client.widgets.KSLabel;
36 import org.kuali.student.common.ui.client.widgets.KSLightBox;
37 import org.kuali.student.common.ui.client.widgets.KSProgressIndicator;
38 import org.kuali.student.common.ui.client.widgets.buttongroups.ButtonEnumerations;
39 import org.kuali.student.common.ui.client.widgets.buttongroups.OkGroup;
40 import org.kuali.student.common.ui.client.widgets.buttongroups.ButtonEnumerations.ButtonEnum;
41 import org.kuali.student.common.ui.client.widgets.buttongroups.ButtonEnumerations.OkEnum;
42 import org.kuali.student.common.ui.client.widgets.field.layout.button.ActionCancelGroup;
43 import org.kuali.student.common.ui.client.widgets.progress.BlockingTask;
44 import org.kuali.student.common.ui.client.widgets.progress.KSBlockingProgressIndicator;
45 import org.kuali.student.core.assembly.data.Data;
46 import org.kuali.student.core.assembly.data.Metadata;
47 import org.kuali.student.core.validation.dto.ValidationResultInfo;
48 import org.kuali.student.core.validation.dto.ValidationResultInfo.ErrorLevel;
49 import org.kuali.student.lum.common.client.widgets.CluSetHelper;
50 import org.kuali.student.lum.common.client.widgets.CluSetManagementRpcService;
51 import org.kuali.student.lum.common.client.widgets.CluSetManagementRpcServiceAsync;
52
53 import com.google.gwt.core.client.GWT;
54 import com.google.gwt.dom.client.Style;
55 import com.google.gwt.user.client.Window;
56 import com.google.gwt.user.client.ui.Widget;
57
58 public class CluSetsManagementController extends BasicLayout {
59
60 private final DataModel cluSetModel = new DataModel();
61 private WorkQueue cluSetModelRequestQueue;
62
63 private ClusetView mainView;
64 private ClusetView createClusetView;
65 private ClusetView editClusetView;
66 private ClusetView viewClusetView;
67
68 private boolean initialized = false;
69 CluSetManagementRpcServiceAsync cluSetManagementRpcServiceAsync = GWT.create(CluSetManagementRpcService.class);
70 public static final String CLUSET_MGT_MODEL = "cluSetManagementModel";
71 private BlockingTask retrievingTask = new BlockingTask("Retrieving ...");
72
73 final KSLightBox progressWindow = new KSLightBox();
74
75
76 public CluSetsManagementController(){
77 super(CluSetsManagementController.class.getName());
78 setName("Course Set Management");
79 initialize();
80 }
81
82 public ClusetView getMainView() {
83 return mainView;
84 }
85
86 @Override
87 public <V extends Enum<?>> void showView(final V viewType) {
88 if (viewType == ClusetView.CluSetsManagementViews.EDIT) {
89 final String cluSetId = mainView.getSelectedCluSetId();
90 editClusetView.setSelectedCluSetId(cluSetId);
91 viewClusetView.setSelectedCluSetId(cluSetId);
92 if (cluSetId != null) {
93 KSBlockingProgressIndicator.addTask(retrievingTask);
94 cluSetManagementRpcServiceAsync.getData(cluSetId, new KSAsyncCallback<Data>() {
95 @Override
96 public void handleFailure(Throwable caught) {
97 KSBlockingProgressIndicator.removeTask(retrievingTask);
98 Window.alert("Failed to retrieve cluset with id" + cluSetId);
99 }
100 @Override
101 public void onSuccess(Data result) {
102 try {
103 cluSetModel.setRoot(result);
104 editClusetView.updateView(cluSetModel);
105 CluSetsManagementController.super.showView(viewType);
106 } finally {
107 KSBlockingProgressIndicator.removeTask(retrievingTask);
108 }
109 }
110 });
111 }
112 } else if (viewType == ClusetView.CluSetsManagementViews.VIEW) {
113 final String cluSetId = mainView.getSelectedCluSetId();
114 editClusetView.setSelectedCluSetId(cluSetId);
115 viewClusetView.setSelectedCluSetId(cluSetId);
116 if (cluSetId != null) {
117 KSBlockingProgressIndicator.addTask(retrievingTask);
118 cluSetManagementRpcServiceAsync.getData(cluSetId, new KSAsyncCallback<Data>() {
119 @Override
120 public void handleFailure(Throwable caught) {
121 KSBlockingProgressIndicator.removeTask(retrievingTask);
122 Window.alert("Failed to retrieve cluset with id" + cluSetId);
123 }
124 @Override
125 public void onSuccess(Data result) {
126 try {
127 cluSetModel.setRoot(result);
128 viewClusetView.updateView(cluSetModel);
129 CluSetsManagementController.super.showView(viewType);
130 } finally {
131 KSBlockingProgressIndicator.removeTask(retrievingTask);
132 }
133 }
134 });
135 }
136 } else {
137 cluSetModel.setRoot(new Data());
138 super.showView(viewType);
139 }
140 }
141
142 private Widget getButtonPanel() {
143 ActionCancelGroup actionCancel = new ActionCancelGroup(
144 ButtonEnumerations.SaveCancelEnum.SAVE,
145 ButtonEnumerations.SaveCancelEnum.CANCEL);
146 actionCancel.addCallback(new Callback<ButtonEnumerations.ButtonEnum>() {
147 @Override
148 public void exec(ButtonEnum result) {
149 if (result == ButtonEnumerations.SaveCancelEnum.SAVE) {
150 fireApplicationEvent(new SaveActionEvent());
151 } else if (result == ButtonEnumerations.SaveCancelEnum.CANCEL) {
152 showView(ClusetView.CluSetsManagementViews.MAIN);
153 }
154 }
155 });
156 return actionCancel;
157 }
158
159 private void initialize() {
160 super.setDefaultModelId(CLUSET_MGT_MODEL);
161
162
163
164
165 createClusetView = new ClusetView(ClusetView.CluSetsManagementViews.CREATE,
166 "Build Course Set", CLUSET_MGT_MODEL, new Callback<Boolean>() {
167 @Override
168 public void exec(Boolean result) {
169 if (result == true) {
170 Widget buttonPanel = getButtonPanel();
171 buttonPanel.getElement().getStyle().setPaddingTop(50, Style.Unit.PX);
172 createClusetView.addWidget(buttonPanel);
173 }
174 }
175 });
176 editClusetView = new ClusetView(ClusetView.CluSetsManagementViews.EDIT,
177 "Edit Course Set", CLUSET_MGT_MODEL, new Callback<Boolean>() {
178 @Override
179 public void exec(Boolean result) {
180 if (result == true) {
181 Widget buttonPanel = getButtonPanel();
182 buttonPanel.getElement().getStyle().setPaddingTop(50, Style.Unit.PX);
183 editClusetView.addWidget(buttonPanel);
184 }
185 }
186 });
187 viewClusetView = new ClusetView(ClusetView.CluSetsManagementViews.VIEW,
188 "View Course Set", CLUSET_MGT_MODEL, null);
189
190 mainView = new ClusetView(ClusetView.CluSetsManagementViews.MAIN,
191 "", CLUSET_MGT_MODEL, null);
192
193 setDefaultView(ClusetView.CluSetsManagementViews.MAIN);
194 addView(createClusetView);
195 addView(editClusetView);
196 addView(viewClusetView);
197 addView(mainView);
198
199 super.registerModel(CLUSET_MGT_MODEL, new ModelProvider<DataModel>() {
200
201 @Override
202 public void requestModel(final ModelRequestCallback<DataModel> callback) {
203 if (cluSetModelRequestQueue == null){
204 cluSetModelRequestQueue = new WorkQueue();
205 }
206
207 WorkItem workItem = new WorkItem(){
208 @Override
209 public void exec(Callback<Boolean> workCompleteCallback) {
210 if (cluSetModel.getRoot() == null || cluSetModel.getRoot().size() == 0){
211 cluSetModel.setRoot(new Data());
212 }
213 callback.onModelReady(cluSetModel);
214 workCompleteCallback.exec(true);
215
216 }
217 };
218 cluSetModelRequestQueue.submit(workItem);
219 }
220
221 });
222
223 }
224
225 private void init(final Callback<Boolean> onReadyCallback) {
226 KSProgressIndicator progressInd = new KSProgressIndicator();
227 progressInd.setText("Loading");
228 progressInd.show();
229 progressWindow.setWidget(progressInd);
230
231 if (initialized) {
232 onReadyCallback.exec(true);
233 } else {
234 progressWindow.show();
235
236 cluSetManagementRpcServiceAsync.getMetadata("courseSet", null, new KSAsyncCallback<Metadata>(){
237
238 @Override
239 public void handleFailure(Throwable caught) {
240 onReadyCallback.exec(false);
241 progressWindow.hide();
242 throw new RuntimeException("Failed to get model definition.", caught);
243 }
244
245 @Override
246 public void onSuccess(Metadata result) {
247 DataModelDefinition def = new DataModelDefinition(result);
248 cluSetModel.setDefinition(def);
249 init(def);
250 initialized = true;
251 onReadyCallback.exec(true);
252 progressWindow.hide();
253 }
254 });
255 }
256 }
257
258 private void init(DataModelDefinition modelDefinition){
259
260 if (!initialized){
261
262
263
264
265
266
267 addApplicationEventHandler(SaveActionEvent.TYPE, new SaveActionHandler(){
268 @Override
269 public void doSave(SaveActionEvent saveAction) {
270 GWT.log("CluSetManagementController received save action request.", null);
271 doSaveAction(saveAction);
272 }
273 });
274 }
275
276 initialized = true;
277 }
278
279
280
281
282 @Override
283 public Class<? extends Enum<?>> getViewsEnum() {
284 return ClusetView.CluSetsManagementViews.class;
285 }
286
287 @Override
288 protected void renderView(View view) {
289 super.renderView(view);
290
291
292 }
293
294 @SuppressWarnings("unchecked")
295 @Override
296 public void requestModel(Class modelType, final ModelRequestCallback callback) {
297 super.requestModel(modelType, callback);
298 }
299
300 public void doSaveAction(final SaveActionEvent saveActionEvent){
301
302
303 getCurrentView().updateModel();
304
305 if(cluSetModel!=null){
306 cluSetModel.validate(new Callback<List<ValidationResultInfo>>() {
307 @Override
308 public void exec(List<ValidationResultInfo> result) {
309
310 boolean save = true;
311 View v = getCurrentView();
312 if(v instanceof Section){
313 ((Section) v).setFieldHasHadFocusFlags(true);
314 ErrorLevel status = ((Section) v).processValidationResults(result);
315 if(status == ErrorLevel.ERROR){
316 save = false;
317 }
318 }
319
320 if(save){
321 getCurrentView().updateModel();
322 CluSetsManagementController.this.updateModel();
323
324
325 CluSetHelper.wrap((Data)cluSetModel.getRoot()).setReusable(new Boolean(true));
326 saveModel(cluSetModel, saveActionEvent);
327 }
328 else{
329 Window.alert("Save failed. Please check fields for errors.");
330 }
331
332 }
333 });
334 }
335 }
336
337 private void saveModel(final DataModel dataModel, final SaveActionEvent saveActionEvent) {
338 final KSLightBox saveWindow = new KSLightBox();
339 final KSLabel saveMessage = new KSLabel(saveActionEvent.getMessage() + "...");
340 final OkGroup buttonGroup = new OkGroup(new Callback<OkEnum>(){
341
342 @Override
343 public void exec(OkEnum result) {
344 saveWindow.hide();
345 saveActionEvent.doActionComplete();
346 }
347 });
348
349 buttonGroup.setWidth("250px");
350 buttonGroup.getButton(OkEnum.Ok).setEnabled(false);
351 buttonGroup.setContent(saveMessage);
352
353
354 if (saveActionEvent.isAcknowledgeRequired()){
355 saveWindow.setWidget(buttonGroup);
356 } else {
357 saveWindow.setWidget(saveMessage);
358 }
359 saveWindow.show();
360
361 final Callback<Throwable> saveFailedCallback = new Callback<Throwable>() {
362
363 @Override
364 public void exec(Throwable caught) {
365 GWT.log("Save Failed.", caught);
366 saveWindow.setWidget(buttonGroup);
367 saveMessage.setText("Save Failed! Please Try Again.");
368 buttonGroup.getButton(OkEnum.Ok).setEnabled(true);
369 }
370
371 };
372 try {
373 cluSetManagementRpcServiceAsync.saveData(dataModel.getRoot(), new KSAsyncCallback<DataSaveResult>() {
374 @Override
375 public void handleFailure(Throwable caught) {
376 saveFailedCallback.exec(caught);
377 }
378
379 @Override
380 public void onSuccess(DataSaveResult result) {
381 if (result.getValidationResults() != null &&
382 !result.getValidationResults().isEmpty()) {
383 StringBuilder errorMessage = new StringBuilder();
384 errorMessage.append("Validation error: ");
385 for (ValidationResultInfo validationError : result.getValidationResults()) {
386 errorMessage.append(validationError.getMessage()).append(" ");
387 }
388 saveMessage.setText(errorMessage.toString());
389 buttonGroup.getButton(OkEnum.Ok).setEnabled(true);
390 } else {
391 dataModel.setRoot(result.getValue());
392 if (saveActionEvent.isAcknowledgeRequired()){
393 saveMessage.setText("Save Successful");
394 buttonGroup.getButton(OkEnum.Ok).setEnabled(true);
395 } else {
396 saveWindow.hide();
397 saveActionEvent.doActionComplete();
398 }
399 }
400 }
401 });
402
403 } catch (Exception e) {
404 saveFailedCallback.exec(e);
405 }
406 }
407
408 @Override
409 public void showDefaultView(final Callback<Boolean> onReadyCallback) {
410 init(new Callback<Boolean>() {
411 @Override
412 public void exec(Boolean result) {
413 if (result) {
414 doShowDefaultView(onReadyCallback);
415 } else {
416 onReadyCallback.exec(false);
417 }
418 }
419 });
420 }
421
422 @Override
423 public void beforeShow(Callback<Boolean> onReadyCallback) {
424 showDefaultView(onReadyCallback);
425 }
426
427 private void doShowDefaultView(final Callback<Boolean> onReadyCallback) {
428 super.showDefaultView(onReadyCallback);
429 }
430
431 @Override
432 public void setParentController(Controller controller) {
433 super.setParentController(controller);
434 }
435
436 }