pull/4938/merge
Gauthier Dandele 2025-04-14 10:33:44 -04:00 committed by GitHub
commit af5373f513
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 131 additions and 1 deletions

View File

@ -639,6 +639,7 @@
"remove": "remove",
"update": "update to __version__",
"updated": "updated",
"updating": "Updating...",
"install": "install",
"installed": "installed",
"conflict": "conflict",
@ -678,6 +679,9 @@
"body": "<p>Updating '__module__'</p><p>Updating the node will require a restart of Node-RED to complete the update. This must be done manually.</p>",
"title": "Update nodes"
},
"updateAll": {
"body": "<p>Updating __count__ nodes</p><p>Updating the nodes will require a restart of Node-RED to complete the update. This must be done manually.</p>"
},
"cannotUpdate": {
"body": "An update for this node is available, but it is not installed in a location that the palette manager can update.<br/><br/>Please refer to the documentation for how to update this node."
},
@ -686,8 +690,12 @@
"install": "Install",
"remove": "Remove",
"update": "Update",
"updateAll": "Update all",
"understood": "Understood"
}
},
"progress": {
"updated": "Updated __count__/__total__ modules"
}
}
},

View File

@ -509,6 +509,24 @@ RED.palette.editor = (function() {
} else {
refreshNodeModuleList();
updateCatalogFilter(loadedCatalogs)
const updateAllButton = $(nodesTabFooter).find("#red-ui-palette-button-updateAll");
const progressRow = $(nodesTabFooter).find(".red-ui-palette-footer-progress");
// Update the "Update all" button when the Palette opening
if (updateAllButton.length) {
updateAllButton.text(RED._("palette.editor.confirm.button.updateAll"));
if (updateAvailable.length) {
updateAllButton.removeClass("disabled");
} else {
updateAllButton.addClass("disabled");
}
}
// Set progress to empty when the Palette opening
if (progressRow.length) {
progressRow.text("");
}
}
}
@ -620,6 +638,7 @@ RED.palette.editor = (function() {
let editorTabs;
let settingsPane;
let nodesTabFooter;
function init() {
if (RED.settings.get('externalModules.palette.allowInstall', true) === false) {
@ -877,7 +896,6 @@ RED.palette.editor = (function() {
update(entry,loadedIndex[entry.name].version,loadedIndex[entry.name].pkg_url,container,function(err){});
})
var removeButton = $('<a href="#" class="red-ui-button red-ui-button-small"></a>').text(RED._('palette.editor.remove')).appendTo(buttonGroup);
removeButton.attr('id','up_'+Math.floor(Math.random()*1000000000));
removeButton.on("click", function(evt) {
@ -1010,6 +1028,25 @@ RED.palette.editor = (function() {
}
}
})
nodesTabFooter = $('<div>', { class: "red-ui-palette-footer" }).appendTo(modulesTab);
const buttonRow = $('<div>', { class: "red-ui-palette-footer-button" }).appendTo(nodesTabFooter);
const updateAllButton = $('<a id="red-ui-palette-button-updateAll" class="red-ui-button red-ui-button-small"></a>').appendTo(buttonRow);
$('<div class="red-ui-palette-footer-progress"><span></span></div>').appendTo(nodesTabFooter);
$('<span>').appendTo(updateAllButton);
updateAllButton.on("click", function (evt) {
evt.preventDefault();
if (updateAllButton.hasClass("disabled")) {
return;
}
updateAllButton.text(RED._("palette.editor.updating"));
updateAllButton.addClass("disabled");
autoUpdateModules(function () {
updateAllButton.text(RED._("palette.editor.updated"));
});
});
}
function createInstallTab(content) {
@ -1254,6 +1291,81 @@ RED.palette.editor = (function() {
$('<div id="red-ui-palette-module-install-shade" class="red-ui-palette-module-shade hide"><div class="red-ui-palette-module-shade-status"></div><img src="red/images/spin.svg" class="red-ui-palette-spinner"/></div>').appendTo(installTab);
}
function autoUpdateModules(done) {
if (RED.settings.get('externalModules.palette.allowInstall', true) === false) {
console.error(new Error('Update failed: Palette not editable'));
return;
}
const updateAllButton = $(nodesTabFooter).find("#red-ui-palette-button-updateAll");
const progressRow = $(nodesTabFooter).find(".red-ui-palette-footer-progress");
const modules = updateAvailable.slice();
const runUpdate = function () {
modules.forEach(function (moduleName, i) {
if (moduleName in nodeEntries) {
const { version, pkg_url } = loadedIndex[moduleName];
const updatedCount = i + 1;
installNodeModule(moduleName, version, pkg_url, function (xhr) {
if (xhr) {
if (xhr.responseJSON) {
const notification = RED.notify(RED._("palette.editor.errors.updateFailed", { module: moduleName, message: xhr.responseJSON.message }), {
type: "error",
modal: true,
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");
}
}
]
});
}
} else {
progressRow.text(RED._("palette.editor.progress.updated", {
count: updatedCount,
total: modules.length
}));
if (i === modules.length - 1) {
done();
}
}
});
}
});
}
const notification = RED.notify(RED._("palette.editor.confirm.updateAll.body", { count: updateAvailable.length }), {
modal: true,
fixed: true,
buttons: [
{
text: RED._("common.label.cancel"),
click: function () {
notification.close();
updateAllButton.removeClass("disabled");
updateAllButton.text(RED._("palette.editor.confirm.button.updateAll"));
}
},
{
text: RED._("palette.editor.confirm.button.updateAll"),
class: "primary red-ui-palette-module-install-confirm-button-update",
click: function () {
notification.close();
runUpdate();
}
},
]
});
}
function update(entry,version,url,container,done) {
if (RED.settings.get('externalModules.palette.allowInstall', true) === false) {
done(new Error('Palette not editable'));

View File

@ -308,6 +308,16 @@ button.red-ui-palette-editor-upload-button {
}
}
.red-ui-palette-footer-button,
.red-ui-palette-footer-progress {
display: inline-block;
vertical-align: middle;
margin: 0 5px;
}
.red-ui-palette-footer-progress {
color: var(--red-ui-secondary-text-color);
}
button.red-ui-update-status {
width: auto;
padding: 0 3px;