@theotherwillembotha/node-red-plugincore 0.0.51 → 0.0.53

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 (30) hide show
  1. package/README.md +153 -7
  2. package/build/GenerateNodes.js +2 -0
  3. package/build/core/ui/template/ScriptEditorTemplate.d.ts +5 -0
  4. package/build/core/ui/template/ScriptEditorTemplate.d.ts.map +1 -0
  5. package/build/core/ui/template/ScriptEditorTemplate.html +50 -0
  6. package/build/core/ui/template/ScriptEditorTemplate.js +11 -0
  7. package/build/core/ui/template/UIHelperTemplate.d.ts +5 -0
  8. package/build/core/ui/template/UIHelperTemplate.d.ts.map +1 -0
  9. package/build/core/ui/template/UIHelperTemplate.html +229 -0
  10. package/build/core/ui/template/UIHelperTemplate.js +11 -0
  11. package/build/index.d.ts +2 -0
  12. package/build/index.d.ts.map +1 -1
  13. package/build/index.js +3 -0
  14. package/build/resources/editorLanguageExtension.d.ts +1 -0
  15. package/build/resources/editorLanguageExtension.d.ts.map +1 -0
  16. package/build/resources/editorLanguageExtension.js +1189 -0
  17. package/documentation/ConsoleLoggerConfigNode.png +0 -0
  18. package/documentation/LokiLoggerConfigNode.png +0 -0
  19. package/documentation/RestLoggerConfigNode.png +0 -0
  20. package/package.json +21 -9
  21. package/resources/editorLanguageExtension.d.ts +1 -0
  22. package/resources/editorLanguageExtension.d.ts.map +1 -0
  23. package/resources/editorLanguageExtension.js +1189 -0
  24. package/src/GenerateNodes.ts +3 -1
  25. package/src/core/ui/template/ScriptEditorTemplate.html +50 -0
  26. package/src/core/ui/template/ScriptEditorTemplate.ts +14 -0
  27. package/src/core/ui/template/UIHelperTemplate.html +229 -0
  28. package/src/core/ui/template/UIHelperTemplate.ts +14 -0
  29. package/src/index.ts +4 -0
  30. package/src/resources/editorLanguageExtension.ts +1281 -0
package/README.md CHANGED
@@ -1,11 +1,11 @@
1
1
  # @theotherwillembotha/node-red-plugincore
2
2
 
3
- A TypeScript framework for building production-grade Node-RED plugins with built-in support for structured logging, Prometheus metrics, and webhook servers.
3
+ A TypeScript framework for building production-grade Node-RED plugins with built-in support for structured logging, Prometheus metrics, webhook servers, and reusable UI components.
4
4
 
5
5
  This package has two roles:
6
6
 
7
7
  1. **Config nodes** — a set of shared configuration nodes (loggers, metric collectors, webhook server) that are installed into Node-RED and referenced by other nodes in a flow.
8
- 2. **Developer framework** — a TypeScript base library that plugin authors extend to build their own Node-RED nodes, with decorators and templates that wire in logging, metrics, and webhooks automatically.
8
+ 2. **Developer framework** — a TypeScript base library that plugin authors extend to build their own Node-RED nodes, with decorators and templates that wire in logging, metrics, webhooks, and editor UI automatically.
9
9
 
10
10
  ---
11
11
 
@@ -16,6 +16,7 @@ This framework is the foundation for a growing set of Node-RED plugins. The foll
16
16
  | Plugin | Description |
17
17
  |--------|-------------|
18
18
  | [@theotherwillembotha/node-red-telemetry](https://github.com/theotherwillembotha/nodered_telemetry) | Ready-to-use flow nodes for structured logging and Prometheus metrics — Logger, Counter, Gauge, and Timer nodes that attach to the config nodes provided by this package. |
19
+ | [@theotherwillembotha/node-red-nginxproxymanager](https://github.com/theotherwillembotha/nodered_nginxproxymanager) | Node-RED nodes for managing Nginx Proxy Manager hosts directly from your flows. Includes a config node that registers as a reverse proxy provider, an Update Host node for creating and updating proxy entries, and a Get Hosts node for retrieving the current host list. |
19
20
 
20
21
  Additional plugins will be listed here as they are published.
21
22
 
@@ -41,11 +42,19 @@ Config nodes are shared resources configured once and referenced across your flo
41
42
 
42
43
  Three logger backends are supported. All expose the same interface and are interchangeable — any node built with the `@Logger` decorator can use any of them.
43
44
 
44
- | Node | Description |
45
- |------|-------------|
46
- | **Console Logger** | Writes structured log output to stdout via Winston. Ideal for development and containerised deployments that forward stdout to a log aggregator. |
47
- | **REST Logger** | Ships log entries to a remote HTTP/HTTPS endpoint. Supports Basic and API Key authentication. |
48
- | **Loki Logger** | Pushes log entries to a Grafana Loki instance via the Loki HTTP API. Supports multi-tenant deployments. |
45
+ **Console Logger** writes structured log output to stdout via Winston. Ideal for development and containerised deployments that forward stdout to a log aggregator.
46
+
47
+ ![Console Logger Config](documentation/ConsoleLoggerConfigNode.png)
48
+
49
+ **REST Logger** ships log entries to a remote HTTP/HTTPS endpoint. Supports Basic and API Key authentication.
50
+
51
+ ![REST Logger Config](documentation/RestLoggerConfigNode.png)
52
+
53
+ **Loki Logger** — pushes log entries to a Grafana Loki instance via the Loki HTTP API. Supports multi-tenant deployments via the Tenant ID field.
54
+
55
+ ![Loki Logger Config](documentation/LokiLoggerConfigNode.png)
56
+
57
+ All three loggers share a **Level** selector (debug, info, warn, error) and a **Template** field — a Handlebars template that controls the shape of each log entry. The default `message:{{msg}}` passes the raw message through; you can customise it to include only the fields you care about.
49
58
 
50
59
  #### Metrics
51
60
 
@@ -169,9 +178,146 @@ Templates bundle reusable UI fragments that compose into any node's editor panel
169
178
  | `GaugeMetricTemplate` | Gauge config node reference |
170
179
  | `TimerMetricTemplate` | Timer config node reference |
171
180
  | `WebhookTemplate` | Webhook server reference, path, auth, and reverse proxy config |
181
+ | `UIHelperTemplate` | Global `PluginCore.dialog()` and `PluginCore.table()` UI factories (see below) |
182
+ | `ScriptEditorTemplate` | Global `PluginCore.createScriptEditor()` factory for Monaco-based script editors (see below) |
172
183
  | `SettingsTemplate` | General settings section |
173
184
  | `BasicTemplate` | Base styles shared by all nodes |
174
185
 
186
+ ### UI helpers
187
+
188
+ Including `UIHelperTemplate` in a node's `templates` list injects two client-side factory functions into the Node-RED editor page. Both are available globally as `PluginCore.dialog(...)` and `PluginCore.table(...)` and are styled to match Node-RED's own editor aesthetic.
189
+
190
+ #### `PluginCore.dialog(options)`
191
+
192
+ Opens a modal overlay with a title bar and one or more tabs. Closes on the close button, an overlay click, or Escape.
193
+
194
+ ```javascript
195
+ PluginCore.dialog({
196
+ title: "My Plugin — Status",
197
+ tabs: [
198
+ {
199
+ label: "Proxy Hosts",
200
+ render: function($container) {
201
+ $container.append(
202
+ PluginCore.table({
203
+ columns: [
204
+ { key: "id", label: "ID" },
205
+ { key: "name", label: "Name" },
206
+ { key: "enabled", label: "Enabled",
207
+ render: function(v) {
208
+ return $("<span>")
209
+ .addClass(v ? "plugincore-status-enabled"
210
+ : "plugincore-status-disabled")
211
+ .text(v ? "✔ Enabled" : "✘ Disabled");
212
+ }}
213
+ ],
214
+ rows: data
215
+ })
216
+ );
217
+ }
218
+ }
219
+ ]
220
+ });
221
+ ```
222
+
223
+ **Options:**
224
+
225
+ | Field | Type | Description |
226
+ |-------|------|-------------|
227
+ | `title` | `string` | Heading shown in the dialog title bar |
228
+ | `tabs` | `array` | One or more tab definitions |
229
+ | `tabs[].label` | `string` | Tab heading |
230
+ | `tabs[].render` | `function($container)` | Called with a jQuery element; append content into it |
231
+
232
+ **Returns:** `{ close() }` — call `close()` to dismiss the dialog programmatically.
233
+
234
+ ---
235
+
236
+ #### `PluginCore.table(config)`
237
+
238
+ Returns a styled jQuery `<table>` element ready to append into any container.
239
+
240
+ ```javascript
241
+ var $table = PluginCore.table({
242
+ columns: [
243
+ { key: "id", label: "ID" },
244
+ { key: "domain", label: "Domain",
245
+ render: function(value, row) { return value.join(", "); } }
246
+ ],
247
+ rows: arrayOfObjects
248
+ });
249
+ $container.append($table);
250
+ ```
251
+
252
+ **Config:**
253
+
254
+ | Field | Type | Description |
255
+ |-------|------|-------------|
256
+ | `columns` | `array` | Column definitions |
257
+ | `columns[].key` | `string` | Property name on each row object |
258
+ | `columns[].label` | `string` | Column header text |
259
+ | `columns[].render` | `function(value, row)` | Optional. Return a string or jQuery element for custom cell rendering |
260
+ | `rows` | `object[]` | Data rows |
261
+
262
+ **CSS classes available for cell content:**
263
+
264
+ | Class | Colour | Intended use |
265
+ |-------|--------|-------------|
266
+ | `plugincore-status-enabled` | Green | Enabled / active state |
267
+ | `plugincore-status-disabled` | Red | Disabled / inactive state |
268
+
269
+ #### `PluginCore.createScriptEditor(elementId, template, initialValue)`
270
+
271
+ Including `ScriptEditorTemplate` in a node's `templates` list injects a Monaco-based script editor factory into the Node-RED editor page. It wraps the async Monaco initialisation boilerplate into a single call and returns a `{ getValue(), dispose() }` handle.
272
+
273
+ ```javascript
274
+ // In onIncludeEditPrepare:
275
+ let scriptTemplate = `
276
+ interface Message { [key: string]: any; }
277
+ async function(msg: Message) {
278
+ \${script}
279
+ }
280
+ `;
281
+
282
+ node.scriptEditor = PluginCore.createScriptEditor(
283
+ 'node-input-script-editor', // DOM id of the container element
284
+ scriptTemplate, // TypeScript context template
285
+ node.script || 'return true;' // initial value
286
+ );
287
+
288
+ // In onIncludeEditSave:
289
+ node.script = node.scriptEditor.getValue();
290
+ delete node.scriptEditor;
291
+
292
+ // In IncludeEditCancel:
293
+ node.scriptEditor.dispose();
294
+ delete node.scriptEditor;
295
+ ```
296
+
297
+ The `template` string provides the TypeScript context that the Monaco language service uses for diagnostics, completions, and hover info. Use `\${script}` as the placeholder for the user's code. The user only sees their code — the surrounding context is invisible to them but informs type checking.
298
+
299
+ **Returns:** `{ getValue(): string, dispose(): void }`
300
+
301
+ ---
302
+
303
+ > **Note — Handlebars escaping in node HTML files**
304
+ >
305
+ > Node HTML files (`.html` template files) are processed by Handlebars during the build. This means any `{{ }}` syntax in the HTML — including in JavaScript comments or JSDoc — will be interpreted as a Handlebars expression and produce unexpected output or an error.
306
+ >
307
+ > Escape curly braces with a backslash wherever they appear literally in the file:
308
+ >
309
+ > ```javascript
310
+ > // Wrong — Handlebars will try to evaluate this:
311
+ > // @returns {{ getValue(): string }}
312
+ >
313
+ > // Correct — escaped so Handlebars passes it through:
314
+ > // @returns \{{ getValue(): string \}}
315
+ > ```
316
+ >
317
+ > This applies anywhere in the HTML file: `<script>` blocks, inline styles, markdown documentation sections, and comments.
318
+
319
+ ---
320
+
175
321
  ### Registering nodes for generation
176
322
 
177
323
  Create a `GenerateNodes.ts` at the root of your `src/` directory. This is the composition root — register every service, template, and node, then call `.generate()` to emit the two Node-RED entry files (`Nodes.js` and `Plugins.js`).
@@ -23,6 +23,8 @@ new index_js_1.NodeGenerator("./src/core/")
23
23
  .registerTemplate(index_js_4.GaugeMetricTemplate)
24
24
  .registerTemplate(index_js_1.TimerMetricTemplate)
25
25
  .registerTemplate(index_js_2.WebhookTemplate)
26
+ .registerTemplate(index_js_1.UIHelperTemplate)
27
+ .registerTemplate(index_js_1.ScriptEditorTemplate)
26
28
  // nodes
27
29
  .registerNode(DelegatedConfigReferenceNode_js_1.DelegatedConfigReferenceNode)
28
30
  .registerNode(index_js_1.ConsoleLoggerConfigNode)
@@ -0,0 +1,5 @@
1
+ import { Template, TemplateDescriptor } from "../../NodeConstructor";
2
+ export declare class ScriptEditorTemplate extends Template {
3
+ static getTemplateDescriptor(): TemplateDescriptor;
4
+ }
5
+ //# sourceMappingURL=ScriptEditorTemplate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScriptEditorTemplate.d.ts","sourceRoot":"","sources":["../../../../src/core/ui/template/ScriptEditorTemplate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAGpE,qBAAa,oBAAqB,SAAQ,QAAQ;WAEhC,qBAAqB,IAAI,kBAAkB;CAQ5D"}
@@ -0,0 +1,50 @@
1
+
2
+ <div template-section="onIncludeOnce">
3
+
4
+ <script src="resources/@theotherwillembotha/node-red-plugincore/editorLanguageExtension.js"></script>
5
+
6
+ <script type="text/javascript">
7
+
8
+ window.PluginCore = window.PluginCore || {};
9
+
10
+ /**
11
+ * PluginCore.createScriptEditor(elementId, template, initialValue)
12
+ *
13
+ * Creates a Monaco editor instance with TypeScript-aware diagnostics,
14
+ * completions, and hover info scoped to the provided type template.
15
+ *
16
+ * @param {string} elementId - DOM id of the container element.
17
+ * @param {string} template - TypeScript template string. Use `${script}`
18
+ * as the placeholder for the user's code.
19
+ * @param {string} initialValue - The starting content of the editor.
20
+ * @returns \{{ getValue(): string, dispose(): void \}}
21
+ */
22
+ PluginCore.createScriptEditor = function(elementId, template, initialValue) {
23
+ var editorInstance = null;
24
+ var currentValue = initialValue || '';
25
+
26
+ ScriptEditorLanguageManager.createLanguage(monaco, template).then(function(language) {
27
+ editorInstance = monaco.editor.create(document.getElementById(elementId), {
28
+ value: currentValue,
29
+ language: language.getName(),
30
+ automaticLayout: true,
31
+ wordBasedSuggestions: 'currentDocument',
32
+ });
33
+ });
34
+
35
+ return {
36
+ getValue: function() {
37
+ return editorInstance ? editorInstance.getValue() : currentValue;
38
+ },
39
+ dispose: function() {
40
+ if (editorInstance) {
41
+ editorInstance.dispose();
42
+ editorInstance = null;
43
+ }
44
+ }
45
+ };
46
+ };
47
+
48
+ </script>
49
+
50
+ </div>
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ScriptEditorTemplate = void 0;
4
+ const NodeConstructor_1 = require("../../NodeConstructor");
5
+ const NodeGenerator_1 = require("../../NodeGenerator");
6
+ class ScriptEditorTemplate extends NodeConstructor_1.Template {
7
+ static getTemplateDescriptor() {
8
+ return new NodeConstructor_1.TemplateDescriptor("script-editor", ScriptEditorTemplate, NodeGenerator_1.SourceUtility.getSourcePath("/build/", "/src/") + "ScriptEditorTemplate.html", []);
9
+ }
10
+ }
11
+ exports.ScriptEditorTemplate = ScriptEditorTemplate;
@@ -0,0 +1,5 @@
1
+ import { Template, TemplateDescriptor } from "../../NodeConstructor";
2
+ export declare class UIHelperTemplate extends Template {
3
+ static getTemplateDescriptor(): TemplateDescriptor;
4
+ }
5
+ //# sourceMappingURL=UIHelperTemplate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UIHelperTemplate.d.ts","sourceRoot":"","sources":["../../../../src/core/ui/template/UIHelperTemplate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAGpE,qBAAa,gBAAiB,SAAQ,QAAQ;WAE5B,qBAAqB,IAAI,kBAAkB;CAQ5D"}
@@ -0,0 +1,229 @@
1
+
2
+ <div template-section="onIncludeOnce">
3
+
4
+ <style>
5
+ /* ─── PluginCore Dialog overlay ─────────────────────────────────────────── */
6
+
7
+ .plugincore-overlay {
8
+ position: fixed;
9
+ top: 0; left: 0; right: 0; bottom: 0;
10
+ background: rgba(0, 0, 0, 0.5);
11
+ z-index: 2000;
12
+ display: flex;
13
+ align-items: center;
14
+ justify-content: center;
15
+ }
16
+
17
+ .plugincore-dialog {
18
+ background: #fff;
19
+ border: 1px solid #aaa;
20
+ border-radius: 4px;
21
+ box-shadow: 0 6px 24px rgba(0, 0, 0, 0.35);
22
+ min-width: 540px;
23
+ max-width: 85vw;
24
+ max-height: 80vh;
25
+ display: flex;
26
+ flex-direction: column;
27
+ overflow: hidden;
28
+ }
29
+
30
+ /* Title bar — matches Node-RED's main nav bar colour */
31
+ .plugincore-dialog-titlebar {
32
+ display: flex;
33
+ align-items: center;
34
+ background: #3d3d3d;
35
+ color: #fff;
36
+ padding: 6px 8px 6px 12px;
37
+ flex-shrink: 0;
38
+ }
39
+
40
+ .plugincore-dialog-title {
41
+ flex: 1;
42
+ font-weight: 600;
43
+ font-size: 13px;
44
+ }
45
+
46
+ /* Close button — jQuery UI styling as used in Node-RED dialogs */
47
+ .plugincore-dialog-close {
48
+ color: #ccc !important;
49
+ background: transparent !important;
50
+ border-color: transparent !important;
51
+ }
52
+
53
+ .plugincore-dialog-close:hover {
54
+ color: #fff !important;
55
+ background: rgba(255, 255, 255, 0.15) !important;
56
+ border-color: rgba(255, 255, 255, 0.3) !important;
57
+ }
58
+
59
+ /* Scrollable body that contains the jQuery UI tab widget */
60
+ .plugincore-dialog-body {
61
+ flex: 1;
62
+ overflow: auto;
63
+ padding: 10px;
64
+ }
65
+
66
+ /* ─── PluginCore Table ───────────────────────────────────────────────────── */
67
+
68
+ .plugincore-table {
69
+ width: 100%;
70
+ border-collapse: collapse;
71
+ font-size: 12px;
72
+ }
73
+
74
+ .plugincore-table th {
75
+ background: #f3f3f3;
76
+ border: 1px solid #ddd;
77
+ padding: 5px 10px;
78
+ text-align: left;
79
+ font-weight: 600;
80
+ white-space: nowrap;
81
+ }
82
+
83
+ .plugincore-table td {
84
+ border: 1px solid #eee;
85
+ padding: 5px 10px;
86
+ vertical-align: middle;
87
+ }
88
+
89
+ .plugincore-table tbody tr:nth-child(even) td {
90
+ background: #fafafa;
91
+ }
92
+
93
+ .plugincore-table tbody tr:hover td {
94
+ background: #f0f6ff;
95
+ }
96
+
97
+ .plugincore-status-enabled { color: #27ae60; }
98
+ .plugincore-status-disabled { color: #c0392b; }
99
+ </style>
100
+
101
+ <script type="text/javascript">
102
+
103
+ window.PluginCore = window.PluginCore || {};
104
+
105
+ /**
106
+ * PluginCore.table(config) → jQuery <table>
107
+ *
108
+ * config: {
109
+ * columns : [{ key, label, render?(value, row) → string | jQuery }],
110
+ * rows : object[]
111
+ * }
112
+ */
113
+ PluginCore.table = function(config) {
114
+ var $table = $('<table class="plugincore-table">');
115
+
116
+ // Header
117
+ var $thead = $('<thead>');
118
+ var $hr = $('<tr>');
119
+ config.columns.forEach(function(col) {
120
+ $hr.append($('<th>').text(col.label));
121
+ });
122
+ $thead.append($hr);
123
+ $table.append($thead);
124
+
125
+ // Body
126
+ var $tbody = $('<tbody>');
127
+ (config.rows || []).forEach(function(row) {
128
+ var $tr = $('<tr>');
129
+ config.columns.forEach(function(col) {
130
+ var $td = $('<td>');
131
+ var val = row[col.key];
132
+ if (col.render) {
133
+ var rendered = col.render(val, row);
134
+ if (rendered && typeof rendered === 'object' && rendered.jquery) {
135
+ $td.append(rendered);
136
+ } else {
137
+ $td.html(rendered != null ? String(rendered) : '');
138
+ }
139
+ } else {
140
+ $td.text(val != null ? String(val) : '');
141
+ }
142
+ $tr.append($td);
143
+ });
144
+ $tbody.append($tr);
145
+ });
146
+ $table.append($tbody);
147
+
148
+ return $table;
149
+ };
150
+
151
+ /**
152
+ * PluginCore.dialog(options) → { close() }
153
+ *
154
+ * options: {
155
+ * title : string,
156
+ * tabs : [{ label: string, render($container) }]
157
+ * }
158
+ *
159
+ * Uses jQuery UI tabs for the tab widget (already bundled with Node-RED).
160
+ * Closes on: close button click, overlay click, or Escape key.
161
+ */
162
+ PluginCore.dialog = function(options) {
163
+ // Only one dialog at a time
164
+ $('.plugincore-overlay').remove();
165
+
166
+ var uid = 'plugincore-' + Date.now();
167
+
168
+ var $overlay = $('<div class="plugincore-overlay">');
169
+ var $dialog = $('<div class="plugincore-dialog">');
170
+
171
+ // ── Title bar ──────────────────────────────────────────────────────
172
+ var $titlebar = $('<div class="plugincore-dialog-titlebar">');
173
+ $titlebar.append(
174
+ $('<span class="plugincore-dialog-title">').text(options.title || '')
175
+ );
176
+ var $closeBtn = $(
177
+ '<button type="button" class="ui-button ui-corner-all ui-widget plugincore-dialog-close" title="Close">' +
178
+ '<span class="ui-icon ui-icon-closethick"></span></button>'
179
+ );
180
+ $titlebar.append($closeBtn);
181
+
182
+ // ── Body + jQuery UI tabs ──────────────────────────────────────────
183
+ var $body = $('<div class="plugincore-dialog-body">');
184
+ var $tabsEl = $('<div>').attr('id', uid + '-tabs');
185
+ var $ul = $('<ul>');
186
+
187
+ (options.tabs || []).forEach(function(tab, i) {
188
+ var paneId = uid + '-pane-' + i;
189
+ $ul.append(
190
+ $('<li>').append($('<a>').attr('href', '#' + paneId).text(tab.label))
191
+ );
192
+ var $pane = $('<div>').attr('id', paneId);
193
+ if (tab.render) { tab.render($pane); }
194
+ $tabsEl.append($pane);
195
+ });
196
+
197
+ $tabsEl.prepend($ul);
198
+ $body.append($tabsEl);
199
+
200
+ // ── Assemble ───────────────────────────────────────────────────────
201
+ $dialog.append($titlebar).append($body);
202
+ $overlay.append($dialog);
203
+ $('body').append($overlay);
204
+
205
+ // Initialise jQuery UI tabs (bundled with Node-RED)
206
+ $tabsEl.tabs();
207
+
208
+ // ── Close logic ───────────────────────────────────────────────────
209
+ var escNs = 'keydown.plugincore-dialog-' + uid;
210
+
211
+ function close() {
212
+ $overlay.fadeOut(150, function() { $overlay.remove(); });
213
+ $(document).off(escNs);
214
+ }
215
+
216
+ $closeBtn.on('click', close);
217
+ $overlay.on('click', function(e) {
218
+ if ($(e.target).is($overlay)) { close(); }
219
+ });
220
+ $(document).on(escNs, function(e) {
221
+ if (e.key === 'Escape') { close(); }
222
+ });
223
+
224
+ return { close: close };
225
+ };
226
+
227
+ </script>
228
+
229
+ </div>
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UIHelperTemplate = void 0;
4
+ const NodeConstructor_1 = require("../../NodeConstructor");
5
+ const NodeGenerator_1 = require("../../NodeGenerator");
6
+ class UIHelperTemplate extends NodeConstructor_1.Template {
7
+ static getTemplateDescriptor() {
8
+ return new NodeConstructor_1.TemplateDescriptor("ui-helper", UIHelperTemplate, NodeGenerator_1.SourceUtility.getSourcePath("/build/", "/src/") + "UIHelperTemplate.html", []);
9
+ }
10
+ }
11
+ exports.UIHelperTemplate = UIHelperTemplate;
package/build/index.d.ts CHANGED
@@ -17,6 +17,8 @@ export * from "./core/metrics/node/TimerMetricConfigNode";
17
17
  export * from "./core/metrics/template/TimerMetricTemplate";
18
18
  export * from "./core/tagging/service/NodeTypeService";
19
19
  export * from "./core/tagging/NodeDescriptionDecorator";
20
+ export * from "./core/ui/template/UIHelperTemplate";
21
+ export * from "./core/ui/template/ScriptEditorTemplate";
20
22
  export * from "./core/other/node/DelegatedConfigReferenceNode";
21
23
  export * from "./core/other/service/InputService";
22
24
  export * from "./core/other/service/SettingsService";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,qCAAqC,CAAC;AACpD,cAAc,uCAAuC,CAAC;AACtD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,yCAAyC,CAAC;AACxD,cAAc,yCAAyC,CAAC;AAGxD,cAAc,uCAAuC,CAAC;AACtD,cAAc,yCAAyC,CAAC;AACxD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,6CAA6C,CAAC;AAC5D,cAAc,uCAAuC,CAAC;AACtD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,6CAA6C,CAAC;AAG5D,cAAc,wCAAwC,CAAC;AACvD,cAAc,yCAAyC,CAAC;AAGxD,cAAc,gDAAgD,CAAC;AAC/D,cAAc,mCAAmC,CAAC;AAClD,cAAc,sCAAsC,CAAC;AACrD,cAAc,qCAAqC,CAAC;AACpD,cAAc,wCAAwC,CAAC;AAGvD,cAAc,yCAAyC,CAAC;AACxD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,6CAA6C,CAAC;AAG5D,cAAc,gDAAgD,CAAC;AAG/D,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAChD,cAAc,iCAAiC,CAAC;AAChD,cAAc,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,qCAAqC,CAAC;AACpD,cAAc,uCAAuC,CAAC;AACtD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,yCAAyC,CAAC;AACxD,cAAc,yCAAyC,CAAC;AAGxD,cAAc,uCAAuC,CAAC;AACtD,cAAc,yCAAyC,CAAC;AACxD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,6CAA6C,CAAC;AAC5D,cAAc,uCAAuC,CAAC;AACtD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,6CAA6C,CAAC;AAG5D,cAAc,wCAAwC,CAAC;AACvD,cAAc,yCAAyC,CAAC;AAGxD,cAAc,qCAAqC,CAAC;AACpD,cAAc,yCAAyC,CAAC;AAGxD,cAAc,gDAAgD,CAAC;AAC/D,cAAc,mCAAmC,CAAC;AAClD,cAAc,sCAAsC,CAAC;AACrD,cAAc,qCAAqC,CAAC;AACpD,cAAc,wCAAwC,CAAC;AAGvD,cAAc,yCAAyC,CAAC;AACxD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,6CAA6C,CAAC;AAG5D,cAAc,gDAAgD,CAAC;AAG/D,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAChD,cAAc,iCAAiC,CAAC;AAChD,cAAc,6BAA6B,CAAC"}
package/build/index.js CHANGED
@@ -36,6 +36,9 @@ __exportStar(require("./core/metrics/template/TimerMetricTemplate"), exports);
36
36
  // TAGGING
37
37
  __exportStar(require("./core/tagging/service/NodeTypeService"), exports);
38
38
  __exportStar(require("./core/tagging/NodeDescriptionDecorator"), exports);
39
+ // UI
40
+ __exportStar(require("./core/ui/template/UIHelperTemplate"), exports);
41
+ __exportStar(require("./core/ui/template/ScriptEditorTemplate"), exports);
39
42
  // OTHER
40
43
  __exportStar(require("./core/other/node/DelegatedConfigReferenceNode"), exports);
41
44
  __exportStar(require("./core/other/service/InputService"), exports);
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=editorLanguageExtension.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editorLanguageExtension.d.ts","sourceRoot":"","sources":["../../src/resources/editorLanguageExtension.ts"],"names":[],"mappings":""}