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 {
25 onBlur?: (event: React.FocusEvent<HTMLInputElement>) => void;
26 onFocus?: (event: React.FocusEvent<HTMLInputElement>) => void;
27 onCreate?: (person: Person) => void;
28 onDelete?: (index: number) => void;
29 onSelect?: (person: Person) => void;
33 export interface PeopleSelectState {
35 suggestions: UserResource[];
38 export const PeopleSelect = connect()(
39 class PeopleSelect extends React.Component<PeopleSelectProps & DispatchProp, PeopleSelectState> {
41 state: PeopleSelectState = {
48 const { label = 'Invite people' } = this.props;
53 value={this.state.value}
54 items={this.props.items}
55 suggestions={this.state.suggestions}
56 onChange={this.handleChange}
57 onCreate={this.handleCreate}
58 onSelect={this.handleSelect}
59 onDelete={this.handleDelete}
60 onFocus={this.props.onFocus}
61 onBlur={this.props.onBlur}
62 renderChipValue={this.renderChipValue}
63 renderSuggestion={this.renderSuggestion} />
67 renderChipValue({ name, uuid }: Person) {
68 return name ? name : uuid;
71 renderSuggestion({ firstName, lastName, email }: UserResource) {
74 <Typography noWrap>{`${firstName} ${lastName} <<${email}>>`}</Typography>
79 handleDelete = (_: Person, index: number) => {
80 const { onDelete = noop } = this.props;
84 handleCreate = () => {
85 const { onCreate } = this.props;
87 this.setState({ value: '', suggestions: [] });
91 uuid: this.state.value,
96 handleSelect = ({ email, firstName, lastName, uuid }: UserResource) => {
97 const { onSelect = noop } = this.props;
98 this.setState({ value: '', suggestions: [] });
101 name: `${firstName} ${lastName}`,
106 handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
107 this.setState({ value: event.target.value }, this.getSuggestions);
110 getSuggestions = debounce(() => this.props.dispatch<any>(this.requestSuggestions), 500);
112 requestSuggestions = async (_: void, __: void, { userService }: ServiceRepository) => {
113 const { value } = this.state;
114 const filters = new FilterBuilder()
115 .addILike('email', value)
117 const { items } = await userService.list({ filters, limit: 5 });
118 this.setState({ suggestions: items });