diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js b/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js index 36e90f9c6..5072a12ca 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js @@ -108,7 +108,92 @@ return matches; } } - + + function getEnvVars (obj, envVars = {}) { + contextKnownKeys.env = contextKnownKeys.env || {} + if (contextKnownKeys.env[obj.id]) { + return contextKnownKeys.env[obj.id] + } + let parent + if (obj.type === 'tab' || obj.type === 'subflow') { + RED.nodes.eachConfig(function (conf) { + if (conf.type === "global-config") { + parent = conf; + } + }) + } else if (obj.g) { + parent = RED.nodes.group(obj.g) + } else if (obj.z) { + parent = RED.nodes.workspace(obj.z) || RED.nodes.subflow(obj.z) + } + if (parent) { + getEnvVars(parent, envVars) + } + if (obj.env) { + obj.env.forEach(env => { + envVars[env.name] = obj + }) + } + contextKnownKeys.env[obj.id] = envVars + return envVars + } + + const envAutoComplete = function (val) { + const editStack = RED.editor.getEditStack() + if (editStack.length === 0) { + done([]) + return + } + const editingNode = editStack.pop() + if (!editingNode) { + return [] + } + const envVarsMap = getEnvVars(editingNode) + const envVars = Object.keys(envVarsMap) + const matches = [] + const i = val.lastIndexOf('${') + let searchKey = val + let isSubkey = false + if (i > -1) { + if (val.lastIndexOf('}') < i) { + searchKey = val.substring(i+2) + isSubkey = true + } + } + envVars.forEach(v => { + let valMatch = getMatch(v, searchKey); + if (valMatch.found) { + const optSrc = envVarsMap[v] + const element = $('
',{style: "display: flex"}); + const valEl = $('
',{style:"font-family: var(--red-ui-monospace-font); white-space:nowrap; overflow: hidden; flex-grow:1"}); + valEl.append(generateSpans(valMatch)) + valEl.appendTo(element) + + if (optSrc) { + const optEl = $('
').css({ "font-size": "0.8em" }); + let label + if (optSrc.type === 'global-config') { + label = RED._('sidebar.context.global') + } else if (optSrc.type === 'group') { + label = RED.utils.getNodeLabel(optSrc) || (RED._('sidebar.info.group') + ': '+optSrc.id) + } else { + label = RED.utils.getNodeLabel(optSrc) || optSrc.id + } + + optEl.append(generateSpans({ match: label })); + optEl.appendTo(element); + } + matches.push({ + value: isSubkey ? val + v + '}' : v, + label: element, + i: valMatch.index + }); + } + }) + matches.sort(function(A,B){return A.i-B.i}) + return matches + } + let contextKnownKeys = {} let contextCache = {} if (RED.events) { @@ -118,9 +203,7 @@ }); } - const contextAutoComplete = function(options) { - const getContextKeysFromRuntime = function(scope, store, searchKey, done) { contextKnownKeys[scope] = contextKnownKeys[scope] || {} contextKnownKeys[scope][store] = contextKnownKeys[scope][store] || new Set() @@ -365,7 +448,8 @@ env: { value: "env", label: "env variable", - icon: "red/images/typedInput/env.svg" + icon: "red/images/typedInput/env.svg", + autoComplete: envAutoComplete }, node: { value: "node",