dbviewer 0.5.3 → 0.5.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9f8d59c15a88c9b63e2765f80b554c2b2a0a33f82fdb094e1ed6f86fdf8dde20
4
- data.tar.gz: d2bbe1fd8acae50c791ab4c32a061c78abbee095001e1647e32b4af4e6918753
3
+ metadata.gz: 4d0b4fd21e1b0a48e17e9301cc629947f80a40e66b4e3f2120848eaffd50fa53
4
+ data.tar.gz: ab3fc815ced156f36e0640334c2ed304fd7c77b8c2b50d780b7c1a2d95ce2fd8
5
5
  SHA512:
6
- metadata.gz: fcdf464a23ec52c45d85645ea0dcc9f57fe59c69b8452a68de7f000606d31d3e29c8b81ca237a228debc6884b57e8fb7a40500c1f02af550b3c5515456009ae5
7
- data.tar.gz: 768b6cb0f7d67c0ecda6301c6a94471ad16a89f37c6164c8e4f976222f1e1f95720b17477e43811f4d9574c79c71e1f6e582471d0acf408b815aeba17b58c961
6
+ metadata.gz: 658597f5db20651fd6fbd40078adfe9b7dec956a2c1933b87e76523a0f33bca278fbcbf02f5c822f92202419bb0c80ec4b9af6b24f9e0a02ea092bed4894b7e0
7
+ data.tar.gz: 96fe5ec2d5f105fd6f041fb393092f39012b8708dcf18f915c2b2fe606e587280d286b766a1f211e01f40f7ed8a3be616826782bede4e28a676ee49b16146e75
@@ -33,12 +33,35 @@
33
33
  <div class="card-body p-0">
34
34
  <div id="erd-container" class="w-100 h-100" style="min-height: 450px;">
35
35
  <div id="erd-loading" class="d-flex justify-content-center align-items-center h-100" style="min-height: 450px;">
36
- <div class="text-center">
37
- <div class="spinner-border text-primary mb-3" role="status">
38
- <span class="visually-hidden">Loading...</span>
36
+ <div class="text-center" style="width: 100%; max-width: 500px;">
37
+ <div class="mb-4">
38
+ <i class="bi bi-diagram-3 text-primary" style="font-size: 3rem;"></i>
39
39
  </div>
40
- <p>Generating Entity Relationship Diagram...</p>
41
- <small class="text-muted">This may take a moment for databases with many tables</small>
40
+ <h5 class="mb-3">Generating Entity Relationship Diagram</h5>
41
+ <p id="loading-phase" class="mb-3">Initializing...</p>
42
+
43
+ <!-- Progress bar for table loading -->
44
+ <div class="progress mb-3" style="height: 8px;">
45
+ <div id="table-progress-bar" class="progress-bar bg-primary" role="progressbar"
46
+ style="width: 0%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
47
+ </div>
48
+ </div>
49
+
50
+ <!-- Progress text -->
51
+ <div class="d-flex justify-content-between align-items-center mb-2">
52
+ <small class="text-muted">Table Details</small>
53
+ <small id="table-progress-text" class="text-muted">0 / 0</small>
54
+ </div>
55
+
56
+ <!-- Relationships loading indicator -->
57
+ <div id="relationships-status" class="d-flex align-items-center justify-content-center mt-3">
58
+ <div class="spinner-border spinner-border-sm text-secondary me-2" role="status">
59
+ <span class="visually-hidden">Loading...</span>
60
+ </div>
61
+ <small class="text-muted">Loading relationships...</small>
62
+ </div>
63
+
64
+ <small class="text-muted d-block mt-3">This may take a moment for databases with many tables</small>
42
65
  </div>
43
66
  </div>
44
67
  <!-- The ERD will be rendered here -->
@@ -175,11 +198,13 @@
175
198
  console.log('Relationships loaded:', data);
176
199
  relationships = data.relationships || [];
177
200
  relationshipsLoaded = true;
201
+ updateRelationshipsStatus(true);
178
202
  return relationships;
179
203
  })
180
204
  .catch(error => {
181
205
  console.error('Error fetching relationships:', error);
182
206
  relationshipsLoaded = true; // Mark as loaded even on error to prevent infinite loading
207
+ updateRelationshipsStatus(true);
183
208
  return [];
184
209
  });
185
210
  }
@@ -187,9 +212,48 @@
187
212
  // Function to update loading status
188
213
  function updateLoadingStatus(message) {
189
214
  const loadingElement = document.getElementById('erd-loading');
190
- const loadingText = loadingElement.querySelector('p');
191
- if (loadingText) {
192
- loadingText.textContent = message;
215
+ const loadingPhase = document.getElementById('loading-phase');
216
+ if (loadingPhase) {
217
+ loadingPhase.textContent = message;
218
+ }
219
+ }
220
+
221
+ // Function to update table loading progress
222
+ function updateTableProgress(loaded, total) {
223
+ const progressBar = document.getElementById('table-progress-bar');
224
+ const progressText = document.getElementById('table-progress-text');
225
+
226
+ if (progressBar && progressText) {
227
+ const percentage = total > 0 ? Math.round((loaded / total) * 100) : 0;
228
+ progressBar.style.width = percentage + '%';
229
+ progressBar.setAttribute('aria-valuenow', percentage);
230
+ progressText.textContent = `${loaded} / ${total}`;
231
+
232
+ // Update progress bar color based on completion
233
+ if (percentage === 100) {
234
+ progressBar.classList.remove('bg-primary');
235
+ progressBar.classList.add('bg-success');
236
+ }
237
+ }
238
+ }
239
+
240
+ // Function to update relationships status
241
+ function updateRelationshipsStatus(loaded) {
242
+ const relationshipsStatus = document.getElementById('relationships-status');
243
+ if (relationshipsStatus) {
244
+ if (loaded) {
245
+ relationshipsStatus.innerHTML = `
246
+ <i class="bi bi-check-circle text-success me-2"></i>
247
+ <small class="text-success">Relationships loaded</small>
248
+ `;
249
+ } else {
250
+ relationshipsStatus.innerHTML = `
251
+ <div class="spinner-border spinner-border-sm text-secondary me-2" role="status">
252
+ <span class="visually-hidden">Loading...</span>
253
+ </div>
254
+ <small class="text-muted">Loading relationships...</small>
255
+ `;
256
+ }
193
257
  }
194
258
  }
195
259
 
@@ -203,8 +267,12 @@
203
267
  let columnsLoadedCount = 0;
204
268
  const totalTables = tables.length;
205
269
 
270
+ // Initialize progress bar
271
+ updateTableProgress(0, totalTables);
272
+ updateLoadingStatus('Loading table details...');
273
+
206
274
  // Start fetching relationships immediately
207
- updateLoadingStatus('Loading database relationships...');
275
+ updateRelationshipsStatus(false);
208
276
  const relationshipsPromise = fetchRelationships();
209
277
 
210
278
  // First pass: add all tables with minimal info and start loading columns
@@ -227,8 +295,8 @@
227
295
  tableColumns[tableName] = data.columns;
228
296
  columnsLoadedCount++;
229
297
 
230
- // Update loading status
231
- updateLoadingStatus(`Loading table details... (${columnsLoadedCount}/${totalTables} tables)`);
298
+ // Update progress bar
299
+ updateTableProgress(columnsLoadedCount, totalTables);
232
300
 
233
301
  checkIfReadyToUpdate();
234
302
  }
@@ -236,6 +304,7 @@
236
304
  .catch(error => {
237
305
  console.error(`Error fetching columns for table ${tableName}:`, error);
238
306
  columnsLoadedCount++;
307
+ updateTableProgress(columnsLoadedCount, totalTables);
239
308
  checkIfReadyToUpdate();
240
309
  });
241
310
  });
@@ -261,9 +330,9 @@
261
330
  if (isUpdatingDiagram) return;
262
331
 
263
332
  isUpdatingDiagram = true;
264
- console.log('Updating diagram with full column and relationship data');
333
+ console.log('Rendering diagram with full column and relationship data');
265
334
 
266
- updateLoadingStatus('Generating diagram...');
335
+ updateLoadingStatus('Generating final diagram...');
267
336
 
268
337
  // Regenerate the diagram with complete data
269
338
  let updatedDefinition = 'erDiagram\n';
@@ -289,43 +358,33 @@
289
358
  updatedDefinition += ' %% No relationships found in the database schema\n';
290
359
  }
291
360
 
292
- // Create a new diagram element
293
- const updatedErdDiv = document.createElement('div');
294
- updatedErdDiv.className = 'mermaid';
295
- updatedErdDiv.innerHTML = updatedDefinition;
361
+ // Create the diagram element
362
+ const erdDiv = document.createElement('div');
363
+ erdDiv.className = 'mermaid';
364
+ erdDiv.innerHTML = updatedDefinition;
296
365
 
297
- // Get the container but don't clear it yet
298
- const container = document.getElementById('erd-container');
299
-
300
- // First, clean up any previous zoom instance
301
- if (panZoomInstance) {
302
- panZoomInstance.destroy();
303
- panZoomInstance = null;
304
- }
305
-
306
- // Create a temporary container
366
+ // Create a temporary container for rendering
307
367
  const tempContainer = document.createElement('div');
308
368
  tempContainer.style.visibility = 'hidden';
309
369
  tempContainer.style.position = 'absolute';
310
370
  tempContainer.style.width = '100%';
311
- tempContainer.appendChild(updatedErdDiv);
371
+ tempContainer.appendChild(erdDiv);
312
372
  document.body.appendChild(tempContainer);
313
373
 
314
- // Render in the temporary container first
315
- mermaid.init(undefined, updatedErdDiv).then(function() {
316
- console.log('Diagram fully updated with all data');
374
+ // Render the diagram in the temporary container
375
+ mermaid.init(undefined, erdDiv).then(function() {
376
+ console.log('Diagram fully rendered with all data');
317
377
 
318
- // Clear original container and move the rendered content
319
378
  try {
320
379
  // Remove from temp container without destroying
321
- tempContainer.removeChild(updatedErdDiv);
380
+ tempContainer.removeChild(erdDiv);
322
381
 
323
382
  // Hide loading indicator
324
383
  document.getElementById('erd-loading').style.display = 'none';
325
384
 
326
385
  // Clear main container and add the diagram
327
386
  container.innerHTML = '';
328
- container.appendChild(updatedErdDiv);
387
+ container.appendChild(erdDiv);
329
388
 
330
389
  // Remove temp container
331
390
  document.body.removeChild(tempContainer);
@@ -342,101 +401,16 @@
342
401
  isUpdatingDiagram = false;
343
402
  }
344
403
  }).catch(function(error) {
345
- console.error('Error rendering updated diagram:', error);
404
+ console.error('Error rendering diagram:', error);
346
405
  document.body.removeChild(tempContainer);
347
406
  isUpdatingDiagram = false;
348
- showError('Error rendering diagram', 'There was an error updating the diagram with complete data.', error.message);
407
+ showError('Error rendering diagram', 'There was an error rendering the entity relationship diagram.', error.message);
349
408
  });
350
409
  }
351
410
 
352
- // Add initial relationships placeholder (empty)
353
- mermaidDefinition += ' %% Relationships loading...\n';
354
-
355
- // Create a div for the initial diagram (shows immediately with table names only)
356
- const erdDiv = document.createElement('div');
357
- erdDiv.className = 'mermaid';
358
- erdDiv.innerHTML = mermaidDefinition;
359
-
360
411
  // Get the container reference for later use
361
412
  const container = document.getElementById('erd-container');
362
413
 
363
- // Create a temporary container for initial rendering
364
- const tempInitContainer = document.createElement('div');
365
- tempInitContainer.style.visibility = 'hidden';
366
- tempInitContainer.style.position = 'absolute';
367
- tempInitContainer.style.width = '100%';
368
- tempInitContainer.appendChild(erdDiv);
369
- document.body.appendChild(tempInitContainer);
370
-
371
- // Update loading status for initial render
372
- updateLoadingStatus('Rendering initial diagram...');
373
-
374
- // Render the initial diagram in the temporary container
375
- mermaid.init(undefined, erdDiv).then(function() {
376
- try {
377
- // Remove from temp container without destroying
378
- tempInitContainer.removeChild(erdDiv);
379
-
380
- // Hide the loading indicator temporarily (will show updated loading for data fetching)
381
- document.getElementById('erd-loading').style.display = 'none';
382
-
383
- // Add the rendered diagram to the main container
384
- container.appendChild(erdDiv);
385
-
386
- // Remove temp container
387
- document.body.removeChild(tempInitContainer);
388
-
389
- // Setup initial zoom controls
390
- setTimeout(() => {
391
- setupZoomControls();
392
- // Show a subtle loading indicator that data is still loading
393
- showDataLoadingIndicator();
394
- }, 100);
395
- } catch(err) {
396
- console.error('Error moving initial diagram to container:', err);
397
- }
398
- }).catch(function(error) {
399
- console.error('Error rendering initial diagram:', error);
400
- document.body.removeChild(tempInitContainer);
401
- showError('Error generating diagram', 'There was an error generating the initial entity relationship diagram.', error.message);
402
- });
403
-
404
- // Function to show a subtle loading indicator for data loading
405
- function showDataLoadingIndicator() {
406
- // Create a small loading badge in the top-right corner
407
- const loadingBadge = document.createElement('div');
408
- loadingBadge.id = 'data-loading-badge';
409
- loadingBadge.className = 'position-absolute top-0 end-0 m-3';
410
- loadingBadge.style.zIndex = '1000';
411
- loadingBadge.innerHTML = `
412
- <div class="badge bg-info d-flex align-items-center">
413
- <div class="spinner-border spinner-border-sm me-2" role="status" style="width: 0.8rem; height: 0.8rem;">
414
- <span class="visually-hidden">Loading...</span>
415
- </div>
416
- Loading details...
417
- </div>
418
- `;
419
-
420
- container.style.position = 'relative';
421
- container.appendChild(loadingBadge);
422
-
423
- // Remove the badge when data loading is complete
424
- const checkComplete = () => {
425
- if (columnsLoadedCount === totalTables && relationshipsLoaded) {
426
- setTimeout(() => {
427
- const badge = document.getElementById('data-loading-badge');
428
- if (badge) {
429
- badge.remove();
430
- }
431
- }, 500); // Small delay to show completion
432
- } else {
433
- setTimeout(checkComplete, 500);
434
- }
435
- };
436
-
437
- setTimeout(checkComplete, 1000);
438
- }
439
-
440
414
  // SVG Pan Zoom instance
441
415
  let panZoomInstance = null;
442
416
 
@@ -1,3 +1,3 @@
1
1
  module Dbviewer
2
- VERSION = "0.5.3"
2
+ VERSION = "0.5.4"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dbviewer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 0.5.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wailan Tirajoh