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

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

job_monarch/templates/header.tpl:

job_monarch/image.php:

  • cache XML data during jobmond's polling interval

job_monarch/jobstore.php:

  • cache XML data during jobmond's polling interval
  • set host link

job_monarch/js/monarch.js:

  • small changes to nodes popup window
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 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        defaults:
767        {
768                hidden:         false,
769                readonly:       true,
770                sortable:       true
771        },
772        columns:
773        [
774                CheckJobs,
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                                {name: 'nodename', type: 'string', mapping: 'nodename'},
930                                {name: 'hostlink', type: 'string', mapping: 'hostlink'}
931                        ]),
932                        listeners:
933                        { 
934                                'beforeload':
935                                {
936                                        scope: this,
937                                        fn:
938
939                                        function( myStore, myOptions )
940                                        {
941                                                // Add a (bogus) timestamp, to create a unique url and prevent browser caching
942                                                //
943                                                myStore.proxy.url       = 'jobstore.php?timestamp=' + new Date().getTime();
944                                        }
945                                }
946                        }
947
948                });
949
950        return nodesDataStore;
951}
952
953function createGraphView( store, jid )
954{
955        var graphView =
956       
957                new Ext.DataView(
958                {
959                        //id:           jid,
960                        //id:           'jobPanel',
961                        itemSelector:   'thumb',
962                        region:         'center',
963                        title:          jid,
964                        //style:                'overflow:auto, heigth: auto',
965                        bodyStyle:      'overflow:auto; background: transparent; heigth: auto',
966                        multiSelect:    true,
967                        //autoHeight:   true,
968                        autoShow:       true,
969                        xtype:          'dataview',
970                        //autoScroll:   true,
971                        //loadMask:     true,
972                        store:          store,
973                        //layout:               'fit',
974                        closable:       true,
975                        tpl:
976                       
977                                new Ext.XTemplate(
978                                        '<tpl for=".">',
979                                        //'<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>',
980                                        '<div class="rrd-float"><img src="./graph.php?z=small&{ga}" border="0" style="cursor:pointer" onclick="nodeWindow(\'{nodename}\', \'{hostlink}\');"></a></div>',
981                                        '</tpl>')
982                });
983
984        return graphView;
985}
986
987
988function createGraphTab( view, jobid, store )
989{
990        var graphTab =
991
992                new Ext.Panel(
993                {
994                        title:          jobid,
995                        layout:         'border',
996                        xtype:          'panel',
997                        bodyStyle:      'overflow:auto; background: transparent; heigth: auto',
998                        closable:       true,
999
1000                        tbar:
1001                        [
1002                                'Metric name: ',
1003                                new Ext.form.ComboBox(
1004                                {
1005                                        fieldLabel:     'Metric',
1006                                        store:          MetricsDataStore,
1007                                        valueField:     'name',
1008                                        displayField:   'name',
1009                                        typeAhead:      true,
1010                                        mode:           'remote',
1011                                        triggerAction:  'all',
1012                                        emptyText:      'load_one',
1013                                        selectOnFocus:  true,
1014                                        xtype:          'combo',
1015                                        width:          100,
1016                                        listeners:
1017                                        {
1018                                                select: 
1019                                                               
1020                                                function(combo, record, index)
1021                                                {
1022                                                        var metric      = record.data.name;
1023
1024                                                        var parentPanel = this.findParentByType( 'panel' );
1025                                                        var my_dataview = parentPanel.items.get(0);
1026
1027                                                        my_dataview.getStore().baseParams.metricname    = metric;
1028                                                        my_dataview.getStore().reload();
1029                                                }
1030                                        }
1031                                }),
1032                                '-',
1033                                'Range: ',
1034                                new Ext.form.ComboBox(
1035                                {
1036                                        fieldLabel:     'Range',
1037                                        //store:                MetricsDataStore,
1038                                        valueField:     'name',
1039                                        displayField:   'name',
1040                                        typeAhead:      true,
1041                                        //mode:         'remote',
1042                                        triggerAction:  'all',
1043                                        emptyText:      'job',
1044                                        selectOnFocus:  true,
1045                                        xtype:          'combo',
1046                                        width:          100,
1047                                        listeners:
1048                                        {
1049                                        //      select:
1050                                                               
1051                                        //      function(combo, record, index)
1052                                        //      {
1053                                        //              var metric      = record.data.name;
1054
1055                                        //              var parentPanel = this.findParentByType( 'panel' );
1056                                        //              var my_dataview = parentPanel.items.get(0);
1057
1058                                        //              my_dataview.getStore().baseParams.metricname    = metric;
1059                                        //              my_dataview.getStore().reload();
1060                                        //      }
1061                                        }
1062                                }),
1063                        ],
1064
1065                        items:
1066                        [
1067                                view,
1068                                {
1069                                        region:         'east',
1070                                        split:          true,
1071                                        title:          'Job info',
1072                                        width:          200,
1073                                        layout:         'fit',
1074                                        //id:           'jobinfo-pane',
1075                                        collapsible:    true,
1076                                        border:         true
1077                                }
1078                        ]
1079                });
1080
1081        return graphTab;
1082}
1083
1084
1085function createGraphPanel( view )
1086{
1087        var scrollerMenu = new Ext.ux.TabScrollerMenu(
1088        {
1089                maxText  : 15,
1090                pageSize : 5
1091        });
1092
1093
1094        var graphPanel = 
1095
1096                new Ext.TabPanel(
1097                {
1098                        //id:           'tabPanel',
1099                        xtype:          'tabpanel',
1100                        //layout:               'border',
1101                        //region:               'center',
1102                        //bodyStyle:    'background: transparent',
1103                        autoShow:       true,
1104                        //autoHeight:   true,
1105                        //autoWidth:    true,
1106                        enableTabScroll:true,
1107                        resizeTabs:     true,
1108                        //border:               false,
1109                        bodyStyle:      'overflow:auto; background: transparent; heigth: auto',
1110                        minTabWidth:    60,
1111                        plugins:        [ scrollerMenu ],
1112
1113                        // RB TODO: range combobox; hour, day, week, etc
1114
1115
1116                        //listeners:
1117                        //{
1118                        //      tabchange:
1119                               
1120                        //      function( panel, tab )
1121                        //      {
1122                        //              if( panel.rendered )
1123                        //              {
1124                        //                      combobox        = tab.findParentByType( 'tabpanel' );
1125                        //                      alert( combobox.xtype );
1126                        //                      combobox.value  = tab.getStore().baseParams.metricname;
1127                        //              }
1128                        //      }
1129                        //}
1130                });
1131
1132        return graphPanel;
1133}
1134
1135function createGraphWindow( panel, Button )
1136{
1137        var graphWindow =
1138
1139                new Ext.Window(
1140                {
1141                        animateTarget:  Button,
1142                        width:          500,
1143                        height:         300,
1144                        closeAction:    'hide',
1145                        collapsible:    true,
1146                        animCollapse:   true,
1147                        maximizable:    true,
1148                        layout:         'fit',
1149                        //autoScroll:   true,
1150                        //defaults:     {autoScroll:true},
1151                        title:          'Jobs',
1152                        //tbar:         panel,
1153                        items:          [ panel ]
1154               
1155                        //listeners:
1156                        //{
1157                        //      resize:
1158
1159                        //      function(  myWindow, width, height )
1160                        //      {
1161                        //              var myPanel     = myWindow.items.get( 'tabPanel' );
1162                        //              var myView      = myPanel.getActiveTab();
1163
1164                        //              myPanel.doLayout();
1165                        //              myWindow.doLayout();
1166                        //      }
1167                        //}
1168                });
1169
1170        return graphWindow;
1171}
1172
1173function nodeWindow( node, node_url )
1174{
1175        source_url      = '../../?c=' + myparams.c + '&h=' + node_url;
1176
1177        var nodePanel = new Ext.Panel(
1178        {
1179                html:   '<iframe style="overflow:auto;width:100%;height:100%;background: transparent;" frameborder="0"  src="' + source_url + '"></iframe>',
1180                layout: 'fit',
1181                tbar:
1182                [
1183                        {
1184                                text:           'Back',
1185                                handler:        function() 
1186                                {
1187                                        history.back();
1188                                }
1189                        },
1190                        {
1191                                text:           'Forward',
1192                                handler:        function() 
1193                                {
1194                                        history.forward();
1195                                }
1196                        },
1197                        {
1198                                text:           'Reload',
1199                                handler:        function() 
1200                                {
1201                                        my_panel        = this.findParentByType('panel').getEl();
1202                                        my_frame        = my_panel.child('iframe', true);
1203
1204                                        my_frame.contentDocument.location.reload();
1205                                }
1206                        }
1207                ],
1208        });
1209
1210        var win = new Ext.Window(
1211        {
1212                width:          800,
1213                //id:           'autoload-win',
1214                height:         300,
1215                maximizable:    true,
1216                //autoScroll:   true,
1217                title:          node,
1218                layout:         'fit',
1219                items:          [ nodePanel ],
1220                collapsible:    true,
1221                listeners:
1222                {
1223                        show:   function() 
1224                        {
1225                                this.loadMask = new Ext.LoadMask(this.body, {
1226                                        msg:'Loading. Please wait...'
1227                                 });
1228                        }
1229                }
1230        });
1231
1232        win.show();
1233}
1234
1235function ShowGraphs( Button, Event ) 
1236{
1237        var row_records         = CheckJobs.getSelections();
1238        var graphJids           = Array();
1239        var windowCount         = 0;
1240        var tabCount            = 0;
1241        var nodeDatastore;
1242        var graphView;
1243        var graphTab;
1244        var myWindow;
1245        var myPanel;
1246
1247        for( var i=0; i<row_records.length; i++ )
1248        {
1249                rsel            = row_records[i];
1250                jid             = rsel.get('jid');
1251
1252                if( graphJids[windowCount] == undefined )
1253                {
1254                        graphJids[windowCount]  = Array();
1255                }
1256
1257                graphJids[windowCount][tabCount]        = jid;
1258
1259                if( (i+1) < row_records.length )
1260                {
1261                        if( graphWindowBehaviour == 'new-window' )
1262                        {
1263                                windowCount++;
1264                        }
1265                        else
1266                        {
1267                                tabCount++;
1268                        }
1269                }
1270        }
1271
1272        for( var w=0; w<=windowCount; w++ )
1273        {
1274                if( ( graphWindowBehaviour == 'tabbed-prev-window' ) && ( previousGraphWindow != null ) && ( previousGraphPanel != null ) )
1275                {
1276                        myWindow        = previousGraphWindow;
1277                        myPanel         = previousGraphPanel;
1278                }
1279                else
1280                {
1281                        myPanel         = createGraphPanel();
1282                        myWindow        = createGraphWindow( myPanel, Button );
1283
1284                        myWindow.add( myPanel );
1285
1286                        globalWindowCount++;
1287                }
1288
1289                for( var t=0; t<=tabCount; t++ )
1290                {
1291                        nodeDatastore   = createNodesDataStore( myparams.c, graphJids[w][t] );
1292                        graphView       = createGraphView( nodeDatastore, graphJids[w][t] );
1293                        graphTab        = createGraphTab( graphView, graphJids[w][t], nodeDatastore );
1294
1295                        nodeDatastore.removeAll();
1296
1297                        lastView        = myPanel.add( graphTab );
1298
1299                        myPanel.doLayout();
1300                }
1301
1302                myPanel.setActiveTab( lastView );
1303
1304                myWindow.show( Button );
1305                myWindow.doLayout();
1306
1307                previousGraphWindow     = myWindow;
1308                previousGraphPanel      = myPanel;
1309        }
1310}
1311
1312var JobListingEditorGrid =
1313
1314        new Ext.grid.GridPanel(
1315        {
1316                id:             'JobListingEditorGrid',
1317                region:         'center',
1318                store:          JobsDataStore,
1319                colModel:       JobsColumnModel,
1320                enableColLock:  false,
1321                clicksToEdit:   1,
1322                loadMask:       true,
1323                selModel:       new Ext.grid.RowSelectionModel( { singleSelect: false } ),
1324                stripeRows:     true,
1325                sm:             CheckJobs,
1326                listeners:
1327                {
1328                        'cellclick':
1329                        {
1330                                scope:  this,
1331                                fn:     jobCellClick
1332                        }
1333                },
1334                bbar:
1335       
1336                new Ext.PagingToolbar(
1337                {
1338                        pageSize:       15,
1339                        store:          JobsDataStore,
1340                        displayInfo:    true,
1341                        displayMsg:     'Displaying jobs {0} - {1} out of {2} jobs total.',
1342                        emptyMsg:       'No jobs found to display',
1343                        plugins:        [ new Ext.ux.ProgressBarPager(), new Ext.ux.PageSizePlugin() ]
1344                }),
1345
1346                tbar: 
1347                [ 
1348                        'Search: ',
1349                        SearchField,
1350                        '-',
1351                        showGraphsButton,
1352                        '-',
1353                        filterButton 
1354                ],
1355
1356                view:           new Ext.ux.grid.BufferView(
1357                {
1358                        // custom row height
1359                        //rowHeight: 34,
1360                        // render rows as they come into viewable area.
1361                        scrollDelay: false
1362                })
1363
1364        });
1365
1366var ClusterImageWindow =
1367
1368        new Ext.Window(
1369        {
1370                id:             'ClusterImageWindow',
1371                title:          'Nodes',
1372                closable:       true,
1373                collapsible:    true,
1374                animCollapse:   true,
1375                width:          1,
1376                height:         1,
1377                y:              15,
1378                plain:          true,
1379                shadow:         true,
1380                resizable:      false,
1381                shadowOffset:   10,
1382                layout:         'fit',
1383                bbar: 
1384               
1385                        new Ext.ux.StatusBar(
1386                        {
1387                                defaultText:    'Ready.',
1388                                id:             'basic-statusbar',
1389                                defaultIconCls: ''
1390                        })
1391        });
1392
1393var GraphSummaryWindow =
1394
1395        new Ext.Window(
1396        {
1397                id:             'GraphSummaryWindow',
1398                title:          'Graph Summary',
1399                closable:       true,
1400                collapsible:    true,
1401                animCollapse:   true,
1402                width:          500,
1403                height:         400,
1404                x:              10,
1405                y:              10,
1406                plain:          true,
1407                shadow:         true,
1408                resizable:      true,
1409                shadowOffset:   10,
1410                layout:         'table',
1411                layoutConfig: 
1412                {
1413                        columns: 2
1414                },
1415                defaults:       { border: false },
1416                items: 
1417                [
1418                        {
1419                                id:             'monarchlogo',
1420                                cls:            'monarch',
1421                                bodyStyle:      'background: transparent'
1422                        },{
1423                                id:             'summarycount'
1424                        },{
1425                                id:             'rjqjgraph'
1426                        },{
1427                                id:             'pie',
1428                                colspan:        2
1429                        }
1430                ],
1431                bbar:
1432               
1433                        new Ext.ux.StatusBar(
1434                        {
1435                                defaultText:    'Ready.',
1436                                id:             'basic-statusbar',
1437                                defaultIconCls: ''
1438                        })
1439        });
1440
1441var JobListingWindow =
1442
1443        new Ext.Window(
1444        {
1445                id:             'JobListingWindow',
1446                title:          'Cluster Jobs Overview',
1447                closable:       true,
1448                collapsible:    true,
1449                animCollapse:   true,
1450                maximizable:    true,
1451                y:              375,
1452                width:          860,
1453                height:         645,
1454                plain:          true,
1455                shadow:         true,
1456                shadowOffset:   10,
1457                bodyStyle:      'overflow:auto; background: transparent; heigth: auto',
1458                layout:         'border',
1459                items:         
1460                [               JobListingEditorGrid,
1461                                {
1462                                        region:         'south', 
1463                                        layout:         'fit',
1464                                        id:             'preview-pane',
1465                                        height:         200,
1466                                        collapsible:    true,
1467                                        border:         true,
1468                                        title:          'Preview',
1469                                        split:          true,
1470                                        bodyStyle:      'overflow:auto; background: transparent; heigth: auto'
1471                                }
1472                ]
1473        });
Note: See TracBrowser for help on using the repository browser.