mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Initial refactor of edit dialogs to separate panes
This commit is contained in:
parent
39aafc5007
commit
e910f3915d
@ -162,7 +162,6 @@ module.exports = function(grunt) {
|
|||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/common/stack.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/common/stack.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/common/toggleButton.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/common/toggleButton.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/common/colorPicker.js",
|
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/actions.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/actions.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/deploy.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/deploy.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/diff.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/diff.js",
|
||||||
@ -182,6 +181,7 @@ module.exports = function(grunt) {
|
|||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/tab-context.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/tab-context.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/editor.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/editor.js",
|
||||||
|
"packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/*.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/editors/*.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/editors/*.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/*.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/*.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/js/ui/event-log.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/event-log.js",
|
||||||
|
@ -592,18 +592,17 @@ RED.nodes = (function() {
|
|||||||
inputLabels: function(i) { return sf.inputLabels?sf.inputLabels[i]:null },
|
inputLabels: function(i) { return sf.inputLabels?sf.inputLabels[i]:null },
|
||||||
outputLabels: function(i) { return sf.outputLabels?sf.outputLabels[i]:null },
|
outputLabels: function(i) { return sf.outputLabels?sf.outputLabels[i]:null },
|
||||||
oneditprepare: function() {
|
oneditprepare: function() {
|
||||||
RED.subflow.buildEditForm("subflow",this);
|
if (this.type !== 'subflow') {
|
||||||
RED.subflow.buildPropertiesForm(this);
|
// Whilst this definition is used for both template and instance
|
||||||
|
// nodes, the work to build the edit form for the template nodes
|
||||||
|
// is handled elsewhere.
|
||||||
|
RED.subflow.buildEditForm("subflow",this);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
oneditresize: function(size) {
|
oneditresize: function(size) {
|
||||||
// var rows = $(".dialog-form>div:not(.node-input-env-container-row)");
|
if (this.type === 'subflow') {
|
||||||
var height = size.height;
|
$("#node-input-env-container").editableList('height',size.height - 80);
|
||||||
// for (var i=0; i<rows.size(); i++) {
|
}
|
||||||
// height -= $(rows[i]).outerHeight(true);
|
|
||||||
// }
|
|
||||||
// var editorRow = $("#dialog-form>div.node-input-env-container-row");
|
|
||||||
// height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom")));
|
|
||||||
$("ol.red-ui-editor-subflow-env-list").editableList('height',height);
|
|
||||||
},
|
},
|
||||||
set:{
|
set:{
|
||||||
module: "node-red"
|
module: "node-red"
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
|||||||
RED.colorPicker = (function() {
|
RED.editor.colorPicker = RED.colorPicker = (function() {
|
||||||
|
|
||||||
function create(options) {
|
function create(options) {
|
||||||
var color = options.value;
|
var color = options.value;
|
99
packages/node_modules/@node-red/editor-client/src/js/ui/editors/iconPicker.js
vendored
Normal file
99
packages/node_modules/@node-red/editor-client/src/js/ui/editors/iconPicker.js
vendored
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
RED.editor.iconPicker = (function() {
|
||||||
|
function showIconPicker(container, backgroundColor, iconPath, faOnly, done) {
|
||||||
|
var picker = $('<div class="red-ui-icon-picker">');
|
||||||
|
var searchDiv = $("<div>",{class:"red-ui-search-container"}).appendTo(picker);
|
||||||
|
searchInput = $('<input type="text">').attr("placeholder",RED._("editor.searchIcons")).appendTo(searchDiv).searchBox({
|
||||||
|
delay: 50,
|
||||||
|
change: function() {
|
||||||
|
var searchTerm = $(this).val().trim();
|
||||||
|
if (searchTerm === "") {
|
||||||
|
iconList.find(".red-ui-icon-list-module").show();
|
||||||
|
iconList.find(".red-ui-icon-list-icon").show();
|
||||||
|
} else {
|
||||||
|
iconList.find(".red-ui-icon-list-module").hide();
|
||||||
|
iconList.find(".red-ui-icon-list-icon").each(function(i,n) {
|
||||||
|
if ($(n).data('icon').indexOf(searchTerm) === -1) {
|
||||||
|
$(n).hide();
|
||||||
|
} else {
|
||||||
|
$(n).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var row = $('<div>').appendTo(picker);
|
||||||
|
var iconList = $('<div class="red-ui-icon-list">').appendTo(picker);
|
||||||
|
var metaRow = $('<div class="red-ui-icon-meta"></div>').appendTo(picker);
|
||||||
|
var summary = $('<span>').appendTo(metaRow);
|
||||||
|
var resetButton = $('<button type="button" class="red-ui-button red-ui-button-small">'+RED._("editor.useDefault")+'</button>').appendTo(metaRow).on("click", function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
iconPanel.hide();
|
||||||
|
done(null);
|
||||||
|
});
|
||||||
|
if (!backgroundColor && faOnly) {
|
||||||
|
iconList.addClass("red-ui-icon-list-dark");
|
||||||
|
}
|
||||||
|
setTimeout(function() {
|
||||||
|
var iconSets = RED.nodes.getIconSets();
|
||||||
|
Object.keys(iconSets).forEach(function(moduleName) {
|
||||||
|
if (faOnly && (moduleName !== "font-awesome")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var icons = iconSets[moduleName];
|
||||||
|
if (icons.length > 0) {
|
||||||
|
// selectIconModule.append($("<option></option>").val(moduleName).text(moduleName));
|
||||||
|
var header = $('<div class="red-ui-icon-list-module"></div>').text(moduleName).appendTo(iconList);
|
||||||
|
$('<i class="fa fa-cube"></i>').prependTo(header);
|
||||||
|
icons.forEach(function(icon) {
|
||||||
|
var iconDiv = $('<div>',{class:"red-ui-icon-list-icon"}).appendTo(iconList);
|
||||||
|
var nodeDiv = $('<div>',{class:"red-ui-search-result-node"}).appendTo(iconDiv);
|
||||||
|
var icon_url = RED.settings.apiRootUrl+"icons/"+moduleName+"/"+icon;
|
||||||
|
iconDiv.data('icon',icon_url);
|
||||||
|
if (backgroundColor) {
|
||||||
|
nodeDiv.css({
|
||||||
|
'backgroundColor': backgroundColor
|
||||||
|
});
|
||||||
|
var borderColor = RED.utils.getDarkerColor(backgroundColor);
|
||||||
|
if (borderColor !== backgroundColor) {
|
||||||
|
nodeDiv.css('border-color',borderColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
var iconContainer = $('<div/>',{class:"red-ui-palette-icon-container"}).appendTo(nodeDiv);
|
||||||
|
RED.utils.createIconElement(icon_url, iconContainer, true);
|
||||||
|
|
||||||
|
if (iconPath.module === moduleName && iconPath.file === icon) {
|
||||||
|
iconDiv.addClass("selected");
|
||||||
|
}
|
||||||
|
iconDiv.on("mouseover", function() {
|
||||||
|
summary.text(icon);
|
||||||
|
})
|
||||||
|
iconDiv.on("mouseout", function() {
|
||||||
|
summary.html(" ");
|
||||||
|
})
|
||||||
|
iconDiv.on("click", function() {
|
||||||
|
iconPanel.hide();
|
||||||
|
done(moduleName+"/"+icon);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setTimeout(function() {
|
||||||
|
spinner.remove();
|
||||||
|
},50);
|
||||||
|
},300);
|
||||||
|
var spinner = RED.utils.addSpinnerOverlay(iconList,true);
|
||||||
|
var iconPanel = RED.popover.panel(picker);
|
||||||
|
iconPanel.show({
|
||||||
|
target: container
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
picker.slideDown(100);
|
||||||
|
searchInput.trigger("focus");
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
show: showIconPicker
|
||||||
|
}
|
||||||
|
})();
|
515
packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/appearance.js
vendored
Normal file
515
packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/appearance.js
vendored
Normal file
@ -0,0 +1,515 @@
|
|||||||
|
;(function() {
|
||||||
|
|
||||||
|
RED.editor.registerEditorPane("editor-tab-appearance", function() {
|
||||||
|
return {
|
||||||
|
label: RED._("editor-tab.appearance"),
|
||||||
|
name: RED._("editor-tab.appearance"),
|
||||||
|
iconClass: "fa fa-object-group",
|
||||||
|
create: function(container, node) {
|
||||||
|
this.content = $('<div>', {class:"red-ui-tray-content"}).appendTo(container);
|
||||||
|
buildAppearanceForm(this.content,node);
|
||||||
|
|
||||||
|
if (node.type === 'subflow') {
|
||||||
|
this.defaultIcon = "node-red/subflow.svg";
|
||||||
|
} else {
|
||||||
|
var iconPath = RED.utils.getDefaultNodeIcon(node._def,node);
|
||||||
|
this.defaultIcon = iconPath.module+"/"+iconPath.file;
|
||||||
|
if (node.icon && node.icon !== this.defaultIcon) {
|
||||||
|
this.isDefaultIcon = false;
|
||||||
|
} else {
|
||||||
|
this.isDefaultIcon = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.content;
|
||||||
|
},
|
||||||
|
resize: function(node, size) {
|
||||||
|
|
||||||
|
},
|
||||||
|
close: function(node) {
|
||||||
|
|
||||||
|
},
|
||||||
|
show: function(node) {
|
||||||
|
refreshLabelForm(this.content, node);
|
||||||
|
},
|
||||||
|
apply: function(node, editState) {
|
||||||
|
if (updateLabels(node, editState.changes, editState.outputMap)) {
|
||||||
|
editState.changed = true;
|
||||||
|
}
|
||||||
|
if (!node._def.defaults || !node._def.defaults.hasOwnProperty("icon")) {
|
||||||
|
var icon = $("#red-ui-editor-node-icon").val()||""
|
||||||
|
if (!this.isDefaultIcon) {
|
||||||
|
if (icon !== node.icon) {
|
||||||
|
editState.changes.icon = node.icon;
|
||||||
|
node.icon = icon;
|
||||||
|
editState.changed = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (icon !== "" && icon !== this.defaultIcon) {
|
||||||
|
editState.changes.icon = node.icon;
|
||||||
|
node.icon = icon;
|
||||||
|
editState.changed = true;
|
||||||
|
} else {
|
||||||
|
var iconPath = RED.utils.getDefaultNodeIcon(node._def, node);
|
||||||
|
var currentDefaultIcon = iconPath.module+"/"+iconPath.file;
|
||||||
|
if (this.defaultIcon !== currentDefaultIcon) {
|
||||||
|
editState.changes.icon = node.icon;
|
||||||
|
node.icon = currentDefaultIcon;
|
||||||
|
editState.changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (node.type === "subflow") {
|
||||||
|
var newCategory = $("#subflow-appearance-input-category").val().trim();
|
||||||
|
if (newCategory === "_custom_") {
|
||||||
|
newCategory = $("#subflow-appearance-input-custom-category").val().trim();
|
||||||
|
if (newCategory === "") {
|
||||||
|
newCategory = node.category;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (newCategory === 'subflows') {
|
||||||
|
newCategory = '';
|
||||||
|
}
|
||||||
|
if (newCategory != node.category) {
|
||||||
|
editState.changes['category'] = node.category;
|
||||||
|
node.category = newCategory;
|
||||||
|
editState.changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var oldColor = node.color;
|
||||||
|
var newColor = $("#red-ui-editor-node-color").val();
|
||||||
|
if (oldColor !== newColor) {
|
||||||
|
editState.changes.color = node.color;
|
||||||
|
node.color = newColor;
|
||||||
|
editState.changed = true;
|
||||||
|
RED.utils.clearNodeColorCache();
|
||||||
|
if (node.type === "subflow") {
|
||||||
|
var nodeDefinition = RED.nodes.getType(
|
||||||
|
"subflow:" + node.id
|
||||||
|
);
|
||||||
|
nodeDefinition["color"] = newColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
if (!$("#node-input-show-label").prop('checked')) {
|
||||||
|
// Not checked - hide label
|
||||||
|
if (!/^link (in|out)$/.test(node.type)) {
|
||||||
|
// Not a link node - default state is true
|
||||||
|
if (node.l !== false) {
|
||||||
|
editState.changes.l = node.l
|
||||||
|
editState.changed = true;
|
||||||
|
}
|
||||||
|
node.l = false;
|
||||||
|
} else {
|
||||||
|
// A link node - default state is false
|
||||||
|
if (node.hasOwnProperty('l') && node.l) {
|
||||||
|
editState.changes.l = node.l
|
||||||
|
editState.changed = true;
|
||||||
|
}
|
||||||
|
delete node.l;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Checked - show label
|
||||||
|
if (!/^link (in|out)$/.test(node.type)) {
|
||||||
|
// Not a link node - default state is true
|
||||||
|
if (node.hasOwnProperty('l') && !node.l) {
|
||||||
|
editState.changes.l = node.l
|
||||||
|
editState.changed = true;
|
||||||
|
}
|
||||||
|
delete node.l;
|
||||||
|
} else {
|
||||||
|
if (!node.l) {
|
||||||
|
editState.changes.l = node.l
|
||||||
|
editState.changed = true;
|
||||||
|
}
|
||||||
|
node.l = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function buildAppearanceForm(container,node) {
|
||||||
|
var dialogForm = $('<form class="dialog-form form-horizontal" autocomplete="off"></form>').appendTo(container);
|
||||||
|
|
||||||
|
var i,row;
|
||||||
|
|
||||||
|
if (node.type === "subflow") {
|
||||||
|
var categoryRow = $("<div/>", {
|
||||||
|
class: "form-row"
|
||||||
|
}).appendTo(dialogForm);
|
||||||
|
$("<label/>", {
|
||||||
|
for: "subflow-appearance-input-category",
|
||||||
|
"data-i18n": "editor:subflow.category"
|
||||||
|
}).appendTo(categoryRow);
|
||||||
|
var categorySelector = $("<select/>", {
|
||||||
|
id: "subflow-appearance-input-category"
|
||||||
|
}).css({
|
||||||
|
width: "250px"
|
||||||
|
}).appendTo(categoryRow);
|
||||||
|
$("<input/>", {
|
||||||
|
type: "text",
|
||||||
|
id: "subflow-appearance-input-custom-category"
|
||||||
|
}).css({
|
||||||
|
display: "none",
|
||||||
|
"margin-left": "10px",
|
||||||
|
width: "calc(100% - 250px)"
|
||||||
|
}).appendTo(categoryRow);
|
||||||
|
|
||||||
|
var categories = RED.palette.getCategories();
|
||||||
|
categories.sort(function(A,B) {
|
||||||
|
return A.label.localeCompare(B.label);
|
||||||
|
})
|
||||||
|
categories.forEach(function(cat) {
|
||||||
|
categorySelector.append($("<option/>").val(cat.id).text(cat.label));
|
||||||
|
})
|
||||||
|
categorySelector.append($("<option/>").attr('disabled',true).text("---"));
|
||||||
|
categorySelector.append($("<option/>").val("_custom_").text(RED._("palette.addCategory")));
|
||||||
|
|
||||||
|
$("#subflow-appearance-input-category").on("change", function() {
|
||||||
|
var val = $(this).val();
|
||||||
|
if (val === "_custom_") {
|
||||||
|
$("#subflow-appearance-input-category").width(120);
|
||||||
|
$("#subflow-appearance-input-custom-category").show();
|
||||||
|
} else {
|
||||||
|
$("#subflow-appearance-input-category").width(250);
|
||||||
|
$("#subflow-appearance-input-custom-category").hide();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
$("#subflow-appearance-input-category").val(node.category||"subflows");
|
||||||
|
var userCount = 0;
|
||||||
|
var subflowType = "subflow:"+node.id;
|
||||||
|
|
||||||
|
// RED.nodes.eachNode(function(n) {
|
||||||
|
// if (n.type === subflowType) {
|
||||||
|
// userCount++;
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
$("#red-ui-editor-subflow-user-count")
|
||||||
|
.text(RED._("subflow.subflowInstances", {count:node.instances.length})).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
$('<div class="form-row">'+
|
||||||
|
'<label for="node-input-show-label-btn" data-i18n="editor.label"></label>'+
|
||||||
|
'<span style="margin-right: 2px;"/>'+
|
||||||
|
'<input type="checkbox" id="node-input-show-label"/>'+
|
||||||
|
'</div>').appendTo(dialogForm);
|
||||||
|
|
||||||
|
$("#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);
|
||||||
|
}
|
||||||
|
$("#node-input-show-label").prop("checked",node.l).trigger("change");
|
||||||
|
|
||||||
|
if (node.type === "subflow") {
|
||||||
|
// subflow template can select its color
|
||||||
|
var color = node.color ? node.color : "#DDAA99";
|
||||||
|
var colorRow = $("<div/>", {
|
||||||
|
class: "form-row"
|
||||||
|
}).appendTo(dialogForm);
|
||||||
|
$("<label/>").text(RED._("editor.color")).appendTo(colorRow);
|
||||||
|
|
||||||
|
var recommendedColors = [
|
||||||
|
"#DDAA99",
|
||||||
|
"#3FADB5", "#87A980", "#A6BBCF",
|
||||||
|
"#AAAA66", "#C0C0C0", "#C0DEED",
|
||||||
|
"#C7E9C0", "#D7D7A0", "#D8BFD8",
|
||||||
|
"#DAC4B4", "#DEB887", "#DEBD5C",
|
||||||
|
"#E2D96E", "#E6E0F8", "#E7E7AE",
|
||||||
|
"#E9967A", "#F3B567", "#FDD0A2",
|
||||||
|
"#FDF0C2", "#FFAAAA", "#FFCC66",
|
||||||
|
"#FFF0F0", "#FFFFFF"
|
||||||
|
]
|
||||||
|
|
||||||
|
RED.editor.colorPicker.create({
|
||||||
|
id: "red-ui-editor-node-color",
|
||||||
|
value: color,
|
||||||
|
palette: recommendedColors,
|
||||||
|
sortPalette: function (a, b) {return a.l - b.l;}
|
||||||
|
}).appendTo(colorRow);
|
||||||
|
|
||||||
|
$("#red-ui-editor-node-color").on('change', function(ev) {
|
||||||
|
// Horribly out of scope...
|
||||||
|
var colour = $(this).val();
|
||||||
|
nodeDiv.css('backgroundColor',colour);
|
||||||
|
var borderColor = RED.utils.getDarkerColor(colour);
|
||||||
|
if (borderColor !== colour) {
|
||||||
|
nodeDiv.css('border-color',borderColor)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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"))) {
|
||||||
|
var iconRow = $('<div class="form-row"></div>').appendTo(dialogForm);
|
||||||
|
$('<label data-i18n="editor.settingIcon">').appendTo(iconRow);
|
||||||
|
|
||||||
|
var iconButton = $('<button type="button" class="red-ui-button red-ui-editor-node-appearance-button">').appendTo(iconRow);
|
||||||
|
$('<i class="fa fa-caret-down"></i>').appendTo(iconButton);
|
||||||
|
var nodeDiv = $('<div>',{class:"red-ui-search-result-node"}).appendTo(iconButton);
|
||||||
|
var colour = RED.utils.getNodeColor(node.type, node._def);
|
||||||
|
var icon_url = RED.utils.getNodeIcon(node._def,node);
|
||||||
|
nodeDiv.css('backgroundColor',colour);
|
||||||
|
var borderColor = RED.utils.getDarkerColor(colour);
|
||||||
|
if (borderColor !== colour) {
|
||||||
|
nodeDiv.css('border-color',borderColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
var iconContainer = $('<div/>',{class:"red-ui-palette-icon-container"}).appendTo(nodeDiv);
|
||||||
|
RED.utils.createIconElement(icon_url, iconContainer, true);
|
||||||
|
|
||||||
|
iconButton.on("click", function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var iconPath;
|
||||||
|
var icon = $("#red-ui-editor-node-icon").val()||"";
|
||||||
|
if (icon) {
|
||||||
|
iconPath = RED.utils.separateIconPath(icon);
|
||||||
|
} else {
|
||||||
|
iconPath = RED.utils.getDefaultNodeIcon(node._def, node);
|
||||||
|
}
|
||||||
|
var backgroundColor = RED.utils.getNodeColor(node.type, node._def);
|
||||||
|
if (node.type === "subflow") {
|
||||||
|
backgroundColor = $("#red-ui-editor-node-color").val();
|
||||||
|
}
|
||||||
|
RED.editor.iconPicker.show(iconButton,backgroundColor,iconPath,false,function(newIcon) {
|
||||||
|
$("#red-ui-editor-node-icon").val(newIcon||"");
|
||||||
|
var icon_url = RED.utils.getNodeIcon(node._def,{type:node.type,icon:newIcon});
|
||||||
|
RED.utils.createIconElement(icon_url, iconContainer, true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
RED.popover.tooltip(iconButton, function() {
|
||||||
|
return $("#red-ui-editor-node-icon").val() || RED._("editor.default");
|
||||||
|
})
|
||||||
|
$('<input type="hidden" id="red-ui-editor-node-icon">').val(node.icon).appendTo(iconRow);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$('<div class="form-row"><span data-i18n="editor.portLabels"></span></div>').appendTo(dialogForm);
|
||||||
|
|
||||||
|
var inputCount = node.inputs || node._def.inputs || 0;
|
||||||
|
var outputCount = node.outputs || node._def.outputs || 0;
|
||||||
|
if (node.type === 'subflow') {
|
||||||
|
inputCount = node.in.length;
|
||||||
|
outputCount = node.out.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
var inputLabels = node.inputLabels || [];
|
||||||
|
var outputLabels = node.outputLabels || [];
|
||||||
|
|
||||||
|
var inputPlaceholder = node._def.inputLabels?RED._("editor.defaultLabel"):RED._("editor.noDefaultLabel");
|
||||||
|
var outputPlaceholder = node._def.outputLabels?RED._("editor.defaultLabel"):RED._("editor.noDefaultLabel");
|
||||||
|
|
||||||
|
$('<div class="form-row"><span style="margin-left: 50px;" data-i18n="editor.labelInputs"></span><div id="red-ui-editor-node-label-form-inputs"></div></div>').appendTo(dialogForm);
|
||||||
|
var inputsDiv = $("#red-ui-editor-node-label-form-inputs");
|
||||||
|
if (inputCount > 0) {
|
||||||
|
for (i=0;i<inputCount;i++) {
|
||||||
|
buildLabelRow("input",i,inputLabels[i],inputPlaceholder).appendTo(inputsDiv);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
buildLabelRow().appendTo(inputsDiv);
|
||||||
|
}
|
||||||
|
$('<div class="form-row"><span style="margin-left: 50px;" data-i18n="editor.labelOutputs"></span><div id="red-ui-editor-node-label-form-outputs"></div></div>').appendTo(dialogForm);
|
||||||
|
var outputsDiv = $("#red-ui-editor-node-label-form-outputs");
|
||||||
|
if (outputCount > 0) {
|
||||||
|
for (i=0;i<outputCount;i++) {
|
||||||
|
buildLabelRow("output",i,outputLabels[i],outputPlaceholder).appendTo(outputsDiv);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
buildLabelRow().appendTo(outputsDiv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function refreshLabelForm(container,node) {
|
||||||
|
|
||||||
|
var inputPlaceholder = node._def.inputLabels?RED._("editor.defaultLabel"):RED._("editor.noDefaultLabel");
|
||||||
|
var outputPlaceholder = node._def.outputLabels?RED._("editor.defaultLabel"):RED._("editor.noDefaultLabel");
|
||||||
|
|
||||||
|
var inputsDiv = $("#red-ui-editor-node-label-form-inputs");
|
||||||
|
var outputsDiv = $("#red-ui-editor-node-label-form-outputs");
|
||||||
|
|
||||||
|
var inputCount;
|
||||||
|
var formInputs = $("#node-input-inputs").val();
|
||||||
|
if (formInputs === undefined) {
|
||||||
|
if (node.type === 'subflow') {
|
||||||
|
inputCount = node.in.length;
|
||||||
|
} else {
|
||||||
|
inputCount = node.inputs || node._def.inputs || 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
inputCount = Math.min(1,Math.max(0,parseInt(formInputs)));
|
||||||
|
if (isNaN(inputCount)) {
|
||||||
|
inputCount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var children = inputsDiv.children();
|
||||||
|
var childCount = children.length;
|
||||||
|
if (childCount === 1 && $(children[0]).hasClass('red-ui-editor-node-label-form-none')) {
|
||||||
|
childCount--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (childCount < inputCount) {
|
||||||
|
if (childCount === 0) {
|
||||||
|
// remove the 'none' placeholder
|
||||||
|
$(children[0]).remove();
|
||||||
|
}
|
||||||
|
for (i = childCount;i<inputCount;i++) {
|
||||||
|
buildLabelRow("input",i,"",inputPlaceholder).appendTo(inputsDiv);
|
||||||
|
}
|
||||||
|
} else if (childCount > inputCount) {
|
||||||
|
for (i=inputCount;i<childCount;i++) {
|
||||||
|
$(children[i]).remove();
|
||||||
|
}
|
||||||
|
if (inputCount === 0) {
|
||||||
|
buildLabelRow().appendTo(inputsDiv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var outputCount;
|
||||||
|
var i;
|
||||||
|
var formOutputs = $("#node-input-outputs").val();
|
||||||
|
|
||||||
|
if (formOutputs === undefined) {
|
||||||
|
if (node.type === 'subflow') {
|
||||||
|
outputCount = node.out.length;
|
||||||
|
} else {
|
||||||
|
inputCount = node.outputs || node._def.outputs || 0;
|
||||||
|
}
|
||||||
|
} else if (isNaN(formOutputs)) {
|
||||||
|
var outputMap = JSON.parse(formOutputs);
|
||||||
|
var keys = Object.keys(outputMap);
|
||||||
|
children = outputsDiv.children();
|
||||||
|
childCount = children.length;
|
||||||
|
if (childCount === 1 && $(children[0]).hasClass('red-ui-editor-node-label-form-none')) {
|
||||||
|
childCount--;
|
||||||
|
}
|
||||||
|
|
||||||
|
outputCount = 0;
|
||||||
|
var rows = [];
|
||||||
|
keys.forEach(function(p) {
|
||||||
|
var row = $("#red-ui-editor-node-label-form-output-"+p).parent();
|
||||||
|
if (row.length === 0 && outputMap[p] !== -1) {
|
||||||
|
if (childCount === 0) {
|
||||||
|
$(children[0]).remove();
|
||||||
|
childCount = -1;
|
||||||
|
}
|
||||||
|
row = buildLabelRow("output",p,"",outputPlaceholder);
|
||||||
|
} else {
|
||||||
|
row.detach();
|
||||||
|
}
|
||||||
|
if (outputMap[p] !== -1) {
|
||||||
|
outputCount++;
|
||||||
|
rows.push({i:parseInt(outputMap[p]),r:row});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
rows.sort(function(A,B) {
|
||||||
|
return A.i-B.i;
|
||||||
|
})
|
||||||
|
rows.forEach(function(r,i) {
|
||||||
|
r.r.find("label").text((i+1)+".");
|
||||||
|
r.r.appendTo(outputsDiv);
|
||||||
|
})
|
||||||
|
if (rows.length === 0) {
|
||||||
|
buildLabelRow("output",i,"").appendTo(outputsDiv);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
outputCount = Math.max(0,parseInt(formOutputs));
|
||||||
|
}
|
||||||
|
children = outputsDiv.children();
|
||||||
|
childCount = children.length;
|
||||||
|
if (childCount === 1 && $(children[0]).hasClass('red-ui-editor-node-label-form-none')) {
|
||||||
|
childCount--;
|
||||||
|
}
|
||||||
|
if (childCount < outputCount) {
|
||||||
|
if (childCount === 0) {
|
||||||
|
// remove the 'none' placeholder
|
||||||
|
$(children[0]).remove();
|
||||||
|
}
|
||||||
|
for (i = childCount;i<outputCount;i++) {
|
||||||
|
buildLabelRow("output",i,"").appendTo(outputsDiv);
|
||||||
|
}
|
||||||
|
} else if (childCount > outputCount) {
|
||||||
|
for (i=outputCount;i<childCount;i++) {
|
||||||
|
$(children[i]).remove();
|
||||||
|
}
|
||||||
|
if (outputCount === 0) {
|
||||||
|
buildLabelRow().appendTo(outputsDiv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildLabelRow(type, index, value, placeHolder) {
|
||||||
|
var result = $('<div>',{class:"red-ui-editor-node-label-form-row"});
|
||||||
|
if (type === undefined) {
|
||||||
|
$('<span>').text(RED._("editor.noDefaultLabel")).appendTo(result);
|
||||||
|
result.addClass("red-ui-editor-node-label-form-none");
|
||||||
|
} else {
|
||||||
|
result.addClass("");
|
||||||
|
var id = "red-ui-editor-node-label-form-"+type+"-"+index;
|
||||||
|
$('<label>',{for:id}).text((index+1)+".").appendTo(result);
|
||||||
|
var input = $('<input>',{type:"text",id:id, placeholder: placeHolder}).val(value).appendTo(result);
|
||||||
|
var clear = $('<button type="button" class="red-ui-button red-ui-button-small"><i class="fa fa-times"></i></button>').appendTo(result);
|
||||||
|
clear.on("click", function(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
input.val("");
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateLabels(node, changes, outputMap) {
|
||||||
|
var inputLabels = $("#red-ui-editor-node-label-form-inputs").children().find("input");
|
||||||
|
var outputLabels = $("#red-ui-editor-node-label-form-outputs").children().find("input");
|
||||||
|
|
||||||
|
var hasNonBlankLabel = false;
|
||||||
|
var changed = false;
|
||||||
|
var newValue = inputLabels.map(function() {
|
||||||
|
var v = $(this).val();
|
||||||
|
hasNonBlankLabel = hasNonBlankLabel || v!== "";
|
||||||
|
return v;
|
||||||
|
}).toArray().slice(0,node.inputs);
|
||||||
|
if ((node.inputLabels === undefined && hasNonBlankLabel) ||
|
||||||
|
(node.inputLabels !== undefined && JSON.stringify(newValue) !== JSON.stringify(node.inputLabels))) {
|
||||||
|
changes.inputLabels = node.inputLabels;
|
||||||
|
node.inputLabels = newValue;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
hasNonBlankLabel = false;
|
||||||
|
newValue = new Array(node.outputs);
|
||||||
|
outputLabels.each(function() {
|
||||||
|
var index = $(this).attr('id').substring("red-ui-editor-node-label-form-output-".length);
|
||||||
|
if (outputMap && outputMap.hasOwnProperty(index)) {
|
||||||
|
index = parseInt(outputMap[index]);
|
||||||
|
if (index === -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var v = $(this).val();
|
||||||
|
hasNonBlankLabel = hasNonBlankLabel || v!== "";
|
||||||
|
newValue[index] = v;
|
||||||
|
});
|
||||||
|
|
||||||
|
if ((node.outputLabels === undefined && hasNonBlankLabel) ||
|
||||||
|
(node.outputLabels !== undefined && JSON.stringify(newValue) !== JSON.stringify(node.outputLabels))) {
|
||||||
|
changes.outputLabels = node.outputLabels;
|
||||||
|
node.outputLabels = newValue;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
})();
|
71
packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/description.js
vendored
Normal file
71
packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/description.js
vendored
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
;(function() {
|
||||||
|
|
||||||
|
RED.editor.registerEditorPane("editor-tab-description", function() {
|
||||||
|
return {
|
||||||
|
label: RED._("editor-tab.description"),
|
||||||
|
name: RED._("editor-tab.description"),
|
||||||
|
iconClass: "fa fa-file-text-o",
|
||||||
|
|
||||||
|
create: function(container, node) {
|
||||||
|
var content = $('<div>', {class:"red-ui-tray-content"}).appendTo(container);
|
||||||
|
this.editor = buildDescriptionForm(content,node);
|
||||||
|
return content;
|
||||||
|
},
|
||||||
|
resize: function(node, size) {
|
||||||
|
this.editor.resize();
|
||||||
|
},
|
||||||
|
close: function(node) {
|
||||||
|
this.editor.destroy();
|
||||||
|
this.editor = null;
|
||||||
|
},
|
||||||
|
show: function() {
|
||||||
|
this.editor.focus();
|
||||||
|
},
|
||||||
|
apply: function(node, editState) {
|
||||||
|
var oldInfo = node.info;
|
||||||
|
var newInfo = this.editor.getValue();
|
||||||
|
if (!!oldInfo) {
|
||||||
|
// Has existing info property
|
||||||
|
if (newInfo.trim() === "") {
|
||||||
|
// New value is blank - remove the property
|
||||||
|
editState.changed = true;
|
||||||
|
editState.changes.info = oldInfo;
|
||||||
|
delete node.info;
|
||||||
|
} else if (newInfo !== oldInfo) {
|
||||||
|
// New value is different
|
||||||
|
editState.changed = true;
|
||||||
|
editState.changes.info = oldInfo;
|
||||||
|
node.info = newInfo;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// No existing info
|
||||||
|
if (newInfo.trim() !== "") {
|
||||||
|
// New value is not blank
|
||||||
|
editState.changed = true;
|
||||||
|
editState.changes.info = undefined;
|
||||||
|
node.info = newInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function buildDescriptionForm(container,node) {
|
||||||
|
var dialogForm = $('<form class="dialog-form form-horizontal" autocomplete="off"></form>').appendTo(container);
|
||||||
|
var toolbarRow = $('<div></div>').appendTo(dialogForm);
|
||||||
|
var row = $('<div class="form-row node-text-editor-row" style="position:relative; padding-top: 4px; height: 100%"></div>').appendTo(dialogForm);
|
||||||
|
var editorId = "node-info-input-info-editor-"+Math.floor(1000*Math.random());
|
||||||
|
$('<div style="height: 100%" class="node-text-editor" id="'+editorId+'" ></div>').appendTo(row);
|
||||||
|
var nodeInfoEditor = RED.editor.createEditor({
|
||||||
|
id: editorId,
|
||||||
|
mode: 'ace/mode/markdown',
|
||||||
|
value: ""
|
||||||
|
});
|
||||||
|
if (node.info) {
|
||||||
|
nodeInfoEditor.getSession().setValue(node.info, -1);
|
||||||
|
}
|
||||||
|
node.infoEditor = nodeInfoEditor;
|
||||||
|
return nodeInfoEditor;
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
190
packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/properties.js
vendored
Normal file
190
packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/properties.js
vendored
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
;(function() {
|
||||||
|
|
||||||
|
RED.editor.registerEditorPane("editor-tab-properties", function() {
|
||||||
|
return {
|
||||||
|
label: RED._("editor-tab.properties"),
|
||||||
|
name: RED._("editor-tab.properties"),
|
||||||
|
iconClass: "fa fa-cog",
|
||||||
|
create: function(container, node) {
|
||||||
|
var content = $('<div>', {class:"red-ui-tray-content"}).appendTo(container);
|
||||||
|
|
||||||
|
var nodeType = node.type;
|
||||||
|
if (node.type === "subflow") {
|
||||||
|
nodeType = "subflow-template";
|
||||||
|
} else if (node.type.substring(0,8) == "subflow:") {
|
||||||
|
nodeType = "subflow";
|
||||||
|
}
|
||||||
|
|
||||||
|
var i18nNamespace;
|
||||||
|
if (node._def.set.module === "node-red") {
|
||||||
|
i18nNamespace = "node-red";
|
||||||
|
} else {
|
||||||
|
i18nNamespace = node._def.set.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
var formStyle = "dialog-form";
|
||||||
|
this.inputClass = "node-input";
|
||||||
|
if (node._def.category === "config" && nodeType !== "group") {
|
||||||
|
this.inputClass = "node-config-input";
|
||||||
|
formStyle = "node-config-dialog-edit-form";
|
||||||
|
}
|
||||||
|
RED.editor.buildEditForm(content,formStyle,nodeType,i18nNamespace,node);
|
||||||
|
|
||||||
|
if (nodeType === "subflow-template") {
|
||||||
|
// This is the 'edit properties' dialog for a subflow template
|
||||||
|
// TODO: this needs to happen later in the dialog open sequence
|
||||||
|
// so that credentials can be loaded prior to building the form
|
||||||
|
RED.subflow.buildEditForm("subflow-template", node);
|
||||||
|
}
|
||||||
|
|
||||||
|
return content;
|
||||||
|
},
|
||||||
|
resize: function(node, size) {
|
||||||
|
if (node && node._def.oneditresize) {
|
||||||
|
try {
|
||||||
|
node._def.oneditresize.call(node,size);
|
||||||
|
} catch(err) {
|
||||||
|
console.log("oneditresize",node.id,node.type,err.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
close: function(node) {
|
||||||
|
|
||||||
|
},
|
||||||
|
apply: function(editing_node, editState) {
|
||||||
|
var newValue;
|
||||||
|
if (editing_node._def.defaults) {
|
||||||
|
for (d in editing_node._def.defaults) {
|
||||||
|
if (editing_node._def.defaults.hasOwnProperty(d)) {
|
||||||
|
var input = $("#"+this.inputClass+"-"+d);
|
||||||
|
if (input.attr('type') === "checkbox") {
|
||||||
|
newValue = input.prop('checked');
|
||||||
|
} else if (input.prop("nodeName") === "select" && input.attr("multiple") === "multiple") {
|
||||||
|
// An empty select-multiple box returns null.
|
||||||
|
// Need to treat that as an empty array.
|
||||||
|
newValue = input.val();
|
||||||
|
if (newValue == null) {
|
||||||
|
newValue = [];
|
||||||
|
}
|
||||||
|
} else if ("format" in editing_node._def.defaults[d] && editing_node._def.defaults[d].format !== "" && input[0].nodeName === "DIV") {
|
||||||
|
newValue = input.text();
|
||||||
|
} else {
|
||||||
|
newValue = input.val();
|
||||||
|
}
|
||||||
|
if (newValue != null) {
|
||||||
|
if (d === "outputs") {
|
||||||
|
if (newValue.trim() === "") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (isNaN(newValue)) {
|
||||||
|
editState.outputMap = JSON.parse(newValue);
|
||||||
|
var outputCount = 0;
|
||||||
|
var outputsChanged = false;
|
||||||
|
var keys = Object.keys(editState.outputMap);
|
||||||
|
keys.forEach(function(p) {
|
||||||
|
if (isNaN(p)) {
|
||||||
|
// New output;
|
||||||
|
outputCount ++;
|
||||||
|
delete editState.outputMap[p];
|
||||||
|
} else {
|
||||||
|
editState.outputMap[p] = editState.outputMap[p]+"";
|
||||||
|
if (editState.outputMap[p] !== "-1") {
|
||||||
|
outputCount++;
|
||||||
|
if (editState.outputMap[p] !== p) {
|
||||||
|
// Output moved
|
||||||
|
outputsChanged = true;
|
||||||
|
} else {
|
||||||
|
delete editState.outputMap[p];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Output removed
|
||||||
|
outputsChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
newValue = outputCount;
|
||||||
|
if (outputsChanged) {
|
||||||
|
editState.changed = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
newValue = parseInt(newValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (editing_node._def.defaults[d].type) {
|
||||||
|
if (newValue == "_ADD_") {
|
||||||
|
newValue = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (editing_node[d] != newValue) {
|
||||||
|
if (editing_node._def.defaults[d].type) {
|
||||||
|
// Change to a related config node
|
||||||
|
var configNode = RED.nodes.node(editing_node[d]);
|
||||||
|
if (configNode) {
|
||||||
|
var users = configNode.users;
|
||||||
|
users.splice(users.indexOf(editing_node),1);
|
||||||
|
RED.events.emit("nodes:change",configNode);
|
||||||
|
}
|
||||||
|
configNode = RED.nodes.node(newValue);
|
||||||
|
if (configNode) {
|
||||||
|
configNode.users.push(editing_node);
|
||||||
|
RED.events.emit("nodes:change",configNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
editState.changes[d] = editing_node[d];
|
||||||
|
editing_node[d] = newValue;
|
||||||
|
editState.changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (editing_node._def.credentials) {
|
||||||
|
var credDefinition = editing_node._def.credentials;
|
||||||
|
var credsChanged = updateNodeCredentials(editing_node,credDefinition,this.inputClass);
|
||||||
|
editState.changed = editState.changed || credsChanged;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the node credentials from the edit form
|
||||||
|
* @param node - the node containing the credentials
|
||||||
|
* @param credDefinition - definition of the credentials
|
||||||
|
* @param prefix - prefix of the input fields
|
||||||
|
* @return {boolean} whether anything has changed
|
||||||
|
*/
|
||||||
|
function updateNodeCredentials(node, credDefinition, prefix) {
|
||||||
|
var changed = false;
|
||||||
|
if (!node.credentials) {
|
||||||
|
node.credentials = {_:{}};
|
||||||
|
} else if (!node.credentials._) {
|
||||||
|
node.credentials._ = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var cred in credDefinition) {
|
||||||
|
if (credDefinition.hasOwnProperty(cred)) {
|
||||||
|
var input = $("#" + prefix + '-' + cred);
|
||||||
|
if (input.length > 0) {
|
||||||
|
var value = input.val();
|
||||||
|
if (credDefinition[cred].type == 'password') {
|
||||||
|
node.credentials['has_' + cred] = (value !== "");
|
||||||
|
if (value == '__PWRD__') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
changed = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
node.credentials[cred] = value;
|
||||||
|
if (value != node.credentials._[cred]) {
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
})();
|
181
packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/subflowModule.js
vendored
Normal file
181
packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/subflowModule.js
vendored
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
(function() {
|
||||||
|
var _subflowModulePaneTemplate = '<form class="dialog-form form-horizontal" autocomplete="off">'+
|
||||||
|
'<div class="form-row">'+
|
||||||
|
'<label for="subflow-input-module-module" data-i18n="[append]editor:subflow.module"><i class="fa fa-cube"></i> </label>'+
|
||||||
|
'<input style="width: calc(100% - 110px)" type="text" id="subflow-input-module-module" data-i18n="[placeholder]common.label.name">'+
|
||||||
|
'</div>'+
|
||||||
|
'<div class="form-row">'+
|
||||||
|
'<label for="subflow-input-module-type" data-i18n="[append]editor:subflow.type"> </label>'+
|
||||||
|
'<input style="width: calc(100% - 110px)" type="text" id="subflow-input-module-type">'+
|
||||||
|
'</div>'+
|
||||||
|
'<div class="form-row">'+
|
||||||
|
'<label for="subflow-input-module-version" data-i18n="[append]editor:subflow.version"></label>'+
|
||||||
|
'<input style="width: calc(100% - 110px)" type="text" id="subflow-input-module-version" data-i18n="[placeholder]editor:subflow.versionPlaceholder">'+
|
||||||
|
'</div>'+
|
||||||
|
'<div class="form-row">'+
|
||||||
|
'<label for="subflow-input-module-desc" data-i18n="[append]editor:subflow.desc"></label>'+
|
||||||
|
'<input style="width: calc(100% - 110px)" type="text" id="subflow-input-module-desc">'+
|
||||||
|
'</div>'+
|
||||||
|
'<div class="form-row">'+
|
||||||
|
'<label for="subflow-input-module-license" data-i18n="[append]editor:subflow.license"></label>'+
|
||||||
|
'<input style="width: calc(100% - 110px)" type="text" id="subflow-input-module-license">'+
|
||||||
|
'</div>'+
|
||||||
|
'<div class="form-row">'+
|
||||||
|
'<label for="subflow-input-module-author" data-i18n="[append]editor:subflow.author"></label>'+
|
||||||
|
'<input style="width: calc(100% - 110px)" type="text" id="subflow-input-module-author" data-i18n="[placeholder]editor:subflow.authorPlaceholder">'+
|
||||||
|
'</div>'+
|
||||||
|
'<div class="form-row">'+
|
||||||
|
'<label for="subflow-input-module-keywords" data-i18n="[append]editor:subflow.keys"></label>'+
|
||||||
|
'<input style="width: calc(100% - 110px)" type="text" id="subflow-input-module-keywords" data-i18n="[placeholder]editor:subflow.keysPlaceholder">'+
|
||||||
|
'</div>'+
|
||||||
|
'</form>';
|
||||||
|
|
||||||
|
RED.editor.registerEditorPane("editor-tab-subflow-module", function() {
|
||||||
|
return {
|
||||||
|
label: RED._("editor-tab.module"),
|
||||||
|
name: RED._("editor-tab.module"),
|
||||||
|
iconClass: "fa fa-cube",
|
||||||
|
create: function(container, node) {
|
||||||
|
var content = $('<div>', {class:"red-ui-tray-content"}).appendTo(container);
|
||||||
|
buildModuleForm(content, node);
|
||||||
|
return content;
|
||||||
|
},
|
||||||
|
resize: function(node, size) {
|
||||||
|
},
|
||||||
|
close: function(node) {
|
||||||
|
|
||||||
|
},
|
||||||
|
apply: function(node, editState) {
|
||||||
|
var newMeta = exportSubflowModuleProperties(node);
|
||||||
|
if (!isSameObj(node.meta,newMeta)) {
|
||||||
|
editState.changes.meta = node.meta;
|
||||||
|
node.meta = newMeta;
|
||||||
|
editState.changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function isSameObj(env0, env1) {
|
||||||
|
return (JSON.stringify(env0) === JSON.stringify(env1));
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupInputValidation(input,validator) {
|
||||||
|
var errorTip;
|
||||||
|
var validateTimeout;
|
||||||
|
|
||||||
|
var validateFunction = function() {
|
||||||
|
if (validateTimeout) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
validateTimeout = setTimeout(function() {
|
||||||
|
var error = validator(input.val());
|
||||||
|
// if (!error && errorTip) {
|
||||||
|
// errorTip.close();
|
||||||
|
// errorTip = null;
|
||||||
|
// } else if (error && !errorTip) {
|
||||||
|
// errorTip = RED.popover.create({
|
||||||
|
// tooltip: true,
|
||||||
|
// target:input,
|
||||||
|
// size: "small",
|
||||||
|
// direction: "bottom",
|
||||||
|
// content: error,
|
||||||
|
// }).open();
|
||||||
|
// }
|
||||||
|
input.toggleClass("input-error",!!error);
|
||||||
|
validateTimeout = null;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
input.on("change keyup paste", validateFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildModuleForm(container, node) {
|
||||||
|
$(_subflowModulePaneTemplate).appendTo(container);
|
||||||
|
var moduleProps = node.meta || {};
|
||||||
|
[
|
||||||
|
'module',
|
||||||
|
'type',
|
||||||
|
'version',
|
||||||
|
'author',
|
||||||
|
'desc',
|
||||||
|
'keywords',
|
||||||
|
'license'
|
||||||
|
].forEach(function(property) {
|
||||||
|
$("#subflow-input-module-"+property).val(moduleProps[property]||"")
|
||||||
|
})
|
||||||
|
$("#subflow-input-module-type").attr("placeholder",node.id);
|
||||||
|
|
||||||
|
setupInputValidation($("#subflow-input-module-module"), function(newValue) {
|
||||||
|
newValue = newValue.trim();
|
||||||
|
var isValid = newValue.length < 215;
|
||||||
|
isValid = isValid && !/^[._]/.test(newValue);
|
||||||
|
isValid = isValid && !/[A-Z]/.test(newValue);
|
||||||
|
if (newValue !== encodeURIComponent(newValue)) {
|
||||||
|
var m = /^@([^\/]+)\/([^\/]+)$/.exec(newValue);
|
||||||
|
if (m) {
|
||||||
|
isValid = isValid && (m[1] === encodeURIComponent(m[1]) && m[2] === encodeURIComponent(m[2]))
|
||||||
|
} else {
|
||||||
|
isValid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return isValid?"":"Invalid module name"
|
||||||
|
})
|
||||||
|
setupInputValidation($("#subflow-input-module-version"), function(newValue) {
|
||||||
|
newValue = newValue.trim();
|
||||||
|
var isValid = newValue === "" ||
|
||||||
|
/^(\d|[1-9]\d*)\.(\d|[1-9]\d*)\.(\d|[1-9]\d*)(-(0|[1-9A-Za-z-][0-9A-Za-z-]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*)(\.(0|[1-9A-Za-z-][0-9A-Za-z-]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*))*)?(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$/.test(newValue);
|
||||||
|
return isValid?"":"Invalid version number"
|
||||||
|
})
|
||||||
|
|
||||||
|
var licenses = ["none", "Apache-2.0", "BSD-3-Clause", "BSD-2-Clause", "GPL-2.0", "GPL-3.0", "MIT", "MPL-2.0", "CDDL-1.0", "EPL-2.0"];
|
||||||
|
var typedLicenses = {
|
||||||
|
types: licenses.map(function(l) {
|
||||||
|
return {
|
||||||
|
value: l,
|
||||||
|
label: l === "none" ? RED._("editor:subflow.licenseNone") : l,
|
||||||
|
hasValue: false
|
||||||
|
};
|
||||||
|
})
|
||||||
|
}
|
||||||
|
typedLicenses.types.push({
|
||||||
|
value:"_custom_", label:RED._("editor:subflow.licenseOther"), icon:"red/images/typedInput/az.svg"
|
||||||
|
})
|
||||||
|
if (!moduleProps.license) {
|
||||||
|
typedLicenses.default = "none";
|
||||||
|
} else if (licenses.indexOf(moduleProps.license) > -1) {
|
||||||
|
typedLicenses.default = moduleProps.license;
|
||||||
|
} else {
|
||||||
|
typedLicenses.default = "_custom_";
|
||||||
|
}
|
||||||
|
$("#subflow-input-module-license").typedInput(typedLicenses)
|
||||||
|
}
|
||||||
|
function exportSubflowModuleProperties(node) {
|
||||||
|
var value;
|
||||||
|
var moduleProps = {};
|
||||||
|
[
|
||||||
|
'module',
|
||||||
|
'type',
|
||||||
|
'version',
|
||||||
|
'author',
|
||||||
|
'desc',
|
||||||
|
'keywords'
|
||||||
|
].forEach(function(property) {
|
||||||
|
value = $("#subflow-input-module-"+property).val().trim();
|
||||||
|
if (value) {
|
||||||
|
moduleProps[property] = value;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
var selectedLicenseType = $("#subflow-input-module-license").typedInput("type");
|
||||||
|
|
||||||
|
if (selectedLicenseType === '_custom_') {
|
||||||
|
value = $("#subflow-input-module-license").val();
|
||||||
|
if (value) {
|
||||||
|
moduleProps.license = value;
|
||||||
|
}
|
||||||
|
} else if (selectedLicenseType !== "none") {
|
||||||
|
moduleProps.license = selectedLicenseType;
|
||||||
|
}
|
||||||
|
return moduleProps;
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
68
packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/subflowProperties.js
vendored
Normal file
68
packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/subflowProperties.js
vendored
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
;(function() {
|
||||||
|
|
||||||
|
RED.editor.registerEditorPane("editor-tab-envProperties", function() {
|
||||||
|
return {
|
||||||
|
label: RED._("editor-tab.envProperties"),
|
||||||
|
name: RED._("editor-tab.envProperties"),
|
||||||
|
iconClass: "fa fa-list",
|
||||||
|
create: function(container, node) {
|
||||||
|
var content = $('<div>', {class:"red-ui-tray-content"}).appendTo(container);
|
||||||
|
var form = $('<form class="dialog-form form-horizontal"></form>').appendTo(content);
|
||||||
|
var listContainer = $('<div class="form-row node-input-env-container-row"></div>').appendTo(form);
|
||||||
|
this.list = $('<ol></ol>').appendTo(listContainer);
|
||||||
|
RED.subflow.buildPropertiesList(this.list, node);
|
||||||
|
return content;
|
||||||
|
},
|
||||||
|
resize: function(node, size) {
|
||||||
|
this.list.editableList('height',size.height);
|
||||||
|
},
|
||||||
|
close: function(node) {
|
||||||
|
|
||||||
|
},
|
||||||
|
apply: function(node, editState) {
|
||||||
|
var old_env = node.env;
|
||||||
|
var new_env = RED.subflow.exportSubflowInstanceEnv(node);
|
||||||
|
|
||||||
|
// Get the values from the Properties table tab
|
||||||
|
var items = this.list.editableList('items');
|
||||||
|
items.each(function (i,el) {
|
||||||
|
var data = el.data('data');
|
||||||
|
var item;
|
||||||
|
if (data.nameField && data.valueField) {
|
||||||
|
item = {
|
||||||
|
name: data.nameField.val(),
|
||||||
|
value: data.valueField.typedInput("value"),
|
||||||
|
type: data.valueField.typedInput("type")
|
||||||
|
}
|
||||||
|
if (item.name.trim() !== "") {
|
||||||
|
new_env.push(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
if (new_env && new_env.length > 0) {
|
||||||
|
new_env.forEach(function(prop) {
|
||||||
|
if (prop.type === "cred") {
|
||||||
|
node.credentials = node.credentials || {_:{}};
|
||||||
|
node.credentials[prop.name] = prop.value;
|
||||||
|
node.credentials['has_'+prop.name] = (prop.value !== "");
|
||||||
|
if (prop.value !== '__PWRD__') {
|
||||||
|
editState.changed = true;
|
||||||
|
}
|
||||||
|
delete prop.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (!isSameObj(old_env, new_env)) {
|
||||||
|
node.env = new_env;
|
||||||
|
editState.changes.env = node.env;
|
||||||
|
editState.changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
function isSameObj(env0, env1) {
|
||||||
|
return (JSON.stringify(env0) === JSON.stringify(env1));
|
||||||
|
}
|
||||||
|
})();
|
@ -100,7 +100,7 @@ RED.group = (function() {
|
|||||||
RED.subflow.buildPropertiesForm(this);
|
RED.subflow.buildPropertiesForm(this);
|
||||||
|
|
||||||
var style = this.style || {};
|
var style = this.style || {};
|
||||||
RED.colorPicker.create({
|
RED.editor.colorPicker.create({
|
||||||
id:"node-input-style-stroke",
|
id:"node-input-style-stroke",
|
||||||
value: style.stroke || defaultGroupStyle.stroke || "#a4a4a4",
|
value: style.stroke || defaultGroupStyle.stroke || "#a4a4a4",
|
||||||
palette: colorPalette,
|
palette: colorPalette,
|
||||||
@ -111,7 +111,7 @@ RED.group = (function() {
|
|||||||
none: true,
|
none: true,
|
||||||
opacity: style.hasOwnProperty('stroke-opacity')?style['stroke-opacity']:(defaultGroupStyle.hasOwnProperty('stroke-opacity')?defaultGroupStyle['stroke-opacity']:1.0)
|
opacity: style.hasOwnProperty('stroke-opacity')?style['stroke-opacity']:(defaultGroupStyle.hasOwnProperty('stroke-opacity')?defaultGroupStyle['stroke-opacity']:1.0)
|
||||||
}).appendTo("#node-input-row-style-stroke");
|
}).appendTo("#node-input-row-style-stroke");
|
||||||
RED.colorPicker.create({
|
RED.editor.colorPicker.create({
|
||||||
id:"node-input-style-fill",
|
id:"node-input-style-fill",
|
||||||
value: style.fill || defaultGroupStyle.fill ||"none",
|
value: style.fill || defaultGroupStyle.fill ||"none",
|
||||||
palette: colorPalette,
|
palette: colorPalette,
|
||||||
@ -128,7 +128,7 @@ RED.group = (function() {
|
|||||||
value:style["label-position"] || "nw"
|
value:style["label-position"] || "nw"
|
||||||
}).appendTo("#node-input-row-style-label-position");
|
}).appendTo("#node-input-row-style-label-position");
|
||||||
|
|
||||||
RED.colorPicker.create({
|
RED.editor.colorPicker.create({
|
||||||
id:"node-input-style-color",
|
id:"node-input-style-color",
|
||||||
value: style.color || defaultGroupStyle.color ||"#a4a4a4",
|
value: style.color || defaultGroupStyle.color ||"#a4a4a4",
|
||||||
palette: colorPalette,
|
palette: colorPalette,
|
||||||
|
@ -536,7 +536,7 @@ RED.library = (function() {
|
|||||||
// evt.preventDefault();
|
// evt.preventDefault();
|
||||||
// var icon = libraryFields['icon'].input.val() || "";
|
// var icon = libraryFields['icon'].input.val() || "";
|
||||||
// var iconPath = (icon ? RED.utils.separateIconPath(icon) : {});
|
// var iconPath = (icon ? RED.utils.separateIconPath(icon) : {});
|
||||||
// RED.editor.showIconPicker(iconButton, null, iconPath, true, function (newIcon) {
|
// RED.editor.iconPicker.show(iconButton, null, iconPath, true, function (newIcon) {
|
||||||
// iconButton.empty();
|
// iconButton.empty();
|
||||||
// var path = newIcon || "";
|
// var path = newIcon || "";
|
||||||
// var newPath = RED.utils.separateIconPath(path);
|
// var newPath = RED.utils.separateIconPath(path);
|
||||||
|
@ -37,7 +37,7 @@ RED.subflow = (function() {
|
|||||||
'<div id="subflow-env-tabs-content">'+
|
'<div id="subflow-env-tabs-content">'+
|
||||||
'<div id="subflow-env-tab-edit">'+
|
'<div id="subflow-env-tab-edit">'+
|
||||||
'<div class="form-row node-input-env-container-row" id="subflow-input-edit-ui">'+
|
'<div class="form-row node-input-env-container-row" id="subflow-input-edit-ui">'+
|
||||||
'<ol class="red-ui-editor-subflow-env-list" id="node-input-env-container"></ol>'+
|
'<ol id="node-input-env-container"></ol>'+
|
||||||
'<div class="node-input-env-locales-row"><i class="fa fa-language"></i> <select id="subflow-input-env-locale"></select></div>'+
|
'<div class="node-input-env-locales-row"><i class="fa fa-language"></i> <select id="subflow-input-env-locale"></select></div>'+
|
||||||
'</div>'+
|
'</div>'+
|
||||||
'</div>'+
|
'</div>'+
|
||||||
@ -47,37 +47,6 @@ RED.subflow = (function() {
|
|||||||
'</div>'+
|
'</div>'+
|
||||||
'</script>';
|
'</script>';
|
||||||
|
|
||||||
var _subflowModulePaneTemplate = '<form class="dialog-form form-horizontal" autocomplete="off">'+
|
|
||||||
'<div class="form-row">'+
|
|
||||||
'<label for="subflow-input-module-module" data-i18n="[append]editor:subflow.module"><i class="fa fa-cube"></i> </label>'+
|
|
||||||
'<input style="width: calc(100% - 110px)" type="text" id="subflow-input-module-module" data-i18n="[placeholder]common.label.name">'+
|
|
||||||
'</div>'+
|
|
||||||
'<div class="form-row">'+
|
|
||||||
'<label for="subflow-input-module-type" data-i18n="[append]editor:subflow.type"> </label>'+
|
|
||||||
'<input style="width: calc(100% - 110px)" type="text" id="subflow-input-module-type">'+
|
|
||||||
'</div>'+
|
|
||||||
'<div class="form-row">'+
|
|
||||||
'<label for="subflow-input-module-version" data-i18n="[append]editor:subflow.version"></label>'+
|
|
||||||
'<input style="width: calc(100% - 110px)" type="text" id="subflow-input-module-version" data-i18n="[placeholder]editor:subflow.versionPlaceholder">'+
|
|
||||||
'</div>'+
|
|
||||||
'<div class="form-row">'+
|
|
||||||
'<label for="subflow-input-module-desc" data-i18n="[append]editor:subflow.desc"></label>'+
|
|
||||||
'<input style="width: calc(100% - 110px)" type="text" id="subflow-input-module-desc">'+
|
|
||||||
'</div>'+
|
|
||||||
'<div class="form-row">'+
|
|
||||||
'<label for="subflow-input-module-license" data-i18n="[append]editor:subflow.license"></label>'+
|
|
||||||
'<input style="width: calc(100% - 110px)" type="text" id="subflow-input-module-license">'+
|
|
||||||
'</div>'+
|
|
||||||
'<div class="form-row">'+
|
|
||||||
'<label for="subflow-input-module-author" data-i18n="[append]editor:subflow.author"></label>'+
|
|
||||||
'<input style="width: calc(100% - 110px)" type="text" id="subflow-input-module-author" data-i18n="[placeholder]editor:subflow.authorPlaceholder">'+
|
|
||||||
'</div>'+
|
|
||||||
'<div class="form-row">'+
|
|
||||||
'<label for="subflow-input-module-keywords" data-i18n="[append]editor:subflow.keys"></label>'+
|
|
||||||
'<input style="width: calc(100% - 110px)" type="text" id="subflow-input-module-keywords" data-i18n="[placeholder]editor:subflow.keysPlaceholder">'+
|
|
||||||
'</div>'+
|
|
||||||
'</form>';
|
|
||||||
|
|
||||||
function findAvailableSubflowIOPosition(subflow,isInput) {
|
function findAvailableSubflowIOPosition(subflow,isInput) {
|
||||||
var pos = {x:50,y:30};
|
var pos = {x:50,y:30};
|
||||||
if (!isInput) {
|
if (!isInput) {
|
||||||
@ -909,7 +878,6 @@ RED.subflow = (function() {
|
|||||||
* Create interface for controlling env var UI definition
|
* Create interface for controlling env var UI definition
|
||||||
*/
|
*/
|
||||||
function buildEnvControl(envList,node) {
|
function buildEnvControl(envList,node) {
|
||||||
|
|
||||||
var tabs = RED.tabs.create({
|
var tabs = RED.tabs.create({
|
||||||
id: "subflow-env-tabs",
|
id: "subflow-env-tabs",
|
||||||
onchange: function(tab) {
|
onchange: function(tab) {
|
||||||
@ -1174,7 +1142,7 @@ RED.subflow = (function() {
|
|||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
var icon = ui.icon || "";
|
var icon = ui.icon || "";
|
||||||
var iconPath = (icon ? RED.utils.separateIconPath(icon) : {});
|
var iconPath = (icon ? RED.utils.separateIconPath(icon) : {});
|
||||||
RED.editor.showIconPicker(iconButton, null, iconPath, true, function (newIcon) {
|
RED.editor.iconPicker.show(iconButton, null, iconPath, true, function (newIcon) {
|
||||||
iconButton.empty();
|
iconButton.empty();
|
||||||
var path = newIcon || "";
|
var path = newIcon || "";
|
||||||
var newPath = RED.utils.separateIconPath(path);
|
var newPath = RED.utils.separateIconPath(path);
|
||||||
@ -1898,25 +1866,11 @@ RED.subflow = (function() {
|
|||||||
env.push(item);
|
env.push(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
if (ui.type === "cred" || item.type !== data.parent.type || item.value !== data.parent.value) {
|
||||||
}
|
|
||||||
// Second, get the values from the Properties table tab
|
|
||||||
var kind = isGroup ? "group" : (isTab ? "tab" : "subflow");
|
|
||||||
var items = $("#red-ui-editor-"+kind+"-env-list").editableList('items');
|
|
||||||
items.each(function (i,el) {
|
|
||||||
var data = el.data('data');
|
|
||||||
var item;
|
|
||||||
if (data.nameField && data.valueField) {
|
|
||||||
item = {
|
|
||||||
name: data.nameField.val(),
|
|
||||||
value: data.valueField.typedInput("value"),
|
|
||||||
type: data.valueField.typedInput("type")
|
|
||||||
}
|
|
||||||
if (item.name.trim() !== "") {
|
|
||||||
env.push(item);
|
env.push(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1948,6 +1902,8 @@ RED.subflow = (function() {
|
|||||||
|
|
||||||
function buildEditForm(type,node) {
|
function buildEditForm(type,node) {
|
||||||
if (type === "subflow-template") {
|
if (type === "subflow-template") {
|
||||||
|
// This is called by the `properties` edit pane when
|
||||||
|
// editing a subflow template.
|
||||||
buildPropertiesList($('#node-input-env-container'), node);
|
buildPropertiesList($('#node-input-env-container'), node);
|
||||||
} else if (type === "subflow") {
|
} else if (type === "subflow") {
|
||||||
// This gets called by the subflow type `oneditprepare` function
|
// This gets called by the subflow type `oneditprepare` function
|
||||||
@ -1956,135 +1912,6 @@ RED.subflow = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildPropertiesForm(node) {
|
|
||||||
var kind = (node.type === "group") ? "group" : ((node.type === "tab") ? "tab": "subflow");
|
|
||||||
var container = $("#editor-"+kind+"-envProperties-content");
|
|
||||||
var form = $('<form class="dialog-form form-horizontal"></form>').appendTo(container);
|
|
||||||
var listContainer = $('<div class="form-row node-input-env-container-row"></div>').appendTo(form);
|
|
||||||
var list = $('<ol id="red-ui-editor-'+kind+'-env-list" class="red-ui-editor-subflow-env-list"></ol>').appendTo(listContainer);
|
|
||||||
buildPropertiesList(list, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupInputValidation(input,validator) {
|
|
||||||
var errorTip;
|
|
||||||
var validateTimeout;
|
|
||||||
|
|
||||||
var validateFunction = function() {
|
|
||||||
if (validateTimeout) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
validateTimeout = setTimeout(function() {
|
|
||||||
var error = validator(input.val());
|
|
||||||
// if (!error && errorTip) {
|
|
||||||
// errorTip.close();
|
|
||||||
// errorTip = null;
|
|
||||||
// } else if (error && !errorTip) {
|
|
||||||
// errorTip = RED.popover.create({
|
|
||||||
// tooltip: true,
|
|
||||||
// target:input,
|
|
||||||
// size: "small",
|
|
||||||
// direction: "bottom",
|
|
||||||
// content: error,
|
|
||||||
// }).open();
|
|
||||||
// }
|
|
||||||
input.toggleClass("input-error",!!error);
|
|
||||||
validateTimeout = null;
|
|
||||||
})
|
|
||||||
}
|
|
||||||
input.on("change keyup paste", validateFunction);
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildModuleForm(container, node) {
|
|
||||||
$(_subflowModulePaneTemplate).appendTo(container);
|
|
||||||
var moduleProps = node.meta || {};
|
|
||||||
[
|
|
||||||
'module',
|
|
||||||
'type',
|
|
||||||
'version',
|
|
||||||
'author',
|
|
||||||
'desc',
|
|
||||||
'keywords',
|
|
||||||
'license'
|
|
||||||
].forEach(function(property) {
|
|
||||||
$("#subflow-input-module-"+property).val(moduleProps[property]||"")
|
|
||||||
})
|
|
||||||
$("#subflow-input-module-type").attr("placeholder",node.id);
|
|
||||||
|
|
||||||
setupInputValidation($("#subflow-input-module-module"), function(newValue) {
|
|
||||||
newValue = newValue.trim();
|
|
||||||
var isValid = newValue.length < 215;
|
|
||||||
isValid = isValid && !/^[._]/.test(newValue);
|
|
||||||
isValid = isValid && !/[A-Z]/.test(newValue);
|
|
||||||
if (newValue !== encodeURIComponent(newValue)) {
|
|
||||||
var m = /^@([^\/]+)\/([^\/]+)$/.exec(newValue);
|
|
||||||
if (m) {
|
|
||||||
isValid = isValid && (m[1] === encodeURIComponent(m[1]) && m[2] === encodeURIComponent(m[2]))
|
|
||||||
} else {
|
|
||||||
isValid = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return isValid?"":"Invalid module name"
|
|
||||||
})
|
|
||||||
setupInputValidation($("#subflow-input-module-version"), function(newValue) {
|
|
||||||
newValue = newValue.trim();
|
|
||||||
var isValid = newValue === "" ||
|
|
||||||
/^(\d|[1-9]\d*)\.(\d|[1-9]\d*)\.(\d|[1-9]\d*)(-(0|[1-9A-Za-z-][0-9A-Za-z-]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*)(\.(0|[1-9A-Za-z-][0-9A-Za-z-]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*))*)?(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$/.test(newValue);
|
|
||||||
return isValid?"":"Invalid version number"
|
|
||||||
})
|
|
||||||
|
|
||||||
var licenses = ["none", "Apache-2.0", "BSD-3-Clause", "BSD-2-Clause", "GPL-2.0", "GPL-3.0", "MIT", "MPL-2.0", "CDDL-1.0", "EPL-2.0"];
|
|
||||||
var typedLicenses = {
|
|
||||||
types: licenses.map(function(l) {
|
|
||||||
return {
|
|
||||||
value: l,
|
|
||||||
label: l === "none" ? RED._("editor:subflow.licenseNone") : l,
|
|
||||||
hasValue: false
|
|
||||||
};
|
|
||||||
})
|
|
||||||
}
|
|
||||||
typedLicenses.types.push({
|
|
||||||
value:"_custom_", label:RED._("editor:subflow.licenseOther"), icon:"red/images/typedInput/az.svg"
|
|
||||||
})
|
|
||||||
if (!moduleProps.license) {
|
|
||||||
typedLicenses.default = "none";
|
|
||||||
} else if (licenses.indexOf(moduleProps.license) > -1) {
|
|
||||||
typedLicenses.default = moduleProps.license;
|
|
||||||
} else {
|
|
||||||
typedLicenses.default = "_custom_";
|
|
||||||
}
|
|
||||||
$("#subflow-input-module-license").typedInput(typedLicenses)
|
|
||||||
}
|
|
||||||
|
|
||||||
function exportSubflowModuleProperties(node) {
|
|
||||||
var value;
|
|
||||||
var moduleProps = {};
|
|
||||||
[
|
|
||||||
'module',
|
|
||||||
'type',
|
|
||||||
'version',
|
|
||||||
'author',
|
|
||||||
'desc',
|
|
||||||
'keywords'
|
|
||||||
].forEach(function(property) {
|
|
||||||
value = $("#subflow-input-module-"+property).val().trim();
|
|
||||||
if (value) {
|
|
||||||
moduleProps[property] = value;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
var selectedLicenseType = $("#subflow-input-module-license").typedInput("type");
|
|
||||||
|
|
||||||
if (selectedLicenseType === '_custom_') {
|
|
||||||
value = $("#subflow-input-module-license").val();
|
|
||||||
if (value) {
|
|
||||||
moduleProps.license = value;
|
|
||||||
}
|
|
||||||
} else if (selectedLicenseType !== "none") {
|
|
||||||
moduleProps.license = selectedLicenseType;
|
|
||||||
}
|
|
||||||
return moduleProps;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
init: init,
|
init: init,
|
||||||
createSubflow: createSubflow,
|
createSubflow: createSubflow,
|
||||||
@ -2095,14 +1922,10 @@ RED.subflow = (function() {
|
|||||||
removeOutput: removeSubflowOutput,
|
removeOutput: removeSubflowOutput,
|
||||||
removeStatus: removeSubflowStatus,
|
removeStatus: removeSubflowStatus,
|
||||||
|
|
||||||
|
|
||||||
buildEditForm: buildEditForm,
|
buildEditForm: buildEditForm,
|
||||||
buildPropertiesForm: buildPropertiesForm,
|
buildPropertiesList: buildPropertiesList,
|
||||||
buildModuleForm: buildModuleForm,
|
|
||||||
|
|
||||||
exportSubflowTemplateEnv: exportEnvList,
|
exportSubflowTemplateEnv: exportEnvList,
|
||||||
exportSubflowInstanceEnv: exportSubflowInstanceEnv,
|
exportSubflowInstanceEnv: exportSubflowInstanceEnv,
|
||||||
exportSubflowModuleProperties: exportSubflowModuleProperties
|
|
||||||
|
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user