2015-03-03 16:18:24 +00:00
"use strict" ;
2014-11-11 16:23:58 +00:00
/ * A l l s h a r e d f u n c t i o n a l i t y t o g o i n l i b t o a s t e r o b j e c t .
* This object really just helps readability since we can then have
* a traceable namespace .
* /
var libtoaster = ( function ( ) {
/ * m a k e T y p e a h e a d p a r a m e t e r s
* elementSelector : JQuery elementSelector string
* xhrUrl : the url to get the JSON from expects JSON in the form :
* { "list" : [ { "name" : "test" , "detail" : "a test thing" } , ... . ] }
* xhrParams : the data / parameters to pass to the getJSON url e . g .
2015-05-19 15:14:29 +00:00
* { 'type' : 'projects' } the text typed will be passed as 'search' .
2014-11-11 16:23:58 +00:00
* selectedCB : function to call once an item has been selected one
* arg of the item .
* /
2015-05-19 15:14:29 +00:00
function _makeTypeahead ( jQElement , xhrUrl , xhrParams , selectedCB ) {
2014-11-11 16:23:58 +00:00
jQElement . typeahead ( {
source : function ( query , process ) {
2015-05-19 15:14:29 +00:00
xhrParams . search = query ;
$ . getJSON ( xhrUrl , this . options . xhrParams , function ( data ) {
2015-03-03 16:18:24 +00:00
if ( data . error !== "ok" ) {
2014-11-26 15:05:07 +00:00
console . log ( "Error getting data from server " + data . error ) ;
return ;
}
2014-11-11 16:23:58 +00:00
return process ( data . list ) ;
} ) ;
} ,
updater : function ( item ) {
var itemObj = this . $menu . find ( '.active' ) . data ( 'itemObject' ) ;
selectedCB ( itemObj ) ;
return item ;
} ,
matcher : function ( item ) { return ~ item . name . toLowerCase ( ) . indexOf ( this . query . toLowerCase ( ) ) ; } ,
highlighter : function ( item ) {
if ( item . hasOwnProperty ( 'detail' ) )
/* Use jquery to escape the value as text into a span */
return $ ( '<span></span>' ) . text ( item . name + ' ' + item . detail ) . get ( 0 ) ;
return $ ( '<span></span>' ) . text ( item . name ) . get ( 0 ) ;
} ,
sorter : function ( items ) { return items ; } ,
2015-05-19 15:14:29 +00:00
xhrUrl : xhrUrl ,
2014-11-11 16:23:58 +00:00
xhrParams : xhrParams ,
} ) ;
/* Copy of bootstrap's render func but sets selectedObject value */
function customRenderFunc ( items ) {
var that = this ;
items = $ ( items ) . map ( function ( i , item ) {
i = $ ( that . options . item ) . attr ( 'data-value' , item . name ) . data ( 'itemObject' , item ) ;
i . find ( 'a' ) . html ( that . highlighter ( item ) ) ;
return i [ 0 ] ;
} ) ;
items . first ( ) . addClass ( 'active' ) ;
this . $menu . html ( items ) ;
return this ;
}
jQElement . data ( 'typeahead' ) . render = customRenderFunc ;
2015-03-03 16:18:24 +00:00
}
2014-11-11 16:23:58 +00:00
/ *
* url - the url of the xhr build * /
function _startABuild ( url , project _id , targets , onsuccess , onfail ) {
2015-03-27 15:49:55 +00:00
var data = {
project _id : project _id ,
targets : targets ,
}
2014-11-11 16:23:58 +00:00
$ . ajax ( {
type : "POST" ,
url : url ,
data : data ,
headers : { 'X-CSRFToken' : $ . cookie ( 'csrftoken' ) } ,
success : function ( _data ) {
2015-03-03 16:18:24 +00:00
if ( _data . error !== "ok" ) {
2015-01-08 13:15:10 +00:00
console . warn ( _data . error ) ;
2014-11-11 16:23:58 +00:00
} else {
2015-03-03 16:18:24 +00:00
if ( onsuccess !== undefined ) onsuccess ( _data ) ;
2014-11-11 16:23:58 +00:00
}
} ,
error : function ( _data ) {
2015-01-08 13:15:10 +00:00
console . warn ( "Call failed" ) ;
console . warn ( _data ) ;
2014-11-11 16:23:58 +00:00
if ( onfail ) onfail ( data ) ;
} } ) ;
2015-03-03 16:18:24 +00:00
}
2014-11-11 16:23:58 +00:00
2015-03-13 14:34:41 +00:00
/ * c a n c e l A B u i l d :
2015-06-08 12:36:56 +00:00
* url : projectbuilds
2015-03-13 14:34:41 +00:00
* builds _ids : space separated list of build request ids
* onsuccess : callback for successful execution
* onfail : callback for failed execution
* /
function _cancelABuild ( url , build _ids , onsuccess , onfail ) {
$ . ajax ( {
type : "POST" ,
url : url ,
data : { 'buildCancel' : build _ids } ,
headers : { 'X-CSRFToken' : $ . cookie ( 'csrftoken' ) } ,
success : function ( _data ) {
if ( _data . error !== "ok" ) {
console . warn ( _data . error ) ;
} else {
if ( onsuccess !== undefined ) onsuccess ( _data ) ;
}
} ,
error : function ( _data ) {
console . warn ( "Call failed" ) ;
console . warn ( _data ) ;
2015-04-21 10:59:37 +00:00
if ( onfail ) onfail ( _data ) ;
2015-03-13 14:34:41 +00:00
}
} ) ;
}
2014-11-14 18:12:20 +00:00
/* Get a project's configuration info */
2015-06-08 17:41:46 +00:00
function _getProjectInfo ( url , onsuccess , onfail ) {
2014-11-14 18:12:20 +00:00
$ . ajax ( {
2015-06-08 17:41:46 +00:00
type : "GET" ,
data : { format : "json" } ,
2014-11-14 18:12:20 +00:00
url : url ,
headers : { 'X-CSRFToken' : $ . cookie ( 'csrftoken' ) } ,
success : function ( _data ) {
2015-03-03 16:18:24 +00:00
if ( _data . error !== "ok" ) {
2015-01-08 13:15:10 +00:00
console . warn ( _data . error ) ;
2014-11-14 18:12:20 +00:00
} else {
2015-03-03 16:18:24 +00:00
if ( onsuccess !== undefined ) onsuccess ( _data ) ;
2014-11-14 18:12:20 +00:00
}
} ,
error : function ( _data ) {
2015-01-08 13:15:10 +00:00
console . warn ( _data ) ;
2015-03-03 16:18:24 +00:00
if ( onfail ) onfail ( _data ) ;
2014-11-14 18:12:20 +00:00
}
} ) ;
2015-03-03 16:18:24 +00:00
}
2014-11-14 18:12:20 +00:00
2014-11-26 15:06:47 +00:00
/ * P r o p e r t i e s f o r d a t a c a n b e :
* layerDel ( csv )
* layerAdd ( csv )
* projectName
* projectVersion
* machineName
* /
2015-04-10 17:15:03 +00:00
function _editCurrentProject ( data , onSuccess , onFail ) {
2014-11-26 15:06:47 +00:00
$ . ajax ( {
type : "POST" ,
2015-06-08 17:41:46 +00:00
url : libtoaster . ctx . projectPageUrl + "?format=json" ,
2014-11-26 15:06:47 +00:00
data : data ,
headers : { 'X-CSRFToken' : $ . cookie ( 'csrftoken' ) } ,
success : function ( data ) {
if ( data . error != "ok" ) {
console . log ( data . error ) ;
2015-03-03 16:18:24 +00:00
if ( onFail !== undefined )
2014-11-26 15:06:47 +00:00
onFail ( data ) ;
} else {
2015-03-03 16:18:24 +00:00
if ( onSuccess !== undefined )
2014-11-26 15:06:47 +00:00
onSuccess ( data ) ;
}
} ,
error : function ( data ) {
console . log ( "Call failed" ) ;
console . log ( data ) ;
}
} ) ;
2015-03-03 16:18:24 +00:00
}
2014-11-26 15:06:47 +00:00
2015-06-08 14:22:01 +00:00
function _getLayerDepsForProject ( url , onSuccess , onFail ) {
2014-11-26 15:06:47 +00:00
/* Check for dependencies not in the current project */
2015-06-08 14:22:01 +00:00
$ . getJSON ( url ,
{ format : 'json' } ,
2014-11-26 15:06:47 +00:00
function ( data ) {
if ( data . error != "ok" ) {
console . log ( data . error ) ;
2015-03-03 16:18:24 +00:00
if ( onFail !== undefined )
2014-11-26 15:06:47 +00:00
onFail ( data ) ;
} else {
2015-06-08 12:36:56 +00:00
onSuccess ( data . layerdeps ) ;
2014-11-26 15:06:47 +00:00
}
} , function ( ) {
console . log ( "E: Failed to make request" ) ;
} ) ;
2015-03-03 16:18:24 +00:00
}
2014-11-26 15:06:47 +00:00
2015-01-14 12:46:52 +00:00
/* parses the query string of the current window.location to an object */
function _parseUrlParams ( ) {
2015-03-03 16:18:24 +00:00
var string = window . location . search ;
2015-01-14 12:46:52 +00:00
string = string . substr ( 1 ) ;
2015-03-03 16:18:24 +00:00
var stringArray = string . split ( "&" ) ;
var obj = { } ;
2015-01-14 12:46:52 +00:00
2015-03-03 16:18:24 +00:00
for ( var i in stringArray ) {
var keyVal = stringArray [ i ] . split ( "=" ) ;
2015-01-14 12:46:52 +00:00
obj [ keyVal [ 0 ] ] = keyVal [ 1 ] ;
}
return obj ;
2015-03-03 16:18:24 +00:00
}
2015-01-14 12:46:52 +00:00
/ * t a k e s a f l a t o b j e c t a n d o u t p u t s i t a s a q u e r y s t r i n g
* e . g . the output of dumpsUrlParams
* /
function _dumpsUrlParams ( obj ) {
var str = "?" ;
2015-03-03 16:18:24 +00:00
for ( var key in obj ) {
2015-01-14 12:46:52 +00:00
if ( ! obj [ key ] )
continue ;
str += key + "=" + obj [ key ] . toString ( ) ;
str += "&" ;
}
2015-05-18 19:08:28 +00:00
/* Maintain the current hash */
str += window . location . hash ;
2015-01-14 12:46:52 +00:00
return str ;
2015-03-03 16:18:24 +00:00
}
2015-01-14 12:46:52 +00:00
2015-04-21 10:59:37 +00:00
function _addRmLayer ( layerObj , add , doneCb ) {
if ( add === true ) {
/* If adding get the deps for this layer */
2015-06-08 14:22:01 +00:00
libtoaster . getLayerDepsForProject ( layerObj . url ,
2015-04-21 10:59:37 +00:00
function ( layers ) {
/* got result for dependencies */
if ( layers . list . length === 0 ) {
var editData = { layerAdd : layerObj . id } ;
libtoaster . editCurrentProject ( editData , function ( ) {
doneCb ( [ ] ) ;
} ) ;
return ;
} else {
try {
showLayerDepsModal ( layerObj , layers . list , null , null , true , doneCb ) ;
} catch ( e ) {
$ . getScript ( libtoaster . ctx . jsUrl + "layerDepsModal.js" , function ( ) {
showLayerDepsModal ( layerObj , layers . list , null , null , true , doneCb ) ;
} , function ( ) {
console . warn ( "Failed to load layerDepsModal" ) ;
} ) ;
}
}
} , null ) ;
} else if ( add === false ) {
var editData = { layerDel : layerObj . id } ;
libtoaster . editCurrentProject ( editData , function ( ) {
doneCb ( [ ] ) ;
} , function ( ) {
console . warn ( "Removing layer from project failed" ) ;
doneCb ( null ) ;
} ) ;
}
}
function _makeLayerAddRmAlertMsg ( layer , layerDepsList , add ) {
var alertMsg ;
if ( layerDepsList . length > 0 && add === true ) {
2015-04-21 19:29:46 +00:00
alertMsg = $ ( "<span>You have added <strong>" + ( layerDepsList . length + 1 ) + "</strong> layers to <a id=\"project-affected-name\"></a>: <a id=\"layer-affected-name\"></a> and its dependencies </span>" ) ;
2015-04-21 10:59:37 +00:00
/* Build the layer deps list */
layerDepsList . map ( function ( layer , i ) {
var link = $ ( "<a></a>" ) ;
link . attr ( "href" , layer . layerdetailurl ) ;
link . text ( layer . name ) ;
link . tooltip ( { title : layer . tooltip } ) ;
if ( i !== 0 )
alertMsg . append ( ", " ) ;
alertMsg . append ( link ) ;
} ) ;
} else if ( layerDepsList . length === 0 && add === true ) {
2015-04-21 19:29:46 +00:00
alertMsg = $ ( "<span>You have added <strong>1</strong> layer to <a id=\"project-affected-name\"></a>: <a id=\"layer-affected-name\"></a></span></span>" ) ;
2015-04-21 10:59:37 +00:00
} else if ( add === false ) {
2015-04-21 19:29:46 +00:00
alertMsg = $ ( "<span>You have deleted <strong>1</strong> layer from <a id=\"project-affected-name\"></a>: <a id=\"layer-affected-name\"></a></span>" ) ;
2015-04-21 10:59:37 +00:00
}
alertMsg . children ( "#layer-affected-name" ) . text ( layer . name ) ;
2015-04-21 19:29:46 +00:00
alertMsg . children ( "#layer-affected-name" ) . attr ( "href" , layer . url ) ;
2015-04-21 10:59:37 +00:00
alertMsg . children ( "#project-affected-name" ) . text ( libtoaster . ctx . projectName ) ;
alertMsg . children ( "#project-affected-name" ) . attr ( "href" , libtoaster . ctx . projectPageUrl ) ;
return alertMsg . html ( ) ;
}
2015-01-14 12:46:52 +00:00
2014-11-11 16:23:58 +00:00
return {
reload _params : reload _params ,
startABuild : _startABuild ,
2015-03-13 14:34:41 +00:00
cancelABuild : _cancelABuild ,
2014-11-11 16:23:58 +00:00
makeTypeahead : _makeTypeahead ,
2014-11-14 18:12:20 +00:00
getProjectInfo : _getProjectInfo ,
2014-11-26 15:06:47 +00:00
getLayerDepsForProject : _getLayerDepsForProject ,
2015-04-10 17:15:03 +00:00
editCurrentProject : _editCurrentProject ,
2015-01-08 13:15:10 +00:00
debug : false ,
2015-01-14 12:46:52 +00:00
parseUrlParams : _parseUrlParams ,
dumpsUrlParams : _dumpsUrlParams ,
2015-04-21 10:59:37 +00:00
addRmLayer : _addRmLayer ,
makeLayerAddRmAlertMsg : _makeLayerAddRmAlertMsg ,
2015-03-03 16:18:24 +00:00
} ;
2014-11-11 16:23:58 +00:00
} ) ( ) ;
/* keep this in the global scope for compatability */
function reload _params ( params ) {
2015-03-03 16:18:24 +00:00
var uri = window . location . href ;
var splitlist = uri . split ( "?" ) ;
var url = splitlist [ 0 ] ;
var parameters = splitlist [ 1 ] ;
2014-11-11 16:23:58 +00:00
// deserialize the call parameters
2015-03-03 16:18:24 +00:00
var cparams = [ ] ;
if ( parameters )
cparams = parameters . split ( "&" ) ;
var nparams = { } ;
for ( var i = 0 ; i < cparams . length ; i ++ ) {
var temp = cparams [ i ] . split ( "=" ) ;
2014-11-11 16:23:58 +00:00
nparams [ temp [ 0 ] ] = temp [ 1 ] ;
}
// update parameter values
for ( i in params ) {
nparams [ encodeURIComponent ( i ) ] = encodeURIComponent ( params [ i ] ) ;
}
// serialize the structure
2015-03-03 16:18:24 +00:00
var callparams = [ ] ;
2014-11-11 16:23:58 +00:00
for ( i in nparams ) {
callparams . push ( i + "=" + nparams [ i ] ) ;
}
window . location . href = url + "?" + callparams . join ( '&' ) ;
}
/* Things that happen for all pages */
$ ( document ) . ready ( function ( ) {
2015-03-03 16:18:24 +00:00
/ * I f w e d o n ' t h a v e a c o n s o l e o b j e c t w h i c h m i g h t b e t h e c a s e i n s o m e
2015-01-08 13:15:10 +00:00
* browsers , no - op it to avoid undefined errors .
* /
if ( ! window . console ) {
window . console = { } ;
window . console . warn = function ( ) { } ;
window . console . error = function ( ) { } ;
}
2014-11-11 16:23:58 +00:00
/ *
* PrettyPrint plugin .
*
* /
// Init
prettyPrint ( ) ;
// Prevent invalid links from jumping page scroll
$ ( 'a[href=#]' ) . click ( function ( ) {
return false ;
} ) ;
2015-05-11 17:51:28 +00:00
/* START TODO Delete this section now redundant */
2014-11-11 16:23:58 +00:00
/* Belen's additions */
// turn Edit columns dropdown into a multiselect menu
$ ( '.dropdown-menu input, .dropdown-menu label' ) . click ( function ( e ) {
e . stopPropagation ( ) ;
} ) ;
// enable popovers in any table cells that contain an anchor with the
// .btn class applied, and make sure popovers work on click, are mutually
// exclusive and they close when your click outside their area
2015-03-03 16:18:24 +00:00
$ ( 'html' ) . click ( function ( ) {
2014-11-11 16:23:58 +00:00
$ ( 'td > a.btn' ) . popover ( 'hide' ) ;
} ) ;
$ ( 'td > a.btn' ) . popover ( {
html : true ,
placement : 'left' ,
container : 'body' ,
trigger : 'manual'
} ) . click ( function ( e ) {
$ ( 'td > a.btn' ) . not ( this ) . popover ( 'hide' ) ;
// ideally we would use 'toggle' here
// but it seems buggy in our Bootstrap version
$ ( this ) . popover ( 'show' ) ;
e . stopPropagation ( ) ;
} ) ;
// enable tooltips for applied filters
$ ( 'th a.btn-primary' ) . tooltip ( { container : 'body' , html : true , placement : 'bottom' , delay : { hide : 1500 } } ) ;
// hide applied filter tooltip when you click on the filter button
$ ( 'th a.btn-primary' ) . click ( function ( ) {
$ ( '.tooltip' ) . hide ( ) ;
} ) ;
// enable help information tooltip
$ ( ".get-help" ) . tooltip ( { container : 'body' , html : true , delay : { show : 300 } } ) ;
// show help bubble only on hover inside tables
$ ( ".hover-help" ) . css ( "visibility" , "hidden" ) ;
$ ( "th, td" ) . hover ( function ( ) {
$ ( this ) . find ( ".hover-help" ) . css ( "visibility" , "visible" ) ;
} ) ;
$ ( "th, td" ) . mouseleave ( function ( ) {
$ ( this ) . find ( ".hover-help" ) . css ( "visibility" , "hidden" ) ;
} ) ;
2015-05-11 17:51:28 +00:00
/* END TODO Delete this section now redundant */
2014-11-11 16:23:58 +00:00
// show task type and outcome in task details pages
$ ( ".task-info" ) . tooltip ( { container : 'body' , html : true , delay : { show : 200 } , placement : 'right' } ) ;
2014-12-03 13:57:30 +00:00
// initialise the tooltips for the icon-pencil icons
$ ( ".icon-pencil" ) . tooltip ( { container : 'body' , html : true , delay : { show : 400 } , title : "Change" } ) ;
2015-02-09 11:48:39 +00:00
// initialise the tooltips for the download icons
$ ( ".icon-download-alt" ) . tooltip ( { container : 'body' , html : true , delay : { show : 200 } } ) ;
2015-02-24 17:20:53 +00:00
// initialise popover for debug information
$ ( ".icon-info-sign" ) . popover ( { placement : 'bottom' , html : true , container : 'body' } ) ;
2014-11-11 16:23:58 +00:00
// linking directly to tabs
$ ( function ( ) {
var hash = window . location . hash ;
2015-03-03 16:18:24 +00:00
$ ( 'ul.nav a[href="' + hash + '"]' ) . tab ( 'show' ) ;
2014-11-11 16:23:58 +00:00
2015-03-03 16:18:24 +00:00
$ ( '.nav-tabs a' ) . click ( function ( ) {
2014-11-11 16:23:58 +00:00
$ ( this ) . tab ( 'show' ) ;
$ ( 'body' ) . scrollTop ( ) ;
} ) ;
} ) ;
// toggle for long content (variables, python stack trace, etc)
$ ( '.full, .full-hide' ) . hide ( ) ;
$ ( '.full-show' ) . click ( function ( ) {
$ ( '.full' ) . slideDown ( function ( ) {
$ ( '.full-hide' ) . show ( ) ;
} ) ;
$ ( this ) . hide ( ) ;
} ) ;
$ ( '.full-hide' ) . click ( function ( ) {
$ ( this ) . hide ( ) ;
$ ( '.full' ) . slideUp ( function ( ) {
$ ( '.full-show' ) . show ( ) ;
} ) ;
} ) ;
//toggle the errors and warnings sections
$ ( '.show-errors' ) . click ( function ( ) {
$ ( '#collapse-errors' ) . addClass ( 'in' ) ;
} ) ;
$ ( '.toggle-errors' ) . click ( function ( ) {
$ ( '#collapse-errors' ) . toggleClass ( 'in' ) ;
} ) ;
$ ( '.show-warnings' ) . click ( function ( ) {
$ ( '#collapse-warnings' ) . addClass ( 'in' ) ;
} ) ;
$ ( '.toggle-warnings' ) . click ( function ( ) {
$ ( '#collapse-warnings' ) . toggleClass ( 'in' ) ;
} ) ;
2014-11-25 10:12:46 +00:00
$ ( '.show-exceptions' ) . click ( function ( ) {
$ ( '#collapse-exceptions' ) . addClass ( 'in' ) ;
} ) ;
$ ( '.toggle-exceptions' ) . click ( function ( ) {
$ ( '#collapse-exceptions' ) . toggleClass ( 'in' ) ;
} ) ;
2015-04-21 10:59:37 +00:00
$ ( "#hide-alert" ) . click ( function ( ) {
$ ( this ) . parent ( ) . fadeOut ( ) ;
} ) ;
2014-11-11 16:23:58 +00:00
//show warnings section when requested from the previous page
if ( location . href . search ( '#warnings' ) > - 1 ) {
$ ( '#collapse-warnings' ) . addClass ( 'in' ) ;
}
2015-01-08 13:15:10 +00:00
function check _for _duplicate _ids ( ) {
/* warn about duplicate element ids */
var ids = { } ;
$ ( "[id]" ) . each ( function ( ) {
if ( this . id && ids [ this . id ] ) {
console . warn ( 'Duplicate element id #' + this . id ) ;
}
ids [ this . id ] = true ;
} ) ;
}
if ( libtoaster . debug ) {
check _for _duplicate _ids ( ) ;
} else {
/* Debug is false so supress warnings by overriding the functions */
window . console . warn = function ( ) { } ;
window . console . error = function ( ) { } ;
}
2014-11-11 16:23:58 +00:00
} ) ;