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

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

job_monarch/js/monarch.js:

  • more changes to graph tabs
File size: 28.2 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 fieldName   = JobsColumnModel.getColumnById( colindex ).dataIndex;
602        var fil_dis     = 'filter';
603        var fil_ena     = 'filterenabled';
604        var filterName  = fieldName;
605
606        if( fieldName == 'owner' || fieldName == 'jid' || fieldName == 'status' || fieldName == 'queue' || fieldName == 'nodes' )
607        {
608                if( fieldName == 'nodes' )
609                {
610                        fil_dis         = 'nodesfilter';
611                        fil_ena         = 'nodesfilterenabled';
612                        filterName      = 'host';
613                }
614                if( myfilters[filterName] != null )
615                {
616                        metadata.css    = fil_ena;
617                }
618                else
619                {
620                        metadata.css    = fil_dis;
621                }
622        }
623        return value;
624}
625
626var JobProxy = new Ext.data.HttpProxy(
627{
628        url:            'jobstore.php',
629        method:         'POST'
630});
631
632JobsDataStore = new Ext.data.Store(
633{
634        id:             'JobsDataStore',
635        proxy:          JobProxy,
636        baseParams:     { task: "GETJOBS" },
637        reader:
638                new Ext.data.JsonReader(
639                {
640                        root:           'results',
641                        totalProperty:  'total',
642                        id:             'id'
643                },
644                [
645                        {name: 'jid', type: 'int', mapping: 'jid'},
646                        {name: 'status', type: 'string', mapping: 'status'},
647                        {name: 'owner', type: 'string', mapping: 'owner'},
648                        {name: 'queue', type: 'string', mapping: 'queue'},
649                        {name: 'name', type: 'string', mapping: 'name'},
650                        {name: 'requested_time', type: 'string', mapping: 'requested_time'},
651                        {name: 'requested_memory', type: 'string', mapping: 'requested_memory'},
652                        {name: 'ppn', type: 'int', mapping: 'ppn'},
653                        {name: 'nodect', type: 'int', mapping: 'nodect'},
654                        {name: 'nodes', type: 'string', mapping: 'nodes'},
655                        {name: 'queued_timestamp', type: 'string', mapping: 'queued_timestamp'},
656                        {name: 'start_timestamp', type: 'string', mapping: 'start_timestamp'},
657                        {name: 'runningtime', type: 'string', mapping: 'runningtime'}
658                ]),
659        sortInfo: 
660        { 
661                field:          'jid', 
662                direction:      "DESC" 
663        },
664        remoteSort: true,
665        listeners:
666        { 
667                'beforeload':
668                {
669                        scope: this,
670                        fn:
671
672                        function( myStore, myOptions )
673                        {
674                                // Add a (bogus) timestamp, to create a unique url and prevent browser caching
675                                //
676                                myStore.proxy.url       = 'jobstore.php?timestamp=' + new Date().getTime();
677
678                                if( SearchField )
679                                {
680                                        search_value = SearchField.getEl().dom.value;
681                                        if( search_value == '' )
682                                        {
683                                                delete SearchField.store.baseParams['query'];
684                                                delete myfilters['query'];
685                                                delete myparams['query'];
686                                        }
687                                        else
688                                        {
689                                                myfilters['query']      = search_value;
690                                        }
691
692                                        makeFilterMenu();
693                                        reloadClusterImage();
694
695                                        filter_str = myparams.c + ' Jobs Overview' + makeFilterString();
696                                        JobListingWindow.setTitle( filter_str );
697                                }
698                        }
699                },
700                'load':
701                {
702                        scope: this,
703                        fn:
704
705                        function( store, records, options )
706                        {
707                                if( records.length == 1 ) // TODO: if job state is running
708                                {
709                                        jobid                   = records[0].get('jid');
710
711                                        var myPanel             = createGraphPanel();
712                                        var nodeDatastore       = createNodesDataStore( myparams.c, jobid );
713                                        var graphView           = createGraphView( nodeDatastore, jobid );
714                                        var graphTab            = createGraphTab( graphView, jobid, nodeDatastore );
715
716                                        //graphView.autoShow = true;
717
718                                        //newtab = myPanel.add( graphView );
719                                        var newtab = myPanel.add( graphTab );
720                                        myPanel.setActiveTab( newtab );
721                                        myPanel.doLayout();
722
723                                        //nodeDatastore.removeAll();
724
725                                        Ext.getCmp('preview-pane').removeAll();
726                                        Ext.getCmp('preview-pane').add( myPanel );
727                                        Ext.getCmp('preview-pane').doLayout();
728                                }
729                                else
730                                {
731                                        Ext.getCmp('preview-pane').removeAll();
732                                        Ext.getCmp('preview-pane').doLayout();
733                                }
734                        }
735                }
736        }
737});
738   
739var CheckJobs =
740
741        new Ext.grid.CheckboxSelectionModel(
742        {
743                listeners:
744                {
745                        'beforerowselect':
746                        {
747                                scope:  this,
748                                fn:     jobBeforeRowSelect
749                        },
750                        'rowselect':
751                        {
752                                scope:  this,
753                                fn:     jobRowSelect
754                        },
755                        'rowdeselect':
756                        {
757                                scope:  this,
758                                fn:     jobRowSelect
759                        }
760                }
761        });
762
763JobsColumnModel = new Ext.grid.ColumnModel(
764[
765        CheckJobs,
766        {
767                header:         '#',
768                tooltip:        'Job id',
769                readOnly:       true,
770                dataIndex:      'jid',
771                width:          50,
772                hidden:         false,
773                renderer:       jobCellRender
774        },{
775                header:         'S',
776                tooltip:        'Job status',
777                readOnly:       true,
778                dataIndex:      'status',
779                width:          20,
780                hidden:         false,
781                renderer:       jobCellRender
782        },{
783                header:         'User',
784                tooltip:        'Owner of job',
785                readOnly:       true,
786                dataIndex:      'owner',
787                width:          60,
788                hidden:         false,
789                renderer:       jobCellRender
790        },{
791                header:         'Queue',
792                tooltip:        'In which queue does this job reside',
793                readOnly:       true,
794                dataIndex:      'queue',
795                width:          60,
796                hidden:         false,
797                renderer:       jobCellRender
798        },{
799                header:         'Name',
800                tooltip:        'Name of job',
801                readOnly:       true,
802                dataIndex:      'name',
803                width:          100,
804                hidden:         false
805        },{
806                header:         'Requested Time',
807                tooltip:        'Amount of requested time (wallclock)',
808                readOnly:       true,
809                dataIndex:      'requested_time',
810                width:          100,
811                hidden:         false
812        },{
813                header:         'Requested Memory',
814                tooltip:        'Amount of requested memory',
815                readOnly:       true,
816                dataIndex:      'requested_memory',
817                width:          100,
818                hidden:         true
819        },{
820                header:         'P',
821                tooltip:        'Number of processors per node (PPN)',
822                readOnly:       true,
823                dataIndex:      'ppn',
824                width:          25,
825                hidden:         false
826        },{
827                header:         'N',
828                tooltip:        'Number of nodes (hosts)',
829                readOnly:       true,
830                dataIndex:      'nodect',
831                width:          25,
832                hidden:         false
833        },{
834                header:         'Nodes',
835                readOnly:       true,
836                dataIndex:      'nodes',
837                width:          100,
838                hidden:         false,
839                renderer:       jobCellRender
840        },{
841                header:         'Queued',
842                tooltip:        'At what time did this job enter the queue',
843                readOnly:       true,
844                dataIndex:      'queued_timestamp',
845                width:          120,
846                hidden:         false
847        },{
848                header:         'Started',
849                tooltip:        'At what time did this job enter the running status',
850                readOnly:       true,
851                dataIndex:      'start_timestamp',
852                width:          120,
853                hidden:         false
854        },{
855                header:         'Runningtime',
856                tooltip:        'How long has this job been in the running status',
857                readOnly:       true,
858                dataIndex:      'runningtime',
859                width:          140,
860                hidden:         false
861        }
862]);
863
864JobsColumnModel.defaultSortable = true;
865
866var win;
867
868MetricsDataStore = new Ext.data.Store(
869{
870        id:             'MetricsDataStore',
871        proxy:          new Ext.data.HttpProxy(
872        {
873                url:            'jobstore.php',
874                method:         'POST'
875        }),
876        autoLoad:       true,
877        baseParams:     { task: "GETMETRICS" },
878        reader:
879                new Ext.data.JsonReader(
880                {
881                        root:           'names',
882                        totalProperty:  'total',
883                        id:             'id'
884                },
885                [{
886                        name:           'ID'
887                },{
888                        name:           'name'
889                }
890                ]),
891        listeners:
892        { 
893                'beforeload':
894                {
895                        scope: this,
896                        fn:
897
898                        function( myStore, myOptions )
899                        {
900                                // Add a (bogus) timestamp, to create a unique url and prevent browser caching
901                                //
902                                myStore.proxy.url       = 'jobstore.php?timestamp=' + new Date().getTime();
903                        }
904                }
905        }
906});
907
908SearchField     = new Ext.app.SearchField(
909                {
910                        store:  JobsDataStore,
911                        params: {start: 0, limit: mylimit},
912                        width:  200
913                });
914
915function createNodesDataStore( cluster, jid )
916{
917        nodesDataStore =
918
919                new Ext.data.Store(
920                {
921                        //id:           'NodesDataStore',
922                        proxy:          new Ext.data.HttpProxy(
923                        {
924                                url:            'jobstore.php',
925                                method:         'POST'
926                        }),
927                        autoLoad:       true,
928                        baseParams:
929                        {
930                                'task':                 "GETNODES",
931                                'c':                    cluster,
932                                'jid':                  jid,
933                                'metricname':           'load_one'
934                        },
935                        reader: new Ext.data.JsonReader(
936                        {
937                                root:           'results',
938                                totalProperty:  'total',
939                                id:             'id'
940                        },[
941                                {name: 'jid', type: 'string', mapping: 'jid'},
942                                {name: 'ga', type: 'string', mapping: 'ga'}
943                        ]),
944                        listeners:
945                        { 
946                                'beforeload':
947                                {
948                                        scope: this,
949                                        fn:
950
951                                        function( myStore, myOptions )
952                                        {
953                                                // Add a (bogus) timestamp, to create a unique url and prevent browser caching
954                                                //
955                                                myStore.proxy.url       = 'jobstore.php?timestamp=' + new Date().getTime();
956                                        }
957                                }
958                        }
959
960                });
961
962        return nodesDataStore;
963}
964
965function createGraphView( store, jid )
966{
967        var graphView =
968       
969                new Ext.DataView(
970                {
971                        //id:           jid,
972                        //id:           'jobPanel',
973                        itemSelector:   'thumb',
974                        region:         'center',
975                        title:          jid,
976                        //style:                'overflow:auto, heigth: auto',
977                        bodyStyle:      'overflow:auto; background: transparent; heigth: auto',
978                        multiSelect:    true,
979                        //autoHeight:   true,
980                        autoShow:       true,
981                        xtype:          'dataview',
982                        //autoScroll:   true,
983                        //loadMask:     true,
984                        store:          store,
985                        //layout:               'fit',
986                        closable:       true,
987                        tpl:
988                       
989                                new Ext.XTemplate(
990                                        '<tpl for=".">',
991                                        //'<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>',
992                                        '<div class="rrd-float"><img src="./graph.php?z=small&{ga}" border="0" style="cursor:pointer" onclick="nodeWindow(\'node x\', \'{ga}\');"></a></div>',
993                                        '</tpl>')
994                });
995
996        return graphView;
997}
998
999
1000function createGraphTab( view, jobid, store )
1001{
1002        var graphTab =
1003
1004                new Ext.Panel(
1005                {
1006                        title:          jobid,
1007                        layout:         'border',
1008                        xtype:          'panel',
1009                        bodyStyle:      'overflow:auto; background: transparent; heigth: auto',
1010                        closable:       true,
1011
1012                        tbar:
1013                        [
1014                                'Metric name: ',
1015                                new Ext.form.ComboBox(
1016                                {
1017                                        fieldLabel:     'Metric',
1018                                        store:          MetricsDataStore,
1019                                        valueField:     'name',
1020                                        displayField:   'name',
1021                                        typeAhead:      true,
1022                                        mode:           'remote',
1023                                        triggerAction:  'all',
1024                                        emptyText:      'load_one',
1025                                        selectOnFocus:  true,
1026                                        xtype:          'combo',
1027                                        width:          100,
1028                                        listeners:
1029                                        {
1030                                                select: 
1031                                                               
1032                                                function(combo, record, index)
1033                                                {
1034                                                        var metric      = record.data.name;
1035
1036                                                        var parentPanel = this.findParentByType( 'panel' );
1037                                                        var my_dataview = parentPanel.items.get(0);
1038
1039                                                        my_dataview.getStore().baseParams.metricname    = metric;
1040                                                        my_dataview.getStore().reload();
1041                                                }
1042                                        }
1043                                }),
1044                                '-',
1045                                'Range: ',
1046                                new Ext.form.ComboBox(
1047                                {
1048                                        fieldLabel:     'Range',
1049                                        //store:                MetricsDataStore,
1050                                        valueField:     'name',
1051                                        displayField:   'name',
1052                                        typeAhead:      true,
1053                                        //mode:         'remote',
1054                                        triggerAction:  'all',
1055                                        emptyText:      'job',
1056                                        selectOnFocus:  true,
1057                                        xtype:          'combo',
1058                                        width:          100,
1059                                        listeners:
1060                                        {
1061                                        //      select:
1062                                                               
1063                                        //      function(combo, record, index)
1064                                        //      {
1065                                        //              var metric      = record.data.name;
1066
1067                                        //              var parentPanel = this.findParentByType( 'panel' );
1068                                        //              var my_dataview = parentPanel.items.get(0);
1069
1070                                        //              my_dataview.getStore().baseParams.metricname    = metric;
1071                                        //              my_dataview.getStore().reload();
1072                                        //      }
1073                                        }
1074                                }),
1075                        ],
1076
1077                        items:
1078                        [
1079                                view,
1080                                {
1081                                        region:         'east',
1082                                        split:          true,
1083                                        title:          'Job info',
1084                                        width:          200,
1085                                        layout:         'fit',
1086                                        //id:           'jobinfo-pane',
1087                                        collapsible:    true,
1088                                        border:         true
1089                                }
1090                        ]
1091                });
1092
1093        return graphTab;
1094}
1095
1096
1097function createGraphPanel( view )
1098{
1099        var scrollerMenu = new Ext.ux.TabScrollerMenu(
1100        {
1101                maxText  : 15,
1102                pageSize : 5
1103        });
1104
1105
1106        var graphPanel = 
1107
1108                new Ext.TabPanel(
1109                {
1110                        //id:           'tabPanel',
1111                        xtype:          'tabpanel',
1112                        //layout:               'border',
1113                        //region:               'center',
1114                        //bodyStyle:    'background: transparent',
1115                        autoShow:       true,
1116                        //autoHeight:   true,
1117                        //autoWidth:    true,
1118                        enableTabScroll:true,
1119                        resizeTabs:     true,
1120                        //border:               false,
1121                        bodyStyle:      'overflow:auto; background: transparent; heigth: auto',
1122                        minTabWidth:    60,
1123                        plugins:        [ scrollerMenu ],
1124
1125                        // RB TODO: range combobox; hour, day, week, etc
1126
1127
1128                        //listeners:
1129                        //{
1130                        //      tabchange:
1131                               
1132                        //      function( panel, tab )
1133                        //      {
1134                        //              if( panel.rendered )
1135                        //              {
1136                        //                      combobox        = tab.findParentByType( 'tabpanel' );
1137                        //                      alert( combobox.xtype );
1138                        //                      combobox.value  = tab.getStore().baseParams.metricname;
1139                        //              }
1140                        //      }
1141                        //}
1142                });
1143
1144        return graphPanel;
1145}
1146
1147function createGraphWindow( panel, Button )
1148{
1149        var graphWindow =
1150
1151                new Ext.Window(
1152                {
1153                        animateTarget:  Button,
1154                        width:          500,
1155                        height:         300,
1156                        closeAction:    'hide',
1157                        collapsible:    true,
1158                        animCollapse:   true,
1159                        maximizable:    true,
1160                        layout:         'fit',
1161                        //autoScroll:   true,
1162                        //defaults:     {autoScroll:true},
1163                        title:          'Jobs',
1164                        //tbar:         panel,
1165                        items:          [ panel ]
1166               
1167                        //listeners:
1168                        //{
1169                        //      resize:
1170
1171                        //      function(  myWindow, width, height )
1172                        //      {
1173                        //              var myPanel     = myWindow.items.get( 'tabPanel' );
1174                        //              var myView      = myPanel.getActiveTab();
1175
1176                        //              myPanel.doLayout();
1177                        //              myWindow.doLayout();
1178                        //      }
1179                        //}
1180                });
1181
1182        return graphWindow;
1183}
1184
1185function nodeWindow( node, node_url )
1186{
1187        source_url      = '../../?c=' + myparams.c + '&h=' + node_url;
1188
1189        var nodePanel = new Ext.Panel(
1190        {
1191                html:   '<iframe style="overflow:auto;width:100%;height:100%;background: transparent;" frameborder="0"  src="' + source_url + '"></iframe>',
1192                layout: 'fit',
1193                tbar:
1194                [
1195                        {
1196                                text:           'Back',
1197                                handler:        function() 
1198                                {
1199                                        history.back();
1200                                }
1201                        },
1202                        {
1203                                text:           'Forward',
1204                                handler:        function() 
1205                                {
1206                                        history.forward();
1207                                }
1208                        },
1209                        {
1210                                text:           'Reload',
1211                                handler:        function() 
1212                                {
1213                                        my_panel        = this.findParentByType('panel').getEl();
1214                                        my_frame        = my_panel.child('iframe', true);
1215
1216                                        my_frame.contentDocument.location.reload();
1217                                }
1218                        }
1219                ],
1220        });
1221
1222        var win = new Ext.Window(
1223        {
1224                width:          800,
1225                //id:           'autoload-win',
1226                height:         300,
1227                maximizable:    true,
1228                //autoScroll:   true,
1229                title:          node,
1230                layout:         'fit',
1231                items:          [ nodePanel ],
1232                collapsible:    true,
1233                listeners:
1234                {
1235                        show:   function() 
1236                        {
1237                                this.loadMask = new Ext.LoadMask(this.body, {
1238                                        msg:'Loading. Please wait...'
1239                                 });
1240                        }
1241                }
1242        });
1243
1244        win.show();
1245}
1246
1247function ShowGraphs( Button, Event ) 
1248{
1249        var row_records         = CheckJobs.getSelections();
1250        var graphJids           = Array();
1251        var windowCount         = 0;
1252        var tabCount            = 0;
1253        var nodeDatastore;
1254        var graphView;
1255        var graphTab;
1256        var myWindow;
1257        var myPanel;
1258
1259        for( var i=0; i<row_records.length; i++ )
1260        {
1261                rsel            = row_records[i];
1262                jid             = rsel.get('jid');
1263
1264                if( graphJids[windowCount] == undefined )
1265                {
1266                        graphJids[windowCount]  = Array();
1267                }
1268
1269                graphJids[windowCount][tabCount]        = jid;
1270
1271                if( (i+1) < row_records.length )
1272                {
1273                        if( graphWindowBehaviour == 'new-window' )
1274                        {
1275                                windowCount++;
1276                        }
1277                        else
1278                        {
1279                                tabCount++;
1280                        }
1281                }
1282        }
1283
1284        for( var w=0; w<=windowCount; w++ )
1285        {
1286                if( ( graphWindowBehaviour == 'tabbed-prev-window' ) && ( previousGraphWindow != null ) && ( previousGraphPanel != null ) )
1287                {
1288                        myWindow        = previousGraphWindow;
1289                        myPanel         = previousGraphPanel;
1290                }
1291                else
1292                {
1293                        myPanel         = createGraphPanel();
1294                        myWindow        = createGraphWindow( myPanel, Button );
1295
1296                        myWindow.add( myPanel );
1297
1298                        globalWindowCount++;
1299                }
1300
1301                for( var t=0; t<=tabCount; t++ )
1302                {
1303                        nodeDatastore   = createNodesDataStore( myparams.c, graphJids[w][t] );
1304                        graphView       = createGraphView( nodeDatastore, graphJids[w][t] );
1305                        graphTab        = createGraphTab( graphView, graphJids[w][t], nodeDatastore );
1306
1307                        nodeDatastore.removeAll();
1308
1309                        lastView        = myPanel.add( graphTab );
1310
1311                        myPanel.doLayout();
1312                }
1313
1314                myPanel.setActiveTab( lastView );
1315
1316                myWindow.show( Button );
1317                myWindow.doLayout();
1318
1319                previousGraphWindow     = myWindow;
1320                previousGraphPanel      = myPanel;
1321        }
1322}
1323
1324var JobListingEditorGrid =
1325
1326        new Ext.grid.EditorGridPanel(
1327        {
1328                id:             'JobListingEditorGrid',
1329                region:         'center',
1330                store:          JobsDataStore,
1331                cm:             JobsColumnModel,
1332                enableColLock:  false,
1333                clicksToEdit:   1,
1334                loadMask:       true,
1335                selModel:       new Ext.grid.RowSelectionModel( { singleSelect: false } ),
1336                stripeRows:     true,
1337                sm:             CheckJobs,
1338                listeners:
1339                {
1340                        'cellclick':
1341                        {
1342                                scope:  this,
1343                                fn:     jobCellClick
1344                        }
1345                },
1346                bbar:
1347       
1348                new Ext.PagingToolbar(
1349                {
1350                        pageSize:       15,
1351                        store:          JobsDataStore,
1352                        displayInfo:    true,
1353                        displayMsg:     'Displaying jobs {0} - {1} out of {2} jobs total.',
1354                        emptyMsg:       'No jobs found to display',
1355                        plugins:        [ new Ext.ux.ProgressBarPager(), new Ext.ux.PageSizePlugin() ]
1356                }),
1357
1358                tbar: 
1359                [ 
1360                        'Search: ',
1361                        SearchField,
1362                        '-',
1363                        showGraphsButton,
1364                        '-',
1365                        filterButton 
1366                ],
1367
1368                view:           new Ext.ux.grid.BufferView(
1369                {
1370                        // custom row height
1371                        //rowHeight: 34,
1372                        // render rows as they come into viewable area.
1373                        scrollDelay: false
1374                })
1375
1376        });
1377
1378var ClusterImageWindow =
1379
1380        new Ext.Window(
1381        {
1382                id:             'ClusterImageWindow',
1383                title:          'Nodes',
1384                closable:       true,
1385                collapsible:    true,
1386                animCollapse:   true,
1387                width:          1,
1388                height:         1,
1389                y:              15,
1390                plain:          true,
1391                shadow:         true,
1392                resizable:      false,
1393                shadowOffset:   10,
1394                layout:         'fit',
1395                bbar: 
1396               
1397                        new Ext.ux.StatusBar(
1398                        {
1399                                defaultText:    'Ready.',
1400                                id:             'basic-statusbar',
1401                                defaultIconCls: ''
1402                        })
1403        });
1404
1405var GraphSummaryWindow =
1406
1407        new Ext.Window(
1408        {
1409                id:             'GraphSummaryWindow',
1410                title:          'Graph Summary',
1411                closable:       true,
1412                collapsible:    true,
1413                animCollapse:   true,
1414                width:          500,
1415                height:         400,
1416                x:              10,
1417                y:              10,
1418                plain:          true,
1419                shadow:         true,
1420                resizable:      true,
1421                shadowOffset:   10,
1422                layout:         'table',
1423                layoutConfig: 
1424                {
1425                        columns: 2
1426                },
1427                defaults:       { border: false },
1428                items: 
1429                [
1430                        {
1431                                id:             'monarchlogo',
1432                                cls:            'monarch',
1433                                bodyStyle:      'background: transparent'
1434                        },{
1435                                id:             'summarycount'
1436                        },{
1437                                id:             'rjqjgraph'
1438                        },{
1439                                id:             'pie',
1440                                colspan:        2
1441                        }
1442                ],
1443                bbar:
1444               
1445                        new Ext.ux.StatusBar(
1446                        {
1447                                defaultText:    'Ready.',
1448                                id:             'basic-statusbar',
1449                                defaultIconCls: ''
1450                        })
1451        });
1452
1453var JobListingWindow =
1454
1455        new Ext.Window(
1456        {
1457                id:             'JobListingWindow',
1458                title:          'Cluster Jobs Overview',
1459                closable:       true,
1460                collapsible:    true,
1461                animCollapse:   true,
1462                maximizable:    true,
1463                y:              375,
1464                width:          860,
1465                height:         645,
1466                plain:          true,
1467                shadow:         true,
1468                shadowOffset:   10,
1469                bodyStyle:      'overflow:auto; background: transparent; heigth: auto',
1470                layout:         'border',
1471                items:         
1472                [               JobListingEditorGrid,
1473                                {
1474                                        region:         'south', 
1475                                        layout:         'fit',
1476                                        id:             'preview-pane',
1477                                        height:         200,
1478                                        collapsible:    true,
1479                                        border:         true,
1480                                        title:          'Preview',
1481                                        split:          true,
1482                                        bodyStyle:      'overflow:auto; background: transparent; heigth: auto'
1483                                }
1484                ]
1485        });
Note: See TracBrowser for help on using the repository browser.