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