/* eslint-disable sonarjs/no-duplicate-string */
import React, { Component } from 'react';
import { connect } from 'react-redux';
import SVGComponent from '../../SVG/SVGComponent';
import { SVG_ICONS, EDIT_USER_MODAL_MESSAGE, ROLE_STATUS } from '../../../constants';
import validateFields from '../../../utils/validation';
import { aSetClearFilters } from '../../../reducers/common';
/**
* @module MI-Admin/UserModal
*/
const actionsToProps = (dispatch) => ({
setClearFilers: (payload) => dispatch(aSetClearFilters(payload)),
});
/**
* @param roleName
* @param status
* @param roleName
* @param status
* @param ind
* @typedef {object} props
* @property {Array} roles
* @property {boolean} editRoles
* @property {boolean} add
* @property {boolean} editInfo
* @property {object} [user]
* @property {string} currentUserId
* @property {string} heading
* @property {Function} save
* @property {Function} setOpenModal
*/
class UserModal extends Component {
constructor(props) {
super(props);
/**
* @member {object}
* @property {string} username
* @property {string} email
* @property {string} name
* @property {Array} roles
* @property {object} errorMgs
*/
this.state = {
username: this.props.editInfo ? this.props.user.username : '',
email: this.props.editInfo ? this.props.user.email : '',
name: this.props.editInfo ? this.props.user.name : '',
roles: props.editRoles ? props.user.roles.map((el) => el.id) : [''],
errorMgs: {},
dropdownId: null,
};
}
/**
* Updating state fields
*
* @function
* @param {string} field
* @param {Event} e
* @returns {void}
*/
updateField = (field, e) => {
const value = e.target.value;
const change = {};
change[field] = value;
this.setState(change);
};
/**
* Handle select
*
* @function
* @param {number} ind
* @param {number} order
* @returns {void}
*/
handleSelect = (ind, order) => {
const newRoles = this.state.roles.slice(0);
newRoles[ind] = order;
this.setState({
roles: newRoles,
errorMgs: {},
});
};
/**
* Handle add role
*
* @function
* @returns {void}
*/
handleAddRole = () => {
const newRoles = this.state.roles.slice(0);
newRoles.push('');
this.setState({
roles: newRoles,
errorMgs: {},
});
};
/**
* Handle remove role
*
* @function
* @param {numer} ind
* @returns {void}
*/
handleRemoveRole = (ind) => {
const newRoles = this.state.roles.slice(0);
newRoles.splice(ind, 1);
this.setState({
roles: newRoles,
errorMgs: {},
});
};
/**
* Handle click on save
*
* @function
* @returns {void}
*/
handleSave = () => {
const validationParams = [];
if (!this.props.editInfo) {
validationParams.push({
label: 'Role',
fieldName: 'role',
value: this.state.roles.toString().replace(/,/g, ''),
rules: ['mandatory'],
});
}
if (this.props.add || this.props.editInfo) {
if (this.props.add) {
validationParams.push({
label: 'Username',
fieldName: 'username',
value: this.state.username,
rules: ['mandatory'],
});
}
validationParams.push({
label: 'Name',
fieldName: 'name',
value: this.state.name,
rules: ['mandatory'],
});
validationParams.push({
label: 'Email',
fieldName: 'email',
value: this.state.email,
rules: ['mandatory', 'regExp'],
expression: '^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+(?:[a-zA-Z0-9])+@(?:[a-zA-Z0-9]+\\.)+[A-Za-z]+$',
});
}
validateFields(validationParams)
.then(() => {
const body = {
roleIds: this.state.roles.filter((x) => x !== ''),
username: this.state.username.trim(),
name: this.state.name.trim(),
email: this.state.email,
user: this.props.user,
callback: this.props.fetchUserList,
};
this.props.save(body);
})
.catch((errorMgs) => {
this.setState({ errorMgs });
});
};
/**
* Close modal
*
* @returns {void}
*/
cancel = () => {
this.props.setClearFilers({ filterState: false });
this.props.setOpenModal({ modal: '' });
};
/**
* Render item for dropdown
*
* @function
* @param {number} ind
* @returns {view}
*/
renderDropdownItem = (ind) =>
this.props.roles.map((el) => (
<div
className={`dialog__fields-list-item${el.status === ROLE_STATUS.DISABLED ? ' is-disable' : ''}`}
key={`role-opt-${ind}-${el.roleId}`}
id={el.roleId}
onClick={this.handleSelect.bind(this, ind, el.roleId)}
>
<span>{el.name}</span>
{el.status === ROLE_STATUS.DISABLED && <span className="txt"> (disabled)</span>}
</div>
));
/**
* Handle Open Dropdown
*
* @function
* @param {number} dropdownId
* @returns {void}
*/
handleDropdown = (dropdownId) => {
if (dropdownId === this.state.dropdownId) {
this.setState({
dropdownId: null,
});
} else {
this.setState({
dropdownId,
});
}
};
/**
* Return name of role
*
* @function
* @param {ind} ind
* @returns {void}
*/
getRoleName = (ind) => {
let roleName = 'Select Role';
this.props.roles.filter((x) => {
if (this.state.roles[ind] === x.roleId) {
roleName = x.name;
}
});
return roleName;
};
/**
* Return status of role
*
* @function
* @param {ind} ind
* @returns {void}
*/
getStatusRole = (ind) => {
let status = false;
this.props.roles.filter((x) => {
if (this.state.roles[ind] === x.roleId && x.status === ROLE_STATUS.DISABLED) {
status = true;
}
});
return status;
};
/**
* Render role
*
* @function
* @param {numer} ind
* @param {boolean} showDelete
* @returns {view}
*/
renderRole = (ind, showDelete) => (
<div className="dialog__row" key={`role-${ind}`} id={ind}>
<div className="dialog__fields" onClick={() => this.handleDropdown(ind)}>
<label className={`${this.props.editRoles ? 'style-1' : 'style-2'}`}>Role</label>
<div className="d-flex align-items-center position-relative">
<div className={`dialog__fields-select${this.state.dropdownId === ind ? ' open' : ''}`}>
<span>{this.getRoleName(ind)}</span>
{this.getStatusRole(ind) && <span className="txt"> (disabled)</span>}
</div>
<div className="dialog__fields-dropdown">
<div className="dialog__fields-list">{this.renderDropdownItem(ind)}</div>
</div>
{showDelete && (
<div className="dialog__icon">
<SVGComponent
onClick={this.handleRemoveRole.bind(this, ind)}
className="icon-xxs"
src={`${SVG_ICONS.utility}#bin`}
/>
</div>
)}
</div>
{this.state.errorMgs.role}
</div>
</div>
);
/**
* Render user info inputs for add user modal
*
* @function
* @returns {view}
*/
renderUserInfo = () => (
<>
<div className="dialog__row">
<div className="dialog__fields">
<label className="style-2">Username</label>
{this.props.editInfo ? (
<div className="dialog__detail">{this.state.username}</div>
) : (
<input
id="username_userModal"
type="text"
className="form-control"
value={this.state.username}
onChange={this.updateField.bind(this, 'username')}
/>
)}
{this.state.errorMgs.username}
</div>
</div>
<div className="dialog__row">
<div className="dialog__fields">
<label className="style-2">Name</label>
<input
id="name_userModal"
type="text"
className="form-control"
value={this.state.name}
onChange={this.updateField.bind(this, 'name')}
/>
{this.state.errorMgs.name}
</div>
</div>
<div className="dialog__row">
<div className="dialog__fields">
<label className="style-2">Email</label>
<input
id="email_userModal"
type="email"
className="form-control"
value={this.state.email}
onChange={this.updateField.bind(this, 'email')}
/>
{this.state.errorMgs.email}
</div>
</div>
{!this.props.editInfo && this.renderRole(0, false)}
</>
);
/**
* Render user info for edit user modal
*
* @function
* @returns {view}
*/
renderEditUserInfo = () => (
<div className="dialog__info">
<div className="dialog_info-left">
<div className="dialog__info-title">Username</div>
<div className="dialog__info-name">{this.props.user.username}</div>
</div>
<div className="dialog__info-right">
<div className="dialog__info-title">Email</div>
<div className="dialog__info-email">{this.props.user.email}</div>
</div>
</div>
);
/**
* Render message for modal
*
* @function
* @returns {view}
*/
renderModalMessage = () => {
if (this.props.currentUserId === this.props.user.userId) {
return <span>{EDIT_USER_MODAL_MESSAGE.sameUser}</span>;
}
return <span>{EDIT_USER_MODAL_MESSAGE.differentUser}</span>;
};
/**
* Render
*
* @returns {view}
*/
render() {
return (
<div className={`dialog open ${this.props.editRoles && 'drm'}`} id="add-user">
<div className="p-20">
<div className="dialog__heading">
<span className="dialog-title">{this.props.heading}</span>
<SVGComponent onClick={this.cancel} className="icon-xxs dialog__close" src={`${SVG_ICONS.utility}#close`} />
</div>
</div>
{this.props.editRoles && this.renderEditUserInfo()}
<div className="dialog__wrapper">
{!this.props.editRoles && this.renderUserInfo()}
{!this.props.editInfo &&
this.state.roles.map((el, ind) => {
// skip first
if (ind === 0 && this.props.add) return null;
return this.renderRole(ind, this.props.add || this.state.roles.length > 1);
})}
</div>
{!this.props.editInfo && (
<div className="dialog__button" onClick={this.handleAddRole} id="addRole_userModal">
<span>+</span>
Add role
</div>
)}
<div className="p-20">
<div className="dialog__button-wrapper flex-wrap">
<div className="dialog__button-wrapper-txt mb-3">
{this.props.user && !this.props.editInfo && this.renderModalMessage()}
</div>
<button id="cancelBtn_userModal" type="button" className="btn btn-secondary" onClick={this.cancel}>
Cancel
</button>
<button id="saveBtn_userModal" type="button" className="btn btn-primary ml-10" onClick={this.handleSave}>
Save
</button>
</div>
</div>
</div>
);
}
}
export default connect(null, actionsToProps)(UserModal);