mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Allow a project to be located below the root of repo
This commit is contained in:
		| @@ -135,7 +135,12 @@ | |||||||
|             "updated": "Project '__project__' updated", |             "updated": "Project '__project__' updated", | ||||||
|             "pull": "Project '__project__' reloaded", |             "pull": "Project '__project__' reloaded", | ||||||
|             "revert": "Project '__project__' reverted", |             "revert": "Project '__project__' reverted", | ||||||
|             "merge-complete": "Git merge completed" |             "merge-complete": "Git merge completed", | ||||||
|  |             "setupCredentials": "Setup credentials", | ||||||
|  |             "setupProjectFiles": "Setup project files", | ||||||
|  |             "no": "No thanks", | ||||||
|  |             "createDefault": "Create default project files", | ||||||
|  |             "mergeConflict": "Show merge conflicts" | ||||||
|         }, |         }, | ||||||
|         "label": { |         "label": { | ||||||
|             "manage-project-dep": "Manage project dependencies", |             "manage-project-dep": "Manage project dependencies", | ||||||
| @@ -544,14 +549,19 @@ | |||||||
|                 "removeFromProject": "remove from project", |                 "removeFromProject": "remove from project", | ||||||
|                 "addToProject": "add to project", |                 "addToProject": "add to project", | ||||||
|                 "files": "Files", |                 "files": "Files", | ||||||
|  |                 "package": "Package", | ||||||
|                 "flow": "Flow", |                 "flow": "Flow", | ||||||
|                 "credentials": "Credentials", |                 "credentials": "Credentials", | ||||||
|  |                 "package":"Package", | ||||||
|  |                 "packageCreate":"File will be created when changes are saved", | ||||||
|  |                 "fileNotExist":"File does not exist", | ||||||
|  |                 "selectFile": "Select File", | ||||||
|                 "invalidEncryptionKey": "Invalid encryption key", |                 "invalidEncryptionKey": "Invalid encryption key", | ||||||
|                 "encryptionEnabled": "Encryption enabled", |                 "encryptionEnabled": "Encryption enabled", | ||||||
|                 "encryptionDisabled": "Encryption disabled", |                 "encryptionDisabled": "Encryption disabled", | ||||||
|                 "setTheEncryptionKey": "Set the encryption key:", |                 "setTheEncryptionKey": "Set the encryption key", | ||||||
|                 "resetTheEncryptionKey": "Reset the encryption key:", |                 "resetTheEncryptionKey": "Reset the encryption key", | ||||||
|                 "changeTheEncryptionKey": "Change the encryption key:", |                 "changeTheEncryptionKey": "Change the encryption key", | ||||||
|                 "currentKey": "Current key", |                 "currentKey": "Current key", | ||||||
|                 "newKey": "New key", |                 "newKey": "New key", | ||||||
|                 "credentialsAlert": "This will delete all existing credentials", |                 "credentialsAlert": "This will delete all existing credentials", | ||||||
|   | |||||||
| @@ -211,7 +211,7 @@ var RED = (function() { | |||||||
|                             } |                             } | ||||||
|                         ] |                         ] | ||||||
|                     } else if (msg.error === "missing-types") { |                     } else if (msg.error === "missing-types") { | ||||||
|                         text+="<ul><li>"+msg.types.join("</li><li>")+"</li></ul>"; |                         text+="<ul><li>"+msg.types.map(RED.utils.sanitize).join("</li><li>")+"</li></ul>"; | ||||||
|                         if (!!RED.projects.getActiveProject()) { |                         if (!!RED.projects.getActiveProject()) { | ||||||
|                             options.buttons = [ |                             options.buttons = [ | ||||||
|                                 { |                                 { | ||||||
| @@ -239,7 +239,7 @@ var RED = (function() { | |||||||
|                             if (RED.user.hasPermission("projects.write")) { |                             if (RED.user.hasPermission("projects.write")) { | ||||||
|                                 options.buttons = [ |                                 options.buttons = [ | ||||||
|                                     { |                                     { | ||||||
|                                         text: "Setup credentials", |                                         text: RED._("notification.project.setupCredentials"), | ||||||
|                                         click: function() { |                                         click: function() { | ||||||
|                                             persistentNotifications[notificationId].hideNotification(); |                                             persistentNotifications[notificationId].hideNotification(); | ||||||
|                                             RED.projects.showCredentialsPrompt(); |                                             RED.projects.showCredentialsPrompt(); | ||||||
| @@ -250,7 +250,7 @@ var RED = (function() { | |||||||
|                         } else { |                         } else { | ||||||
|                             options.buttons = [ |                             options.buttons = [ | ||||||
|                                 { |                                 { | ||||||
|                                     text: "Close", |                                     text: RED._("common.label.close"), | ||||||
|                                     click: function() { |                                     click: function() { | ||||||
|                                         persistentNotifications[notificationId].hideNotification(); |                                         persistentNotifications[notificationId].hideNotification(); | ||||||
|                                     } |                                     } | ||||||
| @@ -261,7 +261,7 @@ var RED = (function() { | |||||||
|                         if (RED.user.hasPermission("projects.write")) { |                         if (RED.user.hasPermission("projects.write")) { | ||||||
|                             options.buttons = [ |                             options.buttons = [ | ||||||
|                                 { |                                 { | ||||||
|                                     text: "Setup project files", |                                     text: RED._("notification.project.setupProjectFiles"), | ||||||
|                                     click: function() { |                                     click: function() { | ||||||
|                                         persistentNotifications[notificationId].hideNotification(); |                                         persistentNotifications[notificationId].hideNotification(); | ||||||
|                                         RED.projects.showFilesPrompt(); |                                         RED.projects.showFilesPrompt(); | ||||||
| @@ -273,10 +273,10 @@ var RED = (function() { | |||||||
|                         if (RED.user.hasPermission("projects.write")) { |                         if (RED.user.hasPermission("projects.write")) { | ||||||
|                             options.buttons = [ |                             options.buttons = [ | ||||||
|                                 { |                                 { | ||||||
|                                     text: "Create default package file", |                                     text: RED._("notification.project.setupProjectFiles"), | ||||||
|                                     click: function() { |                                     click: function() { | ||||||
|                                         persistentNotifications[notificationId].hideNotification(); |                                         persistentNotifications[notificationId].hideNotification(); | ||||||
|                                         RED.projects.createDefaultPackageFile(); |                                         RED.projects.showFilesPrompt(); | ||||||
|                                     } |                                     } | ||||||
|                                 } |                                 } | ||||||
|                             ] |                             ] | ||||||
| @@ -285,13 +285,13 @@ var RED = (function() { | |||||||
|                         if (RED.user.hasPermission("projects.write")) { |                         if (RED.user.hasPermission("projects.write")) { | ||||||
|                             options.buttons = [ |                             options.buttons = [ | ||||||
|                                 { |                                 { | ||||||
|                                     text: "No thanks", |                                     text: RED._("notification.project.no"), | ||||||
|                                     click: function() { |                                     click: function() { | ||||||
|                                         persistentNotifications[notificationId].hideNotification(); |                                         persistentNotifications[notificationId].hideNotification(); | ||||||
|                                     } |                                     } | ||||||
|                                 }, |                                 }, | ||||||
|                                 { |                                 { | ||||||
|                                     text: "Create default project files", |                                     text: RED._("notification.project.createDefault"), | ||||||
|                                     click: function() { |                                     click: function() { | ||||||
|                                         persistentNotifications[notificationId].hideNotification(); |                                         persistentNotifications[notificationId].hideNotification(); | ||||||
|                                         RED.projects.createDefaultFileSet(); |                                         RED.projects.createDefaultFileSet(); | ||||||
| @@ -305,7 +305,7 @@ var RED = (function() { | |||||||
|                         if (RED.user.hasPermission("projects.write")) { |                         if (RED.user.hasPermission("projects.write")) { | ||||||
|                             options.buttons = [ |                             options.buttons = [ | ||||||
|                                 { |                                 { | ||||||
|                                     text: "Show merge conflicts", |                                     text: RED._("notification.project.mergeConflict"), | ||||||
|                                     click: function() { |                                     click: function() { | ||||||
|                                         persistentNotifications[notificationId].hideNotification(); |                                         persistentNotifications[notificationId].hideNotification(); | ||||||
|                                         RED.sidebar.versionControl.showLocalChanges(); |                                         RED.sidebar.versionControl.showLocalChanges(); | ||||||
|   | |||||||
| @@ -526,7 +526,7 @@ RED.projects.settings = (function() { | |||||||
|  |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     function showProjectFileListing(row,activeProject,current,filter,done) { |     function showProjectFileListing(row,activeProject,current,selectFilter,done) { | ||||||
|         var dialog; |         var dialog; | ||||||
|         var dialogBody; |         var dialogBody; | ||||||
|         var filesList; |         var filesList; | ||||||
| @@ -569,14 +569,15 @@ RED.projects.settings = (function() { | |||||||
|                 }) |                 }) | ||||||
|                 return result; |                 return result; | ||||||
|             } |             } | ||||||
|             var files = sortFiles("",files,""); |             var files = sortFiles("",files,"") | ||||||
|             createFileSubList(container,files.children,current,filter,done,"height: 175px"); |  | ||||||
|  |             createFileSubList(container,files.children,current,selectFilter,done,"height: 175px"); | ||||||
|             spinner.remove(); |             spinner.remove(); | ||||||
|         }); |         }); | ||||||
|         return container; |         return container; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     function createFileSubList(container, files, current, filter, onselect, style) { |     function createFileSubList(container, files, current, selectFilter, onselect, style) { | ||||||
|         style = style || ""; |         style = style || ""; | ||||||
|         var list = $('<ol>',{class:"projects-dialog-file-list", style:style}).appendTo(container).editableList({ |         var list = $('<ol>',{class:"projects-dialog-file-list", style:style}).appendTo(container).editableList({ | ||||||
|             addButton: false, |             addButton: false, | ||||||
| @@ -592,7 +593,7 @@ RED.projects.settings = (function() { | |||||||
|                         } else { |                         } else { | ||||||
|                             children.hide(); |                             children.hide(); | ||||||
|                         } |                         } | ||||||
|                         createFileSubList(children,entry.children,current,filter,onselect); |                         createFileSubList(children,entry.children,current,selectFilter,onselect); | ||||||
|                         header.addClass("selectable"); |                         header.addClass("selectable"); | ||||||
|                         header.click(function(e) { |                         header.click(function(e) { | ||||||
|                             if ($(this).hasClass("expanded")) { |                             if ($(this).hasClass("expanded")) { | ||||||
| @@ -618,7 +619,7 @@ RED.projects.settings = (function() { | |||||||
|                         header.addClass("projects-dialog-file-list-entry-file-type-git"); |                         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); |                     $('<span class="projects-dialog-file-list-entry-file"> <i class="fa '+fileIcon+'"></i></span>').appendTo(header); | ||||||
|                     if (filter.test(entry.name)) { |                     if (selectFilter(entry)) { | ||||||
|                         header.addClass("selectable"); |                         header.addClass("selectable"); | ||||||
|                         if (entry.path === current) { |                         if (entry.path === current) { | ||||||
|                             header.addClass("selected"); |                             header.addClass("selected"); | ||||||
| @@ -626,7 +627,7 @@ RED.projects.settings = (function() { | |||||||
|                         header.click(function(e) { |                         header.click(function(e) { | ||||||
|                             $(".projects-dialog-file-list-entry.selected").removeClass("selected"); |                             $(".projects-dialog-file-list-entry.selected").removeClass("selected"); | ||||||
|                             $(this).addClass("selected"); |                             $(this).addClass("selected"); | ||||||
|                             onselect(entry.path); |                             onselect(entry.path,true); | ||||||
|                         }) |                         }) | ||||||
|                         header.dblclick(function(e) { |                         header.dblclick(function(e) { | ||||||
|                             e.preventDefault(); |                             e.preventDefault(); | ||||||
| @@ -730,18 +731,27 @@ RED.projects.settings = (function() { | |||||||
|         var title = $('<h3></h3>').text(RED._("sidebar.project.projectSettings.files")).appendTo(pane); |         var title = $('<h3></h3>').text(RED._("sidebar.project.projectSettings.files")).appendTo(pane); | ||||||
|         var filesContainer = $('<div class="user-settings-section"></div>').appendTo(pane); |         var filesContainer = $('<div class="user-settings-section"></div>').appendTo(pane); | ||||||
|         if (RED.user.hasPermission("projects.write")) { |         if (RED.user.hasPermission("projects.write")) { | ||||||
|             var editFilesButton = $('<button class="editor-button editor-button-small" style="float: right;">' + RED._('sidebar.project.projectSettings.edit') + '</button>') |             var editFilesButton = $('<button type="button" id="project-settings-tab-settings-file-edit" class="editor-button editor-button-small" style="float: right;">' + RED._('sidebar.project.projectSettings.edit') + '</button>') | ||||||
|                 .appendTo(title) |                 .appendTo(title) | ||||||
|                 .click(function(evt) { |                 .click(function(evt) { | ||||||
|                     evt.preventDefault(); |                     evt.preventDefault(); | ||||||
|                     formButtons.show(); |                     formButtons.show(); | ||||||
|                     editFilesButton.hide(); |                     editFilesButton.hide(); | ||||||
|  |                     // packageFileLabelText.hide(); | ||||||
|  |  | ||||||
|  |                     if (!activeProject.files.package) { | ||||||
|  |                         packageFileSubLabel.find(".projects-edit-form-sublabel-text").text(RED._("sidebar.project.projectSettings.packageCreate")); | ||||||
|  |                         packageFileSubLabel.show(); | ||||||
|  |                     } | ||||||
|  |  | ||||||
|  |                     packageFileInputSearch.show(); | ||||||
|  |                     // packageFileInputCreate.show(); | ||||||
|                     flowFileLabelText.hide(); |                     flowFileLabelText.hide(); | ||||||
|                     flowFileInput.show(); |                     flowFileInput.show(); | ||||||
|                     flowFileInputSearch.show(); |                     flowFileInputSearch.show(); | ||||||
|                     credFileLabel.hide(); |  | ||||||
|                     credFileInput.show(); |                     flowFileInputResize(); | ||||||
|                     flowFileInput.focus(); |  | ||||||
|                     // credentialStateLabel.parent().hide(); |                     // credentialStateLabel.parent().hide(); | ||||||
|                     credentialStateLabel.addClass("uneditable-input"); |                     credentialStateLabel.addClass("uneditable-input"); | ||||||
|                     $(".user-settings-row-credentials").show(); |                     $(".user-settings-row-credentials").show(); | ||||||
| @@ -752,14 +762,76 @@ RED.projects.settings = (function() { | |||||||
|         } |         } | ||||||
|         var row; |         var row; | ||||||
|  |  | ||||||
|  |         // Flow files | ||||||
|  |         row = $('<div class="user-settings-row"></div>').appendTo(filesContainer); | ||||||
|  |         $('<label for=""></label>').text(RED._("sidebar.project.projectSettings.package")).appendTo(row); | ||||||
|  |         var packageFileLabel = $('<div class="uneditable-input" style="padding:0">').appendTo(row); | ||||||
|  |         var packageFileLabelPrefixText = $('<span style="display:inline-block; padding: 6px 0 6px 6px">').text("/").appendTo(packageFileLabel); | ||||||
|  |         var packageFileLabelText = $('<span style="display:inline-block;  padding: 6px 6px 6px 0">').text(activeProject.files.package||"package.json").appendTo(packageFileLabel); | ||||||
|  |         var packageFileInput = $('<input type="hidden">').val(activeProject.files.package||"package.json").appendTo(packageFileLabel); | ||||||
|  |  | ||||||
|  |         var packageFileInputSearch = $('<button type="button" class="editor-button toggle single" 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>') | ||||||
|  |             .hide() | ||||||
|  |             .appendTo(packageFileLabel) | ||||||
|  |             .click(function(e) { | ||||||
|  |                 if ($(this).hasClass('selected')) { | ||||||
|  |                     $(this).removeClass('selected'); | ||||||
|  |                     packageFileLabel.find('.project-file-listing-container').slideUp(200,function() { | ||||||
|  |                          $(this).remove(); | ||||||
|  |                          packageFileLabel.css('height',''); | ||||||
|  |                      }); | ||||||
|  |                     packageFileLabel.css('color',''); | ||||||
|  |                 } else { | ||||||
|  |                     $(this).addClass('selected'); | ||||||
|  |                     packageFileLabel.css('color','inherit'); | ||||||
|  |                     var fileList = showProjectFileListing(packageFileLabel,activeProject,packageFileInput.val(), | ||||||
|  |                                         function(entry) { return entry.children || /package\.json$/.test(entry.path); }, | ||||||
|  |                                         function(result,close) { | ||||||
|  |                                             if (result) { | ||||||
|  |                                                 packageFileInput.val(result); | ||||||
|  |                                                 packageFileLabelText.text(result); | ||||||
|  |                                                 var rootDir = result.substring(0,result.length - 12); | ||||||
|  |                                                 flowFileLabelPrefixText.text("/"+rootDir); | ||||||
|  |                                                 credFileLabelPrefixText.text("/"+rootDir); | ||||||
|  |                                                 flowFileInputResize(); | ||||||
|  |                                                 packageFileSubLabel.hide(); | ||||||
|  |                                             } | ||||||
|  |                                             if (close) { | ||||||
|  |                                                 $(packageFileInputSearch).click(); | ||||||
|  |                                             } | ||||||
|  |                                             checkFiles(); | ||||||
|  |                                         }); | ||||||
|  |                     packageFileLabel.css('height','auto'); | ||||||
|  |                     setTimeout(function() { | ||||||
|  |                         fileList.slideDown(200); | ||||||
|  |                     },50); | ||||||
|  |  | ||||||
|  |                 } | ||||||
|  |             }) | ||||||
|  |         RED.popover.tooltip(packageFileInputSearch,RED._("sidebar.project.projectSettings.selectFile")); | ||||||
|  |         var packageFileSubLabel = $('<label style="margin-left: 110px" class="projects-edit-form-sublabel"><small><span class="form-warning"><i class="fa fa-warning"></i> <span class="projects-edit-form-sublabel-text"></span></small></label>').appendTo(row).hide(); | ||||||
|  |         if (!activeProject.files.package) { | ||||||
|  |             packageFileSubLabel.find(".projects-edit-form-sublabel-text").text(RED._("sidebar.project.projectSettings.fileNotExist")); | ||||||
|  |             packageFileSubLabel.show(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         var projectPackage = "/"+(activeProject.files.package||"package.json"); | ||||||
|  |         var projectRoot = projectPackage.substring(0,projectPackage.length - 12); | ||||||
|  |  | ||||||
|         // Flow files |         // Flow files | ||||||
|         row = $('<div class="user-settings-row"></div>').appendTo(filesContainer); |         row = $('<div class="user-settings-row"></div>').appendTo(filesContainer); | ||||||
|         $('<label for=""></label>').text(RED._("sidebar.project.projectSettings.flow")).appendTo(row); |         $('<label for=""></label>').text(RED._("sidebar.project.projectSettings.flow")).appendTo(row); | ||||||
|         var flowFileLabel = $('<div class="uneditable-input" style="padding:0">').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 flowFileLabelPrefixText = $('<span style="display:inline-block; padding: 6px 0 6px 6px">').text(projectRoot).appendTo(flowFileLabel); | ||||||
|  |         var flowFileLabelText = $('<span style="display:inline-block; padding: 6px 6px 6px 0">').text(activeProject.files.flow||"flows.json").appendTo(flowFileLabel); | ||||||
|         var flowFileInput = $('<input id="" type="text" style="margin-bottom: 0;width: 100%; border: none;">').val(activeProject.files.flow).hide().appendTo(flowFileLabel); |         var flowFileInputResize = function() { | ||||||
|         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>') |             flowFileInput.css({ | ||||||
|  |                 "width": "calc(100% - "+(flowFileInputSearch.width() + flowFileLabelPrefixText.width())+"px)" | ||||||
|  |             }); | ||||||
|  |         } | ||||||
|  |         var flowFileInput = $('<input type="text" style="padding-left:1px; margin-top: -2px; margin-bottom: 0;border: none;">').val(activeProject.files.flow||"flows.json").hide().appendTo(flowFileLabel); | ||||||
|  |         var flowFileInputSearch = $('<button type="button" class="editor-button toggle single" 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>') | ||||||
|             .hide() |             .hide() | ||||||
|             .appendTo(flowFileLabel) |             .appendTo(flowFileLabel) | ||||||
|             .click(function(e) { |             .click(function(e) { | ||||||
| @@ -773,15 +845,24 @@ RED.projects.settings = (function() { | |||||||
|                 } else { |                 } else { | ||||||
|                     $(this).addClass('selected'); |                     $(this).addClass('selected'); | ||||||
|                     flowFileLabel.css('color','inherit'); |                     flowFileLabel.css('color','inherit'); | ||||||
|                     var fileList = showProjectFileListing(flowFileLabel,activeProject,flowFileInput.val(), /.*\.json$/,function(result,isDblClick) { |                     var packageFile = packageFileInput.val(); | ||||||
|  |                     var packagePrefix = packageFile.substring(0,packageFile.length - 12); | ||||||
|  |                     var re = new RegExp("^"+packagePrefix+".*\.json$"); | ||||||
|  |                     var fileList = showProjectFileListing(flowFileLabel, | ||||||
|  |                                                           activeProject, | ||||||
|  |                                                           flowFileInput.val(), | ||||||
|  |                                                           function(entry) { return !/package.json$/.test(entry.path) && re.test(entry.path) && !/_cred\.json$/.test(entry.path) }, | ||||||
|  |                                                           function(result,isDblClick) { | ||||||
|                                                               if (result) { |                                                               if (result) { | ||||||
|                             flowFileInput.val(result); |                                                                   flowFileInput.val(result.substring(packagePrefix.length)); | ||||||
|  |  | ||||||
|                                                               } |                                                               } | ||||||
|                                                               if (isDblClick) { |                                                               if (isDblClick) { | ||||||
|                                                                   $(flowFileInputSearch).click(); |                                                                   $(flowFileInputSearch).click(); | ||||||
|                                                               } |                                                               } | ||||||
|                                                               checkFiles(); |                                                               checkFiles(); | ||||||
|                     }); |                                                           } | ||||||
|  |                                                       ); | ||||||
|                     flowFileLabel.css('height','auto'); |                     flowFileLabel.css('height','auto'); | ||||||
|                     setTimeout(function() { |                     setTimeout(function() { | ||||||
|                         fileList.slideDown(200); |                         fileList.slideDown(200); | ||||||
| @@ -789,26 +870,32 @@ RED.projects.settings = (function() { | |||||||
|  |  | ||||||
|                 } |                 } | ||||||
|             }) |             }) | ||||||
|  |         RED.popover.tooltip(flowFileInputSearch,RED._("sidebar.project.projectSettings.selectFile")); | ||||||
|  |  | ||||||
|         row = $('<div class="user-settings-row"></div>').appendTo(filesContainer); |         row = $('<div class="user-settings-row"></div>').appendTo(filesContainer); | ||||||
|         $('<label for=""></label>').text(RED._("sidebar.project.projectSettings.credentials")).appendTo(row); |         $('<label for=""></label>').text(RED._("sidebar.project.projectSettings.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 credFileLabel = $('<div class="uneditable-input" style="padding:0">').appendTo(row); | ||||||
|  |         var credFileLabelPrefixText = $('<span style="display:inline-block;padding: 6px 0 6px 6px">').text(projectRoot).appendTo(credFileLabel); | ||||||
|  |         var credFileLabelText = $('<span style="display:inline-block; padding: 6px 6px 6px 0">').text(activeProject.files.credentials||"flows_cred.json").appendTo(credFileLabel); | ||||||
|  |  | ||||||
|  |         var credFileInput = $('<input type="hidden">').val(activeProject.files.credentials||"flows_cred.json").insertAfter(credFileLabel); | ||||||
|  |  | ||||||
|         var checkFiles = function() { |         var checkFiles = function() { | ||||||
|             var saveDisabled; |             var saveDisabled; | ||||||
|             var currentFlowValue = flowFileInput.val(); |             var currentFlowValue = flowFileInput.val(); | ||||||
|             var m = /^(.+?)(\.[^.]*)?$/.exec(currentFlowValue); |             var m = /^(.+?)(\.[^.]*)?$/.exec(currentFlowValue); | ||||||
|             if (m) { |             if (m) { | ||||||
|                 credFileInput.text(m[1]+"_cred"+(m[2]||".json")); |                 credFileLabelText.text(m[1]+"_cred"+(m[2]||".json")); | ||||||
|             } else if (currentFlowValue === "") { |             } else if (currentFlowValue === "") { | ||||||
|                 credFileInput.text(""); |                 credFileLabelText.text(""); | ||||||
|             } |             } | ||||||
|  |             credFileInput.val(credFileLabelText.text()); | ||||||
|             var isFlowInvalid = currentFlowValue==="" || |             var isFlowInvalid = currentFlowValue==="" || | ||||||
|                                 /\.\./.test(currentFlowValue) || |                                 /\.\./.test(currentFlowValue) || | ||||||
|                                 /\/$/.test(currentFlowValue); |                                 /\/$/.test(currentFlowValue); | ||||||
|  |  | ||||||
|             saveDisabled = isFlowInvalid || credFileInput.text()===""; |             saveDisabled = isFlowInvalid || credFileLabelText.text()===""; | ||||||
|  |  | ||||||
|             if (credentialSecretExistingInput.is(":visible")) { |             if (credentialSecretExistingInput.is(":visible")) { | ||||||
|                 credentialSecretExistingInput.toggleClass("input-error", credentialSecretExistingInput.val() === ""); |                 credentialSecretExistingInput.toggleClass("input-error", credentialSecretExistingInput.val() === ""); | ||||||
| @@ -821,19 +908,22 @@ RED.projects.settings = (function() { | |||||||
|  |  | ||||||
|  |  | ||||||
|             flowFileInput.toggleClass("input-error", isFlowInvalid); |             flowFileInput.toggleClass("input-error", isFlowInvalid); | ||||||
|             credFileInput.toggleClass("input-error",credFileInput.text()===""); |             // credFileInput.toggleClass("input-error",credFileInput.text()===""); | ||||||
|             saveButton.toggleClass('disabled',saveDisabled); |             saveButton.toggleClass('disabled',saveDisabled); | ||||||
|             saveButton.prop('disabled',saveDisabled); |             saveButton.prop('disabled',saveDisabled); | ||||||
|         } |         } | ||||||
|         flowFileInput.on("change keyup paste",checkFiles); |         flowFileInput.on("change keyup paste",checkFiles); | ||||||
|  |  | ||||||
|  |  | ||||||
|         if (!activeProject.files.flow) { |         // if (!activeProject.files.package) { | ||||||
|             $('<span class="form-warning"><i class="fa fa-warning"></i> Missing</span>').appendTo(flowFileLabelText); |         //     $('<span class="form-warning"><i class="fa fa-warning"></i> Missing</span>').appendTo(packageFileLabelText); | ||||||
|         } |         // } | ||||||
|         if (!activeProject.files.credentials) { |         // if (!activeProject.files.flow) { | ||||||
|             $('<span class="form-warning"><i class="fa fa-warning"></i> Missing</span>').appendTo(credFileLabel); |         //     $('<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); | ||||||
|  |         // } | ||||||
|  |  | ||||||
|  |  | ||||||
|         row = $('<div class="user-settings-row"></div>').appendTo(filesContainer); |         row = $('<div class="user-settings-row"></div>').appendTo(filesContainer); | ||||||
| @@ -844,7 +934,7 @@ RED.projects.settings = (function() { | |||||||
|  |  | ||||||
|         credentialStateLabel.css('color','#666'); |         credentialStateLabel.css('color','#666'); | ||||||
|         credentialSecretButtons.css('vertical-align','top'); |         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>') |         var credentialSecretResetButton = $('<button type="button" class="editor-button" style="vertical-align: top; width: 36px; margin-bottom: 10px"><i class="fa fa-trash-o"></i></button>') | ||||||
|             .appendTo(credentialSecretButtons) |             .appendTo(credentialSecretButtons) | ||||||
|             .click(function(e) { |             .click(function(e) { | ||||||
|                 e.preventDefault(); |                 e.preventDefault(); | ||||||
| @@ -866,7 +956,9 @@ RED.projects.settings = (function() { | |||||||
|                 } |                 } | ||||||
|                 checkFiles(); |                 checkFiles(); | ||||||
|             }); |             }); | ||||||
|         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>') |         RED.popover.tooltip(credentialSecretResetButton,RED._("sidebar.project.projectSettings.resetTheEncryptionKey")); | ||||||
|  |  | ||||||
|  |         var credentialSecretEditButton = $('<button type="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>') | ||||||
|             .appendTo(credentialSecretButtons) |             .appendTo(credentialSecretButtons) | ||||||
|             .click(function(e) { |             .click(function(e) { | ||||||
|                 e.preventDefault(); |                 e.preventDefault(); | ||||||
| @@ -896,6 +988,7 @@ RED.projects.settings = (function() { | |||||||
|                 checkFiles(); |                 checkFiles(); | ||||||
|             }) |             }) | ||||||
|  |  | ||||||
|  |         RED.popover.tooltip(credentialSecretEditButton,RED._("sidebar.project.projectSettings.changeTheEncryptionKey")); | ||||||
|  |  | ||||||
|         row = $('<div class="user-settings-row user-settings-row-credentials"></div>').hide().appendTo(filesContainer); |         row = $('<div class="user-settings-row user-settings-row-credentials"></div>').hide().appendTo(filesContainer); | ||||||
|  |  | ||||||
| @@ -930,11 +1023,13 @@ RED.projects.settings = (function() { | |||||||
|         var hideEditForm = function() { |         var hideEditForm = function() { | ||||||
|             editFilesButton.show(); |             editFilesButton.show(); | ||||||
|             formButtons.hide(); |             formButtons.hide(); | ||||||
|  |             // packageFileLabelText.show(); | ||||||
|  |             packageFileInputSearch.hide(); | ||||||
|  |             // packageFileInputCreate.hide(); | ||||||
|             flowFileLabelText.show(); |             flowFileLabelText.show(); | ||||||
|             flowFileInput.hide(); |             flowFileInput.hide(); | ||||||
|             flowFileInputSearch.hide(); |             flowFileInputSearch.hide(); | ||||||
|             credFileLabel.show(); |  | ||||||
|             credFileInput.hide(); |  | ||||||
|             // credentialStateLabel.parent().show(); |             // credentialStateLabel.parent().show(); | ||||||
|             credentialStateLabel.removeClass("uneditable-input"); |             credentialStateLabel.removeClass("uneditable-input"); | ||||||
|             credentialStateLabel.css('height',''); |             credentialStateLabel.css('height',''); | ||||||
| @@ -954,13 +1049,26 @@ RED.projects.settings = (function() { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         var formButtons = $('<span class="button-row" style="position: relative; float: right; margin-right:0;"></span>').hide().appendTo(filesContainer); |         var formButtons = $('<span class="button-row" style="position: relative; float: right; margin-right:0;"></span>').hide().appendTo(filesContainer); | ||||||
|         $('<button class="editor-button">' + RED._("common.label.cancel") + '</button>') |         $('<button type="button" class="editor-button">' + RED._("common.label.cancel") + '</button>') | ||||||
|             .appendTo(formButtons) |             .appendTo(formButtons) | ||||||
|             .click(function(evt) { |             .click(function(evt) { | ||||||
|                 evt.preventDefault(); |                 evt.preventDefault(); | ||||||
|  |                 var projectPackage = "/"+(activeProject.files.package||"package.json"); | ||||||
|  |                 var projectRoot = projectPackage.substring(0,projectPackage.length - 12); | ||||||
|  |                 flowFileLabelPrefixText.text(projectRoot); | ||||||
|  |                 credFileLabelPrefixText.text(projectRoot); | ||||||
|  |                 packageFileLabelText.text(activeProject.files.package||"package.json"); | ||||||
|  |                 if (!activeProject.files.package) { | ||||||
|  |                     packageFileSubLabel.find(".projects-edit-form-sublabel-text").text(RED._("sidebar.project.projectSettings.fileNotExist")); | ||||||
|  |                     packageFileSubLabel.show(); | ||||||
|  |                 } else { | ||||||
|  |                     packageFileSubLabel.hide(); | ||||||
|  |                 } | ||||||
|  |                 flowFileInput.val(flowFileLabelText.text()); | ||||||
|  |                 credFileLabelText.text(activeProject.files.credentials||"flows_cred.json"); | ||||||
|                 hideEditForm(); |                 hideEditForm(); | ||||||
|             }); |             }); | ||||||
|         var saveButton = $('<button class="editor-button">' + RED._("common.label.save") + '</button>') |         var saveButton = $('<button type="button" class="editor-button">' + RED._("common.label.save") + '</button>') | ||||||
|             .appendTo(formButtons) |             .appendTo(formButtons) | ||||||
|             .click(function(evt) { |             .click(function(evt) { | ||||||
|                 evt.preventDefault(); |                 evt.preventDefault(); | ||||||
| @@ -972,13 +1080,15 @@ RED.projects.settings = (function() { | |||||||
|                         return; |                         return; | ||||||
|                     } |                     } | ||||||
|                     flowFileLabelText.text(flowFileInput.val()); |                     flowFileLabelText.text(flowFileInput.val()); | ||||||
|                     credFileLabel.text(credFileInput.text()); |                     credFileLabelText.text(credFileInput.val()); | ||||||
|  |                     packageFileSubLabel.hide(); | ||||||
|                     hideEditForm(); |                     hideEditForm(); | ||||||
|                 } |                 } | ||||||
|                 var payload = { |                 var payload = { | ||||||
|                     files: { |                     files: { | ||||||
|                         flow: flowFileInput.val(), |                         flow: flowFileInput.val(), | ||||||
|                         credentials: credFileInput.text() |                         credentials: credFileInput.val(), | ||||||
|  |                         package: packageFileInput.val() | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
| @@ -992,7 +1102,8 @@ RED.projects.settings = (function() { | |||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 // console.log(JSON.stringify(payload,null,4)); |                 console.log(payload); | ||||||
|  |                 return; | ||||||
|                 RED.deploy.setDeployInflight(true); |                 RED.deploy.setDeployInflight(true); | ||||||
|                 utils.sendRequest({ |                 utils.sendRequest({ | ||||||
|                     url: "projects/"+activeProject.name, |                     url: "projects/"+activeProject.name, | ||||||
|   | |||||||
| @@ -2061,7 +2061,6 @@ RED.projects = (function() { | |||||||
|             console.log(xhr); |             console.log(xhr); | ||||||
|             console.log(textStatus); |             console.log(textStatus); | ||||||
|             console.log(err); |             console.log(err); | ||||||
|             console.log(stack); |  | ||||||
|         }).always(function() { |         }).always(function() { | ||||||
|             var delta = Date.now() - start; |             var delta = Date.now() - start; | ||||||
|             delta = Math.max(0,500-delta); |             delta = Math.max(0,500-delta); | ||||||
| @@ -2389,6 +2388,9 @@ RED.projects = (function() { | |||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|             RED.projects.settings.show('settings'); |             RED.projects.settings.show('settings'); | ||||||
|  |             setTimeout(function() { | ||||||
|  |                 $("#project-settings-tab-settings-file-edit").click(); | ||||||
|  |             },200) | ||||||
|         }, |         }, | ||||||
|         showProjectDependencies: function() { |         showProjectDependencies: function() { | ||||||
|             RED.projects.settings.show('deps'); |             RED.projects.settings.show('deps'); | ||||||
|   | |||||||
| @@ -967,6 +967,7 @@ RED.utils = (function() { | |||||||
|         addSpinnerOverlay: addSpinnerOverlay, |         addSpinnerOverlay: addSpinnerOverlay, | ||||||
|         decodeObject: decodeObject, |         decodeObject: decodeObject, | ||||||
|         parseContextKey: parseContextKey, |         parseContextKey: parseContextKey, | ||||||
|         createIconElement: createIconElement |         createIconElement: createIconElement, | ||||||
|  |         sanitize: sanitize | ||||||
|     } |     } | ||||||
| })(); | })(); | ||||||
|   | |||||||
| @@ -60,7 +60,7 @@ | |||||||
| .project-settings-tab-pane { | .project-settings-tab-pane { | ||||||
|     & * .projects-edit-form-sublabel { |     & * .projects-edit-form-sublabel { | ||||||
|         margin-right: 50px; |         margin-right: 50px; | ||||||
|         margin-top: -10px; |         margin-top: -10px !important; | ||||||
|         margin-bottom: 5px; |         margin-bottom: 5px; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -53,6 +53,7 @@ function getGitUser(user) { | |||||||
|     } |     } | ||||||
|     return null; |     return null; | ||||||
| } | } | ||||||
|  |  | ||||||
| function Project(path) { | function Project(path) { | ||||||
|     this.path = path; |     this.path = path; | ||||||
|     this.name = fspath.basename(path); |     this.name = fspath.basename(path); | ||||||
| @@ -72,7 +73,7 @@ Project.prototype.load = function () { | |||||||
|             projectSettings = globalProjectSettings.projects[this.name] || {}; |             projectSettings = globalProjectSettings.projects[this.name] || {}; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |     this.paths.root = projectSettings.rootPath || ""; | ||||||
|     this.credentialSecret = projectSettings.credentialSecret; |     this.credentialSecret = projectSettings.credentialSecret; | ||||||
|     this.git = projectSettings.git || { user:{} }; |     this.git = projectSettings.git || { user:{} }; | ||||||
|  |  | ||||||
| @@ -83,8 +84,8 @@ Project.prototype.load = function () { | |||||||
|     return checkProjectFiles(project).then(function(missingFiles) { |     return checkProjectFiles(project).then(function(missingFiles) { | ||||||
|         project.missingFiles = missingFiles; |         project.missingFiles = missingFiles; | ||||||
|         if (missingFiles.indexOf('package.json') === -1) { |         if (missingFiles.indexOf('package.json') === -1) { | ||||||
|             project.paths['package.json'] = fspath.join(project.path,"package.json"); |             project.paths['package.json'] = fspath.join(project.paths.root,"package.json"); | ||||||
|             promises.push(fs.readFile(project.paths['package.json'],"utf8").then(function(content) { |             promises.push(fs.readFile(fspath.join(project.path,project.paths['package.json']),"utf8").then(function(content) { | ||||||
|                 try { |                 try { | ||||||
|                     project.package = util.parseJSON(content); |                     project.package = util.parseJSON(content); | ||||||
|                     if (project.package.hasOwnProperty('node-red')) { |                     if (project.package.hasOwnProperty('node-red')) { | ||||||
| @@ -101,17 +102,19 @@ Project.prototype.load = function () { | |||||||
|                     project.package = {}; |                     project.package = {}; | ||||||
|                 } |                 } | ||||||
|             })); |             })); | ||||||
|         } else { |  | ||||||
|             project.package = {}; |  | ||||||
|         } |  | ||||||
|             if (missingFiles.indexOf('README.md') === -1) { |             if (missingFiles.indexOf('README.md') === -1) { | ||||||
|             project.paths['README.md'] = fspath.join(project.path,"README.md"); |                 project.paths['README.md'] = fspath.join(project.paths.root,"README.md"); | ||||||
|             promises.push(fs.readFile(project.paths['README.md'],"utf8").then(function(content) { |                 promises.push(fs.readFile(fspath.join(project.path,project.paths['README.md']),"utf8").then(function(content) { | ||||||
|                     project.description = content; |                     project.description = content; | ||||||
|                 })); |                 })); | ||||||
|             } else { |             } else { | ||||||
|                 project.description = ""; |                 project.description = ""; | ||||||
|             } |             } | ||||||
|  |         } else { | ||||||
|  |             project.package = {}; | ||||||
|  |             project.description = ""; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         // if (missingFiles.indexOf('flow.json') !== -1) { |         // if (missingFiles.indexOf('flow.json') !== -1) { | ||||||
|         //     console.log("MISSING FLOW FILE"); |         //     console.log("MISSING FLOW FILE"); | ||||||
|         // } else { |         // } else { | ||||||
| @@ -131,6 +134,10 @@ Project.prototype.load = function () { | |||||||
|     }); |     }); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | Project.prototype.getFilePath = function(file) { | ||||||
|  |     return fspath.join(this.path,this.paths.root,this.paths[file]) | ||||||
|  | } | ||||||
|  |  | ||||||
| Project.prototype.initialise = function(user,data) { | Project.prototype.initialise = function(user,data) { | ||||||
|     var project = this; |     var project = this; | ||||||
|     // if (!this.empty) { |     // if (!this.empty) { | ||||||
| @@ -224,6 +231,7 @@ Project.prototype.parseRemoteBranch = function (remoteBranch) { | |||||||
| Project.prototype.isEmpty = function () { | Project.prototype.isEmpty = function () { | ||||||
|     return this.empty; |     return this.empty; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| Project.prototype.isMerging = function() { | Project.prototype.isMerging = function() { | ||||||
|     return this.merging; |     return this.merging; | ||||||
| } | } | ||||||
| @@ -243,6 +251,7 @@ Project.prototype.update = function (user, data) { | |||||||
|     var savePackage = false; |     var savePackage = false; | ||||||
|     var flowFilesChanged = false; |     var flowFilesChanged = false; | ||||||
|     var credentialSecretChanged = false; |     var credentialSecretChanged = false; | ||||||
|  |     var reloadProject = false; | ||||||
|  |  | ||||||
|     var globalProjectSettings = settings.get("projects"); |     var globalProjectSettings = settings.get("projects"); | ||||||
|     if (!globalProjectSettings.projects.hasOwnProperty(this.name)) { |     if (!globalProjectSettings.projects.hasOwnProperty(this.name)) { | ||||||
| @@ -250,7 +259,6 @@ Project.prototype.update = function (user, data) { | |||||||
|         saveSettings = true; |         saveSettings = true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|     if (data.credentialSecret && data.credentialSecret !== this.credentialSecret) { |     if (data.credentialSecret && data.credentialSecret !== this.credentialSecret) { | ||||||
|         var existingSecret = data.currentCredentialSecret; |         var existingSecret = data.currentCredentialSecret; | ||||||
|         var isReset = data.resetCredentialSecret; |         var isReset = data.resetCredentialSecret; | ||||||
| @@ -278,6 +286,55 @@ Project.prototype.update = function (user, data) { | |||||||
|         credentialSecretChanged = true; |         credentialSecretChanged = true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     if (this.missingFiles.indexOf('package.json') !== -1) { | ||||||
|  |         if (!data.files || !data.files.package) { | ||||||
|  |             // Cannot update a project that doesn't have a known package.json | ||||||
|  |             return Promise.reject("Cannot update project with missing package.json"); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (data.hasOwnProperty('files')) { | ||||||
|  |         this.package['node-red'] = this.package['node-red'] || { settings: {}}; | ||||||
|  |         if (data.files.hasOwnProperty('package') && data.files.package !== fspath.join(this.paths.root,"package.json")) { | ||||||
|  |             // We have a package file. It could be one that doesn't exist yet, or | ||||||
|  |             // does exist and we need to load it. | ||||||
|  |             if (!/package\.json$/.test(data.files.package)) { | ||||||
|  |                 return Promise.reject("Invalid package file: "+data.files.package) | ||||||
|  |             } | ||||||
|  |             var root = data.files.package.substring(0,data.files.package.length-12); | ||||||
|  |             this.paths.root = root; | ||||||
|  |             this.paths['package.json'] = 'package.json'; | ||||||
|  |             globalProjectSettings.projects[this.name].rootPath = root; | ||||||
|  |             saveSettings = true; | ||||||
|  |             // 1. check if it exists | ||||||
|  |             if (fs.existsSync(fspath.join(this.path,this.paths.root,this.paths['package.json']))) { | ||||||
|  |                 // Load the existing one.... | ||||||
|  |             } else { | ||||||
|  |                 var newPackage = defaultFileSet["package.json"](this); | ||||||
|  |                 fs.writeFileSync(fspath.join(this.path,this.paths.root,this.paths['package.json']),newPackage); | ||||||
|  |                 this.package = JSON.parse(newPackage); | ||||||
|  |             } | ||||||
|  |             reloadProject = true; | ||||||
|  |             flowFilesChanged = true; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (data.files.hasOwnProperty('flow') && this.package['node-red'].settings.flowFile !== data.files.flow) { | ||||||
|  |             this.paths.flowFile = data.files.flow; | ||||||
|  |             this.package['node-red'].settings.flowFile = data.files.flow; | ||||||
|  |             savePackage = true; | ||||||
|  |             flowFilesChanged = true; | ||||||
|  |         } | ||||||
|  |         if (data.files.hasOwnProperty('credentials') && this.package['node-red'].settings.credentialsFile !== data.files.credentials) { | ||||||
|  |             this.paths.credentialsFile = data.files.credentials; | ||||||
|  |             this.package['node-red'].settings.credentialsFile = data.files.credentials; | ||||||
|  |             // Don't know if the credSecret is invalid or not so clear the flag | ||||||
|  |             delete this.credentialSecretInvalid; | ||||||
|  |  | ||||||
|  |             savePackage = true; | ||||||
|  |             flowFilesChanged = true; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     if (data.hasOwnProperty('description')) { |     if (data.hasOwnProperty('description')) { | ||||||
|         saveREADME = true; |         saveREADME = true; | ||||||
|         this.description = data.description; |         this.description = data.description; | ||||||
| @@ -333,47 +390,32 @@ Project.prototype.update = function (user, data) { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (data.hasOwnProperty('files')) { |  | ||||||
|         this.package['node-red'] = this.package['node-red'] || { settings: {}}; |  | ||||||
|         if (data.files.hasOwnProperty('flow') && this.package['node-red'].settings.flowFile !== data.files.flow) { |  | ||||||
|             this.paths.flowFile = data.files.flow; |  | ||||||
|             this.package['node-red'].settings.flowFile = data.files.flow; |  | ||||||
|             savePackage = true; |  | ||||||
|             flowFilesChanged = true; |  | ||||||
|         } |  | ||||||
|         if (data.files.hasOwnProperty('credentials') && this.package['node-red'].settings.credentialsFile !== data.files.credentials) { |  | ||||||
|             this.paths.credentialsFile = data.files.credentials; |  | ||||||
|             this.package['node-red'].settings.credentialsFile = data.files.credentials; |  | ||||||
|             // Don't know if the credSecret is invalid or not so clear the flag |  | ||||||
|             delete this.credentialSecretInvalid; |  | ||||||
|  |  | ||||||
|             savePackage = true; |  | ||||||
|             flowFilesChanged = true; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     if (saveSettings) { |     if (saveSettings) { | ||||||
|         promises.push(settings.set("projects",globalProjectSettings)); |         promises.push(settings.set("projects",globalProjectSettings)); | ||||||
|     } |     } | ||||||
|     if (saveREADME) { |     if (saveREADME) { | ||||||
|         promises.push(util.writeFile(this.paths['README.md'], this.description)); |         promises.push(util.writeFile(fspath.join(this.path,this.paths['README.md']), this.description)); | ||||||
|     } |     } | ||||||
|     if (savePackage) { |     if (savePackage) { | ||||||
|         promises.push(fs.readFile(project.paths['package.json'],"utf8").then(content => { |         promises.push(fs.readFile(fspath.join(project.path,project.paths['package.json']),"utf8").then(content => { | ||||||
|             var currentPackage = {}; |             var currentPackage = {}; | ||||||
|             try { |             try { | ||||||
|                 currentPackage = util.parseJSON(content); |                 currentPackage = util.parseJSON(content); | ||||||
|             } catch(err) { |             } catch(err) { | ||||||
|             } |             } | ||||||
|             this.package = Object.assign(currentPackage,this.package); |             this.package = Object.assign(currentPackage,this.package); | ||||||
|             return util.writeFile(this.paths['package.json'], JSON.stringify(this.package,"",4)); |             return util.writeFile(fspath.join(project.path,this.paths['package.json']), JSON.stringify(this.package,"",4)); | ||||||
|         })); |         })); | ||||||
|     } |     } | ||||||
|     return when.settle(promises).then(function(res) { |     return when.settle(promises).then(res => { | ||||||
|         return { |         if (reloadProject) { | ||||||
|  |             return this.load() | ||||||
|  |         } | ||||||
|  |     }).then(() => { return { | ||||||
|             flowFilesChanged: flowFilesChanged, |             flowFilesChanged: flowFilesChanged, | ||||||
|             credentialSecretChanged: credentialSecretChanged |             credentialSecretChanged: credentialSecretChanged | ||||||
|         } |         }}) | ||||||
|     }) |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| Project.prototype.getFiles = function () { | Project.prototype.getFiles = function () { | ||||||
| @@ -384,12 +426,15 @@ Project.prototype.getFiles = function () { | |||||||
|         throw err; |         throw err; | ||||||
|     }); |     }); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| Project.prototype.stageFile = function(file) { | Project.prototype.stageFile = function(file) { | ||||||
|     return gitTools.stageFile(this.path,file); |     return gitTools.stageFile(this.path,file); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| Project.prototype.unstageFile = function(file) { | Project.prototype.unstageFile = function(file) { | ||||||
|     return gitTools.unstageFile(this.path,file); |     return gitTools.unstageFile(this.path,file); | ||||||
| } | } | ||||||
|  |  | ||||||
| Project.prototype.commit = function(user, options) { | Project.prototype.commit = function(user, options) { | ||||||
|     var self = this; |     var self = this; | ||||||
|     return gitTools.commit(this.path,options.message,getGitUser(user)).then(function() { |     return gitTools.commit(this.path,options.message,getGitUser(user)).then(function() { | ||||||
| @@ -399,9 +444,11 @@ Project.prototype.commit = function(user, options) { | |||||||
|         } |         } | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| Project.prototype.getFileDiff = function(file,type) { | Project.prototype.getFileDiff = function(file,type) { | ||||||
|     return gitTools.getFileDiff(this.path,file,type); |     return gitTools.getFileDiff(this.path,file,type); | ||||||
| } | } | ||||||
|  |  | ||||||
| Project.prototype.getCommits = function(options) { | Project.prototype.getCommits = function(options) { | ||||||
|     return gitTools.getCommits(this.path,options).catch(function(err) { |     return gitTools.getCommits(this.path,options).catch(function(err) { | ||||||
|         if (/bad default revision/i.test(err.message) || /ambiguous argument/i.test(err.message) || /does not have any commits yet/i.test(err.message)) { |         if (/bad default revision/i.test(err.message) || /ambiguous argument/i.test(err.message) || /does not have any commits yet/i.test(err.message)) { | ||||||
| @@ -414,9 +461,11 @@ Project.prototype.getCommits = function(options) { | |||||||
|         throw err; |         throw err; | ||||||
|     }) |     }) | ||||||
| } | } | ||||||
|  |  | ||||||
| Project.prototype.getCommit = function(sha) { | Project.prototype.getCommit = function(sha) { | ||||||
|     return gitTools.getCommit(this.path,sha); |     return gitTools.getCommit(this.path,sha); | ||||||
| } | } | ||||||
|  |  | ||||||
| Project.prototype.getFile = function (filePath,treeish) { | Project.prototype.getFile = function (filePath,treeish) { | ||||||
|     if (treeish !== "_") { |     if (treeish !== "_") { | ||||||
|         return gitTools.getFile(this.path, filePath, treeish); |         return gitTools.getFile(this.path, filePath, treeish); | ||||||
| @@ -424,6 +473,7 @@ Project.prototype.getFile = function (filePath,treeish) { | |||||||
|         return fs.readFile(fspath.join(this.path,filePath),"utf8"); |         return fs.readFile(fspath.join(this.path,filePath),"utf8"); | ||||||
|     } |     } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| Project.prototype.revertFile = function (filePath) { | Project.prototype.revertFile = function (filePath) { | ||||||
|     var self = this; |     var self = this; | ||||||
|     return gitTools.revertFile(this.path, filePath).then(function() { |     return gitTools.revertFile(this.path, filePath).then(function() { | ||||||
| @@ -431,8 +481,6 @@ Project.prototype.revertFile = function (filePath) { | |||||||
|     }); |     }); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| Project.prototype.status = function(user, includeRemote) { | Project.prototype.status = function(user, includeRemote) { | ||||||
|     var self = this; |     var self = this; | ||||||
|  |  | ||||||
| @@ -615,6 +663,7 @@ Project.prototype.resolveMerge = function (file,resolutions) { | |||||||
|         }) |         }) | ||||||
|     }); |     }); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| Project.prototype.abortMerge = function () { | Project.prototype.abortMerge = function () { | ||||||
|     var self = this; |     var self = this; | ||||||
|     return gitTools.abortMerge(this.path).then(function() { |     return gitTools.abortMerge(this.path).then(function() { | ||||||
| @@ -675,12 +724,11 @@ Project.prototype.setBranch = function (branchName, isCreate) { | |||||||
|         return self.load(); |         return self.load(); | ||||||
|     }) |     }) | ||||||
| }; | }; | ||||||
|  |  | ||||||
| Project.prototype.getBranchStatus = function (branchName) { | Project.prototype.getBranchStatus = function (branchName) { | ||||||
|     return gitTools.getBranchStatus(this.path,branchName); |     return gitTools.getBranchStatus(this.path,branchName); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| Project.prototype.getRemotes = function (user) { | Project.prototype.getRemotes = function (user) { | ||||||
|     return gitTools.getRemotes(this.path).then(function(remotes) { |     return gitTools.getRemotes(this.path).then(function(remotes) { | ||||||
|         var result = []; |         var result = []; | ||||||
| @@ -693,12 +741,14 @@ Project.prototype.getRemotes = function (user) { | |||||||
|         return {remotes:result}; |         return {remotes:result}; | ||||||
|     }) |     }) | ||||||
| }; | }; | ||||||
|  |  | ||||||
| Project.prototype.addRemote = function(user,remote,options) { | Project.prototype.addRemote = function(user,remote,options) { | ||||||
|     var project = this; |     var project = this; | ||||||
|     return gitTools.addRemote(this.path,remote,options).then(function() { |     return gitTools.addRemote(this.path,remote,options).then(function() { | ||||||
|         return project.loadRemotes() |         return project.loadRemotes() | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| Project.prototype.updateRemote = function(user,remote,options) { | Project.prototype.updateRemote = function(user,remote,options) { | ||||||
|     var username; |     var username; | ||||||
|     if (!user) { |     if (!user) { | ||||||
| @@ -716,6 +766,7 @@ Project.prototype.updateRemote = function(user,remote,options) { | |||||||
|     } |     } | ||||||
|     return Promise.resolve(); |     return Promise.resolve(); | ||||||
| } | } | ||||||
|  |  | ||||||
| Project.prototype.removeRemote = function(user, remote) { | Project.prototype.removeRemote = function(user, remote) { | ||||||
|     // TODO: if this was the last remote using this url, then remove the authCache |     // TODO: if this was the last remote using this url, then remove the authCache | ||||||
|     // details. |     // details. | ||||||
| @@ -725,11 +776,10 @@ Project.prototype.removeRemote = function(user, remote) { | |||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| Project.prototype.getFlowFile = function() { | Project.prototype.getFlowFile = function() { | ||||||
|     // console.log("Project.getFlowFile = ",this.paths.flowFile); |     // console.log("Project.getFlowFile = ",this.paths.flowFile); | ||||||
|     if (this.paths.flowFile) { |     if (this.paths.flowFile) { | ||||||
|         return fspath.join(this.path,this.paths.flowFile); |         return fspath.join(this.path,this.paths.root,this.paths.flowFile); | ||||||
|     } else { |     } else { | ||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
| @@ -742,14 +792,16 @@ Project.prototype.getFlowFileBackup = function() { | |||||||
|     } |     } | ||||||
|     return null; |     return null; | ||||||
| } | } | ||||||
|  |  | ||||||
| Project.prototype.getCredentialsFile = function() { | Project.prototype.getCredentialsFile = function() { | ||||||
|     // console.log("Project.getCredentialsFile = ",this.paths.credentialsFile); |     // console.log("Project.getCredentialsFile = ",this.paths.credentialsFile); | ||||||
|     if (this.paths.credentialsFile) { |     if (this.paths.credentialsFile) { | ||||||
|         return fspath.join(this.path,this.paths.credentialsFile); |         return fspath.join(this.path,this.paths.root,this.paths.credentialsFile); | ||||||
|     } else { |     } else { | ||||||
|         return this.paths.credentialsFile; |         return this.paths.credentialsFile; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| Project.prototype.getCredentialsFileBackup = function() { | Project.prototype.getCredentialsFileBackup = function() { | ||||||
|     return getBackupFilename(this.getCredentialsFile()); |     return getBackupFilename(this.getCredentialsFile()); | ||||||
| } | } | ||||||
| @@ -763,10 +815,11 @@ Project.prototype.export = function () { | |||||||
|         dependencies: this.package.dependencies||{}, |         dependencies: this.package.dependencies||{}, | ||||||
|         empty: this.empty, |         empty: this.empty, | ||||||
|         settings: { |         settings: { | ||||||
|             credentialsEncrypted: (typeof this.credentialSecret === "string"), |             credentialsEncrypted: (typeof this.credentialSecret === "string") && this.credentialSecret.length > 0, | ||||||
|             credentialSecretInvalid: this.credentialSecretInvalid |             credentialSecretInvalid: this.credentialSecretInvalid | ||||||
|         }, |         }, | ||||||
|         files: { |         files: { | ||||||
|  |             package: this.paths['package.json'], | ||||||
|             flow: this.paths.flowFile, |             flow: this.paths.flowFile, | ||||||
|             credentials: this.paths.credentialsFile |             credentials: this.paths.credentialsFile | ||||||
|         }, |         }, | ||||||
| @@ -777,7 +830,6 @@ Project.prototype.export = function () { | |||||||
|     } |     } | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  |  | ||||||
| function getCredentialsFilename(filename) { | function getCredentialsFilename(filename) { | ||||||
|     filename = filename || "undefined"; |     filename = filename || "undefined"; | ||||||
|     // TODO: DRY - ./index.js |     // TODO: DRY - ./index.js | ||||||
| @@ -793,7 +845,6 @@ function getBackupFilename(filename) { | |||||||
|     var ffDir = fspath.dirname(filename); |     var ffDir = fspath.dirname(filename); | ||||||
|     return fspath.join(ffDir,"."+ffName+".backup"); |     return fspath.join(ffDir,"."+ffName+".backup"); | ||||||
| } | } | ||||||
|  |  | ||||||
| function checkProjectExists(projectPath) { | function checkProjectExists(projectPath) { | ||||||
|     return fs.pathExists(projectPath).then(function(exists) { |     return fs.pathExists(projectPath).then(function(exists) { | ||||||
|         if (!exists) { |         if (!exists) { | ||||||
| @@ -805,7 +856,6 @@ function checkProjectExists(projectPath) { | |||||||
|         } |         } | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| function createDefaultProject(user, project) { | function createDefaultProject(user, project) { | ||||||
|     var projectPath = fspath.join(projectsDir,project.name); |     var projectPath = fspath.join(projectsDir,project.name); | ||||||
|     // Create a basic skeleton of a project |     // Create a basic skeleton of a project | ||||||
| @@ -869,15 +919,15 @@ function createDefaultProject(user, project) { | |||||||
|         }) |         }) | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| function checkProjectFiles(project) { | function checkProjectFiles(project) { | ||||||
|     var projectPath = project.path; |     var projectPath = project.path; | ||||||
|  |     var projectRoot = project.paths.root; | ||||||
|     var promises = []; |     var promises = []; | ||||||
|     var paths = []; |     var paths = []; | ||||||
|     for (var file in defaultFileSet) { |     for (var file in defaultFileSet) { | ||||||
|         if (defaultFileSet.hasOwnProperty(file)) { |         if (defaultFileSet.hasOwnProperty(file)) { | ||||||
|             paths.push(file); |             paths.push(file); | ||||||
|             promises.push(fs.stat(fspath.join(projectPath,file))); |             promises.push(fs.stat(fspath.join(projectPath,projectRoot,file))); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     return when.settle(promises).then(function(results) { |     return when.settle(promises).then(function(results) { | ||||||
| @@ -900,7 +950,6 @@ function checkProjectFiles(project) { | |||||||
|         // } |         // } | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| function createProject(user, metadata) { | function createProject(user, metadata) { | ||||||
|     var username; |     var username; | ||||||
|     if (!user) { |     if (!user) { | ||||||
| @@ -933,6 +982,9 @@ function createProject(user, metadata) { | |||||||
|                 } |                 } | ||||||
|                 projects.projects[project] = {}; |                 projects.projects[project] = {}; | ||||||
|                 if (metadata.hasOwnProperty('credentialSecret')) { |                 if (metadata.hasOwnProperty('credentialSecret')) { | ||||||
|  |                     if (metadata.credentialSecret === "") { | ||||||
|  |                         metadata.credentialSecret = false; | ||||||
|  |                     } | ||||||
|                     projects.projects[project].credentialSecret = metadata.credentialSecret; |                     projects.projects[project].credentialSecret = metadata.credentialSecret; | ||||||
|                 } |                 } | ||||||
|                 return settings.set('projects',projects); |                 return settings.set('projects',projects); | ||||||
| @@ -970,7 +1022,6 @@ function createProject(user, metadata) { | |||||||
|         }) |         }) | ||||||
|     }) |     }) | ||||||
| } | } | ||||||
|  |  | ||||||
| function deleteProject(user, projectPath) { | function deleteProject(user, projectPath) { | ||||||
|     return checkProjectExists(projectPath).then(function() { |     return checkProjectExists(projectPath).then(function() { | ||||||
|         return fs.remove(projectPath).then(function() { |         return fs.remove(projectPath).then(function() { | ||||||
| @@ -981,14 +1032,12 @@ function deleteProject(user, projectPath) { | |||||||
|         }); |         }); | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| function loadProject(projectPath) { | function loadProject(projectPath) { | ||||||
|     return checkProjectExists(projectPath).then(function() { |     return checkProjectExists(projectPath).then(function() { | ||||||
|         var project = new Project(projectPath); |         var project = new Project(projectPath); | ||||||
|         return project.load(); |         return project.load(); | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| function init(_settings, _runtime) { | function init(_settings, _runtime) { | ||||||
|     settings = _settings; |     settings = _settings; | ||||||
|     runtime = _runtime; |     runtime = _runtime; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user