Skip to content

Commit

Permalink
Add subflow meta data edit pane
Browse files Browse the repository at this point in the history
  • Loading branch information
knolleary committed Nov 19, 2020
1 parent 14da04c commit 28184e8
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 1 deletion.
Expand Up @@ -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"
Expand Down Expand Up @@ -1079,6 +1089,7 @@
"editor-tab": {
"properties": "Properties",
"envProperties": "Environment Variables",
"module": "Module Properties",
"description": "Description",
"appearance": "Appearance",
"preview": "UI Preview",
Expand Down
Expand Up @@ -339,6 +339,12 @@
"deleteSubflow": "サブフローを削除",
"info": "詳細",
"category": "カテゴリ",
"module": "モジュール",
"license": "ライセンス",
"version": "バージョン",
"keys": "キーワード",
"author": "作者",
"desc": "説明",
"env": {
"restore": "デフォルト値に戻す",
"remove": "環境変数を削除"
Expand Down
Expand Up @@ -670,6 +670,7 @@ RED.nodes = (function() {
node.in = [];
node.out = [];
node.env = n.env;
node.meta = n.meta;

if (exportCreds) {
var credentialSet = {};
Expand Down
18 changes: 18 additions & 0 deletions packages/node_modules/@node-red/editor-client/src/js/ui/editor.js
Expand Up @@ -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;
Expand Down Expand Up @@ -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"),
Expand Down
143 changes: 142 additions & 1 deletion packages/node_modules/@node-red/editor-client/src/js/ui/subflow.js
Expand Up @@ -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) {
Expand Down Expand Up @@ -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,
Expand All @@ -1906,9 +2045,11 @@ RED.subflow = (function() {

buildEditForm: buildEditForm,
buildPropertiesForm: buildPropertiesForm,
buildModuleForm: buildModuleForm,

exportSubflowTemplateEnv: exportEnvList,
exportSubflowInstanceEnv: exportSubflowInstanceEnv
exportSubflowInstanceEnv: exportSubflowInstanceEnv,
exportSubflowModuleProperties: exportSubflowModuleProperties

}
})();
Expand Up @@ -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 = "";
Expand Down

0 comments on commit 28184e8

Please sign in to comment.