source: trunk/web/addons/job_monarch/js/monarch.js @ 645

Last change on this file since 645 was 645, checked in by ramonb, 15 years ago

job_monarch/js/monarch.js:

  • regression testing fixed joblisting sorting by column
File size: 28.0 KB
Line 
1var JobsDataStore;
2var JobsColumnModel;
3var JobListingEditorGrid;
4var JobListingWindow;
5var JobProxy;
6var SearchField;
7var filterButton;
8var globalWindowCount = 0;
9
10// Extra header to prevent browser caching
11//
12Ext.Ajax.defaultHeaders =
13{
14        'If-Modified-Since':    'Sat, 1 Jan 2005 00:00:00 GMT'
15};
16
17// associative filter array
18//
19var myfilters = { };
20
21// any other datastore params
22//
23var myparams = { };
24
25// (default) paging size
26//
27var mylimit = 15;
28
29var ClusterImageArgs = { };
30
31var filterfields = [ "jid", "queue", "name", "owner" ];
32
33var graphWindowBehaviour = 'tabbed-new-window';
34var previousGraphWindow;
35
36var filterMenu = new Ext.menu.Menu(
37{
38        id:     'filterMenu',
39        items:  [ new Ext.menu.Item({ text: 'Clear all', handler: clearFilters }) ]
40});
41
42var filterButton = new Ext.Button(
43{
44        id:             'filtermenuknop',
45        text:           'Filters',
46        toolip:         'Click to change filter options',
47        disabled:       true,
48        menu:           filterMenu,
49        listeners:
50        {
51                'click':
52                {
53                        scope:  this,
54                        fn:     function( myButton, event )
55                                {       // immediatly show menu when button is clicked
56                                        myButton.menu.show( myButton.getEl() );
57                                }
58                }
59        }
60});
61
62function checkGraphWindowOption( item, checked )
63{
64        graphWindowBehaviour    = item.id;
65}
66
67var graphMenu = new Ext.menu.Menu(
68{
69        id:     'graphMenu',
70        items:
71        [{
72                id:             'new-window',
73                text:           'In new window(s)',
74                checked:        false,
75                group:          'graphwindow',
76                handler:        checkGraphWindowOption
77        },{
78                id:             'tabbed-new-window',
79                text:           'In seperate tab(s), in 1 new window',
80                checked:        true,
81                group:          'graphwindow',
82                handler:        checkGraphWindowOption
83        },{
84                id:             'tabbed-prev-window',
85                text:           'In seperate tab(s), in last opened window',
86                checked:        false,
87                group:          'graphwindow',
88                handler:        checkGraphWindowOption
89        }]
90});
91
92var showGraphsButton = new Ext.Toolbar.SplitButton(
93{
94        id:             'showgraphbutton',
95        text:           'Open selected',
96        disabled:       true,
97        menu:           graphMenu,
98        listeners:
99        {
100                'click':
101                {
102                        scope:  this,
103                        fn:     ShowGraphs
104                }
105        }
106});
107
108Ext.namespace('Ext.ux');
109
110Ext.ux.PageSizePlugin = function()
111{
112        Ext.ux.PageSizePlugin.superclass.constructor.call(this,
113        {
114                store:  new Ext.data.SimpleStore(
115                {
116                        fields: ['text', 'value'],
117                        data:   [['10', 10], ['15', 15], ['20', 20], ['30', 30], ['50', 50], ['100', 100], ['250', 250], ['500', 500], ['all', 'max' ]]
118                }),
119                mode:           'local',
120                displayField:   'text',
121                valueField:     'value',
122                editable:       false,
123                allowBlank:     false,
124                triggerAction:  'all',
125                width:          50
126        });
127};
128
129Ext.extend(Ext.ux.PageSizePlugin, Ext.form.ComboBox,
130{
131        init:                   function(paging)
132                                {
133                                        paging.on('render', this.onInitView, this);
134                                },
135   
136        onInitView:             function(paging)
137                                {
138                                        paging.add('-',
139                                        this,
140                                        'jobs per page');
141                                        this.setValue(paging.pageSize);
142                                        this.on('select', this.onPageSizeChanged, paging);
143                                },
144
145        onPageSizeChanged:      function(combo)
146                                {
147                                        if ( combo.getValue() == 'max' )
148                                        {
149                                                mylimit = JobsDataStore.getTotalCount();
150                                        }
151                                        else
152                                        {
153                                                mylimit = parseInt(combo.getValue());
154                                        }
155                                        this.pageSize = mylimit;
156                                        this.doLoad(0);
157                                }
158});
159
160Ext.namespace( 'Ext' );
161
162function clearFilters()
163{
164        if( inMyArrayKeys( myfilters, 'query' ) )
165        {
166                SearchField.getEl().dom.value = '';
167                delete SearchField.store.baseParams['query'];
168                delete myfilters['query'];
169                delete myparams['query'];
170        }
171        if( inMyArrayKeys( myfilters, 'host' ) )
172        {
173                delete myfilters['host'];
174                delete myparams['host'];
175        }
176        if( inMyArrayKeys( myfilters, 'jid' ) )
177        {
178                delete myfilters['jid'];
179                delete myparams['jid'];
180        }
181        if( inMyArrayKeys( myfilters, 'queue' ) )
182        {
183                delete myfilters['queue'];
184                delete myparams['queue'];
185        }
186        if( inMyArrayKeys( myfilters, 'owner' ) )
187        {
188                delete myfilters['owner'];
189                delete myparams['owner'];
190        }
191        if( inMyArrayKeys( myfilters, 'status' ) )
192        {
193                delete myfilters['status'];
194                delete myparams['status'];
195        }
196        reloadJobStore();
197}
198
199function makeArrayURL( somearr )
200{
201        filter_url = '';
202        filter_sep = '';
203
204        for( filtername in somearr )
205        {
206                filter_url = filter_url + filter_sep + filtername + '=' + somearr[filtername];
207                filter_sep = '&';
208        }
209
210        return filter_url;
211}
212
213
214function isset( somevar )
215{
216        try
217        {
218                if( eval( somevar ) ) { }
219        }
220        catch( err )
221        {
222                return false;
223        }
224        return true;
225}
226
227function inMyArray( arr, someval )
228{
229        for( arval in arr )
230        {
231                if( arval == someval )
232                {
233                        return true;
234                }
235        }
236        return false;
237}
238
239function ArraySize( arr )
240{
241        count = 0;
242
243        for( arkey in arr )
244        {
245                count = count + 1;
246        }
247
248        return count;
249}
250
251function inMyArrayValues( arr, someval )
252{
253        for( arkey in arr )
254        {
255                if( arr[arkey] == someval )
256                {
257                        return true;
258                }
259        }
260        return false;
261}
262
263function inMyArrayKeys( arr, someval )
264{
265        for( arkey in arr )
266        {
267                if( arkey == someval )
268                {
269                        return true;
270                }
271        }
272        return false;
273}
274
275function joinMyArray( arr1, arr2 )
276{
277        for( arkey in arr2 )
278        {
279                arr1[arkey] = arr2[arkey];
280        }
281
282        return arr1;
283}
284
285function ClusterImageSelectHost( somehost )
286{
287        if( !inMyArrayKeys( myfilters, 'host' ) )
288        {
289                myfilters['host'] = somehost;
290        }
291        else
292        {
293                if( myfilters['host'] == somehost )
294                {
295                        delete myfilters['host'];
296                        delete myparams['host'];
297                }
298                else
299                {
300                        myfilters['host'] = somehost;
301                }
302        }
303
304        reloadClusterImage();
305        reloadJobStore();
306
307        // returning false causes a image reload
308        //
309        return false;
310}
311
312function reloadJobStore()
313{
314        // Respect any other parameters that may have been set outside filters
315        //
316        myparams = joinMyArray( myparams, myfilters );
317
318        // Can't be sure if there are enough pages for new filter: reset to page 1
319        //
320        myparams = joinMyArray( myparams, { start: 0, limit: mylimit } );
321
322        JobsDataStore.reload( { params: myparams } );
323}
324
325function addListener(element, type, expression, bubbling)
326{
327        bubbling = bubbling || false;
328
329        if(window.addEventListener)
330        { // Standard
331                element.addEventListener(type, expression, bubbling);
332                return true;
333        } 
334        else if(window.attachEvent) 
335        { // IE
336                element.attachEvent('on' + type, expression);
337                return true;
338        }
339        else 
340        {
341                return false;
342        }
343}
344
345function makeFilterString()
346{
347        var filter_str = '';
348
349        for( arkey in myfilters )
350        {
351                filter_str = filter_str + ' > ' + myfilters[arkey];
352        }
353
354        return filter_str;
355}
356
357var ImageLoader = function( id, url )
358{
359        this.url = url;
360        this.image = document.getElementById( id );
361        this.loadEvent = null;
362};
363
364ImageLoader.prototype = 
365{
366        load:           function()
367                        {
368                                var url         = this.url;
369                                var image       = this.image;
370                                var loadEvent   = this.loadEvent;
371                                addListener( this.image, 'load',
372                                        function(e)
373                                        {
374                                                if( loadEvent != null )
375                                                {
376                                                        loadEvent( url, image );
377                                                }
378                                        }, false);
379                                this.image.src = this.url;
380                        },
381        getImage:       function()
382                        {
383                                return this.image;
384                        }
385};
386
387function achorJobListing()
388{
389        //JobListingWindow.anchorTo( "ClusterImageWindow", "tr-br", [ 0, 10 ] );
390        JobListingWindow.anchorTo( "ClusterImageWindow", "tr-tr", [ 0, 10 ] );
391}
392
393function setClusterImagePosition()
394{
395        //var ci_x = (window.innerWidth - ClusterImageWindow.getSize()['width'] - 20);
396        ClusterImageWindow.setPosition( 10, 10 );
397}
398
399function setJobListingPosition()
400{
401        var jl_x = (window.innerWidth - JobListingWindow.getSize()['width'] - 20); 
402        JobListingWindow.setPosition( jl_x, 10 );
403}
404
405function deselectFilterMenu( menuItem, event )
406{
407        filterValue = menuItem.text;
408
409        if( filterValue == SearchField.getEl().dom.value && inMyArrayKeys( myfilters, 'query' ) )
410        {
411                SearchField.getEl().dom.value = '';
412                delete SearchField.store.baseParams['query'];
413        }
414
415        for( arkey in myfilters )
416        {
417                if( myfilters[arkey] == filterValue )
418                {
419                        delete myfilters[arkey];
420                        delete myparams[arkey];
421                }
422        }
423        reloadJobStore();
424}
425
426function makeFilterMenu()
427{
428        var filterMenu = new Ext.menu.Menu(
429        {
430                id:     'filterMenu',
431                items:  [ new Ext.menu.Item({ text: 'Clear all', handler: clearFilters }) ]
432        });
433
434        if( ArraySize( myfilters ) > 0 )
435        {
436                filterMenu.addSeparator();
437        }
438
439        for( arkey in myfilters )
440        {
441                filterMenu.add( new Ext.menu.CheckItem({ text: myfilters[arkey], handler: deselectFilterMenu, checked: true }) );
442        }
443
444        if( filterButton )
445        {
446                filterButton.menu = filterMenu;
447
448                if( ArraySize( myfilters ) > 0 )
449                {
450                        filterButton.enable();
451                }
452                else
453                {
454                        filterButton.disable();
455                }
456        }
457}
458
459function reloadClusterImage()
460{
461        ClusterImageArgs['view']        = 'big-clusterimage';
462
463        filt_url                        = makeArrayURL( myfilters );
464        imag_url                        = makeArrayURL( ClusterImageArgs );
465        img_url                         = './image.php?' + filt_url + '&' + imag_url;
466
467        var newClusterImage             = new ImageLoader( 'clusterimage', img_url );
468        newClusterImage.loadEvent       = function( url, image ) 
469        {
470                ClusterImageWindow.getBottomToolbar().clearStatus( { useDefaults:true } );
471                setTimeout( "resizeClusterImage()", 250 );
472                //setTimeout( "setClusterImagePosition()", 500 );
473                //setTimeout( "achorJobListing()", 1000 );
474        };
475
476        ClusterImageWindow.getBottomToolbar().showBusy();
477
478        filter_str = 'Nodes' + makeFilterString();
479        ClusterImageWindow.setTitle( filter_str );
480
481        newClusterImage.load();
482}
483
484function resizeClusterImage()
485{
486        var ci_height   = document.getElementById( "clusterimage" ).height + ClusterImageWindow.getFrameHeight();
487        var ci_width    = document.getElementById( "clusterimage" ).width + ClusterImageWindow.getFrameWidth();
488
489        ClusterImageWindow.setSize( ci_width, ci_height );
490}
491
492Ext.apply(Ext.form.VTypes,
493{
494        num:            function(val, field)
495                        {
496                                if (val) 
497                                {
498                                        var strValidChars = "0123456789";
499                                        var blnResult = true;
500
501                                        if (val.length == 0) return false;
502
503                                        //  test strString consists of valid characters listed above
504                                        for (i = 0; i < val.length && blnResult == true; i++)
505                                        {
506                                                strChar = val.charAt(i);
507                                                if (strValidChars.indexOf(strChar) == -1)
508                                                {
509                                                        blnResult = false;
510                                                }
511                                        }
512                                        return blnResult;
513
514                                }
515                        },
516        numText:        'Must be numeric'
517});
518
519function jobBeforeRowSelect( mySelectionModel, rowIndex, keepExisting, myRecord )
520{
521        if( myRecord.get('status') == 'Q' )
522        {       // return false: dont select row if queued
523                return false;
524        }
525
526        return true;
527}
528
529function jobRowSelect( mySelectionModel, rowIndex, myRecord ) 
530{
531        if( mySelectionModel.hasSelection() )
532        {
533                showGraphsButton.enable();
534
535                return 0;
536        }
537
538        showGraphsButton.disable();
539}
540
541function jobCellClick(grid, rowIndex, columnIndex, e)
542{
543        var record              = grid.getStore().getAt(rowIndex);  // Get the Record
544        var fieldName           = grid.getColumnModel().getDataIndex(columnIndex);
545        var data                = record.get(fieldName);
546        var view                = grid.getView();
547        var cell                = view.getCell( rowIndex, columnIndex );
548        var filter_title        = false;
549        var fil_dis             = 'filter';
550        var fil_ena             = 'filterenabled';
551        var filterName          = fieldName;
552
553        if( fieldName == 'owner' || fieldName == 'jid' || fieldName == 'status' || fieldName == 'queue' || fieldName == 'nodes')
554        {
555                if( fieldName == 'nodes' )
556                {
557                        filterName      = 'host';
558                        fil_dis         = 'nodesfilter';
559                        fil_ena         = 'nodesfilterenabled';
560                }
561                if( inMyArrayKeys( myfilters, filterName ) )
562                {
563                        Ext.fly(cell).removeClass( fil_ena );
564                        Ext.fly(cell).addClass( fil_dis );
565
566                        // Remove this filter
567                        //
568                        delete myfilters[filterName];
569                        delete myparams[filterName];
570
571                        reloadJobStore();
572                        //reloadClusterImage();
573                }
574                else
575                {
576                        Ext.fly(cell).removeClass( fil_dis );
577                        Ext.fly(cell).addClass( fil_ena );
578
579                        if( fieldName == 'nodes' )
580                        { // Get the first node (master mom) as node filter
581                                new_data = data.split( ',' )[0];
582                                data = new_data;
583                        }
584
585                        // Set filter for selected column to selected cell value
586                        //
587                        myfilters[filterName] = data;
588
589                        reloadJobStore();
590                        //reloadClusterImage();
591                }
592                JobListingWindow.setTitle( filter_str );
593
594                filter_title    = true;
595                filter_str      = myparams.c + ' Jobs Overview' + makeFilterString();
596        }
597}
598
599function jobCellRender( value, metadata, record, rowindex, colindex, store )
600{
601        var column_id   = JobsColumnModel.getColumnId( colindex );
602        var fieldName   = JobsColumnModel.getColumnById( column_id ).dataIndex;
603        var fil_dis     = 'filter';
604        var fil_ena     = 'filterenabled';
605        var filterName  = fieldName;
606
607        if( fieldName == 'owner' || fieldName == 'jid' || fieldName == 'status' || fieldName == 'queue' || fieldName == 'nodes' )
608        {
609                if( fieldName == 'nodes' )
610                {
611                        fil_dis         = 'nodesfilter';
612                        fil_ena         = 'nodesfilterenabled';
613                        filterName      = 'host';
614                }
615                if( myfilters[filterName] != null )
616                {
617                        metadata.css    = fil_ena;
618                }
619                else
620                {
621                        metadata.css    = fil_dis;
622                }
623        }
624        return value;
625}
626
627var JobProxy = new Ext.data.HttpProxy(
628{
629        url:            'jobstore.php',
630        method:         'POST'
631});
632
633JobsDataStore = new Ext.data.Store(
634{
635        id:             'JobsDataStore',
636        proxy:          JobProxy,
637        baseParams:     { task: "GETJOBS" },
638        reader:
639                new Ext.data.JsonReader(
640                {
641                        root:           'results',
642                        totalProperty:  'total',
643                        id:             'id'
644                },
645                [
646                        {name: 'jid', type: 'int', mapping: 'jid'},
647                        {name: 'status', type: 'string', mapping: 'status'},
648                        {name: 'owner', type: 'string', mapping: 'owner'},
649                        {name: 'queue', type: 'string', mapping: 'queue'},
650                        {name: 'name', type: 'string', mapping: 'name'},
651                        {name: 'requested_time', type: 'string', mapping: 'requested_time'},
652                        {name: 'requested_memory', type: 'string', mapping: 'requested_memory'},
653                        {name: 'ppn', type: 'int', mapping: 'ppn'},
654                        {name: 'nodect', type: 'int', mapping: 'nodect'},
655                        {name: 'nodes', type: 'string', mapping: 'nodes'},
656                        {name: 'queued_timestamp', type: 'string', mapping: 'queued_timestamp'},
657                        {name: 'start_timestamp', type: 'string', mapping: 'start_timestamp'},
658                        {name: 'runningtime', type: 'string', mapping: 'runningtime'}
659                ]),
660        sortInfo: 
661        { 
662                field:          'jid', 
663                direction:      "DESC" 
664        },
665        remoteSort: true,
666        listeners:
667        { 
668                'beforeload':
669                {
670                        scope: this,
671                        fn:
672
673                        function( myStore, myOptions )
674                        {
675                                // Add a (bogus) timestamp, to create a unique url and prevent browser caching
676                                //
677                                myStore.proxy.url       = 'jobstore.php?timestamp=' + new Date().getTime();
678
679                                if( SearchField )
680                                {
681                                        search_value = SearchField.getEl().dom.value;
682                                        if( search_value == '' )
683                                        {
684                                                delete SearchField.store.baseParams['query'];
685                                                delete myfilters['query'];
686                                                delete myparams['query'];
687                                        }
688                                        else
689                                        {
690                                                myfilters['query']      = search_value;
691                                        }
692
693                                        makeFilterMenu();
694                                        reloadClusterImage();
695
696                                        filter_str = myparams.c + ' Jobs Overview' + makeFilterString();
697                                        JobListingWindow.setTitle( filter_str );
698                                }
699                        }
700                },
701                'load':
702                {
703                        scope: this,
704                        fn:
705
706                        function( store, records, options )
707                        {
708                                if( records.length == 1 ) // TODO: if job state is running
709                                {
710                                        jobid                   = records[0].get('jid');
711
712                                        var myPanel             = createGraphPanel();
713                                        var nodeDatastore       = createNodesDataStore( myparams.c, jobid );
714                                        var graphView           = createGraphView( nodeDatastore, jobid );
715                                        var graphTab            = createGraphTab( graphView, jobid, nodeDatastore );
716
717                                        //graphView.autoShow = true;
718
719                                        //newtab = myPanel.add( graphView );
720                                        var newtab = myPanel.add( graphTab );
721                                        myPanel.setActiveTab( newtab );
722                                        myPanel.doLayout();
723
724                                        //nodeDatastore.removeAll();
725
726                                        Ext.getCmp('preview-pane').removeAll();
727                                        Ext.getCmp('preview-pane').add( myPanel );
728                                        Ext.getCmp('preview-pane').doLayout();
729                                }
730                                else
731                                {
732                                        Ext.getCmp('preview-pane').removeAll();
733                                        Ext.getCmp('preview-pane').doLayout();
734                                }
735                        }
736                }
737        }
738});
739   
740var CheckJobs =
741
742        new Ext.grid.CheckboxSelectionModel(
743        {
744                listeners:
745                {
746                        'beforerowselect':
747                        {
748                                scope:  this,
749                                fn:     jobBeforeRowSelect
750                        },
751                        'rowselect':
752                        {
753                                scope:  this,
754                                fn:     jobRowSelect
755                        },
756                        'rowdeselect':
757                        {
758                                scope:  this,
759                                fn:     jobRowSelect
760                        }
761                }
762        });
763
764JobsColumnModel = new Ext.grid.ColumnModel(
765{
766        //CheckJobs,
767        defaults:
768        {
769                hidden:         false,
770                readonly:       true,
771                sortable:       true
772        },
773        columns:
774        [
775                {
776                        header:         '#',
777                        tooltip:        'Job id',
778                        dataIndex:      'jid',
779                        width:          50,
780                        renderer:       jobCellRender
781                },{
782                        header:         'S',
783                        tooltip:        'Job status',
784                        dataIndex:      'status',
785                        width:          20,
786                        renderer:       jobCellRender
787                },{
788                        header:         'User',
789                        tooltip:        'Owner of job',
790                        dataIndex:      'owner',
791                        width:          60,
792                        renderer:       jobCellRender
793                },{
794                        header:         'Queue',
795                        tooltip:        'In which queue does this job reside',
796                        dataIndex:      'queue',
797                        width:          60,
798                        hidden:         false,
799                        renderer:       jobCellRender
800                },{
801                        header:         'Name',
802                        tooltip:        'Name of job',
803                        dataIndex:      'name',
804                        width:          100,
805                },{
806                        header:         'Requested Time',
807                        tooltip:        'Amount of requested time (wallclock)',
808                        dataIndex:      'requested_time',
809                        width:          100,
810                },{
811                        header:         'Requested Memory',
812                        tooltip:        'Amount of requested memory',
813                        dataIndex:      'requested_memory',
814                        width:          100,
815                        hidden:         true
816                },{
817                        header:         'P',
818                        tooltip:        'Number of processors per node (PPN)',
819                        dataIndex:      'ppn',
820                        width:          25,
821                },{
822                        header:         'N',
823                        tooltip:        'Number of nodes (hosts)',
824                        dataIndex:      'nodect',
825                        width:          25,
826                },{
827                        header:         'Nodes',
828                        dataIndex:      'nodes',
829                        width:          100,
830                        renderer:       jobCellRender
831                },{
832                        header:         'Queued',
833                        tooltip:        'At what time did this job enter the queue',
834                        dataIndex:      'queued_timestamp',
835                        width:          120,
836                },{
837                        header:         'Started',
838                        tooltip:        'At what time did this job enter the running status',
839                        dataIndex:      'start_timestamp',
840                        width:          120,
841                },{
842                        header:         'Runningtime',
843                        tooltip:        'How long has this job been in the running status',
844                        dataIndex:      'runningtime',
845                        width:          140,
846                }
847        ]
848});
849
850JobsColumnModel.defaultSortable = true;
851
852var win;
853
854MetricsDataStore = new Ext.data.Store(
855{
856        id:             'MetricsDataStore',
857        proxy:          new Ext.data.HttpProxy(
858        {
859                url:            'jobstore.php',
860                method:         'POST'
861        }),
862        autoLoad:       true,
863        baseParams:     { task: "GETMETRICS" },
864        reader:
865                new Ext.data.JsonReader(
866                {
867                        root:           'names',
868                        totalProperty:  'total',
869                        id:             'id'
870                },
871                [{
872                        name:           'ID'
873                },{
874                        name:           'name'
875                }
876                ]),
877        listeners:
878        { 
879                'beforeload':
880                {
881                        scope: this,
882                        fn:
883
884                        function( myStore, myOptions )
885                        {
886                                // Add a (bogus) timestamp, to create a unique url and prevent browser caching
887                                //
888                                myStore.proxy.url       = 'jobstore.php?timestamp=' + new Date().getTime();
889                        }
890                }
891        }
892});
893
894SearchField     = new Ext.app.SearchField(
895                {
896                        store:  JobsDataStore,
897                        params: {start: 0, limit: mylimit},
898                        width:  200
899                });
900
901function createNodesDataStore( cluster, jid )
902{
903        nodesDataStore =
904
905                new Ext.data.Store(
906                {
907                        //id:           'NodesDataStore',
908                        proxy:          new Ext.data.HttpProxy(
909                        {
910                                url:            'jobstore.php',
911                                method:         'POST'
912                        }),
913                        autoLoad:       true,
914                        baseParams:
915                        {
916                                'task':                 "GETNODES",
917                                'c':                    cluster,
918                                'jid':                  jid,
919                                'metricname':           'load_one'
920                        },
921                        reader: new Ext.data.JsonReader(
922                        {
923                                root:           'results',
924                                totalProperty:  'total',
925                                id:             'id'
926                        },[
927                                {name: 'jid', type: 'string', mapping: 'jid'},
928                                {name: 'ga', type: 'string', mapping: 'ga'}
929                        ]),
930                        listeners:
931                        { 
932                                'beforeload':
933                                {
934                                        scope: this,
935                                        fn:
936
937                                        function( myStore, myOptions )
938                                        {
939                                                // Add a (bogus) timestamp, to create a unique url and prevent browser caching
940                                                //
941                                                myStore.proxy.url       = 'jobstore.php?timestamp=' + new Date().getTime();
942                                        }
943                                }
944                        }
945
946                });
947
948        return nodesDataStore;
949}
950
951function createGraphView( store, jid )
952{
953        var graphView =
954       
955                new Ext.DataView(
956                {
957                        //id:           jid,
958                        //id:           'jobPanel',
959                        itemSelector:   'thumb',
960                        region:         'center',
961                        title:          jid,
962                        //style:                'overflow:auto, heigth: auto',
963                        bodyStyle:      'overflow:auto; background: transparent; heigth: auto',
964                        multiSelect:    true,
965                        //autoHeight:   true,
966                        autoShow:       true,
967                        xtype:          'dataview',
968                        //autoScroll:   true,
969                        //loadMask:     true,
970                        store:          store,
971                        //layout:               'fit',
972                        closable:       true,
973                        tpl:
974                       
975                                new Ext.XTemplate(
976                                        '<tpl for=".">',
977                                        //'<div class="rrd-float"><a href="./graph.php?z=large&{ga}" border="0" rel="lightbox[{jid}.{[globalWindowCount]}]"><img src="./graph.php?z=small&{ga}" border="0"></a></div>',
978                                        '<div class="rrd-float"><img src="./graph.php?z=small&{ga}" border="0" style="cursor:pointer" onclick="nodeWindow(\'node x\', \'{ga}\');"></a></div>',
979                                        '</tpl>')
980                });
981
982        return graphView;
983}
984
985
986function createGraphTab( view, jobid, store )
987{
988        var graphTab =
989
990                new Ext.Panel(
991                {
992                        title:          jobid,
993                        layout:         'border',
994                        xtype:          'panel',
995                        bodyStyle:      'overflow:auto; background: transparent; heigth: auto',
996                        closable:       true,
997
998                        tbar:
999                        [
1000                                'Metric name: ',
1001                                new Ext.form.ComboBox(
1002                                {
1003                                        fieldLabel:     'Metric',
1004                                        store:          MetricsDataStore,
1005                                        valueField:     'name',
1006                                        displayField:   'name',
1007                                        typeAhead:      true,
1008                                        mode:           'remote',
1009                                        triggerAction:  'all',
1010                                        emptyText:      'load_one',
1011                                        selectOnFocus:  true,
1012                                        xtype:          'combo',
1013                                        width:          100,
1014                                        listeners:
1015                                        {
1016                                                select: 
1017                                                               
1018                                                function(combo, record, index)
1019                                                {
1020                                                        var metric      = record.data.name;
1021
1022                                                        var parentPanel = this.findParentByType( 'panel' );
1023                                                        var my_dataview = parentPanel.items.get(0);
1024
1025                                                        my_dataview.getStore().baseParams.metricname    = metric;
1026                                                        my_dataview.getStore().reload();
1027                                                }
1028                                        }
1029                                }),
1030                                '-',
1031                                'Range: ',
1032                                new Ext.form.ComboBox(
1033                                {
1034                                        fieldLabel:     'Range',
1035                                        //store:                MetricsDataStore,
1036                                        valueField:     'name',
1037                                        displayField:   'name',
1038                                        typeAhead:      true,
1039                                        //mode:         'remote',
1040                                        triggerAction:  'all',
1041                                        emptyText:      'job',
1042                                        selectOnFocus:  true,
1043                                        xtype:          'combo',
1044                                        width:          100,
1045                                        listeners:
1046                                        {
1047                                        //      select:
1048                                                               
1049                                        //      function(combo, record, index)
1050                                        //      {
1051                                        //              var metric      = record.data.name;
1052
1053                                        //              var parentPanel = this.findParentByType( 'panel' );
1054                                        //              var my_dataview = parentPanel.items.get(0);
1055
1056                                        //              my_dataview.getStore().baseParams.metricname    = metric;
1057                                        //              my_dataview.getStore().reload();
1058                                        //      }
1059                                        }
1060                                }),
1061                        ],
1062
1063                        items:
1064                        [
1065                                view,
1066                                {
1067                                        region:         'east',
1068                                        split:          true,
1069                                        title:          'Job info',
1070                                        width:          200,
1071                                        layout:         'fit',
1072                                        //id:           'jobinfo-pane',
1073                                        collapsible:    true,
1074                                        border:         true
1075                                }
1076                        ]
1077                });
1078
1079        return graphTab;
1080}
1081
1082
1083function createGraphPanel( view )
1084{
1085        var scrollerMenu = new Ext.ux.TabScrollerMenu(
1086        {
1087                maxText  : 15,
1088                pageSize : 5
1089        });
1090
1091
1092        var graphPanel = 
1093
1094                new Ext.TabPanel(
1095                {
1096                        //id:           'tabPanel',
1097                        xtype:          'tabpanel',
1098                        //layout:               'border',
1099                        //region:               'center',
1100                        //bodyStyle:    'background: transparent',
1101                        autoShow:       true,
1102                        //autoHeight:   true,
1103                        //autoWidth:    true,
1104                        enableTabScroll:true,
1105                        resizeTabs:     true,
1106                        //border:               false,
1107                        bodyStyle:      'overflow:auto; background: transparent; heigth: auto',
1108                        minTabWidth:    60,
1109                        plugins:        [ scrollerMenu ],
1110
1111                        // RB TODO: range combobox; hour, day, week, etc
1112
1113
1114                        //listeners:
1115                        //{
1116                        //      tabchange:
1117                               
1118                        //      function( panel, tab )
1119                        //      {
1120                        //              if( panel.rendered )
1121                        //              {
1122                        //                      combobox        = tab.findParentByType( 'tabpanel' );
1123                        //                      alert( combobox.xtype );
1124                        //                      combobox.value  = tab.getStore().baseParams.metricname;
1125                        //              }
1126                        //      }
1127                        //}
1128                });
1129
1130        return graphPanel;
1131}
1132
1133function createGraphWindow( panel, Button )
1134{
1135        var graphWindow =
1136
1137                new Ext.Window(
1138                {
1139                        animateTarget:  Button,
1140                        width:          500,
1141                        height:         300,
1142                        closeAction:    'hide',
1143                        collapsible:    true,
1144                        animCollapse:   true,
1145                        maximizable:    true,
1146                        layout:         'fit',
1147                        //autoScroll:   true,
1148                        //defaults:     {autoScroll:true},
1149                        title:          'Jobs',
1150                        //tbar:         panel,
1151                        items:          [ panel ]
1152               
1153                        //listeners:
1154                        //{
1155                        //      resize:
1156
1157                        //      function(  myWindow, width, height )
1158                        //      {
1159                        //              var myPanel     = myWindow.items.get( 'tabPanel' );
1160                        //              var myView      = myPanel.getActiveTab();
1161
1162                        //              myPanel.doLayout();
1163                        //              myWindow.doLayout();
1164                        //      }
1165                        //}
1166                });
1167
1168        return graphWindow;
1169}
1170
1171function nodeWindow( node, node_url )
1172{
1173        source_url      = '../../?c=' + myparams.c + '&h=' + node_url;
1174
1175        var nodePanel = new Ext.Panel(
1176        {
1177                html:   '<iframe style="overflow:auto;width:100%;height:100%;background: transparent;" frameborder="0"  src="' + source_url + '"></iframe>',
1178                layout: 'fit',
1179                tbar:
1180                [
1181                        {
1182                                text:           'Back',
1183                                handler:        function() 
1184                                {
1185                                        history.back();
1186                                }
1187                        },
1188                        {
1189                                text:           'Forward',
1190                                handler:        function() 
1191                                {
1192                                        history.forward();
1193                                }
1194                        },
1195                        {
1196                                text:           'Reload',
1197                                handler:        function() 
1198                                {
1199                                        my_panel        = this.findParentByType('panel').getEl();
1200                                        my_frame        = my_panel.child('iframe', true);
1201
1202                                        my_frame.contentDocument.location.reload();
1203                                }
1204                        }
1205                ],
1206        });
1207
1208        var win = new Ext.Window(
1209        {
1210                width:          800,
1211                //id:           'autoload-win',
1212                height:         300,
1213                maximizable:    true,
1214                //autoScroll:   true,
1215                title:          node,
1216                layout:         'fit',
1217                items:          [ nodePanel ],
1218                collapsible:    true,
1219                listeners:
1220                {
1221                        show:   function() 
1222                        {
1223                                this.loadMask = new Ext.LoadMask(this.body, {
1224                                        msg:'Loading. Please wait...'
1225                                 });
1226                        }
1227                }
1228        });
1229
1230        win.show();
1231}
1232
1233function ShowGraphs( Button, Event ) 
1234{
1235        var row_records         = CheckJobs.getSelections();
1236        var graphJids           = Array();
1237        var windowCount         = 0;
1238        var tabCount            = 0;
1239        var nodeDatastore;
1240        var graphView;
1241        var graphTab;
1242        var myWindow;
1243        var myPanel;
1244
1245        for( var i=0; i<row_records.length; i++ )
1246        {
1247                rsel            = row_records[i];
1248                jid             = rsel.get('jid');
1249
1250                if( graphJids[windowCount] == undefined )
1251                {
1252                        graphJids[windowCount]  = Array();
1253                }
1254
1255                graphJids[windowCount][tabCount]        = jid;
1256
1257                if( (i+1) < row_records.length )
1258                {
1259                        if( graphWindowBehaviour == 'new-window' )
1260                        {
1261                                windowCount++;
1262                        }
1263                        else
1264                        {
1265                                tabCount++;
1266                        }
1267                }
1268        }
1269
1270        for( var w=0; w<=windowCount; w++ )
1271        {
1272                if( ( graphWindowBehaviour == 'tabbed-prev-window' ) && ( previousGraphWindow != null ) && ( previousGraphPanel != null ) )
1273                {
1274                        myWindow        = previousGraphWindow;
1275                        myPanel         = previousGraphPanel;
1276                }
1277                else
1278                {
1279                        myPanel         = createGraphPanel();
1280                        myWindow        = createGraphWindow( myPanel, Button );
1281
1282                        myWindow.add( myPanel );
1283
1284                        globalWindowCount++;
1285                }
1286
1287                for( var t=0; t<=tabCount; t++ )
1288                {
1289                        nodeDatastore   = createNodesDataStore( myparams.c, graphJids[w][t] );
1290                        graphView       = createGraphView( nodeDatastore, graphJids[w][t] );
1291                        graphTab        = createGraphTab( graphView, graphJids[w][t], nodeDatastore );
1292
1293                        nodeDatastore.removeAll();
1294
1295                        lastView        = myPanel.add( graphTab );
1296
1297                        myPanel.doLayout();
1298                }
1299
1300                myPanel.setActiveTab( lastView );
1301
1302                myWindow.show( Button );
1303                myWindow.doLayout();
1304
1305                previousGraphWindow     = myWindow;
1306                previousGraphPanel      = myPanel;
1307        }
1308}
1309
1310var JobListingEditorGrid =
1311
1312        new Ext.grid.GridPanel(
1313        {
1314                id:             'JobListingEditorGrid',
1315                region:         'center',
1316                store:          JobsDataStore,
1317                colModel:       JobsColumnModel,
1318                enableColLock:  false,
1319                clicksToEdit:   1,
1320                loadMask:       true,
1321                selModel:       new Ext.grid.RowSelectionModel( { singleSelect: false } ),
1322                stripeRows:     true,
1323                sm:             CheckJobs,
1324                listeners:
1325                {
1326                        'cellclick':
1327                        {
1328                                scope:  this,
1329                                fn:     jobCellClick
1330                        }
1331                },
1332                bbar:
1333       
1334                new Ext.PagingToolbar(
1335                {
1336                        pageSize:       15,
1337                        store:          JobsDataStore,
1338                        displayInfo:    true,
1339                        displayMsg:     'Displaying jobs {0} - {1} out of {2} jobs total.',
1340                        emptyMsg:       'No jobs found to display',
1341                        plugins:        [ new Ext.ux.ProgressBarPager(), new Ext.ux.PageSizePlugin() ]
1342                }),
1343
1344                tbar: 
1345                [ 
1346                        'Search: ',
1347                        SearchField,
1348                        '-',
1349                        showGraphsButton,
1350                        '-',
1351                        filterButton 
1352                ],
1353
1354                view:           new Ext.ux.grid.BufferView(
1355                {
1356                        // custom row height
1357                        //rowHeight: 34,
1358                        // render rows as they come into viewable area.
1359                        scrollDelay: false
1360                })
1361
1362        });
1363
1364var ClusterImageWindow =
1365
1366        new Ext.Window(
1367        {
1368                id:             'ClusterImageWindow',
1369                title:          'Nodes',
1370                closable:       true,
1371                collapsible:    true,
1372                animCollapse:   true,
1373                width:          1,
1374                height:         1,
1375                y:              15,
1376                plain:          true,
1377                shadow:         true,
1378                resizable:      false,
1379                shadowOffset:   10,
1380                layout:         'fit',
1381                bbar: 
1382               
1383                        new Ext.ux.StatusBar(
1384                        {
1385                                defaultText:    'Ready.',
1386                                id:             'basic-statusbar',
1387                                defaultIconCls: ''
1388                        })
1389        });
1390
1391var GraphSummaryWindow =
1392
1393        new Ext.Window(
1394        {
1395                id:             'GraphSummaryWindow',
1396                title:          'Graph Summary',
1397                closable:       true,
1398                collapsible:    true,
1399                animCollapse:   true,
1400                width:          500,
1401                height:         400,
1402                x:              10,
1403                y:              10,
1404                plain:          true,
1405                shadow:         true,
1406                resizable:      true,
1407                shadowOffset:   10,
1408                layout:         'table',
1409                layoutConfig: 
1410                {
1411                        columns: 2
1412                },
1413                defaults:       { border: false },
1414                items: 
1415                [
1416                        {
1417                                id:             'monarchlogo',
1418                                cls:            'monarch',
1419                                bodyStyle:      'background: transparent'
1420                        },{
1421                                id:             'summarycount'
1422                        },{
1423                                id:             'rjqjgraph'
1424                        },{
1425                                id:             'pie',
1426                                colspan:        2
1427                        }
1428                ],
1429                bbar:
1430               
1431                        new Ext.ux.StatusBar(
1432                        {
1433                                defaultText:    'Ready.',
1434                                id:             'basic-statusbar',
1435                                defaultIconCls: ''
1436                        })
1437        });
1438
1439var JobListingWindow =
1440
1441        new Ext.Window(
1442        {
1443                id:             'JobListingWindow',
1444                title:          'Cluster Jobs Overview',
1445                closable:       true,
1446                collapsible:    true,
1447                animCollapse:   true,
1448                maximizable:    true,
1449                y:              375,
1450                width:          860,
1451                height:         645,
1452                plain:          true,
1453                shadow:         true,
1454                shadowOffset:   10,
1455                bodyStyle:      'overflow:auto; background: transparent; heigth: auto',
1456                layout:         'border',
1457                items:         
1458                [               JobListingEditorGrid,
1459                                {
1460                                        region:         'south', 
1461                                        layout:         'fit',
1462                                        id:             'preview-pane',
1463                                        height:         200,
1464                                        collapsible:    true,
1465                                        border:         true,
1466                                        title:          'Preview',
1467                                        split:          true,
1468                                        bodyStyle:      'overflow:auto; background: transparent; heigth: auto'
1469                                }
1470                ]
1471        });
Note: See TracBrowser for help on using the repository browser.