ultravisor 1.0.2 → 1.0.4

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 (121) hide show
  1. package/.claude/launch.json +11 -0
  2. package/.claude/ultravisor-dev-config.json +3 -0
  3. package/.ultravisor.json +426 -0
  4. package/docs/README.md +63 -0
  5. package/package.json +12 -8
  6. package/source/Ultravisor.cjs +22 -3
  7. package/source/cli/Ultravisor-CLIProgram.cjs +35 -23
  8. package/source/cli/commands/Ultravisor-Command-SingleOperation.cjs +29 -18
  9. package/source/cli/commands/Ultravisor-Command-SingleTask.cjs +62 -19
  10. package/source/cli/commands/Ultravisor-Command-UpdateTask.cjs +27 -15
  11. package/source/config/Ultravisor-Default-Command-Configuration.cjs +5 -3
  12. package/source/services/Ultravisor-ExecutionEngine.cjs +1039 -0
  13. package/source/services/Ultravisor-ExecutionManifest.cjs +399 -0
  14. package/source/services/Ultravisor-Hypervisor-State.cjs +270 -97
  15. package/source/services/Ultravisor-Hypervisor.cjs +38 -83
  16. package/source/services/Ultravisor-StateManager.cjs +241 -0
  17. package/source/services/Ultravisor-TaskTypeRegistry.cjs +143 -0
  18. package/source/services/tasks/Ultravisor-TaskType-Base.cjs +105 -0
  19. package/source/services/tasks/control/Ultravisor-TaskType-IfConditional.cjs +148 -0
  20. package/source/services/tasks/control/Ultravisor-TaskType-LaunchOperation.cjs +187 -0
  21. package/source/services/tasks/control/Ultravisor-TaskType-SplitExecute.cjs +184 -0
  22. package/source/services/tasks/data/Ultravisor-TaskType-ReplaceString.cjs +82 -0
  23. package/source/services/tasks/data/Ultravisor-TaskType-SetValues.cjs +81 -0
  24. package/source/services/tasks/data/Ultravisor-TaskType-StringAppender.cjs +101 -0
  25. package/source/services/tasks/file-io/Ultravisor-TaskType-ReadFile.cjs +103 -0
  26. package/source/services/tasks/file-io/Ultravisor-TaskType-WriteFile.cjs +117 -0
  27. package/source/services/tasks/interaction/Ultravisor-TaskType-ErrorMessage.cjs +54 -0
  28. package/source/services/tasks/interaction/Ultravisor-TaskType-ValueInput.cjs +62 -0
  29. package/source/web_server/Ultravisor-API-Server.cjs +237 -124
  30. package/test/Ultravisor_browser_tests.js +2226 -0
  31. package/test/Ultravisor_tests.js +1143 -5830
  32. package/webinterface/css/ultravisor.css +23 -0
  33. package/webinterface/package.json +6 -3
  34. package/webinterface/source/Pict-Application-Ultravisor.js +93 -73
  35. package/webinterface/source/cards/FlowCard-CSVTransform.js +43 -0
  36. package/webinterface/source/cards/FlowCard-Command.js +86 -0
  37. package/webinterface/source/cards/FlowCard-ComprehensionIntersect.js +40 -0
  38. package/webinterface/source/cards/FlowCard-Conditional.js +87 -0
  39. package/webinterface/source/cards/FlowCard-CopyFile.js +55 -0
  40. package/webinterface/source/cards/FlowCard-End.js +29 -0
  41. package/webinterface/source/cards/FlowCard-GetJSON.js +55 -0
  42. package/webinterface/source/cards/FlowCard-GetText.js +54 -0
  43. package/webinterface/source/cards/FlowCard-Histogram.js +176 -0
  44. package/webinterface/source/cards/FlowCard-LaunchOperation.js +82 -0
  45. package/webinterface/source/cards/FlowCard-ListFiles.js +55 -0
  46. package/webinterface/source/cards/FlowCard-MeadowCount.js +44 -0
  47. package/webinterface/source/cards/FlowCard-MeadowCreate.js +44 -0
  48. package/webinterface/source/cards/FlowCard-MeadowDelete.js +45 -0
  49. package/webinterface/source/cards/FlowCard-MeadowRead.js +46 -0
  50. package/webinterface/source/cards/FlowCard-MeadowReads.js +46 -0
  51. package/webinterface/source/cards/FlowCard-MeadowUpdate.js +44 -0
  52. package/webinterface/source/cards/FlowCard-ParseCSV.js +85 -0
  53. package/webinterface/source/cards/FlowCard-ReadJSON.js +54 -0
  54. package/webinterface/source/cards/FlowCard-ReadText.js +54 -0
  55. package/webinterface/source/cards/FlowCard-RestRequest.js +59 -0
  56. package/webinterface/source/cards/FlowCard-SendJSON.js +57 -0
  57. package/webinterface/source/cards/FlowCard-Solver.js +77 -0
  58. package/webinterface/source/cards/FlowCard-Start.js +29 -0
  59. package/webinterface/source/cards/FlowCard-TemplateString.js +77 -0
  60. package/webinterface/source/cards/FlowCard-WriteJSON.js +54 -0
  61. package/webinterface/source/cards/FlowCard-WriteText.js +54 -0
  62. package/webinterface/source/data/ExampleFlow-CSVPipeline.js +231 -0
  63. package/webinterface/source/data/ExampleFlow-FileProcessor.js +315 -0
  64. package/webinterface/source/data/ExampleFlow-MeadowPipeline.js +328 -0
  65. package/webinterface/source/providers/PictRouter-Ultravisor-Configuration.json +8 -8
  66. package/webinterface/source/views/PictView-Ultravisor-Dashboard.js +6 -6
  67. package/webinterface/source/views/PictView-Ultravisor-FlowEditor.js +436 -0
  68. package/webinterface/source/views/PictView-Ultravisor-ManifestList.js +45 -43
  69. package/webinterface/source/views/PictView-Ultravisor-OperationEdit.js +34 -89
  70. package/webinterface/source/views/PictView-Ultravisor-OperationList.js +128 -13
  71. package/webinterface/source/views/PictView-Ultravisor-PendingInput.js +314 -0
  72. package/webinterface/source/views/PictView-Ultravisor-Schedule.js +18 -53
  73. package/webinterface/source/views/PictView-Ultravisor-TimingView.js +27 -14
  74. package/webinterface/source/views/PictView-Ultravisor-TopBar.js +2 -1
  75. package/.babelrc +0 -6
  76. package/.browserslistrc +0 -1
  77. package/.browserslistrc-BACKUP +0 -1
  78. package/.gulpfile-quackage-config.json +0 -7
  79. package/.gulpfile-quackage.js +0 -2
  80. package/debug/Harness.js +0 -5
  81. package/source/services/Ultravisor-Operation-Manifest.cjs +0 -160
  82. package/source/services/Ultravisor-Operation.cjs +0 -200
  83. package/source/services/Ultravisor-Task.cjs +0 -349
  84. package/source/services/events/Ultravisor-Hypervisor-Event-Solver.cjs +0 -11
  85. package/source/services/tasks/Ultravisor-Task-Base.cjs +0 -264
  86. package/source/services/tasks/Ultravisor-Task-CollectValues.cjs +0 -188
  87. package/source/services/tasks/Ultravisor-Task-Command.cjs +0 -65
  88. package/source/services/tasks/Ultravisor-Task-CommandEach.cjs +0 -190
  89. package/source/services/tasks/Ultravisor-Task-Conditional.cjs +0 -104
  90. package/source/services/tasks/Ultravisor-Task-DateWindow.cjs +0 -72
  91. package/source/services/tasks/Ultravisor-Task-GeneratePagedOperation.cjs +0 -336
  92. package/source/services/tasks/Ultravisor-Task-LaunchOperation.cjs +0 -143
  93. package/source/services/tasks/Ultravisor-Task-LaunchTask.cjs +0 -146
  94. package/source/services/tasks/Ultravisor-Task-LineMatch.cjs +0 -158
  95. package/source/services/tasks/Ultravisor-Task-Request.cjs +0 -56
  96. package/source/services/tasks/Ultravisor-Task-Solver.cjs +0 -89
  97. package/source/services/tasks/Ultravisor-Task-TemplateString.cjs +0 -93
  98. package/source/services/tasks/rest/Ultravisor-Task-GetBinary.cjs +0 -127
  99. package/source/services/tasks/rest/Ultravisor-Task-GetJSON.cjs +0 -119
  100. package/source/services/tasks/rest/Ultravisor-Task-GetText.cjs +0 -109
  101. package/source/services/tasks/rest/Ultravisor-Task-GetXML.cjs +0 -112
  102. package/source/services/tasks/rest/Ultravisor-Task-RestRequest.cjs +0 -499
  103. package/source/services/tasks/rest/Ultravisor-Task-SendJSON.cjs +0 -150
  104. package/source/services/tasks/stagingfiles/Ultravisor-Task-CopyFile.cjs +0 -110
  105. package/source/services/tasks/stagingfiles/Ultravisor-Task-ListFiles.cjs +0 -89
  106. package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadBinary.cjs +0 -87
  107. package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadJSON.cjs +0 -67
  108. package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadText.cjs +0 -66
  109. package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadXML.cjs +0 -69
  110. package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteBinary.cjs +0 -95
  111. package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteJSON.cjs +0 -96
  112. package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteText.cjs +0 -99
  113. package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteXML.cjs +0 -102
  114. package/webinterface/.babelrc +0 -6
  115. package/webinterface/.browserslistrc +0 -1
  116. package/webinterface/.browserslistrc-BACKUP +0 -1
  117. package/webinterface/.gulpfile-quackage-config.json +0 -7
  118. package/webinterface/.gulpfile-quackage.js +0 -2
  119. package/webinterface/source/views/PictView-Ultravisor-TaskEdit.js +0 -220
  120. package/webinterface/source/views/PictView-Ultravisor-TaskList.js +0 -248
  121. /package/docs/{cover.md → _cover.md} +0 -0
@@ -113,6 +113,29 @@ th {
113
113
  background: #4a4a6c;
114
114
  }
115
115
 
116
+ /* Flow panel overrides — restore light inputs inside the white panel */
117
+ .pict-flow-panel input,
118
+ .pict-flow-panel select,
119
+ .pict-flow-panel textarea {
120
+ background-color: #fff;
121
+ color: #333;
122
+ border: 1px solid #ccc;
123
+ }
124
+
125
+ .pict-flow-panel input:focus,
126
+ .pict-flow-panel select:focus,
127
+ .pict-flow-panel textarea:focus {
128
+ border-color: #4fc3f7;
129
+ }
130
+
131
+ .pict-flow-panel label {
132
+ color: #555;
133
+ }
134
+
135
+ .pict-flow-panel-body {
136
+ color: #333;
137
+ }
138
+
116
139
  /* Responsive adjustments */
117
140
  @media (max-width: 768px) {
118
141
  html {
@@ -12,12 +12,15 @@
12
12
  "dependencies": {
13
13
  "pict": "^1.0.343",
14
14
  "pict-application": "^1.0.28",
15
+ "pict-provider": "^1.0.3",
15
16
  "pict-router": "^1.0.4",
16
- "pict-view": "^1.0.64",
17
- "pict-provider": "^1.0.3"
17
+ "pict-section-content": "^0.0.6",
18
+ "pict-section-flow": "file:../../../../pict/pict-section-flow",
19
+ "pict-section-form": "^1.0.194",
20
+ "pict-view": "^1.0.64"
18
21
  },
19
22
  "devDependencies": {
20
- "quackage": "^1.0.41"
23
+ "quackage": "^1.0.59"
21
24
  },
22
25
  "copyFilesSettings": {
23
26
  "whenFileExists": "overwrite"
@@ -1,18 +1,20 @@
1
1
  const libPictApplication = require('pict-application');
2
2
  const libPictRouter = require('pict-router');
3
+ const libPictSectionForm = require('pict-section-form');
4
+ const libPictSectionContent = require('pict-section-content');
3
5
 
4
6
  // Views
5
7
  const libViewLayout = require('./views/PictView-Ultravisor-Layout.js');
6
8
  const libViewTopBar = require('./views/PictView-Ultravisor-TopBar.js');
7
9
  const libViewBottomBar = require('./views/PictView-Ultravisor-BottomBar.js');
8
10
  const libViewDashboard = require('./views/PictView-Ultravisor-Dashboard.js');
9
- const libViewTaskList = require('./views/PictView-Ultravisor-TaskList.js');
10
- const libViewTaskEdit = require('./views/PictView-Ultravisor-TaskEdit.js');
11
11
  const libViewOperationList = require('./views/PictView-Ultravisor-OperationList.js');
12
12
  const libViewOperationEdit = require('./views/PictView-Ultravisor-OperationEdit.js');
13
13
  const libViewSchedule = require('./views/PictView-Ultravisor-Schedule.js');
14
14
  const libViewManifestList = require('./views/PictView-Ultravisor-ManifestList.js');
15
15
  const libViewTimingView = require('./views/PictView-Ultravisor-TimingView.js');
16
+ const libViewFlowEditor = require('./views/PictView-Ultravisor-FlowEditor.js');
17
+ const libViewPendingInput = require('./views/PictView-Ultravisor-PendingInput.js');
16
18
 
17
19
  class UltravisorApplication extends libPictApplication
18
20
  {
@@ -32,13 +34,19 @@ class UltravisorApplication extends libPictApplication
32
34
 
33
35
  // Add content views
34
36
  this.pict.addView('Ultravisor-Dashboard', libViewDashboard.default_configuration, libViewDashboard);
35
- this.pict.addView('Ultravisor-TaskList', libViewTaskList.default_configuration, libViewTaskList);
36
- this.pict.addView('Ultravisor-TaskEdit', libViewTaskEdit.default_configuration, libViewTaskEdit);
37
37
  this.pict.addView('Ultravisor-OperationList', libViewOperationList.default_configuration, libViewOperationList);
38
38
  this.pict.addView('Ultravisor-OperationEdit', libViewOperationEdit.default_configuration, libViewOperationEdit);
39
39
  this.pict.addView('Ultravisor-Schedule', libViewSchedule.default_configuration, libViewSchedule);
40
40
  this.pict.addView('Ultravisor-ManifestList', libViewManifestList.default_configuration, libViewManifestList);
41
41
  this.pict.addView('Ultravisor-TimingView', libViewTimingView.default_configuration, libViewTimingView);
42
+ this.pict.addView('Ultravisor-FlowEditor', libViewFlowEditor.default_configuration, libViewFlowEditor);
43
+ this.pict.addView('Ultravisor-PendingInput', libViewPendingInput.default_configuration, libViewPendingInput);
44
+
45
+ // Register pict-section-form service types so Form panels can use them
46
+ this.pict.addServiceType('PictFormMetacontroller', libPictSectionForm.PictFormMetacontroller);
47
+
48
+ // Register pict-section-content service types so Markdown panels can render content
49
+ this.pict.addServiceType('PictContentProvider', libPictSectionContent.PictContentProvider);
42
50
  }
43
51
 
44
52
  onAfterInitializeAsync(fCallback)
@@ -48,14 +56,16 @@ class UltravisorApplication extends libPictApplication
48
56
  {
49
57
  APIBaseURL: '',
50
58
  ServerStatus: { Status: 'Unknown', ScheduleEntries: 0, ScheduleRunning: false },
51
- Tasks: {},
52
- TaskList: [],
59
+ NodeTemplates: {},
60
+ NodeTemplateList: [],
61
+ TaskTypes: [],
53
62
  Operations: {},
54
63
  OperationList: [],
55
64
  Schedule: [],
56
65
  Manifests: [],
57
- CurrentEditTask: null,
58
- CurrentEditOperation: null
66
+ PendingInputs: [],
67
+ CurrentEditOperation: null,
68
+ Flows: {}
59
69
  };
60
70
 
61
71
  // Render the layout shell first, then the initial content
@@ -135,23 +145,22 @@ class UltravisorApplication extends libPictApplication
135
145
  }.bind(this));
136
146
  }
137
147
 
138
- // --- Tasks ---
139
- loadTasks(fCallback)
148
+ // --- Node Templates ---
149
+ loadNodeTemplates(fCallback)
140
150
  {
141
- this.apiCall('GET', '/Task', null,
151
+ this.apiCall('GET', '/NodeTemplate', null,
142
152
  function (pError, pData)
143
153
  {
144
154
  if (!pError && pData)
145
155
  {
146
- this.pict.AppData.Ultravisor.TaskList = Array.isArray(pData) ? pData : [];
147
- // Also index by GUIDTask
148
- let tmpTasks = {};
149
- for (let i = 0; i < this.pict.AppData.Ultravisor.TaskList.length; i++)
156
+ this.pict.AppData.Ultravisor.NodeTemplateList = Array.isArray(pData) ? pData : [];
157
+ let tmpTemplates = {};
158
+ for (let i = 0; i < this.pict.AppData.Ultravisor.NodeTemplateList.length; i++)
150
159
  {
151
- let tmpTask = this.pict.AppData.Ultravisor.TaskList[i];
152
- tmpTasks[tmpTask.GUIDTask] = tmpTask;
160
+ let tmpTemplate = this.pict.AppData.Ultravisor.NodeTemplateList[i];
161
+ tmpTemplates[tmpTemplate.Hash] = tmpTemplate;
153
162
  }
154
- this.pict.AppData.Ultravisor.Tasks = tmpTasks;
163
+ this.pict.AppData.Ultravisor.NodeTemplates = tmpTemplates;
155
164
  }
156
165
  if (typeof fCallback === 'function')
157
166
  {
@@ -160,9 +169,9 @@ class UltravisorApplication extends libPictApplication
160
169
  }.bind(this));
161
170
  }
162
171
 
163
- saveTask(pTaskData, fCallback)
172
+ saveNodeTemplate(pTemplateData, fCallback)
164
173
  {
165
- this.apiCall('POST', '/Task', pTaskData,
174
+ this.apiCall('POST', '/NodeTemplate', pTemplateData,
166
175
  function (pError, pData)
167
176
  {
168
177
  if (typeof fCallback === 'function')
@@ -172,9 +181,9 @@ class UltravisorApplication extends libPictApplication
172
181
  }.bind(this));
173
182
  }
174
183
 
175
- deleteTask(pGUIDTask, fCallback)
184
+ deleteNodeTemplate(pHash, fCallback)
176
185
  {
177
- this.apiCall('DELETE', `/Task/${encodeURIComponent(pGUIDTask)}`, null,
186
+ this.apiCall('DELETE', `/NodeTemplate/${encodeURIComponent(pHash)}`, null,
178
187
  function (pError, pData)
179
188
  {
180
189
  if (typeof fCallback === 'function')
@@ -184,11 +193,16 @@ class UltravisorApplication extends libPictApplication
184
193
  }.bind(this));
185
194
  }
186
195
 
187
- executeTask(pGUIDTask, fCallback)
196
+ // --- Task Types ---
197
+ loadTaskTypes(fCallback)
188
198
  {
189
- this.apiCall('GET', `/Task/${encodeURIComponent(pGUIDTask)}/Execute`, null,
199
+ this.apiCall('GET', '/TaskType', null,
190
200
  function (pError, pData)
191
201
  {
202
+ if (!pError && pData)
203
+ {
204
+ this.pict.AppData.Ultravisor.TaskTypes = Array.isArray(pData) ? pData : [];
205
+ }
192
206
  if (typeof fCallback === 'function')
193
207
  {
194
208
  fCallback(pError, pData);
@@ -209,7 +223,7 @@ class UltravisorApplication extends libPictApplication
209
223
  for (let i = 0; i < this.pict.AppData.Ultravisor.OperationList.length; i++)
210
224
  {
211
225
  let tmpOp = this.pict.AppData.Ultravisor.OperationList[i];
212
- tmpOperations[tmpOp.GUIDOperation] = tmpOp;
226
+ tmpOperations[tmpOp.Hash] = tmpOp;
213
227
  }
214
228
  this.pict.AppData.Ultravisor.Operations = tmpOperations;
215
229
  }
@@ -232,9 +246,9 @@ class UltravisorApplication extends libPictApplication
232
246
  }.bind(this));
233
247
  }
234
248
 
235
- deleteOperation(pGUIDOperation, fCallback)
249
+ deleteOperation(pHash, fCallback)
236
250
  {
237
- this.apiCall('DELETE', `/Operation/${encodeURIComponent(pGUIDOperation)}`, null,
251
+ this.apiCall('DELETE', `/Operation/${encodeURIComponent(pHash)}`, null,
238
252
  function (pError, pData)
239
253
  {
240
254
  if (typeof fCallback === 'function')
@@ -244,9 +258,9 @@ class UltravisorApplication extends libPictApplication
244
258
  }.bind(this));
245
259
  }
246
260
 
247
- executeOperation(pGUIDOperation, fCallback)
261
+ executeOperation(pHash, fCallback)
248
262
  {
249
- this.apiCall('GET', `/Operation/${encodeURIComponent(pGUIDOperation)}/Execute`, null,
263
+ this.apiCall('GET', `/Operation/${encodeURIComponent(pHash)}/Execute`, null,
250
264
  function (pError, pData)
251
265
  {
252
266
  if (typeof fCallback === 'function')
@@ -273,23 +287,10 @@ class UltravisorApplication extends libPictApplication
273
287
  }.bind(this));
274
288
  }
275
289
 
276
- scheduleTask(pGUIDTask, pScheduleType, pParameters, fCallback)
277
- {
278
- this.apiCall('POST', '/Schedule/Task',
279
- { GUIDTask: pGUIDTask, ScheduleType: pScheduleType, Parameters: pParameters },
280
- function (pError, pData)
281
- {
282
- if (typeof fCallback === 'function')
283
- {
284
- fCallback(pError, pData);
285
- }
286
- }.bind(this));
287
- }
288
-
289
- scheduleOperation(pGUIDOperation, pScheduleType, pParameters, fCallback)
290
+ scheduleOperation(pHash, pScheduleType, pParameters, fCallback)
290
291
  {
291
292
  this.apiCall('POST', '/Schedule/Operation',
292
- { GUIDOperation: pGUIDOperation, ScheduleType: pScheduleType, Parameters: pParameters },
293
+ { Hash: pHash, ScheduleType: pScheduleType, Parameters: pParameters },
293
294
  function (pError, pData)
294
295
  {
295
296
  if (typeof fCallback === 'function')
@@ -352,9 +353,9 @@ class UltravisorApplication extends libPictApplication
352
353
  }.bind(this));
353
354
  }
354
355
 
355
- loadManifest(pGUIDRun, fCallback)
356
+ loadManifest(pRunHash, fCallback)
356
357
  {
357
- this.apiCall('GET', `/Manifest/${encodeURIComponent(pGUIDRun)}`, null,
358
+ this.apiCall('GET', `/Manifest/${encodeURIComponent(pRunHash)}`, null,
358
359
  function (pError, pData)
359
360
  {
360
361
  if (typeof fCallback === 'function')
@@ -364,48 +365,67 @@ class UltravisorApplication extends libPictApplication
364
365
  }.bind(this));
365
366
  }
366
367
 
367
- // --- Edit helpers ---
368
- editTask(pGUIDTask)
368
+ // --- Pending Inputs ---
369
+ loadPendingInputs(fCallback)
369
370
  {
370
- if (pGUIDTask && this.pict.AppData.Ultravisor.Tasks[pGUIDTask])
371
- {
372
- this.pict.AppData.Ultravisor.CurrentEditTask = JSON.parse(JSON.stringify(this.pict.AppData.Ultravisor.Tasks[pGUIDTask]));
373
- }
374
- else
375
- {
376
- this.pict.AppData.Ultravisor.CurrentEditTask =
371
+ this.apiCall('GET', '/PendingInput', null,
372
+ function (pError, pData)
377
373
  {
378
- GUIDTask: '',
379
- Code: '',
380
- Name: '',
381
- Type: 'Command',
382
- Command: '',
383
- URL: '',
384
- Method: 'GET',
385
- Parameters: '',
386
- Description: ''
387
- };
388
- }
389
- this.navigateTo('/TaskEdit');
374
+ if (!pError && pData)
375
+ {
376
+ this.pict.AppData.Ultravisor.PendingInputs = Array.isArray(pData) ? pData : [];
377
+ }
378
+ if (typeof fCallback === 'function')
379
+ {
380
+ fCallback(pError, pData);
381
+ }
382
+ }.bind(this));
390
383
  }
391
384
 
392
- editOperation(pGUIDOperation)
385
+ submitPendingInput(pRunHash, pNodeHash, pValue, fCallback)
393
386
  {
394
- if (pGUIDOperation && this.pict.AppData.Ultravisor.Operations[pGUIDOperation])
387
+ this.apiCall('POST', `/PendingInput/${encodeURIComponent(pRunHash)}`,
388
+ { NodeHash: pNodeHash, Value: pValue },
389
+ function (pError, pData)
390
+ {
391
+ if (typeof fCallback === 'function')
392
+ {
393
+ fCallback(pError, pData);
394
+ }
395
+ }.bind(this));
396
+ }
397
+
398
+ // --- Edit helpers ---
399
+ editOperation(pHash)
400
+ {
401
+ if (pHash && this.pict.AppData.Ultravisor.Operations[pHash])
395
402
  {
396
- this.pict.AppData.Ultravisor.CurrentEditOperation = JSON.parse(JSON.stringify(this.pict.AppData.Ultravisor.Operations[pGUIDOperation]));
403
+ let tmpOp = JSON.parse(JSON.stringify(this.pict.AppData.Ultravisor.Operations[pHash]));
404
+ this.pict.AppData.Ultravisor.CurrentEditOperation = tmpOp;
405
+
406
+ // Load the operation's graph into the FlowEditor data
407
+ if (tmpOp.Graph)
408
+ {
409
+ this.pict.AppData.Ultravisor.Flows.Current = JSON.parse(JSON.stringify(tmpOp.Graph));
410
+ }
397
411
  }
398
412
  else
399
413
  {
400
414
  this.pict.AppData.Ultravisor.CurrentEditOperation =
401
415
  {
402
- GUIDOperation: '',
416
+ Hash: '',
403
417
  Name: '',
404
418
  Description: '',
405
- Tasks: []
419
+ Graph: { Nodes: [], Connections: [], ViewState: {} }
420
+ };
421
+ this.pict.AppData.Ultravisor.Flows.Current =
422
+ {
423
+ Nodes: [],
424
+ Connections: [],
425
+ ViewState: { PanX: 0, PanY: 0, Zoom: 1, SelectedNodeHash: null, SelectedConnectionHash: null }
406
426
  };
407
427
  }
408
- this.navigateTo('/OperationEdit');
428
+ this.navigateTo('/FlowEditor');
409
429
  }
410
430
  }
411
431
 
@@ -0,0 +1,43 @@
1
+ const libPictFlowCard = require('pict-section-flow').PictFlowCard;
2
+
3
+ class FlowCardCSVTransform extends libPictFlowCard
4
+ {
5
+ constructor(pFable, pOptions, pServiceHash)
6
+ {
7
+ super(pFable, Object.assign(
8
+ {},
9
+ {
10
+ Title: 'CSV Transform',
11
+ Code: 'CSVXF',
12
+ Description: 'Transform CSV data into structured records.',
13
+ Category: 'Meadow',
14
+ TitleBarColor: '#2e7d32',
15
+ BodyStyle: { fill: '#e8f5e9', stroke: '#2e7d32' },
16
+ Width: 200,
17
+ Height: 80,
18
+ Inputs:
19
+ [
20
+ { Name: 'CSV Data', Side: 'left-top', PortType: 'value', MinimumInputCount: 1, MaximumInputCount: 1 },
21
+ { Name: 'Delimiter', Side: 'left-top', PortType: 'setting', MinimumInputCount: 0, MaximumInputCount: 1 }
22
+ ],
23
+ Outputs:
24
+ [
25
+ { Name: 'Records', Side: 'right-top', PortType: 'value' }
26
+ ],
27
+ PropertiesPanel:
28
+ {
29
+ PanelType: 'Form', DefaultWidth: 360, DefaultHeight: 260, Title: 'CSV Transform Settings',
30
+ Configuration: { Manifest: { Scope: 'FlowCardCSVTransform',
31
+ Sections: [{ Name: 'Transform', Hash: 'CSVSection', Groups: [{ Name: 'Settings', Hash: 'CSVGroup' }] }],
32
+ Descriptors: {
33
+ 'Record.Data.SourceAddress': { Name: 'Source State Address', Hash: 'SourceAddress', DataType: 'String', Default: '', PictForm: { Section: 'CSVSection', Group: 'CSVGroup', Row: 1, Width: 12 } },
34
+ 'Record.Data.Destination': { Name: 'Result Destination', Hash: 'Destination', DataType: 'String', Default: '', PictForm: { Section: 'CSVSection', Group: 'CSVGroup', Row: 2, Width: 12 } },
35
+ 'Record.Data.Delimiter': { Name: 'Delimiter', Hash: 'Delimiter', DataType: 'String', Default: ',', PictForm: { Section: 'CSVSection', Group: 'CSVGroup', Row: 3, Width: 6 } }
36
+ }
37
+ }}
38
+ }
39
+ }, pOptions), pServiceHash);
40
+ }
41
+ }
42
+
43
+ module.exports = FlowCardCSVTransform;
@@ -0,0 +1,86 @@
1
+ const libPictFlowCard = require('pict-section-flow').PictFlowCard;
2
+
3
+ class FlowCardCommand extends libPictFlowCard
4
+ {
5
+ constructor(pFable, pOptions, pServiceHash)
6
+ {
7
+ super(pFable, Object.assign(
8
+ {},
9
+ {
10
+ Title: 'Command',
11
+ Code: 'CMD',
12
+ Description: 'Execute a shell command on the node.',
13
+ Category: 'Core',
14
+ TitleBarColor: '#7b1fa2',
15
+ BodyStyle: { fill: '#f3e5f5', stroke: '#7b1fa2' },
16
+ Width: 180,
17
+ Height: 80,
18
+ Inputs:
19
+ [
20
+ { Name: 'Trigger', Side: 'left-bottom', PortType: 'event-in', MinimumInputCount: 0, MaximumInputCount: 1 },
21
+ { Name: 'Command', Side: 'left-top', PortType: 'setting', MinimumInputCount: 0, MaximumInputCount: 1 }
22
+ ],
23
+ Outputs:
24
+ [
25
+ { Name: 'Complete', Side: 'right', PortType: 'event-out' },
26
+ { Name: 'Error', Side: 'bottom', PortType: 'error' }
27
+ ],
28
+ PropertiesPanel:
29
+ {
30
+ PanelType: 'Form',
31
+ DefaultWidth: 350,
32
+ DefaultHeight: 260,
33
+ Title: 'Command Settings',
34
+ Configuration:
35
+ {
36
+ Manifest:
37
+ {
38
+ Scope: 'FlowCardCommand',
39
+ Sections:
40
+ [
41
+ {
42
+ Name: 'Command Configuration',
43
+ Hash: 'CommandSection',
44
+ Groups:
45
+ [
46
+ { Name: 'Settings', Hash: 'CommandGroup' }
47
+ ]
48
+ }
49
+ ],
50
+ Descriptors:
51
+ {
52
+ 'Record.Data.Command':
53
+ {
54
+ Name: 'Command',
55
+ Hash: 'Command',
56
+ DataType: 'String',
57
+ Default: '',
58
+ PictForm: { Section: 'CommandSection', Group: 'CommandGroup', Row: 1, Width: 12 }
59
+ },
60
+ 'Record.Data.Parameters':
61
+ {
62
+ Name: 'Parameters',
63
+ Hash: 'Parameters',
64
+ DataType: 'String',
65
+ Default: '',
66
+ PictForm: { Section: 'CommandSection', Group: 'CommandGroup', Row: 2, Width: 12 }
67
+ },
68
+ 'Record.Data.Description':
69
+ {
70
+ Name: 'Description',
71
+ Hash: 'Description',
72
+ DataType: 'String',
73
+ Default: '',
74
+ PictForm: { Section: 'CommandSection', Group: 'CommandGroup', Row: 3, Width: 12, InputType: 'TextArea' }
75
+ }
76
+ }
77
+ }
78
+ }
79
+ }
80
+ },
81
+ pOptions),
82
+ pServiceHash);
83
+ }
84
+ }
85
+
86
+ module.exports = FlowCardCommand;
@@ -0,0 +1,40 @@
1
+ const libPictFlowCard = require('pict-section-flow').PictFlowCard;
2
+
3
+ class FlowCardComprehensionIntersect extends libPictFlowCard
4
+ {
5
+ constructor(pFable, pOptions, pServiceHash)
6
+ {
7
+ super(pFable, Object.assign(
8
+ {},
9
+ {
10
+ Title: 'Comprehension Intersect',
11
+ Code: 'CMPINT',
12
+ Description: 'Merge two comprehension data sets by GUID.',
13
+ Category: 'Meadow',
14
+ TitleBarColor: '#2e7d32',
15
+ BodyStyle: { fill: '#e8f5e9', stroke: '#2e7d32' },
16
+ Width: 220,
17
+ Height: 100,
18
+ Inputs:
19
+ [
20
+ { Name: 'Set A', Side: 'left-top', PortType: 'value', MinimumInputCount: 1, MaximumInputCount: 1 },
21
+ { Name: 'Set B', Side: 'left-top', PortType: 'value', MinimumInputCount: 1, MaximumInputCount: 1 }
22
+ ],
23
+ Outputs: [{ Name: 'Result', Side: 'right-top', PortType: 'value' }],
24
+ PropertiesPanel:
25
+ {
26
+ PanelType: 'Form', DefaultWidth: 360, DefaultHeight: 260, Title: 'Comprehension Intersect Settings',
27
+ Configuration: { Manifest: { Scope: 'FlowCardComprehensionIntersect',
28
+ Sections: [{ Name: 'Merge', Hash: 'CISection', Groups: [{ Name: 'Settings', Hash: 'CIGroup' }] }],
29
+ Descriptors: {
30
+ 'Record.Data.SourceAddressA': { Name: 'Set A State Address', Hash: 'SourceAddressA', DataType: 'String', Default: '', PictForm: { Section: 'CISection', Group: 'CIGroup', Row: 1, Width: 12 } },
31
+ 'Record.Data.SourceAddressB': { Name: 'Set B State Address', Hash: 'SourceAddressB', DataType: 'String', Default: '', PictForm: { Section: 'CISection', Group: 'CIGroup', Row: 2, Width: 12 } },
32
+ 'Record.Data.Destination': { Name: 'Result Destination', Hash: 'Destination', DataType: 'String', Default: '', PictForm: { Section: 'CISection', Group: 'CIGroup', Row: 3, Width: 12 } }
33
+ }
34
+ }}
35
+ }
36
+ }, pOptions), pServiceHash);
37
+ }
38
+ }
39
+
40
+ module.exports = FlowCardComprehensionIntersect;
@@ -0,0 +1,87 @@
1
+ const libPictFlowCard = require('pict-section-flow').PictFlowCard;
2
+
3
+ class FlowCardConditional extends libPictFlowCard
4
+ {
5
+ constructor(pFable, pOptions, pServiceHash)
6
+ {
7
+ super(pFable, Object.assign(
8
+ {},
9
+ {
10
+ Title: 'Conditional',
11
+ Code: 'COND',
12
+ Description: 'Evaluate a condition and branch to True or False path.',
13
+ Category: 'Core',
14
+ TitleBarColor: '#7b1fa2',
15
+ BodyStyle: { fill: '#f3e5f5', stroke: '#7b1fa2' },
16
+ Width: 200,
17
+ Height: 100,
18
+ Inputs:
19
+ [
20
+ { Name: 'In', Side: 'left-bottom', PortType: 'event-in', MinimumInputCount: 1, MaximumInputCount: 1 },
21
+ { Name: 'Address', Side: 'left-top', PortType: 'setting', MinimumInputCount: 0, MaximumInputCount: 1 },
22
+ { Name: 'Value', Side: 'left-top', PortType: 'setting', MinimumInputCount: 0, MaximumInputCount: 1 }
23
+ ],
24
+ Outputs:
25
+ [
26
+ { Name: 'True', Side: 'right', PortType: 'event-out' },
27
+ { Name: 'False', Side: 'bottom', PortType: 'event-out' }
28
+ ],
29
+ PropertiesPanel:
30
+ {
31
+ PanelType: 'Form',
32
+ DefaultWidth: 350,
33
+ DefaultHeight: 280,
34
+ Title: 'Conditional Settings',
35
+ Configuration:
36
+ {
37
+ Manifest:
38
+ {
39
+ Scope: 'FlowCardConditional',
40
+ Sections:
41
+ [
42
+ {
43
+ Name: 'Condition',
44
+ Hash: 'CondSection',
45
+ Groups:
46
+ [
47
+ { Name: 'Settings', Hash: 'CondGroup' }
48
+ ]
49
+ }
50
+ ],
51
+ Descriptors:
52
+ {
53
+ 'Record.Data.Address':
54
+ {
55
+ Name: 'State Address',
56
+ Hash: 'Address',
57
+ DataType: 'String',
58
+ Default: '',
59
+ PictForm: { Section: 'CondSection', Group: 'CondGroup', Row: 1, Width: 12 }
60
+ },
61
+ 'Record.Data.Value':
62
+ {
63
+ Name: 'Expected Value',
64
+ Hash: 'Value',
65
+ DataType: 'String',
66
+ Default: '',
67
+ PictForm: { Section: 'CondSection', Group: 'CondGroup', Row: 2, Width: 12 }
68
+ },
69
+ 'Record.Data.Operator':
70
+ {
71
+ Name: 'Operator',
72
+ Hash: 'Operator',
73
+ DataType: 'String',
74
+ Default: '==',
75
+ PictForm: { Section: 'CondSection', Group: 'CondGroup', Row: 3, Width: 6 }
76
+ }
77
+ }
78
+ }
79
+ }
80
+ }
81
+ },
82
+ pOptions),
83
+ pServiceHash);
84
+ }
85
+ }
86
+
87
+ module.exports = FlowCardConditional;
@@ -0,0 +1,55 @@
1
+ const libPictFlowCard = require('pict-section-flow').PictFlowCard;
2
+
3
+ class FlowCardCopyFile extends libPictFlowCard
4
+ {
5
+ constructor(pFable, pOptions, pServiceHash)
6
+ {
7
+ super(pFable, Object.assign(
8
+ {},
9
+ {
10
+ Title: 'Copy File',
11
+ Code: 'CPFILE',
12
+ Description: 'Copy a file within the staging folder.',
13
+ Category: 'File I/O',
14
+ TitleBarColor: '#2980b9',
15
+ BodyStyle: { fill: '#eaf2f8', stroke: '#2980b9' },
16
+ Width: 200,
17
+ Height: 80,
18
+ Inputs:
19
+ [
20
+ { Name: 'Trigger', Side: 'left-bottom', PortType: 'event-in', MinimumInputCount: 0, MaximumInputCount: 1 },
21
+ { Name: 'Source', Side: 'left-top', PortType: 'setting', MinimumInputCount: 0, MaximumInputCount: 1 },
22
+ { Name: 'Target', Side: 'left-top', PortType: 'setting', MinimumInputCount: 0, MaximumInputCount: 1 }
23
+ ],
24
+ Outputs:
25
+ [
26
+ { Name: 'Done', Side: 'right', PortType: 'event-out' },
27
+ { Name: 'Error', Side: 'bottom', PortType: 'error' }
28
+ ],
29
+ PropertiesPanel:
30
+ {
31
+ PanelType: 'Form',
32
+ DefaultWidth: 340,
33
+ DefaultHeight: 220,
34
+ Title: 'Copy File Settings',
35
+ Configuration:
36
+ {
37
+ Manifest:
38
+ {
39
+ Scope: 'FlowCardCopyFile',
40
+ Sections: [{ Name: 'Copy', Hash: 'CPSection', Groups: [{ Name: 'Settings', Hash: 'CPGroup' }] }],
41
+ Descriptors:
42
+ {
43
+ 'Record.Data.Source': { Name: 'Source File', Hash: 'Source', DataType: 'String', Default: '', PictForm: { Section: 'CPSection', Group: 'CPGroup', Row: 1, Width: 12 } },
44
+ 'Record.Data.TargetFile': { Name: 'Target File', Hash: 'TargetFile', DataType: 'String', Default: '', PictForm: { Section: 'CPSection', Group: 'CPGroup', Row: 2, Width: 12 } }
45
+ }
46
+ }
47
+ }
48
+ }
49
+ },
50
+ pOptions),
51
+ pServiceHash);
52
+ }
53
+ }
54
+
55
+ module.exports = FlowCardCopyFile;