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.
- package/.claude/launch.json +11 -0
- package/.claude/ultravisor-dev-config.json +3 -0
- package/.ultravisor.json +426 -0
- package/docs/README.md +63 -0
- package/package.json +12 -8
- package/source/Ultravisor.cjs +22 -3
- package/source/cli/Ultravisor-CLIProgram.cjs +35 -23
- package/source/cli/commands/Ultravisor-Command-SingleOperation.cjs +29 -18
- package/source/cli/commands/Ultravisor-Command-SingleTask.cjs +62 -19
- package/source/cli/commands/Ultravisor-Command-UpdateTask.cjs +27 -15
- package/source/config/Ultravisor-Default-Command-Configuration.cjs +5 -3
- package/source/services/Ultravisor-ExecutionEngine.cjs +1039 -0
- package/source/services/Ultravisor-ExecutionManifest.cjs +399 -0
- package/source/services/Ultravisor-Hypervisor-State.cjs +270 -97
- package/source/services/Ultravisor-Hypervisor.cjs +38 -83
- package/source/services/Ultravisor-StateManager.cjs +241 -0
- package/source/services/Ultravisor-TaskTypeRegistry.cjs +143 -0
- package/source/services/tasks/Ultravisor-TaskType-Base.cjs +105 -0
- package/source/services/tasks/control/Ultravisor-TaskType-IfConditional.cjs +148 -0
- package/source/services/tasks/control/Ultravisor-TaskType-LaunchOperation.cjs +187 -0
- package/source/services/tasks/control/Ultravisor-TaskType-SplitExecute.cjs +184 -0
- package/source/services/tasks/data/Ultravisor-TaskType-ReplaceString.cjs +82 -0
- package/source/services/tasks/data/Ultravisor-TaskType-SetValues.cjs +81 -0
- package/source/services/tasks/data/Ultravisor-TaskType-StringAppender.cjs +101 -0
- package/source/services/tasks/file-io/Ultravisor-TaskType-ReadFile.cjs +103 -0
- package/source/services/tasks/file-io/Ultravisor-TaskType-WriteFile.cjs +117 -0
- package/source/services/tasks/interaction/Ultravisor-TaskType-ErrorMessage.cjs +54 -0
- package/source/services/tasks/interaction/Ultravisor-TaskType-ValueInput.cjs +62 -0
- package/source/web_server/Ultravisor-API-Server.cjs +237 -124
- package/test/Ultravisor_browser_tests.js +2226 -0
- package/test/Ultravisor_tests.js +1143 -5830
- package/webinterface/css/ultravisor.css +23 -0
- package/webinterface/package.json +6 -3
- package/webinterface/source/Pict-Application-Ultravisor.js +93 -73
- package/webinterface/source/cards/FlowCard-CSVTransform.js +43 -0
- package/webinterface/source/cards/FlowCard-Command.js +86 -0
- package/webinterface/source/cards/FlowCard-ComprehensionIntersect.js +40 -0
- package/webinterface/source/cards/FlowCard-Conditional.js +87 -0
- package/webinterface/source/cards/FlowCard-CopyFile.js +55 -0
- package/webinterface/source/cards/FlowCard-End.js +29 -0
- package/webinterface/source/cards/FlowCard-GetJSON.js +55 -0
- package/webinterface/source/cards/FlowCard-GetText.js +54 -0
- package/webinterface/source/cards/FlowCard-Histogram.js +176 -0
- package/webinterface/source/cards/FlowCard-LaunchOperation.js +82 -0
- package/webinterface/source/cards/FlowCard-ListFiles.js +55 -0
- package/webinterface/source/cards/FlowCard-MeadowCount.js +44 -0
- package/webinterface/source/cards/FlowCard-MeadowCreate.js +44 -0
- package/webinterface/source/cards/FlowCard-MeadowDelete.js +45 -0
- package/webinterface/source/cards/FlowCard-MeadowRead.js +46 -0
- package/webinterface/source/cards/FlowCard-MeadowReads.js +46 -0
- package/webinterface/source/cards/FlowCard-MeadowUpdate.js +44 -0
- package/webinterface/source/cards/FlowCard-ParseCSV.js +85 -0
- package/webinterface/source/cards/FlowCard-ReadJSON.js +54 -0
- package/webinterface/source/cards/FlowCard-ReadText.js +54 -0
- package/webinterface/source/cards/FlowCard-RestRequest.js +59 -0
- package/webinterface/source/cards/FlowCard-SendJSON.js +57 -0
- package/webinterface/source/cards/FlowCard-Solver.js +77 -0
- package/webinterface/source/cards/FlowCard-Start.js +29 -0
- package/webinterface/source/cards/FlowCard-TemplateString.js +77 -0
- package/webinterface/source/cards/FlowCard-WriteJSON.js +54 -0
- package/webinterface/source/cards/FlowCard-WriteText.js +54 -0
- package/webinterface/source/data/ExampleFlow-CSVPipeline.js +231 -0
- package/webinterface/source/data/ExampleFlow-FileProcessor.js +315 -0
- package/webinterface/source/data/ExampleFlow-MeadowPipeline.js +328 -0
- package/webinterface/source/providers/PictRouter-Ultravisor-Configuration.json +8 -8
- package/webinterface/source/views/PictView-Ultravisor-Dashboard.js +6 -6
- package/webinterface/source/views/PictView-Ultravisor-FlowEditor.js +436 -0
- package/webinterface/source/views/PictView-Ultravisor-ManifestList.js +45 -43
- package/webinterface/source/views/PictView-Ultravisor-OperationEdit.js +34 -89
- package/webinterface/source/views/PictView-Ultravisor-OperationList.js +128 -13
- package/webinterface/source/views/PictView-Ultravisor-PendingInput.js +314 -0
- package/webinterface/source/views/PictView-Ultravisor-Schedule.js +18 -53
- package/webinterface/source/views/PictView-Ultravisor-TimingView.js +27 -14
- package/webinterface/source/views/PictView-Ultravisor-TopBar.js +2 -1
- package/.babelrc +0 -6
- package/.browserslistrc +0 -1
- package/.browserslistrc-BACKUP +0 -1
- package/.gulpfile-quackage-config.json +0 -7
- package/.gulpfile-quackage.js +0 -2
- package/debug/Harness.js +0 -5
- package/source/services/Ultravisor-Operation-Manifest.cjs +0 -160
- package/source/services/Ultravisor-Operation.cjs +0 -200
- package/source/services/Ultravisor-Task.cjs +0 -349
- package/source/services/events/Ultravisor-Hypervisor-Event-Solver.cjs +0 -11
- package/source/services/tasks/Ultravisor-Task-Base.cjs +0 -264
- package/source/services/tasks/Ultravisor-Task-CollectValues.cjs +0 -188
- package/source/services/tasks/Ultravisor-Task-Command.cjs +0 -65
- package/source/services/tasks/Ultravisor-Task-CommandEach.cjs +0 -190
- package/source/services/tasks/Ultravisor-Task-Conditional.cjs +0 -104
- package/source/services/tasks/Ultravisor-Task-DateWindow.cjs +0 -72
- package/source/services/tasks/Ultravisor-Task-GeneratePagedOperation.cjs +0 -336
- package/source/services/tasks/Ultravisor-Task-LaunchOperation.cjs +0 -143
- package/source/services/tasks/Ultravisor-Task-LaunchTask.cjs +0 -146
- package/source/services/tasks/Ultravisor-Task-LineMatch.cjs +0 -158
- package/source/services/tasks/Ultravisor-Task-Request.cjs +0 -56
- package/source/services/tasks/Ultravisor-Task-Solver.cjs +0 -89
- package/source/services/tasks/Ultravisor-Task-TemplateString.cjs +0 -93
- package/source/services/tasks/rest/Ultravisor-Task-GetBinary.cjs +0 -127
- package/source/services/tasks/rest/Ultravisor-Task-GetJSON.cjs +0 -119
- package/source/services/tasks/rest/Ultravisor-Task-GetText.cjs +0 -109
- package/source/services/tasks/rest/Ultravisor-Task-GetXML.cjs +0 -112
- package/source/services/tasks/rest/Ultravisor-Task-RestRequest.cjs +0 -499
- package/source/services/tasks/rest/Ultravisor-Task-SendJSON.cjs +0 -150
- package/source/services/tasks/stagingfiles/Ultravisor-Task-CopyFile.cjs +0 -110
- package/source/services/tasks/stagingfiles/Ultravisor-Task-ListFiles.cjs +0 -89
- package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadBinary.cjs +0 -87
- package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadJSON.cjs +0 -67
- package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadText.cjs +0 -66
- package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadXML.cjs +0 -69
- package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteBinary.cjs +0 -95
- package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteJSON.cjs +0 -96
- package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteText.cjs +0 -99
- package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteXML.cjs +0 -102
- package/webinterface/.babelrc +0 -6
- package/webinterface/.browserslistrc +0 -1
- package/webinterface/.browserslistrc-BACKUP +0 -1
- package/webinterface/.gulpfile-quackage-config.json +0 -7
- package/webinterface/.gulpfile-quackage.js +0 -2
- package/webinterface/source/views/PictView-Ultravisor-TaskEdit.js +0 -220
- package/webinterface/source/views/PictView-Ultravisor-TaskList.js +0 -248
- /package/docs/{cover.md → _cover.md} +0 -0
|
@@ -26,33 +26,6 @@ const _ViewConfiguration =
|
|
|
26
26
|
font-weight: 300;
|
|
27
27
|
color: #e0e0e0;
|
|
28
28
|
}
|
|
29
|
-
.ultravisor-task-list-editor {
|
|
30
|
-
background: #16213e;
|
|
31
|
-
border: 1px solid #2a2a4a;
|
|
32
|
-
border-radius: 6px;
|
|
33
|
-
padding: 1em;
|
|
34
|
-
}
|
|
35
|
-
.ultravisor-task-list-item {
|
|
36
|
-
display: flex;
|
|
37
|
-
align-items: center;
|
|
38
|
-
justify-content: space-between;
|
|
39
|
-
padding: 0.5em 0.75em;
|
|
40
|
-
background: #1a1a2e;
|
|
41
|
-
border-radius: 4px;
|
|
42
|
-
margin-bottom: 0.5em;
|
|
43
|
-
}
|
|
44
|
-
.ultravisor-task-list-item code {
|
|
45
|
-
color: #4fc3f7;
|
|
46
|
-
font-size: 0.9em;
|
|
47
|
-
}
|
|
48
|
-
.ultravisor-task-list-add {
|
|
49
|
-
display: flex;
|
|
50
|
-
gap: 0.5em;
|
|
51
|
-
margin-top: 0.75em;
|
|
52
|
-
}
|
|
53
|
-
.ultravisor-task-list-add input {
|
|
54
|
-
flex: 1;
|
|
55
|
-
}
|
|
56
29
|
`,
|
|
57
30
|
|
|
58
31
|
Templates:
|
|
@@ -93,15 +66,19 @@ class UltravisorOperationEditView extends libPictView
|
|
|
93
66
|
let tmpOp = this.pict.AppData.Ultravisor.CurrentEditOperation;
|
|
94
67
|
if (!tmpOp)
|
|
95
68
|
{
|
|
96
|
-
tmpOp =
|
|
69
|
+
tmpOp =
|
|
70
|
+
{
|
|
71
|
+
Hash: '', Name: '', Description: '',
|
|
72
|
+
Graph: { Nodes: [], Connections: [], ViewState: {} }
|
|
73
|
+
};
|
|
97
74
|
this.pict.AppData.Ultravisor.CurrentEditOperation = tmpOp;
|
|
98
75
|
}
|
|
99
76
|
|
|
100
|
-
let tmpIsNew = !tmpOp.
|
|
77
|
+
let tmpIsNew = !tmpOp.Hash;
|
|
101
78
|
let tmpTitleEl = document.getElementById('Ultravisor-OperationEdit-Title');
|
|
102
79
|
if (tmpTitleEl)
|
|
103
80
|
{
|
|
104
|
-
tmpTitleEl.textContent = tmpIsNew ? 'New Operation' : ('Edit Operation: ' + (tmpOp.Name || tmpOp.
|
|
81
|
+
tmpTitleEl.textContent = tmpIsNew ? 'New Operation' : ('Edit Operation: ' + (tmpOp.Name || tmpOp.Hash));
|
|
105
82
|
}
|
|
106
83
|
|
|
107
84
|
this.renderForm();
|
|
@@ -124,13 +101,19 @@ class UltravisorOperationEditView extends libPictView
|
|
|
124
101
|
renderForm()
|
|
125
102
|
{
|
|
126
103
|
let tmpOp = this.pict.AppData.Ultravisor.CurrentEditOperation;
|
|
127
|
-
let tmpIsNew = !tmpOp.
|
|
104
|
+
let tmpIsNew = !tmpOp.Hash;
|
|
128
105
|
let tmpGlobalRef = '_Pict';
|
|
129
106
|
let tmpViewRef = tmpGlobalRef + ".views['Ultravisor-OperationEdit']";
|
|
130
107
|
|
|
108
|
+
let tmpNodeCount = (tmpOp.Graph && tmpOp.Graph.Nodes) ? tmpOp.Graph.Nodes.length : 0;
|
|
109
|
+
|
|
131
110
|
let tmpHTML = '';
|
|
132
|
-
|
|
133
|
-
|
|
111
|
+
|
|
112
|
+
if (!tmpIsNew)
|
|
113
|
+
{
|
|
114
|
+
tmpHTML += '<div class="ultravisor-form-group"><label>Hash</label>';
|
|
115
|
+
tmpHTML += '<input type="text" id="Ultravisor-OperationEdit-Hash" value="' + this.escapeAttr(tmpOp.Hash) + '" readonly></div>';
|
|
116
|
+
}
|
|
134
117
|
|
|
135
118
|
tmpHTML += '<div class="ultravisor-form-group"><label>Name</label>';
|
|
136
119
|
tmpHTML += '<input type="text" id="Ultravisor-OperationEdit-Name" value="' + this.escapeAttr(tmpOp.Name || '') + '"></div>';
|
|
@@ -138,91 +121,53 @@ class UltravisorOperationEditView extends libPictView
|
|
|
138
121
|
tmpHTML += '<div class="ultravisor-form-group"><label>Description</label>';
|
|
139
122
|
tmpHTML += '<textarea id="Ultravisor-OperationEdit-Description">' + this.escapeHTML(tmpOp.Description || '') + '</textarea></div>';
|
|
140
123
|
|
|
141
|
-
|
|
142
|
-
tmpHTML += '<div class="ultravisor-task-list-editor">';
|
|
143
|
-
|
|
144
|
-
let tmpTasks = tmpOp.Tasks || [];
|
|
145
|
-
if (tmpTasks.length === 0)
|
|
146
|
-
{
|
|
147
|
-
tmpHTML += '<div style="color: #607d8b; font-size: 0.9em; padding: 0.5em;">No tasks added yet.</div>';
|
|
148
|
-
}
|
|
149
|
-
else
|
|
124
|
+
if (!tmpIsNew)
|
|
150
125
|
{
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
tmpHTML += '<div class="ultravisor-task-list-item">';
|
|
155
|
-
tmpHTML += '<code>' + this.escapeHTML(tmpTasks[i]) + '</code>';
|
|
156
|
-
tmpHTML += '<button class="ultravisor-btn-sm ultravisor-btn-delete" onclick="' + tmpViewRef + '.removeTaskFromOperation(' + i + ')">Remove</button>';
|
|
157
|
-
tmpHTML += '</div>';
|
|
158
|
-
}
|
|
126
|
+
tmpHTML += '<div class="ultravisor-form-group"><label>Graph</label>';
|
|
127
|
+
tmpHTML += '<p style="color:#78909c;">' + tmpNodeCount + ' node' + (tmpNodeCount !== 1 ? 's' : '') + ' in graph. Use the Flow Editor to modify the operation graph.</p>';
|
|
128
|
+
tmpHTML += '</div>';
|
|
159
129
|
}
|
|
160
130
|
|
|
161
|
-
tmpHTML += '<div class="ultravisor-task-list-add">';
|
|
162
|
-
tmpHTML += '<input type="text" id="Ultravisor-OperationEdit-NewTaskGUID" placeholder="Task GUID to add...">';
|
|
163
|
-
tmpHTML += '<button class="ultravisor-btn ultravisor-btn-secondary" onclick="' + tmpViewRef + '.addTaskToOperation()">Add</button>';
|
|
164
|
-
tmpHTML += '</div>';
|
|
165
|
-
tmpHTML += '</div></div>';
|
|
166
|
-
|
|
167
131
|
tmpHTML += '<div class="ultravisor-form-actions">';
|
|
168
|
-
tmpHTML += '<button class="ultravisor-btn ultravisor-btn-primary" onclick="' + tmpViewRef + '.saveOperation()">Save
|
|
132
|
+
tmpHTML += '<button class="ultravisor-btn ultravisor-btn-primary" onclick="' + tmpViewRef + '.saveOperation()">Save Metadata</button>';
|
|
133
|
+
tmpHTML += '<button class="ultravisor-btn ultravisor-btn-primary" onclick="' + tmpViewRef + '.openFlowEditor()">Open in Flow Editor</button>';
|
|
169
134
|
tmpHTML += '<button class="ultravisor-btn ultravisor-btn-secondary" onclick="' + tmpGlobalRef + '.PictApplication.navigateTo(\'/Operations\')">Cancel</button>';
|
|
170
135
|
tmpHTML += '</div>';
|
|
171
136
|
|
|
172
137
|
this.pict.ContentAssignment.assignContent('#Ultravisor-OperationEdit-Form', tmpHTML);
|
|
173
138
|
}
|
|
174
139
|
|
|
175
|
-
|
|
140
|
+
openFlowEditor()
|
|
176
141
|
{
|
|
177
|
-
|
|
178
|
-
let tmpGUID = tmpInput ? tmpInput.value.trim() : '';
|
|
179
|
-
if (!tmpGUID) return;
|
|
180
|
-
|
|
142
|
+
// Sync form values back to the model before navigating
|
|
181
143
|
let tmpOp = this.pict.AppData.Ultravisor.CurrentEditOperation;
|
|
182
|
-
if (!tmpOp.Tasks)
|
|
183
|
-
{
|
|
184
|
-
tmpOp.Tasks = [];
|
|
185
|
-
}
|
|
186
|
-
tmpOp.Tasks.push(tmpGUID);
|
|
187
|
-
|
|
188
|
-
// Preserve current form field values before re-render
|
|
189
|
-
tmpOp.GUIDOperation = document.getElementById('Ultravisor-OperationEdit-GUIDOperation').value.trim();
|
|
190
144
|
tmpOp.Name = document.getElementById('Ultravisor-OperationEdit-Name').value.trim();
|
|
191
145
|
tmpOp.Description = document.getElementById('Ultravisor-OperationEdit-Description').value.trim();
|
|
192
146
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
removeTaskFromOperation(pIndex)
|
|
197
|
-
{
|
|
198
|
-
let tmpOp = this.pict.AppData.Ultravisor.CurrentEditOperation;
|
|
199
|
-
if (tmpOp.Tasks && pIndex >= 0 && pIndex < tmpOp.Tasks.length)
|
|
147
|
+
// Load the graph into FlowEditor data
|
|
148
|
+
if (tmpOp.Graph)
|
|
200
149
|
{
|
|
201
|
-
|
|
150
|
+
this.pict.AppData.Ultravisor.Flows.Current = JSON.parse(JSON.stringify(tmpOp.Graph));
|
|
202
151
|
}
|
|
203
152
|
|
|
204
|
-
|
|
205
|
-
tmpOp.GUIDOperation = document.getElementById('Ultravisor-OperationEdit-GUIDOperation').value.trim();
|
|
206
|
-
tmpOp.Name = document.getElementById('Ultravisor-OperationEdit-Name').value.trim();
|
|
207
|
-
tmpOp.Description = document.getElementById('Ultravisor-OperationEdit-Description').value.trim();
|
|
208
|
-
|
|
209
|
-
this.renderForm();
|
|
153
|
+
this.pict.PictApplication.navigateTo('/FlowEditor');
|
|
210
154
|
}
|
|
211
155
|
|
|
212
156
|
saveOperation()
|
|
213
157
|
{
|
|
158
|
+
let tmpOp = this.pict.AppData.Ultravisor.CurrentEditOperation;
|
|
159
|
+
|
|
214
160
|
let tmpOpData =
|
|
215
161
|
{
|
|
216
|
-
GUIDOperation: document.getElementById('Ultravisor-OperationEdit-GUIDOperation').value.trim(),
|
|
217
162
|
Name: document.getElementById('Ultravisor-OperationEdit-Name').value.trim(),
|
|
218
163
|
Description: document.getElementById('Ultravisor-OperationEdit-Description').value.trim(),
|
|
219
|
-
|
|
164
|
+
Graph: tmpOp.Graph || { Nodes: [], Connections: [], ViewState: {} }
|
|
220
165
|
};
|
|
221
166
|
|
|
222
|
-
|
|
167
|
+
let tmpHashEl = document.getElementById('Ultravisor-OperationEdit-Hash');
|
|
168
|
+
if (tmpHashEl)
|
|
223
169
|
{
|
|
224
|
-
|
|
225
|
-
return;
|
|
170
|
+
tmpOpData.Hash = tmpHashEl.value.trim();
|
|
226
171
|
}
|
|
227
172
|
|
|
228
173
|
this.pict.PictApplication.saveOperation(tmpOpData,
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
const libPictView = require('pict-view');
|
|
2
2
|
|
|
3
|
+
const libExampleCSVPipeline = require('../data/ExampleFlow-CSVPipeline.js');
|
|
4
|
+
const libExampleMeadowPipeline = require('../data/ExampleFlow-MeadowPipeline.js');
|
|
5
|
+
const libExampleFileProcessor = require('../data/ExampleFlow-FileProcessor.js');
|
|
6
|
+
|
|
3
7
|
const _ViewConfiguration =
|
|
4
8
|
{
|
|
5
9
|
ViewIdentifier: "Ultravisor-OperationList",
|
|
@@ -39,7 +43,7 @@ const _ViewConfiguration =
|
|
|
39
43
|
.ultravisor-operation-table tr:hover td {
|
|
40
44
|
background-color: #1a2744;
|
|
41
45
|
}
|
|
42
|
-
.ultravisor-operation-
|
|
46
|
+
.ultravisor-operation-node-count {
|
|
43
47
|
display: inline-block;
|
|
44
48
|
padding: 0.15em 0.5em;
|
|
45
49
|
border-radius: 3px;
|
|
@@ -58,9 +62,15 @@ const _ViewConfiguration =
|
|
|
58
62
|
<div class="ultravisor-operationlist">
|
|
59
63
|
<div class="ultravisor-operationlist-header">
|
|
60
64
|
<h1>Operations</h1>
|
|
61
|
-
<
|
|
65
|
+
<div>
|
|
66
|
+
<button class="ultravisor-btn ultravisor-btn-primary" onclick="{~P~}.PictApplication.editOperation()">New Operation</button>
|
|
67
|
+
<button class="ultravisor-btn ultravisor-btn-secondary" onclick="{~P~}.views['Ultravisor-OperationList'].createExampleOperation('CSVPipeline')">+ Config Processor</button>
|
|
68
|
+
<button class="ultravisor-btn ultravisor-btn-secondary" onclick="{~P~}.views['Ultravisor-OperationList'].createExampleOperation('MeadowPipeline')">+ Template Processor</button>
|
|
69
|
+
<button class="ultravisor-btn ultravisor-btn-secondary" onclick="{~P~}.views['Ultravisor-OperationList'].createExampleOperation('FileProcessor')">+ File Processor</button>
|
|
70
|
+
</div>
|
|
62
71
|
</div>
|
|
63
72
|
<div id="Ultravisor-OperationList-Body"></div>
|
|
73
|
+
<div id="Ultravisor-OperationList-Result"></div>
|
|
64
74
|
</div>
|
|
65
75
|
`
|
|
66
76
|
}
|
|
@@ -108,25 +118,25 @@ class UltravisorOperationListView extends libPictView
|
|
|
108
118
|
}
|
|
109
119
|
|
|
110
120
|
let tmpHTML = '<table class="ultravisor-operation-table">';
|
|
111
|
-
tmpHTML += '<thead><tr><th>
|
|
121
|
+
tmpHTML += '<thead><tr><th>Hash</th><th>Name</th><th>Nodes</th><th>Actions</th></tr></thead>';
|
|
112
122
|
tmpHTML += '<tbody>';
|
|
113
123
|
|
|
114
124
|
for (let i = 0; i < tmpOpList.length; i++)
|
|
115
125
|
{
|
|
116
126
|
let tmpOp = tmpOpList[i];
|
|
117
|
-
let
|
|
118
|
-
let tmpName = tmpOp.Name ||
|
|
119
|
-
let
|
|
120
|
-
let
|
|
127
|
+
let tmpHash = tmpOp.Hash || '';
|
|
128
|
+
let tmpName = tmpOp.Name || tmpHash;
|
|
129
|
+
let tmpNodeCount = (tmpOp.Graph && tmpOp.Graph.Nodes) ? tmpOp.Graph.Nodes.length : 0;
|
|
130
|
+
let tmpEscHash = tmpHash.replace(/'/g, "\\'");
|
|
121
131
|
|
|
122
132
|
tmpHTML += '<tr>';
|
|
123
|
-
tmpHTML += '<td><code>' +
|
|
124
|
-
tmpHTML += '<td>' + tmpName + '</td>';
|
|
125
|
-
tmpHTML += '<td><span class="ultravisor-operation-
|
|
133
|
+
tmpHTML += '<td><code>' + this.escapeHTML(tmpHash) + '</code></td>';
|
|
134
|
+
tmpHTML += '<td>' + this.escapeHTML(tmpName) + '</td>';
|
|
135
|
+
tmpHTML += '<td><span class="ultravisor-operation-node-count">' + tmpNodeCount + ' node' + (tmpNodeCount !== 1 ? 's' : '') + '</span></td>';
|
|
126
136
|
tmpHTML += '<td><div class="ultravisor-task-actions">';
|
|
127
|
-
tmpHTML += '<button class="ultravisor-btn-sm ultravisor-btn-execute" onclick="' + tmpGlobalRef + '.
|
|
128
|
-
tmpHTML += '<button class="ultravisor-btn-sm ultravisor-btn-edit" onclick="' + tmpGlobalRef + '.PictApplication.editOperation(\'' +
|
|
129
|
-
tmpHTML += '<button class="ultravisor-btn-sm ultravisor-btn-delete" onclick="if(confirm(\'Delete operation ' +
|
|
137
|
+
tmpHTML += '<button class="ultravisor-btn-sm ultravisor-btn-execute" onclick="' + tmpGlobalRef + '.views[\'Ultravisor-OperationList\'].runOperation(\'' + tmpEscHash + '\')">Run</button>';
|
|
138
|
+
tmpHTML += '<button class="ultravisor-btn-sm ultravisor-btn-edit" onclick="' + tmpGlobalRef + '.PictApplication.editOperation(\'' + tmpEscHash + '\')">Edit</button>';
|
|
139
|
+
tmpHTML += '<button class="ultravisor-btn-sm ultravisor-btn-delete" onclick="if(confirm(\'Delete operation ' + tmpEscHash + '?\')){ ' + tmpGlobalRef + '.PictApplication.deleteOperation(\'' + tmpEscHash + '\', function(){ ' + tmpGlobalRef + '.PictApplication.showView(\'Ultravisor-OperationList\'); }); }">Delete</button>';
|
|
130
140
|
tmpHTML += '</div></td>';
|
|
131
141
|
tmpHTML += '</tr>';
|
|
132
142
|
}
|
|
@@ -134,6 +144,111 @@ class UltravisorOperationListView extends libPictView
|
|
|
134
144
|
tmpHTML += '</tbody></table>';
|
|
135
145
|
this.pict.ContentAssignment.assignContent('#Ultravisor-OperationList-Body', tmpHTML);
|
|
136
146
|
}
|
|
147
|
+
|
|
148
|
+
runOperation(pHash)
|
|
149
|
+
{
|
|
150
|
+
this.pict.ContentAssignment.assignContent('#Ultravisor-OperationList-Result',
|
|
151
|
+
'<div class="ultravisor-task-result-panel"><h3>Running operation ' + this.escapeHTML(pHash) + '...</h3></div>');
|
|
152
|
+
|
|
153
|
+
this.pict.PictApplication.executeOperation(pHash,
|
|
154
|
+
function (pError, pData)
|
|
155
|
+
{
|
|
156
|
+
if (pError)
|
|
157
|
+
{
|
|
158
|
+
this.pict.ContentAssignment.assignContent('#Ultravisor-OperationList-Result',
|
|
159
|
+
'<div class="ultravisor-task-result-panel"><h3>Error</h3><p style="color:#ef5350;">' + this.escapeHTML(pError.message) + '</p></div>');
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
let tmpHTML = '<div class="ultravisor-task-result-panel">';
|
|
164
|
+
tmpHTML += '<h3>Operation Result: ' + this.escapeHTML(pHash) + '</h3>';
|
|
165
|
+
tmpHTML += '<p><strong>Status:</strong> <span class="ultravisor-manifest-status ' + (pData.Status || '').toLowerCase() + '">' + this.escapeHTML(pData.Status || '') + '</span></p>';
|
|
166
|
+
tmpHTML += '<p><strong>Start:</strong> ' + this.escapeHTML(pData.StartTime || '') + ' · <strong>Stop:</strong> ' + this.escapeHTML(pData.StopTime || '') + '</p>';
|
|
167
|
+
tmpHTML += '<p><strong>Elapsed:</strong> ' + (pData.ElapsedMs || 0) + 'ms</p>';
|
|
168
|
+
|
|
169
|
+
if (pData.TaskOutputs)
|
|
170
|
+
{
|
|
171
|
+
tmpHTML += '<h4 style="color:#b0bec5; margin:0.75em 0 0.25em 0;">Task Outputs</h4>';
|
|
172
|
+
tmpHTML += '<div class="ultravisor-task-result-output">' + this.escapeHTML(JSON.stringify(pData.TaskOutputs, null, 2)) + '</div>';
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (pData.Log && pData.Log.length > 0)
|
|
176
|
+
{
|
|
177
|
+
tmpHTML += '<h4 style="color:#b0bec5; margin:0.75em 0 0.25em 0;">Log</h4>';
|
|
178
|
+
tmpHTML += '<div class="ultravisor-task-result-output">' + this.escapeHTML(pData.Log.join('\n')) + '</div>';
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
tmpHTML += '</div>';
|
|
182
|
+
this.pict.ContentAssignment.assignContent('#Ultravisor-OperationList-Result', tmpHTML);
|
|
183
|
+
}.bind(this));
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
createExampleOperation(pExampleName)
|
|
187
|
+
{
|
|
188
|
+
let tmpFlowData = null;
|
|
189
|
+
let tmpName = '';
|
|
190
|
+
let tmpDescription = '';
|
|
191
|
+
|
|
192
|
+
if (pExampleName === 'CSVPipeline')
|
|
193
|
+
{
|
|
194
|
+
tmpFlowData = libExampleCSVPipeline;
|
|
195
|
+
tmpName = 'Example: Config Processor';
|
|
196
|
+
tmpDescription = 'File-based config processing with branching and error handling.';
|
|
197
|
+
}
|
|
198
|
+
else if (pExampleName === 'MeadowPipeline')
|
|
199
|
+
{
|
|
200
|
+
tmpFlowData = libExampleMeadowPipeline;
|
|
201
|
+
tmpName = 'Example: Template Processor';
|
|
202
|
+
tmpDescription = 'Multi-step text processing with chained replacements and conditional validation.';
|
|
203
|
+
}
|
|
204
|
+
else if (pExampleName === 'FileProcessor')
|
|
205
|
+
{
|
|
206
|
+
tmpFlowData = libExampleFileProcessor;
|
|
207
|
+
tmpName = 'Example: File Processor';
|
|
208
|
+
tmpDescription = 'Search and replace pipeline with user input, looping, and file I/O.';
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (!tmpFlowData)
|
|
212
|
+
{
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
let tmpOpData =
|
|
217
|
+
{
|
|
218
|
+
Name: tmpName,
|
|
219
|
+
Description: tmpDescription,
|
|
220
|
+
Graph:
|
|
221
|
+
{
|
|
222
|
+
Nodes: JSON.parse(JSON.stringify(tmpFlowData.Nodes)),
|
|
223
|
+
Connections: JSON.parse(JSON.stringify(tmpFlowData.Connections)),
|
|
224
|
+
ViewState: tmpFlowData.ViewState ? JSON.parse(JSON.stringify(tmpFlowData.ViewState)) : {}
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
this.pict.PictApplication.saveOperation(tmpOpData,
|
|
229
|
+
function (pError, pData)
|
|
230
|
+
{
|
|
231
|
+
if (pError)
|
|
232
|
+
{
|
|
233
|
+
this.pict.ContentAssignment.assignContent('#Ultravisor-OperationList-Result',
|
|
234
|
+
'<div class="ultravisor-task-result-panel"><p style="color:#ef5350;">Error creating example: ' + this.escapeHTML(pError.message) + '</p></div>');
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Reload the operation list
|
|
239
|
+
this.pict.PictApplication.loadOperations(
|
|
240
|
+
function ()
|
|
241
|
+
{
|
|
242
|
+
this.renderOperationTable();
|
|
243
|
+
}.bind(this));
|
|
244
|
+
}.bind(this));
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
escapeHTML(pValue)
|
|
248
|
+
{
|
|
249
|
+
if (!pValue) return '';
|
|
250
|
+
return String(pValue).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
251
|
+
}
|
|
137
252
|
}
|
|
138
253
|
|
|
139
254
|
module.exports = UltravisorOperationListView;
|