@cyprnet/node-red-contrib-uibuilder-formgen 0.5.17 → 0.5.19
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/CHANGELOG.md +11 -0
- package/docs/user-guide.html +57 -4
- package/index.js +1 -0
- package/nodes/uibuilder-formgen-uib2.html +302 -0
- package/nodes/uibuilder-formgen-uib2.js +566 -0
- package/nodes/uibuilder-formgen-v3.html +27 -0
- package/nodes/uibuilder-formgen-v3.js +77 -3
- package/nodes/uibuilder-formgen.html +28 -0
- package/nodes/uibuilder-formgen.js +80 -3
- package/package.json +2 -1
- package/templates/index.html.mustache +72 -18
- package/templates/index.js.mustache +118 -4
- package/templates/index.uib2.html.mustache +643 -0
- package/templates/index.v3.html.mustache +49 -1
- package/templates/index.v3.js.mustache +114 -3
package/CHANGELOG.md
CHANGED
|
@@ -19,6 +19,17 @@ All notable changes to this package will be documented in this file.
|
|
|
19
19
|
- Lookup/Auto-fill (dynamic): improved per-selection requests and pending/timeout handling to make <code>lookup:get</code> reliable.
|
|
20
20
|
- Documentation: expanded <code>schema.lookups</code> formatting guidance and added dynamic lookup examples in Node-RED help + Schema Builder help.
|
|
21
21
|
|
|
22
|
+
## 0.5.19
|
|
23
|
+
|
|
24
|
+
- Legacy node: fixed license resolution for <code>uibuilder-formgen-uib2</code> to match other nodes and clarified the “logo disabled” warning when custom branding is not enabled by the license policy.
|
|
25
|
+
|
|
26
|
+
## 0.5.18
|
|
27
|
+
|
|
28
|
+
- Added <code>uibuilder-formgen-uib2</code> legacy generator for <strong>uibuilder 2.x</strong> (vendor Vue 2 + Bootstrap-Vue v2 stack).
|
|
29
|
+
- Results view: added <strong>Form</strong> mode (single-record navigation) and <strong>Download Record JSON</strong>.
|
|
30
|
+
- Portal UX: added submit/draft spinners with cancel/timeout behavior.
|
|
31
|
+
- Safety: added <strong>Protect portal edits</strong> overwrite protection using file fingerprints stored in <code>portalsmith.runtime.json</code>.
|
|
32
|
+
|
|
22
33
|
## 0.5.17
|
|
23
34
|
|
|
24
35
|
- Results view: portals now also display **generic results** sent via uibuilder (e.g. <code>msg.payload.result</code> or an array payload), not only <code>submit:ok</code>/<code>submit:error</code>.
|
package/docs/user-guide.html
CHANGED
|
@@ -188,7 +188,7 @@
|
|
|
188
188
|
<li>Validation</li>
|
|
189
189
|
<li>Draft save/load</li>
|
|
190
190
|
<li>Export JSON/CSV/HTML</li>
|
|
191
|
-
<li>Submit + Result page (Table/JSON)</li>
|
|
191
|
+
<li>Submit + Result page (Table/JSON/Form)</li>
|
|
192
192
|
</ul>
|
|
193
193
|
</li>
|
|
194
194
|
<li><strong>Industry templates</strong>: ready-to-use example schemas (IT, HR, Banking, Healthcare, Maintenance).</li>
|
|
@@ -245,6 +245,29 @@
|
|
|
245
245
|
<code>../uibuilder/uibuilder.iife.min.js</code>. This confirms that uibuilder v7 is installed
|
|
246
246
|
and serving the client bundle.
|
|
247
247
|
</div>
|
|
248
|
+
|
|
249
|
+
<h3>Legacy node (uibuilder 2.x)</h3>
|
|
250
|
+
<p>
|
|
251
|
+
If you must support older uibuilder installations, use the legacy generator node
|
|
252
|
+
<code>uibuilder-formgen-uib2</code>. This node is additive and does not change the behavior of
|
|
253
|
+
<code>uibuilder-formgen</code> (uibuilder v7 + Vue 2) or <code>uibuilder-formgen-v3</code> (Vue 3 + Bootstrap 5).
|
|
254
|
+
</p>
|
|
255
|
+
|
|
256
|
+
<h3>Legacy versions (uibuilder 2.8 baseline)</h3>
|
|
257
|
+
<ul>
|
|
258
|
+
<li><strong>node-red-contrib-uibuilder:</strong> 2.8.x (target baseline)</li>
|
|
259
|
+
<li><strong>Vue:</strong> 2.x (loaded from uibuilder <code>vendor/</code>)</li>
|
|
260
|
+
<li><strong>Bootstrap:</strong> 4.x (loaded from uibuilder <code>vendor/</code>)</li>
|
|
261
|
+
<li><strong>Bootstrap-Vue:</strong> v2.x (loaded from uibuilder <code>vendor/</code>)</li>
|
|
262
|
+
<li><strong>Browser:</strong> modern Chrome / Firefox / Edge (recommended)</li>
|
|
263
|
+
</ul>
|
|
264
|
+
|
|
265
|
+
<div class="note">
|
|
266
|
+
<strong>uibuilder 2.x sanity check:</strong>
|
|
267
|
+
For portals generated by <code>uibuilder-formgen-uib2</code>, verify that the page successfully loads
|
|
268
|
+
<code>./uibuilderfe.min.js</code> and the uibuilder vendor libraries (e.g. <code>../uibuilder/vendor/vue/...</code>).
|
|
269
|
+
This confirms that uibuilder 2.x is installed and serving the legacy frontend bundle.
|
|
270
|
+
</div>
|
|
248
271
|
</section>
|
|
249
272
|
|
|
250
273
|
<section id="install">
|
|
@@ -674,10 +697,18 @@ return msg;</pre>
|
|
|
674
697
|
</section>
|
|
675
698
|
|
|
676
699
|
<section id="generate">
|
|
677
|
-
<h2>Generating a portal (uibuilder-formgen / uibuilder-formgen-v3)</h2>
|
|
678
|
-
<p>
|
|
700
|
+
<h2>Generating a portal (uibuilder-formgen / uibuilder-formgen-v3 / uibuilder-formgen-uib2)</h2>
|
|
701
|
+
<p>
|
|
702
|
+
You generate portals by sending a schema into one of the generator nodes:
|
|
703
|
+
<code>uibuilder-formgen</code> (Vue 2 + uibuilder v7),
|
|
704
|
+
<code>uibuilder-formgen-v3</code> (Vue 3 + Bootstrap 5),
|
|
705
|
+
or <code>uibuilder-formgen-uib2</code> (legacy uibuilder 2.x vendor stack).
|
|
706
|
+
</p>
|
|
679
707
|
<div class="note ok">
|
|
680
|
-
<strong>Which one should I use?</strong>
|
|
708
|
+
<strong>Which one should I use?</strong>
|
|
709
|
+
Use <code>uibuilder-formgen-v3</code> for new portals (Vue 3 + Bootstrap 5).
|
|
710
|
+
Use <code>uibuilder-formgen</code> only when you need Vue 2 portals on uibuilder v7.
|
|
711
|
+
Use <code>uibuilder-formgen-uib2</code> only when you must support uibuilder 2.x (e.g. 2.8).
|
|
681
712
|
</div>
|
|
682
713
|
<div class="note">
|
|
683
714
|
<strong>How to confirm which runtime generated a portal:</strong> open the generated <code>portalsmith.runtime.json</code> file and check <code>generatorNode</code>.
|
|
@@ -696,6 +727,28 @@ return msg;</pre>
|
|
|
696
727
|
"overwrite": true
|
|
697
728
|
}
|
|
698
729
|
}</pre>
|
|
730
|
+
|
|
731
|
+
<h3>Protecting user customizations (important)</h3>
|
|
732
|
+
<p>
|
|
733
|
+
Regenerating a portal updates the generated <code>src/index.html</code> and <code>src/index.js</code> files to pick up new features.
|
|
734
|
+
If you (or your users) customize those files, accidental overwrites can be costly.
|
|
735
|
+
</p>
|
|
736
|
+
<ul>
|
|
737
|
+
<li>
|
|
738
|
+
<strong>Default behavior:</strong> PortalSmith enables <strong>Protect portal edits</strong> by default.
|
|
739
|
+
If it detects that <code>src/index.html</code> or <code>src/index.js</code> were modified since the last generation,
|
|
740
|
+
it will refuse to overwrite and return an error.
|
|
741
|
+
</li>
|
|
742
|
+
<li>
|
|
743
|
+
<strong>Override (use carefully):</strong> If you have a backup and intentionally want to replace the portal files,
|
|
744
|
+
send <code>msg.options.forceOverwrite=true</code> along with <code>overwrite=true</code>.
|
|
745
|
+
</li>
|
|
746
|
+
</ul>
|
|
747
|
+
<div class="note warn">
|
|
748
|
+
<strong>Recommendation:</strong> If you expect long-lived customizations, keep them in separate files
|
|
749
|
+
(for example, your own <code>custom.css</code> / <code>custom.js</code>) and avoid editing generated files directly.
|
|
750
|
+
This makes upgrades much easier.
|
|
751
|
+
</div>
|
|
699
752
|
</section>
|
|
700
753
|
|
|
701
754
|
<section id="customize">
|
package/index.js
CHANGED
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
<script type="text/javascript">
|
|
2
|
+
RED.nodes.registerType('uibuilder-formgen-uib2', {
|
|
3
|
+
category: 'PortalSmith',
|
|
4
|
+
color: '#E2D96E',
|
|
5
|
+
defaults: {
|
|
6
|
+
name: { value: "" },
|
|
7
|
+
uibuilderUrl: { value: "/uibuilder" },
|
|
8
|
+
instanceName: { value: "formgen-uib2" },
|
|
9
|
+
projectName: { value: "" },
|
|
10
|
+
uibRootDir: { value: "" },
|
|
11
|
+
instanceRootDir: { value: "" },
|
|
12
|
+
themeMode: { value: "auto" },
|
|
13
|
+
logoPath: { value: "" },
|
|
14
|
+
logoAlt: { value: "Logo" },
|
|
15
|
+
logoHeight: { value: 252 },
|
|
16
|
+
logoWidth: { value: 1100 },
|
|
17
|
+
licenseConfig: { value: "", type: "portalsmith-license", required: false },
|
|
18
|
+
submitMode: { value: "uibuilder" },
|
|
19
|
+
submitUrl: { value: "" },
|
|
20
|
+
submitHeadersJson: { value: "" },
|
|
21
|
+
apiUrl: { value: "" },
|
|
22
|
+
apiMethod: { value: "POST" },
|
|
23
|
+
apiHeadersJson: { value: "" },
|
|
24
|
+
apiInsecureTls: { value: false },
|
|
25
|
+
apiTimeoutMs: { value: 15000 },
|
|
26
|
+
overwrite: { value: true },
|
|
27
|
+
protectEdits: { value: true },
|
|
28
|
+
storageMode: { value: "file", validate: function(val) { return val === "file" || val === "localstorage"; } },
|
|
29
|
+
exportFormats: { value: '["json","csv","html"]' }
|
|
30
|
+
},
|
|
31
|
+
credentials: {
|
|
32
|
+
licenseKey: { type: "password" }
|
|
33
|
+
},
|
|
34
|
+
inputs: 1,
|
|
35
|
+
outputs: 1,
|
|
36
|
+
icon: "font-awesome/fa-magic",
|
|
37
|
+
label: function() {
|
|
38
|
+
return this.name || "uibuilder-formgen-uib2";
|
|
39
|
+
},
|
|
40
|
+
oneditprepare: function() {
|
|
41
|
+
var statusEl = $("#ps-license-status");
|
|
42
|
+
var timer = null;
|
|
43
|
+
var overwriteEl = $("#node-input-overwrite");
|
|
44
|
+
var protectEl = $("#node-input-protectEdits");
|
|
45
|
+
|
|
46
|
+
function setStatus(text, cls) {
|
|
47
|
+
statusEl.removeClass("text-success text-warning text-danger text-muted");
|
|
48
|
+
if (cls) statusEl.addClass(cls);
|
|
49
|
+
statusEl.text(text);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function validate() {
|
|
53
|
+
var licenseKey = $("#node-input-licenseKey").val() || "";
|
|
54
|
+
var licenseConfigId = $("#node-input-licenseConfig").val() || "";
|
|
55
|
+
setStatus("Checking...", "text-muted");
|
|
56
|
+
|
|
57
|
+
$.ajax({
|
|
58
|
+
url: "portalsmith/license/validate",
|
|
59
|
+
type: "POST",
|
|
60
|
+
contentType: "application/json",
|
|
61
|
+
data: JSON.stringify({ licenseKey: licenseKey, licenseConfigId: licenseConfigId })
|
|
62
|
+
})
|
|
63
|
+
.done(function(resp) {
|
|
64
|
+
if (!resp || resp.ok !== true) {
|
|
65
|
+
setStatus("Unknown", "text-muted");
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
var keyInfo = "";
|
|
69
|
+
if (resp.verifier && resp.verifier.source) {
|
|
70
|
+
keyInfo = " (key: " + resp.verifier.source + (resp.verifier.fingerprint ? " " + resp.verifier.fingerprint : "") + ")";
|
|
71
|
+
}
|
|
72
|
+
if (resp.licensed) {
|
|
73
|
+
setStatus((resp.displayName || "Licensed") + keyInfo, "text-success");
|
|
74
|
+
} else if (resp.reason && resp.reason !== "missing") {
|
|
75
|
+
setStatus("Invalid/Expired (" + resp.reason + ")" + keyInfo, "text-warning");
|
|
76
|
+
} else {
|
|
77
|
+
setStatus("Free (Watermarked)" + keyInfo, "text-muted");
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
.fail(function() {
|
|
81
|
+
setStatus("Status unavailable (deploy/restart may be needed)", "text-muted");
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function scheduleValidate() {
|
|
86
|
+
if (timer) clearTimeout(timer);
|
|
87
|
+
timer = setTimeout(validate, 250);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
$("#node-input-licenseKey").on("keyup change", scheduleValidate);
|
|
91
|
+
$("#node-input-licenseConfig").on("change", scheduleValidate);
|
|
92
|
+
scheduleValidate();
|
|
93
|
+
|
|
94
|
+
function maybeWarnProtectOff() {
|
|
95
|
+
try {
|
|
96
|
+
var overwriteOn = !!overwriteEl.prop("checked");
|
|
97
|
+
var protectOn = !!protectEl.prop("checked");
|
|
98
|
+
if (overwriteOn && !protectOn) {
|
|
99
|
+
var ok = confirm("Warning: You have disabled 'Protect portal edits' while Overwrite is enabled.\n\nThis can overwrite user-customized index.html/index.js.\n\nAre you sure?");
|
|
100
|
+
if (!ok) {
|
|
101
|
+
protectEl.prop("checked", true);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
} catch (e) { /* ignore */ }
|
|
105
|
+
}
|
|
106
|
+
protectEl.on("change", maybeWarnProtectOff);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
</script>
|
|
110
|
+
|
|
111
|
+
<script type="text/html" data-template-name="uibuilder-formgen-uib2">
|
|
112
|
+
<div class="form-row">
|
|
113
|
+
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
|
114
|
+
<input type="text" id="node-input-name" placeholder="PortalSmith FormGen (uibuilder 2.x legacy)" />
|
|
115
|
+
</div>
|
|
116
|
+
|
|
117
|
+
<div class="form-row">
|
|
118
|
+
<label for="node-input-uibuilderUrl"><i class="fa fa-link"></i> uibuilder base</label>
|
|
119
|
+
<input type="text" id="node-input-uibuilderUrl" placeholder="/uibuilder" />
|
|
120
|
+
</div>
|
|
121
|
+
|
|
122
|
+
<div class="form-row">
|
|
123
|
+
<label for="node-input-instanceName"><i class="fa fa-folder"></i> Instance</label>
|
|
124
|
+
<input type="text" id="node-input-instanceName" placeholder="form-jobapp" />
|
|
125
|
+
</div>
|
|
126
|
+
|
|
127
|
+
<div class="form-row">
|
|
128
|
+
<label for="node-input-projectName"><i class="fa fa-briefcase"></i> Project (optional)</label>
|
|
129
|
+
<input type="text" id="node-input-projectName" placeholder="my-project" />
|
|
130
|
+
</div>
|
|
131
|
+
|
|
132
|
+
<div class="form-row">
|
|
133
|
+
<label for="node-input-uibRootDir"><i class="fa fa-folder-open"></i> uibuilder root dir (optional)</label>
|
|
134
|
+
<input type="text" id="node-input-uibRootDir" placeholder="/opt/node-red-home/projects/my-project/uibuilder" />
|
|
135
|
+
</div>
|
|
136
|
+
|
|
137
|
+
<div class="form-row">
|
|
138
|
+
<label for="node-input-instanceRootDir"><i class="fa fa-map-marker"></i> Instance root dir (optional)</label>
|
|
139
|
+
<input type="text" id="node-input-instanceRootDir" placeholder="/opt/node-red-home/projects/my-project/uibuilder/form-jobapp" />
|
|
140
|
+
</div>
|
|
141
|
+
|
|
142
|
+
<div class="form-row">
|
|
143
|
+
<label for="node-input-themeMode"><i class="fa fa-adjust"></i> Theme</label>
|
|
144
|
+
<select id="node-input-themeMode">
|
|
145
|
+
<option value="auto">Auto (prefers-color-scheme)</option>
|
|
146
|
+
<option value="light">Light</option>
|
|
147
|
+
<option value="dark">Dark</option>
|
|
148
|
+
</select>
|
|
149
|
+
</div>
|
|
150
|
+
|
|
151
|
+
<div class="form-row">
|
|
152
|
+
<label for="node-input-logoPath"><i class="fa fa-image"></i> Logo path (optional)</label>
|
|
153
|
+
<input type="text" id="node-input-logoPath" placeholder="Either /abs/path/to/logo.png OR just logo.png (assumes src/images/)" />
|
|
154
|
+
</div>
|
|
155
|
+
|
|
156
|
+
<div class="form-row">
|
|
157
|
+
<label for="node-input-logoAlt"><i class="fa fa-font"></i> Logo alt text</label>
|
|
158
|
+
<input type="text" id="node-input-logoAlt" placeholder="Logo" />
|
|
159
|
+
</div>
|
|
160
|
+
|
|
161
|
+
<div class="form-row">
|
|
162
|
+
<label for="node-input-logoHeight"><i class="fa fa-arrows-v"></i> Logo height (px)</label>
|
|
163
|
+
<input type="number" id="node-input-logoHeight" min="1" placeholder="252" />
|
|
164
|
+
</div>
|
|
165
|
+
|
|
166
|
+
<div class="form-row">
|
|
167
|
+
<label for="node-input-logoWidth"><i class="fa fa-arrows-h"></i> Logo width (px)</label>
|
|
168
|
+
<input type="number" id="node-input-logoWidth" min="1" placeholder="1100" />
|
|
169
|
+
</div>
|
|
170
|
+
|
|
171
|
+
<hr/>
|
|
172
|
+
<div class="form-row">
|
|
173
|
+
<strong>Licensing (offline-first)</strong>
|
|
174
|
+
</div>
|
|
175
|
+
|
|
176
|
+
<div class="form-row">
|
|
177
|
+
<label for="node-input-licenseConfig"><i class="fa fa-id-card"></i> License (shared config)</label>
|
|
178
|
+
<input type="text" id="node-input-licenseConfig" />
|
|
179
|
+
</div>
|
|
180
|
+
|
|
181
|
+
<div class="form-row">
|
|
182
|
+
<label for="node-input-licenseKey"><i class="fa fa-key"></i> License Key (optional)</label>
|
|
183
|
+
<input type="password" id="node-input-licenseKey" placeholder="PSLF1.<payload>.<signature>" />
|
|
184
|
+
</div>
|
|
185
|
+
|
|
186
|
+
<div class="form-tips">
|
|
187
|
+
This legacy node generates portals compatible with <strong>uibuilder 2.x</strong> (vendor Vue 2 + Bootstrap-Vue v2 + <code>uibuilderfe.min.js</code>). Leave license fields blank to run in <strong>Free (Watermarked)</strong> mode.
|
|
188
|
+
</div>
|
|
189
|
+
|
|
190
|
+
<div class="form-row">
|
|
191
|
+
<label>License Status</label>
|
|
192
|
+
<span id="ps-license-status" class="text-muted">Free (Watermarked)</span>
|
|
193
|
+
</div>
|
|
194
|
+
|
|
195
|
+
<div class="form-row">
|
|
196
|
+
<label for="node-input-overwrite"><i class="fa fa-refresh"></i> Overwrite</label>
|
|
197
|
+
<input type="checkbox" id="node-input-overwrite" />
|
|
198
|
+
</div>
|
|
199
|
+
|
|
200
|
+
<div class="form-row">
|
|
201
|
+
<label for="node-input-protectEdits"><i class="fa fa-shield"></i> Protect portal edits</label>
|
|
202
|
+
<input type="checkbox" id="node-input-protectEdits" />
|
|
203
|
+
</div>
|
|
204
|
+
|
|
205
|
+
<div class="form-tips">
|
|
206
|
+
<strong>Recommended:</strong> Keep <strong>Protect portal edits</strong> enabled. If a user modified <code>src/index.html</code> or <code>src/index.js</code>,
|
|
207
|
+
regeneration will refuse to overwrite to avoid data loss. You can override once by sending <code>msg.options.forceOverwrite=true</code>.
|
|
208
|
+
</div>
|
|
209
|
+
|
|
210
|
+
<div class="form-row">
|
|
211
|
+
<label for="node-input-storageMode"><i class="fa fa-hdd-o"></i> Storage</label>
|
|
212
|
+
<select id="node-input-storageMode">
|
|
213
|
+
<option value="file">File (recommended)</option>
|
|
214
|
+
<option value="localstorage">Browser localStorage</option>
|
|
215
|
+
</select>
|
|
216
|
+
</div>
|
|
217
|
+
|
|
218
|
+
<div class="form-row">
|
|
219
|
+
<label for="node-input-exportFormats"><i class="fa fa-download"></i> Export Formats (JSON array)</label>
|
|
220
|
+
<input type="text" id="node-input-exportFormats" placeholder='["json","csv","html"]' />
|
|
221
|
+
</div>
|
|
222
|
+
|
|
223
|
+
<div class="form-row">
|
|
224
|
+
<label for="node-input-submitMode"><i class="fa fa-paper-plane"></i> Submit mode</label>
|
|
225
|
+
<select id="node-input-submitMode">
|
|
226
|
+
<option value="uibuilder">uibuilder message (default)</option>
|
|
227
|
+
<option value="http">HTTP POST (API / Node-RED http in)</option>
|
|
228
|
+
</select>
|
|
229
|
+
</div>
|
|
230
|
+
|
|
231
|
+
<div class="form-row">
|
|
232
|
+
<label for="node-input-submitUrl"><i class="fa fa-globe"></i> Submit URL (http mode)</label>
|
|
233
|
+
<input type="text" id="node-input-submitUrl" placeholder="e.g. /api/forms/submit or https://api.example.com/submit" />
|
|
234
|
+
</div>
|
|
235
|
+
|
|
236
|
+
<div class="form-row">
|
|
237
|
+
<label for="node-input-submitHeadersJson"><i class="fa fa-code"></i> Submit headers (JSON, optional)</label>
|
|
238
|
+
<input type="text" id="node-input-submitHeadersJson" placeholder='e.g. {"Authorization":"Bearer ...","X-Org":"CyprNet"}' />
|
|
239
|
+
</div>
|
|
240
|
+
|
|
241
|
+
<hr/>
|
|
242
|
+
<div class="form-row">
|
|
243
|
+
<strong>Server-side API proxy (for uibuilder submit)</strong>
|
|
244
|
+
</div>
|
|
245
|
+
|
|
246
|
+
<div class="form-row">
|
|
247
|
+
<label for="node-input-apiUrl"><i class="fa fa-exchange"></i> API URL</label>
|
|
248
|
+
<input type="text" id="node-input-apiUrl" placeholder="https://api.example.com/submit (leave blank to just emit submit msg)" />
|
|
249
|
+
</div>
|
|
250
|
+
|
|
251
|
+
<div class="form-row">
|
|
252
|
+
<label for="node-input-apiMethod"><i class="fa fa-bolt"></i> API method</label>
|
|
253
|
+
<select id="node-input-apiMethod">
|
|
254
|
+
<option value="POST">POST</option>
|
|
255
|
+
<option value="PUT">PUT</option>
|
|
256
|
+
<option value="PATCH">PATCH</option>
|
|
257
|
+
</select>
|
|
258
|
+
</div>
|
|
259
|
+
|
|
260
|
+
<div class="form-row">
|
|
261
|
+
<label for="node-input-apiHeadersJson"><i class="fa fa-code"></i> API headers (JSON, optional)</label>
|
|
262
|
+
<input type="text" id="node-input-apiHeadersJson" placeholder='e.g. {"Authorization":"Bearer ..."}' />
|
|
263
|
+
</div>
|
|
264
|
+
|
|
265
|
+
<div class="form-row">
|
|
266
|
+
<label for="node-input-apiInsecureTls"><i class="fa fa-shield"></i> Allow insecure TLS (self-signed)</label>
|
|
267
|
+
<input type="checkbox" id="node-input-apiInsecureTls" />
|
|
268
|
+
</div>
|
|
269
|
+
|
|
270
|
+
<div class="form-row">
|
|
271
|
+
<label for="node-input-apiTimeoutMs"><i class="fa fa-clock-o"></i> API timeout (ms)</label>
|
|
272
|
+
<input type="number" id="node-input-apiTimeoutMs" min="1000" step="500" placeholder="15000" />
|
|
273
|
+
</div>
|
|
274
|
+
|
|
275
|
+
<div class="form-tips">
|
|
276
|
+
Input: <code>msg.schema</code> (required), optional <code>msg.uibuilder</code>, <code>msg.options</code><br/>
|
|
277
|
+
Output: generated file list + URL
|
|
278
|
+
</div>
|
|
279
|
+
</script>
|
|
280
|
+
|
|
281
|
+
<script type="text/markdown" data-help-name="uibuilder-formgen-uib2">
|
|
282
|
+
Generates a uibuilder instance (`src/index.html`, `src/index.js`, `src/form.schema.json`) from `msg.schema`.
|
|
283
|
+
|
|
284
|
+
This is a **legacy generator** intended for users running **uibuilder 2.x**.
|
|
285
|
+
It generates a portal that loads the uibuilder 2.x vendor stack (Socket.IO + Vue 2 + Bootstrap-Vue v2) and uses `uibuilderfe.min.js`.
|
|
286
|
+
|
|
287
|
+
**Schema compatibility**
|
|
288
|
+
- Uses the **same PortalSmith schema** as the main nodes and is compatible with the Schema Builder output.
|
|
289
|
+
|
|
290
|
+
**Licensing**
|
|
291
|
+
- Free mode is fully functional but **watermarked** and **custom branding/logo is disabled**.
|
|
292
|
+
- Licensing is **offline-first** (no phone-home). Keys are stored in the Node-RED credentials store.
|
|
293
|
+
|
|
294
|
+
**Paths**
|
|
295
|
+
- Default: `${userDir}/uibuilder/<instance>/src/`
|
|
296
|
+
- Optional overrides (highest priority first): `instanceRootDir`, `uibRootDir`, `projectName`.
|
|
297
|
+
|
|
298
|
+
**Note**
|
|
299
|
+
- This node does not change the behavior of `uibuilder-formgen` (Vue 2 + uibuilder v7) or `uibuilder-formgen-v3` (Vue 3 + Bootstrap 5).
|
|
300
|
+
</script>
|
|
301
|
+
|
|
302
|
+
|