source: trunk/web2/addons/job_monarch/js/jobgrid.js @ 584

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

job_monarch/js/jobgrid.js:

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