cambios para produccion
This commit is contained in:
@@ -3,7 +3,7 @@ import { AlertCircle, Clock, Database, FileX, Loader2, CheckCircle2, Hash, Copy,
|
||||
|
||||
const MAX_DISPLAY_ROWS = 1000;
|
||||
|
||||
export default function ResultTable({ result, loading, pollingProgress }) {
|
||||
export default function ResultTable({ result, loading, pollingProgress, onClear }) {
|
||||
const [copied, setCopied] = useState(false);
|
||||
|
||||
// Normalize data
|
||||
@@ -40,36 +40,19 @@ export default function ResultTable({ result, loading, pollingProgress }) {
|
||||
return [header, ...csvRows].join('\n');
|
||||
};
|
||||
|
||||
// Download as CSV
|
||||
const handleDownloadCSV = (cols, dataRows) => {
|
||||
const csv = generateCSV(cols, dataRows);
|
||||
const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
|
||||
// Download file
|
||||
const handleDownload = (content, filename, type = 'text/csv') => {
|
||||
const blob = new Blob([content], { type: `${type};charset=utf-8;` });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
link.setAttribute('href', url);
|
||||
link.setAttribute('download', `query_result_${Date.now()}.csv`);
|
||||
link.setAttribute('download', filename);
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
URL.revokeObjectURL(url);
|
||||
};
|
||||
|
||||
// Auto-download if too many rows
|
||||
React.useEffect(() => {
|
||||
if (rows.length > MAX_DISPLAY_ROWS) {
|
||||
handleDownloadCSV(columns, rows);
|
||||
}
|
||||
}, [result]);
|
||||
|
||||
// Copy to clipboard
|
||||
const handleCopy = (cols, dataRows) => {
|
||||
const csv = generateCSV(cols, dataRows);
|
||||
navigator.clipboard.writeText(csv).then(() => {
|
||||
setCopied(true);
|
||||
setTimeout(() => setCopied(false), 2000);
|
||||
});
|
||||
};
|
||||
|
||||
// Loading state
|
||||
if (loading) {
|
||||
return (
|
||||
@@ -246,7 +229,7 @@ export default function ResultTable({ result, loading, pollingProgress }) {
|
||||
Para mantener el rendimiento del navegador, los resultados que superan las {MAX_DISPLAY_ROWS} filas no se muestran en pantalla y se descargan automáticamente como CSV.
|
||||
</p>
|
||||
<button
|
||||
onClick={() => handleDownloadCSV(columns, rows)}
|
||||
onClick={() => handleDownload(generateCSV(columns, rows), `query_result_${Date.now()}.csv`)}
|
||||
className="flex items-center gap-2 px-6 py-3 rounded-lg font-medium transition-all hover:scale-105"
|
||||
style={{
|
||||
background: 'var(--accent)',
|
||||
@@ -268,7 +251,48 @@ export default function ResultTable({ result, loading, pollingProgress }) {
|
||||
);
|
||||
}
|
||||
|
||||
// Data table display - DARK THEME
|
||||
// Final safety check for file content
|
||||
const isFileContent = rows.length === 1 && columns.length === 1 && (
|
||||
columns[0]?.toUpperCase() === 'CONTENT' ||
|
||||
columns[0]?.toUpperCase() === 'TEXT' ||
|
||||
columns[0]?.toUpperCase() === 'FILE' ||
|
||||
(result?.command_id && String(result.command_id).startsWith('FILE-'))
|
||||
);
|
||||
|
||||
if (isFileContent) {
|
||||
return (
|
||||
<div className="result-container" style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: '3rem' }}>
|
||||
<div style={{ backgroundColor: 'rgba(16, 185, 129, 0.1)', width: '80px', height: '80px', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', marginBottom: '1.5rem', border: '2px solid rgba(16, 185, 129, 0.3)' }}>
|
||||
<CheckCircle2 size={40} style={{ color: 'var(--success)' }} />
|
||||
</div>
|
||||
<h2 style={{ color: 'var(--text-primary)', fontSize: '1.5rem', fontWeight: 600, marginBottom: '1rem' }}>¡Archivo procesado con éxito!</h2>
|
||||
<p style={{ color: 'var(--text-secondary)', textAlign: 'center', marginBottom: '2rem', maxWidth: '450px' }}>
|
||||
El contenido del archivo <strong>#{result.command_id}</strong> ha sido recibido y la descarga debería haber iniciado automáticamente.
|
||||
</p>
|
||||
<div style={{ display: 'flex', gap: '1rem' }}>
|
||||
<button
|
||||
onClick={() => {
|
||||
const rawText = Array.isArray(rows[0]) ? rows[0][0] : rows[0][columns[0]];
|
||||
handleDownload(rawText, `file_${result.command_id}.txt`, 'text/plain');
|
||||
}}
|
||||
className="px-6 py-2 rounded-lg font-medium transition-all"
|
||||
style={{ background: 'var(--accent)', color: 'white', border: 'none', cursor: 'pointer' }}
|
||||
>
|
||||
<div className="flex items-center gap-2 font-bold"><Download size={18} /> Descargar .txt de nuevo</div>
|
||||
</button>
|
||||
<button
|
||||
onClick={onClear}
|
||||
className="px-6 py-2 rounded-lg font-medium transition-all"
|
||||
style={{ background: 'var(--border)', color: 'var(--text-primary)', border: 'none', cursor: 'pointer' }}
|
||||
>
|
||||
Nueva consulta
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Data table display - STABLE standard view
|
||||
return (
|
||||
<div className="result-container">
|
||||
{/* Stats Header */}
|
||||
@@ -293,9 +317,14 @@ export default function ResultTable({ result, loading, pollingProgress }) {
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
{/* Copy Button */}
|
||||
<button
|
||||
onClick={() => handleCopy(columns, rows)}
|
||||
onClick={() => {
|
||||
const csv = generateCSV(columns, rows);
|
||||
navigator.clipboard.writeText(csv).then(() => {
|
||||
setCopied(true);
|
||||
setTimeout(() => setCopied(false), 2000);
|
||||
});
|
||||
}}
|
||||
className="flex items-center gap-1 px-3 py-1.5 text-xs rounded transition-colors"
|
||||
style={{
|
||||
background: copied ? 'var(--success)' : 'var(--border)',
|
||||
@@ -303,34 +332,21 @@ export default function ResultTable({ result, loading, pollingProgress }) {
|
||||
border: 'none',
|
||||
cursor: 'pointer'
|
||||
}}
|
||||
title="Copiar al portapapeles"
|
||||
>
|
||||
{copied ? <Check size={14} /> : <Copy size={14} />}
|
||||
{copied ? 'Copiado!' : 'Copiar'}
|
||||
</button>
|
||||
{/* Download CSV Button */}
|
||||
<button
|
||||
onClick={() => handleDownloadCSV(columns, rows)}
|
||||
onClick={() => handleDownload(generateCSV(columns, rows), `query_result_${Date.now()}.csv`)}
|
||||
className="flex items-center gap-1 px-3 py-1.5 text-xs rounded transition-colors"
|
||||
style={{
|
||||
background: 'var(--accent)',
|
||||
color: 'white',
|
||||
border: 'none',
|
||||
cursor: 'pointer'
|
||||
}}
|
||||
title="Descargar CSV"
|
||||
style={{ background: 'var(--accent)', color: 'white', border: 'none', cursor: 'pointer' }}
|
||||
>
|
||||
<Download size={14} />
|
||||
CSV
|
||||
<Download size={14} /> CSV
|
||||
</button>
|
||||
<span className="flex items-center gap-1 ml-2">
|
||||
<CheckCircle2 size={14} style={{ color: 'var(--success)' }} />
|
||||
<span className="text-xs" style={{ color: 'var(--success)' }}>Completado</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Data Table */}
|
||||
{/* Standard Table View */}
|
||||
<div className="table-wrapper">
|
||||
<table>
|
||||
<thead>
|
||||
@@ -346,12 +362,7 @@ export default function ResultTable({ result, loading, pollingProgress }) {
|
||||
<tr key={rIdx}>
|
||||
<td style={{ textAlign: 'center', color: 'var(--text-muted)', fontSize: '0.75rem' }}>{rIdx + 1}</td>
|
||||
{columns.map((col, cIdx) => {
|
||||
let val;
|
||||
if (Array.isArray(row)) {
|
||||
val = row[cIdx];
|
||||
} else {
|
||||
val = row[col];
|
||||
}
|
||||
let val = Array.isArray(row) ? row[cIdx] : row[col];
|
||||
return (
|
||||
<td key={cIdx}>
|
||||
{val === null ? (
|
||||
@@ -359,7 +370,7 @@ export default function ResultTable({ result, loading, pollingProgress }) {
|
||||
) : typeof val === 'object' ? (
|
||||
<span style={{ color: 'var(--text-accent)' }}>{JSON.stringify(val)}</span>
|
||||
) : (
|
||||
String(val)
|
||||
String(val).length > 200 ? String(val).substring(0, 200) + '...' : String(val)
|
||||
)}
|
||||
</td>
|
||||
);
|
||||
@@ -372,3 +383,4 @@ export default function ResultTable({ result, loading, pollingProgress }) {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user