fix: исправлено выделение строк через header checkbox и их удаление

- Упрощен обработчик rowSelectionChanged (используется только параметр rows)
- Добавлена отладочная информация для диагностики проблем
- Исправлена логика синхронизации selectedRowsData
- Добавлен console.log для отслеживания процесса выделения
- Проверка работы getRowKey для корректной идентификации строк
This commit is contained in:
2026-01-21 04:35:23 +03:00
parent 2189805015
commit 722fe6b5ea

View File

@@ -174,13 +174,24 @@ let lastEditedRow = null;
function getRowKey(rowData) {
if (!currentMeta || !currentMeta.primaryKey || currentMeta.primaryKey.length === 0) {
// Если нет PK, используем все поля
return JSON.stringify(rowData);
const key = JSON.stringify(rowData);
console.log(' 🔑 getRowKey (no PK):', key.substring(0, 100));
return key;
}
const pkValues = currentMeta.primaryKey.map(pk => rowData[pk]).join('|');
const pkValues = currentMeta.primaryKey.map(pk => {
const value = rowData[pk];
if (value === undefined || value === null) {
console.warn(` ⚠️ PK field '${pk}' is undefined/null in rowData:`, rowData);
}
return value;
}).join('|');
console.log(' 🔑 getRowKey (PK):', pkValues, 'from fields:', currentMeta.primaryKey);
return pkValues;
}
async function selectTable(schema, tableName) {
currentSchema = schema;
currentTable = tableName;
@@ -271,40 +282,52 @@ async function selectTable(schema, tableName) {
};
},
// ✅ ИСПРАВЛЕНО: Обработка выделения строк
// ✅ ИСПРАВЛЕНО: Простая и правильная обработка выделения
rowSelectionChanged: function(data, rows) {
// Синхронизируем selectedRowsData с текущим состоянием ВСЕХ выделенных строк
// data - это массив данных ВСЕХ выбранных строк
console.log('🔔 rowSelectionChanged:', {
dataLength: data.length,
rowsLength: rows.length,
selectedRowsDataSizeBefore: selectedRowsData.size
});
// Сначала удаляем все строки с текущей страницы из selectedRowsData
const currentPageRows = this.getRows();
currentPageRows.forEach(row => {
// Обрабатываем только изменившиеся строки
rows.forEach(row => {
const rowData = row.getData();
const key = getRowKey(rowData);
selectedRowsData.delete(key);
});
const isSelected = row.isSelected();
// Теперь добавляем все выделенные строки обратно
data.forEach(rowData => {
const key = getRowKey(rowData);
console.log(` Row key: ${key}, isSelected: ${isSelected}`);
if (isSelected) {
selectedRowsData.set(key, rowData);
} else {
selectedRowsData.delete(key);
}
});
console.log(' ✅ selectedRowsData size after:', selectedRowsData.size);
updateSelectionCounter();
},
// После загрузки данных восстанавливаем выделение
dataLoaded: function(data) {
console.log('📄 dataLoaded, восстанавливаем выделение для', selectedRowsData.size, 'строк');
if (selectedRowsData.size > 0) {
const rows = this.getRows();
let restoredCount = 0;
rows.forEach(row => {
const rowData = row.getData();
const key = getRowKey(rowData);
if (selectedRowsData.has(key)) {
row.select();
restoredCount++;
}
});
console.log(' ✅ Восстановлено выделение для', restoredCount, 'строк на странице');
}
},
@@ -629,11 +652,42 @@ async function promptForForeignKeys(fkFields) {
// ✅ УДАЛИТЬ (оптимизированное с batch delete)
document.getElementById('btnDelete').addEventListener('click', async () => {
if (!table || !currentSchema || !currentTable) return;
if (!table || !currentSchema || !currentTable) {
alert('Сначала выберите таблицу');
return;
}
const count = selectedRowsData.size;
console.log('🗑️ Удаление:', {
selectedRowsDataSize: count,
selectedRowsDataKeys: Array.from(selectedRowsData.keys())
});
if (count === 0) {
// Дополнительная проверка - может быть строки выделены в Tabulator, но не в selectedRowsData?
const tabulatorSelected = table.getSelectedData();
console.log('Tabulator selected rows:', tabulatorSelected.length);
if (tabulatorSelected.length > 0) {
console.error('❌ Несоответствие: Tabulator имеет выделенные строки, но selectedRowsData пуст!');
console.log('Попытка синхронизации...');
// Синхронизируем
selectedRowsData.clear();
tabulatorSelected.forEach(rowData => {
const key = getRowKey(rowData);
selectedRowsData.set(key, rowData);
});
updateSelectionCounter();
if (selectedRowsData.size > 0) {
alert(`Обнаружено ${selectedRowsData.size} выделенных строк. Попробуйте удалить снова.`);
return;
}
}
alert('Выберите строки для удаления');
return;
}
@@ -652,6 +706,8 @@ document.getElementById('btnDelete').addEventListener('click', async () => {
// Преобразуем Map в массив
const rowsArray = Array.from(selectedRowsData.values());
console.log('Отправка на удаление:', rowsArray.length, 'строк');
// Используем batch delete для оптимизации
const result = await api('/api/table/delete-batch', 'POST', {
schema: currentSchema,
@@ -659,6 +715,8 @@ document.getElementById('btnDelete').addEventListener('click', async () => {
rows: rowsArray
});
console.log('Результат удаления:', result);
document.body.removeChild(modal);
selectedRowsData.clear();
@@ -676,11 +734,12 @@ document.getElementById('btnDelete').addEventListener('click', async () => {
}
} catch (e) {
document.body.removeChild(modal);
console.error(e);
console.error('Ошибка удаления:', e);
alert('Ошибка удаления: ' + e.message);
}
});
// ========== ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ CSV ==========
function detectDelimiter(text) {