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