@theotherwillembotha/node-red-nginxproxymanager 0.0.55 → 0.4.0

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.
Files changed (35) hide show
  1. package/build/GenerateNodes.d.ts +2 -0
  2. package/build/GenerateNodes.d.ts.map +1 -0
  3. package/build/GenerateNodes.js +7 -6
  4. package/build/Nodes.html +653 -414
  5. package/build/Nodes.js +34995 -12
  6. package/build/Plugins.html +37 -0
  7. package/build/Plugins.js +34650 -55
  8. package/build/index.d.ts +5 -0
  9. package/build/index.d.ts.map +1 -0
  10. package/build/nginx/node/NginxGetHostsNode.d.ts +19 -0
  11. package/build/nginx/node/NginxGetHostsNode.d.ts.map +1 -0
  12. package/build/nginx/node/NginxGetHostsNode.js +2 -2
  13. package/build/nginx/node/NginxProxyManagerConfigNode.d.ts +15 -0
  14. package/build/nginx/node/NginxProxyManagerConfigNode.d.ts.map +1 -0
  15. package/build/nginx/node/NginxProxyManagerConfigNode.js +4 -3
  16. package/build/nginx/node/UpdateHostNode.d.ts +18 -0
  17. package/build/nginx/node/UpdateHostNode.d.ts.map +1 -0
  18. package/build/nginx/node/UpdateHostNode.js +2 -3
  19. package/build/nginx/service/NginxProxyManagerClient.d.ts +9 -0
  20. package/build/nginx/service/NginxProxyManagerClient.d.ts.map +1 -0
  21. package/build/nginx/service/NginxProxyManagerClient.js +3 -0
  22. package/build/nginx/service/NginxProxyManagerService.d.ts +9 -0
  23. package/build/nginx/service/NginxProxyManagerService.d.ts.map +1 -0
  24. package/build/nginx/service/NginxProxyManagerService.js +21 -5
  25. package/build/nginx/service/client/NginxClient.d.ts +69 -0
  26. package/build/nginx/service/client/NginxClient.d.ts.map +1 -0
  27. package/build/nginx/service/client/NginxHttpClient.d.ts +26 -0
  28. package/build/nginx/service/client/NginxHttpClient.d.ts.map +1 -0
  29. package/build/nginx/service/client/types.d.ts +291 -0
  30. package/build/nginx/service/client/types.d.ts.map +1 -0
  31. package/build/runtime/NodeManagerRuntime.js +140 -0
  32. package/package.json +10 -6
  33. package/documentation/GetHostsNode.png +0 -0
  34. package/documentation/NginxProxyManagerConfig.png +0 -0
  35. package/documentation/UpdateHostNode.png +0 -0
package/build/Nodes.html CHANGED
@@ -7,113 +7,110 @@
7
7
  You have been warned.
8
8
 
9
9
  -->
10
-
11
10
  <!-- ui-helper -->
12
- <style>
13
- /* ─── PluginCore Dialog overlay ─────────────────────────────────────────── */
14
- .plugincore-overlay {
15
- position: fixed;
16
- top: 0;
17
- left: 0;
18
- right: 0;
19
- bottom: 0;
20
- background: rgba(0, 0, 0, 0.5);
21
- z-index: 2000;
22
- display: flex;
23
- align-items: center;
24
- justify-content: center;
25
- }
11
+
26
12
 
27
- .plugincore-dialog {
28
- background: #fff;
29
- border: 1px solid #aaa;
30
- border-radius: 4px;
31
- box-shadow: 0 6px 24px rgba(0, 0, 0, 0.35);
32
- min-width: 540px;
33
- max-width: 85vw;
34
- max-height: 80vh;
35
- display: flex;
36
- flex-direction: column;
37
- overflow: hidden;
38
- }
13
+ <style>
14
+ /* ─── PluginCore Dialog overlay ─────────────────────────────────────────── */
15
+
16
+ .plugincore-overlay {
17
+ position: fixed;
18
+ top: 0; left: 0; right: 0; bottom: 0;
19
+ background: rgba(0, 0, 0, 0.5);
20
+ z-index: 2000;
21
+ display: flex;
22
+ align-items: center;
23
+ justify-content: center;
24
+ }
39
25
 
40
- /* Title bar — matches Node-RED's main nav bar colour */
41
- .plugincore-dialog-titlebar {
42
- display: flex;
43
- align-items: center;
44
- background: #3d3d3d;
45
- color: #fff;
46
- padding: 6px 8px 6px 12px;
47
- flex-shrink: 0;
48
- }
26
+ .plugincore-dialog {
27
+ background: #fff;
28
+ border: 1px solid #aaa;
29
+ border-radius: 4px;
30
+ box-shadow: 0 6px 24px rgba(0, 0, 0, 0.35);
31
+ min-width: 540px;
32
+ max-width: 85vw;
33
+ max-height: 80vh;
34
+ display: flex;
35
+ flex-direction: column;
36
+ overflow: hidden;
37
+ }
49
38
 
50
- .plugincore-dialog-title {
51
- flex: 1;
52
- font-weight: 600;
53
- font-size: 13px;
54
- }
39
+ /* Title bar - matches Node-RED's main nav bar colour */
40
+ .plugincore-dialog-titlebar {
41
+ display: flex;
42
+ align-items: center;
43
+ background: #3d3d3d;
44
+ color: #fff;
45
+ padding: 6px 8px 6px 12px;
46
+ flex-shrink: 0;
47
+ }
55
48
 
56
- /* Close button — jQuery UI styling as used in Node-RED dialogs */
57
- .plugincore-dialog-close {
58
- color: #ccc !important;
59
- background: transparent !important;
60
- border-color: transparent !important;
61
- }
49
+ .plugincore-dialog-title {
50
+ flex: 1;
51
+ font-weight: 600;
52
+ font-size: 13px;
53
+ }
62
54
 
63
- .plugincore-dialog-close:hover {
64
- color: #fff !important;
65
- background: rgba(255, 255, 255, 0.15) !important;
66
- border-color: rgba(255, 255, 255, 0.3) !important;
67
- }
55
+ /* Close button - jQuery UI styling as used in Node-RED dialogs */
56
+ .plugincore-dialog-close {
57
+ color: #ccc !important;
58
+ background: transparent !important;
59
+ border-color: transparent !important;
60
+ }
68
61
 
69
- /* Scrollable body that contains the jQuery UI tab widget */
70
- .plugincore-dialog-body {
71
- flex: 1;
72
- overflow: auto;
73
- padding: 10px;
74
- }
62
+ .plugincore-dialog-close:hover {
63
+ color: #fff !important;
64
+ background: rgba(255, 255, 255, 0.15) !important;
65
+ border-color: rgba(255, 255, 255, 0.3) !important;
66
+ }
75
67
 
76
- /* ─── PluginCore Table ───────────────────────────────────────────────────── */
77
- .plugincore-table {
78
- width: 100%;
79
- border-collapse: collapse;
80
- font-size: 12px;
81
- }
68
+ /* Scrollable body that contains the jQuery UI tab widget or plain content */
69
+ .plugincore-dialog-body {
70
+ flex: 1 1 auto;
71
+ overflow: auto;
72
+ padding: 10px;
73
+ }
82
74
 
83
- .plugincore-table th {
84
- background: #f3f3f3;
85
- border: 1px solid #ddd;
86
- padding: 5px 10px;
87
- text-align: left;
88
- font-weight: 600;
89
- white-space: nowrap;
90
- }
75
+ /* ─── PluginCore Table ───────────────────────────────────────────────────── */
91
76
 
92
- .plugincore-table td {
93
- border: 1px solid #eee;
94
- padding: 5px 10px;
95
- vertical-align: middle;
96
- }
77
+ .plugincore-table {
78
+ width: 100%;
79
+ border-collapse: collapse;
80
+ font-size: 12px;
81
+ }
97
82
 
98
- .plugincore-table tbody tr:nth-child(even) td {
99
- background: #fafafa;
100
- }
83
+ .plugincore-table th {
84
+ background: #f3f3f3;
85
+ border: 1px solid #ddd;
86
+ padding: 5px 10px;
87
+ text-align: left;
88
+ font-weight: 600;
89
+ white-space: nowrap;
90
+ }
101
91
 
102
- .plugincore-table tbody tr:hover td {
103
- background: #f0f6ff;
104
- }
92
+ .plugincore-table td {
93
+ border: 1px solid #eee;
94
+ padding: 5px 10px;
95
+ vertical-align: middle;
96
+ }
105
97
 
106
- .plugincore-status-enabled {
107
- color: #27ae60;
108
- }
98
+ .plugincore-table tbody tr:nth-child(even) td {
99
+ background: #fafafa;
100
+ }
109
101
 
110
- .plugincore-status-disabled {
111
- color: #c0392b;
112
- }
102
+ .plugincore-table tbody tr:hover td {
103
+ background: #f0f6ff;
104
+ }
113
105
 
106
+ .plugincore-status-enabled { color: #27ae60; }
107
+ .plugincore-status-disabled { color: #c0392b; }
114
108
  </style>
109
+
115
110
  <script type="text/javascript">
111
+
116
112
  window.PluginCore = window.PluginCore || {};
113
+
117
114
  /**
118
115
  * PluginCore.table(config) → jQuery <table>
119
116
  *
@@ -123,108 +120,248 @@
123
120
  * }
124
121
  */
125
122
  PluginCore.table = function(config) {
126
- var $table = $('<table class="plugincore-table">');
127
- // Header
128
- var $thead = $('<thead>');
129
- var $hr = $('<tr>');
130
- config.columns.forEach(function(col) {
131
- $hr.append($('<th>').text(col.label));
132
- });
133
- $thead.append($hr);
134
- $table.append($thead);
135
- // Body
136
- var $tbody = $('<tbody>');
137
- (config.rows || []).forEach(function(row) {
138
- var $tr = $('<tr>');
123
+ var $table = $('<table class="plugincore-table">');
124
+
125
+ // Header
126
+ var $thead = $('<thead>');
127
+ var $hr = $('<tr>');
139
128
  config.columns.forEach(function(col) {
140
- var $td = $('<td>');
141
- var val = row[col.key];
142
- if (col.render) {
143
- var rendered = col.render(val, row);
144
- if (rendered && typeof rendered === 'object' && rendered.jquery) {
145
- $td.append(rendered);
146
- } else {
147
- $td.html(rendered != null ? String(rendered) : '');
148
- }
149
- } else {
150
- $td.text(val != null ? String(val) : '');
151
- }
152
- $tr.append($td);
129
+ $hr.append($('<th>').text(col.label));
153
130
  });
154
- $tbody.append($tr);
155
- });
156
- $table.append($tbody);
157
- return $table;
131
+ $thead.append($hr);
132
+ $table.append($thead);
133
+
134
+ // Body
135
+ var $tbody = $('<tbody>');
136
+ (config.rows || []).forEach(function(row) {
137
+ var $tr = $('<tr>');
138
+ config.columns.forEach(function(col) {
139
+ var $td = $('<td>');
140
+ var val = row[col.key];
141
+ if (col.render) {
142
+ var rendered = col.render(val, row);
143
+ if (rendered && typeof rendered === 'object' && rendered.jquery) {
144
+ $td.append(rendered);
145
+ } else {
146
+ $td.html(rendered != null ? String(rendered) : '');
147
+ }
148
+ } else {
149
+ $td.text(val != null ? String(val) : '');
150
+ }
151
+ $tr.append($td);
152
+ });
153
+ $tbody.append($tr);
154
+ });
155
+ $table.append($tbody);
156
+
157
+ return $table;
158
158
  };
159
+
160
+ /**
161
+ * PluginCore.tabs(tabs) → jQuery element
162
+ *
163
+ * tabs: [{ label: string, render($container) }]
164
+ *
165
+ * Builds and returns a jQuery UI tab widget element.
166
+ * Can be embedded in any container, including inside PluginCore.dialog render().
167
+ */
168
+ PluginCore.tabs = function(tabs) {
169
+ var uid = 'plugincore-tabs-' + Date.now();
170
+ var $tabsEl = $('<div>').attr('id', uid);
171
+ var $ul = $('<ul>');
172
+
173
+ (tabs || []).forEach(function(tab, i) {
174
+ var paneId = uid + '-pane-' + i;
175
+ $ul.append(
176
+ $('<li>').append($('<a>').attr('href', '#' + paneId).text(tab.label))
177
+ );
178
+ var $pane = $('<div>').attr('id', paneId);
179
+ if (tab.render) { tab.render($pane); }
180
+ $tabsEl.append($pane);
181
+ });
182
+
183
+ $tabsEl.prepend($ul);
184
+ $tabsEl.tabs();
185
+
186
+ return $tabsEl;
187
+ };
188
+
159
189
  /**
160
190
  * PluginCore.dialog(options) → { close() }
161
191
  *
162
192
  * options: {
163
- * title : string,
164
- * tabs : [{ label: string, render($container) }]
193
+ * title : string,
194
+ * render : function($container) - simple dialog; body passed directly
195
+ * tabs : [{ label: string, render($c) }] - tabbed dialog; delegates to PluginCore.tabs
165
196
  * }
166
197
  *
167
- * Uses jQuery UI tabs for the tab widget (already bundled with Node-RED).
198
+ * render and tabs can coexist: render is called first, then the tab widget is appended.
168
199
  * Closes on: close button click, overlay click, or Escape key.
169
200
  */
170
201
  PluginCore.dialog = function(options) {
171
- // Only one dialog at a time
172
- $('.plugincore-overlay').remove();
173
- var uid = 'plugincore-' + Date.now();
174
- var $overlay = $('<div class="plugincore-overlay">');
175
- var $dialog = $('<div class="plugincore-dialog">');
176
- // ── Title bar ──────────────────────────────────────────────────────
177
- var $titlebar = $('<div class="plugincore-dialog-titlebar">');
178
- $titlebar.append($('<span class="plugincore-dialog-title">').text(options.title || ''));
179
- var $closeBtn = $('<button type="button" class="ui-button ui-corner-all ui-widget plugincore-dialog-close" title="Close">' + '<span class="ui-icon ui-icon-closethick"></span></button>');
180
- $titlebar.append($closeBtn);
181
- // ── Body + jQuery UI tabs ──────────────────────────────────────────
182
- var $body = $('<div class="plugincore-dialog-body">');
183
- var $tabsEl = $('<div>').attr('id', uid + '-tabs');
184
- var $ul = $('<ul>');
185
- (options.tabs || []).forEach(function(tab, i) {
186
- var paneId = uid + '-pane-' + i;
187
- $ul.append($('<li>').append($('<a>').attr('href', '#' + paneId).text(tab.label)));
188
- var $pane = $('<div>').attr('id', paneId);
189
- if (tab.render) {
190
- tab.render($pane);
202
+ // Only one dialog at a time
203
+ $('.plugincore-overlay').remove();
204
+
205
+ var uid = 'plugincore-' + Date.now();
206
+
207
+ var $overlay = $('<div class="plugincore-overlay">');
208
+ var $dialog = $('<div class="plugincore-dialog">');
209
+
210
+ // ── Title bar ──────────────────────────────────────────────────────
211
+ var $titlebar = $('<div class="plugincore-dialog-titlebar">');
212
+ $titlebar.append(
213
+ $('<span class="plugincore-dialog-title">').text(options.title || '')
214
+ );
215
+ var $closeBtn = $(
216
+ '<button type="button" class="ui-button ui-corner-all ui-widget plugincore-dialog-close" title="Close">' +
217
+ '<span class="ui-icon ui-icon-closethick"></span></button>'
218
+ );
219
+ $titlebar.append($closeBtn);
220
+
221
+ // ── Body ──────────────────────────────────────────────────────────
222
+ var $body = $('<div class="plugincore-dialog-body">');
223
+
224
+ if (options.render) { options.render($body); }
225
+ if (options.tabs) { $body.append(PluginCore.tabs(options.tabs)); }
226
+
227
+ // ── Assemble ───────────────────────────────────────────────────────
228
+ $dialog.append($titlebar).append($body);
229
+ $overlay.append($dialog);
230
+ $('body').append($overlay);
231
+
232
+ // ── Close logic ───────────────────────────────────────────────────
233
+ var escNs = 'keydown.plugincore-dialog-' + uid;
234
+
235
+ function close() {
236
+ $overlay.fadeOut(150, function() { $overlay.remove(); });
237
+ $(document).off(escNs);
191
238
  }
192
- $tabsEl.append($pane);
193
- });
194
- $tabsEl.prepend($ul);
195
- $body.append($tabsEl);
196
- // ── Assemble ───────────────────────────────────────────────────────
197
- $dialog.append($titlebar).append($body);
198
- $overlay.append($dialog);
199
- $('body').append($overlay);
200
- // Initialise jQuery UI tabs (bundled with Node-RED)
201
- $tabsEl.tabs();
202
- // ── Close logic ───────────────────────────────────────────────────
203
- var escNs = 'keydown.plugincore-dialog-' + uid;
204
-
205
- function close() {
206
- $overlay.fadeOut(150, function() {
207
- $overlay.remove();
239
+
240
+ $closeBtn.on('click', close);
241
+ $overlay.on('click', function(e) {
242
+ if ($(e.target).is($overlay)) { close(); }
208
243
  });
209
- $(document).off(escNs);
210
- }
211
- $closeBtn.on('click', close);
212
- $overlay.on('click', function(e) {
213
- if ($(e.target).is($overlay)) {
214
- close();
215
- }
216
- });
217
- $(document).on(escNs, function(e) {
218
- if (e.key === 'Escape') {
219
- close();
220
- }
221
- });
222
- return {
223
- close: close
224
- };
244
+ $(document).on(escNs, function(e) {
245
+ if (e.key === 'Escape') { close(); }
246
+ });
247
+
248
+ return { close: close };
225
249
  };
226
250
 
227
251
  </script>
252
+
253
+
254
+
255
+ <!-- UpdateNginxHostNode -->
256
+
257
+ <style>
258
+ .node_label_white {
259
+ fill:white
260
+ }
261
+ </style>
262
+
263
+
264
+ <!-- logger -->
265
+
266
+ <style>
267
+ .editorgroupborder {
268
+ border-width:1px;
269
+ border-style:solid;
270
+ border-color:lightgray;
271
+ padding: 3px;
272
+ margin-top: 2px;
273
+ margin-bottom: 2px;
274
+ }
275
+
276
+ .editorsectionheading {
277
+ font-weight: 600;
278
+ margin-bottom:1px !important;
279
+ margin-top:6px !important;
280
+ }
281
+
282
+ .nomargin {
283
+ margin-bottom:1px !important;
284
+ margin-top:1px !important;
285
+ }
286
+
287
+ .slidecontainer {
288
+ width: 100%;
289
+ }
290
+
291
+ .slider {
292
+ -webkit-appearance: none;
293
+ appearance: none;
294
+ width: 100%;
295
+ height: 25px;
296
+ background: #d3d3d3;
297
+ outline: none;
298
+ opacity: 0.7;
299
+ -webkit-transition: .2s;
300
+ transition: opacity .2s;
301
+ }
302
+
303
+ .slider:hover {
304
+ opacity: 1;
305
+ }
306
+
307
+ .slider::-webkit-slider-thumb {
308
+ -webkit-appearance: none;
309
+ appearance: none;
310
+ width: 25px;
311
+ height: 25px;
312
+ background: #04AA6D;
313
+ cursor: pointer;
314
+ }
315
+
316
+ .slider::-moz-range-thumb {
317
+ width: 25px;
318
+ height: 25px;
319
+ background: #04AA6D;
320
+ cursor: pointer;
321
+ }
322
+
323
+ .towb_editorlabel {
324
+ width: 120px !important;
325
+ }
326
+ input.towb_editorfield, select.towb_editorfield, textarea.towb_editorfield {
327
+ width: 70% !important;
328
+ }
329
+ input.towb_editorfield_short, select.towb_editorfield_short {
330
+ width: 30% !important;
331
+ }
332
+
333
+ </style>
334
+
335
+ <script type="text/javascript">
336
+
337
+ // CSS
338
+ dropdownStyles = `
339
+ .loggertype-dropdown {
340
+ position: absolute;
341
+ background: white;
342
+ border: 1px solid #ccc;
343
+ border-radius: 4px;
344
+ box-shadow: 0 2px 8px rgba(0,0,0,0.15);
345
+ max-height: 150px;
346
+ overflow-y: auto;
347
+ z-index: 1000;
348
+ min-width: 150px;
349
+ }
350
+ .loggertype-dropdown .dropdown-item {
351
+ padding: 6px 12px;
352
+ cursor: pointer;
353
+ }
354
+ .loggertype-dropdown .dropdown-item:hover {
355
+ background: #f0f0f0;
356
+ }
357
+ `;
358
+ $('<style>').text(dropdownStyles).appendTo('head');
359
+
360
+ </script>
361
+
362
+
363
+
364
+
228
365
  <script type="text/javascript">
229
366
  RED.nodes.registerType('NginxProxyManagerConfigNode', {
230
367
  category: 'config',
@@ -440,109 +577,7 @@ Connection configuration for an Nginx Proxy Manager instance. Referenced by all
440
577
  - [Nginx Proxy Manager - Project](https://nginxproxymanager.com/)
441
578
  - [Nginx Proxy Manager - GitHub](https://github.com/NginxProxyManager/nginx-proxy-manager)
442
579
  </script>
443
- <!-- UpdateNginxHostNode -->
444
- <style>
445
- .node_label_white {
446
- fill: white
447
- }
448
-
449
- </style>
450
- <!-- logger -->
451
- <style>
452
- .editorgroupborder {
453
- border-width: 1px;
454
- border-style: solid;
455
- border-color: lightgray;
456
- padding: 3px;
457
- margin-top: 2px;
458
- margin-bottom: 2px;
459
- }
460
-
461
- .editorsectionheading {
462
- font-weight: 600;
463
- margin-bottom: 1px !important;
464
- margin-top: 6px !important;
465
- }
466
-
467
- .nomargin {
468
- margin-bottom: 1px !important;
469
- margin-top: 1px !important;
470
- }
471
-
472
- .slidecontainer {
473
- width: 100%;
474
- }
475
-
476
- .slider {
477
- -webkit-appearance: none;
478
- appearance: none;
479
- width: 100%;
480
- height: 25px;
481
- background: #d3d3d3;
482
- outline: none;
483
- opacity: 0.7;
484
- -webkit-transition: .2s;
485
- transition: opacity .2s;
486
- }
487
-
488
- .slider:hover {
489
- opacity: 1;
490
- }
491
-
492
- .slider::-webkit-slider-thumb {
493
- -webkit-appearance: none;
494
- appearance: none;
495
- width: 25px;
496
- height: 25px;
497
- background: #04AA6D;
498
- cursor: pointer;
499
- }
500
-
501
- .slider::-moz-range-thumb {
502
- width: 25px;
503
- height: 25px;
504
- background: #04AA6D;
505
- cursor: pointer;
506
- }
507
580
 
508
- .towb_editorlabel {
509
- width: 120px !important;
510
- }
511
-
512
- .towb_editorfield {
513
- width: 70% !important;
514
- }
515
-
516
- .towb_editorfield_short {
517
- width: 30% !important;
518
- }
519
-
520
- </style>
521
- <script type="text/javascript">
522
- // CSS
523
- dropdownStyles = `
524
- .loggertype-dropdown {
525
- position: absolute;
526
- background: white;
527
- border: 1px solid #ccc;
528
- border-radius: 4px;
529
- box-shadow: 0 2px 8px rgba(0,0,0,0.15);
530
- max-height: 150px;
531
- overflow-y: auto;
532
- z-index: 1000;
533
- min-width: 150px;
534
- }
535
- .loggertype-dropdown .dropdown-item {
536
- padding: 6px 12px;
537
- cursor: pointer;
538
- }
539
- .loggertype-dropdown .dropdown-item:hover {
540
- background: #f0f0f0;
541
- }
542
- `;
543
- $('<style>').text(dropdownStyles).appendTo('head');
544
-
545
- </script>
546
581
  <script type="text/javascript">
547
582
  RED.nodes.registerType('UpdateNginxHostNode', {
548
583
  category: 'nginxproxymanager',
@@ -589,8 +624,9 @@ Connection configuration for an Nginx Proxy Manager instance. Referenced by all
589
624
  required: true
590
625
  },
591
626
  metricsReference: {
592
- type: 'MetricsConfigNode',
593
- required: false
627
+ required: false,
628
+ value: '',
629
+ type: 'DelegatedConfigReferenceNode'
594
630
  },
595
631
  },
596
632
  oneditprepare: function() {
@@ -601,11 +637,14 @@ Connection configuration for an Nginx Proxy Manager instance. Referenced by all
601
637
  // **** logger **** //
602
638
  {
603
639
  let node = this;
640
+ let templateConfig = {};
604
641
  // controls.
605
642
  let logEnabled = $("#node-input-logEnabled");
606
643
  let logTemplateEnabled = $("#node-input-logTemplateOverrideEnabled");
607
644
  let logTemplateEnabledSection = $("#section_logTemplateOverrideEnabled");
608
645
  let logEnabledSection = $("#section_logEnabled");
646
+ let loggerSection = $("#section_loggerconfig");
647
+ loggerSection.hide();
609
648
  // functions.
610
649
  let getLoggerTypes = async function() {
611
650
  let types = [];
@@ -729,26 +768,148 @@ Connection configuration for an Nginx Proxy Manager instance. Referenced by all
729
768
  loggerEditButton.removeClass("disabled")
730
769
  }
731
770
  });
732
- // lastly, make sure that we set the correct value on the logger selector.
733
- updateLoggerSelectorList().then(() => {
734
- loggerSelector.val(node.logger);
735
- loggerSelector.trigger('change');
771
+ // Show the logger section only if at least one logger type is registered.
772
+ // If nodered_logging (or any other logger provider) is not installed, the section stays hidden.
773
+ getLoggerTypes().then(loggerTypes => {
774
+ if (loggerTypes.length === 0) return;
775
+ loggerSection.show();
776
+ updateLoggerSelectorList().then(() => {
777
+ loggerSelector.val(node.logger);
778
+ loggerSelector.trigger('change');
779
+ });
736
780
  });
737
781
  }
738
782
  // **** metrics **** //
739
783
  {
740
784
  let node = this;
785
+ let templateConfig = {};
741
786
  let metricsEnabled = $("#node-input-metricsEnabled");
742
- let metricsEnabledSection = $("#section_metricsEnabled");
787
+ let metricsSection = $("#section_metricsconfig");
788
+ let metricsContainer = metricsEnabled.closest(".editorgroupborder");
789
+ let metricsEnabledSection = metricsContainer.find("#section_metricsEnabled");
790
+ let metricsEnableCheck = metricsContainer.find(".metricsEnableCheck");
791
+ metricsSection.hide();
792
+ if (templateConfig.showBorder === false) {
793
+ metricsSection.find(".editorsectionheading").hide();
794
+ metricsSection.find(".editorgroupborder").css({
795
+ border: "none",
796
+ padding: 0,
797
+ margin: 0
798
+ });
799
+ }
800
+ if (templateConfig.showEnable === false) {
801
+ metricsEnableCheck.hide();
802
+ metricsEnabledSection.show();
803
+ }
804
+ let getMetricsProviderTypes = async function() {
805
+ let types = [];
806
+ await $.ajax({
807
+ url: "nodetypeservice/find?tag=MetricsProvider",
808
+ type: "GET",
809
+ contentType: "application/json; charset=utf-8",
810
+ success: (response) => {
811
+ types = response;
812
+ },
813
+ error: (jqXHR, textStatus, errorThrown) => {
814
+ console.log(jqXHR, textStatus, errorThrown);
815
+ },
816
+ });
817
+ return types;
818
+ };
819
+ let getMetricsProviders = async () => {
820
+ let providers = [];
821
+ let providerTypes = (await getMetricsProviderTypes()).map(t => t.id);
822
+ RED.nodes.eachConfig(cfg => {
823
+ if (providerTypes.includes(cfg.type)) {
824
+ providers.push({
825
+ id: cfg.id,
826
+ name: cfg.label(),
827
+ type: cfg.type
828
+ });
829
+ }
830
+ });
831
+ return providers;
832
+ };
833
+ let updateMetricsSelectorList = async () => {
834
+ metricsSelector.empty();
835
+ (await getMetricsProviders()).forEach(provider => {
836
+ $('<option value="' + provider.id + '">' + provider.name + '</option>').appendTo(metricsSelector);
837
+ });
838
+ $('<option value="_ADD_">none</option>').appendTo(metricsSelector);
839
+ };
743
840
  metricsEnabled.on('change', function() {
744
841
  if (metricsEnabled.prop("checked")) {
745
842
  metricsEnabledSection.show();
746
- node._def.defaults.metricsReference.required = true;
747
843
  } else {
748
- metricsEnabledSection.hide()
749
- node._def.defaults.metricsReference.required = false;
844
+ metricsEnabledSection.hide();
845
+ }
846
+ });
847
+ let metricsSelector = metricsContainer.find("#metrics-selector");
848
+ let metricsEditButton = metricsContainer.find("#metrics-edit-btn");
849
+ let metricsAddButton = metricsContainer.find("#metrics-add-btn");
850
+ metricsEditButton.on('click', async function(event) {
851
+ event.stopPropagation();
852
+ if (metricsEditButton.hasClass("disabled")) return;
853
+ let selectedProvider = (await getMetricsProviders()).find(p => p.id === metricsSelector.val());
854
+ if (selectedProvider) {
855
+ RED.editor.editConfig("#metrics-selector", selectedProvider.type, selectedProvider.id);
856
+ }
857
+ });
858
+ metricsAddButton.on('click', function(event) {
859
+ event.stopPropagation();
860
+ let $btn = $(event.currentTarget);
861
+ let btnOffset = $btn.offset();
862
+ let btnH = $btn.outerHeight();
863
+ let btnW = $btn.outerWidth();
864
+ $('.metricstype-dropdown').remove();
865
+ getMetricsProviderTypes().then(providerTypes => {
866
+ let $dropdown = $('<div class="metricstype-dropdown red-ui-editor"></div>').css({
867
+ position: 'absolute',
868
+ zIndex: 1000
869
+ });
870
+ providerTypes.forEach(providerType => {
871
+ $('<div class="dropdown-item"></div>').text(providerType.name).data('value', providerType.id).css({
872
+ padding: '4px 8px',
873
+ cursor: 'pointer'
874
+ }).appendTo($dropdown);
875
+ });
876
+ $('body').append($dropdown);
877
+ $dropdown.css({
878
+ top: btnOffset.top + btnH,
879
+ left: Math.max(0, btnOffset.left + btnW - $dropdown.outerWidth())
880
+ });
881
+ $(document).on('mousedown.metricsdropdown', function(e) {
882
+ if (!$(e.target).closest('.metricstype-dropdown').length) {
883
+ $dropdown.remove();
884
+ $(document).off('mousedown.metricsdropdown');
885
+ }
886
+ });
887
+ $dropdown.on('click', '.dropdown-item', function(e) {
888
+ e.stopPropagation();
889
+ const selectedValue = $(this).data('value');
890
+ $dropdown.remove();
891
+ RED.editor.editConfig("#metrics-selector", selectedValue, "_ADD_");
892
+ });
893
+ });
894
+ });
895
+ metricsSelector.on("focus", updateMetricsSelectorList);
896
+ metricsSelector.on('change', function() {
897
+ if ("_ADD_" === metricsSelector.val()) {
898
+ metricsEditButton.addClass("disabled");
899
+ } else {
900
+ metricsEditButton.removeClass("disabled");
750
901
  }
751
902
  });
903
+ // Show the metrics section only if at least one metrics provider type is registered.
904
+ // If nodered_prometheus (or any other provider) is not installed, the section stays hidden.
905
+ getMetricsProviderTypes().then(providerTypes => {
906
+ if (providerTypes.length === 0) return;
907
+ metricsSection.show();
908
+ updateMetricsSelectorList().then(() => {
909
+ metricsSelector.val(node.metricsReference);
910
+ metricsSelector.trigger('change');
911
+ });
912
+ });
752
913
  }
753
914
  },
754
915
  oneditsave: function() {
@@ -758,6 +919,8 @@ Connection configuration for an Nginx Proxy Manager instance. Referenced by all
758
919
  }
759
920
  // **** logger **** //
760
921
  {
922
+ let node = this;
923
+ let templateConfig = {};
761
924
  node = this;
762
925
  var selectedLogger = $("#logger-selector").val();
763
926
  node.logger = (selectedLogger && selectedLogger !== "_ADD_") ? selectedLogger : '';
@@ -766,7 +929,16 @@ Connection configuration for an Nginx Proxy Manager instance. Referenced by all
766
929
  delete node.logTemplateOverrideEditor;
767
930
  }
768
931
  // **** metrics **** //
769
- {}
932
+ {
933
+ let node = this;
934
+ let templateConfig = {};
935
+ node = this;
936
+ var selectedProvider = $("#metrics-selector").val();
937
+ node.metricsReference = (selectedProvider && selectedProvider !== "_ADD_") ? selectedProvider : '';
938
+ if (templateConfig.showEnable === false) {
939
+ node.metricsEnabled = !!node.metricsReference;
940
+ }
941
+ }
770
942
  },
771
943
  oneditcancel: function() {},
772
944
  oneditdelete: function() {},
@@ -796,13 +968,14 @@ Connection configuration for an Nginx Proxy Manager instance. Referenced by all
796
968
  </div>
797
969
  <div class="editorgroupborder">
798
970
  <div class="form-row nomargin logEnableCheck">
799
- <input type="checkbox" id="node-input-logEnabled" placeholder="logEnabled" value="false" style="margin:8px 0 10px 102px; width:20px;">
800
- <label style="width:auto" for="node-input-logEnabled"><span>Enable Logging</span></label>
971
+ <label class="towb_editorlabel">&nbsp;</label>
972
+ <input class="towb_checkbox" type="checkbox" id="node-input-logEnabled" placeholder="logEnabled" value="false">
973
+ <label class="towb_checkboxlabel" for="node-input-logEnabled"><span>Enable Logging</span></label>
801
974
  </div>
802
975
 
803
976
  <div id="section_logEnabled">
804
977
  <div class="form-row nomargin">
805
- <label for="logger-selector">Logger</label>
978
+ <label class="towb_editorlabel" for="logger-selector">Logger</label>
806
979
  <div style="width: 70%; display: inline-flex;">
807
980
  <select id="logger-selector" style="flex-grow: 1;" class="">
808
981
  <option value="_ADD_">none</option>
@@ -817,8 +990,9 @@ Connection configuration for an Nginx Proxy Manager instance. Referenced by all
817
990
  </div>
818
991
 
819
992
  <div class="form-row nomargin">
820
- <input type="checkbox" id="node-input-logTemplateOverrideEnabled" placeholder="" value="false" style="margin:8px 0 10px 102px; width:20px;">
821
- <label style="width:auto" for="node-input-logTemplateOverrideEnabled"><span>Override Template</span></label>
993
+ <label class="towb_editorlabel">&nbsp;</label>
994
+ <input class="towb_checkbox" type="checkbox" id="node-input-logTemplateOverrideEnabled" placeholder="" value="false">
995
+ <label class="towb_checkboxlabel" for="node-input-logTemplateOverrideEnabled"><span>Override Template</span></label>
822
996
  </div>
823
997
 
824
998
  <div id="section_logTemplateOverrideEnabled">
@@ -840,14 +1014,25 @@ Connection configuration for an Nginx Proxy Manager instance. Referenced by all
840
1014
  </div>
841
1015
  <div class="editorgroupborder">
842
1016
  <div class="form-row nomargin metricsEnableCheck">
843
- <input type="checkbox" id="node-input-metricsEnabled" value="false" style="margin:8px 0 10px 102px; width:20px;" />
844
- <label style="width:auto" for="node-input-metricsEnabled"><span>Enable Metrics</span></label>
1017
+ <label class="towb_editorlabel">&nbsp;</label>
1018
+ <input class="towb_checkbox" type="checkbox" id="node-input-metricsEnabled" value="false" />
1019
+ <label class="towb_checkboxlabel" for="node-input-metricsEnabled"><span>Enable Metrics</span></label>
845
1020
  </div>
846
1021
 
847
1022
  <div id="section_metricsEnabled">
848
1023
  <div class="form-row nomargin">
849
- <label class="towb_editorlabel" for="node-input-metricsReference">Metric Collector</label>
850
- <input id="node-input-metricsReference" placeholder="metrics" />
1024
+ <label class="towb_editorlabel" for="metrics-selector">Metric Provider</label>
1025
+ <div style="width: 70%; display: inline-flex;">
1026
+ <select id="metrics-selector" style="flex-grow: 1; min-width: 0;">
1027
+ <option value="_ADD_">none</option>
1028
+ </select>
1029
+ <a id="metrics-edit-btn" class="red-ui-button disabled" style="margin-left: 10px; flex-shrink: 0;">
1030
+ <i class="fa fa-pencil"></i>
1031
+ </a>
1032
+ <a id="metrics-add-btn" class="red-ui-button" style="margin-left: 10px; flex-shrink: 0;">
1033
+ <i class="fa fa-plus"></i>
1034
+ </a>
1035
+ </div>
851
1036
  </div>
852
1037
  </div>
853
1038
  </div>
@@ -928,104 +1113,9 @@ The original message is forwarded unchanged after the operation completes.
928
1113
 
929
1114
  ### Metrics
930
1115
  : *enable metrics* (boolean) : if checked, then the node will produce metrics output to the specified metrics provider.
931
- : *metric collector* (metricconfig) : the collection point or grouping where this particular metric will be attached.
1116
+ : *metric provider* (metricsconfig) : the metrics backend that this node will report to.
932
1117
  </script>
933
- <!-- logger -->
934
- <style>
935
- .editorgroupborder {
936
- border-width: 1px;
937
- border-style: solid;
938
- border-color: lightgray;
939
- padding: 3px;
940
- margin-top: 2px;
941
- margin-bottom: 2px;
942
- }
943
-
944
- .editorsectionheading {
945
- font-weight: 600;
946
- margin-bottom: 1px !important;
947
- margin-top: 6px !important;
948
- }
949
-
950
- .nomargin {
951
- margin-bottom: 1px !important;
952
- margin-top: 1px !important;
953
- }
954
-
955
- .slidecontainer {
956
- width: 100%;
957
- }
958
-
959
- .slider {
960
- -webkit-appearance: none;
961
- appearance: none;
962
- width: 100%;
963
- height: 25px;
964
- background: #d3d3d3;
965
- outline: none;
966
- opacity: 0.7;
967
- -webkit-transition: .2s;
968
- transition: opacity .2s;
969
- }
970
-
971
- .slider:hover {
972
- opacity: 1;
973
- }
974
-
975
- .slider::-webkit-slider-thumb {
976
- -webkit-appearance: none;
977
- appearance: none;
978
- width: 25px;
979
- height: 25px;
980
- background: #04AA6D;
981
- cursor: pointer;
982
- }
983
-
984
- .slider::-moz-range-thumb {
985
- width: 25px;
986
- height: 25px;
987
- background: #04AA6D;
988
- cursor: pointer;
989
- }
990
-
991
- .towb_editorlabel {
992
- width: 120px !important;
993
- }
994
-
995
- .towb_editorfield {
996
- width: 70% !important;
997
- }
998
-
999
- .towb_editorfield_short {
1000
- width: 30% !important;
1001
- }
1002
-
1003
- </style>
1004
- <script type="text/javascript">
1005
- // CSS
1006
- dropdownStyles = `
1007
- .loggertype-dropdown {
1008
- position: absolute;
1009
- background: white;
1010
- border: 1px solid #ccc;
1011
- border-radius: 4px;
1012
- box-shadow: 0 2px 8px rgba(0,0,0,0.15);
1013
- max-height: 150px;
1014
- overflow-y: auto;
1015
- z-index: 1000;
1016
- min-width: 150px;
1017
- }
1018
- .loggertype-dropdown .dropdown-item {
1019
- padding: 6px 12px;
1020
- cursor: pointer;
1021
- }
1022
- .loggertype-dropdown .dropdown-item:hover {
1023
- background: #f0f0f0;
1024
- }
1025
- `;
1026
- $('<style>').text(dropdownStyles).appendTo('head');
1027
1118
 
1028
- </script>
1029
1119
  <script type="text/javascript">
1030
1120
  RED.nodes.registerType('NginxGetHostsNode', {
1031
1121
  category: 'nginxproxymanager',
@@ -1072,8 +1162,9 @@ The original message is forwarded unchanged after the operation completes.
1072
1162
  required: true
1073
1163
  },
1074
1164
  metricsReference: {
1075
- type: 'MetricsConfigNode',
1076
- required: false
1165
+ required: false,
1166
+ value: '',
1167
+ type: 'DelegatedConfigReferenceNode'
1077
1168
  },
1078
1169
  },
1079
1170
  oneditprepare: function() {
@@ -1087,11 +1178,14 @@ The original message is forwarded unchanged after the operation completes.
1087
1178
  // **** logger **** //
1088
1179
  {
1089
1180
  let node = this;
1181
+ let templateConfig = {};
1090
1182
  // controls.
1091
1183
  let logEnabled = $("#node-input-logEnabled");
1092
1184
  let logTemplateEnabled = $("#node-input-logTemplateOverrideEnabled");
1093
1185
  let logTemplateEnabledSection = $("#section_logTemplateOverrideEnabled");
1094
1186
  let logEnabledSection = $("#section_logEnabled");
1187
+ let loggerSection = $("#section_loggerconfig");
1188
+ loggerSection.hide();
1095
1189
  // functions.
1096
1190
  let getLoggerTypes = async function() {
1097
1191
  let types = [];
@@ -1215,26 +1309,148 @@ The original message is forwarded unchanged after the operation completes.
1215
1309
  loggerEditButton.removeClass("disabled")
1216
1310
  }
1217
1311
  });
1218
- // lastly, make sure that we set the correct value on the logger selector.
1219
- updateLoggerSelectorList().then(() => {
1220
- loggerSelector.val(node.logger);
1221
- loggerSelector.trigger('change');
1312
+ // Show the logger section only if at least one logger type is registered.
1313
+ // If nodered_logging (or any other logger provider) is not installed, the section stays hidden.
1314
+ getLoggerTypes().then(loggerTypes => {
1315
+ if (loggerTypes.length === 0) return;
1316
+ loggerSection.show();
1317
+ updateLoggerSelectorList().then(() => {
1318
+ loggerSelector.val(node.logger);
1319
+ loggerSelector.trigger('change');
1320
+ });
1222
1321
  });
1223
1322
  }
1224
1323
  // **** metrics **** //
1225
1324
  {
1226
1325
  let node = this;
1326
+ let templateConfig = {};
1227
1327
  let metricsEnabled = $("#node-input-metricsEnabled");
1228
- let metricsEnabledSection = $("#section_metricsEnabled");
1328
+ let metricsSection = $("#section_metricsconfig");
1329
+ let metricsContainer = metricsEnabled.closest(".editorgroupborder");
1330
+ let metricsEnabledSection = metricsContainer.find("#section_metricsEnabled");
1331
+ let metricsEnableCheck = metricsContainer.find(".metricsEnableCheck");
1332
+ metricsSection.hide();
1333
+ if (templateConfig.showBorder === false) {
1334
+ metricsSection.find(".editorsectionheading").hide();
1335
+ metricsSection.find(".editorgroupborder").css({
1336
+ border: "none",
1337
+ padding: 0,
1338
+ margin: 0
1339
+ });
1340
+ }
1341
+ if (templateConfig.showEnable === false) {
1342
+ metricsEnableCheck.hide();
1343
+ metricsEnabledSection.show();
1344
+ }
1345
+ let getMetricsProviderTypes = async function() {
1346
+ let types = [];
1347
+ await $.ajax({
1348
+ url: "nodetypeservice/find?tag=MetricsProvider",
1349
+ type: "GET",
1350
+ contentType: "application/json; charset=utf-8",
1351
+ success: (response) => {
1352
+ types = response;
1353
+ },
1354
+ error: (jqXHR, textStatus, errorThrown) => {
1355
+ console.log(jqXHR, textStatus, errorThrown);
1356
+ },
1357
+ });
1358
+ return types;
1359
+ };
1360
+ let getMetricsProviders = async () => {
1361
+ let providers = [];
1362
+ let providerTypes = (await getMetricsProviderTypes()).map(t => t.id);
1363
+ RED.nodes.eachConfig(cfg => {
1364
+ if (providerTypes.includes(cfg.type)) {
1365
+ providers.push({
1366
+ id: cfg.id,
1367
+ name: cfg.label(),
1368
+ type: cfg.type
1369
+ });
1370
+ }
1371
+ });
1372
+ return providers;
1373
+ };
1374
+ let updateMetricsSelectorList = async () => {
1375
+ metricsSelector.empty();
1376
+ (await getMetricsProviders()).forEach(provider => {
1377
+ $('<option value="' + provider.id + '">' + provider.name + '</option>').appendTo(metricsSelector);
1378
+ });
1379
+ $('<option value="_ADD_">none</option>').appendTo(metricsSelector);
1380
+ };
1229
1381
  metricsEnabled.on('change', function() {
1230
1382
  if (metricsEnabled.prop("checked")) {
1231
1383
  metricsEnabledSection.show();
1232
- node._def.defaults.metricsReference.required = true;
1233
1384
  } else {
1234
- metricsEnabledSection.hide()
1235
- node._def.defaults.metricsReference.required = false;
1385
+ metricsEnabledSection.hide();
1386
+ }
1387
+ });
1388
+ let metricsSelector = metricsContainer.find("#metrics-selector");
1389
+ let metricsEditButton = metricsContainer.find("#metrics-edit-btn");
1390
+ let metricsAddButton = metricsContainer.find("#metrics-add-btn");
1391
+ metricsEditButton.on('click', async function(event) {
1392
+ event.stopPropagation();
1393
+ if (metricsEditButton.hasClass("disabled")) return;
1394
+ let selectedProvider = (await getMetricsProviders()).find(p => p.id === metricsSelector.val());
1395
+ if (selectedProvider) {
1396
+ RED.editor.editConfig("#metrics-selector", selectedProvider.type, selectedProvider.id);
1397
+ }
1398
+ });
1399
+ metricsAddButton.on('click', function(event) {
1400
+ event.stopPropagation();
1401
+ let $btn = $(event.currentTarget);
1402
+ let btnOffset = $btn.offset();
1403
+ let btnH = $btn.outerHeight();
1404
+ let btnW = $btn.outerWidth();
1405
+ $('.metricstype-dropdown').remove();
1406
+ getMetricsProviderTypes().then(providerTypes => {
1407
+ let $dropdown = $('<div class="metricstype-dropdown red-ui-editor"></div>').css({
1408
+ position: 'absolute',
1409
+ zIndex: 1000
1410
+ });
1411
+ providerTypes.forEach(providerType => {
1412
+ $('<div class="dropdown-item"></div>').text(providerType.name).data('value', providerType.id).css({
1413
+ padding: '4px 8px',
1414
+ cursor: 'pointer'
1415
+ }).appendTo($dropdown);
1416
+ });
1417
+ $('body').append($dropdown);
1418
+ $dropdown.css({
1419
+ top: btnOffset.top + btnH,
1420
+ left: Math.max(0, btnOffset.left + btnW - $dropdown.outerWidth())
1421
+ });
1422
+ $(document).on('mousedown.metricsdropdown', function(e) {
1423
+ if (!$(e.target).closest('.metricstype-dropdown').length) {
1424
+ $dropdown.remove();
1425
+ $(document).off('mousedown.metricsdropdown');
1426
+ }
1427
+ });
1428
+ $dropdown.on('click', '.dropdown-item', function(e) {
1429
+ e.stopPropagation();
1430
+ const selectedValue = $(this).data('value');
1431
+ $dropdown.remove();
1432
+ RED.editor.editConfig("#metrics-selector", selectedValue, "_ADD_");
1433
+ });
1434
+ });
1435
+ });
1436
+ metricsSelector.on("focus", updateMetricsSelectorList);
1437
+ metricsSelector.on('change', function() {
1438
+ if ("_ADD_" === metricsSelector.val()) {
1439
+ metricsEditButton.addClass("disabled");
1440
+ } else {
1441
+ metricsEditButton.removeClass("disabled");
1236
1442
  }
1237
1443
  });
1444
+ // Show the metrics section only if at least one metrics provider type is registered.
1445
+ // If nodered_prometheus (or any other provider) is not installed, the section stays hidden.
1446
+ getMetricsProviderTypes().then(providerTypes => {
1447
+ if (providerTypes.length === 0) return;
1448
+ metricsSection.show();
1449
+ updateMetricsSelectorList().then(() => {
1450
+ metricsSelector.val(node.metricsReference);
1451
+ metricsSelector.trigger('change');
1452
+ });
1453
+ });
1238
1454
  }
1239
1455
  },
1240
1456
  oneditsave: function() {
@@ -1244,6 +1460,8 @@ The original message is forwarded unchanged after the operation completes.
1244
1460
  }
1245
1461
  // **** logger **** //
1246
1462
  {
1463
+ let node = this;
1464
+ let templateConfig = {};
1247
1465
  node = this;
1248
1466
  var selectedLogger = $("#logger-selector").val();
1249
1467
  node.logger = (selectedLogger && selectedLogger !== "_ADD_") ? selectedLogger : '';
@@ -1252,7 +1470,16 @@ The original message is forwarded unchanged after the operation completes.
1252
1470
  delete node.logTemplateOverrideEditor;
1253
1471
  }
1254
1472
  // **** metrics **** //
1255
- {}
1473
+ {
1474
+ let node = this;
1475
+ let templateConfig = {};
1476
+ node = this;
1477
+ var selectedProvider = $("#metrics-selector").val();
1478
+ node.metricsReference = (selectedProvider && selectedProvider !== "_ADD_") ? selectedProvider : '';
1479
+ if (templateConfig.showEnable === false) {
1480
+ node.metricsEnabled = !!node.metricsReference;
1481
+ }
1482
+ }
1256
1483
  },
1257
1484
  oneditcancel: function() {},
1258
1485
  oneditdelete: function() {},
@@ -1287,13 +1514,14 @@ The original message is forwarded unchanged after the operation completes.
1287
1514
  </div>
1288
1515
  <div class="editorgroupborder">
1289
1516
  <div class="form-row nomargin logEnableCheck">
1290
- <input type="checkbox" id="node-input-logEnabled" placeholder="logEnabled" value="false" style="margin:8px 0 10px 102px; width:20px;">
1291
- <label style="width:auto" for="node-input-logEnabled"><span>Enable Logging</span></label>
1517
+ <label class="towb_editorlabel">&nbsp;</label>
1518
+ <input class="towb_checkbox" type="checkbox" id="node-input-logEnabled" placeholder="logEnabled" value="false">
1519
+ <label class="towb_checkboxlabel" for="node-input-logEnabled"><span>Enable Logging</span></label>
1292
1520
  </div>
1293
1521
 
1294
1522
  <div id="section_logEnabled">
1295
1523
  <div class="form-row nomargin">
1296
- <label for="logger-selector">Logger</label>
1524
+ <label class="towb_editorlabel" for="logger-selector">Logger</label>
1297
1525
  <div style="width: 70%; display: inline-flex;">
1298
1526
  <select id="logger-selector" style="flex-grow: 1;" class="">
1299
1527
  <option value="_ADD_">none</option>
@@ -1308,8 +1536,9 @@ The original message is forwarded unchanged after the operation completes.
1308
1536
  </div>
1309
1537
 
1310
1538
  <div class="form-row nomargin">
1311
- <input type="checkbox" id="node-input-logTemplateOverrideEnabled" placeholder="" value="false" style="margin:8px 0 10px 102px; width:20px;">
1312
- <label style="width:auto" for="node-input-logTemplateOverrideEnabled"><span>Override Template</span></label>
1539
+ <label class="towb_editorlabel">&nbsp;</label>
1540
+ <input class="towb_checkbox" type="checkbox" id="node-input-logTemplateOverrideEnabled" placeholder="" value="false">
1541
+ <label class="towb_checkboxlabel" for="node-input-logTemplateOverrideEnabled"><span>Override Template</span></label>
1313
1542
  </div>
1314
1543
 
1315
1544
  <div id="section_logTemplateOverrideEnabled">
@@ -1331,14 +1560,25 @@ The original message is forwarded unchanged after the operation completes.
1331
1560
  </div>
1332
1561
  <div class="editorgroupborder">
1333
1562
  <div class="form-row nomargin metricsEnableCheck">
1334
- <input type="checkbox" id="node-input-metricsEnabled" value="false" style="margin:8px 0 10px 102px; width:20px;" />
1335
- <label style="width:auto" for="node-input-metricsEnabled"><span>Enable Metrics</span></label>
1563
+ <label class="towb_editorlabel">&nbsp;</label>
1564
+ <input class="towb_checkbox" type="checkbox" id="node-input-metricsEnabled" value="false" />
1565
+ <label class="towb_checkboxlabel" for="node-input-metricsEnabled"><span>Enable Metrics</span></label>
1336
1566
  </div>
1337
1567
 
1338
1568
  <div id="section_metricsEnabled">
1339
1569
  <div class="form-row nomargin">
1340
- <label class="towb_editorlabel" for="node-input-metricsReference">Metric Collector</label>
1341
- <input id="node-input-metricsReference" placeholder="metrics" />
1570
+ <label class="towb_editorlabel" for="metrics-selector">Metric Provider</label>
1571
+ <div style="width: 70%; display: inline-flex;">
1572
+ <select id="metrics-selector" style="flex-grow: 1; min-width: 0;">
1573
+ <option value="_ADD_">none</option>
1574
+ </select>
1575
+ <a id="metrics-edit-btn" class="red-ui-button disabled" style="margin-left: 10px; flex-shrink: 0;">
1576
+ <i class="fa fa-pencil"></i>
1577
+ </a>
1578
+ <a id="metrics-add-btn" class="red-ui-button" style="margin-left: 10px; flex-shrink: 0;">
1579
+ <i class="fa fa-plus"></i>
1580
+ </a>
1581
+ </div>
1342
1582
  </div>
1343
1583
  </div>
1344
1584
  </div>
@@ -1380,7 +1620,6 @@ The original message is forwarded with the specified property set to an array of
1380
1620
 
1381
1621
  ### Metrics
1382
1622
  : *enable metrics* (boolean) : if checked, then the node will produce metrics output to the specified metrics provider.
1383
- : *metric collector* (metricconfig) : the collection point or grouping where this particular metric will be attached.
1623
+ : *metric provider* (metricsconfig) : the metrics backend that this node will report to.
1384
1624
  </script>
1385
-
1386
1625