-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.js
More file actions
126 lines (108 loc) · 5.29 KB
/
main.js
File metadata and controls
126 lines (108 loc) · 5.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
document.addEventListener('DOMContentLoaded', () => {
const generateBtn = document.getElementById('generate-btn');
const queryInput = document.getElementById('query-input');
const sqlOutput = document.getElementById('sql-output');
const explanationContainer = document.getElementById('explanation-container');
const safetyContainer = document.getElementById('safety-container');
const resultsHead = document.getElementById('results-head');
const resultsBody = document.getElementById('results-body');
const resultsCount = document.getElementById('results-count');
const executionTime = document.getElementById('execution-time');
generateBtn.addEventListener('click', async () => {
const query = queryInput.value.trim();
if (!query) return;
// Reset state
generateBtn.disabled = true;
document.getElementById('generate-btn-text').innerText = 'Generating...';
sqlOutput.innerText = '-- Generating SQL...';
explanationContainer.innerText = '';
safetyContainer.innerText = '';
resultsHead.innerHTML = '<tr><th class="py-3 px-6 text-xs font-bold text-slate-500 uppercase tracking-wider">Loading...</th></tr>';
resultsBody.innerHTML = '';
resultsCount.innerText = 'Loading...';
const startTime = performance.now();
try {
// 1. Generate SQL
const generateRes = await fetch('/api/generate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query })
});
if (!generateRes.ok) {
const err = await generateRes.json();
throw new Error(err.detail || 'Failed to generate SQL');
}
const data = await generateRes.json();
sqlOutput.innerText = data.sql;
explanationContainer.innerText = data.explanation;
safetyContainer.innerText = data.safety_report;
// 2. Execute SQL
const executeRes = await fetch('/api/execute', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ sql: data.sql })
});
if (!executeRes.ok) {
const err = await executeRes.json();
throw new Error(err.detail || 'Failed to execute SQL');
}
const resultData = await executeRes.json();
const results = resultData.results;
// 3. Render Results
if (results && results.length > 0) {
const columns = Object.keys(results[0]);
// Headers
resultsHead.innerHTML = `<tr class="bg-slate-50 border-b border-slate-200 sticky top-0">
${columns.map(col => `<th class="py-3 px-6 text-xs font-bold text-slate-500 uppercase tracking-wider">${col}</th>`).join('')}
</tr>`;
// Body
resultsBody.innerHTML = results.map(row => `
<tr class="hover:bg-slate-50 transition-colors">
${columns.map(col => `<td class="py-3 px-6 text-sm text-slate-900">${row[col] !== null ? row[col] : 'NULL'}</td>`).join('')}
</tr>
`).join('');
resultsCount.innerText = `Showing ${results.length} results`;
} else {
resultsHead.innerHTML = '<tr><th class="py-3 px-6 text-xs font-bold text-slate-500 uppercase tracking-wider">No results found</th></tr>';
resultsBody.innerHTML = '';
resultsCount.innerText = 'Showing 0 results';
}
} catch (error) {
console.error(error);
sqlOutput.innerText = `-- Error: ${error.message}`;
resultsHead.innerHTML = '<tr><th class="py-3 px-6 text-xs font-bold text-red-500 uppercase tracking-wider">Error executing query</th></tr>';
resultsCount.innerText = 'Error';
} finally {
generateBtn.disabled = false;
document.getElementById('generate-btn-text').innerText = 'Generate SQL';
const endTime = performance.now();
executionTime.innerText = ((endTime - startTime) / 1000).toFixed(2) + 's';
}
});
});
window.switchTab = function(tabName) {
const tabs = ['sql', 'explanation', 'safety'];
tabs.forEach(tab => {
// Handle content visibility
const container = document.getElementById(tab === 'sql' ? 'sql-container' : `${tab}-container`);
if (tab === tabName) {
container.classList.remove('hidden');
} else {
container.classList.add('hidden');
}
// Handle button styles
const btn = document.getElementById(`tab-${tab}`);
if (tab === tabName) {
btn.className = 'px-3 py-1 text-xs font-medium rounded-md bg-white text-slate-900 shadow-sm';
} else {
btn.className = 'px-3 py-1 text-xs font-medium rounded-md text-slate-500 hover:text-slate-900';
}
});
};
window.copyToClipboard = function(elementId) {
const text = document.getElementById(elementId).innerText;
navigator.clipboard.writeText(text).then(() => {
// Could add a toast notification here
console.log('Copied to clipboard');
});
};