-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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-states): Add ability to search for substatus #48289
Conversation
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## master #48289 +/- ##
==========================================
+ Coverage 80.88% 80.90% +0.01%
==========================================
Files 4770 4777 +7
Lines 201632 201877 +245
Branches 11557 11548 -9
==========================================
+ Hits 163096 163324 +228
- Misses 38280 38298 +18
+ Partials 256 255 -1
|
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.
A few small questions and stylistic nits - feel free to do with them what you will.
Someone more familiar with this part of the codebase should also approve this, but just taking what's here at face value, overall LGTM!
for status_key, status_value in STATUS_QUERY_CHOICES.items(): | ||
is_filter_translation[status_key] = ("status", status_value) | ||
|
||
for substatus_key, substatus_value in SUBSTATUS_UPDATE_CHOICES.items(): |
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.
I'm not familiar enough with this stuff to know: is there a reason one of these is query choices and one is update choices? Do they actually serve different purposes?
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.
I think I just ended up naming SUBSTATUS_UPDATE_CHOICES
based on what I was using it for at the time. They should serve the same purpose.
src/sentry/api/issue_search.py
Outdated
def convert_substatus_value( | ||
value: Iterable[Union[str, int]], | ||
projects: Sequence[Project], | ||
user: User, | ||
environments: Optional[Sequence[Environment]], | ||
) -> List[int]: |
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.
def convert_substatus_value( | |
value: Iterable[Union[str, int]], | |
projects: Sequence[Project], | |
user: User, | |
environments: Optional[Sequence[Environment]], | |
) -> List[int]: | |
def convert_substatus_value( | |
value: Iterable[str | int], | |
projects: Sequence[Project], | |
user: User, | |
environments: Sequence[Environment] | None, | |
) -> list[int]: |
Supposedly the new-fangled way is preferred, though it's making me wonder - do you need a =None
on environments
if you use | None
instead of Optional
? The docs don't say so (and I know in JS you wouldn't) but do you in Python?
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.
I think I agree with this answer - the Optional
typing + default argument is easier to read than X | None = None
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.
I personally like Optional
vs <type> | None
, but I've seen it done both ways throughout the codebase.
InvalidSearchQuery, match="The substatus filter is not supported for this organization" | ||
): | ||
self.make_query(search_filter_query="is:ongoing") | ||
|
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.
Is it legal to filter on incompatible status
and substatus
values, i.e. `search_filter_query="is:ongoing is:resolved"?
What about compatible combinations: search_filter_query="is:ongoing is:unresolved"
?
I wonder what will happen with: search_filter_query="is:ongoing is:forever"
?
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.
This ticket should address that
if search_filter.key.name == "substatus": | ||
if not features.has("organizations:issue-states", organization): | ||
raise InvalidSearchQuery( | ||
"The substatus filter is not supported for this organization" |
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.
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.
Either way is fine with me - @robinrendle do you have a preference here?
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.
I think it should be easy enough to change the predicate to:
if search_filter.key.name == "substatus" and features.has("organizations:issue-states", organization):
# do logic
and just let it fall through if the above is False.
) | ||
|
||
status = GROUP_SUBSTATUS_TO_STATUS_MAP.get( | ||
new_value[0] if isinstance(new_value, list) else new_value |
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.
Hmm, not sure if grabbing the first substatus
value here would be good UX. Should we raise an error instead or let the query go through?
Although, not sure if the is:
query syntax even allows list values so we might be ok here.
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.
new_value
is [0]
when searching for is:unresolved
. Not sure why..
Added error handling if the length is >1 though.
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.
Tbh I wonder if we should have indexed on project, substatus, ...
in retrospect. Each substatus only ever has one status, and it'd simplify this pr a bit
src/sentry/search/utils.py
Outdated
if value in STATUS_QUERY_CHOICES.values(): | ||
return int(value) | ||
def parse_status_value(status: Union[str, int]) -> int: | ||
if status in STATUS_QUERY_CHOICES.keys(): |
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.
Better off not using .keys
here, this changes this from an O(1)
operation to O(N)
Adds substatuses to the approved values for the
is:
search filter.WOR-2898