retold-data-service 2.1.0 → 2.1.2
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/.github/workflows/publish-image.yml +66 -0
- package/BUILDING-AND-PUBLISHING.md +140 -0
- package/Dockerfile +21 -0
- package/package.json +25 -16
- package/source/services/comprehension-loader/pict-app/providers/Pict-Provider-ComprehensionLoader.js +2 -2
- package/source/services/comprehension-loader/pict-app/views/PictView-ComprehensionLoader-Layout.js +43 -43
- package/source/services/comprehension-loader/pict-app/views/PictView-ComprehensionLoader-Load.js +14 -14
- package/source/services/comprehension-loader/pict-app/views/PictView-ComprehensionLoader-Schema.js +3 -3
- package/source/services/comprehension-loader/pict-app/views/PictView-ComprehensionLoader-Session.js +2 -2
- package/source/services/comprehension-loader/pict-app/views/PictView-ComprehensionLoader-Source.js +7 -7
- package/source/services/comprehension-loader/web/comprehension-loader.js +77 -77
- package/source/services/comprehension-loader/web/comprehension-loader.min.js +1 -1
- package/source/services/data-cloner/pict-app/providers/Pict-Provider-DataCloner.js +3 -3
- package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Connection.js +1 -1
- package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Deploy.js +5 -5
- package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Export.js +11 -11
- package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Layout.js +53 -53
- package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Schema.js +3 -3
- package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Session.js +2 -2
- package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Sync.js +22 -22
- package/source/services/data-cloner/pict-app/views/PictView-DataCloner-ViewData.js +4 -4
- package/source/services/data-cloner/web/data-cloner.js +110 -108
- package/source/services/data-cloner/web/data-cloner.js.map +1 -1
- package/source/services/data-cloner/web/data-cloner.min.js +1 -1
- package/source/services/data-cloner/web/data-cloner.min.js.map +1 -1
|
@@ -733,7 +733,7 @@ class DataClonerProvider extends libPictProvider
|
|
|
733
733
|
tmpHtml += '<tr' + tmpRowClass + '>';
|
|
734
734
|
tmpHtml += '<td>' + this.escapeHtml(tmpT.Name) + '</td>';
|
|
735
735
|
tmpHtml += '<td style="text-align:right; font-variant-numeric:tabular-nums">' + tmpCountFmt + '</td>';
|
|
736
|
-
tmpHtml += '<td style="text-align:right; font-variant-numeric:tabular-nums; color
|
|
736
|
+
tmpHtml += '<td style="text-align:right; font-variant-numeric:tabular-nums; color:var(--theme-color-text-muted, #888)">' + tmpTimeFmt + '</td>';
|
|
737
737
|
tmpHtml += '</tr>';
|
|
738
738
|
}
|
|
739
739
|
tmpHtml += '</tbody>';
|
|
@@ -908,11 +908,11 @@ class DataClonerProvider extends libPictProvider
|
|
|
908
908
|
{
|
|
909
909
|
if (tmpIsLive)
|
|
910
910
|
{
|
|
911
|
-
tmpHtml = '<div style="font-size:0.9em; color
|
|
911
|
+
tmpHtml = '<div style="font-size:0.9em; color:var(--theme-color-text-muted, #888); padding:8px 0">Sync in progress, waiting for table data\u2026</div>';
|
|
912
912
|
}
|
|
913
913
|
else
|
|
914
914
|
{
|
|
915
|
-
tmpHtml = '<div style="font-size:0.9em; color
|
|
915
|
+
tmpHtml = '<div style="font-size:0.9em; color:var(--theme-color-text-muted, #888); padding:8px 0">No sync data available. Run a sync to see operation details here.</div>';
|
|
916
916
|
}
|
|
917
917
|
}
|
|
918
918
|
|
|
@@ -51,7 +51,7 @@ const _ViewConfiguration =
|
|
|
51
51
|
<div class="accordion-toggle">▼</div>
|
|
52
52
|
</div>
|
|
53
53
|
<div class="accordion-body">
|
|
54
|
-
<p style="font-size:0.9em; color
|
|
54
|
+
<p style="font-size:0.9em; color:var(--theme-color-text-secondary, #666); margin-bottom:10px">Configure the local database where cloned data will be stored. The provider list comes from the host's installed meadow-connection modules.</p>
|
|
55
55
|
|
|
56
56
|
<div class="inline-group" style="margin-bottom:10px">
|
|
57
57
|
<div style="flex:1; display:flex; align-items:flex-end; gap:8px; justify-content:flex-end">
|
|
@@ -62,7 +62,7 @@ class DataClonerDeployView extends libPictView
|
|
|
62
62
|
auditGUIDIndices()
|
|
63
63
|
{
|
|
64
64
|
let tmpReportEl = document.getElementById('guidIndexReport');
|
|
65
|
-
if (tmpReportEl) tmpReportEl.innerHTML = '<span style="color
|
|
65
|
+
if (tmpReportEl) tmpReportEl.innerHTML = '<span style="color:var(--theme-color-text-muted, #888)">Checking GUID indices...</span>';
|
|
66
66
|
|
|
67
67
|
let tmpSelf = this;
|
|
68
68
|
this.pict.providers.DataCloner.api('GET', '/clone/schema/guid-index-audit')
|
|
@@ -84,7 +84,7 @@ class DataClonerDeployView extends libPictView
|
|
|
84
84
|
|
|
85
85
|
let tmpHTML = '<div style="margin-top:6px"><strong>' + pData.Message + '</strong></div>';
|
|
86
86
|
tmpHTML += '<table style="font-size:0.85em; margin:6px 0; border-collapse:collapse; width:100%">';
|
|
87
|
-
tmpHTML += '<tr style="text-align:left; border-bottom:1px solid #ccc"><th style="padding:3px 8px">Table</th><th style="padding:3px 8px">GUID Column</th><th style="padding:3px 8px">Index</th></tr>';
|
|
87
|
+
tmpHTML += '<tr style="text-align:left; border-bottom:1px solid var(--theme-color-border-default, #ccc)"><th style="padding:3px 8px">Table</th><th style="padding:3px 8px">GUID Column</th><th style="padding:3px 8px">Index</th></tr>';
|
|
88
88
|
|
|
89
89
|
for (let t = 0; t < pData.Tables.length; t++)
|
|
90
90
|
{
|
|
@@ -95,7 +95,7 @@ class DataClonerDeployView extends libPictView
|
|
|
95
95
|
let tmpStatus = tmpCol.HasIndex
|
|
96
96
|
? '<span style="color:green">' + tmpCol.IndexName + '</span>'
|
|
97
97
|
: '<span style="color:red">MISSING</span>';
|
|
98
|
-
tmpHTML += '<tr style="border-bottom:1px solid #eee"><td style="padding:3px 8px">' + tmpTable.Table + '</td><td style="padding:3px 8px">' + tmpCol.Column + '</td><td style="padding:3px 8px">' + tmpStatus + '</td></tr>';
|
|
98
|
+
tmpHTML += '<tr style="border-bottom:1px solid var(--theme-color-border-light, #eee)"><td style="padding:3px 8px">' + tmpTable.Table + '</td><td style="padding:3px 8px">' + tmpCol.Column + '</td><td style="padding:3px 8px">' + tmpStatus + '</td></tr>';
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
tmpHTML += '</table>';
|
|
@@ -112,7 +112,7 @@ class DataClonerDeployView extends libPictView
|
|
|
112
112
|
createMissingGUIDIndices()
|
|
113
113
|
{
|
|
114
114
|
let tmpReportEl = document.getElementById('guidIndexReport');
|
|
115
|
-
if (tmpReportEl) tmpReportEl.innerHTML = '<span style="color
|
|
115
|
+
if (tmpReportEl) tmpReportEl.innerHTML = '<span style="color:var(--theme-color-text-muted, #888)">Creating GUID indices...</span>';
|
|
116
116
|
|
|
117
117
|
let tmpSelf = this;
|
|
118
118
|
this.pict.providers.DataCloner.api('POST', '/clone/schema/guid-index-create')
|
|
@@ -206,7 +206,7 @@ module.exports.default_configuration =
|
|
|
206
206
|
<div class="accordion-toggle">▼</div>
|
|
207
207
|
</div>
|
|
208
208
|
<div class="accordion-body">
|
|
209
|
-
<p style="font-size:0.9em; color
|
|
209
|
+
<p style="font-size:0.9em; color:var(--theme-color-text-secondary, #666); margin-bottom:10px">Creates the selected tables in the local database and sets up CRUD endpoints (e.g. GET /1.0/Documents).</p>
|
|
210
210
|
<button class="primary" onclick="pict.views['DataCloner-Deploy'].deploySchema()">Deploy Selected Tables</button>
|
|
211
211
|
<button onclick="pict.views['DataCloner-Deploy'].auditGUIDIndices()">Check GUID Indices</button>
|
|
212
212
|
<button class="danger" onclick="pict.views['DataCloner-Deploy'].resetDatabase()">Reset Database</button>
|
|
@@ -450,7 +450,7 @@ module.exports.default_configuration =
|
|
|
450
450
|
<div class="accordion-toggle">▼</div>
|
|
451
451
|
</div>
|
|
452
452
|
<div class="accordion-body">
|
|
453
|
-
<p style="font-size:0.9em; color
|
|
453
|
+
<p style="font-size:0.9em; color:var(--theme-color-text-secondary, #666); margin-bottom:10px">Generate a JSON config file from your current settings. Use it to run headless clones from the command line.</p>
|
|
454
454
|
<div style="display:flex; gap:8px; margin-bottom:10px">
|
|
455
455
|
<button class="primary" onclick="pict.views['DataCloner-Export'].generateConfig()">Generate Config</button>
|
|
456
456
|
<button class="secondary" onclick="pict.views['DataCloner-Export'].copyConfig()">Copy to Clipboard</button>
|
|
@@ -458,28 +458,28 @@ module.exports.default_configuration =
|
|
|
458
458
|
</div>
|
|
459
459
|
<div id="configExportStatus"></div>
|
|
460
460
|
<div id="cliCommand" style="display:none; margin-bottom:10px">
|
|
461
|
-
<label style="margin-bottom:4px">CLI Command <span style="color
|
|
462
|
-
<div style="background
|
|
461
|
+
<label style="margin-bottom:4px">CLI Command <span style="color:var(--theme-color-text-muted, #888); font-weight:normal">(with config file)</span></label>
|
|
462
|
+
<div style="background:var(--theme-color-text-primary, #1a1a1a); color:#4fc3f7; padding:10px 14px; border-radius:4px; font-family:monospace; font-size:0.9em; word-break:break-all; cursor:pointer" onclick="pict.views['DataCloner-Export'].copyCLI()" title="Click to copy"></div>
|
|
463
463
|
</div>
|
|
464
464
|
<div id="cliOneShot" style="display:none; margin-bottom:10px">
|
|
465
|
-
<label style="margin-bottom:4px">One-liner <span style="color
|
|
466
|
-
<div style="background
|
|
465
|
+
<label style="margin-bottom:4px">One-liner <span style="color:var(--theme-color-text-muted, #888); font-weight:normal">(no config file needed)</span></label>
|
|
466
|
+
<div style="background:var(--theme-color-text-primary, #1a1a1a); color:#4fc3f7; padding:10px 14px; border-radius:4px; font-family:monospace; font-size:0.9em; word-break:break-all; cursor:pointer; white-space:pre-wrap" onclick="pict.views['DataCloner-Export'].copyOneShot()" title="Click to copy"></div>
|
|
467
467
|
</div>
|
|
468
|
-
<textarea id="configOutput" style="display:none; width:100%; min-height:300px; font-family:monospace; font-size:0.85em; padding:10px; border:1px solid #ccc; border-radius:4px; background
|
|
468
|
+
<textarea id="configOutput" style="display:none; width:100%; min-height:300px; font-family:monospace; font-size:0.85em; padding:10px; border:1px solid var(--theme-color-border-default, #ccc); border-radius:4px; background:var(--theme-color-background-secondary, #fafafa); tab-size:4; resize:vertical" readonly></textarea>
|
|
469
469
|
|
|
470
|
-
<div id="mdwintExport" style="display:none; margin-top:16px; padding-top:16px; border-top:1px solid #eee">
|
|
471
|
-
<h3 style="margin:0 0 8px; font-size:1em">meadow-integration CLI <span style="color
|
|
472
|
-
<p style="font-size:0.85em; color
|
|
470
|
+
<div id="mdwintExport" style="display:none; margin-top:16px; padding-top:16px; border-top:1px solid var(--theme-color-border-light, #eee)">
|
|
471
|
+
<h3 style="margin:0 0 8px; font-size:1em">meadow-integration CLI <span style="color:var(--theme-color-text-muted, #888); font-weight:normal; font-size:0.85em">(mdwint clone)</span></h3>
|
|
472
|
+
<p style="font-size:0.85em; color:var(--theme-color-text-secondary, #666); margin-bottom:8px">Save as <code>.meadow.config.json</code> in your project root, then run the command below. Requires a local Meadow extended schema JSON file.</p>
|
|
473
473
|
<div style="display:flex; gap:8px; margin-bottom:10px">
|
|
474
474
|
<button class="secondary" onclick="pict.views['DataCloner-Export'].copyMdwintConfig()">Copy Config</button>
|
|
475
475
|
<button class="secondary" onclick="pict.views['DataCloner-Export'].downloadMdwintConfig()">Download .meadow.config.json</button>
|
|
476
476
|
</div>
|
|
477
477
|
<div id="mdwintCLICommand" style="margin-bottom:10px">
|
|
478
478
|
<label style="margin-bottom:4px">CLI Command</label>
|
|
479
|
-
<div style="background
|
|
479
|
+
<div style="background:var(--theme-color-text-primary, #1a1a1a); color:#4fc3f7; padding:10px 14px; border-radius:4px; font-family:monospace; font-size:0.9em; word-break:break-all; cursor:pointer" onclick="pict.views['DataCloner-Export'].copyMdwintCLI()" title="Click to copy"></div>
|
|
480
480
|
</div>
|
|
481
481
|
<div id="mdwintConfigStatus"></div>
|
|
482
|
-
<textarea id="mdwintConfigOutput" style="width:100%; min-height:250px; font-family:monospace; font-size:0.85em; padding:10px; border:1px solid #ccc; border-radius:4px; background
|
|
482
|
+
<textarea id="mdwintConfigOutput" style="width:100%; min-height:250px; font-family:monospace; font-size:0.85em; padding:10px; border:1px solid var(--theme-color-border-default, #ccc); border-radius:4px; background:var(--theme-color-background-secondary, #fafafa); tab-size:4; resize:vertical" readonly></textarea>
|
|
483
483
|
</div>
|
|
484
484
|
</div>
|
|
485
485
|
</div>
|
|
@@ -87,11 +87,11 @@ module.exports.default_configuration =
|
|
|
87
87
|
DefaultDestinationAddress: '#DataCloner-Application-Container',
|
|
88
88
|
CSS: /*css*/`
|
|
89
89
|
* { 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; }
|
|
90
|
+
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; }
|
|
91
|
+
h1 { margin-bottom: 20px; color: var(--theme-color-text-primary, #1a1a1a); }
|
|
92
|
+
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
93
|
|
|
94
|
-
.section { background: #fff; border-radius: 8px; padding: 20px; margin-bottom: 16px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
|
|
94
|
+
.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
95
|
|
|
96
96
|
/* Accordion layout */
|
|
97
97
|
.accordion-row { display: flex; gap: 0; margin-bottom: 16px; align-items: stretch; }
|
|
@@ -101,25 +101,25 @@ h2 { margin-bottom: 12px; color: #444; font-size: 1.2em; border-bottom: 2px soli
|
|
|
101
101
|
user-select: none;
|
|
102
102
|
}
|
|
103
103
|
.accordion-card {
|
|
104
|
-
flex: 1; background: #fff; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
|
104
|
+
flex: 1; background: var(--theme-color-background-panel, #fff); border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
|
105
105
|
overflow: hidden; min-width: 0;
|
|
106
106
|
}
|
|
107
107
|
.accordion-header {
|
|
108
108
|
display: flex; align-items: center; padding: 14px 20px; cursor: pointer;
|
|
109
109
|
user-select: none; gap: 12px; transition: background 0.15s; line-height: 1.4;
|
|
110
110
|
}
|
|
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; }
|
|
111
|
+
.accordion-header:hover { background: var(--theme-color-background-secondary, #fafafa); }
|
|
112
|
+
.accordion-title { font-weight: 600; color: var(--theme-color-text-primary, #333); font-size: 1.05em; white-space: nowrap; }
|
|
113
|
+
.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
114
|
.accordion-toggle {
|
|
115
115
|
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;
|
|
116
|
+
border-radius: 4px; transition: background 0.15s, transform 0.25s; font-size: 0.7em; color: var(--theme-color-text-muted, #888);
|
|
117
117
|
}
|
|
118
|
-
.accordion-header:hover .accordion-toggle { background: #eee; color: #555; }
|
|
118
|
+
.accordion-header:hover .accordion-toggle { background: var(--theme-color-border-light, #eee); color: var(--theme-color-text-secondary, #555); }
|
|
119
119
|
.accordion-card.open .accordion-toggle { transform: rotate(180deg); }
|
|
120
120
|
.accordion-body { padding: 0 20px 20px; display: none; }
|
|
121
121
|
.accordion-card.open .accordion-body { display: block; }
|
|
122
|
-
.accordion-card.open .accordion-header { border-bottom: 1px solid #eee; }
|
|
122
|
+
.accordion-card.open .accordion-header { border-bottom: 1px solid var(--theme-color-border-light, #eee); }
|
|
123
123
|
.accordion-card.open .accordion-preview { display: none; }
|
|
124
124
|
|
|
125
125
|
/* Action controls (go link + auto checkbox) */
|
|
@@ -132,13 +132,13 @@ h2 { margin-bottom: 12px; color: #444; font-size: 1.2em; border-bottom: 2px soli
|
|
|
132
132
|
}
|
|
133
133
|
.accordion-go:hover { background: #e8f0fe; text-decoration: underline; }
|
|
134
134
|
.accordion-auto {
|
|
135
|
-
font-size: 0.82em; color: #999; white-space: nowrap; cursor: pointer;
|
|
135
|
+
font-size: 0.82em; color: var(--theme-color-text-muted, #999); white-space: nowrap; cursor: pointer;
|
|
136
136
|
}
|
|
137
137
|
.accordion-auto .auto-label { display: none; }
|
|
138
138
|
.accordion-auto:hover .auto-label { display: inline; }
|
|
139
139
|
.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
140
|
.accordion-auto:hover input[type="checkbox"] { opacity: 1; }
|
|
141
|
-
.accordion-auto:hover { color: #666; }
|
|
141
|
+
.accordion-auto:hover { color: var(--theme-color-text-secondary, #666); }
|
|
142
142
|
|
|
143
143
|
/* Phase status indicator */
|
|
144
144
|
.accordion-phase {
|
|
@@ -146,12 +146,12 @@ h2 { margin-bottom: 12px; color: #444; font-size: 1.2em; border-bottom: 2px soli
|
|
|
146
146
|
font-size: 0.85em; line-height: 1;
|
|
147
147
|
}
|
|
148
148
|
.accordion-phase.visible { display: flex; }
|
|
149
|
-
.accordion-phase-ok { color: #28a745; }
|
|
149
|
+
.accordion-phase-ok { color: var(--theme-color-status-success, #28a745); }
|
|
150
150
|
.accordion-phase-error { color: #dc3545; }
|
|
151
|
-
.accordion-phase-busy { color: #28a745; }
|
|
151
|
+
.accordion-phase-busy { color: var(--theme-color-status-success, #28a745); }
|
|
152
152
|
.accordion-phase-busy .phase-spinner {
|
|
153
153
|
display: inline-block; width: 14px; height: 14px;
|
|
154
|
-
border: 2px solid #28a745; border-top-color: transparent; border-radius: 50%;
|
|
154
|
+
border: 2px solid var(--theme-color-status-success, #28a745); border-top-color: transparent; border-radius: 50%;
|
|
155
155
|
animation: phase-spin 0.8s linear infinite; vertical-align: middle;
|
|
156
156
|
}
|
|
157
157
|
@keyframes phase-spin {
|
|
@@ -163,13 +163,13 @@ h2 { margin-bottom: 12px; color: #444; font-size: 1.2em; border-bottom: 2px soli
|
|
|
163
163
|
}
|
|
164
164
|
.accordion-controls button {
|
|
165
165
|
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;
|
|
166
|
+
border: 1px solid var(--theme-color-border-default, #ccc); border-radius: 4px; color: var(--theme-color-text-secondary, #666); cursor: pointer; margin: 0;
|
|
167
167
|
}
|
|
168
|
-
.accordion-controls button:hover { background: #f0f0f0; border-color: #aaa; color: #333; }
|
|
168
|
+
.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
169
|
|
|
170
170
|
label { display: block; font-weight: 600; margin-bottom: 4px; font-size: 0.9em; }
|
|
171
171
|
input[type="text"], input[type="password"], input[type="number"] {
|
|
172
|
-
width: 100%; padding: 8px 12px; border: 1px solid #ccc; border-radius: 4px;
|
|
172
|
+
width: 100%; padding: 8px 12px; border: 1px solid var(--theme-color-border-default, #ccc); border-radius: 4px;
|
|
173
173
|
font-size: 0.95em; margin-bottom: 10px;
|
|
174
174
|
}
|
|
175
175
|
input[type="text"]:focus, input[type="password"]:focus, input[type="number"]:focus {
|
|
@@ -180,13 +180,13 @@ button {
|
|
|
180
180
|
padding: 8px 16px; border: none; border-radius: 4px; cursor: pointer;
|
|
181
181
|
font-size: 0.9em; font-weight: 600; margin-right: 8px; margin-bottom: 8px;
|
|
182
182
|
}
|
|
183
|
-
button.primary { background: #4a90d9; color: #fff; }
|
|
183
|
+
button.primary { background: #4a90d9; color: var(--theme-color-background-panel, #fff); }
|
|
184
184
|
button.primary:hover { background: #357abd; }
|
|
185
|
-
button.secondary { background: #6c757d; color: #fff; }
|
|
185
|
+
button.secondary { background: #6c757d; color: var(--theme-color-background-panel, #fff); }
|
|
186
186
|
button.secondary:hover { background: #5a6268; }
|
|
187
|
-
button.danger { background: #dc3545; color: #fff; }
|
|
187
|
+
button.danger { background: #dc3545; color: var(--theme-color-background-panel, #fff); }
|
|
188
188
|
button.danger:hover { background: #c82333; }
|
|
189
|
-
button.success { background: #28a745; color: #fff; }
|
|
189
|
+
button.success { background: var(--theme-color-status-success, #28a745); color: var(--theme-color-background-panel, #fff); }
|
|
190
190
|
button.success:hover { background: #218838; }
|
|
191
191
|
button:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
192
192
|
|
|
@@ -201,7 +201,7 @@ button:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
|
201
201
|
|
|
202
202
|
a { color: #4a90d9; }
|
|
203
203
|
|
|
204
|
-
select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #ccc; border-radius: 4px; font-size: 0.95em; margin-bottom: 10px; }
|
|
204
|
+
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
205
|
|
|
206
206
|
.checkbox-row { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
|
|
207
207
|
.checkbox-row input[type="checkbox"] { width: auto; margin: 0; }
|
|
@@ -209,16 +209,16 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
|
|
|
209
209
|
|
|
210
210
|
/* Live Status Bar */
|
|
211
211
|
.live-status-bar {
|
|
212
|
-
background: #fff; border-radius: 8px; margin-bottom: 16px;
|
|
212
|
+
background: var(--theme-color-background-panel, #fff); border-radius: 8px; margin-bottom: 16px;
|
|
213
213
|
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
|
214
214
|
position: sticky; top: 0; z-index: 100; border-left: 4px solid #6c757d;
|
|
215
215
|
}
|
|
216
216
|
.live-status-bar.phase-idle { border-left-color: #6c757d; }
|
|
217
217
|
.live-status-bar.phase-disconnected { border-left-color: #dc3545; }
|
|
218
218
|
.live-status-bar.phase-ready { border-left-color: #4a90d9; }
|
|
219
|
-
.live-status-bar.phase-syncing { border-left-color: #28a745; }
|
|
219
|
+
.live-status-bar.phase-syncing { border-left-color: var(--theme-color-status-success, #28a745); }
|
|
220
220
|
.live-status-bar.phase-stopping { border-left-color: #ffc107; }
|
|
221
|
-
.live-status-bar.phase-complete { border-left-color: #28a745; }
|
|
221
|
+
.live-status-bar.phase-complete { border-left-color: var(--theme-color-status-success, #28a745); }
|
|
222
222
|
|
|
223
223
|
.live-status-dot {
|
|
224
224
|
width: 12px; height: 12px; border-radius: 50%; flex-shrink: 0;
|
|
@@ -228,34 +228,34 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
|
|
|
228
228
|
.live-status-bar.phase-disconnected .live-status-dot { background: #dc3545; }
|
|
229
229
|
.live-status-bar.phase-ready .live-status-dot { background: #4a90d9; }
|
|
230
230
|
.live-status-bar.phase-syncing .live-status-dot {
|
|
231
|
-
background: #28a745;
|
|
231
|
+
background: var(--theme-color-status-success, #28a745);
|
|
232
232
|
animation: live-pulse 1.5s ease-in-out infinite;
|
|
233
233
|
}
|
|
234
234
|
.live-status-bar.phase-stopping .live-status-dot {
|
|
235
235
|
background: #ffc107;
|
|
236
236
|
animation: live-pulse 0.8s ease-in-out infinite;
|
|
237
237
|
}
|
|
238
|
-
.live-status-bar.phase-complete .live-status-dot { background: #28a745; }
|
|
238
|
+
.live-status-bar.phase-complete .live-status-dot { background: var(--theme-color-status-success, #28a745); }
|
|
239
239
|
|
|
240
240
|
@keyframes live-pulse {
|
|
241
241
|
0%, 100% { opacity: 1; transform: scale(1); }
|
|
242
242
|
50% { opacity: 0.4; transform: scale(0.8); }
|
|
243
243
|
}
|
|
244
244
|
|
|
245
|
-
.live-status-message { flex: 1; font-size: 0.92em; color: #333; line-height: 1.4; }
|
|
245
|
+
.live-status-message { flex: 1; font-size: 0.92em; color: var(--theme-color-text-primary, #333); line-height: 1.4; }
|
|
246
246
|
|
|
247
247
|
.live-status-meta {
|
|
248
|
-
display: flex; gap: 16px; flex-shrink: 0; font-size: 0.82em; color: #666;
|
|
248
|
+
display: flex; gap: 16px; flex-shrink: 0; font-size: 0.82em; color: var(--theme-color-text-secondary, #666);
|
|
249
249
|
}
|
|
250
250
|
.live-status-meta-item { white-space: nowrap; }
|
|
251
|
-
.live-status-meta-item strong { color: #333; }
|
|
251
|
+
.live-status-meta-item strong { color: var(--theme-color-text-primary, #333); }
|
|
252
252
|
|
|
253
253
|
.live-status-progress-bar {
|
|
254
254
|
height: 3px; background: #e9ecef; border-radius: 2px; overflow: hidden;
|
|
255
255
|
position: absolute; bottom: 0; left: 0; right: 0;
|
|
256
256
|
}
|
|
257
257
|
.live-status-progress-fill {
|
|
258
|
-
height: 100%; background: #28a745; transition: width 1s ease;
|
|
258
|
+
height: 100%; background: var(--theme-color-status-success, #28a745); transition: width 1s ease;
|
|
259
259
|
}
|
|
260
260
|
/* Expandable status bar */
|
|
261
261
|
.live-status-header {
|
|
@@ -267,7 +267,7 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
|
|
|
267
267
|
}
|
|
268
268
|
.live-status-expand-toggle {
|
|
269
269
|
flex: 0 0 20px; display: flex; align-items: center; justify-content: center;
|
|
270
|
-
font-size: 0.7em; color: #888; transition: transform 0.25s;
|
|
270
|
+
font-size: 0.7em; color: var(--theme-color-text-muted, #888); transition: transform 0.25s;
|
|
271
271
|
}
|
|
272
272
|
.live-status-bar.expanded .live-status-expand-toggle { transform: rotate(180deg); }
|
|
273
273
|
|
|
@@ -281,19 +281,19 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
|
|
|
281
281
|
padding: 8px 0 12px; margin-bottom: 12px; border-bottom: 1px solid #e9ecef;
|
|
282
282
|
}
|
|
283
283
|
.status-detail-summary-message {
|
|
284
|
-
font-size: 0.92em; color: #333; font-weight: 600;
|
|
284
|
+
font-size: 0.92em; color: var(--theme-color-text-primary, #333); font-weight: 600;
|
|
285
285
|
}
|
|
286
286
|
.status-detail-summary-counters {
|
|
287
|
-
display: flex; gap: 16px; flex-wrap: wrap; font-size: 0.82em; color: #666;
|
|
287
|
+
display: flex; gap: 16px; flex-wrap: wrap; font-size: 0.82em; color: var(--theme-color-text-secondary, #666);
|
|
288
288
|
}
|
|
289
289
|
|
|
290
290
|
/* Status Detail Sections */
|
|
291
291
|
.status-detail-section { margin-bottom: 14px; }
|
|
292
292
|
.status-detail-section:last-child { margin-bottom: 0; }
|
|
293
293
|
.status-detail-section-title {
|
|
294
|
-
font-size: 0.85em; font-weight: 600; color: #555; text-transform: uppercase;
|
|
294
|
+
font-size: 0.85em; font-weight: 600; color: var(--theme-color-text-secondary, #555); text-transform: uppercase;
|
|
295
295
|
letter-spacing: 0.5px; margin-bottom: 8px; padding-bottom: 4px;
|
|
296
|
-
border-bottom: 1px solid #eee;
|
|
296
|
+
border-bottom: 1px solid var(--theme-color-border-light, #eee);
|
|
297
297
|
}
|
|
298
298
|
|
|
299
299
|
/* Running Operations */
|
|
@@ -307,18 +307,18 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
|
|
|
307
307
|
min-width: 120px;
|
|
308
308
|
}
|
|
309
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; }
|
|
310
|
+
.running-op-count { font-size: 0.85em; color: var(--theme-color-text-secondary, #666); white-space: nowrap; }
|
|
311
|
+
.running-op-pending { color: var(--theme-color-text-muted, #888); font-size: 0.85em; font-style: italic; padding: 4px 0; }
|
|
312
312
|
|
|
313
313
|
/* Completed Operations */
|
|
314
|
-
.completed-op-row { padding: 8px 0; border-bottom: 1px solid #f0f0f0; }
|
|
314
|
+
.completed-op-row { padding: 8px 0; border-bottom: 1px solid var(--theme-color-background-tertiary, #f0f0f0); }
|
|
315
315
|
.completed-op-row:last-child { border-bottom: none; }
|
|
316
316
|
.completed-op-header {
|
|
317
317
|
display: flex; align-items: center; gap: 10px; font-size: 0.9em; margin-bottom: 4px;
|
|
318
318
|
}
|
|
319
319
|
.completed-op-name { font-weight: 600; }
|
|
320
|
-
.completed-op-stats { color: #666; font-size: 0.85em; }
|
|
321
|
-
.completed-op-checkmark { color: #28a745; }
|
|
320
|
+
.completed-op-stats { color: var(--theme-color-text-secondary, #666); font-size: 0.85em; }
|
|
321
|
+
.completed-op-checkmark { color: var(--theme-color-status-success, #28a745); }
|
|
322
322
|
|
|
323
323
|
/* Ratio Bar */
|
|
324
324
|
.ratio-bar-container {
|
|
@@ -327,28 +327,28 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
|
|
|
327
327
|
}
|
|
328
328
|
.ratio-bar-segment { height: 100%; transition: width 0.5s ease; }
|
|
329
329
|
.ratio-bar-segment.unchanged { background: #6c757d; }
|
|
330
|
-
.ratio-bar-segment.new-records { background: #28a745; }
|
|
330
|
+
.ratio-bar-segment.new-records { background: var(--theme-color-status-success, #28a745); }
|
|
331
331
|
.ratio-bar-segment.updated { background: #4a90d9; }
|
|
332
332
|
.ratio-bar-segment.deleted { background: #dc3545; }
|
|
333
333
|
.ratio-bar-legend {
|
|
334
|
-
display: flex; gap: 12px; font-size: 0.75em; color: #666; margin-top: 2px; flex-wrap: wrap;
|
|
334
|
+
display: flex; gap: 12px; font-size: 0.75em; color: var(--theme-color-text-secondary, #666); margin-top: 2px; flex-wrap: wrap;
|
|
335
335
|
}
|
|
336
336
|
.ratio-bar-legend-item { display: flex; align-items: center; gap: 4px; }
|
|
337
337
|
.ratio-bar-legend-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
|
|
338
338
|
.ratio-bar-legend-dot.unchanged-dot { background: #6c757d; }
|
|
339
|
-
.ratio-bar-legend-dot.new-dot { background: #28a745; }
|
|
339
|
+
.ratio-bar-legend-dot.new-dot { background: var(--theme-color-status-success, #28a745); }
|
|
340
340
|
.ratio-bar-legend-dot.updated-dot { background: #4a90d9; }
|
|
341
341
|
.ratio-bar-legend-dot.deleted-dot { background: #dc3545; }
|
|
342
342
|
|
|
343
343
|
/* Error Operations */
|
|
344
|
-
.error-op-row { padding: 6px 0; border-bottom: 1px solid #f0f0f0; font-size: 0.9em; }
|
|
344
|
+
.error-op-row { padding: 6px 0; border-bottom: 1px solid var(--theme-color-background-tertiary, #f0f0f0); font-size: 0.9em; }
|
|
345
345
|
.error-op-row:last-child { border-bottom: none; }
|
|
346
346
|
.error-op-header { display: flex; align-items: center; gap: 8px; }
|
|
347
347
|
.error-op-name { font-weight: 600; color: #dc3545; }
|
|
348
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; }
|
|
349
|
+
.error-op-message { font-size: 0.82em; color: var(--theme-color-text-muted, #888); margin-top: 2px; padding-left: 18px; }
|
|
350
350
|
.error-op-log-entries {
|
|
351
|
-
font-size: 0.78em; color: #888; margin-top: 4px; padding-left: 18px;
|
|
351
|
+
font-size: 0.78em; color: var(--theme-color-text-muted, #888); margin-top: 4px; padding-left: 18px;
|
|
352
352
|
font-family: monospace; max-height: 80px; overflow-y: auto;
|
|
353
353
|
}
|
|
354
354
|
|
|
@@ -357,12 +357,12 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
|
|
|
357
357
|
width: 100%; border-collapse: collapse; font-size: 0.88em;
|
|
358
358
|
}
|
|
359
359
|
.precount-table thead th {
|
|
360
|
-
text-align: left; font-weight: 600; color: #555; font-size: 0.85em;
|
|
360
|
+
text-align: left; font-weight: 600; color: var(--theme-color-text-secondary, #555); font-size: 0.85em;
|
|
361
361
|
text-transform: uppercase; letter-spacing: 0.3px;
|
|
362
362
|
padding: 4px 8px 6px; border-bottom: 2px solid #e9ecef;
|
|
363
363
|
}
|
|
364
364
|
.precount-table tbody td {
|
|
365
|
-
padding: 4px 8px; border-bottom: 1px solid #f0f0f0;
|
|
365
|
+
padding: 4px 8px; border-bottom: 1px solid var(--theme-color-background-tertiary, #f0f0f0);
|
|
366
366
|
}
|
|
367
367
|
.precount-table tbody tr:last-child td { border-bottom: 1px solid #e9ecef; }
|
|
368
368
|
.precount-table tfoot td {
|
|
@@ -370,12 +370,12 @@ select { background: #fff; width: 100%; padding: 8px 12px; border: 1px solid #cc
|
|
|
370
370
|
}
|
|
371
371
|
.precount-error td { color: #dc3545; }
|
|
372
372
|
.precount-pending {
|
|
373
|
-
color: #888; font-size: 0.85em; font-style: italic; padding: 8px 0 2px;
|
|
373
|
+
color: var(--theme-color-text-muted, #888); font-size: 0.85em; font-style: italic; padding: 8px 0 2px;
|
|
374
374
|
display: flex; align-items: center; gap: 6px;
|
|
375
375
|
}
|
|
376
376
|
.precount-spinner {
|
|
377
377
|
display: inline-block; width: 12px; height: 12px;
|
|
378
|
-
border: 2px solid #ddd; border-top-color: #4a90d9;
|
|
378
|
+
border: 2px solid var(--theme-color-border-default, #ddd); border-top-color: #4a90d9;
|
|
379
379
|
border-radius: 50%; animation: precount-spin 0.8s linear infinite;
|
|
380
380
|
}
|
|
381
381
|
@keyframes precount-spin { to { transform: rotate(360deg); } }
|
|
@@ -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
|
|
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
|
|
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>
|
|
@@ -224,14 +224,14 @@ class DataClonerSyncView extends libPictView
|
|
|
224
224
|
+ '<div class="report-card">'
|
|
225
225
|
+ ' <div class="card-label">Records</div>'
|
|
226
226
|
+ ' <div class="card-value">' + tmpTotalSynced + '</div>'
|
|
227
|
-
+ ' <div style="font-size:0.75em; color
|
|
227
|
+
+ ' <div style="font-size:0.75em; color:var(--theme-color-text-muted, #888)">of ' + tmpTotalRecords + '</div>'
|
|
228
228
|
+ '</div>';
|
|
229
229
|
|
|
230
230
|
// --- Anomalies ---
|
|
231
231
|
let tmpAnomalyContainer = document.getElementById('reportAnomalies');
|
|
232
232
|
if (pReport.Anomalies.length === 0)
|
|
233
233
|
{
|
|
234
|
-
tmpAnomalyContainer.innerHTML = '<div style="color
|
|
234
|
+
tmpAnomalyContainer.innerHTML = '<div style="color:var(--theme-color-status-success, #28a745); font-weight:600; font-size:0.9em">No anomalies detected.</div>';
|
|
235
235
|
}
|
|
236
236
|
else
|
|
237
237
|
{
|
|
@@ -257,7 +257,7 @@ class DataClonerSyncView extends libPictView
|
|
|
257
257
|
let tmpTopCount = Math.min(10, pReport.Tables.length);
|
|
258
258
|
if (tmpTopCount > 0)
|
|
259
259
|
{
|
|
260
|
-
let tmpHtml = '<h4 style="margin:0 0 8px; font-size:0.95em; color
|
|
260
|
+
let tmpHtml = '<h4 style="margin:0 0 8px; font-size:0.95em; color:var(--theme-color-text-secondary, #444)">Top Tables by Duration</h4>';
|
|
261
261
|
tmpHtml += '<table class="progress-table">';
|
|
262
262
|
tmpHtml += '<tr><th>Table</th><th>Duration</th><th>Records</th><th>Status</th></tr>';
|
|
263
263
|
for (let i = 0; i < tmpTopCount; i++)
|
|
@@ -481,22 +481,22 @@ module.exports.default_configuration =
|
|
|
481
481
|
DefaultDestinationAddress: '#DataCloner-Section-Sync',
|
|
482
482
|
CSS: /*css*/`
|
|
483
483
|
.progress-table { width: 100%; border-collapse: collapse; margin-top: 4px; margin-bottom: 4px; }
|
|
484
|
-
.progress-table th, .progress-table td { text-align: left; padding: 6px 12px; border-bottom: 1px solid #eee; font-size: 0.9em; }
|
|
484
|
+
.progress-table th, .progress-table td { text-align: left; padding: 6px 12px; border-bottom: 1px solid var(--theme-color-border-light, #eee); font-size: 0.9em; }
|
|
485
485
|
.progress-table th { background: #f8f9fa; font-weight: 600; }
|
|
486
|
-
.progress-table-muted td { color: #888; padding: 3px 12px; font-size: 0.85em; border-bottom: 1px solid #f4f5f6; }
|
|
486
|
+
.progress-table-muted td { color: var(--theme-color-text-muted, #888); padding: 3px 12px; font-size: 0.85em; border-bottom: 1px solid #f4f5f6; }
|
|
487
487
|
.progress-bar-container { width: 120px; height: 16px; background: #e9ecef; border-radius: 8px; overflow: hidden; display: inline-block; vertical-align: middle; }
|
|
488
|
-
.progress-bar-fill { height: 100%; background: #28a745; transition: width 0.3s; }
|
|
489
|
-
.sync-section-header { font-size: 0.8em; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; color: #4a90d9; padding: 10px 0 2px 0; margin-top: 6px; border-top: 1px solid #e0e0e0; }
|
|
488
|
+
.progress-bar-fill { height: 100%; background: var(--theme-color-status-success, #28a745); transition: width 0.3s; }
|
|
489
|
+
.sync-section-header { font-size: 0.8em; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; color: #4a90d9; padding: 10px 0 2px 0; margin-top: 6px; border-top: 1px solid var(--theme-color-border-default, #e0e0e0); }
|
|
490
490
|
.sync-section-header:first-child { border-top: none; margin-top: 10px; }
|
|
491
491
|
.sync-section-header-error { color: #dc3545; }
|
|
492
|
-
.sync-section-header-ok { color: #28a745; }
|
|
493
|
-
.sync-section-count { font-weight: 400; color: #999; font-size: 0.95em; }
|
|
494
|
-
.sync-section-overflow { font-size: 0.8em; color: #aaa; padding: 2px 12px 6px; }
|
|
495
|
-
.sync-pending-count { text-align: right; color: #aaa; font-size: 0.85em; }
|
|
492
|
+
.sync-section-header-ok { color: var(--theme-color-status-success, #28a745); }
|
|
493
|
+
.sync-section-count { font-weight: 400; color: var(--theme-color-text-muted, #999); font-size: 0.95em; }
|
|
494
|
+
.sync-section-overflow { font-size: 0.8em; color: var(--theme-color-text-muted, #aaa); padding: 2px 12px 6px; }
|
|
495
|
+
.sync-pending-count { text-align: right; color: var(--theme-color-text-muted, #aaa); font-size: 0.85em; }
|
|
496
496
|
.report-card { background: #f8f9fa; border-radius: 8px; padding: 12px 16px; min-width: 140px; text-align: center; border: 1px solid #e9ecef; }
|
|
497
|
-
.report-card .card-label { font-size: 0.8em; color: #666; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 4px; }
|
|
497
|
+
.report-card .card-label { font-size: 0.8em; color: var(--theme-color-text-secondary, #666); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 4px; }
|
|
498
498
|
.report-card .card-value { font-size: 1.4em; font-weight: 700; }
|
|
499
|
-
.report-card.outcome-success { border-left: 4px solid #28a745; }
|
|
499
|
+
.report-card.outcome-success { border-left: 4px solid var(--theme-color-status-success, #28a745); }
|
|
500
500
|
.report-card.outcome-partial { border-left: 4px solid #ffc107; }
|
|
501
501
|
.report-card.outcome-error { border-left: 4px solid #dc3545; }
|
|
502
502
|
.report-card.outcome-stopped { border-left: 4px solid #6c757d; }
|
|
@@ -534,30 +534,30 @@ module.exports.default_configuration =
|
|
|
534
534
|
<button class="danger" style="margin:0" onclick="pict.views['DataCloner-Sync'].stopSync()">Stop Sync</button>
|
|
535
535
|
</div>
|
|
536
536
|
</div>
|
|
537
|
-
<div style="font-size:0.8em; color
|
|
537
|
+
<div style="font-size:0.8em; color:var(--theme-color-text-muted, #888); margin-bottom:10px; padding-left:158px">Cross-DB tolerance for date comparison (default: 1000ms)</div>
|
|
538
538
|
|
|
539
539
|
<div style="margin-bottom:10px">
|
|
540
540
|
<label style="margin-bottom:6px">Sync Mode</label>
|
|
541
541
|
<div style="display:flex; gap:12px 20px; align-items:center; flex-wrap:wrap">
|
|
542
542
|
<label style="font-weight:normal; margin:0; cursor:pointer">
|
|
543
543
|
<input type="radio" name="syncMode" id="syncModeInitial" value="Initial" checked onchange="pict.views['DataCloner-Sync'].onSyncModeChanged()"> Initial
|
|
544
|
-
<span style="color
|
|
544
|
+
<span style="color:var(--theme-color-text-muted, #888); font-size:0.85em">(full clone)</span>
|
|
545
545
|
</label>
|
|
546
546
|
<label style="font-weight:normal; margin:0; cursor:pointer">
|
|
547
547
|
<input type="radio" name="syncMode" id="syncModeOngoing" value="Ongoing" onchange="pict.views['DataCloner-Sync'].onSyncModeChanged()"> Ongoing
|
|
548
|
-
<span style="color
|
|
548
|
+
<span style="color:var(--theme-color-text-muted, #888); font-size:0.85em">(delta sync)</span>
|
|
549
549
|
</label>
|
|
550
550
|
<label style="font-weight:normal; margin:0; cursor:pointer">
|
|
551
551
|
<input type="radio" name="syncMode" id="syncModeOngoingEventualConsistency" value="OngoingEventualConsistency" onchange="pict.views['DataCloner-Sync'].onSyncModeChanged()"> Eventual
|
|
552
|
-
<span style="color
|
|
552
|
+
<span style="color:var(--theme-color-text-muted, #888); font-size:0.85em">(time-budgeted back-sync)</span>
|
|
553
553
|
</label>
|
|
554
554
|
<label style="font-weight:normal; margin:0; cursor:pointer">
|
|
555
555
|
<input type="radio" name="syncMode" id="syncModeTrueUp" value="TrueUp" onchange="pict.views['DataCloner-Sync'].onSyncModeChanged()"> True-Up
|
|
556
|
-
<span style="color
|
|
556
|
+
<span style="color:var(--theme-color-text-muted, #888); font-size:0.85em">(linear walk, one-time)</span>
|
|
557
557
|
</label>
|
|
558
558
|
<label style="font-weight:normal; margin:0; cursor:pointer">
|
|
559
559
|
<input type="radio" name="syncMode" id="syncModeComparisonOnly" value="ComparisonOnly" onchange="pict.views['DataCloner-Sync'].onSyncModeChanged()"> Compare
|
|
560
|
-
<span style="color
|
|
560
|
+
<span style="color:var(--theme-color-text-muted, #888); font-size:0.85em">(diff report, no sync)</span>
|
|
561
561
|
</label>
|
|
562
562
|
</div>
|
|
563
563
|
</div>
|
|
@@ -569,7 +569,7 @@ module.exports.default_configuration =
|
|
|
569
569
|
<input type="number" id="backSyncTimeLimit" value="30000" min="1000" max="600000" style="margin-bottom:0">
|
|
570
570
|
</div>
|
|
571
571
|
</div>
|
|
572
|
-
<div style="font-size:0.8em; color
|
|
572
|
+
<div style="font-size:0.8em; color:var(--theme-color-text-muted, #888); padding-left:4px">Milliseconds devoted to backwards bisection per entity before pulling new records (default: 30000)</div>
|
|
573
573
|
</div>
|
|
574
574
|
|
|
575
575
|
<div id="syncModeOptions-TrueUp" style="display:none; margin-bottom:10px">
|
|
@@ -579,7 +579,7 @@ module.exports.default_configuration =
|
|
|
579
579
|
<input type="number" id="trueUpPageSize" value="500" min="10" max="10000" style="margin-bottom:0">
|
|
580
580
|
</div>
|
|
581
581
|
</div>
|
|
582
|
-
<div style="font-size:0.8em; color
|
|
582
|
+
<div style="font-size:0.8em; color:var(--theme-color-text-muted, #888); padding-left:4px">Records per page for the linear keyset walk (default: 500)</div>
|
|
583
583
|
</div>
|
|
584
584
|
|
|
585
585
|
<div class="checkbox-row">
|
|
@@ -609,7 +609,7 @@ module.exports.default_configuration =
|
|
|
609
609
|
<div id="syncProgress"></div>
|
|
610
610
|
|
|
611
611
|
<!-- Sync Report (appears after sync completes) -->
|
|
612
|
-
<div id="syncReportSection" style="display:none; margin-top:16px; padding-top:16px; border-top:2px solid #ddd">
|
|
612
|
+
<div id="syncReportSection" style="display:none; margin-top:16px; padding-top:16px; border-top:2px solid var(--theme-color-border-default, #ddd)">
|
|
613
613
|
<h3 style="margin:0 0 12px; font-size:1.1em">Sync Report</h3>
|
|
614
614
|
|
|
615
615
|
<!-- Summary cards -->
|