diff --git a/backend/apps/github/graphql/queries/issue.py b/backend/apps/github/graphql/queries/issue.py index 2a1a53fb6b..606ebd204e 100644 --- a/backend/apps/github/graphql/queries/issue.py +++ b/backend/apps/github/graphql/queries/issue.py @@ -1,4 +1,4 @@ -"""OWASP issue GraphQL queries.""" +"""GraphQL queries for handling GitHub issues.""" import graphene @@ -8,18 +8,47 @@ class IssueQuery(BaseQuery): - """Issue queries.""" + """GraphQL query class for retrieving GitHub issues.""" recent_issues = graphene.List( IssueNode, - limit=graphene.Int(default_value=6), + limit=graphene.Int(default_value=15), + distinct=graphene.Boolean(default_value=False), login=graphene.String(required=False), ) - def resolve_recent_issues(root, info, limit, login=None): - """Resolve recent issues.""" - queryset = Issue.objects.select_related("author").order_by("-created_at") + def resolve_recent_issues(root, info, limit=15, distinct=False, login=None): + """Resolve recent issues with optional filtering. + + Args: + ---- + root: The root query object. + info: The GraphQL execution context. + limit (int): Maximum number of issues to return. + distinct (bool): Whether to return unique issues per author and repository. + login (str, optional): Filter issues by a specific author's login. + + Returns: + ------- + Queryset containing the filtered list of issues. + + """ + queryset = Issue.objects.select_related( + "author", + ).order_by( + "-created_at", + ) + if login: queryset = queryset.filter(author__login=login) + if distinct: + queryset = queryset.distinct( + "author_id", + "created_at", + ).order_by( + "-created_at", + "author_id", + ) + return queryset[:limit] diff --git a/backend/apps/github/graphql/queries/release.py b/backend/apps/github/graphql/queries/release.py index f79f5f6400..56cc85a26f 100644 --- a/backend/apps/github/graphql/queries/release.py +++ b/backend/apps/github/graphql/queries/release.py @@ -1,4 +1,4 @@ -"""OWASP release GraphQL queries.""" +"""GraphQL queries for handling OWASP releases.""" import graphene @@ -8,14 +8,41 @@ class ReleaseQuery(BaseQuery): - """Release queries.""" + """GraphQL query class for retrieving recent GitHub releases.""" - recent_releases = graphene.List(ReleaseNode, limit=graphene.Int(default_value=15)) + recent_releases = graphene.List( + ReleaseNode, + limit=graphene.Int(default_value=15), + distinct=graphene.Boolean(default_value=False), + ) - def resolve_recent_releases(root, info, limit): - """Resolve recent release.""" - return Release.objects.filter( + def resolve_recent_releases(root, info, limit=15, distinct=False): + """Resolve recent releases with optional distinct filtering. + + Args: + ---- + root: The root query object. + info: The GraphQL execution context. + limit (int): Maximum number of releases to return. + distinct (bool): Whether to return unique releases per author and repository. + + Returns: + ------- + Queryset containing the filtered list of releases. + + """ + query = Release.objects.filter( is_draft=False, is_pre_release=False, published_at__isnull=False, - ).order_by("-published_at")[:limit] + ).order_by("-published_at") + + if distinct: + query = query.distinct( + "author_id", + "published_at", + ).order_by( + "-published_at", + ) + + return query[:limit] diff --git a/frontend/src/api/queries/homeQueries.ts b/frontend/src/api/queries/homeQueries.ts index 0aa5765b96..2d276edbf6 100644 --- a/frontend/src/api/queries/homeQueries.ts +++ b/frontend/src/api/queries/homeQueries.ts @@ -1,7 +1,7 @@ import { gql } from '@apollo/client' export const GET_MAIN_PAGE_DATA = gql` - query GetMainPageData { + query GetMainPageData($distinct: Boolean) { recentProjects(limit: 5) { createdAt key @@ -32,7 +32,7 @@ export const GET_MAIN_PAGE_DATA = gql` projectName projectUrl } - recentIssues(limit: 5) { + recentIssues(limit: 5, distinct: $distinct) { commentsCount createdAt title @@ -43,7 +43,7 @@ export const GET_MAIN_PAGE_DATA = gql` name } } - recentReleases(limit: 5) { + recentReleases(limit: 5, distinct: $distinct) { author { avatarUrl login diff --git a/frontend/src/pages/Home.tsx b/frontend/src/pages/Home.tsx index c6cdad9b2a..6e4cbbb5ce 100644 --- a/frontend/src/pages/Home.tsx +++ b/frontend/src/pages/Home.tsx @@ -35,7 +35,10 @@ import { toaster } from 'components/ui/toaster' export default function Home() { const [isLoading, setIsLoading] = useState(true) const [data, setData] = useState(null) - const { data: graphQLData, error: graphQLRequestError } = useQuery(GET_MAIN_PAGE_DATA) + const { data: graphQLData, error: graphQLRequestError } = useQuery(GET_MAIN_PAGE_DATA, { + variables: { distinct: true }, + }) + const [geoLocData, setGeoLocData] = useState([]) const [modalOpenIndex, setModalOpenIndex] = useState(null)