2017-09-20 23:51:28 +02:00
/ * *
* Copyright JS Foundation and other contributors , http : //js.foundation
*
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
* * /
RED . projects . settings = ( function ( ) {
var trayWidth = 700 ;
var settingsVisible = false ;
var panes = [ ] ;
function addPane ( options ) {
panes . push ( options ) ;
}
// TODO: DRY - tab-info.js
function addTargetToExternalLinks ( el ) {
$ ( el ) . find ( "a" ) . each ( function ( el ) {
var href = $ ( this ) . attr ( 'href' ) ;
if ( /^https?:/ . test ( href ) ) {
$ ( this ) . attr ( 'target' , '_blank' ) ;
}
} ) ;
return el ;
}
function show ( initialTab ) {
if ( settingsVisible ) {
return ;
}
settingsVisible = true ;
var tabContainer ;
var trayOptions = {
2017-09-21 12:19:24 +02:00
title : "Project Information" , // RED._("menu.label.userSettings"),, // TODO: nls
2017-09-20 23:51:28 +02:00
buttons : [
{
id : "node-dialog-ok" ,
text : RED . _ ( "common.label.close" ) ,
class : "primary" ,
click : function ( ) {
RED . tray . close ( ) ;
}
}
] ,
resize : function ( dimensions ) {
trayWidth = dimensions . width ;
} ,
open : function ( tray ) {
var project = RED . projects . getActiveProject ( ) ;
2017-12-04 12:42:44 +01:00
2017-09-20 23:51:28 +02:00
var trayBody = tray . find ( '.editor-tray-body' ) ;
var settingsContent = $ ( '<div></div>' ) . appendTo ( trayBody ) ;
var tabContainer = $ ( '<div></div>' , { id : "user-settings-tabs-container" } ) . appendTo ( settingsContent ) ;
$ ( '<ul></ul>' , { id : "user-settings-tabs" } ) . appendTo ( tabContainer ) ;
var settingsTabs = RED . tabs . create ( {
id : "user-settings-tabs" ,
vertical : true ,
onchange : function ( tab ) {
setTimeout ( function ( ) {
$ ( "#user-settings-tabs-content" ) . children ( ) . hide ( ) ;
$ ( "#" + tab . id ) . show ( ) ;
if ( tab . pane . focus ) {
tab . pane . focus ( ) ;
}
} , 50 ) ;
}
} ) ;
var tabContents = $ ( '<div></div>' , { id : "user-settings-tabs-content" } ) . appendTo ( settingsContent ) ;
panes . forEach ( function ( pane ) {
settingsTabs . addTab ( {
id : "project-settings-tab-" + pane . id ,
label : pane . title ,
pane : pane
} ) ;
pane . get ( project ) . hide ( ) . appendTo ( tabContents ) ;
} ) ;
settingsContent . i18n ( ) ;
2017-09-26 23:51:08 +02:00
settingsTabs . activateTab ( "project-settings-tab-" + ( initialTab || 'main' ) )
2017-09-20 23:51:28 +02:00
$ ( "#sidebar-shade" ) . show ( ) ;
} ,
close : function ( ) {
settingsVisible = false ;
panes . forEach ( function ( pane ) {
if ( pane . close ) {
pane . close ( ) ;
}
} ) ;
$ ( "#sidebar-shade" ) . hide ( ) ;
} ,
show : function ( ) { }
}
if ( trayWidth !== null ) {
trayOptions . width = trayWidth ;
}
RED . tray . show ( trayOptions ) ;
}
function editDescription ( activeProject , container ) {
RED . editor . editMarkdown ( {
title : RED . _ ( 'sidebar.project.editDescription' ) ,
value : activeProject . description ,
complete : function ( v ) {
container . empty ( ) ;
2017-11-22 00:31:41 +01:00
var spinner = utils . addSpinnerOverlay ( container ) ;
2017-09-20 23:51:28 +02:00
var done = function ( err , res ) {
if ( err ) {
return editDescription ( activeProject , container ) ;
}
activeProject . description = v ;
updateProjectDescription ( activeProject , container ) ;
}
utils . sendRequest ( {
url : "projects/" + activeProject . name ,
type : "PUT" ,
responses : {
0 : function ( error ) {
done ( error , null ) ;
} ,
200 : function ( data ) {
done ( null , data ) ;
2017-12-11 18:05:12 +01:00
RED . sidebar . versionControl . refresh ( true ) ;
2017-09-20 23:51:28 +02:00
} ,
400 : {
'unexpected_error' : function ( error ) {
done ( error , null ) ;
}
} ,
}
} , { description : v } ) . always ( function ( ) {
spinner . remove ( ) ;
} ) ;
}
} ) ;
}
function updateProjectDescription ( activeProject , container ) {
container . empty ( ) ;
2017-12-04 12:42:44 +01:00
var desc ;
if ( activeProject . description ) {
desc = marked ( activeProject . description ) ;
} else {
desc = '<span class="node-info-none">' + 'No description available' + '</span>' ;
}
2017-09-20 23:51:28 +02:00
var description = addTargetToExternalLinks ( $ ( '<span class="bidiAware" dir=\"' + RED . text . bidi . resolveBaseTextDir ( desc ) + '">' + desc + '</span>' ) ) . appendTo ( container ) ;
description . find ( ".bidiAware" ) . contents ( ) . filter ( function ( ) { return this . nodeType === 3 && this . textContent . trim ( ) !== "" } ) . wrap ( "<span></span>" ) ;
}
function editSummary ( activeProject , summary , container ) {
var editButton = container . prev ( ) ;
editButton . hide ( ) ;
container . empty ( ) ;
var bg = $ ( '<span class="button-group" style="position: relative; float: right; margin-right:0;"></span>' ) . appendTo ( container ) ;
var input = $ ( '<input type="text" style="width: calc(100% - 150px); margin-right: 10px;">' ) . val ( summary || "" ) . appendTo ( container ) ;
$ ( '<button class="editor-button">Cancel</button>' )
. appendTo ( bg )
. click ( function ( evt ) {
evt . preventDefault ( ) ;
updateProjectSummary ( activeProject . summary , container ) ;
editButton . show ( ) ;
} ) ;
2017-10-19 22:38:53 +02:00
$ ( '<button class="editor-button">Save</button>' )
2017-09-20 23:51:28 +02:00
. appendTo ( bg )
. click ( function ( evt ) {
evt . preventDefault ( ) ;
var v = input . val ( ) ;
updateProjectSummary ( v , container ) ;
2017-11-22 00:31:41 +01:00
var spinner = utils . addSpinnerOverlay ( container ) ;
2017-09-20 23:51:28 +02:00
var done = function ( err , res ) {
if ( err ) {
spinner . remove ( ) ;
return editSummary ( activeProject , summary , container ) ;
}
activeProject . summary = v ;
spinner . remove ( ) ;
updateProjectSummary ( activeProject . summary , container ) ;
editButton . show ( ) ;
}
utils . sendRequest ( {
url : "projects/" + activeProject . name ,
type : "PUT" ,
responses : {
0 : function ( error ) {
done ( error , null ) ;
} ,
200 : function ( data ) {
2017-12-11 18:05:12 +01:00
RED . sidebar . versionControl . refresh ( true ) ;
2017-09-20 23:51:28 +02:00
done ( null , data ) ;
} ,
400 : {
'unexpected_error' : function ( error ) {
done ( error , null ) ;
}
} ,
}
} , { summary : v } ) ;
} ) ;
}
function updateProjectSummary ( summary , container ) {
container . empty ( ) ;
if ( summary ) {
container . text ( summary ) . removeClass ( 'node-info-node' ) ;
} else {
2017-09-21 12:19:24 +02:00
container . text ( "No summary available" ) . addClass ( 'node-info-none' ) ; // TODO: nls
2017-09-20 23:51:28 +02:00
}
}
2017-09-21 12:19:24 +02:00
function createMainPane ( activeProject ) {
2017-09-20 23:51:28 +02:00
var pane = $ ( '<div id="project-settings-tab-main" class="project-settings-tab-pane node-help"></div>' ) ;
$ ( '<h1>' ) . text ( activeProject . name ) . appendTo ( pane ) ;
var summary = $ ( '<div style="position: relative">' ) . appendTo ( pane ) ;
var summaryContent = $ ( '<div></div>' , { style : "color: #999" } ) . appendTo ( summary ) ;
updateProjectSummary ( activeProject . summary , summaryContent ) ;
$ ( '<button class="editor-button editor-button-small" style="float: right;">edit</button>' )
. prependTo ( summary )
. click ( function ( evt ) {
evt . preventDefault ( ) ;
editSummary ( activeProject , activeProject . summary , summaryContent ) ;
} ) ;
$ ( '<hr>' ) . appendTo ( pane ) ;
var description = $ ( '<div class="node-help" style="position: relative"></div>' ) . appendTo ( pane ) ;
var descriptionContent = $ ( '<div>' , { style : "min-height: 200px" } ) . appendTo ( description ) ;
updateProjectDescription ( activeProject , descriptionContent ) ;
$ ( '<button class="editor-button editor-button-small" style="float: right;">edit</button>' )
. prependTo ( description )
. click ( function ( evt ) {
evt . preventDefault ( ) ;
editDescription ( activeProject , descriptionContent ) ;
} ) ;
return pane ;
}
2017-09-21 12:19:24 +02:00
function updateProjectDependencies ( activeProject , depsList ) {
depsList . editableList ( 'empty' ) ;
2017-09-26 23:51:08 +02:00
var totalCount = 0 ;
var unknownCount = 0 ;
var unusedCount = 0 ;
2017-09-21 12:19:24 +02:00
for ( var m in modulesInUse ) {
if ( modulesInUse . hasOwnProperty ( m ) ) {
depsList . editableList ( 'addItem' , {
module : modulesInUse [ m ] . module ,
version : modulesInUse [ m ] . version ,
count : modulesInUse [ m ] . count ,
known : activeProject . dependencies . hasOwnProperty ( m )
} ) ;
2017-09-26 23:51:08 +02:00
totalCount ++ ;
if ( modulesInUse [ m ] . count === 0 ) {
unusedCount ++ ;
}
if ( ! activeProject . dependencies . hasOwnProperty ( m ) ) {
unknownCount ++ ;
}
2017-09-21 12:19:24 +02:00
}
}
if ( activeProject . dependencies ) {
for ( var m in activeProject . dependencies ) {
if ( activeProject . dependencies . hasOwnProperty ( m ) && ! modulesInUse . hasOwnProperty ( m ) ) {
depsList . editableList ( 'addItem' , {
module : m ,
version : activeProject . dependencies [ m ] , //RED.nodes.registry.getModule(module).version,
count : 0 ,
known : true
} ) ;
2017-09-26 23:51:08 +02:00
totalCount ++ ;
unusedCount ++ ;
2017-09-21 12:19:24 +02:00
}
}
}
2017-09-26 23:51:08 +02:00
if ( unknownCount > 0 ) {
2017-12-04 12:42:44 +01:00
depsList . editableList ( 'addItem' , { index : 1 , label : "Unlisted dependencies" } ) ; // TODO: nls
2017-09-26 23:51:08 +02:00
}
if ( unusedCount > 0 ) {
depsList . editableList ( 'addItem' , { index : 3 , label : "Unused dependencies" } ) ; // TODO: nls
}
if ( totalCount === 0 ) {
depsList . editableList ( 'addItem' , { index : 0 , label : "None" } ) ; // TODO: nls
}
2017-09-21 12:19:24 +02:00
}
function editDependencies ( activeProject , depsJSON , container , depsList ) {
2017-09-26 23:51:08 +02:00
var json = depsJSON || JSON . stringify ( activeProject . dependencies || { } , "" , 4 ) ;
if ( json === "{}" ) {
json = "{\n\n}" ;
}
2017-09-21 12:19:24 +02:00
RED . editor . editJSON ( {
title : RED . _ ( 'sidebar.project.editDependencies' ) ,
2017-09-26 23:51:08 +02:00
value : json ,
2017-09-21 12:19:24 +02:00
requireValid : true ,
complete : function ( v ) {
try {
var parsed = JSON . parse ( v ) ;
2017-11-22 00:31:41 +01:00
var spinner = utils . addSpinnerOverlay ( container ) ;
2017-09-21 12:19:24 +02:00
var done = function ( err , res ) {
if ( err ) {
2017-09-26 23:51:08 +02:00
return editDependencies ( activeProject , v , container , depsList ) ;
2017-09-21 12:19:24 +02:00
}
activeProject . dependencies = parsed ;
updateProjectDependencies ( activeProject , depsList ) ;
}
utils . sendRequest ( {
url : "projects/" + activeProject . name ,
type : "PUT" ,
responses : {
0 : function ( error ) {
done ( error , null ) ;
} ,
200 : function ( data ) {
2017-12-11 18:05:12 +01:00
RED . sidebar . versionControl . refresh ( true ) ;
2017-09-21 12:19:24 +02:00
done ( null , data ) ;
} ,
400 : {
'unexpected_error' : function ( error ) {
done ( error , null ) ;
}
} ,
}
} , { dependencies : parsed } ) . always ( function ( ) {
spinner . remove ( ) ;
} ) ;
} catch ( err ) {
editDependencies ( activeProject , v , container , depsList ) ;
}
}
} ) ;
}
function createDependenciesPane ( activeProject ) {
var pane = $ ( '<div id="project-settings-tab-deps" class="project-settings-tab-pane node-help"></div>' ) ;
$ ( '<button class="editor-button editor-button-small" style="margin-top:10px;float: right;">edit</button>' )
. appendTo ( pane )
. click ( function ( evt ) {
evt . preventDefault ( ) ;
editDependencies ( activeProject , null , pane , depsList )
} ) ;
var depsList = $ ( "<ol>" , { style : "position: absolute;top: 60px;bottom: 20px;left: 20px;right: 20px;" } ) . appendTo ( pane ) ;
depsList . editableList ( {
addButton : false ,
addItem : function ( row , index , entry ) {
// console.log(entry);
var headerRow = $ ( '<div>' , { class : "palette-module-header" } ) . appendTo ( row ) ;
if ( entry . label ) {
2017-09-26 23:51:08 +02:00
if ( entry . index === 0 ) {
headerRow . addClass ( "red-ui-search-empty" )
} else {
row . parent ( ) . addClass ( "palette-module-section" ) ;
}
2017-09-21 12:19:24 +02:00
headerRow . text ( entry . label ) ;
if ( entry . index === 1 ) {
var addButton = $ ( '<button class="editor-button editor-button-small palette-module-button">add to project</button>' ) . appendTo ( headerRow ) . click ( function ( evt ) {
evt . preventDefault ( ) ;
var deps = $ . extend ( true , { } , activeProject . dependencies ) ;
for ( var m in modulesInUse ) {
if ( modulesInUse . hasOwnProperty ( m ) && ! modulesInUse [ m ] . known ) {
deps [ m ] = modulesInUse [ m ] . version ;
}
}
editDependencies ( activeProject , JSON . stringify ( deps , "" , 4 ) , pane , depsList ) ;
} ) ;
} else if ( entry . index === 3 ) {
var removeButton = $ ( '<button class="editor-button editor-button-small palette-module-button">remove from project</button>' ) . appendTo ( headerRow ) . click ( function ( evt ) {
evt . preventDefault ( ) ;
var deps = $ . extend ( true , { } , activeProject . dependencies ) ;
for ( var m in activeProject . dependencies ) {
if ( activeProject . dependencies . hasOwnProperty ( m ) && ! modulesInUse . hasOwnProperty ( m ) ) {
delete deps [ m ] ;
}
}
editDependencies ( activeProject , JSON . stringify ( deps , "" , 4 ) , pane , depsList ) ;
} ) ;
}
} else {
2017-09-26 23:51:08 +02:00
headerRow . addClass ( "palette-module-header" ) ;
2017-09-21 12:19:24 +02:00
headerRow . toggleClass ( "palette-module-unused" , entry . count === 0 ) ;
entry . element = headerRow ;
var titleRow = $ ( '<div class="palette-module-meta palette-module-name"></div>' ) . appendTo ( headerRow ) ;
var icon = $ ( '<i class="fa fa-' + ( entry . known ? 'cube' : 'warning' ) + '"></i>' ) . appendTo ( titleRow ) ;
entry . icon = icon ;
$ ( '<span>' ) . html ( entry . module ) . appendTo ( titleRow ) ;
var metaRow = $ ( '<div class="palette-module-meta palette-module-version"><i class="fa fa-tag"></i></div>' ) . appendTo ( headerRow ) ;
var versionSpan = $ ( '<span>' ) . html ( entry . version ) . appendTo ( metaRow ) ;
if ( ! entry . known ) {
headerRow . addClass ( "palette-module-unknown" ) ;
} else if ( entry . known && entry . count === 0 ) {
}
}
} ,
sort : function ( A , B ) {
if ( A . index && B . index ) {
return A . index - B . index ;
}
var Acategory = A . index ? A . index : ( A . known ? ( A . count > 0 ? 0 : 4 ) : 2 ) ;
var Bcategory = B . index ? B . index : ( B . known ? ( B . count > 0 ? 0 : 4 ) : 2 ) ;
if ( Acategory === Bcategory ) {
return A . module . localeCompare ( B . module ) ;
} else {
return Acategory - Bcategory ;
}
}
} ) ;
updateProjectDependencies ( activeProject , depsList ) ;
return pane ;
}
2017-09-20 23:51:28 +02:00
2017-12-04 12:42:44 +01:00
function showProjectFileListing ( row , activeProject , current , filter , done ) {
2017-10-19 22:38:53 +02:00
var dialog ;
var dialogBody ;
var filesList ;
var selected ;
2017-11-22 00:31:41 +01:00
var container = $ ( '<div class="project-file-listing-container"></div>' , { style : "position: relative; min-height: 175px; height: 175px;" } ) . hide ( ) . appendTo ( row ) ;
var spinner = utils . addSpinnerOverlay ( container ) ;
2017-12-04 12:42:44 +01:00
$ . getJSON ( "projects/" + activeProject . name + "/files" , function ( result ) {
2017-10-19 22:38:53 +02:00
var fileNames = Object . keys ( result ) ;
2017-12-04 12:42:44 +01:00
fileNames = fileNames . filter ( function ( fn ) {
return ! result [ fn ] . status || ! /D/ . test ( result [ fn ] . status ) ;
} )
2017-10-19 22:38:53 +02:00
var files = { } ;
fileNames . sort ( ) ;
fileNames . forEach ( function ( file ) {
file . split ( "/" ) . reduce ( function ( r , v , i , arr ) { if ( v ) { if ( i < arr . length - 1 ) { r [ v ] = r [ v ] || { } ; } else { r [ v ] = true } return r [ v ] ; } } , files ) ;
2017-09-26 23:51:08 +02:00
} ) ;
2017-10-19 22:38:53 +02:00
var sortFiles = function ( key , value , fullPath ) {
var result = {
name : key || "/" ,
path : fullPath + ( fullPath ? "/" : "" ) + key ,
} ;
if ( value === true ) {
result . type = 'f' ;
return result ;
}
result . type = 'd' ;
result . children = [ ] ;
result . path = result . path ;
var files = Object . keys ( value ) ;
files . forEach ( function ( file ) {
result . children . push ( sortFiles ( file , value [ file ] , result . path ) ) ;
} )
result . children . sort ( function ( A , B ) {
if ( A . hasOwnProperty ( "children" ) && ! B . hasOwnProperty ( "children" ) ) {
return - 1 ;
} else if ( ! A . hasOwnProperty ( "children" ) && B . hasOwnProperty ( "children" ) ) {
return 1 ;
2017-09-26 23:51:08 +02:00
}
2017-10-19 22:38:53 +02:00
return A . name . localeCompare ( B . name ) ;
} )
return result ;
}
var files = sortFiles ( "" , files , "" ) ;
2017-12-04 12:42:44 +01:00
createFileSubList ( container , files . children , current , filter , done , "height: 175px" ) ;
2017-10-19 22:38:53 +02:00
spinner . remove ( ) ;
} ) ;
2017-11-22 00:31:41 +01:00
return container ;
2017-10-19 22:38:53 +02:00
}
2017-11-22 00:31:41 +01:00
2017-12-04 12:42:44 +01:00
function createFileSubList ( container , files , current , filter , onselect , style ) {
2017-10-19 22:38:53 +02:00
style = style || "" ;
var list = $ ( '<ol>' , { class : "projects-dialog-file-list" , style : style } ) . appendTo ( container ) . editableList ( {
addButton : false ,
scrollOnAdd : false ,
addItem : function ( row , index , entry ) {
var header = $ ( '<div></div>' , { class : "projects-dialog-file-list-entry" } ) . appendTo ( row ) ;
if ( entry . children ) {
$ ( '<span class="projects-dialog-file-list-entry-folder"><i class="fa fa-angle-right"></i> <i class="fa fa-folder-o"></i></span>' ) . appendTo ( header ) ;
if ( entry . children . length > 0 ) {
var children = $ ( '<div></div>' , { style : "padding-left: 20px;" } ) . appendTo ( row ) ;
if ( current . indexOf ( entry . path + "/" ) === 0 ) {
header . addClass ( "expanded" ) ;
} else {
children . hide ( ) ;
}
2017-12-04 12:42:44 +01:00
createFileSubList ( children , entry . children , current , filter , onselect ) ;
2017-10-19 22:38:53 +02:00
header . addClass ( "selectable" ) ;
header . click ( function ( e ) {
if ( $ ( this ) . hasClass ( "expanded" ) ) {
$ ( this ) . removeClass ( "expanded" ) ;
children . slideUp ( 200 ) ;
} else {
$ ( this ) . addClass ( "expanded" ) ;
children . slideDown ( 200 ) ;
}
2017-09-26 23:51:08 +02:00
2017-10-19 22:38:53 +02:00
} ) ;
2017-09-26 23:51:08 +02:00
2017-10-19 22:38:53 +02:00
}
} else {
var fileIcon = "fa-file-o" ;
var fileClass = "" ;
if ( /\.json$/i . test ( entry . name ) ) {
fileIcon = "fa-file-code-o"
} else if ( /\.md$/i . test ( entry . name ) ) {
fileIcon = "fa-book" ;
} else if ( /^\.git/i . test ( entry . name ) ) {
fileIcon = "fa-code-fork" ;
header . addClass ( "projects-dialog-file-list-entry-file-type-git" ) ;
}
$ ( '<span class="projects-dialog-file-list-entry-file"> <i class="fa ' + fileIcon + '"></i></span>' ) . appendTo ( header ) ;
2017-12-04 12:42:44 +01:00
if ( filter . test ( entry . name ) ) {
header . addClass ( "selectable" ) ;
if ( entry . path === current ) {
header . addClass ( "selected" ) ;
}
header . click ( function ( e ) {
$ ( ".projects-dialog-file-list-entry.selected" ) . removeClass ( "selected" ) ;
$ ( this ) . addClass ( "selected" ) ;
onselect ( entry . path ) ;
} )
header . dblclick ( function ( e ) {
e . preventDefault ( ) ;
onselect ( entry . path , true ) ;
} )
} else {
header . addClass ( "unselectable" ) ;
2017-10-19 22:38:53 +02:00
}
}
$ ( '<span class="projects-dialog-file-list-entry-name" style=""></span>' ) . text ( entry . name ) . appendTo ( header ) ;
}
} ) ;
if ( ! style ) {
list . parent ( ) . css ( "overflow-y" , "" ) ;
2017-09-26 23:51:08 +02:00
}
2017-10-19 22:38:53 +02:00
files . forEach ( function ( f ) {
list . editableList ( 'addItem' , f ) ;
} )
}
2017-09-26 23:51:08 +02:00
2017-10-19 22:38:53 +02:00
// function editFiles(activeProject, container,flowFile, flowFileLabel) {
// var editButton = container.children().first();
// editButton.hide();
//
// var flowFileInput = $('<input id="" type="text" style="width: calc(100% - 300px);">').val(flowFile).insertAfter(flowFileLabel);
//
// var flowFileInputSearch = $('<button class="editor-button" style="margin-left: 10px"><i class="fa fa-folder-open-o"></i></button>')
// .insertAfter(flowFileInput)
// .click(function(e) {
// showProjectFileListing(activeProject,'Select flow file',flowFileInput.val(),function(result) {
// flowFileInput.val(result);
// checkFiles();
// })
// })
//
// var checkFiles = function() {
// saveButton.toggleClass('disabled',flowFileInput.val()==="");
// saveButton.prop('disabled',flowFileInput.val()==="");
// }
// flowFileInput.on("change keyup paste",checkFiles);
// flowFileLabel.hide();
//
// var bg = $('<span class="button-group" style="position: relative; float: right; margin-right:0;"></span>').prependTo(container);
// $('<button class="editor-button">Cancel</button>')
// .appendTo(bg)
// .click(function(evt) {
// evt.preventDefault();
//
// flowFileLabel.show();
// flowFileInput.remove();
// flowFileInputSearch.remove();
// bg.remove();
// editButton.show();
// });
// var saveButton = $('<button class="editor-button">Save</button>')
// .appendTo(bg)
// .click(function(evt) {
// evt.preventDefault();
// var newFlowFile = flowFileInput.val();
// var newCredsFile = credentialsFileInput.val();
2017-11-22 00:31:41 +01:00
// var spinner = utils.addSpinnerOverlay(container);
2017-10-19 22:38:53 +02:00
// var done = function(err,res) {
// if (err) {
// spinner.remove();
// return;
// }
// activeProject.summary = v;
// spinner.remove();
// flowFileLabel.text(newFlowFile);
// flowFileLabel.show();
// flowFileInput.remove();
// flowFileInputSearch.remove();
// bg.remove();
// editButton.show();
// }
// // utils.sendRequest({
// // url: "projects/"+activeProject.name,
// // type: "PUT",
// // responses: {
// // 0: function(error) {
// // done(error,null);
// // },
// // 200: function(data) {
// // done(null,data);
// // },
// // 400: {
// // 'unexpected_error': function(error) {
// // done(error,null);
// // }
// // },
// // }
// // },{summary:v});
// });
//
//
// checkFiles();
//
// }
function createFilesSection ( activeProject , pane ) {
var title = $ ( '<h3></h3>' ) . text ( "Files" ) . appendTo ( pane ) ;
var filesContainer = $ ( '<div class="user-settings-section"></div>' ) . appendTo ( pane ) ;
2017-11-22 00:31:41 +01:00
var editFilesButton = $ ( '<button class="editor-button editor-button-small" style="float: right;">edit</button>' )
2017-10-19 22:38:53 +02:00
. appendTo ( title )
. click ( function ( evt ) {
evt . preventDefault ( ) ;
formButtons . show ( ) ;
2017-11-22 00:31:41 +01:00
editFilesButton . hide ( ) ;
2017-10-19 22:38:53 +02:00
flowFileLabelText . hide ( ) ;
flowFileInput . show ( ) ;
flowFileInputSearch . show ( ) ;
credFileLabel . hide ( ) ;
credFileInput . show ( ) ;
flowFileInput . focus ( ) ;
// credentialStateLabel.parent().hide();
credentialStateLabel . addClass ( "uneditable-input" ) ;
$ ( ".user-settings-row-credentials" ) . show ( ) ;
credentialStateLabel . css ( 'height' , 'auto' ) ;
credentialFormRows . hide ( ) ;
credentialSecretButtons . show ( ) ;
} ) ;
var row ;
// Flow files
row = $ ( '<div class="user-settings-row"></div>' ) . appendTo ( filesContainer ) ;
$ ( '<label for=""></label>' ) . text ( 'Flow' ) . appendTo ( row ) ;
var flowFileLabel = $ ( '<div class="uneditable-input" style="padding:0">' ) . appendTo ( row ) ;
var flowFileLabelText = $ ( '<span style="display:inline-block; padding: 6px">' ) . text ( activeProject . files . flow ) . appendTo ( flowFileLabel ) ;
var flowFileInput = $ ( '<input id="" type="text" style="margin-bottom: 0;width: 100%; border: none;">' ) . val ( activeProject . files . flow ) . hide ( ) . appendTo ( flowFileLabel ) ;
2017-11-22 00:31:41 +01:00
var flowFileInputSearch = $ ( '<button class="editor-button" style="border-top-right-radius: 4px; border-bottom-right-radius: 4px; width: 36px; height: 34px; position: absolute; top: -1px; right: -1px;"><i class="fa fa-folder-open-o"></i></button>' )
2017-10-19 22:38:53 +02:00
. hide ( )
. appendTo ( flowFileLabel )
. click ( function ( e ) {
if ( $ ( this ) . hasClass ( 'selected' ) ) {
$ ( this ) . removeClass ( 'selected' ) ;
2017-11-22 00:31:41 +01:00
flowFileLabel . find ( '.project-file-listing-container' ) . slideUp ( 200 , function ( ) {
$ ( this ) . remove ( ) ;
flowFileLabel . css ( 'height' , '' ) ;
} ) ;
2017-10-19 22:38:53 +02:00
flowFileLabel . css ( 'color' , '' ) ;
} else {
$ ( this ) . addClass ( 'selected' ) ;
flowFileLabel . css ( 'color' , 'inherit' ) ;
2017-12-04 12:42:44 +01:00
var fileList = showProjectFileListing ( flowFileLabel , activeProject , flowFileInput . val ( ) , /.*\.json$/ , function ( result , isDblClick ) {
2017-10-19 22:38:53 +02:00
if ( result ) {
flowFileInput . val ( result ) ;
}
if ( isDblClick ) {
$ ( flowFileInputSearch ) . click ( ) ;
}
checkFiles ( ) ;
2017-11-22 00:31:41 +01:00
} ) ;
flowFileLabel . css ( 'height' , 'auto' ) ;
setTimeout ( function ( ) {
fileList . slideDown ( 200 ) ;
} , 50 ) ;
2017-10-19 22:38:53 +02:00
}
} )
row = $ ( '<div class="user-settings-row"></div>' ) . appendTo ( filesContainer ) ;
$ ( '<label for=""></label>' ) . text ( 'Credentials' ) . appendTo ( row ) ;
var credFileLabel = $ ( '<div class="uneditable-input">' ) . text ( activeProject . files . credentials ) . appendTo ( row ) ;
var credFileInput = $ ( '<div class="uneditable-input">' ) . text ( activeProject . files . credentials ) . hide ( ) . insertAfter ( credFileLabel ) ;
var checkFiles = function ( ) {
var saveDisabled ;
var currentFlowValue = flowFileInput . val ( ) ;
var m = /^(.+?)(\.[^.]*)?$/ . exec ( currentFlowValue ) ;
if ( m ) {
credFileInput . text ( m [ 1 ] + "_cred" + ( m [ 2 ] || ".json" ) ) ;
} else if ( currentFlowValue === "" ) {
credFileInput . text ( "" ) ;
}
var isFlowInvalid = currentFlowValue === "" ||
/\.\./ . test ( currentFlowValue ) ||
/\/$/ . test ( currentFlowValue ) ;
2017-09-26 23:51:08 +02:00
2017-10-19 22:38:53 +02:00
saveDisabled = isFlowInvalid || credFileInput . text ( ) === "" ;
2017-09-26 23:51:08 +02:00
2017-10-19 22:38:53 +02:00
if ( credentialSecretExistingInput . is ( ":visible" ) ) {
credentialSecretExistingInput . toggleClass ( "input-error" , credentialSecretExistingInput . val ( ) === "" ) ;
saveDisabled = saveDisabled || credentialSecretExistingInput . val ( ) === "" ;
2017-09-26 23:51:08 +02:00
}
2017-10-19 22:38:53 +02:00
if ( credentialSecretNewInput . is ( ":visible" ) ) {
credentialSecretNewInput . toggleClass ( "input-error" , credentialSecretNewInput . val ( ) === "" ) ;
saveDisabled = saveDisabled || credentialSecretNewInput . val ( ) === "" ;
2017-09-26 23:51:08 +02:00
}
2017-10-19 22:38:53 +02:00
flowFileInput . toggleClass ( "input-error" , isFlowInvalid ) ;
credFileInput . toggleClass ( "input-error" , credFileInput . text ( ) === "" ) ;
saveButton . toggleClass ( 'disabled' , saveDisabled ) ;
saveButton . prop ( 'disabled' , saveDisabled ) ;
2017-09-26 23:51:08 +02:00
}
2017-10-19 22:38:53 +02:00
flowFileInput . on ( "change keyup paste" , checkFiles ) ;
2017-09-26 23:51:08 +02:00
2017-10-19 22:38:53 +02:00
if ( ! activeProject . files . flow ) {
$ ( '<span class="form-warning"><i class="fa fa-warning"></i> Missing</span>' ) . appendTo ( flowFileLabelText ) ;
}
if ( ! activeProject . files . credentials ) {
$ ( '<span class="form-warning"><i class="fa fa-warning"></i> Missing</span>' ) . appendTo ( credFileLabel ) ;
2017-09-26 23:51:08 +02:00
}
2017-10-19 22:38:53 +02:00
row = $ ( '<div class="user-settings-row"></div>' ) . appendTo ( filesContainer ) ;
$ ( '<label></label>' ) . appendTo ( row ) ;
var credentialStateLabel = $ ( '<span><i class="user-settings-credentials-state-icon fa"></i> <span class="user-settings-credentials-state"></span></span>' ) . appendTo ( row ) ;
var credentialSecretButtons = $ ( '<span class="button-group" style="margin-left: -72px;">' ) . hide ( ) . appendTo ( row ) ;
credentialStateLabel . css ( 'color' , '#666' ) ;
credentialSecretButtons . css ( 'vertical-align' , 'top' ) ;
var credentialSecretResetButton = $ ( '<button class="editor-button" style="vertical-align: top; width: 36px; margin-bottom: 10px"><i class="fa fa-trash-o"></i></button>' )
. appendTo ( credentialSecretButtons )
. click ( function ( e ) {
e . preventDefault ( ) ;
if ( ! $ ( this ) . hasClass ( 'selected' ) ) {
credentialSecretNewInput . val ( "" ) ;
credentialSecretExistingRow . hide ( ) ;
credentialSecretNewRow . show ( ) ;
$ ( this ) . addClass ( "selected" ) ;
credentialSecretEditButton . removeClass ( "selected" ) ;
credentialResetLabel . show ( ) ;
credentialResetWarning . show ( ) ;
credentialSetLabel . hide ( ) ;
credentialChangeLabel . hide ( ) ;
credentialFormRows . show ( ) ;
} else {
$ ( this ) . removeClass ( "selected" ) ;
credentialFormRows . hide ( ) ;
}
checkFiles ( ) ;
} ) ;
2017-11-22 00:31:41 +01:00
var credentialSecretEditButton = $ ( '<button class="editor-button" style="border-top-right-radius: 4px; border-bottom-right-radius: 4px; vertical-align: top; width: 36px; margin-bottom: 10px"><i class="fa fa-pencil"></i></button>' )
2017-10-19 22:38:53 +02:00
. appendTo ( credentialSecretButtons )
. click ( function ( e ) {
e . preventDefault ( ) ;
if ( ! $ ( this ) . hasClass ( 'selected' ) ) {
credentialSecretExistingInput . val ( "" ) ;
credentialSecretNewInput . val ( "" ) ;
if ( activeProject . settings . credentialSecretInvalid || ! activeProject . settings . credentialsEncrypted ) {
credentialSetLabel . show ( ) ;
credentialChangeLabel . hide ( ) ;
credentialSecretExistingRow . hide ( ) ;
} else {
credentialSecretExistingRow . show ( ) ;
credentialSetLabel . hide ( ) ;
credentialChangeLabel . show ( ) ;
}
credentialSecretNewRow . show ( ) ;
credentialSecretEditButton . addClass ( "selected" ) ;
credentialSecretResetButton . removeClass ( "selected" ) ;
credentialResetLabel . hide ( ) ;
credentialResetWarning . hide ( ) ;
credentialFormRows . show ( ) ;
} else {
$ ( this ) . removeClass ( "selected" ) ;
credentialFormRows . hide ( ) ;
}
checkFiles ( ) ;
} )
row = $ ( '<div class="user-settings-row user-settings-row-credentials"></div>' ) . hide ( ) . appendTo ( filesContainer ) ;
var credentialFormRows = $ ( '<div>' , { style : "margin-top:10px" } ) . hide ( ) . appendTo ( credentialStateLabel ) ;
var credentialSetLabel = $ ( '<div style="margin: 20px 0 10px 5px;">Set the encryption key:</div>' ) . hide ( ) . appendTo ( credentialFormRows ) ;
var credentialChangeLabel = $ ( '<div style="margin: 20px 0 10px 5px;">Change the encryption key:</div>' ) . hide ( ) . appendTo ( credentialFormRows ) ;
var credentialResetLabel = $ ( '<div style="margin: 20px 0 10px 5px;">Reset the encryption key:</div>' ) . hide ( ) . appendTo ( credentialFormRows ) ;
var credentialSecretExistingRow = $ ( '<div class="user-settings-row user-settings-row-credentials"></div>' ) . appendTo ( credentialFormRows ) ;
$ ( '<label for=""></label>' ) . text ( 'Current key' ) . appendTo ( credentialSecretExistingRow ) ;
var credentialSecretExistingInput = $ ( '<input type="password">' ) . appendTo ( credentialSecretExistingRow )
. on ( "change keyup paste" , function ( ) {
2017-09-26 23:51:08 +02:00
if ( popover ) {
popover . close ( ) ;
popover = null ;
}
2017-10-19 22:38:53 +02:00
checkFiles ( ) ;
2017-09-26 23:51:08 +02:00
} ) ;
2017-10-19 22:38:53 +02:00
var credentialSecretNewRow = $ ( '<div class="user-settings-row user-settings-row-credentials"></div>' ) . appendTo ( credentialFormRows ) ;
$ ( '<label for=""></label>' ) . text ( 'New key' ) . appendTo ( credentialSecretNewRow ) ;
var credentialSecretNewInput = $ ( '<input type="password">' ) . appendTo ( credentialSecretNewRow ) . on ( "change keyup paste" , checkFiles ) ;
var credentialResetWarning = $ ( '<div class="form-tips form-warning" style="margin: 10px;"><i class="fa fa-warning"></i> This will delete all existing credentials</div>' ) . hide ( ) . appendTo ( credentialFormRows ) ;
var hideEditForm = function ( ) {
2017-11-22 00:31:41 +01:00
editFilesButton . show ( ) ;
2017-10-19 22:38:53 +02:00
formButtons . hide ( ) ;
flowFileLabelText . show ( ) ;
flowFileInput . hide ( ) ;
flowFileInputSearch . hide ( ) ;
credFileLabel . show ( ) ;
credFileInput . hide ( ) ;
// credentialStateLabel.parent().show();
credentialStateLabel . removeClass ( "uneditable-input" ) ;
credentialStateLabel . css ( 'height' , '' ) ;
2017-11-22 00:31:41 +01:00
flowFileInputSearch . removeClass ( 'selected' ) ;
flowFileLabel . find ( '.project-file-listing-container' ) . remove ( ) ;
flowFileLabel . css ( 'height' , '' ) ;
flowFileLabel . css ( 'color' , '' ) ;
2017-10-19 22:38:53 +02:00
$ ( ".user-settings-row-credentials" ) . hide ( ) ;
credentialFormRows . hide ( ) ;
credentialSecretButtons . hide ( ) ;
credentialSecretResetButton . removeClass ( "selected" ) ;
credentialSecretEditButton . removeClass ( "selected" ) ;
}
var formButtons = $ ( '<span class="button-group" style="position: relative; float: right; margin-right:0;"></span>' ) . hide ( ) . appendTo ( filesContainer ) ;
2017-11-22 00:31:41 +01:00
$ ( '<button class="editor-button">Cancel</button>' )
2017-10-19 22:38:53 +02:00
. appendTo ( formButtons )
2017-09-26 23:51:08 +02:00
. click ( function ( evt ) {
evt . preventDefault ( ) ;
2017-10-19 22:38:53 +02:00
hideEditForm ( ) ;
} ) ;
var saveButton = $ ( '<button class="editor-button">Save</button>' )
. appendTo ( formButtons )
. click ( function ( evt ) {
evt . preventDefault ( ) ;
2017-11-22 00:31:41 +01:00
var spinner = utils . addSpinnerOverlay ( filesContainer ) ;
2017-10-19 22:38:53 +02:00
var done = function ( err ) {
spinner . remove ( ) ;
if ( err ) {
console . log ( err ) ;
return ;
}
flowFileLabelText . text ( flowFileInput . val ( ) ) ;
credFileLabel . text ( credFileInput . text ( ) ) ;
hideEditForm ( ) ;
2017-09-26 23:51:08 +02:00
}
var payload = {
2017-10-19 22:38:53 +02:00
files : {
flow : flowFileInput . val ( ) ,
credentials : credFileInput . text ( )
}
2017-09-26 23:51:08 +02:00
}
2017-10-19 22:38:53 +02:00
if ( credentialSecretResetButton . hasClass ( 'selected' ) ) {
payload . resetCredentialSecret = true ;
2017-09-26 23:51:08 +02:00
}
2017-10-19 22:38:53 +02:00
if ( credentialSecretResetButton . hasClass ( 'selected' ) || credentialSecretEditButton . hasClass ( 'selected' ) ) {
payload . credentialSecret = credentialSecretNewInput . val ( ) ;
if ( credentialSecretExistingInput . is ( ":visible" ) ) {
payload . currentCredentialSecret = credentialSecretExistingInput . val ( ) ;
2017-09-26 23:51:08 +02:00
}
}
2017-10-19 22:38:53 +02:00
// console.log(JSON.stringify(payload,null,4));
RED . deploy . setDeployInflight ( true ) ;
2017-09-26 23:51:08 +02:00
utils . sendRequest ( {
url : "projects/" + activeProject . name ,
type : "PUT" ,
responses : {
0 : function ( error ) {
2017-10-19 22:38:53 +02:00
done ( error ) ;
2017-09-26 23:51:08 +02:00
} ,
200 : function ( data ) {
2017-10-19 22:38:53 +02:00
activeProject = data ;
2017-12-11 18:05:12 +01:00
RED . sidebar . versionControl . refresh ( true ) ;
2017-10-19 22:38:53 +02:00
updateForm ( ) ;
done ( ) ;
2017-09-26 23:51:08 +02:00
} ,
400 : {
2017-10-19 22:38:53 +02:00
'credentials_load_failed' : function ( error ) {
done ( error ) ;
} ,
2017-09-26 23:51:08 +02:00
'unexpected_error' : function ( error ) {
2017-10-19 22:38:53 +02:00
console . log ( error ) ;
done ( error ) ;
2017-09-26 23:51:08 +02:00
} ,
'missing_current_credential_key' : function ( error ) {
2017-10-19 22:38:53 +02:00
credentialSecretExistingInput . addClass ( "input-error" ) ;
2017-09-26 23:51:08 +02:00
popover = RED . popover . create ( {
2017-10-19 22:38:53 +02:00
target : credentialSecretExistingInput ,
2017-09-26 23:51:08 +02:00
direction : 'right' ,
size : 'small' ,
2017-10-19 22:38:53 +02:00
content : "Incorrect key" ,
autoClose : 3000
2017-09-26 23:51:08 +02:00
} ) . open ( ) ;
2017-10-19 22:38:53 +02:00
done ( error ) ;
2017-09-26 23:51:08 +02:00
}
} ,
}
} , payload ) . always ( function ( ) {
2017-10-19 22:38:53 +02:00
RED . deploy . setDeployInflight ( false ) ;
2017-09-26 23:51:08 +02:00
} ) ;
2017-10-19 22:38:53 +02:00
} ) ;
var updateForm = function ( ) {
if ( activeProject . settings . credentialSecretInvalid ) {
credentialStateLabel . find ( ".user-settings-credentials-state-icon" ) . removeClass ( ) . addClass ( "user-settings-credentials-state-icon fa fa-warning" ) ;
credentialStateLabel . find ( ".user-settings-credentials-state" ) . text ( "Invalid encryption key" ) ;
} else if ( activeProject . settings . credentialsEncrypted ) {
credentialStateLabel . find ( ".user-settings-credentials-state-icon" ) . removeClass ( ) . addClass ( "user-settings-credentials-state-icon fa fa-lock" ) ;
credentialStateLabel . find ( ".user-settings-credentials-state" ) . text ( "Encryption enabled" ) ;
} else {
credentialStateLabel . find ( ".user-settings-credentials-state-icon" ) . removeClass ( ) . addClass ( "user-settings-credentials-state-icon fa fa-unlock" ) ;
credentialStateLabel . find ( ".user-settings-credentials-state" ) . text ( "Encryption disabled" ) ;
}
credentialSecretResetButton . toggleClass ( 'disabled' , ! activeProject . settings . credentialsEncrypted ) ;
credentialSecretResetButton . prop ( 'disabled' , ! activeProject . settings . credentialsEncrypted ) ;
}
2017-09-26 23:51:08 +02:00
2017-10-19 22:38:53 +02:00
checkFiles ( ) ;
updateForm ( ) ;
}
2017-11-22 00:31:41 +01:00
2017-12-08 17:31:42 +01:00
function createLocalBranchListSection ( activeProject , pane ) {
var localBranchContainer = $ ( '<div class="user-settings-section"></div>' ) . appendTo ( pane ) ;
$ ( '<h4></h4>' ) . text ( "Branches" ) . appendTo ( localBranchContainer ) ;
var row = $ ( '<div class="user-settings-row projects-dialog-branch-list"></div>' ) . appendTo ( localBranchContainer ) ;
var branchList = $ ( '<ol>' ) . appendTo ( row ) . editableList ( {
addButton : false ,
scrollOnAdd : false ,
addItem : function ( row , index , entry ) {
var container = $ ( '<div class="projects-dialog-branch-list-entry">' ) . appendTo ( row ) ;
$ ( '<span><i class="fa fa-code-fork"></i></span>' ) . appendTo ( container ) ;
$ ( '<span class="branch-name">' ) . text ( entry . name ) . appendTo ( container ) ;
// if (entry.commit) {
// $('<span class="commit">').text(entry.commit.sha).appendTo(container);
// }
if ( entry . remote ) {
$ ( '<span class="branch-remote-name">' ) . text ( entry . remote || "" ) . appendTo ( container ) ;
if ( entry . status . ahead + entry . status . behind > 0 ) {
$ ( '<span class="branch-remote-status">' +
'<i class="fa fa-long-arrow-up"></i> <span>' + entry . status . ahead + '</span> ' +
'<i class="fa fa-long-arrow-down"></i> <span>' + entry . status . behind + '</span>' +
'</span>' ) . appendTo ( container ) ;
}
}
var tools = $ ( '<span class="projects-dialog-branch-list-entry-tools">' ) . appendTo ( container ) ;
if ( entry . current ) {
tools . text ( 'current' ) ;
} else {
$ ( '<button class="editor-button editor-button-small">delete</button>' )
. appendTo ( tools )
. click ( function ( e ) {
e . preventDefault ( ) ;
var spinner = utils . addSpinnerOverlay ( row ) . addClass ( 'projects-dialog-spinner-contain' ) ;
var notification = RED . notify ( "Are you sure you want to delete the local branch '" + entry . name + "'? This cannot be undone." , {
type : "warning" ,
modal : true ,
fixed : true ,
buttons : [
{
text : RED . _ ( "common.label.cancel" ) ,
click : function ( ) {
spinner . remove ( ) ;
notification . close ( ) ;
}
} , {
text : 'Delete branch' ,
click : function ( ) {
notification . close ( ) ;
var url = "projects/" + activeProject . name + "/branches/" + entry . name ;
var options = {
url : url ,
type : "DELETE" ,
responses : {
200 : function ( data ) {
row . fadeOut ( 200 , function ( ) {
branchList . editableList ( 'removeItem' , entry ) ;
spinner . remove ( ) ;
} ) ;
} ,
400 : {
'git_delete_branch_unmerged' : function ( error ) {
notification = RED . notify ( "The local branch '" + entry . name + "' has unmerged changes that will be lost. Are you sure you want to delete it?" , {
type : "warning" ,
modal : true ,
fixed : true ,
buttons : [
{
text : RED . _ ( "common.label.cancel" ) ,
click : function ( ) {
spinner . remove ( ) ;
notification . close ( ) ;
}
} , {
text : 'Delete unmerged branch' ,
click : function ( ) {
options . url += "?force=true" ;
notification . close ( ) ;
utils . sendRequest ( options ) ;
}
}
]
} ) ;
} ,
'unexpected_error' : function ( error ) {
console . log ( error ) ;
spinner . remove ( ) ;
}
} ,
}
}
utils . sendRequest ( options ) ;
}
}
]
} )
} )
}
}
} ) ;
$ . getJSON ( "projects/" + activeProject . name + "/branches" , function ( result ) {
if ( result . branches ) {
result . branches . sort ( function ( A , B ) {
if ( A . current ) { return - 1 }
if ( B . current ) { return 1 }
return A . name . localeCompare ( B . name ) ;
} ) ;
result . branches . forEach ( function ( branch ) {
branchList . editableList ( 'addItem' , branch ) ;
} )
}
} )
}
2017-12-04 12:42:44 +01:00
function createRemoteRepositorySection ( activeProject , pane ) {
2017-12-08 17:31:42 +01:00
$ ( '<h3></h3>' ) . text ( "Version Control" ) . appendTo ( pane ) ;
createLocalBranchListSection ( activeProject , pane ) ;
var repoContainer = $ ( '<div class="user-settings-section"></div>' ) . appendTo ( pane ) ;
var title = $ ( '<h4></h4>' ) . text ( "Git remotes" ) . appendTo ( repoContainer ) ;
2017-11-22 00:31:41 +01:00
var editRepoButton = $ ( '<button class="editor-button editor-button-small" style="float: right;">edit</button>' )
. appendTo ( title )
. click ( function ( evt ) {
editRepoButton . hide ( ) ;
formButtons . show ( ) ;
2017-12-04 12:42:44 +01:00
$ ( '.projects-dialog-remote-list-entry-delete' ) . show ( ) ;
remoteListAddButton . show ( ) ;
2017-11-22 00:31:41 +01:00
} ) ;
2017-12-08 17:31:42 +01:00
2017-11-22 00:31:41 +01:00
2017-12-04 12:42:44 +01:00
row = $ ( '<div class="user-settings-row projects-dialog-remote-list"></div>' ) . appendTo ( repoContainer ) ;
var remotesList = $ ( '<ol>' ) . appendTo ( row ) ;
2017-11-22 00:31:41 +01:00
remotesList . editableList ( {
2017-12-04 12:42:44 +01:00
addButton : 'add remote repository' ,
height : 'auto' ,
2017-11-22 00:31:41 +01:00
addItem : function ( outer , index , entry ) {
2017-12-04 12:42:44 +01:00
var header = $ ( '<div class="projects-dialog-remote-list-entry-header"></div>' ) . appendTo ( outer ) ;
entry . header = $ ( '<span>' ) . text ( entry . name || "Add new remote" ) . appendTo ( header ) ;
var body = $ ( '<div>' ) . appendTo ( outer ) ;
entry . body = body ;
if ( entry . name ) {
entry . removeButton = $ ( '<button class="editor-button editor-button-small projects-dialog-remote-list-entry-delete">remove</button>' )
. hide ( )
. appendTo ( header )
. click ( function ( e ) {
entry . removed = true ;
body . fadeOut ( 100 ) ;
entry . header . css ( "text-decoration" , "line-through" )
entry . header . css ( "font-style" , "italic" )
$ ( this ) . hide ( ) ;
} ) ;
if ( entry . urls . fetch === entry . urls . push ) {
row = $ ( '<div class="user-settings-row"></div>' ) . appendTo ( body ) ;
$ ( '<label for=""></label>' ) . text ( 'URL' ) . appendTo ( row ) ;
$ ( '<div class="uneditable-input">' ) . text ( entry . urls . fetch ) . appendTo ( row ) ;
} else {
row = $ ( '<div class="user-settings-row"></div>' ) . appendTo ( body ) ;
$ ( '<label for=""></label>' ) . text ( 'Fetch URL' ) . appendTo ( row ) ;
$ ( '<div class="uneditable-input">' ) . text ( entry . urls . fetch ) . appendTo ( row ) ;
row = $ ( '<div class="user-settings-row"></div>' ) . appendTo ( body ) ;
$ ( '<label for=""></label>' ) . text ( 'Push URL' ) . appendTo ( row ) ;
$ ( '<div class="uneditable-input">' ) . text ( entry . urls . push ) . appendTo ( row ) ;
}
} else {
row = $ ( '<div class="user-settings-row"></div>' ) . appendTo ( body ) ;
$ ( '<label for=""></label>' ) . text ( 'Remote name' ) . appendTo ( row ) ;
entry . nameInput = $ ( '<input type="text">' ) . appendTo ( row ) ;
2017-11-22 00:31:41 +01:00
2017-12-04 12:42:44 +01:00
row = $ ( '<div class="user-settings-row"></div>' ) . appendTo ( body ) ;
var fetchLabel = $ ( '<label for=""></label>' ) . text ( 'URL' ) . appendTo ( row ) ;
entry . urlInput = $ ( '<input type="text">' ) . appendTo ( row ) ;
}
}
} ) ;
2017-11-22 00:31:41 +01:00
2017-12-04 12:42:44 +01:00
var remoteListAddButton = row . find ( ".red-ui-editableList-addButton" ) . hide ( ) ;
2017-11-22 00:31:41 +01:00
var hideEditForm = function ( ) {
editRepoButton . show ( ) ;
formButtons . hide ( ) ;
2017-12-04 12:42:44 +01:00
$ ( '.projects-dialog-remote-list-entry-delete' ) . hide ( ) ;
remoteListAddButton . hide ( ) ;
2017-11-22 00:31:41 +01:00
}
2017-12-04 12:42:44 +01:00
var formButtons = $ ( '<span class="button-group" style="position: relative; float: right; margin-right:0;"></span>' )
. hide ( ) . appendTo ( repoContainer ) ;
2017-11-22 00:31:41 +01:00
$ ( '<button class="editor-button">Cancel</button>' )
. appendTo ( formButtons )
. click ( function ( evt ) {
evt . preventDefault ( ) ;
2017-12-04 12:42:44 +01:00
var items = remotesList . editableList ( 'items' ) ;
items . each ( function ( ) {
var data = $ ( this ) . data ( 'data' ) ;
if ( ! data . name ) {
remotesList . editableList ( 'removeItem' , data ) ;
} else if ( data . removed ) {
delete data . removed ;
data . body . show ( ) ;
data . header . css ( "text-decoration" , "" ) ;
data . header . css ( "font-style" , "" ) ;
}
} )
2017-11-22 00:31:41 +01:00
hideEditForm ( ) ;
} ) ;
var saveButton = $ ( '<button class="editor-button">Save</button>' )
. appendTo ( formButtons )
. click ( function ( evt ) {
evt . preventDefault ( ) ;
2017-12-04 12:42:44 +01:00
var spinner = utils . addSpinnerOverlay ( repoContainer ) ;
var body = {
remotes : { }
}
var items = remotesList . editableList ( 'items' ) ;
items . each ( function ( ) {
var data = $ ( this ) . data ( 'data' ) ;
if ( ! data . name ) {
body . remotes [ data . nameInput . val ( ) ] = {
url : data . urlInput . val ( )
} ;
remotesList . editableList ( 'removeItem' , data ) ;
} else if ( data . removed ) {
body . remotes [ data . name ] = {
removed : true
} ;
delete data . removed ;
data . body . show ( ) ;
data . header . css ( "text-decoration" , "" ) ;
data . header . css ( "font-style" , "" ) ;
}
} )
var done = function ( err ) {
spinner . remove ( ) ;
if ( err ) {
console . log ( err ) ;
return ;
}
hideEditForm ( ) ;
}
var payload = { git : body } ;
// console.log(JSON.stringify(payload,null,4));
RED . deploy . setDeployInflight ( true ) ;
utils . sendRequest ( {
url : "projects/" + activeProject . name ,
type : "PUT" ,
responses : {
0 : function ( error ) {
done ( error ) ;
} ,
200 : function ( data ) {
activeProject . git . remotes = data . git . remotes ;
updateForm ( ) ;
done ( ) ;
} ,
400 : {
'unexpected_error' : function ( error ) {
console . log ( error ) ;
done ( error ) ;
}
} ,
}
} , payload ) ;
2017-11-22 00:31:41 +01:00
} ) ;
2017-12-04 12:42:44 +01:00
var updateForm = function ( ) {
remotesList . editableList ( 'empty' ) ;
if ( activeProject . git . hasOwnProperty ( 'remotes' ) ) {
for ( var name in activeProject . git . remotes ) {
if ( activeProject . git . remotes . hasOwnProperty ( name ) ) {
remotesList . editableList ( 'addItem' , { name : name , urls : activeProject . git . remotes [ name ] } ) ;
}
}
}
}
updateForm ( ) ;
2017-11-22 00:31:41 +01:00
}
2017-10-19 22:38:53 +02:00
function createSettingsPane ( activeProject ) {
var pane = $ ( '<div id="project-settings-tab-settings" class="project-settings-tab-pane node-help"></div>' ) ;
createFilesSection ( activeProject , pane ) ;
2017-11-22 00:31:41 +01:00
// createLocalRepositorySection(activeProject,pane);
createRemoteRepositorySection ( activeProject , pane ) ;
2017-09-26 23:51:08 +02:00
return pane ;
}
var popover ;
2017-09-20 23:51:28 +02:00
var utils ;
2017-09-21 12:19:24 +02:00
var modulesInUse = { } ;
2017-09-20 23:51:28 +02:00
function init ( _utils ) {
utils = _utils ;
addPane ( {
id : 'main' ,
2017-09-21 12:19:24 +02:00
title : "Project" , // TODO: nls
get : createMainPane ,
2017-09-20 23:51:28 +02:00
close : function ( ) { }
2017-09-21 12:19:24 +02:00
} ) ;
addPane ( {
id : 'deps' ,
title : "Dependencies" , // TODO: nls
get : createDependenciesPane ,
close : function ( ) { }
} ) ;
2017-09-26 23:51:08 +02:00
addPane ( {
id : 'settings' ,
title : "Settings" , // TODO: nls
get : createSettingsPane ,
close : function ( ) {
if ( popover ) {
popover . close ( ) ;
popover = null ;
}
}
} ) ;
2017-09-21 12:19:24 +02:00
RED . events . on ( 'nodes:add' , function ( n ) {
if ( ! /^subflow:/ . test ( n . type ) ) {
var module = RED . nodes . registry . getNodeSetForType ( n . type ) . module ;
if ( module !== 'node-red' ) {
if ( ! modulesInUse . hasOwnProperty ( module ) ) {
modulesInUse [ module ] = {
module : module ,
version : RED . nodes . registry . getModule ( module ) . version ,
count : 0 ,
known : false
}
}
modulesInUse [ module ] . count ++ ;
}
}
2017-09-20 23:51:28 +02:00
} )
2017-09-21 12:19:24 +02:00
RED . events . on ( 'nodes:remove' , function ( n ) {
if ( ! /^subflow:/ . test ( n . type ) ) {
var module = RED . nodes . registry . getNodeSetForType ( n . type ) . module ;
if ( module !== 'node-red' && modulesInUse . hasOwnProperty ( module ) ) {
modulesInUse [ module ] . count -- ;
if ( modulesInUse [ module ] . count === 0 ) {
if ( ! modulesInUse [ module ] . known ) {
delete modulesInUse [ module ] ;
}
}
}
}
} )
2017-09-20 23:51:28 +02:00
}
return {
init : init ,
2017-09-26 23:51:08 +02:00
show : show ,
switchProject : function ( name ) {
// TODO: not ideal way to trigger this; should there be an editor-wide event?
modulesInUse = { } ;
}
2017-09-20 23:51:28 +02:00
} ;
} ) ( ) ;