mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Add per-node filter option to Debug pane
This commit is contained in:
		| @@ -123,6 +123,7 @@ module.exports = function(grunt) { | ||||
|                     "editor/js/validators.js", | ||||
|                     "editor/js/ui/utils.js", | ||||
|                     "editor/js/ui/common/editableList.js", | ||||
|                     "editor/js/ui/common/checkboxSet.js", | ||||
|                     "editor/js/ui/common/menu.js", | ||||
|                     "editor/js/ui/common/panels.js", | ||||
|                     "editor/js/ui/common/popover.js", | ||||
|   | ||||
							
								
								
									
										131
									
								
								editor/js/ui/common/checkboxSet.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								editor/js/ui/common/checkboxSet.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,131 @@ | ||||
| /** | ||||
|  * Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
| (function($) { | ||||
|     $.widget( "nodered.checkboxSet", { | ||||
|         _create: function() { | ||||
|             var that = this; | ||||
|             this.uiElement = this.element.wrap( "<span>" ).parent(); | ||||
|             this.uiElement.addClass("red-ui-checkboxSet"); | ||||
|             if (this.options.parent) { | ||||
|                 this.parent = this.options.parent; | ||||
|                 this.parent.checkboxSet('addChild',this.element); | ||||
|             } | ||||
|             this.children = []; | ||||
|             this.partialFlag = false; | ||||
|             this.stateValue = 0; | ||||
|             var initialState = this.element.prop('checked'); | ||||
|             this.options = [ | ||||
|                 $('<span class="red-ui-checkboxSet-option hide"><i class="fa fa-square-o"></i></span>').appendTo(this.uiElement), | ||||
|                 $('<span class="red-ui-checkboxSet-option hide"><i class="fa fa-check-square-o"></i></span>').appendTo(this.uiElement), | ||||
|                 $('<span class="red-ui-checkboxSet-option hide"><i class="fa fa-minus-square-o"></i></span>').appendTo(this.uiElement) | ||||
|             ]; | ||||
|             if (initialState) { | ||||
|                 this.options[1].show(); | ||||
|             } else { | ||||
|                 this.options[0].show(); | ||||
|             } | ||||
|  | ||||
|             this.element.change(function() { | ||||
|                 if (this.checked) { | ||||
|                     that.options[0].hide(); | ||||
|                     that.options[1].show(); | ||||
|                     that.options[2].hide(); | ||||
|                 } else { | ||||
|                     that.options[1].hide(); | ||||
|                     that.options[0].show(); | ||||
|                     that.options[2].hide(); | ||||
|                 } | ||||
|                 var isChecked = this.checked; | ||||
|                 that.children.forEach(function(child) { | ||||
|                     child.checkboxSet('state',isChecked,false,true); | ||||
|                 }) | ||||
|             }) | ||||
|             this.uiElement.click(function(e) { | ||||
|                 e.stopPropagation(); | ||||
|                 // state returns null for a partial state. Clicking on that should | ||||
|                 // result in false. | ||||
|                 that.state((that.state()===false)?true:false); | ||||
|             }) | ||||
|             if (this.parent) { | ||||
|                 this.parent.checkboxSet('updateChild',this); | ||||
|             } | ||||
|         }, | ||||
|         _destroy: function() { | ||||
|             if (this.parent) { | ||||
|                 this.parent.checkboxSet('removeChild',this.element); | ||||
|             } | ||||
|         }, | ||||
|         addChild: function(child) { | ||||
|             var that = this; | ||||
|             this.children.push(child); | ||||
|         }, | ||||
|         removeChild: function(child) { | ||||
|             var index = this.children.indexOf(child); | ||||
|             if (index > -1) { | ||||
|                 this.children.splice(index,1); | ||||
|             } | ||||
|         }, | ||||
|         updateChild: function(child) { | ||||
|             var checkedCount = 0; | ||||
|             this.children.forEach(function(c,i) { | ||||
|                 if (c.checkboxSet('state') === true) { | ||||
|                     checkedCount++; | ||||
|                 } | ||||
|             }); | ||||
|             if (checkedCount === 0) { | ||||
|  | ||||
|                 this.state(false,true); | ||||
|             } else if (checkedCount === this.children.length) { | ||||
|                 this.state(true,true); | ||||
|             } else { | ||||
|                 this.state(null,true); | ||||
|             } | ||||
|         }, | ||||
|         disable: function() { | ||||
|             this.uiElement.addClass('disabled'); | ||||
|         }, | ||||
|         state: function(state,suppressEvent,suppressParentUpdate) { | ||||
|  | ||||
|             if (arguments.length === 0) { | ||||
|                 return this.partialFlag?null:this.element.is(":checked"); | ||||
|             } else { | ||||
|                 this.partialFlag = (state === null); | ||||
|                 var trueState = this.partialFlag||state; | ||||
|                 this.element.prop('checked',trueState); | ||||
|                 if (state === true) { | ||||
|                     this.options[0].hide(); | ||||
|                     this.options[1].show(); | ||||
|                     this.options[2].hide(); | ||||
|                 } else if (state === false) { | ||||
|                     this.options[2].hide(); | ||||
|                     this.options[1].hide(); | ||||
|                     this.options[0].show(); | ||||
|                 } else if (state === null) { | ||||
|                     this.options[0].hide(); | ||||
|                     this.options[1].hide(); | ||||
|                     this.options[2].show(); | ||||
|                 } | ||||
|                 if (!suppressEvent) { | ||||
|                     this.element.trigger('change',null); | ||||
|                 } | ||||
|                 if (!suppressParentUpdate && this.parent) { | ||||
|                     this.parent.checkboxSet('updateChild',this); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     }) | ||||
|  | ||||
| })(jQuery); | ||||
| @@ -50,9 +50,19 @@ | ||||
|             this.uiContainer = this.element | ||||
|                 .wrap( "<div>" ) | ||||
|                 .parent(); | ||||
|             this.topContainer = this.uiContainer.wrap("<div>").parent(); | ||||
|  | ||||
|             if (this.options.header) { | ||||
|                 this.options.header.addClass("red-ui-editableList-header"); | ||||
|                 this.borderContainer = this.uiContainer.wrap("<div>").parent(); | ||||
|                 this.borderContainer.prepend(this.options.header); | ||||
|                 this.topContainer = this.borderContainer.wrap("<div>").parent(); | ||||
|             } else { | ||||
|                 this.topContainer = this.uiContainer.wrap("<div>").parent(); | ||||
|             } | ||||
|             this.topContainer.addClass('red-ui-editableList'); | ||||
|             if (this.options.class) { | ||||
|                 this.topContainer.addClass(this.options.class); | ||||
|             } | ||||
|  | ||||
|             if (this.options.addButton !== false) { | ||||
|                 var addLabel; | ||||
| @@ -86,6 +96,11 @@ | ||||
|                 this.uiContainer.css("position","absolute"); | ||||
|  | ||||
|             } | ||||
|             if (this.options.header) { | ||||
|                 this.borderContainer.addClass("red-ui-editableList-border"); | ||||
|             } else { | ||||
|                 this.uiContainer.addClass("red-ui-editableList-border"); | ||||
|             } | ||||
|             this.uiContainer.addClass("red-ui-editableList-container"); | ||||
|  | ||||
|             this.uiHeight = this.element.height(); | ||||
| @@ -273,6 +288,11 @@ | ||||
|                 },0); | ||||
|             } | ||||
|         }, | ||||
|         addItems: function(items) { | ||||
|             for (var i=0; i<items.length;i++) { | ||||
|                 this.addItem(items[i]); | ||||
|             } | ||||
|         }, | ||||
|         removeItem: function(data) { | ||||
|             var items = this.element.children().filter(function(f) { | ||||
|                 return data === $(this).find(".red-ui-editableList-item-content").data('data'); | ||||
|   | ||||
| @@ -594,12 +594,17 @@ RED.utils = (function() { | ||||
|  | ||||
|     function getNodeLabel(node,defaultLabel) { | ||||
|         defaultLabel = defaultLabel||""; | ||||
|         var l = node._def.label; | ||||
|         try { | ||||
|             l = (typeof l === "function" ? l.call(node) : l)||defaultLabel; | ||||
|         } catch(err) { | ||||
|             console.log("Definition error: "+node.type+".label",err); | ||||
|             l = defaultLabel; | ||||
|         var l; | ||||
|         if (node.type === 'tab') { | ||||
|             l = node.label || defaultLabel | ||||
|         } else { | ||||
|             l = node._def.label; | ||||
|             try { | ||||
|                 l = (typeof l === "function" ? l.call(node) : l)||defaultLabel; | ||||
|             } catch(err) { | ||||
|                 console.log("Definition error: "+node.type+".label",err); | ||||
|                 l = defaultLabel; | ||||
|             } | ||||
|         } | ||||
|         return RED.text.bidi.enforceTextDirectionWithUCC(l); | ||||
|     } | ||||
|   | ||||
| @@ -36,13 +36,16 @@ | ||||
|     top: 42px; | ||||
|     left: 0px; | ||||
|     right: 0px; | ||||
|     z-index: 20; | ||||
|     background: #f9f9f9; | ||||
|     padding: 10px; | ||||
|     border-bottom: 1px solid #ddd; | ||||
|     box-shadow: 0 2px 6px rgba(0,0,0,0.1); | ||||
| } | ||||
| .debug-filter-row { | ||||
|     text-align: right; | ||||
|     .red-ui-nodeList { | ||||
|         margin: 10px 0; | ||||
|     } | ||||
| } | ||||
|  | ||||
| .debug-message { | ||||
|   | ||||
| @@ -52,6 +52,8 @@ | ||||
| @import "ui/common/editableList"; | ||||
| @import "ui/common/searchBox"; | ||||
| @import "ui/common/typedInput"; | ||||
| @import "ui/common/nodeList"; | ||||
| @import "ui/common/checkboxSet"; | ||||
|  | ||||
| @import "dragdrop"; | ||||
|  | ||||
|   | ||||
							
								
								
									
										29
									
								
								editor/sass/ui/common/checkboxSet.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								editor/sass/ui/common/checkboxSet.scss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| /** | ||||
|  * Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
| .red-ui-checkboxSet { | ||||
|     width: 15px; | ||||
|     display: inline-block; | ||||
|     color: #888; | ||||
|     cursor: pointer; | ||||
|     input { | ||||
|         display:none; | ||||
|     } | ||||
|  | ||||
|     &.disabled { | ||||
|         pointer-events: none; | ||||
|         color: #ddd; | ||||
|     } | ||||
| } | ||||
| @@ -13,59 +13,63 @@ | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
| .red-ui-editableList-border { | ||||
|     border: 1px solid $form-input-border-color; | ||||
|     border-radius: 4px; | ||||
|     .red-ui-editableList-header { | ||||
|         border-bottom: 1px solid $form-input-border-color; | ||||
|         padding: 2px 16px 2px 4px; | ||||
|         font-size: 0.9em; | ||||
|     } | ||||
| } | ||||
| .red-ui-editableList-container { | ||||
|     padding: 5px; | ||||
|     margin: 0; | ||||
|     vertical-align: middle; | ||||
|     box-sizing: border-box; | ||||
|     .red-ui-editableList-list { | ||||
|         list-style-type:none; | ||||
|         margin: 0; | ||||
|     } | ||||
|     .red-ui-editabelList-item-placeholder { | ||||
|         border: 2px dashed $secondary-border-color !important; | ||||
|     } | ||||
|     li { | ||||
|         box-sizing: border-box; | ||||
|         position: relative; | ||||
|         background: #fff; | ||||
|         margin:0; | ||||
|         padding:8px 0px; | ||||
|         border-bottom: 1px solid $secondary-border-color; | ||||
|         min-height: 20px; | ||||
|         .red-ui-editableList-item-handle { | ||||
|             position: absolute; | ||||
|             top: 50%; | ||||
|             left: 2px; | ||||
|             margin-top: -7px; | ||||
|             color: #eee; | ||||
|             cursor: move; | ||||
|         } | ||||
|         .red-ui-editableList-item-remove { | ||||
|             position: absolute; | ||||
|             top: 50%; | ||||
|             right: 0px; | ||||
|             margin-top: -9px; | ||||
|         } | ||||
|         &.ui-sortable-helper { | ||||
|             border-top: 1px solid $secondary-border-color; | ||||
|         } | ||||
|         //.red-ui-editableList-item-content { outline: 1px solid red} | ||||
|  | ||||
|         &.red-ui-editableList-item-sortable .red-ui-editableList-item-content { | ||||
|             margin-left: 22px; | ||||
|         } | ||||
|         &.red-ui-editableList-item-removable .red-ui-editableList-item-content { | ||||
|             margin-right: 28px; | ||||
|         } | ||||
|         &.red-ui-editableList-item-deleting { | ||||
|             background: #fee; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  .red-ui-editableList-container { | ||||
|      border: 1px solid $form-input-border-color; | ||||
|      border-radius: 4px; | ||||
|      padding: 5px; | ||||
|      margin: 0; | ||||
|      vertical-align: middle; | ||||
|      box-sizing: border-box; | ||||
|  | ||||
|      .red-ui-editableList-list { | ||||
|          list-style-type:none; | ||||
|          margin: 0; | ||||
|      } | ||||
|      .red-ui-editabelList-item-placeholder { | ||||
|          border: 2px dashed $secondary-border-color !important; | ||||
|      } | ||||
|      li { | ||||
|          box-sizing: border-box; | ||||
|          position: relative; | ||||
|          background: #fff; | ||||
|          margin:0; | ||||
|          padding:8px 0px; | ||||
|          border-bottom: 1px solid $secondary-border-color; | ||||
|          min-height: 20px; | ||||
|          .red-ui-editableList-item-handle { | ||||
|              position: absolute; | ||||
|              top: 50%; | ||||
|              left: 2px; | ||||
|              margin-top: -7px; | ||||
|              color: #eee; | ||||
|              cursor: move; | ||||
|          } | ||||
|          .red-ui-editableList-item-remove { | ||||
|              position: absolute; | ||||
|              top: 50%; | ||||
|              right: 0px; | ||||
|              margin-top: -9px; | ||||
|          } | ||||
|          &.ui-sortable-helper { | ||||
|              border-top: 1px solid $secondary-border-color; | ||||
|          } | ||||
|          //.red-ui-editableList-item-content { outline: 1px solid red} | ||||
|  | ||||
|          &.red-ui-editableList-item-sortable .red-ui-editableList-item-content { | ||||
|              margin-left: 22px; | ||||
|          } | ||||
|          &.red-ui-editableList-item-removable .red-ui-editableList-item-content { | ||||
|              margin-right: 28px; | ||||
|          } | ||||
|          &.red-ui-editableList-item-deleting { | ||||
|              background: #fee; | ||||
|          } | ||||
|      } | ||||
|  | ||||
|  } | ||||
| } | ||||
|   | ||||
							
								
								
									
										65
									
								
								editor/sass/ui/common/nodeList.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								editor/sass/ui/common/nodeList.scss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | ||||
| /** | ||||
|  * Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
| .red-ui-nodeList { | ||||
|     .red-ui-editableList-container { | ||||
|         padding: 0; | ||||
|         li { | ||||
|             padding: 2px 5px; | ||||
|             margin: 0; | ||||
|             white-space: nowrap; | ||||
|             border: none; | ||||
|             background: #fefefe; | ||||
|             &:hover { | ||||
|                 background: #f0f0f0; | ||||
|             } | ||||
|  | ||||
|             i.fa-angle-right { | ||||
|                 text-align: center; | ||||
|                 width: 15px; | ||||
|                 transition: transform 0.1s ease-in-out; | ||||
|             } | ||||
|             .expandable { | ||||
|                 cursor: pointer; | ||||
|             } | ||||
|             .expanded i.fa-angle-right { | ||||
|                 transform: rotate(90deg); | ||||
|             } | ||||
|             .meta { | ||||
|                 float: right; | ||||
|                 input[type="checkbox"] { | ||||
|                     margin: 0; | ||||
|                 } | ||||
|             } | ||||
|             .red-ui-editableList-item-content.disabled { | ||||
|                 color: #ccc; | ||||
|             } | ||||
|             &.red-ui-editableList-section-header { | ||||
|                 background: #f0f0f0; | ||||
|                 .red-ui-editableList-item-content.disabled { | ||||
|                     color: #bbb; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|         } | ||||
|     } | ||||
|     .red-ui-editableList-header { | ||||
|         text-align: left; | ||||
|         &>span:last-child { | ||||
|             float: right; | ||||
|             font-size: 14px; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -168,6 +168,7 @@ | ||||
|                     } | ||||
|                 } | ||||
|             }; | ||||
|             RED.events.on("workspace:change", this.refreshMessageList); | ||||
|  | ||||
|             this.handleDebugMessage = function(t,o) { | ||||
|                 var sourceNode = RED.nodes.node(o.id) || RED.nodes.node(o.z); | ||||
| @@ -186,8 +187,6 @@ | ||||
|             }; | ||||
|             RED.comms.subscribe("debug",this.handleDebugMessage); | ||||
|  | ||||
|             RED.events.on("workspace:change", this.refreshMessageList); | ||||
|  | ||||
|             $("#debug-tab-open").click(function(e) { | ||||
|                 e.preventDefault(); | ||||
|                 subWindow = window.open(document.location.toString().replace(/[?#].*$/,"")+"debug/view/view.html"+document.location.search,"nodeREDDebugView","menubar=no,location=no,toolbar=no,chrome,height=500,width=600"); | ||||
|   | ||||
| @@ -21,22 +21,28 @@ RED.debug = (function() { | ||||
|     var config; | ||||
|     var messageList; | ||||
|     var messageTable; | ||||
|     var filter = false; | ||||
|     var filterType = "filterAll"; | ||||
|     var filteredNodes = {}; // id->true means hide, so default to all visible | ||||
|  | ||||
|     var view = 'list'; | ||||
|     var messages = []; | ||||
|     var messagesByNode = {}; | ||||
|     var sbc; | ||||
|     var activeWorkspace; | ||||
|  | ||||
|     var filterVisible = false; | ||||
|  | ||||
|     var debugNodeList; | ||||
|     var debugNodeListExpandedFlows = {}; | ||||
|  | ||||
|     function init(_config) { | ||||
|         config = _config; | ||||
|  | ||||
|         var content = $("<div>").css({"position":"relative","height":"100%"}); | ||||
|         var toolbar = $('<div class="sidebar-header">'+ | ||||
|             '<span class="button-group"><a id="debug-tab-filter" class="sidebar-header-button" href="#"><i class="fa fa-filter"></i></a></span>'+ | ||||
|             '<span class="button-group"><a id="debug-tab-filter" class="sidebar-header-button" href="#"><i class="fa fa-filter"></i> <span></span></a></span>'+ | ||||
|             '<span class="button-group"><a id="debug-tab-clear" title="clear log" class="sidebar-header-button" href="#"><i class="fa fa-trash"></i></a></span></div>').appendTo(content); | ||||
|  | ||||
|  | ||||
|         var footerToolbar = $('<div>'+ | ||||
|             // '<span class="button-group">'+ | ||||
|             //     '<a class="sidebar-footer-button-toggle text-button selected" id="debug-tab-view-list" href="#"><span data-i18n="">list</span></a>'+ | ||||
| @@ -52,11 +58,82 @@ RED.debug = (function() { | ||||
|         var filterDialog = $('<div class="debug-filter-box hide">'+ | ||||
|             '<div class="debug-filter-row">'+ | ||||
|             '<span class="button-group">'+ | ||||
|                 '<a class="sidebar-header-button-toggle selected" id="debug-tab-filter-all" href="#"><span data-i18n="node-red:debug.sidebar.filterAll">all flows</span></a>'+ | ||||
|                 '<a class="sidebar-header-button-toggle" id="debug-tab-filter-current" href="#"><span data-i18n="node-red:debug.sidebar.filterCurrent">current flow</span></a> '+ | ||||
|                 '<a class="sidebar-header-button-toggle debug-tab-filter-option selected" id="debug-tab-filterAll" href="#"><span data-i18n="node-red:debug.sidebar.filterAll"></span></a>'+ | ||||
|                 '<a class="sidebar-header-button-toggle debug-tab-filter-option" id="debug-tab-filterSelected" href="#"><span data-i18n="node-red:debug.sidebar.filterSelected"></span></a>'+ | ||||
|                 '<a class="sidebar-header-button-toggle debug-tab-filter-option" id="debug-tab-filterCurrent" href="#"><span data-i18n="node-red:debug.sidebar.filterCurrent"></span></a> '+ | ||||
|             '</span>'+ | ||||
|             '</div>'+ | ||||
|         '</div>').appendTo(content); | ||||
|         '</div>').appendTo(toolbar);//content); | ||||
|  | ||||
|         // var filterTypeRow = $('<div class="debug-filter-row"></div>').appendTo(filterDialog); | ||||
|         // $('<select><option>Show all debug nodes</option><option>Show selected debug nodes</option><option>Show current flow only</option></select>').appendTo(filterTypeRow); | ||||
|  | ||||
|         var debugNodeListRow = $('<div class="debug-filter-row hide"></div>').appendTo(filterDialog); | ||||
|         var flowCheckboxes = {}; | ||||
|         var debugNodeListHeader = $('<div><span>Debug nodes</span><span></span></div>'); | ||||
|         var headerCheckbox = $('<input type="checkbox">').appendTo(debugNodeListHeader.find("span")[1]).checkboxSet(); | ||||
|  | ||||
|         debugNodeList = $('<ol>',{style:"text-align: left; min-height: 250px; max-height: 250px"}).appendTo(debugNodeListRow).editableList({ | ||||
|             header: debugNodeListHeader, | ||||
|             class: 'red-ui-nodeList', | ||||
|             addItem: function(container,i,node) { | ||||
|                 var row = $("<div>").appendTo(container); | ||||
|                 row.attr('id','debug-filter-node-list-node-'+node.id.replace(/\./g,"_")); | ||||
|                 if (node.type === 'tab') { | ||||
|                     container.parent().addClass('red-ui-editableList-section-header'); | ||||
|                     if (!debugNodeListExpandedFlows.hasOwnProperty(node.id)) { | ||||
|                         debugNodeListExpandedFlows[node.id] = true; | ||||
|                     } | ||||
|                     var chevron = $('<i class="fa fa-angle-right"></i>').appendTo(row); | ||||
|                     $('<span>').text(RED.utils.getNodeLabel(node,node.id)).appendTo(row); | ||||
|                     var muteControl = $('<input type="checkbox">').appendTo($('<span class="meta">').appendTo(row)); | ||||
|                     muteControl.checkboxSet({ | ||||
|                         parent: headerCheckbox | ||||
|                     }); | ||||
|                     flowCheckboxes[node.id] = muteControl; | ||||
|                     row.click(function(e) { | ||||
|                         e.stopPropagation(); | ||||
|                         debugNodeListExpandedFlows[node.id] = !debugNodeListExpandedFlows[node.id]; | ||||
|                         row.toggleClass('expanded',debugNodeListExpandedFlows[node.id]); | ||||
|                         debugNodeList.editableList('filter'); | ||||
|                     }) | ||||
|                     row.addClass("expandable"); | ||||
|                     if (node.disabled) { | ||||
|                         container.addClass('disabled'); | ||||
|                         muteControl.checkboxSet('disable'); | ||||
|                         debugNodeListExpandedFlows[node.id] = false; | ||||
|                     } | ||||
|                     row.toggleClass('expanded',debugNodeListExpandedFlows[node.id]); | ||||
|                 } else { | ||||
|                     $('<span>',{style: "margin-left: 20px"}).text(RED.utils.getNodeLabel(node,node.id)).appendTo(row); | ||||
|                     row.on("mouseenter",function() { | ||||
|                         config.messageMouseEnter(node.id); | ||||
|                     }); | ||||
|                     row.on("mouseleave",function() { | ||||
|                         config.messageMouseLeave(node.id); | ||||
|                     }); | ||||
|                     var muteControl = $('<input type="checkbox">').prop('checked',!filteredNodes[node.id]).appendTo($('<span class="meta">').appendTo(row)); | ||||
|                     muteControl.checkboxSet({ | ||||
|                         parent: flowCheckboxes[node.z] | ||||
|                     }).change(function(e) { | ||||
|                         filteredNodes[node.id] = !$(this).prop('checked'); | ||||
|                         $(".debug-message-node-"+node.id.replace(/\./g,"_")).toggleClass('hide',filteredNodes[node.id]); | ||||
|                     }); | ||||
|                     if (!node.active || RED.nodes.workspace(node.z).disabled) { | ||||
|                         container.addClass('disabled'); | ||||
|                         muteControl.checkboxSet('disable'); | ||||
|                     } | ||||
|                 } | ||||
|             }, | ||||
|             addButton: false, | ||||
|             scrollOnAdd: false, | ||||
|             filter: function(node) { | ||||
|                 return (node.type === 'tab' || debugNodeListExpandedFlows[node.z] ) | ||||
|             }, | ||||
|             sort: function(A,B) { | ||||
|  | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         try { | ||||
|             content.i18n(); | ||||
| @@ -64,25 +141,32 @@ RED.debug = (function() { | ||||
|             console.log("TODO: i18n library support"); | ||||
|         } | ||||
|  | ||||
|         toolbar.find('#debug-tab-filter span').text(RED._('node-red:debug.sidebar.filterAll')); | ||||
|  | ||||
|         filterDialog.find('#debug-tab-filter-all').on("click",function(e) { | ||||
|             e.preventDefault(); | ||||
|             if (filter) { | ||||
|                 $(this).addClass('selected'); | ||||
|                 $('#debug-tab-filter-current').removeClass('selected'); | ||||
|                 filter = !filter; | ||||
|                 refreshMessageList(); | ||||
|         var filterButtonHandler = function(type) { | ||||
|             return function(e) { | ||||
|                 e.preventDefault(); | ||||
|                 if (filterType !== type) { | ||||
|                     $('.debug-tab-filter-option').removeClass('selected'); | ||||
|                     $(this).addClass('selected'); | ||||
|                     if (filterType === 'filterSelected') { | ||||
|                         debugNodeListRow.slideUp(); | ||||
|                     } | ||||
|                     filterType = type; | ||||
|                     if (filterType === 'filterSelected') { | ||||
|                         debugNodeListRow.slideDown(); | ||||
|                     } | ||||
|  | ||||
|                     $('#debug-tab-filter span').text(RED._('node-red:debug.sidebar.'+filterType)); | ||||
|                     refreshMessageList(); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|         filterDialog.find('#debug-tab-filter-current').on("click",function(e) { | ||||
|             e.preventDefault(); | ||||
|             if (!filter) { | ||||
|                 $(this).addClass('selected'); | ||||
|                 $('#debug-tab-filter-all').removeClass('selected'); | ||||
|                 filter = !filter; | ||||
|                 refreshMessageList(); | ||||
|             } | ||||
|         }); | ||||
|         } | ||||
|         filterDialog.find('#debug-tab-filterAll').on("click",filterButtonHandler('filterAll')); | ||||
|         filterDialog.find('#debug-tab-filterSelected').on("click",filterButtonHandler('filterSelected')); | ||||
|         filterDialog.find('#debug-tab-filterCurrent').on("click",filterButtonHandler('filterCurrent')); | ||||
|  | ||||
|  | ||||
|         // $('#debug-tab-view-list').on("click",function(e) { | ||||
|         //     e.preventDefault(); | ||||
|         //     if (!$(this).hasClass('selected')) { | ||||
| @@ -101,13 +185,33 @@ RED.debug = (function() { | ||||
|         // }); | ||||
|  | ||||
|  | ||||
|         var hideFilterTimeout; | ||||
|         toolbar.on('mouseleave',function() { | ||||
|             if ($('#debug-tab-filter').hasClass('selected')) { | ||||
|                 clearTimeout(hideFilterTimeout); | ||||
|                 hideFilterTimeout = setTimeout(function() { | ||||
|                     filterVisible = false; | ||||
|                     $('#debug-tab-filter').removeClass('selected'); | ||||
|                     filterDialog.slideUp(200); | ||||
|                 },300); | ||||
|             } | ||||
|         }); | ||||
|         toolbar.on('mouseenter',function() { | ||||
|             if ($('#debug-tab-filter').hasClass('selected')) { | ||||
|                 clearTimeout(hideFilterTimeout); | ||||
|             } | ||||
|         }) | ||||
|         toolbar.find('#debug-tab-filter').on("click",function(e) { | ||||
|             e.preventDefault(); | ||||
|             if ($(this).hasClass('selected')) { | ||||
|                 filterVisible = false; | ||||
|                 $(this).removeClass('selected'); | ||||
|                 clearTimeout(hideFilterTimeout); | ||||
|                 filterDialog.slideUp(200); | ||||
|             } else { | ||||
|                 $(this).addClass('selected'); | ||||
|                 filterVisible = true; | ||||
|                 refreshDebugNodeList(); | ||||
|                 filterDialog.slideDown(200); | ||||
|             } | ||||
|         }) | ||||
| @@ -127,6 +231,38 @@ RED.debug = (function() { | ||||
|  | ||||
|     } | ||||
|  | ||||
|     function refreshDebugNodeList() { | ||||
|         debugNodeList.editableList('empty'); | ||||
|         var candidateNodes = RED.nodes.filterNodes({type:'debug'}); | ||||
|         var workspaceOrder = RED.nodes.getWorkspaceOrder(); | ||||
|         var workspaceOrderMap = {}; | ||||
|         workspaceOrder.forEach(function(ws,i) { | ||||
|             workspaceOrderMap[ws] = i; | ||||
|         }); | ||||
|         candidateNodes.sort(function(A,B) { | ||||
|             var wsA = workspaceOrderMap[A.z]; | ||||
|             var wsB = workspaceOrderMap[B.z]; | ||||
|             if (wsA !== wsB) { | ||||
|                 return wsA-wsB; | ||||
|             } | ||||
|             var labelA = RED.utils.getNodeLabel(A,A.id); | ||||
|             var labelB = RED.utils.getNodeLabel(B,B.id); | ||||
|             return labelA.localeCompare(labelB); | ||||
|         }) | ||||
|         var currentWs = null; | ||||
|         var nodeList = []; | ||||
|         candidateNodes.forEach(function(node) { | ||||
|             if (currentWs !== node.z) { | ||||
|                 currentWs = node.z; | ||||
|                 nodeList.push(RED.nodes.workspace(node.z)); | ||||
|             } | ||||
|             nodeList.push(node); | ||||
|         }) | ||||
|  | ||||
|  | ||||
|         debugNodeList.editableList('addItems',nodeList) | ||||
|     } | ||||
|  | ||||
|     function getTimestamp() { | ||||
|         var d = new Date(); | ||||
|         return d.toLocaleString(); | ||||
| @@ -138,11 +274,22 @@ RED.debug = (function() { | ||||
|  | ||||
|     function refreshMessageList(_activeWorkspace) { | ||||
|         if (_activeWorkspace) { | ||||
|             activeWorkspace = _activeWorkspace; | ||||
|             activeWorkspace = _activeWorkspace.replace(/\./g,"_"); | ||||
|         } | ||||
|         if (filterType === "filterAll") { | ||||
|             $(".debug-message").removeClass("hide"); | ||||
|         } else { | ||||
|             $(".debug-message").each(function() { | ||||
|                 if (filterType === 'filterCurrent') { | ||||
|                     $(this).toggleClass('hide',!$(this).hasClass('debug-message-flow-'+activeWorkspace)); | ||||
|                 } else if (filterType === 'filterSelected') { | ||||
|                     var id = $(this).data('source'); | ||||
|                     if (id) { | ||||
|                         $(this).toggleClass('hide',!!filteredNodes[id]); | ||||
|                     } | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|         $(".debug-message").each(function() { | ||||
|             $(this).toggleClass('hide',filter&&!$(this).hasClass('debug-message-flow-'+activeWorkspace)); | ||||
|         }); | ||||
|     } | ||||
|     function refreshMessageTable() { | ||||
|  | ||||
| @@ -191,6 +338,20 @@ RED.debug = (function() { | ||||
|                     }}, | ||||
|                     {id:"debug-message-menu-item-clear-pins",label:RED._("node-red:debug.messageMenu.clearPinned"),onselect:function(){ | ||||
|                         activeMenuMessage.clearPinned(); | ||||
|                     }}, | ||||
|                     null, | ||||
|                     {id:"debug-message-menu-item-filter",label:RED._("node-red:debug.messageMenu.filterNode"),onselect:function(){ | ||||
|                         var candidateNodes = RED.nodes.filterNodes({type:'debug'}); | ||||
|                         candidateNodes.forEach(function(n) { | ||||
|                             filteredNodes[n.id] = true; | ||||
|                         }); | ||||
|                         delete filteredNodes[sourceId]; | ||||
|                         $("#debug-tab-filterSelected").click(); | ||||
|                         refreshMessageList(); | ||||
|                     }}, | ||||
|                     {id:"debug-message-menu-item-clear-filter",label:RED._("node-red:debug.messageMenu.clearFilter"),onselect:function(){ | ||||
|                         $("#debug-tab-filterAll").click(); | ||||
|                         refreshMessageList(); | ||||
|                     }} | ||||
|                 ] | ||||
|             }); | ||||
| @@ -230,8 +391,25 @@ RED.debug = (function() { | ||||
|         var property = sanitize(o.property?o.property:''); | ||||
|         var payload = o.msg; | ||||
|         var format = sanitize((o.format||"").toString()); | ||||
|         msg.className = 'debug-message'+(o.level?(' debug-message-level-'+o.level):'') + | ||||
|         ((sourceNode&&sourceNode.z)?((" debug-message-flow-"+sourceNode.z+((filter&&(activeWorkspace!==sourceNode.z))?" hide":""))):""); | ||||
|         msg.className = 'debug-message'+(o.level?(' debug-message-level-'+o.level):'')+ | ||||
|             (sourceNode?( | ||||
|                 " debug-message-node-"+sourceNode.id.replace(/\./g,"_")+ | ||||
|                 (sourceNode.z?" debug-message-flow-"+sourceNode.z.replace(/\./g,"_"):"") | ||||
|             ):""); | ||||
|  | ||||
|         if (sourceNode) { | ||||
|             $(msg).data('source',sourceNode.id); | ||||
|             if (filterType === "filterCurrent" && activeWorkspace) { | ||||
|                 if (sourceNode.z && sourceNode.z.replace(/\./g,"_") !== activeWorkspace) { | ||||
|                     $(msg).addClass('hide'); | ||||
|                 } | ||||
|             } else if (filterType === 'filterSelected'){ | ||||
|                 if (!!filteredNodes[sourceNode.id]) { | ||||
|                     $(msg).addClass('hide'); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         var metaRow = $('<div class="debug-message-meta"></div>').appendTo(msg); | ||||
|         $('<span class="debug-message-date">'+ getTimestamp()+'</span>').appendTo(metaRow); | ||||
|         if (sourceNode) { | ||||
| @@ -322,9 +500,11 @@ RED.debug = (function() { | ||||
|             messageList.scrollTop(sbc.scrollHeight); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return { | ||||
|         init: init, | ||||
|         refreshMessageList:refreshMessageList, | ||||
|         handleDebugMessage: handleDebugMessage | ||||
|         handleDebugMessage: handleDebugMessage, | ||||
|  | ||||
|     } | ||||
| })(); | ||||
|   | ||||
| @@ -112,12 +112,15 @@ | ||||
|         "sidebar": { | ||||
|             "label": "debug", | ||||
|             "name": "Debug messages", | ||||
|             "filterAll": "all flows", | ||||
|             "filterAll": "all nodes", | ||||
|             "filterSelected": "selected nodes", | ||||
|             "filterCurrent": "current flow" | ||||
|         }, | ||||
|         "messageMenu": { | ||||
|             "collapseAll": "Collapse all paths", | ||||
|             "clearPinned": "Clear pinned paths" | ||||
|             "clearPinned": "Clear pinned paths", | ||||
|             "filterNode": "Filter this node", | ||||
|             "clearFilter": "Clear filter" | ||||
|         } | ||||
|     }, | ||||
|     "link": { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user