[CCSDK-28] populated the seed code for dgbuilder
[ccsdk/distribution.git] / dgbuilder / public / red / main.js
1 /**
2  * Copyright 2013 IBM Corp.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  **/
16 var RED = (function() {
17
18     function hideDropTarget() {
19         $("#dropTarget").hide();
20         RED.keyboard.remove(/* ESCAPE */ 27);
21     }
22
23     $('#chart').on("dragenter",function(event) {
24         if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1) {
25             $("#dropTarget").css({display:'table'});
26             RED.keyboard.add(/* ESCAPE */ 27,hideDropTarget);
27         }
28     });
29
30     $('#dropTarget').on("dragover",function(event) {
31         if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1) {
32             event.preventDefault();
33         }
34     })
35     .on("dragleave",function(event) {
36         hideDropTarget();
37     })
38     .on("drop",function(event) {
39         var data = event.originalEvent.dataTransfer.getData("text/plain");
40         hideDropTarget();
41         RED.view.importNodes(data);
42         event.preventDefault();
43     });
44
45
46     function save(force) {
47         if (RED.view.dirty()) {
48             //$("#debug-tab-clear").click();  // uncomment this to auto clear debug on deploy
49
50             if (!force) {
51                 var invalid = false;
52                 var unknownNodes = [];
53                 RED.nodes.eachNode(function(node) {
54                     invalid = invalid || !node.valid;
55                     if (node.type === "unknown") {
56                         if (unknownNodes.indexOf(node.name) == -1) {
57                             unknownNodes.push(node.name);
58                         }
59                         invalid = true;
60                     }
61                 });
62                 if (invalid) {
63                     if (unknownNodes.length > 0) {
64                         $( "#node-dialog-confirm-deploy-config" ).hide();
65                         $( "#node-dialog-confirm-deploy-unknown" ).show();
66                         var list = "<li>"+unknownNodes.join("</li><li>")+"</li>";
67                         $( "#node-dialog-confirm-deploy-unknown-list" ).html(list);
68                     } else {
69                         $( "#node-dialog-confirm-deploy-config" ).show();
70                         $( "#node-dialog-confirm-deploy-unknown" ).hide();
71                     }
72                     $( "#node-dialog-confirm-deploy" ).dialog( "open" );
73                     return;
74                 }
75             }
76             var nns = RED.nodes.createCompleteNodeSet();
77             /****************************************/
78             /*added new code to save the Tabs order */
79             /****************************************/ 
80             //console.log("nns before changes.");
81             //console.dir(nns);
82             var allTabsObj={};
83             var allTabsList=[];
84             var nnsTabIdsArr = [];
85             var guiTabIdsArr = [];
86             nns.forEach(function(n) {
87                         if(n.type == 'tab'){
88                                 allTabsObj[n.id] = n;
89                                 allTabsList.push(n);
90                                 nnsTabIdsArr.push(n.id);
91                         }
92             });
93             var idx =0; 
94             $("#workspace-tabs li a").each(function(){
95                 var href = $(this).prop("href");
96                 var indexOfHash = href.indexOf("#");
97                 var idVal = href.slice(indexOfHash+1);
98                 guiTabIdsArr.push(idVal);
99                 nns.splice(idx,1,allTabsObj[idVal]);;
100                 idx++;
101             }); 
102             //console.log(nnsTabIdsArr.join(","));      
103             //console.log(guiTabIdsArr.join(","));      
104             //console.log("nns after changes.");
105             //console.dir(nns);
106             /****************************/ 
107             $("#btn-icn-deploy").removeClass('fa-download');
108             $("#btn-icn-deploy").addClass('spinner');
109             RED.view.dirty(false);
110
111             $.ajax({
112                 url:"flows",
113                 type: "POST",
114                 data: JSON.stringify(nns),
115                 contentType: "application/json; charset=utf-8"
116             }).done(function(data,textStatus,xhr) {
117                 RED.notify("Successfully saved","success");
118                 RED.nodes.eachNode(function(node) {
119                     if (node.changed) {
120                         node.dirty = true;
121                         node.changed = false;
122                     }
123                     if(node.credentials) {
124                         delete node.credentials;
125                     }
126                 });
127                 RED.nodes.eachConfig(function (confNode) {
128                     if (confNode.credentials) {
129                         delete confNode.credentials;
130                     }
131                 });
132                 // Once deployed, cannot undo back to a clean state
133                 RED.history.markAllDirty();
134                 RED.view.redraw();
135             }).fail(function(xhr,textStatus,err) {
136                 RED.view.dirty(true);
137                 if (xhr.responseText) {
138                     RED.notify("<strong>Error</strong>: "+xhr.responseText,"error");
139                 } else {
140                     RED.notify("<strong>Error</strong>: no response from server","error");
141                 }
142             }).always(function() {
143                 $("#btn-icn-deploy").removeClass('spinner');
144                 $("#btn-icn-deploy").addClass('fa-download');
145             });
146         }
147     }
148
149     $('#btn-deploy').click(function() { save(); });
150
151     $( "#node-dialog-confirm-deploy" ).dialog({
152             title: "Confirm deploy",
153             modal: true,
154             autoOpen: false,
155             width: 530,
156             height: 230,
157             buttons: [
158                 {
159                     text: "Confirm deploy",
160                     click: function() {
161                         save(true);
162                         $( this ).dialog( "close" );
163                     }
164                 },
165                 {
166                     text: "Cancel",
167                     click: function() {
168                         $( this ).dialog( "close" );
169                     }
170                 }
171             ]
172     });
173
174     function loadSettings() {
175         $.get('settings', function(data) {
176             RED.settings = data;
177             console.log("Node-RED: "+data.version);
178             loadNodeList();
179         });
180     }
181
182     function loadNodeList() {
183         $.ajax({
184             headers: {
185                 "Accept":"application/json"
186             },
187             cache: false,
188             url: 'nodes',
189             success: function(data) {
190                 RED.nodes.setNodeList(data);
191                 loadNodes();
192             }
193         });
194     }
195
196     function loadNodes() {
197         $.ajax({
198             headers: {
199                 "Accept":"text/html"
200             },
201             cache: false,
202             url: 'nodes',
203             success: function(data) {
204                 $("body").append(data);
205                 $(".palette-spinner").hide();
206                 $(".palette-scroll").show();
207                 $("#palette-search").show();
208                 loadFlows();
209             }
210         });
211     }
212
213     function loadFlows() {
214         $.ajax({
215             headers: {
216                 "Accept":"application/json"
217             },
218             cache: false,
219             url: 'flows',
220             success: function(nodes) {
221                 RED.nodes.import(nodes);
222                 RED.view.dirty(false);
223                 RED.view.redraw();
224                 RED.comms.subscribe("status/#",function(topic,msg) {
225                     var parts = topic.split("/");
226                     var node = RED.nodes.node(parts[1]);
227                     if (node) {
228                         node.status = msg;
229                         if (statusEnabled) {
230                             node.dirty = true;
231                             RED.view.redraw();
232                         }
233                     }
234                 });
235                 RED.comms.subscribe("node/#",function(topic,msg) {
236                     var i,m;
237                     var typeList;
238                     var info;
239                     
240                     if (topic == "node/added") {
241                         var addedTypes = [];
242                         for (i=0;i<msg.length;i++) {
243                             m = msg[i];
244                             var id = m.id;
245                             RED.nodes.addNodeSet(m);
246                             if (m.loaded) {
247                                 addedTypes = addedTypes.concat(m.types);
248                                 $.get('nodes/'+id, function(data) {
249                                     $("body").append(data);
250                                 });
251                             }
252                         }
253                         if (addedTypes.length) {
254                             typeList = "<ul><li>"+addedTypes.join("</li><li>")+"</li></ul>";
255                             RED.notify("Node"+(addedTypes.length!=1 ? "s":"")+" added to palette:"+typeList,"success");
256                         }
257                     } else if (topic == "node/removed") {
258                         for (i=0;i<msg.length;i++) {
259                             m = msg[i];
260                             info = RED.nodes.removeNodeSet(m.id);
261                             if (info.added) {
262                                 typeList = "<ul><li>"+m.types.join("</li><li>")+"</li></ul>";
263                                 RED.notify("Node"+(m.types.length!=1 ? "s":"")+" removed from palette:"+typeList,"success");
264                             }
265                         }
266                     } else if (topic == "node/enabled") {
267                         if (msg.types) {
268                             info = RED.nodes.getNodeSet(msg.id);
269                             if (info.added) {
270                                 RED.nodes.enableNodeSet(msg.id);
271                                 typeList = "<ul><li>"+msg.types.join("</li><li>")+"</li></ul>";
272                                 RED.notify("Node"+(msg.types.length!=1 ? "s":"")+" enabled:"+typeList,"success");
273                             } else {
274                                 $.get('nodes/'+msg.id, function(data) {
275                                     $("body").append(data);
276                                     typeList = "<ul><li>"+msg.types.join("</li><li>")+"</li></ul>";
277                                     RED.notify("Node"+(msg.types.length!=1 ? "s":"")+" added to palette:"+typeList,"success");
278                                 });
279                             } 
280                         }
281                     } else if (topic == "node/disabled") {
282                         if (msg.types) {
283                             RED.nodes.disableNodeSet(msg.id);
284                             typeList = "<ul><li>"+msg.types.join("</li><li>")+"</li></ul>";
285                             RED.notify("Node"+(msg.types.length!=1 ? "s":"")+" disabled:"+typeList,"success");
286                         }
287                     }
288                 });
289             }
290         });
291     }
292
293     var statusEnabled = false;
294     function toggleStatus(state) {
295         statusEnabled = state;
296         RED.view.status(statusEnabled);
297     }
298
299     function performLoopDetection(state) {
300         loopDetectionEnabled = state;
301         console.log("loopDetectionEnabled:" + loopDetectionEnabled);
302     }
303
304     var dgNumberEnabled = false;
305     function toggleDgNumberDisplay(state) {
306         dgNumberEnabled = state;
307         RED.view.showNumbers(dgNumberEnabled);
308     }
309
310     var nodePaletteDisplay = false;
311     function toggleNodePaletteDisplay(state) {
312         nodePaletteDisplay = state;
313         RED.view.showNodePalette(nodePaletteDisplay);
314     }
315     function displayAllDGs(state) {
316                 //defined showSLa() in dgstart.html 
317                 showSLA();
318     }
319
320
321     function showHelp() {
322
323         var dialog = $('#node-help');
324
325         //$("#node-help").draggable({
326         //        handle: ".modal-header"
327         //});
328
329         dialog.on('show',function() {
330             RED.keyboard.disable();
331         });
332         dialog.on('hidden',function() {
333             RED.keyboard.enable();
334         });
335
336         dialog.modal();
337     }
338
339
340 //Custom Functions Added here
341         function  showCodeCloudFlows(){
342                 codeCloudFlowFiles=[];
343                 var divStyle="<style>#codecloud-data-container a { color: #067ab4; font-size: 0.75em;} #codecloud-data-container a:hover { text-decoration: underline; padding: -15px -15px -15px 15px; } .header { height: 40px; border-bottom: 1px solid #EEE; background-color: #ffffff; height: 40px; -webkit-border-top-left-radius: 5px; -webkit-border-top-right-radius: 5px; -moz-border-radius-topleft: 5px; -moz-border-radius-topright: 5px; border-top-left-radius: 5px; border-top-right-radius: 5px; } .footer { height: 40px; background-color: whiteSmoke; border-top: 1px solid #DDD; -webkit-border-bottom-left-radius: 5px; -webkit-border-bottom-right-radius: 5px; -moz-border-radius-bottomleft: 5px; -moz-border-radius-bottomright: 5px; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; }</style>";
344                 $.get( "/getCodeCloudFlows")
345                                .done(function( data ) {
346                                         
347                                         var header="<div class='header'>List of DG Flows in Code Cloud</div><div><input id='flowFilterBoxId' type='text' onkeyup='filterFlows(this.value)'></div>";
348                                         var html=  divStyle + header +  "<div id='codecloud-data-container'>";
349                                         html+="<ul>";
350                                         if(data != null){
351                                                 var files=data.files;
352                                                 codeCloudFlowFiles=files;
353                                                 //console.dir(files);
354                                                 files.sort(function (a,b){
355                                                         if(a > b){
356                                                                 return 1;
357                                                         }else if(a <  b){
358                                                                 return -1;
359                                                         }else{  
360                                                                 return 0;
361                                                         }
362                                                 });
363                                                 for(var i=0;files != null && i<files.length;i++){
364                                                         html+="<li><a href=\"#\" onclick=\"getCommits('" + files[i] + "')\">" + files[i] + "</a></li>";
365                                                 }
366                                         }
367                                         html+="</ul>";
368                                         html+="</div>";
369                                         $( "#codecloud-browser-dialog" ).dialog({
370                                         title: "Code Cloud DG Flow Browser",
371                                         modal: true,
372                                         autoOpen: true,
373                                         width: 830,
374                                         height: 630,
375                                         buttons: [
376                                                 {
377                                                         text: "Close",
378                                                         click: function() {
379                                                                 $( this ).dialog( "close" );
380                                                         }
381                                                 }
382                                                 ],
383                                         close: function(ev,ui){
384                                                 $(this).dialog("destroy");
385                                         }
386                                         }).html(html);
387                                         $("#codecloud-browser-dialog").show();
388                                })
389                                 .fail(function(err) {
390                                          RED.notify("Failed to get users.");
391                                 })
392                                  .always(function() {
393                                 });
394         }
395         /*      
396         function  listYangFiles(){
397                 yangFilesList=[];
398                 var divStyle="<style>#list-yang-data-container a { color: #067ab4; font-size: 0.75em;} #list-yang-data-container a:hover { text-decoration: underline; padding: -15px -15px -15px 15px; } .header { height: 40px; border-bottom: 1px solid #EEE; background-color: #ffffff; height: 40px; -webkit-border-top-left-radius: 5px; -webkit-border-top-right-radius: 5px; -moz-border-radius-topleft: 5px; -moz-border-radius-topright: 5px; border-top-left-radius: 5px; border-top-right-radius: 5px; } .footer { height: 40px; background-color: whiteSmoke; border-top: 1px solid #DDD; -webkit-border-bottom-left-radius: 5px; -webkit-border-bottom-right-radius: 5px; -moz-border-radius-bottomleft: 5px; -moz-border-radius-bottomright: 5px; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; }</style>";
399                 $.get( "/getYangFiles")
400                                .done(function( data ) {
401                                         
402                                         var header="<div class='header'>List of Yang Files </div><div><input id='flowFilterBoxId' type='text' onkeyup='filterYangFiles(this.value)'></div>";
403                                         var html=  divStyle + header +  "<div id='list-yang-data-container'>";
404                                         html+="<ul>";
405                                         if(data != null){
406                                                 var files=data.files;
407                                                 yangFilesList=files;
408                                                 //console.dir(files);
409                                                 files.sort(function (a,b){
410                                                         if(a > b){
411                                                                 return 1;
412                                                         }else if(a <  b){
413                                                                 return -1;
414                                                         }else{  
415                                                                 return 0;
416                                                         }
417                                                 });
418                                                 for(var i=0;files != null && i<files.length;i++){
419                                                         html+="<li><a href=\"#\" onclick=\"getYangFile('" + files[i] + "')\">" + files[i] + "</a></li>";
420                                                 }
421                                         }
422                                         html+="</ul>";
423                                         html+="</div>";
424                                         $( "#list-yang-browser-dialog" ).dialog({
425                                         title: "List Yang Files",
426                                         modal: true,
427                                         autoOpen: true,
428                                         width: 830,
429                                         height: 630,
430                                         buttons: [
431                                                 {
432                                                         text: "Close",
433                                                         click: function() {
434                                                                 $( this ).dialog( "close" );
435                                                         }
436                                                 }
437                                                 ],
438                                         close: function(ev,ui){
439                                                 $(this).dialog("destroy");
440                                         }
441                                         }).html(html);
442                                         $("#list-yang-browser-dialog").show();
443                                })
444                                 .fail(function(err) {
445                                          RED.notify("Failed to get yang files.");
446                                 })
447                                  .always(function() {
448                                 });
449         }
450         */
451
452         function  listYangFiles(){
453                 yangFilesList=[];
454         
455                 var divStyle="<style>#yang-files-data-container a { color: #067ab4; font-size: 0.75em;} #yang-files-data-container a:hover { text-decoration: underline; padding: -15px -15px -15px 15px; } .header { height: 40px; border-bottom: 1px solid #EEE; background-color: #ffffff; height: 40px; -webkit-border-top-left-radius: 5px; -webkit-border-top-right-radius: 5px; -moz-border-radius-topleft: 5px; -moz-border-radius-topright: 5px; border-top-left-radius: 5px; border-top-right-radius: 5px; } .footer { height: 40px; background-color: whiteSmoke; border-top: 1px solid #DDD; -webkit-border-bottom-left-radius: 5px; -webkit-border-bottom-right-radius: 5px; -moz-border-radius-bottomleft: 5px; -moz-border-radius-bottomright: 5px; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; } table#yang-file-list-table { width:100%; } table#yang-file-list-table th,table#yang-file-list-table td { border: 1px solid black; border-collapse: collapse; } table#yang-file-list-table th,table#yang-file-list-table td { padding: 5px; text-align: left; } table#yang-file-list-table tr:nth-child(even) { background-color: #eee; } table#yang-file-list-table tr:nth-child(odd) { background-color:#fff; } table#yang-file-list-table th    { background-color: #65a9d7; color: white; } table#yang-file-list-table a { color: #337ab7; } table#yang-file-list-table a:link { color: #65a9d7; } table#yang-file-list-table a:visited { color: #636; } table#yang-file-list-table a:hover { color: #3366CC; cursor: pointer } table#yang-file-list-table a:active { color: #65a9d7 }</style>";
456                 $.get( "/getYangFiles")
457                                .done(function( data ) {
458                                         
459                                         var header="<div class='header'>List of Yang Files </div><div><input id='flowFilterBoxId' type='text' onkeyup='filterYangFiles(this.value)'></div>";
460                                         var html=  divStyle + header +  "<div id='yang-files-data-container'>";
461                                         html+="<table id='yang-file-list-table'  border=1>";
462                                         html+="<tr>";
463                                         html+="<th>File</th>";
464                                         html+="<th>Delete</th>";
465                                         html+="</tr>";
466                                         if(data != null){
467                                                 var files=data.files;
468                                                 yangFilesList=files;
469                                                 //console.dir(files);
470                                                 files.sort(function (a,b){
471                                                         if(a > b){
472                                                                 return 1;
473                                                         }else if(a <  b){
474                                                                 return -1;
475                                                         }else{  
476                                                                 return 0;
477                                                         }
478                                                 });
479                                                 for(var i=0;files != null && i<files.length;i++){
480                                                         html+="<tr><td><a href=\"#\" onclick=\"getYangFile('" + files[i] + "')\">" + files[i] + "</a></td><td>" + "<input type='button'  onclick='deleteYangFile(\"" + files[i]  + "\")' value='Delete'></td></td></td></tr>";
481                                                 }
482                                         }
483                                         html+="</table>";
484                                         html+="</div>";
485                                         $( "#list-yang-browser-dialog" ).dialog({
486                                         title: "List Yang Files",
487                                         modal: true,
488                                         autoOpen: true,
489                                         width: 830,
490                                         height: 630,
491                                         buttons: [
492                                                 {
493                                                         text: "Close",
494                                                         click: function() {
495                                                                 $( this ).dialog( "close" );
496                                                         }
497                                                 }
498                                                 ],
499                                         close: function(ev,ui){
500                                                 $(this).dialog("destroy");
501                                         }
502                                         }).html(html);
503                                         $("#list-yang-browser-dialog").show();
504                                })
505                                 .fail(function(err) {
506                                          RED.notify("Failed to get yang files.");
507                                 })
508                                  .always(function() {
509                                 });
510         }
511                 
512
513         function showGitPullDialog(){
514                 $.get( "/getCurrentGitBranch")
515                                .done(function( data ) {
516                                         if(data != null){ 
517                                                 if(data.output == "GIT_LOCAL_REPOSITORY_NOT_SET" ){
518                                                         RED.notify("Git Local Repository path is not set. Please set it by choosing Configuration from the menu.");
519                                                         return;
520                                                 }       
521
522                                                 var html= "<div id='gitcheckout-container'>";
523                                                 html+="<table>";
524                                                 html+="<tr>";
525                                                 html+="<td>Branch</td>";
526                                                 html+="<td>" +  data.output + "</td>";
527                                                 html+="</tr>";
528                                                 html+="<tr>";
529                                                 html+="<td><input id='gitPullBtnId' type='button' value='Pull' onclick='performGitPull()'></td>";
530                                                 html+="<td>&nbsp;&nbsp;</td>"
531                                                 html+="</tr>";
532                                                 html+="<tr>";
533                                                 //html+="<td colspan=3><textarea readonly='1' rows='5' cols='200'  id='responseId'></textarea></td>";
534                                                 html+="</tr>";
535                                                 html+="</table>";
536                                                 html+="<br><div id='responseId'></div>";
537                                                 html+="</div>";
538                                                 $( "#gitcommands-dialog" ).dialog({
539                                                         title: "Git Pull",
540                                                         modal: true,
541                                                         autoOpen: true,
542                                                         width: 630,
543                                                         height: 500,
544                                                         buttons: [
545                                                         {
546                                                                 text: "Close",
547                                                                 click: function() {
548                                                                         $( this ).dialog( "close" );
549                                                                 }
550                                                         }
551                                                         ],
552                                                         close: function(ev,ui){
553                                                                 $(this).dialog("destroy");
554                                                         }
555                                                 }).html(html);
556                                           $("#responseId").css({width:'550',height:'275px', border: '2px solid lightgrey',overflow:'scroll', padding: '20px' });
557                                           $("#responseId").hide();
558                                         $("#gitcommands-dialog").show();
559                                 }
560                                })
561                                 .fail(function(err) {
562                                          RED.notify("Failed to get gitBranch.");
563                                 })
564                                  .always(function() {
565                                 });
566         }
567
568         function showGitStatusDialog(){
569                 $.get( "/getCurrentGitBranch")
570                                .done(function( data ) {
571                                         if(data != null){ 
572                                                 if(data.output == "GIT_LOCAL_REPOSITORY_NOT_SET" ){
573                                                         RED.notify("Git Local Repository path is not set. Please set it by choosing Configuration from the menu.");
574                                                         return;
575                                                 }       
576
577                                                 var html= "<div id='gitcheckout-container'>";
578                                                 html+="<table>";
579                                                 html+="<tr>";
580                                                 html+="<td>Branch</td>";
581                                                 html+="<td>" + data.output + "</td>";
582                                                 html+="</tr>";
583                                                 html+="<tr>";
584                                                 html+="<td><input id='gitStatusBtnId' type='button' value='Status' onclick='performGitStatus()'></td>";
585                                                 html+="<td>&nbsp;&nbsp;</td>"
586                                                 html+="</tr>";
587                                                 html+="<tr>";
588                                                 //html+="<td colspan=3><textarea readonly='1' rows='5' cols='200'  id='responseId'></textarea></td>";
589                                                 html+="</tr>";
590                                                 html+="</table>";
591                                                 html+="<br><div id='responseId'></div>";
592                                                 html+="</div>";
593                                                 $( "#gitcommands-dialog" ).dialog({
594                                                         title: "Git Status",
595                                                         modal: true,
596                                                         autoOpen: true,
597                                                         width: 630,
598                                                         height: 500,
599                                                         buttons: [
600                                                         {
601                                                                 text: "Close",
602                                                                 click: function() {
603                                                                         $( this ).dialog( "close" );
604                                                                 }
605                                                         }
606                                                         ],
607                                                         close: function(ev,ui){
608                                                                 $(this).dialog("destroy");
609                                                         }
610                                                 }).html(html);
611                                           //$("#responseId").css({width:'600px',height:'100px','border-radius' : '25px', border: '2px solid lightgrey', padding: '20px' });
612                                           $("#responseId").css({width:'550px',height:'100px', border: '2px solid lightgrey',overflow:'scroll', padding: '20px' });
613                                           $("#responseId").hide();
614                                         $("#gitcommands-dialog").show();
615                                 }
616                                })
617                                 .fail(function(err) {
618                                          RED.notify("Failed to get gitBranch.");
619                                 })
620                                  .always(function() {
621                                 });
622         }
623
624         function showGitCheckoutDialog(){
625                 $.get( "/getCurrentGitBranch")
626                                .done(function( data ) {
627                                         if(data != null){ 
628                                                 if(data.output == "GIT_LOCAL_REPOSITORY_NOT_SET" ){
629                                                         RED.notify("Git Local Repository path is not set. Please set it by choosing Configuration from the menu.");
630                                                         return;
631                                                 }       
632
633                                                 var html= "<div id='gitcheckout-container'>";
634                                                 html+="<table>";
635                                                 html+="<tr>";
636                                                 html+="<td>Branch</td>";
637                                                 html+="<td><input id='branchId' type='text' value='" + data.output + "'></td>";
638                                                 html+="</tr>";
639                                                 html+="<tr>";
640                                                 html+="<td><input id='checkoutBtnId' type='button' value='Checkout' onclick='performGitCheckout()'></td>";
641                                                 html+="<td>&nbsp;&nbsp;</td>"
642                                                 html+="</tr>";
643                                                 html+="<tr>";
644                                                 //html+="<td colspan=3><textarea readonly='1' rows='5' cols='200'  id='responseId'></textarea></td>";
645                                                 html+="</tr>";
646                                                 html+="</table>";
647                                                 html+="<br><div id='responseId'></div>";
648                                                 html+="</div>";
649                                                 $( "#gitcommands-dialog" ).dialog({
650                                                         title: "Git Checkout",
651                                                         modal: true,
652                                                         autoOpen: true,
653                                                         width: 430,
654                                                         height: 350,
655                                                         buttons: [
656                                                         {
657                                                                 text: "Close",
658                                                                 click: function() {
659                                                                         $( this ).dialog( "close" );
660                                                                 }
661                                                         }
662                                                         ],
663                                                         close: function(ev,ui){
664                                                                 $(this).dialog("destroy");
665                                                         }
666                                                 }).html(html);
667                                           $("#responseId").css({width:'300',height:'100px', border: '2px solid lightgrey',overflow:'scroll', padding: '20px' });
668                                           $("#responseId").hide();
669                                         $("#gitcommands-dialog").show();
670                                 }
671                                })
672                                 .fail(function(err) {
673                                          RED.notify("Failed to get gitBranch.");
674                                 })
675                                  .always(function() {
676                                 });
677         }
678
679         function  showGitLocalFlows(){
680                 giLocalFlowFiles=[];
681                 var divStyle="<style>#gitlocal-data-container a { color: #067ab4; font-size: 0.75em;} #gitlocal-data-container a:hover { text-decoration: underline; padding: -15px -15px -15px 15px; } .header { height: 40px; border-bottom: 1px solid #EEE; background-color: #ffffff; height: 40px; -webkit-border-top-left-radius: 5px; -webkit-border-top-right-radius: 5px; -moz-border-radius-topleft: 5px; -moz-border-radius-topright: 5px; border-top-left-radius: 5px; border-top-right-radius: 5px; } .footer { height: 40px; background-color: whiteSmoke; border-top: 1px solid #DDD; -webkit-border-bottom-left-radius: 5px; -webkit-border-bottom-right-radius: 5px; -moz-border-radius-bottomleft: 5px; -moz-border-radius-bottomright: 5px; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; }</style>";
682                 $.get( "/getGitLocalFlows")
683                                .done(function( data ) {
684                                         if(data != null && data.files != null && data.files.length == 1){
685                                                 if(data.files[0] == "GIT_LOCAL_REPOSITORY_NOT_SET" ){
686                                                         RED.notify("Git Local Repository path is not set. Please set it by choosing Configuration from the menu.");
687                                                         return;
688                                                 }       
689                                         }
690                                         //console.log("got response from server.");
691                                         
692                                         var header="<div class='header'>List of DG Flows  from  Git Local Repository </div><div><input id='flowFilterBoxId' type='text' onkeyup='filterGitLocalFlows(this.value)'></div>";
693                                         var html=  divStyle + header +  "<div id='gitlocal-data-container'>";
694                                         html+="<ul>";
695                                         if(data != null){
696                                                 var files=data.files;
697                                                 gitLocalFlowFiles=files;
698                                                 //console.dir(files);
699                                                 files.sort(function (a,b){
700                                                         if(a > b){
701                                                                 return 1;
702                                                         }else if(a <  b){
703                                                                 return -1;
704                                                         }else{  
705                                                                 return 0;
706                                                         }
707                                                 });
708                                                 for(var i=0;files != null && i<files.length;i++){
709                                                         html+="<li><a href=\"#\" onclick=\"importGitLocalFlow('" + files[i] + "')\">" + files[i] + "</a></li>";
710                                                 }
711                                         }
712                                         html+="</ul>";
713                                         html+="</div>";
714                                         $( "#gitlocal-browser-dialog" ).dialog({
715                                         title: "Git Local Repository DG Flow Browser",
716                                         modal: true,
717                                         autoOpen: true,
718                                         width: 830,
719                                         height: 630,
720                                         buttons: [
721                                                 {
722                                                         text: "Close",
723                                                         click: function() {
724                                                                 $(this).dialog("close");
725                                                         }
726                                                 }
727                                                 ]
728                                         }).html(html);
729                                         $("#gitlocal-browser-dialog").show();
730                                         /*
731                                         if ($("#gitlocal-browser-dialog").dialog( "isOpen" )===true) {
732                                                 console.log("gitlocal dialog box is open");     
733                                                 //true
734                                         } else {
735                                                 console.log("gitlocal dialog box is not open"); 
736                                         //      $( "#gitlocal-browser-dialog" ).dialog("destroy").remove();
737                                                 console.log($("#gitlocal-browser-dialog").dialog( "widget" ));
738                                                 $("#gitlocal-browser-dialog").dialog( "open" );
739                                                 if ($("#gitlocal-browser-dialog").dialog( "isOpen" )===true) {
740                                                         console.log("gitlocal dialog box is now open"); 
741                                                 }
742                                                 $("#gitlocal-browser-dialog").show();
743                                                 //false
744                                         }
745                                         */
746                                })
747                                 .fail(function(err) {
748                                          RED.notify("Failed to get flows.");
749                                 })
750                                  .always(function() {
751                                         console.log("Done displaying");
752                                 });
753         }
754
755         function  showFlowShareUsers(){
756                 var divStyle="<style>#data-container a { color: #067ab4; font-size: 0.75em;} #data-container a:hover { text-decoration: underline; padding: -15px -15px -15px 15px; } .header { height: 40px; border-bottom: 1px solid #EEE; background-color: #ffffff; height: 40px; -webkit-border-top-left-radius: 5px; -webkit-border-top-right-radius: 5px; -moz-border-radius-topleft: 5px; -moz-border-radius-topright: 5px; border-top-left-radius: 5px; border-top-right-radius: 5px; } .footer { height: 40px; background-color: whiteSmoke; border-top: 1px solid #DDD; -webkit-border-bottom-left-radius: 5px; -webkit-border-bottom-right-radius: 5px; -moz-border-radius-bottomleft: 5px; -moz-border-radius-bottomright: 5px; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; }</style>";
757                 $.get("/flowShareUsers")
758                         .done(function (data){
759                                         
760                                         var header="<div class='header'>List of Downloaded DG Flows</div>";
761                                         var html=  divStyle + header +  "<div id='data-container'>";
762                                         html+="<ul>";
763                                         if(data != null){
764                                                 var users=data.flowShareUsers;
765                                                 users.sort(function (a,b){
766                                                         if(a.name > b.name){
767                                                                 return 1;
768                                                         }else if(a.name <  b.name){
769                                                                 return -1;
770                                                         }else{  
771                                                                 return 0;
772                                                         }
773                                                 });
774                                                 for(var i=0;users != null && i<users.length;i++){
775                                                         html+="<li><a href=\"#\" onclick=\"showFlowFiles('" + users[i].rootDir + "')\">" + users[i].name + "</a></li>";
776                                                 }
777                                         }
778                                         html+="</ul>";
779                                         html+="</div>";
780                                         $( "#dgflow-browser-dialog" ).dialog({
781                                         title: "Downloaded DG Flows Browser",
782                                         modal: true,
783                                         autoOpen: true,
784                                         width: 530,
785                                         height: 530,
786                                         buttons: [
787                                                 {
788                                                         text: "Close",
789                                                         click: function() {
790                                                                 $( this ).dialog( "close" );
791                                                                 //$(this).dialog('destroy').remove();
792                                                         }
793                                                 }
794                                                 ]
795                                         }).html(html);
796                                         $("#dgflow-browser-dialog").show();
797                                         /*
798                                         if ($("#dgflow-browser-dialog").dialog( "isOpen" )===true) {
799                                                 console.log("dgflow dialog box is open");       
800                                                 //true
801                                         } else {
802                                                 console.log("dgflow dialog box is not open");   
803                                                 $("#dgflow-browser-dialog").dialog( "open" );
804                                                 $("#dgflow-browser-dialog").show();
805                                                 //false
806                                         }
807                                         */
808                                })
809                                 .fail(function(err) {
810                                          RED.notify("Failed to get users.");
811                                 })
812                                  .always(function() {
813                                 });
814         }
815
816 /*      function  showFlowShareUsers(){
817                 var divStyle="<style>#data-container a { color: #067ab4; font-size: 0.75em;} #data-container a:hover { text-decoration: underline; padding: -15px -15px -15px 15px; } .header { height: 40px; border-bottom: 1px solid #EEE; background-color: #ffffff; height: 40px; -webkit-border-top-left-radius: 5px; -webkit-border-top-right-radius: 5px; -moz-border-radius-topleft: 5px; -moz-border-radius-topright: 5px; border-top-left-radius: 5px; border-top-right-radius: 5px; } .footer { height: 40px; background-color: whiteSmoke; border-top: 1px solid #DDD; -webkit-border-bottom-left-radius: 5px; -webkit-border-bottom-right-radius: 5px; -moz-border-radius-bottomleft: 5px; -moz-border-radius-bottomright: 5px; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; }</style>";
818                 $.get( "/flowShareUsers")
819                                .done(function( data ) {
820                                         
821                                         var header="<div class='header'>List of Downloaded DG Flows</div>";
822                                         var html=  divStyle + header +  "<div id='data-container'>";
823                                         html+="<ul>";
824                                         if(data != null){
825                                                 var users=data.flowShareUsers;
826                                                 users.sort(function (a,b){
827                                                         if(a.name > b.name){
828                                                                 return 1;
829                                                         }else if(a.name <  b.name){
830                                                                 return -1;
831                                                         }else{  
832                                                                 return 0;
833                                                         }
834                                                 });
835                                                 for(var i=0;users != null && i<users.length;i++){
836                                                         html+="<li><a href=\"#\" onclick=\"showFlowFiles('" + users[i].rootDir + "')\">" + users[i].name + "</a></li>";
837                                                 }
838                                         }
839                                         html+="</ul>";
840                                         html+="</div>";
841                                         $( "#dgflow-browser-dialog" ).dialog({
842                                         title: "Downloaded DG Flows Browser",
843                                         modal: true,
844                                         autoOpen: true,
845                                         width: 530,
846                                         height: 530,
847                                         buttons: [
848                                                 {
849                                                         text: "Close",
850                                                         click: function() {
851                                                                 //$( this ).dialog( "close" );
852                                                                 $(this).dialog('destroy').remove();
853                                                         }
854                                                 }
855                                                 ]
856                                         }).html(html);
857                                         //$("#dgflow-browser-dialog").show();
858                                         $( "#dgflow-browser-dialog" ).dialog( "open" );
859                                })
860                                 .fail(function(err) {
861                                          RED.notify("Failed to get users.");
862                                 })
863                                  .always(function() {
864                                 });
865         }
866         */
867
868
869 function detectLoopInFlow(){
870                 var errList = [];
871                 var activeWorkspace=RED.view.getWorkspace();
872                 var nSet=[];
873                 
874                 RED.nodes.eachNode(function(n) {
875                         if (n.z == activeWorkspace) {
876                                 nSet.push({n:n});
877                         }
878                 });
879
880                 var nodeSet = RED.nodes.createExportableNodeSet(nSet);
881
882                 var isLoopDetected = false;     
883                 var dgStartNode = getDgStartNode(nodeSet);
884                 if(dgStartNode == null || dgStartNode == undefined) {
885                         console.log("dgstart node not linked.");
886                         return null;
887                 }
888
889                 var wires = dgStartNode.wires;
890                 var nodesInPath = {};
891                 var dgStartNodeId = dgStartNode.id;
892                 if(wires != null && wires != undefined && wires[0] != undefined){
893                         for(var k=0;k<wires[0].length;k++){
894                                 var val = wires[0][k];
895                                 nodesInPath[dgStartNodeId + "->" + val] = "";
896                         }
897                 }else{
898                                 nodesInPath[dgStartNodeId + "->" + ""] = "";
899                 }
900                         
901                 var loopDetectedObj = {};
902                 /* the nodes will not be in order so will need to loop thru again */
903         for(var m=0;nodeSet != null && m<nodeSet.length;m++){
904                 for(var i=0;nodeSet != null && i<nodeSet.length;i++){
905                         var link=nodeSet[i].id;
906                         //console.log("NAME:" + nodeSet[i].name + ":" + link);
907                         if(link == dgStartNodeId) continue;
908                         var wires = nodeSet[i].wires;
909                         //console.log("link:" + link);
910                         var delKeys = [];
911                         if(wires != null && wires != undefined && wires[0] != undefined){
912                                 for(var k=0;k<wires[0].length;k++){
913                                         var val = (wires[0])[k];
914                                         var keys = Object.keys(nodesInPath);
915                                         //console.log("keys:" + keys);
916                                         for (var j=0;j<keys.length;j++){
917                                                 //console.log("key:" + keys[j]);
918                                                 //console.log("val:" + val);
919                                                 var index = keys[j].indexOf("->" + link);
920                                                 var lastIndex = keys[j].lastIndexOf("->");
921                                                 if(index != -1 && index == lastIndex){
922                                                         //delete nodesInPath[key];
923                                                         var previousNodeId = keys[j].substr(lastIndex +2);
924                                                         var indexOfArrow = -1;
925                                                         if(previousNodeId != ""){
926                                                                 indexOfArrow = previousNodeId.indexOf("->");
927                                                         }
928                                                         if(previousNodeId != null && indexOfArrow != -1){
929                                                                 previousNodeId = previousNodeId.substr(0,indexOfArrow);
930                                                         }       
931                                                         nodesInPath[keys[j] + "->" + val] = "";
932                                                         //console.log("keys[j]:" + keys[j]);
933                                                         delKeys.push(keys[j]);
934                                                         var prevNodeIdIndex = keys[j].indexOf("->" + previousNodeId);
935                                                         var priorOccurence = keys[j].indexOf(val + "->");
936                                                         if(priorOccurence != -1 && priorOccurence<prevNodeIdIndex){
937                                                                 //console.log("previousNodeId:" + previousNodeId);
938                                                                 //console.log("val:" + val);
939                                                                 var n1 = getNode(nodeSet,previousNodeId);
940                                                                 var n2 = getNode(nodeSet,val);
941                                                                 //console.log("loop detected for node " + n1.name + " and " + n2.name); 
942                                                                 loopDetectedObj[n1.name + "->" + n2.name] ="looped";
943                                                                 console.dir(loopDetectedObj);
944                                                                 errList.push("Loop detected between " + n1.name + " and " + n2.name);
945                                                                 isLoopDetected = true;
946                                                         }               
947                                                 } 
948                                         }
949                                 }
950                         }
951                         for(var l=0;delKeys != null && l<delKeys.length;l++){
952                                 delete nodesInPath[delKeys[l]];
953                         }
954                 }
955
956
957         }       
958         /*
959         if(loopDetectedObj != null ){ 
960                 var msg = "";
961                 for(var key in loopDetectedObj){
962                         if(loopDetectedObj.hasOwnProperty(key)) {
963                                 console.log("Loop detected  " + key);
964                                 msg += "<strong>Loop detected for:" + key + "</strong><br>";
965                         }
966                 }
967                 if(msg != ""){
968                         isLoopDetected = true;
969                         //RED.notify(msg);
970                 }
971         }       
972         */
973         //images/page-loading.gif
974                 return errList;
975 }
976
977 function showLoopDetectionBox(){
978         $(function() {
979         var htmlStr="<div id='loop-box-div' style='width:375;height:225'><p>Loop detection in Progress ...</p><img src='images/page-loading.gif'></div>"
980         $("#loop-detection-dialog").dialog({
981                 modal:true,     
982                 autoOpen :true,
983                 title: "DG Flow Loop Detection",
984                 width: 400,
985                 height: 250,
986                 minWidth : 400, 
987                 minHeight :200, 
988                 }).html(htmlStr);
989                 if($("#loop-detection-dialog").dialog("isOpen") == true){
990                         var errList = detectLoopInFlow();
991                         var errList=[];
992                         if(errList == null){
993                                 $("#loop-detection-dialog").dialog("close");
994                         }
995                         var msgHtml = "";
996                         for(var i=0;errList != null && i<errList.length;i++){
997                                 msgHtml += "<p>" + errList[i] + "</p>";
998                         }
999                         if(msgHtml == ""){
1000                                 $("loop-box-div").html("<p>SUCCESS. No Loop detected.</p>");
1001                         }else{
1002                                 $("loop-box-div").html(msgHtml);
1003                         }
1004                 }
1005         });
1006         
1007 }
1008
1009 function showSelectedTabs(){
1010         var tabSheets = [];
1011         var beforeTabsOrder=[];
1012         $(".red-ui-tabs li a").each(function(i){
1013                 var id=$(this).attr("href").replace('#','');
1014                 var title=$(this).attr("title");
1015                 var isVisible = $(this).parent().is(":visible"); 
1016                 if(title != 'info'){
1017                         tabSheets.push({"id" : id ,"title":title,"module":"NOT_SET","version" : "NOT_SET","rpc":"NOT_SET","isVisible":isVisible});
1018                         beforeTabsOrder.push(id);
1019                 }
1020         });
1021
1022         RED.nodes.eachNode(function(n) {
1023                 if(n.type == 'service-logic'){
1024                         var id = n.z;
1025                         var module = n.module;
1026                         tabSheets.forEach(function(tab){
1027                                 if(tab.id == id){
1028                                         tab.module=module;
1029                                         tab.version=n.version;
1030                                 }       
1031                         });
1032                 }else if(n.type == 'method'){
1033                         var id = n.z;
1034                         tabSheets.forEach(function(tab){
1035                                 if(tab.id == id){
1036                                         var rpc=getAttributeValue(n.xml,"rpc");
1037                                         tab.rpc=rpc;
1038                                 }       
1039                         });
1040                 }
1041         });
1042         //console.dir(tabSheets);
1043         var htmlStr = getHtmlStr(tabSheets);
1044         $("#filter-tabs-dialog").dialog({
1045                 modal:true,     
1046                 title: "DG Builder Tabs",
1047                 width: 1200,
1048                 height: 750,
1049                 minWidth : 600, 
1050                 minHeight :450, 
1051                 }).html(htmlStr);
1052 /* This code allows for the drag-drop of the rows in the table */
1053         var fixHelperModified = function(e, tr) {
1054                 var $originals = tr.children();
1055                 var $helper = tr.clone();
1056                 $helper.children().each(function(index) {
1057                 $(this).width($originals.eq(index).width())
1058         });
1059         return $helper;
1060         },
1061         updateIndex = function(e, ui) {
1062                 var afterTabsOrder=[];
1063                 $('td.index', ui.item.parent()).each(function (i) {
1064                         $(this).html(i + 1);
1065                 });
1066                 //RE-ARRANGE the tabs
1067                 var ul = $("#workspace-tabs");
1068                 $("#ftab02 tr td:nth-child(1)").each(function(i){
1069                         var idStr = $(this).prop("id").replace("tab-td_","");
1070                         afterTabsOrder.push(idStr);
1071                         link = ul.find("a[href='#"+ idStr+"']");
1072                         li = link.parent();
1073                         //li.remove();
1074                         firstTab = $("#workspace-tabs li:first-child");
1075                         lastTab = $("#workspace-tabs li:last-child");
1076                         li.insertAfter(lastTab);
1077                         //console.log( idStr);
1078                 });
1079                 var beforeTabsStr = beforeTabsOrder.join(",");
1080                 var afterTabsStr = afterTabsOrder.join(",");
1081                 //console.log("beforeTabsStr:" +beforeTabsStr);
1082                 //console.log("afterTabsStr:" +afterTabsStr);
1083                 if(beforeTabsStr !== afterTabsStr){
1084                         //activate only when order has changed
1085                         //activate the deploy button
1086                         RED.view.dirty(true);
1087                         $("#btn-deploy").removeClass("disabled");
1088                 }
1089         };
1090
1091         $("#ftab02 tbody").sortable({
1092         helper: fixHelperModified,
1093         stop: updateIndex
1094         }).disableSelection();
1095
1096 }
1097
1098 function getHtmlStr(rows){
1099         var styleStr = "<style> " + 
1100                         "table#ftab02 { width:100%; } \n" +
1101                                 "table#ftab02 th,table#ftab02 td { border: 1px solid black; border-collapse: collapse; } \n" +
1102                                 /*"table, th, td { border: 1px solid #65a9d7; border-collapse: collapse; } \n" +*/
1103                                 "table#ftab02 th,table#ftab02 td { padding: 5px; text-align: left; } \n" +
1104                                 "table#ftab02 tr:nth-child(even) { background-color: #eee; }\n" +
1105                                 "table#ftab02 tr:nth-child(odd) { background-color:#fff; }\n" +
1106                                 "table#ftab02 th        { background-color: #65a9d7; color: white; }\n" +
1107                                 "table#ftab02 a { color: #337ab7; }\n" +
1108                                 "table#ftab02 a:link { color: #65a9d7; }\n" +
1109                                 "table#ftab02 a:visited { color: #636; }\n" + 
1110                                 "table#ftab02 a:hover { color: #3366CC; cursor: pointer }\n" + 
1111                                 "table#ftab02 a:active { color: #65a9d7 }\n" +
1112                                 "</style>";
1113                         if(rows != null && rows != undefined){
1114                                 //var alertDialog = '<div id="confdialog"></div>';
1115                                 //htmlStr= alertDialog +  "<div style='width:1050;height:650'>" + styleStr;
1116                                 var alertDialog = '<div id="tabAlertDialog"></div>';
1117                                 htmlStr= alertDialog +  "<div id='tabs-div' style='width:1050;height:650'>" + styleStr;
1118                                 htmlStr += "<table id='ftab02' >";
1119                                 htmlStr += "<tr>";
1120                                 htmlStr += "<th class='index'>No.</th>" ;
1121                                 htmlStr += "<th>Tab Title</th>" ;
1122                                 htmlStr += "<th>Module</th>" ;
1123                                 htmlStr += "<th>RPC</th>" ;
1124                                 htmlStr += "<th>Version</th>" ;
1125                                 htmlStr += "<th>Rename</th>" ;
1126                                 htmlStr += "<th>Delete</th>" ;
1127                                 htmlStr += "</tr>";
1128                                 htmlStr += "<tbody>";
1129                                 if(rows != null && rows.length == 0){
1130                                         htmlStr += "<tr>";
1131                                         htmlStr += "<td><b>No rows found</b></td>";
1132                                         htmlStr += "</tr></table></div>";
1133                                         return htmlStr;
1134                                 }
1135                                 for(var i=0;i<rows.length;i++){
1136                                         var row = rows[i];
1137                                         var title = row.title;
1138                                         var _module = row.module;
1139                                         var version = row.version;
1140                                         var rpc = row.rpc;
1141                                         var idVal = row.id;
1142                                         var isVisible = row.isVisible;
1143                                         htmlStr += "<tr id='tab-tr_" + idVal + "'>";
1144                                         //htmlStr += "<td id=" + "'tab-td_" + idVal  + "' ><a href='javascript:activateClickedTab(\"" + idVal + "\")'>" + (i+1) + "</a></td>";
1145                                         htmlStr += "<td class='index' id=" + "'tab-td_" + idVal  + "' >" + (i+1) + "</td>";
1146                                         htmlStr += "<td><a href='javascript:activateClickedTab(\"" + idVal + "\")'>" + title + "</a></td>";
1147                                         htmlStr += "<td>" + _module + "</td>";
1148                                         htmlStr += "<td>" + rpc + "</td>";
1149                                         htmlStr += "<td>" + version + "</td>";
1150                                         //htmlStr += "<td><a href='javascript:deleteOrRenameTab(\"" + idVal + "\")'>Delete/Rename</a></td>";
1151                                         htmlStr += "<td><input type='button' onclick='renameSelectedTab(\"" + idVal + "\",\"" + title + "\",\"" +  _module + "\",\"" + rpc + "\",\"" + version + "\")' value='Rename'></td>";
1152                                         if(rows.length == 1){
1153                                                 htmlStr += "<td><input type='button' disabled='1' onclick='deleteSelectedTab(\"" + idVal + "\",\"" + title + "\",\"" +  _module + "\",\"" + rpc + "\",\"" + version + "\")' value='Delete'></td>";
1154                                         }else{
1155                                                 htmlStr += "<td><input type='button'  onclick='deleteSelectedTab(\"" + idVal + "\",\"" + title + "\",\"" +  _module + "\",\"" + rpc + "\",\"" + version + "\")' value='Delete'></td>";
1156                                         }
1157                                         /*
1158                                         if(isVisible){
1159                                                 htmlStr += "<td><input type='checkbox' onclick=\"showOrHideTab(this,'" + idVal + "')\" checked='true'></td>";
1160                                         }else{
1161                                                 htmlStr += "<td><input type='checkbox' onclick=\"showOrHideTab(this,'" + idVal + "')\"></td>";
1162                                         }
1163                                         */
1164                                         htmlStr += "</tr>";
1165                                 }
1166                                 htmlStr += "</tbody>";
1167                                 htmlStr += "</table>";
1168                                 htmlStr += "</div>";
1169                         }
1170         return htmlStr;
1171 }
1172 /*
1173 Added this logic because , when the configuration item is choosen in the menu the other dialog boxes were not poping up
1174 */
1175 (function(){
1176         //var msecs1= Date.now();
1177                 $( "#gitlocal-browser-dialog" ).dialog();
1178                 $( "#gitlocal-browser-dialog" ).dialog("close");
1179                 $( "#dgflow-browser-dialog" ).dialog();
1180                 $( "#dgflow-browser-dialog" ).dialog("close");
1181                 $( "#update-password-dialog" ).dialog();
1182                 $( "#update-password-dialog" ).dialog("close");
1183                 $( "#codecloud-browser-dialog" ).dialog();
1184                 $( "#codecloud-browser-dialog" ).dialog("close");
1185                 $( "#update-configuration-dialog" ).dialog();
1186                 $( "#update-configuration-dialog" ).dialog("close");
1187                 $( "#gitcommands-dialog" ).dialog();
1188                 $( "#gitcommands-dialog" ).dialog("close");
1189                 $("#filter-tabs-dialog").dialog();
1190                 $("#filter-tabs-dialog").dialog("close");
1191                 $("#loop-detection-dialog").dialog();
1192                 $("#loop-detection-dialog").dialog("close");
1193                 $("#dgstart-generate-xml-dialog").dialog();
1194                 $("#dgstart-generate-xml-dialog").dialog("close");
1195                 $("#xmldialog").dialog();
1196                 $("#xmldialog").dialog("close");
1197                 $("#upload-xml-status-dialog").dialog();
1198                 $("#upload-xml-status-dialog").dialog("close");
1199                 $("#flow-design-err-dialog").dialog();
1200                 $("#flow-design-err-dialog").dialog("close");
1201                 $("#sli-values-dialog").dialog();
1202                 $("#sli-values-dialog").dialog("close");
1203                 $("#comments-dialog").dialog();
1204                 $("#comments-dialog").dialog("close");
1205                 $("#show-errors-dialog").dialog();
1206                 $("#show-errors-dialog").dialog("close");
1207                 $("#dgnumber-find-dialog").dialog();
1208                 $("#dgnumber-find-dialog").dialog("close");
1209                 $("#search-text-dialog").dialog();
1210                 $("#search-text-dialog").dialog("close");
1211                 $("#yang-upload-dialog").dialog();
1212                 $("#yang-upload-dialog").dialog("close");
1213                 $("#yang-modules-browser-dialog").dialog();
1214                 $("#yang-modules-browser-dialog").dialog("close");
1215                 $("#list-yang-browser-dialog").dialog();
1216                 $("#list-yang-browser-dialog").dialog("close");
1217                 $("#request-input-dialog").dialog();
1218                 $("#request-input-dialog").dialog("close");
1219                 //var msecs2= Date.now();
1220                 //console.log("Time taken for dialog boxes:" + (msecs2 - msecs1));
1221 })();
1222
1223         function updateConfiguration(){
1224                 //console.log("in updateConfiguration");
1225                 $.get("/getCurrentSettings",function (data){
1226                 var dbHost = data.dbHost;
1227                 var dbPort = data.dbPort;
1228                 var dbName = data.dbName;
1229                 var dbUser = data.dbUser;
1230                 var dbPassword = data.dbPassword;
1231                 var gitLocalRepository = data.gitLocalRepository;
1232                 var performGitPull = data.performGitPull;
1233
1234                 if(dbHost == undefined) dbHost="";
1235                 if(dbPort == undefined) dbPort="";
1236                 if(dbName == undefined) dbName="";
1237                 if(dbUser == undefined) dbUser="";
1238                 if(dbPassword == undefined) dbPassword="";
1239                 if(gitLocalRepository == undefined) gitLocalRepository="";
1240                 if(performGitPull  == undefined || performGitPull == null) performGitPull="N";
1241
1242                 var divStyle="border: 1px solid #a1a1a1; padding: 10px 40px; background: #dddddd; width: 500px; border-radius: 25px;";
1243                 //var divStyle="border: 2px solid #a1a1a1; padding: 10px 40px; background: #99CCFF; width: 400px; border-radius: 25px;";
1244         
1245
1246                    var  html = "<div>";
1247                         html += "<script>function changeType(obj,targetId){if( obj.checked== true){$('#' + targetId).prop('type','password');}else{$('#'+ targetId).prop('type','text');}} function changeTitle(){ document.getElementById(\"gitLocalRepository\").title=document.getElementById(\"gitLocalRepository\").value;}</script>";
1248                         html += "<div style='" + divStyle + "' >";
1249                         html += "<table border='0' cellpadding='5' >";
1250                         html += "<tr>";
1251                         html += "<td style='font-size:12px;align:center'><b>DB Host IP</b></td>";
1252                         html += "<td><input  style='align:center;font-size:11px;font-weight:bold' id='dbhost' name='dbhost' type='text' value='" + dbHost + "'></td>";
1253                         html += "</tr>";
1254                         html += "<tr>";
1255                         html += "<td style='font-size:12px;align:center'><b>DB Port</b></td>";
1256                         html += "<td><input style='align:center;font-size:11px;font-weight:bold' id='dbport' name='dbport' type='text' value='" + dbPort + "'></td>";
1257                         html += "</tr>";
1258                         html += "<tr>";
1259                         html += "<td style='font-size:12px;align:center'><b>DB Name</b></td>";
1260                         html += "<td><input style='align:center;font-size:11px;font-weight:bold' id='dbname' name='dbname' type='text' value='" + dbName + "'></td>";
1261                         html += "</tr>";
1262                         html += "<tr>";
1263                         html += "<td style='font-size:12px;align:center'><b>DB UserName</b></td>";
1264                         html += "<td><input style='align:center;font-size:11px;font-weight:bold' id='dbuser' name='dbuser' type='password' value='" + dbUser + "'></td>";
1265                         html += "<td><input style='background:background:white;width:20px;height:20px' type='checkbox' checked value='1' onclick=\"changeType(this,'dbuser')\">Hide</td>";
1266                         html += "</tr>";
1267                         html += "<tr>";
1268                         html += "<td style='font-size:12px;align:center'><b>DB Password</b></td>";
1269                         html += "<td><input style='align:center;font-size:11px;font-weight:bold' id='dbpassword' name='dbpassword' type='password' value='" + dbPassword + "'></td>";
1270                         html += "<td><input style='background:background:white;width:20px;height:20px' type='checkbox' checked value='1' onclick=\"changeType(this,'dbpassword')\">Hide</td>";
1271                         html += "</tr>";
1272                         html += "</table>";
1273                         html += "</div>";
1274                         html += "<div style='fill:both;clear:both'></div><br>";
1275         
1276                         html += "<div style='" + divStyle + "' >";
1277                         html += "<table border='0' cellpadding='5' >";
1278                         html += "<tr>";
1279                         html += "<td style='font-size:12px;align:center'><b>Git Local Repository Path</b></td>";
1280                         html += "<td><textarea style='align:center;font-size:14px;' cols='50' rows='4' id='gitLocalRepository' name='gitLocalRepository' onkeyup='changeTitle()' title='" + gitLocalRepository + "'>" + gitLocalRepository + "</textarea></td>";
1281                         html += "</tr>";
1282                         html += "</table>";
1283                         html += "<table border='0' cellpadding='5' >";
1284                         html += "<tr>";
1285                         if(performGitPull == "N"){
1286                                 html += "<td style='align:center;'><input style='color:blue;width:20px;height:20px;' id='performGitPull' type='checkbox' value='Y'>Perform Git Pull in Local Git Repository prior to import</td>";
1287                         }else{
1288                                 html += "<td style='align:center;'><input style='color:blue;width:20px;height:20px;' id='performGitPull' type='checkbox' value='Y' checked>Perform Git Pull in Local Git Repository prior to import</td>";
1289                         }
1290                         html += "</tr>";
1291                         html += "</table>";
1292                         html += "</div>";
1293                         html += "</div>";
1294                         //console.log("html:" + html);
1295                 $( "#update-configuration-dialog" ).dialog({
1296                         title: "Configuration",
1297                         modal: true,
1298                         autoOpen: true,
1299                         width: 630,
1300                         height: 630,
1301                         buttons: [
1302                                 {
1303                                 text: "Save",
1304                                 click: function() {
1305                                         var newDBHost = $("#dbhost").val().trim();
1306                                         var newDBPort = $("#dbport").val().trim();
1307                                         var newDBName = $("#dbname").val().trim();
1308                                         var newDBUser = $("#dbuser").val().trim();
1309                                         var newDBPassword = $("#dbpassword").val().trim();
1310                                         var newGitLocalRepository = $("#gitLocalRepository").val().trim();
1311                                         var isPerformGitPullChecked = $('#performGitPull').is(':checked');
1312                                         var newPerformGitPull = "N";
1313                                         if(isPerformGitPullChecked){
1314                                                 newPerformGitPull = "Y";
1315                                         }
1316                                         if(newDBHost == ""){
1317                                                 RED.notify("Error: DB Host is required.");              
1318                                                 $("#dbhost").focus();
1319                                                 return;
1320                                         }else if(newDBPort == ""){
1321                                                 RED.notify("Error: DB Port is required.");              
1322                                                 $("#dbport").focus();
1323                                                 return;
1324                                         }else if(newDBName == ""){
1325                                                 RED.notify("Error: DB Name is required.");              
1326                                                 $("#dbname").focus();
1327                                                 return;
1328                                         }else if(newDBUser == ""){
1329                                                 RED.notify("Error: DB User is required.");              
1330                                                 $("#dbuser").focus();
1331                                                 return;
1332                                         }else if(newDBPassword == ""){
1333                                                 RED.notify("Error: DB Password is required.");          
1334                                                 $("#dbpassword").focus();
1335                                                 return;
1336                                         }else{ 
1337                                                 console.log("newGitLocalRepository:" + newGitLocalRepository);
1338                                                 var reqData= {"dbHost":newDBHost,
1339                                                                 "dbPort" : newDBPort,
1340                                                                 "dbName" : newDBName,
1341                                                                 "dbUser" : newDBUser,
1342                                                                 "dbPassword" : newDBPassword,
1343                                                                 "gitLocalRepository" : newGitLocalRepository, 
1344                                                                 "performGitPull" : newPerformGitPull 
1345                                                              };
1346                                                  $.post( "/updateConfiguration",reqData )
1347                                                 .done(function( data ) {
1348                                                         RED.notify("Configuration updated successfully"); 
1349                                                         //loadSettings();
1350                                                         //RED.comms.connect();
1351                                                         //$( "#update-configuration-dialog" ).dialog('close');
1352                                                         $("#update-configuration-dialog").dialog("close");
1353                                                         //location.reload();
1354                                                                 
1355                                                 })
1356                                                 .fail(function(err) {
1357                                                         console.log( "error" + err );
1358                                                         RED.notify("Failed to update the Configuration.");
1359                                                 })
1360                                                 .always(function() {
1361                                                 });
1362                                         }
1363                                    }
1364                                 },
1365                                 {
1366                                         text: "Cancel",
1367                                         click: function() {
1368                                                 $( this ).dialog( "close" );
1369                                         }
1370                                 }
1371                         ]
1372                 }).html(html);
1373                 //$("#update-configuration-dialog").show();
1374                 $("#gitLocalRepository").css({"width" : 300});
1375
1376                 });
1377         }
1378
1379         function updatePassword(){
1380                 var html="<div>";
1381                         html += "<div><span><b>New Password</b></span><br>";
1382                         html += "<input id='passwd1' name='passwd1' type='password' value=''>";
1383                         html += "</div>";
1384                         html += "<div><span><b>Confirm Password</b></span><br>";
1385                         html += "<input id='passwd2' name='passwd2' type='password' value=''>";
1386                         html += "</div>";
1387                 $( "#update-password-dialog" ).dialog({
1388                         title: "Update Password",
1389                         modal: true,
1390                         autoOpen: true,
1391                         width: 530,
1392                         height: 230,
1393                         buttons: [
1394                                 {
1395                                 text: "Update Password",
1396                                 click: function() {
1397                                         var passwd1 = $("#passwd1").val().trim();
1398                                         var passwd2 = $("#passwd2").val().trim();
1399                                         if((passwd1 != passwd2) || (passwd1 == "" || passwd2 == "")){
1400                                                 RED.notify("Error:Passwords entered must be same and must be populated.");              
1401                                                 return;
1402                                         }else{ 
1403                                                 var reqData= {"password":passwd1};
1404                                                  $.post( "/updatePassword",reqData )
1405                                                 .done(function( data ) {
1406                                                         RED.notify("Password updated successfully"); 
1407                                                         //loadSettings();
1408                                                         $( "#update-password-dialog" ).dialog('close');
1409                                                 })
1410                                                 .fail(function(err) {
1411                                                         console.log( "error" + err );
1412                                                         RED.notify("Failed to update the password.");
1413                                                 })
1414                                                 .always(function() {
1415                                                 });
1416                                         }
1417                                    }
1418                                 },
1419                                 {
1420                                         text: "Cancel",
1421                                         click: function() {
1422                                                 $( this ).dialog( "close" );
1423                                         }
1424                                 }
1425                         ]
1426                 }).html(html);
1427                 $("#update-password-dialog").show();
1428
1429         }
1430
1431         function  showAvailableYangModules(){
1432                 availableYangModules=[];
1433                 var divStyle="<style>#yang-modules-data-container a { color: #067ab4; font-size: 0.75em;} #yang-modules-data-container a:hover { text-decoration: underline; padding: -15px -15px -15px 15px; } .header { height: 40px; border-bottom: 1px solid #EEE; background-color: #ffffff; height: 40px; -webkit-border-top-left-radius: 5px; -webkit-border-top-right-radius: 5px; -moz-border-radius-topleft: 5px; -moz-border-radius-topright: 5px; border-top-left-radius: 5px; border-top-right-radius: 5px; } .footer { height: 40px; background-color: whiteSmoke; border-top: 1px solid #DDD; -webkit-border-bottom-left-radius: 5px; -webkit-border-bottom-right-radius: 5px; -moz-border-radius-bottomleft: 5px; -moz-border-radius-bottomright: 5px; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; } table#yang-list-table { width:100%; } table#yang-list-table th,table#yang-list-table td { border: 1px solid black; border-collapse: collapse; } table#yang-list-table th,table#yang-list-table td { padding: 5px; text-align: left; } table#yang-list-table tr:nth-child(even) { background-color: #eee; } table#yang-list-table tr:nth-child(odd) { background-color:#fff; } table#yang-list-table th        { background-color: #65a9d7; color: white; } table#yang-list-table a { color: #337ab7; } table#yang-list-table a:link { color: #65a9d7; } table#yang-list-table a:visited { color: #636; } table#yang-list-table a:hover { color: #3366CC; cursor: pointer } table#yang-list-table a:active { color: #65a9d7 }</style>";
1434                 $.get( "/listAvailableModules")
1435                                .done(function( data ) {
1436                                         var header="<div class='header'>List of Available Yang Modules</div>";
1437                                         header += "<div><p><i>Check the modules that you want to load and click on the Load button.</i></p></div>";     
1438                                         //header += "<div><input id='yangModuleFilterBoxId' type='text' onkeyup='filterYangModules(this.value)'></div>";
1439                                         var html=  divStyle + header +  "<div id='yang-modules-data-container'>";
1440                                         html+="<table id='yang-list-table'  border=1>";
1441                                         html+="<tr>";
1442                                         html+="<th>#</th>";
1443                                         html+="<th>Load</th>";
1444                                         html+="<th>Module</th>";
1445                                         html+="</tr>";
1446                                         if(data != null){
1447                                                 var files=data.files;
1448                                                 availableYangModules=files;
1449                                                 //console.dir(files);
1450                                                 files.sort(function (a,b){
1451                                                         if(a > b){
1452                                                                 return 1;
1453                                                         }else if(a <  b){
1454                                                                 return -1;
1455                                                         }else{  
1456                                                                 return 0;
1457                                                         }
1458                                                 });
1459                                                 var count=1;
1460                                                 for(var i=0;files != null && i<files.length;i++){
1461                                                         var val = files[i].replace(/:.*/,"");
1462                                                         if(files[i].indexOf(":checked") != -1){
1463                                                                 html+="<tr><td>" + count + "</td><td><input type='checkbox' checked value='" + val + "'></td><td>" + val + "</td></tr>";
1464                                                         }else{
1465                                                                 html+="<tr><td>" + count + "</td><td><input type='checkbox' value='" + val + "'></td><td>" + val + "</td></tr>";
1466                                                         }
1467                                                         count++;
1468                                                 }
1469                                         }
1470                                         html+="</table>";
1471                                         html+="</div>";
1472                                         $( "#yang-modules-browser-dialog" ).dialog({
1473                                         title: "Available Yang Modules",
1474                                         modal: true,
1475                                         autoOpen: true,
1476                                         width: 830,
1477                                         height: 630,
1478                                         buttons: [
1479                                                 {
1480                                                         text: "Load",
1481                                                         click: function() {
1482                                                                 var allVals = [];
1483                                                                 function getValuesForSelected() {         
1484                                                                         $('#yang-modules-data-container :checked').each(function() {
1485                                                                                 allVals.push($(this).val());
1486                                                                         });
1487                                                                         return allVals;
1488                                                                 }
1489                                                                 var selectedModules = getValuesForSelected().toString();
1490                                                                 console.log(selectedModules);
1491                                                                 $.ajax({
1492                                                                         type: 'GET',
1493                                                                         /*contentType: "application/x-www-form-urlencoded",*/
1494                                                                         url: '/loadSelectedModules?selectedModules=' + selectedModules,
1495                                                                         success: function(data) {
1496                                                                                 RED.notify("Modules Loaded successfully"); 
1497                                                                                 //emptying existing g;obal variables
1498                                                                                 sliValuesObj = {};
1499                                                                                 rpcValues = {};
1500                                                                                 reqInputValues = {};
1501
1502                                                                                 if(data != undefined && data != null){
1503                                                                                         for(var i=0;i<data.sliValuesObj.length;i++){
1504                                                                                                 var moduleName = data.sliValuesObj[i].moduleName;
1505                                                                                                 sliValuesObj[moduleName] = data.sliValuesObj[i][moduleName + '_PROPS'];
1506                                                                                                 rpcValues[moduleName] = data.sliValuesObj[i][ moduleName +'_RPCS'];
1507                                                                                                 for(var k=0;rpcValues[moduleName] != undefined && k<rpcValues[moduleName].length;k++){
1508                                                                                                         var rpcName = rpcValues[moduleName][k];
1509                                                                                                         reqInputValues[moduleName + "_" + rpcName] = data.sliValuesObj[i][rpcName +"-input"];
1510                                                                                                         //console.dir(reqInputValues);
1511                                                                                                 }
1512                                                                                         }
1513                                                                                 }
1514                                                                                 $( "#yang-modules-browser-dialog" ).dialog('close');
1515                                                                                 console.log('success');
1516                                                                                 //console.log(JSON.stringify(data));                               
1517                                                                         },
1518                                                                         error: function(error) {
1519                                                                                 RED.notify("Failed to load modules.");
1520                                                                                 console.log("some error in fetching the notifications");
1521                                                                         }
1522                                                                 });     
1523                                                         }
1524                                                 },
1525                                                 {
1526                                                         text: "Close",
1527                                                         click: function() {
1528                                                                 $(this).dialog("close");
1529                                                         }
1530                                                 }
1531                                                 ]
1532                                         }).html(html);
1533                                         $("#yang-modules-browser-dialog").show();
1534                                })
1535                                 .fail(function(err) {
1536                                          RED.notify("Failed to get yang modules.");
1537                                 })
1538                                  .always(function() {
1539                                         console.log("Done displaying");
1540                                 });
1541         }
1542
1543
1544     $(function() {
1545         RED.menu.init({id:"btn-sidemenu",
1546             options: [
1547                 {id:"btn-sidebar",icon:"fa fa-columns",label:"Sidebar   (Ctrl+Space)",toggle:true,onselect:RED.sidebar.toggleSidebar},
1548                 null,
1549                 {id:"btn-manage-yang-modules-menu",icon:"fa fa-sign-in",label:"Manage Yang Modules",options:[
1550                     {id:"btn-yang-upload",icon:"fa fa-clipboard",label:"Upload Yang File",onselect:RED.view.showYangUploadDialog},
1551                     {id:"btn-available-yang-modules",icon:"fa fa-clipboard",label:"Available Yang Modules",onselect:showAvailableYangModules},
1552                     {id:"btn-list-yang-files",icon:"fa fa-clipboard",label:"List Yang Files",onselect:listYangFiles},
1553                 ]},
1554                 null,
1555                 {id:"btn-configure-upload",icon:"fa fa-book",label:"Configuration",toggle:false,onselect:updateConfiguration},
1556                 null,
1557                 {id:"btn-manage-tabs",icon:"fa fa-info",label:"Manage Tabs",toggle:false,onselect:showSelectedTabs},
1558                 null,
1559                 {id:"btn-search-text",icon:"fa fa-info",label:"Search Text (Ctrl+[)",toggle:false,onselect:RED.view.showSearchTextDialog},
1560                 null,
1561                 {id:"btn-find-dgnumber",icon:"fa fa-info",label:"Find Node (Ctrl+B)",toggle:false,onselect:RED.view.showDgNumberDialog},
1562                 null,
1563                 {id:"btn-request-input",icon:"fa fa-info",label:"RPC Input (Ctrl+O)",toggle:false,onselect:RED.view.showRequestTemplateDialog},
1564                 null,
1565                 {id:"btn-node-status",icon:"fa fa-info",label:"Node Status",toggle:true,onselect:toggleStatus},
1566                 null,
1567                 {id:"btn-node-dgnumber",icon:"fa fa-info",label:"Show Node Numbers",toggle:true,onselect:toggleDgNumberDisplay},
1568                 null,
1569                 {id:"btn-node-panel",icon:"fa fa-columns",label:"Node Palette (Ctrl+M)",toggle:true,onselect:toggleNodePaletteDisplay},
1570                 null,
1571                 {id:"btn-node-viewdgs",icon:"fa fa-info",label:"View All DG List",toggle:false,onselect:displayAllDGs},
1572                 null,
1573                 /*
1574                 {id:"btn-node-gitmenu",icon:"fa fa-info",label:"Git Commands",options: [
1575                     {id:"btn-node-gitcheckout",icon:"fa fa-info",label:"Git Checkout",onselect:showGitCheckoutDialog},
1576                     {id:"btn-node-gitpull",icon:"fa fa-info",label:"Git Pull",onselect:showGitPullDialog},
1577                     {id:"btn-node-gitstatus",icon:"fa fa-info",label:"Git Status",onselect:showGitStatusDialog}
1578                 ]},
1579                 null,
1580                 */
1581                 {id:"btn-import-menu",icon:"fa fa-sign-in",label:"Import...",options:[
1582                     /*{id:"btn-import-codecloud",icon:"fa fa-clipboard",label:"Code Cloud",onselect:showCodeCloudFlows},
1583                         */
1584                     {id:"btn-import-codecloud",icon:"fa fa-clipboard",label:"Git Local Repository",onselect:showGitLocalFlows},
1585                     {id:"btn-import-userflows",icon:"fa fa-clipboard",label:"Downloaded DG Flows...",onselect:showFlowShareUsers},
1586                     {id:"btn-import-clipboard",icon:"fa fa-clipboard",label:"Clipboard...",onselect:RED.view.showImportNodesDialog},
1587                     {id:"btn-import-library",icon:"fa fa-book",label:"Library",options:[]}
1588                 ]},
1589                 {id:"btn-export-menu",icon:"fa fa-sign-out",label:"Export...",disabled:true,options:[
1590                     {id:"btn-export-clipboard",icon:"fa fa-clipboard",label:"Clipboard...",disabled:true,onselect:RED.view.showExportNodesDialog},
1591                     {id:"btn-export-library",icon:"fa fa-book",label:"Library...",disabled:true,onselect:RED.view.showExportNodesLibraryDialog}
1592                 ]},
1593                 null,
1594                 {id:"btn-change-password",icon:"fa fa-columns",label:"Change Password",toggle:false,onselect:updatePassword},
1595                 null,
1596                 /*{id:"btn-config-nodes",icon:"fa fa-th-list",label:"Configuration nodes...",onselect:RED.sidebar.config.show},
1597                 null,*/
1598                 {id:"btn-workspace-menu",icon:"fa fa-th-large",label:"Workspaces",options:[
1599                     {id:"btn-workspace-add",icon:"fa fa-plus",label:"Add"},
1600                     {id:"btn-workspace-edit",icon:"fa fa-pencil",label:"Rename"},
1601                     {id:"btn-workspace-delete",icon:"fa fa-minus",label:"Delete"},
1602                     null
1603                 ]},
1604                 null,
1605                 {id:"btn-keyboard-shortcuts",icon:"fa fa-keyboard-o",label:"Keyboard Shortcuts",onselect:showHelp}
1606                 /*{id:"btn-help",icon:"fa fa-question",label:"Help...", href:"http://nodered.org/docs"}*/
1607             ]
1608         });
1609
1610         //Making default loop detection on and display check mark in the menu
1611         //$("#btn-loop-detection").addClass("active");
1612
1613         RED.keyboard.add(/* ? */ 191,{shift:true},function(){showHelp();d3.event.preventDefault();});
1614         loadSettings();
1615         RED.comms.connect();
1616     });
1617
1618     return {
1619     };
1620 })();