/* eslint-disable jsx-a11y/control-has-associated-label */
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { getUsers, getRolesList } from '../../selectors/admin';
import {
getActiveModal,
checkPermisson,
getModalData,
getPagination,
getUser,
hasRecord,
clearFilters,
getFilterData,
getSelectedTimezone,
} from '../../selectors/common';
import Pagination from '../../components/Pagination';
import { MODALS, SVG_ICONS, PERMISSIONS } from '../../constants';
import SVGComponent from '../../components/SVG/SVGComponent';
import UserModal from '../../components/MenuItems/Admin/UserModal';
import Filter from '../../components/Filter';
import { getCountryDateTime } from '../../utils/common';
import ConfirmationModal from '../../components/Modals/ConfirmationModal';
import TableNoResult from '../../components/TableNoResult';
import { aClearFilterData } from '../../reducers/cashier';
import { aSetClearFilters, aSetFilters, aSetOpenModal } from '../../reducers/common';
import {
aRolesInit,
aSetPagination,
aUserAdd,
aUserEditInfo,
aUserEditRoles,
aUserEditStatus,
aUserList,
aUserRemove,
aUserResetPass,
} from '../../reducers/actions';
const mapToProps = (state) => ({
pagination: getPagination(state),
users: getUsers(state),
activeModal: getActiveModal(state),
roles: getRolesList(state),
checkPermisson: (payload) => checkPermisson(state, payload),
modalData: getModalData(state),
currentUser: getUser(state),
hasRecord: hasRecord(state),
clearFilters: clearFilters(state),
filters: getFilterData(state),
selectedTimezone: getSelectedTimezone(state),
});
const actionsToProps = (dispatch) => ({
fetchUserList: (payload) => dispatch(aUserList(payload)),
setOpenModal: (payload) => dispatch(aSetOpenModal(payload)),
getRoles: (payload) => dispatch(aRolesInit(payload)),
addUser: (payload) => dispatch(aUserAdd(payload)),
userResetPass: (payload) => dispatch(aUserResetPass(payload)),
userRemove: (payload) => dispatch(aUserRemove(payload)),
userEditStatus: (payload) => dispatch(aUserEditStatus(payload)),
userEditRoles: (payload) => dispatch(aUserEditRoles(payload)),
userEditInfo: (payload) => dispatch(aUserEditInfo(payload)),
setFilterData: (payload) => dispatch(aSetFilters(payload)),
setPagination: (payload) => dispatch(aSetPagination(payload)),
setClearFilers: (payload) => dispatch(aSetClearFilters(payload)),
clearFilterData: (payload) => dispatch(aClearFilterData(payload)),
});
/**
* @class
* @property {object} props
* @property {object} props.pagination Pagination data
* @property {Array} props.users User data
* @property {string} props.activeModal Active modal
* @property {Array} props.roles All roles data
* @property {boolean} props.checkPermisson Check if user have
* permission for specific action or view
* @property {object} props.currentUser Information about the current logged in user
* @property {object} props.modalData Modal data
* @property {Function} props.fetchUserList API action to get users list data
* @property {Function} props.setOpenModal Open modal
* @property {Function} props.getRoles API action to get roles data
* @property {Function} props.addUser API action to add new user
* @property {Function} props.userResetPass API action to reset user password
* @property {Function} props.userRemove API action to remove user
* @property {Function} props.userEditStatus API action to edit user status
* @property {Function} props.userEditRoles API action to edit user's roles
* @property {Function} props.userEditInfo API action to edit user info
* @property {Function} props.setFilterData Filter users
* @property {Function} props.setPagination Set pagination data
* @property {object} props.filters Filters data
* @property {Function} props.clearFilterData Clear Filter Data
*/
class UserSettings extends Component {
constructor(props) {
super(props);
/**
* @member {object}
* @property {number|null} openUserMenuUserId
* @property {object|null} operation
* @property {object} operationUser
*/
this.state = {
openUserMenuUserId: null,
operation: null,
operationUser: {},
};
/**
* @member {Array}
* @description Filtering fields settings
*/
this.filterFields = [
{
text: 'Username',
field: 'filter.username',
},
{
text: 'Email',
field: 'filter.email',
},
];
/**
* @member {object}
*/
this.filters = props.filters ? { ...props.filters } : {};
/**
* @member {boolean}
*/
this.addPermission = props.checkPermisson(PERMISSIONS.ADMIN_USERS_ADD);
/**
* @member {boolean}
*/
this.enablePermission = props.checkPermisson(PERMISSIONS.ADMIN_USERS_ENABLE);
/**
* @member {boolean}
*/
this.resetPassPermission = props.checkPermisson(PERMISSIONS.ADMIN_USERS_RESET_PASSWORD);
/**
* @member {boolean}
*/
this.editRolesPermission = props.checkPermisson(PERMISSIONS.ADMIN_USERS_ROLES);
/**
* @member {boolean}
*/
this.deletePermission = props.checkPermisson(PERMISSIONS.ADMIN_USERS_DELETE);
/**
* @member {boolean}
*/
this.updateUserPermission = props.checkPermisson(PERMISSIONS.ADMIN_USERS_UPDATE);
/**
* @member {boolean}
*/
this.hasThreeDots =
this.enablePermission ||
this.resetPassPermission ||
this.editRolesPermission ||
this.updateUserPermission ||
this.deletePermission;
/**
* @member {object}
* @description Confirmation modal data
*/
this.confirmationData = {
REMOVE: {
heading: 'Remove?',
title: 'Are you sure you want to remove user: ',
confirmation: this.userRemove,
},
DISABLE: {
heading: 'Disable?',
title: 'Are you sure you want to disable user: ',
confirmation: this.disableUser,
},
ENABLE: {
heading: 'Enable?',
title: 'Are you sure you want to enable user: ',
confirmation: this.enableUser,
},
RESET: {
heading: 'Reset password?',
title: 'Are you sure you want to reset password for user: ',
confirmation: this.resetPassword,
},
};
}
/**
* Get all roles
*
* @returns {void}
*/
componentDidMount() {
this.props.getRoles({ skipParams: true });
}
/**
* Handle remove user
*
* @function
* @returns {void}
*/
userRemove = () => {
this.props.userRemove({
userId: this.state.operationUser.userId,
username: this.state.operationUser.username,
});
this.closeModal();
};
/**
* Handle disable user
*
* @function
* @returns {void}
*/
disableUser = () => {
this.props.userEditStatus({
userId: this.state.operationUser.userId,
status: -1,
});
this.closeModal();
};
/**
* Handle enable user
*
* @function
* @returns {void}
*/
enableUser = () => {
this.props.userEditStatus({
userId: this.state.operationUser.userId,
status: 1,
username: this.state.operationUser.username,
});
this.closeModal();
};
/**
* Handle reset password
*
* @function
* @returns {void}
*/
resetPassword = () => {
this.props.userResetPass({
userId: this.state.operationUser.userId,
username: this.state.operationUser.username,
email: this.state.operationUser.email,
});
this.closeModal();
};
/**
* Handle user menu click
*
* @function
* @param {number} userId
* @returns {void}
*/
handleUserMenuClick = (userId) => {
if (this.state.openUserMenuUserId === userId) {
this.setState({ openUserMenuUserId: null });
} else {
this.setState({ openUserMenuUserId: userId });
}
};
/**
* Handle user operation click
*
* @function
* @param {object} operation
* @param {object} user
* @returns {void}
*/
handleUserOperationClick = (operation, user) => {
this.props.setOpenModal({ modal: MODALS.USER_CONFIRM });
this.setState({
operation,
operationUser: user,
openUserMenuUserId: null,
});
};
/**
* Handle edit roles
*
* @function
* @param {object} user
* @returns {void}
*/
handleEditRoles = (user) => {
this.setState({
operationUser: user,
openUserMenuUserId: null,
});
this.props.setOpenModal({ modal: MODALS.USER_EDIT });
};
/**
* Handle edit user information
*
* @function
* @param {object} user
* @returns {void}
*/
handleEditUserInfo = (user) => {
this.setState({
operationUser: user,
openUserMenuUserId: null,
});
this.props.setOpenModal({ modal: MODALS.USER_INFO_EDIT });
};
/**
* Close modal
*
* @function
* @returns {void}
*/
closeModal = () => {
this.props.setOpenModal({ modal: '' });
};
/**
* Open add user modal
*
* @function
* @returns {void}
*/
openAddUserModal = () => {
this.props.setOpenModal({ modal: MODALS.USER_ADD });
this.props.setClearFilers({ filterState: true });
};
/**
* Render user row
*
* @function
* @param {object} user
* @returns {void}
*/
renderUserRow = (user) => {
const openClass = user.userId === this.state.openUserMenuUserId ? ' open active' : '';
return (
<tr key={`user${user.userId}`} className={`table-style-row ${openClass}`}>
<td>{user.userId}</td>
<td>{user.username}</td>
<td>{user.name}</td>
<td>{user.email}</td>
<td>{getCountryDateTime(user.insertionDate, this.props.selectedTimezone)}</td>
<td>{user.insertionUser}</td>
<td>{getCountryDateTime(user.lastLogin, this.props.selectedTimezone)}</td>
<td className="text-left">
{user.roles.map((el) => {
const key = `user-${user.userId}-role-${el.id}`;
return (
<div key={key}>
{el.name}
{el.status === -1 && <span className="txt-disable">D</span>}
</div>
);
})}
</td>
<td className="text-left">{user.status === 1 ? 'Enabled' : 'Disabled'}</td>
{this.hasThreeDots ? (
<td className="table-style-icon">
<SVGComponent
onClick={this.handleUserMenuClick.bind(this, user.userId)}
className="icon-xs"
src={`${SVG_ICONS.utility}#dots`}
/>
<div className="table-style-option">
{user.status === 1
? this.enablePermission && (
<div
className="table-style-option-item"
onClick={this.handleUserOperationClick.bind(this, this.confirmationData.DISABLE, user)}
>
Disable
</div>
)
: this.enablePermission && (
<div
className="table-style-option-item"
onClick={this.handleUserOperationClick.bind(this, this.confirmationData.ENABLE, user)}
>
Enable
</div>
)}
{this.resetPassPermission && (
<div
className="table-style-option-item"
onClick={this.handleUserOperationClick.bind(this, this.confirmationData.RESET, user)}
>
Reset Password
</div>
)}
{this.editRolesPermission && (
<div className="table-style-option-item" onClick={this.handleEditRoles.bind(this, user)}>
Edit Roles
</div>
)}
{this.updateUserPermission && (
<div className="table-style-option-item" onClick={this.handleEditUserInfo.bind(this, user)}>
Edit User
</div>
)}
{this.deletePermission && (
<div
className="table-style-option-item"
onClick={this.handleUserOperationClick.bind(this, this.confirmationData.REMOVE, user)}
>
Remove
</div>
)}
</div>
</td>
) : null}
</tr>
);
};
/**
* Render modals
*
* @function
* @returns {view|null}
*/
renderModals = () => {
switch (this.props.activeModal) {
case MODALS.USER_ADD:
return (
<UserModal
roles={this.props.roles}
add
heading="Add user"
save={this.props.addUser}
setOpenModal={this.props.setOpenModal}
/>
);
case MODALS.USER_CONFIRM:
return (
<ConfirmationModal
modalData={{
heading: this.state.operation.heading,
title: this.state.operation.title,
additionalMessages: [this.state.operationUser.username],
}}
cancel={this.closeModal}
confirmation={this.state.operation.confirmation}
/>
);
case MODALS.USER_EDIT:
return (
<UserModal
roles={this.props.roles}
user={this.state.operationUser}
editRoles
heading="Edit user roles"
save={this.props.userEditRoles}
setOpenModal={this.props.setOpenModal}
currentUserId={this.props.currentUser.userId}
fetchUserList={this.props.fetchUserList}
/>
);
case MODALS.USER_INFO_EDIT:
return (
<UserModal
roles={this.props.roles}
user={this.state.operationUser}
editInfo
heading="Edit user"
save={this.props.userEditInfo}
setOpenModal={this.props.setOpenModal}
/>
);
default:
return null;
}
};
/**
* Render
*
* @returns {view}
*/
render() {
const isFaded = this.state.openUserMenuUserId !== null;
return (
<>
<div className="user">
<Filter
filterFields={this.filterFields}
info
setFilterData={this.props.setFilterData}
search={this.props.fetchUserList}
initialApiCall
allowEmpty
clearFilters={this.props.clearFilters}
filtersProps={this.props.filters}
defaultFilter={{}}
filters={this.filters}
clearFilterData={this.props.clearFilterData}
selectedTimezone={this.props.selectedTimezone}
>
{this.addPermission && (
<button id="addUser_filter" type="button" className="btn btn-secondary" onClick={this.openAddUserModal}>
Add User
</button>
)}
</Filter>
<div className="table-wrapper">
<div className="table-mask" />
<div className="table-responsive">
<table className="table-style table-s" id="data-table">
<thead>
<tr>
<th>ID</th>
<th>Username</th>
<th>Name</th>
<th>Email</th>
<th>Creation Date</th>
<th>Created By</th>
<th>Last Login Dt</th>
<th className="text-left">Roles</th>
<th className="text-left">Status</th>
<th />
</tr>
</thead>
<tbody>{this.props.users.map((user) => this.renderUserRow(user))}</tbody>
</table>
{!this.props.hasRecord && <TableNoResult />}
</div>
</div>
{this.renderModals()}
{this.props.pagination.page && (
<Pagination
{...this.props.pagination}
paging={this.props.fetchUserList}
setPagination={this.props.setPagination}
/>
)}
</div>
{isFaded && <div className="overlay-mask bg-grey open" />}
</>
);
}
}
export default connect(mapToProps, actionsToProps)(UserSettings);