From a6f01d7085524de3bb2105a72ee345eae12cb55d Mon Sep 17 00:00:00 2001 From: GogoVega <92022724+GogoVega@users.noreply.github.com> Date: Wed, 6 Nov 2024 16:20:23 +0100 Subject: [PATCH] Support for a module with nodes and plugins in the palette --- .../editor-client/src/js/ui/palette-editor.js | 160 +++++++++++++----- 1 file changed, 118 insertions(+), 42 deletions(-) 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 3d949f8ca..8b5ddc325 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 @@ -231,40 +231,82 @@ RED.palette.editor = (function() { } } - function _refreshNodeModule(module) { if (!nodeEntries.hasOwnProperty(module)) { - nodeEntries[module] = {info:RED.nodes.registry.getModule(module)}; - var index = [module]; - for (var s in nodeEntries[module].info.sets) { - if (nodeEntries[module].info.sets.hasOwnProperty(s)) { - index.push(s); - index = index.concat(nodeEntries[module].info.sets[s].types) + const nodeInfo = RED.nodes.registry.getModule(module); + let index = [module]; + + nodeEntries[module] = { + info: { + name: nodeInfo.name, + version: nodeInfo.version, + local: nodeInfo.local, + nodeSet: nodeInfo.sets, + }, + }; + + if (nodeInfo.pending_version) { + nodeEntries[module].info.pending_version = nodeInfo.pending_version; + } + + for (const set in nodeInfo.sets) { + if (nodeInfo.sets.hasOwnProperty(set)) { + index.push(set); + index = index.concat(nodeInfo.sets[set].types); } } + nodeEntries[module].index = index.join(",").toLowerCase(); nodeList.editableList('addItem', nodeEntries[module]); } else { - var moduleInfo = nodeEntries[module].info; - var nodeEntry = nodeEntries[module].elements; - if (nodeEntry) { - if (moduleInfo.plugin) { - nodeEntry.enableButton.hide(); - nodeEntry.removeButton.show(); + if (nodeEntries[module].info.pluginSet && !nodeEntries[module].info.nodeSet) { + // Since plugins are loaded before nodes, check if the module has nodes too + const nodeInfo = RED.nodes.registry.getModule(module); + + if (nodeInfo) { + let index = [nodeEntries[module].index]; + + for (const set in nodeInfo.sets) { + if (nodeInfo.sets.hasOwnProperty(set)) { + index.push(set); + index = index.concat(nodeInfo.sets[set].types) + } + } + + nodeEntries[module].info.nodeSet = nodeInfo.sets; + nodeEntries[module].index = index.join(",").toLowerCase(); + } + } + const moduleInfo = nodeEntries[module].info; + const nodeEntry = nodeEntries[module].elements; + if (nodeEntry) { + const setCount = []; + + if (moduleInfo.pluginSet) { let pluginCount = 0; - for (let setName in moduleInfo.sets) { - if (moduleInfo.sets.hasOwnProperty(setName)) { - let set = moduleInfo.sets[setName]; - if (set.plugins) { + for (const setName in moduleInfo.pluginSet) { + if (moduleInfo.pluginSet.hasOwnProperty(setName)) { + let set = moduleInfo.pluginSet[setName]; + if (set.plugins && set.plugins.length) { pluginCount += set.plugins.length; + } else if (set.plugins && !!RED.plugins.getPlugin(setName)) { + // `registerPlugin` in runtime not called but called in editor, add it + pluginCount++; } } } - - nodeEntry.setCount.text(RED._('palette.editor.pluginCount',{count:pluginCount,label:pluginCount})); - } else { + setCount.push(RED._('palette.editor.pluginCount', { count: pluginCount })); + + if (!moduleInfo.nodeSet) { + // Module only have plugins + nodeEntry.enableButton.hide(); + nodeEntry.removeButton.show(); + } + } + + if (moduleInfo.nodeSet) { var activeTypeCount = 0; var typeCount = 0; var errorCount = 0; @@ -272,10 +314,10 @@ RED.palette.editor = (function() { nodeEntries[module].totalUseCount = 0; nodeEntries[module].setUseCount = {}; - for (var setName in moduleInfo.sets) { - if (moduleInfo.sets.hasOwnProperty(setName)) { - var inUseCount = 0; - const set = moduleInfo.sets[setName]; + for (const setName in moduleInfo.nodeSet) { + if (moduleInfo.nodeSet.hasOwnProperty(setName)) { + let inUseCount = 0; + const set = moduleInfo.nodeSet[setName]; const setElements = nodeEntry.sets[setName] if (set.err) { @@ -292,8 +334,8 @@ RED.palette.editor = (function() { activeTypeCount += set.types.length; } typeCount += set.types.length; - for (var i=0;i 0) { nodeEntry.enableButton.text(RED._('palette.editor.inuse')); @@ -349,6 +391,7 @@ RED.palette.editor = (function() { nodeEntry.container.toggleClass("disabled",(activeTypeCount === 0)); } } + nodeEntry.setCount.text(setCount.join(" & ") || RED._("sidebar.info.empty")); } if (moduleInfo.pending_version) { nodeEntry.versionSpan.html(moduleInfo.version+' '+moduleInfo.pending_version).appendTo(nodeEntry.metaRow) @@ -700,19 +743,36 @@ RED.palette.editor = (function() { }) RED.events.on("registry:plugin-module-added", function(module) { - if (!nodeEntries.hasOwnProperty(module)) { - nodeEntries[module] = {info:RED.plugins.getModule(module)}; - var index = [module]; - for (var s in nodeEntries[module].info.sets) { - if (nodeEntries[module].info.sets.hasOwnProperty(s)) { - index.push(s); - index = index.concat(nodeEntries[module].info.sets[s].types) + const pluginInfo = RED.plugins.getModule(module); + let index = [module]; + + nodeEntries[module] = { + info: { + name: pluginInfo.name, + version: pluginInfo.version, + local: pluginInfo.local, + pluginSet: pluginInfo.sets, + } + }; + + if (pluginInfo.pending_version) { + nodeEntries[module].info.pending_version = pluginInfo.pending_version; + } + + for (const set in pluginInfo.sets) { + if (pluginInfo.sets.hasOwnProperty(set)) { + index.push(set); + // TODO: not sure plugin has `types` property + index = index.concat(pluginInfo.sets[set].types) } } + nodeEntries[module].index = index.join(",").toLowerCase(); nodeList.editableList('addItem', nodeEntries[module]); } else { + // Since plugins are loaded before nodes, + // `nodeEntries[module]` should be undefined _refreshNodeModule(module); } @@ -873,12 +933,28 @@ RED.palette.editor = (function() { } }) const populateSetList = function () { - var setList = Object.keys(entry.sets) - setList.sort(function(A,B) { + const setList = [...Object.keys(entry.nodeSet || {}), ...Object.keys(entry.pluginSet || {})]; + setList.sort(function (A, B) { return A.toLowerCase().localeCompare(B.toLowerCase()); }); - setList.forEach(function(setName) { - var set = entry.sets[setName]; + setList.forEach(function (setName) { + const set = (entry.nodeSet && setName in entry.nodeSet) ? entry.nodeSet[setName] : entry.pluginSet[setName]; + + if (set.plugins && !set.plugins.length) { + // `registerPlugin` in the runtime not called + if (!!RED.plugins.getPlugin(setName)) { + // Add plugin if registered in editor but not in runtime + // Can happen if plugin doesn't have .js file + set.plugins.push({ id: setName }); + } else { + // `registerPlugin` in the editor not called - do not add this empty set + return; + } + } else if (set.types && !set.types.length) { + // `registerPlugin` in the runtime not called - do not add this empty set + return; + } + var setRow = $('
',{class:"red-ui-palette-module-set"}).appendTo(contentRow); var buttonGroup = $('
',{class:"red-ui-palette-module-set-button-group"}).appendTo(setRow); var typeSwatches = {}; @@ -1317,7 +1393,7 @@ RED.palette.editor = (function() { } } else { // dedicated list management for plugins - if (entry.plugin) { + if (entry.pluginSet) { let e = nodeEntries[entry.name]; if (e) { @@ -1329,9 +1405,9 @@ RED.palette.editor = (function() { // cleans the editor accordingly of its left-overs. let found_onremove = true; - let keys = Object.keys(entry.sets); + let keys = Object.keys(entry.pluginSet); keys.forEach((key) => { - let set = entry.sets[key]; + let set = entry.pluginSet[key]; for (let i=0; i