retold-data-service 2.0.43 → 2.1.1

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.
@@ -76,60 +76,25 @@ class DataClonerProvider extends libPictProvider
76
76
 
77
77
  updateAllPreviews()
78
78
  {
79
- // Section 1 — Database Connection
80
- let tmpProvider = document.getElementById('connProvider');
81
- if (!tmpProvider) return;
82
- tmpProvider = tmpProvider.value;
83
- let tmpPreview1 = tmpProvider;
84
- if (tmpProvider === 'SQLite')
85
- {
86
- let tmpPath = document.getElementById('sqliteFilePath').value || '~/headlight-liveconnect-local/cloned.sqlite';
87
- tmpPreview1 = 'SQLite at ' + tmpPath;
88
- }
89
- else if (tmpProvider === 'MySQL')
90
- {
91
- let tmpHost = document.getElementById('mysqlServer').value || '127.0.0.1';
92
- let tmpPort = document.getElementById('mysqlPort').value || '3306';
93
- let tmpUser = document.getElementById('mysqlUser').value || 'root';
94
- tmpPreview1 = 'MySQL on ' + tmpHost + ':' + tmpPort + ' as ' + tmpUser;
95
- }
96
- else if (tmpProvider === 'MSSQL')
97
- {
98
- let tmpHost = document.getElementById('mssqlServer').value || '127.0.0.1';
99
- let tmpPort = document.getElementById('mssqlPort').value || '1433';
100
- let tmpUser = document.getElementById('mssqlUser').value || 'sa';
101
- tmpPreview1 = 'MSSQL on ' + tmpHost + ':' + tmpPort + ' as ' + tmpUser;
102
- }
103
- else if (tmpProvider === 'PostgreSQL')
104
- {
105
- let tmpHost = document.getElementById('postgresqlHost').value || '127.0.0.1';
106
- let tmpPort = document.getElementById('postgresqlPort').value || '5432';
107
- let tmpUser = document.getElementById('postgresqlUser').value || 'postgres';
108
- tmpPreview1 = 'PostgreSQL on ' + tmpHost + ':' + tmpPort + ' as ' + tmpUser;
109
- }
110
- else if (tmpProvider === 'MongoDB')
111
- {
112
- let tmpHost = document.getElementById('mongodbHost').value || '127.0.0.1';
113
- let tmpPort = document.getElementById('mongodbPort').value || '27017';
114
- tmpPreview1 = 'MongoDB on ' + tmpHost + ':' + tmpPort;
115
- }
116
- else if (tmpProvider === 'Solr')
117
- {
118
- let tmpHost = document.getElementById('solrHost').value || '127.0.0.1';
119
- let tmpPort = document.getElementById('solrPort').value || '8983';
120
- tmpPreview1 = 'Solr on ' + tmpHost + ':' + tmpPort;
79
+ // Section 1 — Database Connection (schema-driven; the
80
+ // Connection view owns the heuristic that turns the active
81
+ // schema's field values into preview text). The view's
82
+ // _buildPreviewText reads live DOM values for the active
83
+ // provider and falls back to schema Defaults if a field's
84
+ // element doesn't exist yet.
85
+ let tmpConnView = this.pict.views['DataCloner-Connection'];
86
+ let tmpConnState = (this.pict.AppData.DataCloner && this.pict.AppData.DataCloner.Connection) || null;
87
+ let tmpPreview1Text;
88
+ if (tmpConnView && tmpConnState && (tmpConnState.Schemas || []).length > 0)
89
+ {
90
+ tmpPreview1Text = tmpConnView._buildPreviewText(tmpConnState);
121
91
  }
122
- else if (tmpProvider === 'RocksDB')
123
- {
124
- let tmpFolder = document.getElementById('rocksdbFolder').value || '~/headlight-liveconnect-local/rocksdb';
125
- tmpPreview1 = 'RocksDB at ' + tmpFolder;
126
- }
127
- else if (tmpProvider === 'Bibliograph')
92
+ else
128
93
  {
129
- let tmpFolder = document.getElementById('bibliographFolder').value || '~/headlight-liveconnect-local/bibliograph';
130
- tmpPreview1 = 'Bibliograph at ' + tmpFolder;
94
+ tmpPreview1Text = (tmpConnState && tmpConnState.PreviewText) || 'Loading providers…';
131
95
  }
132
- document.getElementById('preview1').textContent = tmpPreview1;
96
+ let tmpPreview1El = document.getElementById('preview1');
97
+ if (tmpPreview1El) { tmpPreview1El.textContent = tmpPreview1Text; }
133
98
 
134
99
  // Section 2 — Remote Session
135
100
  let tmpServerURL = document.getElementById('serverURL').value;
@@ -210,14 +175,12 @@ class DataClonerProvider extends libPictProvider
210
175
  {
211
176
  let tmpSelf = this;
212
177
 
178
+ // Static (non-connection) fields that drive accordion previews.
179
+ // Connection-section fields hook updateAllPreviews via
180
+ // _persistConnectionFields() once schemas load — see
181
+ // bootstrapConnectionSchemas().
213
182
  let tmpPreviewFields = [
214
- 'connProvider', 'sqliteFilePath',
215
- 'mysqlServer', 'mysqlPort', 'mysqlUser',
216
- 'mssqlServer', 'mssqlPort', 'mssqlUser',
217
- 'postgresqlHost', 'postgresqlPort', 'postgresqlUser',
218
- 'mongodbHost', 'mongodbPort',
219
- 'solrHost', 'solrPort',
220
- 'rocksdbFolder', 'bibliographFolder',
183
+ 'connProvider',
221
184
  'serverURL', 'userName',
222
185
  'schemaURL',
223
186
  'pageSize', 'dateTimePrecisionMS',
@@ -258,7 +221,17 @@ class DataClonerProvider extends libPictProvider
258
221
  saveField(pFieldId)
259
222
  {
260
223
  let tmpEl = document.getElementById(pFieldId);
261
- if (tmpEl)
224
+ if (!tmpEl) { return; }
225
+ // Checkboxes persist .checked, everything else persists .value.
226
+ // Older code special-cased a small set of checkbox ids (solrSecure,
227
+ // mssqlLegacyPagination, etc.); the schema-driven path no longer
228
+ // needs those — the checkbox handler in bootstrapConnectionSchemas
229
+ // stores 'true' / 'false' which restore picks up below.
230
+ if (tmpEl.type === 'checkbox')
231
+ {
232
+ localStorage.setItem('dataCloner_' + pFieldId, tmpEl.checked ? 'true' : 'false');
233
+ }
234
+ else
262
235
  {
263
236
  localStorage.setItem('dataCloner_' + pFieldId, tmpEl.value);
264
237
  }
@@ -274,38 +247,40 @@ class DataClonerProvider extends libPictProvider
274
247
  if (tmpSaved !== null)
275
248
  {
276
249
  let tmpEl = document.getElementById(tmpId);
277
- if (tmpEl) tmpEl.value = tmpSaved;
250
+ if (tmpEl)
251
+ {
252
+ if (tmpEl.type === 'checkbox')
253
+ {
254
+ tmpEl.checked = (tmpSaved === 'true');
255
+ }
256
+ else
257
+ {
258
+ tmpEl.value = tmpSaved;
259
+ }
260
+ }
278
261
  }
279
262
  }
280
263
 
281
- // Restore checkbox state
264
+ // Restore checkbox state for non-connection checkboxes that
265
+ // aren't in PersistFields (these all live outside the schema-
266
+ // driven Connection section, so they stay hardcoded).
282
267
  let tmpSyncDeleted = localStorage.getItem('dataCloner_syncDeletedRecords');
283
268
  if (tmpSyncDeleted !== null)
284
269
  {
285
- document.getElementById('syncDeletedRecords').checked = tmpSyncDeleted === 'true';
270
+ let tmpEl = document.getElementById('syncDeletedRecords');
271
+ if (tmpEl) tmpEl.checked = tmpSyncDeleted === 'true';
286
272
  }
287
- // Restore sync mode
288
273
  let tmpSyncMode = localStorage.getItem('dataCloner_syncMode');
289
274
  if (tmpSyncMode === 'Ongoing')
290
275
  {
291
- document.getElementById('syncModeOngoing').checked = true;
292
- }
293
- let tmpSolrSecure = localStorage.getItem('dataCloner_solrSecure');
294
- if (tmpSolrSecure !== null)
295
- {
296
- document.getElementById('solrSecure').checked = tmpSolrSecure === 'true';
297
- }
298
- let tmpMssqlLegacyPagination = localStorage.getItem('dataCloner_mssqlLegacyPagination');
299
- if (tmpMssqlLegacyPagination !== null)
300
- {
301
- let tmpEl = document.getElementById('mssqlLegacyPagination');
302
- if (tmpEl) tmpEl.checked = tmpMssqlLegacyPagination === 'true';
276
+ let tmpEl = document.getElementById('syncModeOngoing');
277
+ if (tmpEl) tmpEl.checked = true;
303
278
  }
304
- // Restore advanced ID pagination checkbox
305
279
  let tmpAdvancedIDPagination = localStorage.getItem('dataCloner_syncAdvancedIDPagination');
306
280
  if (tmpAdvancedIDPagination !== null)
307
281
  {
308
- document.getElementById('syncAdvancedIDPagination').checked = tmpAdvancedIDPagination === 'true';
282
+ let tmpEl = document.getElementById('syncAdvancedIDPagination');
283
+ if (tmpEl) tmpEl.checked = tmpAdvancedIDPagination === 'true';
309
284
  }
310
285
  }
311
286
 
@@ -347,25 +322,9 @@ class DataClonerProvider extends libPictProvider
347
322
  });
348
323
  });
349
324
 
350
- // Persist solr secure checkbox
351
- let tmpSolrSecureEl = document.getElementById('solrSecure');
352
- if (tmpSolrSecureEl)
353
- {
354
- tmpSolrSecureEl.addEventListener('change', function()
355
- {
356
- localStorage.setItem('dataCloner_solrSecure', this.checked);
357
- });
358
- }
359
-
360
- // Persist MSSQL legacy pagination checkbox
361
- let tmpMssqlLegacyPaginationEl = document.getElementById('mssqlLegacyPagination');
362
- if (tmpMssqlLegacyPaginationEl)
363
- {
364
- tmpMssqlLegacyPaginationEl.addEventListener('change', function()
365
- {
366
- localStorage.setItem('dataCloner_mssqlLegacyPagination', this.checked);
367
- });
368
- }
325
+ // (Connection-section checkboxes solrSecure, mssqlLegacyPagination —
326
+ // are handled by bootstrapConnectionSchemas() which hooks change
327
+ // listeners after the schema-driven form renders.)
369
328
 
370
329
  // Persist advanced ID pagination checkbox
371
330
  let tmpAdvancedIDPaginationEl = document.getElementById('syncAdvancedIDPagination');
@@ -397,6 +356,136 @@ class DataClonerProvider extends libPictProvider
397
356
  }
398
357
  }
399
358
 
359
+ // ================================================================
360
+ // Connection Schemas Bootstrap
361
+ //
362
+ // Fetches the host's aggregated connection-form schemas and re-
363
+ // renders the Connection view so it shows the real provider list +
364
+ // per-provider field blocks. Then restores localStorage values
365
+ // for the new (schema-driven) DOM ids and hooks save listeners.
366
+ // ================================================================
367
+
368
+ bootstrapConnectionSchemas(fCallback)
369
+ {
370
+ let tmpSelf = this;
371
+ let tmpDone = (typeof(fCallback) === 'function') ? fCallback : function () {};
372
+
373
+ this.api('GET', '/clone/connection/schemas')
374
+ .then(function (pData)
375
+ {
376
+ let tmpSchemas = (pData && Array.isArray(pData.Schemas)) ? pData.Schemas : [];
377
+ tmpSelf._applyConnectionSchemas(tmpSchemas);
378
+ return tmpDone(null, tmpSchemas);
379
+ })
380
+ .catch(function (pError)
381
+ {
382
+ if (tmpSelf.fable && tmpSelf.fable.log && tmpSelf.fable.log.error)
383
+ {
384
+ tmpSelf.fable.log.error(`DataCloner: failed to fetch connection schemas: ${pError && pError.message}`);
385
+ }
386
+ // On failure, leave the empty-schema state in place — the
387
+ // shared view's "no schemas detected" notice will surface.
388
+ tmpSelf._applyConnectionSchemas([]);
389
+ return tmpDone(pError);
390
+ });
391
+ }
392
+
393
+ _applyConnectionSchemas(pSchemas)
394
+ {
395
+ let tmpAppData = this.pict.AppData.DataCloner;
396
+ if (!tmpAppData.Connection) { tmpAppData.Connection = { Schemas: [], ActiveProvider: '', PreviewText: '' }; }
397
+ tmpAppData.Connection.Schemas = pSchemas;
398
+
399
+ // Pick an initial ActiveProvider — restore from localStorage
400
+ // if the saved value matches one of the available providers,
401
+ // otherwise default to the first schema (or stay empty).
402
+ let tmpAvailable = pSchemas.map(function (pS) { return pS.Provider; });
403
+ let tmpSavedProvider = localStorage.getItem('dataCloner_activeProvider');
404
+ if (tmpSavedProvider && tmpAvailable.indexOf(tmpSavedProvider) >= 0)
405
+ {
406
+ tmpAppData.Connection.ActiveProvider = tmpSavedProvider;
407
+ }
408
+ else if (pSchemas.length > 0)
409
+ {
410
+ tmpAppData.Connection.ActiveProvider = pSchemas[0].Provider;
411
+ }
412
+
413
+ // Hand the schemas to the shared view, which renders the form
414
+ // into #DataCloner-Connection-FormSlot.
415
+ let tmpForm = this.pict.views['PictSection-ConnectionForm'];
416
+ if (tmpForm)
417
+ {
418
+ let tmpSelf = this;
419
+ tmpForm.options.OnProviderChange = function (pProvider)
420
+ {
421
+ tmpAppData.Connection.ActiveProvider = pProvider;
422
+ localStorage.setItem('dataCloner_activeProvider', pProvider);
423
+ // Re-hook persistence on the new active form's inputs
424
+ // (the shared view re-renders on provider change, so the
425
+ // previous input listeners are gone).
426
+ tmpSelf._persistConnectionFields(pSchemas);
427
+ tmpSelf.updateAllPreviews();
428
+ };
429
+ if (tmpAppData.Connection.ActiveProvider)
430
+ {
431
+ tmpForm._ActiveProvider = tmpAppData.Connection.ActiveProvider;
432
+ }
433
+ tmpForm.setSchemas(pSchemas);
434
+ }
435
+
436
+ // Re-render the DataCloner accordion shell so the preview text
437
+ // reflects the active provider.
438
+ let tmpAccordion = this.pict.views['DataCloner-Connection'];
439
+ if (tmpAccordion) { tmpAccordion.render(); }
440
+
441
+ // Restore values + hook input listeners on the freshly-rendered
442
+ // shared-view inputs.
443
+ this._persistConnectionFields(pSchemas);
444
+ this.updateAllPreviews();
445
+ }
446
+
447
+ _persistConnectionFields(pSchemas)
448
+ {
449
+ let tmpForm = this.pict.views['PictSection-ConnectionForm'];
450
+ if (!tmpForm) { return; }
451
+
452
+ let tmpSelf = this;
453
+
454
+ // Restore + hook every per-provider field. saveField()
455
+ // dispatches on element type internally so checkboxes and
456
+ // text inputs share the same path.
457
+ (pSchemas || []).forEach(function (pSchema)
458
+ {
459
+ (pSchema.Fields || []).forEach(function (pField)
460
+ {
461
+ let tmpId = tmpForm.fieldDOMId(pSchema.Provider, pField.Name);
462
+ let tmpEl = document.getElementById(tmpId);
463
+ if (!tmpEl) { return; }
464
+
465
+ let tmpSaved = localStorage.getItem('dataCloner_' + tmpId);
466
+ if (tmpSaved !== null)
467
+ {
468
+ if (tmpEl.type === 'checkbox')
469
+ {
470
+ tmpEl.checked = (tmpSaved === 'true');
471
+ }
472
+ else
473
+ {
474
+ tmpEl.value = tmpSaved;
475
+ }
476
+ }
477
+
478
+ // Avoid double-binding when the shared view re-renders
479
+ // on provider change. We tag the element so subsequent
480
+ // runs of this method are no-ops.
481
+ if (tmpEl.dataset && tmpEl.dataset.dataclonerHooked === '1') { return; }
482
+ if (tmpEl.dataset) { tmpEl.dataset.dataclonerHooked = '1'; }
483
+ tmpEl.addEventListener('input', function () { tmpSelf.saveField(tmpId); tmpSelf.updateAllPreviews(); });
484
+ tmpEl.addEventListener('change', function () { tmpSelf.saveField(tmpId); tmpSelf.updateAllPreviews(); });
485
+ });
486
+ });
487
+ }
488
+
400
489
  // ================================================================
401
490
  // Live Status Indicator
402
491
  // ================================================================