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 {
21 export interface PeopleSelectProps {
27 onBlur?: (event: React.FocusEvent<HTMLInputElement>) => void;
28 onFocus?: (event: React.FocusEvent<HTMLInputElement>) => void;
29 onCreate?: (person: Person) => void;
30 onDelete?: (index: number) => void;
31 onSelect?: (person: Person) => void;
35 export interface PeopleSelectState {
37 suggestions: UserResource[];
40 export const PeopleSelect = connect()(
41 class PeopleSelect extends React.Component<PeopleSelectProps & DispatchProp, PeopleSelectState> {
43 state: PeopleSelectState = {
50 const { label = 'Invite people' } = this.props;
55 value={this.state.value}
56 items={this.props.items}
57 suggestions={this.state.suggestions}
58 autofocus={this.props.autofocus}
59 onChange={this.handleChange}
60 onCreate={this.handleCreate}
61 onSelect={this.handleSelect}
62 onDelete={this.handleDelete}
63 onFocus={this.props.onFocus}
64 onBlur={this.props.onBlur}
65 renderChipValue={this.renderChipValue}
66 renderSuggestion={this.renderSuggestion} />
70 renderChipValue({ name, uuid }: Person) {
71 return name ? name : uuid;
74 renderSuggestion({ firstName, lastName, email }: UserResource) {
77 <Typography noWrap>{`${firstName} ${lastName} <<${email}>>`}</Typography>
82 handleDelete = (_: Person, index: number) => {
83 const { onDelete = noop } = this.props;
87 handleCreate = () => {
88 const { onCreate } = this.props;
90 this.setState({ value: '', suggestions: [] });
94 uuid: this.state.value,
99 handleSelect = ({ email, firstName, lastName, uuid }: UserResource) => {
100 const { onSelect = noop } = this.props;
101 this.setState({ value: '', suggestions: [] });
104 name: `${firstName} ${lastName}`,
109 handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
110 this.setState({ value: event.target.value }, this.getSuggestions);
113 getSuggestions = debounce(() => this.props.dispatch<any>(this.requestSuggestions), 500);
115 requestSuggestions = async (_: void, __: void, { userService }: ServiceRepository) => {
116 const { value } = this.state;
117 const filters = new FilterBuilder()
118 .addILike('email', value)
120 const { items } = await userService.list({ filters, limit: 5 });
121 this.setState({ suggestions: items });