156 lines
3.9 KiB
JavaScript
Raw Normal View History

/**
2019-04-16 16:55:53 +02:00
*
* InputSearchContainer
*
*/
2019-09-18 17:39:54 +02:00
import React, { useEffect, useRef, useState } from 'react';
import { FormattedMessage } from 'react-intl';
import PropTypes from 'prop-types';
import { difference, findIndex, has, includes, isEmpty, map, toLower } from 'lodash';
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';
2019-09-17 16:20:45 +02:00
import { Addon, List, Wrapper } from './Components';
2019-09-17 15:24:22 +02:00
2019-09-18 17:39:54 +02:00
function InputSearchContainer({
2019-09-19 14:49:18 +02:00
didDeleteUser,
2019-09-19 10:13:03 +02:00
didFetchUsers,
getUser,
2019-09-18 17:39:54 +02:00
label,
name,
onClickAdd,
onClickDelete,
2019-09-19 14:49:18 +02:00
users,
2019-09-18 17:39:54 +02:00
values,
}) {
const searchInput = useRef(null);
const [filteredUsers, setFilteredUsers] = useState(values);
const [isAdding, setIsAdding] = useState(false);
const [isFocused, setIsFocused] = useState(false);
2019-09-19 14:49:18 +02:00
const [currUsers, setCurrUsers] = useState(values);
2019-09-18 17:39:54 +02:00
const [value, setValue] = useState('');
useEffect(() => {
if (values !== filteredUsers) {
setFilteredUsers(values);
2019-09-19 14:49:18 +02:00
setCurrUsers(values);
}
2019-09-19 16:37:26 +02:00
// eslint-disable-next-line react-hooks/exhaustive-deps
2019-09-19 14:49:18 +02:00
}, [didDeleteUser]);
2019-09-19 10:13:03 +02:00
useEffect(() => {
2019-09-19 16:37:26 +02:00
if (!isEmpty(difference(users, filteredUsers))) {
2019-09-19 14:49:18 +02:00
setFilteredUsers(users);
2019-09-19 16:37:26 +02:00
setIsAdding(true);
2019-09-19 10:13:03 +02:00
}
2019-09-19 16:37:26 +02:00
// eslint-disable-next-line react-hooks/exhaustive-deps
2019-09-19 10:13:03 +02:00
}, [didFetchUsers]);
2019-09-18 17:39:54 +02:00
const handleBlur = () => setIsFocused(prev => !prev);
2019-09-19 14:49:18 +02:00
const handleChange = ({ target: { value } }) => {
2019-09-19 10:13:03 +02:00
const filteredUsers = isEmpty(value)
2019-09-19 14:49:18 +02:00
? currUsers
: currUsers.filter(user => includes(toLower(user.name), toLower(value)));
2019-09-19 10:13:03 +02:00
2019-09-19 14:49:18 +02:00
if (!isEmpty(value)) {
if (isEmpty(filteredUsers)) {
getUser(value);
}
2019-09-19 10:13:03 +02:00
2019-09-19 14:49:18 +02:00
setValue(value);
setFilteredUsers(filteredUsers);
} else {
2019-09-19 10:13:03 +02:00
setValue(value);
setFilteredUsers(values);
setIsAdding(false);
2019-09-19 14:49:18 +02:00
setCurrUsers(values);
2019-09-19 10:13:03 +02:00
}
};
2019-09-18 17:39:54 +02:00
const handleClick = item => {
if (isAdding) {
2017-11-29 12:36:35 +01:00
const id = has(item, '_id') ? '_id' : 'id';
2019-09-18 17:39:54 +02:00
const users = values;
2017-11-29 12:36:35 +01:00
// Check if user is already associated with this role
2017-12-08 10:42:45 +01:00
if (findIndex(users, [id, item[id]]) === -1) {
2019-09-18 17:39:54 +02:00
onClickAdd(item);
2017-11-29 12:36:35 +01:00
users.push(item);
}
2019-09-19 14:49:18 +02:00
searchInput.current.focus();
2017-11-29 12:36:35 +01:00
2019-09-19 14:49:18 +02:00
setValue('');
setIsAdding(false);
setCurrUsers(users);
setFilteredUsers(users);
2017-11-23 13:09:05 +01:00
} else {
2019-09-18 17:39:54 +02:00
onClickDelete(item);
2017-11-23 13:09:05 +01:00
}
2019-04-16 16:55:53 +02:00
};
2017-11-23 13:09:05 +01:00
2019-09-18 17:39:54 +02:00
const handleFocus = () => setIsFocused(prev => !prev);
return (
<Wrapper className="col-md-6">
<Label htmlFor={name} message={label} />
<div className="input-group">
<Addon className={`input-group-addon ${isFocused && 'focus'}`}>
<i className="fas fa-search"></i>
</Addon>
<FormattedMessage id="users-permissions.InputSearch.placeholder">
{message => (
<input
2019-09-19 14:49:18 +02:00
className={`form-control`}
2019-09-18 17:39:54 +02:00
id={name}
name={name}
onBlur={handleBlur}
onChange={handleChange}
onFocus={handleFocus}
value={value}
placeholder={message}
type="text"
ref={searchInput}
/>
)}
</FormattedMessage>
</div>
<List className={isFocused && 'focused'}>
<ul>
{map(filteredUsers, user => (
<InputSearchLi
key={user.id || user._id}
item={user}
isAdding={isAdding}
onClick={handleClick}
/>
))}
</ul>
</List>
</Wrapper>
);
}
InputSearchContainer.defaultProps = {
2017-11-23 12:43:40 +01:00
users: [],
2017-11-08 16:06:21 +01:00
values: [],
};
InputSearchContainer.propTypes = {
2019-09-19 14:49:18 +02:00
didDeleteUser: PropTypes.bool.isRequired,
2017-11-23 12:43:40 +01:00
didFetchUsers: PropTypes.bool.isRequired,
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;