diff --git a/packages/node_modules/@node-red/editor-client/src/js/nodes.js b/packages/node_modules/@node-red/editor-client/src/js/nodes.js
index 4a1c6e9a0..5c544e7b7 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/nodes.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/nodes.js
@@ -463,7 +463,9 @@ RED.nodes = (function() {
node.id = n.id;
node.type = n.type;
node.z = n.z;
-
+ if (n.d === true) {
+ node.d = true;
+ }
if (node.type == "unknown") {
for (var p in n._orig) {
if (n._orig.hasOwnProperty(p)) {
@@ -967,6 +969,9 @@ RED.nodes = (function() {
users:[],
_config:{}
};
+ if (n.hasOwnProperty('d')) {
+ configNode.d = n.d;
+ }
for (d in def.defaults) {
if (def.defaults.hasOwnProperty(d)) {
configNode[d] = n[d];
@@ -1016,6 +1021,9 @@ RED.nodes = (function() {
if (n.hasOwnProperty('l')) {
node.l = n.l;
}
+ if (n.hasOwnProperty('d')) {
+ node.d = n.d;
+ }
if (createNewIds) {
if (subflow_blacklist[n.z]) {
continue;
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/common/toggleButton.js b/packages/node_modules/@node-red/editor-client/src/js/ui/common/toggleButton.js
index 1a52183d3..999606912 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/common/toggleButton.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/common/toggleButton.js
@@ -42,12 +42,11 @@
var enabledLabel = this.options.enabledLabel || RED._("editor:workspace.enabled");
var disabledLabel = this.options.disabledLabel || RED._("editor:workspace.disabled");
- this.element.addClass("red-ui-toggleButton");
this.element.css("display","none");
this.element.on("focus", function() {
that.button.focus();
});
- this.button = $('');
+ this.button = $('');
if (this.options.class) {
this.button.addClass(this.options.class)
}
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js b/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js
index b64bb8e5c..1b3ccea52 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js
@@ -955,34 +955,19 @@ RED.editor = (function() {
$('
'+
''+
- ' '+
- ''+
+ ''+
'
').appendTo(dialogForm);
- var setToggleState = function(state) {
- var i = $("#node-input-show-label-btn-i");
- if (!state) {
- i.addClass('fa-toggle-off');
- i.removeClass('fa-toggle-on');
- $("#node-input-show-label").prop("checked",false);
- $("#node-input-show-label-label").text(RED._("editor.hide"));
- } else {
- i.addClass('fa-toggle-on');
- i.removeClass('fa-toggle-off');
- $("#node-input-show-label").prop("checked",true);
- $("#node-input-show-label-label").text(RED._("editor.show"));
- }
- }
- dialogForm.find('#node-input-show-label-btn').on("click",function(e) {
- e.preventDefault();
- var i = $("#node-input-show-label-btn-i");
- setToggleState(i.hasClass('fa-toggle-off'));
+ $("#node-input-show-label").toggleButton({
+ enabledLabel: RED._("editor.show"),
+ disabledLabel: RED._("editor.hide")
})
+
if (!node.hasOwnProperty("l")) {
// Show label if type not link
node.l = !/^link (in|out)$/.test(node._def.type);
}
- setToggleState(node.l);
+ $("#node-input-show-label").prop("checked",node.l).trigger("change");
// If a node has icon property in defaults, the icon of the node cannot be modified. (e.g, ui_button node in dashboard)
if ((!node._def.defaults || !node._def.defaults.hasOwnProperty("icon"))) {
@@ -1396,6 +1381,20 @@ RED.editor = (function() {
node.l = true;
}
}
+ if ($("#node-input-node-disabled").prop('checked')) {
+ if (node.d !== true) {
+ changes.d = node.d;
+ changed = true;
+ node.d = true;
+ }
+ } else {
+ if (node.d === true) {
+ changes.d = node.d;
+ changed = true;
+ delete node.d;
+ }
+ }
+
node.resize = true;
var oldInfo = node.info;
@@ -1498,6 +1497,14 @@ RED.editor = (function() {
var trayBody = tray.find('.red-ui-tray-body');
trayBody.parent().css('overflow','hidden');
+ var trayFooterLeft = $('').appendTo(trayFooter)
+
+ $('').prop("checked",!!node.d).appendTo(trayFooterLeft).toggleButton({
+ enabledIcon: "fa-circle-thin",
+ disabledIcon: "fa-ban",
+ invertState: true
+ })
+
var editorTabEl = $('').appendTo(trayBody);
var editorContent = $('').appendTo(trayBody);
@@ -1675,9 +1682,17 @@ RED.editor = (function() {
var trayHeader = tray.find(".red-ui-tray-header");
var trayBody = tray.find('.red-ui-tray-body');
var trayFooter = tray.find(".red-ui-tray-footer");
- var userCountDiv;
+
+ var trayFooterLeft = $('').appendTo(trayFooter)
+
+ $('').prop("checked",!!editing_config_node.d).appendTo(trayFooterLeft).toggleButton({
+ enabledIcon: "fa-circle-thin",
+ disabledIcon: "fa-ban",
+ invertState: true
+ })
+
if (node_def.hasUsers !== false) {
- userCountDiv = $('').prependTo(trayFooter);
+ $(' ').css("margin-left", "10px").appendTo(trayFooterLeft);
}
trayFooter.append('');
@@ -1771,8 +1786,8 @@ RED.editor = (function() {
}
});
}
- if (node_def.hasUsers !== false && userCountDiv) {
- userCountDiv.find("span").text(RED._("editor.nodesUse", {count:editing_config_node.users.length})).parent().show();
+ if (node_def.hasUsers !== false) {
+ $("#red-ui-editor-config-user-count").text(RED._("editor.nodesUse", {count:editing_config_node.users.length})).parent().show();
}
trayBody.i18n();
trayFooter.i18n();
@@ -1907,6 +1922,16 @@ RED.editor = (function() {
editing_config_node.label = configTypeDef.label;
editing_config_node.z = scope;
+ if ($("#node-config-input-node-disabled").prop('checked')) {
+ if (editing_config_node.d !== true) {
+ editing_config_node.d = true;
+ }
+ } else {
+ if (editing_config_node.d === true) {
+ delete editing_config_node.d;
+ }
+ }
+
if (scope) {
// Search for nodes that use this one that are no longer
// in scope, so must be removed
@@ -2061,7 +2086,7 @@ RED.editor = (function() {
RED.nodes.eachConfig(function(config) {
if (config.type == type && (!config.z || config.z === activeWorkspace.id)) {
var label = RED.utils.getNodeLabel(config,config.id);
- config.__label__ = label;
+ config.__label__ = label+(config.d?" ["+RED._("workspace.disabled")+"]":"");
configNodes.push(config);
}
});
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/tab-config.js b/packages/node_modules/@node-red/editor-client/src/js/ui/tab-config.js
index c7131aa7e..86785c385 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/tab-config.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/tab-config.js
@@ -145,7 +145,12 @@ RED.sidebar.config = (function() {
var entry = $('').appendTo(list);
var nodeDiv = $('').appendTo(entry);
entry.data('node',node.id);
- $('').text(label).appendTo(nodeDiv);
+ var label = $('').text(label).appendTo(nodeDiv);
+ if (node.d) {
+ nodeDiv.addClass("red-ui-palette-node-config-disabled");
+ $('').prependTo(label);
+ }
+
if (node._def.hasUsers !== false) {
var iconContainer = $('',{class:"red-ui-palette-icon-container red-ui-palette-icon-container-right"}).appendTo(nodeDiv);
if (node.users.length === 0) {
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/view.js b/packages/node_modules/@node-red/editor-client/src/js/ui/view.js
index 4f5e4da9b..e3aa33a7f 100755
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/view.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/view.js
@@ -410,6 +410,8 @@ RED.view = (function() {
RED.actions.add("core:zoom-in",zoomIn);
RED.actions.add("core:zoom-out",zoomOut);
RED.actions.add("core:zoom-reset",zoomZero);
+ RED.actions.add("core:enable-selected-nodes", function() { setSelectedNodeState(false)});
+ RED.actions.add("core:disable-selected-nodes", function() { setSelectedNodeState(true)});
RED.actions.add("core:toggle-show-grid",function(state) {
if (state === undefined) {
@@ -2376,7 +2378,7 @@ RED.view = (function() {
function isButtonEnabled(d) {
var buttonEnabled = true;
var ws = RED.nodes.workspace(RED.workspaces.active());
- if (ws && !ws.disabled) {
+ if (ws && !ws.disabled && !d.d) {
if (d._def.button.hasOwnProperty('enabled')) {
if (typeof d._def.button.enabled === "function") {
buttonEnabled = d._def.button.enabled.call(d);
@@ -2397,7 +2399,7 @@ RED.view = (function() {
}
var activeWorkspace = RED.workspaces.active();
var ws = RED.nodes.workspace(activeWorkspace);
- if (ws && !ws.disabled) {
+ if (ws && !ws.disabled && !d.d) {
if (d._def.button.toggle) {
d[d._def.button.toggle] = !d[d._def.button.toggle];
d.dirty = true;
@@ -2929,6 +2931,7 @@ RED.view = (function() {
d.resize = false;
}
var thisNode = d3.select(this);
+ thisNode.classed("red-ui-flow-node-disabled", function(d) { return d.d === true});
thisNode.classed("red-ui-flow-subflow",function(d) { return activeSubflow != null; })
//thisNode.selectAll(".centerDot").attr({"cx":function(d) { return d.w/2;},"cy":function(d){return d.h/2}});
@@ -3248,6 +3251,7 @@ RED.view = (function() {
}
return path;
});
+ link.classed("red-ui-flow-node-disabled", function(d) { return d.source.d || d.target.d; });
}
})
@@ -3578,6 +3582,48 @@ RED.view = (function() {
//TODO: subscribe/unsubscribe here
redraw();
}
+ function setSelectedNodeState(isDisabled) {
+ if (mouse_mode === RED.state.SELECTING_NODE) {
+ return;
+ }
+ var workspaceSelection = RED.workspaces.selection();
+ var changed = false;
+ if (workspaceSelection.length > 0) {
+ // TODO: toggle workspace state
+ } else if (moving_set.length > 0) {
+ var historyEvents = [];
+ for (var i=0;i 0) {
+ RED.history.push({
+ t:"multi",
+ events: historyEvents,
+ dirty:RED.nodes.dirty()
+ })
+ RED.nodes.dirty(true)
+ }
+ }
+ RED.view.redraw();
+
+ }
return {
init: init,
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/workspaces.js b/packages/node_modules/@node-red/editor-client/src/js/ui/workspaces.js
index 3fffe2e64..db36004ab 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/workspaces.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/workspaces.js
@@ -201,8 +201,11 @@ RED.workspaces = (function() {
} else {
workspace.disabled = false;
}
- $("#node-input-disabled").toggleButton({invertState: true})
-
+ $("#node-input-disabled").toggleButton({
+ enabledIcon: "fa-circle-thin",
+ disabledIcon: "fa-ban",
+ invertState: true
+ })
$('').prependTo(dialogForm);
dialogForm.on("submit", function(e) { e.preventDefault();});
diff --git a/packages/node_modules/@node-red/editor-client/src/sass/colors.scss b/packages/node_modules/@node-red/editor-client/src/sass/colors.scss
index 3b6d14280..8411343c5 100644
--- a/packages/node_modules/@node-red/editor-client/src/sass/colors.scss
+++ b/packages/node_modules/@node-red/editor-client/src/sass/colors.scss
@@ -224,10 +224,10 @@ $node-status-colors: (
$node-selected-color: #ff7f0e;
$port-selected-color: #ff7f0e;
-$link-color: #888;
-$link-link-color: #ccc;
+$link-color: #999;
+$link-link-color: #aaa;
+$link-disabled-color: #ccc;
$link-link-active-color: #ff7f0e;
-$link-subflow-color: #bbb;
$link-unknown-color: #f00;
$clipboard-textarea-background: #F3E7E7;
diff --git a/packages/node_modules/@node-red/editor-client/src/sass/editor.scss b/packages/node_modules/@node-red/editor-client/src/sass/editor.scss
index 83c72b07b..6338eb73e 100644
--- a/packages/node_modules/@node-red/editor-client/src/sass/editor.scss
+++ b/packages/node_modules/@node-red/editor-client/src/sass/editor.scss
@@ -79,15 +79,20 @@
.red-ui-tray-footer {
@include component-footer;
height: 35px;
- font-size: 12px !important;
+ font-size: 14px !important;
line-height: 35px;
vertical-align: middle;
- button {
- @include editor-button;
- padding: 3px 7px;
- font-size: 11px;
+ button.red-ui-button {
+ padding: 0px 8px;
+ height: 26px;
+ line-height: 26px;
+ &.toggle:not(.selected) {
+ color: $workspace-button-color-selected !important;
+ background: $workspace-button-background-active;
+ }
}
+
.red-ui-tray-footer-left {
display:inline-block;
margin-right: 20px;
@@ -563,8 +568,6 @@ button.red-ui-button-small
}
-
-
.red-ui-editor-type-json-editor-item-handle {
cursor: move;
}
@@ -572,3 +575,7 @@ button.red-ui-button-small
position: relative;
height: calc(100% - 40px);
}
+
+button.red-ui-toggleButton.toggle {
+ text-align: left;
+}
diff --git a/packages/node_modules/@node-red/editor-client/src/sass/flow.scss b/packages/node_modules/@node-red/editor-client/src/sass/flow.scss
index 4f24a6f11..4aae0869c 100644
--- a/packages/node_modules/@node-red/editor-client/src/sass/flow.scss
+++ b/packages/node_modules/@node-red/editor-client/src/sass/flow.scss
@@ -146,23 +146,42 @@ g.red-ui-flow-node-selected {
border-style: dashed !important;
stroke: $node-selected-color;
stroke-width: 2;
- stroke-dasharray: 10, 4;
+ stroke-dasharray: 8, 3;
}
.red-ui-flow-subflow .red-ui-flow-node {
- stroke-dasharray:8, 3;
-}
-.red-ui-workspace-disabled {
- .red-ui-flow-link-line {
- stroke-dasharray: 10,5 !important;
- stroke-width: 2 !important;
- stroke: $link-subflow-color;
- }
- .red-ui-flow-node {
- stroke-dasharray: 10,4;
- }
}
+.red-ui-workspace-disabled {
+ .red-ui-flow-node {
+ stroke-dasharray: 8, 3;
+ fill-opacity: 0.5;
+ }
+ .red-ui-flow-link-line {
+ stroke-dasharray: 10,8 !important;
+ stroke-width: 2 !important;
+ stroke: $link-disabled-color;
+ }
+ .red-ui-flow-port {
+ fill-opacity: 1;
+ stroke-dasharray: none;
+ }
+}
+.red-ui-flow-node-disabled {
+ &.red-ui-flow-node, .red-ui-flow-node {
+ stroke-dasharray: 8, 3;
+ fill-opacity: 0.5;
+ }
+ &.red-ui-flow-link-line {
+ stroke-dasharray: 10,8 !important;
+ stroke-width: 2 !important;
+ stroke: $link-disabled-color;
+ }
+ .red-ui-flow-port {
+ fill-opacity: 1;
+ stroke-dasharray: none;
+ }
+}
@each $current-color in red green yellow blue grey {
.red-ui-flow-node-status-dot-#{$current-color} {
fill: map-get($node-status-colors,$current-color);
@@ -188,7 +207,6 @@ g.red-ui-flow-node-selected {
}
.red-ui-flow-subflow-port {
- stroke-dasharray: 5,5;
fill: $node-background-placeholder;
stroke: $node-border;
}
@@ -208,12 +226,14 @@ g.red-ui-flow-node-selected {
}
.red-ui-flow-link-link {
stroke-width: 2;
- stroke-dasharray: 10,5;
stroke: $link-link-color;
fill: none;
- stroke-dasharray: 15,2;
- // pointer-events: none;
+ stroke-dasharray: 25,4;
}
+.red-ui-flow-link-off-flow {
+ stroke-width: 2;
+}
+
.red-ui-flow-link-port {
fill: $node-link-port-background;
stroke: $link-link-color;
@@ -225,11 +245,6 @@ g.red-ui-flow-node-selected {
.red-ui-flow-link-group:hover {
cursor: pointer;
}
-.red-ui-flow-subflow-link {
- stroke: $link-subflow-color;
- stroke-dasharray: 10,5;
- stroke-width: 2;
-}
.red-ui-flow-link-outline {
stroke: $view-background;
diff --git a/packages/node_modules/@node-red/editor-client/src/sass/mixins.scss b/packages/node_modules/@node-red/editor-client/src/sass/mixins.scss
index 91978057e..dda9ef384 100644
--- a/packages/node_modules/@node-red/editor-client/src/sass/mixins.scss
+++ b/packages/node_modules/@node-red/editor-client/src/sass/mixins.scss
@@ -192,7 +192,7 @@
right: 0;
height: 25px;
line-height: 25px;
- padding: 0 10px;
+ padding: 0 6px;
user-select: none;
.button-group:not(:last-child) {
diff --git a/packages/node_modules/@node-red/editor-client/src/sass/tab-config.scss b/packages/node_modules/@node-red/editor-client/src/sass/tab-config.scss
index 69a2ee5dd..467ce8511 100644
--- a/packages/node_modules/@node-red/editor-client/src/sass/tab-config.scss
+++ b/packages/node_modules/@node-red/editor-client/src/sass/tab-config.scss
@@ -94,12 +94,20 @@ ul.red-ui-sidebar-node-config-list li.red-ui-palette-node-config-type {
text-align:right;
padding-right: 3px;
}
-.red-ui-palette-node-config-unused {
+.red-ui-palette-node-config-unused,.red-ui-palette-node-config-disabled {
border-color: $primary-border-color;
background: $secondary-background-inactive;
border-style: dashed;
color: $tertiary-text-color;
}
+.red-ui-palette-node-config-disabled {
+ opacity: 0.6;
+ font-style: italic;
+ i {
+ color: $secondary-text-color;
+ margin-right: 5px;
+ }
+}
.red-ui-sidebar-node-config-filter-info {
position: absolute;
top: 0;
diff --git a/packages/node_modules/@node-red/runtime/lib/nodes/flows/Flow.js b/packages/node_modules/@node-red/runtime/lib/nodes/flows/Flow.js
index 8b0341463..6077f50cd 100644
--- a/packages/node_modules/@node-red/runtime/lib/nodes/flows/Flow.js
+++ b/packages/node_modules/@node-red/runtime/lib/nodes/flows/Flow.js
@@ -132,29 +132,39 @@ class Flow {
id = configNodes.shift();
node = this.flow.configs[id];
if (!this.activeNodes[id]) {
- var readyToCreate = true;
- // This node doesn't exist.
- // Check it doesn't reference another non-existent config node
- for (var prop in node) {
- if (node.hasOwnProperty(prop) && prop !== 'id' && prop !== 'wires' && prop !== '_users' && this.flow.configs[node[prop]]) {
- if (!this.activeNodes[node[prop]]) {
- // References a non-existent config node
- // Add it to the back of the list to try again later
- configNodes.push(id);
- configNodeAttempts[id] = (configNodeAttempts[id]||0)+1;
- if (configNodeAttempts[id] === 100) {
- throw new Error("Circular config node dependency detected: "+id);
+ if (node.d !== true) {
+ var readyToCreate = true;
+ // This node doesn't exist.
+ // Check it doesn't reference another non-existent config node
+ for (var prop in node) {
+ if (node.hasOwnProperty(prop) &&
+ prop !== 'id' &&
+ prop !== 'wires' &&
+ prop !== '_users' &&
+ this.flow.configs[node[prop]] &&
+ this.flow.configs[node[prop]].d !== true
+ ) {
+ if (!this.activeNodes[node[prop]]) {
+ // References a non-existent config node
+ // Add it to the back of the list to try again later
+ configNodes.push(id);
+ configNodeAttempts[id] = (configNodeAttempts[id]||0)+1;
+ if (configNodeAttempts[id] === 100) {
+ throw new Error("Circular config node dependency detected: "+id);
+ }
+ readyToCreate = false;
+ break;
}
- readyToCreate = false;
- break;
}
}
- }
- if (readyToCreate) {
- newNode = flowUtil.createNode(this,node);
- if (newNode) {
- this.activeNodes[id] = newNode;
+ if (readyToCreate) {
+ newNode = flowUtil.createNode(this,node);
+ if (newNode) {
+ this.activeNodes[id] = newNode;
+ }
}
+ } else {
+ this.debug("not starting disabled config node : "+id);
}
}
}
@@ -171,39 +181,43 @@ class Flow {
for (id in this.flow.nodes) {
if (this.flow.nodes.hasOwnProperty(id)) {
node = this.flow.nodes[id];
- if (!node.subflow) {
- if (!this.activeNodes[id]) {
- newNode = flowUtil.createNode(this,node);
- if (newNode) {
- this.activeNodes[id] = newNode;
+ if (node.d !== true) {
+ if (!node.subflow) {
+ if (!this.activeNodes[id]) {
+ newNode = flowUtil.createNode(this,node);
+ if (newNode) {
+ this.activeNodes[id] = newNode;
+ }
+ }
+ } else {
+ if (!this.subflowInstanceNodes[id]) {
+ try {
+ var subflowDefinition = this.flow.subflows[node.subflow]||this.global.subflows[node.subflow]
+ // console.log("NEED TO CREATE A SUBFLOW",id,node.subflow);
+ this.subflowInstanceNodes[id] = true;
+ var subflow = Subflow.create(
+ this,
+ this.global,
+ subflowDefinition,
+ node
+ );
+ this.subflowInstanceNodes[id] = subflow;
+ subflow.start();
+ this.activeNodes[id] = subflow.node;
+
+ // this.subflowInstanceNodes[id] = nodes.map(function(n) { return n.id});
+ // for (var i=0;i