@node-red/editor-client 4.1.0-beta.1 → 4.1.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/locales/en-US/editor.json +2 -1
- package/locales/en-US/infotips.json +1 -1
- package/locales/es-ES/infotips.json +1 -1
- package/locales/fr/infotips.json +1 -1
- package/locales/ja/editor.json +25 -1
- package/locales/ru/infotips.json +3 -3
- package/package.json +1 -1
- package/public/red/about +30 -0
- package/public/red/red.js +312 -82
- package/public/red/red.min.js +3 -3
- package/public/red/tours/4.0/welcome.js +8 -8
- package/public/red/tours/welcome.js +23 -3
- package/public/vendor/jquery/css/base/images/ui-icons_444444_256x240.png +0 -0
- package/public/vendor/jquery/css/base/images/ui-icons_555555_256x240.png +0 -0
- package/public/vendor/jquery/css/base/images/ui-icons_777620_256x240.png +0 -0
- package/public/vendor/jquery/css/base/images/ui-icons_777777_256x240.png +0 -0
- package/public/vendor/jquery/css/base/images/ui-icons_cc0000_256x240.png +0 -0
- package/public/vendor/jquery/css/base/images/ui-icons_ffffff_256x240.png +0 -0
- package/public/vendor/jquery/css/base/jquery-ui.min.css +6 -6
- package/public/vendor/vendor.js +7 -9
package/public/red/red.js
CHANGED
|
@@ -6501,29 +6501,29 @@ RED.nodes = (function() {
|
|
|
6501
6501
|
// Provide option to install missing modules
|
|
6502
6502
|
notificationOptions.buttons = [
|
|
6503
6503
|
{
|
|
6504
|
-
text: RED._("palette.editor.
|
|
6504
|
+
text: RED._("palette.editor.installAll"),
|
|
6505
6505
|
class: "primary",
|
|
6506
6506
|
click: function(e) {
|
|
6507
6507
|
unknownNotification.close();
|
|
6508
6508
|
|
|
6509
6509
|
RED.actions.invoke('core:manage-palette', {
|
|
6510
|
-
|
|
6511
|
-
|
|
6510
|
+
autoInstall: true,
|
|
6511
|
+
modules: missingModules.reduce((modules, moduleName) => {
|
|
6512
|
+
modules[moduleName] = options.modules[moduleName];
|
|
6513
|
+
return modules;
|
|
6514
|
+
}, {}),
|
|
6512
6515
|
});
|
|
6513
6516
|
}
|
|
6514
6517
|
},
|
|
6515
6518
|
{
|
|
6516
|
-
text: RED._("palette.editor.
|
|
6519
|
+
text: RED._("palette.editor.manageModules"),
|
|
6517
6520
|
class: "pull-left",
|
|
6518
6521
|
click: function(e) {
|
|
6519
6522
|
unknownNotification.close();
|
|
6520
6523
|
|
|
6521
6524
|
RED.actions.invoke('core:manage-palette', {
|
|
6522
|
-
|
|
6523
|
-
|
|
6524
|
-
modules[moduleName] = options.modules[moduleName];
|
|
6525
|
-
return modules;
|
|
6526
|
-
}, {}),
|
|
6525
|
+
view: 'install',
|
|
6526
|
+
filter: '"' + missingModules.join('", "') + '"'
|
|
6527
6527
|
});
|
|
6528
6528
|
}
|
|
6529
6529
|
}
|
|
@@ -9864,7 +9864,7 @@ RED.utils = (function() {
|
|
|
9864
9864
|
|
|
9865
9865
|
renderer.code = function (code, lang) {
|
|
9866
9866
|
if(lang === "mermaid") {
|
|
9867
|
-
return `<pre class='mermaid'>${code}</pre>`;
|
|
9867
|
+
return `<pre style='word-break: unset;' data-c64='${btoa(code)}' class='mermaid'>${code}</pre>`;
|
|
9868
9868
|
} else {
|
|
9869
9869
|
return "<pre><code>" +code +"</code></pre>";
|
|
9870
9870
|
}
|
|
@@ -17310,14 +17310,25 @@ RED.stack = (function() {
|
|
|
17310
17310
|
* The function must either return auto-complete options, or pass them
|
|
17311
17311
|
* to the optional 'done' parameter.
|
|
17312
17312
|
* If the function signature includes 'done', it must be used
|
|
17313
|
+
* The auto-complete options can either be an array of strings, or an array of objects in the form:
|
|
17314
|
+
* {
|
|
17315
|
+
* value: String : the value to insert if selected
|
|
17316
|
+
* label: String|DOM Element : the label to display in the dropdown.
|
|
17317
|
+
* }
|
|
17318
|
+
*
|
|
17313
17319
|
* minLength: number
|
|
17314
17320
|
* If `minLength` is 0, pressing down arrow will show the list
|
|
17321
|
+
*
|
|
17322
|
+
* completionPluginType: String
|
|
17323
|
+
* If provided instead of `search`, this will look for any plugins
|
|
17324
|
+
* registered with the given type that implement the `getCompletions` function. This
|
|
17325
|
+
* can be an async function that returns an array of string completions. It does not support
|
|
17326
|
+
* the full options object as above.
|
|
17315
17327
|
*
|
|
17316
|
-
*
|
|
17317
|
-
*
|
|
17318
|
-
*
|
|
17319
|
-
*
|
|
17320
|
-
* }
|
|
17328
|
+
* node: Node
|
|
17329
|
+
* If provided, this will be passed to the `getCompletions` function of the plugin
|
|
17330
|
+
* to allow the plugin to provide context-aware completions.
|
|
17331
|
+
*
|
|
17321
17332
|
*
|
|
17322
17333
|
*/
|
|
17323
17334
|
|
|
@@ -17326,6 +17337,54 @@ RED.stack = (function() {
|
|
|
17326
17337
|
const that = this;
|
|
17327
17338
|
this.completionMenuShown = false;
|
|
17328
17339
|
this.options.minLength = parseInteger(this.options.minLength, 1, 0);
|
|
17340
|
+
if (!this.options.search) {
|
|
17341
|
+
// No search function provided; nothing to provide completions
|
|
17342
|
+
if (this.options.completionPluginType) {
|
|
17343
|
+
const plugins = RED.plugins.getPluginsByType(this.options.completionPluginType)
|
|
17344
|
+
if (plugins.length > 0) {
|
|
17345
|
+
this.options.search = async function (value, done) {
|
|
17346
|
+
// for now, only support a single plugin
|
|
17347
|
+
const promises = plugins.map(plugin => plugin.getCompletions(value, that.options.context))
|
|
17348
|
+
const completions = (await Promise.all(promises)).flat()
|
|
17349
|
+
const results = []
|
|
17350
|
+
completions.forEach(completion => {
|
|
17351
|
+
const element = $('<div>',{style: "display: flex"})
|
|
17352
|
+
const valEl = $('<div/>',{ class: "red-ui-autoComplete-completion" })
|
|
17353
|
+
const valMatch = getMatch(completion, value)
|
|
17354
|
+
if (valMatch.found) {
|
|
17355
|
+
valEl.append(generateSpans(valMatch))
|
|
17356
|
+
valEl.appendTo(element)
|
|
17357
|
+
results.push({
|
|
17358
|
+
value: completion,
|
|
17359
|
+
label: element,
|
|
17360
|
+
match: valMatch
|
|
17361
|
+
})
|
|
17362
|
+
}
|
|
17363
|
+
results.sort((a, b) => {
|
|
17364
|
+
if (a.match.exact && !b.match.exact) {
|
|
17365
|
+
return -1;
|
|
17366
|
+
} else if (!a.match.exact && b.match.exact) {
|
|
17367
|
+
return 1;
|
|
17368
|
+
} else if (a.match.index < b.match.index) {
|
|
17369
|
+
return -1;
|
|
17370
|
+
} else if (a.match.index > b.match.index) {
|
|
17371
|
+
return 1;
|
|
17372
|
+
} else {
|
|
17373
|
+
return 0;
|
|
17374
|
+
}
|
|
17375
|
+
})
|
|
17376
|
+
})
|
|
17377
|
+
done(results)
|
|
17378
|
+
}
|
|
17379
|
+
} else {
|
|
17380
|
+
// No search function and no plugins found
|
|
17381
|
+
return
|
|
17382
|
+
}
|
|
17383
|
+
} else {
|
|
17384
|
+
// No search function and no plugin type provided
|
|
17385
|
+
return
|
|
17386
|
+
}
|
|
17387
|
+
}
|
|
17329
17388
|
this.options.search = this.options.search || function() { return [] };
|
|
17330
17389
|
this.element.addClass("red-ui-autoComplete");
|
|
17331
17390
|
this.element.on("keydown.red-ui-autoComplete", function(evt) {
|
|
@@ -17387,6 +17446,11 @@ RED.stack = (function() {
|
|
|
17387
17446
|
}
|
|
17388
17447
|
return
|
|
17389
17448
|
}
|
|
17449
|
+
if (typeof completions[0] === "string") {
|
|
17450
|
+
completions = completions.map(function(c) {
|
|
17451
|
+
return { value: c, label: c };
|
|
17452
|
+
});
|
|
17453
|
+
}
|
|
17390
17454
|
if (that.completionMenuShown) {
|
|
17391
17455
|
that.menu.options(completions);
|
|
17392
17456
|
} else {
|
|
@@ -17418,6 +17482,27 @@ RED.stack = (function() {
|
|
|
17418
17482
|
if(isNaN(n) || n < min || n > max) { n = def || 0; }
|
|
17419
17483
|
return n;
|
|
17420
17484
|
}
|
|
17485
|
+
// TODO: this is copied from typedInput - should be a shared utility
|
|
17486
|
+
function getMatch(value, searchValue) {
|
|
17487
|
+
const idx = value.toLowerCase().indexOf(searchValue.toLowerCase());
|
|
17488
|
+
const len = idx > -1 ? searchValue.length : 0;
|
|
17489
|
+
return {
|
|
17490
|
+
index: idx,
|
|
17491
|
+
found: idx > -1,
|
|
17492
|
+
pre: value.substring(0,idx),
|
|
17493
|
+
match: value.substring(idx,idx+len),
|
|
17494
|
+
post: value.substring(idx+len),
|
|
17495
|
+
exact: idx === 0 && value.length === searchValue.length
|
|
17496
|
+
}
|
|
17497
|
+
}
|
|
17498
|
+
// TODO: this is copied from typedInput - should be a shared utility
|
|
17499
|
+
function generateSpans(match) {
|
|
17500
|
+
const els = [];
|
|
17501
|
+
if(match.pre) { els.push($('<span/>').text(match.pre)); }
|
|
17502
|
+
if(match.match) { els.push($('<span/>',{style:"font-weight: bold; color: var(--red-ui-text-color-link);"}).text(match.match)); }
|
|
17503
|
+
if(match.post) { els.push($('<span/>').text(match.post)); }
|
|
17504
|
+
return els;
|
|
17505
|
+
}
|
|
17421
17506
|
})(jQuery);
|
|
17422
17507
|
;RED.actions = (function() {
|
|
17423
17508
|
var actions = {
|
|
@@ -20657,6 +20742,7 @@ RED.keyboard = (function() {
|
|
|
20657
20742
|
"backspace": 8,
|
|
20658
20743
|
"delete": 46,
|
|
20659
20744
|
"space": 32,
|
|
20745
|
+
"tab": 9,
|
|
20660
20746
|
";":186,
|
|
20661
20747
|
"=":187,
|
|
20662
20748
|
"+":187, // <- QWERTY specific
|
|
@@ -23195,7 +23281,9 @@ RED.view = (function() {
|
|
|
23195
23281
|
return;
|
|
23196
23282
|
}
|
|
23197
23283
|
var historyEvent = result.historyEvent;
|
|
23198
|
-
|
|
23284
|
+
const linkToSplice = $(ui.helper).data("splice");
|
|
23285
|
+
|
|
23286
|
+
var nn = RED.nodes.add(result.node, { source: 'palette', splice: !!linkToSplice });
|
|
23199
23287
|
|
|
23200
23288
|
var showLabel = RED.utils.getMessageProperty(RED.settings.get('editor'),"view.view-node-show-label");
|
|
23201
23289
|
if (showLabel !== undefined && (nn._def.hasOwnProperty("showLabel")?nn._def.showLabel:true) && !nn._def.defaults.hasOwnProperty("l")) {
|
|
@@ -23254,7 +23342,6 @@ RED.view = (function() {
|
|
|
23254
23342
|
nn.y -= gridOffset.y;
|
|
23255
23343
|
}
|
|
23256
23344
|
|
|
23257
|
-
var linkToSplice = $(ui.helper).data("splice");
|
|
23258
23345
|
if (linkToSplice) {
|
|
23259
23346
|
spliceLink(linkToSplice, nn, historyEvent)
|
|
23260
23347
|
}
|
|
@@ -23937,10 +24024,12 @@ RED.view = (function() {
|
|
|
23937
24024
|
var lastAddedX;
|
|
23938
24025
|
var lastAddedWidth;
|
|
23939
24026
|
|
|
23940
|
-
const context = {
|
|
24027
|
+
const context = {
|
|
24028
|
+
workspace: RED.workspaces.active()
|
|
24029
|
+
}
|
|
23941
24030
|
|
|
23942
24031
|
if (quickAddLink) {
|
|
23943
|
-
context.source = quickAddLink.node
|
|
24032
|
+
context.source = quickAddLink.node;
|
|
23944
24033
|
context.sourcePort = quickAddLink.port;
|
|
23945
24034
|
context.sourcePortType = quickAddLink.portType;
|
|
23946
24035
|
if (quickAddLink?.virtualLink) {
|
|
@@ -23956,6 +24045,7 @@ RED.view = (function() {
|
|
|
23956
24045
|
y:clientY-mainPos.top+ node_height/2 + 5 - (oy-point[1]),
|
|
23957
24046
|
disableFocus: touchTrigger,
|
|
23958
24047
|
filter: filter,
|
|
24048
|
+
context,
|
|
23959
24049
|
move: function(dx,dy) {
|
|
23960
24050
|
if (ghostNode) {
|
|
23961
24051
|
var pos = d3.transform(ghostNode.attr("transform")).translate;
|
|
@@ -24004,8 +24094,9 @@ RED.view = (function() {
|
|
|
24004
24094
|
if (quickAddLink) {
|
|
24005
24095
|
// Need to attach the link to the suggestion. This is assumed to be the first
|
|
24006
24096
|
// node in the array - as that's the one we've focussed on.
|
|
24007
|
-
|
|
24008
|
-
|
|
24097
|
+
// We need to map from the suggested node's id to the imported node's id,
|
|
24098
|
+
// and then get the proxy object for the node
|
|
24099
|
+
const targetNode = RED.nodes.node(importResult.nodeMap[type.nodes[0].id].id)
|
|
24009
24100
|
const drag_line = quickAddLink;
|
|
24010
24101
|
let src = null, dst, src_port;
|
|
24011
24102
|
if (drag_line.portType === PORT_TYPE_OUTPUT && (targetNode.inputs > 0 || drag_line.virtualLink) ) {
|
|
@@ -24091,7 +24182,7 @@ RED.view = (function() {
|
|
|
24091
24182
|
if (nn.type === 'junction') {
|
|
24092
24183
|
nn = RED.nodes.addJunction(nn);
|
|
24093
24184
|
} else {
|
|
24094
|
-
nn = RED.nodes.add(nn, { source: 'typeSearch' });
|
|
24185
|
+
nn = RED.nodes.add(nn, { source: 'typeSearch', splice: !!linkToSplice });
|
|
24095
24186
|
}
|
|
24096
24187
|
if (quickAddLink) {
|
|
24097
24188
|
var drag_line = quickAddLink;
|
|
@@ -24278,15 +24369,11 @@ RED.view = (function() {
|
|
|
24278
24369
|
suggest: function (suggestion) {
|
|
24279
24370
|
if (suggestion?.nodes?.length > 0) {
|
|
24280
24371
|
// Reposition the suggestion relative to the existing ghost node position
|
|
24281
|
-
const deltaX = suggestion.nodes[0].x - point[0]
|
|
24282
|
-
const deltaY = suggestion.nodes[0].y - point[1]
|
|
24372
|
+
const deltaX = (suggestion.nodes[0].x || 0) - point[0]
|
|
24373
|
+
const deltaY = (suggestion.nodes[0].y || 0) - point[1]
|
|
24283
24374
|
suggestion.nodes.forEach(node => {
|
|
24284
|
-
|
|
24285
|
-
|
|
24286
|
-
}
|
|
24287
|
-
if (Object.hasOwn(node, 'y')) {
|
|
24288
|
-
node.y = node.y - deltaY
|
|
24289
|
-
}
|
|
24375
|
+
node.x = (node.x || 0) - deltaX
|
|
24376
|
+
node.y = (node.y || 0) - deltaY
|
|
24290
24377
|
})
|
|
24291
24378
|
}
|
|
24292
24379
|
setSuggestedFlow(suggestion);
|
|
@@ -27297,6 +27384,10 @@ RED.view = (function() {
|
|
|
27297
27384
|
.on("touchend",nodeTouchEnd)
|
|
27298
27385
|
.on("mouseover",nodeMouseOver)
|
|
27299
27386
|
.on("mouseout",nodeMouseOut);
|
|
27387
|
+
} else if (d.__ghostClick) {
|
|
27388
|
+
d3.select(mainRect)
|
|
27389
|
+
.on("mousedown",d.__ghostClick)
|
|
27390
|
+
.on("touchstart",d.__ghostClick)
|
|
27300
27391
|
}
|
|
27301
27392
|
nodeContents.appendChild(mainRect);
|
|
27302
27393
|
//node.append("rect").attr("class", "node-gradient-top").attr("rx", 6).attr("ry", 6).attr("height",30).attr("stroke","none").attr("fill","url(#gradient-top)").style("pointer-events","none");
|
|
@@ -27539,6 +27630,10 @@ RED.view = (function() {
|
|
|
27539
27630
|
.on("mouseover",function(d){portMouseOver(d3.select(this),d,PORT_TYPE_INPUT,0);})
|
|
27540
27631
|
.on("mouseout",function(d) {portMouseOut(d3.select(this),d,PORT_TYPE_INPUT,0);});
|
|
27541
27632
|
RED.hooks.trigger("viewAddPort",{node:d,el: this, port: inputGroup[0][0], portType: "input", portIndex: 0})
|
|
27633
|
+
} else if (d.__ghostClick) {
|
|
27634
|
+
inputGroupPorts
|
|
27635
|
+
.on("mousedown",d.__ghostClick)
|
|
27636
|
+
.on("touchstart",d.__ghostClick)
|
|
27542
27637
|
}
|
|
27543
27638
|
}
|
|
27544
27639
|
var numOutputs = d.outputs;
|
|
@@ -27597,6 +27692,9 @@ RED.view = (function() {
|
|
|
27597
27692
|
portPort.addEventListener("touchend", portTouchEndProxy);
|
|
27598
27693
|
portPort.addEventListener("mouseover", portMouseOverProxy);
|
|
27599
27694
|
portPort.addEventListener("mouseout", portMouseOutProxy);
|
|
27695
|
+
} else if (d.__ghostClick) {
|
|
27696
|
+
portPort.addEventListener("mousedown", d.__ghostClick)
|
|
27697
|
+
portPort.addEventListener("touchstart", d.__ghostClick)
|
|
27600
27698
|
}
|
|
27601
27699
|
|
|
27602
27700
|
this.appendChild(portGroup);
|
|
@@ -27898,6 +27996,10 @@ RED.view = (function() {
|
|
|
27898
27996
|
}
|
|
27899
27997
|
}
|
|
27900
27998
|
})
|
|
27999
|
+
} else if (d.__ghostClick) {
|
|
28000
|
+
d3.select(pathBack)
|
|
28001
|
+
.on("mousedown",d.__ghostClick)
|
|
28002
|
+
.on("touchstart",d.__ghostClick)
|
|
27901
28003
|
}
|
|
27902
28004
|
|
|
27903
28005
|
var pathOutline = document.createElementNS("http://www.w3.org/2000/svg","path");
|
|
@@ -28914,10 +29016,10 @@ RED.view = (function() {
|
|
|
28914
29016
|
nn.w = RED.view.node_width;
|
|
28915
29017
|
nn.h = Math.max(RED.view.node_height, (nn.outputs || 0) * 15);
|
|
28916
29018
|
nn.resize = true;
|
|
28917
|
-
if (x != null && typeof x == "number"
|
|
29019
|
+
if (x != null && typeof x == "number") {
|
|
28918
29020
|
nn.x = x;
|
|
28919
29021
|
}
|
|
28920
|
-
if (y != null && typeof y == "number"
|
|
29022
|
+
if (y != null && typeof y == "number") {
|
|
28921
29023
|
nn.y = y;
|
|
28922
29024
|
}
|
|
28923
29025
|
var historyEvent = {
|
|
@@ -29007,7 +29109,9 @@ RED.view = (function() {
|
|
|
29007
29109
|
* x: 0,
|
|
29008
29110
|
* y: 0,
|
|
29009
29111
|
* }
|
|
29010
|
-
*
|
|
29112
|
+
* ],
|
|
29113
|
+
* "source": <sourceNode>,
|
|
29114
|
+
* "sourcePort": <sourcePort>,
|
|
29011
29115
|
* }
|
|
29012
29116
|
* If `nodes` is a single node without an id property, it will be generated
|
|
29013
29117
|
* using its default properties.
|
|
@@ -29015,6 +29119,9 @@ RED.view = (function() {
|
|
|
29015
29119
|
* If `nodes` has multiple, they must all have ids and will be assumed to be 'importable'.
|
|
29016
29120
|
* In other words, a piece of valid flow json.
|
|
29017
29121
|
*
|
|
29122
|
+
* `source`/`sourcePort` are option and used to indicate a node the suggestion should be connected to.
|
|
29123
|
+
* If provided, a ghost wire will be added between the source and the first node in the suggestion.
|
|
29124
|
+
*
|
|
29018
29125
|
* Limitations:
|
|
29019
29126
|
* - does not support groups, subflows or whole tabs
|
|
29020
29127
|
* - does not support config nodes
|
|
@@ -29025,6 +29132,7 @@ RED.view = (function() {
|
|
|
29025
29132
|
* @param {Object} suggestion - The suggestion object
|
|
29026
29133
|
*/
|
|
29027
29134
|
function setSuggestedFlow (suggestion) {
|
|
29135
|
+
$(window).off('keydown.suggestedFlow')
|
|
29028
29136
|
if (!currentSuggestion && !suggestion) {
|
|
29029
29137
|
// Avoid unnecessary redraws
|
|
29030
29138
|
return
|
|
@@ -29035,6 +29143,24 @@ RED.view = (function() {
|
|
|
29035
29143
|
if (suggestion?.nodes?.length > 0) {
|
|
29036
29144
|
const nodeMap = {}
|
|
29037
29145
|
const links = []
|
|
29146
|
+
const positionOffset = { x: 0, y: 0 }
|
|
29147
|
+
if (suggestion.source && suggestion.position === 'relative') {
|
|
29148
|
+
// If the suggestion is relative to a source node, use its position plus a suitable offset
|
|
29149
|
+
let targetX = suggestion.source.x + (suggestion.source.w || 120) + (3 * gridSize)
|
|
29150
|
+
const targetY = suggestion.source.y
|
|
29151
|
+
// Keep targetY where it is, but ensure targetX is grid aligned
|
|
29152
|
+
if (snapGrid) {
|
|
29153
|
+
// This isn't a perfect grid snap, as we don't have the true node width at this point.
|
|
29154
|
+
// TODO: defer grid snapping until the node is created?
|
|
29155
|
+
const gridOffset = RED.view.tools.calculateGridSnapOffsets({ x: targetX, y: targetY, w: node_width, h: node_height });
|
|
29156
|
+
targetX += gridOffset.x
|
|
29157
|
+
}
|
|
29158
|
+
|
|
29159
|
+
positionOffset.x = targetX - (suggestion.nodes[0].x || 0)
|
|
29160
|
+
positionOffset.y = targetY - (suggestion.nodes[0].y || 0)
|
|
29161
|
+
}
|
|
29162
|
+
|
|
29163
|
+
|
|
29038
29164
|
suggestion.nodes.forEach(nodeConfig => {
|
|
29039
29165
|
if (!nodeConfig.type || nodeConfig.type === 'group' || nodeConfig.type === 'subflow' || nodeConfig.type === 'tab') {
|
|
29040
29166
|
// A node type we don't support previewing
|
|
@@ -29042,8 +29168,9 @@ RED.view = (function() {
|
|
|
29042
29168
|
}
|
|
29043
29169
|
|
|
29044
29170
|
let node
|
|
29045
|
-
|
|
29046
29171
|
if (nodeConfig.type === 'junction') {
|
|
29172
|
+
nodeConfig.x = (nodeConfig.x || 0) + positionOffset.x
|
|
29173
|
+
nodeConfig.y = (nodeConfig.y || 0) + positionOffset.y
|
|
29047
29174
|
node = {
|
|
29048
29175
|
_def: {defaults:{}},
|
|
29049
29176
|
type: 'junction',
|
|
@@ -29064,6 +29191,8 @@ RED.view = (function() {
|
|
|
29064
29191
|
// TODO: unknown node types could happen...
|
|
29065
29192
|
return
|
|
29066
29193
|
}
|
|
29194
|
+
nodeConfig.x = (nodeConfig.x || 0) + positionOffset.x
|
|
29195
|
+
nodeConfig.y = (nodeConfig.y || 0) + positionOffset.y
|
|
29067
29196
|
const result = createNode(nodeConfig.type, nodeConfig.x, nodeConfig.y)
|
|
29068
29197
|
if (!result) {
|
|
29069
29198
|
return
|
|
@@ -29086,6 +29215,11 @@ RED.view = (function() {
|
|
|
29086
29215
|
node.id = nodeConfig.id || node.id
|
|
29087
29216
|
node.__ghost = true;
|
|
29088
29217
|
node.dirty = true;
|
|
29218
|
+
if (suggestion.clickToApply) {
|
|
29219
|
+
node.__ghostClick = function () {
|
|
29220
|
+
applySuggestedFlow()
|
|
29221
|
+
}
|
|
29222
|
+
}
|
|
29089
29223
|
nodeMap[node.id] = node
|
|
29090
29224
|
|
|
29091
29225
|
if (nodeConfig.wires) {
|
|
@@ -29114,6 +29248,30 @@ RED.view = (function() {
|
|
|
29114
29248
|
suggestedLinks.push(link)
|
|
29115
29249
|
}
|
|
29116
29250
|
})
|
|
29251
|
+
if (suggestion.source && suggestedNodes[0]?._def?.inputs > 0) {
|
|
29252
|
+
suggestedLinks.push({
|
|
29253
|
+
source: suggestion.source,
|
|
29254
|
+
sourcePort: suggestion.sourcePort || 0,
|
|
29255
|
+
target: suggestedNodes[0],
|
|
29256
|
+
targetPort: 0,
|
|
29257
|
+
__ghost: true
|
|
29258
|
+
})
|
|
29259
|
+
}
|
|
29260
|
+
if (!RED.typeSearch.isVisible()) {
|
|
29261
|
+
$(window).on('keydown.suggestedFlow', function (evt) {
|
|
29262
|
+
if (evt.keyCode === 9) { // tab
|
|
29263
|
+
applySuggestedFlow();
|
|
29264
|
+
} else {
|
|
29265
|
+
clearSuggestedFlow();
|
|
29266
|
+
RED.view.redraw(true);
|
|
29267
|
+
}
|
|
29268
|
+
});
|
|
29269
|
+
}
|
|
29270
|
+
if (suggestion.clickToApply) {
|
|
29271
|
+
$(window).on('mousedown.suggestedFlow', function (evnt) {
|
|
29272
|
+
clearSuggestedFlow();
|
|
29273
|
+
})
|
|
29274
|
+
}
|
|
29117
29275
|
}
|
|
29118
29276
|
if (ghostNode) {
|
|
29119
29277
|
if (suggestedNodes.length > 0) {
|
|
@@ -29126,6 +29284,8 @@ RED.view = (function() {
|
|
|
29126
29284
|
}
|
|
29127
29285
|
|
|
29128
29286
|
function clearSuggestedFlow () {
|
|
29287
|
+
$(window).off('mousedown.suggestedFlow');
|
|
29288
|
+
$(window).off('keydown.suggestedFlow')
|
|
29129
29289
|
currentSuggestion = null
|
|
29130
29290
|
suggestedNodes = []
|
|
29131
29291
|
suggestedLinks = []
|
|
@@ -29134,14 +29294,40 @@ RED.view = (function() {
|
|
|
29134
29294
|
function applySuggestedFlow () {
|
|
29135
29295
|
if (currentSuggestion && currentSuggestion.nodes) {
|
|
29136
29296
|
const nodesToImport = currentSuggestion.nodes
|
|
29297
|
+
const sourceNode = currentSuggestion.source
|
|
29298
|
+
const sourcePort = currentSuggestion.sourcePort || 0
|
|
29137
29299
|
setSuggestedFlow(null)
|
|
29138
|
-
|
|
29300
|
+
const result = importNodes(nodesToImport, {
|
|
29139
29301
|
generateIds: true,
|
|
29140
29302
|
touchImport: true,
|
|
29141
29303
|
notify: false,
|
|
29142
29304
|
// Ensure the node gets all of its defaults applied
|
|
29143
29305
|
applyNodeDefaults: true
|
|
29144
29306
|
})
|
|
29307
|
+
if (sourceNode) {
|
|
29308
|
+
const firstNode = result.nodeMap[nodesToImport[0].id]
|
|
29309
|
+
if (firstNode && firstNode._def?.inputs > 0) {
|
|
29310
|
+
// Connect the source node to the first node in the suggestion
|
|
29311
|
+
const link = {
|
|
29312
|
+
source: sourceNode,
|
|
29313
|
+
target: RED.nodes.node(firstNode.id),
|
|
29314
|
+
sourcePort: sourcePort,
|
|
29315
|
+
targetPort: 0
|
|
29316
|
+
};
|
|
29317
|
+
RED.nodes.addLink(link)
|
|
29318
|
+
let historyEvent = RED.history.peek();
|
|
29319
|
+
if (historyEvent.t === "multi") {
|
|
29320
|
+
historyEvent = historyEvent.events.find(e => e.t === "add")
|
|
29321
|
+
}
|
|
29322
|
+
if (historyEvent) {
|
|
29323
|
+
historyEvent.links = historyEvent.links || [];
|
|
29324
|
+
historyEvent.links.push(link);
|
|
29325
|
+
}
|
|
29326
|
+
RED.view.redraw(true);
|
|
29327
|
+
}
|
|
29328
|
+
}
|
|
29329
|
+
|
|
29330
|
+
return result
|
|
29145
29331
|
}
|
|
29146
29332
|
}
|
|
29147
29333
|
|
|
@@ -30900,8 +31086,8 @@ RED.view.tools = (function() {
|
|
|
30900
31086
|
t: 'multi',
|
|
30901
31087
|
events: historyEvents
|
|
30902
31088
|
})
|
|
31089
|
+
RED.nodes.dirty(true)
|
|
30903
31090
|
}
|
|
30904
|
-
RED.nodes.dirty(true)
|
|
30905
31091
|
RED.view.redraw()
|
|
30906
31092
|
}
|
|
30907
31093
|
}
|
|
@@ -31562,7 +31748,7 @@ RED.palette = (function() {
|
|
|
31562
31748
|
getNodeCount: function (visibleOnly) {
|
|
31563
31749
|
const nodes = catDiv.find(".red-ui-palette-node")
|
|
31564
31750
|
if (visibleOnly) {
|
|
31565
|
-
return nodes.filter(function() { return $(this).
|
|
31751
|
+
return nodes.filter(function() { return $(this).attr("data-filter") !== "true"}).length
|
|
31566
31752
|
} else {
|
|
31567
31753
|
return nodes.length
|
|
31568
31754
|
}
|
|
@@ -32054,8 +32240,10 @@ RED.palette = (function() {
|
|
|
32054
32240
|
var currentLabel = $(el).attr("data-palette-label");
|
|
32055
32241
|
var type = $(el).attr("data-palette-type");
|
|
32056
32242
|
if (val === "" || re.test(type) || re.test(currentLabel)) {
|
|
32243
|
+
$(el).attr("data-filter", null)
|
|
32057
32244
|
$(this).show();
|
|
32058
32245
|
} else {
|
|
32246
|
+
$(el).attr("data-filter", "true")
|
|
32059
32247
|
$(this).hide();
|
|
32060
32248
|
}
|
|
32061
32249
|
});
|
|
@@ -35691,6 +35879,11 @@ RED.palette.editor = (function() {
|
|
|
35691
35879
|
});
|
|
35692
35880
|
|
|
35693
35881
|
RED.events.on('registry:module-updated', function(ns) {
|
|
35882
|
+
if (nodeEntries[ns.module]) {
|
|
35883
|
+
// Set the node/plugin as updated
|
|
35884
|
+
nodeEntries[ns.module].info.pending_version = ns.version;
|
|
35885
|
+
}
|
|
35886
|
+
|
|
35694
35887
|
refreshNodeModule(ns.module);
|
|
35695
35888
|
refreshUpdateStatus();
|
|
35696
35889
|
});
|
|
@@ -37827,6 +38020,7 @@ RED.editor = (function() {
|
|
|
37827
38020
|
|
|
37828
38021
|
function showEditDialog(node, defaultTab) {
|
|
37829
38022
|
if (buildingEditDialog) { return }
|
|
38023
|
+
if (editStack.includes(node)) { return }
|
|
37830
38024
|
buildingEditDialog = true;
|
|
37831
38025
|
if (node.z && RED.workspaces.isLocked(node.z)) { return }
|
|
37832
38026
|
var editing_node = node;
|
|
@@ -38144,6 +38338,7 @@ RED.editor = (function() {
|
|
|
38144
38338
|
var editing_config_node = RED.nodes.node(id);
|
|
38145
38339
|
var activeEditPanes = [];
|
|
38146
38340
|
|
|
38341
|
+
if (editStack.includes(editing_config_node)) { return }
|
|
38147
38342
|
if (editing_config_node && editing_config_node.z && RED.workspaces.isLocked(editing_config_node.z)) { return }
|
|
38148
38343
|
|
|
38149
38344
|
var configNodeScope = ""; // default to global
|
|
@@ -38587,6 +38782,7 @@ RED.editor = (function() {
|
|
|
38587
38782
|
|
|
38588
38783
|
function showEditSubflowDialog(subflow, defaultTab) {
|
|
38589
38784
|
if (buildingEditDialog) { return }
|
|
38785
|
+
if (editStack.includes(subflow)) { return }
|
|
38590
38786
|
buildingEditDialog = true;
|
|
38591
38787
|
|
|
38592
38788
|
editStack.push(subflow);
|
|
@@ -38803,6 +38999,7 @@ RED.editor = (function() {
|
|
|
38803
38999
|
|
|
38804
39000
|
function showEditGroupDialog(group, defaultTab) {
|
|
38805
39001
|
if (buildingEditDialog) { return }
|
|
39002
|
+
if (editStack.includes(group)) { return }
|
|
38806
39003
|
buildingEditDialog = true;
|
|
38807
39004
|
if (group.z && RED.workspaces.isLocked(group.z)) { return }
|
|
38808
39005
|
var editing_node = group;
|
|
@@ -38917,6 +39114,7 @@ RED.editor = (function() {
|
|
|
38917
39114
|
|
|
38918
39115
|
function showEditFlowDialog(workspace, defaultTab) {
|
|
38919
39116
|
if (buildingEditDialog) { return }
|
|
39117
|
+
if (editStack.includes(workspace)) { return }
|
|
38920
39118
|
buildingEditDialog = true;
|
|
38921
39119
|
var activeEditPanes = [];
|
|
38922
39120
|
RED.view.state(RED.state.EDITING);
|
|
@@ -43208,7 +43406,7 @@ RED.editor = (function() {
|
|
|
43208
43406
|
|
|
43209
43407
|
nodes.forEach(async node => {
|
|
43210
43408
|
if (!node.getAttribute('mermaid-processed')) {
|
|
43211
|
-
const mermaidContent = node.
|
|
43409
|
+
const mermaidContent = atob($(node).data('c64'))
|
|
43212
43410
|
node.setAttribute('mermaid-processed', true)
|
|
43213
43411
|
try {
|
|
43214
43412
|
const { svg } = await mermaid.render('mermaid-render-'+Date.now()+'-'+(diagramIds++), mermaidContent);
|
|
@@ -45000,11 +45198,14 @@ RED.editor.codeEditor.monaco = (function() {
|
|
|
45000
45198
|
**/
|
|
45001
45199
|
RED.eventLog = (function() {
|
|
45002
45200
|
|
|
45003
|
-
|
|
45201
|
+
const template = '<script type="text/x-red" data-template-name="_eventLog"><div class="form-row node-text-editor-row"><div style="height: 100%;min-height: 150px;" class="node-text-editor" id="red-ui-event-log-editor"></div></div></script>';
|
|
45202
|
+
|
|
45203
|
+
let eventLogEditor;
|
|
45204
|
+
let backlog = [];
|
|
45205
|
+
let shown = false;
|
|
45206
|
+
|
|
45207
|
+
const activeLogs = new Set()
|
|
45004
45208
|
|
|
45005
|
-
var eventLogEditor;
|
|
45006
|
-
var backlog = [];
|
|
45007
|
-
var shown = false;
|
|
45008
45209
|
|
|
45009
45210
|
function appendLogLine(line) {
|
|
45010
45211
|
backlog.push(line);
|
|
@@ -45023,6 +45224,18 @@ RED.eventLog = (function() {
|
|
|
45023
45224
|
init: function() {
|
|
45024
45225
|
$(template).appendTo("#red-ui-editor-node-configs");
|
|
45025
45226
|
RED.actions.add("core:show-event-log",RED.eventLog.show);
|
|
45227
|
+
|
|
45228
|
+
const statusWidget = $('<button type="button" class="red-ui-footer-button red-ui-event-log-status" style="line-height: normal"><img style="width: 80%" src="red/images/spin.svg"/></div></button>');
|
|
45229
|
+
statusWidget.on("click", function(evt) {
|
|
45230
|
+
RED.actions.invoke("core:show-event-log");
|
|
45231
|
+
})
|
|
45232
|
+
RED.statusBar.add({
|
|
45233
|
+
id: "red-ui-event-log-status",
|
|
45234
|
+
align: "right",
|
|
45235
|
+
element: statusWidget
|
|
45236
|
+
});
|
|
45237
|
+
RED.statusBar.hide("red-ui-event-log-status");
|
|
45238
|
+
|
|
45026
45239
|
},
|
|
45027
45240
|
show: function() {
|
|
45028
45241
|
if (shown) {
|
|
@@ -45083,6 +45296,12 @@ RED.eventLog = (function() {
|
|
|
45083
45296
|
},
|
|
45084
45297
|
log: function(id,payload) {
|
|
45085
45298
|
var ts = (new Date(payload.ts)).toISOString()+" ";
|
|
45299
|
+
if (!payload.end) {
|
|
45300
|
+
activeLogs.add(id)
|
|
45301
|
+
} else {
|
|
45302
|
+
activeLogs.delete(id);
|
|
45303
|
+
}
|
|
45304
|
+
|
|
45086
45305
|
if (payload.type) {
|
|
45087
45306
|
ts += "["+payload.type+"] "
|
|
45088
45307
|
}
|
|
@@ -45096,6 +45315,11 @@ RED.eventLog = (function() {
|
|
|
45096
45315
|
appendLogLine(ts+line);
|
|
45097
45316
|
})
|
|
45098
45317
|
}
|
|
45318
|
+
if (activeLogs.size > 0) {
|
|
45319
|
+
RED.statusBar.show("red-ui-event-log-status");
|
|
45320
|
+
} else {
|
|
45321
|
+
RED.statusBar.hide("red-ui-event-log-status");
|
|
45322
|
+
}
|
|
45099
45323
|
},
|
|
45100
45324
|
startEvent: function(name) {
|
|
45101
45325
|
backlog.push("");
|
|
@@ -45337,14 +45561,6 @@ RED.eventLog = (function() {
|
|
|
45337
45561
|
editorStack = $("#red-ui-editor-stack");
|
|
45338
45562
|
$(window).on("resize", handleWindowResize);
|
|
45339
45563
|
RED.events.on("sidebar:resize",handleWindowResize);
|
|
45340
|
-
$("#red-ui-editor-shade").on("click", function() {
|
|
45341
|
-
if (!openingTray) {
|
|
45342
|
-
var tray = stack[stack.length-1];
|
|
45343
|
-
if (tray && tray.primaryButton) {
|
|
45344
|
-
tray.primaryButton.click();
|
|
45345
|
-
}
|
|
45346
|
-
}
|
|
45347
|
-
});
|
|
45348
45564
|
},
|
|
45349
45565
|
show: function show(options) {
|
|
45350
45566
|
lowerTrayZ();
|
|
@@ -49422,7 +49638,6 @@ RED.actionList = (function() {
|
|
|
49422
49638
|
addItem: function(container, i, nodeItem) {
|
|
49423
49639
|
// nodeItem can take multiple forms
|
|
49424
49640
|
// - A node type: {type: "inject", def: RED.nodes.getType("inject"), label: "Inject"}
|
|
49425
|
-
// - A flow suggestion: { suggestion: true, nodes: [] }
|
|
49426
49641
|
// - A placeholder suggestion: { suggestionPlaceholder: true, label: 'loading suggestions...' }
|
|
49427
49642
|
|
|
49428
49643
|
let nodeDef = nodeItem.def;
|
|
@@ -49502,7 +49717,17 @@ RED.actionList = (function() {
|
|
|
49502
49717
|
|
|
49503
49718
|
}
|
|
49504
49719
|
|
|
49720
|
+
let activeSuggestion
|
|
49505
49721
|
function updateSuggestion(nodeItem) {
|
|
49722
|
+
if (nodeItem === activeSuggestion) {
|
|
49723
|
+
return
|
|
49724
|
+
}
|
|
49725
|
+
if (!visible && nodeItem) {
|
|
49726
|
+
// Do not update suggestion if the dialog is not visible
|
|
49727
|
+
// - for example, whilst the dialog is closing and the user mouses over a new item
|
|
49728
|
+
return
|
|
49729
|
+
}
|
|
49730
|
+
activeSuggestion = nodeItem
|
|
49506
49731
|
if (suggestCallback) {
|
|
49507
49732
|
if (!nodeItem) {
|
|
49508
49733
|
suggestCallback(null);
|
|
@@ -49559,6 +49784,7 @@ RED.actionList = (function() {
|
|
|
49559
49784
|
}
|
|
49560
49785
|
visible = true;
|
|
49561
49786
|
} else {
|
|
49787
|
+
updateSuggestion(null)
|
|
49562
49788
|
dialog.hide();
|
|
49563
49789
|
searchResultsDiv.hide();
|
|
49564
49790
|
}
|
|
@@ -49599,9 +49825,7 @@ RED.actionList = (function() {
|
|
|
49599
49825
|
},200);
|
|
49600
49826
|
}
|
|
49601
49827
|
function hide(fast) {
|
|
49602
|
-
|
|
49603
|
-
suggestCallback(null);
|
|
49604
|
-
}
|
|
49828
|
+
updateSuggestion(null)
|
|
49605
49829
|
if (visible) {
|
|
49606
49830
|
visible = false;
|
|
49607
49831
|
if (dialog !== null) {
|
|
@@ -49700,32 +49924,37 @@ RED.actionList = (function() {
|
|
|
49700
49924
|
|
|
49701
49925
|
let index = 0;
|
|
49702
49926
|
|
|
49703
|
-
|
|
49704
|
-
|
|
49705
|
-
|
|
49706
|
-
|
|
49707
|
-
|
|
49708
|
-
|
|
49709
|
-
|
|
49710
|
-
|
|
49711
|
-
|
|
49712
|
-
|
|
49713
|
-
|
|
49714
|
-
|
|
49715
|
-
|
|
49716
|
-
|
|
49717
|
-
|
|
49718
|
-
|
|
49719
|
-
|
|
49720
|
-
|
|
49721
|
-
|
|
49722
|
-
|
|
49723
|
-
|
|
49724
|
-
|
|
49725
|
-
|
|
49726
|
-
|
|
49727
|
-
|
|
49728
|
-
|
|
49927
|
+
if (!opts.context?.virtualLink) {
|
|
49928
|
+
// Check for suggestion plugins
|
|
49929
|
+
const suggestionPlugins = RED.plugins.getPluginsByType('node-red-flow-suggestion-source');
|
|
49930
|
+
if (suggestionPlugins.length > 0) {
|
|
49931
|
+
const suggestionItem = {
|
|
49932
|
+
suggestionPlaceholder: true,
|
|
49933
|
+
label: RED._('palette.loadingSuggestions'),
|
|
49934
|
+
separator: true,
|
|
49935
|
+
i: index++
|
|
49936
|
+
}
|
|
49937
|
+
searchResults.editableList('addItem', suggestionItem);
|
|
49938
|
+
suggestionPlugins[0].getSuggestions(opts.context).then(function (suggestedFlows) {
|
|
49939
|
+
searchResults.editableList('removeItem', suggestionItem);
|
|
49940
|
+
if (!Array.isArray(suggestedFlows)) {
|
|
49941
|
+
suggestedFlows = [suggestedFlows];
|
|
49942
|
+
}
|
|
49943
|
+
suggestedFlows.forEach(function(suggestion, index) {
|
|
49944
|
+
const suggestedItem = {
|
|
49945
|
+
suggestion: true,
|
|
49946
|
+
separator: index === suggestedFlows.length - 1,
|
|
49947
|
+
i: suggestionItem.i,
|
|
49948
|
+
...suggestion
|
|
49949
|
+
}
|
|
49950
|
+
if (!suggestion.label && suggestion.nodes && suggestion.nodes.length === 1 && suggestion.nodes[0].type) {
|
|
49951
|
+
suggestedItem.label = getTypeLabel(suggestion.nodes[0].type, RED.nodes.getType(suggestion.nodes[0].type));
|
|
49952
|
+
}
|
|
49953
|
+
searchResults.editableList('addItem', suggestedItem);
|
|
49954
|
+
})
|
|
49955
|
+
})
|
|
49956
|
+
}
|
|
49957
|
+
}
|
|
49729
49958
|
|
|
49730
49959
|
for(i=0;i<common.length;i++) {
|
|
49731
49960
|
let itemDef
|
|
@@ -49776,9 +50005,10 @@ RED.actionList = (function() {
|
|
|
49776
50005
|
}
|
|
49777
50006
|
|
|
49778
50007
|
return {
|
|
49779
|
-
show
|
|
50008
|
+
show,
|
|
49780
50009
|
refresh: refreshTypeList,
|
|
49781
|
-
hide
|
|
50010
|
+
hide,
|
|
50011
|
+
isVisible: () => visible
|
|
49782
50012
|
};
|
|
49783
50013
|
|
|
49784
50014
|
})();
|