mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Merge pull request #2655 from node-red/reorder-sidebar
Reorderable sidebar tabs
This commit is contained in:
		| @@ -29,7 +29,7 @@ RED.tabs = (function() { | ||||
|         var currentTabWidth; | ||||
|         var currentActiveTabWidth = 0; | ||||
|         var collapsibleMenu; | ||||
|  | ||||
|         var preferredOrder = options.order; | ||||
|         var ul = options.element || $("#"+options.id); | ||||
|         var wrapper = ul.wrap( "<div>" ).parent(); | ||||
|         var scrollContainer = ul.wrap( "<div>" ).parent(); | ||||
| @@ -132,11 +132,11 @@ RED.tabs = (function() { | ||||
|                                     activateTab(id); | ||||
|                                 } | ||||
|                             }; | ||||
|                             if (tabs[id].pinned) { | ||||
|                                 pinnedOptions.push(opt); | ||||
|                             } else { | ||||
|                             // if (tabs[id].pinned) { | ||||
|                             //     pinnedOptions.push(opt); | ||||
|                             // } else { | ||||
|                                 options.push(opt); | ||||
|                             } | ||||
|                             // } | ||||
|                         }); | ||||
|                         options = pinnedOptions.concat(options); | ||||
|                         collapsibleMenu = RED.menu.init({options: options}); | ||||
| @@ -363,23 +363,39 @@ RED.tabs = (function() { | ||||
|             var tabWidth; | ||||
|  | ||||
|             if (options.collapsible) { | ||||
|                 var availableCount = collapsedButtonsRow.children().length; | ||||
|                 var visibleCount = collapsedButtonsRow.children(":visible").length; | ||||
|                 tabWidth = width - collapsedButtonsRow.width()-10; | ||||
|                 if (tabWidth < 198) { | ||||
|                     var delta = 198 - tabWidth; | ||||
|                 var maxTabWidth = 198; | ||||
|                 var minTabWidth = 80; | ||||
|                 if (tabWidth <= minTabWidth || (tabWidth < maxTabWidth && visibleCount > 5)) { | ||||
|                     // The tab is too small. Hide the next button to make room | ||||
|                     // Start at the end of the button row, -1 for the menu button | ||||
|                     var b = collapsedButtonsRow.find("a:last").prev(); | ||||
|                     var index = collapsedButtonsRow.children().length - 2; | ||||
|                     // Work backwards to find the first visible button | ||||
|                     while (b.is(":not(:visible)")) { | ||||
|                         b = b.prev(); | ||||
|                         index--; | ||||
|                     } | ||||
|                     if (!b.hasClass("red-ui-tab-link-button-pinned")) { | ||||
|                     // If it isn't a pinned button, hide it to get the room | ||||
|                     if (tabWidth <= minTabWidth || visibleCount>6) {//}!b.hasClass("red-ui-tab-link-button-pinned")) { | ||||
|                         b.hide(); | ||||
|                     } | ||||
|                     tabWidth = width - collapsedButtonsRow.width()-10; | ||||
|                     tabWidth = Math.max(minTabWidth,width - collapsedButtonsRow.width()-10); | ||||
|                 } else { | ||||
|                     var space = width - 198 - collapsedButtonsRow.width(); | ||||
|                     if (visibleCount !== availableCount) { | ||||
|                         if (visibleCount < 6) { | ||||
|                             tabWidth = minTabWidth; | ||||
|                         } else { | ||||
|                             tabWidth = maxTabWidth; | ||||
|                         } | ||||
|                     } | ||||
|                     var space = width - tabWidth - collapsedButtonsRow.width(); | ||||
|                     if (space > 40) { | ||||
|                         collapsedButtonsRow.find("a:not(:visible):first").show(); | ||||
|                         tabWidth = width - collapsedButtonsRow.width()-10; | ||||
|                     } | ||||
|                     tabWidth = width - collapsedButtonsRow.width()-10; | ||||
|                 } | ||||
|                 tabs.css({width:tabWidth}); | ||||
|  | ||||
| @@ -469,7 +485,7 @@ RED.tabs = (function() { | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|         var tabAPI =  { | ||||
|             addTab: function(tab,targetIndex) { | ||||
|                 if (options.onselect) { | ||||
|                     var selection = ul.find("li.red-ui-tab.selected"); | ||||
| @@ -531,11 +547,92 @@ RED.tabs = (function() { | ||||
|                         evt.preventDefault(); | ||||
|                         activateTab(tab.id); | ||||
|                     }); | ||||
|                     pinnedLink.data("tabId",tab.id) | ||||
|                     if (tab.pinned) { | ||||
|                         pinnedLink.addClass("red-ui-tab-link-button-pinned"); | ||||
|                         pinnedTabsCount++; | ||||
|                     } | ||||
|                     RED.popover.tooltip($(pinnedLink), tab.name, tab.action); | ||||
|                     if (options.onreorder) { | ||||
|                         var pinnedLinkIndex; | ||||
|                         var pinnedLinks = []; | ||||
|                         var startPinnedIndex; | ||||
|                         pinnedLink.draggable({ | ||||
|                             distance: 10, | ||||
|                             axis:"x", | ||||
|                             containment: ".red-ui-tab-link-buttons", | ||||
|                             start: function(event,ui) { | ||||
|                                 dragActive = true; | ||||
|                                 $(".red-ui-tab-link-buttons").width($(".red-ui-tab-link-buttons").width()); | ||||
|                                 if (dblClickArmed) { dblClickArmed = false; return false } | ||||
|                                 collapsedButtonsRow.children().each(function(i) { | ||||
|                                     pinnedLinks[i] = { | ||||
|                                         el:$(this), | ||||
|                                         text: $(this).text(), | ||||
|                                         left: $(this).position().left, | ||||
|                                         width: $(this).width(), | ||||
|                                         menu: $(this).hasClass("red-ui-tab-link-button-menu") | ||||
|                                     }; | ||||
|                                     if ($(this).is(pinnedLink)) { | ||||
|                                         pinnedLinkIndex = i; | ||||
|                                         startPinnedIndex = i; | ||||
|                                     } | ||||
|                                 }); | ||||
|                                 collapsedButtonsRow.children().each(function(i) { | ||||
|                                     if (i!==pinnedLinkIndex) { | ||||
|                                         $(this).css({ | ||||
|                                             position: 'absolute', | ||||
|                                             left: pinnedLinks[i].left+"px", | ||||
|                                             width: pinnedLinks[i].width+2, | ||||
|                                             transition: "left 0.3s" | ||||
|                                         }); | ||||
|                                     } | ||||
|                                 }) | ||||
|                                 if (!pinnedLink.hasClass('active')) { | ||||
|                                     pinnedLink.css({'zIndex':1}); | ||||
|                                 } | ||||
|                             }, | ||||
|                             drag: function(event,ui) { | ||||
|                                 ui.position.left += pinnedLinks[pinnedLinkIndex].left; | ||||
|                                 var tabCenter = ui.position.left + pinnedLinks[pinnedLinkIndex].width/2; | ||||
|                                 for (var i=0;i<pinnedLinks.length;i++) { | ||||
|                                     if (i === pinnedLinkIndex || pinnedLinks[i].menu || pinnedLinks[i].el.is(":not(:visible)")) { | ||||
|                                         continue; | ||||
|                                     } | ||||
|                                     if (tabCenter > pinnedLinks[i].left && tabCenter < pinnedLinks[i].left+pinnedLinks[i].width) { | ||||
|                                         if (i < pinnedLinkIndex) { | ||||
|                                             pinnedLinks[i].left += pinnedLinks[pinnedLinkIndex].width+8; | ||||
|                                             pinnedLinks[pinnedLinkIndex].el.detach().insertBefore(pinnedLinks[i].el); | ||||
|                                         } else { | ||||
|                                             pinnedLinks[i].left -= pinnedLinks[pinnedLinkIndex].width+8; | ||||
|                                             pinnedLinks[pinnedLinkIndex].el.detach().insertAfter(pinnedLinks[i].el); | ||||
|                                         } | ||||
|                                         pinnedLinks[i].el.css({left:pinnedLinks[i].left+"px"}); | ||||
|  | ||||
|                                         pinnedLinks.splice(i, 0, pinnedLinks.splice(pinnedLinkIndex, 1)[0]); | ||||
|  | ||||
|                                         pinnedLinkIndex = i; | ||||
|                                         break; | ||||
|                                     } | ||||
|                                 } | ||||
|                             }, | ||||
|                             stop: function(event,ui) { | ||||
|                                 collapsedButtonsRow.children().css({position:"relative",left:"",transition:""}); | ||||
|                                 $(".red-ui-tab-link-buttons").width('auto'); | ||||
|                                 pinnedLink.css({zIndex:""}); | ||||
|                                 updateTabWidths(); | ||||
|                                 if (startPinnedIndex !== pinnedLinkIndex) { | ||||
|                                     if (collapsibleMenu) { | ||||
|                                         collapsibleMenu.remove(); | ||||
|                                         collapsibleMenu = null; | ||||
|                                     } | ||||
|                                     var newOrder = $.makeArray(collapsedButtonsRow.children().map(function() { return $(this).data('tabId');})); | ||||
|                                     tabAPI.order(newOrder); | ||||
|                                     options.onreorder(newOrder); | ||||
|                                 } | ||||
|                             } | ||||
|                         }); | ||||
|                     } | ||||
|  | ||||
|                 } | ||||
|                 link.on("mouseup",onTabClick); | ||||
| @@ -565,7 +662,7 @@ RED.tabs = (function() { | ||||
|                 if (ul.find("li.red-ui-tab").length == 1) { | ||||
|                     activateTab(link); | ||||
|                 } | ||||
|                 if (options.onreorder) { | ||||
|                 if (options.onreorder && !options.collapsible) { | ||||
|                     var originalTabOrder; | ||||
|                     var tabDragIndex; | ||||
|                     var tabElements = []; | ||||
| @@ -652,6 +749,9 @@ RED.tabs = (function() { | ||||
|                     collapsibleMenu.remove(); | ||||
|                     collapsibleMenu = null; | ||||
|                 } | ||||
|                 if (preferredOrder) { | ||||
|                     tabAPI.order(preferredOrder); | ||||
|                 } | ||||
|             }, | ||||
|             removeTab: removeTab, | ||||
|             activateTab: activateTab, | ||||
| @@ -673,10 +773,8 @@ RED.tabs = (function() { | ||||
|             }, | ||||
|             selection: getSelection, | ||||
|             order: function(order) { | ||||
|                 preferredOrder = order; | ||||
|                 var existingTabOrder = $.makeArray(ul.children().map(function() { return $(this).data('tabId');})); | ||||
|                 if (existingTabOrder.length !== order.length) { | ||||
|                     return | ||||
|                 } | ||||
|                 var i; | ||||
|                 var match = true; | ||||
|                 for (i=0;i<order.length;i++) { | ||||
| @@ -692,12 +790,41 @@ RED.tabs = (function() { | ||||
|                 var existingTabs = ul.children().detach().each(function() { | ||||
|                     existingTabMap[$(this).data("tabId")] = $(this); | ||||
|                 }); | ||||
|                 var pinnedButtons = {}; | ||||
|                 if (options.collapsible) { | ||||
|                     collapsedButtonsRow.children().detach().each(function() { | ||||
|                         var id = $(this).data("tabId"); | ||||
|                         if (!id) { | ||||
|                             id = "__menu__" | ||||
|                         } | ||||
|                         pinnedButtons[id] = $(this); | ||||
|                     }); | ||||
|                 } | ||||
|                 for (i=0;i<order.length;i++) { | ||||
|                     existingTabMap[order[i]].appendTo(ul); | ||||
|                     if (existingTabMap[order[i]]) { | ||||
|                         existingTabMap[order[i]].appendTo(ul); | ||||
|                         if (options.collapsible) { | ||||
|                             pinnedButtons[order[i]].appendTo(collapsedButtonsRow); | ||||
|                         } | ||||
|                         delete existingTabMap[order[i]]; | ||||
|                     } | ||||
|                 } | ||||
|                 // Add any tabs that aren't known in the order | ||||
|                 for (i in existingTabMap) { | ||||
|                     if (existingTabMap.hasOwnProperty(i)) { | ||||
|                         existingTabMap[i].appendTo(ul); | ||||
|                         if (options.collapsible) { | ||||
|                             pinnedButtons[i].appendTo(collapsedButtonsRow); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 if (options.collapsible) { | ||||
|                     pinnedButtons["__menu__"].appendTo(collapsedButtonsRow); | ||||
|                     updateTabWidths(); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|         } | ||||
|         return tabAPI; | ||||
|     } | ||||
|  | ||||
|     return { | ||||
|   | ||||
| @@ -232,7 +232,11 @@ RED.sidebar = (function() { | ||||
|                 } | ||||
|             }, | ||||
|             // minimumActiveTabWidth: 70, | ||||
|             collapsible: true | ||||
|             collapsible: true, | ||||
|             onreorder: function(order) { | ||||
|                 RED.settings.set("editor.sidebar.order",order); | ||||
|             }, | ||||
|             order: RED.settings.get("editor.sidebar.order",["info", "help", "version-control", "debug"]) | ||||
|             // scrollable: true | ||||
|         }); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user