import React from 'react'; import {Select2} from './select2'; import {keyBy} from 'lodash'; import {ListItem, ListItemColumn, ListItemRow} from 'core/components/ListItem'; import {IBaseRestApiResponse, IRestApiResponse} from 'superdesk-api'; interface IProps { placeholder: string; query(searchString): Promise>; queryById(id): Promise; getLabel(item: T): string; onSelect(item: T): void; selected?: string; disabled?: boolean; autoFocus?: boolean; 'data-test-id'?: string; } interface IState { fetchedItems?: Array; loading: boolean; selectedItem: T | null; } export class AutoComplete extends React.Component, IState> { private _mounted: boolean; constructor(props: IProps) { super(props); this.state = { loading: true, selectedItem: null, }; this.queryItems = this.queryItems.bind(this); this.fetchSelected = this.fetchSelected.bind(this); } queryItems(_searchString: string = '') { const searchString = _searchString.trim(); this.setState({loading: true, fetchedItems: null}); return this.props.query(searchString).then((res) => { if (this._mounted) { this.setState({ fetchedItems: res?._items ?? this.state.fetchedItems, loading: false, }); } }); } componentDidMount() { this._mounted = true; this.queryItems(); this.fetchSelected(); } componentWillUnmount() { this._mounted = false; } fetchSelected() { if (this.props.selected != null) { this.props.queryById(this.props.selected).then((selectedItem) => { this.setState({selectedItem, loading: false}); }); } } render() { const keyedItems: {[key: string]: T} = keyBy(this.state.fetchedItems, (item) => item._id); return ( {this.props.placeholder} )} value={this.props.selected == null ? undefined : this.props.selected} valueObject={this.state.selectedItem} items={keyedItems} getItemValue={(item) => item._id} onSelect={(value) => { this.props.onSelect(keyedItems[value]); }} renderItem={(item) => ( {this.props.getLabel(item)} )} onSearch={(search) => { return this.queryItems(search); }} loading={this.state.loading} data-test-id={this.props['data-test-id']} /> ); } }