diff --git a/public/app.js b/public/app.js
index 6e53baf..f129963 100644
--- a/public/app.js
+++ b/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 = `
+
${message}
+
+
+ ⏳
+ Пожалуйста, подождите...
+
+
+ `;
+
+ 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 BATCH_SIZE = 1000; // Удаляем по 1000 строк за раз
- const batches = [];
- for (let i = 0; i < rowsArray.length; i += BATCH_SIZE) {
- batches.push(rowsArray.slice(i, i + BATCH_SIZE));
- }
+ // Создаем модальное окно с прогресс-баром
+ const modal = createProgressModal('Удаление записей...');
+ document.body.appendChild(modal);
- if (batches.length > 1) {
- // Множество батчей - показываем реальный прогресс
- const modal = createProgressModal(`Удаление ${count} записей...`);
- document.body.appendChild(modal);
+ try {
+ // Преобразуем Map в массив
+ const rowsArray = Array.from(selectedRowsData.values());
- const progressBar = modal.querySelector('.progress-bar');
- const progressText = modal.querySelector('.spinner').parentElement;
+ // Используем batch delete для оптимизации
+ const result = await api('/api/table/delete-batch', 'POST', {
+ schema: currentSchema,
+ table: currentTable,
+ rows: rowsArray
+ });
- let totalDeleted = 0;
- let totalErrors = 0;
- let allErrorMessages = [];
-
- try {
- for (let i = 0; i < batches.length; i++) {
- const batch = batches[i];
-
- progressText.innerHTML = `⏳ Обработка ${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);
+ 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);
}
});
-
// ========== ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ CSV ==========
function detectDelimiter(text) {
@@ -849,4 +847,4 @@ document.getElementById('btnExportCSV').addEventListener('click', async () => {
console.error('Ошибка экспорта:', err);
alert('Ошибка экспорта: ' + err.message);
}
-});
\ No newline at end of file
+});