1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import * as React from 'react';
6 import { Autocomplete } from '~/components/autocomplete/autocomplete';
7 import { UserResource } from '~/models/user';
8 import { connect, DispatchProp } from 'react-redux';
9 import { ServiceRepository } from '~/services/services';
10 import { FilterBuilder } from '../../services/api/filter-builder';
11 import { debounce } from 'debounce';
12 import { ListItemText, Typography } from '@material-ui/core';
13 import { noop } from 'lodash/fp';
15 export interface Person {
20 export interface PeopleSelectProps {
24 onBlur?: (event: React.FocusEvent<HTMLInputElement>) => void;
25 onFocus?: (event: React.FocusEvent<HTMLInputElement>) => void;
26 onCreate?: (person: Person) => void;
27 onDelete?: (index: number) => void;
28 onSelect?: (person: Person) => void;
32 export interface PeopleSelectState {
34 suggestions: UserResource[];
37 export const PeopleSelect = connect()(
38 class PeopleSelect extends React.Component<PeopleSelectProps & DispatchProp, PeopleSelectState> {
40 state: PeopleSelectState = {
49 value={this.state.value}
50 items={this.props.items}
51 suggestions={this.state.suggestions}
52 onChange={this.handleChange}
53 onCreate={this.handleCreate}
54 onSelect={this.handleSelect}
55 onDelete={this.handleDelete}
56 onFocus={this.props.onFocus}
57 onBlur={this.props.onBlur}
58 renderChipValue={this.renderChipValue}
59 renderSuggestion={this.renderSuggestion} />
63 renderChipValue({ name, uuid }: Person) {
64 return name ? name : uuid;
67 renderSuggestion({ firstName, lastName, email }: UserResource) {
70 <Typography noWrap>{`${firstName} ${lastName} <<${email}>>`}</Typography>
75 handleDelete = (_: Person, index: number) => {
76 const { onDelete = noop } = this.props;
80 handleCreate = () => {
81 const { onCreate } = this.props;
83 this.setState({ value: '', suggestions: [] });
87 uuid: this.state.value,
92 handleSelect = ({ email, firstName, lastName, uuid }: UserResource) => {
93 const { onSelect = noop } = this.props;
94 this.setState({ value: '', suggestions: [] });
97 name: `${firstName} ${lastName}`,
102 handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
103 this.setState({ value: event.target.value }, this.getSuggestions);
106 getSuggestions = debounce(() => this.props.dispatch<any>(this.requestSuggestions), 500);
108 requestSuggestions = async (_: void, __: void, { userService }: ServiceRepository) => {
109 const { value } = this.state;
110 const filters = new FilterBuilder()
111 .addILike('email', value)
113 const { items } = await userService.list({ filters, limit: 5 });
114 this.setState({ suggestions: items });