mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Add subflow meta data edit pane
This commit is contained in:
parent
814fc8bc69
commit
de15a1c36f
@ -339,6 +339,16 @@
|
||||
"deleteSubflow": "delete subflow",
|
||||
"info": "Description",
|
||||
"category": "Category",
|
||||
"module": "Module",
|
||||
"license": "License",
|
||||
"licenseOther": "Other",
|
||||
"version": "Version",
|
||||
"versionPlaceholder": "x.y.z",
|
||||
"keys": "Keywords",
|
||||
"keysPlaceholder": "Comma-separated keywords",
|
||||
"author": "Author",
|
||||
"authorPlaceholder": "Your Name <email@example.com>",
|
||||
"desc": "Description",
|
||||
"env": {
|
||||
"restore": "Restore to subflow default",
|
||||
"remove": "Remove environment variable"
|
||||
@ -1079,6 +1089,7 @@
|
||||
"editor-tab": {
|
||||
"properties": "Properties",
|
||||
"envProperties": "Environment Variables",
|
||||
"module": "Module Properties",
|
||||
"description": "Description",
|
||||
"appearance": "Appearance",
|
||||
"preview": "UI Preview",
|
||||
|
@ -339,6 +339,12 @@
|
||||
"deleteSubflow": "サブフローを削除",
|
||||
"info": "詳細",
|
||||
"category": "カテゴリ",
|
||||
"module": "モジュール",
|
||||
"license": "ライセンス",
|
||||
"version": "バージョン",
|
||||
"keys": "キーワード",
|
||||
"author": "作者",
|
||||
"desc": "説明",
|
||||
"env": {
|
||||
"restore": "デフォルト値に戻す",
|
||||
"remove": "環境変数を削除"
|
||||
|
@ -670,6 +670,7 @@ RED.nodes = (function() {
|
||||
node.in = [];
|
||||
node.out = [];
|
||||
node.env = n.env;
|
||||
node.meta = n.meta;
|
||||
|
||||
if (exportCreds) {
|
||||
var credentialSet = {};
|
||||
|
@ -2253,6 +2253,14 @@ RED.editor = (function() {
|
||||
changed = true;
|
||||
}
|
||||
|
||||
var newMeta = RED.subflow.exportSubflowModuleProperties(editing_node);
|
||||
|
||||
if (!isSameObj(editing_node.meta,newMeta)) {
|
||||
changes.meta = editing_node.meta;
|
||||
editing_node.meta = newMeta;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
var wasChanged = editing_node.changed;
|
||||
editing_node.changed = true;
|
||||
@ -2359,6 +2367,16 @@ RED.editor = (function() {
|
||||
};
|
||||
editorTabs.addTab(nodePropertiesTab);
|
||||
|
||||
var moduleTab = {
|
||||
id: "editor-tab-module",
|
||||
label: RED._("editor-tab.module"),
|
||||
name: RED._("editor-tab.module"),
|
||||
content: $('<div>', {class:"red-ui-tray-content"}).appendTo(editorContent).hide(),
|
||||
iconClass: "fa fa-cube",
|
||||
};
|
||||
editorTabs.addTab(moduleTab);
|
||||
RED.subflow.buildModuleForm(moduleTab.content, editing_node);
|
||||
|
||||
var descriptionTab = {
|
||||
id: "editor-tab-description",
|
||||
label: RED._("editor-tab.description"),
|
||||
|
@ -47,6 +47,33 @@ RED.subflow = (function() {
|
||||
'</div>'+
|
||||
'</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-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-version" 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) {
|
||||
var pos = {x:50,y:30};
|
||||
if (!isInput) {
|
||||
@ -1893,6 +1920,118 @@ RED.subflow = (function() {
|
||||
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',
|
||||
'version',
|
||||
'author',
|
||||
'desc',
|
||||
'keywords',
|
||||
'license'
|
||||
].forEach(function(property) {
|
||||
$("#subflow-input-module-"+property).val(moduleProps[property]||"")
|
||||
})
|
||||
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,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',
|
||||
'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 {
|
||||
init: init,
|
||||
createSubflow: createSubflow,
|
||||
@ -1906,9 +2045,11 @@ RED.subflow = (function() {
|
||||
|
||||
buildEditForm: buildEditForm,
|
||||
buildPropertiesForm: buildPropertiesForm,
|
||||
buildModuleForm: buildModuleForm,
|
||||
|
||||
exportSubflowTemplateEnv: exportEnvList,
|
||||
exportSubflowInstanceEnv: exportSubflowInstanceEnv
|
||||
exportSubflowInstanceEnv: exportSubflowInstanceEnv,
|
||||
exportSubflowModuleProperties: exportSubflowModuleProperties
|
||||
|
||||
}
|
||||
})();
|
||||
|
@ -382,6 +382,12 @@ RED.sidebar.info = (function() {
|
||||
var category = subflowNode.category||"subflows";
|
||||
$(propRow.children()[1]).text(RED._("palette.label."+category,{defaultValue:category}))
|
||||
$('<tr class="node-info-subflow-row"><td>'+RED._("sidebar.info.instances")+"</td><td>"+subflowUserCount+'</td></tr>').appendTo(tableBody);
|
||||
if (subflowNode.meta) {
|
||||
propRow = $('<tr class="red-ui-help-info-row"><td>'+RED._("subflow.module")+'</td><td></td></tr>').appendTo(tableBody);
|
||||
$(propRow.children()[1]).text(subflowNode.meta.module||"")
|
||||
propRow = $('<tr class="red-ui-help-info-row"><td>'+RED._("subflow.version")+'</td><td></td></tr>').appendTo(tableBody);
|
||||
$(propRow.children()[1]).text(subflowNode.meta.version||"")
|
||||
}
|
||||
}
|
||||
|
||||
// var helpText = "";
|
||||
|
Loading…
Reference in New Issue
Block a user