mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Support ctrl-click selection of flow tabs
This commit is contained in:
		| @@ -91,12 +91,15 @@ RED.history = (function() { | |||||||
|             } else if (ev.t == "delete") { |             } else if (ev.t == "delete") { | ||||||
|                 if (ev.workspaces) { |                 if (ev.workspaces) { | ||||||
|                     for (i=0;i<ev.workspaces.length;i++) { |                     for (i=0;i<ev.workspaces.length;i++) { | ||||||
|                         RED.nodes.addWorkspace(ev.workspaces[i]); |                         RED.nodes.addWorkspace(ev.workspaces[i],ev.workspaces[i]._index); | ||||||
|                         RED.workspaces.add(ev.workspaces[i]); |                         RED.workspaces.add(ev.workspaces[i],undefined,ev.workspaces[i]._index); | ||||||
|  |                         delete ev.workspaces[i]._index; | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 if (ev.subflow && ev.subflow.subflow) { |                 if (ev.subflows) { | ||||||
|                     RED.nodes.addSubflow(ev.subflow.subflow); |                     for (i=0;i<ev.subflows.length;i++) { | ||||||
|  |                         RED.nodes.addSubflow(ev.subflows[i]); | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|                 if (ev.subflowInputs && ev.subflowInputs.length > 0) { |                 if (ev.subflowInputs && ev.subflowInputs.length > 0) { | ||||||
|                     subflow = RED.nodes.subflow(ev.subflowInputs[0].z); |                     subflow = RED.nodes.subflow(ev.subflowInputs[0].z); | ||||||
|   | |||||||
| @@ -291,9 +291,18 @@ RED.clipboard = (function() { | |||||||
|             var flow = ""; |             var flow = ""; | ||||||
|             var nodes = null; |             var nodes = null; | ||||||
|             if (type === 'export-range-selected') { |             if (type === 'export-range-selected') { | ||||||
|                 var selection = RED.view.selection(); |                 var selection = RED.workspaces.selection(); | ||||||
|  |                 if (selection.length > 0) { | ||||||
|  |                     nodes = []; | ||||||
|  |                     selection.forEach(function(n) { | ||||||
|  |                         nodes.push(n); | ||||||
|  |                         nodes = nodes.concat(RED.nodes.filterNodes({z:n.id})); | ||||||
|  |                     }); | ||||||
|  |                 } else { | ||||||
|  |                     nodes = RED.view.selection().nodes||[]; | ||||||
|  |                 } | ||||||
|                 // Don't include the subflow meta-port nodes in the exported selection |                 // Don't include the subflow meta-port nodes in the exported selection | ||||||
|                 nodes = RED.nodes.createExportableNodeSet(selection.nodes.filter(function(n) { return n.type !== 'subflow'})); |                 nodes = RED.nodes.createExportableNodeSet(nodes.filter(function(n) { return n.type !== 'subflow'})); | ||||||
|             } else if (type === 'export-range-flow') { |             } else if (type === 'export-range-flow') { | ||||||
|                 var activeWorkspace = RED.workspaces.active(); |                 var activeWorkspace = RED.workspaces.active(); | ||||||
|                 nodes = RED.nodes.filterNodes({z:activeWorkspace}); |                 nodes = RED.nodes.filterNodes({z:activeWorkspace}); | ||||||
| @@ -323,12 +332,17 @@ RED.clipboard = (function() { | |||||||
|         $("#clipboard-dialog-cancel").hide(); |         $("#clipboard-dialog-cancel").hide(); | ||||||
|         $("#clipboard-dialog-copy").hide(); |         $("#clipboard-dialog-copy").hide(); | ||||||
|         $("#clipboard-dialog-close").hide(); |         $("#clipboard-dialog-close").hide(); | ||||||
|         var selection = RED.view.selection(); |         var selection = RED.workspaces.selection(); | ||||||
|         if (selection.nodes) { |         if (selection.length > 0) { | ||||||
|             $("#export-range-selected").click(); |             $("#export-range-selected").click(); | ||||||
|         } else { |         } else { | ||||||
|             $("#export-range-selected").addClass('disabled').removeClass('selected'); |             selection = RED.view.selection(); | ||||||
|             $("#export-range-flow").click(); |             if (selection.nodes) { | ||||||
|  |                 $("#export-range-selected").click(); | ||||||
|  |             } else { | ||||||
|  |                 $("#export-range-selected").addClass('disabled').removeClass('selected'); | ||||||
|  |                 $("#export-range-flow").click(); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|         if (format === "export-format-full") { |         if (format === "export-format-full") { | ||||||
|             $("#export-format-full").click(); |             $("#export-format-full").click(); | ||||||
|   | |||||||
| @@ -161,11 +161,86 @@ RED.tabs = (function() { | |||||||
|         ul.children().first().addClass("active"); |         ul.children().first().addClass("active"); | ||||||
|         ul.children().addClass("red-ui-tab"); |         ul.children().addClass("red-ui-tab"); | ||||||
|  |  | ||||||
|         function onTabClick() { |         function getSelection() { | ||||||
|             if (options.onclick) { |             var selection = ul.find("li.red-ui-tab.selected"); | ||||||
|                 options.onclick(tabs[$(this).attr('href').slice(1)]); |             var selectedTabs = []; | ||||||
|  |             selection.each(function() { | ||||||
|  |                 selectedTabs.push(tabs[$(this).find('a').attr('href').slice(1)]) | ||||||
|  |             }) | ||||||
|  |             return selectedTabs; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         function selectionChanged() { | ||||||
|  |             options.onselect(getSelection()); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         function onTabClick(evt) { | ||||||
|  |             evt.preventDefault(); | ||||||
|  |             var currentTab = ul.find("li.red-ui-tab.active"); | ||||||
|  |             var thisTab = $(this).parent(); | ||||||
|  |             var fireSelectionChanged = false; | ||||||
|  |             if (options.onselect) { | ||||||
|  |                 if (evt.metaKey) { | ||||||
|  |                     if (thisTab.hasClass("selected")) { | ||||||
|  |                         thisTab.removeClass("selected"); | ||||||
|  |                         if (thisTab[0] !== currentTab[0]) { | ||||||
|  |                             // Deselect background tab | ||||||
|  |                             // - don't switch to it | ||||||
|  |                             selectionChanged(); | ||||||
|  |                             return; | ||||||
|  |                         } else { | ||||||
|  |                             // Deselect current tab | ||||||
|  |                             // - if nothing remains selected, do nothing | ||||||
|  |                             // - otherwise switch to first selected tab | ||||||
|  |                             var selection = ul.find("li.red-ui-tab.selected"); | ||||||
|  |                             if (selection.length === 0) { | ||||||
|  |                                 selectionChanged(); | ||||||
|  |                                 return; | ||||||
|  |                             } | ||||||
|  |                             thisTab = selection.first(); | ||||||
|  |                         } | ||||||
|  |                     } else { | ||||||
|  |                         if (!currentTab.hasClass("selected")) { | ||||||
|  |                             var currentTabObj = tabs[currentTab.find('a').attr('href').slice(1)]; | ||||||
|  |                             // Auto select current tab | ||||||
|  |                             currentTab.addClass("selected"); | ||||||
|  |                         } | ||||||
|  |                         thisTab.addClass("selected"); | ||||||
|  |                     } | ||||||
|  |                     fireSelectionChanged = true; | ||||||
|  |                 } else if (evt.shiftKey) { | ||||||
|  |                     if (currentTab[0] !== thisTab[0]) { | ||||||
|  |                         var firstTab,lastTab; | ||||||
|  |                         if (currentTab.index() < thisTab.index()) { | ||||||
|  |                             firstTab = currentTab; | ||||||
|  |                             lastTab = thisTab; | ||||||
|  |                         } else { | ||||||
|  |                             firstTab = thisTab; | ||||||
|  |                             lastTab = currentTab; | ||||||
|  |                         } | ||||||
|  |                         ul.find("li.red-ui-tab").removeClass("selected"); | ||||||
|  |                         firstTab.addClass("selected"); | ||||||
|  |                         lastTab.addClass("selected"); | ||||||
|  |                         firstTab.nextUntil(lastTab).addClass("selected"); | ||||||
|  |                     } | ||||||
|  |                     fireSelectionChanged = true; | ||||||
|  |                 } else { | ||||||
|  |                     var selection = ul.find("li.red-ui-tab.selected"); | ||||||
|  |                     if (selection.length > 0) { | ||||||
|  |                         selection.removeClass("selected"); | ||||||
|  |                         fireSelectionChanged = true; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             var thisTabA = thisTab.find("a"); | ||||||
|  |             if (options.onclick) { | ||||||
|  |                 options.onclick(tabs[thisTabA.attr('href').slice(1)]); | ||||||
|  |             } | ||||||
|  |             activateTab(thisTabA); | ||||||
|  |             if (fireSelectionChanged) { | ||||||
|  |                 selectionChanged(); | ||||||
|             } |             } | ||||||
|             activateTab($(this)); |  | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -186,7 +261,12 @@ RED.tabs = (function() { | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         function onTabDblClick() { |         function onTabDblClick(evt) { | ||||||
|  |             evt.preventDefault(); | ||||||
|  |             evt.stopPropagation(); | ||||||
|  |             if (evt.metaKey || evt.shiftKey) { | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|             if (options.ondblclick) { |             if (options.ondblclick) { | ||||||
|                 options.ondblclick(tabs[$(this).attr('href').slice(1)]); |                 options.ondblclick(tabs[$(this).attr('href').slice(1)]); | ||||||
|             } |             } | ||||||
| @@ -288,23 +368,23 @@ RED.tabs = (function() { | |||||||
|                         currentActiveTabWidth = 0; |                         currentActiveTabWidth = 0; | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 if (options.collapsible) { |                 // if (options.collapsible) { | ||||||
|                     console.log(currentTabWidth); |                 //     console.log(currentTabWidth); | ||||||
|                 } |                 // } | ||||||
|  |  | ||||||
|                 tabs.css({width:currentTabWidth}); |                 tabs.css({width:currentTabWidth}); | ||||||
|                 if (tabWidth < 50) { |                 if (tabWidth < 50) { | ||||||
|                     ul.find(".red-ui-tab-close").hide(); |                     // ul.find(".red-ui-tab-close").hide(); | ||||||
|                     ul.find(".red-ui-tab-icon").hide(); |                     ul.find(".red-ui-tab-icon").hide(); | ||||||
|                     ul.find(".red-ui-tab-label").css({paddingLeft:Math.min(12,Math.max(0,tabWidth-38))+"px"}) |                     ul.find(".red-ui-tab-label").css({paddingLeft:Math.min(12,Math.max(0,tabWidth-38))+"px"}) | ||||||
|                 } else { |                 } else { | ||||||
|                     ul.find(".red-ui-tab-close").show(); |                     // ul.find(".red-ui-tab-close").show(); | ||||||
|                     ul.find(".red-ui-tab-icon").show(); |                     ul.find(".red-ui-tab-icon").show(); | ||||||
|                     ul.find(".red-ui-tab-label").css({paddingLeft:""}) |                     ul.find(".red-ui-tab-label").css({paddingLeft:""}) | ||||||
|                 } |                 } | ||||||
|                 if (currentActiveTabWidth !== 0) { |                 if (currentActiveTabWidth !== 0) { | ||||||
|                     ul.find("li.red-ui-tab.active").css({"width":options.minimumActiveTabWidth}); |                     ul.find("li.red-ui-tab.active").css({"width":options.minimumActiveTabWidth}); | ||||||
|                     ul.find("li.red-ui-tab.active .red-ui-tab-close").show(); |                     // ul.find("li.red-ui-tab.active .red-ui-tab-close").show(); | ||||||
|                     ul.find("li.red-ui-tab.active .red-ui-tab-icon").show(); |                     ul.find("li.red-ui-tab.active .red-ui-tab-icon").show(); | ||||||
|                     ul.find("li.red-ui-tab.active .red-ui-tab-label").css({paddingLeft:""}) |                     ul.find("li.red-ui-tab.active .red-ui-tab-label").css({paddingLeft:""}) | ||||||
|                 } |                 } | ||||||
| @@ -319,6 +399,13 @@ RED.tabs = (function() { | |||||||
|  |  | ||||||
|  |  | ||||||
|         function removeTab(id) { |         function removeTab(id) { | ||||||
|  |             if (options.onselect) { | ||||||
|  |                 var selection = ul.find("li.red-ui-tab.selected"); | ||||||
|  |                 if (selection.length > 0) { | ||||||
|  |                     selection.removeClass("selected"); | ||||||
|  |                     selectionChanged(); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|             var li = ul.find("a[href='#"+id+"']").parent(); |             var li = ul.find("a[href='#"+id+"']").parent(); | ||||||
|             if (li.hasClass("active")) { |             if (li.hasClass("active")) { | ||||||
|                 var tab = li.prev(); |                 var tab = li.prev(); | ||||||
| @@ -341,14 +428,24 @@ RED.tabs = (function() { | |||||||
|  |  | ||||||
|         return { |         return { | ||||||
|             addTab: function(tab,targetIndex) { |             addTab: function(tab,targetIndex) { | ||||||
|  |                 if (options.onselect) { | ||||||
|  |                     var selection = ul.find("li.red-ui-tab.selected"); | ||||||
|  |                     if (selection.length > 0) { | ||||||
|  |                         selection.removeClass("selected"); | ||||||
|  |                         selectionChanged(); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|                 tabs[tab.id] = tab; |                 tabs[tab.id] = tab; | ||||||
|                 var li = $("<li/>",{class:"red-ui-tab"}); |                 var li = $("<li/>",{class:"red-ui-tab"}); | ||||||
|                 if (targetIndex === undefined) { |                 if (ul.children().length === 0) { | ||||||
|                     li.appendTo(ul); |                     targetIndex = undefined; | ||||||
|                 } else if (targetIndex === 0) { |                 } | ||||||
|  |                 if (targetIndex === 0) { | ||||||
|                     li.prependTo(ul); |                     li.prependTo(ul); | ||||||
|                 } else { |                 } else if (targetIndex > 0) { | ||||||
|                     li.insertAfter(ul.find("li:nth-child("+(targetIndex)+")")); |                     li.insertAfter(ul.find("li:nth-child("+(targetIndex)+")")); | ||||||
|  |                 } else { | ||||||
|  |                     li.appendTo(ul); | ||||||
|                 } |                 } | ||||||
|                 li.attr('id',"red-ui-tab-"+(tab.id.replace(".","-"))); |                 li.attr('id',"red-ui-tab-"+(tab.id.replace(".","-"))); | ||||||
|                 li.data("tabId",tab.id); |                 li.data("tabId",tab.id); | ||||||
| @@ -400,15 +497,23 @@ RED.tabs = (function() { | |||||||
|                 } |                 } | ||||||
|                 link.on("click",onTabClick); |                 link.on("click",onTabClick); | ||||||
|                 link.on("dblclick",onTabDblClick); |                 link.on("dblclick",onTabDblClick); | ||||||
|  |  | ||||||
|  |  | ||||||
|                 if (tab.closeable) { |                 if (tab.closeable) { | ||||||
|  |                     li.addClass("red-ui-tabs-closeable") | ||||||
|                     var closeLink = $("<a/>",{href:"#",class:"red-ui-tab-close"}).appendTo(li); |                     var closeLink = $("<a/>",{href:"#",class:"red-ui-tab-close"}).appendTo(li); | ||||||
|                     closeLink.append('<i class="fa fa-times" />'); |                     closeLink.append('<i class="fa fa-times" />'); | ||||||
|  |  | ||||||
|                     closeLink.on("click",function(event) { |                     closeLink.on("click",function(event) { | ||||||
|                         event.preventDefault(); |                         event.preventDefault(); | ||||||
|                         removeTab(tab.id); |                         removeTab(tab.id); | ||||||
|                     }); |                     }); | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|  |                 var badges = $('<span class="red-ui-tabs-badges"></span>').appendTo(li); | ||||||
|  |                 if (options.onselect) { | ||||||
|  |                     $('<i class="red-ui-tabs-badge-changed fa fa-circle"></i>').appendTo(badges); | ||||||
|  |                     $('<i class="red-ui-tabs-badge-selected fa fa-check-circle"></i>').appendTo(badges); | ||||||
|  |                 } | ||||||
|                 if (options.onadd) { |                 if (options.onadd) { | ||||||
|                     options.onadd(tab); |                     options.onadd(tab); | ||||||
|                 } |                 } | ||||||
| @@ -516,6 +621,7 @@ RED.tabs = (function() { | |||||||
|                 tab.find("span.bidiAware").text(label).attr('dir', RED.text.bidi.resolveBaseTextDir(label)); |                 tab.find("span.bidiAware").text(label).attr('dir', RED.text.bidi.resolveBaseTextDir(label)); | ||||||
|                 updateTabWidths(); |                 updateTabWidths(); | ||||||
|             }, |             }, | ||||||
|  |             selection: getSelection, | ||||||
|             order: function(order) { |             order: function(order) { | ||||||
|                 var existingTabOrder = $.makeArray(ul.children().map(function() { return $(this).data('tabId');})); |                 var existingTabOrder = $.makeArray(ul.children().map(function() { return $(this).data('tabId');})); | ||||||
|                 if (existingTabOrder.length !== order.length) { |                 if (existingTabOrder.length !== order.length) { | ||||||
|   | |||||||
| @@ -370,9 +370,7 @@ RED.subflow = (function() { | |||||||
|         return { |         return { | ||||||
|             nodes:removedNodes, |             nodes:removedNodes, | ||||||
|             links:removedLinks, |             links:removedLinks, | ||||||
|             subflow: { |             subflows: [activeSubflow] | ||||||
|                 subflow: activeSubflow |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     function init() { |     function init() { | ||||||
|   | |||||||
| @@ -158,11 +158,37 @@ RED.sidebar.info = (function() { | |||||||
|         } else if (Array.isArray(node)) { |         } else if (Array.isArray(node)) { | ||||||
|             // Multiple things selected |             // Multiple things selected | ||||||
|             // - hide help and info sections |             // - hide help and info sections | ||||||
|  |  | ||||||
|  |             var types = { | ||||||
|  |                 nodes:0, | ||||||
|  |                 flows:0, | ||||||
|  |                 subflows:0 | ||||||
|  |             } | ||||||
|  |             node.forEach(function(n) { | ||||||
|  |                 if (n.type === 'tab') { | ||||||
|  |                     types.flows++; | ||||||
|  |                     types.nodes += RED.nodes.filterNodes({z:n.id}).length; | ||||||
|  |                 } else if (n.type === 'subflow') { | ||||||
|  |                     types.subflows++; | ||||||
|  |                 } else { | ||||||
|  |                     types.nodes++; | ||||||
|  |                 } | ||||||
|  |             }); | ||||||
|             helpSection.container.hide(); |             helpSection.container.hide(); | ||||||
|             infoSection.container.hide(); |             infoSection.container.hide(); | ||||||
|             // - show the count of selected nodes |             // - show the count of selected nodes | ||||||
|             propRow = $('<tr class="node-info-node-row"><td>'+RED._("sidebar.info.selection")+"</td><td></td></tr>").appendTo(tableBody); |             propRow = $('<tr class="node-info-node-row"><td>'+RED._("sidebar.info.selection")+"</td><td></td></tr>").appendTo(tableBody); | ||||||
|             $(propRow.children()[1]).text(RED._("sidebar.info.nodes",{count:node.length})) |  | ||||||
|  |             var counts = $('<div>').appendTo($(propRow.children()[1])); | ||||||
|  |             if (types.flows > 0) { | ||||||
|  |                 $('<div>').text(RED._("clipboard.flow",{count:types.flows})).appendTo(counts); | ||||||
|  |             } | ||||||
|  |             if (types.subflows > 0) { | ||||||
|  |                 $('<div>').text(RED._("clipboard.subflow",{count:types.subflows})).appendTo(counts); | ||||||
|  |             } | ||||||
|  |             if (types.nodes > 0) { | ||||||
|  |                 $('<div>').text(RED._("clipboard.node",{count:types.nodes})).appendTo(counts); | ||||||
|  |             } | ||||||
|         } else { |         } else { | ||||||
|             // A single 'thing' selected. |             // A single 'thing' selected. | ||||||
|  |  | ||||||
| @@ -458,6 +484,8 @@ RED.sidebar.info = (function() { | |||||||
|             } else { |             } else { | ||||||
|                 refresh(selection.nodes); |                 refresh(selection.nodes); | ||||||
|             } |             } | ||||||
|  |         } else if (selection.flows || selection.subflows) { | ||||||
|  |             refresh(selection.flows); | ||||||
|         } else { |         } else { | ||||||
|             var activeWS = RED.workspaces.active(); |             var activeWS = RED.workspaces.active(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -325,7 +325,9 @@ RED.view = (function() { | |||||||
|                 mouse_position[0] += scrollDeltaLeft; |                 mouse_position[0] += scrollDeltaLeft; | ||||||
|                 mouse_position[1] += scrollDeltaTop; |                 mouse_position[1] += scrollDeltaTop; | ||||||
|             } |             } | ||||||
|             clearSelection(); |             if (RED.workspaces.selection().length === 0) { | ||||||
|  |                 clearSelection(); | ||||||
|  |             } | ||||||
|             RED.nodes.eachNode(function(n) { |             RED.nodes.eachNode(function(n) { | ||||||
|                 n.dirty = true; |                 n.dirty = true; | ||||||
|             }); |             }); | ||||||
| @@ -1197,76 +1199,81 @@ RED.view = (function() { | |||||||
|     function updateSelection() { |     function updateSelection() { | ||||||
|         var selection = {}; |         var selection = {}; | ||||||
|  |  | ||||||
|         if (moving_set.length > 0) { |         var workspaceSelection = RED.workspaces.selection(); | ||||||
|             selection.nodes = moving_set.map(function(n) { return n.n;}); |         if (workspaceSelection.length === 0) { | ||||||
|         } |             if (moving_set.length > 0) { | ||||||
|         if (selected_link != null) { |                 selection.nodes = moving_set.map(function(n) { return n.n;}); | ||||||
|             selection.link = selected_link; |             } | ||||||
|         } |             if (selected_link != null) { | ||||||
|         var activeWorkspace = RED.workspaces.active(); |                 selection.link = selected_link; | ||||||
|         activeLinks = RED.nodes.filterLinks({ |             } | ||||||
|             source:{z:activeWorkspace}, |             var activeWorkspace = RED.workspaces.active(); | ||||||
|             target:{z:activeWorkspace} |             activeLinks = RED.nodes.filterLinks({ | ||||||
|         }); |                 source:{z:activeWorkspace}, | ||||||
|         var tabOrder = RED.nodes.getWorkspaceOrder(); |                 target:{z:activeWorkspace} | ||||||
|         var currentLinks = activeLinks; |             }); | ||||||
|         var addedLinkLinks = {}; |             var tabOrder = RED.nodes.getWorkspaceOrder(); | ||||||
|         activeFlowLinks = []; |             var currentLinks = activeLinks; | ||||||
|         for (var i=0;i<moving_set.length;i++) { |             var addedLinkLinks = {}; | ||||||
|             if (moving_set[i].n.type === "link out" || moving_set[i].n.type === "link in") { |             activeFlowLinks = []; | ||||||
|                 var linkNode = moving_set[i].n; |             for (var i=0;i<moving_set.length;i++) { | ||||||
|                 var offFlowLinks = {}; |                 if (moving_set[i].n.type === "link out" || moving_set[i].n.type === "link in") { | ||||||
|                 linkNode.links.forEach(function(id) { |                     var linkNode = moving_set[i].n; | ||||||
|                     var target = RED.nodes.node(id); |                     var offFlowLinks = {}; | ||||||
|                     if (target) { |                     linkNode.links.forEach(function(id) { | ||||||
|                         if (linkNode.type === "link out") { |                         var target = RED.nodes.node(id); | ||||||
|                             if (target.z === linkNode.z) { |                         if (target) { | ||||||
|                                 if (!addedLinkLinks[linkNode.id+":"+target.id]) { |                             if (linkNode.type === "link out") { | ||||||
|                                     activeLinks.push({ |                                 if (target.z === linkNode.z) { | ||||||
|                                         source:linkNode, |                                     if (!addedLinkLinks[linkNode.id+":"+target.id]) { | ||||||
|                                         sourcePort:0, |                                         activeLinks.push({ | ||||||
|                                         target: target, |                                             source:linkNode, | ||||||
|                                         link: true |                                             sourcePort:0, | ||||||
|                                     }); |                                             target: target, | ||||||
|                                     addedLinkLinks[linkNode.id+":"+target.id] = true; |                                             link: true | ||||||
|  |                                         }); | ||||||
|  |                                         addedLinkLinks[linkNode.id+":"+target.id] = true; | ||||||
|  |                                     } | ||||||
|  |                                 } else { | ||||||
|  |                                     offFlowLinks[target.z] = offFlowLinks[target.z]||[]; | ||||||
|  |                                     offFlowLinks[target.z].push(target); | ||||||
|                                 } |                                 } | ||||||
|                             } else { |                             } else { | ||||||
|                                 offFlowLinks[target.z] = offFlowLinks[target.z]||[]; |                                 if (target.z === linkNode.z) { | ||||||
|                                 offFlowLinks[target.z].push(target); |                                     if (!addedLinkLinks[target.id+":"+linkNode.id]) { | ||||||
|                             } |                                         activeLinks.push({ | ||||||
|                         } else { |                                             source:target, | ||||||
|                             if (target.z === linkNode.z) { |                                             sourcePort:0, | ||||||
|                                 if (!addedLinkLinks[target.id+":"+linkNode.id]) { |                                             target: linkNode, | ||||||
|                                     activeLinks.push({ |                                             link: true | ||||||
|                                         source:target, |                                         }); | ||||||
|                                         sourcePort:0, |                                         addedLinkLinks[target.id+":"+linkNode.id] = true; | ||||||
|                                         target: linkNode, |                                     } | ||||||
|                                         link: true |                                 } else { | ||||||
|                                     }); |                                     offFlowLinks[target.z] = offFlowLinks[target.z]||[]; | ||||||
|                                     addedLinkLinks[target.id+":"+linkNode.id] = true; |                                     offFlowLinks[target.z].push(target); | ||||||
|                                 } |                                 } | ||||||
|                             } else { |  | ||||||
|                                 offFlowLinks[target.z] = offFlowLinks[target.z]||[]; |  | ||||||
|                                 offFlowLinks[target.z].push(target); |  | ||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|                     } |  | ||||||
|                 }); |  | ||||||
|                 var offFlows = Object.keys(offFlowLinks); |  | ||||||
|                 // offFlows.sort(function(A,B) { |  | ||||||
|                 //     return tabOrder.indexOf(A) - tabOrder.indexOf(B); |  | ||||||
|                 // }); |  | ||||||
|                 if (offFlows.length > 0) { |  | ||||||
|                     activeFlowLinks.push({ |  | ||||||
|                         refresh: Math.floor(Math.random()*10000), |  | ||||||
|                         node: linkNode, |  | ||||||
|                         links: offFlowLinks//offFlows.map(function(i) { return {id:i,links:offFlowLinks[i]};}) |  | ||||||
|                     }); |                     }); | ||||||
|  |                     var offFlows = Object.keys(offFlowLinks); | ||||||
|  |                     // offFlows.sort(function(A,B) { | ||||||
|  |                     //     return tabOrder.indexOf(A) - tabOrder.indexOf(B); | ||||||
|  |                     // }); | ||||||
|  |                     if (offFlows.length > 0) { | ||||||
|  |                         activeFlowLinks.push({ | ||||||
|  |                             refresh: Math.floor(Math.random()*10000), | ||||||
|  |                             node: linkNode, | ||||||
|  |                             links: offFlowLinks//offFlows.map(function(i) { return {id:i,links:offFlowLinks[i]};}) | ||||||
|  |                         }); | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |         } else { | ||||||
|  |             selection.flows = workspaceSelection; | ||||||
|         } |         } | ||||||
|         var selectionJSON = activeWorkspace+":"+JSON.stringify(selection,function(key,value) { |         var selectionJSON = activeWorkspace+":"+JSON.stringify(selection,function(key,value) { | ||||||
|             if (key === 'nodes') { |             if (key === 'nodes' || key === 'flows') { | ||||||
|                 return value.map(function(n) { return n.id }) |                 return value.map(function(n) { return n.id }) | ||||||
|             } else if (key === 'link') { |             } else if (key === 'link') { | ||||||
|                 return value.source.id+":"+value.sourcePort+":"+value.target.id; |                 return value.source.id+":"+value.sourcePort+":"+value.target.id; | ||||||
| @@ -1347,7 +1354,45 @@ RED.view = (function() { | |||||||
|             portLabelHover.remove(); |             portLabelHover.remove(); | ||||||
|             portLabelHover = null; |             portLabelHover = null; | ||||||
|         } |         } | ||||||
|         if (moving_set.length > 0 || selected_link != null) { |         var workspaceSelection = RED.workspaces.selection(); | ||||||
|  |         if (workspaceSelection.length > 0) { | ||||||
|  |             var workspaceCount = 0; | ||||||
|  |             workspaceSelection.forEach(function(ws) { if (ws.type === 'tab') workspaceCount++ }); | ||||||
|  |             if (workspaceCount === RED.workspaces.count()) { | ||||||
|  |                 // Cannot delete all workspaces | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |             var historyEvent = { | ||||||
|  |                 t: 'delete', | ||||||
|  |                 dirty: RED.nodes.dirty(), | ||||||
|  |                 nodes: [], | ||||||
|  |                 links: [], | ||||||
|  |                 workspaces: [], | ||||||
|  |                 subflows: [] | ||||||
|  |             } | ||||||
|  |             var workspaceOrder = RED.nodes.getWorkspaceOrder().slice(0); | ||||||
|  |  | ||||||
|  |             for (var i=0;i<workspaceSelection.length;i++) { | ||||||
|  |                 var ws = workspaceSelection[i]; | ||||||
|  |                 ws._index = workspaceOrder.indexOf(ws.id); | ||||||
|  |                 RED.workspaces.remove(ws); | ||||||
|  |                 var subEvent; | ||||||
|  |                 if (ws.type === 'tab') { | ||||||
|  |                     historyEvent.workspaces.push(ws); | ||||||
|  |                     subEvent = RED.nodes.removeWorkspace(ws.id); | ||||||
|  |                 } else { | ||||||
|  |                     subEvent = RED.subflow.removeSubflow(ws.id); | ||||||
|  |                     historyEvent.subflows = historyEvent.subflows.concat(subEvent.subflows); | ||||||
|  |                 } | ||||||
|  |                 historyEvent.nodes = historyEvent.nodes.concat(subEvent.nodes); | ||||||
|  |                 historyEvent.links = historyEvent.links.concat(subEvent.links); | ||||||
|  |             } | ||||||
|  |             RED.history.push(historyEvent); | ||||||
|  |             RED.nodes.dirty(true); | ||||||
|  |             updateActiveNodes(); | ||||||
|  |             updateSelection(); | ||||||
|  |             redraw(); | ||||||
|  |         } else if (moving_set.length > 0 || selected_link != null) { | ||||||
|             var result; |             var result; | ||||||
|             var removedNodes = []; |             var removedNodes = []; | ||||||
|             var removedLinks = []; |             var removedLinks = []; | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ RED.workspaces = (function() { | |||||||
|  |  | ||||||
|     function addWorkspace(ws,skipHistoryEntry,targetIndex) { |     function addWorkspace(ws,skipHistoryEntry,targetIndex) { | ||||||
|         if (ws) { |         if (ws) { | ||||||
|             workspace_tabs.addTab(ws); |             workspace_tabs.addTab(ws,targetIndex); | ||||||
|             workspace_tabs.resize(); |             workspace_tabs.resize(); | ||||||
|         } else { |         } else { | ||||||
|             var tabId = RED.nodes.id(); |             var tabId = RED.nodes.id(); | ||||||
| @@ -46,6 +46,8 @@ RED.workspaces = (function() { | |||||||
|         if (workspaceTabCount === 1) { |         if (workspaceTabCount === 1) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |         var workspaceOrder = RED.nodes.getWorkspaceOrder(); | ||||||
|  |         ws._index = workspaceOrder.indexOf(ws.id); | ||||||
|         removeWorkspace(ws); |         removeWorkspace(ws); | ||||||
|         var historyEvent = RED.nodes.removeWorkspace(ws.id); |         var historyEvent = RED.nodes.removeWorkspace(ws.id); | ||||||
|         historyEvent.t = 'delete'; |         historyEvent.t = 'delete'; | ||||||
| @@ -287,6 +289,20 @@ RED.workspaces = (function() { | |||||||
|                 RED.nodes.dirty(true); |                 RED.nodes.dirty(true); | ||||||
|                 setWorkspaceOrder(newOrder); |                 setWorkspaceOrder(newOrder); | ||||||
|             }, |             }, | ||||||
|  |             onselect: function(selectedTabs) { | ||||||
|  |                 RED.view.select(false) | ||||||
|  |                 if (selectedTabs.length === 0) { | ||||||
|  |                     // TODO: workspace-toolbar | ||||||
|  |                     $("#chart svg").css({"pointer-events":"auto",filter:"none"}) | ||||||
|  |                     $("#palette-container").css({"pointer-events":"auto",filter:"none"}) | ||||||
|  |                     $(".sidebar-shade").hide(); | ||||||
|  |                 } else { | ||||||
|  |                     RED.view.select(false) | ||||||
|  |                     $("#chart svg").css({"pointer-events":"none",filter:"opacity(60%)"}) | ||||||
|  |                     $("#palette-container").css({"pointer-events":"none",filter:"opacity(60%)"}) | ||||||
|  |                     $(".sidebar-shade").show(); | ||||||
|  |                 } | ||||||
|  |             }, | ||||||
|             minimumActiveTabWidth: 150, |             minimumActiveTabWidth: 150, | ||||||
|             scrollable: true, |             scrollable: true, | ||||||
|             addButton: "core:add-flow", |             addButton: "core:add-flow", | ||||||
| @@ -366,6 +382,9 @@ RED.workspaces = (function() { | |||||||
|         active: function() { |         active: function() { | ||||||
|             return activeWorkspace |             return activeWorkspace | ||||||
|         }, |         }, | ||||||
|  |         selection: function() { | ||||||
|  |             return workspace_tabs.selection(); | ||||||
|  |         }, | ||||||
|         show: function(id) { |         show: function(id) { | ||||||
|             if (!workspace_tabs.contains(id)) { |             if (!workspace_tabs.contains(id)) { | ||||||
|                 var sf = RED.nodes.subflow(id); |                 var sf = RED.nodes.subflow(id); | ||||||
|   | |||||||
| @@ -35,6 +35,7 @@ $primary-border-color: #bbbbbb; | |||||||
| $secondary-border-color: #dddddd; | $secondary-border-color: #dddddd; | ||||||
|  |  | ||||||
| $tab-background-active: #fff; | $tab-background-active: #fff; | ||||||
|  | $tab-background-selected: #f9f9f9; | ||||||
| $tab-background-inactive: #f0f0f0; | $tab-background-inactive: #f0f0f0; | ||||||
| $tab-background-hover: #ddd; | $tab-background-hover: #ddd; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -57,7 +57,14 @@ | |||||||
|             overflow: hidden; |             overflow: hidden; | ||||||
|             white-space: nowrap; |             white-space: nowrap; | ||||||
|             position: relative; |             position: relative; | ||||||
|  |             &.red-ui-tabs-closeable:hover { | ||||||
|  |                 .red-ui-tabs-badges { | ||||||
|  |                     display: none; | ||||||
|  |                 } | ||||||
|  |                 .red-ui-tab-close { | ||||||
|  |                     display: block; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|             a.red-ui-tab-label { |             a.red-ui-tab-label { | ||||||
|                 display: block; |                 display: block; | ||||||
|                 font-size: 14px; |                 font-size: 14px; | ||||||
| @@ -97,6 +104,19 @@ | |||||||
|                     opacity: 0.2; |                     opacity: 0.2; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |             &.selected { | ||||||
|  |                 &:not(.active) { | ||||||
|  |                     background: $tab-background-selected; | ||||||
|  |                 } | ||||||
|  |                 font-weight: bold; | ||||||
|  |                 .red-ui-tabs-badge-selected { | ||||||
|  |                     display: inline; | ||||||
|  |                 } | ||||||
|  |                 .red-ui-tabs-badge-changed { | ||||||
|  |                     display: none; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |             } | ||||||
|             &:not(.active) a:hover { |             &:not(.active) a:hover { | ||||||
|                 color: $workspace-button-color-hover; |                 color: $workspace-button-color-hover; | ||||||
|                 background: $tab-background-hover; |                 background: $tab-background-hover; | ||||||
| @@ -282,11 +302,20 @@ i.red-ui-tab-icon { | |||||||
|  |  | ||||||
| .red-ui-tabs-badges { | .red-ui-tabs-badges { | ||||||
|     position: absolute; |     position: absolute; | ||||||
|     top:2px; |     top:0px; | ||||||
|     right:2px; |     right:0px; | ||||||
|  |     width: 20px; | ||||||
|  |     pointer-events: none; | ||||||
|  |     display: block; | ||||||
|  |     height: 30px; | ||||||
|  |     line-height: 28px; | ||||||
|  |     text-align: center; | ||||||
|  |     padding:0px; | ||||||
|  |     color: #aaa; | ||||||
| } | } | ||||||
| .red-ui-tab-closeable .red-ui-tabs-badges { |  | ||||||
|     right: 22px; | .red-ui-tabs-badges i { | ||||||
|  |     display: none; | ||||||
| } | } | ||||||
|  |  | ||||||
| .red-ui-tab.node_changed img.node_changed { | .red-ui-tab.node_changed img.node_changed { | ||||||
| @@ -303,13 +332,14 @@ i.red-ui-tab-icon { | |||||||
|     vertical-align: top; |     vertical-align: top; | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| .red-ui-tab-close { | .red-ui-tab-close { | ||||||
|  |     display: none; | ||||||
|     background: $tab-background-inactive; |     background: $tab-background-inactive; | ||||||
|     opacity: 0.8; |     opacity: 0.8; | ||||||
|     position: absolute; |     position: absolute; | ||||||
|     right: 0px; |     right: 0px; | ||||||
|     top: 0px; |     top: 0px; | ||||||
|     display: block; |  | ||||||
|     width: 20px; |     width: 20px; | ||||||
|     height: 30px; |     height: 30px; | ||||||
|     line-height: 28px; |     line-height: 28px; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user