Сохранение и восстановление состояния таблицы

- Сохранение последней открытой таблицы в localStorage
- Сохранение фильтров и страницы при изменении
- Восстановление таблицы, фильтров и страницы при входе
- Сброс настроек теперь включает фильтры и последнюю таблицу

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-24 08:38:06 +03:00
parent f3be92d1f9
commit 647ab96d1a

View File

@@ -265,8 +265,10 @@ function logout() {
// Сбросить все настройки
function resetSettings() {
if (confirm('Сбросить все сохранённые настройки столбцов?')) {
if (confirm('Сбросить все сохранённые настройки (столбцы, фильтры, последняя таблица)?')) {
localStorage.removeItem(STORAGE_KEYS.columns);
localStorage.removeItem(STORAGE_KEYS.tableState);
localStorage.removeItem(STORAGE_KEYS.lastTable);
alert('Настройки сброшены. Перезагрузите страницу.');
location.reload();
}
@@ -366,6 +368,17 @@ async function loadTree() {
treeEl.appendChild(tableEl);
});
});
// ✅ Восстанавливаем последнюю открытую таблицу
const lastTable = loadLastTable();
if (lastTable) {
console.log('📂 Восстанавливаем последнюю таблицу:', lastTable.schema, '.', lastTable.table);
// Проверяем, существует ли таблица в дереве
const schemaExists = tree.find(s => s.name === lastTable.schema);
if (schemaExists && schemaExists.tables.includes(lastTable.table)) {
selectTable(lastTable.schema, lastTable.table, true);
}
}
} catch (e) {
console.error('loadTree ошибка:', e);
treeEl.innerHTML = 'Ошибка загрузки: ' + e.message;
@@ -560,15 +573,23 @@ function showColumnManager() {
// selectTable
async function selectTable(schema, tableName, restoreState = false) {
console.log('🔄 SELECTTABLE ВЫЗВАН:', schema, '.', tableName);
console.log('🔄 SELECTTABLE ВЫЗВАН:', schema, '.', tableName, restoreState ? '(с восстановлением)' : '');
currentSchema = schema;
currentTable = tableName;
selectedRowsDataGlobal.clear();
updateSelectionCounter();
// Сохраняем последнюю открытую таблицу
saveLastTable();
// Сохраняем последнюю открытую таблицу (только если не восстанавливаем)
if (!restoreState) {
saveLastTable();
}
// ✅ Загружаем сохранённое состояние, если нужно восстановить
const savedState = restoreState ? loadTableState() : null;
if (savedState) {
console.log('📂 Сохранённое состояние:', savedState);
}
if (enterHandler) {
document.removeEventListener('keydown', enterHandler);
@@ -928,15 +949,19 @@ async function selectTable(schema, tableName, restoreState = false) {
// Добавьте после создания таблицы, перед подключением событий:
// ✅ Флаги для восстановления состояния
let stateRestored = false;
let filtersApplied = false;
table.on("tableBuilt", function() {
console.log('🏗️ Таблица построена, фиксируем ширину чекбоксов');
// Находим столбец с чекбоксами
const checkboxColumn = table.getColumns().find(col => {
const def = col.getDefinition();
return def.formatter === 'rowSelection';
});
if (checkboxColumn) {
// Принудительно устанавливаем ширину для столбца
const element = checkboxColumn.getElement();
@@ -948,7 +973,7 @@ async function selectTable(schema, tableName, restoreState = false) {
element.style.padding = '0';
element.style.boxSizing = 'border-box';
}
// ✅ Также устанавливаем ширину для ячейки заголовка
setTimeout(() => {
const headerCell = element?.querySelector('.tabulator-cell');
@@ -959,7 +984,7 @@ async function selectTable(schema, tableName, restoreState = false) {
headerCell.style.padding = '4px';
headerCell.style.boxSizing = 'border-box';
}
// ✅ Устанавливаем ширину для всех ячеек данных в этом столбце
const dataCells = document.querySelectorAll('.tabulator-row .tabulator-cell:first-child');
dataCells.forEach(cell => {
@@ -970,9 +995,21 @@ async function selectTable(schema, tableName, restoreState = false) {
cell.style.boxSizing = 'border-box';
});
}, 50);
console.log('✅ Ширина столбца чекбоксов зафиксирована');
}
// ✅ Применяем сохранённые фильтры после построения таблицы
if (savedState && savedState.filters && savedState.filters.length > 0 && !filtersApplied) {
console.log('📂 Применяем сохранённые фильтры:', savedState.filters);
filtersApplied = true;
savedState.filters.forEach(filter => {
if (filter.field && filter.value) {
table.setHeaderFilterValue(filter.field, filter.value);
}
});
}
});
@@ -1084,6 +1121,21 @@ async function selectTable(schema, tableName, restoreState = false) {
}
});
}
// ✅ Восстанавливаем страницу после загрузки данных
if (savedState && savedState.page && savedState.page > 1 && !stateRestored) {
stateRestored = true;
const maxPage = table.getPageMax ? table.getPageMax() : 1;
const targetPage = Math.min(savedState.page, maxPage);
if (targetPage > 1) {
console.log('📂 Переход на сохранённую страницу:', targetPage);
// Используем setTimeout чтобы избежать конфликтов с текущей загрузкой
setTimeout(() => {
table.setPage(targetPage);
}, 100);
}
}
});
// Не окрашиваем при начале редактирования - только при реальном изменении
@@ -1137,6 +1189,15 @@ async function selectTable(schema, tableName, restoreState = false) {
});
await Promise.all(savePromises);
}
// ✅ Сохраняем состояние таблицы при смене страницы
saveTableState();
});
// ✅ Сохраняем состояние при изменении фильтров
table.on("dataFiltered", function(filters, rows) {
console.log('🔍 Фильтры изменены:', filters);
saveTableState();
});
enterHandler = async function(e) {