-
-
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-views): add query counts back to tabs #82990
base: master
Are you sure you want to change the base?
Changes from 5 commits
26d2cb9
5c19909
fcf22f7
fe8ec7e
f6dc071
5953f0c
c87ba48
2d5726d
5a837ad
9e04918
6f26b33
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 |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import styled from '@emotion/styled'; | ||
import {motion} from 'framer-motion'; | ||
|
||
import type {PageFilters} from 'sentry/types/core'; | ||
import {getUtcDateString} from 'sentry/utils/dates'; | ||
import theme from 'sentry/utils/theme'; | ||
import useOrganization from 'sentry/utils/useOrganization'; | ||
import usePageFilters from 'sentry/utils/usePageFilters'; | ||
import type {IssueView} from 'sentry/views/issueList/issueViews/issueViews'; | ||
import {useFetchIssueCounts} from 'sentry/views/issueList/queries/useFetchIssueCounts'; | ||
|
||
const TAB_MAX_COUNT = 99; | ||
|
||
const constructCountTimeFrame = ( | ||
pageFilters: PageFilters['datetime'] | ||
): { | ||
end?: string; | ||
start?: string; | ||
statsPeriod?: string; | ||
} => { | ||
if (pageFilters.period) { | ||
return {statsPeriod: pageFilters.period}; | ||
} | ||
return { | ||
...(pageFilters.start ? {start: getUtcDateString(pageFilters.start)} : {}), | ||
...(pageFilters.end ? {end: getUtcDateString(pageFilters.end)} : {}), | ||
}; | ||
}; | ||
|
||
interface IssueViewQueryCountProps { | ||
view: IssueView; | ||
} | ||
|
||
export function IssueViewQueryCount({view}: IssueViewQueryCountProps) { | ||
const organization = useOrganization(); | ||
const pageFilters = usePageFilters(); | ||
|
||
// TODO(msun): Once page filters are saved to views, remember to use the view's specific | ||
// page filters here instead of the global pageFilters, if they exist. | ||
const {data: queryCount, isFetching: queryCountFetching} = useFetchIssueCounts({ | ||
orgSlug: organization.slug, | ||
query: [view.unsavedChanges ? view.unsavedChanges[0] : view.query], | ||
project: pageFilters.selection.projects, | ||
environment: pageFilters.selection.environments, | ||
...constructCountTimeFrame(pageFilters.selection.datetime), | ||
}); | ||
|
||
const displayedCount = | ||
queryCount?.[view.unsavedChanges ? view.unsavedChanges[0] : view.query] ?? 0; | ||
|
||
return ( | ||
<QueryCountBubble | ||
layout="size" | ||
animate={{ | ||
backgroundColor: queryCountFetching | ||
? [theme.gray100, theme.translucentSurface100, theme.gray100] | ||
: 'transparent', | ||
}} | ||
transition={{ | ||
layout: { | ||
duration: 0.1, | ||
}, | ||
default: { | ||
duration: 2.5, | ||
repeat: queryCountFetching ? Infinity : 0, | ||
ease: 'easeInOut', | ||
}, | ||
}} | ||
> | ||
<motion.span | ||
layout="position" | ||
initial={{opacity: 0}} | ||
animate={{opacity: queryCountFetching ? 0 : 1}} | ||
transition={{duration: 0.1}} | ||
> | ||
{displayedCount > TAB_MAX_COUNT ? `${TAB_MAX_COUNT}+` : displayedCount} | ||
</motion.span> | ||
</QueryCountBubble> | ||
); | ||
} | ||
|
||
const QueryCountBubble = styled(motion.span)` | ||
line-height: 20px; | ||
font-size: 75%; | ||
MichaelSun48 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
padding: 0 5px; | ||
MichaelSun48 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
min-width: 20px; | ||
display: flex; | ||
height: 16px; | ||
align-items: center; | ||
justify-content: center; | ||
border-radius: 10px; | ||
border: 1px solid ${p => p.theme.gray200}; | ||
color: ${p => p.theme.gray300}; | ||
margin-left: 0; | ||
`; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
import type {ApiQueryKey, UseApiQueryOptions} from 'sentry/utils/queryClient'; | ||
import {useApiQuery} from 'sentry/utils/queryClient'; | ||
import {keepPreviousData, useApiQuery} from 'sentry/utils/queryClient'; | ||
import type {QueryCount, QueryCounts} from 'sentry/views/issueList/utils'; | ||
|
||
interface FetchIssueCountsParameters { | ||
|
@@ -31,6 +31,7 @@ export const useFetchIssueCounts = ( | |
) => { | ||
return useApiQuery<QueryCounts>(makeFetchIssueCounts(params), { | ||
staleTime: 0, | ||
placeholderData: keepPreviousData, | ||
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. We want to keep previous data while new data loads so that the query count bubble doesn't change size while the new count loads. If this were not here, the previous data would be scrubbed, and the query count bubble would lose its content and shrink to its min width before growing again. |
||
...options, | ||
}); | ||
}; |
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.
Very minor change to align the view name better with the count:
Before:
After: