',{class:"palette-module-meta"}).appendTo(headerRow);
var buttonGroup = $('
',{class:"palette-module-button-group"}).appendTo(buttonRow);
- var shade = $('
').appendTo(container);
var installButton = $('
').html(RED._('palette.editor.install')).appendTo(buttonGroup);
installButton.click(function(e) {
e.preventDefault();
if (!$(this).hasClass('disabled')) {
- $("#palette-module-install-confirm").data('module',entry.id);
- $("#palette-module-install-confirm").data('version',entry.version);
- $("#palette-module-install-confirm").data('url',entry.url);
- $("#palette-module-install-confirm").data('shade',shade);
- $("#palette-module-install-confirm-body").html(RED._("palette.editor.confirm.install.body"));
- $(".palette-module-install-confirm-button-install").show();
- $(".palette-module-install-confirm-button-remove").hide();
- $(".palette-module-install-confirm-button-update").hide();
- $("#palette-module-install-confirm")
- .dialog('option', 'title', RED._("palette.editor.confirm.install.title"))
- .dialog('open');
+ install(entry,container,function(xhr) {});
}
})
if (nodeEntries.hasOwnProperty(entry.id)) {
@@ -869,88 +826,126 @@ RED.palette.editor = (function() {
});
$('
').appendTo(installTab);
-
- $('
').appendTo(document.body);
- $("#palette-module-install-confirm").dialog({
- title: RED._('palette.editor.confirm.title'),
+ }
+ function update(entry,version,container,done) {
+ if (RED.settings.theme('palette.editable') === false) {
+ done(new Error('Palette not editable'));
+ return;
+ }
+ var notification = RED.notify(RED._("palette.editor.confirm.update.body",{module:entry.name}),{
modal: true,
- autoOpen: false,
- width: 550,
- height: "auto",
+ fixed: true,
buttons: [
{
text: RED._("common.label.cancel"),
click: function() {
- $( this ).dialog( "close" );
- }
- },
- {
- text: RED._("palette.editor.confirm.button.review"),
- class: "primary palette-module-install-confirm-button-install",
- click: function() {
- var url = $(this).data('url');
- window.open(url);
- }
- },
- {
- text: RED._("palette.editor.confirm.button.install"),
- class: "primary palette-module-install-confirm-button-install",
- click: function() {
- var id = $(this).data('module');
- var version = $(this).data('version');
- var shade = $(this).data('shade');
- installNodeModule(id,version,shade,function(xhr) {
- if (xhr) {
- if (xhr.responseJSON) {
- RED.notify(RED._('palette.editor.errors.installFailed',{module: id,message:xhr.responseJSON.message}));
- }
- }
- });
- $( this ).dialog( "close" );
- }
- },
- {
- text: RED._("palette.editor.confirm.button.remove"),
- class: "primary palette-module-install-confirm-button-remove",
- click: function() {
- var id = $(this).data('module');
- var shade = $(this).data('shade');
- shade.show();
- removeNodeModule(id, function(xhr) {
- shade.hide();
- if (xhr) {
- if (xhr.responseJSON) {
- RED.notify(RED._('palette.editor.errors.removeFailed',{module: id,message:xhr.responseJSON.message}));
- }
- }
- })
-
- $( this ).dialog( "close" );
+ notification.close();
}
},
{
text: RED._("palette.editor.confirm.button.update"),
class: "primary palette-module-install-confirm-button-update",
click: function() {
- var id = $(this).data('module');
- var version = $(this).data('version');
- var shade = $(this).data('shade');
- shade.show();
- installNodeModule(id,version,shade,function(xhr) {
- if (xhr) {
- if (xhr.responseJSON) {
- RED.notify(RED._('palette.editor.errors.updateFailed',{module: id,message:xhr.responseJSON.message}));
- }
- }
+ var spinner = RED.utils.addSpinnerOverlay(container, true);
+ installNodeModule(entry.name,version,function(xhr) {
+ spinner.remove();
+ if (xhr) {
+ if (xhr.responseJSON) {
+ RED.notify(RED._('palette.editor.errors.updateFailed',{module: entry.name,message:xhr.responseJSON.message}));
+ }
+ }
+ done(xhr);
});
- $( this ).dialog( "close" );
+ notification.close();
}
}
]
})
}
+ function remove(entry,container,done) {
+ if (RED.settings.theme('palette.editable') === false) {
+ done(new Error('Palette not editable'));
+ return;
+ }
+ var notification = RED.notify(RED._("palette.editor.confirm.remove.body",{module:entry.name}),{
+ modal: true,
+ fixed: true,
+ buttons: [
+ {
+ text: RED._("common.label.cancel"),
+ click: function() {
+ notification.close();
+ }
+ },
+ {
+ text: RED._("palette.editor.confirm.button.remove"),
+ class: "primary palette-module-install-confirm-button-remove",
+ click: function() {
+ var spinner = RED.utils.addSpinnerOverlay(container, true);
+ removeNodeModule(entry.name, function(xhr) {
+ spinner.remove();
+ if (xhr) {
+ if (xhr.responseJSON) {
+ RED.notify(RED._('palette.editor.errors.removeFailed',{module: entry.name,message:xhr.responseJSON.message}));
+ }
+ }
+ })
+ notification.close();
+ }
+ }
+ ]
+ })
+ }
+ function install(entry,container,done) {
+ if (RED.settings.theme('palette.editable') === false) {
+ done(new Error('Palette not editable'));
+ return;
+ }
+ var buttons = [
+ {
+ text: RED._("common.label.cancel"),
+ click: function() {
+ notification.close();
+ }
+ }
+ ];
+ if (entry.url) {
+ buttons.push({
+ text: RED._("palette.editor.confirm.button.review"),
+ class: "primary palette-module-install-confirm-button-install",
+ click: function() {
+ var url = entry.url||"";
+ window.open(url);
+ }
+ });
+ }
+ buttons.push({
+ text: RED._("palette.editor.confirm.button.install"),
+ class: "primary palette-module-install-confirm-button-install",
+ click: function() {
+ var spinner = RED.utils.addSpinnerOverlay(container, true);
+ installNodeModule(entry.id,entry.version,function(xhr) {
+ spinner.remove();
+ if (xhr) {
+ if (xhr.responseJSON) {
+ RED.notify(RED._('palette.editor.errors.installFailed',{module: entry.id,message:xhr.responseJSON.message}));
+ }
+ }
+ done(xhr);
+ });
+ notification.close();
+ }
+ });
+
+ var notification = RED.notify(RED._("palette.editor.confirm.install.body",{module:entry.id}),{
+ modal: true,
+ fixed: true,
+ buttons: buttons
+ })
+ }
return {
- init: init
+ init: init,
+ install: install
}
})();
diff --git a/editor/js/ui/projects/projectSettings.js b/editor/js/ui/projects/projectSettings.js
index c4736a65c..62fce76aa 100644
--- a/editor/js/ui/projects/projectSettings.js
+++ b/editor/js/ui/projects/projectSettings.js
@@ -262,14 +262,16 @@ RED.projects.settings = (function() {
var totalCount = 0;
var unknownCount = 0;
var unusedCount = 0;
+ var notInstalledCount = 0;
for (var m in modulesInUse) {
if (modulesInUse.hasOwnProperty(m)) {
depsList.editableList('addItem',{
- module: modulesInUse[m].module,
+ id: modulesInUse[m].module,
version: modulesInUse[m].version,
count: modulesInUse[m].count,
- known: activeProject.dependencies.hasOwnProperty(m)
+ known: activeProject.dependencies.hasOwnProperty(m),
+ installed: true
});
totalCount++;
if (modulesInUse[m].count === 0) {
@@ -284,29 +286,69 @@ RED.projects.settings = (function() {
if (activeProject.dependencies) {
for (var m in activeProject.dependencies) {
if (activeProject.dependencies.hasOwnProperty(m) && !modulesInUse.hasOwnProperty(m)) {
+ var installed = !!RED.nodes.registry.getModule(m);
depsList.editableList('addItem',{
- module: m,
+ id: m,
version: activeProject.dependencies[m], //RED.nodes.registry.getModule(module).version,
count: 0,
- known: true
+ known: true,
+ installed: installed
});
totalCount++;
- unusedCount++;
+ if (installed) {
+ unusedCount++;
+ } else {
+ notInstalledCount++;
+ }
}
}
}
- if (unknownCount > 0) {
- depsList.editableList('addItem',{index:1, label:"Unlisted dependencies"}); // TODO: nls
- }
- if (unusedCount > 0) {
- depsList.editableList('addItem',{index:3, label:"Unused dependencies"}); // TODO: nls
- }
+ // if (notInstalledCount > 0) {
+ // depsList.editableList('addItem',{index:1, label:"Missing dependencies"}); // TODO: nls
+ // }
+ // if (unknownCount > 0) {
+ // depsList.editableList('addItem',{index:1, label:"Unlisted dependencies"}); // TODO: nls
+ // }
+ // 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
}
}
+ function saveDependencies(depsList,container,dependencies,complete) {
+ var activeProject = RED.projects.getActiveProject();
+ var spinner = utils.addSpinnerOverlay(container).addClass('projects-dialog-spinner-contain');
+ var done = function(err,res) {
+ spinner.remove();
+ if (err) {
+ return complete(err);
+ }
+ activeProject.dependencies = dependencies;
+ RED.sidebar.versionControl.refresh(true);
+ complete();
+ }
+ utils.sendRequest({
+ url: "projects/"+activeProject.name,
+ type: "PUT",
+ responses: {
+ 0: function(error) {
+ done(error,null);
+ },
+ 200: function(data) {
+ RED.sidebar.versionControl.refresh(true);
+ done(null,data);
+ },
+ 400: {
+ '*': function(error) {
+ done(error,null);
+ }
+ },
+ }
+ },{dependencies:dependencies});
+ }
function editDependencies(activeProject,depsJSON,container,depsList) {
var json = depsJSON||JSON.stringify(activeProject.dependencies||{},"",4);
if (json === "{}") {
@@ -319,34 +361,12 @@ RED.projects.settings = (function() {
complete: function(v) {
try {
var parsed = JSON.parse(v);
- var spinner = utils.addSpinnerOverlay(container);
-
- var done = function(err,res) {
+ saveDependencies(depsList,container,parsed,function(err) {
if (err) {
return editDependencies(activeProject,v,container,depsList);
}
activeProject.dependencies = parsed;
updateProjectDependencies(activeProject,depsList);
- }
- utils.sendRequest({
- url: "projects/"+activeProject.name,
- type: "PUT",
- responses: {
- 0: function(error) {
- done(error,null);
- },
- 200: function(data) {
- RED.sidebar.versionControl.refresh(true);
- done(null,data);
- },
- 400: {
- 'unexpected_error': function(error) {
- done(error,null);
- }
- },
- }
- },{dependencies:parsed}).always(function() {
- spinner.remove();
});
} catch(err) {
editDependencies(activeProject,v,container,depsList);
@@ -378,59 +398,119 @@ RED.projects.settings = (function() {
row.parent().addClass("palette-module-section");
}
headerRow.text(entry.label);
- if (RED.user.hasPermission("projects.write")) {
- if (entry.index === 1) {
- var addButton = $('
add to project ').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 = $('
remove from project ').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);
- });
- }
- }
+ // if (RED.user.hasPermission("projects.write")) {
+ // if (entry.index === 1) {
+ // var addButton = $('
add to project ').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 = $('
remove from project ').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 {
headerRow.addClass("palette-module-header");
- headerRow.toggleClass("palette-module-unused",entry.count === 0);
+ if (!entry.installed) {
+ headerRow.addClass("palette-module-not-installed");
+ } else if (entry.count === 0) {
+ headerRow.addClass("palette-module-unused");
+ } else if (!entry.known) {
+ headerRow.addClass("palette-module-unknown");
+ }
+
entry.element = headerRow;
var titleRow = $('
').appendTo(headerRow);
- var icon = $('
').appendTo(titleRow);
+ var iconClass = "fa-cube";
+ if (!entry.installed) {
+ iconClass = "fa-warning";
+ }
+ var icon = $('
').appendTo(titleRow);
entry.icon = icon;
- $('
').html(entry.module).appendTo(titleRow);
+ $('').html(entry.id).appendTo(titleRow);
var metaRow = $('
').appendTo(headerRow);
var versionSpan = $('').html(entry.version).appendTo(metaRow);
- if (!entry.known) {
- headerRow.addClass("palette-module-unknown");
- } else if (entry.known && entry.count === 0) {
-
+ metaRow = $('
').appendTo(headerRow);
+ var buttons = $('
').appendTo(metaRow);
+ if (RED.user.hasPermission("projects.write")) {
+ if (!entry.installed && RED.settings.theme('palette.editable') !== false) {
+ $('install ').appendTo(buttons)
+ .click(function(evt) {
+ evt.preventDefault();
+ RED.palette.editor.install(entry,row,function(err) {
+ if (!err) {
+ entry.installed = true;
+ var spinner = RED.utils.addSpinnerOverlay(row,true);
+ setTimeout(function() {
+ depsList.editableList('removeItem',entry);
+ refreshModuleInUseCounts();
+ entry.count = modulesInUse[entry.id].count;
+ depsList.editableList('addItem',entry);
+ },500);
+ }
+ });
+ })
+ } else if (entry.known && entry.count === 0) {
+ $('remove from project ').appendTo(buttons)
+ .click(function(evt) {
+ evt.preventDefault();
+ var deps = $.extend(true, {}, activeProject.dependencies);
+ delete deps[entry.id];
+ saveDependencies(depsList,row,deps,function(err) {
+ if (!err) {
+ row.fadeOut(200,function() {
+ depsList.editableList('removeItem',entry);
+ });
+ } else {
+ console.log(err);
+ }
+ });
+ });
+ } else if (!entry.known) {
+ $('add to project ').appendTo(buttons)
+ .click(function(evt) {
+ evt.preventDefault();
+ var deps = $.extend(true, {}, activeProject.dependencies);
+ deps[entry.id] = modulesInUse[entry.id].version;
+ saveDependencies(depsList,row,deps,function(err) {
+ if (!err) {
+ buttons.remove();
+ headerRow.removeClass("palette-module-unknown");
+ } else {
+ console.log(err);
+ }
+ });
+ });
+ }
}
}
},
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;
- }
+ return A.id.localeCompare(B.id);
+ // 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.id.localeCompare(B.id);
+ // } else {
+ // return Acategory - Bcategory;
+ // }
}
});
@@ -1332,8 +1412,30 @@ RED.projects.settings = (function() {
return pane;
}
- var popover;
+ function refreshModuleInUseCounts() {
+ modulesInUse = {};
+ RED.nodes.eachNode(_updateModulesInUse);
+ RED.nodes.eachConfig(_updateModulesInUse);
+ }
+ function _updateModulesInUse(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++;
+ }
+ }
+ }
+
+ var popover;
var utils;
var modulesInUse = {};
function init(_utils) {
@@ -1362,22 +1464,7 @@ RED.projects.settings = (function() {
}
});
- 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++;
- }
- }
- })
+ RED.events.on('nodes:add', _updateModulesInUse);
RED.events.on('nodes:remove', function(n) {
if (!/^subflow:/.test(n.type)) {
var module = RED.nodes.registry.getNodeSetForType(n.type).module;
diff --git a/editor/js/ui/projects/projects.js b/editor/js/ui/projects/projects.js
index 6c542550d..45663e852 100644
--- a/editor/js/ui/projects/projects.js
+++ b/editor/js/ui/projects/projects.js
@@ -920,9 +920,9 @@ RED.projects = (function() {
// $('Credentials encryption key ').appendTo(row);
// projectSecretInput = $(' ').appendTo(row);
switch(options.screen||"empty") {
- case "empty": console.log("createasempty"); createAsEmpty.click(); break;
- case "open": console.log("opening"); openProject.click(); break;
- case "clone": console.log("cloning"); createAsClone.click(); break;
+ case "empty": createAsEmpty.click(); break;
+ case "open": openProject.click(); break;
+ case "clone": createAsClone.click(); break;
}
setTimeout(function() {
@@ -1096,12 +1096,7 @@ RED.projects = (function() {
done(null,data);
},
400: {
- 'credentials_load_failed': function(error) {
- done(error,null);
- },
- 'unexpected_error': function(error) {
- done(error,null);
- }
+ '*': done
},
}
},{active:true}).then(function() {
@@ -1538,6 +1533,10 @@ RED.projects = (function() {
resultCallback = responses[xhr.responseJSON.error];
resultCallbackArgs = xhr.responseJSON;
return;
+ } else if (responses['*']) {
+ resultCallback = responses['*'];
+ resultCallbackArgs = xhr.responseJSON;
+ return;
}
}
console.log("Unhandled error response:");
@@ -1816,6 +1815,9 @@ RED.projects = (function() {
}
RED.projects.settings.show('settings');
},
+ showProjectDependencies: function() {
+ RED.projects.settings.show('deps');
+ },
createDefaultFileSet: createDefaultFileSet,
// showSidebar: showSidebar,
refresh: refresh,
diff --git a/editor/js/ui/utils.js b/editor/js/ui/utils.js
index 53c6150c6..dc96ae37c 100644
--- a/editor/js/ui/utils.js
+++ b/editor/js/ui/utils.js
@@ -765,6 +765,14 @@ RED.utils = (function() {
return RED.text.bidi.enforceTextDirectionWithUCC(l);
}
+ function addSpinnerOverlay(container,contain) {
+ var spinner = $('').appendTo(container);
+ if (contain) {
+ spinner.addClass('projects-dialog-spinner-contain');
+ }
+ return spinner;
+ }
+
return {
createObjectElement: buildMessageElement,
getMessageProperty: getMessageProperty,
@@ -774,5 +782,6 @@ RED.utils = (function() {
getDefaultNodeIcon: getDefaultNodeIcon,
getNodeIcon: getNodeIcon,
getNodeLabel: getNodeLabel,
+ addSpinnerOverlay: addSpinnerOverlay
}
})();
diff --git a/editor/sass/palette-editor.scss b/editor/sass/palette-editor.scss
index 0c83071b3..b2fb61df3 100644
--- a/editor/sass/palette-editor.scss
+++ b/editor/sass/palette-editor.scss
@@ -76,22 +76,6 @@
border-bottom: 1px solid $primary-border-color;
text-align: right;
}
- .palette-module-button-group {
- position: absolute;
- right: 0;
- bottom: 0;
- a {
- margin-left: 5px;
- }
- }
- .palette-module-shade {
- @include shade;
- text-align: center;
- padding-top: 20px;
- }
- #palette-module-install-shade {
- padding-top: 80px;
- }
.palette-module-shade-status {
color: #666;
}
@@ -230,3 +214,19 @@
color: #666;
}
+.palette-module-button-group {
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ a {
+ margin-left: 5px;
+ }
+}
+.palette-module-shade {
+ @include shade;
+ text-align: center;
+ padding-top: 20px;
+}
+#palette-module-install-shade {
+ padding-top: 80px;
+}
diff --git a/editor/sass/projects.scss b/editor/sass/projects.scss
index e230ed2cb..134e43a93 100644
--- a/editor/sass/projects.scss
+++ b/editor/sass/projects.scss
@@ -313,7 +313,12 @@
// border: 1px dashed #bbb;
}
.palette-module-unknown {
- // border: 1px dashed #b72828;
+ border: 1px dashed #aaa;
+ background: #fafafa;
+ }
+ .palette-module-not-installed {
+ border: 1px dashed #b07575;
+ background: #fee;
i.fa-warning {
color: #b07575; //#b72828;
}
diff --git a/red/api/editor/locales/en-US/editor.json b/red/api/editor/locales/en-US/editor.json
index 73a2b3758..d7ae5759c 100644
--- a/red/api/editor/locales/en-US/editor.json
+++ b/red/api/editor/locales/en-US/editor.json
@@ -344,24 +344,24 @@
"sortRecent": "recent",
"more": "+ __count__ more",
"errors": {
- "catalogLoadFailed": "Failed to load node catalogue. Check the browser console for more information",
- "installFailed": "Failed to install: __module__ __message__ Check the log for more information",
- "removeFailed": "Failed to remove: __module__ __message__ Check the log for more information",
- "updateFailed": "Failed to update: __module__ __message__ Check the log for more information",
- "enableFailed": "Failed to enable: __module__ __message__ Check the log for more information",
- "disableFailed": "Failed to disable: __module__ __message__ Check the log for more information"
+ "catalogLoadFailed": "Failed to load node catalogue.
Check the browser console for more information
",
+ "installFailed": "Failed to install: __module__
__message__
Check the log for more information
",
+ "removeFailed": "Failed to remove: __module__
__message__
Check the log for more information
",
+ "updateFailed": "Failed to update: __module__
__message__
Check the log for more information
",
+ "enableFailed": "Failed to enable: __module__
__message__
Check the log for more information
",
+ "disableFailed": "Failed to disable: __module__
__message__
Check the log for more information
"
},
"confirm": {
"install": {
- "body":"Before installing, please read the node's documentation. Some nodes have dependencies that cannot be automatically resolved and can require a restart of Node-RED. ",
+ "body":"Installing '__module__'
Before installing, please read the node's documentation. Some nodes have dependencies that cannot be automatically resolved and can require a restart of Node-RED.
",
"title": "Install nodes"
},
"remove": {
- "body":"Removing the node will uninstall it from Node-RED. The node may continue to use resources until Node-RED is restarted.",
+ "body":"Removing '__module__'
Removing the node will uninstall it from Node-RED. The node may continue to use resources until Node-RED is restarted.
",
"title": "Remove nodes"
},
"update": {
- "body":"Updating the node will require a restart of Node-RED to complete the update. This must be done manually.",
+ "body":"Updating '__module__'
Updating the node will require a restart of Node-RED to complete the update. This must be done manually.
",
"title": "Update nodes"
},
"cannotUpdate": {
diff --git a/red/runtime/nodes/registry/installer.js b/red/runtime/nodes/registry/installer.js
index a81d051ad..cb54b59d1 100644
--- a/red/runtime/nodes/registry/installer.js
+++ b/red/runtime/nodes/registry/installer.js
@@ -99,7 +99,10 @@ function installModule(module,version) {
}
var installDir = settings.userDir || process.env.NODE_RED_HOME || ".";
- var child = child_process.execFile(npmCommand,['install','--save','--save-prefix="~"','--production',installName],
+
+ var args = ['install','--save','--save-prefix="~"','--production',installName];
+ log.trace(npmCommand + JSON.stringify(args));
+ var child = child_process.execFile(npmCommand,args,
{
cwd: installDir
},
@@ -186,7 +189,11 @@ function uninstallModule(module) {
var list = registry.removeModule(module);
log.info(log._("server.install.uninstalling",{name:module}));
- var child = child_process.execFile(npmCommand,['remove','--save',module],
+
+ var args = ['remove','--save',module];
+ log.trace(npmCommand + JSON.stringify(args));
+
+ var child = child_process.execFile(npmCommand,args,
{
cwd: installDir
},