ultravisor 1.0.3 → 1.0.8
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/card-audit.json +1545 -0
- package/docs/_sidebar.md +17 -0
- package/docs/css/docuserve.css +73 -0
- package/docs/features/beacon-authentication.md +209 -0
- package/docs/features/beacon-providers.md +1299 -0
- package/docs/features/beacons.md +530 -0
- package/docs/features/capabilities.md +193 -0
- package/docs/features/llm-model-setup.md +505 -0
- package/docs/features/llm.md +262 -0
- package/docs/features/tasks-content-system.md +110 -0
- package/docs/features/tasks-data-transform.md +233 -0
- package/docs/features/tasks-extension.md +36 -0
- package/docs/features/tasks-file-system.md +203 -0
- package/docs/features/tasks-flow-control.md +125 -0
- package/docs/features/tasks-http-client.md +119 -0
- package/docs/features/tasks-llm.md +118 -0
- package/docs/features/tasks-meadow-api.md +163 -0
- package/docs/features/tasks-user-interaction.md +49 -0
- package/docs/features/tasks.md +14 -0
- package/docs/index.html +1 -1
- package/docs/retold-catalog.json +1 -1
- package/docs/retold-keyword-index.json +17374 -5
- package/operation-library/api-data-pipeline.json +143 -0
- package/operation-library/beacon-remote-command.json +72 -0
- package/operation-library/conditional-file-backup.json +143 -0
- package/operation-library/config-processor.json +136 -0
- package/operation-library/csv-data-analysis.json +228 -0
- package/operation-library/csv-to-json.json +160 -0
- package/operation-library/directory-inventory.json +128 -0
- package/operation-library/expression-calculator.json +114 -0
- package/operation-library/file-search-replace.json +175 -0
- package/operation-library/git-status-report.json +368 -0
- package/operation-library/health-check-ping.json +329 -0
- package/operation-library/json-config-merge.json +313 -0
- package/operation-library/llm-embedding-tool-use.json +314 -0
- package/operation-library/llm-multi-turn-analysis.json +322 -0
- package/operation-library/llm-summarize.json +264 -0
- package/operation-library/log-line-counter.json +185 -0
- package/operation-library/meadow-crud-lifecycle.json +264 -0
- package/operation-library/npm-project-validator.json +193 -0
- package/operation-library/rest-api-orchestrator.json +218 -0
- package/operation-library/shell-system-info.json +137 -0
- package/operation-library/simple-echo.json +95 -0
- package/operation-library/template-processor.json +299 -0
- package/operation-library/text-sanitizer.json +176 -0
- package/package.json +12 -8
- package/source/Ultravisor.cjs +30 -3
- package/source/beacon/Ultravisor-Beacon-CLI.cjs +143 -0
- package/source/beacon/Ultravisor-Beacon-CapabilityProvider.cjs +129 -0
- package/source/beacon/Ultravisor-Beacon-Client.cjs +568 -0
- package/source/beacon/Ultravisor-Beacon-Executor.cjs +500 -0
- package/source/beacon/Ultravisor-Beacon-ProviderRegistry.cjs +330 -0
- package/source/beacon/providers/Ultravisor-Beacon-Provider-FileSystem.cjs +331 -0
- package/source/beacon/providers/Ultravisor-Beacon-Provider-LLM.cjs +966 -0
- package/source/beacon/providers/Ultravisor-Beacon-Provider-Shell.cjs +95 -0
- package/source/cli/Ultravisor-CLIProgram.cjs +44 -22
- 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 +12 -3
- package/source/services/Ultravisor-Beacon-Coordinator.cjs +966 -0
- package/source/services/Ultravisor-ExecutionEngine.cjs +1093 -0
- package/source/services/Ultravisor-ExecutionManifest.cjs +629 -0
- package/source/services/Ultravisor-Hypervisor-State.cjs +270 -97
- package/source/services/Ultravisor-Hypervisor.cjs +185 -75
- package/source/services/Ultravisor-Schedule-Persistence-Base.cjs +45 -0
- package/source/services/Ultravisor-StateManager.cjs +253 -0
- package/source/services/Ultravisor-TaskTypeRegistry.cjs +213 -0
- package/source/services/persistence/Ultravisor-Schedule-Persistence-JSONFile.cjs +140 -0
- package/source/services/tasks/Ultravisor-BuiltIn-TaskConfigs.cjs +19 -0
- package/source/services/tasks/Ultravisor-TaskHelper-BeaconDispatch.cjs +107 -0
- package/source/services/tasks/Ultravisor-TaskType-Base.cjs +125 -0
- package/source/services/tasks/content-system/Ultravisor-TaskConfigs-ContentSystem.cjs +90 -0
- package/source/services/tasks/content-system/definitions/content-create-folder.json +24 -0
- package/source/services/tasks/content-system/definitions/content-list-files.json +27 -0
- package/source/services/tasks/content-system/definitions/content-read-file.json +26 -0
- package/source/services/tasks/content-system/definitions/content-save-file.json +26 -0
- package/source/services/tasks/data-transform/Ultravisor-TaskConfigs-DataTransform.cjs +577 -0
- package/source/services/tasks/data-transform/Ultravisor-TaskType-ReplaceString.cjs +80 -0
- package/source/services/tasks/data-transform/Ultravisor-TaskType-SetValues.cjs +74 -0
- package/source/services/tasks/data-transform/Ultravisor-TaskType-StringAppender.cjs +90 -0
- package/source/services/tasks/data-transform/definitions/comprehension-intersect.json +24 -0
- package/source/services/tasks/data-transform/definitions/csv-transform.json +24 -0
- package/source/services/tasks/data-transform/definitions/expression-solver.json +20 -0
- package/source/services/tasks/data-transform/definitions/histogram.json +23 -0
- package/source/services/tasks/data-transform/definitions/parse-csv.json +27 -0
- package/source/services/tasks/data-transform/definitions/replace-string.json +27 -0
- package/source/services/tasks/data-transform/definitions/set-values.json +17 -0
- package/source/services/tasks/data-transform/definitions/string-appender.json +22 -0
- package/source/services/tasks/data-transform/definitions/template-string.json +20 -0
- package/source/services/tasks/extension/Ultravisor-TaskConfigs-Extension.cjs +87 -0
- package/source/services/tasks/extension/definitions/beacon-dispatch.json +32 -0
- package/source/services/tasks/file-system/Ultravisor-TaskConfigs-FileSystem.cjs +509 -0
- package/source/services/tasks/file-system/Ultravisor-TaskType-ReadFile.cjs +96 -0
- package/source/services/tasks/file-system/Ultravisor-TaskType-ReadFileBuffered.cjs +123 -0
- package/source/services/tasks/file-system/Ultravisor-TaskType-WriteFile.cjs +106 -0
- package/source/services/tasks/file-system/definitions/copy-file.json +27 -0
- package/source/services/tasks/file-system/definitions/list-files.json +27 -0
- package/source/services/tasks/file-system/definitions/read-file-buffered.json +31 -0
- package/source/services/tasks/file-system/definitions/read-file.json +26 -0
- package/source/services/tasks/file-system/definitions/read-json.json +23 -0
- package/source/services/tasks/file-system/definitions/write-file.json +29 -0
- package/source/services/tasks/file-system/definitions/write-json.json +30 -0
- package/source/services/tasks/flow-control/Ultravisor-TaskConfigs-FlowControl.cjs +353 -0
- package/source/services/tasks/flow-control/Ultravisor-TaskType-IfConditional.cjs +125 -0
- package/source/services/tasks/flow-control/Ultravisor-TaskType-LaunchOperation.cjs +186 -0
- package/source/services/tasks/flow-control/Ultravisor-TaskType-SplitExecute.cjs +164 -0
- package/source/services/tasks/flow-control/definitions/if-conditional.json +25 -0
- package/source/services/tasks/flow-control/definitions/launch-operation.json +27 -0
- package/source/services/tasks/flow-control/definitions/split-execute.json +32 -0
- package/source/services/tasks/http-client/Ultravisor-TaskConfigs-HttpClient.cjs +281 -0
- package/source/services/tasks/http-client/definitions/get-json.json +26 -0
- package/source/services/tasks/http-client/definitions/get-text.json +26 -0
- package/source/services/tasks/http-client/definitions/rest-request.json +32 -0
- package/source/services/tasks/http-client/definitions/send-json.json +28 -0
- package/source/services/tasks/llm/Ultravisor-TaskConfigs-LLM.cjs +605 -0
- package/source/services/tasks/llm/definitions/llm-chat-completion.json +46 -0
- package/source/services/tasks/llm/definitions/llm-embedding.json +31 -0
- package/source/services/tasks/llm/definitions/llm-tool-use.json +42 -0
- package/source/services/tasks/meadow-api/Ultravisor-TaskConfigs-MeadowApi.cjs +341 -0
- package/source/services/tasks/meadow-api/definitions/meadow-count.json +26 -0
- package/source/services/tasks/meadow-api/definitions/meadow-create.json +26 -0
- package/source/services/tasks/meadow-api/definitions/meadow-delete.json +23 -0
- package/source/services/tasks/meadow-api/definitions/meadow-read.json +26 -0
- package/source/services/tasks/meadow-api/definitions/meadow-reads.json +29 -0
- package/source/services/tasks/meadow-api/definitions/meadow-update.json +26 -0
- package/source/services/tasks/shell/Ultravisor-TaskConfigs-Shell.cjs +63 -0
- package/source/services/tasks/shell/definitions/command.json +29 -0
- package/source/services/tasks/user-interaction/Ultravisor-TaskConfigs-UserInteraction.cjs +64 -0
- package/source/services/tasks/user-interaction/Ultravisor-TaskType-ErrorMessage.cjs +55 -0
- package/source/services/tasks/user-interaction/Ultravisor-TaskType-ValueInput.cjs +47 -0
- package/source/services/tasks/user-interaction/definitions/error-message.json +18 -0
- package/source/services/tasks/user-interaction/definitions/value-input.json +23 -0
- package/source/web_server/Ultravisor-API-Server.cjs +849 -124
- package/test/Ultravisor_browser_tests.js +2226 -0
- package/test/Ultravisor_operation_library_tests.js +894 -0
- package/test/Ultravisor_tests.js +4946 -5044
- package/test/workflows/test-content-concatenate-all.json +339 -0
- package/test/workflows/test-content-full-pipeline.json +159 -0
- package/test/workflows/test-content-list-files.json +76 -0
- package/test/workflows/test-content-save-and-read.json +106 -0
- package/webinterface/css/ultravisor-themes.css +668 -0
- package/webinterface/css/ultravisor.css +37 -14
- package/webinterface/docs/card-help/beacon-dispatch.md +30 -0
- package/webinterface/docs/card-help/command.md +27 -0
- package/webinterface/docs/card-help/comprehension-intersect.md +24 -0
- package/webinterface/docs/card-help/content-create-folder.md +22 -0
- package/webinterface/docs/card-help/content-list-files.md +25 -0
- package/webinterface/docs/card-help/content-read-file.md +24 -0
- package/webinterface/docs/card-help/content-save-file.md +24 -0
- package/webinterface/docs/card-help/copy-file.md +25 -0
- package/webinterface/docs/card-help/csv-transform.md +24 -0
- package/webinterface/docs/card-help/end.md +11 -0
- package/webinterface/docs/card-help/error-message.md +16 -0
- package/webinterface/docs/card-help/expression-solver.md +21 -0
- package/webinterface/docs/card-help/get-json.md +24 -0
- package/webinterface/docs/card-help/get-text.md +24 -0
- package/webinterface/docs/card-help/histogram.md +23 -0
- package/webinterface/docs/card-help/if-conditional.md +23 -0
- package/webinterface/docs/card-help/launch-operation.md +25 -0
- package/webinterface/docs/card-help/list-files.md +25 -0
- package/webinterface/docs/card-help/llm-chat-completion.md +43 -0
- package/webinterface/docs/card-help/llm-embedding.md +24 -0
- package/webinterface/docs/card-help/llm-tool-use.md +39 -0
- package/webinterface/docs/card-help/meadow-count.md +24 -0
- package/webinterface/docs/card-help/meadow-create.md +24 -0
- package/webinterface/docs/card-help/meadow-delete.md +19 -0
- package/webinterface/docs/card-help/meadow-read.md +24 -0
- package/webinterface/docs/card-help/meadow-reads.md +27 -0
- package/webinterface/docs/card-help/meadow-update.md +24 -0
- package/webinterface/docs/card-help/parse-csv.md +27 -0
- package/webinterface/docs/card-help/read-file-buffered.md +29 -0
- package/webinterface/docs/card-help/read-file.md +24 -0
- package/webinterface/docs/card-help/read-json.md +21 -0
- package/webinterface/docs/card-help/replace-string.md +25 -0
- package/webinterface/docs/card-help/rest-request.md +30 -0
- package/webinterface/docs/card-help/send-json.md +26 -0
- package/webinterface/docs/card-help/set-values.md +16 -0
- package/webinterface/docs/card-help/split-execute.md +35 -0
- package/webinterface/docs/card-help/start.md +11 -0
- package/webinterface/docs/card-help/string-appender.md +22 -0
- package/webinterface/docs/card-help/template-string.md +21 -0
- package/webinterface/docs/card-help/value-input.md +24 -0
- package/webinterface/docs/card-help/write-file.md +27 -0
- package/webinterface/docs/card-help/write-json.md +28 -0
- package/webinterface/html/index.html +5 -0
- package/webinterface/package.json +13 -4
- package/webinterface/source/Pict-Application-Ultravisor.js +564 -70
- package/webinterface/source/Ultravisor-TimingUtils.js +99 -0
- package/webinterface/source/card-help-content.js +46 -0
- package/webinterface/source/cards/Ultravisor-BuiltIn-CardConfigs.js +174 -0
- package/webinterface/source/cards/Ultravisor-CardConfigGenerator.js +431 -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/panels/Ultravisor-CardSettingsPanel.js +902 -0
- package/webinterface/source/providers/PictRouter-Ultravisor-Configuration.json +20 -8
- package/webinterface/source/views/PictView-Ultravisor-BeaconList.js +817 -0
- package/webinterface/source/views/PictView-Ultravisor-BottomBar.js +5 -5
- package/webinterface/source/views/PictView-Ultravisor-Dashboard.js +25 -25
- package/webinterface/source/views/PictView-Ultravisor-Documentation.js +856 -0
- package/webinterface/source/views/PictView-Ultravisor-FlowEditor.js +777 -0
- package/webinterface/source/views/PictView-Ultravisor-ManifestList.js +321 -58
- package/webinterface/source/views/PictView-Ultravisor-OperationEdit.js +36 -91
- package/webinterface/source/views/PictView-Ultravisor-OperationList.js +388 -16
- package/webinterface/source/views/PictView-Ultravisor-PendingInput.js +314 -0
- package/webinterface/source/views/PictView-Ultravisor-Schedule.js +521 -65
- package/webinterface/source/views/PictView-Ultravisor-TimingView.js +333 -71
- package/webinterface/source/views/PictView-Ultravisor-TopBar.js +257 -21
- package/webinterface/theme-sampler.html +645 -0
- package/debug/Harness.js +0 -6
- 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/source/views/PictView-Ultravisor-TaskEdit.js +0 -220
- package/webinterface/source/views/PictView-Ultravisor-TaskList.js +0 -248
|
@@ -1,18 +1,32 @@
|
|
|
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');
|
|
5
|
+
|
|
6
|
+
const THEME_LIST =
|
|
7
|
+
[
|
|
8
|
+
{ Key: 'desert-dusk', Label: 'Desert Dusk', Colors: ['#252018', '#c4956a', '#4a9090', '#6a3040', '#8a9a5a'] },
|
|
9
|
+
{ Key: 'desert-day', Label: 'Desert Day', Colors: ['#faf6f0', '#5c3d2e', '#3a8a8c', '#7a2e3a', '#6b8f4a'] },
|
|
10
|
+
{ Key: 'desert-sunset', Label: 'Desert Sunset', Colors: ['#1e1610', '#e8943a', '#2a8a8a', '#8b2442', '#d4a46a'] },
|
|
11
|
+
{ Key: 'professional-light', Label: 'Professional Light', Colors: ['#f5f6f8', '#3b82f6', '#10b981', '#ef4444', '#6366f1'] },
|
|
12
|
+
{ Key: 'professional-dark', Label: 'Professional Dark', Colors: ['#111318', '#60a5fa', '#34d399', '#f87171', '#a78bfa'] },
|
|
13
|
+
{ Key: 'desert-canyon', Label: 'Desert Canyon', Colors: ['#18120e', '#e8943a', '#18a0a0', '#e05830', '#e0c870'] }
|
|
14
|
+
];
|
|
3
15
|
|
|
4
16
|
// Views
|
|
5
17
|
const libViewLayout = require('./views/PictView-Ultravisor-Layout.js');
|
|
6
18
|
const libViewTopBar = require('./views/PictView-Ultravisor-TopBar.js');
|
|
7
19
|
const libViewBottomBar = require('./views/PictView-Ultravisor-BottomBar.js');
|
|
8
20
|
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
21
|
const libViewOperationList = require('./views/PictView-Ultravisor-OperationList.js');
|
|
12
22
|
const libViewOperationEdit = require('./views/PictView-Ultravisor-OperationEdit.js');
|
|
13
23
|
const libViewSchedule = require('./views/PictView-Ultravisor-Schedule.js');
|
|
14
24
|
const libViewManifestList = require('./views/PictView-Ultravisor-ManifestList.js');
|
|
15
25
|
const libViewTimingView = require('./views/PictView-Ultravisor-TimingView.js');
|
|
26
|
+
const libViewFlowEditor = require('./views/PictView-Ultravisor-FlowEditor.js');
|
|
27
|
+
const libViewPendingInput = require('./views/PictView-Ultravisor-PendingInput.js');
|
|
28
|
+
const libViewDocumentation = require('./views/PictView-Ultravisor-Documentation.js');
|
|
29
|
+
const libViewBeaconList = require('./views/PictView-Ultravisor-BeaconList.js');
|
|
16
30
|
|
|
17
31
|
class UltravisorApplication extends libPictApplication
|
|
18
32
|
{
|
|
@@ -20,6 +34,10 @@ class UltravisorApplication extends libPictApplication
|
|
|
20
34
|
{
|
|
21
35
|
super(pFable, pOptions, pServiceHash);
|
|
22
36
|
|
|
37
|
+
// Skip premature route resolution during addRoute(); the Layout view
|
|
38
|
+
// calls resolve() explicitly after the DOM is ready.
|
|
39
|
+
this.pict.settings.RouterSkipRouteResolveOnAdd = true;
|
|
40
|
+
|
|
23
41
|
// Add the router provider with routes
|
|
24
42
|
this.pict.addProvider('PictRouter', require('./providers/PictRouter-Ultravisor-Configuration.json'), libPictRouter);
|
|
25
43
|
|
|
@@ -32,36 +50,74 @@ class UltravisorApplication extends libPictApplication
|
|
|
32
50
|
|
|
33
51
|
// Add content views
|
|
34
52
|
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
53
|
this.pict.addView('Ultravisor-OperationList', libViewOperationList.default_configuration, libViewOperationList);
|
|
38
54
|
this.pict.addView('Ultravisor-OperationEdit', libViewOperationEdit.default_configuration, libViewOperationEdit);
|
|
39
55
|
this.pict.addView('Ultravisor-Schedule', libViewSchedule.default_configuration, libViewSchedule);
|
|
40
56
|
this.pict.addView('Ultravisor-ManifestList', libViewManifestList.default_configuration, libViewManifestList);
|
|
41
57
|
this.pict.addView('Ultravisor-TimingView', libViewTimingView.default_configuration, libViewTimingView);
|
|
58
|
+
this.pict.addView('Ultravisor-FlowEditor', libViewFlowEditor.default_configuration, libViewFlowEditor);
|
|
59
|
+
this.pict.addView('Ultravisor-PendingInput', libViewPendingInput.default_configuration, libViewPendingInput);
|
|
60
|
+
this.pict.addView('Ultravisor-Documentation', libViewDocumentation.default_configuration, libViewDocumentation);
|
|
61
|
+
this.pict.addView('Ultravisor-BeaconList', libViewBeaconList.default_configuration, libViewBeaconList);
|
|
62
|
+
|
|
63
|
+
// Register pict-section-form service types so Form panels can use them
|
|
64
|
+
this.pict.addServiceType('PictFormMetacontroller', libPictSectionForm.PictFormMetacontroller);
|
|
65
|
+
|
|
66
|
+
// Register pict-section-content service types so Markdown panels can render content
|
|
67
|
+
this.pict.addServiceType('PictContentProvider', libPictSectionContent.PictContentProvider);
|
|
68
|
+
|
|
69
|
+
// Register the Ultravisor card settings panel for per-field mode toggles (Constant/Address/Default)
|
|
70
|
+
const libUltravisorCardSettingsPanel = require('./panels/Ultravisor-CardSettingsPanel.js');
|
|
71
|
+
this.pict.addServiceType('PictFlowCardPropertiesPanel-UltravisorSettings', libUltravisorCardSettingsPanel);
|
|
42
72
|
}
|
|
43
73
|
|
|
44
74
|
onAfterInitializeAsync(fCallback)
|
|
45
75
|
{
|
|
76
|
+
// Apply saved theme before first render
|
|
77
|
+
this.loadSavedTheme();
|
|
78
|
+
|
|
46
79
|
// Initialize application state
|
|
47
80
|
this.pict.AppData.Ultravisor =
|
|
48
81
|
{
|
|
49
82
|
APIBaseURL: '',
|
|
50
83
|
ServerStatus: { Status: 'Unknown', ScheduleEntries: 0, ScheduleRunning: false },
|
|
51
|
-
|
|
52
|
-
|
|
84
|
+
NodeTemplates: {},
|
|
85
|
+
NodeTemplateList: [],
|
|
86
|
+
TaskTypes: [],
|
|
53
87
|
Operations: {},
|
|
54
88
|
OperationList: [],
|
|
55
89
|
Schedule: [],
|
|
56
90
|
Manifests: [],
|
|
57
|
-
|
|
58
|
-
|
|
91
|
+
PendingInputs: [],
|
|
92
|
+
OperationLibrary: [],
|
|
93
|
+
Beacons: [],
|
|
94
|
+
WorkItems: [],
|
|
95
|
+
BeaconCapabilities: {},
|
|
96
|
+
AffinityBindings: [],
|
|
97
|
+
CurrentEditOperation: null,
|
|
98
|
+
Flows: {},
|
|
99
|
+
DebugMode: false
|
|
59
100
|
};
|
|
60
101
|
|
|
61
|
-
//
|
|
62
|
-
|
|
102
|
+
// Load task type definitions from the server BEFORE rendering the layout.
|
|
103
|
+
// The layout render triggers route resolution (via PictRouter.resolve()),
|
|
104
|
+
// and route handlers like editOperationFromRoute need TaskTypes to be
|
|
105
|
+
// populated so the FlowEditor can generate card configs with all ports.
|
|
106
|
+
let tmpSuper = super.onAfterInitializeAsync.bind(this);
|
|
107
|
+
this.loadTaskTypes(
|
|
108
|
+
function (pError)
|
|
109
|
+
{
|
|
110
|
+
if (pError)
|
|
111
|
+
{
|
|
112
|
+
this.pict.log.warn('Failed to load task types during init; flow editor will have no cards.');
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Now render the layout shell — this resolves the current route,
|
|
116
|
+
// which may immediately render the FlowEditor if the URL matches.
|
|
117
|
+
this.pict.views['Ultravisor-Layout'].render();
|
|
63
118
|
|
|
64
|
-
|
|
119
|
+
return tmpSuper(fCallback);
|
|
120
|
+
}.bind(this));
|
|
65
121
|
}
|
|
66
122
|
|
|
67
123
|
navigateTo(pRoute)
|
|
@@ -102,15 +158,25 @@ class UltravisorApplication extends libPictApplication
|
|
|
102
158
|
.then(
|
|
103
159
|
function (pData)
|
|
104
160
|
{
|
|
161
|
+
// Server responded — clear disconnected state if it was set
|
|
162
|
+
if (this.pict.AppData.Ultravisor.ServerStatus.StatusClass === 'error')
|
|
163
|
+
{
|
|
164
|
+
this._setConnectionState(true);
|
|
165
|
+
}
|
|
166
|
+
|
|
105
167
|
if (typeof fCallback === 'function')
|
|
106
168
|
{
|
|
107
169
|
fCallback(null, pData);
|
|
108
170
|
}
|
|
109
|
-
})
|
|
171
|
+
}.bind(this))
|
|
110
172
|
.catch(
|
|
111
173
|
function (pError)
|
|
112
174
|
{
|
|
113
175
|
this.pict.log.error(`API call failed: ${pMethod} ${pPath}`, pError);
|
|
176
|
+
|
|
177
|
+
// Network error — mark as disconnected
|
|
178
|
+
this._setConnectionState(false);
|
|
179
|
+
|
|
114
180
|
if (typeof fCallback === 'function')
|
|
115
181
|
{
|
|
116
182
|
fCallback(pError);
|
|
@@ -118,6 +184,59 @@ class UltravisorApplication extends libPictApplication
|
|
|
118
184
|
}.bind(this));
|
|
119
185
|
}
|
|
120
186
|
|
|
187
|
+
/**
|
|
188
|
+
* Update the connection state and show/hide the disconnected banner.
|
|
189
|
+
*
|
|
190
|
+
* @param {boolean} pConnected - true if the server is reachable
|
|
191
|
+
*/
|
|
192
|
+
_setConnectionState(pConnected)
|
|
193
|
+
{
|
|
194
|
+
let tmpStatus = this.pict.AppData.Ultravisor.ServerStatus;
|
|
195
|
+
|
|
196
|
+
if (!pConnected)
|
|
197
|
+
{
|
|
198
|
+
if (tmpStatus.StatusClass !== 'error')
|
|
199
|
+
{
|
|
200
|
+
tmpStatus.StatusClass = 'error';
|
|
201
|
+
tmpStatus.StatusText = 'Disconnected';
|
|
202
|
+
|
|
203
|
+
// Update status indicator
|
|
204
|
+
let tmpContent = this.pict.parseTemplateByHash('Ultravisor-TopBar-Status-Template', {}, null, this.pict);
|
|
205
|
+
this.pict.ContentAssignment.assignContent('#Ultravisor-TopBar-StatusArea', tmpContent);
|
|
206
|
+
|
|
207
|
+
// Show a prominent banner in the content area
|
|
208
|
+
let tmpContentContainer = document.getElementById('Ultravisor-Content-Container');
|
|
209
|
+
if (tmpContentContainer)
|
|
210
|
+
{
|
|
211
|
+
tmpContentContainer.innerHTML = '<div class="ultravisor-disconnected-banner">'
|
|
212
|
+
+ '<div class="ultravisor-disconnected-banner-icon">⚠</div>'
|
|
213
|
+
+ '<h2>Server Unreachable</h2>'
|
|
214
|
+
+ '<p>The Ultravisor server is not responding. Make sure it is running and refresh the page.</p>'
|
|
215
|
+
+ '</div>';
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
else
|
|
220
|
+
{
|
|
221
|
+
if (tmpStatus.StatusClass === 'error')
|
|
222
|
+
{
|
|
223
|
+
tmpStatus.StatusClass = 'connected';
|
|
224
|
+
tmpStatus.StatusText = tmpStatus.Status || 'Connected';
|
|
225
|
+
|
|
226
|
+
// Update status indicator
|
|
227
|
+
let tmpContent = this.pict.parseTemplateByHash('Ultravisor-TopBar-Status-Template', {}, null, this.pict);
|
|
228
|
+
this.pict.ContentAssignment.assignContent('#Ultravisor-TopBar-StatusArea', tmpContent);
|
|
229
|
+
|
|
230
|
+
// Remove the disconnected banner if present
|
|
231
|
+
let tmpBanner = document.querySelector('.ultravisor-disconnected-banner');
|
|
232
|
+
if (tmpBanner)
|
|
233
|
+
{
|
|
234
|
+
tmpBanner.remove();
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
121
240
|
// --- Status ---
|
|
122
241
|
loadStatus(fCallback)
|
|
123
242
|
{
|
|
@@ -135,23 +254,22 @@ class UltravisorApplication extends libPictApplication
|
|
|
135
254
|
}.bind(this));
|
|
136
255
|
}
|
|
137
256
|
|
|
138
|
-
// ---
|
|
139
|
-
|
|
257
|
+
// --- Node Templates ---
|
|
258
|
+
loadNodeTemplates(fCallback)
|
|
140
259
|
{
|
|
141
|
-
this.apiCall('GET', '/
|
|
260
|
+
this.apiCall('GET', '/NodeTemplate', null,
|
|
142
261
|
function (pError, pData)
|
|
143
262
|
{
|
|
144
263
|
if (!pError && pData)
|
|
145
264
|
{
|
|
146
|
-
this.pict.AppData.Ultravisor.
|
|
147
|
-
|
|
148
|
-
let
|
|
149
|
-
for (let i = 0; i < this.pict.AppData.Ultravisor.TaskList.length; i++)
|
|
265
|
+
this.pict.AppData.Ultravisor.NodeTemplateList = Array.isArray(pData) ? pData : [];
|
|
266
|
+
let tmpTemplates = {};
|
|
267
|
+
for (let i = 0; i < this.pict.AppData.Ultravisor.NodeTemplateList.length; i++)
|
|
150
268
|
{
|
|
151
|
-
let
|
|
152
|
-
|
|
269
|
+
let tmpTemplate = this.pict.AppData.Ultravisor.NodeTemplateList[i];
|
|
270
|
+
tmpTemplates[tmpTemplate.Hash] = tmpTemplate;
|
|
153
271
|
}
|
|
154
|
-
this.pict.AppData.Ultravisor.
|
|
272
|
+
this.pict.AppData.Ultravisor.NodeTemplates = tmpTemplates;
|
|
155
273
|
}
|
|
156
274
|
if (typeof fCallback === 'function')
|
|
157
275
|
{
|
|
@@ -160,9 +278,9 @@ class UltravisorApplication extends libPictApplication
|
|
|
160
278
|
}.bind(this));
|
|
161
279
|
}
|
|
162
280
|
|
|
163
|
-
|
|
281
|
+
saveNodeTemplate(pTemplateData, fCallback)
|
|
164
282
|
{
|
|
165
|
-
this.apiCall('POST', '/
|
|
283
|
+
this.apiCall('POST', '/NodeTemplate', pTemplateData,
|
|
166
284
|
function (pError, pData)
|
|
167
285
|
{
|
|
168
286
|
if (typeof fCallback === 'function')
|
|
@@ -172,9 +290,9 @@ class UltravisorApplication extends libPictApplication
|
|
|
172
290
|
}.bind(this));
|
|
173
291
|
}
|
|
174
292
|
|
|
175
|
-
|
|
293
|
+
deleteNodeTemplate(pHash, fCallback)
|
|
176
294
|
{
|
|
177
|
-
this.apiCall('DELETE', `/
|
|
295
|
+
this.apiCall('DELETE', `/NodeTemplate/${encodeURIComponent(pHash)}`, null,
|
|
178
296
|
function (pError, pData)
|
|
179
297
|
{
|
|
180
298
|
if (typeof fCallback === 'function')
|
|
@@ -184,11 +302,16 @@ class UltravisorApplication extends libPictApplication
|
|
|
184
302
|
}.bind(this));
|
|
185
303
|
}
|
|
186
304
|
|
|
187
|
-
|
|
305
|
+
// --- Task Types ---
|
|
306
|
+
loadTaskTypes(fCallback)
|
|
188
307
|
{
|
|
189
|
-
this.apiCall('GET',
|
|
308
|
+
this.apiCall('GET', '/TaskType', null,
|
|
190
309
|
function (pError, pData)
|
|
191
310
|
{
|
|
311
|
+
if (!pError && pData)
|
|
312
|
+
{
|
|
313
|
+
this.pict.AppData.Ultravisor.TaskTypes = Array.isArray(pData) ? pData : [];
|
|
314
|
+
}
|
|
192
315
|
if (typeof fCallback === 'function')
|
|
193
316
|
{
|
|
194
317
|
fCallback(pError, pData);
|
|
@@ -209,7 +332,7 @@ class UltravisorApplication extends libPictApplication
|
|
|
209
332
|
for (let i = 0; i < this.pict.AppData.Ultravisor.OperationList.length; i++)
|
|
210
333
|
{
|
|
211
334
|
let tmpOp = this.pict.AppData.Ultravisor.OperationList[i];
|
|
212
|
-
tmpOperations[tmpOp.
|
|
335
|
+
tmpOperations[tmpOp.Hash] = tmpOp;
|
|
213
336
|
}
|
|
214
337
|
this.pict.AppData.Ultravisor.Operations = tmpOperations;
|
|
215
338
|
}
|
|
@@ -232,9 +355,9 @@ class UltravisorApplication extends libPictApplication
|
|
|
232
355
|
}.bind(this));
|
|
233
356
|
}
|
|
234
357
|
|
|
235
|
-
deleteOperation(
|
|
358
|
+
deleteOperation(pHash, fCallback)
|
|
236
359
|
{
|
|
237
|
-
this.apiCall('DELETE', `/Operation/${encodeURIComponent(
|
|
360
|
+
this.apiCall('DELETE', `/Operation/${encodeURIComponent(pHash)}`, null,
|
|
238
361
|
function (pError, pData)
|
|
239
362
|
{
|
|
240
363
|
if (typeof fCallback === 'function')
|
|
@@ -244,9 +367,18 @@ class UltravisorApplication extends libPictApplication
|
|
|
244
367
|
}.bind(this));
|
|
245
368
|
}
|
|
246
369
|
|
|
247
|
-
executeOperation(
|
|
370
|
+
executeOperation(pHash, pRunMode, fCallback)
|
|
248
371
|
{
|
|
249
|
-
|
|
372
|
+
if (typeof pRunMode === 'function')
|
|
373
|
+
{
|
|
374
|
+
fCallback = pRunMode;
|
|
375
|
+
pRunMode = null;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
let tmpRunMode = pRunMode || (this.pict.AppData.Ultravisor.DebugMode ? 'debug' : 'standard');
|
|
379
|
+
let tmpURL = `/Operation/${encodeURIComponent(pHash)}/Execute?RunMode=${encodeURIComponent(tmpRunMode)}`;
|
|
380
|
+
|
|
381
|
+
this.apiCall('GET', tmpURL, null,
|
|
250
382
|
function (pError, pData)
|
|
251
383
|
{
|
|
252
384
|
if (typeof fCallback === 'function')
|
|
@@ -273,10 +405,10 @@ class UltravisorApplication extends libPictApplication
|
|
|
273
405
|
}.bind(this));
|
|
274
406
|
}
|
|
275
407
|
|
|
276
|
-
|
|
408
|
+
scheduleOperation(pHash, pScheduleType, pParameters, fCallback)
|
|
277
409
|
{
|
|
278
|
-
this.apiCall('POST', '/Schedule/
|
|
279
|
-
{
|
|
410
|
+
this.apiCall('POST', '/Schedule/Operation',
|
|
411
|
+
{ Hash: pHash, ScheduleType: pScheduleType, Parameters: pParameters },
|
|
280
412
|
function (pError, pData)
|
|
281
413
|
{
|
|
282
414
|
if (typeof fCallback === 'function')
|
|
@@ -286,10 +418,9 @@ class UltravisorApplication extends libPictApplication
|
|
|
286
418
|
}.bind(this));
|
|
287
419
|
}
|
|
288
420
|
|
|
289
|
-
|
|
421
|
+
removeScheduleEntry(pGUID, fCallback)
|
|
290
422
|
{
|
|
291
|
-
this.apiCall('
|
|
292
|
-
{ GUIDOperation: pGUIDOperation, ScheduleType: pScheduleType, Parameters: pParameters },
|
|
423
|
+
this.apiCall('DELETE', `/Schedule/${encodeURIComponent(pGUID)}`, null,
|
|
293
424
|
function (pError, pData)
|
|
294
425
|
{
|
|
295
426
|
if (typeof fCallback === 'function')
|
|
@@ -299,9 +430,9 @@ class UltravisorApplication extends libPictApplication
|
|
|
299
430
|
}.bind(this));
|
|
300
431
|
}
|
|
301
432
|
|
|
302
|
-
|
|
433
|
+
startSchedule(fCallback)
|
|
303
434
|
{
|
|
304
|
-
this.apiCall('
|
|
435
|
+
this.apiCall('GET', '/Schedule/Start', null,
|
|
305
436
|
function (pError, pData)
|
|
306
437
|
{
|
|
307
438
|
if (typeof fCallback === 'function')
|
|
@@ -311,9 +442,9 @@ class UltravisorApplication extends libPictApplication
|
|
|
311
442
|
}.bind(this));
|
|
312
443
|
}
|
|
313
444
|
|
|
314
|
-
|
|
445
|
+
stopSchedule(fCallback)
|
|
315
446
|
{
|
|
316
|
-
this.apiCall('GET', '/Schedule/
|
|
447
|
+
this.apiCall('GET', '/Schedule/Stop', null,
|
|
317
448
|
function (pError, pData)
|
|
318
449
|
{
|
|
319
450
|
if (typeof fCallback === 'function')
|
|
@@ -323,9 +454,21 @@ class UltravisorApplication extends libPictApplication
|
|
|
323
454
|
}.bind(this));
|
|
324
455
|
}
|
|
325
456
|
|
|
326
|
-
|
|
457
|
+
startScheduleEntry(pGUID, fCallback)
|
|
327
458
|
{
|
|
328
|
-
this.apiCall('GET',
|
|
459
|
+
this.apiCall('GET', `/Schedule/Start/${encodeURIComponent(pGUID)}`, null,
|
|
460
|
+
function (pError, pData)
|
|
461
|
+
{
|
|
462
|
+
if (typeof fCallback === 'function')
|
|
463
|
+
{
|
|
464
|
+
fCallback(pError, pData);
|
|
465
|
+
}
|
|
466
|
+
}.bind(this));
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
stopScheduleEntry(pGUID, fCallback)
|
|
470
|
+
{
|
|
471
|
+
this.apiCall('GET', `/Schedule/Stop/${encodeURIComponent(pGUID)}`, null,
|
|
329
472
|
function (pError, pData)
|
|
330
473
|
{
|
|
331
474
|
if (typeof fCallback === 'function')
|
|
@@ -352,9 +495,9 @@ class UltravisorApplication extends libPictApplication
|
|
|
352
495
|
}.bind(this));
|
|
353
496
|
}
|
|
354
497
|
|
|
355
|
-
loadManifest(
|
|
498
|
+
loadManifest(pRunHash, fCallback)
|
|
356
499
|
{
|
|
357
|
-
this.apiCall('GET', `/Manifest/${encodeURIComponent(
|
|
500
|
+
this.apiCall('GET', `/Manifest/${encodeURIComponent(pRunHash)}`, null,
|
|
358
501
|
function (pError, pData)
|
|
359
502
|
{
|
|
360
503
|
if (typeof fCallback === 'function')
|
|
@@ -364,48 +507,399 @@ class UltravisorApplication extends libPictApplication
|
|
|
364
507
|
}.bind(this));
|
|
365
508
|
}
|
|
366
509
|
|
|
367
|
-
// ---
|
|
368
|
-
|
|
510
|
+
// --- Pending Inputs ---
|
|
511
|
+
loadPendingInputs(fCallback)
|
|
512
|
+
{
|
|
513
|
+
this.apiCall('GET', '/PendingInput', null,
|
|
514
|
+
function (pError, pData)
|
|
515
|
+
{
|
|
516
|
+
if (!pError && pData)
|
|
517
|
+
{
|
|
518
|
+
this.pict.AppData.Ultravisor.PendingInputs = Array.isArray(pData) ? pData : [];
|
|
519
|
+
}
|
|
520
|
+
if (typeof fCallback === 'function')
|
|
521
|
+
{
|
|
522
|
+
fCallback(pError, pData);
|
|
523
|
+
}
|
|
524
|
+
}.bind(this));
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
submitPendingInput(pRunHash, pNodeHash, pValue, fCallback)
|
|
528
|
+
{
|
|
529
|
+
this.apiCall('POST', `/PendingInput/${encodeURIComponent(pRunHash)}`,
|
|
530
|
+
{ NodeHash: pNodeHash, Value: pValue },
|
|
531
|
+
function (pError, pData)
|
|
532
|
+
{
|
|
533
|
+
if (typeof fCallback === 'function')
|
|
534
|
+
{
|
|
535
|
+
fCallback(pError, pData);
|
|
536
|
+
}
|
|
537
|
+
}.bind(this));
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
// --- Beacons ---
|
|
541
|
+
loadBeacons(fCallback)
|
|
542
|
+
{
|
|
543
|
+
this.apiCall('GET', '/Beacon', null,
|
|
544
|
+
function (pError, pData)
|
|
545
|
+
{
|
|
546
|
+
if (!pError && pData)
|
|
547
|
+
{
|
|
548
|
+
this.pict.AppData.Ultravisor.Beacons = Array.isArray(pData) ? pData : [];
|
|
549
|
+
}
|
|
550
|
+
if (typeof fCallback === 'function')
|
|
551
|
+
{
|
|
552
|
+
fCallback(pError, pData);
|
|
553
|
+
}
|
|
554
|
+
}.bind(this));
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
loadBeacon(pBeaconID, fCallback)
|
|
558
|
+
{
|
|
559
|
+
this.apiCall('GET', `/Beacon/${encodeURIComponent(pBeaconID)}`, null,
|
|
560
|
+
function (pError, pData)
|
|
561
|
+
{
|
|
562
|
+
if (typeof fCallback === 'function')
|
|
563
|
+
{
|
|
564
|
+
fCallback(pError, pData);
|
|
565
|
+
}
|
|
566
|
+
}.bind(this));
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
deregisterBeacon(pBeaconID, fCallback)
|
|
570
|
+
{
|
|
571
|
+
this.apiCall('DELETE', `/Beacon/${encodeURIComponent(pBeaconID)}`, null,
|
|
572
|
+
function (pError, pData)
|
|
573
|
+
{
|
|
574
|
+
if (typeof fCallback === 'function')
|
|
575
|
+
{
|
|
576
|
+
fCallback(pError, pData);
|
|
577
|
+
}
|
|
578
|
+
}.bind(this));
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
loadWorkItems(fCallback)
|
|
582
|
+
{
|
|
583
|
+
this.apiCall('GET', '/Beacon/Work', null,
|
|
584
|
+
function (pError, pData)
|
|
585
|
+
{
|
|
586
|
+
if (!pError && pData)
|
|
587
|
+
{
|
|
588
|
+
this.pict.AppData.Ultravisor.WorkItems = Array.isArray(pData) ? pData : [];
|
|
589
|
+
}
|
|
590
|
+
if (typeof fCallback === 'function')
|
|
591
|
+
{
|
|
592
|
+
fCallback(pError, pData);
|
|
593
|
+
}
|
|
594
|
+
}.bind(this));
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
loadBeaconCapabilities(fCallback)
|
|
598
|
+
{
|
|
599
|
+
this.apiCall('GET', '/Beacon/Capabilities', null,
|
|
600
|
+
function (pError, pData)
|
|
601
|
+
{
|
|
602
|
+
if (!pError && pData)
|
|
603
|
+
{
|
|
604
|
+
this.pict.AppData.Ultravisor.BeaconCapabilities = pData || {};
|
|
605
|
+
}
|
|
606
|
+
if (typeof fCallback === 'function')
|
|
607
|
+
{
|
|
608
|
+
fCallback(pError, pData);
|
|
609
|
+
}
|
|
610
|
+
}.bind(this));
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
loadAffinityBindings(fCallback)
|
|
614
|
+
{
|
|
615
|
+
this.apiCall('GET', '/Beacon/Affinity', null,
|
|
616
|
+
function (pError, pData)
|
|
617
|
+
{
|
|
618
|
+
if (!pError && pData)
|
|
619
|
+
{
|
|
620
|
+
this.pict.AppData.Ultravisor.AffinityBindings = Array.isArray(pData) ? pData : [];
|
|
621
|
+
}
|
|
622
|
+
if (typeof fCallback === 'function')
|
|
623
|
+
{
|
|
624
|
+
fCallback(pError, pData);
|
|
625
|
+
}
|
|
626
|
+
}.bind(this));
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
// --- Operation Library ---
|
|
630
|
+
loadOperationLibrary(fCallback)
|
|
631
|
+
{
|
|
632
|
+
this.apiCall('GET', '/OperationLibrary', null,
|
|
633
|
+
function (pError, pData)
|
|
634
|
+
{
|
|
635
|
+
if (!pError && pData)
|
|
636
|
+
{
|
|
637
|
+
this.pict.AppData.Ultravisor.OperationLibrary = Array.isArray(pData) ? pData : [];
|
|
638
|
+
}
|
|
639
|
+
if (typeof fCallback === 'function')
|
|
640
|
+
{
|
|
641
|
+
fCallback(pError, pData);
|
|
642
|
+
}
|
|
643
|
+
}.bind(this));
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
importLibraryOperation(pFileName, fCallback)
|
|
647
|
+
{
|
|
648
|
+
this.apiCall('GET', `/OperationLibrary/${encodeURIComponent(pFileName)}`, null,
|
|
649
|
+
function (pError, pData)
|
|
650
|
+
{
|
|
651
|
+
if (pError)
|
|
652
|
+
{
|
|
653
|
+
if (typeof fCallback === 'function')
|
|
654
|
+
{
|
|
655
|
+
fCallback(pError);
|
|
656
|
+
}
|
|
657
|
+
return;
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
// Strip library metadata, keep operation-relevant fields
|
|
661
|
+
let tmpOperationData =
|
|
662
|
+
{
|
|
663
|
+
Name: pData.Name || '',
|
|
664
|
+
Description: pData.Description || '',
|
|
665
|
+
Graph: pData.Graph || { Nodes: [], Connections: [], ViewState: {} }
|
|
666
|
+
};
|
|
667
|
+
|
|
668
|
+
if (pData.SavedLayouts)
|
|
669
|
+
{
|
|
670
|
+
tmpOperationData.SavedLayouts = pData.SavedLayouts;
|
|
671
|
+
}
|
|
672
|
+
if (pData.InitialGlobalState)
|
|
673
|
+
{
|
|
674
|
+
tmpOperationData.InitialGlobalState = pData.InitialGlobalState;
|
|
675
|
+
}
|
|
676
|
+
if (pData.InitialOperationState)
|
|
677
|
+
{
|
|
678
|
+
tmpOperationData.InitialOperationState = pData.InitialOperationState;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
// Save as a new operation (no Hash => auto-generated)
|
|
682
|
+
this.saveOperation(tmpOperationData, fCallback);
|
|
683
|
+
}.bind(this));
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
importOperationFromJSON(pOperationJSON, fCallback)
|
|
369
687
|
{
|
|
370
|
-
if (
|
|
688
|
+
if (typeof (pOperationJSON) !== 'object' || pOperationJSON === null)
|
|
689
|
+
{
|
|
690
|
+
if (typeof fCallback === 'function')
|
|
691
|
+
{
|
|
692
|
+
fCallback(new Error('Invalid operation JSON.'));
|
|
693
|
+
}
|
|
694
|
+
return;
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
// Strip identifiers so a fresh hash is auto-generated on import
|
|
698
|
+
let tmpOperationData =
|
|
371
699
|
{
|
|
372
|
-
|
|
700
|
+
Name: pOperationJSON.Name || 'Imported Operation',
|
|
701
|
+
Description: pOperationJSON.Description || '',
|
|
702
|
+
Graph: pOperationJSON.Graph || { Nodes: [], Connections: [], ViewState: {} }
|
|
703
|
+
};
|
|
704
|
+
|
|
705
|
+
if (pOperationJSON.SavedLayouts)
|
|
706
|
+
{
|
|
707
|
+
tmpOperationData.SavedLayouts = pOperationJSON.SavedLayouts;
|
|
373
708
|
}
|
|
374
|
-
|
|
709
|
+
if (pOperationJSON.InitialGlobalState)
|
|
710
|
+
{
|
|
711
|
+
tmpOperationData.InitialGlobalState = pOperationJSON.InitialGlobalState;
|
|
712
|
+
}
|
|
713
|
+
if (pOperationJSON.InitialOperationState)
|
|
375
714
|
{
|
|
376
|
-
|
|
715
|
+
tmpOperationData.InitialOperationState = pOperationJSON.InitialOperationState;
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
// Save as a new operation (no Hash => auto-generated)
|
|
719
|
+
this.saveOperation(tmpOperationData, fCallback);
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
exportOperation(pHash, fCallback)
|
|
723
|
+
{
|
|
724
|
+
this.apiCall('GET', `/Operation/${encodeURIComponent(pHash)}/Export`, null,
|
|
725
|
+
function (pError, pData)
|
|
377
726
|
{
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
727
|
+
if (pError)
|
|
728
|
+
{
|
|
729
|
+
if (typeof fCallback === 'function')
|
|
730
|
+
{
|
|
731
|
+
fCallback(pError);
|
|
732
|
+
}
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
// Trigger a browser download of the JSON
|
|
737
|
+
let tmpFileName = (pData.Name || pData.Hash || 'operation').replace(/[^a-zA-Z0-9_-]/g, '_') + '.json';
|
|
738
|
+
let tmpBlob = new Blob([JSON.stringify(pData, null, '\t')], { type: 'application/json' });
|
|
739
|
+
let tmpLink = document.createElement('a');
|
|
740
|
+
tmpLink.href = URL.createObjectURL(tmpBlob);
|
|
741
|
+
tmpLink.download = tmpFileName;
|
|
742
|
+
tmpLink.click();
|
|
743
|
+
URL.revokeObjectURL(tmpLink.href);
|
|
744
|
+
|
|
745
|
+
if (typeof fCallback === 'function')
|
|
746
|
+
{
|
|
747
|
+
fCallback(null, pData);
|
|
748
|
+
}
|
|
749
|
+
}.bind(this));
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
// --- Theme ---
|
|
753
|
+
applyTheme(pThemeKey)
|
|
754
|
+
{
|
|
755
|
+
let tmpThemeKey = pThemeKey || 'desert-dusk';
|
|
756
|
+
|
|
757
|
+
if (tmpThemeKey === 'desert-dusk')
|
|
758
|
+
{
|
|
759
|
+
delete document.body.dataset.theme;
|
|
760
|
+
}
|
|
761
|
+
else
|
|
762
|
+
{
|
|
763
|
+
document.body.dataset.theme = tmpThemeKey;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
localStorage.setItem('ultravisor-theme', tmpThemeKey);
|
|
767
|
+
|
|
768
|
+
if (this.pict.AppData.Ultravisor)
|
|
769
|
+
{
|
|
770
|
+
this.pict.AppData.Ultravisor.CurrentTheme = tmpThemeKey;
|
|
388
771
|
}
|
|
389
|
-
this.navigateTo('/TaskEdit');
|
|
390
772
|
}
|
|
391
773
|
|
|
392
|
-
|
|
774
|
+
loadSavedTheme()
|
|
775
|
+
{
|
|
776
|
+
let tmpSavedTheme = localStorage.getItem('ultravisor-theme') || 'desert-dusk';
|
|
777
|
+
this.applyTheme(tmpSavedTheme);
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
getThemeList()
|
|
781
|
+
{
|
|
782
|
+
return THEME_LIST;
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
// --- Edit helpers ---
|
|
786
|
+
|
|
787
|
+
/**
|
|
788
|
+
* Populate CurrentEditOperation and Flows.Current from a loaded operation.
|
|
789
|
+
* Does not navigate — caller decides whether to navigate or render directly.
|
|
790
|
+
*/
|
|
791
|
+
_setCurrentEditOperation(pHash)
|
|
393
792
|
{
|
|
394
|
-
if (
|
|
793
|
+
if (pHash && this.pict.AppData.Ultravisor.Operations[pHash])
|
|
395
794
|
{
|
|
396
|
-
|
|
795
|
+
let tmpOp = JSON.parse(JSON.stringify(this.pict.AppData.Ultravisor.Operations[pHash]));
|
|
796
|
+
this.pict.AppData.Ultravisor.CurrentEditOperation = tmpOp;
|
|
797
|
+
|
|
798
|
+
// Load the operation's graph into the FlowEditor data
|
|
799
|
+
if (tmpOp.Graph)
|
|
800
|
+
{
|
|
801
|
+
this.pict.AppData.Ultravisor.Flows.Current = JSON.parse(JSON.stringify(tmpOp.Graph));
|
|
802
|
+
}
|
|
397
803
|
}
|
|
398
804
|
else
|
|
399
805
|
{
|
|
400
806
|
this.pict.AppData.Ultravisor.CurrentEditOperation =
|
|
401
807
|
{
|
|
402
|
-
|
|
808
|
+
Hash: '',
|
|
403
809
|
Name: '',
|
|
404
810
|
Description: '',
|
|
405
|
-
|
|
811
|
+
Graph: { Nodes: [], Connections: [], ViewState: {} }
|
|
812
|
+
};
|
|
813
|
+
this.pict.AppData.Ultravisor.Flows.Current =
|
|
814
|
+
{
|
|
815
|
+
Nodes: [],
|
|
816
|
+
Connections: [],
|
|
817
|
+
ViewState: { PanX: 0, PanY: 0, Zoom: 1, SelectedNodeHash: null, SelectedConnectionHash: null }
|
|
406
818
|
};
|
|
407
819
|
}
|
|
408
|
-
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
/**
|
|
823
|
+
* Called from the Operations list UI to edit an operation. Navigates to the
|
|
824
|
+
* parameterized FlowEditor route so the URL reflects the operation hash.
|
|
825
|
+
*/
|
|
826
|
+
editOperation(pHash)
|
|
827
|
+
{
|
|
828
|
+
this._setCurrentEditOperation(pHash);
|
|
829
|
+
|
|
830
|
+
if (pHash)
|
|
831
|
+
{
|
|
832
|
+
this.navigateTo(`/FlowEditor/${encodeURIComponent(pHash)}`);
|
|
833
|
+
}
|
|
834
|
+
else
|
|
835
|
+
{
|
|
836
|
+
this.navigateTo('/FlowEditor');
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
/**
|
|
841
|
+
* Route handler for `/FlowEditor/:hash`. On a cold page load both the
|
|
842
|
+
* Operations map and TaskTypes may be empty, so we load them first.
|
|
843
|
+
* TaskTypes must be available before the FlowEditor renders so that
|
|
844
|
+
* _buildFlowCardNodeTypes() can generate card configs with all ports.
|
|
845
|
+
*/
|
|
846
|
+
editOperationFromRoute(pHash)
|
|
847
|
+
{
|
|
848
|
+
let tmpHash = decodeURIComponent(pHash);
|
|
849
|
+
|
|
850
|
+
let tmpNeedOperations = (this.pict.AppData.Ultravisor.OperationList.length < 1);
|
|
851
|
+
let tmpNeedTaskTypes = (this.pict.AppData.Ultravisor.TaskTypes.length < 1);
|
|
852
|
+
|
|
853
|
+
// Hot navigation — everything already loaded
|
|
854
|
+
if (!tmpNeedOperations && !tmpNeedTaskTypes)
|
|
855
|
+
{
|
|
856
|
+
this._setCurrentEditOperation(tmpHash);
|
|
857
|
+
this.pict.views['Ultravisor-FlowEditor'].render();
|
|
858
|
+
return;
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
// Cold reload — load whatever is missing, then render
|
|
862
|
+
let tmpPending = 0;
|
|
863
|
+
let tmpSelf = this;
|
|
864
|
+
|
|
865
|
+
function onLoaded()
|
|
866
|
+
{
|
|
867
|
+
tmpPending--;
|
|
868
|
+
if (tmpPending > 0)
|
|
869
|
+
{
|
|
870
|
+
return;
|
|
871
|
+
}
|
|
872
|
+
tmpSelf._setCurrentEditOperation(tmpHash);
|
|
873
|
+
tmpSelf.pict.views['Ultravisor-FlowEditor'].render();
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
if (tmpNeedOperations)
|
|
877
|
+
{
|
|
878
|
+
tmpPending++;
|
|
879
|
+
this.loadOperations(
|
|
880
|
+
function (pError)
|
|
881
|
+
{
|
|
882
|
+
if (pError)
|
|
883
|
+
{
|
|
884
|
+
this.pict.log.warn(`Failed to load operations for route /FlowEditor/${tmpHash}`);
|
|
885
|
+
}
|
|
886
|
+
onLoaded();
|
|
887
|
+
}.bind(this));
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
if (tmpNeedTaskTypes)
|
|
891
|
+
{
|
|
892
|
+
tmpPending++;
|
|
893
|
+
this.loadTaskTypes(
|
|
894
|
+
function (pError)
|
|
895
|
+
{
|
|
896
|
+
if (pError)
|
|
897
|
+
{
|
|
898
|
+
this.pict.log.warn('Failed to load task types for FlowEditor route.');
|
|
899
|
+
}
|
|
900
|
+
onLoaded();
|
|
901
|
+
}.bind(this));
|
|
902
|
+
}
|
|
409
903
|
}
|
|
410
904
|
}
|
|
411
905
|
|