@@ -3,19 +3,20 @@ import styled from '@emotion/styled';
3
3
import Color from 'color' ;
4
4
5
5
import { Flex } from 'sentry/components/container/flex' ;
6
- import { Alert } from 'sentry/components/core/alert' ;
7
6
import { NumberInput } from 'sentry/components/core/input/numberInput' ;
8
7
import { Tooltip } from 'sentry/components/core/tooltip' ;
9
8
import { OrderBy , SortBy } from 'sentry/components/events/featureFlags/utils' ;
10
9
import useSuspectFlagScoreThreshold from 'sentry/components/issues/suspect/useSuspectFlagScoreThreshold' ;
10
+ import Link from 'sentry/components/links/link' ;
11
11
import { IconSentry } from 'sentry/icons/iconSentry' ;
12
12
import { t } from 'sentry/locale' ;
13
13
import { space } from 'sentry/styles/space' ;
14
14
import type { Group } from 'sentry/types/group' ;
15
15
import { trackAnalytics } from 'sentry/utils/analytics' ;
16
16
import toRoundedPercent from 'sentry/utils/number/toRoundedPercent' ;
17
+ import { useLocation } from 'sentry/utils/useLocation' ;
17
18
import useOrganization from 'sentry/utils/useOrganization' ;
18
- import FlagDetailsLink from 'sentry/views/issueDetails/groupFeatureFlags/details/flagDetailsLink ' ;
19
+ import { DrawerTab } from 'sentry/views/issueDetails/groupDistributions/types ' ;
19
20
import useGroupFlagDrawerData from 'sentry/views/issueDetails/groupFeatureFlags/hooks/useGroupFlagDrawerData' ;
20
21
21
22
interface Props {
@@ -26,6 +27,7 @@ interface Props {
26
27
27
28
export default function SuspectTable ( { debugSuspectScores, environments, group} : Props ) {
28
29
const organization = useOrganization ( ) ;
30
+ const location = useLocation ( ) ;
29
31
const [ threshold , setThreshold ] = useSuspectFlagScoreThreshold ( ) ;
30
32
31
33
const { displayFlags, isPending} = useGroupFlagDrawerData ( {
@@ -57,27 +59,32 @@ export default function SuspectTable({debugSuspectScores, environments, group}:
57
59
}
58
60
} , [ isPending , organization , displayFlags . length , susFlags . length , threshold ] ) ;
59
61
62
+ if ( displayFlags . length === 0 ) {
63
+ // If there are no display flags then we don't need this section at all.
64
+ return null ;
65
+ }
66
+
60
67
if ( isPending ) {
61
68
return (
62
- < Alert type = "muted" >
69
+ < GradientBox >
63
70
< TagHeader >
64
- { t ( 'Suspect' ) }
71
+ { t ( 'Suspect Flags ' ) }
65
72
{ debugThresholdInput }
66
73
</ TagHeader >
67
74
{ t ( 'Loading...' ) }
68
- </ Alert >
75
+ </ GradientBox >
69
76
) ;
70
77
}
71
78
72
79
if ( ! susFlags . length ) {
73
80
return (
74
- < Alert type = "muted" >
81
+ < GradientBox >
75
82
< TagHeader >
76
- { t ( 'Suspect' ) }
83
+ { t ( 'Suspect Flags ' ) }
77
84
{ debugThresholdInput }
78
85
</ TagHeader >
79
86
{ t ( 'Nothing suspicious' ) }
80
- </ Alert >
87
+ </ GradientBox >
81
88
) ;
82
89
}
83
90
@@ -95,15 +102,24 @@ export default function SuspectTable({debugSuspectScores, environments, group}:
95
102
return (
96
103
< TagValueRow key = { flag . key } >
97
104
{ /* TODO: why is flag.name transformed to TitleCase? */ }
98
- < FlagDetailsLink flag = { flag } >
99
- < Tooltip
100
- title = { flag . key }
101
- showOnlyOnOverflow
102
- data-underline-on-hover = "true"
105
+ < Tooltip
106
+ skipWrapper
107
+ title = { flag . key }
108
+ showOnlyOnOverflow
109
+ data-underline-on-hover = "true"
110
+ >
111
+ < StyledLink
112
+ to = { {
113
+ pathname : `${ location . pathname } ${ flag . key } /` ,
114
+ query : {
115
+ ...location . query ,
116
+ tab : DrawerTab . FEATURE_FLAGS ,
117
+ } ,
118
+ } }
103
119
>
104
120
{ flag . key }
105
- </ Tooltip >
106
- </ FlagDetailsLink >
121
+ </ StyledLink >
122
+ </ Tooltip >
107
123
< RightAligned >
108
124
{ toRoundedPercent ( ( topValue ?. count ?? 0 ) / flag . totalValues ) }
109
125
</ RightAligned >
@@ -128,6 +144,9 @@ const GradientBox = styled('div')`
128
144
border-radius: ${ p => p . theme . borderRadius } ;
129
145
color: ${ p => p . theme . textColor } ;
130
146
padding: ${ space ( 1 ) } ;
147
+ height: max-content;
148
+ display: flex;
149
+ flex-direction: column;
131
150
` ;
132
151
133
152
const TagHeader = styled ( 'h4' ) `
@@ -140,21 +159,20 @@ const TagHeader = styled('h4')`
140
159
font-weight: ${ p => p . theme . fontWeightBold } ;
141
160
` ;
142
161
143
- const progressBarWidth = '45px' ; // Prevent percentages from overflowing
144
162
const TagValueGrid = styled ( 'ul' ) `
145
163
display: grid;
146
- grid-template-columns: 4fr ${ progressBarWidth } auto auto max-content auto ;
147
-
164
+ grid-template-columns: auto max-content max-content ;
165
+ gap: ${ space ( 0.25 ) } ${ space ( 0.5 ) } ;
148
166
margin: 0;
149
167
padding: 0;
150
168
list-style: none;
151
169
` ;
152
170
153
171
const TagValueRow = styled ( 'li' ) `
154
172
display: grid;
155
- grid-template-columns: subgrid;
156
173
grid-column: 1 / -1;
157
- grid-column-gap: ${ space ( 1 ) } ;
174
+ grid-template-columns: subgrid;
175
+
158
176
align-items: center;
159
177
padding: ${ space ( 0.25 ) } ${ space ( 0.75 ) } ;
160
178
border-radius: ${ p => p . theme . borderRadius } ;
@@ -166,6 +184,15 @@ const TagValueRow = styled('li')`
166
184
}
167
185
` ;
168
186
187
+ const StyledLink = styled ( Link ) `
188
+ ${ p => p . theme . overflowEllipsis } ;
189
+ width: auto;
190
+
191
+ &:hover [data-underline-on-hover='true'] {
192
+ text-decoration: underline;
193
+ }
194
+ ` ;
195
+
169
196
const RightAligned = styled ( 'span' ) `
170
197
text-align: right;
171
198
` ;
0 commit comments