001 /** =====================================================================
002 *
003 * File Name : $Id: QuickViewReport.java,v 1.12 2008/01/15 11:08:15 cb Exp $
004 *
005 * Description
006 * -----------
007 *
008 * See javadoc comment
009 *
010 * =====================================================================
011 *
012 * @Author : Craige Bevil
013 * Control Software Group
014 * Isaac Newton Group of Telescopes
015 *
016 * =====================================================================
017 *
018 * Modification Log
019 *
020 * Vers Date Author Reason
021 * ---- ---- ------ ------
022 * 1 2 Jul 2007 C.Bevil First Release
023 *
024 * Commissioning Notes
025 * -------------------
026 *
027 * None
028 *
029 * =====================================================================
030 *
031 * @Version : $Id: QuickViewReport.java,v 1.12 2008/01/15 11:08:15 cb Exp $
032 *
033 * @Author : $Author: cb $
034 *
035 * Header : $Header: /opt/INGsrc/src/CVS/softproj/FaultDatabase/src/FaultDatabase/FaultDatabase/src/GWTApplication/client/QuickViewReport.java,v 1.12 2008/01/15 11:08:15 cb Exp $
036 *
037 * Log : $Log: QuickViewReport.java,v $
038 * Log : Revision 1.12 2008/01/15 11:08:15 cb
039 * Log : Ran through PMD and sorted out the javadoc so that we could export the
040 * Log : javadoc to the javadoc repository.
041 * Log :
042 * Log : Revision 1.11 2007/12/18 16:50:43 cb
043 * Log : White space
044 * Log :
045 * Log : Revision 1.10 2007/12/12 15:26:11 cb
046 * Log : Added new javascript library which allows fancy message boxes to be
047 * Log : displayed.
048 * Log :
049 * Log : Revision 1.9 2007/09/06 07:59:18 cb
050 * Log : Updated to support the concept of a single FaultUpdateMonitor
051 * Log : throughout the entire application so we do not hammer the database
052 * Log : when looking for updated faults.
053 * Log :
054 * Log : Revision 1.8 2007/08/22 15:58:28 cb
055 * Log : Added a callback mechanism where the SearchResultFormatter can call
056 * Log : back the quick view to have the search results updated in their
057 * Log : entirety.
058 * Log :
059 * Log : Revision 1.7 2007/08/20 14:47:48 cb
060 * Log : Converted 48 to 72 hours in the quick view
061 * Log :
062 * Log : Revision 1.6 2007/08/16 12:44:19 cb
063 * Log : Reordered the tabs to be in alphabetic order
064 * Log :
065 * Log : Revision 1.5 2007/08/14 09:28:14 cb
066 * Log : Revised after using PMD
067 * Log :
068 * Log : Revision 1.4 2007/08/02 12:22:54 cb
069 * Log : Modified to support the extra tabs in the quick view tab panel to
070 * Log : include the different groups of outstanding faults.
071 * Log :
072 * Log : Revision 1.3 2007/08/01 13:00:04 cb
073 * Log : First prototype after import
074 * Log :
075 * Log : Revision 1.2 2007/07/13 10:54:04 cb
076 * Log : Complete interface prototype
077 * Log :
078 * Log : Revision 1.1.1.1 2007/06/01 08:33:26 cb
079 * Log : Imported using TkCVS
080 * Log :
081 *
082 * =====================================================================*/
083
084 package GWTApplication.client;
085
086 import com.google.gwt.user.client.*;
087 import com.google.gwt.user.client.rpc.*;
088 import com.google.gwt.user.client.ui.*;
089 import com.google.gwt.user.client.ui.TabListener.*;
090
091 import com.gwtext.client.core.EventObject;
092 import com.gwtext.client.util.Format;
093 import com.gwtext.client.widgets.MessageBox;
094 import com.gwtext.client.widgets.MessageBoxConfig;
095
096 import java.util.*;
097
098 /**
099 * The purpose of this class is to allow the user to very quickly
100 * access some of the most populat views upon the data within the
101 * fault management system. It will permit the use of for example To
102 * access information relating to outstanding faults for the last
103 * twenty four hours or forty eight hours. <P> the user will be
104 * presented with a tree structure from which he can quickly select
105 * the desired report. this report will subsequently be displayed in
106 * an adjacent panel.
107 * @author Craige Bevil
108 * @version $Id: QuickViewReport.java,v 1.12 2008/01/15 11:08:15 cb Exp $
109 */
110
111 public class QuickViewReport extends FaultDBForm implements TabListener {
112
113 /**
114 * Constants which are used for determining which of the quick
115 * searches were selected by the user in the tree widget. Enums
116 * would be good but we are stuck with java 1.4 at the moment :-(
117 */
118
119 public final static int TWENTYFOURHOURS = 1;
120 public final static int SEVENTYTWOHOURS = 2;
121 public final static int ONEWEEK = 3;
122 public final static int ONEMONTH = 4;
123 public final static int TWENTYFOURHOURSOUTSTANDING = 5;
124 public final static int SEVENTYTWOHOURSOUTSTANDING = 6;
125 public final static int ONEWEEKOUTSTANDING = 7;
126 public final static int ONEMONTHOUTSTANDING = 8;
127
128 // These are the outstanding faults categories
129
130 public final static int OUTSTANDING = 9;
131 public final static int TI_OUTSTANDING = 10;
132 public final static int COMPUTING_OUTSTANDING = 11;
133 public final static int OPERATIONS_OUTSTANDING = 12;
134 public final static int ASTRONOMY_OUTSTANDING = 13;
135
136 /**
137 * Used to check the database intermittingly and report back to
138 * listeners which faults they are displaying have changed so that
139 * they may update their view accordingly.
140 */
141
142 private FaultUpdateMonitor faultUpdateMonitor = null;
143
144 /**
145 * This inner class describes a tab in the quick view search which
146 * will be used by the user to view a specific view on the
147 * database. The page is active in that if a fault is updated in
148 * the database behind the scenes, the information in the quick
149 * view will be updated.
150 * @author Craige Bevil
151 * @version $Id: QuickViewReport.java,v 1.12 2008/01/15 11:08:15 cb Exp $
152 */
153
154 class QuickSearchType implements ClickListener,RefreshSearchResultsListener {
155
156 /**
157 * Whether or not to include the <b>Open All</b> button in the
158 * quick view. Having the <b>Open All</b> button has to be
159 * used carefully as it can hammer the servlet and the
160 * client. Use carefully on views which do not contain so many
161 * entries.
162 */
163
164 public boolean UseOpenAllButton = false;
165
166 /**
167 * This is a search formatter which will be used for
168 * formatting the data which is returned by a specific search
169 * query.
170 */
171
172 private SearchResultFormatter searchResultFormatter;
173
174 /**
175 * This is the label which is to be associated with the
176 * quick view tab.
177 */
178
179 public String TabLabel;
180
181 /**
182 * This is the tab index which is associated with this quick
183 * view tab.
184 */
185
186 public int TabIndex;
187
188 /**
189 * This is the type of quick view which is associated with
190 * the quick view tab.
191 */
192
193 public int QuickViewType;
194
195 /**
196 * This is a table into which the results of the search will
197 * be displayed.
198 */
199
200 public FlexTable SearchResultTable = new FlexTable();
201
202 /**
203 * This is the panel into which the search results are
204 * dropped.
205 */
206
207 public DockPanel SearchResultsPanel = new DockPanel();
208
209 /**
210 * If we have initialised the quick view tab or not.
211 */
212
213 public boolean TabInitialised = false;
214
215 /**
216 * This is a button widget which will be pressed to instruct
217 * the application to refresh the display
218 */
219
220 Button refreshButton;
221
222 /**
223 * This button widget will be used to collapse the details of
224 * all of the faults
225 */
226
227 Button collapseAllButton;
228
229 /**
230 * This button will be used to open all of the details of the
231 * faults. This button is not present on all quick views and
232 * needs to be configured. The presence of the can be
233 * determined through the {@link
234 * #UseOpenAllButton UseOpenAllButton} attribute.
235 */
236
237 Button openAllButton;
238
239 /**
240 * Whether to update the quick view when new faults are
241 * entered into the system
242 */
243
244 boolean UpdateWithNewFaults = false;
245
246 /**
247 * Constructor
248 * @param TabLabel This is the label text which is associated with
249 * this tab.
250 * @param TabIndex This is the index in the tab panel where to
251 * construct this tab.
252 * @param QuickViewType This is the type of the quick
253 * view.
254 * @param UseOpenAllButton Whether we should provide an Open
255 * All button which can be used be the user to open all of the
256 * faults in the quick panel simultaneously.
257 */
258
259 QuickSearchType (final String TabLabel,
260 final int TabIndex,
261 final int QuickViewType,
262 final boolean UseOpenAllButton,
263 final boolean UpdateWithNewFaults) {
264
265 this.TabLabel = TabLabel;
266 this.TabIndex = TabIndex;
267 this.QuickViewType = QuickViewType;
268 this.UseOpenAllButton = UseOpenAllButton;
269 this.UpdateWithNewFaults = UpdateWithNewFaults;
270 }
271
272 /**
273 * Used to set the search formatter
274 * @param searchResultFormatter This is the search result
275 * formatter.
276 */
277
278 private void setSearchFormatter(final SearchResultFormatter searchResultFormatter) {
279
280 this.searchResultFormatter = searchResultFormatter;
281
282 // Set whether to display new faults or not
283
284 searchResultFormatter.setdisplayNewFaults(UpdateWithNewFaults);
285
286 // Ensure that the search result formatter can call us to
287 // update the full list of results should it be
288 // necessary. We have to be careful here not to do it with
289 // the more SQL intensive views such as outstanding
290 // operations/T&I etc.
291
292 searchResultFormatter.searchResultUpdater = this;
293 }
294
295 /**
296 * This is called when the user presses the refresh button on the
297 * interface and results in the quick view in the tab panel
298 * selected being updated.
299 * @param sender This is the widget which is responsible for
300 * sending this event.
301 */
302
303 public void onClick(Widget sender) {
304
305 // Work out which of the tabs is selected and the update the
306 // quick view which is contained within that tab
307
308 if (sender.equals(refreshButton)) {
309 fillQuickViewPanel(QuickViewTabPanel.getTabBar().getSelectedTab());
310 } else if (sender.equals(collapseAllButton)) {
311 searchResultFormatter.setDisclosurePanelState(false);
312 } else if (sender.equals(openAllButton)) {
313 searchResultFormatter.setDisclosurePanelState(true);
314 }
315 }
316
317 /**
318 * This implements the interface {@link
319 * RefreshSearchResultsListener RefreshSearchResultsListener}
320 * and will result in the quick view for the selected tab
321 * being refreshed.
322 */
323
324 public void refreshResults () {
325 fillQuickViewPanel(TabIndex);
326 }
327
328 /**
329 * This is called to update the tab with the view associated with
330 * the quick view tab. It is called when the user clicks on the
331 * tab for the first time or presses the refresh button
332 * @param tabIndex This is the tab which is to be updated
333 */
334
335 private void fillQuickViewPanel (final int tabIndex) {
336
337 // Now we need to call the servlet on in order to search for
338 // the faults which fall into this window
339
340 busyIndicator.showBusy(true);
341
342 svc.getQuickViewFaultData (QuickSearchInfo[tabIndex].QuickViewType, internationalizationConstants.locale(), new AsyncCallback() {
343
344 /**
345 * On success we fill in the table which contains the
346 * search results and then display it to the user
347 */
348
349 public void onSuccess (final Object result) {
350
351 // Set the table into which the formatter will
352 // insert the search results
353
354 searchResultFormatter.setResultsTable(SearchResultTable);
355
356 searchResultFormatter.displaySearchResults((ArrayList)result,MainTabPanel);
357
358 // Flag the fact that we have initialised the tab
359
360 TabInitialised = true;
361
362 busyIndicator.showBusy(false);
363 }
364
365 public void onFailure (Throwable ex)
366 {
367 busyIndicator.showBusy(false);
368 MessageBox.alert(internationalizationConstants.information(),"Unable to get quick view data");
369 }
370 });
371
372 }
373
374 /**
375 * This will be used to build the quick view panel for this
376 * particular quick view tab.
377 */
378
379 void buildQuickViewPage () {
380
381 HorizontalPanel buttonPanel = new HorizontalPanel();
382
383 SearchResultTable.setWidth("100%");
384 SearchResultsPanel.setWidth("100%");
385
386 // Now add a button panel which contains the
387 // Refresh,Collapse all and the open all buttons
388
389 refreshButton = new Button(internationalizationConstants.refresh(),this);
390 collapseAllButton = new Button(internationalizationConstants.collapseAll(),this);
391 openAllButton = new Button(internationalizationConstants.openAll(),this);
392
393 buttonPanel.add(refreshButton);
394
395 // If we have been requested to use the open all button
396
397 if (UseOpenAllButton) {
398 buttonPanel.add(openAllButton);
399 }
400
401 buttonPanel.add(collapseAllButton);
402
403 buttonPanel.setStyleName("QuickViewButtonPanel");
404
405 // Add the button to the panel which will display the
406 // results of the quick search
407
408 SearchResultsPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP);
409
410 SearchResultsPanel.add(buttonPanel,DockPanel.NORTH);
411
412 // Now add the table to the scroll panel into which we
413 // will add the results of the search
414
415 SearchResultsPanel.add(SearchResultTable,DockPanel.CENTER);
416
417 SearchResultsPanel.setCellHeight(SearchResultTable,"100%");
418
419 // Now create a tab which will allow the user to select
420 // this quick view
421
422 QuickViewTabPanel.add(SearchResultsPanel,TabLabel);
423 }
424 }
425
426 /**
427 * This is an array which is used to set up the tabs which the
428 * user can select the quick views from.
429 */
430
431 private final QuickSearchType[] QuickSearchInfo = new QuickSearchType[] {
432 new QuickSearchType("24 " + internationalizationConstants.hours(),0,TWENTYFOURHOURS,true,true),
433 new QuickSearchType("72 " + internationalizationConstants.hours(),1,SEVENTYTWOHOURS,true,true),
434 new QuickSearchType("1 " + internationalizationConstants.week(),2,ONEWEEK,true,true),
435 new QuickSearchType("1 " + internationalizationConstants.month(),3,ONEMONTH,true,true),
436 new QuickSearchType(internationalizationConstants.astronomy(),4,ASTRONOMY_OUTSTANDING,true,false),
437 new QuickSearchType(internationalizationConstants.computing(),5,COMPUTING_OUTSTANDING,true,false),
438 new QuickSearchType(internationalizationConstants.operations(),6,OPERATIONS_OUTSTANDING,true,false),
439 new QuickSearchType(internationalizationConstants.TandI(),7,TI_OUTSTANDING,true,false),
440 };
441
442 /**
443 * This widget is a tab panel which will contain tabs for all of
444 * the quick views which the user may accessa
445 */
446
447 private TabPanel QuickViewTabPanel;
448
449 /**
450 * This is the main tab panel for the application so that we can
451 * programatically change the tabs which are selected. This is
452 * done for instance when the user selects the update link in the
453 * and we need to then select the update tab to show the form
454 * which contains the fault to be edited.
455 */
456
457 private TabPanel MainTabPanel;
458
459 /**
460 * This is used to create the panel which is used to generate
461 * reports for the user on request.
462 * @param MainTabPanel This is the main tab panel into which we will drop the quick view panel.
463 * @param svc This is a remote servelt object which will be running in the tomcat servlet container
464 *
465 * @param ModifyFormPage This is the tab panel which can be used
466 * to modify the details of faults which have been entered into
467 * the database
468 * @param faultUpdateMonitor This is will be used for keeping track of changes to faults in the database
469 */
470
471 QuickViewReport (final TabPanel MainTabPanel,
472 final FaultServiceAsync svc,
473 final ModifyFormPanel ModifyFormPage,
474 final AuthenticationDetails UserAuthentication,
475 final FaultUpdateMonitor faultUpdateMonitor) {
476
477 this.svc = svc;
478 this.MainTabPanel = MainTabPanel;
479 this.UserAuthentication = UserAuthentication;
480 this.faultUpdateMonitor = faultUpdateMonitor;
481
482 // Now create the tab panel into which we will put the rest of
483 // the widgets
484
485 QuickViewTabPanel = new TabPanel();
486 QuickViewTabPanel.addTabListener(this);
487
488 QuickViewTabPanel.setStyleName("quickViewBackGround");
489
490 for (int i=0; i < QuickSearchInfo.length ;i++) {
491
492 // Now create a formatter which will be used for displaying
493 // the search results.
494
495 QuickSearchInfo[i].setSearchFormatter(new SearchResultFormatter(null,ModifyFormPage,UserAuthentication,svc,internationalizationConstants,faultUpdateMonitor));
496
497 QuickSearchInfo[i].buildQuickViewPage();
498 }
499
500 // Now add the quick view panel to the main panel
501
502 MainTabPanel.add(QuickViewTabPanel,internationalizationConstants.quickView());
503
504 // Now select the tab which displays all of the faults in the
505 // last 72 hours
506
507 QuickViewTabPanel.selectTab(1);
508 }
509
510 /**
511 * This is part of the tab listener interface which is not used
512 * but needs to be defined.
513 * @param sender This is the widget which is responsible for
514 * sending this event.
515 * @param tabIndex This is the tab which has been selected.
516
517 */
518
519 public boolean onBeforeTabSelected (final SourcesTabEvents sender,final int tabIndex) {
520 return true;
521 }
522
523 /**
524 * This is called when a tab in the quick view panel is
525 * selected. If the tab has already been selected previously then
526 * there is nothing to do otherwise it builds up the contents of
527 * the quick view tab from the database dynamically.
528 * @param sender This is the widget which is responsible for
529 * sending this event.
530 * @param tabIndex This is the index of the tab which caused the
531 * event to be raised.
532 */
533
534 public void onTabSelected (SourcesTabEvents sender,final int tabIndex) {
535
536 // If the tab has already been selected then we do nothing
537 // here
538
539 if (QuickSearchInfo[tabIndex].TabInitialised) {
540 return;
541 }
542
543 QuickSearchInfo[tabIndex].fillQuickViewPanel(tabIndex);
544 }
545 }
546