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