mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Merge branch 'dev' into dev-addjpn
This commit is contained in:
@@ -143,7 +143,8 @@
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.inject-time-count {
|
||||
width: 40px !important;
|
||||
padding-left: 3px !important;
|
||||
width: 80px !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -538,12 +539,10 @@
|
||||
var propertyValue = $('<input/>',{class:"node-input-prop-property-value",type:"text"})
|
||||
.css("width","calc(70% - 30px)")
|
||||
.appendTo(row)
|
||||
.typedInput({default:'str',types:['flow','global','str','num','bool','json','bin','date','jsonata','env','msg']});
|
||||
.typedInput({default:prop.vt,types:['flow','global','str','num','bool','json','bin','date','jsonata','env','msg']});
|
||||
|
||||
propertyName.typedInput('value',prop.p);
|
||||
|
||||
propertyValue.typedInput('value',prop.v);
|
||||
propertyValue.typedInput('type',prop.vt);
|
||||
},
|
||||
removable: true,
|
||||
sortable: true
|
||||
|
@@ -292,6 +292,7 @@
|
||||
};
|
||||
RED.events.on("project:change", this.clearMessageList);
|
||||
RED.actions.add("core:clear-debug-messages", function() { RED.debug.clearMessageList(true) });
|
||||
RED.actions.add("core:clear-filtered-debug-messages", function() { RED.debug.clearMessageList(true, true) });
|
||||
|
||||
RED.actions.add("core:activate-selected-debug-nodes", function() { setDebugNodeState(getSelectedDebugNodes(true), true); });
|
||||
RED.actions.add("core:activate-all-debug-nodes", function() { setDebugNodeState(getMatchingDebugNodes(true, true),true); });
|
||||
|
@@ -52,7 +52,7 @@
|
||||
treeList = $("<div>")
|
||||
.css({width: "100%", height: "100%"})
|
||||
.appendTo(".node-input-link-row")
|
||||
.treeList({})
|
||||
.treeList({autoSelect:false})
|
||||
.on('treelistitemmouseover',function(e,item) {
|
||||
if (item.node) {
|
||||
item.node.highlighted = true;
|
||||
@@ -68,6 +68,8 @@
|
||||
}
|
||||
});
|
||||
var candidateNodes = RED.nodes.filterNodes({type:targetType});
|
||||
var candidateNodesCount = 0;
|
||||
|
||||
var search = $("#node-input-link-target-filter").searchBox({
|
||||
style: "compact",
|
||||
delay: 300,
|
||||
@@ -80,7 +82,7 @@
|
||||
var count = treeList.treeList("filter", function(item) {
|
||||
return item.label.toLowerCase().indexOf(val) > -1 || (item.node && item.node.type.toLowerCase().indexOf(val) > -1)
|
||||
});
|
||||
search.searchBox("count",count+" / "+candidateNodes.length);
|
||||
search.searchBox("count",count+" / "+candidateNodesCount);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -113,6 +115,11 @@
|
||||
|
||||
candidateNodes.forEach(function(n) {
|
||||
if (flowMap[n.z]) {
|
||||
if (targetType === "link out" && n.mode === 'return') {
|
||||
// Link In nodes looking for Link Out nodes should not
|
||||
// include return-mode nodes.
|
||||
return
|
||||
}
|
||||
var isChecked = false;
|
||||
isChecked = (node.links.indexOf(n.id) !== -1) || (n.links||[]).indexOf(node.id) !== -1;
|
||||
if (isChecked) {
|
||||
@@ -126,6 +133,7 @@
|
||||
checkbox: node.type !== "link call",
|
||||
radio: node.type === "link call"
|
||||
})
|
||||
candidateNodesCount++;
|
||||
}
|
||||
});
|
||||
flows = flows.filter(function(f) { return f.children.length > 0 })
|
||||
@@ -149,7 +157,7 @@
|
||||
function onEditSave(node) {
|
||||
var flows = treeList.treeList('data');
|
||||
node.links = [];
|
||||
if (node.type !== "link out" || $("node-input-mode").val() === 'link') {
|
||||
if (node.type !== "link out" || $("#node-input-mode").val() === 'link') {
|
||||
flows.forEach(function(f) {
|
||||
f.children.forEach(function(n) {
|
||||
if (n.selected) {
|
||||
@@ -234,6 +242,12 @@
|
||||
},
|
||||
oneditsave: function() {
|
||||
onEditSave(this);
|
||||
// In case the name has changed, ensure any link call nodes on this
|
||||
// tab are redrawn with the updated name
|
||||
var localCallNodes = RED.nodes.filterNodes({z:RED.workspaces.active(), type:"link call"});
|
||||
localCallNodes.forEach(function(node) {
|
||||
node.dirty = true;
|
||||
});
|
||||
},
|
||||
onadd: onAdd,
|
||||
oneditresize: resizeNodeList
|
||||
@@ -259,12 +273,12 @@
|
||||
}
|
||||
if (this.links.length > 0) {
|
||||
var targetNode = RED.nodes.node(this.links[0]);
|
||||
return targetNode && (targetNode.name || targetNode.id);
|
||||
return targetNode && (targetNode.name || this._("link.linkCall"));
|
||||
}
|
||||
return this._("link.linkCall");
|
||||
return this._("inject.none");
|
||||
},
|
||||
labelStyle: function() {
|
||||
return (this.name || this.links.length > 0)?"node_label_italic":"";
|
||||
return this.name?"node_label_italic":"";
|
||||
},
|
||||
oneditprepare: function() {
|
||||
onEditPrepare(this,"link in");
|
||||
@@ -275,7 +289,6 @@
|
||||
oneditresize: resizeNodeList
|
||||
});
|
||||
|
||||
|
||||
RED.nodes.registerType('link out',{
|
||||
category: 'common',
|
||||
color:"#ddd",//"#87D8CF",
|
||||
|
@@ -31,24 +31,22 @@ RED.debug = (function() {
|
||||
var activeWorkspace;
|
||||
var numMessages = 100; // Hardcoded number of message to show in debug window scrollback
|
||||
|
||||
var filterVisible = false;
|
||||
|
||||
var debugNodeList;
|
||||
var debugNodeListExpandedFlows = {};
|
||||
var debugNodeTreeList;
|
||||
|
||||
function init(_config) {
|
||||
config = _config;
|
||||
|
||||
var content = $("<div>").css({"position":"relative","height":"100%"});
|
||||
var toolbar = $('<div class="red-ui-sidebar-header">'+
|
||||
'<span class="button-group"><a id="red-ui-sidebar-debug-filter" class="red-ui-sidebar-header-button" href="#"><i class="fa fa-filter"></i> <span></span></a></span>'+
|
||||
'<span class="button-group"><a id="red-ui-sidebar-debug-clear" class="red-ui-sidebar-header-button" href="#"><i class="fa fa-trash"></i></a></span></div>').appendTo(content);
|
||||
'<span class="button-group">'+
|
||||
'<a id="red-ui-sidebar-debug-filter" style="padding-right: 5px" class="red-ui-sidebar-header-button" href="#"><i class="fa fa-filter"></i> <span></span> <i style="padding-left: 5px;" class="fa fa-caret-down"></i></a>'+
|
||||
'</span>'+
|
||||
'<span class="button-group">'+
|
||||
'<a id="red-ui-sidebar-debug-clear" style="border-right: none; padding-right: 6px" class="red-ui-sidebar-header-button" href="#" data-clear-type="all"><i class="fa fa-trash"></i> <span>all</span></a>' +
|
||||
'<a id="red-ui-sidebar-debug-clear-opts" style="padding: 5px; border-left: none;" class="red-ui-sidebar-header-button" href="#"><i class="fa fa-caret-down"></i></a>'+
|
||||
'</span></div>').appendTo(content);
|
||||
|
||||
var footerToolbar = $('<div>'+
|
||||
// '<span class="button-group">'+
|
||||
// '<a class="red-ui-footer-button-toggle text-button selected" id="red-ui-sidebar-debug-view-list" href="#"><span data-i18n="">list</span></a>'+
|
||||
// '<a class="red-ui-footer-button-toggle text-button" id="red-ui-sidebar-debug-view-table" href="#"><span data-i18n="">table</span></a> '+
|
||||
// '</span>'+
|
||||
'<span class="button-group"><a id="red-ui-sidebar-debug-open" class="red-ui-footer-button" href="#"><i class="fa fa-desktop"></i></a></span> ' +
|
||||
'</div>');
|
||||
|
||||
@@ -56,85 +54,100 @@ RED.debug = (function() {
|
||||
sbc = messageList[0];
|
||||
messageTable = $('<div class="red-ui-debug-content red-ui-debug-content-table hide"/>').appendTo(content);
|
||||
|
||||
var filterDialog = $('<div class="red-ui-debug-filter-box hide">'+
|
||||
'<div class="red-ui-debug-filter-row">'+
|
||||
'<span class="button-group">'+
|
||||
'<a class="red-ui-sidebar-header-button-toggle red-ui-sidebar-debug-filter-option selected" id="red-ui-sidebar-debug-filterAll" href="#"><span data-i18n="node-red:debug.sidebar.filterAll"></span></a>'+
|
||||
'<a class="red-ui-sidebar-header-button-toggle red-ui-sidebar-debug-filter-option" id="red-ui-sidebar-debug-filterSelected" href="#"><span data-i18n="node-red:debug.sidebar.filterSelected"></span></a>'+
|
||||
'<a class="red-ui-sidebar-header-button-toggle red-ui-sidebar-debug-filter-option" id="red-ui-sidebar-debug-filterCurrent" href="#"><span data-i18n="node-red:debug.sidebar.filterCurrent"></span></a> '+
|
||||
var filterDialogCloseTimeout;
|
||||
var filterDialogShown = false;
|
||||
var filterDialog = $('<div class="red-ui-debug-filter-box hide"></div>').appendTo(toolbar);//content);
|
||||
filterDialog.on('mouseleave' ,function(evt) {
|
||||
if (filterDialogShown) {
|
||||
filterDialogCloseTimeout = setTimeout(function() {
|
||||
filterDialog.slideUp(200);
|
||||
filterDialogShown = false;
|
||||
},500)
|
||||
}
|
||||
})
|
||||
filterDialog.on('mouseenter' ,function(evt) {
|
||||
clearTimeout(filterDialogCloseTimeout)
|
||||
})
|
||||
var filterToolbar = $('<div style="margin-bottom: 3px; display: flex;">'+
|
||||
'<span style="flex-grow:1; text-align: left;">'+
|
||||
'<span class="button-group"><button type="button" id="red-ui-sidebar-filter-select-all" class="red-ui-sidebar-header-button red-ui-button-small" data-i18n="node-red:debug.sidebar.selectAll"></button></span>' +
|
||||
'<span class="button-group"><button type="button" id="red-ui-sidebar-filter-select-none" class="red-ui-sidebar-header-button red-ui-button-small" data-i18n="node-red:debug.sidebar.selectNone"></button></span>' +
|
||||
'</span>'+
|
||||
'</div>'+
|
||||
'</div>').appendTo(toolbar);//content);
|
||||
'<span class="button-group"><button type="button" id="red-ui-sidebar-filter-select-close" class="red-ui-sidebar-header-button red-ui-button-small"><i class="fa fa-times"></i></button></span>'+
|
||||
'</div>').appendTo(filterDialog);
|
||||
|
||||
// var filterTypeRow = $('<div class="red-ui-debug-filter-row"></div>').appendTo(filterDialog);
|
||||
// $('<select><option>Show all debug nodes</option><option>Show selected debug nodes</option><option>Show current flow only</option></select>').appendTo(filterTypeRow);
|
||||
filterToolbar.find("#red-ui-sidebar-filter-select-close").on('click', function(evt) {
|
||||
clearTimeout(filterDialogCloseTimeout)
|
||||
filterDialogShown = false;
|
||||
filterDialog.slideUp(200);
|
||||
})
|
||||
|
||||
var debugNodeListRow = $('<div class="red-ui-debug-filter-row hide" id="red-ui-sidebar-debug-filter-node-list-row"></div>').appendTo(filterDialog);
|
||||
var flowCheckboxes = {};
|
||||
var debugNodeListHeader = $('<div><span data-i18n="node-red:debug.sidebar.debugNodes"></span><span></span></div>');
|
||||
var headerCheckbox = $('<input type="checkbox">').appendTo(debugNodeListHeader.find("span")[1]).checkboxSet();
|
||||
|
||||
debugNodeList = $('<ol>',{style:"text-align: left; min-height: 250px; max-height: 250px"}).appendTo(debugNodeListRow).editableList({
|
||||
header: debugNodeListHeader,
|
||||
class: 'red-ui-nodeList',
|
||||
addItem: function(container,i,node) {
|
||||
var row = $("<div>").appendTo(container);
|
||||
row.attr('id','debug-filter-node-list-node-'+node.id.replace(/\./g,"_"));
|
||||
if (node.type === 'tab') {
|
||||
container.parent().addClass('red-ui-editableList-section-header');
|
||||
if (!debugNodeListExpandedFlows.hasOwnProperty(node.id)) {
|
||||
debugNodeListExpandedFlows[node.id] = true;
|
||||
filterToolbar.find("#red-ui-sidebar-filter-select-all").on('click', function(evt) {
|
||||
evt.preventDefault();
|
||||
var data = debugNodeTreeList.treeList('data');
|
||||
data.forEach(function(flow) {
|
||||
if (!flow.selected) {
|
||||
if (flow.treeList.checkbox) {
|
||||
flow.treeList.checkbox.trigger('click')
|
||||
}
|
||||
var chevron = $('<i class="fa fa-angle-right"></i>').appendTo(row);
|
||||
$('<span>').text(RED.utils.getNodeLabel(node,node.id)).appendTo(row);
|
||||
var muteControl = $('<input type="checkbox">').appendTo($('<span class="meta">').appendTo(row));
|
||||
muteControl.checkboxSet({
|
||||
parent: headerCheckbox
|
||||
});
|
||||
flowCheckboxes[node.id] = muteControl;
|
||||
row.on("click", function(e) {
|
||||
e.stopPropagation();
|
||||
debugNodeListExpandedFlows[node.id] = !debugNodeListExpandedFlows[node.id];
|
||||
row.toggleClass('expanded',debugNodeListExpandedFlows[node.id]);
|
||||
debugNodeList.editableList('filter');
|
||||
})
|
||||
row.addClass("expandable");
|
||||
if (node.disabled) {
|
||||
container.addClass('disabled');
|
||||
muteControl.checkboxSet('disable');
|
||||
debugNodeListExpandedFlows[node.id] = false;
|
||||
}
|
||||
row.toggleClass('expanded',debugNodeListExpandedFlows[node.id]);
|
||||
} else {
|
||||
$('<span>',{style: "margin-left: 20px"}).text(RED.utils.getNodeLabel(node,node.id)).appendTo(row);
|
||||
row.on("mouseenter",function() {
|
||||
config.messageMouseEnter(node.id);
|
||||
});
|
||||
row.on("mouseleave",function() {
|
||||
config.messageMouseLeave(node.id);
|
||||
});
|
||||
var muteControl = $('<input type="checkbox">').prop('checked',!filteredNodes[node.id]).appendTo($('<span class="meta">').appendTo(row));
|
||||
muteControl.checkboxSet({
|
||||
parent: flowCheckboxes[node.z]
|
||||
}).on("change", function(e) {
|
||||
filteredNodes[node.id] = !$(this).prop('checked');
|
||||
$(".red-ui-debug-msg-node-"+node.id.replace(/\./g,"_")).toggleClass('hide',filteredNodes[node.id]);
|
||||
});
|
||||
if ((node.hasOwnProperty("active") && !node.active) || RED.nodes.workspace(node.z).disabled) {
|
||||
container.addClass('disabled');
|
||||
muteControl.checkboxSet('disable');
|
||||
flow.children.forEach(function(item) {
|
||||
if (!item.selected) {
|
||||
item.treeList.select();
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
refreshMessageList();
|
||||
})
|
||||
|
||||
filterToolbar.find("#red-ui-sidebar-filter-select-none").on('click', function(evt) {
|
||||
evt.preventDefault();
|
||||
debugNodeTreeList.treeList('clearSelection');
|
||||
var data = debugNodeTreeList.treeList('data');
|
||||
data.forEach(function(flow) {
|
||||
if (flow.children) {
|
||||
flow.children.forEach(function(item) {
|
||||
filteredNodes[item.node.id] = true;
|
||||
})
|
||||
}
|
||||
});
|
||||
RED.settings.set('debug.filteredNodes',Object.keys(filteredNodes))
|
||||
refreshMessageList();
|
||||
})
|
||||
var debugNodeListRow = $('<div class="red-ui-debug-filter-row" id="red-ui-sidebar-debug-filter-node-list-row"></div>').appendTo(filterDialog);
|
||||
debugNodeTreeList = $("<div></div>").appendTo(debugNodeListRow).css({width: "100%", height: "300px"})
|
||||
.treeList({autoSelect: false}).on("treelistitemmouseover", function(e, item) {
|
||||
if (item.node) {
|
||||
item.node.highlighted = true;
|
||||
item.node.dirty = true;
|
||||
RED.view.redraw();
|
||||
}
|
||||
}).on("treelistitemmouseout", function(e, item) {
|
||||
if (item.node) {
|
||||
item.node.highlighted = false;
|
||||
item.node.dirty = true;
|
||||
RED.view.redraw();
|
||||
}
|
||||
}).on("treelistselect", function(e, item) {
|
||||
if (item.children) {
|
||||
item.children.forEach(function(child) {
|
||||
if (child.checkbox) {
|
||||
child.treeList.select(item.selected)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
if (item.node) {
|
||||
if (item.selected) {
|
||||
delete filteredNodes[item.node.id]
|
||||
} else {
|
||||
filteredNodes[item.node.id] = true;
|
||||
}
|
||||
RED.settings.set('debug.filteredNodes',Object.keys(filteredNodes))
|
||||
refreshMessageList();
|
||||
}
|
||||
}
|
||||
},
|
||||
addButton: false,
|
||||
scrollOnAdd: false,
|
||||
filter: function(node) {
|
||||
return (node.type === 'tab' || debugNodeListExpandedFlows[node.z] )
|
||||
},
|
||||
sort: function(A,B) {
|
||||
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
try {
|
||||
content.i18n();
|
||||
@@ -144,85 +157,95 @@ RED.debug = (function() {
|
||||
|
||||
toolbar.find('#red-ui-sidebar-debug-filter span').text(RED._('node-red:debug.sidebar.filterAll'));
|
||||
|
||||
var filterButtonHandler = function(type) {
|
||||
return function(e) {
|
||||
e.preventDefault();
|
||||
if (filterType !== type) {
|
||||
$('.red-ui-sidebar-debug-filter-option').removeClass('selected');
|
||||
$(this).addClass('selected');
|
||||
if (filterType === 'filterSelected') {
|
||||
debugNodeListRow.slideUp();
|
||||
}
|
||||
filterType = type;
|
||||
if (filterType === 'filterSelected') {
|
||||
debugNodeListRow.slideDown();
|
||||
}
|
||||
|
||||
$('#red-ui-sidebar-debug-filter span').text(RED._('node-red:debug.sidebar.'+filterType));
|
||||
refreshMessageList();
|
||||
}
|
||||
}
|
||||
}
|
||||
filterDialog.find('#red-ui-sidebar-debug-filterAll').on("click",filterButtonHandler('filterAll'));
|
||||
filterDialog.find('#red-ui-sidebar-debug-filterSelected').on("click",filterButtonHandler('filterSelected'));
|
||||
filterDialog.find('#red-ui-sidebar-debug-filterCurrent').on("click",filterButtonHandler('filterCurrent'));
|
||||
|
||||
|
||||
// $('#red-ui-sidebar-debug-view-list').on("click",function(e) {
|
||||
// e.preventDefault();
|
||||
// if (!$(this).hasClass('selected')) {
|
||||
// $(this).addClass('selected');
|
||||
// $('#red-ui-sidebar-debug-view-table').removeClass('selected');
|
||||
// showMessageList();
|
||||
// }
|
||||
// });
|
||||
// $('#red-ui-sidebar-debug-view-table').on("click",function(e) {
|
||||
// e.preventDefault();
|
||||
// if (!$(this).hasClass('selected')) {
|
||||
// $(this).addClass('selected');
|
||||
// $('#red-ui-sidebar-debug-view-list').removeClass('selected');
|
||||
// showMessageTable();
|
||||
// }
|
||||
// });
|
||||
|
||||
|
||||
var hideFilterTimeout;
|
||||
toolbar.on('mouseleave',function() {
|
||||
if ($('#red-ui-sidebar-debug-filter').hasClass('selected')) {
|
||||
clearTimeout(hideFilterTimeout);
|
||||
hideFilterTimeout = setTimeout(function() {
|
||||
filterVisible = false;
|
||||
$('#red-ui-sidebar-debug-filter').removeClass('selected');
|
||||
filterDialog.slideUp(200);
|
||||
},300);
|
||||
}
|
||||
});
|
||||
toolbar.on('mouseenter',function() {
|
||||
if ($('#red-ui-sidebar-debug-filter').hasClass('selected')) {
|
||||
clearTimeout(hideFilterTimeout);
|
||||
}
|
||||
})
|
||||
toolbar.find('#red-ui-sidebar-debug-filter').on("click",function(e) {
|
||||
e.preventDefault();
|
||||
if ($(this).hasClass('selected')) {
|
||||
filterVisible = false;
|
||||
$(this).removeClass('selected');
|
||||
clearTimeout(hideFilterTimeout);
|
||||
filterDialog.slideUp(200);
|
||||
} else {
|
||||
$(this).addClass('selected');
|
||||
filterVisible = true;
|
||||
refreshDebugNodeList();
|
||||
filterDialog.slideDown(200);
|
||||
}
|
||||
var options = [
|
||||
{ label: $('<span data-i18n="[append]node-red:debug.sidebar.filterAll"><input type="radio" value="filterAll" name="filter-type" style="margin-top:0"> </span>').i18n() , value: "filterAll" },
|
||||
{ label: $('<span><span data-i18n="[append]node-red:debug.sidebar.filterSelected"><input type="radio" value="filterSelected" name="filter-type" style="margin-top:0"> </span>...</span>').i18n(), value: "filterSelected" },
|
||||
{ label: $('<span data-i18n="[append]node-red:debug.sidebar.filterCurrent"><input type="radio" value="filterCurrent" name="filter-type" style="margin-top:0"> </span>').i18n(), value: "filterCurrent" }
|
||||
]
|
||||
var menu = RED.popover.menu({
|
||||
options: options,
|
||||
onselect: function(item) {
|
||||
if (item.value !== filterType) {
|
||||
filterType = item.value;
|
||||
$('#red-ui-sidebar-debug-filter span').text(RED._('node-red:debug.sidebar.'+filterType));
|
||||
refreshMessageList();
|
||||
RED.settings.set("debug.filter",filterType)
|
||||
}
|
||||
if (filterType === 'filterSelected') {
|
||||
refreshDebugNodeList();
|
||||
filterDialog.slideDown(200);
|
||||
filterDialogShown = true;
|
||||
debugNodeTreeList.focus();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
menu.show({
|
||||
target: $("#red-ui-sidebar-debug-filter"),
|
||||
align: "left",
|
||||
offset: [$("#red-ui-sidebar-debug-filter").outerWidth()-2, -1]
|
||||
})
|
||||
$('input[name="filter-type"][value="'+RED.settings.get("debug.filter","filterAll")+'"]').prop("checked", true)
|
||||
});
|
||||
RED.popover.tooltip(toolbar.find('#red-ui-sidebar-debug-filter'),RED._('node-red:debug.sidebar.filterLog'));
|
||||
|
||||
toolbar.find("#red-ui-sidebar-debug-clear").on("click", function(e) {
|
||||
e.preventDefault();
|
||||
clearMessageList(false);
|
||||
var action = RED.settings.get("debug.clearType","all")
|
||||
clearMessageList(false, action === 'filtered');
|
||||
});
|
||||
RED.popover.tooltip(toolbar.find("#red-ui-sidebar-debug-clear"),RED._('node-red:debug.sidebar.clearLog'),"core:clear-debug-messages");
|
||||
var clearTooltip = RED.popover.tooltip(toolbar.find("#red-ui-sidebar-debug-clear"),RED._('node-red:debug.sidebar.clearLog'),"core:clear-debug-messages");
|
||||
toolbar.find("#red-ui-sidebar-debug-clear-opts").on("click", function(e) {
|
||||
e.preventDefault();
|
||||
var options = [
|
||||
{ label: $('<span data-i18n="[append]node-red:debug.sidebar.clearLog"><input type="radio" value="all" name="clear-type" style="margin-top:0"> </span>').i18n() , value: "all" },
|
||||
{ label: $('<span data-i18n="[append]node-red:debug.sidebar.clearFilteredLog"><input type="radio" value="filtered" name="clear-type" style="margin-top:0"> </span>').i18n(), value: "filtered" }
|
||||
]
|
||||
var menu = RED.popover.menu({
|
||||
options: options,
|
||||
onselect: function(item) {
|
||||
if (item.value === "all") {
|
||||
$("#red-ui-sidebar-debug-clear > span").text(RED._('node-red:debug.sidebar.all'));
|
||||
clearTooltip.setAction("core:clear-debug-messages");
|
||||
clearTooltip.setContent(RED._('node-red:debug.sidebar.clearLog'))
|
||||
RED.settings.set("debug.clearType","all")
|
||||
} else {
|
||||
$("#red-ui-sidebar-debug-clear > span").text(RED._('node-red:debug.sidebar.filtered'));
|
||||
clearTooltip.setAction("core:clear-filtered-debug-messages");
|
||||
clearTooltip.setContent(RED._('node-red:debug.sidebar.clearFilteredLog'))
|
||||
RED.settings.set("debug.clearType","filtered")
|
||||
}
|
||||
}
|
||||
});
|
||||
menu.show({
|
||||
target: $("#red-ui-sidebar-debug-clear-opts"),
|
||||
align: "left",
|
||||
offset: [$("#red-ui-sidebar-debug-clear-opts").outerWidth()-2, -1]
|
||||
})
|
||||
$('input[name="clear-type"][value="'+RED.settings.get("debug.clearType","all")+'"]').prop("checked", true)
|
||||
})
|
||||
|
||||
var clearType = RED.settings.get("debug.clearType","all");
|
||||
if (clearType === "all") {
|
||||
toolbar.find("#red-ui-sidebar-debug-clear > span").text(RED._('node-red:debug.sidebar.all'));
|
||||
clearTooltip.setAction("core:clear-debug-messages");
|
||||
clearTooltip.setContent(RED._('node-red:debug.sidebar.clearLog'))
|
||||
} else {
|
||||
toolbar.find("#red-ui-sidebar-debug-clear > span").text(RED._('node-red:debug.sidebar.filtered'));
|
||||
clearTooltip.setAction("core:clear-filtered-debug-messages");
|
||||
clearTooltip.setContent(RED._('node-red:debug.sidebar.clearFilteredLog'))
|
||||
}
|
||||
|
||||
filterType = RED.settings.get("debug.filter","filterAll")
|
||||
var filteredNodeList = RED.settings.get("debug.filteredNodes",[]);
|
||||
filteredNodes = {}
|
||||
filteredNodeList.forEach(function(id) {
|
||||
filteredNodes[id] = true
|
||||
})
|
||||
toolbar.find('#red-ui-sidebar-debug-filter span').text(RED._('node-red:debug.sidebar.'+filterType));
|
||||
refreshMessageList();
|
||||
|
||||
return {
|
||||
content: content,
|
||||
@@ -254,8 +277,6 @@ RED.debug = (function() {
|
||||
|
||||
|
||||
function refreshDebugNodeList() {
|
||||
debugNodeList.editableList('empty');
|
||||
|
||||
var workspaceOrder = RED.nodes.getWorkspaceOrder();
|
||||
var workspaceOrderMap = {};
|
||||
workspaceOrder.forEach(function(ws,i) {
|
||||
@@ -320,15 +341,45 @@ RED.debug = (function() {
|
||||
return labelA.localeCompare(labelB);
|
||||
});
|
||||
var currentWs = null;
|
||||
var nodeList = [];
|
||||
var data = [];
|
||||
var currentFlow;
|
||||
var currentSelectedCount = 0;
|
||||
candidateNodes.forEach(function(node) {
|
||||
if (currentWs !== node.z) {
|
||||
if (currentFlow && currentFlow.checkbox) {
|
||||
currentFlow.selected = currentSelectedCount === currentFlow.children.length
|
||||
}
|
||||
currentSelectedCount = 0;
|
||||
currentWs = node.z;
|
||||
nodeList.push(RED.nodes.workspace(node.z));
|
||||
var parent = RED.nodes.workspace(currentWs) || RED.nodes.subflow(currentWs);
|
||||
currentFlow = {
|
||||
label: RED.utils.getNodeLabel(parent, currentWs),
|
||||
}
|
||||
if (!parent.disabled) {
|
||||
currentFlow.children = [];
|
||||
currentFlow.checkbox = true;
|
||||
} else {
|
||||
currentFlow.class = "disabled"
|
||||
}
|
||||
data.push(currentFlow);
|
||||
}
|
||||
if (currentFlow.children) {
|
||||
if (!filteredNodes[node.id]) {
|
||||
currentSelectedCount++;
|
||||
}
|
||||
currentFlow.children.push({
|
||||
label: RED.utils.getNodeLabel(node,node.id),
|
||||
node: node,
|
||||
checkbox: true,
|
||||
selected: !filteredNodes[node.id]
|
||||
});
|
||||
}
|
||||
nodeList.push(node);
|
||||
});
|
||||
debugNodeList.editableList('addItems',nodeList);
|
||||
if (currentFlow && currentFlow.checkbox) {
|
||||
currentFlow.selected = currentSelectedCount === currentFlow.children.length
|
||||
}
|
||||
|
||||
debugNodeTreeList.treeList("data", data);
|
||||
}
|
||||
|
||||
function getTimestamp() {
|
||||
@@ -340,7 +391,16 @@ RED.debug = (function() {
|
||||
return m.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");
|
||||
}
|
||||
|
||||
var refreshTimeout;
|
||||
function refreshMessageList(_activeWorkspace) {
|
||||
if (refreshTimeout) {
|
||||
clearTimeout(refreshTimeout);
|
||||
}
|
||||
refreshTimeout = setTimeout(function() {
|
||||
_refreshMessageList(_activeWorkspace);
|
||||
},200);
|
||||
}
|
||||
function _refreshMessageList(_activeWorkspace) {
|
||||
if (_activeWorkspace) {
|
||||
activeWorkspace = _activeWorkspace.replace(/\./g,"_");
|
||||
}
|
||||
@@ -415,6 +475,7 @@ RED.debug = (function() {
|
||||
});
|
||||
delete filteredNodes[sourceId];
|
||||
$("#red-ui-sidebar-debug-filterSelected").trigger("click");
|
||||
RED.settings.set('debug.filteredNodes',Object.keys(filteredNodes))
|
||||
refreshMessageList();
|
||||
}},
|
||||
{id:"red-ui-debug-msg-menu-item-clear-filter",label:RED._("node-red:debug.messageMenu.clearFilter"),onselect:function(){
|
||||
@@ -601,8 +662,12 @@ RED.debug = (function() {
|
||||
}
|
||||
}
|
||||
|
||||
function clearMessageList(clearFilter) {
|
||||
$(".red-ui-debug-msg").remove();
|
||||
function clearMessageList(clearFilter, filteredOnly) {
|
||||
if (!filteredOnly) {
|
||||
$(".red-ui-debug-msg").remove();
|
||||
} else {
|
||||
$(".red-ui-debug-msg:not(.hide)").remove();
|
||||
}
|
||||
config.clear();
|
||||
if (!!clearFilter) {
|
||||
clearFilterSettings();
|
||||
@@ -613,10 +678,9 @@ RED.debug = (function() {
|
||||
function clearFilterSettings() {
|
||||
filteredNodes = {};
|
||||
filterType = 'filterAll';
|
||||
$('.red-ui-sidebar-debug-filter-option').removeClass('selected');
|
||||
$('#red-ui-sidebar-debug-filterAll').addClass('selected');
|
||||
RED.settings.set("debug.filter",filterType);
|
||||
RED.settings.set('debug.filteredNodes',Object.keys(filteredNodes))
|
||||
$('#red-ui-sidebar-debug-filter span').text(RED._('node-red:debug.sidebar.filterAll'));
|
||||
$('#red-ui-sidebar-debug-filter-node-list-row').slideUp();
|
||||
}
|
||||
|
||||
return {
|
||||
|
@@ -15,18 +15,22 @@ $(function() {
|
||||
}
|
||||
}
|
||||
|
||||
var uiComponents = RED.debug.init(options);
|
||||
try {
|
||||
var uiComponents = RED.debug.init(options);
|
||||
$(".red-ui-debug-window").append(uiComponents.content);
|
||||
|
||||
$(".red-ui-debug-window").append(uiComponents.content);
|
||||
window.addEventListener('message',function(evt) {
|
||||
if (evt.data.event === "message") {
|
||||
RED.debug.handleDebugMessage(evt.data.msg);
|
||||
} else if (evt.data.event === "workspaceChange") {
|
||||
RED.debug.refreshMessageList(evt.data.activeWorkspace);
|
||||
} else if (evt.data.event === "projectChange") {
|
||||
RED.debug.clearMessageList(true);
|
||||
}
|
||||
},false);
|
||||
} catch(err) {
|
||||
console.error(err)
|
||||
}
|
||||
|
||||
window.addEventListener('message',function(evt) {
|
||||
if (evt.data.event === "message") {
|
||||
RED.debug.handleDebugMessage(evt.data.msg);
|
||||
} else if (evt.data.event === "workspaceChange") {
|
||||
RED.debug.refreshMessageList(evt.data.activeWorkspace);
|
||||
} else if (evt.data.event === "projectChange") {
|
||||
RED.debug.clearMessageList(true);
|
||||
}
|
||||
},false);
|
||||
})
|
||||
});
|
||||
|
@@ -117,30 +117,35 @@
|
||||
return r;
|
||||
}
|
||||
|
||||
function createValueField(row){
|
||||
return $('<input/>',{class:"node-input-rule-value",type:"text",style:"width: 100%;"}).appendTo(row).typedInput({default:'str',types:['msg','flow','global','str','num','jsonata','env',previousValueType]});
|
||||
function createValueField(row, defaultType){
|
||||
return $('<input/>',{class:"node-input-rule-value",type:"text",style:"width: 100%;"}).appendTo(row)
|
||||
.typedInput({default:defaultType||'str',types:['msg','flow','global','str','num','jsonata','env',previousValueType]});
|
||||
}
|
||||
|
||||
function createNumValueField(row){
|
||||
return $('<input/>',{class:"node-input-rule-num-value",type:"text",style:"width: 100%;"}).appendTo(row).typedInput({default:'num',types:['flow','global','num','jsonata','env']});
|
||||
function createNumValueField(row, defaultType){
|
||||
return $('<input/>',{class:"node-input-rule-num-value",type:"text",style:"width: 100%;"}).appendTo(row)
|
||||
.typedInput({default:defaultType||'num',types:['flow','global','num','jsonata','env']});
|
||||
}
|
||||
|
||||
function createExpValueField(row){
|
||||
return $('<input/>',{class:"node-input-rule-exp-value",type:"text",style:"width: 100%;"}).appendTo(row).typedInput({default:'jsonata',types:['jsonata']});
|
||||
return $('<input/>',{class:"node-input-rule-exp-value",type:"text",style:"width: 100%;"}).appendTo(row)
|
||||
.typedInput({default:'jsonata',types:['jsonata']});
|
||||
}
|
||||
|
||||
function createBtwnValueField(row){
|
||||
return $('<input/>',{class:"node-input-rule-btwn-value",type:"text",style:"width: 100%;"}).appendTo(row).typedInput({default:'num',types:['msg','flow','global','str','num','jsonata','env',previousValueType]});
|
||||
function createBtwnValueField(row, defaultType){
|
||||
return $('<input/>',{class:"node-input-rule-btwn-value",type:"text",style:"width: 100%;"}).appendTo(row)
|
||||
.typedInput({default:defaultType||'num',types:['msg','flow','global','str','num','jsonata','env',previousValueType]});
|
||||
}
|
||||
|
||||
function createBtwnValue2Field(row3, andLabel){
|
||||
function createBtwnValue2Field(row3, andLabel, defaultType){
|
||||
$('<div/>',{class:"node-input-rule-btwn-label", style:"width: 120px; text-align: right;"}).text(" "+andLabel+" ").appendTo(row3);
|
||||
var row3InputCell = $('<div/>',{style:"flex-grow:1; margin-left: 5px;"}).appendTo(row3);
|
||||
return $('<input/>',{class:"node-input-rule-btwn-value2",type:"text",style:"width: 100%"}).appendTo(row3InputCell).typedInput({default:'num',types:['msg','flow','global','str','num','jsonata','env',previousValueType]});
|
||||
return $('<input/>',{class:"node-input-rule-btwn-value2",type:"text",style:"width: 100%"}).appendTo(row3InputCell)
|
||||
.typedInput({default:defaultType||'num',types:['msg','flow','global','str','num','jsonata','env',previousValueType]});
|
||||
}
|
||||
|
||||
function createTypeValueField(){
|
||||
return $('<input/>',{class:"node-input-rule-type-value",type:"text",style:"width: 100%;"}).appendTo(row).typedInput({default:'string',types:[
|
||||
function createTypeValueField(row, defaultType){
|
||||
return $('<input/>',{class:"node-input-rule-type-value",type:"text",style:"width: 100%;"}).appendTo(row).typedInput({default:defaultType || 'string',types:[
|
||||
{value:"string",label:RED._("common.type.string"),hasValue:false,icon:"red/images/typedInput/az.png"},
|
||||
{value:"number",label:RED._("common.type.number"),hasValue:false,icon:"red/images/typedInput/09.png"},
|
||||
{value:"boolean",label:RED._("common.type.boolean"),hasValue:false,icon:"red/images/typedInput/bool.png"},
|
||||
@@ -211,6 +216,7 @@
|
||||
var lastRule = $("#node-input-rule-container").editableList('getItemAt',i-1);
|
||||
var exportedRule = exportRule(lastRule.element);
|
||||
opt.r.vt = exportedRule.vt;
|
||||
opt.r.v = "";
|
||||
// We could copy the value over as well and preselect it (see the 'activeElement' code below)
|
||||
// But not sure that feels right. Is copying over the last value 'expected' behaviour?
|
||||
// It would make sense for an explicit 'copy' action, but not sure where the copy button would
|
||||
@@ -278,24 +284,12 @@
|
||||
selectField.on("change", function() {
|
||||
var fieldToFocus;
|
||||
var type = selectField.val();
|
||||
if (valueField){
|
||||
valueField.typedInput('hide');
|
||||
}
|
||||
if (expValueField){
|
||||
expValueField.typedInput('hide');
|
||||
}
|
||||
if (numValueField){
|
||||
numValueField.typedInput('hide');
|
||||
}
|
||||
if (typeValueField){
|
||||
typeValueField.typedInput('hide');
|
||||
}
|
||||
if (btwnValueField){
|
||||
btwnValueField.typedInput('hide');
|
||||
}
|
||||
if (btwnValue2Field){
|
||||
btwnValue2Field.typedInput('hide');
|
||||
}
|
||||
if (valueField) { valueField.typedInput('hide'); }
|
||||
if (expValueField) { expValueField.typedInput('hide'); }
|
||||
if (numValueField) { numValueField.typedInput('hide'); }
|
||||
if (typeValueField) { typeValueField.typedInput('hide'); }
|
||||
if (btwnValueField) { btwnValueField.typedInput('hide'); }
|
||||
if (btwnValue2Field) { btwnValue2Field.typedInput('hide'); }
|
||||
|
||||
if ((type === "btwn") || (type === "index")) {
|
||||
if (!btwnValueField){
|
||||
@@ -318,7 +312,7 @@
|
||||
|
||||
} else if (type === "istype") {
|
||||
if (!typeValueField){
|
||||
typeValueField = createTypeValueField();
|
||||
typeValueField = createTypeValueField(rowInputCell);
|
||||
}
|
||||
typeValueField.typedInput('show');
|
||||
fieldToFocus = typeValueField;
|
||||
@@ -351,7 +345,9 @@
|
||||
} else {
|
||||
selectField.width("auto")
|
||||
}
|
||||
fieldToFocus.typedInput("focus");
|
||||
if (fieldToFocus) {
|
||||
fieldToFocus.typedInput("focus");
|
||||
}
|
||||
// Preselect the contents of the element
|
||||
// if (focusValueField && document.activeElement) {
|
||||
// document.activeElement.selectionStart = 0;
|
||||
@@ -359,48 +355,26 @@
|
||||
// }
|
||||
});
|
||||
selectField.val(rule.t);
|
||||
if ((rule.t == "btwn") || (rule.t == "index")) {
|
||||
if (!btwnValueField){
|
||||
btwnValueField = createBtwnValueField(rowInputCell);
|
||||
}
|
||||
btwnValueField.typedInput('value',rule.v);
|
||||
btwnValueField.typedInput('type',rule.vt||'num');
|
||||
|
||||
if (!btwnValue2Field){
|
||||
btwnValue2Field = createBtwnValue2Field(row3, andLabel);
|
||||
}
|
||||
if ((rule.t == "btwn") || (rule.t == "index")) {
|
||||
btwnValueField = createBtwnValueField(rowInputCell,rule.vt||'num');
|
||||
btwnValueField.typedInput('value',rule.v);
|
||||
btwnValue2Field = createBtwnValue2Field(row3, andLabel,rule.v2t||'num');
|
||||
btwnValue2Field.typedInput('value',rule.v2);
|
||||
btwnValue2Field.typedInput('type',rule.v2t||'num');
|
||||
} else if ((rule.t === "head") || (rule.t === "tail")) {
|
||||
if (!numValueField){
|
||||
numValueField = createNumValueField(row);
|
||||
}
|
||||
numValueField = createNumValueField(rowInputCell,rule.vt||'num');
|
||||
numValueField.typedInput('value',rule.v);
|
||||
numValueField.typedInput('type',rule.vt||'num');
|
||||
} else if (rule.t === "istype") {
|
||||
if (!typeValueField){
|
||||
typeValueField =createTypeValueField();
|
||||
}
|
||||
typeValueField = createTypeValueField(rowInputCell,rule.vt);
|
||||
typeValueField.typedInput('value',rule.vt);
|
||||
typeValueField.typedInput('type',rule.vt);
|
||||
} else if (rule.t === "jsonata_exp") {
|
||||
if (!expValueField){
|
||||
expValueField = createExpValueField(row);
|
||||
}
|
||||
expValueField = createExpValueField(rowInputCell,rule.vt||'jsonata');
|
||||
expValueField.typedInput('value',rule.v);
|
||||
expValueField.typedInput('type',rule.vt||'jsonata');
|
||||
} else if (typeof rule.v != "undefined") {
|
||||
if (!valueField){
|
||||
valueField = createValueField(rowInputCell);
|
||||
}
|
||||
valueField = createValueField(rowInputCell,rule.vt||'str');
|
||||
valueField.typedInput('value',rule.v);
|
||||
valueField.typedInput('type',rule.vt||'str');
|
||||
}
|
||||
if (rule.case) {
|
||||
caseSensitive.prop('checked',true);
|
||||
} else {
|
||||
caseSensitive.prop('checked',false);
|
||||
}
|
||||
caseSensitive.prop('checked',!!rule.case);
|
||||
selectField.change();
|
||||
|
||||
var currentOutputs = JSON.parse(outputCount.val()||"{}");
|
||||
|
@@ -115,12 +115,12 @@
|
||||
var regex = this._("change.label.regex");
|
||||
var deepCopyLabel = this._("change.label.deepCopy");
|
||||
|
||||
function createPropertyValue(row2_1,row2_2) {
|
||||
function createPropertyValue(row2_1, row2_2, defaultType) {
|
||||
var propValInput = $('<input/>',{class:"node-input-rule-property-value",type:"text"})
|
||||
.appendTo(row2_1)
|
||||
.typedInput({default:'str',types:['msg','flow','global','str','num','bool','json','bin','date','jsonata','env']});
|
||||
.typedInput({default:defaultType||'str',types:['msg','flow','global','str','num','bool','json','bin','date','jsonata','env']});
|
||||
|
||||
var dcLabel = $('<label style="padding-left: 130px; display: flex; align-items: center "></label>').appendTo(row2_2);
|
||||
var dcLabel = $('<label style="padding-left: 130px;"></label>').appendTo(row2_2);
|
||||
var deepCopy = $('<input type="checkbox" class="node-input-rule-property-deepCopy" style="width: auto; margin: 0 6px 0 0">').appendTo(dcLabel)
|
||||
$('<span>').text(deepCopyLabel).appendTo(dcLabel)
|
||||
|
||||
@@ -129,20 +129,20 @@
|
||||
})
|
||||
return [propValInput, deepCopy];
|
||||
}
|
||||
function createFromValue(row3_1) {
|
||||
function createFromValue(row3_1, defaultType) {
|
||||
return $('<input/>',{class:"node-input-rule-property-search-value",type:"text"})
|
||||
.appendTo(row3_1)
|
||||
.typedInput({default:'str',types:['msg','flow','global','str','re','num','bool','env']});
|
||||
.typedInput({default:defaultType||'str',types:['msg','flow','global','str','re','num','bool','env']});
|
||||
}
|
||||
function createToValue(row3_2) {
|
||||
function createToValue(row3_2, defaultType) {
|
||||
return $('<input/>',{class:"node-input-rule-property-replace-value",type:"text"})
|
||||
.appendTo(row3_2)
|
||||
.typedInput({default:'str',types:['msg','flow','global','str','num','bool','json','bin','env']});
|
||||
.typedInput({default:defaultType||'str',types:['msg','flow','global','str','num','bool','json','bin','env']});
|
||||
}
|
||||
function createMoveValue(row4) {
|
||||
function createMoveValue(row4, defaultType) {
|
||||
return $('<input/>',{class:"node-input-rule-property-move-value",type:"text"})
|
||||
.appendTo(row4)
|
||||
.typedInput({default:'msg',types:['msg','flow','global']});
|
||||
.typedInput({default:defaultType||'msg',types:['msg','flow','global']});
|
||||
}
|
||||
|
||||
$('#node-input-rule-container').css('min-height','150px').css('min-width','450px').editableList({
|
||||
@@ -268,33 +268,22 @@
|
||||
propertyName.typedInput('value',rule.p);
|
||||
propertyName.typedInput('type',rule.pt);
|
||||
if (rule.t == "set") {
|
||||
if(!propertyValue) {
|
||||
var parts = createPropertyValue(row2_1, row2_2);
|
||||
propertyValue = parts[0];
|
||||
deepCopy = parts[1];
|
||||
}
|
||||
var parts = createPropertyValue(row2_1, row2_2, rule.tot);
|
||||
propertyValue = parts[0];
|
||||
deepCopy = parts[1];
|
||||
propertyValue.typedInput('value',rule.to);
|
||||
propertyValue.typedInput('type',rule.tot);
|
||||
deepCopy.prop("checked", !!rule.dc);
|
||||
}
|
||||
if (rule.t == "move") {
|
||||
if(!moveValue) {
|
||||
moveValue = createMoveValue(row4);
|
||||
}
|
||||
moveValue = createMoveValue(row4,rule.tot);
|
||||
moveValue.typedInput('value',rule.to);
|
||||
moveValue.typedInput('type',rule.tot);
|
||||
}
|
||||
if (rule.t == "change") {
|
||||
if(!fromValue) {
|
||||
fromValue = createFromValue(row3_1);
|
||||
}
|
||||
fromValue = createFromValue(row3_1, rule.fromt);
|
||||
fromValue.typedInput('value',rule.from);
|
||||
fromValue.typedInput('type',rule.fromt);
|
||||
if (!toValue) {
|
||||
toValue = createToValue(row3_2);
|
||||
}
|
||||
|
||||
toValue = createToValue(row3_2,rule.tot);
|
||||
toValue.typedInput('value',rule.to);
|
||||
toValue.typedInput('type',rule.tot);
|
||||
}
|
||||
selectField.change();
|
||||
container[0].appendChild(fragment);
|
||||
|
@@ -54,6 +54,18 @@
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
}
|
||||
.form-row-mqtt5 {
|
||||
display: none;
|
||||
}
|
||||
.form-row-mqtt5.form-row-mqtt5-active:not(.form-row-mqtt-static-disabled) {
|
||||
display: block
|
||||
}
|
||||
.form-row-mqtt-static-disabled {
|
||||
display: none;
|
||||
/* opacity: 0.3;
|
||||
pointer-events: none; */
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<script type="text/html" data-template-name="mqtt in">
|
||||
@@ -62,10 +74,18 @@
|
||||
<input type="text" id="node-input-broker">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-topicType" data-i18n="mqtt.label.action"></label>
|
||||
<select id="node-input-topicType" style="width: 70%">
|
||||
<option value="topic" data-i18n="mqtt.label.staticTopic"></option>
|
||||
<option value="dynamic" data-i18n="mqtt.label.dynamicTopic"></option>
|
||||
</select>
|
||||
<input type="hidden" id="node-input-inputs">
|
||||
</div>
|
||||
<div class="form-row form-row-mqtt-static">
|
||||
<label for="node-input-topic"><i class="fa fa-tasks"></i> <span data-i18n="common.label.topic"></span></label>
|
||||
<input type="text" id="node-input-topic" data-i18n="[placeholder]common.label.topic">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-row form-row-mqtt-static">
|
||||
<label for="node-input-qos"><i class="fa fa-empire"></i> <span data-i18n="mqtt.label.qos"></span></label>
|
||||
<select id="node-input-qos" style="width:125px !important">
|
||||
<option value="0">0</option>
|
||||
@@ -73,17 +93,7 @@
|
||||
<option value="2">2</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-datatype"><i class="fa fa-sign-out"></i> <span data-i18n="mqtt.label.output"></span></label>
|
||||
<select id="node-input-datatype" style="width:70%;">
|
||||
<option value="auto" data-i18n="mqtt.output.auto"></option>
|
||||
<option value="buffer" data-i18n="mqtt.output.buffer"></option>
|
||||
<option value="utf8" data-i18n="mqtt.output.string"></option>
|
||||
<option value="json" data-i18n="mqtt.output.json"></option>
|
||||
<option value="base64" data-i18n="mqtt.output.base64"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row mqtt-flags-row mqtt5">
|
||||
<div class="form-row mqtt-flags-row form-row-mqtt5 form-row-mqtt-static">
|
||||
<label for="node-input-nl" ><i class="fa fa-flag"></i> <span data-i18n="mqtt.label.flags">Flags</span></label>
|
||||
<div class="mqtt-flags">
|
||||
<div class="mqtt-flag">
|
||||
@@ -100,7 +110,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row mqtt5">
|
||||
<div class="form-row form-row-mqtt5 form-row-mqtt-static">
|
||||
<label for="node-input-rh" style="width:100%"><i class="fa fa-tag"></i> <span data-i18n="mqtt.label.rh"></span></label>
|
||||
<select id="node-input-rh" style="margin-left: 104px; width: 70%">
|
||||
<option value="0" data-i18n="mqtt.label.rh0"></option>
|
||||
@@ -108,6 +118,16 @@
|
||||
<option value="2" data-i18n="mqtt.label.rh2"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-datatype"><i class="fa fa-sign-out"></i> <span data-i18n="mqtt.label.output"></span></label>
|
||||
<select id="node-input-datatype" style="width:70%;">
|
||||
<option value="auto" data-i18n="mqtt.output.auto"></option>
|
||||
<option value="buffer" data-i18n="mqtt.output.buffer"></option>
|
||||
<option value="utf8" data-i18n="mqtt.output.string"></option>
|
||||
<option value="json" data-i18n="mqtt.output.json"></option>
|
||||
<option value="base64" data-i18n="mqtt.output.base64"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
||||
@@ -185,6 +205,10 @@
|
||||
<label for="node-config-input-port" style="margin-left:20px; width:43px; "> <span data-i18n="mqtt.label.port"></span></label>
|
||||
<input type="text" id="node-config-input-port" data-i18n="[placeholder]mqtt.label.port" style="width:55px">
|
||||
</div>
|
||||
<div class="form-row" style="margin-bottom:0">
|
||||
<input type="checkbox" id="node-config-input-autoConnect" style="margin: 0 5px 0 104px; display: inline-block; width: auto;">
|
||||
<label for="node-config-input-autoConnect" style="width: auto"><span data-i18n="mqtt.label.auto-connect"></span></label>
|
||||
</div>
|
||||
<div class="form-row" style="height: 34px;">
|
||||
<input type="checkbox" id="node-config-input-usetls" style="height: 34px; margin: 0 5px 0 104px; display: inline-block; width: auto; vertical-align: top;">
|
||||
<label for="node-config-input-usetls" style="width: 100px; line-height: 34px;"><span data-i18n="mqtt.label.use-tls"></span></label>
|
||||
@@ -434,6 +458,7 @@
|
||||
return (this.cleansession===undefined || this.cleansession) || (v||"").length > 0;
|
||||
}
|
||||
}},
|
||||
autoConnect: {value: true},
|
||||
usetls: {value: false},
|
||||
verifyservercert: { value: false},
|
||||
compatmode: { value: false},
|
||||
@@ -558,6 +583,10 @@
|
||||
this.usetls = false;
|
||||
$("#node-config-input-usetls").prop("checked",false);
|
||||
}
|
||||
if (typeof this.autoConnect === 'undefined') {
|
||||
this.autoConnect = true;
|
||||
$("#node-config-input-autoConnect").prop("checked",true);
|
||||
}
|
||||
if (this.compatmode === 'true' || this.compatmode === true) {
|
||||
delete this.compatmode;
|
||||
this.protocolVersion = 4;
|
||||
@@ -704,11 +733,22 @@
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
RED.nodes.registerType('mqtt in',{
|
||||
category: 'network',
|
||||
defaults: {
|
||||
name: {value:""},
|
||||
topic: {value:"",required:true,validate: RED.validators.regex(/^(#$|(\+|[^+#]*)(\/(\+|[^+#]*))*(\/(\+|#|[^+#]*))?$)/)},
|
||||
topic: {
|
||||
value:"",
|
||||
validate: function(v) {
|
||||
var isDynamic = this.inputs === 1;
|
||||
var topicTypeSelect = $("#node-input-topicType");
|
||||
if (topicTypeSelect.length) {
|
||||
isDynamic = topicTypeSelect.val()==='dynamic'
|
||||
}
|
||||
return isDynamic || ((!!v) && RED.validators.regex(/^(#$|(\+|[^+#]*)(\/(\+|[^+#]*))*(\/(\+|#|[^+#]*))?$)/)(v));
|
||||
}
|
||||
},
|
||||
qos: {value: "2"},
|
||||
datatype: {value:"auto",required:true},
|
||||
broker: {type:"mqtt-broker", required:true},
|
||||
@@ -716,33 +756,64 @@
|
||||
nl: {value:false},
|
||||
rap: {value:true},
|
||||
rh: {value:0},
|
||||
inputs: {value:0},
|
||||
},
|
||||
color:"#d8bfd8",
|
||||
inputs:0,
|
||||
outputs:1,
|
||||
icon: "bridge.svg",
|
||||
label: function() {
|
||||
return this.name||this.topic||"mqtt";
|
||||
var label = "mqtt";
|
||||
if(this.topicType !== "dynamic" && this.topic) {
|
||||
label = this.topic;
|
||||
}
|
||||
return this.name || label;
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
},
|
||||
oneditprepare: function() {
|
||||
$("#node-input-broker").on("change",function(d){
|
||||
const node = this;
|
||||
const isV5Broker = function() {
|
||||
var confNode = RED.nodes.node($("#node-input-broker").val());
|
||||
var v5 = confNode && confNode.protocolVersion == "5";
|
||||
if(v5) {
|
||||
$("div.form-row.mqtt5").show();
|
||||
} else {
|
||||
$("div.form-row.mqtt5").hide();
|
||||
}
|
||||
return confNode && confNode.protocolVersion === "5";
|
||||
}
|
||||
const isDynamic = function() {
|
||||
return $('#node-input-topicType').val() === "dynamic";
|
||||
}
|
||||
const updateVisibility = function() {
|
||||
var v5 = isV5Broker();
|
||||
var dynamic = isDynamic();
|
||||
$("div.form-row-mqtt5").toggleClass("form-row-mqtt5-active",!!v5);
|
||||
$("div.form-row.form-row-mqtt-static").toggleClass("form-row-mqtt-static-disabled", !!dynamic)
|
||||
}
|
||||
$("#node-input-broker").on("change",function(d){
|
||||
updateVisibility();
|
||||
});
|
||||
|
||||
$('#node-input-topicType').on("change", function () {
|
||||
$("#node-input-inputs").val(isDynamic() ? 1 : 0);
|
||||
updateVisibility();
|
||||
});
|
||||
|
||||
if (this.inputs === 1) {
|
||||
$('#node-input-topicType').val('dynamic')
|
||||
} else {
|
||||
$('#node-input-topicType').val('topic')
|
||||
}
|
||||
$('#node-input-topicType').trigger("change");
|
||||
|
||||
if (this.qos === undefined) {
|
||||
$("#node-input-qos").val("2");
|
||||
}
|
||||
if (this.datatype === undefined) {
|
||||
$("#node-input-datatype").val("auto");
|
||||
}
|
||||
},
|
||||
oneditsave: function() {
|
||||
if ($('#node-input-topicType').val() === "dynamic") {
|
||||
$('#node-input-topic').val("");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -143,12 +143,17 @@
|
||||
"filterSelected": "selected nodes",
|
||||
"filterCurrent": "current flow",
|
||||
"debugNodes": "Debug nodes",
|
||||
"clearLog": "Clear log",
|
||||
"filterLog": "Filter log",
|
||||
"clearLog": "Clear messages",
|
||||
"clearFilteredLog": "Clear filtered messages",
|
||||
"filterLog": "Filter messages",
|
||||
"openWindow": "Open in new window",
|
||||
"copyPath": "Copy path",
|
||||
"copyPayload": "Copy value",
|
||||
"pinPath": "Pin open"
|
||||
"pinPath": "Pin open",
|
||||
"selectAll": "select all",
|
||||
"selectNone": "select none",
|
||||
"all": "all",
|
||||
"filtered": "filtered"
|
||||
},
|
||||
"messageMenu": {
|
||||
"collapseAll": "Collapse all paths",
|
||||
@@ -411,7 +416,11 @@
|
||||
"maximumPacketSize": "Max Packet Size",
|
||||
"receiveMaximum": "Receive Max",
|
||||
"session": "Session",
|
||||
"delay": "Delay"
|
||||
"delay": "Delay",
|
||||
"action": "Action",
|
||||
"staticTopic": "Subscribe to single topic",
|
||||
"dynamicTopic": "Dynamic subscription",
|
||||
"auto-connect": "Connect automatically"
|
||||
},
|
||||
"sections-label":{
|
||||
"birth-message": "Message sent on connection (birth message)",
|
||||
@@ -452,7 +461,10 @@
|
||||
"invalid-topic": "Invalid topic specified",
|
||||
"nonclean-missingclientid": "No client ID set, using clean session",
|
||||
"invalid-json-string": "Invalid JSON string",
|
||||
"invalid-json-parse": "Failed to parse JSON string"
|
||||
"invalid-json-parse": "Failed to parse JSON string",
|
||||
"invalid-action-action": "Invalid action specified",
|
||||
"invalid-action-alreadyconnected": "Disconnect from broker before connecting",
|
||||
"invalid-action-badsubscription": "msg.topic is missing or invalid"
|
||||
}
|
||||
},
|
||||
"httpin": {
|
||||
|
@@ -40,6 +40,38 @@
|
||||
<p>This node requires a connection to a MQTT broker to be configured. This is configured by clicking
|
||||
the pencil icon.</p>
|
||||
<p>Several MQTT nodes (in or out) can share the same broker connection if required.</p>
|
||||
<h4>Dynamic Subscription</h4>
|
||||
The node can be configured to dynamically control the MQTT connection and its subscriptions. When
|
||||
enabled, the node will have an input and can be controlled by passing it messages.
|
||||
<h3>Inputs</h3>
|
||||
<p>These only apply when the node has been configured for dynamic subscriptions.</p>
|
||||
<dl class="message-properties">
|
||||
<dt>action <span class="property-type">string</span></dt>
|
||||
<dd>the name of the action the node should perform. Available actions are: <code>"connect"</code>,
|
||||
<code>"disconnect"</code>, <code>"subscribe"</code> and <code>"unsubscribe"</code>.</dd>
|
||||
<dt class="optional">topic <span class="property-type">string|object|array</span></dt>
|
||||
<dd>For the <code>"subscribe"</code> and <code>"unsubscribe"</code> actions, this property
|
||||
provides the topic. It can be set as either:<ul>
|
||||
<li>a String continaing the topic filter</li>
|
||||
<li>an Object containing <code>topic</code> and <code>qos</code> properties</li>
|
||||
<li>an array of either strings or objects to handle multiple topics in one</li>
|
||||
</ul>
|
||||
</dd>
|
||||
<dt class="optional">broker <span class="property-type">broker</span> </dt>
|
||||
<dd>For the <code>"connect"</code> action, this property can override any
|
||||
of the individual broker configuration settings, including: <ul>
|
||||
<li><code>broker</code></li>
|
||||
<li><code>port</code></li>
|
||||
<li><code>url</code> - overrides broker/port to provide a complete connection url</li>
|
||||
<li><code>username</code></li>
|
||||
<li><code>password</code></li>
|
||||
</ul>
|
||||
<p>If this property is set and the broker is already connected an error
|
||||
will be logged unless it has the <code>force</code> property set - in which case it will
|
||||
disconnect from the broker, apply the new settings and reconnect.</p>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-help-name="mqtt out">
|
||||
@@ -78,6 +110,30 @@
|
||||
<p>This node requires a connection to a MQTT broker to be configured. This is configured by clicking
|
||||
the pencil icon.</p>
|
||||
<p>Several MQTT nodes (in or out) can share the same broker connection if required.</p>
|
||||
|
||||
<h4>Dynamic Control</h4>
|
||||
The connection shared by the node can be controlled dynamically. If the node receives
|
||||
one of the following control messages, it will not publish the message payload as well.
|
||||
<h3>Inputs</h3>
|
||||
<dl class="message-properties">
|
||||
<dt>action <span class="property-type">string</span></dt>
|
||||
<dd>the name of the action the node should perform. Available actions are: <code>"connect"</code>,
|
||||
and <code>"disconnect"</code>.</dd>
|
||||
<dt class="optional">broker <span class="property-type">broker</span> </dt>
|
||||
<dd>For the <code>"connect"</code> action, this property can override any
|
||||
of the individual broker configuration settings, including: <ul>
|
||||
<li><code>broker</code></li>
|
||||
<li><code>port</code></li>
|
||||
<li><code>url</code> - overrides broker/port to provide a complete connection url</li>
|
||||
<li><code>username</code></li>
|
||||
<li><code>password</code></li>
|
||||
</ul>
|
||||
<p>If this property is set and the broker is already connected an error
|
||||
will be logged unless it has the <code>force</code> property set - in which case it will
|
||||
disconnect from the broker, apply the new settings and reconnect.</p>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-help-name="mqtt-broker">
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@node-red/nodes",
|
||||
"version": "2.1.0-beta.1",
|
||||
"version": "2.1.0-beta.2",
|
||||
"license": "Apache-2.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
Reference in New Issue
Block a user