1
0
mirror of https://github.com/node-red/node-red.git synced 2023-10-10 13:36:53 +02:00

move new inject button to existing edit form

- revert refactoring of building editableList (not needed now)
- remove node button modifier click & tray.show feature
- add inject button to editableList [buttons] array
- add `id` option to editableList to permit DOM access after creation
- get the new inject button via its `id` and float it to the right
- removed the popup tray buttons i18n entries
This commit is contained in:
Steve-Mcl 2021-05-22 10:52:44 +01:00
parent 70f975e4f0
commit e1c5764fbf
2 changed files with 144 additions and 250 deletions

View File

@ -18,7 +18,7 @@
/** /**
* options: * options:
* - addButton : boolean|string - text for add label, default 'add' * - addButton : boolean|string - text for add label, default 'add'
* - buttons : array - list of custom buttons (objects with fields 'label', 'icon', 'title', 'click') * - buttons : array - list of custom buttons (objects with fields 'id', 'label', 'icon', 'title', 'click')
* - height : number|'auto' * - height : number|'auto'
* - resize : function - called when list as a whole is resized * - resize : function - called when list as a whole is resized
* - resizeItem : function(item) - called to resize individual item * - resizeItem : function(item) - called to resize individual item
@ -103,6 +103,9 @@
} }
}); });
if (button.id) {
element.attr("id", button.id);
}
if (button.title) { if (button.title) {
element.attr("title", button.title); element.attr("title", button.title);
} }

View File

@ -149,7 +149,20 @@
<script type="text/javascript"> <script type="text/javascript">
(function() { (function() {
/** Retrieve editableList items (refactored for re-use in the custom inject)*/
function resizeDialog(size) {
size = size || { height: $(".red-ui-tray-content form").height() }
var rows = $("#dialog-form>div:not(.node-input-property-container-row):visible");
var height = size.height;
for (var i=0; i<rows.length; i++) {
height -= $(rows[i]).outerHeight(true);
}
var editorRow = $("#dialog-form>div.node-input-property-container-row");
height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom")));
height += 16;
$("#node-input-property-container").editableList('height',height);
}
/** Retrieve editableList items (refactored for re-use in the form inject button)*/
function getProps(el, legacy) { function getProps(el, legacy) {
var result = { var result = {
props: [] props: []
@ -178,86 +191,33 @@
}); });
return result; return result;
} }
/** Build the editableList items (refactored for re-use in the custom inject)*/ /** Perform inject, optionally sending a custom msg (refactored for re-use in the form inject button)*/
function buildEditableList(el, props, legacyProps) { function doInject(node, customMsg) {
legacyProps = legacyProps || {}; var label = node._def.label.call(node);
var list = $(el); if (label.length > 30) {
list.editableList({ label = label.substring(0, 50) + "...";
addItem: function(container,i,opt) { }
var prop = opt; label = label.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
if (!prop.hasOwnProperty('p')) { $.ajax({
prop = {p:"",v:"",vt:"str"}; url: "inject/" + node.id,
} type: "POST",
container.css({ data: customMsg,
overflow: 'hidden', success: function (resp) {
whiteSpace: 'nowrap' RED.notify(node._("inject.success", { label: label }), { type: "success", id: "inject", timeout: 2000 });
});
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, error: function (jqXHR, textStatus, errorThrown) {
sortable: true if (jqXHR.status == 404) {
}); RED.notify(node._("common.notification.error", { message: node._("common.notification.errors.not-deployed") }), "error");
if (!props) { } else if (jqXHR.status == 500) {
var payload = { RED.notify(node._("common.notification.error", { message: node._("inject.errors.failed") }), "error");
p:'payload', } else if (jqXHR.status == 0) {
v: legacyProps.payload ? legacyProps.payload : '', RED.notify(node._("common.notification.error", { message: node._("common.notification.errors.no-response") }), "error");
vt:legacyProps.payloadType ? legacyProps.payloadType : 'date' } else {
}; RED.notify(node._("common.notification.error", { message: node._("common.notification.errors.unexpected", { status: jqXHR.status, message: textStatus }) }), "error");
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) {
size = size || { height: $(".red-ui-tray-content form").height() }
var rows = $("#dialog-form>div:not(.node-input-property-container-row):visible");
var height = size.height;
for (var i=0; i<rows.length; i++) {
height -= $(rows[i]).outerHeight(true);
}
var editorRow = $("#dialog-form>div.node-input-property-container-row");
height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom")));
height += 16;
$("#node-input-property-container").editableList('height',height);
}
RED.nodes.registerType('inject',{   RED.nodes.registerType('inject',{  
category: 'common', category: 'common',
color:"#a6bbcf", color:"#a6bbcf",
@ -378,14 +338,15 @@
return this.name?"node_label_italic":""; return this.name?"node_label_italic":"";
}, },
oneditprepare: function() { oneditprepare: function() {
if (this.payloadType == null) { var node = this;
if (this.payload == "") { if (node.payloadType == null) {
this.payloadType = "date"; if (node.payload == "") {
node.payloadType = "date";
} else { } else {
this.payloadType = "str"; node.payloadType = "str";
} }
} else if (this.payloadType === 'string' || this.payloadType === 'none') { } else if (node.payloadType === 'string' || node.payloadType === 'none') {
this.payloadType = "str"; node.payloadType = "str";
} }
$("#inject-time-type-select").on("change", function() { $("#inject-time-type-select").on("change", function() {
@ -440,17 +401,17 @@
}); });
var repeattype = "none"; var repeattype = "none";
if (this.repeat != "" && this.repeat != 0) { if (node.repeat != "" && node.repeat != 0) {
repeattype = "interval"; repeattype = "interval";
var r = "s"; var r = "s";
var c = this.repeat; var c = node.repeat;
if (this.repeat % 60 === 0) { r = "m"; c = c/60; } if (node.repeat % 60 === 0) { r = "m"; c = c/60; }
if (this.repeat % 1440 === 0) { r = "h"; c = c/60; } if (node.repeat % 1440 === 0) { r = "h"; c = c/60; }
$("#inject-time-interval-count").val(c); $("#inject-time-interval-count").val(c);
$("#inject-time-interval-units").val(r); $("#inject-time-interval-units").val(r);
$("#inject-time-interval-days").prop("disabled","disabled"); $("#inject-time-interval-days").prop("disabled","disabled");
} else if (this.crontab) { } else if (node.crontab) {
var cronparts = this.crontab.split(" "); var cronparts = node.crontab.split(" ");
var days = cronparts[4]; var days = cronparts[4];
if (!isNaN(cronparts[0]) && !isNaN(cronparts[1])) { if (!isNaN(cronparts[0]) && !isNaN(cronparts[1])) {
repeattype = "time"; repeattype = "time";
@ -525,21 +486,93 @@
$("#inject-time-row-"+repeattype).show(); $("#inject-time-row-"+repeattype).show();
/* */ /* */
var list = $('#node-input-property-container');
list.css('min-height','120px').css('min-width','450px'); var eList = $('#node-input-property-container').css('min-height','120px').css('min-width','450px');
var legacyOptions = { eList.editableList({
topic: this.topic, buttons: [
payload: this.payload, {
payloadType: this.payloadType, id: "node-inject-test-inject-button",
label: node._("inject.inject"),
icon: "fa fa-bolt",
click: function(e) {
var items = eList.editableList('items');
var result = getProps(items);
var m = {__user_inject_props__: []};
if (result && result.props && result.props.length) {
m.__user_inject_props__ = result.props;
}
doInject(node, m);
}
}
],
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
});
$('#node-inject-test-inject-button').addClass('primary').css("float", "right").css("margin-right", "unset");
if (!node.props) {
var payload = {
p:'payload',
v: node.payload ? node.payload : '',
vt:node.payloadType ? node.payloadType : 'date'
};
var topic = {
p:'topic',
v: node.topic ? node.topic : '',
vt:'string'
}
node.props = [payload,topic];
}
for (var i=0; i<node.props.length; i++) {
var prop = node.props[i];
var newProp = { p: prop.p, v: prop.v, vt: prop.vt };
if (newProp.v === undefined) {
if (prop.p === 'payload') {
newProp.v = node.payload ? node.payload : '';
newProp.vt = node.payloadType ? node.payloadType : 'date';
} else if (prop.p === 'topic' && prop.vt === "str") {
newProp.v = node.topic ? node.topic : '';
}
}
eList.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();
@ -630,168 +663,26 @@
$("#node-input-repeat").val(repeat); $("#node-input-repeat").val(repeat);
$("#node-input-crontab").val(crontab); $("#node-input-crontab").val(crontab);
/* Gather the injected properties of the msg object */ /* Gather the properties */
var items = $("#node-input-property-container").editableList('items'); var items = $("#node-input-property-container").editableList('items');
delete node.payloadType; delete this.payloadType;
delete node.payload; delete this.payload;
node.topic = ""; this.topic = "";
var result = getProps(items, true); var result = getProps(items, true);
node.props = result.props; this.props = result.props;
if(result.payloadType) { node.payloadType = result.payloadType; }; if(result.payloadType) { this.payloadType = result.payloadType; };
if(result.payload) { node.payload = result.payload; }; if(result.payload) { this.payload = result.payload; };
if(result.topic) { node.topic = result.topic; }; if(result.topic) { this.topic = result.topic; };
}, },
button: { button: {
enabled: function() { enabled: function() {
return !this.changed return !this.changed
}, },
onclick: function () { onclick: function () {
var node = this; if (this.changed) {
if (node.changed) {
return RED.notify(RED._("notification.warning", { message: RED._("notification.warnings.undeployedChanges") }), "warning"); return RED.notify(RED._("notification.warning", { message: RED._("notification.warnings.undeployedChanges") }), "warning");
} }
doInject(this);
var doInject = function (customMsg) {
var label = node._def.label.call(node);
if (label.length > 30) {
label = label.substring(0, 50) + "...";
}
label = label.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
$.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");
}
}
});
}
if (window.event.ctrlKey) {
var wasDirty = node.dirty;
// var wasDirty = RED.nodes.dirty();
var originalProps = {
props: node.props,
payloadType: node.payloadType,
payload: node.payload,
topic: node.topic
};
var originalPropsJSON = JSON.stringify(originalProps);
var trayOptions = {
title: node.name || (node._def.label && node._def.label.call(node)) || node._('inject.inject'),
width: 'inherit',
buttons: [
{
id: 'node-dialog-apply',
text: node._('inject.userValueButtons.apply'),
click: function () {
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-cancel',
class: 'primary',
text: node._('inject.userValueButtons.close'),
click: function () {
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 dialog = $('<div id="dialog-form" class="form-horizontal"></div>');
var row1 = $('<div class="form-row" style="text-align: right;"></div>');
var button = $('<button class="ui-button ui-corner-all ui-widget" id="node-inject-inject"></button>');
button.text(node._('inject.userValueButtons.inject'));
row1.append(button);
var row2 = $('<div class="form-row"></div>');
var list = $('<ol id="node-inject-custom-list"></ol>');
list.css('min-height', '120px').css('min-width', '400px');
row2.append(list);
dialog.append(row1);
dialog.append(row2);
trayBody.append(dialog);
button.on("click", function() {
var items = $('#node-inject-custom-list').editableList('items');
var result = getProps(items);
if (result && result.props && result.props.length) {
m = { __user_inject_props__: result.props };
}
doInject(m);
});
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) {
$('#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