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

Last change on this file since 555 was 555, checked in by ramonb, 16 years ago

job_monarch/js/jobgrid.js:

job_monarch/templates/header.tpl:

  • removed some positioning stuff

job_monarch/index.php,
job_monarch/image.php:

  • more memory limits
File size: 11.6 KB
Line 
1var JobsDataStore;
2var JobsColumnModel;
3var JobListingEditorGrid;
4var JobListingWindow;
5var JobProxy;
6var myfilters = { };
7var myparams = { };
8var ClusterImageArgs = { };
9
10var filterfields = [ "jid", "queue", "name", "owner" ];
11
12function makeArrayURL( somearr )
13{
14  filter_url = '';
15  filter_sep = '';
16
17  for( filtername in somearr )
18  {
19    filter_url = filter_url + filter_sep + filtername + '=' + somearr[filtername];
20    filter_sep = '&';
21  }
22
23  return filter_url;
24}
25
26
27function isset( somevar )
28{
29  try
30  {
31    if( eval( somevar ) ) { }
32  }
33  catch( err )
34  {
35    return false;
36  }
37  return true;
38}
39
40function inMyArray( arr, someval )
41{
42  for( arval in arr )
43  {
44    if( arval == someval )
45    {
46      return true;
47    }
48  }
49  return false;
50}
51
52function inMyArrayValues( arr, someval )
53{
54  for( arkey in arr )
55  {
56    if( arr[arkey] == someval )
57    {
58      return true;
59    }
60  }
61  return false;
62}
63
64function inMyArrayKeys( arr, someval )
65{
66  for( arkey in arr )
67  {
68    if( arkey == someval )
69    {
70      return true;
71    }
72  }
73  return false;
74}
75
76function joinMyArray( arr1, arr2 )
77{
78  for( arkey in arr2 )
79  {
80    arr1[arkey] = arr2[arkey];
81  }
82
83  return arr1;
84}
85
86function ClusterImageSelectHost( somehost )
87{
88
89  if( !inMyArrayKeys( myfilters, 'host' ) )
90  {
91    myfilters['host'] = somehost;
92  }
93  else
94  {
95    delete myfilters['host'];
96    delete myparams['host'];
97  }
98
99  reloadClusterImage();
100  reloadJobStore();
101
102  return false;
103}
104
105function reloadJobStore()
106{
107  // Respect any other parameters that may have been set outside filters
108  //
109  myparams = joinMyArray( myparams, myfilters );
110
111  // Can't be sure if there are enough pages for new filter: reset to page 1
112  //
113  myparams = joinMyArray( myparams, { start: 0, limit: 30 } );
114
115  JobsDataStore.reload( { params: myparams } );
116}
117
118function addListener(element, type, expression, bubbling)
119{
120  bubbling = bubbling || false;
121  if(window.addEventListener)
122  { // Standard
123    element.addEventListener(type, expression, bubbling);
124    return true;
125  } 
126  else if(window.attachEvent) 
127  { // IE
128    element.attachEvent('on' + type, expression);
129    return true;
130  } 
131  else 
132    return false;
133}
134
135var ImageLoader = function( id, url )
136{
137  this.url = url;
138  this.image = document.getElementById( id );
139  this.loadEvent = null;
140};
141
142ImageLoader.prototype = 
143{
144  load:function()
145  {
146    var url = this.url;
147    var image = this.image;
148    var loadEvent = this.loadEvent;
149    addListener( this.image, 'load', function(e)
150    {
151      if( loadEvent != null )
152      {
153        loadEvent( url, image );
154      }
155    }, false);
156    this.image.src = this.url;
157  },
158  getImage: function()
159  {
160    return this.image;
161  }
162};
163
164function reloadClusterImage()
165{
166  ClusterImageArgs['view'] = 'big-clusterimage';
167
168  filt_url = makeArrayURL( myfilters );
169  imag_url = makeArrayURL( ClusterImageArgs );
170  img_url = './image.php?' + filt_url + '&' + imag_url;
171
172  var newClusterImage = new ImageLoader( 'clusterimage', img_url );
173  newClusterImage.loadEvent = function( url, image ) 
174    {
175      resizeClusterImage();
176      ClusterImageWindow.getBottomToolbar().clearStatus( { useDefaults:true } );
177    }
178
179  ClusterImageWindow.getBottomToolbar().showBusy();
180  newClusterImage.load();
181}
182
183function getCiWindowWidth()
184{
185  return (document.getElementById( "clusterimage" ).width + ClusterImageWindow.getFrameWidth());
186}
187function getCiWindowHeight()
188{
189  return (document.getElementById( "clusterimage" ).height + ClusterImageWindow.getFrameHeight());
190}
191
192function resizeClusterImage()
193{
194  var ci_height = getCiWindowHeight();
195  var ci_width = getCiWindowWidth();
196
197  ClusterImageWindow.setSize( ci_width, ci_height );
198}
199
200function initJobGrid() {
201
202  Ext.QuickTips.init();
203
204  function clusterImageResize( window, width, heigth )
205  {
206    var ci_height = getCiWindowHeight();
207    var ci_width = getCiWindowWidth();
208
209    if( ci_height != heigth || ci_width != width )
210    {
211      resizeClusterImage();
212    }
213  }
214
215  function jobCellClick(grid, rowIndex, columnIndex, e)
216  {
217    var record = grid.getStore().getAt(rowIndex);  // Get the Record
218    var fieldName = grid.getColumnModel().getDataIndex(columnIndex);
219    var data = record.get(fieldName);
220    var view = grid.getView();
221    var cell = view.getCell( rowIndex, columnIndex );
222
223    if( fieldName == 'owner' || fieldName == 'jid' || fieldName == 'status' || fieldName == 'queue' )
224    {
225      if( inMyArrayKeys( myfilters, fieldName ) )
226      {
227        Ext.fly(cell).removeClass( 'filterenabled' );
228        Ext.fly(cell).addClass( 'filter' );
229
230        // Remove this filter
231        //
232        delete myfilters[fieldName];
233        delete myparams[fieldName];
234
235        reloadJobStore();
236        reloadClusterImage();
237      }
238      else
239      {
240        Ext.fly(cell).removeClass( 'filter' );
241        Ext.fly(cell).addClass( 'filterenabled' );
242
243        // Set filter for selected column to selected cell value
244        //
245        myfilters[fieldName] = data;
246
247        reloadJobStore();
248        reloadClusterImage();
249      }
250    }
251  }
252
253  function jobCellRender( value, metadata, record, rowindex, colindex, store )
254  {
255    var fieldName = JobsColumnModel.getColumnById( colindex ).dataIndex;
256
257    if( fieldName == 'owner' || fieldName == 'jid' || fieldName == 'status' || fieldName == 'queue' )
258    {
259      if( myfilters[fieldName] != null )
260      {
261        metadata.css = 'filterenabled';
262      }
263      else
264      {
265        metadata.css = 'filter';
266      }
267    }
268    return value;
269  }
270
271  JobProxy = new Ext.data.HttpProxy({
272                url: 'jobstore.php',
273                method: 'POST'
274            });
275
276  JobsDataStore = new Ext.data.Store({
277      id: 'JobsDataStore',
278      proxy: JobProxy,
279      baseParams: { task: "LISTING" },
280      reader: new Ext.data.JsonReader({
281        root: 'results',
282        totalProperty: 'total',
283        id: 'id'
284      },[
285        {name: 'jid', type: 'int', mapping: 'jid'},
286        {name: 'status', type: 'string', mapping: 'status'},
287        {name: 'owner', type: 'string', mapping: 'owner'},
288        {name: 'queue', type: 'string', mapping: 'queue'},
289        {name: 'name', type: 'string', mapping: 'name'},
290        {name: 'requested_time', type: 'string', mapping: 'requested_time'},
291        {name: 'requested_memory', type: 'string', mapping: 'requested_memory'},
292        {name: 'ppn', type: 'int', mapping: 'ppn'},
293        {name: 'nodect', type: 'int', mapping: 'nodect'},
294        {name: 'nodes', type: 'string', mapping: 'nodes'},
295        {name: 'queued_timestamp', type: 'string', mapping: 'queued_timestamp'},
296        {name: 'start_timestamp', type: 'string', mapping: 'start_timestamp'},
297        {name: 'runningtime', type: 'string', mapping: 'runningtime'}
298      ]),
299      sortInfo: { field: 'jid', direction: "DESC" },
300      remoteSort: true
301    });
302   
303  JobsColumnModel = new Ext.grid.ColumnModel(
304    [{
305        header: '#',
306        tooltip: 'Job id',
307        readOnly: true,
308        dataIndex: 'jid',
309        width: 50,
310        hidden: false,
311        renderer: jobCellRender
312      },{
313        header: 'S',
314        tooltip: 'Job status',
315        readOnly: true,
316        dataIndex: 'status',
317        width: 20,
318        hidden: false,
319        renderer: jobCellRender
320      },{
321        header: 'User',
322        tooltip: 'Owner of job',
323        readOnly: true,
324        dataIndex: 'owner',
325        width: 60,
326        hidden: false,
327        renderer: jobCellRender
328      },{
329        header: 'Queue',
330        tooltip: 'In which queue does this job reside',
331        readOnly: true,
332        dataIndex: 'queue',
333        width: 60,
334        hidden: false,
335        renderer: jobCellRender
336      },{
337        header: 'Name',
338        tooltip: 'Name of job',
339        readOnly: true,
340        dataIndex: 'name',
341        width: 100,
342        hidden: false
343      },{
344        header: 'Requested Time',
345        tooltip: 'Amount of requested time (wallclock)',
346        readOnly: true,
347        dataIndex: 'requested_time',
348        width: 100,
349        hidden: false
350      },{
351        header: 'Requested Memory',
352        tooltip: 'Amount of requested memory',
353        readOnly: true,
354        dataIndex: 'requested_memory',
355        width: 100,
356        hidden: true
357      },{
358        header: 'P',
359        tooltip: 'Number of processors per node (PPN)',
360        readOnly: true,
361        dataIndex: 'ppn',
362        width: 25,
363        hidden: false
364      },{
365        header: 'N',
366        tooltip: 'Number of nodes (hosts)',
367        readOnly: true,
368        dataIndex: 'nodect',
369        width: 25,
370        hidden: false
371      },{
372        header: 'Nodes',
373        readOnly: true,
374        dataIndex: 'nodes',
375        width: 100,
376        hidden: true
377      },{
378        header: 'Queued',
379        tooltip: 'At what time did this job enter the queue',
380        readOnly: true,
381        dataIndex: 'queued_timestamp',
382        width: 120,
383        hidden: false
384      },{
385        header: 'Started',
386        tooltip: 'At what time did this job enter the running status',
387        readOnly: true,
388        dataIndex: 'start_timestamp',
389        width: 120,
390        hidden: false
391      },{
392        header: 'Runningtime',
393        tooltip: 'How long has this job been in the running status',
394        readOnly: true,
395        dataIndex: 'runningtime',
396        width: 140,
397        hidden: false
398      }]
399    );
400    JobsColumnModel.defaultSortable= true;
401
402  JobListingEditorGrid =  new Ext.grid.EditorGridPanel({
403      id: 'JobListingEditorGrid',
404      store: JobsDataStore,
405      cm: JobsColumnModel,
406      enableColLock:false,
407      clicksToEdit:1,
408      loadMask: true,
409      selModel: new Ext.grid.RowSelectionModel({singleSelect:false}),
410      stripeRows: true,
411      bbar: new Ext.PagingToolbar({
412                pageSize: 30,
413                store: JobsDataStore,
414                displayInfo: true,
415                displayMsg: 'Displaying jobs {0} - {1} out of {2} jobs total found.',
416                emptyMsg: 'No jobs found to display'
417            }),
418      tbar: [ new Ext.app.SearchField({
419                                store: JobsDataStore,
420                                params: {start: 0, limit: 30},
421                                width: 200
422                    })
423      ]
424    });
425
426  ClusterImageWindow = new Ext.Window({
427      id: 'ClusterImageWindow',
428      title: 'Nodes',
429      closable: true,
430      collapsible: true,
431      animCollapse: true,
432      width: 1,
433      height: 1,
434      y: 15,
435      plain: true,
436      shadow: true,
437      //resizable: false,
438      resizable: true,
439      shadowOffset: 10,
440      layout: 'fit',
441      bbar: new Ext.StatusBar({
442                defaultText: 'Ready.',
443                id: 'basic-statusbar',
444                defaultIconCls: ''
445        })
446
447    });
448
449  GraphSummaryWindow = new Ext.Window({
450      id: 'GraphSummaryWindow',
451      title: 'Graph Summary',
452      closable: true,
453      collapsible: true,
454      animCollapse: true,
455      width: 300,
456      height: 500,
457      y: 15,
458      plain: true,
459      shadow: true,
460      resizable: true,
461      shadowOffset: 10,
462      layout: 'table',
463      layoutConfig: {
464                columns: 2
465        },
466      defaults:{border: false},
467      items: [{
468        id: 'monarchlogo',
469        cls: 'monarch',
470        bodyStyle: 'background: transparent',
471        html: '<A HREF="https://subtrac.sara.nl/oss/jobmonarch/" TARGET="_blank"><IMG SRC="./jobmonarch.gif" ALT="Job Monarch" BORDER="0"></A>'
472        //colspan: 2
473       },{
474        id: 'summarycount'
475       },{
476        id: 'rjqjgraph'
477       },{
478        id: 'pie',
479        colspan: 2
480       }],
481      bbar: new Ext.StatusBar({
482                defaultText: 'Ready.',
483                id: 'basic-statusbar',
484                defaultIconCls: ''
485        })
486    });
487
488  JobListingWindow = new Ext.Window({
489      id: 'JobListingWindow',
490      title: 'Cluster Jobs Overview',
491      closable:true,
492      collapsible: true,
493      animCollapse: true,
494      maximizable: true,
495      y: 375,
496      width:860,
497      height:500,
498      plain:true,
499      shadow: true,
500      shadowOffset: 10,
501      layout: 'fit',
502      items: JobListingEditorGrid
503    });
504
505  JobListingEditorGrid.addListener( 'cellclick', jobCellClick );
506  ClusterImageWindow.addListener( 'resize', clusterImageResize );
507}
Note: See TracBrowser for help on using the repository browser.