fix: исправлена ошибка "createProgressModal is not defined"

- Добавлена функция createProgressModal в правильное место в app.js
- Упрощен код удаления до одного варианта (без излишней сложности)
- Функция определена до использования
- Проверена работоспособность batch delete
This commit is contained in:
2026-01-21 04:20:53 +03:00
parent 23c9c04a87
commit 92a5c0040c

View File

@@ -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,106 +647,43 @@ document.getElementById('btnDelete').addEventListener('click', async () => {
if (!confirm(confirmMsg)) return;
const rowsArray = Array.from(selectedRowsData.values());
// Создаем модальное окно с прогресс-баром
const modal = createProgressModal('Удаление записей...');
document.body.appendChild(modal);
// Для очень больших удалений - показываем прогресс
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));
}
try {
// Преобразуем Map в массив
const rowsArray = Array.from(selectedRowsData.values());
if (batches.length > 1) {
// Множество батчей - показываем реальный прогресс
const modal = createProgressModal(`Удаление ${count} записей...`);
document.body.appendChild(modal);
// Используем batch delete для оптимизации
const result = await api('/api/table/delete-batch', 'POST', {
schema: currentSchema,
table: currentTable,
rows: rowsArray
});
const progressBar = modal.querySelector('.progress-bar');
const progressText = modal.querySelector('.spinner').parentElement;
document.body.removeChild(modal);
let totalDeleted = 0;
let totalErrors = 0;
let allErrorMessages = [];
selectedRowsData.clear();
updateSelectionCounter();
await table.replaceData();
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 {
const result = await api('/api/table/delete-batch', 'POST', {
schema: currentSchema,
table: currentTable,
rows: rowsArray
});
document.body.removeChild(modal);
selectedRowsData.clear();
updateSelectionCounter();
await table.replaceData();
if (result.errors > 0) {
const errorsToShow = result.errorMessages.slice(0, 10);
const moreErrors = result.errorMessages.length > 10
? `\n... и еще ${result.errorMessages.length - 10} ошибок`
: '';
alert(`Удалено строк: ${result.deleted}\nОшибок: ${result.errors}\n\nПервые ошибки:\n${errorsToShow.join('\n')}${moreErrors}`);
} else {
alert(`✓ Удалено строк: ${result.deleted}`);
}
} catch (e) {
document.body.removeChild(modal);
console.error(e);
alert('Ошибка удаления: ' + e.message);
if (result.errors > 0) {
const errorsToShow = result.errorMessages.slice(0, 10);
const moreErrors = result.errorMessages.length > 10
? `\n... и еще ${result.errorMessages.length - 10} ошибок`
: '';
alert(`Удалено строк: ${result.deleted}\nОшибок: ${result.errors}\n\nПервые ошибки:\n${errorsToShow.join('\n')}${moreErrors}`);
} else {
alert(`✓ Удалено строк: ${result.deleted}`);
}
} catch (e) {
document.body.removeChild(modal);
console.error(e);
alert('Ошибка удаления: ' + e.message);
}
});
// ========== ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ CSV ==========
function detectDelimiter(text) {