@gregoriusrippenstein/node-red-contrib-introspection 0.5.2 → 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,15 +1,16 @@
1
1
  {
2
2
  "name": "@gregoriusrippenstein/node-red-contrib-introspection",
3
- "version": "0.5.2",
3
+ "version": "0.5.4",
4
4
  "dependencies": {
5
- "got": "latest"
5
+ "got": ">=13.0.0"
6
6
  },
7
7
 
8
8
  "keywords": [
9
9
  "node-red",
10
10
  "introspection",
11
11
  "selfreflection",
12
- "node-red-editor"
12
+ "node-red-editor",
13
+ "screenshot"
13
14
  ],
14
15
 
15
16
  "homepage": "https://github.com/gorenje/node-red-contrib-introspection#readme",
@@ -22,8 +23,7 @@
22
23
  "node-red": {
23
24
  "version": ">=2.0.0",
24
25
  "plugins": {
25
- "screenshot": "plugins/screenshot.html",
26
- "orphans": "plugins/orphans.html"
26
+ "screenshot": "plugins/sidebar.html"
27
27
  },
28
28
  "nodes": {
29
29
  "seeker": "nodes/05-seeker.js",
@@ -2,7 +2,9 @@
2
2
  (function() {
3
3
  var globalRefToSvgData;
4
4
 
5
- function nr_intro_generate_svg_3_1(r){return e=>{try{handleSvgObject($($("svg[width=8000]")[0]),e)}catch(t){var n="Error Generating SVG: "+JSON.stringify(t);r.notify(n,{type:"error"}),e('<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg width="1000" height="1000" viewBox="0 0 1000 1000" pointer-events="all" style="cursor: crosshair; touch-action: none;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style>.small { font: bold 20px sans-serif; fill: red;}</style><text x="10" y="30" class="small">'+n+"</text></svg>")}}}function nr_intro_generate_svg_3_0(r){return e=>{try{handleSvgObject($($("svg")[0]),e)}catch(t){var n="Error Generating SVG: "+JSON.stringify(t);r.notify(n,{type:"error"}),e('<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg width="1000" height="1000" viewBox="0 0 1000 1000" pointer-events="all" style="cursor: crosshair; touch-action: none;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style>.small { font: bold 20px sans-serif; fill: red;}</style><text x="10" y="30" class="small">'+n+"</text></svg>")}}}function handleSvgObject(o,e){var t=o.clone();t.find("foreignObject").remove(),t.find("svg.__screenshot").remove();function a(t,e){for(var n=0;n<t.length;n++){var s=t.item(n),i=e[n];["stroke-width","fill-opacity","stroke-opacity","opacity","stroke-dasharray"].forEach(function(t){s.setAttribute(t,$(i).attr(t)||$(i).css(t))}),["fill","stroke"].forEach(function(t){var e,n,r=(e=$(i).attr(t)||$(i).css(t))&&null!==e&&"none"!=e?(n=e.match(/^#(.)(.)(.)$/))?"#"+n[1]+n[1]+n[2]+n[2]+n[3]+n[3]:(n=e.match(/^#......$/))?e:null===(n=e.match(/^rgb\(([0-9]+),\s+([0-9]+),\s+([0-9]+)/))?(r=e.match(/^rgba\(([0-9]+),\s+([0-9]+),\s+([0-9]+),\s+([0-9]+)/))?{clr:"#"+("0"+parseInt(r[1],10).toString(16)).slice(-2)+("0"+parseInt(r[2],10).toString(16)).slice(-2)+("0"+parseInt(r[3],10).toString(16)).slice(-2),opa:r[4]}:(console.log("Screenshot node: returned unknown color: "+e),e):"#"+("0"+parseInt(n[1],10).toString(16)).slice(-2)+("0"+parseInt(n[2],10).toString(16)).slice(-2)+("0"+parseInt(n[3],10).toString(16)).slice(-2):"none";"object"==typeof r?(s.setAttribute(t+"-opacity",r.opa),s.setAttribute(t,r.clr)):s.setAttribute(t,r)}),$(i).hasClass("hide")&&("g"==s.tagName&&s.setAttribute("opacity","0"),s.setAttribute("visibility","hidden"))}}var n='<?xml version="1.0" standalone="no"?>\r\n<svg '+('width="'+o.attr("width")+'" height="'+o.attr("height")+'"')+' pointer-events="all" style="cursor: crosshair; touch-action: none;" xmlns="http://www.w3.org/2000/svg" class="__screenshot" xmlns:xlink="http://www.w3.org/1999/xlink">\r\n',t=t.html(),l=(new DOMParser).parseFromString(n+t+"\r\n</svg>","image/svg+xml"),r=e=>(["g","rect","line","path","circle","image","text"].forEach(t=>{$(e.getElementsByTagName(t)).each((t,e)=>{e.setAttribute("class",""),e.setAttribute("id","")})}),e),s=(["g","rect","line","path","circle","image"].forEach(function(t){a(l.getElementsByTagName(t),o.find(t))}),["text"].forEach(function(t){a(l.getElementsByTagName(t),o.find(t));for(var e=l.getElementsByTagName(t),n=o.find(t),r=0;r<e.length;r++){var s=e.item(r),i=n[r];["font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","text-anchor","dominant-baseline"].forEach(function(t){s.setAttribute(t,$(i).attr(t)||$(i).css(t))})}}),l.getElementsByTagName("image")),g={},i=(n,r,s)=>{var i=n.getAttribute("xlink:href"),o=i.substr(-4,4).toLowerCase(),a={".jpg":"jpeg",jpeg:"jpeg",".png":"png",".svg":"svg+xml"};if(g[i])return n.setAttribute("xlink:href","data:image/"+a[o]+";base64,"+g[i]),s(r-1);switch(o){case".jpg":case"jpeg":case".png":var l=new XMLHttpRequest;l.open("GET",i,!0),l.responseType="arraybuffer";l.onload=function(t){var e=l.response;e&&(e=(t=>{for(var e="",n=new Uint8Array(t),r=n.byteLength,s=0;s<r;s++)e+=String.fromCharCode(n[s]);return window.btoa(e)})(e),g[i]=e,n.setAttribute("xlink:href","data:image/"+a[o]+";base64,"+e)),s(r-1)},l.send(null);break;case".svg":$.get(i,function(t){var e=new XMLSerializer,e=btoa(e.serializeToString(t));g[i]=e,n.setAttribute("xlink:href","data:image/svg+xml;base64,"+e),s(r-1)})}},c=t=>{t<0?e((new XMLSerializer).serializeToString(r(l))):i(s.item(t),t,c)};0<s.length?i(s.item(s.length-1),s.length-1,c):e((new XMLSerializer).serializeToString(r(l)))}function generatorFunctionForVersion(t){var n,e=t.settings.version.split("."),r=e[0],e=e[1];if("3"==r){if("0"==e)return nr_intro_generate_svg_3_0(t);if("1"==e)return nr_intro_generate_svg_3_1(t)}return n=t,t=>{var e="Node-RED version ("+n.settings.version+") not supported";n.notify(e,{type:"error"}),t&&t('<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg width="1000" height="1000" viewBox="0 0 1000 1000" pointer-events="all" style="cursor: crosshair; touch-action: none;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style>.small { font: bold 20px sans-serif; fill: red;}</style><text x="10" y="30" class="small">'+e+"</text></svg>")}}
5
+ function setupTreelist(){var e=collectOrphans();if(0==e.length){RED.notify("No Orphans Found",{type:"warning",timeout:2e3});try{$("#node-input-orphan-target-container-div").treeList("empty")}catch(e){}}else{try{$("#node-input-orphan-target-container-div").treeList("empty")}catch(e){$("#node-input-orphan-target-container-div").css({width:"100%",height:"calc(100%)"}).treeList({multi:!1}).on("treelistitemmouseover",function(e,t){t.node&&t.node.z==RED.workspaces.active()&&(RED.view.reveal(t.node.id,!0),RED.view.redraw())}).on("treelistitemmouseout",function(e,t){}).on("treelistselect",function(e,t){t.node&&(RED.workspaces.show(t.node.z,!1,!1,!0),RED.view.reveal(t.node.id,!0),RED.view.redraw())}).on("treelistconfirm",function(e,t){var n;t.node&&(n=t.node.id,setTimeout(()=>{var e=RED.nodes.node(n);e&&(RED.view.reveal(e.id),RED.view.select(e.id),RED.editor.edit(e)),n==RED.workspaces.active()&&RED.workspaces.edit()},50))}),$("#node-input-orphan-target-filter").show();var n=$("#node-input-orphan-target-filter").searchBox({style:"compact",delay:300,change:function(){var e,t=$(this).val().trim().toLowerCase();""===t?($("#node-input-orphan-target-container-div").treeList("filter",null),n.searchBox("count","")):(e=$("#node-input-orphan-target-container-div").treeList("filter",function(e){return-1<e.label.toLowerCase().indexOf(t)||-1<e.node.type.toLowerCase().indexOf(t)}),n.searchBox("count",e+" / "+$("#node-input-orphan-target-container-div").treeList("data").length))}})}$("#node-input-orphan-target-container-div").treeList("data",e.sort((e,t)=>e.node.z>t.node.z))}}function collectOrphans(){const t=new Set;var n=[],i=(RED.nodes.eachLink(e=>{t.add(e.source),t.add(e.target)}),RED.nodes.eachNode(e=>{t.has(e)||n.push(e)}),[]),r={};return n.forEach(function(e){var t=RED.nodes.getType(e.type);if(t){var n=t.label,n=("function"==typeof n?n.call(e):n)||"",o=e.type;if(0===o.indexOf("subflow:"))return}t&&n||(n=e.type),r[e.id]={node:e,label:n,sublabel:o,selected:!1,checkbox:!1},i.push(r[e.id])}),i}
6
+
7
+ function nr_intro_generate_svg_3_1(r){return e=>{try{handleSvgObject($($("svg[width=8000]")[0]),e)}catch(t){var n="Error Generating SVG: "+JSON.stringify(t);r.notify(n,{type:"error"}),e('<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg width="1000" height="1000" viewBox="0 0 1000 1000" pointer-events="all" style="cursor: crosshair; touch-action: none;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style>.small { font: bold 20px sans-serif; fill: red;}</style><text x="10" y="30" class="small">'+n+"</text></svg>")}}}function nr_intro_generate_svg_3_0(r){return e=>{try{handleSvgObject($($("svg")[0]),e)}catch(t){var n="Error Generating SVG: "+JSON.stringify(t);r.notify(n,{type:"error"}),e('<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg width="1000" height="1000" viewBox="0 0 1000 1000" pointer-events="all" style="cursor: crosshair; touch-action: none;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style>.small { font: bold 20px sans-serif; fill: red;}</style><text x="10" y="30" class="small">'+n+"</text></svg>")}}}function handleSvgObject(o,e){var t=o.clone();t.find("foreignObject").remove(),t.find("svg.__screenshot").remove();function a(t,e){for(var n=0;n<t.length;n++){var s=t.item(n),i=e[n];["stroke-width","fill-opacity","stroke-opacity","opacity","stroke-dasharray"].forEach(function(t){s.setAttribute(t,$(i).attr(t)||$(i).css(t))}),["fill","stroke"].forEach(function(t){var e,n,r=(e=$(i).attr(t)||$(i).css(t))&&null!==e&&"none"!=e?(n=e.match(/^#(.)(.)(.)$/))?"#"+n[1]+n[1]+n[2]+n[2]+n[3]+n[3]:(n=e.match(/^#......$/))?e:null===(n=e.match(/^rgb\(([0-9]+),\s+([0-9]+),\s+([0-9]+)/))?(r=e.match(/^rgba\(([0-9]+),\s+([0-9]+),\s+([0-9]+),\s+([0-9]+)/))?{clr:"#"+("0"+parseInt(r[1],10).toString(16)).slice(-2)+("0"+parseInt(r[2],10).toString(16)).slice(-2)+("0"+parseInt(r[3],10).toString(16)).slice(-2),opa:r[4]}:(console.log("Screenshot node: returned unknown color: "+e),e):"#"+("0"+parseInt(n[1],10).toString(16)).slice(-2)+("0"+parseInt(n[2],10).toString(16)).slice(-2)+("0"+parseInt(n[3],10).toString(16)).slice(-2):"none";"object"==typeof r?(s.setAttribute(t+"-opacity",r.opa),s.setAttribute(t,r.clr)):s.setAttribute(t,r)}),$(i).hasClass("hide")&&("g"==s.tagName&&s.setAttribute("opacity","0"),s.setAttribute("visibility","hidden"))}}var n='<?xml version="1.0" standalone="no"?>\r\n<svg '+('width="'+o.attr("width")+'" height="'+o.attr("height")+'"')+' pointer-events="all" style="cursor: crosshair; touch-action: none;" xmlns="http://www.w3.org/2000/svg" class="__screenshot" xmlns:xlink="http://www.w3.org/1999/xlink">\r\n',t=t.html(),l=(new DOMParser).parseFromString(n+t+"\r\n</svg>","image/svg+xml"),r=e=>(["g","rect","line","path","circle","image","text"].forEach(t=>{$(e.getElementsByTagName(t)).each((t,e)=>{e.setAttribute("class",""),e.setAttribute("id","")})}),e),s=(["g","rect","line","path","circle","image"].forEach(function(t){a(l.getElementsByTagName(t),o.find(t))}),["text"].forEach(function(t){a(l.getElementsByTagName(t),o.find(t));for(var e=l.getElementsByTagName(t),n=o.find(t),r=0;r<e.length;r++){var s=e.item(r),i=n[r];["font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","text-anchor","dominant-baseline"].forEach(function(t){s.setAttribute(t,$(i).attr(t)||$(i).css(t))})}}),l.getElementsByTagName("image")),g={},i=(n,r,s)=>{var i=n.getAttribute("xlink:href"),o=i.substr(-4,4).toLowerCase(),a={".jpg":"jpeg",jpeg:"jpeg",".png":"png",".svg":"svg+xml"};if(g[i])return n.setAttribute("xlink:href","data:image/"+a[o]+";base64,"+g[i]),s(r-1);switch(o){case".jpg":case"jpeg":case".png":var l=new XMLHttpRequest;l.open("GET",i,!0),l.responseType="arraybuffer";l.onload=function(t){var e=l.response;e&&(e=(t=>{for(var e="",n=new Uint8Array(t),r=n.byteLength,s=0;s<r;s++)e+=String.fromCharCode(n[s]);return window.btoa(e)})(e),g[i]=e,n.setAttribute("xlink:href","data:image/"+a[o]+";base64,"+e)),s(r-1)},l.send(null);break;case".svg":$.get(i,function(t){var e=new XMLSerializer,e=btoa(e.serializeToString(t));g[i]=e,n.setAttribute("xlink:href","data:image/svg+xml;base64,"+e),s(r-1)})}},c=t=>{t<0?e((new XMLSerializer).serializeToString(r(l))):i(s.item(t),t,c)};0<s.length?i(s.item(s.length-1),s.length-1,c):e((new XMLSerializer).serializeToString(r(l)))}function generatorFunctionForVersion(t){var n,e=t.settings.version.split("."),r=e[0],e=e[1];if("3"==r){if("0"==e)return nr_intro_generate_svg_3_0(t);if("1"==e)return nr_intro_generate_svg_3_1(t)}return n=t,t=>{var e="Node-RED version ("+n.settings.version+") not supported";n.notify(e,{type:"error"}),t&&t('<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg width="1000" height="1000" viewBox="0 0 1000 1000" pointer-events="all" style="cursor: crosshair; touch-action: none;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style>.small { font: bold 20px sans-serif; fill: red;}</style><text x="10" y="30" class="small">'+e+"</text></svg>")}}function addPanZoom(){var t=d3.select("#node-input-screenshot-svgcontainer svg"),e=(t.html("<g>"+t.html()+"</g>"),t.select("g")),n=d3.behavior.zoom().scaleExtent([.2,100]).on("zoom",function(t){e.attr({transform:"translate("+n.translate()+") scale("+n.scale()+")"})});t.call(n)}
6
8
 
7
9
  // Add your plugin as a new tabsheet in the right sidebar AFTER the flow editor is completely started
8
10
  var initialiseConfigNodeOnce = () => {
@@ -14,14 +16,36 @@
14
16
  // Add a "Your sidebar" tabsheet to the right sidebar panel, in which this sidebar panel can be displayed
15
17
  // --> more details: https://nodered.org/docs/api/ui/sidebar/
16
18
  RED.sidebar.addTab({
17
- id: "Screenshot",
18
- label: "Screenshot", // short name for the tab
19
- name: "Screenshot", // long name for the menu
19
+ id: "Introspection",
20
+ label: "Introspection", // short name for the tab
21
+ name: "Introspection", // long name for the menu
20
22
  content: content,
21
23
  enableOnEdit: true,
22
24
  iconClass: "fa fa-camera" // your fontawesome icon
23
25
  });
24
26
 
27
+ var tabs = RED.tabs.create({
28
+ id: 'func-introspection-tabs',
29
+ onchange: function(tab) {
30
+ $('#func-introspection-tabs-content').children().hide();
31
+ $('#' + tab.id).show();
32
+ }
33
+ });
34
+
35
+ // Add first tab, screenshot
36
+ tabs.addTab({
37
+ id: 'func-introspection-tab-screenshot',
38
+ iconClass: 'fa fa-photo',
39
+ label: 'Screenshot'
40
+ });
41
+
42
+ // Add tab, orphans
43
+ tabs.addTab({
44
+ id: 'func-introspection-tab-orphans',
45
+ iconClass: 'fa fa-life-ring',
46
+ label: 'Orphans'
47
+ });
48
+
25
49
  $('#node-screenshot-capture-btn').on("click", function (e) {
26
50
  if ( e ) { e.preventDefault() }
27
51
 
@@ -30,6 +54,9 @@
30
54
  generatorFunctionForVersion(RED)( (svgdata) => {
31
55
  $('#node-input-screenshot-svgcontainer').html(svgdata);
32
56
  globalRefToSvgData = svgdata;
57
+ setTimeout(() => {
58
+ addPanZoom()
59
+ },150)
33
60
  });
34
61
  })
35
62
 
@@ -52,23 +79,75 @@
52
79
  RED.notify("SVG copied to clipboard", { type: "success" });
53
80
  }
54
81
  });
82
+
83
+ // When the user has entered new data in the sidebar, then store it into the config node
84
+ $("#node-input-orphan-find-btn").on("click", function(e) {
85
+ if ( e ) { e.preventDefault() }
86
+ setupTreelist();
87
+ })
55
88
  };
56
89
  RED.events.on('runtime-state', initialiseConfigNodeOnce);
57
90
  })();
58
91
  </script>
59
92
 
93
+ <style>
94
+ .col-100 .red-ui-typedInput-container {
95
+ width: 70% !important;
96
+ }
97
+
98
+ .col-100.no-label .red-ui-typedInput-container {
99
+ width: 100% !important;
100
+ }
101
+ </style>
102
+
60
103
  <!-- The html for the right sidebar plugin screen -->
61
104
  <script type="text/x-red" data-template-name="Screenshot">
62
- <div class="form-row" style="margin-left: 10px; margin-top: 30px;">
63
- <button type="button" id="node-screenshot-capture-btn" class="red-ui-button red-ui-button-large"><i class="fa fa-camera"></i> Capture</button>
64
- </div>
65
105
 
66
- <div class="form-row" style="min-height: 300px; overflow: scroll; margin-left: 10px; margin-right: 15px; height: 300px; border: 1px rgb(196, 196, 196) solid; border-radius: 5px;">
67
- <div id="node-input-screenshot-svgcontainer"></div>
106
+ <div class="form-row func-introspection-tabs-row">
107
+ <ul style="min-width: 600px; margin-bottom: 20px;" id="func-introspection-tabs"></ul>
68
108
  </div>
69
109
 
70
- <div class="form-row" style="margin-left: 10px; margin-top: 5px;">
71
- <button type="button" id="node-screenshot-download-svg" class="red-ui-button red-ui-button-large"><i class="fa fa-download"></i>Download</button>
72
- <button type="button" id="node-screenshot-copy-to-clipboard-svg" class="red-ui-button red-ui-button-large"><i class="fa fa-clipboard"></i>Copy to Clipboard</button>
110
+ <div id="func-introspection-tabs-content" style="min-height: calc(100% - 95px);">
111
+ <div id="func-introspection-tab-screenshot" style="display:none; min-height: calc(100%);">
112
+ <div class="form-row">
113
+ <div class="col-100">
114
+
115
+ <div class="form-row" style="margin-left: 10px; margin-top: 30px;">
116
+ <button type="button" id="node-screenshot-capture-btn"
117
+ class="red-ui-button red-ui-button-large"><i class="fa fa-camera"></i> Capture</button>
118
+
119
+ <button type="button" id="node-screenshot-download-svg" style="margin-left: 30px;"
120
+ class="red-ui-button red-ui-button-large"><i class="fa fa-download"></i> Download</button>
121
+ <button type="button" id="node-screenshot-copy-to-clipboard-svg"
122
+ class="red-ui-button red-ui-button-large"><i class="fa fa-clipboard"></i> Copy to Clipboard</button>
123
+ </div>
124
+
125
+ <div class="form-row" style="min-height: 300px; height: 450px; overflow: hidden; margin-left: 10px; margin-right: 15px; border: 1px rgb(196, 196, 196) solid; border-radius: 5px;">
126
+ <div id="node-input-screenshot-svgcontainer"></div>
127
+ </div>
128
+ </div>
129
+ </div>
130
+ </div>
131
+
132
+ <div id="func-introspection-tab-orphans" style="display:none; min-height: calc(100%);">
133
+ <div class="form-row">
134
+ <div class="col-100">
135
+ <div class="form-row node-input-target-row" style="margin-left: 10px; margin-top: 30px">
136
+ <button id="node-input-orphan-find-btn"
137
+ class="red-ui-button"><i class="fa fa-rotate-right"></i> Refresh</button>
138
+ </div>
139
+
140
+ <div class="form-row node-input-target-row node-input-target-list-row"
141
+ style="margin-left: 10px; position: relative; min-height: 200px; height: 450px; margin-right: 15px; ">
142
+ <div style="margin-bottom: 5px; width: 35%; padding-left: 60%;">
143
+ <input type="text" id="node-input-orphan-target-filter" style="display: none;">
144
+ </div>
145
+ <div id="node-input-orphan-target-container-div"></div>
146
+ </div>
147
+ </div>
148
+ </div>
149
+ </div>
73
150
  </div>
151
+
152
+
74
153
  </script>
@@ -1,45 +0,0 @@
1
- <script type="text/javascript">
2
- (function() {
3
- function setupTreelist(){var e=collectOrphans();if(0==e.length){RED.notify("No Orphans Found",{type:"warning",timeout:2e3});try{$("#node-input-orphan-target-container-div").treeList("empty")}catch(e){}}else{try{$("#node-input-orphan-target-container-div").treeList("empty")}catch(e){$("#node-input-orphan-target-container-div").css({width:"100%",height:"400px"}).treeList({multi:!1}).on("treelistitemmouseover",function(e,t){t.node&&t.node.z==RED.workspaces.active()&&(RED.view.reveal(t.node.id,!0),RED.view.redraw())}).on("treelistitemmouseout",function(e,t){}).on("treelistselect",function(e,t){t.node&&(RED.workspaces.show(t.node.z,!1,!1,!0),RED.view.reveal(t.node.id,!0),RED.view.redraw())}),$("#node-input-orphan-target-filter").show();var n=$("#node-input-orphan-target-filter").searchBox({style:"compact",delay:300,change:function(){var e,t=$(this).val().trim().toLowerCase();""===t?($("#node-input-orphan-target-container-div").treeList("filter",null),n.searchBox("count","")):(e=$("#node-input-orphan-target-container-div").treeList("filter",function(e){return-1<e.label.toLowerCase().indexOf(t)||-1<e.node.type.toLowerCase().indexOf(t)}),n.searchBox("count",e+" / "+$("#node-input-orphan-target-container-div").treeList("data").length))}})}$("#node-input-orphan-target-container-div").treeList("data",e.sort((e,t)=>e.node.z>t.node.z))}}function collectOrphans(){const t=new Set;var n=[],r=(RED.nodes.eachLink(e=>{t.add(e.source),t.add(e.target)}),RED.nodes.eachNode(e=>{t.has(e)||n.push(e)}),[]),i={};return n.forEach(function(e){var t=RED.nodes.getType(e.type);if(t){var n=t.label,n=("function"==typeof n?n.call(e):n)||"",o=e.type;if(0===o.indexOf("subflow:"))return}t&&n||(n=e.type),i[e.id]={node:e,label:n,sublabel:o,selected:!1,checkbox:!1},r.push(i[e.id])}),r}
4
-
5
- var initialiseSidebarOrphanNodeOnce = () => {
6
- RED.events.off('runtime-state', initialiseSidebarOrphanNodeOnce);
7
-
8
- // The html content of the sidebar has been specified below as a data-template, from where it can be loaded:
9
- var content = $($('script[type="text/x-red"][data-template-name="Orphans"]').i18n().html());
10
-
11
- // Add a "Your sidebar" tabsheet to the right sidebar panel, in which this sidebar panel can be displayed
12
- // --> more details: https://nodered.org/docs/api/ui/sidebar/
13
- RED.sidebar.addTab({
14
- id: "Orphans",
15
- label: "Orphans", // short name for the tab
16
- name: "Orphan Nodes", // long name for the menu
17
- content: content,
18
- enableOnEdit: true,
19
- iconClass: "fa fa-life-ring" // your fontawesome icon
20
- });
21
-
22
- // When the user has entered new data in the sidebar, then store it into the config node
23
- $("#node-input-orphan-find-btn").on("click", function(e) {
24
- if ( e ) { e.preventDefault() }
25
- setupTreelist();
26
- })
27
- };
28
- RED.events.on('runtime-state', initialiseSidebarOrphanNodeOnce);
29
- })();
30
- </script>
31
-
32
- <!-- The html for the right sidebar plugin screen -->
33
- <script type="text/x-red" data-template-name="Orphans">
34
- <div class="form-row node-input-target-row" style="margin-left: 10px; margin-top: 30px">
35
- <button id="node-input-orphan-find-btn"
36
- class="red-ui-button">Find Orphans</button>
37
- </div>
38
-
39
- <div class="form-row node-input-target-row node-input-target-list-row" style="margin-left: 10px; position: relative; min-height: 200px; margin-right: 15px;">
40
- <div style="margin-bottom: 5px; width: 35%; padding-left: 60%;">
41
- <input type="text" id="node-input-orphan-target-filter" style="display: none;">
42
- </div>
43
- <div id="node-input-orphan-target-container-div"></div>
44
- </div>
45
- </script>