diff --git a/src/backend/app/db/models.py b/src/backend/app/db/models.py index 212d475ee..24c990dba 100644 --- a/src/backend/app/db/models.py +++ b/src/backend/app/db/models.py @@ -1163,15 +1163,15 @@ async def one(cls, db: Connection, project_id: int, minimal: bool = False) -> Se async def all( cls, db: Connection, - skip: int = 0, - limit: int = 100, + skip: Optional[int] = None, + limit: Optional[int] = None, user_id: Optional[int] = None, hashtags: Optional[list[str]] = None, search: Optional[str] = None, ) -> Optional[list[Self]]: """Fetch all projects with optional filters for user, hashtags, and search.""" filters = [] - params = {"offset": skip, "limit": limit} + params = {"offset": skip, "limit": limit} if skip and limit else {} # Filter by user_id (project author) if user_id: @@ -1185,7 +1185,7 @@ async def all( # Filter by search term (project name using ILIKE for case-insensitive match) if search: - filters.append("slug ILIKE %(search)s") + filters.append("p.slug ILIKE %(search)s") params["search"] = f"%{search}%" # Base query with optional filtering @@ -1210,9 +1210,15 @@ async def all( p.id, project_org.id ORDER BY p.created_at DESC + """ + sql += ( + """ OFFSET %(offset)s LIMIT %(limit)s; """ + if skip and limit + else ";" + ) async with db.cursor(row_factory=class_row(cls)) as cur: await cur.execute(sql, params) diff --git a/src/backend/app/projects/project_crud.py b/src/backend/app/projects/project_crud.py index cc24d6fdc..71d5e95db 100644 --- a/src/backend/app/projects/project_crud.py +++ b/src/backend/app/projects/project_crud.py @@ -853,8 +853,8 @@ def generate_project_basemap( async def get_pagination(page: int, count: int, results_per_page: int, total: int): """Pagination result for splash page.""" - total_pages = (count + results_per_page - 1) // results_per_page - has_next = (page * results_per_page) < count # noqa: N806 + total_pages = (total + results_per_page - 1) // results_per_page + has_next = (page * results_per_page) < total # noqa: N806 has_prev = page > 1 # noqa: N806 pagination = project_schemas.PaginationInfo( @@ -883,26 +883,19 @@ async def get_paginated_projects( if hashtags: hashtags = hashtags.split(",") - # Calculate pagination offsets - skip = (page - 1) * results_per_page - limit = results_per_page - # Get subset of projects projects = await DbProject.all( - db, skip=skip, limit=limit, user_id=user_id, hashtags=hashtags, search=search + db, user_id=user_id, hashtags=hashtags, search=search ) - - # Count total number of projects for pagination - async with db.cursor() as cur: - await cur.execute("SELECT COUNT(*) FROM projects") - total_project_count = await cur.fetchone() - total_project_count = total_project_count[0] + start_index = (page - 1) * results_per_page + end_index = start_index + results_per_page + paginated_projects = projects[start_index:end_index] pagination = await get_pagination( - page, len(projects), results_per_page, total_project_count + page, len(paginated_projects), results_per_page, len(projects) ) - return {"results": projects, "pagination": pagination} + return {"results": paginated_projects, "pagination": pagination} async def get_project_users_plus_contributions(db: Connection, project_id: int): diff --git a/src/backend/app/projects/project_routes.py b/src/backend/app/projects/project_routes.py index 1c27420ae..3ade2b7b4 100644 --- a/src/backend/app/projects/project_routes.py +++ b/src/backend/app/projects/project_routes.py @@ -144,10 +144,11 @@ async def read_project_summaries( results_per_page: int = Query(13, le=100), user_id: Optional[int] = None, hashtags: Optional[str] = None, + search: Optional[str] = None, ): """Get a paginated summary of projects.""" return await project_crud.get_paginated_projects( - db, page, results_per_page, user_id, hashtags + db, page, results_per_page, user_id, hashtags, search )