Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,8 @@ class ProjectHealthMetricsFilter:
def level(self, value: str, prefix: str):
"""Filter by project level."""
return Q(project__level=ProjectLevel(value)) if value else Q()

@strawberry_django.filter_field
def is_active(self, *, value: bool, prefix: str):
"""Filter by active projects."""
return Q(project__is_active=value) if value else Q()
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""OWASP Project Health Metrics Ordering."""

from strawberry import auto
import strawberry
from strawberry_django import order_type

from apps.owasp.models.project_health_metrics import ProjectHealthMetrics
Expand All @@ -10,4 +10,9 @@
class ProjectHealthMetricsOrder:
"""Ordering for Project Health Metrics."""

score: auto
score: strawberry.auto
# We need to order by another field in case of equal scores
# to ensure unique metrics in pagination.
# because SQL returns random order if no order is specified.
# We didn't do this ordering in the model since we order already in the query.
project__name: strawberry.auto
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason for having __ in the name?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strawberry use these attributes in the order_by method. project_name is not an attribute of the metrics but it is an attribute of the project. And like we access nested attributes in django methods, strawberry does the same.

Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ def test_filter_fields(self):
filter_fields = {
field.name for field in ProjectHealthMetricsFilter.__strawberry_definition__.fields
}
expected_fields = {"score", "level"}
expected_fields = {"score", "level", "is_active"}
assert expected_fields.issubset(filter_fields)

def test_filtering(self):
"""Test filtering by project level and score."""
filter_instance = ProjectHealthMetricsFilter(level="flagship", score=50)
filter_instance = ProjectHealthMetricsFilter(level="flagship", score=50, is_active=True)
assert filter_instance.level == ProjectLevel.FLAGSHIP
assert filter_instance.score == 50
assert filter_instance.is_active is True
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,11 @@ def test_order_fields(self):
order_fields = {
field.name for field in ProjectHealthMetricsOrder.__strawberry_definition__.fields
}
expected_fields = {"score"}
expected_fields = {"score", "project__name"}
assert expected_fields == order_fields

def test_order_by(self):
"""Test ordering by score."""
order_instance = ProjectHealthMetricsOrder(
score="DESC",
)
order_instance = ProjectHealthMetricsOrder(score="DESC", project__name="ASC")
assert order_instance.score == "DESC"
assert order_instance.project__name == "ASC"
21 changes: 17 additions & 4 deletions frontend/src/app/projects/dashboard/metrics/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ const MetricsPage: FC = () => {
},
}

let currentFilters = {}
let currentFilters = {
isActive: true,
}
let currentOrdering = {
score: 'DESC',
}
Expand All @@ -62,6 +64,7 @@ const MetricsPage: FC = () => {
const currentFilterKeys = []
if (healthFilter) {
currentFilters = {
...currentFilters,
...healthFiltersMapping[healthFilter],
}
currentFilterKeys.push(healthFilter)
Expand Down Expand Up @@ -99,7 +102,12 @@ const MetricsPage: FC = () => {
variables: {
filters,
pagination: { offset: 0, limit: PAGINATION_LIMIT },
ordering,
ordering: [
ordering,
{
['project_Name']: 'ASC',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What naming convention was used here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is automatically converted by strawberry. Since the attribute is project__name, it is handled like other attributes. Just first underscore removed and capitalize the second name.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how it works though. Let's merge it as is and improve sorting capabilities later.

},
],
},
})

Expand Down Expand Up @@ -176,7 +184,7 @@ const MetricsPage: FC = () => {
} else {
newParams.delete('health')
newParams.delete('level')
newFilters = {}
newFilters = { isActive: true }
}
setFilters(newFilters)
setActiveFilters(
Expand Down Expand Up @@ -246,7 +254,12 @@ const MetricsPage: FC = () => {
variables: {
filters,
pagination: newPagination,
ordering,
ordering: [
ordering,
{
['project_Name']: 'ASC',
},
],
},
updateQuery: (prev, { fetchMoreResult }) => {
if (!fetchMoreResult) return prev
Expand Down