mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Move envVar list component to own file
This commit is contained in:
		| @@ -593,10 +593,11 @@ RED.nodes = (function() { | ||||
|             outputLabels: function(i) { return sf.outputLabels?sf.outputLabels[i]:null }, | ||||
|             oneditprepare: function() { | ||||
|                 if (this.type !== 'subflow') { | ||||
|                     // 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. | ||||
|                     // A subflow instance node | ||||
|                     RED.subflow.buildEditForm("subflow",this); | ||||
|                 } else { | ||||
|                     // A subflow template node | ||||
|                     RED.subflow.buildEditForm("subflow-template", this); | ||||
|                 } | ||||
|             }, | ||||
|             oneditresize: function(size) { | ||||
| @@ -681,7 +682,13 @@ RED.nodes = (function() { | ||||
|     } | ||||
|  | ||||
|  | ||||
|     function convertWorkspace(n) { | ||||
|     function convertWorkspace(n,opts) { | ||||
|         var exportCreds = true; | ||||
|         if (opts) { | ||||
|             if (opts.hasOwnProperty("credentials")) { | ||||
|                 exportCreds = opts.credentials; | ||||
|             } | ||||
|         } | ||||
|         var node = {}; | ||||
|         node.id = n.id; | ||||
|         node.type = n.type; | ||||
| @@ -690,19 +697,21 @@ RED.nodes = (function() { | ||||
|                 node[d] = n[d]; | ||||
|             } | ||||
|         } | ||||
|         var credentialSet = {}; | ||||
|         if (n.credentials) { | ||||
|             for (var tabCred in n.credentials) { | ||||
|                 if (n.credentials.hasOwnProperty(tabCred)) { | ||||
|                     if (!n.credentials._ || | ||||
|                         n.credentials["has_"+tabCred] != n.credentials._["has_"+tabCred] || | ||||
|                         (n.credentials["has_"+tabCred] && n.credentials[tabCred])) { | ||||
|                         credentialSet[tabCred] = n.credentials[tabCred]; | ||||
|         if (exportCreds) { | ||||
|             var credentialSet = {}; | ||||
|             if (n.credentials) { | ||||
|                 for (var tabCred in n.credentials) { | ||||
|                     if (n.credentials.hasOwnProperty(tabCred)) { | ||||
|                         if (!n.credentials._ || | ||||
|                             n.credentials["has_"+tabCred] != n.credentials._["has_"+tabCred] || | ||||
|                             (n.credentials["has_"+tabCred] && n.credentials[tabCred])) { | ||||
|                             credentialSet[tabCred] = n.credentials[tabCred]; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             if (Object.keys(credentialSet).length > 0) { | ||||
|                 node.credentials = credentialSet; | ||||
|                 if (Object.keys(credentialSet).length > 0) { | ||||
|                     node.credentials = credentialSet; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return node; | ||||
| @@ -725,7 +734,7 @@ RED.nodes = (function() { | ||||
|         } | ||||
|  | ||||
|         if (n.type === 'tab') { | ||||
|             return convertWorkspace(n); | ||||
|             return convertWorkspace(n, { credentials: exportCreds }); | ||||
|         } | ||||
|         var node = {}; | ||||
|         node.id = n.id; | ||||
| @@ -1047,7 +1056,7 @@ RED.nodes = (function() { | ||||
|         var i; | ||||
|         for (i=0;i<workspacesOrder.length;i++) { | ||||
|             if (workspaces[workspacesOrder[i]].type == "tab") { | ||||
|                 nns.push(convertWorkspace(workspaces[workspacesOrder[i]])); | ||||
|                 nns.push(convertWorkspace(workspaces[workspacesOrder[i]], opts)); | ||||
|             } | ||||
|         } | ||||
|         for (i in subflows) { | ||||
|   | ||||
							
								
								
									
										616
									
								
								packages/node_modules/@node-red/editor-client/src/js/ui/editors/envVarList.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										616
									
								
								packages/node_modules/@node-red/editor-client/src/js/ui/editors/envVarList.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,616 @@ | ||||
| RED.editor.envVarList = (function() { | ||||
|  | ||||
|     var currentLocale = 'en-US'; | ||||
|     var DEFAULT_ENV_TYPE_LIST = ['str','num','bool','json','bin','env']; | ||||
|     var DEFAULT_ENV_TYPE_LIST_INC_CRED = ['str','num','bool','json','bin','env','cred']; | ||||
|  | ||||
|     /** | ||||
|      * Create env var edit interface | ||||
|      * @param container - container | ||||
|      * @param node - subflow node | ||||
|      */ | ||||
|     function buildPropertiesList(envContainer, node) { | ||||
|  | ||||
|         var isTemplateNode = (node.type === "subflow"); | ||||
|  | ||||
|         envContainer | ||||
|             .css({ | ||||
|                 'min-height':'150px', | ||||
|                 'min-width':'450px' | ||||
|             }) | ||||
|             .editableList({ | ||||
|                 header: isTemplateNode?$('<div><div><div></div><div data-i18n="common.label.name"></div><div data-i18n="editor-tab.defaultValue"></div><div></div></div></div>'):undefined, | ||||
|                 addItem: function(container, i, opt) { | ||||
|                     // If this is an instance node, these are properties unique to | ||||
|                     // this instance - ie opt.parent will not be defined. | ||||
|  | ||||
|                     if (isTemplateNode) { | ||||
|                         container.addClass("red-ui-editor-subflow-env-editable") | ||||
|                     } | ||||
|  | ||||
|                     var envRow = $('<div/>').appendTo(container); | ||||
|                     var nameField = null; | ||||
|                     var valueField = null; | ||||
|  | ||||
|                     nameField = $('<input/>', { | ||||
|                         class: "node-input-env-name", | ||||
|                         type: "text", | ||||
|                         placeholder: RED._("common.label.name") | ||||
|                     }).attr("autocomplete","disable").appendTo(envRow).val(opt.name); | ||||
|                     valueField = $('<input/>',{ | ||||
|                         style: "width:100%", | ||||
|                         class: "node-input-env-value", | ||||
|                         type: "text", | ||||
|                     }).attr("autocomplete","disable").appendTo(envRow) | ||||
|                     valueField.typedInput({default:'str',types:isTemplateNode?DEFAULT_ENV_TYPE_LIST:DEFAULT_ENV_TYPE_LIST_INC_CRED}); | ||||
|                     valueField.typedInput('type', opt.type); | ||||
|                     if (opt.type === "cred") { | ||||
|                         if (opt.value) { | ||||
|                             valueField.typedInput('value', opt.value); | ||||
|                         } else if (node.credentials && node.credentials[opt.name]) { | ||||
|                             valueField.typedInput('value', node.credentials[opt.name]); | ||||
|                         } else if (node.credentials && node.credentials['has_'+opt.name]) { | ||||
|                             valueField.typedInput('value', "__PWRD__"); | ||||
|                         } else { | ||||
|                             valueField.typedInput('value', ""); | ||||
|                         } | ||||
|                     } else { | ||||
|                         valueField.typedInput('value', opt.value); | ||||
|                     } | ||||
|  | ||||
|  | ||||
|                     opt.nameField = nameField; | ||||
|                     opt.valueField = valueField; | ||||
|  | ||||
|                     var actionButton = $('<a/>',{href:"#",class:"red-ui-editableList-item-remove red-ui-button red-ui-button-small"}).appendTo(envRow); | ||||
|                     $('<i/>',{class:"fa "+(opt.parent?"fa-reply":"fa-remove")}).appendTo(actionButton); | ||||
|                     var removeTip = RED.popover.tooltip(actionButton,RED._("subflow.env.remove")); | ||||
|                     actionButton.on("click", function(evt) { | ||||
|                         evt.preventDefault(); | ||||
|                         removeTip.close(); | ||||
|                         container.parent().addClass("red-ui-editableList-item-deleting") | ||||
|                         container.fadeOut(300, function() { | ||||
|                             envContainer.editableList('removeItem',opt); | ||||
|                         }); | ||||
|                     }); | ||||
|  | ||||
|                     if (isTemplateNode) { | ||||
|                         // Add the UI customisation row | ||||
|                         // if `opt.ui` does not exist, then apply defaults. If these | ||||
|                         // defaults do not change then they will get stripped off | ||||
|                         // before saving. | ||||
|                         if (opt.type === 'cred') { | ||||
|                             opt.ui = opt.ui || { | ||||
|                                 icon: "", | ||||
|                                 type: "cred" | ||||
|                             } | ||||
|                             opt.ui.type = "cred"; | ||||
|                         } else { | ||||
|                             opt.ui = opt.ui || { | ||||
|                                 icon: "", | ||||
|                                 type: "input", | ||||
|                                 opts: {types:DEFAULT_ENV_TYPE_LIST} | ||||
|                             } | ||||
|                         } | ||||
|                         opt.ui.label = opt.ui.label || {}; | ||||
|                         opt.ui.type = opt.ui.type || "input"; | ||||
|  | ||||
|                         var uiRow = $('<div/>').appendTo(container).hide(); | ||||
|                         // save current info for reverting on cancel | ||||
|                         // var copy = $.extend(true, {}, ui); | ||||
|  | ||||
|                          $('<a href="#"><i class="fa fa-angle-right"></a>').prependTo(envRow).on("click", function (evt) { | ||||
|                             evt.preventDefault(); | ||||
|                             if ($(this).hasClass('expanded')) { | ||||
|                                 uiRow.slideUp(); | ||||
|                                 $(this).removeClass('expanded'); | ||||
|                             } else { | ||||
|                                 uiRow.slideDown(); | ||||
|                                 $(this).addClass('expanded'); | ||||
|                             } | ||||
|                         }); | ||||
|  | ||||
|                         buildEnvEditRow(uiRow, opt.ui, nameField, valueField); | ||||
|                         nameField.trigger('change'); | ||||
|                     } | ||||
|                 }, | ||||
|                 sortable: ".red-ui-editableList-item-handle", | ||||
|                 removable: false | ||||
|             }); | ||||
|         var parentEnv = {}; | ||||
|         var envList = []; | ||||
|         if (/^subflow:/.test(node.type)) { | ||||
|             var subflowDef = RED.nodes.subflow(node.type.substring(8)); | ||||
|             if (subflowDef.env) { | ||||
|                 subflowDef.env.forEach(function(env) { | ||||
|                     var item = { | ||||
|                         name:env.name, | ||||
|                         parent: { | ||||
|                             type: env.type, | ||||
|                             value: env.value, | ||||
|                             ui: env.ui | ||||
|                         } | ||||
|                     } | ||||
|                     envList.push(item); | ||||
|                     parentEnv[env.name] = item; | ||||
|                 }) | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (node.env) { | ||||
|             for (var i = 0; i < node.env.length; i++) { | ||||
|                 var env = node.env[i]; | ||||
|                 if (parentEnv.hasOwnProperty(env.name)) { | ||||
|                     parentEnv[env.name].type = env.type; | ||||
|                     parentEnv[env.name].value = env.value; | ||||
|                 } else { | ||||
|                     envList.push({ | ||||
|                         name: env.name, | ||||
|                         type: env.type, | ||||
|                         value: env.value, | ||||
|                         ui: env.ui | ||||
|                     }); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         envList.forEach(function(env) { | ||||
|             if (env.parent && env.parent.ui && env.parent.ui.type === 'hide') { | ||||
|                 return; | ||||
|             } | ||||
|             if (!isTemplateNode && env.parent) { | ||||
|                 return; | ||||
|             } | ||||
|             envContainer.editableList('addItem', JSON.parse(JSON.stringify(env))); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Create UI edit interface for environment variable | ||||
|      * @param container - container | ||||
|      * @param env - env var definition | ||||
|      * @param nameField - name field of env var | ||||
|      * @param valueField - value field of env var | ||||
|      */ | ||||
|      function buildEnvEditRow(container, ui, nameField, valueField) { | ||||
|          container.addClass("red-ui-editor-subflow-env-ui-row") | ||||
|          var topRow = $('<div></div>').appendTo(container); | ||||
|          $('<div></div>').appendTo(topRow); | ||||
|          $('<div>').text(RED._("editor.icon")).appendTo(topRow); | ||||
|          $('<div>').text(RED._("editor.label")).appendTo(topRow); | ||||
|          $('<div>').text(RED._("editor.inputType")).appendTo(topRow); | ||||
|  | ||||
|          var row = $('<div></div>').appendTo(container); | ||||
|          $('<div><i class="red-ui-editableList-item-handle fa fa-bars"></i></div>').appendTo(row); | ||||
|          var typeOptions = { | ||||
|              'input': {types:DEFAULT_ENV_TYPE_LIST}, | ||||
|              'select': {opts:[]}, | ||||
|              'spinner': {}, | ||||
|              'cred': {} | ||||
|          }; | ||||
|          if (ui.opts) { | ||||
|              typeOptions[ui.type] = ui.opts; | ||||
|          } else { | ||||
|              // Pick up the default values if not otherwise provided | ||||
|              ui.opts = typeOptions[ui.type]; | ||||
|          } | ||||
|          var iconCell = $('<div></div>').appendTo(row); | ||||
|  | ||||
|          var iconButton = $('<a href="#"></a>').appendTo(iconCell); | ||||
|          iconButton.on("click", function(evt) { | ||||
|              evt.preventDefault(); | ||||
|              var icon = ui.icon || ""; | ||||
|              var iconPath = (icon ? RED.utils.separateIconPath(icon) : {}); | ||||
|              RED.editor.iconPicker.show(iconButton, null, iconPath, true, function (newIcon) { | ||||
|                  iconButton.empty(); | ||||
|                  var path = newIcon || ""; | ||||
|                  var newPath = RED.utils.separateIconPath(path); | ||||
|                  if (newPath) { | ||||
|                      $('<i class="fa"></i>').addClass(newPath.file).appendTo(iconButton); | ||||
|                  } | ||||
|                  ui.icon = path; | ||||
|              }); | ||||
|          }) | ||||
|  | ||||
|          if (ui.icon) { | ||||
|              var newPath = RED.utils.separateIconPath(ui.icon); | ||||
|              $('<i class="fa '+newPath.file+'"></i>').appendTo(iconButton); | ||||
|          } | ||||
|  | ||||
|          var labelCell = $('<div></div>').appendTo(row); | ||||
|  | ||||
|          var label = ui.label && ui.label[currentLocale] || ""; | ||||
|          var labelInput = $('<input type="text">').val(label).appendTo(labelCell); | ||||
|          ui.labelField = labelInput; | ||||
|          labelInput.on('change', function(evt) { | ||||
|              ui.label = ui.label || {}; | ||||
|              var val = $(this).val().trim(); | ||||
|              if (val === "") { | ||||
|                  delete ui.label[currentLocale]; | ||||
|              } else { | ||||
|                  ui.label[currentLocale] = val; | ||||
|              } | ||||
|          }) | ||||
|          var labelIcon = $('<span class="red-ui-editor-subflow-env-lang-icon"><i class="fa fa-language"></i></span>').appendTo(labelCell); | ||||
|          RED.popover.tooltip(labelIcon,function() { | ||||
|              var langs = Object.keys(ui.label); | ||||
|              var content = $("<div>"); | ||||
|              if (langs.indexOf(currentLocale) === -1) { | ||||
|                  langs.push(currentLocale); | ||||
|                  langs.sort(); | ||||
|              } | ||||
|              langs.forEach(function(l) { | ||||
|                  var row = $('<div>').appendTo(content); | ||||
|                  $('<span>').css({display:"inline-block",width:"120px"}).text(RED._("languages."+l)+(l===currentLocale?"*":"")).appendTo(row); | ||||
|                  $('<span>').text(ui.label[l]||"").appendTo(row); | ||||
|              }); | ||||
|              return content; | ||||
|          }) | ||||
|  | ||||
|          nameField.on('change',function(evt) { | ||||
|             labelInput.attr("placeholder",$(this).val()) | ||||
|         }); | ||||
|  | ||||
|         var inputCell = $('<div></div>').appendTo(row); | ||||
|         var inputCellInput = $('<input type="text">').css("width","100%").appendTo(inputCell); | ||||
|         if (ui.type === "input") { | ||||
|             inputCellInput.val(ui.opts.types.join(",")); | ||||
|         } | ||||
|         var checkbox; | ||||
|         var selectBox; | ||||
|  | ||||
|         inputCellInput.typedInput({ | ||||
|             types: [ | ||||
|                 { | ||||
|                     value:"input", | ||||
|                     label:RED._("editor.inputs.input"), icon:"fa fa-i-cursor",showLabel:false,multiple:true,options:[ | ||||
|                         {value:"str",label:RED._("editor.types.str"),icon:"red/images/typedInput/az.svg"}, | ||||
|                         {value:"num",label:RED._("editor.types.num"),icon:"red/images/typedInput/09.svg"}, | ||||
|                         {value:"bool",label:RED._("editor.types.bool"),icon:"red/images/typedInput/bool.svg"}, | ||||
|                         {value:"json",label:RED._("editor.types.json"),icon:"red/images/typedInput/json.svg"}, | ||||
|                         {value: "bin",label: RED._("editor.types.bin"),icon: "red/images/typedInput/bin.svg"}, | ||||
|                         {value: "env",label: RED._("editor.types.env"),icon: "red/images/typedInput/env.svg"}, | ||||
|                         {value: "cred",label: RED._("editor.types.cred"),icon: "fa fa-lock"} | ||||
|                     ], | ||||
|                     default: DEFAULT_ENV_TYPE_LIST, | ||||
|                     valueLabel: function(container,value) { | ||||
|                         container.css("padding",0); | ||||
|                         var innerContainer = $('<div class="red-ui-editor-subflow-env-input-type"></div>').appendTo(container); | ||||
|  | ||||
|                         var input = $('<div class="placeholder-input">').appendTo(innerContainer); | ||||
|                         $('<span><i class="fa fa-i-cursor"></i></span>').appendTo(input); | ||||
|                         if (value.length) { | ||||
|                             value.forEach(function(v) { | ||||
|                                 if (!/^fa /.test(v.icon)) { | ||||
|                                     $('<img>',{src:v.icon,style:"max-width:14px; padding: 0 3px; margin-top:-4px; margin-left: 1px"}).appendTo(input); | ||||
|                                 } else { | ||||
|                                     var s = $('<span>',{style:"max-width:14px; padding: 0 3px; margin-top:-4px; margin-left: 1px"}).appendTo(input); | ||||
|                                     $("<i>",{class: v.icon}).appendTo(s); | ||||
|                                 } | ||||
|                             }) | ||||
|                         } else { | ||||
|                             $('<span class="red-ui-editor-subflow-env-input-type-placeholder"></span>').text(RED._("editor.selectType")).appendTo(input); | ||||
|                         } | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
|                     value: "cred", | ||||
|                     label: RED._("typedInput.type.cred"), icon:"fa fa-lock", showLabel: false, | ||||
|                     valueLabel: function(container,value) { | ||||
|                         container.css("padding",0); | ||||
|                         var innerContainer = $('<div class="red-ui-editor-subflow-env-input-type">').css({ | ||||
|                             "border-top-right-radius": "4px", | ||||
|                             "border-bottom-right-radius": "4px" | ||||
|                         }).appendTo(container); | ||||
|                         $('<div class="placeholder-input">').html("••••••••").appendTo(innerContainer); | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
|                     value:"select", | ||||
|                     label:RED._("editor.inputs.select"), icon:"fa fa-tasks",showLabel:false, | ||||
|                     valueLabel: function(container,value) { | ||||
|                         container.css("padding","0"); | ||||
|  | ||||
|                         selectBox = $('<select></select>').appendTo(container); | ||||
|                         if (ui.opts && Array.isArray(ui.opts.opts)) { | ||||
|                             ui.opts.opts.forEach(function(o) { | ||||
|                                 var label = lookupLabel(o.l, o.l["en-US"]||o.v, currentLocale); | ||||
|                                 // $('<option>').val((o.t||'str')+":"+o.v).text(label).appendTo(selectBox); | ||||
|                                 $('<option>').val(o.v).text(label).appendTo(selectBox); | ||||
|                             }) | ||||
|                         } | ||||
|                         selectBox.on('change', function(evt) { | ||||
|                             var v = selectBox.val(); | ||||
|                             // var parts = v.split(":"); | ||||
|                             // var t = parts.shift(); | ||||
|                             // v = parts.join(":"); | ||||
|                             // | ||||
|                             // valueField.typedInput("type",'str') | ||||
|                             valueField.typedInput("value",v) | ||||
|                         }); | ||||
|                         selectBox.val(valueField.typedInput("value")); | ||||
|                         // selectBox.val(valueField.typedInput('type')+":"+valueField.typedInput("value")); | ||||
|                     }, | ||||
|                     expand: { | ||||
|                         icon: "fa-caret-down", | ||||
|                         minWidth: 400, | ||||
|                         content: function(container) { | ||||
|                             var content = $('<div class="red-ui-editor-subflow-ui-edit-panel">').appendTo(container); | ||||
|                             var optList = $('<ol>').appendTo(content).editableList({ | ||||
|                                 header:$("<div><div>"+RED._("editor.select.label")+"</div><div>"+RED._("editor.select.value")+"</div></div>"), | ||||
|                                 addItem: function(row,index,itemData) { | ||||
|                                     var labelDiv = $('<div>').appendTo(row); | ||||
|                                     var label = lookupLabel(itemData.l, "", currentLocale); | ||||
|                                     itemData.label = $('<input type="text">').val(label).appendTo(labelDiv); | ||||
|                                     itemData.label.on('keydown', function(evt) { | ||||
|                                         if (evt.keyCode === 13) { | ||||
|                                             itemData.input.focus(); | ||||
|                                             evt.preventDefault(); | ||||
|                                         } | ||||
|                                     }); | ||||
|                                     var labelIcon = $('<span class="red-ui-editor-subflow-env-lang-icon"><i class="fa fa-language"></i></span>').appendTo(labelDiv); | ||||
|                                     RED.popover.tooltip(labelIcon,function() { | ||||
|                                         return currentLocale; | ||||
|                                     }) | ||||
|                                     itemData.input = $('<input type="text">').val(itemData.v).appendTo(row); | ||||
|  | ||||
|                                     // Problem using a TI here: | ||||
|                                     //  - this is in a popout panel | ||||
|                                     //  - clicking the expand button in the TI will close the parent edit tray | ||||
|                                     //    and open the type editor. | ||||
|                                     //  - but it leaves the popout panel over the top. | ||||
|                                     //  - there is no way to get back to the popout panel after closing the type editor | ||||
|                                     //.typedInput({default:itemData.t||'str', types:DEFAULT_ENV_TYPE_LIST}); | ||||
|                                     itemData.input.on('keydown', function(evt) { | ||||
|                                         if (evt.keyCode === 13) { | ||||
|                                             // Enter or Tab | ||||
|                                             var index = optList.editableList('indexOf',itemData); | ||||
|                                             var length = optList.editableList('length'); | ||||
|                                             if (index + 1 === length) { | ||||
|                                                 var newItem = {}; | ||||
|                                                 optList.editableList('addItem',newItem); | ||||
|                                                 setTimeout(function() { | ||||
|                                                     if (newItem.label) { | ||||
|                                                         newItem.label.focus(); | ||||
|                                                     } | ||||
|                                                 },100) | ||||
|                                             } else { | ||||
|                                                 var nextItem = optList.editableList('getItemAt',index+1); | ||||
|                                                 if (nextItem.label) { | ||||
|                                                     nextItem.label.focus() | ||||
|                                                 } | ||||
|                                             } | ||||
|                                             evt.preventDefault(); | ||||
|                                         } | ||||
|                                     }); | ||||
|                                 }, | ||||
|                                 sortable: true, | ||||
|                                 removable: true, | ||||
|                                 height: 160 | ||||
|                             }) | ||||
|                             if (ui.opts.opts.length > 0) { | ||||
|                                 ui.opts.opts.forEach(function(o) { | ||||
|                                     optList.editableList('addItem',$.extend(true,{},o)) | ||||
|                                 }) | ||||
|                             } else { | ||||
|                                 optList.editableList('addItem',{}) | ||||
|                             } | ||||
|                             return { | ||||
|                                 onclose: function() { | ||||
|                                     var items = optList.editableList('items'); | ||||
|                                     var vals = []; | ||||
|                                     items.each(function (i,el) { | ||||
|                                         var data = el.data('data'); | ||||
|                                         var l = data.label.val().trim(); | ||||
|                                         var v = data.input.val(); | ||||
|                                         // var t = data.input.typedInput('type'); | ||||
|                                         // var v = data.input.typedInput('value'); | ||||
|                                         if (l.length > 0) { | ||||
|                                             data.l = data.l || {}; | ||||
|                                             data.l[currentLocale] = l; | ||||
|                                         } | ||||
|                                         data.v = v; | ||||
|  | ||||
|                                         if (l.length > 0 || v.length > 0) { | ||||
|                                             var val = {l:data.l,v:data.v}; | ||||
|                                             // if (t !== 'str') { | ||||
|                                             //     val.t = t; | ||||
|                                             // } | ||||
|                                             vals.push(val); | ||||
|                                         } | ||||
|                                     }); | ||||
|                                     ui.opts.opts = vals; | ||||
|                                     inputCellInput.typedInput('value',Date.now()) | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
|                     value:"checkbox", | ||||
|                     label:RED._("editor.inputs.checkbox"), icon:"fa fa-check-square-o",showLabel:false, | ||||
|                     valueLabel: function(container,value) { | ||||
|                         container.css("padding",0); | ||||
|                         checkbox = $('<input type="checkbox">').appendTo(container); | ||||
|                         checkbox.on('change', function(evt) { | ||||
|                             valueField.typedInput('value',$(this).prop('checked')?"true":"false"); | ||||
|                         }) | ||||
|                         checkbox.prop('checked',valueField.typedInput('value')==="true"); | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
|                     value:"spinner", | ||||
|                     label:RED._("editor.inputs.spinner"), icon:"fa fa-sort-numeric-asc", showLabel:false, | ||||
|                     valueLabel: function(container,value) { | ||||
|                         container.css("padding",0); | ||||
|                         var innerContainer = $('<div class="red-ui-editor-subflow-env-input-type"></div>').appendTo(container); | ||||
|  | ||||
|                         var input = $('<div class="placeholder-input">').appendTo(innerContainer); | ||||
|                         $('<span><i class="fa fa-sort-numeric-asc"></i></span>').appendTo(input); | ||||
|  | ||||
|                         var min = ui.opts && ui.opts.min; | ||||
|                         var max = ui.opts && ui.opts.max; | ||||
|                         var label = ""; | ||||
|                         if (min !== undefined && max !== undefined) { | ||||
|                             label = Math.min(min,max)+" - "+Math.max(min,max); | ||||
|                         } else if (min !== undefined) { | ||||
|                             label = "> "+min; | ||||
|                         } else if (max !== undefined) { | ||||
|                             label = "< "+max; | ||||
|                         } | ||||
|                         $('<span>').css("margin-left","15px").text(label).appendTo(input); | ||||
|                     }, | ||||
|                     expand: { | ||||
|                         icon: "fa-caret-down", | ||||
|                         content: function(container) { | ||||
|                             var content = $('<div class="red-ui-editor-subflow-ui-edit-panel">').appendTo(container); | ||||
|                             content.css("padding","8px 5px") | ||||
|                             var min = ui.opts.min; | ||||
|                             var max = ui.opts.max; | ||||
|                             var minInput = $('<input type="number" style="margin-bottom:0; width:60px">'); | ||||
|                             minInput.val(min); | ||||
|                             var maxInput = $('<input type="number" style="margin-bottom:0; width:60px">'); | ||||
|                             maxInput.val(max); | ||||
|                             $('<div class="form-row" style="margin-bottom:3px"><label>'+RED._("editor.spinner.min")+'</label></div>').append(minInput).appendTo(content); | ||||
|                             $('<div class="form-row" style="margin-bottom:0"><label>'+RED._("editor.spinner.max")+'</label></div>').append(maxInput).appendTo(content); | ||||
|                             return { | ||||
|                                 onclose: function() { | ||||
|                                     var min = minInput.val().trim(); | ||||
|                                     var max = maxInput.val().trim(); | ||||
|                                     if (min !== "") { | ||||
|                                         ui.opts.min = parseInt(min); | ||||
|                                     } else { | ||||
|                                         delete ui.opts.min; | ||||
|                                     } | ||||
|                                     if (max !== "") { | ||||
|                                         ui.opts.max = parseInt(max); | ||||
|                                     } else { | ||||
|                                         delete ui.opts.max; | ||||
|                                     } | ||||
|                                     inputCellInput.typedInput('value',Date.now()) | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
|                     value:"none", | ||||
|                     label:RED._("editor.inputs.none"), icon:"fa fa-times",hasValue:false | ||||
|                 }, | ||||
|                 { | ||||
|                     value:"hide", | ||||
|                     label:RED._("editor.inputs.hidden"), icon:"fa fa-ban",hasValue:false | ||||
|                 } | ||||
|             ], | ||||
|             default: 'none' | ||||
|         }).on("typedinputtypechange", function(evt,type) { | ||||
|             ui.type = $(this).typedInput("type"); | ||||
|             ui.opts = typeOptions[ui.type]; | ||||
|             if (ui.type === 'input') { | ||||
|                 // In the case of 'input' type, the typedInput uses the multiple-option | ||||
|                 // mode. Its value needs to be set to a comma-separately list of the | ||||
|                 // selected options. | ||||
|                 inputCellInput.typedInput('value',ui.opts.types.join(",")) | ||||
|             } else { | ||||
|                 // No other type cares about `value`, but doing this will | ||||
|                 // force a refresh of the label now that `ui.opts` has | ||||
|                 // been updated. | ||||
|                 inputCellInput.typedInput('value',Date.now()) | ||||
|             } | ||||
|  | ||||
|             switch (ui.type) { | ||||
|                 case 'input': | ||||
|                     valueField.typedInput('types',ui.opts.types); | ||||
|                     break; | ||||
|                 case 'select': | ||||
|                     valueField.typedInput('types',['str']); | ||||
|                     break; | ||||
|                 case 'checkbox': | ||||
|                     valueField.typedInput('types',['bool']); | ||||
|                     break; | ||||
|                 case 'spinner': | ||||
|                     valueField.typedInput('types',['num']); | ||||
|                     break; | ||||
|                 case 'cred': | ||||
|                     valueField.typedInput('types',['cred']); | ||||
|                     break; | ||||
|                 default: | ||||
|                     valueField.typedInput('types',DEFAULT_ENV_TYPE_LIST) | ||||
|             } | ||||
|             if (ui.type === 'checkbox') { | ||||
|                 valueField.typedInput('type','bool'); | ||||
|             } else if (ui.type === 'spinner') { | ||||
|                 valueField.typedInput('type','num'); | ||||
|             } | ||||
|             if (ui.type !== 'checkbox') { | ||||
|                 checkbox = null; | ||||
|             } | ||||
|  | ||||
|         }).on("change", function(evt,type) { | ||||
|             if (ui.type === 'input') { | ||||
|                 var types = inputCellInput.typedInput('value'); | ||||
|                 ui.opts.types = (types === "") ? ["str"] : types.split(","); | ||||
|                 valueField.typedInput('types',ui.opts.types); | ||||
|             } | ||||
|         }); | ||||
|         valueField.on("change", function(evt) { | ||||
|             if (checkbox) { | ||||
|                 checkbox.prop('checked',$(this).typedInput('value')==="true") | ||||
|             } | ||||
|         }) | ||||
|         // Set the input to the right type. This will trigger the 'typedinputtypechange' | ||||
|         // event handler (just above ^^) to update the value if needed | ||||
|         inputCellInput.typedInput('type',ui.type) | ||||
|     } | ||||
|  | ||||
|     function setLocale(l, list) { | ||||
|         currentLocale = l; | ||||
|         if (list) { | ||||
|             var items = list.editableList("items"); | ||||
|             items.each(function (i, item) { | ||||
|                 var entry = $(this).data('data'); | ||||
|                 var labelField = entry.ui.labelField; | ||||
|                 labelField.val(lookupLabel(entry.ui.label, "", currentLocale)); | ||||
|                 if (labelField.timeout) { | ||||
|                     clearTimeout(labelField.timeout); | ||||
|                     delete labelField.timeout; | ||||
|                 } | ||||
|                 labelField.addClass("input-updated"); | ||||
|                 labelField.timeout = setTimeout(function() { | ||||
|                     delete labelField.timeout | ||||
|                     labelField.removeClass("input-updated"); | ||||
|                 },3000); | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Lookup text for specific locale | ||||
|      * @param labels - dict of labels | ||||
|      * @param defaultLabel - fallback label if not found | ||||
|      * @param locale - target locale | ||||
|      * @returns {string} text for specified locale | ||||
|      */ | ||||
|     function lookupLabel(labels, defaultLabel, locale) { | ||||
|         if (labels) { | ||||
|             if (labels[locale]) { | ||||
|                 return labels[locale]; | ||||
|             } | ||||
|             if (locale) { | ||||
|                 var lang = locale.substring(0, 2); | ||||
|                 if (labels[lang]) { | ||||
|                     return labels[lang]; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return defaultLabel; | ||||
|     } | ||||
|  | ||||
|     return { | ||||
|         create: buildPropertiesList, | ||||
|         setLocale: setLocale, | ||||
|         lookupLabel: lookupLabel, | ||||
|         DEFAULT_ENV_TYPE_LIST: DEFAULT_ENV_TYPE_LIST, | ||||
|         DEFAULT_ENV_TYPE_LIST_INC_CRED: DEFAULT_ENV_TYPE_LIST_INC_CRED | ||||
|     } | ||||
| })(); | ||||
| @@ -10,7 +10,7 @@ | ||||
|                 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); | ||||
|                 RED.editor.envVarList.create(this.list, node); | ||||
|                 return content; | ||||
|             }, | ||||
|             resize: function(node, size) { | ||||
|   | ||||
| @@ -30,13 +30,6 @@ | ||||
|                 } | ||||
|                 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) { | ||||
|   | ||||
							
								
								
									
										63
									
								
								packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/subflowProperties.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/subflowProperties.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | ||||
| ;(function() { | ||||
|  | ||||
|     RED.editor.registerEditorPane("editor-tab-subflow-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 dialogForm = $('<form id="dialog-form" class="form-horizontal"></form>').appendTo(content); | ||||
|                 $('<div class="form-row">'+ | ||||
|                   '<label for="node-input-name" data-i18n="[append]editor:common.label.name"><i class="fa fa-tag"></i> </label>'+ | ||||
|                   '<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">'+ | ||||
|                   '</div>').appendTo(dialogForm); | ||||
|  | ||||
|                 var row = $('<div class="form-row node-text-editor-row">'+ | ||||
|                             '<label for="node-input-info" data-i18n="editor:workspace.info" style="width:300px;"></label>'+ | ||||
|                             '<div style="min-height:150px;" class="node-text-editor" id="node-input-info"></div>'+ | ||||
|                             '</div>').appendTo(dialogForm); | ||||
|                 this.tabflowEditor = RED.editor.createEditor({ | ||||
|                     id: 'node-input-info', | ||||
|                     mode: 'ace/mode/markdown', | ||||
|                     value: "" | ||||
|                 }); | ||||
|  | ||||
|                 $('<input type="text" style="display: none;" />').prependTo(dialogForm); | ||||
|                 dialogForm.on("submit", function(e) { e.preventDefault();}); | ||||
|  | ||||
|                 $("#node-input-name").val(node.label); | ||||
|                 RED.text.bidi.prepareInput($("#node-input-name")); | ||||
|                 this.tabflowEditor.getSession().setValue(node.info || "", -1); | ||||
|                 return content; | ||||
|             }, | ||||
|             resize: function(node, size) { | ||||
|                 $("#node-input-info").css("height", (size.height-70)+"px"); | ||||
|                 this.tabflowEditor.resize(); | ||||
|             }, | ||||
|             close: function(node) { | ||||
|                 this.tabflowEditor.destroy(); | ||||
|             }, | ||||
|             apply: function(workspace, editState) { | ||||
|                 var label = $( "#node-input-name" ).val(); | ||||
|  | ||||
|                 if (workspace.label != label) { | ||||
|                     editState.changes.label = workspace.label; | ||||
|                     editState.changed = true; | ||||
|                     workspace.label = label; | ||||
|                 } | ||||
|  | ||||
|                 var info = this.tabflowEditor.getValue(); | ||||
|                 if (workspace.info !== info) { | ||||
|                     editState.changes.info = workspace.info; | ||||
|                     editState.changed = true; | ||||
|                     workspace.info = info; | ||||
|                 } | ||||
|                 $("#red-ui-tab-"+(workspace.id.replace(".","-"))).toggleClass('red-ui-workspace-disabled',!!workspace.disabled); | ||||
|                 $("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!workspace.disabled); | ||||
|  | ||||
|             } | ||||
|         } | ||||
|     }); | ||||
| })(); | ||||
| @@ -16,8 +16,6 @@ | ||||
|  | ||||
| RED.subflow = (function() { | ||||
|  | ||||
|     var currentLocale = "en-US"; | ||||
|  | ||||
|     var _subflowEditTemplate = '<script type="text/x-red" data-template-name="subflow">'+ | ||||
|         '<div class="form-row">'+ | ||||
|             '<label for="node-input-name" data-i18n="[append]editor:common.label.name"><i class="fa fa-tag"></i> </label>'+ | ||||
| @@ -918,588 +916,11 @@ RED.subflow = (function() { | ||||
|         locales.val(locale); | ||||
|  | ||||
|         locales.on("change", function() { | ||||
|             currentLocale = $(this).val(); | ||||
|             var items = $("#node-input-env-container").editableList("items"); | ||||
|             items.each(function (i, item) { | ||||
|                 var entry = $(this).data('data'); | ||||
|                 var labelField = entry.ui.labelField; | ||||
|                 labelField.val(lookupLabel(entry.ui.label, "", currentLocale)); | ||||
|                 if (labelField.timeout) { | ||||
|                     clearTimeout(labelField.timeout); | ||||
|                     delete labelField.timeout; | ||||
|                 } | ||||
|                 labelField.addClass("input-updated"); | ||||
|                 labelField.timeout = setTimeout(function() { | ||||
|                     delete labelField.timeout | ||||
|                     labelField.removeClass("input-updated"); | ||||
|                 },3000); | ||||
|             }); | ||||
|             RED.editor.envVarList.setLocale($(this).val(), $("#node-input-env-container")); | ||||
|         }); | ||||
|         RED.editor.envVarList.setLocale(locale); | ||||
|     } | ||||
|  | ||||
|     var DEFAULT_ENV_TYPE_LIST = ['str','num','bool','json','bin','env']; | ||||
|     var DEFAULT_ENV_TYPE_LIST_INC_CRED = ['str','num','bool','json','bin','env','cred']; | ||||
|  | ||||
|     /** | ||||
|      * Create env var edit interface | ||||
|      * @param container - container | ||||
|      * @param node - subflow node | ||||
|      */ | ||||
|     function buildPropertiesList(envContainer, node) { | ||||
|  | ||||
|         var isTemplateNode = (node.type === "subflow"); | ||||
|  | ||||
|         if (isTemplateNode) { | ||||
|             buildEnvControl(envContainer, node); | ||||
|         } | ||||
|         envContainer | ||||
|             .css({ | ||||
|                 'min-height':'150px', | ||||
|                 'min-width':'450px' | ||||
|             }) | ||||
|             .editableList({ | ||||
|                 header: isTemplateNode?$('<div><div><div></div><div data-i18n="common.label.name"></div><div data-i18n="editor-tab.defaultValue"></div><div></div></div></div>'):undefined, | ||||
|                 addItem: function(container, i, opt) { | ||||
|                     // If this is an instance node, these are properties unique to | ||||
|                     // this instance - ie opt.parent will not be defined. | ||||
|  | ||||
|                     if (isTemplateNode) { | ||||
|                         container.addClass("red-ui-editor-subflow-env-editable") | ||||
|                     } | ||||
|  | ||||
|                     var envRow = $('<div/>').appendTo(container); | ||||
|                     var nameField = null; | ||||
|                     var valueField = null; | ||||
|  | ||||
|                     nameField = $('<input/>', { | ||||
|                         class: "node-input-env-name", | ||||
|                         type: "text", | ||||
|                         placeholder: RED._("common.label.name") | ||||
|                     }).attr("autocomplete","disable").appendTo(envRow).val(opt.name); | ||||
|                     valueField = $('<input/>',{ | ||||
|                         style: "width:100%", | ||||
|                         class: "node-input-env-value", | ||||
|                         type: "text", | ||||
|                     }).attr("autocomplete","disable").appendTo(envRow) | ||||
|                     valueField.typedInput({default:'str',types:isTemplateNode?DEFAULT_ENV_TYPE_LIST:DEFAULT_ENV_TYPE_LIST_INC_CRED}); | ||||
|                     valueField.typedInput('type', opt.type); | ||||
|                     if (opt.type === "cred") { | ||||
|                         if (opt.value) { | ||||
|                             valueField.typedInput('value', opt.value); | ||||
|                         } else if (node.credentials && node.credentials[opt.name]) { | ||||
|                             valueField.typedInput('value', node.credentials[opt.name]); | ||||
|                         } else if (node.credentials && node.credentials['has_'+opt.name]) { | ||||
|                             valueField.typedInput('value', "__PWRD__"); | ||||
|                         } else { | ||||
|                             valueField.typedInput('value', ""); | ||||
|                         } | ||||
|                     } else { | ||||
|                         valueField.typedInput('value', opt.value); | ||||
|                     } | ||||
|  | ||||
|  | ||||
|                     opt.nameField = nameField; | ||||
|                     opt.valueField = valueField; | ||||
|  | ||||
|                     var actionButton = $('<a/>',{href:"#",class:"red-ui-editableList-item-remove red-ui-button red-ui-button-small"}).appendTo(envRow); | ||||
|                     $('<i/>',{class:"fa "+(opt.parent?"fa-reply":"fa-remove")}).appendTo(actionButton); | ||||
|                     var removeTip = RED.popover.tooltip(actionButton,RED._("subflow.env.remove")); | ||||
|                     actionButton.on("click", function(evt) { | ||||
|                         evt.preventDefault(); | ||||
|                         removeTip.close(); | ||||
|                         container.parent().addClass("red-ui-editableList-item-deleting") | ||||
|                         container.fadeOut(300, function() { | ||||
|                             envContainer.editableList('removeItem',opt); | ||||
|                         }); | ||||
|                     }); | ||||
|  | ||||
|                     if (isTemplateNode) { | ||||
|                         // Add the UI customisation row | ||||
|                         // if `opt.ui` does not exist, then apply defaults. If these | ||||
|                         // defaults do not change then they will get stripped off | ||||
|                         // before saving. | ||||
|                         if (opt.type === 'cred') { | ||||
|                             opt.ui = opt.ui || { | ||||
|                                 icon: "", | ||||
|                                 type: "cred" | ||||
|                             } | ||||
|                             opt.ui.type = "cred"; | ||||
|                         } else { | ||||
|                             opt.ui = opt.ui || { | ||||
|                                 icon: "", | ||||
|                                 type: "input", | ||||
|                                 opts: {types:DEFAULT_ENV_TYPE_LIST} | ||||
|                             } | ||||
|                         } | ||||
|                         opt.ui.label = opt.ui.label || {}; | ||||
|                         opt.ui.type = opt.ui.type || "input"; | ||||
|  | ||||
|                         var uiRow = $('<div/>').appendTo(container).hide(); | ||||
|                         // save current info for reverting on cancel | ||||
|                         // var copy = $.extend(true, {}, ui); | ||||
|  | ||||
|                          $('<a href="#"><i class="fa fa-angle-right"></a>').prependTo(envRow).on("click", function (evt) { | ||||
|                             evt.preventDefault(); | ||||
|                             if ($(this).hasClass('expanded')) { | ||||
|                                 uiRow.slideUp(); | ||||
|                                 $(this).removeClass('expanded'); | ||||
|                             } else { | ||||
|                                 uiRow.slideDown(); | ||||
|                                 $(this).addClass('expanded'); | ||||
|                             } | ||||
|                         }); | ||||
|  | ||||
|                         buildEnvEditRow(uiRow, opt.ui, nameField, valueField); | ||||
|                         nameField.trigger('change'); | ||||
|                     } | ||||
|                 }, | ||||
|                 sortable: ".red-ui-editableList-item-handle", | ||||
|                 removable: false | ||||
|             }); | ||||
|         var parentEnv = {}; | ||||
|         var envList = []; | ||||
|         if (/^subflow:/.test(node.type)) { | ||||
|             var subflowDef = RED.nodes.subflow(node.type.substring(8)); | ||||
|             if (subflowDef.env) { | ||||
|                 subflowDef.env.forEach(function(env) { | ||||
|                     var item = { | ||||
|                         name:env.name, | ||||
|                         parent: { | ||||
|                             type: env.type, | ||||
|                             value: env.value, | ||||
|                             ui: env.ui | ||||
|                         } | ||||
|                     } | ||||
|                     envList.push(item); | ||||
|                     parentEnv[env.name] = item; | ||||
|                 }) | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (node.env) { | ||||
|             for (var i = 0; i < node.env.length; i++) { | ||||
|                 var env = node.env[i]; | ||||
|                 if (parentEnv.hasOwnProperty(env.name)) { | ||||
|                     parentEnv[env.name].type = env.type; | ||||
|                     parentEnv[env.name].value = env.value; | ||||
|                 } else { | ||||
|                     envList.push({ | ||||
|                         name: env.name, | ||||
|                         type: env.type, | ||||
|                         value: env.value, | ||||
|                         ui: env.ui | ||||
|                     }); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         envList.forEach(function(env) { | ||||
|             if (env.parent && env.parent.ui && env.parent.ui.type === 'hide') { | ||||
|                 return; | ||||
|             } | ||||
|             if (!isTemplateNode && env.parent) { | ||||
|                 return; | ||||
|             } | ||||
|             envContainer.editableList('addItem', JSON.parse(JSON.stringify(env))); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Create UI edit interface for environment variable | ||||
|      * @param container - container | ||||
|      * @param env - env var definition | ||||
|      * @param nameField - name field of env var | ||||
|      * @param valueField - value field of env var | ||||
|      */ | ||||
|      function buildEnvEditRow(container, ui, nameField, valueField) { | ||||
|          container.addClass("red-ui-editor-subflow-env-ui-row") | ||||
|          var topRow = $('<div></div>').appendTo(container); | ||||
|          $('<div></div>').appendTo(topRow); | ||||
|          $('<div>').text(RED._("editor.icon")).appendTo(topRow); | ||||
|          $('<div>').text(RED._("editor.label")).appendTo(topRow); | ||||
|          $('<div>').text(RED._("editor.inputType")).appendTo(topRow); | ||||
|  | ||||
|          var row = $('<div></div>').appendTo(container); | ||||
|          $('<div><i class="red-ui-editableList-item-handle fa fa-bars"></i></div>').appendTo(row); | ||||
|          var typeOptions = { | ||||
|              'input': {types:DEFAULT_ENV_TYPE_LIST}, | ||||
|              'select': {opts:[]}, | ||||
|              'spinner': {}, | ||||
|              'cred': {} | ||||
|          }; | ||||
|          if (ui.opts) { | ||||
|              typeOptions[ui.type] = ui.opts; | ||||
|          } else { | ||||
|              // Pick up the default values if not otherwise provided | ||||
|              ui.opts = typeOptions[ui.type]; | ||||
|          } | ||||
|          var iconCell = $('<div></div>').appendTo(row); | ||||
|  | ||||
|          var iconButton = $('<a href="#"></a>').appendTo(iconCell); | ||||
|          iconButton.on("click", function(evt) { | ||||
|              evt.preventDefault(); | ||||
|              var icon = ui.icon || ""; | ||||
|              var iconPath = (icon ? RED.utils.separateIconPath(icon) : {}); | ||||
|              RED.editor.iconPicker.show(iconButton, null, iconPath, true, function (newIcon) { | ||||
|                  iconButton.empty(); | ||||
|                  var path = newIcon || ""; | ||||
|                  var newPath = RED.utils.separateIconPath(path); | ||||
|                  if (newPath) { | ||||
|                      $('<i class="fa"></i>').addClass(newPath.file).appendTo(iconButton); | ||||
|                  } | ||||
|                  ui.icon = path; | ||||
|              }); | ||||
|          }) | ||||
|  | ||||
|          if (ui.icon) { | ||||
|              var newPath = RED.utils.separateIconPath(ui.icon); | ||||
|              $('<i class="fa '+newPath.file+'"></i>').appendTo(iconButton); | ||||
|          } | ||||
|  | ||||
|          var labelCell = $('<div></div>').appendTo(row); | ||||
|  | ||||
|          var label = ui.label && ui.label[currentLocale] || ""; | ||||
|          var labelInput = $('<input type="text">').val(label).appendTo(labelCell); | ||||
|          ui.labelField = labelInput; | ||||
|          labelInput.on('change', function(evt) { | ||||
|              ui.label = ui.label || {}; | ||||
|              var val = $(this).val().trim(); | ||||
|              if (val === "") { | ||||
|                  delete ui.label[currentLocale]; | ||||
|              } else { | ||||
|                  ui.label[currentLocale] = val; | ||||
|              } | ||||
|          }) | ||||
|          var labelIcon = $('<span class="red-ui-editor-subflow-env-lang-icon"><i class="fa fa-language"></i></span>').appendTo(labelCell); | ||||
|          RED.popover.tooltip(labelIcon,function() { | ||||
|              var langs = Object.keys(ui.label); | ||||
|              var content = $("<div>"); | ||||
|              if (langs.indexOf(currentLocale) === -1) { | ||||
|                  langs.push(currentLocale); | ||||
|                  langs.sort(); | ||||
|              } | ||||
|              langs.forEach(function(l) { | ||||
|                  var row = $('<div>').appendTo(content); | ||||
|                  $('<span>').css({display:"inline-block",width:"120px"}).text(RED._("languages."+l)+(l===currentLocale?"*":"")).appendTo(row); | ||||
|                  $('<span>').text(ui.label[l]||"").appendTo(row); | ||||
|              }); | ||||
|              return content; | ||||
|          }) | ||||
|  | ||||
|          nameField.on('change',function(evt) { | ||||
|             labelInput.attr("placeholder",$(this).val()) | ||||
|         }); | ||||
|  | ||||
|         var inputCell = $('<div></div>').appendTo(row); | ||||
|         var inputCellInput = $('<input type="text">').css("width","100%").appendTo(inputCell); | ||||
|         if (ui.type === "input") { | ||||
|             inputCellInput.val(ui.opts.types.join(",")); | ||||
|         } | ||||
|         var checkbox; | ||||
|         var selectBox; | ||||
|  | ||||
|         inputCellInput.typedInput({ | ||||
|             types: [ | ||||
|                 { | ||||
|                     value:"input", | ||||
|                     label:RED._("editor.inputs.input"), icon:"fa fa-i-cursor",showLabel:false,multiple:true,options:[ | ||||
|                         {value:"str",label:RED._("editor.types.str"),icon:"red/images/typedInput/az.svg"}, | ||||
|                         {value:"num",label:RED._("editor.types.num"),icon:"red/images/typedInput/09.svg"}, | ||||
|                         {value:"bool",label:RED._("editor.types.bool"),icon:"red/images/typedInput/bool.svg"}, | ||||
|                         {value:"json",label:RED._("editor.types.json"),icon:"red/images/typedInput/json.svg"}, | ||||
|                         {value: "bin",label: RED._("editor.types.bin"),icon: "red/images/typedInput/bin.svg"}, | ||||
|                         {value: "env",label: RED._("editor.types.env"),icon: "red/images/typedInput/env.svg"}, | ||||
|                         {value: "cred",label: RED._("editor.types.cred"),icon: "fa fa-lock"} | ||||
|                     ], | ||||
|                     default: DEFAULT_ENV_TYPE_LIST, | ||||
|                     valueLabel: function(container,value) { | ||||
|                         container.css("padding",0); | ||||
|                         var innerContainer = $('<div class="red-ui-editor-subflow-env-input-type"></div>').appendTo(container); | ||||
|  | ||||
|                         var input = $('<div class="placeholder-input">').appendTo(innerContainer); | ||||
|                         $('<span><i class="fa fa-i-cursor"></i></span>').appendTo(input); | ||||
|                         if (value.length) { | ||||
|                             value.forEach(function(v) { | ||||
|                                 if (!/^fa /.test(v.icon)) { | ||||
|                                     $('<img>',{src:v.icon,style:"max-width:14px; padding: 0 3px; margin-top:-4px; margin-left: 1px"}).appendTo(input); | ||||
|                                 } else { | ||||
|                                     var s = $('<span>',{style:"max-width:14px; padding: 0 3px; margin-top:-4px; margin-left: 1px"}).appendTo(input); | ||||
|                                     $("<i>",{class: v.icon}).appendTo(s); | ||||
|                                 } | ||||
|                             }) | ||||
|                         } else { | ||||
|                             $('<span class="red-ui-editor-subflow-env-input-type-placeholder"></span>').text(RED._("editor.selectType")).appendTo(input); | ||||
|                         } | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
|                     value: "cred", | ||||
|                     label: RED._("typedInput.type.cred"), icon:"fa fa-lock", showLabel: false, | ||||
|                     valueLabel: function(container,value) { | ||||
|                         container.css("padding",0); | ||||
|                         var innerContainer = $('<div class="red-ui-editor-subflow-env-input-type">').css({ | ||||
|                             "border-top-right-radius": "4px", | ||||
|                             "border-bottom-right-radius": "4px" | ||||
|                         }).appendTo(container); | ||||
|                         $('<div class="placeholder-input">').html("••••••••").appendTo(innerContainer); | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
|                     value:"select", | ||||
|                     label:RED._("editor.inputs.select"), icon:"fa fa-tasks",showLabel:false, | ||||
|                     valueLabel: function(container,value) { | ||||
|                         container.css("padding","0"); | ||||
|  | ||||
|                         selectBox = $('<select></select>').appendTo(container); | ||||
|                         if (ui.opts && Array.isArray(ui.opts.opts)) { | ||||
|                             ui.opts.opts.forEach(function(o) { | ||||
|                                 var label = lookupLabel(o.l, o.l["en-US"]||o.v, currentLocale); | ||||
|                                 // $('<option>').val((o.t||'str')+":"+o.v).text(label).appendTo(selectBox); | ||||
|                                 $('<option>').val(o.v).text(label).appendTo(selectBox); | ||||
|                             }) | ||||
|                         } | ||||
|                         selectBox.on('change', function(evt) { | ||||
|                             var v = selectBox.val(); | ||||
|                             // var parts = v.split(":"); | ||||
|                             // var t = parts.shift(); | ||||
|                             // v = parts.join(":"); | ||||
|                             // | ||||
|                             // valueField.typedInput("type",'str') | ||||
|                             valueField.typedInput("value",v) | ||||
|                         }); | ||||
|                         selectBox.val(valueField.typedInput("value")); | ||||
|                         // selectBox.val(valueField.typedInput('type')+":"+valueField.typedInput("value")); | ||||
|                     }, | ||||
|                     expand: { | ||||
|                         icon: "fa-caret-down", | ||||
|                         minWidth: 400, | ||||
|                         content: function(container) { | ||||
|                             var content = $('<div class="red-ui-editor-subflow-ui-edit-panel">').appendTo(container); | ||||
|                             var optList = $('<ol>').appendTo(content).editableList({ | ||||
|                                 header:$("<div><div>"+RED._("editor.select.label")+"</div><div>"+RED._("editor.select.value")+"</div></div>"), | ||||
|                                 addItem: function(row,index,itemData) { | ||||
|                                     var labelDiv = $('<div>').appendTo(row); | ||||
|                                     var label = lookupLabel(itemData.l, "", currentLocale); | ||||
|                                     itemData.label = $('<input type="text">').val(label).appendTo(labelDiv); | ||||
|                                     itemData.label.on('keydown', function(evt) { | ||||
|                                         if (evt.keyCode === 13) { | ||||
|                                             itemData.input.focus(); | ||||
|                                             evt.preventDefault(); | ||||
|                                         } | ||||
|                                     }); | ||||
|                                     var labelIcon = $('<span class="red-ui-editor-subflow-env-lang-icon"><i class="fa fa-language"></i></span>').appendTo(labelDiv); | ||||
|                                     RED.popover.tooltip(labelIcon,function() { | ||||
|                                         return currentLocale; | ||||
|                                     }) | ||||
|                                     itemData.input = $('<input type="text">').val(itemData.v).appendTo(row); | ||||
|  | ||||
|                                     // Problem using a TI here: | ||||
|                                     //  - this is in a popout panel | ||||
|                                     //  - clicking the expand button in the TI will close the parent edit tray | ||||
|                                     //    and open the type editor. | ||||
|                                     //  - but it leaves the popout panel over the top. | ||||
|                                     //  - there is no way to get back to the popout panel after closing the type editor | ||||
|                                     //.typedInput({default:itemData.t||'str', types:DEFAULT_ENV_TYPE_LIST}); | ||||
|                                     itemData.input.on('keydown', function(evt) { | ||||
|                                         if (evt.keyCode === 13) { | ||||
|                                             // Enter or Tab | ||||
|                                             var index = optList.editableList('indexOf',itemData); | ||||
|                                             var length = optList.editableList('length'); | ||||
|                                             if (index + 1 === length) { | ||||
|                                                 var newItem = {}; | ||||
|                                                 optList.editableList('addItem',newItem); | ||||
|                                                 setTimeout(function() { | ||||
|                                                     if (newItem.label) { | ||||
|                                                         newItem.label.focus(); | ||||
|                                                     } | ||||
|                                                 },100) | ||||
|                                             } else { | ||||
|                                                 var nextItem = optList.editableList('getItemAt',index+1); | ||||
|                                                 if (nextItem.label) { | ||||
|                                                     nextItem.label.focus() | ||||
|                                                 } | ||||
|                                             } | ||||
|                                             evt.preventDefault(); | ||||
|                                         } | ||||
|                                     }); | ||||
|                                 }, | ||||
|                                 sortable: true, | ||||
|                                 removable: true, | ||||
|                                 height: 160 | ||||
|                             }) | ||||
|                             if (ui.opts.opts.length > 0) { | ||||
|                                 ui.opts.opts.forEach(function(o) { | ||||
|                                     optList.editableList('addItem',$.extend(true,{},o)) | ||||
|                                 }) | ||||
|                             } else { | ||||
|                                 optList.editableList('addItem',{}) | ||||
|                             } | ||||
|                             return { | ||||
|                                 onclose: function() { | ||||
|                                     var items = optList.editableList('items'); | ||||
|                                     var vals = []; | ||||
|                                     items.each(function (i,el) { | ||||
|                                         var data = el.data('data'); | ||||
|                                         var l = data.label.val().trim(); | ||||
|                                         var v = data.input.val(); | ||||
|                                         // var t = data.input.typedInput('type'); | ||||
|                                         // var v = data.input.typedInput('value'); | ||||
|                                         if (l.length > 0) { | ||||
|                                             data.l = data.l || {}; | ||||
|                                             data.l[currentLocale] = l; | ||||
|                                         } | ||||
|                                         data.v = v; | ||||
|  | ||||
|                                         if (l.length > 0 || v.length > 0) { | ||||
|                                             var val = {l:data.l,v:data.v}; | ||||
|                                             // if (t !== 'str') { | ||||
|                                             //     val.t = t; | ||||
|                                             // } | ||||
|                                             vals.push(val); | ||||
|                                         } | ||||
|                                     }); | ||||
|                                     ui.opts.opts = vals; | ||||
|                                     inputCellInput.typedInput('value',Date.now()) | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
|                     value:"checkbox", | ||||
|                     label:RED._("editor.inputs.checkbox"), icon:"fa fa-check-square-o",showLabel:false, | ||||
|                     valueLabel: function(container,value) { | ||||
|                         container.css("padding",0); | ||||
|                         checkbox = $('<input type="checkbox">').appendTo(container); | ||||
|                         checkbox.on('change', function(evt) { | ||||
|                             valueField.typedInput('value',$(this).prop('checked')?"true":"false"); | ||||
|                         }) | ||||
|                         checkbox.prop('checked',valueField.typedInput('value')==="true"); | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
|                     value:"spinner", | ||||
|                     label:RED._("editor.inputs.spinner"), icon:"fa fa-sort-numeric-asc", showLabel:false, | ||||
|                     valueLabel: function(container,value) { | ||||
|                         container.css("padding",0); | ||||
|                         var innerContainer = $('<div class="red-ui-editor-subflow-env-input-type"></div>').appendTo(container); | ||||
|  | ||||
|                         var input = $('<div class="placeholder-input">').appendTo(innerContainer); | ||||
|                         $('<span><i class="fa fa-sort-numeric-asc"></i></span>').appendTo(input); | ||||
|  | ||||
|                         var min = ui.opts && ui.opts.min; | ||||
|                         var max = ui.opts && ui.opts.max; | ||||
|                         var label = ""; | ||||
|                         if (min !== undefined && max !== undefined) { | ||||
|                             label = Math.min(min,max)+" - "+Math.max(min,max); | ||||
|                         } else if (min !== undefined) { | ||||
|                             label = "> "+min; | ||||
|                         } else if (max !== undefined) { | ||||
|                             label = "< "+max; | ||||
|                         } | ||||
|                         $('<span>').css("margin-left","15px").text(label).appendTo(input); | ||||
|                     }, | ||||
|                     expand: { | ||||
|                         icon: "fa-caret-down", | ||||
|                         content: function(container) { | ||||
|                             var content = $('<div class="red-ui-editor-subflow-ui-edit-panel">').appendTo(container); | ||||
|                             content.css("padding","8px 5px") | ||||
|                             var min = ui.opts.min; | ||||
|                             var max = ui.opts.max; | ||||
|                             var minInput = $('<input type="number" style="margin-bottom:0; width:60px">'); | ||||
|                             minInput.val(min); | ||||
|                             var maxInput = $('<input type="number" style="margin-bottom:0; width:60px">'); | ||||
|                             maxInput.val(max); | ||||
|                             $('<div class="form-row" style="margin-bottom:3px"><label>'+RED._("editor.spinner.min")+'</label></div>').append(minInput).appendTo(content); | ||||
|                             $('<div class="form-row" style="margin-bottom:0"><label>'+RED._("editor.spinner.max")+'</label></div>').append(maxInput).appendTo(content); | ||||
|                             return { | ||||
|                                 onclose: function() { | ||||
|                                     var min = minInput.val().trim(); | ||||
|                                     var max = maxInput.val().trim(); | ||||
|                                     if (min !== "") { | ||||
|                                         ui.opts.min = parseInt(min); | ||||
|                                     } else { | ||||
|                                         delete ui.opts.min; | ||||
|                                     } | ||||
|                                     if (max !== "") { | ||||
|                                         ui.opts.max = parseInt(max); | ||||
|                                     } else { | ||||
|                                         delete ui.opts.max; | ||||
|                                     } | ||||
|                                     inputCellInput.typedInput('value',Date.now()) | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
|                     value:"none", | ||||
|                     label:RED._("editor.inputs.none"), icon:"fa fa-times",hasValue:false | ||||
|                 }, | ||||
|                 { | ||||
|                     value:"hide", | ||||
|                     label:RED._("editor.inputs.hidden"), icon:"fa fa-ban",hasValue:false | ||||
|                 } | ||||
|             ], | ||||
|             default: 'none' | ||||
|         }).on("typedinputtypechange", function(evt,type) { | ||||
|             ui.type = $(this).typedInput("type"); | ||||
|             ui.opts = typeOptions[ui.type]; | ||||
|             if (ui.type === 'input') { | ||||
|                 // In the case of 'input' type, the typedInput uses the multiple-option | ||||
|                 // mode. Its value needs to be set to a comma-separately list of the | ||||
|                 // selected options. | ||||
|                 inputCellInput.typedInput('value',ui.opts.types.join(",")) | ||||
|             } else { | ||||
|                 // No other type cares about `value`, but doing this will | ||||
|                 // force a refresh of the label now that `ui.opts` has | ||||
|                 // been updated. | ||||
|                 inputCellInput.typedInput('value',Date.now()) | ||||
|             } | ||||
|  | ||||
|             switch (ui.type) { | ||||
|                 case 'input': | ||||
|                     valueField.typedInput('types',ui.opts.types); | ||||
|                     break; | ||||
|                 case 'select': | ||||
|                     valueField.typedInput('types',['str']); | ||||
|                     break; | ||||
|                 case 'checkbox': | ||||
|                     valueField.typedInput('types',['bool']); | ||||
|                     break; | ||||
|                 case 'spinner': | ||||
|                     valueField.typedInput('types',['num']); | ||||
|                     break; | ||||
|                 case 'cred': | ||||
|                     valueField.typedInput('types',['cred']); | ||||
|                     break; | ||||
|                 default: | ||||
|                     valueField.typedInput('types',DEFAULT_ENV_TYPE_LIST) | ||||
|             } | ||||
|             if (ui.type === 'checkbox') { | ||||
|                 valueField.typedInput('type','bool'); | ||||
|             } else if (ui.type === 'spinner') { | ||||
|                 valueField.typedInput('type','num'); | ||||
|             } | ||||
|             if (ui.type !== 'checkbox') { | ||||
|                 checkbox = null; | ||||
|             } | ||||
|  | ||||
|         }).on("change", function(evt,type) { | ||||
|             if (ui.type === 'input') { | ||||
|                 var types = inputCellInput.typedInput('value'); | ||||
|                 ui.opts.types = (types === "") ? ["str"] : types.split(","); | ||||
|                 valueField.typedInput('types',ui.opts.types); | ||||
|             } | ||||
|         }); | ||||
|         valueField.on("change", function(evt) { | ||||
|             if (checkbox) { | ||||
|                 checkbox.prop('checked',$(this).typedInput('value')==="true") | ||||
|             } | ||||
|         }) | ||||
|         // Set the input to the right type. This will trigger the 'typedinputtypechange' | ||||
|         // event handler (just above ^^) to update the value if needed | ||||
|         inputCellInput.typedInput('type',ui.type) | ||||
|     } | ||||
|  | ||||
|     function buildEnvUIRow(row, tenv, ui, node) { | ||||
|         ui.label = ui.label||{}; | ||||
| @@ -1508,7 +929,7 @@ RED.subflow = (function() { | ||||
|             ui.opts = {}; | ||||
|         } else if (!ui.type) { | ||||
|             ui.type = "input"; | ||||
|             ui.opts = {types:DEFAULT_ENV_TYPE_LIST} | ||||
|             ui.opts = { types: RED.editor.envVarList.DEFAULT_ENV_TYPE_LIST } | ||||
|         } else { | ||||
|             if (!ui.opts) { | ||||
|                 ui.opts = (ui.type === "select") ? {opts:[]} : {}; | ||||
| @@ -1517,7 +938,7 @@ RED.subflow = (function() { | ||||
|  | ||||
|         var labels = ui.label || {}; | ||||
|         var locale = RED.i18n.lang(); | ||||
|         var labelText = lookupLabel(labels, labels["en-US"]||tenv.name, locale); | ||||
|         var labelText = RED.editor.envVarList.lookupLabel(labels, labels["en-US"]||tenv.name, locale); | ||||
|         var label = $('<label>').appendTo(row); | ||||
|         $('<span> </span>').appendTo(row); | ||||
|         var labelContainer = $('<span></span>').appendTo(label); | ||||
| @@ -1570,7 +991,7 @@ RED.subflow = (function() { | ||||
|                 input = $('<select>').css('width','70%').appendTo(row); | ||||
|                 if (ui.opts.opts) { | ||||
|                     ui.opts.opts.forEach(function(o) { | ||||
|                         $('<option>').val(o.v).text(lookupLabel(o.l, o.l['en-US']||o.v, locale)).appendTo(input); | ||||
|                         $('<option>').val(o.v).text(RED.editor.envVarList.lookupLabel(o.l, o.l['en-US']||o.v, locale)).appendTo(input); | ||||
|                     }) | ||||
|                 } | ||||
|                 input.val(val.value); | ||||
| @@ -1636,9 +1057,8 @@ RED.subflow = (function() { | ||||
|      * @param uiContainer - container for UI | ||||
|      * @param envList - env var definitions of template | ||||
|      */ | ||||
|     function buildEnvUI(uiContainer, envList,node) { | ||||
|     function buildEnvUI(uiContainer, envList, node) { | ||||
|         uiContainer.empty(); | ||||
|         var elementID = 0; | ||||
|         for (var i = 0; i < envList.length; i++) { | ||||
|             var tenv = envList[i]; | ||||
|             if (tenv.ui && tenv.ui.type === 'hide') { | ||||
| @@ -1646,8 +1066,6 @@ RED.subflow = (function() { | ||||
|             } | ||||
|             var row = $("<div/>", { class: "form-row" }).appendTo(uiContainer); | ||||
|             buildEnvUIRow(row,tenv, tenv.ui || {}, node); | ||||
|  | ||||
|             // console.log(ui); | ||||
|         } | ||||
|     } | ||||
|     // buildEnvUI | ||||
| @@ -1683,7 +1101,7 @@ RED.subflow = (function() { | ||||
|                             //     icon: "", | ||||
|                             //     label: {}, | ||||
|                             //     type: "input", | ||||
|                             //     opts: {types:DEFAULT_ENV_TYPE_LIST} | ||||
|                             //     opts: {types:RED.editor.envVarList.DEFAULT_ENV_TYPE_LIST} | ||||
|                             // } | ||||
|                             if (!ui.icon) { | ||||
|                                 delete ui.icon; | ||||
| @@ -1693,7 +1111,7 @@ RED.subflow = (function() { | ||||
|                             } | ||||
|                             switch (ui.type) { | ||||
|                                 case "input": | ||||
|                                     if (JSON.stringify(ui.opts) === JSON.stringify({types:DEFAULT_ENV_TYPE_LIST})) { | ||||
|                                     if (JSON.stringify(ui.opts) === JSON.stringify({types:RED.editor.envVarList.DEFAULT_ENV_TYPE_LIST})) { | ||||
|                                         // This is the default input config. Delete it as it will | ||||
|                                         // be applied automatically | ||||
|                                         delete ui.type; | ||||
| @@ -1820,7 +1238,7 @@ RED.subflow = (function() { | ||||
|                     ui.type = "cred"; | ||||
|                 } else { | ||||
|                     ui.type = "input"; | ||||
|                     ui.opts = {types:DEFAULT_ENV_TYPE_LIST} | ||||
|                     ui.opts = {types:RED.editor.envVarList.DEFAULT_ENV_TYPE_LIST} | ||||
|                 } | ||||
|             } else { | ||||
|                 ui.opts = ui.opts || {}; | ||||
| @@ -1867,36 +1285,15 @@ RED.subflow = (function() { | ||||
|         return 'node-input-subflow-env-'+name.replace(/[^a-z0-9-_]/ig,"_"); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Lookup text for specific locale | ||||
|      * @param labels - dict of labels | ||||
|      * @param defaultLabel - fallback label if not found | ||||
|      * @param locale - target locale | ||||
|      * @returns {string} text for specified locale | ||||
|      */ | ||||
|     function lookupLabel(labels, defaultLabel, locale) { | ||||
|         if (labels) { | ||||
|             if (labels[locale]) { | ||||
|                 return labels[locale]; | ||||
|             } | ||||
|             if (locale) { | ||||
|                 var lang = locale.substring(0, 2); | ||||
|                 if (labels[lang]) { | ||||
|                     return labels[lang]; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return defaultLabel; | ||||
|     } | ||||
|  | ||||
|     // Called by subflow.oneditprepare for both instances and templates | ||||
|     function buildEditForm(type,node) { | ||||
|         if (type === "subflow-template") { | ||||
|             // This is called by the `properties` edit pane when | ||||
|             // editing a subflow template. | ||||
|             buildPropertiesList($('#node-input-env-container'), node); | ||||
|             // This is the tabbed UI that offers the env list - with UI options | ||||
|             // plus the preview tab | ||||
|             buildEnvControl($('#node-input-env-container'), node); | ||||
|             RED.editor.envVarList.create($('#node-input-env-container'), node); | ||||
|         } else  if (type === "subflow") { | ||||
|             // This gets called by the subflow type `oneditprepare` function | ||||
|             // registered in nodes.js#addSubflow() | ||||
|             // This is the rendered version of the subflow env var list | ||||
|             buildEnvUI($("#subflow-input-ui"), getSubflowInstanceParentEnv(node), node); | ||||
|         } | ||||
|     } | ||||
| @@ -1912,7 +1309,6 @@ RED.subflow = (function() { | ||||
|         removeStatus: removeSubflowStatus, | ||||
|  | ||||
|         buildEditForm: buildEditForm, | ||||
|         buildPropertiesList: buildPropertiesList, | ||||
|  | ||||
|         exportSubflowTemplateEnv: exportEnvList, | ||||
|         exportSubflowInstanceEnv: exportSubflowInstanceEnv | ||||
|   | ||||
		Reference in New Issue
	
	Block a user