1- import { Component , ReactElement } from 'react' ;
1+ import { Component , ComponentClass } from 'react' ;
22import styled from '@emotion/styled' ;
33
44import { toggleKeyTransaction } from 'app/actionCreators/performance' ;
55import { Client } from 'app/api' ;
6+ import MenuHeader from 'app/components/actions/menuHeader' ;
67import CheckboxFancy from 'app/components/checkboxFancy/checkboxFancy' ;
7- import DropdownLink from 'app/components/dropdownLink' ;
8+ import DropdownControl , { Content } from 'app/components/dropdownControl' ;
9+ import { GetActorPropsFn } from 'app/components/dropdownMenu' ;
10+ import MenuItem from 'app/components/menuItem' ;
811import { t } from 'app/locale' ;
912import space from 'app/styles/space' ;
1013import { Organization , Team } from 'app/types' ;
1114import withApi from 'app/utils/withApi' ;
1215
13- export type TitleProps = {
16+ export type TitleProps = Partial < ReturnType < GetActorPropsFn > > & {
1417 keyedTeamsCount : number ;
1518 disabled ?: boolean ;
1619} ;
@@ -21,7 +24,7 @@ type Props = {
2124 organization : Organization ;
2225 teams : Team [ ] ;
2326 transactionName : string ;
24- title : ( props : TitleProps ) => ReactElement ;
27+ title : ComponentClass < TitleProps > ;
2528} ;
2629
2730type State = {
@@ -142,16 +145,17 @@ class TeamKeyTransaction extends Component<Props, State> {
142145 } ;
143146
144147 render ( ) {
145- const { teams, title : Title } = this . props ;
148+ const { teams, title} = this . props ;
146149 const { keyedTeams, isLoading} = this . state ;
147150
148151 if ( isLoading ) {
149- return < Title disabled keyedTeamsCount = { keyedTeams . size } /> ;
152+ const Title = title ;
153+ return < Title disabled keyedTeamsCount = { 0 } /> ;
150154 }
151155
152156 return (
153157 < TeamKeyTransactionSelector
154- title = { < Title keyedTeamsCount = { keyedTeams . size } /> }
158+ title = { title }
155159 handleToggleKeyTransaction = { this . handleToggleKeyTransaction }
156160 teams = { teams }
157161 keyedTeams = { keyedTeams }
@@ -161,14 +165,14 @@ class TeamKeyTransaction extends Component<Props, State> {
161165}
162166
163167type SelectorProps = {
164- title : React . ReactNode ;
168+ title : ComponentClass < TitleProps > ;
165169 handleToggleKeyTransaction : ( selection : TeamSelection ) => void ;
166170 teams : Team [ ] ;
167171 keyedTeams : Set < string > ;
168172} ;
169173
170174function TeamKeyTransactionSelector ( {
171- title,
175+ title : Title ,
172176 handleToggleKeyTransaction,
173177 teams,
174178 keyedTeams,
@@ -179,52 +183,129 @@ function TeamKeyTransactionSelector({
179183 } ;
180184
181185 return (
182- < DropdownLink caret = { false } title = { title } anchorMiddle >
183- < DropdownMenuHeader
184- first
185- onClick = { toggleTeam ( {
186- type : 'my teams' ,
187- action : teams . length === keyedTeams . size ? 'unkey' : 'key' ,
188- } ) }
189- >
190- { t ( 'My Teams' ) }
191- < StyledCheckbox
192- isChecked = { teams . length === keyedTeams . size }
193- isIndeterminate = { teams . length > keyedTeams . size && keyedTeams . size > 0 }
194- />
195- </ DropdownMenuHeader >
196- { teams . map ( team => (
197- < DropdownMenuItem
198- key = { team . slug }
199- onClick = { toggleTeam ( {
200- type : 'id' ,
201- action : keyedTeams . has ( team . id ) ? 'unkey' : 'key' ,
202- teamId : team . id ,
203- } ) }
186+ < DropdownControl
187+ button = { ( { getActorProps} ) => (
188+ < Title keyedTeamsCount = { keyedTeams . size } { ...getActorProps ( ) } />
189+ ) }
190+ >
191+ { ( { isOpen, getMenuProps} ) => (
192+ < DropdownWrapper
193+ { ...getMenuProps ( ) }
194+ isOpen = { isOpen }
195+ blendCorner
196+ alignMenu = "right"
197+ width = "220px"
204198 >
205- { team . name }
206- < StyledCheckbox isChecked = { keyedTeams . has ( team . id ) } />
207- </ DropdownMenuItem >
208- ) ) }
209- </ DropdownLink >
199+ { isOpen && (
200+ < DropdownContent >
201+ < DropdownMenuHeader first >
202+ { t ( 'My Teams' ) }
203+ < StyledCheckbox
204+ isChecked = { teams . length === keyedTeams . size }
205+ isIndeterminate = { teams . length > keyedTeams . size && keyedTeams . size > 0 }
206+ onClick = { toggleTeam ( {
207+ type : 'my teams' ,
208+ action : teams . length === keyedTeams . size ? 'unkey' : 'key' ,
209+ } ) }
210+ />
211+ </ DropdownMenuHeader >
212+ { teams . map ( team => (
213+ < DropdownMenuItem
214+ key = { team . slug }
215+ onClick = { toggleTeam ( {
216+ type : 'id' ,
217+ action : keyedTeams . has ( team . id ) ? 'unkey' : 'key' ,
218+ teamId : team . id ,
219+ } ) }
220+ >
221+ < MenuItemContent >
222+ { team . name }
223+ < StyledCheckbox isChecked = { keyedTeams . has ( team . id ) } />
224+ </ MenuItemContent >
225+ </ DropdownMenuItem >
226+ ) ) }
227+ </ DropdownContent >
228+ ) }
229+ </ DropdownWrapper >
230+ ) }
231+ </ DropdownControl >
210232 ) ;
211233}
212234
213- const DropdownMenuItemBase = styled ( 'li' ) `
235+ const DropdownWrapper = styled ( Content ) `
236+ margin-top: 9px;
237+ left: auto;
238+ right: 50%;
239+ transform: translateX(calc(50%));
240+
241+ /* Adapted from the dropdown-menu class */
242+ border: none;
243+ border-radius: 2px;
244+ box-shadow: 0 0 0 1px rgba(52, 60, 69, 0.2), 0 1px 3px rgba(70, 82, 98, 0.25);
245+ background-clip: padding-box;
246+ overflow: visible;
247+
248+ &:before {
249+ width: 0;
250+ height: 0;
251+ border-left: 9px solid transparent;
252+ border-right: 9px solid transparent;
253+ border-bottom: 9px solid ${ p => p . theme . border } ;
254+ content: '';
255+ display: block;
256+ position: absolute;
257+ top: -9px;
258+ left: calc(50% - 9px);
259+ right: auto;
260+ z-index: -2;
261+ }
262+
263+ &:after {
264+ width: 0;
265+ height: 0;
266+ border-left: 8px solid transparent;
267+ border-right: 8px solid transparent;
268+ border-bottom: 8px solid ${ p => p . theme . background } ;
269+ content: '';
270+ display: block;
271+ position: absolute;
272+ top: -8px;
273+ left: calc(50% - 8px);
274+ right: auto;
275+ z-index: -1;
276+ }
277+ ` ;
278+
279+ const DropdownContent = styled ( 'div' ) `
280+ max-height: 250px;
281+ overflow-y: auto;
282+ ` ;
283+
284+ const DropdownMenuHeader = styled ( MenuHeader ) < { first ?: boolean } > `
214285 display: flex;
215286 flex-direction: row;
216287 justify-content: space-between;
217288 align-items: center;
218- padding: ${ space ( 1 ) } ${ space ( 1.5 ) } ;
219- ` ;
289+ padding: ${ space ( 1.5 ) } ${ space ( 2 ) } ;
220290
221- const DropdownMenuHeader = styled ( DropdownMenuItemBase ) < { first ?: boolean } > `
222291 background: ${ p => p . theme . backgroundSecondary } ;
223292 ${ p => p . first && 'border-radius: 2px' } ;
224293` ;
225294
226- const DropdownMenuItem = styled ( DropdownMenuItemBase ) `
227- border-top: 1px solid ${ p => p . theme . border } ;
295+ const DropdownMenuItem = styled ( MenuItem ) `
296+ font-size: ${ p => p . theme . fontSizeMedium } ;
297+
298+ &:not(:last-child) {
299+ border-bottom: 1px solid ${ p => p . theme . innerBorder } ;
300+ }
301+ ` ;
302+
303+ const MenuItemContent = styled ( 'div' ) `
304+ display: flex;
305+ flex-direction: row;
306+ justify-content: space-between;
307+ align-items: center;
308+ width: 100%;
228309` ;
229310
230311const StyledCheckbox = styled ( CheckboxFancy ) `
0 commit comments