Team Ai
Apppublic

Jakvai/postgresql-pixie-dust

sourceHugging Faceupdated 11mo agoView on Hugging Face
0likes
script.js236 linesDownload Raw Back to root
1document.addEventListener('DOMContentLoaded', function() {2    // DOM Elements3    const queryInput = document.getElementById('query-input');4    const generateBtn = document.getElementById('generate-btn');5    const clearBtn = document.getElementById('clear-btn');6    const formatBtn = document.getElementById('format-btn');7    const resultsSection = document.getElementById('results-section');8    const tableHeaders = document.getElementById('table-headers');9    const tableBody = document.getElementById('table-body');10    const exportCsv = document.getElementById('export-csv');11    const exportJson = document.getElementById('export-json');12    const fileUpload = document.getElementById('sql-upload');13    // Database configuration from environment14    const dbConfig = {15        host: '127.0.0.1', // Will be replaced with process.env.DB_HOST in Node.js16        port: 5432,        // Will be replaced with process.env.DB_PORT17        database: 'queryviz', // Will be replaced with process.env.DB_DATABASE18        user: 'postgres',   // Will be replaced with process.env.DB_USERNAME19        password: '',       // Will be replaced with process.env.DB_PASSWORD20        max: 20,           // Will be replaced with process.env.DB_POOL_MAX_CONNECTIONS21        idleTimeoutMillis: 30000 // Will be replaced with process.env.DB_POOL_IDLE_TIMEOUT22    };23 24    // Sample data for demo purposes25    const sampleData = {26headers: ['id', 'name', 'email', 'created_at', 'status'],27        rows: [28            [1, 'John Doe', 'john@example.com', '2023-01-15', 'active'],29            [2, 'Jane Smith', 'jane@example.com', '2023-02-20', 'active'],30            [3, 'Bob Johnson', 'bob@example.com', '2023-03-10', 'inactive'],31            [4, 'Alice Brown', 'alice@example.com', '2023-04-05', 'active'],32            [5, 'Charlie Wilson', 'charlie@example.com', '2023-05-12', 'pending']33        ]34    };35    36    // Event Listeners37    generateBtn.addEventListener('click', generateReport);38    clearBtn.addEventListener('click', clearInput);39    formatBtn.addEventListener('click', formatQuery);40    exportCsv.addEventListener('click', exportToCsv);41    exportJson.addEventListener('click', exportToJson);42    fileUpload.addEventListener('change', handleFileUpload);43    44    // Functions45    function generateReport() {46        const query = queryInput.value.trim();47        48        if (!query) {49            showToast('Please enter or upload a SQL query', 'error');50            return;51        }52        53        // Show loading state54        generateBtn.disabled = true;55        generateBtn.innerHTML = '<i data-feather="loader" class="w-4 h-4 mr-2 animate-spin"></i> Processing...';56        feather.replace();57        58        // Simulate API call with timeout59        setTimeout(() => {60        // In a real app, this would connect to PostgreSQL using the dbConfig61        // Example connection using pg (Node.js PostgreSQL client):62        // const { Pool } = require('pg');63        // const pool = new Pool(dbConfig);64        // const { rows } = await pool.query(query);65displayResults(sampleData);66            67            // Reset button68            generateBtn.disabled = false;69            generateBtn.innerHTML = '<i data-feather="zap" class="w-4 h-4 mr-2"></i> Generate Report';70            feather.replace();71        }, 1500);72    }73    74    function displayResults(data) {75        // Clear previous results76        tableHeaders.innerHTML = '';77        tableBody.innerHTML = '';78        79        // Add headers80        data.headers.forEach(header => {81            const th = document.createElement('th');82            th.className = 'px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider';83            th.textContent = header;84            tableHeaders.appendChild(th);85        });86        87        // Add rows88        data.rows.forEach(row => {89            const tr = document.createElement('tr');90            row.forEach(cell => {91                const td = document.createElement('td');92                td.className = 'px-6 py-4 whitespace-nowrap text-sm text-gray-700 dark:text-gray-300';93                td.textContent = cell;94                tr.appendChild(td);95            });96            tableBody.appendChild(tr);97        });98        99        // Show results section100        resultsSection.classList.remove('hidden');101        102        // Render chart103        renderChart(data);104        105        // Scroll to results106        resultsSection.scrollIntoView({ behavior: 'smooth' });107    }108    109    function renderChart(data) {110        const ctx = document.getElementById('results-chart').getContext('2d');111        112        // Simple chart showing count by status (for demo)113        const statusCounts = {};114        const statusIndex = data.headers.indexOf('status');115        116        if (statusIndex !== -1) {117            data.rows.forEach(row => {118                const status = row[statusIndex];119                statusCounts[status] = (statusCounts[status] || 0) + 1;120            });121        }122        123        new Chart(ctx, {124            type: 'bar',125            data: {126                labels: Object.keys(statusCounts),127                datasets: [{128                    label: 'Records by Status',129                    data: Object.values(statusCounts),130                    backgroundColor: [131                        'rgba(59, 130, 246, 0.7)',132                        'rgba(16, 185, 129, 0.7)',133                        'rgba(245, 158, 11, 0.7)'134                    ],135                    borderColor: [136                        'rgba(59, 130, 246, 1)',137                        'rgba(16, 185, 129, 1)',138                        'rgba(245, 158, 11, 1)'139                    ],140                    borderWidth: 1141                }]142            },143            options: {144                responsive: true,145                maintainAspectRatio: false,146                scales: {147                    y: {148                        beginAtZero: true,149                        ticks: {150                            color: '#6b7280'151                        },152                        grid: {153                            color: 'rgba(209, 213, 219, 0.3)'154                        }155                    },156                    x: {157                        ticks: {158                            color: '#6b7280'159                        },160                        grid: {161                            color: 'rgba(209, 213, 219, 0.3)'162                        }163                    }164                },165                plugins: {166                    legend: {167                        labels: {168                            color: '#6b7280'169                        }170                    }171                }172            }173        });174    }175    176    function clearInput() {177        queryInput.value = '';178        fileUpload.value = '';179    }180    181    function formatQuery() {182        // In a real app, you would use a proper SQL formatter library183        const query = queryInput.value.trim();184        if (query) {185            // Simple formatting for demo186            const formatted = query187                .replace(/SELECT/gi, '\nSELECT')188                .replace(/FROM/gi, '\nFROM')189                .replace(/WHERE/gi, '\nWHERE')190                .replace(/GROUP BY/gi, '\nGROUP BY')191                .replace(/ORDER BY/gi, '\nORDER BY')192                .replace(/LIMIT/gi, '\nLIMIT');193            194            queryInput.value = formatted.trim();195            showToast('Query formatted', 'success');196        }197    }198    199    function handleFileUpload(event) {200        const file = event.target.files[0];201        if (!file) return;202        203        const reader = new FileReader();204        reader.onload = function(e) {205            queryInput.value = e.target.result;206            showToast('File loaded successfully', 'success');207        };208        reader.readAsText(file);209    }210    211    function exportToCsv() {212        // In a real app, implement CSV export213        showToast('CSV export would be implemented here', 'info');214    }215    216    function exportToJson() {217        // In a real app, implement JSON export218        showToast('JSON export would be implemented here', 'info');219    }220    221    function showToast(message, type = 'info') {222        const toast = document.createElement('div');223        toast.className = `fixed bottom-4 right-4 px-4 py-2 rounded-md shadow-lg text-white ${224            type === 'error' ? 'bg-red-500' : 225            type === 'success' ? 'bg-green-500' : 226            'bg-blue-500'227        }`;228        toast.textContent = message;229        document.body.appendChild(toast);230        231        setTimeout(() => {232            toast.classList.add('opacity-0', 'transition-opacity', 'duration-300');233            setTimeout(() => toast.remove(), 300);234        }, 3000);235    }236});