mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Allow sidebar tabs to be reordered
The sidebar tab buttons can now be dragged to reorder them. Changes to the order are stored in user preferences.
This commit is contained in:
parent
8b36279e52
commit
73d8dfe381
@ -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
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user