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
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
const libPictView = require('pict-view');
|
|
2
|
+
|
|
3
|
+
const _ViewConfiguration =
|
|
4
|
+
{
|
|
5
|
+
ViewIdentifier: "Ultravisor-PendingInput",
|
|
6
|
+
|
|
7
|
+
DefaultRenderable: "Ultravisor-PendingInput-Content",
|
|
8
|
+
DefaultDestinationAddress: "#Ultravisor-Content-Container",
|
|
9
|
+
|
|
10
|
+
AutoRender: false,
|
|
11
|
+
|
|
12
|
+
CSS: /*css*/`
|
|
13
|
+
.ultravisor-pendinginput {
|
|
14
|
+
padding: 2em;
|
|
15
|
+
max-width: 1200px;
|
|
16
|
+
margin: 0 auto;
|
|
17
|
+
}
|
|
18
|
+
.ultravisor-pendinginput-header {
|
|
19
|
+
display: flex;
|
|
20
|
+
justify-content: space-between;
|
|
21
|
+
align-items: center;
|
|
22
|
+
margin-bottom: 1.5em;
|
|
23
|
+
padding-bottom: 1em;
|
|
24
|
+
border-bottom: 1px solid #2a2a4a;
|
|
25
|
+
}
|
|
26
|
+
.ultravisor-pendinginput-header h1 {
|
|
27
|
+
margin: 0;
|
|
28
|
+
font-size: 2em;
|
|
29
|
+
font-weight: 300;
|
|
30
|
+
color: #e0e0e0;
|
|
31
|
+
}
|
|
32
|
+
.ultravisor-pendinginput-card {
|
|
33
|
+
background: #16213e;
|
|
34
|
+
border: 1px solid #f57f17;
|
|
35
|
+
border-radius: 8px;
|
|
36
|
+
padding: 1.5em;
|
|
37
|
+
margin-bottom: 1em;
|
|
38
|
+
}
|
|
39
|
+
.ultravisor-pendinginput-card-header {
|
|
40
|
+
display: flex;
|
|
41
|
+
justify-content: space-between;
|
|
42
|
+
align-items: center;
|
|
43
|
+
margin-bottom: 1em;
|
|
44
|
+
}
|
|
45
|
+
.ultravisor-pendinginput-card-header h3 {
|
|
46
|
+
margin: 0;
|
|
47
|
+
color: #e0e0e0;
|
|
48
|
+
font-weight: 500;
|
|
49
|
+
}
|
|
50
|
+
.ultravisor-pendinginput-meta {
|
|
51
|
+
color: #78909c;
|
|
52
|
+
font-size: 0.85em;
|
|
53
|
+
margin-bottom: 1em;
|
|
54
|
+
}
|
|
55
|
+
.ultravisor-pendinginput-meta code {
|
|
56
|
+
color: #4fc3f7;
|
|
57
|
+
font-size: 0.9em;
|
|
58
|
+
}
|
|
59
|
+
.ultravisor-pendinginput-task {
|
|
60
|
+
background: #1a1a2e;
|
|
61
|
+
border-radius: 4px;
|
|
62
|
+
padding: 1em;
|
|
63
|
+
margin-bottom: 0.75em;
|
|
64
|
+
}
|
|
65
|
+
.ultravisor-pendinginput-prompt {
|
|
66
|
+
color: #fff9c4;
|
|
67
|
+
font-size: 1.1em;
|
|
68
|
+
margin-bottom: 0.75em;
|
|
69
|
+
}
|
|
70
|
+
.ultravisor-pendinginput-address {
|
|
71
|
+
color: #78909c;
|
|
72
|
+
font-size: 0.8em;
|
|
73
|
+
margin-bottom: 0.75em;
|
|
74
|
+
}
|
|
75
|
+
.ultravisor-pendinginput-form {
|
|
76
|
+
display: flex;
|
|
77
|
+
gap: 0.75em;
|
|
78
|
+
align-items: center;
|
|
79
|
+
}
|
|
80
|
+
.ultravisor-pendinginput-form input[type="text"] {
|
|
81
|
+
flex: 1;
|
|
82
|
+
padding: 0.5em 0.75em;
|
|
83
|
+
border: 1px solid #2a2a4a;
|
|
84
|
+
border-radius: 4px;
|
|
85
|
+
background: #0d1117;
|
|
86
|
+
color: #e0e0e0;
|
|
87
|
+
font-size: 1em;
|
|
88
|
+
font-family: monospace;
|
|
89
|
+
}
|
|
90
|
+
.ultravisor-pendinginput-form input[type="text"]:focus {
|
|
91
|
+
outline: none;
|
|
92
|
+
border-color: #f57f17;
|
|
93
|
+
}
|
|
94
|
+
.ultravisor-pendinginput-submit {
|
|
95
|
+
padding: 0.5em 1.25em;
|
|
96
|
+
background-color: #f57f17;
|
|
97
|
+
color: #1a1a2e;
|
|
98
|
+
border: none;
|
|
99
|
+
border-radius: 4px;
|
|
100
|
+
font-weight: 600;
|
|
101
|
+
cursor: pointer;
|
|
102
|
+
font-size: 0.95em;
|
|
103
|
+
}
|
|
104
|
+
.ultravisor-pendinginput-submit:hover {
|
|
105
|
+
background-color: #ff8f00;
|
|
106
|
+
}
|
|
107
|
+
.ultravisor-pendinginput-submit:disabled {
|
|
108
|
+
opacity: 0.5;
|
|
109
|
+
cursor: not-allowed;
|
|
110
|
+
}
|
|
111
|
+
.ultravisor-pendinginput-result {
|
|
112
|
+
margin-top: 0.75em;
|
|
113
|
+
padding: 0.5em 0.75em;
|
|
114
|
+
border-radius: 4px;
|
|
115
|
+
font-size: 0.85em;
|
|
116
|
+
}
|
|
117
|
+
.ultravisor-pendinginput-result.success {
|
|
118
|
+
background: #1b5e20;
|
|
119
|
+
color: #c8e6c9;
|
|
120
|
+
}
|
|
121
|
+
.ultravisor-pendinginput-result.error {
|
|
122
|
+
background: #b71c1c;
|
|
123
|
+
color: #ffcdd2;
|
|
124
|
+
}
|
|
125
|
+
`,
|
|
126
|
+
|
|
127
|
+
Templates:
|
|
128
|
+
[
|
|
129
|
+
{
|
|
130
|
+
Hash: "Ultravisor-PendingInput-Template",
|
|
131
|
+
Template: /*html*/`
|
|
132
|
+
<div class="ultravisor-pendinginput">
|
|
133
|
+
<div class="ultravisor-pendinginput-header">
|
|
134
|
+
<h1>Pending Input</h1>
|
|
135
|
+
<button class="ultravisor-btn ultravisor-btn-secondary" onclick="{~P~}.PictApplication.showView('Ultravisor-PendingInput')">Refresh</button>
|
|
136
|
+
</div>
|
|
137
|
+
<div id="Ultravisor-PendingInput-Body"></div>
|
|
138
|
+
</div>
|
|
139
|
+
`
|
|
140
|
+
}
|
|
141
|
+
],
|
|
142
|
+
|
|
143
|
+
Renderables:
|
|
144
|
+
[
|
|
145
|
+
{
|
|
146
|
+
RenderableHash: "Ultravisor-PendingInput-Content",
|
|
147
|
+
TemplateHash: "Ultravisor-PendingInput-Template",
|
|
148
|
+
DestinationAddress: "#Ultravisor-Content-Container",
|
|
149
|
+
RenderMethod: "replace"
|
|
150
|
+
}
|
|
151
|
+
]
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
class UltravisorPendingInputView extends libPictView
|
|
155
|
+
{
|
|
156
|
+
constructor(pFable, pOptions, pServiceHash)
|
|
157
|
+
{
|
|
158
|
+
super(pFable, pOptions, pServiceHash);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
onAfterRender(pRenderable, pRenderDestinationAddress, pRecord, pContent)
|
|
162
|
+
{
|
|
163
|
+
this.pict.PictApplication.loadPendingInputs(
|
|
164
|
+
function ()
|
|
165
|
+
{
|
|
166
|
+
this.renderPendingInputs();
|
|
167
|
+
}.bind(this));
|
|
168
|
+
|
|
169
|
+
return super.onAfterRender(pRenderable, pRenderDestinationAddress, pRecord, pContent);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
renderPendingInputs()
|
|
173
|
+
{
|
|
174
|
+
let tmpPendingInputs = this.pict.AppData.Ultravisor.PendingInputs;
|
|
175
|
+
let tmpGlobalRef = '_Pict';
|
|
176
|
+
let tmpViewRef = tmpGlobalRef + ".views['Ultravisor-PendingInput']";
|
|
177
|
+
|
|
178
|
+
if (!tmpPendingInputs || tmpPendingInputs.length === 0)
|
|
179
|
+
{
|
|
180
|
+
this.pict.ContentAssignment.assignContent('#Ultravisor-PendingInput-Body',
|
|
181
|
+
'<div class="ultravisor-empty-message">No operations waiting for input.</div>');
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
let tmpHTML = '';
|
|
186
|
+
|
|
187
|
+
for (let i = 0; i < tmpPendingInputs.length; i++)
|
|
188
|
+
{
|
|
189
|
+
let tmpPending = tmpPendingInputs[i];
|
|
190
|
+
let tmpRunHash = tmpPending.RunHash || '';
|
|
191
|
+
let tmpEscRunHash = tmpRunHash.replace(/'/g, "\\'");
|
|
192
|
+
|
|
193
|
+
tmpHTML += '<div class="ultravisor-pendinginput-card">';
|
|
194
|
+
tmpHTML += '<div class="ultravisor-pendinginput-card-header">';
|
|
195
|
+
tmpHTML += '<h3>' + this.escapeHTML(tmpPending.OperationName || tmpPending.OperationHash || 'Unknown') + '</h3>';
|
|
196
|
+
tmpHTML += '<span class="ultravisor-manifest-status waiting">Waiting for Input</span>';
|
|
197
|
+
tmpHTML += '</div>';
|
|
198
|
+
tmpHTML += '<div class="ultravisor-pendinginput-meta">';
|
|
199
|
+
tmpHTML += 'Operation: <code>' + this.escapeHTML(tmpPending.OperationHash || '') + '</code>';
|
|
200
|
+
tmpHTML += ' · Run: <code>' + this.escapeHTML(tmpRunHash) + '</code>';
|
|
201
|
+
if (tmpPending.StartTime)
|
|
202
|
+
{
|
|
203
|
+
tmpHTML += ' · Started: ' + this.escapeHTML(tmpPending.StartTime);
|
|
204
|
+
}
|
|
205
|
+
tmpHTML += '</div>';
|
|
206
|
+
|
|
207
|
+
// Render each waiting task
|
|
208
|
+
let tmpWaitingTasks = tmpPending.WaitingTasks || {};
|
|
209
|
+
let tmpNodeHashes = Object.keys(tmpWaitingTasks);
|
|
210
|
+
|
|
211
|
+
for (let j = 0; j < tmpNodeHashes.length; j++)
|
|
212
|
+
{
|
|
213
|
+
let tmpNodeHash = tmpNodeHashes[j];
|
|
214
|
+
let tmpEscNodeHash = tmpNodeHash.replace(/'/g, "\\'");
|
|
215
|
+
let tmpTask = tmpWaitingTasks[tmpNodeHash];
|
|
216
|
+
let tmpInputId = 'pending-input-' + tmpRunHash + '-' + tmpNodeHash;
|
|
217
|
+
let tmpResultId = 'pending-result-' + tmpRunHash + '-' + tmpNodeHash;
|
|
218
|
+
|
|
219
|
+
tmpHTML += '<div class="ultravisor-pendinginput-task">';
|
|
220
|
+
tmpHTML += '<div class="ultravisor-pendinginput-prompt">' + this.escapeHTML(tmpTask.PromptMessage || 'Enter a value') + '</div>';
|
|
221
|
+
if (tmpTask.OutputAddress)
|
|
222
|
+
{
|
|
223
|
+
tmpHTML += '<div class="ultravisor-pendinginput-address">Target: <code>' + this.escapeHTML(tmpTask.OutputAddress) + '</code></div>';
|
|
224
|
+
}
|
|
225
|
+
tmpHTML += '<div class="ultravisor-pendinginput-form">';
|
|
226
|
+
tmpHTML += '<input type="text" id="' + tmpInputId + '" placeholder="Enter value..." />';
|
|
227
|
+
tmpHTML += '<button class="ultravisor-pendinginput-submit" onclick="' + tmpViewRef + '.submitInput(\'' + tmpEscRunHash + '\', \'' + tmpEscNodeHash + '\', \'' + tmpInputId + '\', \'' + tmpResultId + '\')">Submit</button>';
|
|
228
|
+
tmpHTML += '</div>';
|
|
229
|
+
tmpHTML += '<div id="' + tmpResultId + '"></div>';
|
|
230
|
+
tmpHTML += '</div>';
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
tmpHTML += '</div>';
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
this.pict.ContentAssignment.assignContent('#Ultravisor-PendingInput-Body', tmpHTML);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
submitInput(pRunHash, pNodeHash, pInputId, pResultId)
|
|
240
|
+
{
|
|
241
|
+
let tmpInputEl = document.getElementById(pInputId);
|
|
242
|
+
if (!tmpInputEl)
|
|
243
|
+
{
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
let tmpValue = tmpInputEl.value;
|
|
248
|
+
|
|
249
|
+
// Disable the input and button while submitting
|
|
250
|
+
tmpInputEl.disabled = true;
|
|
251
|
+
let tmpButton = tmpInputEl.parentElement.querySelector('.ultravisor-pendinginput-submit');
|
|
252
|
+
if (tmpButton)
|
|
253
|
+
{
|
|
254
|
+
tmpButton.disabled = true;
|
|
255
|
+
tmpButton.textContent = 'Submitting...';
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
this.pict.PictApplication.submitPendingInput(pRunHash, pNodeHash, tmpValue,
|
|
259
|
+
function (pError, pData)
|
|
260
|
+
{
|
|
261
|
+
if (pError)
|
|
262
|
+
{
|
|
263
|
+
this.pict.ContentAssignment.assignContent('#' + pResultId,
|
|
264
|
+
'<div class="ultravisor-pendinginput-result error">Error: ' + this.escapeHTML(pError.message || 'Request failed') + '</div>');
|
|
265
|
+
// Re-enable
|
|
266
|
+
tmpInputEl.disabled = false;
|
|
267
|
+
if (tmpButton)
|
|
268
|
+
{
|
|
269
|
+
tmpButton.disabled = false;
|
|
270
|
+
tmpButton.textContent = 'Submit';
|
|
271
|
+
}
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (pData && pData.Error)
|
|
276
|
+
{
|
|
277
|
+
this.pict.ContentAssignment.assignContent('#' + pResultId,
|
|
278
|
+
'<div class="ultravisor-pendinginput-result error">Error: ' + this.escapeHTML(pData.Error) + '</div>');
|
|
279
|
+
tmpInputEl.disabled = false;
|
|
280
|
+
if (tmpButton)
|
|
281
|
+
{
|
|
282
|
+
tmpButton.disabled = false;
|
|
283
|
+
tmpButton.textContent = 'Submit';
|
|
284
|
+
}
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
let tmpStatus = (pData && pData.Status) || 'Submitted';
|
|
289
|
+
this.pict.ContentAssignment.assignContent('#' + pResultId,
|
|
290
|
+
'<div class="ultravisor-pendinginput-result success">Input submitted — operation status: ' + this.escapeHTML(tmpStatus) + '</div>');
|
|
291
|
+
|
|
292
|
+
// Refresh the list after a brief delay so the user sees the success message
|
|
293
|
+
setTimeout(
|
|
294
|
+
function ()
|
|
295
|
+
{
|
|
296
|
+
this.pict.PictApplication.loadPendingInputs(
|
|
297
|
+
function ()
|
|
298
|
+
{
|
|
299
|
+
this.renderPendingInputs();
|
|
300
|
+
}.bind(this));
|
|
301
|
+
}.bind(this), 1500);
|
|
302
|
+
}.bind(this));
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
escapeHTML(pValue)
|
|
306
|
+
{
|
|
307
|
+
if (!pValue) return '';
|
|
308
|
+
return String(pValue).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
module.exports = UltravisorPendingInputView;
|
|
313
|
+
|
|
314
|
+
module.exports.default_configuration = _ViewConfiguration;
|
|
@@ -156,7 +156,7 @@ class UltravisorScheduleView extends libPictView
|
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
let tmpHTML = '<table class="ultravisor-schedule-table">';
|
|
159
|
-
tmpHTML += '<thead><tr><th>GUID</th><th>Type</th><th>Target</th><th>Cron</th><th>Active</th><th>Actions</th></tr></thead>';
|
|
159
|
+
tmpHTML += '<thead><tr><th>GUID</th><th>Type</th><th>Target Hash</th><th>Cron</th><th>Active</th><th>Actions</th></tr></thead>';
|
|
160
160
|
tmpHTML += '<tbody>';
|
|
161
161
|
|
|
162
162
|
for (let i = 0; i < tmpSchedule.length; i++)
|
|
@@ -167,10 +167,10 @@ class UltravisorScheduleView extends libPictView
|
|
|
167
167
|
let tmpActive = tmpEntry.Active ? 'yes' : 'no';
|
|
168
168
|
|
|
169
169
|
tmpHTML += '<tr>';
|
|
170
|
-
tmpHTML += '<td><code style="font-size:0.8em;">' + tmpGUID + '</code></td>';
|
|
171
|
-
tmpHTML += '<td>' + (tmpEntry.TargetType || '') + '</td>';
|
|
172
|
-
tmpHTML += '<td><code>' + (tmpEntry.
|
|
173
|
-
tmpHTML += '<td><code>' + (tmpEntry.CronExpression || tmpEntry.Parameters || '') + '</code></td>';
|
|
170
|
+
tmpHTML += '<td><code style="font-size:0.8em;">' + this.escapeHTML(tmpGUID) + '</code></td>';
|
|
171
|
+
tmpHTML += '<td>' + this.escapeHTML(tmpEntry.TargetType || '') + '</td>';
|
|
172
|
+
tmpHTML += '<td><code>' + this.escapeHTML(tmpEntry.TargetHash || '') + '</code></td>';
|
|
173
|
+
tmpHTML += '<td><code>' + this.escapeHTML(tmpEntry.CronExpression || tmpEntry.Parameters || '') + '</code></td>';
|
|
174
174
|
tmpHTML += '<td><span class="ultravisor-schedule-active ' + tmpActive + '">' + (tmpEntry.Active ? 'Active' : 'Inactive') + '</span></td>';
|
|
175
175
|
tmpHTML += '<td>';
|
|
176
176
|
tmpHTML += '<button class="ultravisor-btn-sm ultravisor-btn-delete" onclick="if(confirm(\'Remove schedule entry?\')){ ' + tmpGlobalRef + '.PictApplication.removeScheduleEntry(\'' + tmpEscGUID + '\', function(){ ' + tmpGlobalRef + '.PictApplication.showView(\'Ultravisor-Schedule\'); }); }">Remove</button>';
|
|
@@ -189,29 +189,12 @@ class UltravisorScheduleView extends libPictView
|
|
|
189
189
|
|
|
190
190
|
let tmpHTML = '';
|
|
191
191
|
|
|
192
|
-
// Schedule a task
|
|
193
|
-
tmpHTML += '<div class="ultravisor-schedule-add-section">';
|
|
194
|
-
tmpHTML += '<h3>Schedule a Task</h3>';
|
|
195
|
-
tmpHTML += '<div class="ultravisor-schedule-add-form">';
|
|
196
|
-
tmpHTML += '<div class="ultravisor-form-group"><label>Task GUID</label>';
|
|
197
|
-
tmpHTML += '<input type="text" id="Ultravisor-Schedule-TaskGUID" placeholder="e.g. MY-TASK-001"></div>';
|
|
198
|
-
tmpHTML += '<div class="ultravisor-form-group"><label>Schedule Type</label>';
|
|
199
|
-
tmpHTML += '<select id="Ultravisor-Schedule-TaskScheduleType">';
|
|
200
|
-
tmpHTML += '<option value="cron">Cron</option>';
|
|
201
|
-
tmpHTML += '<option value="daily">Daily</option>';
|
|
202
|
-
tmpHTML += '<option value="hourly">Hourly</option>';
|
|
203
|
-
tmpHTML += '</select></div>';
|
|
204
|
-
tmpHTML += '<div class="ultravisor-form-group"><label>Parameters (cron expression)</label>';
|
|
205
|
-
tmpHTML += '<input type="text" id="Ultravisor-Schedule-TaskParameters" placeholder="e.g. 0 * * * *"></div>';
|
|
206
|
-
tmpHTML += '<button class="ultravisor-btn ultravisor-btn-primary" onclick="' + tmpViewRef + '.addTaskSchedule()">Add</button>';
|
|
207
|
-
tmpHTML += '</div></div>';
|
|
208
|
-
|
|
209
192
|
// Schedule an operation
|
|
210
|
-
tmpHTML += '<div class="ultravisor-schedule-add-section"
|
|
193
|
+
tmpHTML += '<div class="ultravisor-schedule-add-section">';
|
|
211
194
|
tmpHTML += '<h3>Schedule an Operation</h3>';
|
|
212
195
|
tmpHTML += '<div class="ultravisor-schedule-add-form">';
|
|
213
|
-
tmpHTML += '<div class="ultravisor-form-group"><label>Operation
|
|
214
|
-
tmpHTML += '<input type="text" id="Ultravisor-Schedule-
|
|
196
|
+
tmpHTML += '<div class="ultravisor-form-group"><label>Operation Hash</label>';
|
|
197
|
+
tmpHTML += '<input type="text" id="Ultravisor-Schedule-OperationHash" placeholder="e.g. OPR-0001"></div>';
|
|
215
198
|
tmpHTML += '<div class="ultravisor-form-group"><label>Schedule Type</label>';
|
|
216
199
|
tmpHTML += '<select id="Ultravisor-Schedule-OperationScheduleType">';
|
|
217
200
|
tmpHTML += '<option value="cron">Cron</option>';
|
|
@@ -226,43 +209,19 @@ class UltravisorScheduleView extends libPictView
|
|
|
226
209
|
this.pict.ContentAssignment.assignContent('#Ultravisor-Schedule-AddForms', tmpHTML);
|
|
227
210
|
}
|
|
228
211
|
|
|
229
|
-
addTaskSchedule()
|
|
230
|
-
{
|
|
231
|
-
let tmpGUID = document.getElementById('Ultravisor-Schedule-TaskGUID').value.trim();
|
|
232
|
-
let tmpType = document.getElementById('Ultravisor-Schedule-TaskScheduleType').value;
|
|
233
|
-
let tmpParams = document.getElementById('Ultravisor-Schedule-TaskParameters').value.trim();
|
|
234
|
-
|
|
235
|
-
if (!tmpGUID)
|
|
236
|
-
{
|
|
237
|
-
alert('Task GUID is required.');
|
|
238
|
-
return;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
this.pict.PictApplication.scheduleTask(tmpGUID, tmpType, tmpParams,
|
|
242
|
-
function (pError)
|
|
243
|
-
{
|
|
244
|
-
if (pError)
|
|
245
|
-
{
|
|
246
|
-
alert('Error scheduling task: ' + pError.message);
|
|
247
|
-
return;
|
|
248
|
-
}
|
|
249
|
-
this.pict.PictApplication.showView('Ultravisor-Schedule');
|
|
250
|
-
}.bind(this));
|
|
251
|
-
}
|
|
252
|
-
|
|
253
212
|
addOperationSchedule()
|
|
254
213
|
{
|
|
255
|
-
let
|
|
214
|
+
let tmpHash = document.getElementById('Ultravisor-Schedule-OperationHash').value.trim();
|
|
256
215
|
let tmpType = document.getElementById('Ultravisor-Schedule-OperationScheduleType').value;
|
|
257
216
|
let tmpParams = document.getElementById('Ultravisor-Schedule-OperationParameters').value.trim();
|
|
258
217
|
|
|
259
|
-
if (!
|
|
218
|
+
if (!tmpHash)
|
|
260
219
|
{
|
|
261
|
-
alert('Operation
|
|
220
|
+
alert('Operation Hash is required.');
|
|
262
221
|
return;
|
|
263
222
|
}
|
|
264
223
|
|
|
265
|
-
this.pict.PictApplication.scheduleOperation(
|
|
224
|
+
this.pict.PictApplication.scheduleOperation(tmpHash, tmpType, tmpParams,
|
|
266
225
|
function (pError)
|
|
267
226
|
{
|
|
268
227
|
if (pError)
|
|
@@ -273,6 +232,12 @@ class UltravisorScheduleView extends libPictView
|
|
|
273
232
|
this.pict.PictApplication.showView('Ultravisor-Schedule');
|
|
274
233
|
}.bind(this));
|
|
275
234
|
}
|
|
235
|
+
|
|
236
|
+
escapeHTML(pValue)
|
|
237
|
+
{
|
|
238
|
+
if (!pValue) return '';
|
|
239
|
+
return String(pValue).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
240
|
+
}
|
|
276
241
|
}
|
|
277
242
|
|
|
278
243
|
module.exports = UltravisorScheduleView;
|
|
@@ -235,26 +235,26 @@ class UltravisorTimingView extends libPictView
|
|
|
235
235
|
for (let i = tmpManifests.length - 1; i >= 0; i--)
|
|
236
236
|
{
|
|
237
237
|
let tmpManifest = tmpManifests[i];
|
|
238
|
-
let
|
|
239
|
-
let tmpLabel = (tmpManifest.
|
|
238
|
+
let tmpRunHash = tmpManifest.Hash || '';
|
|
239
|
+
let tmpLabel = (tmpManifest.OperationHash || tmpRunHash);
|
|
240
240
|
let tmpStatus = tmpManifest.Status || 'Unknown';
|
|
241
241
|
let tmpTime = tmpManifest.StartTime ? tmpManifest.StartTime.replace('T', ' ').replace(/\.\d+Z$/, '') : '';
|
|
242
|
-
tmpHTML += '<option value="' + this.escapeHTML(
|
|
242
|
+
tmpHTML += '<option value="' + this.escapeHTML(tmpRunHash) + '">' + this.escapeHTML(tmpLabel) + ' [' + tmpStatus + '] ' + tmpTime + '</option>';
|
|
243
243
|
}
|
|
244
244
|
|
|
245
245
|
tmpHTML += '</select>';
|
|
246
246
|
this.pict.ContentAssignment.assignContent('#Ultravisor-Timing-Selector', tmpHTML);
|
|
247
247
|
}
|
|
248
248
|
|
|
249
|
-
onSelectManifest(
|
|
249
|
+
onSelectManifest(pRunHash)
|
|
250
250
|
{
|
|
251
|
-
if (!
|
|
251
|
+
if (!pRunHash)
|
|
252
252
|
{
|
|
253
253
|
this.pict.ContentAssignment.assignContent('#Ultravisor-Timing-Detail', '');
|
|
254
254
|
return;
|
|
255
255
|
}
|
|
256
256
|
|
|
257
|
-
this.pict.PictApplication.loadManifest(
|
|
257
|
+
this.pict.PictApplication.loadManifest(pRunHash,
|
|
258
258
|
function (pError, pManifest)
|
|
259
259
|
{
|
|
260
260
|
if (pError || !pManifest)
|
|
@@ -270,10 +270,22 @@ class UltravisorTimingView extends libPictView
|
|
|
270
270
|
|
|
271
271
|
renderTimingVisualization(pManifest)
|
|
272
272
|
{
|
|
273
|
-
|
|
273
|
+
// Convert TaskManifests object to an array for visualization
|
|
274
|
+
let tmpTaskResults = [];
|
|
275
|
+
if (pManifest.TaskManifests && typeof pManifest.TaskManifests === 'object')
|
|
276
|
+
{
|
|
277
|
+
let tmpKeys = Object.keys(pManifest.TaskManifests);
|
|
278
|
+
for (let k = 0; k < tmpKeys.length; k++)
|
|
279
|
+
{
|
|
280
|
+
let tmpEntry = pManifest.TaskManifests[tmpKeys[k]];
|
|
281
|
+
tmpEntry._NodeHash = tmpKeys[k];
|
|
282
|
+
tmpTaskResults.push(tmpEntry);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
274
286
|
let tmpOperationElapsedMs = pManifest.ElapsedMs || 0;
|
|
275
|
-
let tmpOperationElapsedFormatted =
|
|
276
|
-
let tmpAverageTaskMs =
|
|
287
|
+
let tmpOperationElapsedFormatted = this.formatMs(tmpOperationElapsedMs);
|
|
288
|
+
let tmpAverageTaskMs = 0;
|
|
277
289
|
let tmpStatus = (pManifest.Status || 'Unknown').toLowerCase();
|
|
278
290
|
let tmpStatusClass = (tmpStatus === 'complete' || tmpStatus === 'error' || tmpStatus === 'running') ? tmpStatus : '';
|
|
279
291
|
|
|
@@ -287,8 +299,8 @@ class UltravisorTimingView extends libPictView
|
|
|
287
299
|
tmpOperationElapsedFormatted = this.formatMs(tmpOperationElapsedMs);
|
|
288
300
|
}
|
|
289
301
|
|
|
290
|
-
// Compute average
|
|
291
|
-
if (
|
|
302
|
+
// Compute average
|
|
303
|
+
if (tmpTaskResults.length > 0 && tmpOperationElapsedMs > 0)
|
|
292
304
|
{
|
|
293
305
|
tmpAverageTaskMs = tmpOperationElapsedMs / tmpTaskResults.length;
|
|
294
306
|
}
|
|
@@ -312,7 +324,7 @@ class UltravisorTimingView extends libPictView
|
|
|
312
324
|
|
|
313
325
|
// Summary header
|
|
314
326
|
tmpHTML += '<div class="ultravisor-timing-summary">';
|
|
315
|
-
tmpHTML += '<div class="ultravisor-timing-stat"><span class="ultravisor-timing-stat-label">Operation</span><span class="ultravisor-timing-stat-value">' + this.escapeHTML(pManifest.
|
|
327
|
+
tmpHTML += '<div class="ultravisor-timing-stat"><span class="ultravisor-timing-stat-label">Operation</span><span class="ultravisor-timing-stat-value">' + this.escapeHTML(pManifest.OperationHash || '') + '</span></div>';
|
|
316
328
|
tmpHTML += '<div class="ultravisor-timing-stat"><span class="ultravisor-timing-stat-label">Status</span><span class="ultravisor-timing-stat-value ' + tmpStatusClass + '">' + this.escapeHTML(pManifest.Status || 'Unknown') + '</span></div>';
|
|
317
329
|
tmpHTML += '<div class="ultravisor-timing-stat"><span class="ultravisor-timing-stat-label">Total Time</span><span class="ultravisor-timing-stat-value">' + this.escapeHTML(tmpOperationElapsedFormatted) + '</span></div>';
|
|
318
330
|
tmpHTML += '<div class="ultravisor-timing-stat"><span class="ultravisor-timing-stat-label">Tasks</span><span class="ultravisor-timing-stat-value">' + tmpTaskResults.length + '</span></div>';
|
|
@@ -350,10 +362,11 @@ class UltravisorTimingView extends libPictView
|
|
|
350
362
|
}
|
|
351
363
|
|
|
352
364
|
let tmpWidthPercent = (tmpMaxTaskMs > 0) ? Math.max((tmpTaskMs / tmpMaxTaskMs) * 100, 1) : 1;
|
|
353
|
-
let
|
|
365
|
+
let tmpNodeHash = tmpResult._NodeHash || '';
|
|
366
|
+
let tmpBarLabel = this.escapeHTML(tmpResult.Name || tmpNodeHash || '');
|
|
354
367
|
|
|
355
368
|
tmpHTML += '<div class="ultravisor-timing-row">';
|
|
356
|
-
tmpHTML += '<div class="ultravisor-timing-row-label" title="' + this.escapeHTML(
|
|
369
|
+
tmpHTML += '<div class="ultravisor-timing-row-label" title="' + this.escapeHTML(tmpNodeHash) + '">' + this.escapeHTML(tmpResult.Name || tmpNodeHash || 'Task ' + (i + 1)) + '</div>';
|
|
357
370
|
tmpHTML += '<div class="ultravisor-timing-row-bar-container">';
|
|
358
371
|
tmpHTML += '<div class="ultravisor-timing-row-bar ' + tmpBarClass + '" style="width: ' + tmpWidthPercent.toFixed(1) + '%;">';
|
|
359
372
|
if (tmpWidthPercent > 20)
|
|
@@ -82,11 +82,12 @@ const _ViewConfiguration =
|
|
|
82
82
|
<a class="ultravisor-topbar-brand" onclick="{~P~}.PictApplication.navigateTo('/Home')">Ultravisor</a>
|
|
83
83
|
<div class="ultravisor-topbar-nav">
|
|
84
84
|
<a onclick="{~P~}.PictApplication.navigateTo('/Home')">Dashboard</a>
|
|
85
|
-
<a onclick="{~P~}.PictApplication.navigateTo('/Tasks')">Tasks</a>
|
|
86
85
|
<a onclick="{~P~}.PictApplication.navigateTo('/Operations')">Operations</a>
|
|
87
86
|
<a onclick="{~P~}.PictApplication.navigateTo('/Schedule')">Schedule</a>
|
|
88
87
|
<a onclick="{~P~}.PictApplication.navigateTo('/Manifests')">Manifests</a>
|
|
88
|
+
<a onclick="{~P~}.PictApplication.navigateTo('/PendingInput')">Pending Input</a>
|
|
89
89
|
<a onclick="{~P~}.PictApplication.navigateTo('/Timing')">Timing</a>
|
|
90
|
+
<a onclick="{~P~}.PictApplication.editOperation()">Flow Editor</a>
|
|
90
91
|
</div>
|
|
91
92
|
<div class="ultravisor-topbar-status" id="Ultravisor-TopBar-StatusArea"></div>
|
|
92
93
|
</div>
|
package/.babelrc
DELETED
package/.browserslistrc
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
> 0.01%
|
package/.browserslistrc-BACKUP
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
since 2018
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"EntrypointInputSourceFile": "/Users/stevenvelozo/Code/retold/modules/utility/ultravisor/source/Ultravisor.js",
|
|
3
|
-
"LibraryObjectName": "Ultravisor",
|
|
4
|
-
"LibraryOutputFolder": "/Users/stevenvelozo/Code/retold/modules/utility/ultravisor/dist/",
|
|
5
|
-
"LibraryUniminifiedFileName": "ultravisor.compatible.js",
|
|
6
|
-
"LibraryMinifiedFileName": "ultravisor.compatible.min.js"
|
|
7
|
-
}
|
package/.gulpfile-quackage.js
DELETED