1import React, { Component } from 'react'; 2import { debounce, isNil } from 'lodash'; 3import { AsyncSelect } from '@grafana/ui'; 4import { SelectableValue } from '@grafana/data'; 5import { getBackendSrv } from '@grafana/runtime'; 6import { Team } from 'app/types'; 7 8export interface Props { 9 onSelected: (team: SelectableValue<Team>) => void; 10 className?: string; 11} 12 13export interface State { 14 isLoading: boolean; 15} 16 17export class TeamPicker extends Component<Props, State> { 18 debouncedSearch: any; 19 20 constructor(props: Props) { 21 super(props); 22 this.state = { isLoading: false }; 23 this.search = this.search.bind(this); 24 25 this.debouncedSearch = debounce(this.search, 300, { 26 leading: true, 27 trailing: true, 28 }); 29 } 30 31 search(query?: string) { 32 this.setState({ isLoading: true }); 33 34 if (isNil(query)) { 35 query = ''; 36 } 37 38 return getBackendSrv() 39 .get(`/api/teams/search?perpage=100&page=1&query=${query}`) 40 .then((result: { teams: Team[] }) => { 41 const teams: Array<SelectableValue<Team>> = result.teams.map((team) => { 42 return { 43 value: team, 44 label: team.name, 45 imgUrl: team.avatarUrl, 46 }; 47 }); 48 49 this.setState({ isLoading: false }); 50 return teams; 51 }); 52 } 53 54 render() { 55 const { onSelected, className } = this.props; 56 const { isLoading } = this.state; 57 return ( 58 <div className="user-picker" data-testid="teamPicker"> 59 <AsyncSelect 60 menuShouldPortal 61 isLoading={isLoading} 62 defaultOptions={true} 63 loadOptions={this.debouncedSearch} 64 onChange={onSelected} 65 className={className} 66 placeholder="Select a team" 67 noOptionsMessage="No teams found" 68 aria-label="Team picker" 69 /> 70 </div> 71 ); 72 } 73} 74