2013-09-05 16:02:48 +02:00
/ * *
2015-01-18 10:35:32 +01:00
* Copyright 2013 , 2015 IBM Corp .
2013-09-05 16:02:48 +02:00
*
* 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 .
* * /
2014-08-08 01:01:35 +02:00
var RED = ( function ( ) {
2013-09-05 16:02:48 +02:00
2015-01-08 23:34:26 +01:00
var deploymentTypes = {
2015-01-17 21:36:18 +01:00
"full" : { img : "images/deploy-full-o.png" } ,
"nodes" : { img : "images/deploy-nodes-o.png" } ,
"flows" : { img : "images/deploy-flows-o.png" }
2015-01-08 23:34:26 +01:00
}
var deploymentType = "full" ;
2013-09-05 16:02:48 +02:00
function save ( force ) {
if ( RED . view . dirty ( ) ) {
2014-09-04 09:19:37 +02:00
//$("#debug-tab-clear").click(); // uncomment this to auto clear debug on deploy
2013-12-11 23:22:33 +01:00
2013-09-05 16:02:48 +02:00
if ( ! force ) {
var invalid = false ;
2013-12-12 16:51:15 +01:00
var unknownNodes = [ ] ;
2013-09-05 16:02:48 +02:00
RED . nodes . eachNode ( function ( node ) {
2014-05-08 15:15:54 +02:00
invalid = invalid || ! node . valid ;
if ( node . type === "unknown" ) {
if ( unknownNodes . indexOf ( node . name ) == - 1 ) {
unknownNodes . push ( node . name ) ;
2013-12-11 23:22:33 +01:00
}
2014-05-08 15:15:54 +02:00
invalid = true ;
}
2013-09-05 16:02:48 +02:00
} ) ;
if ( invalid ) {
2013-12-12 16:51:15 +01:00
if ( unknownNodes . length > 0 ) {
$ ( "#node-dialog-confirm-deploy-config" ) . hide ( ) ;
$ ( "#node-dialog-confirm-deploy-unknown" ) . show ( ) ;
var list = "<li>" + unknownNodes . join ( "</li><li>" ) + "</li>" ;
$ ( "#node-dialog-confirm-deploy-unknown-list" ) . html ( list ) ;
} else {
$ ( "#node-dialog-confirm-deploy-config" ) . show ( ) ;
$ ( "#node-dialog-confirm-deploy-unknown" ) . hide ( ) ;
}
2013-09-05 16:02:48 +02:00
$ ( "#node-dialog-confirm-deploy" ) . dialog ( "open" ) ;
return ;
}
}
var nns = RED . nodes . createCompleteNodeSet ( ) ;
2014-09-04 09:19:37 +02:00
2014-08-19 23:58:52 +02:00
$ ( "#btn-icn-deploy" ) . removeClass ( 'fa-download' ) ;
2014-02-20 18:31:40 +01:00
$ ( "#btn-icn-deploy" ) . addClass ( 'spinner' ) ;
RED . view . dirty ( false ) ;
2014-09-04 09:19:37 +02:00
2014-04-15 23:30:07 +02:00
$ . ajax ( {
url : "flows" ,
type : "POST" ,
data : JSON . stringify ( nns ) ,
2015-01-08 23:34:26 +01:00
contentType : "application/json; charset=utf-8" ,
headers : {
"Node-RED-Deployment-Type" : deploymentType
}
2014-04-15 23:30:07 +02:00
} ) . done ( function ( data , textStatus , xhr ) {
RED . notify ( "Successfully deployed" , "success" ) ;
RED . nodes . eachNode ( function ( node ) {
if ( node . changed ) {
node . dirty = true ;
node . changed = false ;
2013-09-05 16:02:48 +02:00
}
2014-07-19 01:16:21 +02:00
if ( node . credentials ) {
delete node . credentials ;
2014-06-24 12:13:19 +02:00
}
} ) ;
RED . nodes . eachConfig ( function ( confNode ) {
2014-07-19 01:16:21 +02:00
if ( confNode . credentials ) {
delete confNode . credentials ;
2014-06-24 12:13:19 +02:00
}
2014-04-15 23:30:07 +02:00
} ) ;
// Once deployed, cannot undo back to a clean state
RED . history . markAllDirty ( ) ;
RED . view . redraw ( ) ;
} ) . fail ( function ( xhr , textStatus , err ) {
RED . view . dirty ( true ) ;
if ( xhr . responseText ) {
RED . notify ( "<strong>Error</strong>: " + xhr . responseText , "error" ) ;
} else {
RED . notify ( "<strong>Error</strong>: no response from server" , "error" ) ;
}
} ) . always ( function ( ) {
$ ( "#btn-icn-deploy" ) . removeClass ( 'spinner' ) ;
2014-08-19 23:58:52 +02:00
$ ( "#btn-icn-deploy" ) . addClass ( 'fa-download' ) ;
2013-09-05 16:02:48 +02:00
} ) ;
}
}
$ ( '#btn-deploy' ) . click ( function ( ) { save ( ) ; } ) ;
$ ( "#node-dialog-confirm-deploy" ) . dialog ( {
title : "Confirm deploy" ,
modal : true ,
autoOpen : false ,
width : 530 ,
height : 230 ,
buttons : [
{
text : "Confirm deploy" ,
click : function ( ) {
save ( true ) ;
$ ( this ) . dialog ( "close" ) ;
}
} ,
{
text : "Cancel" ,
click : function ( ) {
$ ( this ) . dialog ( "close" ) ;
}
}
]
} ) ;
2014-02-16 01:39:30 +01:00
function loadSettings ( ) {
2014-10-30 15:19:44 +01:00
RED . settings . init ( loadNodeList ) ;
2014-08-28 01:35:07 +02:00
}
2014-10-30 15:19:44 +01:00
2014-08-28 01:35:07 +02:00
function loadNodeList ( ) {
$ . ajax ( {
headers : {
"Accept" : "application/json"
} ,
2014-09-24 10:57:45 +02:00
cache : false ,
2014-08-28 01:35:07 +02:00
url : 'nodes' ,
success : function ( data ) {
RED . nodes . setNodeList ( data ) ;
loadNodes ( ) ;
}
2014-02-16 01:39:30 +01:00
} ) ;
}
2014-09-04 09:19:37 +02:00
2013-09-05 16:02:48 +02:00
function loadNodes ( ) {
2014-08-28 01:35:07 +02:00
$ . ajax ( {
headers : {
"Accept" : "text/html"
} ,
2014-09-24 10:57:45 +02:00
cache : false ,
2014-08-28 01:35:07 +02:00
url : 'nodes' ,
success : function ( data ) {
$ ( "body" ) . append ( data ) ;
$ ( ".palette-spinner" ) . hide ( ) ;
$ ( ".palette-scroll" ) . show ( ) ;
$ ( "#palette-search" ) . show ( ) ;
loadFlows ( ) ;
}
2013-09-05 16:02:48 +02:00
} ) ;
}
function loadFlows ( ) {
2014-09-24 10:57:45 +02:00
$ . ajax ( {
headers : {
"Accept" : "application/json"
} ,
cache : false ,
url : 'flows' ,
success : function ( nodes ) {
RED . nodes . import ( nodes ) ;
RED . view . dirty ( false ) ;
2015-03-12 12:21:05 +01:00
RED . view . redraw ( true ) ;
2014-09-24 10:57:45 +02:00
RED . comms . subscribe ( "status/#" , function ( topic , msg ) {
var parts = topic . split ( "/" ) ;
var node = RED . nodes . node ( parts [ 1 ] ) ;
if ( node ) {
node . status = msg ;
if ( statusEnabled ) {
node . dirty = true ;
RED . view . redraw ( ) ;
2014-08-28 01:35:07 +02:00
}
}
2014-09-24 10:57:45 +02:00
} ) ;
RED . comms . subscribe ( "node/#" , function ( topic , msg ) {
var i , m ;
var typeList ;
var info ;
2014-11-07 13:28:19 +01:00
2014-09-24 10:57:45 +02:00
if ( topic == "node/added" ) {
var addedTypes = [ ] ;
for ( i = 0 ; i < msg . length ; i ++ ) {
m = msg [ i ] ;
var id = m . id ;
RED . nodes . addNodeSet ( m ) ;
if ( m . loaded ) {
addedTypes = addedTypes . concat ( m . types ) ;
$ . get ( 'nodes/' + id , function ( data ) {
$ ( "body" ) . append ( data ) ;
} ) ;
}
2014-08-07 14:46:03 +02:00
}
2014-09-24 10:57:45 +02:00
if ( addedTypes . length ) {
typeList = "<ul><li>" + addedTypes . join ( "</li><li>" ) + "</li></ul>" ;
RED . notify ( "Node" + ( addedTypes . length != 1 ? "s" : "" ) + " added to palette:" + typeList , "success" ) ;
}
} else if ( topic == "node/removed" ) {
for ( i = 0 ; i < msg . length ; i ++ ) {
m = msg [ i ] ;
info = RED . nodes . removeNodeSet ( m . id ) ;
if ( info . added ) {
typeList = "<ul><li>" + m . types . join ( "</li><li>" ) + "</li></ul>" ;
RED . notify ( "Node" + ( m . types . length != 1 ? "s" : "" ) + " removed from palette:" + typeList , "success" ) ;
}
}
} else if ( topic == "node/enabled" ) {
if ( msg . types ) {
info = RED . nodes . getNodeSet ( msg . id ) ;
if ( info . added ) {
RED . nodes . enableNodeSet ( msg . id ) ;
2014-08-28 01:35:07 +02:00
typeList = "<ul><li>" + msg . types . join ( "</li><li>" ) + "</li></ul>" ;
2014-09-24 10:57:45 +02:00
RED . notify ( "Node" + ( msg . types . length != 1 ? "s" : "" ) + " enabled:" + typeList , "success" ) ;
} else {
$ . get ( 'nodes/' + msg . id , function ( data ) {
$ ( "body" ) . append ( data ) ;
typeList = "<ul><li>" + msg . types . join ( "</li><li>" ) + "</li></ul>" ;
RED . notify ( "Node" + ( msg . types . length != 1 ? "s" : "" ) + " added to palette:" + typeList , "success" ) ;
} ) ;
2014-11-07 13:28:19 +01:00
}
2014-09-24 10:57:45 +02:00
}
} else if ( topic == "node/disabled" ) {
if ( msg . types ) {
RED . nodes . disableNodeSet ( msg . id ) ;
typeList = "<ul><li>" + msg . types . join ( "</li><li>" ) + "</li></ul>" ;
RED . notify ( "Node" + ( msg . types . length != 1 ? "s" : "" ) + " disabled:" + typeList , "success" ) ;
}
2014-08-07 14:46:03 +02:00
}
2014-09-24 10:57:45 +02:00
} ) ;
}
2013-09-05 16:02:48 +02:00
} ) ;
}
2014-05-11 00:33:02 +02:00
var statusEnabled = false ;
2014-08-20 22:58:54 +02:00
function toggleStatus ( state ) {
statusEnabled = state ;
2014-05-11 00:33:02 +02:00
RED . view . status ( statusEnabled ) ;
}
2014-09-04 09:19:37 +02:00
2013-09-05 16:02:48 +02:00
function showHelp ( ) {
2013-12-11 23:22:33 +01:00
2013-09-05 16:02:48 +02:00
var dialog = $ ( '#node-help' ) ;
2013-12-11 23:22:33 +01:00
2013-09-05 16:02:48 +02:00
//$("#node-help").draggable({
// handle: ".modal-header"
2013-12-11 23:22:33 +01:00
//});
2013-09-05 16:02:48 +02:00
dialog . on ( 'show' , function ( ) {
2014-05-08 15:15:54 +02:00
RED . keyboard . disable ( ) ;
2013-09-05 16:02:48 +02:00
} ) ;
dialog . on ( 'hidden' , function ( ) {
2014-05-08 15:15:54 +02:00
RED . keyboard . enable ( ) ;
2013-09-05 16:02:48 +02:00
} ) ;
dialog . modal ( ) ;
}
2015-01-08 23:34:26 +01:00
function changeDeploymentType ( type ) {
deploymentType = type ;
2015-01-14 23:40:45 +01:00
$ ( "#btn-deploy img" ) . attr ( "src" , deploymentTypes [ type ] . img ) ;
2015-01-08 23:34:26 +01:00
}
2014-11-11 11:15:02 +01:00
2014-11-12 14:21:39 +01:00
function loadEditor ( ) {
RED . menu . init ( { id : "btn-sidemenu" ,
options : [
{ id : "btn-sidebar" , label : "Sidebar" , toggle : true , onselect : RED . sidebar . toggleSidebar , selected : true } ,
{ id : "btn-node-status" , label : "Display node status" , toggle : true , onselect : toggleStatus , selected : true } ,
null ,
{ id : "btn-import-menu" , label : "Import" , options : [
{ id : "btn-import-clipboard" , label : "Clipboard" , onselect : RED . view . showImportNodesDialog } ,
{ id : "btn-import-library" , label : "Library" , options : [ ] }
] } ,
{ id : "btn-export-menu" , label : "Export" , disabled : true , options : [
{ id : "btn-export-clipboard" , label : "Clipboard" , disabled : true , onselect : RED . view . showExportNodesDialog } ,
{ id : "btn-export-library" , label : "Library" , disabled : true , onselect : RED . view . showExportNodesLibraryDialog }
] } ,
null ,
{ id : "btn-config-nodes" , label : "Configuration nodes" , onselect : RED . sidebar . config . show } ,
null ,
{ id : "btn-subflow-menu" , label : "Subflows" , options : [
2015-03-12 01:08:47 +01:00
{ id : "btn-create-subflow" , label : "Create subflow" , onselect : RED . subflow . createSubflow } ,
{ id : "btn-convert-subflow" , label : "Selection to subflow" , disabled : true , onselect : RED . subflow . convertToSubflow } ,
2014-11-12 14:21:39 +01:00
] } ,
null ,
{ id : "btn-workspace-menu" , label : "Workspaces" , options : [
{ id : "btn-workspace-add" , label : "Add" } ,
{ id : "btn-workspace-edit" , label : "Rename" } ,
{ id : "btn-workspace-delete" , label : "Delete" } ,
null
] } ,
null ,
{ id : "btn-keyboard-shortcuts" , label : "Keyboard Shortcuts" , onselect : showHelp } ,
{ id : "btn-help" , label : "Node-RED Website" , href : "http://nodered.org/docs" }
]
} ) ;
RED . menu . init ( { id : "btn-deploy-options" ,
options : [
{ id : "btn-deploy-full" , toggle : "deploy-type" , icon : "images/deploy-full.png" , label : "Full" , sublabel : "Deploys everything in the workspace" , onselect : function ( s ) { if ( s ) { changeDeploymentType ( "full" ) } } } ,
{ id : "btn-deploy-flow" , toggle : "deploy-type" , icon : "images/deploy-flows.png" , label : "Modified Flows" , sublabel : "Only deploys flows that contain changed nodes" , onselect : function ( s ) { if ( s ) { changeDeploymentType ( "flows" ) } } } ,
{ id : "btn-deploy-node" , toggle : "deploy-type" , icon : "images/deploy-nodes.png" , label : "Modified Nodes" , sublabel : "Only deploys nodes that have changed" , onselect : function ( s ) { if ( s ) { changeDeploymentType ( "nodes" ) } } }
]
} ) ;
if ( RED . settings . user ) {
2014-12-10 15:16:07 +01:00
RED . menu . init ( { id : "btn-usermenu" ,
options : [ ]
2014-11-11 11:15:02 +01:00
} ) ;
2014-12-10 15:58:53 +01:00
var updateUserMenu = function ( ) {
2014-12-10 15:16:07 +01:00
$ ( "#btn-usermenu-submenu li" ) . remove ( ) ;
if ( RED . settings . user . anonymous ) {
RED . menu . addItem ( "btn-usermenu" , {
id : "btn-login" ,
label : "Login" ,
onselect : function ( ) {
RED . user . login ( { cancelable : true } , function ( ) {
RED . settings . load ( function ( ) {
RED . notify ( "Logged in as " + RED . settings . user . username , "success" ) ;
updateUserMenu ( ) ;
} ) ;
} ) ;
}
} ) ;
} else {
RED . menu . addItem ( "btn-usermenu" , {
id : "btn-username" ,
label : "<b>" + RED . settings . user . username + "</b>"
} ) ;
RED . menu . addItem ( "btn-usermenu" , {
id : "btn-logout" ,
label : "Logout" ,
onselect : function ( ) {
RED . user . logout ( ) ;
}
} ) ;
}
}
updateUserMenu ( ) ;
2014-12-10 15:58:53 +01:00
} else {
$ ( "#btn-usermenu" ) . parent ( ) . hide ( ) ;
2014-11-12 14:21:39 +01:00
}
$ ( "#main-container" ) . show ( ) ;
2014-12-10 15:16:07 +01:00
$ ( ".header-toolbar" ) . show ( ) ;
2015-01-08 23:34:26 +01:00
2014-11-12 14:21:39 +01:00
RED . library . init ( ) ;
RED . palette . init ( ) ;
RED . sidebar . init ( ) ;
2015-03-12 01:08:47 +01:00
RED . subflow . init ( ) ;
2014-11-12 14:21:39 +01:00
RED . view . init ( ) ;
RED . keyboard . add ( /* ? */ 191 , { shift : true } , function ( ) { showHelp ( ) ; d3 . event . preventDefault ( ) ; } ) ;
RED . comms . connect ( ) ;
loadNodeList ( ) ;
}
2014-11-11 11:15:02 +01:00
$ ( function ( ) {
if ( ( window . location . hostname !== "localhost" ) && ( window . location . hostname !== "127.0.0.1" ) ) {
document . title = "Node-RED : " + window . location . hostname ;
}
2015-01-18 10:35:32 +01:00
2015-02-26 22:29:56 +01:00
ace . require ( "ace/ext/language_tools" ) ;
2014-12-10 15:16:07 +01:00
RED . settings . init ( loadEditor ) ;
2013-09-05 16:02:48 +02:00
} ) ;
2014-11-07 13:28:19 +01:00
2013-09-05 16:02:48 +02:00
return {
} ;
2014-08-08 01:01:35 +02:00
} ) ( ) ;