mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Merge 1fd4fbc2991c6b612fff2df0f77622a2f21b2202 into 99b3b6530411665b0f4b76e3d0c3d69f973f4d6c
This commit is contained in:
commit
7f73c1fb5d
@ -265,6 +265,8 @@
|
|||||||
"download": "Download",
|
"download": "Download",
|
||||||
"importUnrecognised": "Imported unrecognised type:",
|
"importUnrecognised": "Imported unrecognised type:",
|
||||||
"importUnrecognised_plural": "Imported unrecognised types:",
|
"importUnrecognised_plural": "Imported unrecognised types:",
|
||||||
|
"importWithModuleInfo": "Required dependencies missing",
|
||||||
|
"importWithModuleInfoDesc": "These nodes are not currently installed in your palette and are required for the imported flow:",
|
||||||
"importDuplicate": "Imported duplicate node:",
|
"importDuplicate": "Imported duplicate node:",
|
||||||
"importDuplicate_plural": "Imported duplicate nodes:",
|
"importDuplicate_plural": "Imported duplicate nodes:",
|
||||||
"nodesExported": "Nodes exported to clipboard",
|
"nodesExported": "Nodes exported to clipboard",
|
||||||
|
@ -1474,7 +1474,12 @@ RED.nodes = (function() {
|
|||||||
/**
|
/**
|
||||||
* Converts the current node selection to an exportable JSON Object
|
* Converts the current node selection to an exportable JSON Object
|
||||||
**/
|
**/
|
||||||
function createExportableNodeSet(set, exportedIds, exportedSubflows, exportedConfigNodes) {
|
function createExportableNodeSet(set, {
|
||||||
|
exportedIds,
|
||||||
|
exportedSubflows,
|
||||||
|
exportedConfigNodes,
|
||||||
|
includeModuleConfig = false
|
||||||
|
} = {}) {
|
||||||
var nns = [];
|
var nns = [];
|
||||||
|
|
||||||
exportedIds = exportedIds || {};
|
exportedIds = exportedIds || {};
|
||||||
@ -1508,7 +1513,7 @@ RED.nodes = (function() {
|
|||||||
subflowSet = subflowSet.concat(RED.nodes.junctions(subflowId))
|
subflowSet = subflowSet.concat(RED.nodes.junctions(subflowId))
|
||||||
subflowSet = subflowSet.concat(RED.nodes.groups(subflowId))
|
subflowSet = subflowSet.concat(RED.nodes.groups(subflowId))
|
||||||
|
|
||||||
var exportableSubflow = createExportableNodeSet(subflowSet, exportedIds, exportedSubflows, exportedConfigNodes);
|
var exportableSubflow = createExportableNodeSet(subflowSet, { exportedIds, exportedSubflows, exportedConfigNodes });
|
||||||
nns = exportableSubflow.concat(nns);
|
nns = exportableSubflow.concat(nns);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1543,13 +1548,16 @@ RED.nodes = (function() {
|
|||||||
}
|
}
|
||||||
nns.push(convertedNode);
|
nns.push(convertedNode);
|
||||||
if (node.type === "group") {
|
if (node.type === "group") {
|
||||||
nns = nns.concat(createExportableNodeSet(node.nodes, exportedIds, exportedSubflows, exportedConfigNodes));
|
nns = nns.concat(createExportableNodeSet(node.nodes, { exportedIds, exportedSubflows, exportedConfigNodes }));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var convertedSubflow = convertSubflow(node, { credentials: false });
|
var convertedSubflow = convertSubflow(node, { credentials: false });
|
||||||
nns.push(convertedSubflow);
|
nns.push(convertedSubflow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (includeModuleConfig) {
|
||||||
|
updateGlobalConfigModuleList(nns)
|
||||||
|
}
|
||||||
return nns;
|
return nns;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1587,6 +1595,7 @@ RED.nodes = (function() {
|
|||||||
RED.nodes.eachNode(function(n) {
|
RED.nodes.eachNode(function(n) {
|
||||||
nns.push(convertNode(n, opts));
|
nns.push(convertNode(n, opts));
|
||||||
})
|
})
|
||||||
|
updateGlobalConfigModuleList(nns)
|
||||||
return nns;
|
return nns;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1802,6 +1811,7 @@ RED.nodes = (function() {
|
|||||||
* - id:import - import as-is
|
* - id:import - import as-is
|
||||||
* - id:copy - import with new id
|
* - id:copy - import with new id
|
||||||
* - id:replace - import over the top of existing
|
* - id:replace - import over the top of existing
|
||||||
|
* - modules: map of module:version - hints for unknown nodes
|
||||||
*/
|
*/
|
||||||
function importNodes(newNodesObj,options) { // createNewIds,createMissingWorkspace) {
|
function importNodes(newNodesObj,options) { // createNewIds,createMissingWorkspace) {
|
||||||
const defOpts = { generateIds: false, addFlow: false, markChanged: false, reimport: false, importMap: {} }
|
const defOpts = { generateIds: false, addFlow: false, markChanged: false, reimport: false, importMap: {} }
|
||||||
@ -1937,12 +1947,54 @@ RED.nodes = (function() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
if (!isInitialLoad && unknownTypes.length > 0) {
|
if (!isInitialLoad && unknownTypes.length > 0) {
|
||||||
var typeList = $("<ul>");
|
const notificationOptions = {
|
||||||
unknownTypes.forEach(function(t) {
|
type: "error",
|
||||||
$("<li>").text(t).appendTo(typeList);
|
fixed: false,
|
||||||
})
|
timeout: 10000,
|
||||||
typeList = typeList[0].outerHTML;
|
}
|
||||||
RED.notify("<p>"+RED._("clipboard.importUnrecognised",{count:unknownTypes.length})+"</p>"+typeList,"error",false,10000);
|
let unknownNotification
|
||||||
|
if (options.modules) {
|
||||||
|
notificationOptions.fixed = true
|
||||||
|
delete notificationOptions.timeout
|
||||||
|
// We have module hint list from imported global-config
|
||||||
|
// Provide option to install missing modules
|
||||||
|
notificationOptions.buttons = [
|
||||||
|
{
|
||||||
|
text: "Manage dependencies",
|
||||||
|
class:"primary",
|
||||||
|
click: function(e) {
|
||||||
|
unknownNotification.close();
|
||||||
|
|
||||||
|
RED.actions.invoke('core:manage-palette', {
|
||||||
|
view: 'install',
|
||||||
|
filter: '"' + Object.keys(options.modules).join('", "') + '"'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
let moduleList = $("<ul>");
|
||||||
|
Object.keys(options.modules).forEach(function(t) {
|
||||||
|
$("<li>").text(t).appendTo(moduleList);
|
||||||
|
})
|
||||||
|
moduleList = moduleList[0].outerHTML;
|
||||||
|
unknownNotification = RED.notify(
|
||||||
|
"<p>"+RED._("clipboard.importWithModuleInfo")+"</p>"+
|
||||||
|
"<p>"+RED._("clipboard.importWithModuleInfoDesc")+"</p>"+
|
||||||
|
moduleList,
|
||||||
|
notificationOptions
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
var typeList = $("<ul>");
|
||||||
|
unknownTypes.forEach(function(t) {
|
||||||
|
$("<li>").text(t).appendTo(typeList);
|
||||||
|
})
|
||||||
|
typeList = typeList[0].outerHTML;
|
||||||
|
|
||||||
|
unknownNotification = RED.notify(
|
||||||
|
"<p>"+RED._("clipboard.importUnrecognised",{count:unknownTypes.length})+"</p>"+typeList,
|
||||||
|
notificationOptions
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var activeWorkspace = RED.workspaces.active();
|
var activeWorkspace = RED.workspaces.active();
|
||||||
@ -2310,6 +2362,9 @@ RED.nodes = (function() {
|
|||||||
delete node.z;
|
delete node.z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const unknownTypeDef = RED.nodes.getType('unknown')
|
||||||
|
node._def.oneditprepare = unknownTypeDef.oneditprepare
|
||||||
|
|
||||||
var orig = {};
|
var orig = {};
|
||||||
for (var p in n) {
|
for (var p in n) {
|
||||||
if (n.hasOwnProperty(p) && p!="x" && p!="y" && p!="z" && p!="id" && p!="wires") {
|
if (n.hasOwnProperty(p) && p!="x" && p!="y" && p!="z" && p!="id" && p!="wires") {
|
||||||
@ -2319,6 +2374,10 @@ RED.nodes = (function() {
|
|||||||
node._orig = orig;
|
node._orig = orig;
|
||||||
node.name = n.type;
|
node.name = n.type;
|
||||||
node.type = "unknown";
|
node.type = "unknown";
|
||||||
|
if (options.modules) {
|
||||||
|
// We have a module hint list. Attach to the unknown node so we can reference it later
|
||||||
|
node.modules = Object.keys(options.modules)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (node._def.category != "config") {
|
if (node._def.category != "config") {
|
||||||
if (n.hasOwnProperty('inputs')) {
|
if (n.hasOwnProperty('inputs')) {
|
||||||
@ -2931,7 +2990,33 @@ RED.nodes = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function getModuleListForNodes(nodes) {
|
||||||
|
const modules = {}
|
||||||
|
nodes.forEach(n => {
|
||||||
|
const nodeSet = RED.nodes.registry.getNodeSetForType(n.type)
|
||||||
|
if (nodeSet) {
|
||||||
|
modules[nodeSet.module] = nodeSet.version
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return modules
|
||||||
|
}
|
||||||
|
function updateGlobalConfigModuleList(nodes) {
|
||||||
|
const modules = getModuleListForNodes(nodes)
|
||||||
|
delete modules['node-red']
|
||||||
|
const hasModules = (Object.keys(modules).length > 0)
|
||||||
|
let globalConfigNode = nodes.find(n => n.type === 'global-config')
|
||||||
|
if (!globalConfigNode && hasModules) {
|
||||||
|
globalConfigNode = {
|
||||||
|
id: RED.nodes.id(),
|
||||||
|
type: 'global-config',
|
||||||
|
env: [],
|
||||||
|
modules
|
||||||
|
}
|
||||||
|
nodes.push(globalConfigNode)
|
||||||
|
} else if (globalConfigNode) {
|
||||||
|
globalConfigNode.modules = modules
|
||||||
|
}
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
init: function() {
|
init: function() {
|
||||||
RED.events.on("registry:node-type-added",function(type) {
|
RED.events.on("registry:node-type-added",function(type) {
|
||||||
|
@ -730,7 +730,7 @@ RED.clipboard = (function() {
|
|||||||
nodes = RED.view.selection().nodes||[];
|
nodes = RED.view.selection().nodes||[];
|
||||||
}
|
}
|
||||||
// Don't include the subflow meta-port nodes in the exported selection
|
// Don't include the subflow meta-port nodes in the exported selection
|
||||||
nodes = RED.nodes.createExportableNodeSet(nodes.filter(function(n) { return n.type !== 'subflow'}));
|
nodes = RED.nodes.createExportableNodeSet(nodes.filter(function(n) { return n.type !== 'subflow'}), { includeModuleConfig: true });
|
||||||
} else if (type === 'flow') {
|
} else if (type === 'flow') {
|
||||||
var activeWorkspace = RED.workspaces.active();
|
var activeWorkspace = RED.workspaces.active();
|
||||||
nodes = RED.nodes.groups(activeWorkspace);
|
nodes = RED.nodes.groups(activeWorkspace);
|
||||||
@ -745,7 +745,7 @@ RED.clipboard = (function() {
|
|||||||
});
|
});
|
||||||
var parentNode = RED.nodes.workspace(activeWorkspace)||RED.nodes.subflow(activeWorkspace);
|
var parentNode = RED.nodes.workspace(activeWorkspace)||RED.nodes.subflow(activeWorkspace);
|
||||||
nodes.unshift(parentNode);
|
nodes.unshift(parentNode);
|
||||||
nodes = RED.nodes.createExportableNodeSet(nodes);
|
nodes = RED.nodes.createExportableNodeSet(nodes, { includeModuleConfig: true });
|
||||||
} else if (type === 'full') {
|
} else if (type === 'full') {
|
||||||
nodes = RED.nodes.createCompleteNodeSet({ credentials: false });
|
nodes = RED.nodes.createCompleteNodeSet({ credentials: false });
|
||||||
}
|
}
|
||||||
@ -848,7 +848,7 @@ RED.clipboard = (function() {
|
|||||||
children: []
|
children: []
|
||||||
};
|
};
|
||||||
treeSubflows.push(subflows[node.id])
|
treeSubflows.push(subflows[node.id])
|
||||||
} else {
|
} else if (node.type !== 'global-config') {
|
||||||
nodes.push(node);
|
nodes.push(node);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -33,8 +33,7 @@ RED.envVar = (function() {
|
|||||||
id: RED.nodes.id(),
|
id: RED.nodes.id(),
|
||||||
type: "global-config",
|
type: "global-config",
|
||||||
env: [],
|
env: [],
|
||||||
name: "global-config",
|
modules: {},
|
||||||
label: "",
|
|
||||||
hasUsers: false,
|
hasUsers: false,
|
||||||
users: [],
|
users: [],
|
||||||
credentials: cred,
|
credentials: cred,
|
||||||
|
@ -666,8 +666,20 @@ RED.palette.editor = (function() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
RED.actions.add("core:manage-palette",function() {
|
RED.actions.add("core:manage-palette", function(opts) {
|
||||||
RED.userSettings.show('palette');
|
RED.userSettings.show('palette');
|
||||||
|
if (opts) {
|
||||||
|
if (opts.view) {
|
||||||
|
editorTabs.activateTab(opts.view);
|
||||||
|
}
|
||||||
|
if (opts.filter) {
|
||||||
|
if (opts.view === 'install') {
|
||||||
|
searchInput.searchBox('value', opts.filter)
|
||||||
|
} else if (opts.view === 'nodes') {
|
||||||
|
filterInput.searchBox('value', opts.filter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
RED.events.on('registry:module-updated', function(ns) {
|
RED.events.on('registry:module-updated', function(ns) {
|
||||||
@ -1023,8 +1035,35 @@ RED.palette.editor = (function() {
|
|||||||
change: function() {
|
change: function() {
|
||||||
var searchTerm = $(this).val().trim().toLowerCase();
|
var searchTerm = $(this).val().trim().toLowerCase();
|
||||||
if (searchTerm.length > 0 || loadedList.length < 20) {
|
if (searchTerm.length > 0 || loadedList.length < 20) {
|
||||||
|
const searchTerms = []
|
||||||
|
searchTerm.split(',').forEach(term => {
|
||||||
|
term = term.trim()
|
||||||
|
if (term) {
|
||||||
|
const isExact = term[0] === '"' && term[term.length-1] === '"'
|
||||||
|
searchTerms.push({
|
||||||
|
exact: isExact,
|
||||||
|
term: isExact ? term.substring(1,term.length-1) : term
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
filteredList = loadedList.filter(function(m) {
|
filteredList = loadedList.filter(function(m) {
|
||||||
return (m.index.indexOf(searchTerm) > -1);
|
for (let i = 0; i < searchTerms.length; i++) {
|
||||||
|
const location = m.index.indexOf(searchTerms[i].term)
|
||||||
|
if (
|
||||||
|
(
|
||||||
|
searchTerms[i].exact &&
|
||||||
|
(
|
||||||
|
location === 0 && (
|
||||||
|
m.index.length === searchTerms[i].term.length ||
|
||||||
|
m.index[searchTerms[i].term.length] === ','
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) ||
|
||||||
|
(!searchTerms[i].exact && location > -1)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
}).map(function(f) { return {info:f}});
|
}).map(function(f) { return {info:f}});
|
||||||
refreshFilteredItems();
|
refreshFilteredItems();
|
||||||
searchInput.searchBox('count',filteredList.length+" / "+loadedList.length);
|
searchInput.searchBox('count',filteredList.length+" / "+loadedList.length);
|
||||||
|
@ -5664,27 +5664,29 @@ RED.view = (function() {
|
|||||||
activeSubflowChanged = activeSubflow.changed;
|
activeSubflowChanged = activeSubflow.changed;
|
||||||
}
|
}
|
||||||
var filteredNodesToImport = nodesToImport;
|
var filteredNodesToImport = nodesToImport;
|
||||||
var globalConfig = null;
|
var importedGlobalConfig = null;
|
||||||
var gconf = null;
|
var existingGlobalConfig = null;
|
||||||
|
|
||||||
RED.nodes.eachConfig(function (conf) {
|
RED.nodes.eachConfig(function (conf) {
|
||||||
if (conf.type === "global-config") {
|
if (conf.type === "global-config") {
|
||||||
gconf = conf;
|
existingGlobalConfig = conf;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (gconf) {
|
if (existingGlobalConfig) {
|
||||||
filteredNodesToImport = nodesToImport.filter(function (n) {
|
filteredNodesToImport = nodesToImport.filter(function (n) {
|
||||||
return (n.type !== "global-config");
|
if (n.type === "global-config") {
|
||||||
});
|
importedGlobalConfig = n
|
||||||
globalConfig = nodesToImport.find(function (n) {
|
return false
|
||||||
return (n.type === "global-config");
|
}
|
||||||
|
return true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
var result = RED.nodes.import(filteredNodesToImport,{
|
var result = RED.nodes.import(filteredNodesToImport,{
|
||||||
generateIds: options.generateIds,
|
generateIds: options.generateIds,
|
||||||
addFlow: addNewFlow,
|
addFlow: addNewFlow,
|
||||||
importMap: options.importMap,
|
importMap: options.importMap,
|
||||||
markChanged: true
|
markChanged: true,
|
||||||
|
modules: importedGlobalConfig ? (importedGlobalConfig.modules || {}) : {}
|
||||||
});
|
});
|
||||||
if (result) {
|
if (result) {
|
||||||
var new_nodes = result.nodes;
|
var new_nodes = result.nodes;
|
||||||
@ -5808,38 +5810,38 @@ RED.view = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (globalConfig) {
|
if (importedGlobalConfig) {
|
||||||
// merge global env to existing global-config
|
// merge global env to existing global-config
|
||||||
var env0 = gconf.env;
|
var existingEnv = existingGlobalConfig.env || [];
|
||||||
var env1 = globalConfig.env;
|
var importedEnv = importedGlobalConfig.env || []
|
||||||
var newEnv = Array.from(env0);
|
var newEnv = Array.from(existingEnv);
|
||||||
var changed = false;
|
var changed = false;
|
||||||
|
|
||||||
env1.forEach(function (item1) {
|
importedEnv.forEach(function (importedItem) {
|
||||||
var index = newEnv.findIndex(function (item0) {
|
var index = newEnv.findIndex(function (existingItem) {
|
||||||
return (item0.name === item1.name);
|
return (existingItem.name === importedItem.name);
|
||||||
});
|
});
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
var item0 = newEnv[index];
|
const existingItem = newEnv[index];
|
||||||
if ((item0.type !== item1.type) ||
|
if ((existingItem.type !== importedItem.type) ||
|
||||||
(item0.value !== item1.value)) {
|
(existingItem.value !== importedItem.value)) {
|
||||||
newEnv[index] = item1;
|
newEnv[index] = importedItem;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
newEnv.push(item1);
|
newEnv.push(importedItem);
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if(changed) {
|
if (changed) {
|
||||||
gconf.env = newEnv;
|
existingGlobalConfig.env = newEnv;
|
||||||
var replaceEvent = {
|
var replaceEvent = {
|
||||||
t: "edit",
|
t: "edit",
|
||||||
node: gconf,
|
node: existingGlobalConfig,
|
||||||
changed: true,
|
changed: true,
|
||||||
changes: {
|
changes: {
|
||||||
env: env0
|
env: existingEnv
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
historyEvent = {
|
historyEvent = {
|
||||||
|
@ -11,12 +11,13 @@
|
|||||||
RED.nodes.registerType('global-config',{
|
RED.nodes.registerType('global-config',{
|
||||||
category: 'config',
|
category: 'config',
|
||||||
defaults: {
|
defaults: {
|
||||||
name: { value: "" },
|
|
||||||
env: { value: [] },
|
env: { value: [] },
|
||||||
|
modules: { value: {} }
|
||||||
},
|
},
|
||||||
credentials: {
|
credentials: {
|
||||||
map: { type: "map" }
|
map: { type: "map" }
|
||||||
},
|
},
|
||||||
|
label: 'global-config',
|
||||||
oneditprepare: function() {
|
oneditprepare: function() {
|
||||||
$('#node-input-edit-env-var').on('click', function(evt) {
|
$('#node-input-edit-env-var').on('click', function(evt) {
|
||||||
RED.actions.invoke('core:show-user-settings', 'envvar')
|
RED.actions.invoke('core:show-user-settings', 'envvar')
|
||||||
|
@ -1,14 +1,22 @@
|
|||||||
|
|
||||||
<script type="text/html" data-template-name="unknown">
|
<script type="text/html" data-template-name="unknown">
|
||||||
<div class="form-tips"><span data-i18n="[html]unknown.tip"></span></div>
|
<div class="form-tips">
|
||||||
|
<span data-i18n="[html]unknown.tip"></span>
|
||||||
|
<p id="unknown-module-known">
|
||||||
|
<button id="unknown-manage-dependencies" class="red-ui-button">Manage dependencies</button>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
RED.nodes.registerType('unknown',{
|
RED.nodes.registerType('unknown', {
|
||||||
category: 'unknown',
|
category: 'unknown',
|
||||||
color:"#fff0f0",
|
color:"#fff000",
|
||||||
defaults: {
|
defaults: {
|
||||||
name: {value:""}
|
name: {value:""},
|
||||||
|
modules: { value: [] }
|
||||||
},
|
},
|
||||||
inputs:1,
|
inputs:1,
|
||||||
outputs:1,
|
outputs:1,
|
||||||
@ -18,6 +26,20 @@
|
|||||||
},
|
},
|
||||||
labelStyle: function() {
|
labelStyle: function() {
|
||||||
return "node_label_unknown";
|
return "node_label_unknown";
|
||||||
|
},
|
||||||
|
oneditprepare: function () {
|
||||||
|
const node = this
|
||||||
|
if (this.modules && this.modules.length > 0) {
|
||||||
|
$('#unknown-manage-dependencies').on('click', function () {
|
||||||
|
RED.actions.invoke('core:cancel-edit-tray')
|
||||||
|
RED.actions.invoke('core:manage-palette', {
|
||||||
|
view: 'install',
|
||||||
|
filter: '"' + node.modules.join('", "') + '"'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
$('#unknown-module-known').hide()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user