feat(admin): вкладки фильтра по статусу в списке пользователей

Задача 3 переопределена оператором: вместо окончательного удаления
пользователя (упёрлось в CHECK-constraint'ы participant/chat_messages,
требующие миграции схемы — решили отложить) добавлены вкладки
«Активные»/«Заблокированные»/«Все» перед полем поиска в админке —
список фильтруется по `is_blocked` на бэкенде (GET /admin/users?status=).
This commit is contained in:
2026-07-27 20:59:29 +03:00
parent 25ffd9e678
commit 09215da22a
5 changed files with 85 additions and 12 deletions

View File

@@ -13,7 +13,7 @@
import uuid
from pathlib import Path
from typing import Annotated
from typing import Annotated, Literal
import anyio
from fastapi import APIRouter, Depends, File, HTTPException, Query, UploadFile, status
@@ -174,12 +174,16 @@ async def send_conference_invitations(
async def list_users(
admin: Annotated[User, Depends(require_admin)],
session: Annotated[AsyncSession, Depends(get_session)],
status: Annotated[Literal["active", "blocked"] | None, Query()] = None,
q: Annotated[str | None, Query()] = None,
limit: Annotated[int, Query(gt=0, le=MAX_LIMIT)] = DEFAULT_LIMIT,
offset: Annotated[int, Query(ge=0)] = 0,
) -> AdminUserListOut:
"""Список всех пользователей инстанса с текстовым поиском по email/имени."""
rows, total = await AdminUserRepository(session).list_paginated(q=q, limit=limit, offset=offset)
"""Список пользователей инстанса — фильтр по статусу (`active`/`blocked`, без
параметра — все) и текстовый поиск по email/имени."""
rows, total = await AdminUserRepository(session).list_paginated(
status=status, q=q, limit=limit, offset=offset
)
media_root = _media_root()
items = [
_to_admin_user_out(user, team_name=team_name, media_root=media_root)