1
1
import { useContext , useEffect , useMemo } from 'react' ;
2
2
3
3
import Avatar from 'sentry/components/avatar' ;
4
+ import { Tooltip } from 'sentry/components/tooltip' ;
4
5
import { t } from 'sentry/locale' ;
6
+ import type { DetailedTeam } from 'sentry/types' ;
7
+ import { defined } from 'sentry/utils' ;
5
8
import { useMembers } from 'sentry/utils/useMembers' ;
6
9
import { useTeams } from 'sentry/utils/useTeams' ;
7
10
import { useTeamsById } from 'sentry/utils/useTeamsById' ;
@@ -15,6 +18,10 @@ import SelectField from './selectField';
15
18
// projects can be passed as a direct prop as well
16
19
export interface RenderFieldProps extends SelectFieldProps < any > {
17
20
avatarSize ?: number ;
21
+ /**
22
+ * Ensures the only selectable teams and members are members of the given project
23
+ */
24
+ memberOfProjectSlug ?: string ;
18
25
/**
19
26
* Use the slug as the select field value. Without setting this the numeric id
20
27
* of the project will be used.
@@ -25,6 +32,7 @@ export interface RenderFieldProps extends SelectFieldProps<any> {
25
32
function SentryMemberTeamSelectorField ( {
26
33
avatarSize = 20 ,
27
34
placeholder = t ( 'Choose Teams and Members' ) ,
35
+ memberOfProjectSlug,
28
36
...props
29
37
} : RenderFieldProps ) {
30
38
const { form} = useContext ( FormContext ) ;
@@ -77,11 +85,36 @@ function SentryMemberTeamSelectorField({
77
85
loadMore : loadMoreTeams ,
78
86
} = useTeams ( { provideUserTeams : true } ) ;
79
87
80
- const teamOptions = teams ?. map ( team => ( {
81
- value : `team:${ team . id } ` ,
82
- label : `#${ team . slug } ` ,
83
- leadingItems : < Avatar team = { team } size = { avatarSize } /> ,
84
- } ) ) ;
88
+ // TODO(davidenwang): Fix the team type here to avoid this type cast
89
+ const teamOptions = ( teams as DetailedTeam [ ] )
90
+ . map ( team => {
91
+ const isDisabledTeam =
92
+ memberOfProjectSlug &&
93
+ ! defined ( team . projects . find ( ( { slug} ) => memberOfProjectSlug === slug ) ) ;
94
+ return {
95
+ value : `team:${ team . id } ` ,
96
+ leadingItems : < Avatar team = { team } size = { avatarSize } /> ,
97
+ ...( isDisabledTeam
98
+ ? {
99
+ disabled : true ,
100
+ label : (
101
+ < Tooltip
102
+ position = "left"
103
+ title = { t ( '%s is not a member of the selected project' , `#${ team . slug } ` ) }
104
+ >
105
+ #{ team . slug }
106
+ </ Tooltip >
107
+ ) ,
108
+ }
109
+ : {
110
+ disabled : false ,
111
+ label : `#${ team . slug } ` ,
112
+ } ) ,
113
+ } ;
114
+ } )
115
+ . sort ( ( { disabled : teamADisabled } , { disabled : teamBDisabled } ) =>
116
+ teamADisabled === teamBDisabled ? 0 : teamADisabled ? 1 : - 1
117
+ ) ;
85
118
86
119
// TODO(epurkhiser): This is an unfortunate hack right now since we don't
87
120
// actually load members anywhere and the useMembers and useTeams hook don't
0 commit comments