retold-data-service 2.1.1 → 2.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/BUILDING-AND-PUBLISHING.md +2 -2
  2. package/Dockerfile +1 -1
  3. package/README.md +12 -27
  4. package/build-all.js +66 -0
  5. package/diagrams/architecture.excalidraw +2966 -0
  6. package/diagrams/architecture.mmd +17 -0
  7. package/diagrams/architecture.svg +2 -0
  8. package/docs/README.md +12 -12
  9. package/docs/_brand.json +18 -0
  10. package/docs/_cover.md +1 -1
  11. package/docs/_topbar.md +1 -1
  12. package/docs/_version.json +3 -3
  13. package/docs/api/reference.md +8 -8
  14. package/docs/architecture.md +6 -84
  15. package/docs/diagrams/component-diagram.excalidraw +2807 -0
  16. package/docs/diagrams/component-diagram.mmd +14 -0
  17. package/docs/diagrams/component-diagram.svg +2 -0
  18. package/docs/diagrams/component-stack.excalidraw +1169 -0
  19. package/docs/diagrams/component-stack.mmd +6 -0
  20. package/docs/diagrams/component-stack.svg +2 -0
  21. package/docs/diagrams/hook-execution-order.excalidraw +3230 -0
  22. package/docs/diagrams/hook-execution-order.mmd +19 -0
  23. package/docs/diagrams/hook-execution-order.svg +2 -0
  24. package/docs/diagrams/initialization-flow.excalidraw +1800 -0
  25. package/docs/diagrams/initialization-flow.mmd +22 -0
  26. package/docs/diagrams/initialization-flow.svg +2 -0
  27. package/docs/index.html +6 -7
  28. package/docs/lifecycle-hooks.md +2 -21
  29. package/docs/retold-catalog.json +141 -141
  30. package/docs/retold-keyword-index.json +6818 -1608
  31. package/package.json +130 -96
  32. package/source/services/RetoldDataService-Brand.js +13 -0
  33. package/source/services/comprehension-loader/pict-app/Pict-Application-ComprehensionLoader.js +65 -15
  34. package/source/services/comprehension-loader/pict-app/providers/Pict-Provider-ComprehensionLoader.js +2 -2
  35. package/source/services/comprehension-loader/pict-app/views/PictView-ComprehensionLoader-Layout.js +68 -114
  36. package/source/services/comprehension-loader/pict-app/views/PictView-ComprehensionLoader-Load.js +29 -29
  37. package/source/services/comprehension-loader/pict-app/views/PictView-ComprehensionLoader-Schema.js +3 -3
  38. package/source/services/comprehension-loader/pict-app/views/PictView-ComprehensionLoader-Session.js +2 -2
  39. package/source/services/comprehension-loader/pict-app/views/PictView-ComprehensionLoader-SettingsPanel.js +62 -0
  40. package/source/services/comprehension-loader/pict-app/views/PictView-ComprehensionLoader-Shell.js +142 -0
  41. package/source/services/comprehension-loader/pict-app/views/PictView-ComprehensionLoader-Source.js +7 -7
  42. package/source/services/comprehension-loader/pict-app/views/PictView-ComprehensionLoader-StatusBar.js +125 -0
  43. package/source/services/comprehension-loader/pict-app/views/PictView-ComprehensionLoader-StatusDetail.js +89 -0
  44. package/source/services/comprehension-loader/pict-app/views/PictView-ComprehensionLoader-TopBar-Nav.js +42 -0
  45. package/source/services/comprehension-loader/pict-app/views/PictView-ComprehensionLoader-TopBar-User.js +48 -0
  46. package/source/services/comprehension-loader/web/comprehension-loader.js +5475 -6243
  47. package/source/services/comprehension-loader/web/comprehension-loader.js.map +1 -1
  48. package/source/services/comprehension-loader/web/comprehension-loader.min.js +75 -1
  49. package/source/services/comprehension-loader/web/comprehension-loader.min.js.map +1 -1
  50. package/source/services/comprehension-loader/web/favicons/favicon-dark.svg +13 -0
  51. package/source/services/comprehension-loader/web/favicons/favicon-light.svg +13 -0
  52. package/source/services/comprehension-loader/web/favicons/favicon.svg +13 -0
  53. package/source/services/comprehension-loader/web/index.html +3 -0
  54. package/source/services/comprehension-loader/web/pict.min.js +12 -0
  55. package/source/services/data-cloner/DataCloner-Command-Headless.js +2 -1
  56. package/source/services/data-cloner/DataCloner-Command-Sync.js +110 -75
  57. package/source/services/data-cloner/pict-app/Pict-Application-DataCloner.js +70 -47
  58. package/source/services/data-cloner/pict-app/providers/Pict-Provider-DataCloner.js +3 -3
  59. package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Connection.js +1 -1
  60. package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Deploy.js +5 -5
  61. package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Export.js +11 -11
  62. package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Layout.js +89 -135
  63. package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Schema.js +3 -3
  64. package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Session.js +2 -2
  65. package/source/services/data-cloner/pict-app/views/PictView-DataCloner-SettingsPanel.js +61 -0
  66. package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Shell.js +136 -0
  67. package/source/services/data-cloner/pict-app/views/PictView-DataCloner-StatusBar.js +117 -0
  68. package/source/services/data-cloner/pict-app/views/PictView-DataCloner-StatusDetail.js +81 -0
  69. package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Sync.js +38 -38
  70. package/source/services/data-cloner/pict-app/views/PictView-DataCloner-TopBar-Nav.js +42 -0
  71. package/source/services/data-cloner/pict-app/views/PictView-DataCloner-TopBar-User.js +48 -0
  72. package/source/services/data-cloner/pict-app/views/PictView-DataCloner-ViewData.js +5 -5
  73. package/source/services/data-cloner/web/data-cloner.js +5855 -8067
  74. package/source/services/data-cloner/web/data-cloner.js.map +1 -1
  75. package/source/services/data-cloner/web/data-cloner.min.js +75 -1
  76. package/source/services/data-cloner/web/data-cloner.min.js.map +1 -1
  77. package/source/services/data-cloner/web/favicons/favicon-dark.svg +13 -0
  78. package/source/services/data-cloner/web/favicons/favicon-light.svg +13 -0
  79. package/source/services/data-cloner/web/favicons/favicon.svg +13 -0
  80. package/source/services/data-cloner/web/favicons/favicons/favicon-dark.svg +13 -0
  81. package/source/services/data-cloner/web/favicons/favicons/favicon-light.svg +13 -0
  82. package/source/services/data-cloner/web/favicons/favicons/favicon.svg +13 -0
  83. package/source/services/data-cloner/web/index.html +3 -0
  84. package/source/services/data-cloner/web/pict.min.js +12 -0
  85. package/test/Bundles_smoke_tests.js +43 -0
  86. package/test/ComprehensionLoader_smoke_tests.js +95 -0
  87. package/test/DataCloner-RuntimeOverrides_tests.js +344 -0
  88. package/test/DataCloner_smoke_tests.js +87 -0
  89. package/docs/css/docuserve.css +0 -327
@@ -0,0 +1,142 @@
1
+ 'use strict';
2
+
3
+ const libPictView = require('pict-view');
4
+
5
+ class ComprehensionLoaderShellView extends libPictView
6
+ {
7
+ constructor(pFable, pOptions, pServiceHash)
8
+ {
9
+ super(pFable, pOptions, pServiceHash);
10
+ this._shellPanelsBuilt = false;
11
+ }
12
+
13
+ onAfterRender(pRenderable, pAddress, pRecord, pContent)
14
+ {
15
+ if (this.pict.CSSMap) { this.pict.CSSMap.injectCSS(); }
16
+ if (!this._shellPanelsBuilt)
17
+ {
18
+ this._buildShell();
19
+ this._shellPanelsBuilt = true;
20
+ }
21
+ return super.onAfterRender(pRenderable, pAddress, pRecord, pContent);
22
+ }
23
+
24
+ _buildShell()
25
+ {
26
+ let tmpModal = this.pict.views['Pict-Section-Modal'];
27
+ let tmpMount = document.getElementById('ComprehensionLoader-Shell-Mount');
28
+ if (!tmpModal || typeof tmpModal.shell !== 'function' || !tmpMount)
29
+ {
30
+ this.log.warn('ComprehensionLoader-Shell: Pict-Section-Modal or mount not available; shell not built.');
31
+ return;
32
+ }
33
+
34
+ this._shell = tmpModal.shell(tmpMount, { PersistenceKey: 'comprehension-loader-shell' });
35
+
36
+ // Top — Theme-TopBar (BrandMark + Nav + User slots)
37
+ this._shell.addPanel({
38
+ Hash: 'topbar', Side: 'top', Mode: 'fixed', Size: 56,
39
+ ContentDestinationId: 'Theme-TopBar', ContentView: 'Theme-TopBar'
40
+ });
41
+
42
+ // Bottom — Theme-BottomBar (StatusView slot)
43
+ this._shell.addPanel({
44
+ Hash: 'bottombar', Side: 'bottom', Mode: 'fixed', Size: 36,
45
+ ContentDestinationId: 'Theme-BottomBar', ContentView: 'Theme-BottomBar'
46
+ });
47
+
48
+ // Bottom (hidden overlay) — status detail expansion
49
+ this._shell.addPanel({
50
+ Hash: 'status-detail', Side: 'bottom', Mode: 'resizable', Position: 'overlay',
51
+ Size: 320, MinSize: 200, MaxSize: 480,
52
+ Hidden: true, Collapsed: true, Title: 'Status Detail',
53
+ ContentDestinationId: 'ComprehensionLoader-StatusDetail-Panel',
54
+ ContentView: 'ComprehensionLoader-StatusDetail'
55
+ });
56
+
57
+ // Right (hidden overlay) — settings
58
+ this._shell.addPanel({
59
+ Hash: 'settings', Side: 'right', Mode: 'resizable', Position: 'overlay',
60
+ Size: 360, MinSize: 280, MaxSize: 540,
61
+ Hidden: true, Collapsed: true, Title: 'Settings',
62
+ ContentDestinationId: 'ComprehensionLoader-Settings-Panel',
63
+ ContentView: 'ComprehensionLoader-SettingsPanel'
64
+ });
65
+
66
+ // Center — the workspace (existing Layout renders here)
67
+ this._shell.center({ ContentDestinationId: 'ComprehensionLoader-Workspace' });
68
+ }
69
+
70
+ getSettingsPanel() { return this._shell ? this._shell.getPanel('settings') : null; }
71
+ getStatusDetailPanel() { return this._shell ? this._shell.getPanel('status-detail') : null; }
72
+
73
+ toggleSettingsPanel()
74
+ {
75
+ let tmpPanel = this.getSettingsPanel();
76
+ if (tmpPanel) { tmpPanel.toggle(); }
77
+ }
78
+
79
+ toggleStatusDetail()
80
+ {
81
+ let tmpPanel = this.getStatusDetailPanel();
82
+ if (!tmpPanel) { return; }
83
+ tmpPanel.toggle();
84
+
85
+ // Notify the provider so it can start/stop the higher-frequency detail poll.
86
+ let tmpProvider = this.pict.providers.ComprehensionLoader;
87
+ let tmpOpen = !tmpPanel.Collapsed;
88
+ if (tmpProvider && tmpOpen && typeof tmpProvider.onStatusDetailExpanded === 'function')
89
+ {
90
+ tmpProvider.onStatusDetailExpanded();
91
+ }
92
+ else if (tmpProvider && !tmpOpen && typeof tmpProvider.onStatusDetailCollapsed === 'function')
93
+ {
94
+ tmpProvider.onStatusDetailCollapsed();
95
+ }
96
+ }
97
+
98
+ renderTopBar()
99
+ {
100
+ let tmpNav = this.pict.views['ComprehensionLoader-TopBar-Nav'];
101
+ let tmpUser = this.pict.views['ComprehensionLoader-TopBar-User'];
102
+ if (tmpNav) { tmpNav.render(); }
103
+ if (tmpUser) { tmpUser.render(); }
104
+ }
105
+ }
106
+
107
+ module.exports = ComprehensionLoaderShellView;
108
+
109
+ module.exports.default_configuration =
110
+ {
111
+ ViewIdentifier: 'ComprehensionLoader-Shell',
112
+ DefaultRenderable: 'ComprehensionLoader-Shell',
113
+ DefaultDestinationAddress: '#ComprehensionLoader-Application-Container',
114
+ AutoRender: false,
115
+ CSS: /*css*/`
116
+ html, body { height: 100%; margin: 0; padding: 0; }
117
+ body {
118
+ background: var(--theme-color-background-primary, #f5f5f5);
119
+ color: var(--theme-color-text-primary, #333333);
120
+ font-family: var(--theme-typography-family-sans,
121
+ -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif);
122
+ }
123
+ #ComprehensionLoader-Application-Container { height: 100%; min-height: 0; overflow: hidden; }
124
+ .pict-modal-shell-host { height: 100%; }
125
+ .pict-modal-shell { background: var(--theme-color-background-primary, #f5f5f5); }
126
+ .pict-modal-shell-panel { background: var(--theme-color-background-panel, #ffffff); }
127
+ .pict-modal-shell-center {
128
+ background: var(--theme-color-background-primary, #f5f5f5);
129
+ overflow: auto;
130
+ padding: 20px;
131
+ }
132
+ `,
133
+ Templates: [{
134
+ Hash: 'ComprehensionLoader-Shell',
135
+ Template: /*html*/`<div id="ComprehensionLoader-Shell-Mount" style="height:100%"></div>`
136
+ }],
137
+ Renderables: [{
138
+ RenderableHash: 'ComprehensionLoader-Shell',
139
+ TemplateHash: 'ComprehensionLoader-Shell',
140
+ DestinationAddress: '#ComprehensionLoader-Application-Container'
141
+ }]
142
+ };
@@ -189,8 +189,8 @@ class ComprehensionLoaderSourceView extends libPictView
189
189
  if (!tmpContainer) return;
190
190
 
191
191
  let tmpHtml = '<table style="width:100%; border-collapse:collapse; margin-top:8px; font-size:0.9em">';
192
- tmpHtml += '<thead><tr><th style="text-align:left; padding:6px 12px; border-bottom:2px solid #ddd">Entity</th>';
193
- tmpHtml += '<th style="text-align:right; padding:6px 12px; border-bottom:2px solid #ddd">Records</th></tr></thead>';
192
+ tmpHtml += '<thead><tr><th style="text-align:left; padding:6px 12px; border-bottom:2px solid var(--theme-color-border-default, #ddd)">Entity</th>';
193
+ tmpHtml += '<th style="text-align:right; padding:6px 12px; border-bottom:2px solid var(--theme-color-border-default, #ddd)">Records</th></tr></thead>';
194
194
  tmpHtml += '<tbody>';
195
195
 
196
196
  let tmpEntityList = pResult.EntityList || [];
@@ -200,8 +200,8 @@ class ComprehensionLoaderSourceView extends libPictView
200
200
  let tmpName = tmpEntityList[i];
201
201
  let tmpCount = tmpRecordCounts[tmpName] || 0;
202
202
  tmpHtml += '<tr>';
203
- tmpHtml += '<td style="padding:4px 12px; border-bottom:1px solid #f0f0f0">' + this.pict.providers.ComprehensionLoader.escapeHtml(tmpName) + '</td>';
204
- tmpHtml += '<td style="padding:4px 12px; border-bottom:1px solid #f0f0f0; text-align:right; font-variant-numeric:tabular-nums">' + this.pict.providers.ComprehensionLoader.formatNumber(tmpCount) + '</td>';
203
+ tmpHtml += '<td style="padding:4px 12px; border-bottom:1px solid var(--theme-color-background-tertiary, #f0f0f0)">' + this.pict.providers.ComprehensionLoader.escapeHtml(tmpName) + '</td>';
204
+ tmpHtml += '<td style="padding:4px 12px; border-bottom:1px solid var(--theme-color-background-tertiary, #f0f0f0); text-align:right; font-variant-numeric:tabular-nums">' + this.pict.providers.ComprehensionLoader.formatNumber(tmpCount) + '</td>';
205
205
  tmpHtml += '</tr>';
206
206
  }
207
207
 
@@ -287,11 +287,11 @@ module.exports.default_configuration =
287
287
  <div style="display:flex; gap:16px; align-items:center">
288
288
  <label style="font-weight:normal; margin:0; cursor:pointer">
289
289
  <input type="radio" name="comprehensionSourceMode" id="sourceMode_url" value="url" checked onchange="pict.views['ComprehensionLoader-Source'].onSourceModeChange()"> URL
290
- <span style="color:#888; font-size:0.85em">(fetch from a URL)</span>
290
+ <span style="color:var(--theme-color-text-muted, #888); font-size:0.85em">(fetch from a URL)</span>
291
291
  </label>
292
292
  <label style="font-weight:normal; margin:0; cursor:pointer">
293
293
  <input type="radio" name="comprehensionSourceMode" id="sourceMode_file" value="file" onchange="pict.views['ComprehensionLoader-Source'].onSourceModeChange()"> File Upload
294
- <span style="color:#888; font-size:0.85em">(load JSON from local files)</span>
294
+ <span style="color:var(--theme-color-text-muted, #888); font-size:0.85em">(load JSON from local files)</span>
295
295
  </label>
296
296
  </div>
297
297
  </div>
@@ -305,7 +305,7 @@ module.exports.default_configuration =
305
305
  <div id="sourceFileSection" style="display:none">
306
306
  <label for="comprehensionFiles">Comprehension JSON File(s)</label>
307
307
  <input type="file" id="comprehensionFiles" multiple accept=".json" style="margin-bottom:10px">
308
- <div style="font-size:0.8em; color:#888; margin-bottom:10px">Multiple files will be merged (entity keys combined).</div>
308
+ <div style="font-size:0.8em; color:var(--theme-color-text-muted, #888); margin-bottom:10px">Multiple files will be merged (entity keys combined).</div>
309
309
  <button class="primary" onclick="pict.views['ComprehensionLoader-Source'].loadFromFiles()">Load Files</button>
310
310
  </div>
311
311
 
@@ -0,0 +1,125 @@
1
+ 'use strict';
2
+
3
+ const libPictView = require('pict-view');
4
+
5
+ /**
6
+ * StatusBar — renders into Theme-BottomBar's #Theme-BottomBar-Status slot.
7
+ *
8
+ * Markup preserves the same element ids (#liveStatusBar, #liveStatusMessage,
9
+ * #liveStatusMeta, #liveStatusProgressFill) that the provider's existing
10
+ * renderLiveStatus() poll handler manipulates by id — so the provider's
11
+ * imperative DOM update flow keeps working untouched.
12
+ */
13
+ class ComprehensionLoaderStatusBarView extends libPictView
14
+ {
15
+ onAfterRender(pRenderable, pAddress, pRecord, pContent)
16
+ {
17
+ if (this.pict.CSSMap) { this.pict.CSSMap.injectCSS(); }
18
+ return super.onAfterRender(pRenderable, pAddress, pRecord, pContent);
19
+ }
20
+ }
21
+
22
+ module.exports = ComprehensionLoaderStatusBarView;
23
+
24
+ module.exports.default_configuration =
25
+ {
26
+ ViewIdentifier: 'ComprehensionLoader-StatusBar',
27
+ DefaultRenderable: 'ComprehensionLoader-StatusBar',
28
+ DefaultDestinationAddress: '#Theme-BottomBar-Status',
29
+ AutoRender: false,
30
+ CSS: /*css*/`
31
+ .rds-status-bar {
32
+ display: flex; align-items: center; gap: 12px;
33
+ height: 100%; padding: 0 12px;
34
+ color: var(--theme-color-text-primary, #333333);
35
+ font-size: 0.88em;
36
+ border-top: 1px solid var(--theme-color-border-light, #e9e9e9);
37
+ border-left: 3px solid var(--theme-color-text-secondary, #6c757d);
38
+ position: relative;
39
+ }
40
+ .rds-status-bar.phase-idle { border-left-color: var(--theme-color-text-secondary, #6c757d); }
41
+ .rds-status-bar.phase-disconnected { border-left-color: var(--theme-color-status-error, #dc3545); }
42
+ .rds-status-bar.phase-ready { border-left-color: var(--theme-color-brand-primary, #4a90d9); }
43
+ .rds-status-bar.phase-loading { border-left-color: var(--theme-color-status-success, #28a745); }
44
+ .rds-status-bar.phase-stopping { border-left-color: var(--theme-color-status-warning, #ffc107); }
45
+ .rds-status-bar.phase-complete { border-left-color: var(--theme-color-status-success, #28a745); }
46
+
47
+ .rds-status-dot {
48
+ width: 10px; height: 10px; border-radius: 50%;
49
+ flex-shrink: 0;
50
+ background: var(--theme-color-text-secondary, #6c757d);
51
+ }
52
+ .rds-status-bar.phase-idle .rds-status-dot { background: var(--theme-color-text-secondary, #6c757d); }
53
+ .rds-status-bar.phase-disconnected .rds-status-dot { background: var(--theme-color-status-error, #dc3545); }
54
+ .rds-status-bar.phase-ready .rds-status-dot { background: var(--theme-color-brand-primary, #4a90d9); }
55
+ .rds-status-bar.phase-loading .rds-status-dot {
56
+ background: var(--theme-color-status-success, #28a745);
57
+ animation: rds-status-pulse 1.5s ease-in-out infinite;
58
+ }
59
+ .rds-status-bar.phase-stopping .rds-status-dot {
60
+ background: var(--theme-color-status-warning, #ffc107);
61
+ animation: rds-status-pulse 0.8s ease-in-out infinite;
62
+ }
63
+ .rds-status-bar.phase-complete .rds-status-dot { background: var(--theme-color-status-success, #28a745); }
64
+
65
+ @keyframes rds-status-pulse {
66
+ 0%, 100% { opacity: 1; transform: scale(1); }
67
+ 50% { opacity: 0.4; transform: scale(0.8); }
68
+ }
69
+
70
+ .rds-status-message { flex: 1; line-height: 1.2; }
71
+ .rds-status-meta {
72
+ display: flex; gap: 12px; flex-shrink: 0;
73
+ font-size: 0.92em; color: var(--theme-color-text-secondary, #666);
74
+ }
75
+ .rds-status-meta .live-status-meta-item { white-space: nowrap; }
76
+ .rds-status-meta .live-status-meta-item strong { color: var(--theme-color-text-primary, #333); }
77
+
78
+ .rds-status-detail-btn {
79
+ padding: 2px 8px;
80
+ background: transparent;
81
+ border: 1px solid var(--theme-color-border-default, #ccc);
82
+ border-radius: 3px;
83
+ color: var(--theme-color-text-secondary, #666);
84
+ cursor: pointer;
85
+ font-size: 0.92em;
86
+ line-height: 1;
87
+ }
88
+ .rds-status-detail-btn:hover {
89
+ background: var(--theme-color-background-hover, #f0f0f0);
90
+ color: var(--theme-color-text-primary, #333);
91
+ }
92
+
93
+ .rds-status-progress-bar {
94
+ position: absolute; left: 0; right: 0; bottom: 0;
95
+ height: 2px;
96
+ background: var(--theme-color-background-tertiary, #e9ecef);
97
+ overflow: hidden;
98
+ }
99
+ .rds-status-progress-fill {
100
+ height: 100%;
101
+ background: var(--theme-color-status-success, #28a745);
102
+ transition: width 1s ease;
103
+ }
104
+ `,
105
+ Templates: [{
106
+ Hash: 'ComprehensionLoader-StatusBar',
107
+ Template: /*html*/`
108
+ <div id="liveStatusBar" class="rds-status-bar phase-idle">
109
+ <div class="rds-status-dot live-status-dot"></div>
110
+ <div id="liveStatusMessage" class="rds-status-message live-status-message">Idle</div>
111
+ <div id="liveStatusMeta" class="rds-status-meta live-status-meta"></div>
112
+ <button class="rds-status-detail-btn"
113
+ onclick="_Pict.views['ComprehensionLoader-Shell'].toggleStatusDetail()"
114
+ title="Show detail">Detail</button>
115
+ <div class="rds-status-progress-bar live-status-progress-bar">
116
+ <div id="liveStatusProgressFill" class="rds-status-progress-fill live-status-progress-fill" style="width:0%"></div>
117
+ </div>
118
+ </div>`
119
+ }],
120
+ Renderables: [{
121
+ RenderableHash: 'ComprehensionLoader-StatusBar',
122
+ TemplateHash: 'ComprehensionLoader-StatusBar',
123
+ DestinationAddress: '#Theme-BottomBar-Status'
124
+ }]
125
+ };
@@ -0,0 +1,89 @@
1
+ 'use strict';
2
+
3
+ const libPictView = require('pict-view');
4
+
5
+ /**
6
+ * StatusDetail — content for the expandable bottom overlay panel.
7
+ *
8
+ * Renders the throughput histogram slot and the running-ops / completed-ops /
9
+ * errors detail container, both of which the existing provider populates by
10
+ * direct DOM manipulation. The element ids (#X-Throughput-Histogram,
11
+ * #X-StatusDetail-Container) are preserved so the provider keeps working.
12
+ */
13
+ class ComprehensionLoaderStatusDetailView extends libPictView
14
+ {
15
+ onAfterRender(pRenderable, pAddress, pRecord, pContent)
16
+ {
17
+ if (this.pict.CSSMap) { this.pict.CSSMap.injectCSS(); }
18
+ return super.onAfterRender(pRenderable, pAddress, pRecord, pContent);
19
+ }
20
+ }
21
+
22
+ module.exports = ComprehensionLoaderStatusDetailView;
23
+
24
+ module.exports.default_configuration =
25
+ {
26
+ ViewIdentifier: 'ComprehensionLoader-StatusDetail',
27
+ DefaultRenderable: 'ComprehensionLoader-StatusDetail',
28
+ DefaultDestinationAddress: '#ComprehensionLoader-StatusDetail-Panel',
29
+ AutoRender: false,
30
+ CSS: /*css*/`
31
+ .rds-status-detail-body {
32
+ padding: 12px 20px 16px;
33
+ max-height: 100%;
34
+ overflow-y: auto;
35
+ color: var(--theme-color-text-primary, #333);
36
+ }
37
+ .rds-status-detail-section { margin-bottom: 14px; }
38
+ .rds-status-detail-section:last-child { margin-bottom: 0; }
39
+ .rds-status-detail-section-title {
40
+ font-size: 0.85em; font-weight: 600;
41
+ color: var(--theme-color-text-secondary, #555);
42
+ text-transform: uppercase; letter-spacing: 0.5px;
43
+ margin-bottom: 8px; padding-bottom: 4px;
44
+ border-bottom: 1px solid var(--theme-color-border-light, #eee);
45
+ }
46
+ .running-op-row { display: flex; align-items: center; gap: 12px; padding: 6px 0; font-size: 0.9em; }
47
+ .running-op-name { font-weight: 600; min-width: 180px; }
48
+ .running-op-bar {
49
+ flex: 1; height: 8px;
50
+ background: var(--theme-color-background-tertiary, #e9ecef);
51
+ border-radius: 4px; overflow: hidden; min-width: 120px;
52
+ }
53
+ .running-op-bar-fill {
54
+ height: 100%;
55
+ background: var(--theme-color-brand-primary, #4a90d9);
56
+ transition: width 0.5s ease;
57
+ }
58
+ .running-op-count { font-size: 0.85em; color: var(--theme-color-text-secondary, #666); white-space: nowrap; }
59
+ .running-op-pending { color: var(--theme-color-text-muted, #888); font-size: 0.85em; font-style: italic; padding: 4px 0; }
60
+ .completed-op-row { padding: 8px 0; border-bottom: 1px solid var(--theme-color-background-tertiary, #f0f0f0); }
61
+ .completed-op-row:last-child { border-bottom: none; }
62
+ .completed-op-header { display: flex; align-items: center; gap: 10px; font-size: 0.9em; margin-bottom: 4px; }
63
+ .completed-op-name { font-weight: 600; }
64
+ .completed-op-stats { color: var(--theme-color-text-secondary, #666); font-size: 0.85em; }
65
+ .completed-op-checkmark { color: var(--theme-color-status-success, #28a745); }
66
+ .error-op-row { padding: 6px 0; border-bottom: 1px solid var(--theme-color-background-tertiary, #f0f0f0); font-size: 0.9em; }
67
+ .error-op-row:last-child { border-bottom: none; }
68
+ .error-op-header { display: flex; align-items: center; gap: 8px; }
69
+ .error-op-name { font-weight: 600; color: var(--theme-color-status-error, #dc3545); }
70
+ .error-op-status { font-size: 0.82em; color: var(--theme-color-status-error, #dc3545); }
71
+ .error-op-message { font-size: 0.82em; color: var(--theme-color-text-muted, #888); margin-top: 2px; padding-left: 18px; }
72
+ `,
73
+ Templates: [{
74
+ Hash: 'ComprehensionLoader-StatusDetail',
75
+ Template: /*html*/`
76
+ <div class="rds-status-detail-body">
77
+ <div class="rds-status-detail-section">
78
+ <div class="rds-status-detail-section-title">Throughput</div>
79
+ <div id="ComprehensionLoader-Throughput-Histogram" style="height:120px"></div>
80
+ </div>
81
+ <div id="ComprehensionLoader-StatusDetail-Container"></div>
82
+ </div>`
83
+ }],
84
+ Renderables: [{
85
+ RenderableHash: 'ComprehensionLoader-StatusDetail',
86
+ TemplateHash: 'ComprehensionLoader-StatusDetail',
87
+ DestinationAddress: '#ComprehensionLoader-StatusDetail-Panel'
88
+ }]
89
+ };
@@ -0,0 +1,42 @@
1
+ 'use strict';
2
+
3
+ const libPictView = require('pict-view');
4
+
5
+ class ComprehensionLoaderTopBarNavView extends libPictView
6
+ {
7
+ onAfterRender(pRenderable, pAddress, pRecord, pContent)
8
+ {
9
+ if (this.pict.CSSMap) { this.pict.CSSMap.injectCSS(); }
10
+ return super.onAfterRender(pRenderable, pAddress, pRecord, pContent);
11
+ }
12
+ }
13
+
14
+ module.exports = ComprehensionLoaderTopBarNavView;
15
+
16
+ module.exports.default_configuration =
17
+ {
18
+ ViewIdentifier: 'ComprehensionLoader-TopBar-Nav',
19
+ DefaultRenderable: 'ComprehensionLoader-TopBar-Nav',
20
+ DefaultDestinationAddress: '#Theme-TopBar-Nav',
21
+ AutoRender: false,
22
+ CSS: /*css*/`
23
+ .rds-nav {
24
+ display: flex; align-items: center; height: 100%;
25
+ padding: 0 12px; gap: 8px;
26
+ color: var(--theme-color-text-on-brand,
27
+ var(--theme-color-text-primary, #1a1a1a));
28
+ font-weight: 500;
29
+ }
30
+ .rds-nav-sep { opacity: 0.5; font-weight: 400; margin: 0 2px; }
31
+ .rds-nav-app { font-weight: 600; opacity: 0.95; }
32
+ `,
33
+ Templates: [{
34
+ Hash: 'ComprehensionLoader-TopBar-Nav',
35
+ Template: /*html*/`<div class="rds-nav"><span class="rds-nav-sep">·</span><span class="rds-nav-app">Comprehension Loader</span></div>`
36
+ }],
37
+ Renderables: [{
38
+ RenderableHash: 'ComprehensionLoader-TopBar-Nav',
39
+ TemplateHash: 'ComprehensionLoader-TopBar-Nav',
40
+ DestinationAddress: '#Theme-TopBar-Nav'
41
+ }]
42
+ };
@@ -0,0 +1,48 @@
1
+ 'use strict';
2
+
3
+ const libPictView = require('pict-view');
4
+
5
+ class ComprehensionLoaderTopBarUserView extends libPictView
6
+ {
7
+ onAfterRender(pRenderable, pAddress, pRecord, pContent)
8
+ {
9
+ if (this.pict.CSSMap) { this.pict.CSSMap.injectCSS(); }
10
+ return super.onAfterRender(pRenderable, pAddress, pRecord, pContent);
11
+ }
12
+ }
13
+
14
+ module.exports = ComprehensionLoaderTopBarUserView;
15
+
16
+ module.exports.default_configuration =
17
+ {
18
+ ViewIdentifier: 'ComprehensionLoader-TopBar-User',
19
+ DefaultRenderable: 'ComprehensionLoader-TopBar-User',
20
+ DefaultDestinationAddress: '#Theme-TopBar-User',
21
+ AutoRender: false,
22
+ CSS: /*css*/`
23
+ .rds-user { display: flex; align-items: center; height: 100%; gap: 8px; padding: 0 12px; }
24
+ .rds-user-btn {
25
+ padding: 4px 8px;
26
+ border: 1px solid var(--theme-color-border-default, #5E5549);
27
+ background: transparent;
28
+ color: var(--theme-color-text-on-brand,
29
+ var(--theme-color-text-secondary, #1a1a1a));
30
+ border-radius: 4px;
31
+ cursor: pointer;
32
+ display: inline-flex; align-items: center; justify-content: center;
33
+ font-size: 1em; line-height: 1;
34
+ }
35
+ .rds-user-btn:hover {
36
+ background: var(--theme-color-background-hover, rgba(255,255,255,0.08));
37
+ }
38
+ `,
39
+ Templates: [{
40
+ Hash: 'ComprehensionLoader-TopBar-User',
41
+ Template: /*html*/`<div class="rds-user"><button class="rds-user-btn" onclick="_Pict.views['ComprehensionLoader-Shell'].toggleSettingsPanel()" title="Settings" aria-label="Settings">{~I:Settings~}</button></div>`
42
+ }],
43
+ Renderables: [{
44
+ RenderableHash: 'ComprehensionLoader-TopBar-User',
45
+ TemplateHash: 'ComprehensionLoader-TopBar-User',
46
+ DestinationAddress: '#Theme-TopBar-User'
47
+ }]
48
+ };