fix(chat): автоскролл задач только у низа, картинки с фикс. размером, упоминания по @ и 3+ буквам имени/фамилии

- TaskChat: atBottomRef-гвард (scrollHeight-scrollTop-clientHeight<80) — чужие
  сообщения больше не дёргают чат вниз, когда пользователь читает историю;
  свои сообщения и смена задачи скроллят как раньше
- ChatAttachments: img w-180 h-180 object-cover вместо max-* — высота строки
  не меняется при догрузке, measureElement виртуализатора не дёргает список
- упоминания: голый @ открывает список сразу; текстовый триггер от 3 букв;
  сервер ищет ILIKE по имени/отчеству/фамилии/email и отдаёт всех при пустом q;
  починен мёртвый fallback-резолв (Response без .json())
- groupByDate/flattenGroupedMessages обёрнуты в useMemo
This commit is contained in:
2026-09-17 22:00:10 +03:00
parent d0112657b8
commit 267af046a3
4 changed files with 60 additions and 21 deletions

View File

@@ -505,9 +505,9 @@ export function registerUserManagementRoutes(router: Router): void {
try {
const { q: query, limit = '10' } = req.query;
if (!query || typeof query !== 'string' || query.trim().length === 0) {
return res.status(400).json({ success: false, error: 'Поисковый запрос обязателен' });
}
// Пустой запрос допустим (голый '@' в чате): возвращаем первых пользователей
// организации и всех доступных ботов
const trimmedQuery = typeof query === 'string' ? query.trim() : '';
if (!req.organizationId || typeof req.organizationId !== 'number') {
return res.status(400).json({ success: false, error: 'Ошибка идентификации организации' });
@@ -515,8 +515,8 @@ export function registerUserManagementRoutes(router: Router): void {
const searchLimit = Math.min(parseInt(limit as string) || 10, 20);
const [users, allBots] = await Promise.all([
storage.searchUsers(query.trim(), req.organizationId, searchLimit),
storage.searchBots(query.trim(), req.organizationId, searchLimit)
storage.searchUsers(trimmedQuery, req.organizationId, searchLimit),
storage.searchBots(trimmedQuery, req.organizationId, searchLimit)
]);
const currentUser = req.user!;

View File

@@ -370,6 +370,8 @@ export class SocialStorage extends TasksStorage {
${users.middleName} ILIKE ${'%' + query + '%'}
OR
${users.lastName} ILIKE ${'%' + query + '%'}
OR
${users.email} ILIKE ${'%' + query + '%'}
)`
))
.limit(limit)