diff --git a/editor/js/nodes.js b/editor/js/nodes.js index 062654ca2..d1ff205ab 100644 --- a/editor/js/nodes.js +++ b/editor/js/nodes.js @@ -509,9 +509,9 @@ RED.nodes = (function() { node.icon = n.icon; } } - if (n.info) { - node.info = n.info; - } + } + if (n.info) { + node.info = n.info; } return node; } @@ -907,7 +907,14 @@ RED.nodes = (function() { } if (!existingConfigNode || existingConfigNode._def.exclusive) { //} || !compareNodes(existingConfigNode,n,true) || existingConfigNode.z !== n.z) { - configNode = {id:n.id, z:n.z, type:n.type, users:[], _config:{}}; + configNode = { + id:n.id, + z:n.z, + type:n.type, + info: n.info, + users:[], + _config:{} + }; for (d in def.defaults) { if (def.defaults.hasOwnProperty(d)) { configNode[d] = n[d]; diff --git a/editor/js/ui/editor.js b/editor/js/ui/editor.js index 634006963..73ef5e6b7 100644 --- a/editor/js/ui/editor.js +++ b/editor/js/ui/editor.js @@ -20,7 +20,6 @@ RED.editor = (function() { var editing_node = null; var editing_config_node = null; var subflowEditor; - var nodeInfoEditor; var editTrayWidthCache = {}; @@ -773,7 +772,7 @@ RED.editor = (function() { searchInput.focus(); } - function buildLabelForm(container,node) { + function buildAppearanceForm(container,node) { var dialogForm = $('
').appendTo(container); var inputCount = node.inputs || node._def.inputs || 0; @@ -840,20 +839,6 @@ RED.editor = (function() { }) $('
').text(node.icon).appendTo(iconRow); } - - if (node.type.indexOf("subflow") != 0 && node.type !== "comment") { - $('
').appendTo(dialogForm); - $('
').appendTo(dialogForm); - $('
').appendTo(dialogForm); - nodeInfoEditor = RED.editor.createEditor({ - id: 'node-info-input-info-editor', - mode: 'ace/mode/markdown', - value: "" - }); - if (node.info) { - nodeInfoEditor.getSession().setValue(node.info, -1); - } - } } function updateLabels(editing_node, changes, outputMap) { @@ -897,10 +882,27 @@ RED.editor = (function() { return changed; } + function buildDescriptionForm(container,node) { + var dialogForm = $('
').appendTo(container); + $('
').appendTo(dialogForm); + var nodeInfoEditor = RED.editor.createEditor({ + id: "node-info-input-info-editor", + mode: 'ace/mode/markdown', + value: "" + }); + if (node.info) { + nodeInfoEditor.getSession().setValue(node.info, -1); + } + return nodeInfoEditor; + } + function showEditDialog(node) { var editing_node = node; var isDefaultIcon; var defaultIcon; + var nodeInfoEditor; + var finishedBuilding = false; + editStack.push(node); RED.view.state(RED.state.EDITING); var type = node.type; @@ -1141,8 +1143,31 @@ RED.editor = (function() { } } - if (node.type.indexOf("subflow") != 0 && node.type !== "comment") { - node.info = nodeInfoEditor.getValue(); + var oldInfo = node.info; + if (nodeInfoEditor) { + var newInfo = nodeInfoEditor.getValue(); + if (!!oldInfo) { + // Has existing info property + if (newInfo.trim() === "") { + // New value is blank - remove the property + changed = true; + changes.info = oldInfo; + delete node.info; + } else if (newInfo !== oldInfo) { + // New value is different + changed = true; + changes.info = oldInfo; + node.info = newInfo; + } + } else { + // No existing info + if (newInfo.trim() !== "") { + // New value is not blank + changed = true; + changes.info = undefined; + node.info = newInfo; + } + } } if (changed) { @@ -1193,8 +1218,8 @@ RED.editor = (function() { ], resize: function(dimensions) { editTrayWidthCache[type] = dimensions.width; - $(".editor-tray-content").height(dimensions.height - 78); - var form = $(".editor-tray-content form").height(dimensions.height - 78 - 40); + $(".editor-tray-content").height(dimensions.height - 50); + var form = $(".editor-tray-content form").height(dimensions.height - 50 - 40); if (editing_node && editing_node._def.oneditresize) { try { editing_node._def.oneditresize.call(editing_node,{width:form.width(),height:form.height()}); @@ -1208,25 +1233,23 @@ RED.editor = (function() { var trayBody = tray.find('.editor-tray-body'); trayBody.parent().css('overflow','hidden'); - var stack = RED.stack.create({ - container: trayBody, - singleExpanded: true - }); - var nodeProperties = stack.add({ - title: RED._("editor.nodeProperties"), - expanded: true - }); - nodeProperties.content.addClass("editor-tray-content"); + var editorTabEl = $('').appendTo(trayBody); + var editorContent = $('
').appendTo(trayBody); - var portLabels = stack.add({ - title: RED._("editor.portLabels"), - onexpand: function() { - refreshLabelForm(this.content,node); - } + var editorTabs = RED.tabs.create({ + element:editorTabEl, + onchange:function(tab) { + editorContent.children().hide(); + if (tab.onchange) { + tab.onchange.call(tab); + } + tab.content.show(); + if (finishedBuilding) { + RED.tray.resize(); + } + }, + collapsible: true }); - portLabels.content.addClass("editor-tray-content"); - - if (editing_node) { RED.sidebar.info.refresh(editing_node); } @@ -1243,11 +1266,48 @@ RED.editor = (function() { } else { isDefaultIcon = true; } - buildEditForm(nodeProperties.content,"dialog-form",type,ns); - buildLabelForm(portLabels.content,node); + + var nodePropertiesTab = { + id: "editor-tab-properties", + label: "Properties", + name: "Properties", + content: $('
', {class:"editor-tray-content"}).appendTo(editorContent).hide(), + iconClass: "fa fa-cog" + }; + buildEditForm(nodePropertiesTab.content,"dialog-form",type,ns); + editorTabs.addTab(nodePropertiesTab); + + if (!node._def.defaults || !node._def.defaults.hasOwnProperty('info')) { + var descriptionTab = { + id: "editor-tab-description", + label: "Description", + name: "Description", + content: $('
', {class:"editor-tray-content"}).appendTo(editorContent).hide(), + iconClass: "fa fa-file-text-o", + onchange: function() { + nodeInfoEditor.focus(); + } + }; + editorTabs.addTab(descriptionTab); + nodeInfoEditor = buildDescriptionForm(descriptionTab.content,node); + } + + var appearanceTab = { + id: "editor-tab-appearance", + label: "Appearance", + name: "Appearance", + content: $('
', {class:"editor-tray-content"}).appendTo(editorContent).hide(), + iconClass: "fa fa-object-group", + onchange: function() { + refreshLabelForm(this.content,node); + } + }; + buildAppearanceForm(appearanceTab.content,node); + editorTabs.addTab(appearanceTab); prepareEditDialog(node,node._def,"node-input", function() { trayBody.i18n(); + finishedBuilding = true; done(); }); }, @@ -1259,8 +1319,9 @@ RED.editor = (function() { RED.sidebar.info.refresh(editing_node); } RED.workspaces.refresh(); - if (node.type.indexOf("subflow") != 0 && node.type !== "comment") { + if (nodeInfoEditor) { nodeInfoEditor.destroy(); + nodeInfoEditor = null; } RED.view.redraw(true); editStack.pop(); @@ -1299,6 +1360,8 @@ RED.editor = (function() { var adding = (id == "_ADD_"); var node_def = RED.nodes.getType(type); var editing_config_node = RED.nodes.node(id); + var nodeInfoEditor; + var finishedBuilding = false; var ns; if (node_def.set.module === "node-red") { @@ -1331,7 +1394,8 @@ RED.editor = (function() { RED.view.state(RED.state.EDITING); var trayOptions = { title: getEditStackTitle(), //(adding?RED._("editor.addNewConfig", {type:type}):RED._("editor.editConfig", {type:type})), - resize: function() { + resize: function(dimensions) { + $(".editor-tray-content").height(dimensions.height - 50); if (editing_config_node && editing_config_node._def.oneditresize) { var form = $("#node-config-dialog-edit-form"); try { @@ -1343,6 +1407,7 @@ RED.editor = (function() { }, open: function(tray, done) { var trayHeader = tray.find(".editor-tray-header"); + var trayBody = tray.find('.editor-tray-body'); var trayFooter = tray.find(".editor-tray-footer"); if (node_def.hasUsers !== false) { @@ -1350,7 +1415,49 @@ RED.editor = (function() { } trayFooter.append(''); - var dialogForm = buildEditForm(tray.find('.editor-tray-body'),"node-config-dialog-edit-form",type,ns); + var editorTabEl = $('
    ').appendTo(trayBody); + var editorContent = $('
    ').appendTo(trayBody); + + var editorTabs = RED.tabs.create({ + element:editorTabEl, + onchange:function(tab) { + editorContent.children().hide(); + if (tab.onchange) { + tab.onchange.call(tab); + } + tab.content.show(); + if (finishedBuilding) { + RED.tray.resize(); + } + }, + collapsible: true + }); + + var nodePropertiesTab = { + id: "editor-tab-cproperties", + label: "Properties", + name: "Properties", + content: $('
    ', {class:"editor-tray-content"}).appendTo(editorContent).hide(), + iconClass: "fa fa-cog" + }; + editorTabs.addTab(nodePropertiesTab); + buildEditForm(nodePropertiesTab.content,"node-config-dialog-edit-form",type,ns); + + if (!node_def.defaults || !node_def.defaults.hasOwnProperty('info')) { + var descriptionTab = { + id: "editor-tab-description", + label: "Description", + name: "Description", + content: $('
    ', {class:"editor-tray-content"}).appendTo(editorContent).hide(), + iconClass: "fa fa-file-text-o", + onchange: function() { + nodeInfoEditor.focus(); + } + }; + editorTabs.addTab(descriptionTab); + nodeInfoEditor = buildDescriptionForm(descriptionTab.content,editing_config_node); + } + prepareEditDialog(editing_config_node,node_def,"node-config-input", function() { if (editing_config_node._def.exclusive) { @@ -1398,17 +1505,20 @@ RED.editor = (function() { } }); } - tabSelect.i18n(); - - dialogForm.i18n(); if (node_def.hasUsers !== false) { $("#node-config-dialog-user-count").find("span").text(RED._("editor.nodesUse", {count:editing_config_node.users.length})).parent().show(); } + trayBody.i18n(); + finishedBuilding = true; done(); }); }, close: function() { RED.workspaces.refresh(); + if (nodeInfoEditor) { + nodeInfoEditor.destroy(); + nodeInfoEditor = null; + } editStack.pop(); }, show: function() { @@ -1502,6 +1612,31 @@ RED.editor = (function() { } } } + + if (nodeInfoEditor) { + editing_config_node.info = nodeInfoEditor.getValue(); + + var oldInfo = editing_config_node.info; + if (nodeInfoEditor) { + var newInfo = nodeInfoEditor.getValue(); + if (!!oldInfo) { + // Has existing info property + if (newInfo.trim() === "") { + // New value is blank - remove the property + delete editing_config_node.info; + } else if (newInfo !== oldInfo) { + // New value is different + editing_config_node.info = newInfo; + } + } else { + // No existing info + if (newInfo.trim() !== "") { + // New value is not blank + editing_config_node.info = newInfo; + } + } + } + } editing_config_node.label = configTypeDef.label; editing_config_node.z = scope; @@ -1689,7 +1824,7 @@ RED.editor = (function() { editStack.push(subflow); RED.view.state(RED.state.EDITING); var subflowEditor; - + var finishedBuilding = false; var trayOptions = { title: getEditStackTitle(), buttons: [ @@ -1790,48 +1925,76 @@ RED.editor = (function() { } ], resize: function(dimensions) { - $(".editor-tray-content").height(dimensions.height - 78); - var form = $(".editor-tray-content form").height(dimensions.height - 78 - 40); - - var rows = $("#dialog-form>div:not(.node-text-editor-row)"); - var editorRow = $("#dialog-form>div.node-text-editor-row"); - var height = $("#dialog-form").height(); - for (var i=0;i').appendTo(trayBody); + var editorContent = $('
    ').appendTo(trayBody); + + var editorTabs = RED.tabs.create({ + element:editorTabEl, + onchange:function(tab) { + editorContent.children().hide(); + if (tab.onchange) { + tab.onchange.call(tab); + } + tab.content.show(); + if (finishedBuilding) { + RED.tray.resize(); + } + }, + collapsible: true }); + var nodePropertiesTab = { + id: "editor-tab-properties", + label: "Properties", + name: "Properties", + content: $('
    ', {class:"editor-tray-content"}).appendTo(editorContent).hide(), + iconClass: "fa fa-cog" + }; + buildEditForm(nodePropertiesTab.content,"dialog-form","subflow-template"); + editorTabs.addTab(nodePropertiesTab); + + var descriptionTab = { + id: "editor-tab-description", + label: "Description", + name: "Description", + content: $('
    ', {class:"editor-tray-content"}).appendTo(editorContent).hide(), + iconClass: "fa fa-file-text-o", + onchange: function() { + subflowEditor.focus(); + } + }; + editorTabs.addTab(descriptionTab); + subflowEditor = buildDescriptionForm(descriptionTab.content,editing_node); + + var appearanceTab = { + id: "editor-tab-appearance", + label: "Appearance", + name: "Appearance", + content: $('
    ', {class:"editor-tray-content"}).appendTo(editorContent).hide(), + iconClass: "fa fa-object-group", + onchange: function() { + refreshLabelForm(this.content,editing_node); + } + }; + buildAppearanceForm(appearanceTab.content,editing_node); + editorTabs.addTab(appearanceTab); + + + + $("#subflow-input-name").val(subflow.name); RED.text.bidi.prepareInput($("#subflow-input-name")); @@ -1858,10 +2021,7 @@ RED.editor = (function() { } }) - $("#subflow-input-category").val(subflow.category||"subflows"); - - subflowEditor.getSession().setValue(subflow.info||"",-1); var userCount = 0; var subflowType = "subflow:"+editing_node.id; @@ -1872,8 +2032,8 @@ RED.editor = (function() { }); $("#subflow-dialog-user-count").text(RED._("subflow.subflowInstances", {count:userCount})).show(); - buildLabelForm(portLabels.content,subflow); trayBody.i18n(); + finishedBuilding = true; }, close: function() { if (RED.view.state() != RED.state.IMPORT_DRAGGING) { @@ -1882,6 +2042,7 @@ RED.editor = (function() { RED.sidebar.info.refresh(editing_node); RED.workspaces.refresh(); subflowEditor.destroy(); + subflowEditor = null; editStack.pop(); editing_node = null; }, diff --git a/editor/js/ui/tray.js b/editor/js/ui/tray.js index 3c6a78a6b..2fdbb2ac8 100644 --- a/editor/js/ui/tray.js +++ b/editor/js/ui/tray.js @@ -232,6 +232,7 @@ RED.tray = (function() { } }, + resize: handleWindowResize, close: function close(done) { if (stack.length > 0) { var tray = stack.pop(); diff --git a/editor/templates/index.mst b/editor/templates/index.mst index e63008584..5815b5afb 100644 --- a/editor/templates/index.mst +++ b/editor/templates/index.mst @@ -136,13 +136,6 @@
    -
    - - -
    -
    -
    -