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
@@ -45,37 +45,6 @@ class DataClonerLayoutView extends libPictView
45
45
  tmpCards[i].classList.remove('open');
46
46
  }
47
47
  }
48
-
49
- toggleStatusDetail()
50
- {
51
- let tmpDetail = document.getElementById('liveStatusDetail');
52
- let tmpMeta = document.getElementById('liveStatusMeta');
53
- let tmpMessage = document.getElementById('liveStatusMessage');
54
- let tmpToggle = document.getElementById('liveStatusToggle');
55
- let tmpBar = document.getElementById('liveStatusBar');
56
- if (!tmpDetail) return;
57
-
58
- let tmpIsExpanded = tmpDetail.style.display !== 'none';
59
-
60
- if (tmpIsExpanded)
61
- {
62
- tmpDetail.style.display = 'none';
63
- tmpMeta.style.display = '';
64
- tmpMessage.style.display = '';
65
- tmpToggle.innerHTML = '▼';
66
- tmpBar.classList.remove('expanded');
67
- this.pict.providers.DataCloner.onStatusDetailCollapsed();
68
- }
69
- else
70
- {
71
- tmpDetail.style.display = '';
72
- tmpMeta.style.display = 'none';
73
- tmpMessage.style.display = 'none';
74
- tmpToggle.innerHTML = '▲';
75
- tmpBar.classList.add('expanded');
76
- this.pict.providers.DataCloner.onStatusDetailExpanded();
77
- }
78
- }
79
48
  }
80
49
 
81
50
  module.exports = DataClonerLayoutView;
@@ -84,61 +53,61 @@ module.exports.default_configuration =
84
53
  {
85
54
  ViewIdentifier: 'DataCloner-Layout',
86
55
  DefaultRenderable: 'DataCloner-Layout',
87
- DefaultDestinationAddress: '#DataCloner-Application-Container',
56
+ DefaultDestinationAddress: '#DataCloner-Workspace',
88
57
  CSS: /*css*/`
89
58
  * { box-sizing: border-box; margin: 0; padding: 0; }
90
- body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #f5f5f5; color: #333; padding: 20px; }
91
- h1 { margin-bottom: 20px; color: #1a1a1a; }
92
- h2 { margin-bottom: 12px; color: #444; font-size: 1.2em; border-bottom: 2px solid #ddd; padding-bottom: 6px; }
59
+ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: var(--theme-color-background-secondary, #f5f5f5); color: var(--theme-color-text-primary, #333); padding: 20px; }
60
+ h1 { margin-bottom: 20px; color: var(--theme-color-text-primary, #1a1a1a); }
61
+ h2 { margin-bottom: 12px; color: var(--theme-color-text-secondary, #444); font-size: 1.2em; border-bottom: 2px solid var(--theme-color-border-default, #ddd); padding-bottom: 6px; }
93
62
 
94
- .section { background: #fff; border-radius: 8px; padding: 20px; margin-bottom: 16px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
63
+ .section { background: var(--theme-color-background-panel, #fff); border-radius: 8px; padding: 20px; margin-bottom: 16px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
95
64
 
96
65
  /* Accordion layout */
97
66
  .accordion-row { display: flex; gap: 0; margin-bottom: 16px; align-items: stretch; }
98
67
  .accordion-number {
99
68
  flex: 0 0 48px; display: flex; align-items: flex-start; justify-content: center;
100
- padding-top: 16px; font-size: 1.6em; font-weight: 700; color: #4a90d9;
69
+ padding-top: 16px; font-size: 1.6em; font-weight: 700; color: var(--theme-color-brand-primary, #4a90d9);
101
70
  user-select: none;
102
71
  }
103
72
  .accordion-card {
104
- flex: 1; background: #fff; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.1);
73
+ flex: 1; background: var(--theme-color-background-panel, #fff); border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.1);
105
74
  overflow: hidden; min-width: 0;
106
75
  }
107
76
  .accordion-header {
108
77
  display: flex; align-items: center; padding: 14px 20px; cursor: pointer;
109
78
  user-select: none; gap: 12px; transition: background 0.15s; line-height: 1.4;
110
79
  }
111
- .accordion-header:hover { background: #fafafa; }
112
- .accordion-title { font-weight: 600; color: #333; font-size: 1.05em; white-space: nowrap; }
113
- .accordion-preview { flex: 1; font-style: italic; color: #888; font-size: 0.9em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
80
+ .accordion-header:hover { background: var(--theme-color-background-secondary, #fafafa); }
81
+ .accordion-title { font-weight: 600; color: var(--theme-color-text-primary, #333); font-size: 1.05em; white-space: nowrap; }
82
+ .accordion-preview { flex: 1; font-style: italic; color: var(--theme-color-text-muted, #888); font-size: 0.9em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
114
83
  .accordion-toggle {
115
84
  flex: 0 0 20px; display: flex; align-items: center; justify-content: center;
116
- border-radius: 4px; transition: background 0.15s, transform 0.25s; font-size: 0.7em; color: #888;
85
+ border-radius: 4px; transition: background 0.15s, transform 0.25s; font-size: 0.7em; color: var(--theme-color-text-muted, #888);
117
86
  }
118
- .accordion-header:hover .accordion-toggle { background: #eee; color: #555; }
87
+ .accordion-header:hover .accordion-toggle { background: var(--theme-color-border-light, #eee); color: var(--theme-color-text-secondary, #555); }
119
88
  .accordion-card.open .accordion-toggle { transform: rotate(180deg); }
120
89
  .accordion-body { padding: 0 20px 20px; display: none; }
121
90
  .accordion-card.open .accordion-body { display: block; }
122
- .accordion-card.open .accordion-header { border-bottom: 1px solid #eee; }
91
+ .accordion-card.open .accordion-header { border-bottom: 1px solid var(--theme-color-border-light, #eee); }
123
92
  .accordion-card.open .accordion-preview { display: none; }
124
93
 
125
94
  /* Action controls (go link + auto checkbox) */
126
95
  .accordion-actions { display: flex; align-items: baseline; gap: 8px; flex-shrink: 0; }
127
96
  .accordion-card.open .accordion-actions { display: none; }
128
97
  .accordion-go {
129
- font-size: 0.82em; color: #4a90d9; cursor: pointer; text-decoration: none;
98
+ font-size: 0.82em; color: var(--theme-color-brand-primary, #4a90d9); cursor: pointer; text-decoration: none;
130
99
  font-weight: 500; white-space: nowrap; padding: 2px 6px; border-radius: 3px;
131
100
  transition: background 0.15s;
132
101
  }
133
- .accordion-go:hover { background: #e8f0fe; text-decoration: underline; }
102
+ .accordion-go:hover { background: var(--theme-color-background-hover, #e8f0fe); text-decoration: underline; }
134
103
  .accordion-auto {
135
- font-size: 0.82em; color: #999; white-space: nowrap; cursor: pointer;
104
+ font-size: 0.82em; color: var(--theme-color-text-muted, #999); white-space: nowrap; cursor: pointer;
136
105
  }
137
106
  .accordion-auto .auto-label { display: none; }
138
107
  .accordion-auto:hover .auto-label { display: inline; }
139
108
  .accordion-auto input[type="checkbox"] { width: auto; margin: 0; cursor: pointer; vertical-align: middle; position: relative; top: 0px; opacity: 0.75; transition: opacity 0.15s; }
140
109
  .accordion-auto:hover input[type="checkbox"] { opacity: 1; }
141
- .accordion-auto:hover { color: #666; }
110
+ .accordion-auto:hover { color: var(--theme-color-text-secondary, #666); }
142
111
 
143
112
  /* Phase status indicator */
144
113
  .accordion-phase {
@@ -146,12 +115,12 @@ h2 { margin-bottom: 12px; color: #444; font-size: 1.2em; border-bottom: 2px soli
146
115
  font-size: 0.85em; line-height: 1;
147
116
  }
148
117
  .accordion-phase.visible { display: flex; }
149
- .accordion-phase-ok { color: #28a745; }
150
- .accordion-phase-error { color: #dc3545; }
151
- .accordion-phase-busy { color: #28a745; }
118
+ .accordion-phase-ok { color: var(--theme-color-status-success, #28a745); }
119
+ .accordion-phase-error { color: var(--theme-color-status-error, #dc3545); }
120
+ .accordion-phase-busy { color: var(--theme-color-status-success, #28a745); }
152
121
  .accordion-phase-busy .phase-spinner {
153
122
  display: inline-block; width: 14px; height: 14px;
154
- border: 2px solid #28a745; border-top-color: transparent; border-radius: 50%;
123
+ border: 2px solid var(--theme-color-status-success, #28a745); border-top-color: transparent; border-radius: 50%;
155
124
  animation: phase-spin 0.8s linear infinite; vertical-align: middle;
156
125
  }
157
126
  @keyframes phase-spin {
@@ -163,30 +132,30 @@ h2 { margin-bottom: 12px; color: #444; font-size: 1.2em; border-bottom: 2px soli
163
132
  }
164
133
  .accordion-controls button {
165
134
  padding: 4px 10px; font-size: 0.82em; font-weight: 500; background: none;
166
- border: 1px solid #ccc; border-radius: 4px; color: #666; cursor: pointer; margin: 0;
135
+ border: 1px solid var(--theme-color-border-default, #ccc); border-radius: 4px; color: var(--theme-color-text-secondary, #666); cursor: pointer; margin: 0;
167
136
  }
168
- .accordion-controls button:hover { background: #f0f0f0; border-color: #aaa; color: #333; }
137
+ .accordion-controls button:hover { background: var(--theme-color-background-tertiary, #f0f0f0); border-color: var(--theme-color-text-muted, #aaa); color: var(--theme-color-text-primary, #333); }
169
138
 
170
139
  label { display: block; font-weight: 600; margin-bottom: 4px; font-size: 0.9em; }
171
140
  input[type="text"], input[type="password"], input[type="number"] {
172
- width: 100%; padding: 8px 12px; border: 1px solid #ccc; border-radius: 4px;
141
+ width: 100%; padding: 8px 12px; border: 1px solid var(--theme-color-border-default, #ccc); border-radius: 4px;
173
142
  font-size: 0.95em; margin-bottom: 10px;
174
143
  }
175
144
  input[type="text"]:focus, input[type="password"]:focus, input[type="number"]:focus {
176
- outline: none; border-color: #4a90d9;
145
+ outline: none; border-color: var(--theme-color-brand-primary, #4a90d9);
177
146
  }
178
147
 
179
148
  button {
180
149
  padding: 8px 16px; border: none; border-radius: 4px; cursor: pointer;
181
150
  font-size: 0.9em; font-weight: 600; margin-right: 8px; margin-bottom: 8px;
182
151
  }
183
- button.primary { background: #4a90d9; color: #fff; }
184
- button.primary:hover { background: #357abd; }
185
- button.secondary { background: #6c757d; color: #fff; }
152
+ button.primary { background: var(--theme-color-brand-primary, #4a90d9); color: var(--theme-color-background-panel, #fff); }
153
+ button.primary:hover { background: var(--theme-color-brand-primary-hover, #357abd); }
154
+ button.secondary { background: var(--theme-color-text-secondary, #6c757d); color: var(--theme-color-background-panel, #fff); }
186
155
  button.secondary:hover { background: #5a6268; }
187
- button.danger { background: #dc3545; color: #fff; }
156
+ button.danger { background: var(--theme-color-status-error, #dc3545); color: var(--theme-color-background-panel, #fff); }
188
157
  button.danger:hover { background: #c82333; }
189
- button.success { background: #28a745; color: #fff; }
158
+ button.success { background: var(--theme-color-status-success, #28a745); color: var(--theme-color-background-panel, #fff); }
190
159
  button.success:hover { background: #218838; }
191
160
  button:disabled { opacity: 0.5; cursor: not-allowed; }
192
161
 
@@ -199,9 +168,9 @@ button:disabled { opacity: 0.5; cursor: not-allowed; }
199
168
  .inline-group { display: flex; gap: 8px; align-items: flex-end; margin-bottom: 10px; }
200
169
  .inline-group > div { flex: 1; }
201
170
 
202
- a { color: #4a90d9; }
171
+ a { color: var(--theme-color-brand-primary, #4a90d9); }
203
172
 
204
- select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #ccc; border-radius: 4px; font-size: 0.95em; margin-bottom: 10px; }
173
+ select { background: var(--theme-color-background-panel, #fff); width: 100%; padding: 8px 12px; border: 1px solid var(--theme-color-border-default, #ccc); border-radius: 4px; font-size: 0.95em; margin-bottom: 10px; }
205
174
 
206
175
  .checkbox-row { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
207
176
  .checkbox-row input[type="checkbox"] { width: auto; margin: 0; }
@@ -209,53 +178,53 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
209
178
 
210
179
  /* Live Status Bar */
211
180
  .live-status-bar {
212
- background: #fff; border-radius: 8px; margin-bottom: 16px;
181
+ background: var(--theme-color-background-panel, #fff); border-radius: 8px; margin-bottom: 16px;
213
182
  box-shadow: 0 1px 3px rgba(0,0,0,0.1);
214
- position: sticky; top: 0; z-index: 100; border-left: 4px solid #6c757d;
183
+ position: sticky; top: 0; z-index: 100; border-left: 4px solid var(--theme-color-text-secondary, #6c757d);
215
184
  }
216
- .live-status-bar.phase-idle { border-left-color: #6c757d; }
217
- .live-status-bar.phase-disconnected { border-left-color: #dc3545; }
218
- .live-status-bar.phase-ready { border-left-color: #4a90d9; }
219
- .live-status-bar.phase-syncing { border-left-color: #28a745; }
220
- .live-status-bar.phase-stopping { border-left-color: #ffc107; }
221
- .live-status-bar.phase-complete { border-left-color: #28a745; }
185
+ .live-status-bar.phase-idle { border-left-color: var(--theme-color-text-secondary, #6c757d); }
186
+ .live-status-bar.phase-disconnected { border-left-color: var(--theme-color-status-error, #dc3545); }
187
+ .live-status-bar.phase-ready { border-left-color: var(--theme-color-brand-primary, #4a90d9); }
188
+ .live-status-bar.phase-syncing { border-left-color: var(--theme-color-status-success, #28a745); }
189
+ .live-status-bar.phase-stopping { border-left-color: var(--theme-color-status-warning, #ffc107); }
190
+ .live-status-bar.phase-complete { border-left-color: var(--theme-color-status-success, #28a745); }
222
191
 
223
192
  .live-status-dot {
224
193
  width: 12px; height: 12px; border-radius: 50%; flex-shrink: 0;
225
- background: #6c757d;
194
+ background: var(--theme-color-text-secondary, #6c757d);
226
195
  }
227
- .live-status-bar.phase-idle .live-status-dot { background: #6c757d; }
228
- .live-status-bar.phase-disconnected .live-status-dot { background: #dc3545; }
229
- .live-status-bar.phase-ready .live-status-dot { background: #4a90d9; }
196
+ .live-status-bar.phase-idle .live-status-dot { background: var(--theme-color-text-secondary, #6c757d); }
197
+ .live-status-bar.phase-disconnected .live-status-dot { background: var(--theme-color-status-error, #dc3545); }
198
+ .live-status-bar.phase-ready .live-status-dot { background: var(--theme-color-brand-primary, #4a90d9); }
230
199
  .live-status-bar.phase-syncing .live-status-dot {
231
- background: #28a745;
200
+ background: var(--theme-color-status-success, #28a745);
232
201
  animation: live-pulse 1.5s ease-in-out infinite;
233
202
  }
234
203
  .live-status-bar.phase-stopping .live-status-dot {
235
- background: #ffc107;
204
+ background: var(--theme-color-status-warning, #ffc107);
236
205
  animation: live-pulse 0.8s ease-in-out infinite;
237
206
  }
238
- .live-status-bar.phase-complete .live-status-dot { background: #28a745; }
207
+ .live-status-bar.phase-complete .live-status-dot { background: var(--theme-color-status-success, #28a745); }
239
208
 
240
209
  @keyframes live-pulse {
241
210
  0%, 100% { opacity: 1; transform: scale(1); }
242
211
  50% { opacity: 0.4; transform: scale(0.8); }
243
212
  }
244
213
 
245
- .live-status-message { flex: 1; font-size: 0.92em; color: #333; line-height: 1.4; }
214
+ .live-status-message { flex: 1; font-size: 0.92em; color: var(--theme-color-text-primary, #333); line-height: 1.4; }
246
215
 
247
216
  .live-status-meta {
248
- display: flex; gap: 16px; flex-shrink: 0; font-size: 0.82em; color: #666;
217
+ display: flex; gap: 16px; flex-shrink: 0; font-size: 0.82em; color: var(--theme-color-text-secondary, #666);
249
218
  }
250
219
  .live-status-meta-item { white-space: nowrap; }
251
- .live-status-meta-item strong { color: #333; }
220
+ .live-status-meta-item strong { color: var(--theme-color-text-primary, #333); }
252
221
 
253
222
  .live-status-progress-bar {
254
- height: 3px; background: #e9ecef; border-radius: 2px; overflow: hidden;
223
+ height: 3px; background: var(--theme-color-background-tertiary, #e9ecef); border-radius: 2px; overflow: hidden;
255
224
  position: absolute; bottom: 0; left: 0; right: 0;
256
225
  }
257
226
  .live-status-progress-fill {
258
- height: 100%; background: #28a745; transition: width 1s ease;
227
+ height: 100%; background: var(--theme-color-status-success, #28a745); transition: width 1s ease;
259
228
  }
260
229
  /* Expandable status bar */
261
230
  .live-status-header {
@@ -263,11 +232,11 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
263
232
  padding: 14px 20px; user-select: none;
264
233
  }
265
234
  .live-status-bar.expanded .live-status-header {
266
- border-bottom: 1px solid #e9ecef; padding-bottom: 10px;
235
+ border-bottom: 1px solid var(--theme-color-background-tertiary, #e9ecef); padding-bottom: 10px;
267
236
  }
268
237
  .live-status-expand-toggle {
269
238
  flex: 0 0 20px; display: flex; align-items: center; justify-content: center;
270
- font-size: 0.7em; color: #888; transition: transform 0.25s;
239
+ font-size: 0.7em; color: var(--theme-color-text-muted, #888); transition: transform 0.25s;
271
240
  }
272
241
  .live-status-bar.expanded .live-status-expand-toggle { transform: rotate(180deg); }
273
242
 
@@ -278,22 +247,22 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
278
247
  /* Status Detail Summary Banner */
279
248
  .status-detail-summary {
280
249
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
281
- padding: 8px 0 12px; margin-bottom: 12px; border-bottom: 1px solid #e9ecef;
250
+ padding: 8px 0 12px; margin-bottom: 12px; border-bottom: 1px solid var(--theme-color-background-tertiary, #e9ecef);
282
251
  }
283
252
  .status-detail-summary-message {
284
- font-size: 0.92em; color: #333; font-weight: 600;
253
+ font-size: 0.92em; color: var(--theme-color-text-primary, #333); font-weight: 600;
285
254
  }
286
255
  .status-detail-summary-counters {
287
- display: flex; gap: 16px; flex-wrap: wrap; font-size: 0.82em; color: #666;
256
+ display: flex; gap: 16px; flex-wrap: wrap; font-size: 0.82em; color: var(--theme-color-text-secondary, #666);
288
257
  }
289
258
 
290
259
  /* Status Detail Sections */
291
260
  .status-detail-section { margin-bottom: 14px; }
292
261
  .status-detail-section:last-child { margin-bottom: 0; }
293
262
  .status-detail-section-title {
294
- font-size: 0.85em; font-weight: 600; color: #555; text-transform: uppercase;
263
+ font-size: 0.85em; font-weight: 600; color: var(--theme-color-text-secondary, #555); text-transform: uppercase;
295
264
  letter-spacing: 0.5px; margin-bottom: 8px; padding-bottom: 4px;
296
- border-bottom: 1px solid #eee;
265
+ border-bottom: 1px solid var(--theme-color-border-light, #eee);
297
266
  }
298
267
 
299
268
  /* Running Operations */
@@ -303,52 +272,52 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
303
272
  }
304
273
  .running-op-name { font-weight: 600; min-width: 180px; }
305
274
  .running-op-bar {
306
- flex: 1; height: 8px; background: #e9ecef; border-radius: 4px; overflow: hidden;
275
+ flex: 1; height: 8px; background: var(--theme-color-background-tertiary, #e9ecef); border-radius: 4px; overflow: hidden;
307
276
  min-width: 120px;
308
277
  }
309
- .running-op-bar-fill { height: 100%; background: #4a90d9; transition: width 0.5s ease; }
310
- .running-op-count { font-size: 0.85em; color: #666; white-space: nowrap; }
311
- .running-op-pending { color: #888; font-size: 0.85em; font-style: italic; padding: 4px 0; }
278
+ .running-op-bar-fill { height: 100%; background: var(--theme-color-brand-primary, #4a90d9); transition: width 0.5s ease; }
279
+ .running-op-count { font-size: 0.85em; color: var(--theme-color-text-secondary, #666); white-space: nowrap; }
280
+ .running-op-pending { color: var(--theme-color-text-muted, #888); font-size: 0.85em; font-style: italic; padding: 4px 0; }
312
281
 
313
282
  /* Completed Operations */
314
- .completed-op-row { padding: 8px 0; border-bottom: 1px solid #f0f0f0; }
283
+ .completed-op-row { padding: 8px 0; border-bottom: 1px solid var(--theme-color-background-tertiary, #f0f0f0); }
315
284
  .completed-op-row:last-child { border-bottom: none; }
316
285
  .completed-op-header {
317
286
  display: flex; align-items: center; gap: 10px; font-size: 0.9em; margin-bottom: 4px;
318
287
  }
319
288
  .completed-op-name { font-weight: 600; }
320
- .completed-op-stats { color: #666; font-size: 0.85em; }
321
- .completed-op-checkmark { color: #28a745; }
289
+ .completed-op-stats { color: var(--theme-color-text-secondary, #666); font-size: 0.85em; }
290
+ .completed-op-checkmark { color: var(--theme-color-status-success, #28a745); }
322
291
 
323
292
  /* Ratio Bar */
324
293
  .ratio-bar-container {
325
294
  display: flex; height: 10px; border-radius: 5px; overflow: hidden;
326
- background: #e9ecef; margin: 4px 0;
295
+ background: var(--theme-color-background-tertiary, #e9ecef); margin: 4px 0;
327
296
  }
328
297
  .ratio-bar-segment { height: 100%; transition: width 0.5s ease; }
329
- .ratio-bar-segment.unchanged { background: #6c757d; }
330
- .ratio-bar-segment.new-records { background: #28a745; }
331
- .ratio-bar-segment.updated { background: #4a90d9; }
332
- .ratio-bar-segment.deleted { background: #dc3545; }
298
+ .ratio-bar-segment.unchanged { background: var(--theme-color-text-secondary, #6c757d); }
299
+ .ratio-bar-segment.new-records { background: var(--theme-color-status-success, #28a745); }
300
+ .ratio-bar-segment.updated { background: var(--theme-color-brand-primary, #4a90d9); }
301
+ .ratio-bar-segment.deleted { background: var(--theme-color-status-error, #dc3545); }
333
302
  .ratio-bar-legend {
334
- display: flex; gap: 12px; font-size: 0.75em; color: #666; margin-top: 2px; flex-wrap: wrap;
303
+ display: flex; gap: 12px; font-size: 0.75em; color: var(--theme-color-text-secondary, #666); margin-top: 2px; flex-wrap: wrap;
335
304
  }
336
305
  .ratio-bar-legend-item { display: flex; align-items: center; gap: 4px; }
337
306
  .ratio-bar-legend-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
338
- .ratio-bar-legend-dot.unchanged-dot { background: #6c757d; }
339
- .ratio-bar-legend-dot.new-dot { background: #28a745; }
340
- .ratio-bar-legend-dot.updated-dot { background: #4a90d9; }
341
- .ratio-bar-legend-dot.deleted-dot { background: #dc3545; }
307
+ .ratio-bar-legend-dot.unchanged-dot { background: var(--theme-color-text-secondary, #6c757d); }
308
+ .ratio-bar-legend-dot.new-dot { background: var(--theme-color-status-success, #28a745); }
309
+ .ratio-bar-legend-dot.updated-dot { background: var(--theme-color-brand-primary, #4a90d9); }
310
+ .ratio-bar-legend-dot.deleted-dot { background: var(--theme-color-status-error, #dc3545); }
342
311
 
343
312
  /* Error Operations */
344
- .error-op-row { padding: 6px 0; border-bottom: 1px solid #f0f0f0; font-size: 0.9em; }
313
+ .error-op-row { padding: 6px 0; border-bottom: 1px solid var(--theme-color-background-tertiary, #f0f0f0); font-size: 0.9em; }
345
314
  .error-op-row:last-child { border-bottom: none; }
346
315
  .error-op-header { display: flex; align-items: center; gap: 8px; }
347
- .error-op-name { font-weight: 600; color: #dc3545; }
348
- .error-op-status { font-size: 0.82em; color: #dc3545; }
349
- .error-op-message { font-size: 0.82em; color: #888; margin-top: 2px; padding-left: 18px; }
316
+ .error-op-name { font-weight: 600; color: var(--theme-color-status-error, #dc3545); }
317
+ .error-op-status { font-size: 0.82em; color: var(--theme-color-status-error, #dc3545); }
318
+ .error-op-message { font-size: 0.82em; color: var(--theme-color-text-muted, #888); margin-top: 2px; padding-left: 18px; }
350
319
  .error-op-log-entries {
351
- font-size: 0.78em; color: #888; margin-top: 4px; padding-left: 18px;
320
+ font-size: 0.78em; color: var(--theme-color-text-muted, #888); margin-top: 4px; padding-left: 18px;
352
321
  font-family: monospace; max-height: 80px; overflow-y: auto;
353
322
  }
354
323
 
@@ -357,25 +326,25 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
357
326
  width: 100%; border-collapse: collapse; font-size: 0.88em;
358
327
  }
359
328
  .precount-table thead th {
360
- text-align: left; font-weight: 600; color: #555; font-size: 0.85em;
329
+ text-align: left; font-weight: 600; color: var(--theme-color-text-secondary, #555); font-size: 0.85em;
361
330
  text-transform: uppercase; letter-spacing: 0.3px;
362
- padding: 4px 8px 6px; border-bottom: 2px solid #e9ecef;
331
+ padding: 4px 8px 6px; border-bottom: 2px solid var(--theme-color-background-tertiary, #e9ecef);
363
332
  }
364
333
  .precount-table tbody td {
365
- padding: 4px 8px; border-bottom: 1px solid #f0f0f0;
334
+ padding: 4px 8px; border-bottom: 1px solid var(--theme-color-background-tertiary, #f0f0f0);
366
335
  }
367
- .precount-table tbody tr:last-child td { border-bottom: 1px solid #e9ecef; }
336
+ .precount-table tbody tr:last-child td { border-bottom: 1px solid var(--theme-color-background-tertiary, #e9ecef); }
368
337
  .precount-table tfoot td {
369
338
  padding: 6px 8px 2px; font-size: 0.95em;
370
339
  }
371
- .precount-error td { color: #dc3545; }
340
+ .precount-error td { color: var(--theme-color-status-error, #dc3545); }
372
341
  .precount-pending {
373
- color: #888; font-size: 0.85em; font-style: italic; padding: 8px 0 2px;
342
+ color: var(--theme-color-text-muted, #888); font-size: 0.85em; font-style: italic; padding: 8px 0 2px;
374
343
  display: flex; align-items: center; gap: 6px;
375
344
  }
376
345
  .precount-spinner {
377
346
  display: inline-block; width: 12px; height: 12px;
378
- border: 2px solid #ddd; border-top-color: #4a90d9;
347
+ border: 2px solid var(--theme-color-border-default, #ddd); border-top-color: var(--theme-color-brand-primary, #4a90d9);
379
348
  border-radius: 50%; animation: precount-spin 0.8s linear infinite;
380
349
  }
381
350
  @keyframes precount-spin { to { transform: rotate(360deg); } }
@@ -387,21 +356,6 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
387
356
  Template: /*html*/`
388
357
  <h1>Retold Data Cloner</h1>
389
358
 
390
- <!-- Live Status Bar (Expandable) -->
391
- <div id="liveStatusBar" class="live-status-bar phase-idle" style="position:relative">
392
- <div class="live-status-header" onclick="pict.views['DataCloner-Layout'].toggleStatusDetail()">
393
- <div class="live-status-dot"></div>
394
- <div class="live-status-message" id="liveStatusMessage">Idle</div>
395
- <div class="live-status-meta" id="liveStatusMeta"></div>
396
- <div class="live-status-expand-toggle" id="liveStatusToggle">&#9660;</div>
397
- </div>
398
- <div class="live-status-detail" id="liveStatusDetail" style="display:none">
399
- <div id="DataCloner-Throughput-Histogram"></div>
400
- <div id="DataCloner-StatusDetail-Container"></div>
401
- </div>
402
- <div class="live-status-progress-bar"><div class="live-status-progress-fill" id="liveStatusProgressFill" style="width:0%"></div></div>
403
- </div>
404
-
405
359
  <!-- Expand / Collapse All -->
406
360
  <div class="accordion-controls">
407
361
  <button onclick="pict.views['DataCloner-Layout'].expandAllSections()">Expand All</button>
@@ -424,7 +378,7 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
424
378
  {
425
379
  RenderableHash: 'DataCloner-Layout',
426
380
  TemplateHash: 'DataCloner-Layout',
427
- DestinationAddress: '#DataCloner-Application-Container'
381
+ DestinationAddress: '#DataCloner-Workspace'
428
382
  }
429
383
  ]
430
384
  };
@@ -183,9 +183,9 @@ module.exports.default_configuration =
183
183
  DefaultRenderable: 'DataCloner-Schema',
184
184
  DefaultDestinationAddress: '#DataCloner-Section-Schema',
185
185
  CSS: /*css*/`
186
- .table-list { max-height: 300px; overflow-y: auto; border: 1px solid #ddd; border-radius: 4px; padding: 8px; margin: 10px 0; }
186
+ .table-list { max-height: 300px; overflow-y: auto; border: 1px solid var(--theme-color-border-default, #ddd); border-radius: 4px; padding: 8px; margin: 10px 0; }
187
187
  .table-item { padding: 4px 8px; display: flex; align-items: center; }
188
- .table-item:hover { background: #f0f0f0; }
188
+ .table-item:hover { background: var(--theme-color-background-tertiary, #f0f0f0); }
189
189
  .table-item input[type="checkbox"] { margin-right: 8px; width: auto; }
190
190
  .table-item label { display: inline; font-weight: normal; margin-bottom: 0; cursor: pointer; }
191
191
  `,
@@ -220,7 +220,7 @@ module.exports.default_configuration =
220
220
  <input type="text" id="tableFilter" placeholder="Filter tables..." style="flex:1; margin-bottom:0" oninput="pict.views['DataCloner-Schema'].filterTableList()">
221
221
  <button class="secondary" onclick="pict.views['DataCloner-Schema'].selectAllTables(true)" style="font-size:0.8em">Select All</button>
222
222
  <button class="secondary" onclick="pict.views['DataCloner-Schema'].selectAllTables(false)" style="font-size:0.8em">Deselect All</button>
223
- <span id="tableSelectionCount" style="font-size:0.85em; color:#666; white-space:nowrap"></span>
223
+ <span id="tableSelectionCount" style="font-size:0.85em; color:var(--theme-color-text-secondary, #666); white-space:nowrap"></span>
224
224
  </div>
225
225
  <div id="tableList" class="table-list"></div>
226
226
  </div>
@@ -214,7 +214,7 @@ module.exports.default_configuration =
214
214
  </div>
215
215
 
216
216
  <details style="margin-bottom:10px">
217
- <summary style="cursor:pointer; font-size:0.9em; color:#666">Advanced Session Options</summary>
217
+ <summary style="cursor:pointer; font-size:0.9em; color:var(--theme-color-text-secondary, #666)">Advanced Session Options</summary>
218
218
  <div style="padding:10px 0">
219
219
  <label for="authURI">Authentication URI Template (leave blank for default)</label>
220
220
  <input type="text" id="authURI" placeholder="Authenticate/{~D:Record.UserName~}/{~D:Record.Password~}">
@@ -234,7 +234,7 @@ module.exports.default_configuration =
234
234
  <button class="primary" onclick="pict.views['DataCloner-Session'].configureSession()">Configure Session</button>
235
235
  <div id="sessionConfigStatus"></div>
236
236
 
237
- <hr style="margin:16px 0; border:none; border-top:1px solid #eee">
237
+ <hr style="margin:16px 0; border:none; border-top:1px solid var(--theme-color-border-light, #eee)">
238
238
 
239
239
  <div class="inline-group">
240
240
  <div>
@@ -0,0 +1,61 @@
1
+ 'use strict';
2
+
3
+ const libPictView = require('pict-view');
4
+
5
+ class DataClonerSettingsPanelView extends libPictView
6
+ {
7
+ onAfterRender(pRenderable, pAddress, pRecord, pContent)
8
+ {
9
+ if (this.pict.CSSMap) { this.pict.CSSMap.injectCSS(); }
10
+
11
+ let tmpTheme = this.pict.providers && this.pict.providers['Theme-Section'];
12
+ if (tmpTheme && typeof tmpTheme.mount === 'function')
13
+ {
14
+ tmpTheme.mount({
15
+ Container: '#DataCloner-Settings-Theme',
16
+ Views: ['Picker', 'ModeToggle', 'ScaleSelect']
17
+ });
18
+ }
19
+ return super.onAfterRender(pRenderable, pAddress, pRecord, pContent);
20
+ }
21
+ }
22
+
23
+ module.exports = DataClonerSettingsPanelView;
24
+
25
+ module.exports.default_configuration =
26
+ {
27
+ ViewIdentifier: 'DataCloner-SettingsPanel',
28
+ DefaultRenderable: 'DataCloner-SettingsPanel',
29
+ DefaultDestinationAddress: '#DataCloner-Settings-Panel',
30
+ AutoRender: false,
31
+ CSS: /*css*/`
32
+ .rds-settings-body {
33
+ padding: 12px;
34
+ display: flex; flex-direction: column; gap: 16px;
35
+ color: var(--theme-color-text-primary, #333333);
36
+ }
37
+ .rds-settings-section { display: flex; flex-direction: column; gap: 6px; }
38
+ .rds-settings-label {
39
+ font-size: 0.85em;
40
+ font-weight: 600;
41
+ text-transform: uppercase;
42
+ letter-spacing: 0.04em;
43
+ color: var(--theme-color-text-secondary, #555555);
44
+ }
45
+ `,
46
+ Templates: [{
47
+ Hash: 'DataCloner-SettingsPanel',
48
+ Template: /*html*/`
49
+ <div class="rds-settings-body">
50
+ <div class="rds-settings-section">
51
+ <div class="rds-settings-label">Appearance</div>
52
+ <div id="DataCloner-Settings-Theme"></div>
53
+ </div>
54
+ </div>`
55
+ }],
56
+ Renderables: [{
57
+ RenderableHash: 'DataCloner-SettingsPanel',
58
+ TemplateHash: 'DataCloner-SettingsPanel',
59
+ DestinationAddress: '#DataCloner-Settings-Panel'
60
+ }]
61
+ };