Merge pull request #5499 from node-red/palette-updates

Allow node-red integrator access to available updates
pull/5502/head
Nick O'Leary 2026-02-25 15:55:17 +00:00 committed by GitHub
commit 4cf4817526
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 36 additions and 16 deletions

View File

@ -40,6 +40,12 @@ RED.palette.editor = (function() {
// Install tab - search input
let searchInput;
// Core and Package Updates
/** @type {Array<{package: string, current: string, available: string}>} */
const moduleUpdates = []
const updateStatusState = { version: null, moduleCount: 0 }
const SMALL_CATALOGUE_SIZE = 40
const typesInUse = {};
@ -1825,8 +1831,6 @@ RED.palette.editor = (function() {
const updateStatusWidget = $('<button type="button" class="red-ui-footer-button red-ui-update-status"></button>');
let updateStatusWidgetPopover;
const updateStatusState = { moduleCount: 0 }
let updateAvailable = [];
function addUpdateInfoToStatusBar() {
updateStatusWidgetPopover = RED.popover.create({
@ -1835,7 +1839,7 @@ RED.palette.editor = (function() {
interactive: true,
direction: "bottom",
content: function () {
const count = updateAvailable.length || 0;
const count = moduleUpdates.length || 0
const content = $('<div style="display: flex; flex-direction: column; gap: 5px;"></div>');
if (updateStatusState.version) {
$(`<a class='red-ui-button' href="https://github.com/node-red/node-red/releases/tag/${updateStatusState.version}" target="_blank">${RED._("telemetry.updateAvailableDesc", updateStatusState)}</a>`).appendTo(content)
@ -1845,7 +1849,7 @@ RED.palette.editor = (function() {
updateStatusWidgetPopover.close()
RED.actions.invoke("core:manage-palette", {
view: "nodes",
filter: '"' + updateAvailable.join('", "') + '"'
filter: '"' + moduleUpdates.map(u => u.package).join('", "') + '"'
});
}).appendTo(content)
}
@ -1867,7 +1871,7 @@ RED.palette.editor = (function() {
function refreshUpdateStatus() {
clearTimeout(pendingRefreshTimeout)
pendingRefreshTimeout = setTimeout(() => {
updateAvailable = [];
moduleUpdates.length = 0
for (const module of Object.keys(nodeEntries)) {
if (loadedIndex.hasOwnProperty(module)) {
const moduleInfo = nodeEntries[module].info;
@ -1875,35 +1879,51 @@ RED.palette.editor = (function() {
// Module updated
continue;
}
const current = moduleInfo.version
const latest = loadedIndex[module].version
if (updateAllowed &&
semVerCompare(loadedIndex[module].version, moduleInfo.version) > 0 &&
semVerCompare(latest, current) > 0 &&
RED.utils.checkModuleAllowed(module, null, updateAllowList, updateDenyList)
) {
updateAvailable.push(module);
moduleUpdates.push({ package: module, current, latest })
}
}
}
updateStatusState.moduleCount = updateAvailable.length;
updateStatusState.moduleCount = moduleUpdates.length
updateStatus();
}, 200)
}
function updateStatus() {
if (updateStatusState.moduleCount || updateStatusState.version) {
const updates = RED.palette.editor.getAvailableUpdates()
if (updates.count > 0) {
updateStatusWidget.empty();
let count = updateStatusState.moduleCount || 0;
if (updateStatusState.version) {
count ++
}
$(`<span><i class="fa fa-cube"></i> ${RED._("telemetry.updateAvailable", { count: count })}</span>`).appendTo(updateStatusWidget);
$(`<span><i class="fa fa-cube"></i> ${RED._("telemetry.updateAvailable", { count: updates.count })}</span>`).appendTo(updateStatusWidget);
RED.statusBar.show("red-ui-status-package-update");
} else {
RED.statusBar.hide("red-ui-status-package-update");
}
RED.events.emit("registry:updates-available", updates)
}
function getAvailableUpdates () {
const palette = [...moduleUpdates]
let core = null
let count = palette.length
if (updateStatusState.version) {
core = { current: RED.settings.version, latest: updateStatusState.version }
count ++
}
return {
count,
core,
palette
}
}
return {
init: init,
install: install
init,
install,
getAvailableUpdates
}
})();