- ApiClient теперь обрабатывает 401 и 403 ошибки для обновления токена - Добавлен JWTRefreshMiddleware для проактивного обновления токенов за 5 минут до истечения - Добавлена настройка JWT_REFRESH_THRESHOLD_MINUTES (по умолчанию 5) - Исправлена проблема с периодическими 403 ошибками после истечения access token
6.8 KiB
6.8 KiB
Исправления списка чатов
Дата: 20 ноября 2025
Проблемы
- ❌ Код JavaScript отображался на странице
- ❌ Дублирование обработчиков событий фильтрации
- ❌ Ненужная секция "Закрепленные" (отдельная категория)
- ❌ Фильтр не работал
Решение
1. Убрана секция "Закрепленные"
Было:
<div class="feed-card chat-section mb-3" data-sec="pinned" id="pinnedSection" style="display:none;">
<div class="feed-hd">
<div class="feed-ava"><i class="bi-pin-angle-fill text-warning"></i></div>
<div class="feed-meta flex-grow-1">
<h6 class="mb-0 text-secondary">Закрепленные</h6>
</div>
</div>
<div id="sec-pinned" class="list-chats"></div>
</div>
Стало:
- Секция удалена полностью
- Закрепленные чаты остаются внутри своих категорий (глобальный, отделы, личные, группы и т.д.)
2. Исправлено дублирование JavaScript
Было:
// В одном месте
applyBtn?.addEventListener('click', applyTypeFilter);
resetBtn?.addEventListener('click', resetFilter);
</script>
// И второй раз ниже
if (chatTypeSelect) {
chatTypeSelect.addEventListener('change', applyTypeFilter);
}
if (applyBtn) {
applyBtn.addEventListener('click', applyTypeFilter); // ДУБЛЬ!
}
if (resetBtn) {
resetBtn.addEventListener('click', resetFilter); // ДУБЛЬ!
}
applyTypeFilter();
</script>
Стало:
applyBtn?.addEventListener('click', applyTypeFilter);
resetBtn?.addEventListener('click', resetFilter);
// Применяем фильтр при загрузке
applyTypeFilter();
</script>
{# Подключаем chat-list-enhanced.js #}
<script src="{% static 'js/chat-list-enhanced.js' %}"></script>
{% endblock %}
3. Убрана опция "Закрепленные" из фильтра
Было в _filters.html:
<option value="pinned">Закрепленные</option>
Стало:
- Опция удалена
- Фильтр работает с типами: все, глобальный, отделы, личные, группы, каналы, объявления
Как работает закрепление
Визуальное выделение
Закрепленные чаты остаются в своих категориях, но выделяются:
- 🎨 Желтый фон (
background: #fffbeb) - 📌 Желтая левая граница (
border-left: 4px solid var(--bs-warning)) - 🏷️ Бейдж с иконкой булавки в правом верхнем углу
Сортировка
chat-list-enhanced.js при загрузке и при закреплении:
function moveToPinnedSection(chatRow) {
const parent = chatRow.parentElement;
const firstUnpinned = Array.from(parent.children).find(row =>
!row.classList.contains('pinned')
);
if (firstUnpinned) {
parent.insertBefore(chatRow, firstUnpinned); // Вставляем перед первым незакрепленным
} else {
parent.appendChild(chatRow);
}
}
- Закрепленные чаты перемещаются в начало своей категории
- Незакрепленные остаются ниже
Пример структуры
📁 Личные
📌 Иван Иванов (закреплен) ← желтый фон, иконка булавки
📌 Мария Петрова (закреплена)
👤 Алексей Сидоров
👤 Ольга Николаева
📁 Группы
📌 Отдел разработки (закреплена)
👥 Проект X
👥 HR обсуждения
Контекстное меню
Правый клик на чате → меню:
- 📌 Закрепить / Открепить
- 🔔 Уведомления вкл/выкл
- 👁️ Скрыть
- ✅ Отметить прочитанным
API запрос:
fetch(`/communications/api/chat/${chatId}/pin/`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-CSRFToken': csrfToken
},
body: `pinned=${!isPinned}`
})
Проверка работы
1. Открыть страницу чатов
http://localhost:9000/communications/chats/
2. Проверить фильтр
- Выбрать "Личные" → должны показаться только личные чаты
- Выбрать "Группы" → только группы
- Выбрать "Все" → все категории видны
3. Проверить закрепление
- Правый клик на любом чате
- Выбрать "Закрепить"
- Чат должен:
- Получить желтый фон
- Переместиться в начало своей категории
- Показать бейдж с булавкой
4. Проверить открепление
- Правый клик на закрепленном чате
- Выбрать "Открепить"
- Чат должен:
- Вернуть обычный фон
- Переместиться вниз категории
- Убрать бейдж
Файлы изменены
-
✅
backend/templates/communications/chat_list.html- Убрана секция
#pinnedSection - Исправлено дублирование JavaScript
- Добавлен вызов
applyTypeFilter()при загрузке
- Убрана секция
-
✅
backend/templates/communications/_filters.html- Убрана опция
<option value="pinned">
- Убрана опция
-
⚙️
backend/static/js/chat-list-enhanced.js(без изменений)- Уже работает правильно с закреплением внутри категорий
-
⚙️
backend/static/css/components/chat-list-enhanced.css(без изменений)- Уже есть стили
.chat-row.pinnedи.chat-pinned-badge
- Уже есть стили
Итог
✅ Код JavaScript больше не отображается на странице
✅ Фильтр работает корректно
✅ Закрепленные чаты остаются в своих категориях
✅ Визуальное выделение закрепленных чатов (желтый фон + булавка)
✅ Контекстное меню для управления закреплением
✅ Нет дублирования обработчиков событий
Система готова к использованию! 🎉