-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(issue-views): Update GET endpoint to validate view's projects #84338
Changes from 5 commits
7439d11
a43050a
e46dc05
40973ff
181c062
17624ab
6a5d705
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,7 +18,7 @@ | |
GroupSearchViewValidator, | ||
GroupSearchViewValidatorResponse, | ||
) | ||
from sentry.models.groupsearchview import GroupSearchView | ||
from sentry.models.groupsearchview import DEFAULT_TIME_FILTER, GroupSearchView | ||
from sentry.models.organization import Organization | ||
from sentry.models.project import Project | ||
from sentry.models.savedsearch import SortOptions | ||
|
@@ -31,6 +31,9 @@ | |
"query": "is:unresolved issue.priority:[high, medium]", | ||
"querySort": SortOptions.DATE.value, | ||
"position": 0, | ||
"isAllProjects": False, | ||
"environments": [], | ||
"timeFilters": DEFAULT_TIME_FILTER, | ||
"dateCreated": None, | ||
"dateUpdated": None, | ||
} | ||
|
@@ -65,23 +68,53 @@ def get(self, request: Request, organization: Organization) -> Response: | |
): | ||
return Response(status=status.HTTP_404_NOT_FOUND) | ||
|
||
has_global_views = features.has("organizations:global-views", organization) | ||
|
||
query = GroupSearchView.objects.filter(organization=organization, user_id=request.user.id) | ||
|
||
# Return only the prioritized view if user has no custom views yet | ||
# Return only the default view(s) if user has no custom views yet | ||
if not query.exists(): | ||
return self.paginate( | ||
request=request, | ||
paginator=SequencePaginator( | ||
[(idx, view) for idx, view in enumerate(DEFAULT_VIEWS)] | ||
[ | ||
( | ||
idx, | ||
{ | ||
**view, | ||
"projects": ( | ||
[] | ||
if has_global_views | ||
else [pick_default_project(organization, request.user)] | ||
), | ||
}, | ||
) | ||
for idx, view in enumerate(DEFAULT_VIEWS) | ||
] | ||
), | ||
on_results=lambda results: serialize(results, request.user), | ||
) | ||
|
||
default_project = None | ||
if not has_global_views: | ||
default_project = pick_default_project(organization, request.user) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Technically this query might not be necessary if all the views have a single project, so we can make this even better if we avoid it in that case There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is handled by Django's lazy loading of query sets - so if default project is never accessed in the for loop after this, the DB query isn't actually made. |
||
if default_project is None: | ||
return Response( | ||
status=status.HTTP_400_BAD_REQUEST, | ||
data={"detail": "You do not have access to any projects."}, | ||
) | ||
|
||
return self.paginate( | ||
request=request, | ||
queryset=query, | ||
order_by="position", | ||
on_results=lambda x: serialize(x, request.user, serializer=GroupSearchViewSerializer()), | ||
on_results=lambda x: serialize( | ||
x, | ||
request.user, | ||
serializer=GroupSearchViewSerializer( | ||
has_global_views=has_global_views, default_project=default_project | ||
), | ||
), | ||
) | ||
|
||
def put(self, request: Request, organization: Organization) -> Response: | ||
|
@@ -90,7 +123,6 @@ def put(self, request: Request, organization: Organization) -> Response: | |
will delete any views that are not included in the request, add views if | ||
they are new, and update existing views if they are included in the request. | ||
This endpoint is explcititly designed to be used by our frontend. | ||
|
||
""" | ||
if not features.has( | ||
"organizations:issue-stream-custom-views", organization, actor=request.user | ||
|
@@ -175,8 +207,6 @@ def pick_default_project(org: Organization, user: User | AnonymousUser) -> int: | |
.values_list("id", flat=True) | ||
.first() | ||
) | ||
if default_user_project is None: | ||
raise ValidationError("You do not have access to any projects") | ||
return default_user_project | ||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this make a query for each view? This would be slow for many views and would be better if we could prefetch them in the initial query since we know we'll need it anyway
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added! (organization_group_search_views, line 75)