2015-03-15 23:54:55 +01:00
/ * *
* Copyright 2015 IBM Corp .
*
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
* * /
2015-07-01 00:42:03 +02:00
2015-03-15 23:54:55 +01:00
RED . deploy = ( function ( ) {
2015-07-01 00:42:03 +02:00
2015-03-15 23:54:55 +01:00
var deploymentTypes = {
2015-04-02 00:24:47 +02:00
"full" : { img : "red/images/deploy-full-o.png" } ,
"nodes" : { img : "red/images/deploy-nodes-o.png" } ,
"flows" : { img : "red/images/deploy-flows-o.png" }
2015-03-15 23:54:55 +01:00
}
2015-07-01 00:42:03 +02:00
2015-06-10 15:52:58 +02:00
var ignoreDeployWarnings = {
unknown : false ,
unusedConfig : false ,
invalid : false
}
2015-07-01 00:42:03 +02:00
2015-03-15 23:54:55 +01:00
var deploymentType = "full" ;
2015-07-01 00:42:03 +02:00
2015-03-15 23:54:55 +01:00
function changeDeploymentType ( type ) {
deploymentType = type ;
$ ( "#btn-deploy img" ) . attr ( "src" , deploymentTypes [ type ] . img ) ;
}
2015-07-01 00:42:03 +02:00
2015-04-10 16:13:40 +02:00
/ * *
* options :
* type : "default" - Button with drop - down options - no further customisation available
* type : "simple" - Button without dropdown . Customisations :
* label : the text to display - default : "Deploy"
* icon : the icon to use . Null removes the icon . default : "red/images/deploy-full-o.png"
* /
function init ( options ) {
options = options || { } ;
var type = options . type || "default" ;
2015-07-01 00:42:03 +02:00
2015-04-10 16:13:40 +02:00
if ( type == "default" ) {
$ ( '<li><span class="deploy-button-group button-group">' +
2015-05-22 01:40:27 +02:00
'<a id="btn-deploy" class="deploy-button disabled" href="#"><img id="btn-deploy-icon" src="red/images/deploy-full-o.png"> <span>' + RED . _ ( "deploy.deploy" ) + '</span></a>' +
2015-04-13 22:50:40 +02:00
'<a id="btn-deploy-options" data-toggle="dropdown" class="deploy-button" href="#"><i class="fa fa-caret-down"></i></a>' +
2015-04-10 16:13:40 +02:00
'</span></li>' ) . prependTo ( ".header-toolbar" ) ;
RED . menu . init ( { id : "btn-deploy-options" ,
options : [
2015-05-22 01:40:27 +02:00
{ id : "deploymenu-item-full" , toggle : "deploy-type" , icon : "red/images/deploy-full.png" , label : RED . _ ( "deploy.full" ) , sublabel : RED . _ ( "deploy.fullDesc" ) , selected : true , onselect : function ( s ) { if ( s ) { changeDeploymentType ( "full" ) } } } ,
{ id : "deploymenu-item-flow" , toggle : "deploy-type" , icon : "red/images/deploy-flows.png" , label : RED . _ ( "deploy.modifiedFlows" ) , sublabel : RED . _ ( "deploy.modifiedFlowsDesc" ) , onselect : function ( s ) { if ( s ) { changeDeploymentType ( "flows" ) } } } ,
{ id : "deploymenu-item-node" , toggle : "deploy-type" , icon : "red/images/deploy-nodes.png" , label : RED . _ ( "deploy.modifiedNodes" ) , sublabel : RED . _ ( "deploy.modifiedNodesDesc" ) , onselect : function ( s ) { if ( s ) { changeDeploymentType ( "nodes" ) } } }
2015-04-10 16:13:40 +02:00
]
} ) ;
} else if ( type == "simple" ) {
2015-05-22 01:40:27 +02:00
var label = options . label || RED . _ ( "deploy.deploy" ) ;
2015-04-10 16:13:40 +02:00
var icon = 'red/images/deploy-full-o.png' ;
if ( options . hasOwnProperty ( 'icon' ) ) {
icon = options . icon ;
}
2015-07-01 00:42:03 +02:00
2015-04-10 16:13:40 +02:00
$ ( '<li><span class="deploy-button-group button-group">' +
2015-04-13 22:50:40 +02:00
'<a id="btn-deploy" class="deploy-button disabled" href="#">' +
2015-04-13 17:48:38 +02:00
( icon ? '<img id="btn-deploy-icon" src="' + icon + '"> ' : '' ) +
2015-04-10 16:13:40 +02:00
'<span>' + label + '</span></a>' +
'</span></li>' ) . prependTo ( ".header-toolbar" ) ;
}
2015-07-01 00:42:03 +02:00
2015-03-15 23:54:55 +01:00
$ ( '#btn-deploy' ) . click ( function ( ) { save ( ) ; } ) ;
2015-07-01 00:42:03 +02:00
2015-03-15 23:54:55 +01:00
$ ( "#node-dialog-confirm-deploy" ) . dialog ( {
title : "Confirm deploy" ,
modal : true ,
autoOpen : false ,
2015-06-10 15:52:58 +02:00
width : 550 ,
height : "auto" ,
2015-03-15 23:54:55 +01:00
buttons : [
{
2015-07-01 00:42:03 +02:00
text : RED . _ ( "deploy.confirm.button.confirm" ) ,
2015-03-15 23:54:55 +01:00
click : function ( ) {
2015-07-01 00:42:03 +02:00
2015-06-10 15:52:58 +02:00
var ignoreChecked = $ ( "#node-dialog-confirm-deploy-hide" ) . prop ( "checked" ) ;
if ( ignoreChecked ) {
ignoreDeployWarnings [ $ ( "#node-dialog-confirm-deploy-type" ) . val ( ) ] = true ;
}
2015-03-15 23:54:55 +01:00
save ( true ) ;
$ ( this ) . dialog ( "close" ) ;
}
} ,
{
2015-07-01 00:42:03 +02:00
text : RED . _ ( "deploy.confirm.button.cancel" ) ,
2015-03-15 23:54:55 +01:00
click : function ( ) {
$ ( this ) . dialog ( "close" ) ;
}
}
2015-06-10 15:52:58 +02:00
] ,
create : function ( ) {
$ ( "#node-dialog-confirm-deploy" ) . parent ( ) . find ( "div.ui-dialog-buttonpane" )
2015-09-23 23:49:48 +02:00
. prepend ( '<div style="height:0; vertical-align: middle; display:inline-block; margin-top: 13px; float:left;">' +
2015-06-10 15:52:58 +02:00
'<input style="vertical-align:top;" type="checkbox" id="node-dialog-confirm-deploy-hide">' +
'<label style="display:inline;" for="node-dialog-confirm-deploy-hide"> do not warn about this again</label>' +
'<input type="hidden" id="node-dialog-confirm-deploy-type">' +
'</div>' ) ;
}
2015-03-15 23:54:55 +01:00
} ) ;
2015-03-17 16:38:31 +01:00
2015-07-10 20:49:31 +02:00
RED . events . on ( 'nodes:change' , function ( state ) {
2015-03-15 23:54:55 +01:00
if ( state . dirty ) {
2015-03-16 00:48:02 +01:00
window . onbeforeunload = function ( ) {
2015-07-01 00:42:03 +02:00
return RED . _ ( "deploy.confirm.undeployedChanges" ) ;
2015-03-16 00:48:02 +01:00
}
2015-03-15 23:54:55 +01:00
$ ( "#btn-deploy" ) . removeClass ( "disabled" ) ;
} else {
2015-03-16 00:48:02 +01:00
window . onbeforeunload = null ;
2015-03-15 23:54:55 +01:00
$ ( "#btn-deploy" ) . addClass ( "disabled" ) ;
}
} ) ;
}
2015-03-17 16:38:31 +01:00
2015-09-25 23:33:54 +02:00
function getNodeInfo ( node ) {
var tabLabel = "" ;
if ( node . z ) {
var tab = RED . nodes . workspace ( node . z ) ;
if ( ! tab ) {
tab = RED . nodes . subflow ( node . z ) ;
tabLabel = tab . name ;
} else {
tabLabel = tab . label ;
}
}
var label = "" ;
if ( typeof node . _def . label == "function" ) {
label = node . _def . label . call ( node ) ;
} else {
label = node . _def . label ;
}
label = label || node . id ;
return { tab : tabLabel , type : node . type , label : label } ;
}
function sortNodeInfo ( A , B ) {
if ( A . tab < B . tab ) { return - 1 ; }
if ( A . tab > B . tab ) { return 1 ; }
if ( A . type < B . type ) { return - 1 ; }
if ( A . type > B . type ) { return 1 ; }
if ( A . name < B . name ) { return - 1 ; }
if ( A . name > B . name ) { return 1 ; }
return 0 ;
}
2015-03-15 23:54:55 +01:00
function save ( force ) {
if ( RED . nodes . dirty ( ) ) {
//$("#debug-tab-clear").click(); // uncomment this to auto clear debug on deploy
if ( ! force ) {
2015-06-10 15:52:58 +02:00
var hasUnknown = false ;
var hasInvalid = false ;
var hasUnusedConfig = false ;
2015-07-01 00:42:03 +02:00
2015-03-15 23:54:55 +01:00
var unknownNodes = [ ] ;
2015-09-25 23:33:54 +02:00
var invalidNodes = [ ] ;
2015-03-15 23:54:55 +01:00
RED . nodes . eachNode ( function ( node ) {
2015-06-10 15:52:58 +02:00
hasInvalid = hasInvalid || ! node . valid ;
2015-09-25 23:33:54 +02:00
if ( ! node . valid ) {
invalidNodes . push ( getNodeInfo ( node ) ) ;
}
2015-03-15 23:54:55 +01:00
if ( node . type === "unknown" ) {
if ( unknownNodes . indexOf ( node . name ) == - 1 ) {
unknownNodes . push ( node . name ) ;
}
}
} ) ;
2015-06-10 15:52:58 +02:00
hasUnknown = unknownNodes . length > 0 ;
2015-07-01 00:42:03 +02:00
2015-09-25 23:33:54 +02:00
var unusedConfigNodes = [ ] ;
2015-06-10 15:52:58 +02:00
RED . nodes . eachConfig ( function ( node ) {
if ( node . users . length === 0 ) {
2015-09-25 23:33:54 +02:00
unusedConfigNodes . push ( getNodeInfo ( node ) ) ;
2015-06-10 15:52:58 +02:00
hasUnusedConfig = true ;
2015-03-15 23:54:55 +01:00
}
2015-06-10 15:52:58 +02:00
} ) ;
2015-07-01 00:42:03 +02:00
2015-06-10 15:52:58 +02:00
$ ( "#node-dialog-confirm-deploy-config" ) . hide ( ) ;
$ ( "#node-dialog-confirm-deploy-unknown" ) . hide ( ) ;
$ ( "#node-dialog-confirm-deploy-unused" ) . hide ( ) ;
2015-07-01 00:42:03 +02:00
2015-06-10 15:52:58 +02:00
var showWarning = false ;
2015-07-01 00:42:03 +02:00
2015-06-10 15:52:58 +02:00
if ( hasUnknown && ! ignoreDeployWarnings . unknown ) {
showWarning = true ;
$ ( "#node-dialog-confirm-deploy-type" ) . val ( "unknown" ) ;
$ ( "#node-dialog-confirm-deploy-unknown" ) . show ( ) ;
$ ( "#node-dialog-confirm-deploy-unknown-list" )
. html ( "<li>" + unknownNodes . join ( "</li><li>" ) + "</li>" ) ;
} else if ( hasInvalid && ! ignoreDeployWarnings . invalid ) {
showWarning = true ;
$ ( "#node-dialog-confirm-deploy-type" ) . val ( "invalid" ) ;
$ ( "#node-dialog-confirm-deploy-config" ) . show ( ) ;
2015-09-25 23:33:54 +02:00
invalidNodes . sort ( sortNodeInfo ) ;
$ ( "#node-dialog-confirm-deploy-invalid-list" )
. html ( "<li>" + invalidNodes . map ( function ( A ) { return ( A . tab ? "[" + A . tab + "] " : "" ) + A . label + " (" + A . type + ")" } ) . join ( "</li><li>" ) + "</li>" ) ;
2015-06-10 15:52:58 +02:00
} else if ( hasUnusedConfig && ! ignoreDeployWarnings . unusedConfig ) {
2016-01-12 18:54:53 +01:00
// showWarning = true;
// $( "#node-dialog-confirm-deploy-type" ).val("unusedConfig");
// $( "#node-dialog-confirm-deploy-unused" ).show();
//
// unusedConfigNodes.sort(sortNodeInfo);
// $( "#node-dialog-confirm-deploy-unused-list" )
// .html("<li>"+unusedConfigNodes.map(function(A) { return (A.tab?"["+A.tab+"] ":"")+A.label+" ("+A.type+")"}).join("</li><li>")+"</li>");
2015-06-10 15:52:58 +02:00
}
if ( showWarning ) {
$ ( "#node-dialog-confirm-deploy-hide" ) . prop ( "checked" , false ) ;
2015-03-15 23:54:55 +01:00
$ ( "#node-dialog-confirm-deploy" ) . dialog ( "open" ) ;
return ;
}
}
2015-07-01 00:42:03 +02:00
2015-03-15 23:54:55 +01:00
var nns = RED . nodes . createCompleteNodeSet ( ) ;
2015-04-13 17:48:38 +02:00
$ ( "#btn-deploy-icon" ) . removeClass ( 'fa-download' ) ;
$ ( "#btn-deploy-icon" ) . addClass ( 'spinner' ) ;
2015-03-15 23:54:55 +01:00
RED . nodes . dirty ( false ) ;
$ . ajax ( {
url : "flows" ,
type : "POST" ,
data : JSON . stringify ( nns ) ,
contentType : "application/json; charset=utf-8" ,
headers : {
"Node-RED-Deployment-Type" : deploymentType
}
} ) . done ( function ( data , textStatus , xhr ) {
2016-01-12 18:54:53 +01:00
if ( hasUnusedConfig ) {
RED . notify ( RED . _ ( "deploy.successfulDeploy" ) +
'<p><br>You have some unused configuration nodes. <a href="#" onclick="RED.sidebar.config.show(); return false;" >Click here</a> to see them</p>' , "success" , false , 6000 ) ;
} else {
RED . notify ( RED . _ ( "deploy.successfulDeploy" ) , "success" ) ;
}
2015-03-15 23:54:55 +01:00
RED . nodes . eachNode ( function ( node ) {
if ( node . changed ) {
node . dirty = true ;
node . changed = false ;
}
if ( node . credentials ) {
delete node . credentials ;
}
} ) ;
RED . nodes . eachConfig ( function ( confNode ) {
if ( confNode . credentials ) {
delete confNode . credentials ;
}
} ) ;
// Once deployed, cannot undo back to a clean state
RED . history . markAllDirty ( ) ;
RED . view . redraw ( ) ;
2015-07-10 20:49:31 +02:00
RED . events . emit ( "deploy" ) ;
2015-03-15 23:54:55 +01:00
} ) . fail ( function ( xhr , textStatus , err ) {
RED . nodes . dirty ( true ) ;
if ( xhr . responseText ) {
2015-07-15 11:11:16 +02:00
RED . notify ( RED . _ ( "notification.error" , { message : xhr . responseText } ) , "error" ) ;
2015-03-15 23:54:55 +01:00
} else {
2015-07-01 00:42:03 +02:00
RED . notify ( RED . _ ( "notification.error" , { message : RED . _ ( "deploy.errors.noResponse" ) } ) , "error" ) ;
2015-03-15 23:54:55 +01:00
}
} ) . always ( function ( ) {
2015-04-13 17:48:38 +02:00
$ ( "#btn-deploy-icon" ) . removeClass ( 'spinner' ) ;
$ ( "#btn-deploy-icon" ) . addClass ( 'fa-download' ) ;
2015-03-15 23:54:55 +01:00
} ) ;
}
}
return {
init : init
}
} ) ( ) ;