source: trunk/web2/addons/job_monarch/js/monarch.js @ 595

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

js/monarch.js:

  • added modulair/tabbed graph views of jobs
File size: 21.6 KB
RevLine 
[532]1var JobsDataStore;
2var JobsColumnModel;
3var JobListingEditorGrid;
4var JobListingWindow;
[535]5var JobProxy;
[567]6var SearchField;
[583]7var filterButton;
[593]8
9// associative filter array
10//
[546]11var myfilters = { };
[593]12
13// any other datastore params
14//
[546]15var myparams = { };
[593]16
17// (default) paging size
18//
[558]19var mylimit = 15;
[593]20
[549]21var ClusterImageArgs = { };
[532]22
[546]23var filterfields = [ "jid", "queue", "name", "owner" ];
24
[595]25var graphWindowBehaviour = 'tabbed-new-window';
26var previousGraphWindow;
27
[593]28var filterMenu = new Ext.menu.Menu(
29{
30        id:     'filterMenu',
31        items:  [ new Ext.menu.Item({ text: 'Clear all', handler: clearFilters }) ]
[583]32});
33
[593]34var filterButton = new Ext.MenuButton(
35{
36        id:             'filtermenuknop',
37        text:           'Filters',
[595]38        toolip:         'Click to change filter options',
[593]39        disabled:       true,
40        menu:           filterMenu,
41        listeners:
42        {
43                'click':
44                {
45                        scope:  this,
46                        fn:     function( myButton, event )
[595]47                                {       // immediatly show menu when button is clicked
[593]48                                        myButton.menu.show( myButton.getEl() );
[590]49                                }
[593]50                }
51        }
52});
[590]53
[594]54function checkGraphWindowOption( item, checked )
55{
[595]56        graphWindowBehaviour    = item.id;
[594]57}
58
59var graphMenu = new Ext.menu.Menu(
60{
61        id:     'graphMenu',
62        items:
63        [{
[595]64                id:             'new-window',
[594]65                text:           'Each job in new window',
66                checked:        false,
67                group:          'graphwindow',
68                handler:        checkGraphWindowOption
69        },{
[595]70                id:             'tabbed-new-window',
[594]71                text:           'Each job in a seperate tab, in new window',
72                checked:        true,
73                group:          'graphwindow',
74                handler:        checkGraphWindowOption
75        },{
[595]76                id:             'tabbed-prev-window',
[594]77                text:           'Each job in a seperate tab, in last opened window',
78                checked:        false,
79                group:          'graphwindow',
80                handler:        checkGraphWindowOption
81        }]
82});
83
84var showGraphsButton = new Ext.MenuButton(
85{
86        id:             'showgraphbutton',
87        text:           'Show graphs',
88        disabled:       true,
89        menu:           graphMenu,
90        listeners:
91        {
92                'click':
93                {
94                        scope:  this,
95                        fn:     ShowGraphs
96                }
97        }
98});
99
[558]100Ext.namespace('Ext.ux');
101
[593]102Ext.ux.PageSizePlugin = function()
103{
104        Ext.ux.PageSizePlugin.superclass.constructor.call(this,
105        {
106                store:  new Ext.data.SimpleStore(
107                {
108                        fields: ['text', 'value'],
109                        data:   [['10', 10], ['15', 15], ['20', 20], ['30', 30], ['50', 50], ['100', 100], ['max', 'max' ]]
110                }),
111                mode:           'local',
112                displayField:   'text',
113                valueField:     'value',
114                editable:       false,
115                allowBlank:     false,
116                triggerAction:  'all',
117                width:          40
118        });
[558]119};
120
[593]121Ext.extend(Ext.ux.PageSizePlugin, Ext.form.ComboBox,
122{
123        init:                   function(paging)
124                                {
125                                        paging.on('render', this.onInitView, this);
126                                },
[558]127   
[593]128        onInitView:             function(paging)
129                                {
130                                        paging.add('-',
131                                        this,
132                                        'jobs per page'
133                                        );
134                                        this.setValue(paging.pageSize);
135                                        this.on('select', this.onPageSizeChanged, paging);
136                                },
137
138        onPageSizeChanged:      function(combo)
139                                {
140                                        if ( combo.getValue() == 'max' )
141                                        {
142                                                mylimit = JobsDataStore.getTotalCount();
143                                        }
144                                        else
145                                        {
146                                                mylimit = parseInt(combo.getValue());
147                                        }
148                                        this.pageSize = mylimit;
149                                        this.doLoad(0);
150                                }
[558]151});
152
153Ext.namespace( 'Ext' );
154
[583]155function clearFilters()
156{
[588]157        if( inMyArrayKeys( myfilters, 'query' ) )
158        {
159                SearchField.getEl().dom.value = '';
160                delete SearchField.store.baseParams['query'];
161                delete myfilters['query'];
162                delete myparams['query'];
163        }
[583]164        if( inMyArrayKeys( myfilters, 'host' ) )
165        {
166                delete myfilters['host'];
167                delete myparams['host'];
168        }
169        if( inMyArrayKeys( myfilters, 'jid' ) )
170        {
171                delete myfilters['jid'];
172                delete myparams['jid'];
173        }
174        if( inMyArrayKeys( myfilters, 'queue' ) )
175        {
176                delete myfilters['queue'];
177                delete myparams['queue'];
178        }
179        if( inMyArrayKeys( myfilters, 'owner' ) )
180        {
181                delete myfilters['owner'];
182                delete myparams['owner'];
183        }
184        if( inMyArrayKeys( myfilters, 'status' ) )
185        {
186                delete myfilters['status'];
187                delete myparams['status'];
188        }
189        reloadJobStore();
190}
191
[549]192function makeArrayURL( somearr )
[547]193{
[593]194        filter_url = '';
195        filter_sep = '';
[549]196
[593]197        for( filtername in somearr )
198        {
199                filter_url = filter_url + filter_sep + filtername + '=' + somearr[filtername];
200                filter_sep = '&';
201        }
[549]202
[593]203        return filter_url;
[547]204}
205
[549]206
[546]207function isset( somevar )
208{
[593]209        try
210        {
211                if( eval( somevar ) ) { }
212        }
213        catch( err )
214        {
215                return false;
216        }
217        return true;
[546]218}
219
220function inMyArray( arr, someval )
221{
[593]222        for( arval in arr )
223        {
224                if( arval == someval )
225                {
226                        return true;
227                }
228        }
229        return false;
[546]230}
231
[583]232function ArraySize( arr )
233{
[593]234        count = 0;
[583]235
[593]236        for( arkey in arr )
237        {
238                count = count + 1;
239        }
[583]240
[593]241        return count;
[583]242}
243
[546]244function inMyArrayValues( arr, someval )
245{
[593]246        for( arkey in arr )
247        {
248                if( arr[arkey] == someval )
249                {
250                        return true;
251                }
252        }
253        return false;
[546]254}
255
256function inMyArrayKeys( arr, someval )
257{
[593]258        for( arkey in arr )
259        {
260                if( arkey == someval )
261                {
262                        return true;
263                }
264        }
265        return false;
[546]266}
267
268function joinMyArray( arr1, arr2 )
269{
[593]270        for( arkey in arr2 )
271        {
272                arr1[arkey] = arr2[arkey];
273        }
[546]274
[593]275        return arr1;
[546]276}
277
[549]278function ClusterImageSelectHost( somehost )
279{
[593]280        if( !inMyArrayKeys( myfilters, 'host' ) )
281        {
282                myfilters['host'] = somehost;
283        }
284        else
285        {
286                if( myfilters['host'] == somehost )
287                {
288                        delete myfilters['host'];
289                        delete myparams['host'];
290                }
291                else
292                {
293                        myfilters['host'] = somehost;
294                }
295        }
[549]296
[593]297        reloadClusterImage();
298        reloadJobStore();
[549]299
[593]300        // returning false causes a image reload
301        //
302        return false;
[550]303}
304
305function reloadJobStore()
306{
[593]307        // Respect any other parameters that may have been set outside filters
308        //
309        myparams = joinMyArray( myparams, myfilters );
[550]310
[593]311        // Can't be sure if there are enough pages for new filter: reset to page 1
312        //
313        myparams = joinMyArray( myparams, { start: 0, limit: mylimit } );
[550]314
[593]315        JobsDataStore.reload( { params: myparams } );
[550]316}
317
[551]318function addListener(element, type, expression, bubbling)
319{
[593]320        bubbling = bubbling || false;
321
322        if(window.addEventListener)
323        { // Standard
324                element.addEventListener(type, expression, bubbling);
325                return true;
326        } 
327        else if(window.attachEvent) 
328        { // IE
329                element.attachEvent('on' + type, expression);
330                return true;
331        }
332        else 
333        {
334                return false;
335        }
[551]336}
337
[567]338function makeFilterString()
339{
[593]340        var filter_str = '';
[567]341
[593]342        for( arkey in myfilters )
343        {
344                filter_str = filter_str + ' > ' + myfilters[arkey];
345        }
[567]346
[593]347        return filter_str;
[567]348}
349
[551]350var ImageLoader = function( id, url )
351{
[593]352        this.url = url;
353        this.image = document.getElementById( id );
354        this.loadEvent = null;
[551]355};
356
[553]357ImageLoader.prototype = 
358{
[593]359        load:           function()
360                        {
361                                var url = this.url;
362                                var image = this.image;
363                                var loadEvent = this.loadEvent;
364                                addListener( this.image, 'load',
365                                        function(e)
366                                        {
367                                                if( loadEvent != null )
368                                                {
369                                                        loadEvent( url, image );
370                                                }
371                                        }, false);
372                                this.image.src = this.url;
373                        },
374        getImage:       function()
375                        {
376                                return this.image;
377                        }
[551]378};
379
[556]380function achorJobListing()
381{
[593]382        JobListingWindow.anchorTo( "ClusterImageWindow", "tr-br", [ 0, 10 ] );
[556]383}
384
385function setClusterImagePosition()
386{
[593]387        ci_x = (window.innerWidth - ClusterImageWindow.getSize()['width'] - 20); 
388        ClusterImageWindow.setPosition( ci_x, 10 );
[556]389}
390
[583]391function deselectFilterMenu( menuItem, event )
392{
[593]393        filterValue = menuItem.text;
[583]394
[593]395        if( filterValue == SearchField.getEl().dom.value && inMyArrayKeys( myfilters, 'query' ) )
396        {
397                SearchField.getEl().dom.value = '';
398                delete SearchField.store.baseParams['query'];
399        }
[588]400
[593]401        for( arkey in myfilters )
402        {
403                if( myfilters[arkey] == filterValue )
404                {
405                        delete myfilters[arkey];
406                        delete myparams[arkey];
407                }
408        }
409        reloadJobStore();
[583]410}
411
412function makeFilterMenu()
413{
[593]414        var filterMenu = new Ext.menu.Menu(
415        {
416                id:     'filterMenu',
417                items:  [ new Ext.menu.Item({ text: 'Clear all', handler: clearFilters }) ]
418        });
[583]419
[593]420        if( ArraySize( myfilters ) > 0 )
421        {
422                filterMenu.addSeparator();
423        }
[583]424
[593]425        for( arkey in myfilters )
426        {
427                filterMenu.add( new Ext.menu.CheckItem({ text: myfilters[arkey], handler: deselectFilterMenu, checked: true }) );
428        }
[583]429
[593]430        if( filterButton )
431        {
432                filterButton.menu = filterMenu;
[584]433
[593]434                if( ArraySize( myfilters ) > 0 )
435                {
436                        filterButton.enable();
437                }
438                else
439                {
440                        filterButton.disable();
441                }
442        }
[583]443}
444
[550]445function reloadClusterImage()
446{
[593]447        ClusterImageArgs['view'] = 'big-clusterimage';
[549]448
[593]449        filt_url = makeArrayURL( myfilters );
450        imag_url = makeArrayURL( ClusterImageArgs );
451        img_url = './image.php?' + filt_url + '&' + imag_url;
[549]452
[593]453        var newClusterImage = new ImageLoader( 'clusterimage', img_url );
454        newClusterImage.loadEvent = function( url, image ) 
455        {
456                ClusterImageWindow.getBottomToolbar().clearStatus( { useDefaults:true } );
457                setTimeout( "resizeClusterImage()", 250 );
458                setTimeout( "setClusterImagePosition()", 500 );
459                //setTimeout( "achorJobListing()", 1000 );
460        }
[551]461
[593]462        ClusterImageWindow.getBottomToolbar().showBusy();
[567]463
[593]464        filter_str = 'Nodes' + makeFilterString();
465        ClusterImageWindow.setTitle( filter_str );
[567]466
[593]467        newClusterImage.load();
[549]468}
469
[555]470function resizeClusterImage()
471{
[593]472        var ci_height = document.getElementById( "clusterimage" ).height + ClusterImageWindow.getFrameHeight();
473        var ci_width = document.getElementById( "clusterimage" ).width + ClusterImageWindow.getFrameWidth();
[555]474
[593]475        ClusterImageWindow.setSize( ci_width, ci_height );
[555]476}
477
[593]478Ext.apply(Ext.form.VTypes,
479{
480        num:            function(val, field)
481                        {
482                                if (val) 
483                                {
484                                        var strValidChars = "0123456789";
485                                        var blnResult = true;
[558]486
[593]487                                        if (val.length == 0) return false;
[558]488
[593]489                                        //  test strString consists of valid characters listed above
490                                        for (i = 0; i < val.length && blnResult == true; i++)
491                                        {
492                                                strChar = val.charAt(i);
493                                                if (strValidChars.indexOf(strChar) == -1)
494                                                {
495                                                        blnResult = false;
496                                                }
497                                        }
498                                        return blnResult;
[558]499
[593]500                                }
501                        },
502        numText:        'Must be numeric'
[558]503});
504
[593]505function jobRowSelect( selModel ) 
506{
507        if( selModel.hasSelection() )
508        {
509                showGraphsButton.enable();
510        }
511        else
512        {
513                showGraphsButton.disable();
514        }
515}
[536]516
[593]517function jobCellClick(grid, rowIndex, columnIndex, e)
518{
519        var record              = grid.getStore().getAt(rowIndex);  // Get the Record
520        var fieldName           = grid.getColumnModel().getDataIndex(columnIndex);
521        var data                = record.get(fieldName);
522        var view                = grid.getView();
523        var cell                = view.getCell( rowIndex, columnIndex );
524        var filter_title        = false;
525        var fil_dis             = 'filter';
526        var fil_ena             = 'filterenabled';
527        var filterName          = fieldName;
[532]528
[593]529        if( fieldName == 'owner' || fieldName == 'jid' || fieldName == 'status' || fieldName == 'queue' || fieldName == 'nodes')
530        {
531                if( fieldName == 'nodes' )
532                {
533                        filterName = 'host';
534                        fil_dis = 'nodesfilter';
535                        fil_ena = 'nodesfilterenabled';
536                }
537                if( inMyArrayKeys( myfilters, filterName ) )
538                {
539                        Ext.fly(cell).removeClass( fil_ena );
540                        Ext.fly(cell).addClass( fil_dis );
[589]541
[593]542                        // Remove this filter
543                        //
544                        delete myfilters[filterName];
545                        delete myparams[filterName];
[541]546
[593]547                        reloadJobStore();
548                        //reloadClusterImage();
549                }
550                else
551                {
552                        Ext.fly(cell).removeClass( fil_dis );
553                        Ext.fly(cell).addClass( fil_ena );
[543]554
[593]555                        if( fieldName == 'nodes' )
556                        { // Get the first node (master mom) as node filter
557                                new_data = data.split( ',' )[0];
558                                data = new_data;
559                        }
[543]560
[593]561                        // Set filter for selected column to selected cell value
562                        //
563                        myfilters[filterName] = data;
[543]564
[593]565                        reloadJobStore();
566                        //reloadClusterImage();
567                }
568                JobListingWindow.setTitle( filter_str );
569                filter_title = true;
570                filter_str = myparams.c + ' Jobs Overview' + makeFilterString();
[568]571        }
[593]572}
[568]573
[593]574function jobCellRender( value, metadata, record, rowindex, colindex, store )
575{
576        var fieldName = JobsColumnModel.getColumnById( colindex ).dataIndex;
577        var fil_dis = 'filter';
578        var fil_ena = 'filterenabled';
579        var filterName = fieldName;
[543]580
[593]581        if( fieldName == 'owner' || fieldName == 'jid' || fieldName == 'status' || fieldName == 'queue' || fieldName == 'nodes' )
582        {
583                if( fieldName == 'nodes' )
584                {
585                        fil_dis = 'nodesfilter';
586                        fil_ena = 'nodesfilterenabled';
587                        filterName = 'host';
588                }
589                if( myfilters[filterName] != null )
590                {
591                        metadata.css = fil_ena;
592                }
593                else
594                {
595                        metadata.css = fil_dis;
596                }
597        }
598        return value;
599}
[541]600
[593]601JobProxy = new Ext.data.HttpProxy(
602{
603        url:    'jobstore.php',
604        method: 'POST'
605});
[541]606
[593]607JobsDataStore = new Ext.data.Store(
608{
609        id:             'JobsDataStore',
610        proxy:          JobProxy,
611        baseParams:     { task: "GETJOBS" },
612        reader:
613                new Ext.data.JsonReader(
[567]614                {
[593]615                        root: 'results',
616                        totalProperty: 'total',
617                        id: 'id'
618                },
619                [
620                        {name: 'jid', type: 'int', mapping: 'jid'},
621                        {name: 'status', type: 'string', mapping: 'status'},
622                        {name: 'owner', type: 'string', mapping: 'owner'},
623                        {name: 'queue', type: 'string', mapping: 'queue'},
624                        {name: 'name', type: 'string', mapping: 'name'},
625                        {name: 'requested_time', type: 'string', mapping: 'requested_time'},
626                        {name: 'requested_memory', type: 'string', mapping: 'requested_memory'},
627                        {name: 'ppn', type: 'int', mapping: 'ppn'},
628                        {name: 'nodect', type: 'int', mapping: 'nodect'},
629                        {name: 'nodes', type: 'string', mapping: 'nodes'},
630                        {name: 'queued_timestamp', type: 'string', mapping: 'queued_timestamp'},
631                        {name: 'start_timestamp', type: 'string', mapping: 'start_timestamp'},
632                        {name: 'runningtime', type: 'string', mapping: 'runningtime'}
633                ]),
634        sortInfo: 
635        { 
636                field: 'jid', 
637                direction: "DESC" 
638        },
639        remoteSort: true,
640        listeners:
641        { 
642                'beforeload':
643                {
[567]644                        scope: this,
[593]645                        fn:
646
647                        function()
[567]648                        {
649                                if( SearchField )
650                                {
651                                        search_value = SearchField.getEl().dom.value;
652                                        if( search_value == '' )
653                                        {
654                                                delete SearchField.store.baseParams['query'];
655                                                delete myfilters['query'];
656                                                delete myparams['query'];
657                                        }
[583]658                                        else
[567]659                                        {
660                                                myfilters['query']      = search_value;
661                                        }
[563]662
[583]663                                        makeFilterMenu();
[567]664                                        reloadClusterImage();
[563]665
[567]666                                        filter_str = myparams.c + ' Jobs Overview' + makeFilterString();
667                                        JobListingWindow.setTitle( filter_str );
[563]668                                }
669                        }
[593]670                }
671        }
672});
673   
674var CheckJobs =
[583]675
[593]676        new Ext.grid.CheckboxSelectionModel(
677        {
678                listeners:
679                {
680                        'selectionchange':
681                        {
682                                scope:  this,
683                                fn:     jobRowSelect
684                        }
685                },
686        });
[583]687
[593]688JobsColumnModel = new Ext.grid.ColumnModel(
689[
690        CheckJobs,
691        {
692                header:         '#',
693                tooltip:        'Job id',
694                readOnly:       true,
695                dataIndex:      'jid',
696                width:          50,
697                hidden:         false,
698                renderer:       jobCellRender
699        },{
700                header:         'S',
701                tooltip:        'Job status',
702                readOnly:       true,
703                dataIndex:      'status',
704                width:          20,
705                hidden:         false,
706                renderer:       jobCellRender
707        },{
708                header:         'User',
709                tooltip:        'Owner of job',
710                readOnly:       true,
711                dataIndex:      'owner',
712                width:          60,
713                hidden:         false,
714                renderer:       jobCellRender
715        },{
716                header:         'Queue',
717                tooltip:        'In which queue does this job reside',
718                readOnly:       true,
719                dataIndex:      'queue',
720                width:          60,
721                hidden:         false,
722                renderer:       jobCellRender
723        },{
724                header:         'Name',
725                tooltip:        'Name of job',
726                readOnly:       true,
727                dataIndex:      'name',
728                width:          100,
729                hidden:         false
730        },{
731                header:         'Requested Time',
732                tooltip:        'Amount of requested time (wallclock)',
733                readOnly:       true,
734                dataIndex:      'requested_time',
735                width:          100,
736                hidden:         false
737        },{
738                header:         'Requested Memory',
739                tooltip:        'Amount of requested memory',
740                readOnly:       true,
741                dataIndex:      'requested_memory',
742                width:          100,
743                hidden:         true
744        },{
745                header:         'P',
746                tooltip:        'Number of processors per node (PPN)',
747                readOnly:       true,
748                dataIndex:      'ppn',
749                width:          25,
750                hidden:         false
751        },{
752                header:         'N',
753                tooltip:        'Number of nodes (hosts)',
754                readOnly:       true,
755                dataIndex:      'nodect',
756                width:          25,
757                hidden:         false
758        },{
759                header:         'Nodes',
760                readOnly:       true,
761                dataIndex:      'nodes',
762                width:          100,
763                hidden:         false,
764                renderer:       jobCellRender
765        },{
766                header:         'Queued',
767                tooltip:        'At what time did this job enter the queue',
768                readOnly:       true,
769                dataIndex:      'queued_timestamp',
770                width:          120,
771                hidden:         false
772        },{
773                header:         'Started',
774                tooltip:        'At what time did this job enter the running status',
775                readOnly:       true,
776                dataIndex:      'start_timestamp',
777                width:          120,
778                hidden:         false
779        },{
780                header:         'Runningtime',
781                tooltip:        'How long has this job been in the running status',
782                readOnly:       true,
783                dataIndex:      'runningtime',
784                width:          140,
785                hidden:         false
786        }]
787);
[583]788
[593]789JobsColumnModel.defaultSortable = true;
[583]790
[593]791var win;
[560]792
[593]793MetricsDataStore = new Ext.data.Store(
794{
795        id:             'MetricsDataStore',
796        proxy:          JobProxy,
797        autoLoad:       false,
798        baseParams:     { task: "GETMETRICS" },
799        reader:
800                new Ext.data.JsonReader(
801                {
802                        root: 'names',
803                        totalProperty: 'total',
804                        id: 'id'
805                },
806                [{
807                        name: 'ID'
808                },{
809                        name: 'name'
810                }]
811                )
812});
[532]813
[593]814SearchField     = new Ext.app.SearchField(
815                {
816                        store:  JobsDataStore,
817                        params: {start: 0, limit: mylimit},
818                        width:  200
819                });
[560]820
[595]821function createNodesDataStore( cluster, jid )
[593]822{
[595]823        nodesDataStore =
824
825                new Ext.data.Store(
[593]826                {
[595]827                        //id:           'NodesDataStore',
828                        proxy:          JobProxy,
829                        autoLoad:       false,
830                        baseParams:
[593]831                        {
[595]832                                'task':         "GETNODES",
833                                'c':            cluster,
834                                'jid':          jid
835                        },
836                        reader: new Ext.data.JsonReader(
837                        {
838                                root:           'results',
839                                totalProperty:  'total',
840                                id:             'id'
841                        },[
842                                {name: 'c', type: 'string', mapping: 'c'},
843                                {name: 'h', type: 'string', mapping: 'h'},
844                                {name: 'x', type: 'string', mapping: 'x'},
845                                {name: 'v', type: 'string', mapping: 'v'},
846                                {name: 'l', type: 'string', mapping: 'l'},
847                                {name: 'jr', type: 'string', mapping: 'jr'},
848                                {name: 'js', type: 'string', mapping: 'js'}
849                        ])
850                });
[569]851
[595]852        return nodesDataStore;
853}
[563]854
[595]855function createGraphView( store, jid )
[593]856{
[595]857        var graphView =
[593]858       
859                new Ext.DataView(
860                {
[595]861                        id:             jid,   
[593]862                        itemSelector:   'thumb',
[595]863                        title:          jid,
[593]864                        style:          'overflow:auto',
865                        multiSelect:    true,
[595]866                        //autoHeight:   true,
867                        autoShow:       true,
868                        store:          store,
869                        layout:         'fit',
[593]870                        tpl:
871                       
872                                new Ext.XTemplate(
873                                        '<tpl for=".">',
874                                        '<div class="rrd-float"><img src="../../graph.php?z=small&c={c}&h={h}&l={l}&v={v}&x={x}&r=job&jr={jr}&js={js}" border="0"></div>',
875                                        '</tpl>'
876                                )
877                });
[566]878
[595]879        return graphView;
880}
[566]881
[595]882function createGraphPanel( view )
883{
884        var graphPanel = 
885
886                new Ext.TabPanel(
[593]887                {
888                        id:             'images',
889                        region:         'center',
890                        bodyStyle:      'background: transparent',
[595]891                        autoShow:       true,
892                        autoHeight:     true,
[593]893                        //margins:      '2 2 2 0',
[595]894                        //layout:       'fit',
895                        resizeTabs:     true,
896                        minTabWidth:    115,
897                        tabWidth:       135,
898                        enableTabScroll:true,
899                        defaults:       {autoScroll:true}
[593]900                });
901
[595]902        return graphPanel;
903}
904
905function createGraphWindow( panel, Button )
906{
907        graphWindow =
908
909                new Ext.Window(
[593]910                {
911                        animateTarget:  Button,
912                        width:          500,
913                        height:         300,
914                        closeAction:    'hide',
915                        collapsible:    true,
916                        animCollapse:   true,
917                        maximizable:    true,
918                        title:          'Node graph details',
[595]919                        //layout:               'fit',
[593]920                        tbar:   
[595]921               
922                        // RB TODO: range combobox; hour, day, week, etc
923       
[593]924                        new Ext.form.ComboBox(
925                        {
926                                fieldLabel:     'Metric',
927                                store:          MetricsDataStore,
928                                valueField:     'name',
929                                displayField:   'name',
930                                typeAhead:      true,
931                                mode:           'remote',
932                                triggerAction:  'all',
[595]933                                emptyText:      'load_one',
[593]934                                selectOnFocus:  true,
935                                xtype:          'combo',
936                                width:          190,
937                                listeners:
938                                {
939                                        select: 
940                                                       
941                                        function(combo, record, index)
942                                        {
943                                                var metric = record.data.name;
944                                                // doe iets
[595]945
946                                                // RB: misschien zo metric opgeven aan datastore?
947                                                //items[0].items[0].getStore().baseParams.metric = metric;
[571]948                                        }
[593]949                                }
950
951                        }),
952
[595]953                        items:  [ panel ]
[593]954                });
[595]955
956        return graphWindow;
957}
958
959function ShowGraphs( Button, Event ) 
960{
961        var row_records         = CheckJobs.getSelections();
962        var graphJids           = Array();
963        var windowCount         = 0;
964        var tabCount            = 0;
965
966        for( var i=0; i<row_records.length; i++ )
967        {
968                rsel            = row_records[i];
969                jid             = rsel.get('jid');
970
971                if( graphJids[windowCount] == undefined )
972                {
973                        graphJids[windowCount]  = Array();
974                }
975
976                graphJids[windowCount][tabCount]        = jid;
977
978                if( (i+1) < row_records.length )
979                {
980                        if( graphWindowBehaviour == 'new-window' )
981                        {
982                                windowCount++;
983                        }
984                        else
985                        {
986                                tabCount++;
987                        }
988                }
[569]989        }
[595]990
991        for( var w=0; w<=windowCount; w++ )
992        {
993                if( graphWindowBehaviour == 'tabbed-prev-window' )
994                {
995                        myWindow        = previousGraphWindow;
996                        myPanel         = previousGraphPanel;
997                }
998                else
999                {
1000                        myPanel         = createGraphPanel();
1001                        myWindow        = createGraphWindow( myPanel, Button );
1002
1003                        myWindow.add( myPanel );
1004                }
1005
1006                for( var t=0; t<=tabCount; t++ )
1007                {
1008                        nodeDatastore   = createNodesDataStore( myparams.c, graphJids[w][t] );
1009                        graphView       = createGraphView( nodeDatastore, graphJids[w][t] );
1010                        lastView        = myPanel.add( graphView );
1011
1012                        nodeDatastore.load();
1013                        myPanel.setActiveTab( lastView );
1014                }
1015
1016                myWindow.show( Button );
1017
1018                myPanel.doLayout();
1019                myWindow.doLayout();
1020
1021                previousGraphWindow     = myWindow;
1022                previousGraphPanel      = myPanel;
1023        }
[566]1024}
1025
[593]1026var JobListingEditorGrid =
[547]1027
[593]1028        new Ext.grid.EditorGridPanel(
1029        {
1030                id:             'JobListingEditorGrid',
1031                store:          JobsDataStore,
1032                cm:             JobsColumnModel,
1033                enableColLock:  false,
1034                clicksToEdit:   1,
1035                loadMask:       true,
1036                selModel:       new Ext.grid.RowSelectionModel({singleSelect:false}),
1037                stripeRows:     true,
1038                sm:             CheckJobs,
1039                listeners:
1040                {
1041                        'cellclick':
1042                        {
1043                                scope:  this,
1044                                fn:     jobCellClick
1045                        }
1046                },
1047                bbar:
1048       
1049                new Ext.PagingToolbar(
1050                {
1051                        pageSize: 15,
1052                        store: JobsDataStore,
1053                        displayInfo: true,
1054                        displayMsg: 'Displaying jobs {0} - {1} out of {2} jobs total found.',
1055                        emptyMsg: 'No jobs found to display',
1056                        plugins: [new Ext.ux.PageSizePlugin()]
1057                }),
[554]1058
[593]1059                tbar: 
1060                [ 
1061                        SearchField,
1062                        showGraphsButton,
1063                        filterButton 
1064                ]
1065        });
[541]1066
[593]1067var ClusterImageWindow =
1068
1069        new Ext.Window(
1070        {
1071                id:             'ClusterImageWindow',
1072                title:          'Nodes',
1073                closable:       true,
1074                collapsible:    true,
1075                animCollapse:   true,
1076                width:          1,
1077                height:         1,
1078                y:              15,
1079                plain:          true,
1080                shadow:         true,
1081                resizable:      false,
1082                shadowOffset:   10,
1083                layout:         'fit',
1084                bbar: 
1085               
1086                        new Ext.StatusBar(
1087                        {
1088                                defaultText: 'Ready.',
1089                                id: 'basic-statusbar',
1090                                defaultIconCls: ''
1091                        })
1092        });
1093
1094var GraphSummaryWindow =
1095
1096        new Ext.Window(
1097        {
1098                id:             'GraphSummaryWindow',
1099                title:          'Graph Summary',
1100                closable:       true,
1101                collapsible:    true,
1102                animCollapse:   true,
1103                width:          500,
1104                height:         400,
1105                x:              10,
1106                y:              10,
1107                plain:          true,
1108                shadow:         true,
1109                resizable:      true,
1110                shadowOffset:   10,
1111                layout:         'table',
1112                layoutConfig: 
1113                {
1114                        columns: 2
1115                },
1116                defaults:       { border: false },
1117                items: 
1118                [
1119                        {
1120                                id:             'monarchlogo',
1121                                cls:            'monarch',
1122                                bodyStyle:      'background: transparent',
1123                                html:           '<A HREF="https://subtrac.sara.nl/oss/jobmonarch/" TARGET="_blank"><IMG SRC="./jobmonarch.gif" ALT="Job Monarch" BORDER="0"></A>'
1124                                //colspan: 2
1125                        },{
1126                                id:             'summarycount'
1127                        },{
1128                                id:             'rjqjgraph'
1129                        },{
1130                                id:             'pie',
1131                                colspan:        2
1132                        }
1133                ],
1134                bbar:
1135               
1136                        new Ext.StatusBar(
1137                        {
1138                                defaultText:    'Ready.',
1139                                id:             'basic-statusbar',
1140                                defaultIconCls: ''
1141                        })
1142        });
1143
1144var JobListingWindow =
1145
1146        new Ext.Window(
1147        {
1148                id:             'JobListingWindow',
1149                title:          'Cluster Jobs Overview',
1150                closable:       true,
1151                collapsible:    true,
1152                animCollapse:   true,
1153                maximizable:    true,
1154                y:              375,
1155                width:          860,
1156                height:         445,
1157                plain:          true,
1158                shadow:         true,
1159                shadowOffset:   10,
1160                layout:         'fit',
1161                items:          JobListingEditorGrid
1162        });
Note: See TracBrowser for help on using the repository browser.