178 lines
4.7 KiB
JavaScript
Raw Normal View History

/**
2019-04-16 16:55:53 +02:00
*
* InputSearchContainer
*
*/
import React from 'react';
import { FormattedMessage } from 'react-intl';
2018-01-08 14:15:27 +01:00
import { findIndex, has, includes, isEmpty, map, toLower } from 'lodash';
import cn from 'classnames';
import PropTypes from 'prop-types';
2019-04-16 16:55:53 +02:00
import { Label } from 'strapi-helper-plugin';
2019-02-22 11:16:42 +01:00
import InputSearchLi from '../InputSearchLi';
import styles from './styles.scss';
2019-04-16 16:55:53 +02:00
class InputSearchContainer 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,
isFocused: false,
2017-11-23 13:09:05 +01:00
users: this.props.values,
value: '',
};
2019-08-13 11:31:10 +02:00
UNSAFE_componentWillReceiveProps(nextProps) {
if (nextProps.didDeleteUser !== this.props.didDeleteUser) {
2019-04-16 16:55:53 +02:00
this.setState({
users: nextProps.values,
filteredUsers: nextProps.values,
});
}
if (nextProps.didGetUsers !== this.props.didGetUsers) {
2019-04-16 16:55:53 +02:00
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
}
}
handleBlur = () => this.setState({ isFocused: !this.state.isFocused });
handleChange = ({ target }) => {
2019-04-16 16:55:53 +02:00
const filteredUsers = isEmpty(target.value)
? this.state.users
: this.state.users.filter(user =>
2019-08-13 11:31:10 +02:00
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)) {
2019-04-16 16:55:53 +02:00
return this.setState({
value: target.value,
isAdding: false,
users: this.props.values,
filteredUsers: this.props.values,
});
2017-11-23 13:09:05 +01:00
}
this.setState({ value: target.value, filteredUsers });
2019-04-16 16:55:53 +02:00
};
handleFocus = () => this.setState({ isFocused: !this.state.isFocused });
2019-04-16 16:55:53 +02:00
handleClick = item => {
2017-11-23 13:09:05 +01:00
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
2019-04-16 16:55:53 +02:00
this.setState({
value: '',
isAdding: false,
users,
filteredUsers: users,
});
2017-11-23 13:09:05 +01:00
} else {
this.props.onClickDelete(item);
}
2019-04-16 16:55:53 +02:00
};
2017-11-23 13:09:05 +01:00
render() {
return (
<div className={cn(styles.inputSearch, 'col-md-6')}>
<Label htmlFor={this.props.name} message={this.props.label} />
<div className={cn('input-group')}>
2019-04-16 16:55:53 +02:00
<span
className={cn(
'input-group-addon',
styles.addon,
2019-08-13 11:31:10 +02:00
this.state.isFocused && styles.addonFocus
2019-04-16 16:55:53 +02:00
)}
/>
<FormattedMessage id="users-permissions.InputSearch.placeholder">
2019-04-16 16:55:53 +02:00
{message => (
<input
2019-04-16 16:55:53 +02:00
className={cn(
'form-control',
2019-08-13 11:31:10 +02:00
!isEmpty(this.state.errors) ? 'is-invalid' : ''
2019-04-16 16:55:53 +02:00
)}
id={this.props.name}
name={this.props.name}
onBlur={this.handleBlur}
onChange={this.handleChange}
onFocus={this.handleFocus}
value={this.state.value}
placeholder={message}
type="text"
2019-04-16 16:55:53 +02:00
ref={input => {
this.searchInput = input;
}}
/>
)}
</FormattedMessage>
</div>
2019-04-16 16:55:53 +02:00
<div
className={cn(
styles.ulContainer,
2019-08-13 11:31:10 +02:00
this.state.isFocused && styles.ulFocused
2019-04-16 16:55:53 +02:00
)}
>
<ul>
2019-04-16 16:55:53 +02:00
{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}
/>
))}
</ul>
</div>
</div>
);
}
}
InputSearchContainer.defaultProps = {
2017-11-23 12:43:40 +01:00
users: [],
2017-11-08 16:06:21 +01:00
values: [],
};
InputSearchContainer.propTypes = {
2017-11-08 16:06:21 +01:00
didDeleteUser: PropTypes.bool.isRequired,
2017-11-23 12:43:40 +01:00
didFetchUsers: PropTypes.bool.isRequired,
didGetUsers: PropTypes.bool.isRequired,
2017-11-23 12:43:40 +01:00
getUser: PropTypes.func.isRequired,
label: PropTypes.shape({
id: PropTypes.string,
params: PropTypes.object,
}).isRequired,
name: PropTypes.string.isRequired,
2017-11-23 13:09:05 +01:00
onClickAdd: PropTypes.func.isRequired,
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,
};
export default InputSearchContainer;