mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	improve contineous search
- rename action core:search-prev for core:search-previous - Ensure search counter in toolbar is i18n ready - remember (and display in toolbar) the search term - recall the search term when magnifier clicked - esnure currently flashing node is cancelled before flashing next node - Add "flash" for flow tabs revealed by a search - Fix "flash" for config nodes revealed by a search
This commit is contained in:
		| @@ -152,7 +152,8 @@ | |||||||
|         "zoom-in": "Zoom in", |         "zoom-in": "Zoom in", | ||||||
|         "search-flows": "Search flows", |         "search-flows": "Search flows", | ||||||
|         "search-prev": "Previous", |         "search-prev": "Previous", | ||||||
|         "search-next": "Next" |         "search-next": "Next", | ||||||
|  |         "search-counter": "\"__term__\" __result__ of __count__" | ||||||
|     }, |     }, | ||||||
|     "user": { |     "user": { | ||||||
|         "loggedInAs": "Logged in as __name__", |         "loggedInAs": "Logged in as __name__", | ||||||
|   | |||||||
| @@ -91,7 +91,7 @@ | |||||||
|         "alt-a c": "core:align-selection-to-center", |         "alt-a c": "core:align-selection-to-center", | ||||||
|         "alt-a h": "core:distribute-selection-horizontally", |         "alt-a h": "core:distribute-selection-horizontally", | ||||||
|         "alt-a v": "core:distribute-selection-vertically", |         "alt-a v": "core:distribute-selection-vertically", | ||||||
|         "shift-f": "core:search-prev", |         "shift-f": "core:search-previous", | ||||||
|         "f": "core:search-next" |         "f": "core:search-next" | ||||||
|      } |      } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -248,6 +248,7 @@ RED.search = (function() { | |||||||
|                 } |                 } | ||||||
|                 currentResults = search(value); |                 currentResults = search(value); | ||||||
|                 if (currentResults.length > 0) { |                 if (currentResults.length > 0) { | ||||||
|  |                     $("#red-ui-view-searchtools-search").data("term", value); | ||||||
|                     for (i=0;i<Math.min(currentResults.length,25);i++) { |                     for (i=0;i<Math.min(currentResults.length,25);i++) { | ||||||
|                         searchResults.editableList('addItem',currentResults[i]) |                         searchResults.editableList('addItem',currentResults[i]) | ||||||
|                     } |                     } | ||||||
| @@ -524,7 +525,17 @@ RED.search = (function() { | |||||||
|     } |     } | ||||||
|     function updateSearchToolbar() { |     function updateSearchToolbar() { | ||||||
|         if(!disabled && currentIndex >= 0 && currentResults && currentResults.length ) { |         if(!disabled && currentIndex >= 0 && currentResults && currentResults.length ) { | ||||||
|             $("#red-ui-view-searchtools-counter").text((currentIndex+1) + " of " + currentResults.length ) |             //$("#red-ui-view-searchtools-counter").text((currentIndex+1) + " of " + currentResults.length ) | ||||||
|  |             let term = $("#red-ui-view-searchtools-search").data("term") || ""; | ||||||
|  |             if(term.length > 16) { | ||||||
|  |                 term = term.substring(0,12) + "..." | ||||||
|  |             } | ||||||
|  |             const i18nSearchCounterData = { | ||||||
|  |                 term : term, | ||||||
|  |                 result: (currentIndex+1), | ||||||
|  |                 count: currentResults.length | ||||||
|  |             }  | ||||||
|  |             $("#red-ui-view-searchtools-counter").text(RED._('actions.search-counter', i18nSearchCounterData)); | ||||||
|             $("#view-search-tools > :not(:first-child)").show(); //show other tools |             $("#view-search-tools > :not(:first-child)").show(); //show other tools | ||||||
|         } else { |         } else { | ||||||
|             $("#view-search-tools > :not(:first-child)").hide(); //hide all but search button |             $("#view-search-tools > :not(:first-child)").hide(); //hide all but search button | ||||||
| @@ -554,7 +565,7 @@ RED.search = (function() { | |||||||
|  |  | ||||||
|     function init() { |     function init() { | ||||||
|         RED.actions.add("core:search",show); |         RED.actions.add("core:search",show); | ||||||
|         RED.actions.add("core:search-prev",revealPrev); |         RED.actions.add("core:search-previous",revealPrev); | ||||||
|         RED.actions.add("core:search-next",revealNext); |         RED.actions.add("core:search-next",revealNext); | ||||||
|  |  | ||||||
|         RED.events.on("editor:open",function() { disabled = true; }); |         RED.events.on("editor:open",function() { disabled = true; }); | ||||||
| @@ -573,6 +584,7 @@ RED.search = (function() { | |||||||
|  |  | ||||||
|         $("#red-ui-view-searchtools-close").on("click", function close() { |         $("#red-ui-view-searchtools-close").on("click", function close() { | ||||||
|             currentResults = []; |             currentResults = []; | ||||||
|  |             $("#red-ui-view-searchtools-search").data("term", ""); | ||||||
|             updateSearchToolbar(); |             updateSearchToolbar(); | ||||||
|         }); |         }); | ||||||
|         $("#red-ui-view-searchtools-close").trigger("click"); |         $("#red-ui-view-searchtools-close").trigger("click"); | ||||||
|   | |||||||
| @@ -15,6 +15,8 @@ | |||||||
|  **/ |  **/ | ||||||
| RED.sidebar.config = (function() { | RED.sidebar.config = (function() { | ||||||
|  |  | ||||||
|  |     let flashingConfigNode; | ||||||
|  |     let flashingConfigNodeTimer; | ||||||
|  |  | ||||||
|     var content = document.createElement("div"); |     var content = document.createElement("div"); | ||||||
|     content.className = "red-ui-sidebar-node-config"; |     content.className = "red-ui-sidebar-node-config"; | ||||||
| @@ -145,6 +147,7 @@ RED.sidebar.config = (function() { | |||||||
|                 var entry = $('<li class="red-ui-palette-node_id_'+node.id.replace(/\./g,"-")+'"></li>').appendTo(list); |                 var entry = $('<li class="red-ui-palette-node_id_'+node.id.replace(/\./g,"-")+'"></li>').appendTo(list); | ||||||
|                 var nodeDiv = $('<div class="red-ui-palette-node-config red-ui-palette-node"></div>').appendTo(entry); |                 var nodeDiv = $('<div class="red-ui-palette-node-config red-ui-palette-node"></div>').appendTo(entry); | ||||||
|                 entry.data('node',node.id); |                 entry.data('node',node.id); | ||||||
|  |                 nodeDiv.data('node',node.id); | ||||||
|                 var label = $('<div class="red-ui-palette-label"></div>').text(label).appendTo(nodeDiv); |                 var label = $('<div class="red-ui-palette-label"></div>').text(label).appendTo(nodeDiv); | ||||||
|                 if (node.d) { |                 if (node.d) { | ||||||
|                     nodeDiv.addClass("red-ui-palette-node-config-disabled"); |                     nodeDiv.addClass("red-ui-palette-node-config-disabled"); | ||||||
| @@ -350,6 +353,32 @@ RED.sidebar.config = (function() { | |||||||
|         RED.popover.tooltip($('#red-ui-sidebar-config-filter-unused'), RED._("sidebar.config.showAllUnusedConfigNodes")); |         RED.popover.tooltip($('#red-ui-sidebar-config-filter-unused'), RED._("sidebar.config.showAllUnusedConfigNodes")); | ||||||
|  |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     function flashConfigNode(el) { | ||||||
|  |         if(flashingConfigNode && flashingConfigNode.length) { | ||||||
|  |             //cancel current flashing node before flashing new node | ||||||
|  |             clearInterval(flashingConfigNodeTimer); | ||||||
|  |             flashingConfigNodeTimer = null; | ||||||
|  |             flashingConfigNode.children("div").removeClass('highlighted'); | ||||||
|  |             flashingConfigNode = null; | ||||||
|  |         } | ||||||
|  |         if(!el || !el.children("div").length) { return; } | ||||||
|  |  | ||||||
|  |         flashingConfigNodeTimer = setInterval(function(flashEndTime) { | ||||||
|  |             if (flashEndTime >= Date.now()) { | ||||||
|  |                 const highlighted = el.children("div").hasClass("highlighted"); | ||||||
|  |                 el.children("div").toggleClass('highlighted', !highlighted) | ||||||
|  |             } else { | ||||||
|  |                 clearInterval(flashingConfigNodeTimer); | ||||||
|  |                 flashingConfigNodeTimer = null; | ||||||
|  |                 flashingConfigNode = null; | ||||||
|  |                 el.children("div").removeClass('highlighted'); | ||||||
|  |             } | ||||||
|  |         }, 100, Date.now() + 2200); | ||||||
|  |         flashingConfigNode = el; | ||||||
|  |         el.children("div").addClass('highlighted'); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     function show(id) { |     function show(id) { | ||||||
|         if (typeof id === 'boolean') { |         if (typeof id === 'boolean') { | ||||||
|             if (id) { |             if (id) { | ||||||
| @@ -374,19 +403,7 @@ RED.sidebar.config = (function() { | |||||||
|                 } else if (y<0) { |                 } else if (y<0) { | ||||||
|                     scrollWindow.animate({scrollTop: '+='+(y-10)},150); |                     scrollWindow.animate({scrollTop: '+='+(y-10)},150); | ||||||
|                 } |                 } | ||||||
|                 var flash = 21; |                 flashConfigNode(node, id); | ||||||
|                 var flashFunc = function() { |  | ||||||
|                     if ((flash%2)===0) { |  | ||||||
|                         node.removeClass('node_highlighted'); |  | ||||||
|                     } else { |  | ||||||
|                         node.addClass('node_highlighted'); |  | ||||||
|                     } |  | ||||||
|                     flash--; |  | ||||||
|                     if (flash >= 0) { |  | ||||||
|                         setTimeout(flashFunc,100); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|                 flashFunc(); |  | ||||||
|             },100); |             },100); | ||||||
|         } |         } | ||||||
|         RED.sidebar.show("config"); |         RED.sidebar.show("config"); | ||||||
|   | |||||||
| @@ -90,6 +90,9 @@ RED.view = (function() { | |||||||
|     var lastClickPosition = []; |     var lastClickPosition = []; | ||||||
|     var selectNodesOptions; |     var selectNodesOptions; | ||||||
|  |  | ||||||
|  |     let flashingNodeId; | ||||||
|  |     let flashingNodeTimer; | ||||||
|  |  | ||||||
|     var clipboard = ""; |     var clipboard = ""; | ||||||
|  |  | ||||||
|     // Note: these are the permitted status colour aliases. The actual RGB values |     // Note: these are the permitted status colour aliases. The actual RGB values | ||||||
| @@ -465,7 +468,7 @@ RED.view = (function() { | |||||||
|         $("#red-ui-view-searchtools-search").on("click", searchFlows); |         $("#red-ui-view-searchtools-search").on("click", searchFlows); | ||||||
|         RED.popover.tooltip($("#red-ui-view-searchtools-search"),RED._('actions.search-flows'),'core:search'); |         RED.popover.tooltip($("#red-ui-view-searchtools-search"),RED._('actions.search-flows'),'core:search'); | ||||||
|         $("#red-ui-view-searchtools-prev").on("click", searchPrev); |         $("#red-ui-view-searchtools-prev").on("click", searchPrev); | ||||||
|         RED.popover.tooltip($("#red-ui-view-searchtools-prev"),RED._('actions.search-prev'),'core:search-prev'); |         RED.popover.tooltip($("#red-ui-view-searchtools-prev"),RED._('actions.search-prev'),'core:search-previous'); | ||||||
|         $("#red-ui-view-searchtools-next").on("click", searchNext); |         $("#red-ui-view-searchtools-next").on("click", searchNext); | ||||||
|         RED.popover.tooltip($("#red-ui-view-searchtools-next"),RED._('actions.search-next'),'core:search-next'); |         RED.popover.tooltip($("#red-ui-view-searchtools-next"),RED._('actions.search-next'),'core:search-next'); | ||||||
|         RED.popover.tooltip($("#red-ui-view-searchtools-close"),RED._('common.label.close')); |         RED.popover.tooltip($("#red-ui-view-searchtools-close"),RED._('common.label.close')); | ||||||
| @@ -2024,8 +2027,8 @@ RED.view = (function() { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     function zoomZero() { zoomView(1); } |     function zoomZero() { zoomView(1); } | ||||||
|     function searchFlows() { RED.actions.invoke("core:search"); } |     function searchFlows() { RED.actions.invoke("core:search", $(this).data("term")); } | ||||||
|     function searchPrev() { RED.actions.invoke("core:search-prev"); } |     function searchPrev() { RED.actions.invoke("core:search-previous"); } | ||||||
|     function searchNext() { RED.actions.invoke("core:search-next"); } |     function searchNext() { RED.actions.invoke("core:search-next"); } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -5554,6 +5557,37 @@ RED.view = (function() { | |||||||
|         return result; |         return result; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     function flashNode(n) { | ||||||
|  |         let node = n; | ||||||
|  |         if(typeof node === "string") { node = RED.nodes.node(n); } | ||||||
|  |         if(!node) { return; } | ||||||
|  |  | ||||||
|  |         const flashingNode = flashingNodeTimer && flashingNodeId && RED.nodes.node(flashingNodeId); | ||||||
|  |         if(flashingNode) { | ||||||
|  |             //cancel current flashing node before flashing new node | ||||||
|  |             clearInterval(flashingNodeTimer); | ||||||
|  |             flashingNodeTimer = null; | ||||||
|  |             flashingNode.dirty = true; | ||||||
|  |             flashingNode.highlighted = false; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         flashingNodeTimer = setInterval(function(flashEndTime) { | ||||||
|  |             node.dirty = true; | ||||||
|  |             if (flashEndTime >= Date.now()) { | ||||||
|  |                 node.highlighted = !node.highlighted; | ||||||
|  |             } else { | ||||||
|  |                 clearInterval(flashingNodeTimer); | ||||||
|  |                 flashingNodeTimer = null; | ||||||
|  |                 node.highlighted = false; | ||||||
|  |                 flashingNodeId = null; | ||||||
|  |             } | ||||||
|  |             RED.view.redraw(); | ||||||
|  |         }, 100, Date.now() + 2200) | ||||||
|  |         flashingNodeId = node.id; | ||||||
|  |         node.highlighted = true; | ||||||
|  |         RED.view.redraw(); | ||||||
|  |     } | ||||||
|     return { |     return { | ||||||
|         init: init, |         init: init, | ||||||
|         state:function(state) { |         state:function(state) { | ||||||
| @@ -5636,7 +5670,7 @@ RED.view = (function() { | |||||||
|         getActiveGroup: function() { return activeGroup }, |         getActiveGroup: function() { return activeGroup }, | ||||||
|         reveal: function(id,triggerHighlight) { |         reveal: function(id,triggerHighlight) { | ||||||
|             if (RED.nodes.workspace(id) || RED.nodes.subflow(id)) { |             if (RED.nodes.workspace(id) || RED.nodes.subflow(id)) { | ||||||
|                 RED.workspaces.show(id); |                 RED.workspaces.show(id, null, null, true); | ||||||
|             } else { |             } else { | ||||||
|                 var node = RED.nodes.node(id) || RED.nodes.group(id); |                 var node = RED.nodes.node(id) || RED.nodes.group(id); | ||||||
|                 if (node) { |                 if (node) { | ||||||
| @@ -5661,24 +5695,7 @@ RED.view = (function() { | |||||||
|                             },200); |                             },200); | ||||||
|                         } |                         } | ||||||
|                         if (triggerHighlight !== false) { |                         if (triggerHighlight !== false) { | ||||||
|                             node.highlighted = true; |                             flashNode(node); | ||||||
|                             if (!node._flashing) { |  | ||||||
|                                 node._flashing = true; |  | ||||||
|                                 var flash = 22; |  | ||||||
|                                 var flashFunc = function() { |  | ||||||
|                                     flash--; |  | ||||||
|                                     node.dirty = true; |  | ||||||
|                                     if (flash >= 0) { |  | ||||||
|                                         node.highlighted = !node.highlighted; |  | ||||||
|                                         setTimeout(flashFunc,100); |  | ||||||
|                                     } else { |  | ||||||
|                                         node.highlighted = false; |  | ||||||
|                                         delete node._flashing; |  | ||||||
|                                     } |  | ||||||
|                                     RED.view.redraw(); |  | ||||||
|                                 } |  | ||||||
|                                 flashFunc(); |  | ||||||
|                             } |  | ||||||
|                         } |                         } | ||||||
|                     } else if (node._def.category === 'config') { |                     } else if (node._def.category === 'config') { | ||||||
|                         RED.sidebar.config.show(id); |                         RED.sidebar.config.show(id); | ||||||
|   | |||||||
| @@ -24,6 +24,9 @@ RED.workspaces = (function() { | |||||||
|     var hideStack = []; |     var hideStack = []; | ||||||
|     var viewStackPos = 0; |     var viewStackPos = 0; | ||||||
|  |  | ||||||
|  |     let flashingTab; | ||||||
|  |     let flashingTabTimer; | ||||||
|  |  | ||||||
|     function addToViewStack(id) { |     function addToViewStack(id) { | ||||||
|         if (viewStackPos !== viewStack.length) { |         if (viewStackPos !== viewStack.length) { | ||||||
|             viewStack.splice(viewStackPos); |             viewStack.splice(viewStackPos); | ||||||
| @@ -528,6 +531,31 @@ RED.workspaces = (function() { | |||||||
|         workspace_tabs.order(order); |         workspace_tabs.order(order); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     function flashTab(tabId) { | ||||||
|  |         if(flashingTab && flashingTab.length) { | ||||||
|  |             //cancel current flashing node before flashing new node | ||||||
|  |             clearInterval(flashingTabTimer); | ||||||
|  |             flashingTabTimer = null; | ||||||
|  |             flashingTab.removeClass('highlighted'); | ||||||
|  |             flashingTab = null; | ||||||
|  |         } | ||||||
|  |         let tab = $("#red-ui-tab-" + tabId); | ||||||
|  |         if(!tab || !tab.length) { return; } | ||||||
|  |  | ||||||
|  |         flashingTabTimer = setInterval(function(flashEndTime) { | ||||||
|  |             if (flashEndTime >= Date.now()) { | ||||||
|  |                 const highlighted = tab.hasClass("highlighted"); | ||||||
|  |                 tab.toggleClass('highlighted', !highlighted) | ||||||
|  |             } else { | ||||||
|  |                 clearInterval(flashingTabTimer); | ||||||
|  |                 flashingTabTimer = null; | ||||||
|  |                 flashingTab = null; | ||||||
|  |                 tab.removeClass('highlighted'); | ||||||
|  |             } | ||||||
|  |         }, 100, Date.now() + 2200); | ||||||
|  |         flashingTab = tab; | ||||||
|  |         tab.addClass('highlighted'); | ||||||
|  |     } | ||||||
|     return { |     return { | ||||||
|         init: init, |         init: init, | ||||||
|         add: addWorkspace, |         add: addWorkspace, | ||||||
| @@ -560,7 +588,7 @@ RED.workspaces = (function() { | |||||||
|         isHidden: function(id) { |         isHidden: function(id) { | ||||||
|             return hideStack.includes(id) |             return hideStack.includes(id) | ||||||
|         }, |         }, | ||||||
|         show: function(id,skipStack,unhideOnly) { |         show: function(id,skipStack,unhideOnly,flash) { | ||||||
|             if (!workspace_tabs.contains(id)) { |             if (!workspace_tabs.contains(id)) { | ||||||
|                 var sf = RED.nodes.subflow(id); |                 var sf = RED.nodes.subflow(id); | ||||||
|                 if (sf) { |                 if (sf) { | ||||||
| @@ -582,6 +610,9 @@ RED.workspaces = (function() { | |||||||
|                 } |                 } | ||||||
|                 workspace_tabs.activateTab(id); |                 workspace_tabs.activateTab(id); | ||||||
|             } |             } | ||||||
|  |             if(flash) { | ||||||
|  |                 flashTab(id.replace(".","-")) | ||||||
|  |             } | ||||||
|         }, |         }, | ||||||
|         refresh: function() { |         refresh: function() { | ||||||
|             RED.nodes.eachWorkspace(function(ws) { |             RED.nodes.eachWorkspace(function(ws) { | ||||||
|   | |||||||
| @@ -42,6 +42,10 @@ ul.red-ui-sidebar-node-config-list { | |||||||
|             border-color: transparent; |             border-color: transparent; | ||||||
|             box-shadow: 0 0 0 2px $node-selected-color; |             box-shadow: 0 0 0 2px $node-selected-color; | ||||||
|         } |         } | ||||||
|  |         &.highlighted { | ||||||
|  |             border-color: transparent; | ||||||
|  |             outline: dashed $node-selected-color 4px; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|     .red-ui-palette-label { |     .red-ui-palette-label { | ||||||
|         margin-left: 8px; |         margin-left: 8px; | ||||||
|   | |||||||
| @@ -85,6 +85,10 @@ | |||||||
|             &:not(.active) a:hover+a.red-ui-tab-close { |             &:not(.active) a:hover+a.red-ui-tab-close { | ||||||
|                 background: $tab-background-hover; |                 background: $tab-background-hover; | ||||||
|             } |             } | ||||||
|  |             &.highlighted { | ||||||
|  |                 box-shadow: 0px 0px 4px 2px $node-selected-color; | ||||||
|  |                 border: dashed 1px $node-selected-color; | ||||||
|  |             } | ||||||
|             &.active { |             &.active { | ||||||
|                 background: $tab-background-active; |                 background: $tab-background-active; | ||||||
|                 font-weight: bold; |                 font-weight: bold; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user