fix: исправлена ошибка "createProgressModal is not defined"
- Добавлена функция createProgressModal в правильное место в app.js - Упрощен код удаления до одного варианта (без излишней сложности) - Функция определена до использования - Проверена работоспособность batch delete
This commit is contained in:
148
public/app.js
148
public/app.js
@@ -31,6 +31,73 @@ function updateSelectionCounter() {
|
||||
}
|
||||
}
|
||||
|
||||
// Функция создания модального окна с прогресс-баром
|
||||
function createProgressModal(message) {
|
||||
const modal = document.createElement('div');
|
||||
modal.style.cssText = `
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0,0,0,0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 10000;
|
||||
`;
|
||||
|
||||
const dialog = document.createElement('div');
|
||||
dialog.style.cssText = `
|
||||
background: white;
|
||||
padding: 30px;
|
||||
border-radius: 8px;
|
||||
min-width: 300px;
|
||||
text-align: center;
|
||||
`;
|
||||
|
||||
dialog.innerHTML = `
|
||||
<div style="font-size: 16px; margin-bottom: 20px;">${message}</div>
|
||||
<div style="width: 100%; height: 30px; background: #e0e0e0; border-radius: 15px; overflow: hidden;">
|
||||
<div class="progress-bar" style="width: 0%; height: 100%; background: linear-gradient(90deg, #4CAF50, #45a049); transition: width 0.3s;"></div>
|
||||
</div>
|
||||
<div style="margin-top: 10px; font-size: 14px; color: #666;">
|
||||
<span class="spinner" style="display: inline-block; animation: spin 1s linear infinite;">⏳</span>
|
||||
Пожалуйста, подождите...
|
||||
</div>
|
||||
<style>
|
||||
@keyframes spin {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
</style>
|
||||
`;
|
||||
|
||||
modal.appendChild(dialog);
|
||||
|
||||
// Анимация прогресс-бара (имитация)
|
||||
const progressBar = dialog.querySelector('.progress-bar');
|
||||
let progress = 0;
|
||||
const interval = setInterval(() => {
|
||||
progress += Math.random() * 15;
|
||||
if (progress > 90) progress = 90; // Останавливаемся на 90%
|
||||
progressBar.style.width = progress + '%';
|
||||
}, 200);
|
||||
|
||||
modal.stopProgress = () => {
|
||||
clearInterval(interval);
|
||||
progressBar.style.width = '100%';
|
||||
};
|
||||
|
||||
return modal;
|
||||
}
|
||||
|
||||
function escapeHtml(text) {
|
||||
const div = document.createElement('div');
|
||||
div.textContent = text;
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
// Логин
|
||||
document.getElementById('loginBtn').addEventListener('click', async () => {
|
||||
const user = document.getElementById('loginUser').value.trim();
|
||||
@@ -563,13 +630,7 @@ async function promptForForeignKeys(fkFields) {
|
||||
});
|
||||
}
|
||||
|
||||
function escapeHtml(text) {
|
||||
const div = document.createElement('div');
|
||||
div.textContent = text;
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
// ✅ УДАЛИТЬ (с реальным прогрессом для больших объемов)
|
||||
// ✅ УДАЛИТЬ (оптимизированное с batch delete)
|
||||
document.getElementById('btnDelete').addEventListener('click', async () => {
|
||||
if (!table || !currentSchema || !currentTable) return;
|
||||
|
||||
@@ -586,76 +647,15 @@ document.getElementById('btnDelete').addEventListener('click', async () => {
|
||||
|
||||
if (!confirm(confirmMsg)) return;
|
||||
|
||||
const rowsArray = Array.from(selectedRowsData.values());
|
||||
|
||||
// Для очень больших удалений - показываем прогресс
|
||||
const BATCH_SIZE = 1000; // Удаляем по 1000 строк за раз
|
||||
const batches = [];
|
||||
for (let i = 0; i < rowsArray.length; i += BATCH_SIZE) {
|
||||
batches.push(rowsArray.slice(i, i + BATCH_SIZE));
|
||||
}
|
||||
|
||||
if (batches.length > 1) {
|
||||
// Множество батчей - показываем реальный прогресс
|
||||
const modal = createProgressModal(`Удаление ${count} записей...`);
|
||||
document.body.appendChild(modal);
|
||||
|
||||
const progressBar = modal.querySelector('.progress-bar');
|
||||
const progressText = modal.querySelector('.spinner').parentElement;
|
||||
|
||||
let totalDeleted = 0;
|
||||
let totalErrors = 0;
|
||||
let allErrorMessages = [];
|
||||
|
||||
try {
|
||||
for (let i = 0; i < batches.length; i++) {
|
||||
const batch = batches[i];
|
||||
|
||||
progressText.innerHTML = `<span class="spinner" style="display: inline-block; animation: spin 1s linear infinite;">⏳</span> Обработка ${i + 1} из ${batches.length} батчей...`;
|
||||
|
||||
const result = await api('/api/table/delete-batch', 'POST', {
|
||||
schema: currentSchema,
|
||||
table: currentTable,
|
||||
rows: batch
|
||||
});
|
||||
|
||||
totalDeleted += result.deleted;
|
||||
totalErrors += result.errors;
|
||||
if (result.errorMessages) {
|
||||
allErrorMessages.push(...result.errorMessages);
|
||||
}
|
||||
|
||||
// Обновляем прогресс
|
||||
const progress = ((i + 1) / batches.length) * 100;
|
||||
progressBar.style.width = progress + '%';
|
||||
}
|
||||
|
||||
document.body.removeChild(modal);
|
||||
|
||||
selectedRowsData.clear();
|
||||
updateSelectionCounter();
|
||||
await table.replaceData();
|
||||
|
||||
if (totalErrors > 0) {
|
||||
const errorsToShow = allErrorMessages.slice(0, 10);
|
||||
const moreErrors = allErrorMessages.length > 10
|
||||
? `\n... и еще ${allErrorMessages.length - 10} ошибок`
|
||||
: '';
|
||||
alert(`Удалено строк: ${totalDeleted}\nОшибок: ${totalErrors}\n\nПервые ошибки:\n${errorsToShow.join('\n')}${moreErrors}`);
|
||||
} else {
|
||||
alert(`✓ Успешно удалено строк: ${totalDeleted}`);
|
||||
}
|
||||
} catch (e) {
|
||||
document.body.removeChild(modal);
|
||||
console.error(e);
|
||||
alert('Ошибка удаления: ' + e.message);
|
||||
}
|
||||
} else {
|
||||
// Один батч - используем простое модальное окно
|
||||
// Создаем модальное окно с прогресс-баром
|
||||
const modal = createProgressModal('Удаление записей...');
|
||||
document.body.appendChild(modal);
|
||||
|
||||
try {
|
||||
// Преобразуем Map в массив
|
||||
const rowsArray = Array.from(selectedRowsData.values());
|
||||
|
||||
// Используем batch delete для оптимизации
|
||||
const result = await api('/api/table/delete-batch', 'POST', {
|
||||
schema: currentSchema,
|
||||
table: currentTable,
|
||||
@@ -682,10 +682,8 @@ document.getElementById('btnDelete').addEventListener('click', async () => {
|
||||
console.error(e);
|
||||
alert('Ошибка удаления: ' + e.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// ========== ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ CSV ==========
|
||||
|
||||
function detectDelimiter(text) {
|
||||
|
||||
Reference in New Issue
Block a user