Rework Subflow Instance property UI (#2236)

* Add support of Subflow UI definition

* new UI definition for env var

* fix label

* fixed value obtaining

* fixed label width

* fix checkbox

* fix subflow info

* remove old subflow ui tests

* add tests

* merge ui new changes

* fix initial open button

* fix environment variable edit tab

* WIP: cp-1

* Rework subflow ui property

* Restrict SF value type according to input selection

* Move subflow property UI code to subflow.js

* Update subflow ui type select appearance

* Present subflow instance properties as table rather than generated UI

* Move subflow instance properties to separate tab

* Fix subflow property ui element layout issues
This commit is contained in:
Nick O'Leary
2019-08-12 15:01:54 +01:00
committed by GitHub
parent c8acc6a12e
commit 880757fb5d
19 changed files with 2125 additions and 381 deletions

View File

@@ -24,6 +24,54 @@ const flowUtil = require("./util");
var Log;
/**
* Create deep copy of object
*/
function deepCopy(obj) {
return JSON.parse(JSON.stringify(obj));
}
/**
* Evaluate Input Value
*/
function evaluateInputValue(value, type, node) {
if (type === "bool") {
return (value === "true") || (value === true);
}
return redUtil.evaluateNodeProperty(value, type, node, null, null);
}
/**
* Compose information object for env var
*/
function composeInfo(info, val) {
var result = {
name: info.name,
type: info.type,
value: val,
};
if (info.ui) {
var ui = info.ui;
result.ui = {
hasUI: ui.hasUI,
icon: ui.icon,
labels: ui.labels,
type: ui.type
};
var retUI = result.ui;
if (ui.type === "input") {
retUI.inputTypes = ui.inputTypes;
}
if (ui.type === "select") {
retUI.menu = ui.menu;
}
if (ui.type === "spinner") {
retUI.spinner = ui.spinner;
}
}
return result;
}
/**
* This class represents a subflow - which is handled as a special type of Flow
@@ -95,10 +143,19 @@ class Subflow extends Flow {
var env = [];
if (this.subflowDef.env) {
this.subflowDef.env.forEach(e => { env[e.name] = e; });
this.subflowDef.env.forEach(e => {
env[e.name] = e;
});
}
if (this.subflowInstance.env) {
this.subflowInstance.env.forEach(e => { env[e.name] = e; });
this.subflowInstance.env.forEach(e => {
var old = env[e.name];
var ui = old ? old.ui : null;
env[e.name] = e;
if (ui) {
env[e.name].ui = ui;
}
});
}
this.env = env;
}
@@ -257,6 +314,7 @@ class Subflow extends Flow {
super.start(diff);
}
/**
* Get environment variable of subflow
* @param {String} name name of env var
@@ -266,8 +324,16 @@ class Subflow extends Flow {
this.trace("getSetting:"+name);
if (!/^\$parent\./.test(name)) {
var env = this.env;
if (env && env.hasOwnProperty(name)) {
var val = env[name];
var is_info = name.endsWith("_info");
var is_type = name.endsWith("_type");
var ename = (is_info || is_type) ? name.substring(0, name.length -5) : name; // 5 = length of "_info"/"_type"
if (env && env.hasOwnProperty(ename)) {
var val = env[ename];
if (is_type) {
return val ? val.type : undefined;
}
// If this is an env type property we need to be careful not
// to get into lookup loops.
// 1. if the value to lookup is the same as this one, go straight to parent
@@ -276,11 +342,15 @@ class Subflow extends Flow {
// See https://github.com/node-red/node-red/issues/2099
if (val.type !== 'env' || val.value !== name) {
let value = val.value;
if (val.type === 'env') {
var type = val.type;
if (type === 'env') {
value = value.replace(new RegExp("\\${"+name+"}","g"),"${$parent."+name+"}");
}
try {
var ret = redUtil.evaluateNodeProperty(value, val.type, this.node, null, null);
var ret = evaluateInputValue(value, type, this.node);
if (is_info) {
return composeInfo(val, ret);
}
return ret;
}
catch (e) {