diff --git a/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json b/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json
index c2e89133b..a89abb992 100644
--- a/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json
+++ b/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json
@@ -265,7 +265,7 @@
"download": "Download",
"importUnrecognised": "Imported unrecognised type:",
"importUnrecognised_plural": "Imported unrecognised types:",
- "importWithModuleInfo": "Required dependencies missing",
+ "importWithModuleInfo": "Required modules missing",
"importWithModuleInfoDesc": "These nodes are not currently installed in your palette and are required for the imported flow:",
"importDuplicate": "Imported duplicate node:",
"importDuplicate_plural": "Imported duplicate nodes:",
@@ -616,6 +616,7 @@
"yearsMonthsV": "__y__ years, __count__ month ago",
"yearsMonthsV_plural": "__y__ years, __count__ months ago"
},
+ "manageModules": "Manage modules",
"nodeCount": "__label__ node",
"nodeCount_plural": "__label__ nodes",
"pluginCount": "__count__ plugin",
@@ -631,7 +632,9 @@
"update": "update to __version__",
"updated": "updated",
"install": "install",
+ "installEverything": "Install everything",
"installed": "installed",
+ "installing": "Module installation in progress: __module__",
"conflict": "conflict",
"conflictTip": "
This module cannot be installed as it includes a
node type that has already been installed
Conflicts with __module__
",
"loading": "Loading catalogues...",
@@ -641,6 +644,7 @@
"sortRelevance": "relevance",
"sortAZ": "a-z",
"sortRecent": "recent",
+ "successfulInstall": "Successfully installed modules",
"more": "+ __count__ more",
"upload": "Upload module tgz file",
"refresh": "Refresh module list",
diff --git a/packages/node_modules/@node-red/editor-client/src/js/nodes.js b/packages/node_modules/@node-red/editor-client/src/js/nodes.js
index d676e0edb..e18c72eae 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/nodes.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/nodes.js
@@ -1971,15 +1971,27 @@ RED.nodes = (function() {
// Provide option to install missing modules
notificationOptions.buttons = [
{
- text: "Manage dependencies",
- class:"primary",
+ text: RED._("palette.editor.manageModules"),
+ class: "primary",
click: function(e) {
unknownNotification.close();
RED.actions.invoke('core:manage-palette', {
view: 'install',
filter: '"' + Object.keys(options.modules).join('", "') + '"'
- })
+ });
+ }
+ },
+ {
+ text: RED._("palette.editor.installEverything"),
+ class: "pull-left",
+ click: function(e) {
+ unknownNotification.close();
+
+ RED.actions.invoke('core:manage-palette', {
+ autoInstall: true,
+ modules: options.modules
+ });
}
}
]
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js b/packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js
index 44e6146c8..644a094f4 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js
@@ -626,6 +626,9 @@ RED.palette.editor = (function() {
})
RED.actions.add("core:manage-palette", function(opts) {
+ if (opts && opts.autoInstall && opts.modules) {
+ autoInstallModules(opts.modules);
+ } else {
RED.userSettings.show('palette');
if (opts) {
if (opts.view) {
@@ -639,7 +642,8 @@ RED.palette.editor = (function() {
}
}
}
- });
+ }
+ });
RED.events.on('registry:module-updated', function(ns) {
refreshNodeModule(ns.module);
@@ -1501,6 +1505,80 @@ RED.palette.editor = (function() {
})
}
+ function autoInstallModules(modules) {
+ if (RED.settings.get('externalModules.palette.allowInstall', true) === false) {
+ console.error(new Error('Palette not editable'));
+ return;
+ }
+
+ let notification;
+ const notificationOptions = {
+ fixed: true,
+ buttons: [
+ {
+ text: RED._("common.label.close"),
+ click: function () {
+ notification.close();
+ }
+ }, {
+ text: RED._("eventLog.view"),
+ click: function () {
+ notification.close();
+ RED.actions.invoke("core:show-event-log");
+ }
+ }
+ ]
+ };
+
+ const moduleArray = Object.entries(modules);
+ const installModule = function (module) {
+ const [moduleName, moduleVersion] = module;
+
+ const msg = RED.notify(RED._("palette.editor.installing", { module: moduleName }));
+
+ if (!notification) {
+ notification = RED.notify(msg, notificationOptions);
+ } else {
+ notification.update(msg);
+ }
+
+ // TODO: add spinner to a div below the title
+ //const spinner = RED.utils.addSpinnerOverlay(container, true);
+
+ RED.eventLog.startEvent(RED._("palette.editor.confirm.button.install") + " : " + moduleName + " " + moduleVersion);
+
+ installNodeModule(moduleName, moduleVersion, undefined, function(xhr, textStatus, err) {
+ //spinner.close();
+ if (err && xhr.status === 504) {
+ notification.update(RED._("palette.editor.errors.installTimeout"), {
+ modal: true,
+ fixed: true,
+ buttons: notificationOptions.buttons
+ });
+ } else if (xhr) {
+ if (xhr.responseJSON) {
+ notification.update(RED._("palette.editor.errors.installFailed", { module: moduleName, message:xhr.responseJSON.message }), {
+ type: "error",
+ modal: true,
+ fixed: true,
+ buttons: notificationOptions.buttons
+ });
+ }
+ } else {
+ if (moduleArray.length) {
+ installModule(moduleArray.shift());
+ } else {
+ notification.update(RED._("palette.editor.successfulInstall"), { ...notificationOptions, type: "success", timeout: 1000 });
+ }
+ }
+ });
+ };
+
+ if (moduleArray.length) {
+ installModule(moduleArray.shift());
+ }
+ }
+
return {
init: init,
install: install