@cyprnet/node-red-contrib-uibuilder-formgen 0.4.11

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 (52) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/LICENSE +22 -0
  3. package/README.md +58 -0
  4. package/docs/user-guide.html +565 -0
  5. package/examples/formgen-builder/src/index.html +921 -0
  6. package/examples/formgen-builder/src/index.js +1338 -0
  7. package/examples/portalsmith-formgen-example.json +531 -0
  8. package/examples/schema-builder-integration.json +109 -0
  9. package/examples/schemas/Banking/banking_fraud_report.json +102 -0
  10. package/examples/schemas/Banking/banking_kyc_update.json +59 -0
  11. package/examples/schemas/Banking/banking_loan_application.json +113 -0
  12. package/examples/schemas/Banking/banking_new_account.json +98 -0
  13. package/examples/schemas/Banking/banking_wire_transfer_request.json +94 -0
  14. package/examples/schemas/HR/hr_employee_change_form.json +65 -0
  15. package/examples/schemas/HR/hr_exit_interview.json +105 -0
  16. package/examples/schemas/HR/hr_job_application.json +166 -0
  17. package/examples/schemas/HR/hr_onboarding_request.json +140 -0
  18. package/examples/schemas/HR/hr_time_off_request.json +95 -0
  19. package/examples/schemas/HR/hr_training_request.json +70 -0
  20. package/examples/schemas/Healthcare/health_appointment_request.json +103 -0
  21. package/examples/schemas/Healthcare/health_incident_report.json +82 -0
  22. package/examples/schemas/Healthcare/health_lab_order_request.json +72 -0
  23. package/examples/schemas/Healthcare/health_medication_refill.json +72 -0
  24. package/examples/schemas/Healthcare/health_patient_intake.json +113 -0
  25. package/examples/schemas/IT/it_access_request.json +145 -0
  26. package/examples/schemas/IT/it_dhcp_reservation.json +175 -0
  27. package/examples/schemas/IT/it_dns_domain_external.json +192 -0
  28. package/examples/schemas/IT/it_dns_domain_internal.json +171 -0
  29. package/examples/schemas/IT/it_network_change_request.json +126 -0
  30. package/examples/schemas/IT/it_network_request-form.json +299 -0
  31. package/examples/schemas/IT/it_new_hardware_request.json +155 -0
  32. package/examples/schemas/IT/it_password_reset.json +133 -0
  33. package/examples/schemas/IT/it_software_license_request.json +93 -0
  34. package/examples/schemas/IT/it_static_ip_request.json +199 -0
  35. package/examples/schemas/IT/it_subnet_request_form.json +216 -0
  36. package/examples/schemas/Maintenance/maint_checklist.json +176 -0
  37. package/examples/schemas/Maintenance/maint_facility_issue_report.json +127 -0
  38. package/examples/schemas/Maintenance/maint_incident_intake.json +174 -0
  39. package/examples/schemas/Maintenance/maint_inventory_restock.json +79 -0
  40. package/examples/schemas/Maintenance/maint_safety_audit.json +92 -0
  41. package/examples/schemas/Maintenance/maint_vehicle_inspection.json +112 -0
  42. package/examples/schemas/Maintenance/maint_work_order.json +134 -0
  43. package/index.js +12 -0
  44. package/lib/licensing.js +254 -0
  45. package/nodes/portalsmith-license.html +40 -0
  46. package/nodes/portalsmith-license.js +23 -0
  47. package/nodes/uibuilder-formgen.html +261 -0
  48. package/nodes/uibuilder-formgen.js +598 -0
  49. package/package.json +47 -0
  50. package/scripts/normalize_schema_titles.py +77 -0
  51. package/templates/index.html.mustache +541 -0
  52. package/templates/index.js.mustache +1135 -0
@@ -0,0 +1,261 @@
1
+ <script type="text/javascript">
2
+ RED.nodes.registerType('uibuilder-formgen', {
3
+ category: 'PortalSmith',
4
+ color: '#E2D96E',
5
+ defaults: {
6
+ name: { value: "" },
7
+ uibuilderUrl: { value: "/uibuilder" },
8
+ instanceName: { value: "formgen" },
9
+ projectName: { value: "" },
10
+ uibRootDir: { value: "" },
11
+ instanceRootDir: { value: "" },
12
+ themeMode: { value: "auto" },
13
+ logoPath: { value: "" },
14
+ logoAlt: { value: "Logo" },
15
+ licenseConfig: { value: "", type: "portalsmith-license", required: false },
16
+ submitMode: { value: "uibuilder" },
17
+ submitUrl: { value: "" },
18
+ submitHeadersJson: { value: "" },
19
+ apiUrl: { value: "" },
20
+ apiMethod: { value: "POST" },
21
+ apiHeadersJson: { value: "" },
22
+ apiInsecureTls: { value: false },
23
+ apiTimeoutMs: { value: 15000 },
24
+ overwrite: { value: true },
25
+ storageMode: { value: "file", validate: function(val) { return val === "file" || val === "localstorage"; } },
26
+ exportFormats: { value: '["json","csv","html"]' }
27
+ },
28
+ credentials: {
29
+ licenseKey: { type: "password" }
30
+ },
31
+ inputs: 1,
32
+ outputs: 1,
33
+ icon: "font-awesome/fa-magic",
34
+ label: function() {
35
+ return this.name || "uibuilder-formgen";
36
+ },
37
+ oneditprepare: function() {
38
+ var statusEl = $("#ps-license-status");
39
+ var timer = null;
40
+
41
+ function setStatus(text, cls) {
42
+ statusEl.removeClass("text-success text-warning text-danger text-muted");
43
+ if (cls) statusEl.addClass(cls);
44
+ statusEl.text(text);
45
+ }
46
+
47
+ function validate() {
48
+ var licenseKey = $("#node-input-licenseKey").val() || "";
49
+ var licenseConfigId = $("#node-input-licenseConfig").val() || "";
50
+ setStatus("Checking...", "text-muted");
51
+
52
+ $.ajax({
53
+ url: "portalsmith/license/validate",
54
+ type: "POST",
55
+ contentType: "application/json",
56
+ data: JSON.stringify({ licenseKey: licenseKey, licenseConfigId: licenseConfigId })
57
+ })
58
+ .done(function(resp) {
59
+ if (!resp || resp.ok !== true) {
60
+ setStatus("Unknown", "text-muted");
61
+ return;
62
+ }
63
+ var keyInfo = "";
64
+ if (resp.verifier && resp.verifier.source) {
65
+ keyInfo = " (key: " + resp.verifier.source + (resp.verifier.fingerprint ? " " + resp.verifier.fingerprint : "") + ")";
66
+ }
67
+ if (resp.licensed) {
68
+ setStatus((resp.displayName || "Licensed") + keyInfo, "text-success");
69
+ } else if (resp.reason && resp.reason !== "missing") {
70
+ setStatus("Invalid/Expired (" + resp.reason + ")" + keyInfo, "text-warning");
71
+ } else {
72
+ setStatus("Free (Watermarked)" + keyInfo, "text-muted");
73
+ }
74
+ })
75
+ .fail(function() {
76
+ setStatus("Status unavailable (deploy/restart may be needed)", "text-muted");
77
+ });
78
+ }
79
+
80
+ function scheduleValidate() {
81
+ if (timer) clearTimeout(timer);
82
+ timer = setTimeout(validate, 250);
83
+ }
84
+
85
+ $("#node-input-licenseKey").on("keyup change", scheduleValidate);
86
+ $("#node-input-licenseConfig").on("change", scheduleValidate);
87
+ scheduleValidate();
88
+ }
89
+ });
90
+ </script>
91
+
92
+ <script type="text/html" data-template-name="uibuilder-formgen">
93
+ <div class="form-row">
94
+ <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
95
+ <input type="text" id="node-input-name" placeholder="PortalSmith FormGen" />
96
+ </div>
97
+
98
+ <div class="form-row">
99
+ <label for="node-input-uibuilderUrl"><i class="fa fa-link"></i> uibuilder base</label>
100
+ <input type="text" id="node-input-uibuilderUrl" placeholder="/uibuilder" />
101
+ </div>
102
+
103
+ <div class="form-row">
104
+ <label for="node-input-instanceName"><i class="fa fa-folder"></i> Instance</label>
105
+ <input type="text" id="node-input-instanceName" placeholder="form-jobapp" />
106
+ </div>
107
+
108
+ <div class="form-row">
109
+ <label for="node-input-projectName"><i class="fa fa-briefcase"></i> Project (optional)</label>
110
+ <input type="text" id="node-input-projectName" placeholder="my-project" />
111
+ </div>
112
+
113
+ <div class="form-row">
114
+ <label for="node-input-uibRootDir"><i class="fa fa-folder-open"></i> uibuilder root dir (optional)</label>
115
+ <input type="text" id="node-input-uibRootDir" placeholder="/opt/node-red-home/projects/my-project/uibuilder" />
116
+ </div>
117
+
118
+ <div class="form-row">
119
+ <label for="node-input-instanceRootDir"><i class="fa fa-map-marker"></i> Instance root dir (optional)</label>
120
+ <input type="text" id="node-input-instanceRootDir" placeholder="/opt/node-red-home/projects/my-project/uibuilder/form-jobapp" />
121
+ </div>
122
+
123
+ <div class="form-row">
124
+ <label for="node-input-themeMode"><i class="fa fa-adjust"></i> Theme</label>
125
+ <select id="node-input-themeMode">
126
+ <option value="auto">Auto (prefers-color-scheme)</option>
127
+ <option value="light">Light</option>
128
+ <option value="dark">Dark</option>
129
+ </select>
130
+ </div>
131
+
132
+ <div class="form-row">
133
+ <label for="node-input-logoPath"><i class="fa fa-image"></i> Logo path (optional)</label>
134
+ <input type="text" id="node-input-logoPath" placeholder="Either /abs/path/to/logo.png OR just logo.png (assumes src/images/)" />
135
+ </div>
136
+
137
+ <div class="form-row">
138
+ <label for="node-input-logoAlt"><i class="fa fa-font"></i> Logo alt text</label>
139
+ <input type="text" id="node-input-logoAlt" placeholder="Logo" />
140
+ </div>
141
+
142
+ <hr/>
143
+ <div class="form-row">
144
+ <strong>Licensing (offline-first)</strong>
145
+ </div>
146
+
147
+ <div class="form-row">
148
+ <label for="node-input-licenseConfig"><i class="fa fa-id-card"></i> License (shared config)</label>
149
+ <input type="text" id="node-input-licenseConfig" />
150
+ </div>
151
+
152
+ <div class="form-row">
153
+ <label for="node-input-licenseKey"><i class="fa fa-key"></i> License Key (optional)</label>
154
+ <input type="password" id="node-input-licenseKey" placeholder="PSLF1.<payload>.<signature>" />
155
+ </div>
156
+
157
+ <div class="form-tips">
158
+ Leave license fields blank to run in <strong>Free (Watermarked)</strong> mode. For PRO, paste the <code>PSLF1...</code> license string (provided by PortalSmith/CyprNet).
159
+ </div>
160
+
161
+ <div class="form-row">
162
+ <label>License Status</label>
163
+ <span id="ps-license-status" class="text-muted">Free (Watermarked)</span>
164
+ </div>
165
+
166
+ <div class="form-row">
167
+ <label for="node-input-overwrite"><i class="fa fa-refresh"></i> Overwrite</label>
168
+ <input type="checkbox" id="node-input-overwrite" />
169
+ </div>
170
+
171
+ <div class="form-row">
172
+ <label for="node-input-storageMode"><i class="fa fa-hdd-o"></i> Storage</label>
173
+ <select id="node-input-storageMode">
174
+ <option value="file">File (recommended)</option>
175
+ <option value="localstorage">Browser localStorage</option>
176
+ </select>
177
+ </div>
178
+
179
+ <div class="form-row">
180
+ <label for="node-input-exportFormats"><i class="fa fa-download"></i> Export Formats (JSON array)</label>
181
+ <input type="text" id="node-input-exportFormats" placeholder='["json","csv","html"]' />
182
+ </div>
183
+
184
+ <div class="form-row">
185
+ <label for="node-input-submitMode"><i class="fa fa-paper-plane"></i> Submit mode</label>
186
+ <select id="node-input-submitMode">
187
+ <option value="uibuilder">uibuilder message (default)</option>
188
+ <option value="http">HTTP POST (API / Node-RED http in)</option>
189
+ </select>
190
+ </div>
191
+
192
+ <div class="form-row">
193
+ <label for="node-input-submitUrl"><i class="fa fa-globe"></i> Submit URL (http mode)</label>
194
+ <input type="text" id="node-input-submitUrl" placeholder="e.g. /api/forms/submit or https://api.example.com/submit" />
195
+ </div>
196
+
197
+ <div class="form-row">
198
+ <label for="node-input-submitHeadersJson"><i class="fa fa-code"></i> Submit headers (JSON, optional)</label>
199
+ <input type="text" id="node-input-submitHeadersJson" placeholder='e.g. {"Authorization":"Bearer ...","X-Org":"CyprNet"}' />
200
+ </div>
201
+
202
+ <hr/>
203
+ <div class="form-row">
204
+ <strong>Server-side API proxy (for uibuilder submit)</strong>
205
+ </div>
206
+
207
+ <div class="form-row">
208
+ <label for="node-input-apiUrl"><i class="fa fa-exchange"></i> API URL</label>
209
+ <input type="text" id="node-input-apiUrl" placeholder="https://api.example.com/submit (leave blank to just emit submit msg)" />
210
+ </div>
211
+
212
+ <div class="form-row">
213
+ <label for="node-input-apiMethod"><i class="fa fa-bolt"></i> API method</label>
214
+ <select id="node-input-apiMethod">
215
+ <option value="POST">POST</option>
216
+ <option value="PUT">PUT</option>
217
+ <option value="PATCH">PATCH</option>
218
+ </select>
219
+ </div>
220
+
221
+ <div class="form-row">
222
+ <label for="node-input-apiHeadersJson"><i class="fa fa-code"></i> API headers (JSON, optional)</label>
223
+ <input type="text" id="node-input-apiHeadersJson" placeholder='e.g. {"Authorization":"Bearer ..."}' />
224
+ </div>
225
+
226
+ <div class="form-row">
227
+ <label for="node-input-apiInsecureTls"><i class="fa fa-shield"></i> Allow insecure TLS (self-signed)</label>
228
+ <input type="checkbox" id="node-input-apiInsecureTls" />
229
+ </div>
230
+
231
+ <div class="form-row">
232
+ <label for="node-input-apiTimeoutMs"><i class="fa fa-clock-o"></i> API timeout (ms)</label>
233
+ <input type="number" id="node-input-apiTimeoutMs" min="1000" step="500" placeholder="15000" />
234
+ </div>
235
+
236
+ <div class="form-tips">
237
+ Input: <code>msg.schema</code> (required), optional <code>msg.uibuilder</code>, <code>msg.options</code><br/>
238
+ Output: generated file list + URL
239
+ </div>
240
+ </script>
241
+
242
+ <script type="text/markdown" data-help-name="uibuilder-formgen">
243
+ Generates a uibuilder instance (`src/index.html`, `src/index.js`, `src/form.schema.json`) from `msg.schema`.
244
+
245
+ **Licensing**
246
+ - Free mode is fully functional but **watermarked** and **custom branding/logo is disabled**.
247
+ - Licensing is **offline-first** (no phone-home). Keys are stored in the Node-RED credentials store.
248
+
249
+ **Industry templates**
250
+ - This node ships with ready-to-use schema templates under `examples/schemas/`:
251
+ - `examples/schemas/IT/`
252
+ - `examples/schemas/Maintenance/`
253
+ - `examples/schemas/HR/`
254
+ - `examples/schemas/Banking/`
255
+ - `examples/schemas/Healthcare/`
256
+ - You can copy any of those JSON files into an Inject node as `msg.schema`, then click Inject to generate a portal.
257
+
258
+ **Paths**
259
+ - Default: `${userDir}/uibuilder/<instance>/src/`
260
+ - Optional overrides (highest priority first): `instanceRootDir`, `uibRootDir`, `projectName` (see README for details).
261
+ </script>