diff --git a/packages/strapi-plugin-users-permissions/admin/src/components/InputSearch/index.js b/packages/strapi-plugin-users-permissions/admin/src/components/InputSearch/index.js index 9ca7b42579..d46856cb91 100644 --- a/packages/strapi-plugin-users-permissions/admin/src/components/InputSearch/index.js +++ b/packages/strapi-plugin-users-permissions/admin/src/components/InputSearch/index.js @@ -6,14 +6,33 @@ import React from 'react'; import { FormattedMessage } from 'react-intl'; -import { isEmpty } from 'lodash'; +import { includes, isEmpty, map, toLower } from 'lodash'; import cn from 'classnames'; import PropTypes from 'prop-types'; +import InputSearchLi from 'components/InputSearchLi'; + import styles from './styles.scss'; class InputSearch extends React.Component { // eslint-disable-line react/prefer-stateless-function - state = { errors: [] }; + state = { errors: [], value: '', users: this.props.values, filteredUsers: this.props.values }; + + componentWillReceiveProps(nextProps) { + if (nextProps.didDeleteUser !== this.props.didDeleteUser) { + this.setState({ users: nextProps.values, filteredUsers: nextProps.values }); + } + } + + handleChange = ({ target }) => { + const filteredUsers = isEmpty(target.value) ? + this.state.users + : this.state.users.filter((user) => { + if (includes(toLower(user.name), toLower(target.value))) { + return user; + } + }); + this.setState({ value: target.value, filteredUsers }); + } render() { return ( @@ -29,14 +48,21 @@ class InputSearch extends React.Component { // eslint-disable-line react/prefer- className={cn('form-control', !isEmpty(this.state.errors) ? 'is-invalid': '')} id={this.props.name} name={this.props.name} - onChange={this.props.onChange} - value={this.props.value} + onChange={this.handleChange} + value={this.state.value} placeholder={message} type="text" /> )} +
+ +
); } @@ -54,6 +80,7 @@ InputSearch.proptypes = { labelValues: PropTypes.object, name: PropTypes.string.isRequired, onChange: PropTypes.func.isRequired, + onClickDelete: PropTypes.func.isRequired, value: PropTypes.string, }; diff --git a/packages/strapi-plugin-users-permissions/admin/src/components/InputSearch/styles.scss b/packages/strapi-plugin-users-permissions/admin/src/components/InputSearch/styles.scss index 3547a1c5f0..46309cdd63 100644 --- a/packages/strapi-plugin-users-permissions/admin/src/components/InputSearch/styles.scss +++ b/packages/strapi-plugin-users-permissions/admin/src/components/InputSearch/styles.scss @@ -5,6 +5,7 @@ background-color: rgba(16, 22, 34, 0.02); border: 1px solid #E3E9F3; border-radius: 0.25rem; + border-bottom-left-radius: 0; color: rgba(16, 22, 34, 0.5); line-height: 3.2rem; font-size: 1.3rem; @@ -38,8 +39,23 @@ background-size: 0 !important; border: 1px solid #E3E9F3; border-radius: 0.25rem; + border-bottom-right-radius: 0; line-height: 3.4rem; font-size: 1.3rem; font-family: 'Lato' !important; } } + +.ulContainer { + height: 16.3rem; + overflow: scroll; + border: 1px solid #E3E9F3; + border-top-left-radius: 0; + border-top-right-radius: 0; + border-top: none; + border-radius: 0.25rem; + > ul { + list-style: none; + padding: 1px 0; + } +} diff --git a/packages/strapi-plugin-users-permissions/admin/src/components/InputSearchLi/index.js b/packages/strapi-plugin-users-permissions/admin/src/components/InputSearchLi/index.js new file mode 100644 index 0000000000..9a633a09ae --- /dev/null +++ b/packages/strapi-plugin-users-permissions/admin/src/components/InputSearchLi/index.js @@ -0,0 +1,37 @@ +/** +* +* InputSearchLi +* +*/ + +import React from 'react'; +import PropTypes from 'prop-types'; +import styles from './styles.scss'; + +function InputSearchLi({ item, onClickDelete }) { + return ( +
  • +
    +
    + {item.name} +
    +
    onClickDelete(item)}> + +
    +
    +
  • + ); +} + +InputSearchLi.defaultProps = { + item: { + name: '', + } +} + +InputSearchLi.proptypes = { + item: PropTypes.object, + onClickDelete: PropTypes.func.isRequired, +}; + +export default InputSearchLi; diff --git a/packages/strapi-plugin-users-permissions/admin/src/components/InputSearchLi/styles.scss b/packages/strapi-plugin-users-permissions/admin/src/components/InputSearchLi/styles.scss new file mode 100644 index 0000000000..104d89182d --- /dev/null +++ b/packages/strapi-plugin-users-permissions/admin/src/components/InputSearchLi/styles.scss @@ -0,0 +1,29 @@ +.li { + height: 3.6rem; + margin: 0 !important; + padding: 0rem 1rem; + font-size: 13px; + font-weight: 500; + line-height: 3.6rem; + border-bottom: 1px solid #F6F6F6; + &:hover { + background-color: #FAFAFB; + background-size: 3.6rem; + > div { + >div:last-child { + color: #4B515A; + } + } + } + &:after { + content: ''; + display: block; + } + > div { + display: flex; + justify-content: space-between; + > div:last-child { + color: #B3B5B9; + } + } +} diff --git a/packages/strapi-plugin-users-permissions/admin/src/containers/EditPage/actions.js b/packages/strapi-plugin-users-permissions/admin/src/containers/EditPage/actions.js index 915d4dde7c..06d26e0e67 100644 --- a/packages/strapi-plugin-users-permissions/admin/src/containers/EditPage/actions.js +++ b/packages/strapi-plugin-users-permissions/admin/src/containers/EditPage/actions.js @@ -5,10 +5,19 @@ */ import { + ADD_USER, ON_CANCEL, ON_CHANGE_INPUT, + ON_CLICK_DELETE, } from './constants'; +export function addUser(newUser) { + return { + type: ADD_USER, + newUser, + }; +} + export function onCancel() { return { type: ON_CANCEL, @@ -22,3 +31,10 @@ export function onChangeInput({ target }) { value: target.value, }; } + +export function onClickDelete(itemToDelete) { + return { + type: ON_CLICK_DELETE, + itemToDelete, + }; +} diff --git a/packages/strapi-plugin-users-permissions/admin/src/containers/EditPage/constants.js b/packages/strapi-plugin-users-permissions/admin/src/containers/EditPage/constants.js index 0e04e1468a..a6dc0e7500 100644 --- a/packages/strapi-plugin-users-permissions/admin/src/containers/EditPage/constants.js +++ b/packages/strapi-plugin-users-permissions/admin/src/containers/EditPage/constants.js @@ -4,5 +4,7 @@ * */ +export const ADD_USER = 'UsersPermissions/EditPage/ADD_USER'; export const ON_CANCEL = 'UsersPermissions/EditPage/ON_CANCEL'; export const ON_CHANGE_INPUT = 'UsersPermissions/EditPage/ON_CHANGE_INPUT'; +export const ON_CLICK_DELETE = 'UsersPermissions/EditPage/ON_CLICK_DELETE'; diff --git a/packages/strapi-plugin-users-permissions/admin/src/containers/EditPage/index.js b/packages/strapi-plugin-users-permissions/admin/src/containers/EditPage/index.js index 61072de4a8..d0b8b1d233 100644 --- a/packages/strapi-plugin-users-permissions/admin/src/containers/EditPage/index.js +++ b/packages/strapi-plugin-users-permissions/admin/src/containers/EditPage/index.js @@ -10,7 +10,7 @@ import { connect } from 'react-redux'; import { createStructuredSelector } from 'reselect'; import { bindActionCreators, compose } from 'redux'; import { FormattedMessage } from 'react-intl'; -import { get } from 'lodash'; +import { get, size } from 'lodash'; import cn from 'classnames'; // Design @@ -24,8 +24,10 @@ import injectReducer from 'utils/injectReducer'; // Actions import { + addUser, onCancel, onChangeInput, + onClickDelete, } from './actions'; // Selectors @@ -61,6 +63,7 @@ export class EditPage extends React.Component { // eslint-disable-line react/pre : 'users-permissions.EditPage.header.description'; const pluginHeaderActions = this.props.editPage.showButtons ? this.pluginHeaderActions : []; + return (
    this.props.history.goBack()} /> @@ -113,13 +116,15 @@ export class EditPage extends React.Component { // eslint-disable-line react/pre
    console.log('change')} + labelValues={{ number: size(get(this.props.editPage, ['modifiedData', 'users'])) }} type="text" validations={{ required: true }} - value="" + values={get(this.props.editPage, ['modifiedData', 'users'])} name="users" + onClickDelete={this.props.onClickDelete} /> @@ -133,9 +138,11 @@ export class EditPage extends React.Component { // eslint-disable-line react/pre } EditPage.propTypes = { + addUser: PropTypes.func.isRequired, history: PropTypes.object.isRequired, onCancel: PropTypes.func.isRequired, onChangeInput: PropTypes.func.isRequired, + onClickDelete: PropTypes.func.isRequired, }; const mapStateToProps = createStructuredSelector({ @@ -145,8 +152,10 @@ const mapStateToProps = createStructuredSelector({ function mapDispatchToProps(dispatch) { return bindActionCreators( { + addUser, onCancel, onChangeInput, + onClickDelete, }, dispatch, ); diff --git a/packages/strapi-plugin-users-permissions/admin/src/containers/EditPage/reducer.js b/packages/strapi-plugin-users-permissions/admin/src/containers/EditPage/reducer.js index e351ed0ff9..e1c22c2b5e 100644 --- a/packages/strapi-plugin-users-permissions/admin/src/containers/EditPage/reducer.js +++ b/packages/strapi-plugin-users-permissions/admin/src/containers/EditPage/reducer.js @@ -6,34 +6,55 @@ import { fromJS, List, Map } from 'immutable'; import { + ADD_USER, ON_CANCEL, ON_CHANGE_INPUT, + ON_CLICK_DELETE, } from './constants'; const initialState = fromJS({ + didDeleteUser: false, initialData: Map({ name: '', description: '', - users: List([]), + users: List([ + { name: 'Pierre Burgy' }, + { name: 'Jim Laurie' }, + { name: 'Aurelien Georget' }, + { name: 'Cyril Lopez' }, + ]), }), modifiedData: Map({ name: '', description: '', - users: List([]), + users: List([ + { name: 'Pierre Burgy' }, + { name: 'Jim Laurie' }, + { name: 'Aurelien Georget' }, + { name: 'Cyril Lopez' }, + ]), }), showButtons: false, }); function editPageReducer(state = initialState, action) { switch (action.type) { + case ADD_USER: + return state.updateIn(['modifiedData', 'users'], list => list.push(action.newUser)); case ON_CANCEL: return state .set('showButtons', false) + .set('didDeleteUser', !state.get('didDeleteUser')) .set('modifiedData', state.get('initialData')); case ON_CHANGE_INPUT: return state .set('showButtons', true) .setIn(['modifiedData', action.key], action.value); + case ON_CLICK_DELETE: + return state + .set('didDeleteUser', !state.get('didDeleteUser')) + .set('showButtons', true) + .updateIn(['modifiedData', 'users'], list => list.filter(o => o.name !== action.itemToDelete.name)); default: return state; }