@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.
- package/README.md +153 -7
- package/build/GenerateNodes.js +2 -0
- package/build/core/ui/template/ScriptEditorTemplate.d.ts +5 -0
- package/build/core/ui/template/ScriptEditorTemplate.d.ts.map +1 -0
- package/build/core/ui/template/ScriptEditorTemplate.html +50 -0
- package/build/core/ui/template/ScriptEditorTemplate.js +11 -0
- package/build/core/ui/template/UIHelperTemplate.d.ts +5 -0
- package/build/core/ui/template/UIHelperTemplate.d.ts.map +1 -0
- package/build/core/ui/template/UIHelperTemplate.html +229 -0
- package/build/core/ui/template/UIHelperTemplate.js +11 -0
- package/build/index.d.ts +2 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +3 -0
- package/build/resources/editorLanguageExtension.d.ts +1 -0
- package/build/resources/editorLanguageExtension.d.ts.map +1 -0
- package/build/resources/editorLanguageExtension.js +1189 -0
- package/documentation/ConsoleLoggerConfigNode.png +0 -0
- package/documentation/LokiLoggerConfigNode.png +0 -0
- package/documentation/RestLoggerConfigNode.png +0 -0
- package/package.json +21 -9
- package/resources/editorLanguageExtension.d.ts +1 -0
- package/resources/editorLanguageExtension.d.ts.map +1 -0
- package/resources/editorLanguageExtension.js +1189 -0
- package/src/GenerateNodes.ts +3 -1
- package/src/core/ui/template/ScriptEditorTemplate.html +50 -0
- package/src/core/ui/template/ScriptEditorTemplate.ts +14 -0
- package/src/core/ui/template/UIHelperTemplate.html +229 -0
- package/src/core/ui/template/UIHelperTemplate.ts +14 -0
- package/src/index.ts +4 -0
- package/src/resources/editorLanguageExtension.ts +1281 -0
package/src/GenerateNodes.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
import { DelegatedConfigReferenceNode } from "./core/other/node/DelegatedConfigReferenceNode.js";
|
|
3
3
|
import { NodeTypeService } from "./core/tagging/service/NodeTypeService.js";
|
|
4
|
-
import { NodeGenerator, SettingsService, BasicTemplate, SettingsTemplate, TimerMetricTemplate, ConsoleLoggerConfigNode, RestLoggerConfigNode, LokiLoggerConfigNode } from "./index.js"
|
|
4
|
+
import { NodeGenerator, SettingsService, BasicTemplate, SettingsTemplate, TimerMetricTemplate, ConsoleLoggerConfigNode, RestLoggerConfigNode, LokiLoggerConfigNode, UIHelperTemplate, ScriptEditorTemplate } from "./index.js"
|
|
5
5
|
import { WebhookServerConfigNode, WebhookServerService, WebhookTemplate, } from "./index.js"
|
|
6
6
|
|
|
7
7
|
import {LoggerService, LoggerTemplate } from "./index.js";
|
|
@@ -26,6 +26,8 @@ new NodeGenerator("./src/core/")
|
|
|
26
26
|
.registerTemplate(GaugeMetricTemplate)
|
|
27
27
|
.registerTemplate(TimerMetricTemplate)
|
|
28
28
|
.registerTemplate(WebhookTemplate)
|
|
29
|
+
.registerTemplate(UIHelperTemplate)
|
|
30
|
+
.registerTemplate(ScriptEditorTemplate)
|
|
29
31
|
|
|
30
32
|
// nodes
|
|
31
33
|
.registerNode(DelegatedConfigReferenceNode)
|
|
@@ -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,14 @@
|
|
|
1
|
+
import { Template, TemplateDescriptor } from "../../NodeConstructor"
|
|
2
|
+
import { SourceUtility } from "../../NodeGenerator";
|
|
3
|
+
|
|
4
|
+
export class ScriptEditorTemplate extends Template {
|
|
5
|
+
|
|
6
|
+
public static getTemplateDescriptor(): TemplateDescriptor {
|
|
7
|
+
return new TemplateDescriptor(
|
|
8
|
+
"script-editor",
|
|
9
|
+
ScriptEditorTemplate,
|
|
10
|
+
SourceUtility.getSourcePath("/build/", "/src/") + "ScriptEditorTemplate.html",
|
|
11
|
+
[]
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -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,14 @@
|
|
|
1
|
+
import { Template, TemplateDescriptor } from "../../NodeConstructor"
|
|
2
|
+
import { SourceUtility } from "../../NodeGenerator";
|
|
3
|
+
|
|
4
|
+
export class UIHelperTemplate extends Template {
|
|
5
|
+
|
|
6
|
+
public static getTemplateDescriptor(): TemplateDescriptor {
|
|
7
|
+
return new TemplateDescriptor(
|
|
8
|
+
"ui-helper",
|
|
9
|
+
UIHelperTemplate,
|
|
10
|
+
SourceUtility.getSourcePath("/build/", "/src/") + "UIHelperTemplate.html",
|
|
11
|
+
[]
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -24,6 +24,10 @@ export * from "./core/metrics/template/TimerMetricTemplate";
|
|
|
24
24
|
export * from "./core/tagging/service/NodeTypeService";
|
|
25
25
|
export * from "./core/tagging/NodeDescriptionDecorator";
|
|
26
26
|
|
|
27
|
+
// UI
|
|
28
|
+
export * from "./core/ui/template/UIHelperTemplate";
|
|
29
|
+
export * from "./core/ui/template/ScriptEditorTemplate";
|
|
30
|
+
|
|
27
31
|
// OTHER
|
|
28
32
|
export * from "./core/other/node/DelegatedConfigReferenceNode";
|
|
29
33
|
export * from "./core/other/service/InputService";
|