2014-11-28 20:12:18 +00:00
"use strict"
function importLayerPageInit ( ctx ) {
var layerDepBtn = $ ( "#add-layer-dependency-btn" ) ;
var importAndAddBtn = $ ( "#import-and-add-btn" ) ;
2014-12-08 15:26:27 +00:00
var layerNameInput = $ ( "#import-layer-name" ) ;
2014-11-28 20:12:18 +00:00
var vcsURLInput = $ ( "#layer-git-repo-url" ) ;
var gitRefInput = $ ( "#layer-git-ref" ) ;
var layerDepInput = $ ( "#layer-dependency" ) ;
var layerNameCtrl = $ ( "#layer-name-ctrl" ) ;
var duplicatedLayerName = $ ( "#duplicated-layer-name-hint" ) ;
2016-07-19 07:54:49 +00:00
var localDirPath = $ ( "#local-dir-path" ) ;
2014-11-28 20:12:18 +00:00
var layerDeps = { } ;
var layerDepsDeps = { } ;
var currentLayerDepSelection ;
var validLayerName = /^(\w|-)+$/ ;
2016-09-26 10:59:35 +00:00
libtoaster . makeTypeahead ( layerDepInput ,
libtoaster . ctx . layersTypeAheadUrl ,
{ include _added : "true" } , function ( item ) {
2014-11-28 20:12:18 +00:00
currentLayerDepSelection = item ;
2016-10-06 00:08:52 +00:00
layerDepBtn . removeAttr ( "disabled" ) ;
2016-04-19 16:28:40 +00:00
} ) ;
2016-10-06 00:08:52 +00:00
layerDepInput . on ( "typeahead:select" , function ( event , data ) {
currentLayerDepSelection = data ;
2014-11-28 20:12:18 +00:00
} ) ;
2016-07-19 07:54:49 +00:00
// Disable local dir repo when page is loaded.
$ ( '#local-dir' ) . hide ( ) ;
2016-04-19 16:28:40 +00:00
// disable the "Add layer" button when the layer input typeahead is empty
// or not in the typeahead choices
2016-10-06 00:08:52 +00:00
layerDepInput . on ( "input change" , function ( ) {
layerDepBtn . attr ( "disabled" , "disabled" ) ;
2016-04-19 16:28:40 +00:00
} ) ;
2014-11-28 20:12:18 +00:00
/ * W e a u t o m a t i c a l l y a d d " o p e n e m b e d d e d - c o r e " l a y e r f o r c o n v e n i e n c e a s a
* dependency as pretty much all layers depend on this one
* /
2015-08-04 19:46:34 +00:00
$ . getJSON ( libtoaster . ctx . layersTypeAheadUrl ,
{ include _added : "true" , search : "openembedded-core" } ,
2015-07-31 12:09:05 +00:00
function ( layer ) {
2015-08-04 19:46:34 +00:00
if ( layer . results . length > 0 ) {
currentLayerDepSelection = layer . results [ 0 ] ;
2016-12-09 16:52:50 +00:00
layerDepBtn . click ( ) ;
2014-11-28 20:12:18 +00:00
}
} ) ;
layerDepBtn . click ( function ( ) {
if ( currentLayerDepSelection == undefined )
return ;
layerDeps [ currentLayerDepSelection . id ] = currentLayerDepSelection ;
/* Make a list item for the new layer dependency */
2016-04-12 14:56:43 +00:00
var newLayerDep = $ ( "<li><a></a><span class=\"glyphicon glyphicon-trash\" data-toggle=\"tooltip\" title=\"Remove\"></span></li>" ) ;
2014-11-28 20:12:18 +00:00
newLayerDep . data ( 'layer-id' , currentLayerDepSelection . id ) ;
newLayerDep . children ( "span" ) . tooltip ( ) ;
var link = newLayerDep . children ( "a" ) ;
2015-07-31 12:09:07 +00:00
link . attr ( "href" , currentLayerDepSelection . layerdetailurl ) ;
2014-11-28 20:12:18 +00:00
link . text ( currentLayerDepSelection . name ) ;
link . tooltip ( { title : currentLayerDepSelection . tooltip , placement : "right" } ) ;
var trashItem = newLayerDep . children ( "span" ) ;
trashItem . click ( function ( ) {
var toRemove = $ ( this ) . parent ( ) . data ( 'layer-id' ) ;
delete layerDeps [ toRemove ] ;
$ ( this ) . parent ( ) . fadeOut ( function ( ) {
$ ( this ) . remove ( ) ;
} ) ;
} ) ;
$ ( "#layer-deps-list" ) . append ( newLayerDep ) ;
2016-09-26 10:59:35 +00:00
libtoaster . getLayerDepsForProject ( currentLayerDepSelection . layerdetailurl ,
function ( data ) {
2014-11-28 20:12:18 +00:00
/* These are the dependencies of the layer added as a dependency */
if ( data . list . length > 0 ) {
2015-07-31 12:09:07 +00:00
currentLayerDepSelection . url = currentLayerDepSelection . layerdetailurl ;
2015-06-08 14:22:01 +00:00
layerDeps [ currentLayerDepSelection . id ] . deps = data . list ;
2014-11-28 20:12:18 +00:00
}
/* Clear the current selection */
layerDepInput . val ( "" ) ;
currentLayerDepSelection = undefined ;
layerDepBtn . attr ( "disabled" , "disabled" ) ;
} , null ) ;
} ) ;
2016-04-12 14:56:43 +00:00
importAndAddBtn . click ( function ( e ) {
e . preventDefault ( ) ;
2014-12-05 17:25:51 +00:00
/ * T h i s i s a l i s t o f t h e n a m e s f r o m l a y e r D e p s f o r t h e l a y e r d e p s
* modal dialog body
* /
var depNames = [ ] ;
2014-11-28 20:12:18 +00:00
/* arrray of all layer dep ids includes parent and child deps */
var allDeps = [ ] ;
2014-12-05 17:25:51 +00:00
2014-11-28 20:12:18 +00:00
/ * t e m p o r a r y o b j e c t t o u s e t o d o a r e d u c e o n t h e d e p e n d e n c i e s f o r e a c h
* layer dependency added
* /
var depDeps = { } ;
/ * t h e l a y e r s t h a t h a v e d e p e n d e n c i e s h a v e a n e x t r a p r o p e r t y " d e p s "
* look in this for each layer and reduce this to a unquie object
* of deps .
* /
for ( var key in layerDeps ) {
if ( layerDeps [ key ] . hasOwnProperty ( 'deps' ) ) {
for ( var dep in layerDeps [ key ] . deps ) {
var layer = layerDeps [ key ] . deps [ dep ] ;
depDeps [ layer . id ] = layer ;
}
}
2014-12-05 17:25:51 +00:00
depNames . push ( layerDeps [ key ] . name ) ;
2014-11-28 20:12:18 +00:00
allDeps . push ( layerDeps [ key ] . id ) ;
}
/* we actually want it as an array so convert it now */
var depDepsArray = [ ] ;
for ( var key in depDeps )
depDepsArray . push ( depDeps [ key ] ) ;
if ( depDepsArray . length > 0 ) {
var layer = { name : layerNameInput . val ( ) , url : "#" , id : - 1 } ;
2014-12-05 17:25:51 +00:00
var title = "Layer" ;
var body = "<strong>" + layer . name + "</strong>'s dependencies (" +
depNames . join ( ", " ) + "</span>) require some layers that are not added to your project. Select the ones you want to add:</p>" ;
2016-09-26 10:59:35 +00:00
showLayerDepsModal ( layer ,
depDepsArray ,
title , body , false , function ( layerObsList ) {
2015-04-21 10:59:37 +00:00
/* Add the accepted layer dependencies' ids to the allDeps array */
for ( var key in layerObsList ) {
allDeps . push ( layerObsList [ key ] . id ) ;
2014-11-28 20:12:18 +00:00
}
import _and _add ( ) ;
} ) ;
} else {
import _and _add ( ) ;
}
function import _and _add ( ) {
/* convert to a csv of all the deps to be added */
var layerDepsCsv = allDeps . join ( "," ) ;
var layerData = {
name : layerNameInput . val ( ) ,
vcs _url : vcsURLInput . val ( ) ,
git _ref : gitRefInput . val ( ) ,
dir _path : $ ( "#layer-subdir" ) . val ( ) ,
2015-04-10 17:15:03 +00:00
project _id : libtoaster . ctx . projectId ,
2014-11-28 20:12:18 +00:00
layer _deps : layerDepsCsv ,
2016-07-19 07:54:49 +00:00
local _source _dir : $ ( '#local-dir-path' ) . val ( ) ,
2016-12-09 16:52:46 +00:00
add _to _project : true ,
2014-11-28 20:12:18 +00:00
} ;
2016-07-19 07:54:49 +00:00
if ( $ ( 'input[name=repo]:checked' ) . val ( ) == "git" ) {
layerData . local _source _dir = "" ;
} else {
layerData . vcs _url = "" ;
layerData . git _ref = "" ;
}
2014-11-28 20:12:18 +00:00
$ . ajax ( {
2016-12-09 16:52:46 +00:00
type : "PUT" ,
url : ctx . xhrLayerUrl ,
data : JSON . stringify ( layerData ) ,
2014-11-28 20:12:18 +00:00
headers : { 'X-CSRFToken' : $ . cookie ( 'csrftoken' ) } ,
success : function ( data ) {
if ( data . error != "ok" ) {
console . log ( data . error ) ;
2017-09-14 23:58:15 +00:00
/* let the user know why nothing happened */
alert ( data . error )
2014-11-28 20:12:18 +00:00
} else {
2016-09-26 10:59:35 +00:00
createImportedNotification ( data ) ;
window . location . replace ( libtoaster . ctx . projectPageUrl ) ;
2014-11-28 20:12:18 +00:00
}
} ,
error : function ( data ) {
console . log ( "Call failed" ) ;
console . log ( data ) ;
}
} ) ;
}
} ) ;
2016-09-26 10:59:35 +00:00
/* Layer imported notification */
function createImportedNotification ( imported ) {
var message = "Layer imported" ;
if ( imported . deps _added . length === 0 ) {
message = "You have imported <strong><a class=\"alert-link\" href=\"" + imported . imported _layer . layerdetailurl + "\">" + imported . imported _layer . name + "</a></strong> and added it to your project." ;
} else {
var links = "<a href=\"" + imported . imported _layer . layerdetailurl + "\">" + imported . imported _layer . name + "</a>, " ;
imported . deps _added . map ( function ( item , index ) {
links += '<a href="' + item . layerdetailurl + '">' + item . name + '</a>' ;
/*If we're at the last element we don't want the trailing comma */
if ( imported . deps _added [ index + 1 ] !== undefined )
links += ', ' ;
} ) ;
/* Length + 1 here to do deps + the imported layer */
message = 'You have imported <strong><a href="' + imported . imported _layer . layerdetailurl + '">' + imported . imported _layer . name + '</a></strong> and added <strong>' + ( imported . deps _added . length + 1 ) + '</strong> layers to your project: <strong>' + links + '</strong>' ;
}
libtoaster . setNotification ( "layer-imported" , message ) ;
}
2015-03-02 15:00:49 +00:00
function enable _import _btn ( enabled ) {
2014-11-28 20:12:18 +00:00
var importAndAddHint = $ ( "#import-and-add-hint" ) ;
if ( enabled ) {
importAndAddBtn . removeAttr ( "disabled" ) ;
importAndAddHint . hide ( ) ;
return ;
}
importAndAddBtn . attr ( "disabled" , "disabled" ) ;
importAndAddHint . show ( ) ;
}
function check _form ( ) {
var valid = false ;
var inputs = $ ( "input:required" ) ;
2016-07-19 07:54:49 +00:00
var inputStr = inputs . val ( ) . split ( "" ) ;
2014-11-28 20:12:18 +00:00
2016-07-19 07:54:49 +00:00
for ( var i = 0 ; i < inputs . val ( ) . length ; i ++ ) {
if ( ! ( valid = inputStr [ i ] ) ) {
2014-11-28 20:12:18 +00:00
enable _import _btn ( false ) ;
break ;
}
}
2016-07-19 07:54:49 +00:00
if ( valid ) {
2016-09-26 10:59:35 +00:00
if ( $ ( "#local-dir-radio" ) . prop ( "checked" ) &&
localDirPath . val ( ) . length > 0 ) {
2016-07-19 07:54:49 +00:00
enable _import _btn ( true ) ;
}
2016-09-26 10:59:35 +00:00
2017-09-14 23:58:15 +00:00
if ( $ ( "#git-repo-radio" ) . prop ( "checked" ) ) {
if ( gitRefInput . val ( ) . length > 0 &&
gitRefInput . val ( ) == 'HEAD' ) {
$ ( '#invalid-layer-revision-hint' ) . show ( ) ;
$ ( '#layer-revision-ctrl' ) . addClass ( 'has-error' ) ;
enable _import _btn ( false ) ;
} else if ( vcsURLInput . val ( ) . length > 0 &&
gitRefInput . val ( ) . length > 0 ) {
$ ( '#invalid-layer-revision-hint' ) . hide ( ) ;
$ ( '#layer-revision-ctrl' ) . removeClass ( 'has-error' ) ;
enable _import _btn ( true ) ;
}
2016-07-19 07:54:49 +00:00
}
}
if ( inputs . val ( ) . length == 0 )
enable _import _btn ( false ) ;
2014-11-28 20:12:18 +00:00
}
2015-03-02 15:00:49 +00:00
function layerExistsError ( layer ) {
var dupLayerInfo = $ ( "#duplicate-layer-info" ) ;
2016-07-19 07:54:49 +00:00
if ( layer . local _source _dir ) {
$ ( "#git-layer-dup" ) . hide ( ) ;
$ ( "#local-layer-dup" ) . fadeIn ( ) ;
dupLayerInfo . find ( ".dup-layer-name" ) . text ( layer . name ) ;
dupLayerInfo . find ( ".dup-layer-link" ) . attr ( "href" , layer . layerdetailurl ) ;
dupLayerInfo . find ( "#dup-local-source-dir-name" ) . text ( layer . local _source _dir ) ;
} else {
$ ( "#git-layer-dup" ) . fadeIn ( ) ;
$ ( "#local-layer-dup" ) . hide ( ) ;
dupLayerInfo . find ( ".dup-layer-name" ) . text ( layer . name ) ;
dupLayerInfo . find ( ".dup-layer-link" ) . attr ( "href" , layer . layerdetailurl ) ;
dupLayerInfo . find ( "#dup-layer-vcs-url" ) . text ( layer . vcs _url ) ;
dupLayerInfo . find ( "#dup-layer-revision" ) . text ( layer . vcs _reference ) ;
}
2015-03-02 15:00:49 +00:00
$ ( ".fields-apart-from-layer-name" ) . fadeOut ( function ( ) {
dupLayerInfo . fadeIn ( ) ;
} ) ;
}
layerNameInput . on ( 'blur' , function ( ) {
2016-09-26 10:59:35 +00:00
if ( ! $ ( this ) . val ( ) ) {
return ;
}
var name = $ ( this ) . val ( ) ;
2015-03-02 15:00:49 +00:00
2016-09-26 10:59:35 +00:00
/* Check if the layer name exists */
$ . getJSON ( libtoaster . ctx . layersTypeAheadUrl ,
2015-07-31 12:09:05 +00:00
{ include _added : "true" , search : name , format : "json" } ,
function ( layer ) {
2015-10-14 11:10:10 +00:00
if ( layer . results . length > 0 ) {
for ( var i in layer . results ) {
if ( layer . results [ i ] . name == name ) {
layerExistsError ( layer . results [ i ] ) ;
2015-07-31 12:09:05 +00:00
}
}
2015-03-02 15:00:49 +00:00
}
2015-07-31 12:09:05 +00:00
} ) ;
2015-03-02 15:00:49 +00:00
} ) ;
2015-02-06 19:18:19 +00:00
vcsURLInput . on ( 'input' , function ( ) {
2014-11-28 20:12:18 +00:00
check _form ( ) ;
} ) ;
2015-02-06 19:18:19 +00:00
gitRefInput . on ( 'input' , function ( ) {
2014-11-28 20:12:18 +00:00
check _form ( ) ;
} ) ;
2015-02-06 19:18:19 +00:00
layerNameInput . on ( 'input' , function ( ) {
2014-11-28 20:12:18 +00:00
if ( $ ( this ) . val ( ) && ! validLayerName . test ( $ ( this ) . val ( ) ) ) {
2016-04-12 14:56:43 +00:00
layerNameCtrl . addClass ( "has-error" )
2014-11-28 20:12:18 +00:00
$ ( "#invalid-layer-name-hint" ) . show ( ) ;
enable _import _btn ( false ) ;
return ;
}
2015-03-02 15:00:49 +00:00
if ( $ ( "#duplicate-layer-info" ) . css ( "display" ) != "None" ) {
$ ( "#duplicate-layer-info" ) . fadeOut ( function ( ) {
2016-07-19 07:54:49 +00:00
$ ( ".fields-apart-from-layer-name" ) . show ( ) ;
radioDisplay ( ) ;
} ) ;
2015-03-02 15:00:49 +00:00
2016-07-19 07:54:49 +00:00
}
radioDisplay ( ) ;
2015-03-02 15:00:49 +00:00
2014-11-28 20:12:18 +00:00
/ * D o n ' t r e m o v e t h e e r r o r c l a s s i f w e ' r e d i s p l a y i n g t h e e r r o r f o r a n o t h e r
* reason .
* /
if ( ! duplicatedLayerName . is ( ":visible" ) )
2016-04-12 14:56:43 +00:00
layerNameCtrl . removeClass ( "has-error" )
2014-11-28 20:12:18 +00:00
$ ( "#invalid-layer-name-hint" ) . hide ( ) ;
check _form ( ) ;
} ) ;
2016-12-09 16:52:50 +00:00
/* Setup 'blank' typeahead */
libtoaster . makeTypeahead ( gitRefInput ,
ctx . xhrGitRevTypeAheadUrl ,
{ git _url : null } , function ( ) { } ) ;
2014-11-28 20:12:18 +00:00
vcsURLInput . focusout ( function ( ) {
2016-12-09 16:52:50 +00:00
if ( ! $ ( this ) . val ( ) )
return ;
2014-11-28 20:12:18 +00:00
/ * I f w e a l a y e r n a m e s p e c i f i e d d o n ' t o v e r w r i t e i t o r i f t h e r e i s n ' t a
* url typed in yet return
* /
2016-12-09 16:52:50 +00:00
if ( ! layerNameInput . val ( ) && $ ( this ) . val ( ) . search ( "/" ) ) {
2014-11-28 20:12:18 +00:00
var urlPts = $ ( this ) . val ( ) . split ( "/" ) ;
2016-12-09 16:52:50 +00:00
/* Add a suggestion of the layer name */
2014-11-28 20:12:18 +00:00
var suggestion = urlPts [ urlPts . length - 1 ] . replace ( ".git" , "" ) ;
layerNameInput . val ( suggestion ) ;
}
2016-12-09 16:52:50 +00:00
/* Now actually setup the typeahead properly with the git url entered */
gitRefInput . _typeahead ( 'destroy' ) ;
libtoaster . makeTypeahead ( gitRefInput ,
ctx . xhrGitRevTypeAheadUrl ,
{ git _url : $ ( this ) . val ( ) } ,
function ( selected ) {
gitRefInput . _typeahead ( "close" ) ;
} ) ;
2014-11-28 20:12:18 +00:00
} ) ;
2016-07-19 07:54:49 +00:00
function radioDisplay ( ) {
if ( $ ( 'input[name=repo]:checked' ) . val ( ) == "local" ) {
$ ( '#git-repo' ) . hide ( ) ;
$ ( '#import-git-layer-and-add-hint' ) . hide ( ) ;
$ ( '#local-dir' ) . fadeIn ( ) ;
$ ( '#import-local-dir-and-add-hint' ) . fadeIn ( ) ;
} else {
$ ( '#local-dir' ) . hide ( ) ;
$ ( '#import-local-dir-and-add-hint' ) . hide ( ) ;
$ ( '#git-repo' ) . fadeIn ( ) ;
$ ( '#import-git-layer-and-add-hint' ) . fadeIn ( ) ;
}
}
$ ( 'input:radio[name="repo"]' ) . change ( function ( ) {
radioDisplay ( ) ;
if ( $ ( "#local-dir-radio" ) . prop ( "checked" ) ) {
if ( localDirPath . val ( ) . length > 0 ) {
enable _import _btn ( true ) ;
} else {
enable _import _btn ( false ) ;
}
}
if ( $ ( "#git-repo-radio" ) . prop ( "checked" ) ) {
if ( vcsURLInput . val ( ) . length > 0 && gitRefInput . val ( ) . length > 0 ) {
enable _import _btn ( true ) ;
} else {
enable _import _btn ( false ) ;
}
}
} ) ;
localDirPath . on ( 'input' , function ( ) {
if ( $ ( this ) . val ( ) . trim ( ) . length == 0 ) {
$ ( '#import-and-add-btn' ) . attr ( "disabled" , "disabled" ) ;
$ ( '#local-dir' ) . addClass ( 'has-error' ) ;
$ ( '#hintError-dir-abs-path' ) . show ( ) ;
$ ( '#hintError-dir-path-starts-with-slash' ) . show ( ) ;
} else {
var input = $ ( this ) ;
var reBeginWithSlash = /^\// ;
var reCheckVariable = /^\$/ ;
var re = /([ <>\\|":\.%\?\*]+)/ ;
var invalidDir = re . test ( input . val ( ) ) ;
var invalidSlash = reBeginWithSlash . test ( input . val ( ) ) ;
var invalidVar = reCheckVariable . test ( input . val ( ) ) ;
if ( ! invalidSlash && ! invalidVar ) {
$ ( '#local-dir' ) . addClass ( 'has-error' ) ;
$ ( '#import-and-add-btn' ) . attr ( "disabled" , "disabled" ) ;
$ ( '#hintError-dir-abs-path' ) . show ( ) ;
$ ( '#hintError-dir-path-starts-with-slash' ) . show ( ) ;
} else if ( invalidDir ) {
$ ( '#local-dir' ) . addClass ( 'has-error' ) ;
$ ( '#import-and-add-btn' ) . attr ( "disabled" , "disabled" ) ;
$ ( '#hintError-dir-path' ) . show ( ) ;
} else {
$ ( '#local-dir' ) . removeClass ( 'has-error' ) ;
if ( layerNameInput . val ( ) . length > 0 ) {
$ ( '#import-and-add-btn' ) . removeAttr ( "disabled" ) ;
}
$ ( '#hintError-dir-abs-path' ) . hide ( ) ;
$ ( '#hintError-dir-path-starts-with-slash' ) . hide ( ) ;
$ ( '#hintError-dir-path' ) . hide ( ) ;
}
}
} ) ;
2014-11-28 20:12:18 +00:00
}