PR fixes, extract format start and finished dates
[arvados-workbench2.git] / src / views-components / sharing-dialog / people-select.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
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';
14
15 export interface Person {
16     name: string;
17     email: string;
18     uuid: string;
19 }
20 export interface PeopleSelectProps {
21
22     items: Person[];
23
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;
29
30 }
31
32 export interface PeopleSelectState {
33     value: string;
34     suggestions: UserResource[];
35 }
36
37 export const PeopleSelect = connect()(
38     class PeopleSelect extends React.Component<PeopleSelectProps & DispatchProp, PeopleSelectState> {
39
40         state: PeopleSelectState = {
41             value: '',
42             suggestions: []
43         };
44
45         render() {
46             return (
47                 <Autocomplete
48                     label='Invite people'
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} />
60             );
61         }
62
63         renderChipValue({ name, uuid }: Person) {
64             return name ? name : uuid;
65         }
66
67         renderSuggestion({ firstName, lastName, email }: UserResource) {
68             return (
69                 <ListItemText>
70                     <Typography noWrap>{`${firstName} ${lastName} <<${email}>>`}</Typography>
71                 </ListItemText>
72             );
73         }
74
75         handleDelete = (_: Person, index: number) => {
76             const { onDelete = noop } = this.props;
77             onDelete(index);
78         }
79
80         handleCreate = () => {
81             const { onCreate } = this.props;
82             if (onCreate) {
83                 this.setState({ value: '', suggestions: [] });
84                 onCreate({
85                     email: '',
86                     name: '',
87                     uuid: this.state.value,
88                 });
89             }
90         }
91
92         handleSelect = ({ email, firstName, lastName, uuid }: UserResource) => {
93             const { onSelect = noop } = this.props;
94             this.setState({ value: '', suggestions: [] });
95             onSelect({
96                 email,
97                 name: `${firstName} ${lastName}`,
98                 uuid,
99             });
100         }
101
102         handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
103             this.setState({ value: event.target.value }, this.getSuggestions);
104         }
105
106         getSuggestions = debounce(() => this.props.dispatch<any>(this.requestSuggestions), 500);
107
108         requestSuggestions = async (_: void, __: void, { userService }: ServiceRepository) => {
109             const { value } = this.state;
110             const filters = new FilterBuilder()
111                 .addILike('email', value)
112                 .getFilters();
113             const { items } = await userService.list({ filters, limit: 5 });
114             this.setState({ suggestions: items });
115         }
116
117     });