2017-11-07 16:33:15 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* InputSearch
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
import React from 'react';
|
|
|
|
import { FormattedMessage } from 'react-intl';
|
2017-12-18 11:57:09 +01:00
|
|
|
import { findIndex, has, includes, isEmpty, map, toLower, upperFirst } from 'lodash';
|
2017-11-07 16:33:15 +01:00
|
|
|
import cn from 'classnames';
|
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
|
2017-11-07 18:16:42 +01:00
|
|
|
import InputSearchLi from 'components/InputSearchLi';
|
|
|
|
|
2017-11-07 16:33:15 +01:00
|
|
|
import styles from './styles.scss';
|
|
|
|
|
|
|
|
class InputSearch extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
2017-11-23 13:09:05 +01:00
|
|
|
state = {
|
|
|
|
errors: [],
|
|
|
|
filteredUsers: this.props.values,
|
|
|
|
isAdding: false,
|
|
|
|
users: this.props.values,
|
|
|
|
value: '',
|
2017-11-29 12:36:35 +01:00
|
|
|
autoFocus: false,
|
2017-11-23 13:09:05 +01:00
|
|
|
};
|
2017-11-07 18:16:42 +01:00
|
|
|
|
|
|
|
componentWillReceiveProps(nextProps) {
|
|
|
|
if (nextProps.didDeleteUser !== this.props.didDeleteUser) {
|
|
|
|
this.setState({ users: nextProps.values, filteredUsers: nextProps.values });
|
|
|
|
}
|
2017-11-15 14:00:51 +01:00
|
|
|
|
|
|
|
if (nextProps.didGetUsers !== this.props.didGetUsers) {
|
|
|
|
this.setState({ users: nextProps.values, filteredUsers: nextProps.values });
|
|
|
|
}
|
2017-11-23 12:43:40 +01:00
|
|
|
|
|
|
|
if (nextProps.didFetchUsers !== this.props.didFetchUsers) {
|
2017-11-23 13:09:05 +01:00
|
|
|
this.setState({ filteredUsers: nextProps.users, isAdding: true });
|
2017-11-23 12:43:40 +01:00
|
|
|
}
|
2017-11-07 18:16:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
handleChange = ({ target }) => {
|
|
|
|
const filteredUsers = isEmpty(target.value) ?
|
2017-11-08 16:06:21 +01:00
|
|
|
this.state.users
|
2017-12-07 18:31:19 +01:00
|
|
|
: this.state.users.filter((user) => includes(toLower(user.name), toLower(target.value)));
|
2017-11-23 12:43:40 +01:00
|
|
|
|
|
|
|
if (isEmpty(filteredUsers) && !isEmpty(target.value)) {
|
|
|
|
this.props.getUser(target.value);
|
|
|
|
}
|
|
|
|
|
2017-11-23 13:09:05 +01:00
|
|
|
if (isEmpty(target.value)) {
|
|
|
|
return this.setState({ value: target.value, isAdding: false, users: this.props.values, filteredUsers: this.props.values });
|
|
|
|
}
|
|
|
|
|
2017-11-07 18:16:42 +01:00
|
|
|
this.setState({ value: target.value, filteredUsers });
|
|
|
|
}
|
2017-11-07 16:33:15 +01:00
|
|
|
|
2017-11-23 13:09:05 +01:00
|
|
|
handleClick = (item) => {
|
|
|
|
if (this.state.isAdding) {
|
2017-11-29 12:36:35 +01:00
|
|
|
const id = has(item, '_id') ? '_id' : 'id';
|
|
|
|
const users = this.props.values;
|
|
|
|
// Check if user is already associated with this role
|
2017-12-08 10:42:45 +01:00
|
|
|
if (findIndex(users, [id, item[id]]) === -1) {
|
2017-11-29 12:36:35 +01:00
|
|
|
this.props.onClickAdd(item);
|
|
|
|
users.push(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reset the input focus
|
|
|
|
this.searchInput.focus();
|
|
|
|
// Empty the input and display users
|
|
|
|
this.setState({ value: '', isAdding: false, users, filteredUsers: users });
|
2017-11-23 13:09:05 +01:00
|
|
|
} else {
|
|
|
|
this.props.onClickDelete(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-07 16:33:15 +01:00
|
|
|
render() {
|
|
|
|
return (
|
|
|
|
<div className={cn(styles.inputSearch, 'col-md-6')}>
|
|
|
|
<label htmlFor={this.props.name}>
|
2017-12-18 11:57:09 +01:00
|
|
|
<FormattedMessage id={this.props.label} values={upperFirst(this.props.labelValues)} />
|
2017-11-07 16:33:15 +01:00
|
|
|
</label>
|
|
|
|
<div className={cn('input-group')}>
|
|
|
|
<span className={cn('input-group-addon', styles.addon)} />
|
|
|
|
<FormattedMessage id="users-permissions.InputSearch.placeholder">
|
|
|
|
{(message) => (
|
|
|
|
<input
|
|
|
|
className={cn('form-control', !isEmpty(this.state.errors) ? 'is-invalid': '')}
|
|
|
|
id={this.props.name}
|
|
|
|
name={this.props.name}
|
2017-11-07 18:16:42 +01:00
|
|
|
onChange={this.handleChange}
|
|
|
|
value={this.state.value}
|
2017-11-07 16:33:15 +01:00
|
|
|
placeholder={message}
|
|
|
|
type="text"
|
2017-11-29 12:36:35 +01:00
|
|
|
ref={(input) => { this.searchInput = input; }}
|
2017-11-07 16:33:15 +01:00
|
|
|
/>
|
|
|
|
)}
|
|
|
|
</FormattedMessage>
|
|
|
|
</div>
|
2017-11-07 18:16:42 +01:00
|
|
|
<div className={styles.ulContainer}>
|
|
|
|
<ul>
|
|
|
|
{map(this.state.filteredUsers, (user) => (
|
2017-11-23 13:09:05 +01:00
|
|
|
<InputSearchLi
|
2017-11-27 14:26:54 +01:00
|
|
|
key={user.id || user._id}
|
2017-11-23 13:09:05 +01:00
|
|
|
item={user}
|
|
|
|
isAdding={this.state.isAdding}
|
|
|
|
onClick={this.handleClick}
|
|
|
|
/>
|
2017-11-07 18:16:42 +01:00
|
|
|
))}
|
|
|
|
</ul>
|
|
|
|
</div>
|
2017-11-07 16:33:15 +01:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
InputSearch.defaultProps = {
|
|
|
|
labelValues: {
|
|
|
|
number: 0,
|
|
|
|
},
|
2017-11-23 12:43:40 +01:00
|
|
|
users: [],
|
2017-11-08 16:06:21 +01:00
|
|
|
values: [],
|
|
|
|
};
|
2017-11-07 16:33:15 +01:00
|
|
|
|
2017-11-08 16:06:21 +01:00
|
|
|
InputSearch.propTypes = {
|
|
|
|
didDeleteUser: PropTypes.bool.isRequired,
|
2017-11-23 12:43:40 +01:00
|
|
|
didFetchUsers: PropTypes.bool.isRequired,
|
2017-11-15 14:00:51 +01:00
|
|
|
didGetUsers: PropTypes.bool.isRequired,
|
2017-11-23 12:43:40 +01:00
|
|
|
getUser: PropTypes.func.isRequired,
|
2017-11-07 16:33:15 +01:00
|
|
|
label: PropTypes.string.isRequired,
|
|
|
|
labelValues: PropTypes.object,
|
|
|
|
name: PropTypes.string.isRequired,
|
2017-11-23 13:09:05 +01:00
|
|
|
onClickAdd: PropTypes.func.isRequired,
|
2017-11-07 18:16:42 +01:00
|
|
|
onClickDelete: PropTypes.func.isRequired,
|
2017-11-23 12:43:40 +01:00
|
|
|
users: PropTypes.array,
|
2017-11-08 16:06:21 +01:00
|
|
|
values: PropTypes.array,
|
2017-11-07 16:33:15 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
export default InputSearch;
|