dbviewer 0.3.5 → 0.3.15
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 +4 -4
- data/README.md +10 -0
- data/app/controllers/concerns/dbviewer/database_operations.rb +137 -0
- data/app/controllers/dbviewer/logs_controller.rb +8 -0
- data/app/controllers/dbviewer/tables_controller.rb +40 -0
- data/app/views/dbviewer/home/index.html.erb +77 -47
- data/app/views/dbviewer/tables/mini_erd.html.erb +517 -0
- data/app/views/dbviewer/tables/show.html.erb +603 -54
- data/app/views/layouts/dbviewer/application.html.erb +35 -3
- data/config/routes.rb +1 -0
- data/lib/dbviewer/configuration.rb +4 -0
- data/lib/dbviewer/logger.rb +2 -0
- data/lib/dbviewer/version.rb +1 -1
- metadata +3 -2
@@ -0,0 +1,517 @@
|
|
1
|
+
<div class="modal-header">
|
2
|
+
<h5 class="modal-title">Relationships for <%= @table_name %></h5>
|
3
|
+
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
4
|
+
</div>
|
5
|
+
<div class="modal-body p-0">
|
6
|
+
<div id="mini-erd-container" class="w-100" style="min-height: 450px; height: 100%;">
|
7
|
+
<div id="mini-erd-loading" class="d-flex justify-content-center align-items-center" style="height: 100%; min-height: 450px;">
|
8
|
+
<div class="text-center">
|
9
|
+
<div class="spinner-border text-primary mb-3" role="status">
|
10
|
+
<span class="visually-hidden">Loading...</span>
|
11
|
+
</div>
|
12
|
+
<p>Generating Relationships Diagram...</p>
|
13
|
+
</div>
|
14
|
+
</div>
|
15
|
+
<!-- The mini ERD will be rendered here -->
|
16
|
+
<div id="mini-erd-error" class="alert alert-danger m-3 d-none">
|
17
|
+
<h5>Error generating diagram</h5>
|
18
|
+
<p id="mini-erd-error-message">There was an error rendering the relationships diagram.</p>
|
19
|
+
<pre id="mini-erd-error-details" class="bg-light p-2 small mt-2"></pre>
|
20
|
+
</div>
|
21
|
+
</div>
|
22
|
+
|
23
|
+
<!-- Debug section - will be visible if there are any issues -->
|
24
|
+
<div id="debug-data" class="d-none m-3 border-top pt-3">
|
25
|
+
<details>
|
26
|
+
<summary>Debug Information</summary>
|
27
|
+
<div class="alert alert-info small">
|
28
|
+
<pre id="erd-data-debug" style="max-height: 100px; overflow: auto;"><%= @erd_data.to_json %></pre>
|
29
|
+
</div>
|
30
|
+
</details>
|
31
|
+
</div>
|
32
|
+
</div>
|
33
|
+
<div class="modal-footer">
|
34
|
+
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
35
|
+
<a href="<%= dbviewer.entity_relationship_diagrams_path %>" class="btn btn-primary">View Full ERD</a>
|
36
|
+
</div>
|
37
|
+
|
38
|
+
<script>
|
39
|
+
// Immediately invoke this function to initialize everything
|
40
|
+
(function() {
|
41
|
+
// Check if mermaid is loaded first
|
42
|
+
if (typeof mermaid === 'undefined') {
|
43
|
+
console.error('Mermaid library not loaded!');
|
44
|
+
showError('Mermaid library not loaded', 'The diagram library could not be loaded. Please check your internet connection and try again.');
|
45
|
+
return;
|
46
|
+
}
|
47
|
+
|
48
|
+
console.log('Initializing Mermaid for mini ERD');
|
49
|
+
|
50
|
+
// Configure Mermaid
|
51
|
+
mermaid.initialize({
|
52
|
+
startOnLoad: false,
|
53
|
+
theme: document.documentElement.getAttribute('data-bs-theme') === 'dark' ? 'dark' : 'default',
|
54
|
+
securityLevel: 'loose',
|
55
|
+
er: {
|
56
|
+
diagramPadding: 20,
|
57
|
+
layoutDirection: 'TB',
|
58
|
+
minEntityWidth: 100,
|
59
|
+
minEntityHeight: 75,
|
60
|
+
entityPadding: 15,
|
61
|
+
stroke: 'gray',
|
62
|
+
fill: 'honeydew',
|
63
|
+
fontSize: 12
|
64
|
+
}
|
65
|
+
});
|
66
|
+
|
67
|
+
// Immediately hide debug data - only reveal if there's an error
|
68
|
+
const debugElement = document.getElementById('debug-data');
|
69
|
+
if (debugElement) {
|
70
|
+
debugElement.classList.add('d-none');
|
71
|
+
}
|
72
|
+
|
73
|
+
// Directly parse the ERD data instead of waiting for DOM loaded event
|
74
|
+
// This is important because the modal might already be loaded
|
75
|
+
try {
|
76
|
+
// Try to parse the data - it's critical to wrap this in JSON.parse when needed
|
77
|
+
<% if @erd_data.is_a?(String) %>
|
78
|
+
// If somehow we got a string instead of a hash
|
79
|
+
const erdData = JSON.parse(<%= raw @erd_data.to_json %>);
|
80
|
+
<% else %>
|
81
|
+
// Normal case - Ruby hash will be converted to JS object
|
82
|
+
const erdData = <%= raw @erd_data.to_json %>;
|
83
|
+
<% end %>
|
84
|
+
|
85
|
+
if (erdData && typeof erdData === 'object') {
|
86
|
+
// Store data in debug element for troubleshooting
|
87
|
+
const debugDataEl = document.getElementById('erd-data-debug');
|
88
|
+
if (debugDataEl) {
|
89
|
+
debugDataEl.textContent = JSON.stringify(erdData, null, 2);
|
90
|
+
}
|
91
|
+
|
92
|
+
renderMiniERD(erdData);
|
93
|
+
} else {
|
94
|
+
throw new Error('ERD data is not an object');
|
95
|
+
}
|
96
|
+
} catch (e) {
|
97
|
+
console.error('Error parsing ERD data:', e);
|
98
|
+
showError('Data parsing error', 'Failed to parse relationship data: ' + e.message);
|
99
|
+
|
100
|
+
// Show debug data when there's an error
|
101
|
+
if (debugElement) {
|
102
|
+
debugElement.classList.remove('d-none');
|
103
|
+
}
|
104
|
+
}
|
105
|
+
})();
|
106
|
+
|
107
|
+
function showError(title, message, details = '') {
|
108
|
+
const errorContainer = document.getElementById('mini-erd-error');
|
109
|
+
const errorMessage = document.getElementById('mini-erd-error-message');
|
110
|
+
const errorDetails = document.getElementById('mini-erd-error-details');
|
111
|
+
|
112
|
+
// Hide the loading indicator
|
113
|
+
document.getElementById('mini-erd-loading').style.display = 'none';
|
114
|
+
|
115
|
+
// Set error message
|
116
|
+
errorMessage.textContent = message;
|
117
|
+
|
118
|
+
// Set error details if provided
|
119
|
+
if (details) {
|
120
|
+
errorDetails.textContent = details;
|
121
|
+
errorDetails.classList.remove('d-none');
|
122
|
+
} else {
|
123
|
+
errorDetails.classList.add('d-none');
|
124
|
+
}
|
125
|
+
|
126
|
+
// Show the error container
|
127
|
+
errorContainer.classList.remove('d-none');
|
128
|
+
}
|
129
|
+
|
130
|
+
function renderMiniERD(tableData) {
|
131
|
+
try {
|
132
|
+
const tables = tableData.tables || [];
|
133
|
+
const relationships = tableData.relationships || [];
|
134
|
+
|
135
|
+
// Validate data before proceeding
|
136
|
+
if (!Array.isArray(tables) || !Array.isArray(relationships)) {
|
137
|
+
showError('Invalid data format', 'The relationship data is not in the expected format.');
|
138
|
+
console.error('Invalid data format received:', tableData);
|
139
|
+
return;
|
140
|
+
}
|
141
|
+
|
142
|
+
console.log(`Found ${tables.length} tables and ${relationships.length} relationships`);
|
143
|
+
|
144
|
+
// Create the ER diagram definition in Mermaid syntax
|
145
|
+
let mermaidDefinition = 'erDiagram\n';
|
146
|
+
|
147
|
+
// Add tables to the diagram - ensure we have at least one table
|
148
|
+
if (tables.length === 0) {
|
149
|
+
mermaidDefinition += ` <%= @table_name.gsub(/[^\w]/, '_') %> {\n`;
|
150
|
+
mermaidDefinition += ` string id PK\n`;
|
151
|
+
mermaidDefinition += ` }\n`;
|
152
|
+
} else {
|
153
|
+
tables.forEach(function(table) {
|
154
|
+
const tableName = table.name;
|
155
|
+
|
156
|
+
if (!tableName) {
|
157
|
+
console.warn('Table with no name found:', table);
|
158
|
+
return; // Skip this table
|
159
|
+
}
|
160
|
+
|
161
|
+
// Clean table name for mermaid (remove special characters)
|
162
|
+
const cleanTableName = tableName.replace(/[^\w]/g, '_');
|
163
|
+
|
164
|
+
// Make the current table stand out with a different visualization
|
165
|
+
if (tableName === '<%= @table_name %>') {
|
166
|
+
mermaidDefinition += ` ${cleanTableName} {\n`;
|
167
|
+
mermaidDefinition += ` string id PK\n`;
|
168
|
+
mermaidDefinition += ` }\n`;
|
169
|
+
} else {
|
170
|
+
mermaidDefinition += ` ${cleanTableName} {\n`;
|
171
|
+
mermaidDefinition += ` string id\n`;
|
172
|
+
mermaidDefinition += ` }\n`;
|
173
|
+
}
|
174
|
+
});
|
175
|
+
}
|
176
|
+
|
177
|
+
// Add relationships
|
178
|
+
if (relationships && relationships.length > 0) {
|
179
|
+
relationships.forEach(function(rel) {
|
180
|
+
try {
|
181
|
+
// Ensure all required properties exist
|
182
|
+
if (!rel.from_table || !rel.to_table) {
|
183
|
+
console.error('Missing table in relationship:', rel);
|
184
|
+
return; // Skip this relationship
|
185
|
+
}
|
186
|
+
|
187
|
+
// Clean up table names for mermaid (remove special characters)
|
188
|
+
const fromTable = rel.from_table.replace(/[^\w]/g, '_');
|
189
|
+
const toTable = rel.to_table.replace(/[^\w]/g, '_');
|
190
|
+
const relationLabel = rel.from_column || '';
|
191
|
+
|
192
|
+
// Customize the display based on direction
|
193
|
+
mermaidDefinition += ` ${fromTable} }|--|| ${toTable} : "${relationLabel}"\n`;
|
194
|
+
} catch (err) {
|
195
|
+
console.error('Error processing relationship:', err, rel);
|
196
|
+
}
|
197
|
+
});
|
198
|
+
} else {
|
199
|
+
// Add a note if no relationships are found
|
200
|
+
mermaidDefinition += ' %% No relationships found for this table\n';
|
201
|
+
}
|
202
|
+
|
203
|
+
// Log the generated mermaid definition for debugging
|
204
|
+
console.log('Mermaid Definition:', mermaidDefinition);
|
205
|
+
|
206
|
+
// Hide the loading indicator first since render might take time
|
207
|
+
document.getElementById('mini-erd-loading').style.display = 'none';
|
208
|
+
|
209
|
+
// Render the diagram
|
210
|
+
try {
|
211
|
+
mermaid.render('mini-erd-graph', mermaidDefinition)
|
212
|
+
.then(function(result) {
|
213
|
+
console.log('Mermaid rendering successful');
|
214
|
+
|
215
|
+
// Get the container
|
216
|
+
const container = document.getElementById('mini-erd-container');
|
217
|
+
|
218
|
+
// Insert the rendered SVG
|
219
|
+
container.innerHTML = result.svg;
|
220
|
+
|
221
|
+
// Apply SVG-Pan-Zoom to make the diagram interactive
|
222
|
+
try {
|
223
|
+
const svgElement = container.querySelector('svg');
|
224
|
+
if (svgElement && typeof svgPanZoom !== 'undefined') {
|
225
|
+
svgPanZoom(svgElement, {
|
226
|
+
zoomEnabled: true,
|
227
|
+
controlIconsEnabled: true,
|
228
|
+
fit: true,
|
229
|
+
center: true
|
230
|
+
});
|
231
|
+
}
|
232
|
+
} catch (e) {
|
233
|
+
console.warn('Failed to initialize svg-pan-zoom:', e);
|
234
|
+
// Not critical, continue without pan-zoom
|
235
|
+
}
|
236
|
+
|
237
|
+
// Add highlighting for the current table
|
238
|
+
setTimeout(function() {
|
239
|
+
try {
|
240
|
+
const cleanTableName = '<%= @table_name %>'.replace(/[^\w]/g, '_');
|
241
|
+
const currentTableElement = container.querySelector(`[id*="${cleanTableName}"]`);
|
242
|
+
if (currentTableElement) {
|
243
|
+
const rect = currentTableElement.querySelector('rect');
|
244
|
+
if (rect) {
|
245
|
+
// Highlight the current table
|
246
|
+
rect.setAttribute('fill', document.documentElement.getAttribute('data-bs-theme') === 'dark' ? '#2c3034' : '#e2f0ff');
|
247
|
+
rect.setAttribute('stroke', document.documentElement.getAttribute('data-bs-theme') === 'dark' ? '#6ea8fe' : '#0d6efd');
|
248
|
+
rect.setAttribute('stroke-width', '2');
|
249
|
+
}
|
250
|
+
}
|
251
|
+
} catch (e) {
|
252
|
+
console.error('Error highlighting current table:', e);
|
253
|
+
}
|
254
|
+
}, 100);
|
255
|
+
})
|
256
|
+
.catch(function(error) {
|
257
|
+
console.error('Error rendering mini ERD:', error);
|
258
|
+
showError(
|
259
|
+
'Error rendering diagram',
|
260
|
+
'There was an error rendering the relationships diagram.',
|
261
|
+
error.message || 'Unknown error'
|
262
|
+
);
|
263
|
+
|
264
|
+
// Show debug data when there's an error
|
265
|
+
document.getElementById('debug-data').classList.remove('d-none');
|
266
|
+
});
|
267
|
+
} catch (renderError) {
|
268
|
+
console.error('Exception in mermaid.render call:', renderError);
|
269
|
+
showError(
|
270
|
+
'Rendering exception',
|
271
|
+
'Failed to render the diagram.',
|
272
|
+
renderError.message || 'Unknown error'
|
273
|
+
);
|
274
|
+
|
275
|
+
// Show debug data when there's an error
|
276
|
+
document.getElementById('debug-data').classList.remove('d-none');
|
277
|
+
}
|
278
|
+
} catch (error) {
|
279
|
+
console.error('Exception in renderMiniERD function:', error);
|
280
|
+
showError(
|
281
|
+
'Exception generating diagram',
|
282
|
+
'There was an exception processing the relationships diagram.',
|
283
|
+
error.message || 'Unknown error'
|
284
|
+
);
|
285
|
+
|
286
|
+
// Show debug data when there's an error
|
287
|
+
document.getElementById('debug-data').classList.remove('d-none');
|
288
|
+
}
|
289
|
+
}
|
290
|
+
</script>
|
291
|
+
|
292
|
+
<script>
|
293
|
+
// Immediately invoke this function to initialize everything
|
294
|
+
(function() {
|
295
|
+
// Check if mermaid is loaded first
|
296
|
+
if (typeof mermaid === 'undefined') {
|
297
|
+
console.error('Mermaid library not loaded!');
|
298
|
+
showError('Mermaid library not loaded', 'The diagram library could not be loaded. Please check your internet connection and try again.');
|
299
|
+
return;
|
300
|
+
}
|
301
|
+
|
302
|
+
console.log('Initializing Mermaid for mini ERD');
|
303
|
+
|
304
|
+
// Configure Mermaid
|
305
|
+
mermaid.initialize({
|
306
|
+
startOnLoad: false,
|
307
|
+
theme: document.documentElement.getAttribute('data-bs-theme') === 'dark' ? 'dark' : 'default',
|
308
|
+
securityLevel: 'loose',
|
309
|
+
er: {
|
310
|
+
diagramPadding: 20,
|
311
|
+
layoutDirection: 'TB',
|
312
|
+
minEntityWidth: 100,
|
313
|
+
minEntityHeight: 75,
|
314
|
+
entityPadding: 15,
|
315
|
+
stroke: 'gray',
|
316
|
+
fill: 'honeydew',
|
317
|
+
fontSize: 12
|
318
|
+
}
|
319
|
+
});
|
320
|
+
|
321
|
+
// Directly parse the ERD data instead of waiting for DOM loaded event
|
322
|
+
// This is important because the modal might already be loaded
|
323
|
+
try {
|
324
|
+
// Parse ERD data directly from Rails
|
325
|
+
const erdData = <%= raw @erd_data.to_json %>;
|
326
|
+
|
327
|
+
// Display debug info
|
328
|
+
document.getElementById('debug-data').classList.remove('d-none');
|
329
|
+
document.getElementById('erd-data-debug').textContent = JSON.stringify(erdData, null, 2);
|
330
|
+
|
331
|
+
renderMiniERD(erdData);
|
332
|
+
} catch (e) {
|
333
|
+
console.error('Error parsing ERD data:', e);
|
334
|
+
showError('Data parsing error', 'Failed to parse relationship data: ' + e.message);
|
335
|
+
}
|
336
|
+
})();
|
337
|
+
|
338
|
+
function showError(title, message, details = '') {
|
339
|
+
const errorContainer = document.getElementById('mini-erd-error');
|
340
|
+
const errorMessage = document.getElementById('mini-erd-error-message');
|
341
|
+
const errorDetails = document.getElementById('mini-erd-error-details');
|
342
|
+
|
343
|
+
// Hide the loading indicator
|
344
|
+
document.getElementById('mini-erd-loading').style.display = 'none';
|
345
|
+
|
346
|
+
// Set error message
|
347
|
+
errorMessage.textContent = message;
|
348
|
+
|
349
|
+
// Set error details if provided
|
350
|
+
if (details) {
|
351
|
+
errorDetails.textContent = details;
|
352
|
+
errorDetails.classList.remove('d-none');
|
353
|
+
} else {
|
354
|
+
errorDetails.classList.add('d-none');
|
355
|
+
}
|
356
|
+
|
357
|
+
// Show the error container
|
358
|
+
errorContainer.classList.remove('d-none');
|
359
|
+
}
|
360
|
+
|
361
|
+
function renderMiniERD(tableData) {
|
362
|
+
try {
|
363
|
+
console.log('ERD Data received:', tableData); // Debug log
|
364
|
+
|
365
|
+
const tables = tableData.tables || [];
|
366
|
+
const relationships = tableData.relationships || [];
|
367
|
+
|
368
|
+
// Validate data before proceeding
|
369
|
+
if (!Array.isArray(tables) || !Array.isArray(relationships)) {
|
370
|
+
showError('Invalid data format', 'The relationship data is not in the expected format.');
|
371
|
+
console.error('Invalid data format received:', tableData);
|
372
|
+
return;
|
373
|
+
}
|
374
|
+
|
375
|
+
console.log(`Found ${tables.length} tables and ${relationships.length} relationships`);
|
376
|
+
|
377
|
+
// Create the ER diagram definition in Mermaid syntax
|
378
|
+
let mermaidDefinition = 'erDiagram\n';
|
379
|
+
|
380
|
+
// Add tables to the diagram - ensure we have at least one table
|
381
|
+
if (tables.length === 0) {
|
382
|
+
mermaidDefinition += ` <%= @table_name %> {\n`;
|
383
|
+
mermaidDefinition += ` string id PK\n`;
|
384
|
+
mermaidDefinition += ` }\n`;
|
385
|
+
} else {
|
386
|
+
tables.forEach(function(table) {
|
387
|
+
const tableName = table.name;
|
388
|
+
|
389
|
+
if (!tableName) {
|
390
|
+
console.warn('Table with no name found:', table);
|
391
|
+
return; // Skip this table
|
392
|
+
}
|
393
|
+
|
394
|
+
// Clean table name for mermaid (remove special characters)
|
395
|
+
const cleanTableName = tableName.replace(/[^\w]/g, '_');
|
396
|
+
|
397
|
+
// Make the current table stand out with a different visualization
|
398
|
+
if (tableName === '<%= @table_name %>') {
|
399
|
+
mermaidDefinition += ` ${cleanTableName} {\n`;
|
400
|
+
mermaidDefinition += ` string id PK\n`;
|
401
|
+
mermaidDefinition += ` }\n`;
|
402
|
+
} else {
|
403
|
+
mermaidDefinition += ` ${cleanTableName} {\n`;
|
404
|
+
mermaidDefinition += ` string id\n`;
|
405
|
+
mermaidDefinition += ` }\n`;
|
406
|
+
}
|
407
|
+
});
|
408
|
+
}
|
409
|
+
|
410
|
+
// Add relationships
|
411
|
+
if (relationships && relationships.length > 0) {
|
412
|
+
relationships.forEach(function(rel) {
|
413
|
+
try {
|
414
|
+
// Ensure all required properties exist
|
415
|
+
if (!rel.from_table || !rel.to_table) {
|
416
|
+
console.error('Missing table in relationship:', rel);
|
417
|
+
return; // Skip this relationship
|
418
|
+
}
|
419
|
+
|
420
|
+
// Clean up table names for mermaid (remove special characters)
|
421
|
+
const fromTable = rel.from_table.replace(/[^\w]/g, '_');
|
422
|
+
const toTable = rel.to_table.replace(/[^\w]/g, '_');
|
423
|
+
const relationLabel = rel.from_column || '';
|
424
|
+
|
425
|
+
// Customize the display based on direction
|
426
|
+
mermaidDefinition += ` ${fromTable} }|--|| ${toTable} : "${relationLabel}"\n`;
|
427
|
+
} catch (err) {
|
428
|
+
console.error('Error processing relationship:', err, rel);
|
429
|
+
}
|
430
|
+
});
|
431
|
+
} else {
|
432
|
+
// Add a note if no relationships are found
|
433
|
+
mermaidDefinition += ' %% No relationships found for this table\n';
|
434
|
+
}
|
435
|
+
|
436
|
+
// Create a div for the diagram
|
437
|
+
const miniErdDiv = document.createElement('div');
|
438
|
+
miniErdDiv.className = 'mermaid';
|
439
|
+
miniErdDiv.innerHTML = mermaidDefinition;
|
440
|
+
|
441
|
+
// Get the container reference
|
442
|
+
const container = document.getElementById('mini-erd-container');
|
443
|
+
|
444
|
+
// Log the generated mermaid definition for debugging
|
445
|
+
console.log('Mermaid Definition:', mermaidDefinition);
|
446
|
+
|
447
|
+
// Hide the loading indicator first since render might take time
|
448
|
+
document.getElementById('mini-erd-loading').style.display = 'none';
|
449
|
+
|
450
|
+
// Render the diagram
|
451
|
+
try {
|
452
|
+
mermaid.render('mini-erd-graph', mermaidDefinition)
|
453
|
+
.then(function(result) {
|
454
|
+
console.log('Mermaid rendering successful');
|
455
|
+
// Insert the rendered SVG
|
456
|
+
container.innerHTML = result.svg;
|
457
|
+
|
458
|
+
// Apply SVG-Pan-Zoom to make the diagram interactive
|
459
|
+
try {
|
460
|
+
const svgElement = container.querySelector('svg');
|
461
|
+
if (svgElement && typeof svgPanZoom !== 'undefined') {
|
462
|
+
svgPanZoom(svgElement, {
|
463
|
+
zoomEnabled: true,
|
464
|
+
controlIconsEnabled: true,
|
465
|
+
fit: true,
|
466
|
+
center: true
|
467
|
+
});
|
468
|
+
}
|
469
|
+
} catch (e) {
|
470
|
+
console.warn('Failed to initialize svg-pan-zoom:', e);
|
471
|
+
// Not critical, continue without pan-zoom
|
472
|
+
}
|
473
|
+
|
474
|
+
// Add highlighting for the current table
|
475
|
+
setTimeout(function() {
|
476
|
+
try {
|
477
|
+
const currentTableElement = container.querySelector(`[id*="${'<%= @table_name %>'.replace(/[^\w]/g, '_')}"]`);
|
478
|
+
if (currentTableElement) {
|
479
|
+
const rect = currentTableElement.querySelector('rect');
|
480
|
+
if (rect) {
|
481
|
+
// Highlight the current table
|
482
|
+
rect.setAttribute('fill', document.documentElement.getAttribute('data-bs-theme') === 'dark' ? '#2c3034' : '#e2f0ff');
|
483
|
+
rect.setAttribute('stroke', document.documentElement.getAttribute('data-bs-theme') === 'dark' ? '#6ea8fe' : '#0d6efd');
|
484
|
+
rect.setAttribute('stroke-width', '2');
|
485
|
+
}
|
486
|
+
}
|
487
|
+
} catch (e) {
|
488
|
+
console.error('Error highlighting current table:', e);
|
489
|
+
}
|
490
|
+
}, 100);
|
491
|
+
})
|
492
|
+
.catch(function(error) {
|
493
|
+
console.error('Error rendering mini ERD:', error);
|
494
|
+
showError(
|
495
|
+
'Error rendering diagram',
|
496
|
+
'There was an error rendering the relationships diagram.',
|
497
|
+
error.message || 'Unknown error'
|
498
|
+
);
|
499
|
+
});
|
500
|
+
} catch (renderError) {
|
501
|
+
console.error('Exception in mermaid.render call:', renderError);
|
502
|
+
showError(
|
503
|
+
'Rendering exception',
|
504
|
+
'Failed to render the diagram.',
|
505
|
+
renderError.message || 'Unknown error'
|
506
|
+
);
|
507
|
+
}
|
508
|
+
} catch (error) {
|
509
|
+
console.error('Exception in renderMiniERD function:', error);
|
510
|
+
showError(
|
511
|
+
'Exception generating diagram',
|
512
|
+
'There was an exception processing the relationships diagram.',
|
513
|
+
error.message || 'Unknown error'
|
514
|
+
);
|
515
|
+
}
|
516
|
+
}
|
517
|
+
</script>
|