mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Merge pull request #3120 from node-red/hide-flows
Allow tabs to be hidden
This commit is contained in:
		| @@ -53,8 +53,15 @@ | ||||
|         "confirmDelete": "Confirm delete", | ||||
|         "delete": "Are you sure you want to delete '__label__'?", | ||||
|         "dropFlowHere": "Drop the flow here", | ||||
|         "addFlow": "Add Flow", | ||||
|         "listFlows": "List Flows", | ||||
|         "addFlow": "Add flow", | ||||
|         "addFlowToRight": "Add flow to the right", | ||||
|         "hideFlow": "Hide flow", | ||||
|         "hideOtherFlows": "Hide other flows", | ||||
|         "showAllFlows": "Show all flows", | ||||
|         "hideAllFlows": "Hide all flows", | ||||
|         "showLastHiddenFlow": "Show last hidden flow", | ||||
|         "listFlows": "List flows", | ||||
|         "listSubflows": "List subflows", | ||||
|         "status": "Status", | ||||
|         "enabled": "Enabled", | ||||
|         "disabled":"Disabled", | ||||
|   | ||||
| @@ -25,7 +25,9 @@ | ||||
|         "ctrl-alt-o": "core:open-project", | ||||
|         "ctrl-g v": "core:show-version-control-tab", | ||||
|         "ctrl-shift-l": "core:show-event-log", | ||||
|         "ctrl-shift-p":"core:show-action-list" | ||||
|         "ctrl-shift-p":"core:show-action-list", | ||||
|         "alt-w": "core:hide-flow", | ||||
|         "alt-shift-w": "core:show-last-hidden-flow" | ||||
|     }, | ||||
|     "red-ui-sidebar-node-config": { | ||||
|         "backspace": "core:delete-config-selection", | ||||
|   | ||||
| @@ -220,6 +220,16 @@ RED.settings = (function () { | ||||
|             return defaultValue; | ||||
|         } | ||||
|     } | ||||
|     function getLocal(key) { | ||||
|         return localStorage.getItem(key) | ||||
|     } | ||||
|     function setLocal(key, value) { | ||||
|         localStorage.setItem(key, value); | ||||
|     } | ||||
|     function removeLocal(key) { | ||||
|         localStorage.removeItem(key) | ||||
|     } | ||||
|  | ||||
|  | ||||
|     return { | ||||
|         init: init, | ||||
| @@ -228,6 +238,9 @@ RED.settings = (function () { | ||||
|         set: set, | ||||
|         get: get, | ||||
|         remove: remove, | ||||
|         theme: theme | ||||
|         theme: theme, | ||||
|         setLocal: setLocal, | ||||
|         getLocal: getLocal, | ||||
|         removeLocal: removeLocal | ||||
|     } | ||||
| })(); | ||||
|   | ||||
| @@ -498,6 +498,13 @@ RED.clipboard = (function() { | ||||
|         $("#red-ui-clipboard-dialog-import-text").on("keyup", validateImport); | ||||
|         $("#red-ui-clipboard-dialog-import-text").on('paste',function() { setTimeout(validateImport,10)}); | ||||
|  | ||||
|         if (RED.workspaces.active() === 0) { | ||||
|             $("#red-ui-clipboard-dialog-import-opt-current").addClass('disabled').removeClass("selected"); | ||||
|             $("#red-ui-clipboard-dialog-import-opt-new").addClass("selected"); | ||||
|         } else { | ||||
|             $("#red-ui-clipboard-dialog-import-opt-current").removeClass('disabled').addClass("selected"); | ||||
|             $("#red-ui-clipboard-dialog-import-opt-new").removeClass("selected"); | ||||
|         } | ||||
|         $("#red-ui-clipboard-dialog-import-opt > a").on("click", function(evt) { | ||||
|             evt.preventDefault(); | ||||
|             if ($(this).hasClass('disabled') || $(this).hasClass('selected')) { | ||||
| @@ -611,9 +618,6 @@ RED.clipboard = (function() { | ||||
|             activeLibraries[tabId] = browser; | ||||
|         }) | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|         $("#red-ui-clipboard-dialog-tab-library-name").on("keyup", validateExportFilename); | ||||
|         $("#red-ui-clipboard-dialog-tab-library-name").on('paste',function() { setTimeout(validateExportFilename,10)}); | ||||
|         $("#red-ui-clipboard-dialog-export").button("enable"); | ||||
| @@ -636,7 +640,6 @@ RED.clipboard = (function() { | ||||
|             label: RED._("editor.types.json") | ||||
|         }); | ||||
|  | ||||
|  | ||||
|         var previewList = $("#red-ui-clipboard-dialog-export-tab-clipboard-preview-list").css({position:"absolute",top:0,right:0,bottom:0,left:0}).treeList({ | ||||
|             data: [] | ||||
|         }) | ||||
| @@ -738,16 +741,22 @@ RED.clipboard = (function() { | ||||
|         $("#red-ui-clipboard-dialog-export").hide(); | ||||
|         $("#red-ui-clipboard-dialog-import-conflict").hide(); | ||||
|  | ||||
|         var selection = RED.workspaces.selection(); | ||||
|         if (selection.length > 0) { | ||||
|             $("#red-ui-clipboard-dialog-export-rng-selected").trigger("click"); | ||||
|         if (RED.workspaces.active() === 0) { | ||||
|             $("#red-ui-clipboard-dialog-export-rng-selected").addClass('disabled').removeClass('selected'); | ||||
|             $("#red-ui-clipboard-dialog-export-rng-flow").addClass('disabled').removeClass('selected'); | ||||
|             $("#red-ui-clipboard-dialog-export-rng-full").trigger("click"); | ||||
|         } else { | ||||
|             selection = RED.view.selection(); | ||||
|             if (selection.nodes) { | ||||
|             var selection = RED.workspaces.selection(); | ||||
|             if (selection.length > 0) { | ||||
|                 $("#red-ui-clipboard-dialog-export-rng-selected").trigger("click"); | ||||
|             } else { | ||||
|                 $("#red-ui-clipboard-dialog-export-rng-selected").addClass('disabled').removeClass('selected'); | ||||
|                 $("#red-ui-clipboard-dialog-export-rng-flow").trigger("click"); | ||||
|                 selection = RED.view.selection(); | ||||
|                 if (selection.nodes) { | ||||
|                     $("#red-ui-clipboard-dialog-export-rng-selected").trigger("click"); | ||||
|                 } else { | ||||
|                     $("#red-ui-clipboard-dialog-export-rng-selected").addClass('disabled').removeClass('selected'); | ||||
|                     $("#red-ui-clipboard-dialog-export-rng-flow").trigger("click"); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         if (format === "red-ui-clipboard-dialog-export-fmt-full") { | ||||
|   | ||||
| @@ -82,7 +82,7 @@ RED.menu = (function() { | ||||
|                 linkContent += '<span class="red-ui-menu-label-container"><span class="red-ui-menu-label">'+opt.label+'</span>'+ | ||||
|                                '<span class="red-ui-menu-sublabel">'+opt.sublabel+'</span></span>' | ||||
|             } else { | ||||
|                 linkContent += '<span class="red-ui-menu-label">'+opt.label+'</span>' | ||||
|                 linkContent += '<span class="red-ui-menu-label"><span>'+opt.label+'</span></span>' | ||||
|             } | ||||
|  | ||||
|             linkContent += '</a>'; | ||||
| @@ -92,7 +92,7 @@ RED.menu = (function() { | ||||
|             if (typeof opt.onselect === 'string') { | ||||
|                 var shortcut = RED.keyboard.getShortcut(opt.onselect); | ||||
|                 if (shortcut && shortcut.key) { | ||||
|                     opt.shortcutSpan = $('<span class="red-ui-popover-key">'+RED.keyboard.formatKey(shortcut.key, true)+'</span>').appendTo(link); | ||||
|                     opt.shortcutSpan = $('<span class="red-ui-popover-key">'+RED.keyboard.formatKey(shortcut.key, true)+'</span>').appendTo(link.find(".red-ui-menu-label")); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|   | ||||
| @@ -38,6 +38,7 @@ RED.tabs = (function() { | ||||
|         if (options.vertical) { | ||||
|             wrapper.addClass("red-ui-tabs-vertical"); | ||||
|         } | ||||
|  | ||||
|         if (options.addButton) { | ||||
|             wrapper.addClass("red-ui-tabs-add"); | ||||
|             var addButton = $('<div class="red-ui-tab-button red-ui-tabs-add"><a href="#"><i class="fa fa-plus"></i></a></div>').appendTo(wrapper); | ||||
| @@ -75,6 +76,8 @@ RED.tabs = (function() { | ||||
|             }); | ||||
|         } | ||||
|         if (options.searchButton) { | ||||
|             // This is soft-deprecated as we don't use this in the core anymore | ||||
|             // We no use the `menu` option to provide a drop-down list of actions | ||||
|             wrapper.addClass("red-ui-tabs-search"); | ||||
|             var searchButton = $('<div class="red-ui-tab-button red-ui-tabs-search"><a href="#"><i class="fa fa-list-ul"></i></a></div>').appendTo(wrapper); | ||||
|             searchButton.find('a').on("click", function(evt) { | ||||
| @@ -94,6 +97,48 @@ RED.tabs = (function() { | ||||
|             } | ||||
|  | ||||
|         } | ||||
|         if (options.menu) { | ||||
|             wrapper.addClass("red-ui-tabs-menu"); | ||||
|             var menuButton = $('<div class="red-ui-tab-button red-ui-tabs-menu"><a href="#"><i class="fa fa-caret-down"></i></a></div>').appendTo(wrapper); | ||||
|             var menuButtonLink = menuButton.find('a') | ||||
|             var menuOpen = false; | ||||
|             menuButtonLink.on("click", function(evt) { | ||||
|                 evt.stopPropagation(); | ||||
|                 evt.preventDefault(); | ||||
|                 if (menuOpen) { | ||||
|                     menu.remove(); | ||||
|                     menuOpen = false; | ||||
|                     return; | ||||
|                 } | ||||
|                 menuOpen = true; | ||||
|                 var menuOptions = []; | ||||
|                 if (typeof options.searchButton === 'function') { | ||||
|                     menuOptions = options.menu() | ||||
|                 } else if (Array.isArray(options.menu)) { | ||||
|                     menuOptions = options.menu; | ||||
|                 } | ||||
|                 var menu = RED.menu.init({options: menuOptions}); | ||||
|                 menu.css({ | ||||
|                     position: "absolute" | ||||
|                 }) | ||||
|                 menu.appendTo("body"); | ||||
|                 var elementPos = menuButton.offset(); | ||||
|                 menu.css({ | ||||
|                     top: (elementPos.top+menuButton.height()-2)+"px", | ||||
|                     left: (elementPos.left - menu.width() + menuButton.width())+"px" | ||||
|                 }) | ||||
|                 $(".red-ui-menu.red-ui-menu-dropdown").hide(); | ||||
|                 $(document).on("click.red-ui-tabmenu", function(evt) { | ||||
|                     $(document).off("click.red-ui-tabmenu"); | ||||
|                     menuOpen = false; | ||||
|                     menu.remove(); | ||||
|                 }); | ||||
|                 menu.show(); | ||||
|             }) | ||||
|         } | ||||
|  | ||||
|  | ||||
|  | ||||
|         var scrollLeft; | ||||
|         var scrollRight; | ||||
|  | ||||
| @@ -337,6 +382,12 @@ RED.tabs = (function() { | ||||
|             if (link.length === 0) { | ||||
|                 return; | ||||
|             } | ||||
|             if (link.parent().hasClass("hide-tab")) { | ||||
|                 link.parent().removeClass("hide-tab").removeClass("hide"); | ||||
|                 if (options.onshow) { | ||||
|                     options.onshow(tabs[link.attr('href').slice(1)]) | ||||
|                 } | ||||
|             } | ||||
|             if (!link.parent().hasClass("active")) { | ||||
|                 ul.children().removeClass("active"); | ||||
|                 ul.children().css({"transition": "width 100ms"}); | ||||
| @@ -362,13 +413,13 @@ RED.tabs = (function() { | ||||
|             } | ||||
|         } | ||||
|         function activatePreviousTab() { | ||||
|             var previous = ul.find("li.active").prev(); | ||||
|             var previous = findPreviousVisibleTab(); | ||||
|             if (previous.length > 0) { | ||||
|                 activateTab(previous.find("a")); | ||||
|             } | ||||
|         } | ||||
|         function activateNextTab() { | ||||
|             var next = ul.find("li.active").next(); | ||||
|             var next = findNextVisibleTab(); | ||||
|             if (next.length > 0) { | ||||
|                 activateTab(next.find("a")); | ||||
|             } | ||||
| @@ -378,7 +429,9 @@ RED.tabs = (function() { | ||||
|             if (options.vertical) { | ||||
|                 return; | ||||
|             } | ||||
|             var tabs = ul.find("li.red-ui-tab"); | ||||
|             var allTabs = ul.find("li.red-ui-tab"); | ||||
|             var tabs = allTabs.filter(":not(.hide-tab)"); | ||||
|             var hiddenTabs = allTabs.filter(".hide-tab"); | ||||
|             var width = wrapper.width(); | ||||
|             var tabCount = tabs.length; | ||||
|             var tabWidth; | ||||
| @@ -446,6 +499,7 @@ RED.tabs = (function() { | ||||
|                 // } | ||||
|  | ||||
|                 tabs.css({width:currentTabWidth}); | ||||
|                 hiddenTabs.css({width:"0px"}); | ||||
|                 if (tabWidth < 50) { | ||||
|                     // ul.find(".red-ui-tab-close").hide(); | ||||
|                     ul.find(".red-ui-tab-icon").hide(); | ||||
| @@ -486,24 +540,101 @@ RED.tabs = (function() { | ||||
|             } | ||||
|             var li = ul.find("a[href='#"+id+"']").parent(); | ||||
|             if (li.hasClass("active")) { | ||||
|                 var tab = li.prev(); | ||||
|                 var tab = findPreviousVisibleTab(li); | ||||
|                 if (tab.length === 0) { | ||||
|                     tab = li.next(); | ||||
|                     tab = findNextVisibleTab(li); | ||||
|                 } | ||||
|                 if (tab.length > 0) { | ||||
|                     activateTab(tab.find("a")); | ||||
|                 } else { | ||||
|                     if (options.onchange) { | ||||
|                         options.onchange(null); | ||||
|                     } | ||||
|                 } | ||||
|                 activateTab(tab.find("a")); | ||||
|             } | ||||
|             li.remove(); | ||||
|             if (tabs[id].pinned) { | ||||
|                 pinnedTabsCount--; | ||||
|  | ||||
|             li.one("transitionend", function(evt) { | ||||
|                 li.remove(); | ||||
|                 if (tabs[id].pinned) { | ||||
|                     pinnedTabsCount--; | ||||
|                 } | ||||
|                 if (options.onremove) { | ||||
|                     options.onremove(tabs[id]); | ||||
|                 } | ||||
|                 delete tabs[id]; | ||||
|                 updateTabWidths(); | ||||
|                 if (collapsibleMenu) { | ||||
|                     collapsibleMenu.remove(); | ||||
|                     collapsibleMenu = null; | ||||
|                 } | ||||
|             }) | ||||
|             li.addClass("hide-tab"); | ||||
|             li.width(0); | ||||
|         } | ||||
|  | ||||
|         function findPreviousVisibleTab(li) { | ||||
|             if (!li) { | ||||
|                 li = ul.find("li.active").parent(); | ||||
|             } | ||||
|             if (options.onremove) { | ||||
|                 options.onremove(tabs[id]); | ||||
|             var previous = li.prev(); | ||||
|             while(previous.length > 0 && previous.hasClass("hide-tab")) { | ||||
|                 previous = previous.prev(); | ||||
|             } | ||||
|             delete tabs[id]; | ||||
|             updateTabWidths(); | ||||
|             if (collapsibleMenu) { | ||||
|                 collapsibleMenu.remove(); | ||||
|                 collapsibleMenu = null; | ||||
|             return previous; | ||||
|         } | ||||
|         function findNextVisibleTab(li) { | ||||
|             if (!li) { | ||||
|                 li = ul.find("li.active").parent(); | ||||
|             } | ||||
|             var next = ul.find("li.active").next(); | ||||
|             while(next.length > 0 && next.hasClass("hide-tab")) { | ||||
|                 next = next.next(); | ||||
|             } | ||||
|             return next; | ||||
|         } | ||||
|         function showTab(id) { | ||||
|             if (tabs[id]) { | ||||
|                 var li = ul.find("a[href='#"+id+"']").parent(); | ||||
|                 if (li.hasClass("hide-tab")) { | ||||
|                     li.removeClass("hide-tab").removeClass("hide"); | ||||
|                     if (ul.find("li.red-ui-tab:not(.hide-tab)").length === 1) { | ||||
|                         activateTab(li.find("a")) | ||||
|                     } | ||||
|                     updateTabWidths(); | ||||
|                     if (options.onshow) { | ||||
|                         options.onshow(tabs[id]) | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         function hideTab(id) { | ||||
|             if (tabs[id]) { | ||||
|                 var li = ul.find("a[href='#"+id+"']").parent(); | ||||
|                 if (!li.hasClass("hide-tab")) { | ||||
|                     if (li.hasClass("active")) { | ||||
|                         var tab = findPreviousVisibleTab(li); | ||||
|                         if (tab.length === 0) { | ||||
|                             tab = findNextVisibleTab(li); | ||||
|                         } | ||||
|                         if (tab.length > 0) { | ||||
|                             activateTab(tab.find("a")); | ||||
|                         } else { | ||||
|                             if (options.onchange) { | ||||
|                                 options.onchange(null); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                     li.removeClass("active"); | ||||
|                     li.one("transitionend", function(evt) { | ||||
|                         li.addClass("hide"); | ||||
|                         updateTabWidths(); | ||||
|                         if (options.onhide) { | ||||
|                             options.onhide(tabs[id]) | ||||
|                         } | ||||
|                     }) | ||||
|                     li.addClass("hide-tab"); | ||||
|                     li.css({width:0}) | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @@ -663,7 +794,6 @@ RED.tabs = (function() { | ||||
|                 link.on("click", function(evt) { evt.preventDefault(); }) | ||||
|                 link.on("dblclick", function(evt) { evt.stopPropagation(); evt.preventDefault(); }) | ||||
|  | ||||
|  | ||||
|                 $('<span class="red-ui-tabs-fade"></span>').appendTo(li); | ||||
|  | ||||
|                 if (tab.closeable) { | ||||
| @@ -675,6 +805,15 @@ RED.tabs = (function() { | ||||
|                         removeTab(tab.id); | ||||
|                     }); | ||||
|                 } | ||||
|                 if (tab.hideable) { | ||||
|                     li.addClass("red-ui-tabs-closeable") | ||||
|                     var closeLink = $("<a/>",{href:"#",class:"red-ui-tab-close"}).appendTo(li); | ||||
|                     closeLink.append('<i class="fa fa-times" />'); | ||||
|                     closeLink.on("click",function(event) { | ||||
|                         event.preventDefault(); | ||||
|                         hideTab(tab.id); | ||||
|                     }); | ||||
|                 } | ||||
|  | ||||
|                 var badges = $('<span class="red-ui-tabs-badges"></span>').appendTo(li); | ||||
|                 if (options.onselect) { | ||||
| @@ -682,11 +821,11 @@ RED.tabs = (function() { | ||||
|                     $('<i class="red-ui-tabs-badge-selected fa fa-check-circle"></i>').appendTo(badges); | ||||
|                 } | ||||
|  | ||||
|                 link.attr("title",tab.label); | ||||
|  | ||||
|                 if (options.onadd) { | ||||
|                     options.onadd(tab); | ||||
|                 } | ||||
|                 link.attr("title",tab.label); | ||||
|                 if (ul.find("li.red-ui-tab").length == 1) { | ||||
|                     activateTab(link); | ||||
|                 } | ||||
| @@ -787,7 +926,7 @@ RED.tabs = (function() { | ||||
|             previousTab: activatePreviousTab, | ||||
|             resize: updateTabWidths, | ||||
|             count: function() { | ||||
|                 return ul.find("li.red-ui-tab").length; | ||||
|                 return ul.find("li.red-ui-tab:not(.hide)").length; | ||||
|             }, | ||||
|             activeIndex: function() { | ||||
|                 return ul.find("li.active").index() | ||||
| @@ -795,6 +934,9 @@ RED.tabs = (function() { | ||||
|             contains: function(id) { | ||||
|                 return ul.find("a[href='#"+id+"']").length > 0; | ||||
|             }, | ||||
|             showTab: showTab, | ||||
|             hideTab: hideTab, | ||||
|  | ||||
|             renameTab: function(id,label) { | ||||
|                 tabs[id].label = label; | ||||
|                 var tab = ul.find("a[href='#"+id+"']"); | ||||
| @@ -802,7 +944,20 @@ RED.tabs = (function() { | ||||
|                 tab.find("span.red-ui-text-bidi-aware").text(label).attr('dir', RED.text.bidi.resolveBaseTextDir(label)); | ||||
|                 updateTabWidths(); | ||||
|             }, | ||||
|             listTabs: function() { | ||||
|                 return $.makeArray(ul.children().map(function() { return $(this).data('tabId');})); | ||||
|             }, | ||||
|             selection: getSelection, | ||||
|             clearSelection: function() { | ||||
|                 if (options.onselect) { | ||||
|                     var selection = ul.find("li.red-ui-tab.selected"); | ||||
|                     if (selection.length > 0) { | ||||
|                         selection.removeClass("selected"); | ||||
|                         selectionChanged(); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|             }, | ||||
|             order: function(order) { | ||||
|                 preferredOrder = order; | ||||
|                 var existingTabOrder = $.makeArray(ul.children().map(function() { return $(this).data('tabId');})); | ||||
|   | ||||
| @@ -532,8 +532,8 @@ | ||||
|                 }).appendTo(label) | ||||
|  | ||||
|             } | ||||
|             var labelPaddingWidth = (item.gutter?item.gutter.width()+2:0)+(depth*20); | ||||
|             // var labelPaddingWidth = (item.gutter ? item.gutter[0].offsetWidth + 2 : 0) + (depth * 20) | ||||
|             // var labelPaddingWidth = (item.gutter?item.gutter.width()+2:0)+(depth*20); | ||||
|             var labelPaddingWidth = (item.gutter ? item.gutter[0].offsetWidth + 2 : 0) + (depth * 20) | ||||
|             item.treeList.labelPadding = $('<span>').css({ | ||||
|                 display: "inline-block", | ||||
|                 width:  labelPaddingWidth+'px' | ||||
|   | ||||
| @@ -229,7 +229,7 @@ RED.sidebar.config = (function() { | ||||
|         var globalConfigNodes = []; | ||||
|         var configList = {}; | ||||
|         RED.nodes.eachConfig(function(cn) { | ||||
|             if (cn.z) {//} == RED.workspaces.active()) { | ||||
|             if (cn.z) { | ||||
|                 configList[cn.z.replace(/\./g,"-")] = configList[cn.z.replace(/\./g,"-")]||[]; | ||||
|                 configList[cn.z.replace(/\./g,"-")].push(cn); | ||||
|             } else if (!cn.z) { | ||||
|   | ||||
| @@ -122,11 +122,20 @@ RED.sidebar.info.outliner = (function() { | ||||
|             }) | ||||
|             RED.popover.tooltip(triggerButton,RED._("sidebar.info.triggerAction")); | ||||
|         } | ||||
|         // $('<button type="button" class="red-ui-info-outline-item-control-reveal red-ui-button red-ui-button-small"><i class="fa fa-eye"></i></button>').appendTo(controls).on("click",function(evt) { | ||||
|         //     evt.preventDefault(); | ||||
|         //     evt.stopPropagation(); | ||||
|         //     RED.view.reveal(n.id); | ||||
|         // }) | ||||
|  | ||||
|         if (n.type === "tab") { | ||||
|             var toggleVisibleButton = $('<button type="button" class="red-ui-info-outline-item-control-hide red-ui-button red-ui-button-small"><i class="fa fa-eye"></i><i class="fa fa-eye-slash"></i></button>').appendTo(controls).on("click",function(evt) { | ||||
|                 evt.preventDefault(); | ||||
|                 evt.stopPropagation(); | ||||
|                 var isHidden = !div.hasClass("red-ui-info-outline-item-hidden"); | ||||
|                 div.toggleClass("red-ui-info-outline-item-hidden",isHidden); | ||||
|                 if (isHidden) { | ||||
|                     RED.workspaces.hide(n.id); | ||||
|                 } else { | ||||
|                     RED.workspaces.show(n.id, null, true); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|         if (n.type !== 'subflow') { | ||||
|             var toggleButton = $('<button type="button" class="red-ui-info-outline-item-control-disable red-ui-button red-ui-button-small"><i class="fa fa-circle-thin"></i><i class="fa fa-ban"></i></button>').appendTo(controls).on("click",function(evt) { | ||||
|                 evt.preventDefault(); | ||||
| @@ -317,13 +326,27 @@ RED.sidebar.info.outliner = (function() { | ||||
|         RED.events.on("groups:remove",onObjectRemove); | ||||
|         RED.events.on("groups:change",onNodeChange); | ||||
|  | ||||
|         RED.events.on("workspace:clear", onWorkspaceClear) | ||||
|         RED.events.on("workspace:show", onWorkspaceShow); | ||||
|         RED.events.on("workspace:hide", onWorkspaceHide); | ||||
|         RED.events.on("workspace:clear", onWorkspaceClear); | ||||
|  | ||||
|         return container; | ||||
|     } | ||||
|     function onWorkspaceClear() { | ||||
|         treeList.treeList('data',getFlowData()); | ||||
|     } | ||||
|     function onWorkspaceShow(event) { | ||||
|         var existingObject = objects[event.workspace]; | ||||
|         if (existingObject) { | ||||
|             existingObject.element.removeClass("red-ui-info-outline-item-hidden") | ||||
|         } | ||||
|     } | ||||
|     function onWorkspaceHide(event) { | ||||
|         var existingObject = objects[event.workspace]; | ||||
|         if (existingObject) { | ||||
|             existingObject.element.addClass("red-ui-info-outline-item-hidden") | ||||
|         } | ||||
|     } | ||||
|     function onFlowAdd(ws) { | ||||
|         objects[ws.id] = { | ||||
|             id: ws.id, | ||||
|   | ||||
| @@ -180,6 +180,10 @@ RED.sidebar.info = (function() { | ||||
|  | ||||
|         if (node === null) { | ||||
|             RED.sidebar.info.outliner.select(null); | ||||
|             propertiesPanelHeaderIcon.empty(); | ||||
|             propertiesPanelHeaderLabel.text(""); | ||||
|             propertiesPanelHeaderReveal.hide(); | ||||
|             propertiesPanelHeaderHelp.hide(); | ||||
|             return; | ||||
|         } else if (Array.isArray(node)) { | ||||
|             // Multiple things selected | ||||
|   | ||||
| @@ -345,8 +345,8 @@ RED.view = (function() { | ||||
|  | ||||
|             activeSubflow = RED.nodes.subflow(event.workspace); | ||||
|  | ||||
|             RED.menu.setDisabled("menu-item-workspace-edit", activeSubflow); | ||||
|             RED.menu.setDisabled("menu-item-workspace-delete",RED.workspaces.count() == 1 || activeSubflow); | ||||
|             RED.menu.setDisabled("menu-item-workspace-edit", activeSubflow || event.workspace === 0); | ||||
|             RED.menu.setDisabled("menu-item-workspace-delete",event.workspace === 0 || RED.workspaces.count() == 1 || activeSubflow); | ||||
|  | ||||
|             if (workspaceScrollPositions[event.workspace]) { | ||||
|                 chart.scrollLeft(workspaceScrollPositions[event.workspace].left); | ||||
| @@ -675,27 +675,33 @@ RED.view = (function() { | ||||
|  | ||||
|     function updateActiveNodes() { | ||||
|         var activeWorkspace = RED.workspaces.active(); | ||||
|         if (activeWorkspace !== 0) { | ||||
|             activeNodes = RED.nodes.filterNodes({z:activeWorkspace}); | ||||
|             activeNodes.forEach(function(n,i) { | ||||
|                 n._index = i; | ||||
|             }) | ||||
|             activeLinks = RED.nodes.filterLinks({ | ||||
|                 source:{z:activeWorkspace}, | ||||
|                 target:{z:activeWorkspace} | ||||
|             }); | ||||
|  | ||||
|         activeNodes = RED.nodes.filterNodes({z:activeWorkspace}); | ||||
|         activeNodes.forEach(function(n,i) { | ||||
|             n._index = i; | ||||
|         }) | ||||
|         activeLinks = RED.nodes.filterLinks({ | ||||
|             source:{z:activeWorkspace}, | ||||
|             target:{z:activeWorkspace} | ||||
|         }); | ||||
|             activeGroups = RED.nodes.groups(activeWorkspace)||[]; | ||||
|             activeGroups.forEach(function(g, i) { | ||||
|                 g._index = i; | ||||
|                 if (g.g) { | ||||
|                     g._root = g.g; | ||||
|                     g._depth = 1; | ||||
|                 } else { | ||||
|                     g._root = g.id; | ||||
|                     g._depth = 0; | ||||
|                 } | ||||
|             }); | ||||
|         } else { | ||||
|             activeNodes = []; | ||||
|             activeLinks = []; | ||||
|             activeGroups = []; | ||||
|         } | ||||
|  | ||||
|         activeGroups = RED.nodes.groups(activeWorkspace)||[]; | ||||
|         activeGroups.forEach(function(g,i) { | ||||
|             g._index = i; | ||||
|             if (g.g) { | ||||
|                 g._root = g.g; | ||||
|                 g._depth = 1; | ||||
|             } else { | ||||
|                 g._root = g.id; | ||||
|                 g._depth = 0; | ||||
|             } | ||||
|         }); | ||||
|         var changed = false; | ||||
|         do { | ||||
|             changed = false; | ||||
| @@ -1966,93 +1972,94 @@ RED.view = (function() { | ||||
|     function updateSelection() { | ||||
|         var selection = {}; | ||||
|         var activeWorkspace = RED.workspaces.active(); | ||||
|  | ||||
|         var workspaceSelection = RED.workspaces.selection(); | ||||
|         if (workspaceSelection.length === 0) { | ||||
|             selection = getSelection(); | ||||
|             activeLinks = RED.nodes.filterLinks({ | ||||
|                 source:{z:activeWorkspace}, | ||||
|                 target:{z:activeWorkspace} | ||||
|             }); | ||||
|             var tabOrder = RED.nodes.getWorkspaceOrder(); | ||||
|             var currentLinks = activeLinks; | ||||
|             var addedLinkLinks = {}; | ||||
|             activeFlowLinks = []; | ||||
|             var activeLinkNodeIds = Object.keys(activeLinkNodes); | ||||
|             activeLinkNodeIds.forEach(function(n) { | ||||
|                 activeLinkNodes[n].dirty = true; | ||||
|             }) | ||||
|             activeLinkNodes = {}; | ||||
|             for (var i=0;i<movingSet.length();i++) { | ||||
|                 var msn = movingSet.get(i); | ||||
|                 if ((msn.n.type === "link out" || msn.n.type === "link in") && | ||||
|                     (msn.n.z === activeWorkspace)) { | ||||
|                     var linkNode = msn.n; | ||||
|                     activeLinkNodes[linkNode.id] = linkNode; | ||||
|                     var offFlowLinks = {}; | ||||
|                     linkNode.links.forEach(function(id) { | ||||
|                         var target = RED.nodes.node(id); | ||||
|                         if (target) { | ||||
|                             if (linkNode.type === "link out") { | ||||
|                                 if (target.z === linkNode.z) { | ||||
|                                     if (!addedLinkLinks[linkNode.id+":"+target.id]) { | ||||
|                                         activeLinks.push({ | ||||
|                                             source:linkNode, | ||||
|                                             sourcePort:0, | ||||
|                                             target: target, | ||||
|                                             link: true | ||||
|                                         }); | ||||
|                                         addedLinkLinks[linkNode.id+":"+target.id] = true; | ||||
|                                         activeLinkNodes[target.id] = target; | ||||
|                                         target.dirty = true; | ||||
|         if (activeWorkspace !== 0) { | ||||
|             if (workspaceSelection.length === 0) { | ||||
|                 selection = getSelection(); | ||||
|                 activeLinks = RED.nodes.filterLinks({ | ||||
|                     source:{z:activeWorkspace}, | ||||
|                     target:{z:activeWorkspace} | ||||
|                 }); | ||||
|                 var tabOrder = RED.nodes.getWorkspaceOrder(); | ||||
|                 var currentLinks = activeLinks; | ||||
|                 var addedLinkLinks = {}; | ||||
|                 activeFlowLinks = []; | ||||
|                 var activeLinkNodeIds = Object.keys(activeLinkNodes); | ||||
|                 activeLinkNodeIds.forEach(function(n) { | ||||
|                     activeLinkNodes[n].dirty = true; | ||||
|                 }) | ||||
|                 activeLinkNodes = {}; | ||||
|                 for (var i=0;i<movingSet.length();i++) { | ||||
|                     var msn = movingSet.get(i); | ||||
|                     if ((msn.n.type === "link out" || msn.n.type === "link in") && | ||||
|                         (msn.n.z === activeWorkspace)) { | ||||
|                         var linkNode = msn.n; | ||||
|                         activeLinkNodes[linkNode.id] = linkNode; | ||||
|                         var offFlowLinks = {}; | ||||
|                         linkNode.links.forEach(function(id) { | ||||
|                             var target = RED.nodes.node(id); | ||||
|                             if (target) { | ||||
|                                 if (linkNode.type === "link out") { | ||||
|                                     if (target.z === linkNode.z) { | ||||
|                                         if (!addedLinkLinks[linkNode.id+":"+target.id]) { | ||||
|                                             activeLinks.push({ | ||||
|                                                 source:linkNode, | ||||
|                                                 sourcePort:0, | ||||
|                                                 target: target, | ||||
|                                                 link: true | ||||
|                                             }); | ||||
|                                             addedLinkLinks[linkNode.id+":"+target.id] = true; | ||||
|                                             activeLinkNodes[target.id] = target; | ||||
|                                             target.dirty = true; | ||||
|  | ||||
|                                         } | ||||
|                                     } else { | ||||
|                                         offFlowLinks[target.z] = offFlowLinks[target.z]||[]; | ||||
|                                         offFlowLinks[target.z].push(target); | ||||
|                                     } | ||||
|                                 } else { | ||||
|                                     offFlowLinks[target.z] = offFlowLinks[target.z]||[]; | ||||
|                                     offFlowLinks[target.z].push(target); | ||||
|                                 } | ||||
|                             } else { | ||||
|                                 if (target.z === linkNode.z) { | ||||
|                                     if (!addedLinkLinks[target.id+":"+linkNode.id]) { | ||||
|                                         activeLinks.push({ | ||||
|                                             source:target, | ||||
|                                             sourcePort:0, | ||||
|                                             target: linkNode, | ||||
|                                             link: true | ||||
|                                         }); | ||||
|                                         addedLinkLinks[target.id+":"+linkNode.id] = true; | ||||
|                                         activeLinkNodes[target.id] = target; | ||||
|                                         target.dirty = true; | ||||
|                                     if (target.z === linkNode.z) { | ||||
|                                         if (!addedLinkLinks[target.id+":"+linkNode.id]) { | ||||
|                                             activeLinks.push({ | ||||
|                                                 source:target, | ||||
|                                                 sourcePort:0, | ||||
|                                                 target: linkNode, | ||||
|                                                 link: true | ||||
|                                             }); | ||||
|                                             addedLinkLinks[target.id+":"+linkNode.id] = true; | ||||
|                                             activeLinkNodes[target.id] = target; | ||||
|                                             target.dirty = true; | ||||
|                                         } | ||||
|                                     } else { | ||||
|                                         offFlowLinks[target.z] = offFlowLinks[target.z]||[]; | ||||
|                                         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]};}) | ||||
|                             }); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 if (activeFlowLinks.length === 0 && selected_link !== null && selected_link.link) { | ||||
|                     activeLinks.push(selected_link); | ||||
|                     activeLinkNodes[selected_link.source.id] = selected_link.source; | ||||
|                     selected_link.source.dirty = true; | ||||
|                     activeLinkNodes[selected_link.target.id] = selected_link.target; | ||||
|                     selected_link.target.dirty = true; | ||||
|                 } | ||||
|             } else { | ||||
|                 selection.flows = workspaceSelection; | ||||
|             } | ||||
|             if (activeFlowLinks.length === 0 && selected_link !== null && selected_link.link) { | ||||
|                 activeLinks.push(selected_link); | ||||
|                 activeLinkNodes[selected_link.source.id] = selected_link.source; | ||||
|                 selected_link.source.dirty = true; | ||||
|                 activeLinkNodes[selected_link.target.id] = selected_link.target; | ||||
|                 selected_link.target.dirty = true; | ||||
|             } | ||||
|         } else { | ||||
|             selection.flows = workspaceSelection; | ||||
|         } | ||||
|         var selectionJSON = activeWorkspace+":"+JSON.stringify(selection,function(key,value) { | ||||
|             if (key === 'nodes' || key === 'flows') { | ||||
|   | ||||
| @@ -21,24 +21,46 @@ RED.workspaces = (function() { | ||||
|     var workspaceIndex = 0; | ||||
|  | ||||
|     var viewStack = []; | ||||
|     var hideStack = []; | ||||
|     var viewStackPos = 0; | ||||
|  | ||||
|     function isSameObj(env0, env1) { | ||||
|         return (JSON.stringify(env0) === JSON.stringify(env1)); | ||||
|     } | ||||
|  | ||||
|     function addToViewStack(id) { | ||||
|         if (viewStackPos !== viewStack.length) { | ||||
|             viewStack.splice(viewStackPos); | ||||
|         } | ||||
|         viewStack.push(id); | ||||
|         viewStackPos = viewStack.length; | ||||
|         // console.warn("addToViewStack",id,viewStack); | ||||
|     } | ||||
|  | ||||
|     function removeFromHideStack(id) { | ||||
|         hideStack = hideStack.filter(function(v) { | ||||
|             if (v === id) { | ||||
|                 return false; | ||||
|             } else if (Array.isArray(v)) { | ||||
|                 var i = v.indexOf(id); | ||||
|                 if (i > -1) { | ||||
|                     v.splice(i,1); | ||||
|                 } | ||||
|                 if (v.length === 0) { | ||||
|                     return false; | ||||
|                 } | ||||
|                 return true | ||||
|             } | ||||
|             return true; | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     function addWorkspace(ws,skipHistoryEntry,targetIndex) { | ||||
|         if (ws) { | ||||
|             if (!ws.closeable) { | ||||
|                 ws.hideable = true; | ||||
|             } | ||||
|             workspace_tabs.addTab(ws,targetIndex); | ||||
|  | ||||
|             var hiddenTabs = JSON.parse(RED.settings.getLocal("hiddenTabs")||"{}"); | ||||
|             if (hiddenTabs[ws.id]) { | ||||
|                 workspace_tabs.hideTab(ws.id); | ||||
|             } | ||||
|             workspace_tabs.resize(); | ||||
|         } else { | ||||
|             var tabId = RED.nodes.id(); | ||||
| @@ -46,7 +68,15 @@ RED.workspaces = (function() { | ||||
|                 workspaceIndex += 1; | ||||
|             } while ($("#red-ui-workspace-tabs a[title='"+RED._('workspace.defaultName',{number:workspaceIndex})+"']").size() !== 0); | ||||
|  | ||||
|             ws = {type:"tab",id:tabId,disabled: false,info:"",label:RED._('workspace.defaultName',{number:workspaceIndex}),env:[]}; | ||||
|             ws = { | ||||
|                 type: "tab", | ||||
|                 id: tabId, | ||||
|                 disabled: false, | ||||
|                 info: "", | ||||
|                 label: RED._('workspace.defaultName',{number:workspaceIndex}), | ||||
|                 env: [], | ||||
|                 hideable: true | ||||
|             }; | ||||
|             RED.nodes.addWorkspace(ws,targetIndex); | ||||
|             workspace_tabs.addTab(ws,targetIndex); | ||||
|             workspace_tabs.activateTab(tabId); | ||||
| @@ -97,11 +127,18 @@ RED.workspaces = (function() { | ||||
|                 var event = { | ||||
|                     old: activeWorkspace | ||||
|                 } | ||||
|                 activeWorkspace = tab.id; | ||||
|                 if (tab) { | ||||
|                     $("#red-ui-workspace-chart").show(); | ||||
|                     activeWorkspace = tab.id; | ||||
|                     window.location.hash = 'flow/'+tab.id; | ||||
|                     $("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!tab.disabled); | ||||
|                     } else { | ||||
|                     $("#red-ui-workspace-chart").hide(); | ||||
|                     activeWorkspace = 0; | ||||
|                     window.location.hash = ''; | ||||
|                 } | ||||
|                 event.workspace = activeWorkspace; | ||||
|                 RED.events.emit("workspace:change",event); | ||||
|                 window.location.hash = 'flow/'+tab.id; | ||||
|                 $("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!tab.disabled); | ||||
|                 RED.sidebar.config.refresh(); | ||||
|                 RED.view.focus(); | ||||
|             }, | ||||
| @@ -126,7 +163,7 @@ RED.workspaces = (function() { | ||||
|                 if (tab.disabled) { | ||||
|                     $("#red-ui-tab-"+(tab.id.replace(".","-"))).addClass('red-ui-workspace-disabled'); | ||||
|                 } | ||||
|                 RED.menu.setDisabled("menu-item-workspace-delete",workspaceTabCount <= 1); | ||||
|                 RED.menu.setDisabled("menu-item-workspace-delete",activeWorkspace === 0 || workspaceTabCount <= 1); | ||||
|                 if (workspaceTabCount === 1) { | ||||
|                     showWorkspace(); | ||||
|                 } | ||||
| @@ -134,8 +171,10 @@ RED.workspaces = (function() { | ||||
|             onremove: function(tab) { | ||||
|                 if (tab.type === "tab") { | ||||
|                     workspaceTabCount--; | ||||
|                 } else { | ||||
|                     hideStack.push(tab.id); | ||||
|                 } | ||||
|                 RED.menu.setDisabled("menu-item-workspace-delete",workspaceTabCount <= 1); | ||||
|                 RED.menu.setDisabled("menu-item-workspace-delete",activeWorkspace === 0 || workspaceTabCount <= 1); | ||||
|                 if (workspaceTabCount === 0) { | ||||
|                     hideWorkspace(); | ||||
|                 } | ||||
| @@ -167,12 +206,67 @@ RED.workspaces = (function() { | ||||
|                     $(".red-ui-sidebar-shade").show(); | ||||
|                 } | ||||
|             }, | ||||
|             onhide: function(tab) { | ||||
|                 hideStack.push(tab.id); | ||||
|                 RED.events.emit("workspace:hide",{workspace: tab.id}) | ||||
|             }, | ||||
|             onshow: function(tab) { | ||||
|                 removeFromHideStack(tab.id); | ||||
|                 RED.events.emit("workspace:show",{workspace: tab.id}) | ||||
|             }, | ||||
|             minimumActiveTabWidth: 150, | ||||
|             scrollable: true, | ||||
|             addButton: "core:add-flow", | ||||
|             addButtonCaption: RED._("workspace.addFlow"), | ||||
|             searchButton: "core:list-flows", | ||||
|             searchButtonCaption: RED._("workspace.listFlows") | ||||
|             menu: [ | ||||
|                 { | ||||
|                     id:"red-ui-tabs-menu-option-search-flows", | ||||
|                     label: RED._("workspace.listFlows"), | ||||
|                     onselect: "core:list-flows" | ||||
|                 }, | ||||
|                 { | ||||
|                     id:"red-ui-tabs-menu-option-search-subflows", | ||||
|                     label: RED._("workspace.listSubflows"), | ||||
|                     onselect: "core:list-subflows" | ||||
|                 }, | ||||
|                 null, | ||||
|                 { | ||||
|                     id:"red-ui-tabs-menu-option-add-flow", | ||||
|                     label: RED._("workspace.addFlow"), | ||||
|                     onselect: "core:add-flow" | ||||
|                 }, | ||||
|                 { | ||||
|                     id:"red-ui-tabs-menu-option-add-flow-right", | ||||
|                     label: RED._("workspace.addFlowToRight"), | ||||
|                     onselect: "core:add-flow-to-right" | ||||
|                 }, | ||||
|                 null, | ||||
|                 { | ||||
|                     id:"red-ui-tabs-menu-option-add-hide-flows", | ||||
|                     label: RED._("workspace.hideFlow"), | ||||
|                     onselect: "core:hide-flow" | ||||
|                 }, | ||||
|                 { | ||||
|                     id:"red-ui-tabs-menu-option-add-hide-other-flows", | ||||
|                     label: RED._("workspace.hideOtherFlows"), | ||||
|                     onselect: "core:hide-other-flows" | ||||
|                 }, | ||||
|                 { | ||||
|                     id:"red-ui-tabs-menu-option-add-show-all-flows", | ||||
|                     label: RED._("workspace.showAllFlows"), | ||||
|                     onselect: "core:show-all-flows" | ||||
|                 }, | ||||
|                 { | ||||
|                     id:"red-ui-tabs-menu-option-add-hide-all-flows", | ||||
|                     label: RED._("workspace.hideAllFlows"), | ||||
|                     onselect: "core:hide-all-flows" | ||||
|                 }, | ||||
|                 { | ||||
|                     id:"red-ui-tabs-menu-option-add-show-last-flow", | ||||
|                     label: RED._("workspace.showLastHiddenFlow"), | ||||
|                     onselect: "core:show-last-hidden-flow" | ||||
|                 } | ||||
|             ] | ||||
|         }); | ||||
|         workspaceTabCount = 0; | ||||
|     } | ||||
| @@ -223,15 +317,102 @@ RED.workspaces = (function() { | ||||
|         }); | ||||
|  | ||||
|         RED.actions.add("core:add-flow",function(opts) { addWorkspace(undefined,undefined,opts?opts.index:undefined)}); | ||||
|         RED.actions.add("core:add-flow-to-right",function(opts) { addWorkspace(undefined,undefined,workspace_tabs.activeIndex()+1)}); | ||||
|         RED.actions.add("core:edit-flow",editWorkspace); | ||||
|         RED.actions.add("core:remove-flow",removeWorkspace); | ||||
|         RED.actions.add("core:enable-flow",enableWorkspace); | ||||
|         RED.actions.add("core:disable-flow",disableWorkspace); | ||||
|  | ||||
|         RED.actions.add("core:hide-flow", function() { | ||||
|             var selection = workspace_tabs.selection(); | ||||
|             if (selection.length === 0) { | ||||
|                 selection = [{id:activeWorkspace}] | ||||
|             } | ||||
|             var hiddenTabs = []; | ||||
|             selection.forEach(function(ws) { | ||||
|                 RED.workspaces.hide(ws.id); | ||||
|                 hideStack.pop(); | ||||
|                 hiddenTabs.push(ws.id); | ||||
|             }) | ||||
|             if (hiddenTabs.length > 0) { | ||||
|                 hideStack.push(hiddenTabs); | ||||
|             } | ||||
|             workspace_tabs.clearSelection(); | ||||
|         }) | ||||
|  | ||||
|         RED.actions.add("core:hide-other-flows", function() { | ||||
|             var selection = workspace_tabs.selection(); | ||||
|             if (selection.length === 0) { | ||||
|                 selection = [{id:activeWorkspace}] | ||||
|             } | ||||
|             var selected = new Set(selection.map(function(ws) { return ws.id })) | ||||
|  | ||||
|             var currentTabs = workspace_tabs.listTabs(); | ||||
|             var hiddenTabs = []; | ||||
|             currentTabs.forEach(function(id) { | ||||
|                 if (!selected.has(id)) { | ||||
|                     RED.workspaces.hide(id); | ||||
|                     hideStack.pop(); | ||||
|                     hiddenTabs.push(id); | ||||
|                 } | ||||
|             }) | ||||
|             if (hiddenTabs.length > 0) { | ||||
|                 hideStack.push(hiddenTabs); | ||||
|             } | ||||
|         }) | ||||
|  | ||||
|         RED.actions.add("core:hide-all-flows", function() { | ||||
|             var currentTabs = workspace_tabs.listTabs(); | ||||
|             currentTabs.forEach(function(id) { | ||||
|                 RED.workspaces.hide(id); | ||||
|                 hideStack.pop(); | ||||
|             }) | ||||
|             if (currentTabs.length > 0) { | ||||
|                 hideStack.push(currentTabs); | ||||
|             } | ||||
|             workspace_tabs.clearSelection(); | ||||
|         }) | ||||
|         RED.actions.add("core:show-all-flows", function() { | ||||
|             var currentTabs = workspace_tabs.listTabs(); | ||||
|             currentTabs.forEach(function(id) { | ||||
|                 RED.workspaces.show(id, null, true) | ||||
|             }) | ||||
|         }) | ||||
|         // RED.actions.add("core:toggle-flows", function() { | ||||
|         //     var currentTabs = workspace_tabs.listTabs(); | ||||
|         //     var visibleCount = workspace_tabs.count(); | ||||
|         //     currentTabs.forEach(function(id) { | ||||
|         //         if (visibleCount === 0) { | ||||
|         //             RED.workspaces.show(id) | ||||
|         //         } else { | ||||
|         //             RED.workspaces.hide(id) | ||||
|         //         } | ||||
|         //     }) | ||||
|         // }) | ||||
|         RED.actions.add("core:show-last-hidden-flow", function() { | ||||
|             var id = hideStack.pop(); | ||||
|             if (id) { | ||||
|                 if (typeof id === 'string') { | ||||
|                     RED.workspaces.show(id); | ||||
|                 } else { | ||||
|                     var last = id.pop(); | ||||
|                     id.forEach(function(i) { | ||||
|                         RED.workspaces.show(i, null, true); | ||||
|                     }) | ||||
|                     setTimeout(function() { | ||||
|                         RED.workspaces.show(last); | ||||
|                     },150) | ||||
|  | ||||
|                 } | ||||
|             } | ||||
|         }) | ||||
|  | ||||
|         RED.actions.add("core:list-flows",function() { | ||||
|             RED.actions.invoke("core:search","type:tab "); | ||||
|         }) | ||||
|  | ||||
|         RED.actions.add("core:list-subflows",function() { | ||||
|             RED.actions.invoke("core:search","type:subflow "); | ||||
|         }) | ||||
|         RED.actions.add("core:go-to-previous-location", function() { | ||||
|             if (viewStackPos > 0) { | ||||
|                 if (viewStackPos === viewStack.length) { | ||||
| @@ -247,8 +428,6 @@ RED.workspaces = (function() { | ||||
|                 RED.workspaces.show(viewStack[++viewStackPos],true); | ||||
|             } | ||||
|         }) | ||||
|  | ||||
|  | ||||
|         hideWorkspace(); | ||||
|     } | ||||
|  | ||||
| @@ -346,7 +525,18 @@ RED.workspaces = (function() { | ||||
|         selection: function() { | ||||
|             return workspace_tabs.selection(); | ||||
|         }, | ||||
|         show: function(id,skipStack) { | ||||
|         hide: function(id) { | ||||
|             if (!id) { | ||||
|                 id = activeWorkspace; | ||||
|             } | ||||
|             if (workspace_tabs.contains(id)) { | ||||
|                 workspace_tabs.hideTab(id); | ||||
|                 var hiddenTabs = JSON.parse(RED.settings.getLocal("hiddenTabs")||"{}"); | ||||
|                 hiddenTabs[id] = true; | ||||
|                 RED.settings.setLocal("hiddenTabs",JSON.stringify(hiddenTabs)); | ||||
|             } | ||||
|         }, | ||||
|         show: function(id,skipStack,unhideOnly) { | ||||
|             if (!workspace_tabs.contains(id)) { | ||||
|                 var sf = RED.nodes.subflow(id); | ||||
|                 if (sf) { | ||||
| @@ -355,14 +545,22 @@ RED.workspaces = (function() { | ||||
|                         null, | ||||
|                         workspace_tabs.activeIndex()+1 | ||||
|                     ); | ||||
|                     removeFromHideStack(id); | ||||
|                 } else { | ||||
|                     return; | ||||
|                 } | ||||
|             } | ||||
|             if (!skipStack && activeWorkspace !== id) { | ||||
|                 addToViewStack(activeWorkspace) | ||||
|             if (unhideOnly) { | ||||
|                 workspace_tabs.showTab(id); | ||||
|             } else { | ||||
|                 if (!skipStack && activeWorkspace !== id) { | ||||
|                     addToViewStack(activeWorkspace) | ||||
|                 } | ||||
|                 workspace_tabs.activateTab(id); | ||||
|             } | ||||
|             workspace_tabs.activateTab(id); | ||||
|             var hiddenTabs = JSON.parse(RED.settings.getLocal("hiddenTabs")||"{}"); | ||||
|             delete hiddenTabs[id]; | ||||
|             RED.settings.setLocal("hiddenTabs",JSON.stringify(hiddenTabs)); | ||||
|         }, | ||||
|         refresh: function() { | ||||
|             RED.nodes.eachWorkspace(function(ws) { | ||||
|   | ||||
| @@ -19,7 +19,7 @@ | ||||
|     font-size: $primary-font-size; | ||||
|     position: absolute; | ||||
|     top: 100%; | ||||
|     width: 200px; | ||||
|     width: 230px; | ||||
|     left: 0; | ||||
|     z-index: 1000; | ||||
|     display: none; | ||||
| @@ -46,7 +46,7 @@ | ||||
|     & > li > a, | ||||
|     & > li > a:focus { | ||||
|         display: block; | ||||
|         padding: 4px 0 4px 32px; | ||||
|         padding: 4px 12px 4px 32px; | ||||
|         clear: both; | ||||
|         font-weight: normal; | ||||
|         line-height: 20px; | ||||
| @@ -106,11 +106,17 @@ | ||||
|                 display: none; | ||||
|             } | ||||
|         } | ||||
|         .red-ui-menu-label { | ||||
|             display: flex; | ||||
|             & > :first-child { | ||||
|                 flex-grow: 1 | ||||
|             } | ||||
|         } | ||||
|         .red-ui-popover-key { | ||||
|             border: none; | ||||
|             padding: 0; | ||||
|             font-size: 13px; | ||||
|             float: right; | ||||
|             // float: right; | ||||
|             color: $menuColor; | ||||
|             border-color: $menuColor; | ||||
|         } | ||||
|   | ||||
| @@ -214,7 +214,6 @@ | ||||
|             } | ||||
|             span.red-ui-menu-label { | ||||
|                 font-size: 14px; | ||||
|                 display: inline-block; | ||||
|                 text-indent: 0px; | ||||
|             } | ||||
|             span.red-ui-menu-sublabel { | ||||
|   | ||||
| @@ -435,6 +435,12 @@ div.red-ui-info-table { | ||||
|             border: none; | ||||
|             background: none; | ||||
|         } | ||||
|         .fa-circle-thin { | ||||
|             display: none; | ||||
|         } | ||||
|         .fa-eye { | ||||
|             display: none; | ||||
|         } | ||||
|     } | ||||
|     .red-ui-info-outline-item-control-reveal, | ||||
|     .red-ui-info-outline-item-control-action { | ||||
| @@ -446,7 +452,17 @@ div.red-ui-info-table { | ||||
|             display: inline-block; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     .fa-eye-slash { | ||||
|         display: none; | ||||
|     } | ||||
|     .red-ui-info-outline-item.red-ui-info-outline-item-hidden & { | ||||
|         .fa-eye-slash { | ||||
|             display: inline-block; | ||||
|         } | ||||
|         .fa-eye { | ||||
|             display: none; | ||||
|         } | ||||
|     } | ||||
|     .fa-ban { | ||||
|         display: none; | ||||
|     } | ||||
|   | ||||
| @@ -21,6 +21,9 @@ | ||||
|     height: 35px; | ||||
|     box-sizing: border-box; | ||||
|  | ||||
|     .hide-tab { | ||||
|         transition: width 0.1s ease-in; | ||||
|     } | ||||
|     .red-ui-tabs-scroll-container { | ||||
|         height: 60px; | ||||
|         overflow-x: scroll; | ||||
| @@ -142,13 +145,18 @@ | ||||
|         padding-right: 21px; | ||||
|     } | ||||
|     &.red-ui-tabs-add { | ||||
|         padding-right: 35px; | ||||
|         padding-right: 29px; | ||||
|     } | ||||
|     &.red-ui-tabs-add.red-ui-tabs-scrollable { | ||||
|         padding-right: 59px; | ||||
|         padding-right: 53px; | ||||
|     } | ||||
|     &.red-ui-tabs-add.red-ui-tabs-menu.red-ui-tabs-scrollable, | ||||
|     &.red-ui-tabs-add.red-ui-tabs-search.red-ui-tabs-scrollable { | ||||
|         padding-right: 95px; | ||||
|         padding-right: 83px; | ||||
|     } | ||||
|  | ||||
|     &.red-ui-tabs-add.red-ui-tabs-search.red-ui-tabs-menu.red-ui-tabs-scrollable { | ||||
|         padding-right: 113px; | ||||
|     } | ||||
|  | ||||
|     &.red-ui-tabs-collapsible { | ||||
| @@ -232,13 +240,14 @@ | ||||
|  | ||||
|     a { | ||||
|         @include workspace-button; | ||||
|         line-height: 32px; | ||||
|         height: 32px; | ||||
|         width: 32px; | ||||
|         line-height: 30px; | ||||
|         height: 28px; | ||||
|         width: 28px; | ||||
|         margin-left: 2px; | ||||
|         margin-right: 2px; | ||||
|         margin-top: 3px; | ||||
|         margin-right:3px; | ||||
|         margin-left:3px; | ||||
|         border: 1px solid $primary-border-color; | ||||
|         margin-bottom: 3px; | ||||
|         border: none; | ||||
|         z-index: 2; | ||||
|     } | ||||
| } | ||||
| @@ -280,6 +289,8 @@ | ||||
|         border-left: none; | ||||
|         border-right: none; | ||||
|         border-top: none; | ||||
|         border-bottom: 1px solid $primary-border-color; | ||||
|         line-height: 34px; | ||||
|     } | ||||
| } | ||||
| .red-ui-tab-scroll-left { | ||||
| @@ -296,15 +307,30 @@ | ||||
|  | ||||
| } | ||||
| .red-ui-tabs.red-ui-tabs-add .red-ui-tab-scroll-right { | ||||
|     right: 38px; | ||||
|     right: 32px; | ||||
| } | ||||
|  | ||||
| .red-ui-tabs.red-ui-tabs-add.red-ui-tabs-menu .red-ui-tab-scroll-right, | ||||
| .red-ui-tabs.red-ui-tabs-add.red-ui-tabs-search .red-ui-tab-scroll-right { | ||||
|     right: 76px; | ||||
|     right: 64px; | ||||
| } | ||||
| .red-ui-tabs.red-ui-tabs-add.red-ui-tabs-menu .red-ui-tabs-add, | ||||
| .red-ui-tabs.red-ui-tabs-add.red-ui-tabs-search .red-ui-tabs-add { | ||||
|     right: 38px; | ||||
|     right: 32px; | ||||
| } | ||||
|  | ||||
| .red-ui-tabs.red-ui-tabs-add.red-ui-tabs-search.red-ui-tabs-menu { | ||||
|     .red-ui-tab-scroll-right { | ||||
|         right: 96px; | ||||
|     } | ||||
|     .red-ui-tabs-add { | ||||
|         right: 64px; | ||||
|     } | ||||
|     .red-ui-tabs-search { | ||||
|         right: 32px; | ||||
|     } | ||||
| } | ||||
|  | ||||
| .red-ui-tabs-fade { | ||||
|     position: absolute; | ||||
|     bottom: 0; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user