retold-data-service 2.0.42 → 2.1.0

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.
@@ -1,5 +1,85 @@
1
+ /**
2
+ * DataCloner — Database Connection (section 1)
3
+ *
4
+ * Thin accordion shell + connect/test wiring around the shared
5
+ * `pict-section-connection-form` view, which owns the schema-driven
6
+ * provider <select> + per-provider field rendering. The shared view
7
+ * is registered separately in Pict-Application-DataCloner.js and
8
+ * renders into the FormSlot below.
9
+ *
10
+ * Flow:
11
+ * 1. Layout renders, this view paints the accordion shell with an
12
+ * empty FormSlot + "Loading providers…" preview text.
13
+ * 2. Pict-Provider-DataCloner#bootstrapConnectionSchemas() fetches
14
+ * GET /clone/connection/schemas and calls setSchemas() on the
15
+ * shared view, which renders the per-provider form into FormSlot.
16
+ * 3. User clicks Connect / Test → this view delegates to the shared
17
+ * view's getProviderConfig() to assemble the wire-format payload,
18
+ * then POSTs to /clone/connection/{configure,test}.
19
+ *
20
+ * Earlier versions of this view contained the schema rendering inline;
21
+ * that logic has been lifted into pict-section-connection-form so
22
+ * retold-databeacon and retold-facto can share it. See:
23
+ * modules/pict/pict-section-connection-form/source/Pict-Section-ConnectionForm.js
24
+ */
25
+ 'use strict';
26
+
1
27
  const libPictView = require('pict-view');
2
28
 
29
+ const _ViewConfiguration =
30
+ {
31
+ ViewIdentifier: 'DataCloner-Connection',
32
+ DefaultRenderable: 'DataCloner-Connection',
33
+ DefaultDestinationAddress: '#DataCloner-Section-Connection',
34
+
35
+ Templates:
36
+ [
37
+ {
38
+ Hash: 'DataCloner-Connection',
39
+ Template: /*html*/`
40
+ <div class="accordion-row">
41
+ <div class="accordion-number">1</div>
42
+ <div class="accordion-card" id="section1" data-section="1">
43
+ <div class="accordion-header" onclick="pict.views['DataCloner-Layout'].toggleSection('section1')">
44
+ <label class="accordion-auto" onclick="event.stopPropagation()"><input type="checkbox" id="auto1"> <span class="auto-label">auto</span></label>
45
+ <div class="accordion-title">Database Connection</div>
46
+ <span class="accordion-phase" id="phase1"></span>
47
+ <div class="accordion-preview" id="preview1">{~D:AppData.DataCloner.Connection.PreviewText~}</div>
48
+ <div class="accordion-actions">
49
+ <span class="accordion-go" onclick="event.stopPropagation(); pict.views['DataCloner-Connection'].connectProvider()">go</span>
50
+ </div>
51
+ <div class="accordion-toggle">&#9660;</div>
52
+ </div>
53
+ <div class="accordion-body">
54
+ <p style="font-size:0.9em; color:#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
+
56
+ <div class="inline-group" style="margin-bottom:10px">
57
+ <div style="flex:1; display:flex; align-items:flex-end; gap:8px; justify-content:flex-end">
58
+ <button class="primary" onclick="pict.views['DataCloner-Connection'].connectProvider()">Connect</button>
59
+ <button class="secondary" onclick="pict.views['DataCloner-Connection'].testConnection()">Test Connection</button>
60
+ </div>
61
+ </div>
62
+
63
+ <!-- pict-section-connection-form renders here -->
64
+ <div id="DataCloner-Connection-FormSlot"></div>
65
+
66
+ <div id="connectionStatus"></div>
67
+ </div>
68
+ </div>
69
+ </div>`
70
+ }
71
+ ],
72
+
73
+ Renderables:
74
+ [
75
+ {
76
+ RenderableHash: 'DataCloner-Connection',
77
+ TemplateHash: 'DataCloner-Connection',
78
+ DestinationAddress: '#DataCloner-Section-Connection'
79
+ }
80
+ ]
81
+ };
82
+
3
83
  class DataClonerConnectionView extends libPictView
4
84
  {
5
85
  constructor(pFable, pOptions, pServiceHash)
@@ -7,126 +87,126 @@ class DataClonerConnectionView extends libPictView
7
87
  super(pFable, pOptions, pServiceHash);
8
88
  }
9
89
 
10
- onProviderChange()
90
+ // ====================================================================
91
+ // Lifecycle
92
+ // ====================================================================
93
+
94
+ onBeforeRender(pRenderable)
11
95
  {
12
- let tmpProvider = document.getElementById('connProvider').value;
13
- let tmpProviders = ['SQLite', 'MySQL', 'MSSQL', 'PostgreSQL', 'Solr', 'MongoDB', 'RocksDB', 'Bibliograph'];
14
- for (let i = 0; i < tmpProviders.length; i++)
96
+ // Make sure AppData has the slot the accordion preview reads
97
+ // from (the Provider's bootstrapConnectionSchemas() will fill in
98
+ // the live values once schemas arrive).
99
+ if (!this.pict.AppData.DataCloner) { this.pict.AppData.DataCloner = {}; }
100
+ if (!this.pict.AppData.DataCloner.Connection)
15
101
  {
16
- let tmpEl = document.getElementById('config' + tmpProviders[i]);
17
- if (tmpEl)
18
- {
19
- tmpEl.style.display = (tmpProvider === tmpProviders[i]) ? '' : 'none';
20
- }
102
+ this.pict.AppData.DataCloner.Connection =
103
+ {
104
+ Schemas: [],
105
+ ActiveProvider: '',
106
+ PreviewText: 'Loading providers…'
107
+ };
21
108
  }
22
- this.pict.providers.DataCloner.saveField('connProvider');
109
+ return super.onBeforeRender(pRenderable);
23
110
  }
24
111
 
25
- getProviderConfig()
112
+ // ====================================================================
113
+ // Helpers used by the provider's preview / persistence layer
114
+ // ====================================================================
115
+
116
+ /**
117
+ * Build the section 1 accordion preview text. Reads live DOM
118
+ * values via the shared view if it's mounted, otherwise falls back
119
+ * to schema defaults.
120
+ *
121
+ * @param {{Schemas: object[], ActiveProvider: string}} pState
122
+ * @returns {string}
123
+ */
124
+ _buildPreviewText(pState)
26
125
  {
27
- let tmpProvider = document.getElementById('connProvider').value;
28
- let tmpConfig = {};
126
+ let tmpActive = pState.ActiveProvider;
127
+ let tmpSchema = (pState.Schemas || []).find((pS) => pS.Provider === tmpActive);
128
+ if (!tmpSchema) { return tmpActive || '(no provider selected)'; }
29
129
 
30
- if (tmpProvider === 'SQLite')
31
- {
32
- tmpConfig.SQLiteFilePath = document.getElementById('sqliteFilePath').value.trim() || '~/headlight-liveconnect-local/cloned.sqlite';
33
- }
34
- else if (tmpProvider === 'MySQL')
130
+ // Heuristics:
131
+ // - file-based providers (single Path field) → "<DisplayName> at <path>"
132
+ // - host/port/user providers → "<DisplayName> on host:port [as user]"
133
+ // Host/port/user are matched by canonical schema field names.
134
+ let tmpFields = tmpSchema.Fields || [];
135
+ let tmpPath = tmpFields.find((pF) => pF.Type === 'Path');
136
+ if (tmpPath)
35
137
  {
36
- tmpConfig.host = document.getElementById('mysqlServer').value.trim() || '127.0.0.1';
37
- tmpConfig.port = parseInt(document.getElementById('mysqlPort').value, 10) || 3306;
38
- tmpConfig.user = document.getElementById('mysqlUser').value.trim() || 'root';
39
- tmpConfig.password = document.getElementById('mysqlPassword').value;
40
- tmpConfig.database = document.getElementById('mysqlDatabase').value.trim();
41
- tmpConfig.connectionLimit = parseInt(document.getElementById('mysqlConnectionLimit').value, 10) || 20;
138
+ let tmpVal = this._readFieldValue(tmpSchema.Provider, tmpPath) || tmpPath.Default || '';
139
+ return `${tmpSchema.DisplayName} at ${tmpVal}`;
42
140
  }
43
- else if (tmpProvider === 'MSSQL')
141
+ let tmpHostField = tmpFields.find((pF) => pF.Name === 'host' || pF.Name === 'server');
142
+ let tmpPortField = tmpFields.find((pF) => pF.Name === 'port');
143
+ let tmpUserField = tmpFields.find((pF) => pF.Name === 'user');
144
+ if (tmpHostField && tmpPortField)
44
145
  {
45
- tmpConfig.server = document.getElementById('mssqlServer').value.trim() || '127.0.0.1';
46
- tmpConfig.port = parseInt(document.getElementById('mssqlPort').value, 10) || 1433;
47
- tmpConfig.user = document.getElementById('mssqlUser').value.trim() || 'sa';
48
- tmpConfig.password = document.getElementById('mssqlPassword').value;
49
- tmpConfig.database = document.getElementById('mssqlDatabase').value.trim();
50
- tmpConfig.connectionLimit = parseInt(document.getElementById('mssqlConnectionLimit').value, 10) || 20;
51
- // Use ROW_NUMBER() pagination instead of OFFSET/FETCH for
52
- // SQL Server 2008 R2 / 2012 or databases whose compatibility
53
- // level is < 110 (the parser rejects OFFSET/FETCH syntax
54
- // otherwise).
55
- tmpConfig.LegacyPagination = document.getElementById('mssqlLegacyPagination').checked;
56
-
57
- // Reliability tuning — pull from the advanced settings block.
58
- // All are optional; the connection provider falls back to
59
- // sensible defaults when a value is missing or zero.
60
- let tmpReqSec = parseInt(document.getElementById('mssqlRequestTimeoutSec').value, 10);
61
- if (tmpReqSec > 0) tmpConfig.RequestTimeoutMs = tmpReqSec * 1000;
62
- let tmpConnSec = parseInt(document.getElementById('mssqlConnectionTimeoutSec').value, 10);
63
- if (tmpConnSec > 0) tmpConfig.ConnectionTimeoutMs = tmpConnSec * 1000;
64
-
65
- let tmpConnectAttempts = parseInt(document.getElementById('mssqlConnectMaxAttempts').value, 10);
66
- let tmpDDLAttempts = parseInt(document.getElementById('mssqlDDLMaxAttempts').value, 10);
67
- let tmpInitialDelaySec = parseInt(document.getElementById('mssqlRetryInitialDelaySec').value, 10);
68
- let tmpMaxDelaySec = parseInt(document.getElementById('mssqlRetryMaxDelaySec').value, 10);
69
-
70
- if (tmpConnectAttempts > 0 || tmpInitialDelaySec > 0 || tmpMaxDelaySec > 0)
71
- {
72
- tmpConfig.ConnectRetryOptions = {};
73
- if (tmpConnectAttempts > 0) tmpConfig.ConnectRetryOptions.MaxAttempts = tmpConnectAttempts;
74
- if (tmpInitialDelaySec > 0) tmpConfig.ConnectRetryOptions.InitialDelayMs = tmpInitialDelaySec * 1000;
75
- if (tmpMaxDelaySec > 0) tmpConfig.ConnectRetryOptions.MaxDelayMs = tmpMaxDelaySec * 1000;
76
- }
77
- if (tmpDDLAttempts > 0 || tmpInitialDelaySec > 0 || tmpMaxDelaySec > 0)
146
+ let tmpHost = this._readFieldValue(tmpSchema.Provider, tmpHostField) || tmpHostField.Default || '';
147
+ let tmpPort = this._readFieldValue(tmpSchema.Provider, tmpPortField) || tmpPortField.Default || '';
148
+ let tmpPreview = `${tmpSchema.DisplayName} on ${tmpHost}:${tmpPort}`;
149
+ if (tmpUserField)
78
150
  {
79
- tmpConfig.DDLRetryOptions = {};
80
- if (tmpDDLAttempts > 0) tmpConfig.DDLRetryOptions.MaxAttempts = tmpDDLAttempts;
81
- if (tmpInitialDelaySec > 0) tmpConfig.DDLRetryOptions.InitialDelayMs = tmpInitialDelaySec * 1000;
82
- if (tmpMaxDelaySec > 0) tmpConfig.DDLRetryOptions.MaxDelayMs = tmpMaxDelaySec * 1000;
151
+ let tmpUser = this._readFieldValue(tmpSchema.Provider, tmpUserField) || tmpUserField.Default || '';
152
+ if (tmpUser) { tmpPreview += ` as ${tmpUser}`; }
83
153
  }
154
+ return tmpPreview;
84
155
  }
85
- else if (tmpProvider === 'PostgreSQL')
86
- {
87
- tmpConfig.host = document.getElementById('postgresqlHost').value.trim() || '127.0.0.1';
88
- tmpConfig.port = parseInt(document.getElementById('postgresqlPort').value, 10) || 5432;
89
- tmpConfig.user = document.getElementById('postgresqlUser').value.trim() || 'postgres';
90
- tmpConfig.password = document.getElementById('postgresqlPassword').value;
91
- tmpConfig.database = document.getElementById('postgresqlDatabase').value.trim();
92
- tmpConfig.max = parseInt(document.getElementById('postgresqlConnectionLimit').value, 10) || 10;
93
- }
94
- else if (tmpProvider === 'Solr')
95
- {
96
- tmpConfig.host = document.getElementById('solrHost').value.trim() || 'localhost';
97
- tmpConfig.port = parseInt(document.getElementById('solrPort').value, 10) || 8983;
98
- tmpConfig.core = document.getElementById('solrCore').value.trim() || 'default';
99
- tmpConfig.path = document.getElementById('solrPath').value.trim() || '/solr';
100
- tmpConfig.secure = document.getElementById('solrSecure').checked;
101
- }
102
- else if (tmpProvider === 'MongoDB')
103
- {
104
- tmpConfig.host = document.getElementById('mongodbHost').value.trim() || '127.0.0.1';
105
- tmpConfig.port = parseInt(document.getElementById('mongodbPort').value, 10) || 27017;
106
- tmpConfig.user = document.getElementById('mongodbUser').value.trim();
107
- tmpConfig.password = document.getElementById('mongodbPassword').value;
108
- tmpConfig.database = document.getElementById('mongodbDatabase').value.trim() || 'test';
109
- tmpConfig.maxPoolSize = parseInt(document.getElementById('mongodbConnectionLimit').value, 10) || 10;
110
- }
111
- else if (tmpProvider === 'RocksDB')
156
+ return tmpSchema.DisplayName;
157
+ }
158
+
159
+ _readFieldValue(pProvider, pField)
160
+ {
161
+ if (typeof(document) === 'undefined') { return ''; }
162
+ let tmpForm = this.pict.views['PictSection-ConnectionForm'];
163
+ if (!tmpForm) { return ''; }
164
+ let tmpEl = document.getElementById(tmpForm.fieldDOMId(pProvider, pField.Name));
165
+ if (!tmpEl) { return ''; }
166
+ if (pField.Type === 'Boolean') { return tmpEl.checked ? 'true' : ''; }
167
+ return tmpEl.value;
168
+ }
169
+
170
+ /**
171
+ * DOM-id resolver for fields owned by the shared view. Forwarded
172
+ * to PictSection-ConnectionForm so the provider's persistence
173
+ * layer (saveField, restoreFields) can compute element ids without
174
+ * needing to know the prefix.
175
+ */
176
+ fieldDOMId(pProvider, pFieldName)
177
+ {
178
+ let tmpForm = this.pict.views['PictSection-ConnectionForm'];
179
+ if (tmpForm && typeof(tmpForm.fieldDOMId) === 'function')
112
180
  {
113
- tmpConfig.RocksDBFolder = document.getElementById('rocksdbFolder').value.trim() || 'data/rocksdb';
181
+ return tmpForm.fieldDOMId(pProvider, pFieldName);
114
182
  }
115
- else if (tmpProvider === 'Bibliograph')
183
+ // Fallback before the shared view is mounted.
184
+ let tmpProvider = String(pProvider || '').toLowerCase();
185
+ let tmpField = String(pFieldName || '').replace(/\./g, '_');
186
+ return `datacloner-conn-${tmpProvider}-${tmpField}`;
187
+ }
188
+
189
+ // ====================================================================
190
+ // Connect / Test — delegate field collection to the shared view
191
+ // ====================================================================
192
+
193
+ getProviderConfig()
194
+ {
195
+ let tmpForm = this.pict.views['PictSection-ConnectionForm'];
196
+ if (tmpForm && typeof(tmpForm.getProviderConfig) === 'function')
116
197
  {
117
- tmpConfig.StorageFolder = document.getElementById('bibliographFolder').value.trim() || 'data/bibliograph';
198
+ return tmpForm.getProviderConfig();
118
199
  }
119
-
120
- return { Provider: tmpProvider, Config: tmpConfig };
200
+ // Shared view not mounted yet (early bootstrap, or schemas
201
+ // failed to load). Surface a plain empty payload — the
202
+ // connect/test handlers downstream will report the failure
203
+ // from the server side.
204
+ return { Provider: '', Config: {} };
121
205
  }
122
206
 
123
207
  connectProvider()
124
208
  {
125
- // Guard against re-entrant calls (e.g. rapid auto-connect polling)
126
- if (this._connectInFlight)
127
- {
128
- return;
129
- }
209
+ if (this._connectInFlight) { return; }
130
210
  this._connectInFlight = true;
131
211
 
132
212
  let tmpConnInfo = this.getProviderConfig();
@@ -199,291 +279,9 @@ class DataClonerConnectionView extends libPictView
199
279
  }
200
280
  })
201
281
  .catch(
202
- () =>
203
- {
204
- /* ignore */
205
- });
282
+ () => { /* ignore */ });
206
283
  }
207
284
  }
208
285
 
209
286
  module.exports = DataClonerConnectionView;
210
-
211
- module.exports.default_configuration =
212
- {
213
- ViewIdentifier: 'DataCloner-Connection',
214
- DefaultRenderable: 'DataCloner-Connection',
215
- DefaultDestinationAddress: '#DataCloner-Section-Connection',
216
- Templates:
217
- [
218
- {
219
- Hash: 'DataCloner-Connection',
220
- Template: /*html*/`
221
- <div class="accordion-row">
222
- <div class="accordion-number">1</div>
223
- <div class="accordion-card" id="section1" data-section="1">
224
- <div class="accordion-header" onclick="pict.views['DataCloner-Layout'].toggleSection('section1')">
225
- <label class="accordion-auto" onclick="event.stopPropagation()"><input type="checkbox" id="auto1"> <span class="auto-label">auto</span></label>
226
- <div class="accordion-title">Database Connection</div>
227
- <span class="accordion-phase" id="phase1"></span>
228
- <div class="accordion-preview" id="preview1">SQLite at data/cloned.sqlite</div>
229
- <div class="accordion-actions">
230
- <span class="accordion-go" onclick="event.stopPropagation(); pict.views['DataCloner-Connection'].connectProvider()">go</span>
231
- </div>
232
- <div class="accordion-toggle">&#9660;</div>
233
- </div>
234
- <div class="accordion-body">
235
- <p style="font-size:0.9em; color:#666; margin-bottom:10px">Configure the local database where cloned data will be stored. SQLite is connected by default.</p>
236
-
237
- <div class="inline-group">
238
- <div style="flex:0 0 200px">
239
- <label for="connProvider">Provider</label>
240
- <select id="connProvider" onchange="pict.views['DataCloner-Connection'].onProviderChange()">
241
- <option value="SQLite" selected>SQLite</option>
242
- <option value="MySQL">MySQL</option>
243
- <option value="MSSQL">MSSQL</option>
244
- <option value="PostgreSQL">PostgreSQL</option>
245
- <option value="Solr">Solr</option>
246
- <option value="MongoDB">MongoDB</option>
247
- <option value="RocksDB">RocksDB</option>
248
- <option value="Bibliograph">Bibliograph</option>
249
- </select>
250
- </div>
251
- <div style="flex:1; display:flex; align-items:flex-end; gap:8px">
252
- <button class="primary" onclick="pict.views['DataCloner-Connection'].connectProvider()">Connect</button>
253
- <button class="secondary" onclick="pict.views['DataCloner-Connection'].testConnection()">Test Connection</button>
254
- </div>
255
- </div>
256
-
257
- <!-- SQLite Config -->
258
- <div id="configSQLite">
259
- <label for="sqliteFilePath">SQLite File Path</label>
260
- <input type="text" id="sqliteFilePath" placeholder="~/headlight-liveconnect-local/cloned.sqlite" value="~/headlight-liveconnect-local/cloned.sqlite">
261
- </div>
262
-
263
- <!-- MySQL Config -->
264
- <div id="configMySQL" style="display:none">
265
- <div class="inline-group">
266
- <div style="flex:2">
267
- <label for="mysqlServer">Server</label>
268
- <input type="text" id="mysqlServer" placeholder="127.0.0.1" value="127.0.0.1">
269
- </div>
270
- <div style="flex:1">
271
- <label for="mysqlPort">Port</label>
272
- <input type="number" id="mysqlPort" placeholder="3306" value="3306">
273
- </div>
274
- </div>
275
- <div class="inline-group">
276
- <div>
277
- <label for="mysqlUser">User</label>
278
- <input type="text" id="mysqlUser" placeholder="root" value="root">
279
- </div>
280
- <div>
281
- <label for="mysqlPassword">Password</label>
282
- <input type="password" id="mysqlPassword" placeholder="password">
283
- </div>
284
- </div>
285
- <label for="mysqlDatabase">Database</label>
286
- <input type="text" id="mysqlDatabase" placeholder="meadow_clone">
287
- <div class="inline-group">
288
- <div>
289
- <label for="mysqlConnectionLimit">Connection Limit</label>
290
- <input type="number" id="mysqlConnectionLimit" placeholder="20" value="20">
291
- </div>
292
- <div></div>
293
- </div>
294
- </div>
295
-
296
- <!-- MSSQL Config -->
297
- <div id="configMSSQL" style="display:none">
298
- <div class="inline-group">
299
- <div style="flex:2">
300
- <label for="mssqlServer">Server</label>
301
- <input type="text" id="mssqlServer" placeholder="127.0.0.1" value="127.0.0.1">
302
- </div>
303
- <div style="flex:1">
304
- <label for="mssqlPort">Port</label>
305
- <input type="number" id="mssqlPort" placeholder="1433" value="1433">
306
- </div>
307
- </div>
308
- <div class="inline-group">
309
- <div>
310
- <label for="mssqlUser">User</label>
311
- <input type="text" id="mssqlUser" placeholder="sa" value="sa">
312
- </div>
313
- <div>
314
- <label for="mssqlPassword">Password</label>
315
- <input type="password" id="mssqlPassword" placeholder="password">
316
- </div>
317
- </div>
318
- <label for="mssqlDatabase">Database</label>
319
- <input type="text" id="mssqlDatabase" placeholder="meadow_clone">
320
- <div class="inline-group">
321
- <div>
322
- <label for="mssqlConnectionLimit">Connection Limit</label>
323
- <input type="number" id="mssqlConnectionLimit" placeholder="20" value="20">
324
- </div>
325
- <div></div>
326
- </div>
327
- <div style="margin-top:8px">
328
- <input type="checkbox" id="mssqlLegacyPagination">
329
- <label for="mssqlLegacyPagination" title="Enable for SQL Server 2008 R2 / 2012 or databases at compatibility_level &lt; 110. Uses ROW_NUMBER() pagination instead of OFFSET/FETCH.">Legacy pagination (SQL Server &lt; 2012 / compat level &lt; 110)</label>
330
- </div>
331
-
332
- <details style="margin-top:8px">
333
- <summary style="cursor:pointer; font-weight:600">Reliability &amp; timeouts (advanced)</summary>
334
- <p style="margin:8px 0; font-size:0.9em; color:#555">Tune these for slow / flaky customer networks. Connection and DDL operations will retry with exponential backoff, classifying each failure (NetworkError / RequestTimeout / PoolDegraded / ServerError) in the logs so the failure mode is obvious.</p>
335
- <div class="inline-group">
336
- <div>
337
- <label for="mssqlRequestTimeoutSec">Request timeout (sec)</label>
338
- <input type="number" id="mssqlRequestTimeoutSec" placeholder="120" value="120">
339
- </div>
340
- <div>
341
- <label for="mssqlConnectionTimeoutSec">Connection timeout (sec)</label>
342
- <input type="number" id="mssqlConnectionTimeoutSec" placeholder="60" value="60">
343
- </div>
344
- </div>
345
- <div class="inline-group">
346
- <div>
347
- <label for="mssqlConnectMaxAttempts">Connect retries (max attempts)</label>
348
- <input type="number" id="mssqlConnectMaxAttempts" placeholder="5" value="5" min="1" max="20">
349
- </div>
350
- <div>
351
- <label for="mssqlDDLMaxAttempts">DDL retries (max attempts)</label>
352
- <input type="number" id="mssqlDDLMaxAttempts" placeholder="5" value="5" min="1" max="20">
353
- </div>
354
- </div>
355
- <div class="inline-group">
356
- <div>
357
- <label for="mssqlRetryInitialDelaySec">Retry initial delay (sec)</label>
358
- <input type="number" id="mssqlRetryInitialDelaySec" placeholder="3" value="3" min="1" max="60">
359
- </div>
360
- <div>
361
- <label for="mssqlRetryMaxDelaySec">Retry max delay (sec)</label>
362
- <input type="number" id="mssqlRetryMaxDelaySec" placeholder="30" value="30" min="1" max="600">
363
- </div>
364
- </div>
365
- </details>
366
- </div>
367
-
368
- <!-- PostgreSQL Config -->
369
- <div id="configPostgreSQL" style="display:none">
370
- <div class="inline-group">
371
- <div style="flex:2">
372
- <label for="postgresqlHost">Host</label>
373
- <input type="text" id="postgresqlHost" placeholder="127.0.0.1" value="127.0.0.1">
374
- </div>
375
- <div style="flex:1">
376
- <label for="postgresqlPort">Port</label>
377
- <input type="number" id="postgresqlPort" placeholder="5432" value="5432">
378
- </div>
379
- </div>
380
- <div class="inline-group">
381
- <div>
382
- <label for="postgresqlUser">User</label>
383
- <input type="text" id="postgresqlUser" placeholder="postgres" value="postgres">
384
- </div>
385
- <div>
386
- <label for="postgresqlPassword">Password</label>
387
- <input type="password" id="postgresqlPassword" placeholder="password">
388
- </div>
389
- </div>
390
- <label for="postgresqlDatabase">Database</label>
391
- <input type="text" id="postgresqlDatabase" placeholder="meadow_clone">
392
- <div class="inline-group">
393
- <div>
394
- <label for="postgresqlConnectionLimit">Connection Pool Limit</label>
395
- <input type="number" id="postgresqlConnectionLimit" placeholder="10" value="10">
396
- </div>
397
- <div></div>
398
- </div>
399
- </div>
400
-
401
- <!-- Solr Config -->
402
- <div id="configSolr" style="display:none">
403
- <div class="inline-group">
404
- <div style="flex:2">
405
- <label for="solrHost">Host</label>
406
- <input type="text" id="solrHost" placeholder="localhost" value="localhost">
407
- </div>
408
- <div style="flex:1">
409
- <label for="solrPort">Port</label>
410
- <input type="number" id="solrPort" placeholder="8983" value="8983">
411
- </div>
412
- </div>
413
- <div class="inline-group">
414
- <div style="flex:2">
415
- <label for="solrCore">Core</label>
416
- <input type="text" id="solrCore" placeholder="default" value="default">
417
- </div>
418
- <div style="flex:1">
419
- <label for="solrPath">Path</label>
420
- <input type="text" id="solrPath" placeholder="/solr" value="/solr">
421
- </div>
422
- </div>
423
- <div class="checkbox-row">
424
- <input type="checkbox" id="solrSecure">
425
- <label for="solrSecure">Use HTTPS</label>
426
- </div>
427
- </div>
428
-
429
- <!-- MongoDB Config -->
430
- <div id="configMongoDB" style="display:none">
431
- <div class="inline-group">
432
- <div style="flex:2">
433
- <label for="mongodbHost">Host</label>
434
- <input type="text" id="mongodbHost" placeholder="127.0.0.1" value="127.0.0.1">
435
- </div>
436
- <div style="flex:1">
437
- <label for="mongodbPort">Port</label>
438
- <input type="number" id="mongodbPort" placeholder="27017" value="27017">
439
- </div>
440
- </div>
441
- <div class="inline-group">
442
- <div>
443
- <label for="mongodbUser">User</label>
444
- <input type="text" id="mongodbUser" placeholder="(optional)">
445
- </div>
446
- <div>
447
- <label for="mongodbPassword">Password</label>
448
- <input type="password" id="mongodbPassword" placeholder="(optional)">
449
- </div>
450
- </div>
451
- <label for="mongodbDatabase">Database</label>
452
- <input type="text" id="mongodbDatabase" placeholder="test" value="test">
453
- <div class="inline-group">
454
- <div>
455
- <label for="mongodbConnectionLimit">Max Pool Size</label>
456
- <input type="number" id="mongodbConnectionLimit" placeholder="10" value="10">
457
- </div>
458
- <div></div>
459
- </div>
460
- </div>
461
-
462
- <!-- RocksDB Config -->
463
- <div id="configRocksDB" style="display:none">
464
- <label for="rocksdbFolder">RocksDB Folder Path</label>
465
- <input type="text" id="rocksdbFolder" placeholder="data/rocksdb" value="data/rocksdb">
466
- </div>
467
-
468
- <!-- Bibliograph Config -->
469
- <div id="configBibliograph" style="display:none">
470
- <label for="bibliographFolder">Storage Folder Path</label>
471
- <input type="text" id="bibliographFolder" placeholder="data/bibliograph" value="data/bibliograph">
472
- </div>
473
-
474
- <div id="connectionStatus"></div>
475
- </div>
476
- </div>
477
- </div>
478
- `
479
- }
480
- ],
481
- Renderables:
482
- [
483
- {
484
- RenderableHash: 'DataCloner-Connection',
485
- TemplateHash: 'DataCloner-Connection',
486
- DestinationAddress: '#DataCloner-Section-Connection'
487
- }
488
- ]
489
- };
287
+ module.exports.default_configuration = _ViewConfiguration;