mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Add inject values without deploy feature
This commit is contained in:
parent
8a63390464
commit
bae6bfc32d
@ -13,7 +13,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
**/
|
**/
|
||||||
RED.tray = (function() {
|
RED.tray = (function() {
|
||||||
|
|
||||||
var stack = [];
|
var stack = [];
|
||||||
var editorStack;
|
var editorStack;
|
||||||
@ -288,9 +288,9 @@ RED.tray = (function() {
|
|||||||
right: -(tray.tray.width()+10)+"px"
|
right: -(tray.tray.width()+10)+"px"
|
||||||
});
|
});
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
if (tray.options.close) {
|
try {
|
||||||
tray.options.close();
|
if (tray.options.close) { tray.options.close(); }
|
||||||
}
|
} catch (ex) { }
|
||||||
tray.tray.remove();
|
tray.tray.remove();
|
||||||
if (stack.length > 0) {
|
if (stack.length > 0) {
|
||||||
var oldTray = stack[stack.length-1];
|
var oldTray = stack[stack.length-1];
|
||||||
|
@ -149,6 +149,101 @@
|
|||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
(function() {
|
(function() {
|
||||||
|
/** Retrieve editableList items (refactored for re-use in the custom inject)*/
|
||||||
|
function getProps(el, legacy) {
|
||||||
|
var result = {
|
||||||
|
props: []
|
||||||
|
}
|
||||||
|
el.each(function(i) {
|
||||||
|
var prop = $(this);
|
||||||
|
var p = {
|
||||||
|
p:prop.find(".node-input-prop-property-name").typedInput('value')
|
||||||
|
};
|
||||||
|
if (p.p) {
|
||||||
|
p.v = prop.find(".node-input-prop-property-value").typedInput('value');
|
||||||
|
p.vt = prop.find(".node-input-prop-property-value").typedInput('type');
|
||||||
|
if(legacy) {
|
||||||
|
if (p.p === "payload") { // save payload to old "legacy" property
|
||||||
|
result.payloadType = p.vt;
|
||||||
|
result.payload = p.v;
|
||||||
|
delete p.v;
|
||||||
|
delete p.vt;
|
||||||
|
} else if (p.p === "topic" && p.vt === "str") {
|
||||||
|
result.topic = p.v;
|
||||||
|
delete p.v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.props.push(p);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
/** Build the editableList items (refactored for re-use in the custom inject)*/
|
||||||
|
function buildEditableList(el, props, legacyProps) {
|
||||||
|
legacyProps = legacyProps || {};
|
||||||
|
var list = $(el);
|
||||||
|
list.editableList({
|
||||||
|
addItem: function(container,i,opt) {
|
||||||
|
var prop = opt;
|
||||||
|
if (!prop.hasOwnProperty('p')) {
|
||||||
|
prop = {p:"",v:"",vt:"str"};
|
||||||
|
}
|
||||||
|
container.css({
|
||||||
|
overflow: 'hidden',
|
||||||
|
whiteSpace: 'nowrap'
|
||||||
|
});
|
||||||
|
var row = $('<div/>').appendTo(container);
|
||||||
|
|
||||||
|
var propertyName = $('<input/>',{class:"node-input-prop-property-name",type:"text"})
|
||||||
|
.css("width","30%")
|
||||||
|
.appendTo(row)
|
||||||
|
.typedInput({types:['msg']});
|
||||||
|
|
||||||
|
$('<div/>',{style: 'display:inline-block; padding:0px 6px;'})
|
||||||
|
.text('=')
|
||||||
|
.appendTo(row);
|
||||||
|
|
||||||
|
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']});
|
||||||
|
|
||||||
|
propertyName.typedInput('value',prop.p);
|
||||||
|
propertyValue.typedInput('value',prop.v);
|
||||||
|
propertyValue.typedInput('type',prop.vt);
|
||||||
|
},
|
||||||
|
removable: true,
|
||||||
|
sortable: true
|
||||||
|
});
|
||||||
|
if (!props) {
|
||||||
|
var payload = {
|
||||||
|
p:'payload',
|
||||||
|
v: legacyProps.payload ? legacyProps.payload : '',
|
||||||
|
vt:legacyProps.payloadType ? legacyProps.payloadType : 'date'
|
||||||
|
};
|
||||||
|
var topic = {
|
||||||
|
p:'topic',
|
||||||
|
v: legacyProps.topic ? legacyProps.topic : '',
|
||||||
|
vt:'string'
|
||||||
|
}
|
||||||
|
props = [payload,topic];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i=0; i<props.length; i++) {
|
||||||
|
var prop = props[i];
|
||||||
|
var newProp = { p: prop.p, v: prop.v, vt: prop.vt };
|
||||||
|
if (newProp.v === undefined) {
|
||||||
|
if (prop.p === 'payload') {
|
||||||
|
newProp.v = legacyProps.payload ? legacyProps.payload : '';
|
||||||
|
newProp.vt = legacyProps.payloadType ? legacyProps.payloadType : 'date';
|
||||||
|
} else if (prop.p === 'topic' && prop.vt === "str") {
|
||||||
|
newProp.v = legacyProps.topic ? legacyProps.topic : '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list.editableList('addItem',newProp);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
function resizeDialog(size) {
|
function resizeDialog(size) {
|
||||||
size = size || { height: $(".red-ui-tray-content form").height() }
|
size = size || { height: $(".red-ui-tray-content form").height() }
|
||||||
@ -430,75 +525,21 @@
|
|||||||
$("#inject-time-row-"+repeattype).show();
|
$("#inject-time-row-"+repeattype).show();
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
|
var list = $('#node-input-property-container');
|
||||||
$('#node-input-property-container').css('min-height','120px').css('min-width','450px').editableList({
|
list.css('min-height','120px').css('min-width','450px');
|
||||||
addItem: function(container,i,opt) {
|
var legacyOptions = {
|
||||||
var prop = opt;
|
topic: this.topic,
|
||||||
if (!prop.hasOwnProperty('p')) {
|
payload: this.payload,
|
||||||
prop = {p:"",v:"",vt:"str"};
|
payloadType: this.payloadType,
|
||||||
}
|
|
||||||
container.css({
|
|
||||||
overflow: 'hidden',
|
|
||||||
whiteSpace: 'nowrap'
|
|
||||||
});
|
|
||||||
var row = $('<div/>').appendTo(container);
|
|
||||||
|
|
||||||
var propertyName = $('<input/>',{class:"node-input-prop-property-name",type:"text"})
|
|
||||||
.css("width","30%")
|
|
||||||
.appendTo(row)
|
|
||||||
.typedInput({types:['msg']});
|
|
||||||
|
|
||||||
$('<div/>',{style: 'display:inline-block; padding:0px 6px;'})
|
|
||||||
.text('=')
|
|
||||||
.appendTo(row);
|
|
||||||
|
|
||||||
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']});
|
|
||||||
|
|
||||||
propertyName.typedInput('value',prop.p);
|
|
||||||
|
|
||||||
propertyValue.typedInput('value',prop.v);
|
|
||||||
propertyValue.typedInput('type',prop.vt);
|
|
||||||
},
|
|
||||||
removable: true,
|
|
||||||
sortable: true
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!this.props) {
|
|
||||||
var payload = {
|
|
||||||
p:'payload',
|
|
||||||
v: this.payload ? this.payload : '',
|
|
||||||
vt:this.payloadType ? this.payloadType : 'date'
|
|
||||||
};
|
|
||||||
var topic = {
|
|
||||||
p:'topic',
|
|
||||||
v: this.topic ? this.topic : '',
|
|
||||||
vt:'string'
|
|
||||||
}
|
|
||||||
this.props = [payload,topic];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i=0; i<this.props.length; i++) {
|
|
||||||
var prop = this.props[i];
|
|
||||||
var newProp = { p: prop.p, v: prop.v, vt: prop.vt };
|
|
||||||
if (newProp.v === undefined) {
|
|
||||||
if (prop.p === 'payload') {
|
|
||||||
newProp.v = this.payload ? this.payload : '';
|
|
||||||
newProp.vt = this.payloadType ? this.payloadType : 'date';
|
|
||||||
} else if (prop.p === 'topic' && prop.vt === "str") {
|
|
||||||
newProp.v = this.topic ? this.topic : '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$("#node-input-property-container").editableList('addItem',newProp);
|
|
||||||
}
|
}
|
||||||
|
buildEditableList(list, this.props, legacyOptions);
|
||||||
|
|
||||||
$("#inject-time-type-select").trigger("change");
|
$("#inject-time-type-select").trigger("change");
|
||||||
$("#inject-time-interval-time-start").trigger("change");
|
$("#inject-time-interval-time-start").trigger("change");
|
||||||
|
|
||||||
},
|
},
|
||||||
oneditsave: function() {
|
oneditsave: function() {
|
||||||
|
var node = this;
|
||||||
var repeat = "";
|
var repeat = "";
|
||||||
var crontab = "";
|
var crontab = "";
|
||||||
var type = $("#inject-time-type-select").val();
|
var type = $("#inject-time-type-select").val();
|
||||||
@ -590,66 +631,165 @@
|
|||||||
$("#node-input-crontab").val(crontab);
|
$("#node-input-crontab").val(crontab);
|
||||||
|
|
||||||
/* Gather the injected properties of the msg object */
|
/* Gather the injected properties of the msg object */
|
||||||
var props = $("#node-input-property-container").editableList('items');
|
var items = $("#node-input-property-container").editableList('items');
|
||||||
var node = this;
|
|
||||||
node.props= [];
|
|
||||||
delete node.payloadType;
|
delete node.payloadType;
|
||||||
delete node.payload;
|
delete node.payload;
|
||||||
node.topic = "";
|
node.topic = "";
|
||||||
props.each(function(i) {
|
var result = getProps(items, true);
|
||||||
var prop = $(this);
|
node.props = result.props;
|
||||||
var p = {
|
if(result.payloadType) { node.payloadType = result.payloadType; };
|
||||||
p:prop.find(".node-input-prop-property-name").typedInput('value')
|
if(result.payload) { node.payload = result.payload; };
|
||||||
};
|
if(result.topic) { node.topic = result.topic; };
|
||||||
if (p.p) {
|
|
||||||
p.v = prop.find(".node-input-prop-property-value").typedInput('value');
|
|
||||||
p.vt = prop.find(".node-input-prop-property-value").typedInput('type');
|
|
||||||
if (p.p === "payload") { // save payload to old "legacy" property
|
|
||||||
node.payloadType = p.vt;
|
|
||||||
node.payload = p.v;
|
|
||||||
delete p.v;
|
|
||||||
delete p.vt;
|
|
||||||
} else if (p.p === "topic" && p.vt === "str") {
|
|
||||||
node.topic = p.v;
|
|
||||||
delete p.v;
|
|
||||||
}
|
|
||||||
node.props.push(p);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
button: {
|
button: {
|
||||||
enabled: function() {
|
enabled: function() {
|
||||||
return !this.changed
|
return !this.changed
|
||||||
},
|
},
|
||||||
onclick: function() {
|
onclick: function () {
|
||||||
if (this.changed) {
|
console.log("inject inject click")
|
||||||
return RED.notify(RED._("notification.warning", {message:RED._("notification.warnings.undeployedChanges")}),"warning");
|
var node = this;
|
||||||
|
if (node.changed) {
|
||||||
|
return RED.notify(RED._("notification.warning", { message: RED._("notification.warnings.undeployedChanges") }), "warning");
|
||||||
}
|
}
|
||||||
|
|
||||||
var label = this._def.label.call(this);
|
var doInject = function (customMsg) {
|
||||||
if (label.length > 30) {
|
var label = node._def.label.call(node);
|
||||||
label = label.substring(0,50)+"...";
|
if (label.length > 30) {
|
||||||
|
label = label.substring(0, 50) + "...";
|
||||||
|
}
|
||||||
|
label = label.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
||||||
|
$.ajax({
|
||||||
|
url: "inject/" + node.id,
|
||||||
|
type: "POST",
|
||||||
|
data: customMsg,
|
||||||
|
success: function (resp) {
|
||||||
|
RED.notify(node._("inject.success", { label: label }), { type: "success", id: "inject", timeout: 2000 });
|
||||||
|
},
|
||||||
|
error: function (jqXHR, textStatus, errorThrown) {
|
||||||
|
if (jqXHR.status == 404) {
|
||||||
|
RED.notify(node._("common.notification.error", { message: node._("common.notification.errors.not-deployed") }), "error");
|
||||||
|
} else if (jqXHR.status == 500) {
|
||||||
|
RED.notify(node._("common.notification.error", { message: node._("inject.errors.failed") }), "error");
|
||||||
|
} else if (jqXHR.status == 0) {
|
||||||
|
RED.notify(node._("common.notification.error", { message: node._("common.notification.errors.no-response") }), "error");
|
||||||
|
} else {
|
||||||
|
RED.notify(node._("common.notification.error", { message: node._("common.notification.errors.unexpected", { status: jqXHR.status, message: textStatus }) }), "error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
label = label.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");
|
|
||||||
var node = this;
|
if (window.event.ctrlKey) {
|
||||||
$.ajax({
|
var wasDirty = node.dirty;
|
||||||
url: "inject/"+this.id,
|
// var wasDirty = RED.nodes.dirty();
|
||||||
type:"POST",
|
var originalProps = {
|
||||||
success: function(resp) {
|
props: node.props,
|
||||||
RED.notify(node._("inject.success",{label:label}),{type:"success",id:"inject", timeout: 2000});
|
payloadType: node.payloadType,
|
||||||
},
|
payload: node.payload,
|
||||||
error: function(jqXHR,textStatus,errorThrown) {
|
topic: node.topic
|
||||||
if (jqXHR.status == 404) {
|
};
|
||||||
RED.notify(node._("common.notification.error",{message:node._("common.notification.errors.not-deployed")}),"error");
|
var originalPropsJSON = JSON.stringify(originalProps);
|
||||||
} else if (jqXHR.status == 500) {
|
var trayOptions = {
|
||||||
RED.notify(node._("common.notification.error",{message:node._("inject.errors.failed")}),"error");
|
title: node.name || (node._def.label && node._def.label.call(node)) || node._('inject.inject'),
|
||||||
} else if (jqXHR.status == 0) {
|
width: 'inherit',
|
||||||
RED.notify(node._("common.notification.error",{message:node._("common.notification.errors.no-response")}),"error");
|
buttons: [
|
||||||
} else {
|
{
|
||||||
RED.notify(node._("common.notification.error",{message:node._("common.notification.errors.unexpected",{status:jqXHR.status,message:textStatus})}),"error");
|
id: 'node-dialog-cancel',
|
||||||
|
class: 'primary',
|
||||||
|
text: 'Close' || RED._('common.label.cancel'),
|
||||||
|
click: function () {
|
||||||
|
RED.tray.close();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'node-dialog-apply',
|
||||||
|
text: 'Apply', //RED._('common.label.apply'),
|
||||||
|
click: function () {
|
||||||
|
debugger
|
||||||
|
delete node.payload;
|
||||||
|
node.topic = "";
|
||||||
|
var items = $('#node-inject-custom-list').editableList('items');
|
||||||
|
var result = getProps(items, true);
|
||||||
|
node.props = result.props;
|
||||||
|
if(result.payloadType) { node.payloadType = result.payloadType; };
|
||||||
|
if(result.payload) { node.payload = result.payload; };
|
||||||
|
if(result.topic) { node.topic = result.topic; };
|
||||||
|
var newProps = {
|
||||||
|
props: node.props,
|
||||||
|
payloadType: node.payloadType,
|
||||||
|
payload: node.payload,
|
||||||
|
topic: node.topic
|
||||||
|
};
|
||||||
|
var newPropsJSON = JSON.stringify(newProps);
|
||||||
|
var changed = newPropsJSON != originalPropsJSON;
|
||||||
|
if (changed) {
|
||||||
|
var changes = JSON.parse(originalPropsJSON);
|
||||||
|
node.changed = true;
|
||||||
|
RED.nodes.dirty(true);
|
||||||
|
var historyEvent = {
|
||||||
|
t:'edit',
|
||||||
|
node:node,
|
||||||
|
changes:changes,
|
||||||
|
dirty:wasDirty,
|
||||||
|
changed:changed
|
||||||
|
};
|
||||||
|
RED.history.push(historyEvent);
|
||||||
|
}
|
||||||
|
node.dirty = true;
|
||||||
|
RED.editor.validateNode(node);
|
||||||
|
RED.events.emit("editor:save",node);
|
||||||
|
RED.events.emit("nodes:change",node);
|
||||||
|
RED.tray.close();//should apply close the dialog?
|
||||||
|
RED.view.redraw();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'node-dialog-ok',
|
||||||
|
text: 'Inject', //RED._('inject.inject'),
|
||||||
|
click: function () {
|
||||||
|
var items = $('#node-inject-custom-list').editableList('items');
|
||||||
|
var result = getProps(items);
|
||||||
|
if (result && result.props && result.props.length) {
|
||||||
|
m = { __customProps: result.props };
|
||||||
|
}
|
||||||
|
doInject(m);
|
||||||
|
//RED.tray.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
resize: function (dimensions) {
|
||||||
|
$('#node-dialog-inject-custom .red-ui-editableList-container').css('height', '');//allow editable list to self size
|
||||||
|
},
|
||||||
|
open: function (tray) {
|
||||||
|
var trayBody = tray.find('.red-ui-tray-body');
|
||||||
|
var dialog = $('<div id="node-dialog-inject-custom"></div>');
|
||||||
|
var list = $('<ol id="node-inject-custom-list"></ol>');
|
||||||
|
dialog.append(list);
|
||||||
|
trayBody.append(dialog);
|
||||||
|
list.css('min-height', '120px').css('min-width', '400px');
|
||||||
|
var legacyOptions = {
|
||||||
|
topic: node.topic,
|
||||||
|
payload: node.payload,
|
||||||
|
payloadType: node.payloadType,
|
||||||
|
}
|
||||||
|
buildEditableList(list, node.props, legacyOptions);
|
||||||
|
},
|
||||||
|
close: function () {
|
||||||
|
setTimeout(function () {
|
||||||
|
$('#node-dialog-inject-custom').dialog('destroy').remove();
|
||||||
|
}, 5);
|
||||||
|
},
|
||||||
|
show: function (tray) {
|
||||||
|
//primary button is the cancel button but, for aestetics, colour the inject button.
|
||||||
|
$('#node-dialog-cancel').removeClass('primary');
|
||||||
|
$('#node-dialog-ok').addClass('primary');
|
||||||
|
$('#node-dialog-inject-custom .red-ui-editableList-container').css('height', '');//allow editable list to self size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
RED.tray.show(trayOptions);
|
||||||
|
} else {
|
||||||
|
doInject();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
oneditresize: resizeDialog
|
oneditresize: resizeDialog
|
||||||
|
@ -100,8 +100,12 @@ module.exports = function(RED) {
|
|||||||
|
|
||||||
this.on("input", function(msg, send, done) {
|
this.on("input", function(msg, send, done) {
|
||||||
var errors = [];
|
var errors = [];
|
||||||
|
var props = this.props;
|
||||||
this.props.forEach(p => {
|
if(msg.__customProps && Array.isArray(msg.__customProps)) {
|
||||||
|
props = msg.__customProps;
|
||||||
|
}
|
||||||
|
delete msg.__customProps;
|
||||||
|
props.forEach(p => {
|
||||||
var property = p.p;
|
var property = p.p;
|
||||||
var value = p.v ? p.v : '';
|
var value = p.v ? p.v : '';
|
||||||
var valueType = p.vt ? p.vt : 'str';
|
var valueType = p.vt ? p.vt : 'str';
|
||||||
@ -156,7 +160,11 @@ module.exports = function(RED) {
|
|||||||
var node = RED.nodes.getNode(req.params.id);
|
var node = RED.nodes.getNode(req.params.id);
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
try {
|
try {
|
||||||
node.receive();
|
if (req.body && req.body.__customProps) {
|
||||||
|
node.receive(req.body);
|
||||||
|
} else {
|
||||||
|
node.receive();
|
||||||
|
}
|
||||||
res.sendStatus(200);
|
res.sendStatus(200);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
res.sendStatus(500);
|
res.sendStatus(500);
|
||||||
|
Loading…
Reference in New Issue
Block a user