Merge branch 'develop' into fix/WMS-66
This commit is contained in:
@@ -6,13 +6,13 @@ import TransferList from 'components/MDTransferList';
|
||||
import './AllocationManager.component.scss';
|
||||
|
||||
const AllocationManager = props => {
|
||||
const {boxStyleOverride, component, gridStyleOverride, initlist, list, matchProp, md, onChange, title, variant, xs} = props;
|
||||
const {allDisabled, boxStyleOverride, component, gridStyleOverride, allocatedList, list, matchProp, md, onChange, title, variant, xs} = props;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const [allocationStatus, setAllocationStatus] = useState();
|
||||
|
||||
const handleAllocationChange = state => {
|
||||
setAllocationStatus(state);
|
||||
onChange && onChange(state.assigned?.map(obj => obj._id).join(','));
|
||||
onChange && onChange(state.assigned);
|
||||
};
|
||||
|
||||
return <Grid item className='c-AllocationManager' xs={xs || 12} md={md || 6} sx={gridStyleOverride}>
|
||||
@@ -29,16 +29,17 @@ const AllocationManager = props => {
|
||||
<Typography gutterBottom variant={variant || 'h6'} component={component || 'div'}>
|
||||
{title}
|
||||
</Typography>
|
||||
<TransferList list={list || []} initlist={initlist} matchProp={matchProp} onChange={handleAllocationChange} />
|
||||
<TransferList allDisabled={allDisabled} list={list || []} allocatedList={allocatedList} matchProp={matchProp} onChange={handleAllocationChange} />
|
||||
</MDBox>
|
||||
</Grid>;
|
||||
};
|
||||
|
||||
AllocationManager.propTypes = {
|
||||
allDisabled: PropTypes.bool,
|
||||
boxStyleOverride: PropTypes.object,
|
||||
component: PropTypes.string,
|
||||
gridStyleOverride: PropTypes.object,
|
||||
initlist: PropTypes.oneOfType([
|
||||
allocatedList: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.array
|
||||
]),
|
||||
|
||||
@@ -43,7 +43,7 @@ const useStyles = makeStyles({
|
||||
}
|
||||
});
|
||||
|
||||
export default function TransferList({list, initlist, matchProp, onChange}) {
|
||||
export default function TransferList({allDisabled, list, allocatedList, matchProp, onChange}) {
|
||||
const classes = useStyles();
|
||||
const [checked, setChecked] = useState([]);
|
||||
const [left, setLeft] = useState(list || []);
|
||||
@@ -53,14 +53,14 @@ export default function TransferList({list, initlist, matchProp, onChange}) {
|
||||
const rightChecked = intersection(checked, right);
|
||||
|
||||
useEffect(() => {
|
||||
if (initlist) {
|
||||
const initlistClone = typeof initlist === 'object' ? initlist : initlist.split(',');
|
||||
const left = notBy(matchProp, list, initlistClone);
|
||||
const right = intersectionBy(matchProp, list, initlistClone);
|
||||
if (typeof allocatedList === 'string') {
|
||||
const allocatedListClone = typeof allocatedList === 'object' ? allocatedList : allocatedList.split(',');
|
||||
const left = notBy(matchProp, list, allocatedListClone);
|
||||
const right = intersectionBy(matchProp, list, allocatedListClone);
|
||||
setLeft(left);
|
||||
setRight(right);
|
||||
}
|
||||
}, []);
|
||||
}, [allocatedList]);
|
||||
|
||||
const handleToggle = (value) => () => {
|
||||
const currentIndex = checked.indexOf(value);
|
||||
@@ -116,7 +116,7 @@ export default function TransferList({list, initlist, matchProp, onChange}) {
|
||||
const labelId = `transfer-list-item-${value}-label`;
|
||||
|
||||
return (
|
||||
<ListItem button key={value + '-' + key} role="listitem" onClick={handleToggle(item)}>
|
||||
<ListItem button disabled={allDisabled} key={value + '-' + key} role="listitem" onClick={handleToggle(item)}>
|
||||
<ListItemIcon className={classes.unsetwidth}>
|
||||
<Checkbox
|
||||
disableRipple
|
||||
@@ -205,7 +205,8 @@ export default function TransferList({list, initlist, matchProp, onChange}) {
|
||||
}
|
||||
|
||||
TransferList.propTypes = {
|
||||
initlist: PropTypes.oneOfType([
|
||||
allDisabled: PropTypes.bool,
|
||||
allocatedList: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.array
|
||||
]),
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { styled } from '@mui/material/styles';
|
||||
import { TableBody, TableCell, TableRow } from '@mui/material';
|
||||
import BasicTable from 'components/BasicTable';
|
||||
import TabPanel from 'components/Tabs';
|
||||
import EditIcon from '@mui/icons-material/Edit';
|
||||
import "./PwTablePanel.component.scss";
|
||||
import './PwTablePanel.component.scss';
|
||||
|
||||
const PwTablePanel = props => {
|
||||
const {backgroundColor, classes, color, headCells, id, index, navUrl, records, table, value} = props;
|
||||
const { backgroundColor, classes, color, headCells, id, loader, index, navUrl, records, table, value } = props;
|
||||
const navigate = useNavigate();
|
||||
|
||||
const StyledTableRow = styled(TableRow)(({ theme }) => ({
|
||||
@@ -18,7 +18,7 @@ const PwTablePanel = props => {
|
||||
}
|
||||
}));
|
||||
|
||||
const rowRenders = ({records, headers, navUrl, table}) => {
|
||||
const rowRenders = ({ records, headers, navUrl, table }) => {
|
||||
return records && records.map((record, keyouter) => {
|
||||
return <StyledTableRow key={record.id + '-' + keyouter}>
|
||||
{headers.map((columnConfig, key) => {
|
||||
@@ -26,15 +26,15 @@ const PwTablePanel = props => {
|
||||
const isAfter = columnConfig.placement && columnConfig.placement === 'after';
|
||||
const limitWidth = columnConfig.limitWidth;
|
||||
return <TableCell key={key} className={`${isAfter ? 'position-relative pe-5' : ''}${limitWidth ? ' overflow-auto ' + classes.limitWidth : ''}`}
|
||||
onClick={() => canEdit && navigate(navUrl, {state: {[table]: record}})}>
|
||||
onClick={() => canEdit && navigate(navUrl, { state: { [table]: record } })}>
|
||||
{canEdit
|
||||
? isAfter
|
||||
? <span className={classes.iconwrap}>
|
||||
{columnConfig.value(record)}
|
||||
<EditIcon className={classes.iconSize + ' ' + classes.rightPlaced}/>
|
||||
<EditIcon className={classes.iconSize + ' ' + classes.rightPlaced} />
|
||||
</span>
|
||||
: <span className={classes.iconwrap}>
|
||||
<EditIcon className={classes.iconSize}/>
|
||||
<EditIcon className={classes.iconSize} />
|
||||
{columnConfig.value(record)}
|
||||
</span>
|
||||
: <span>{columnConfig.value(record)}</span>}
|
||||
@@ -52,13 +52,13 @@ const PwTablePanel = props => {
|
||||
backgroundColor={backgroundColor || '#007AFF'}
|
||||
color={color || '#fff'}
|
||||
>
|
||||
<TableBody>
|
||||
{records && records.length > 0 && rowRenders({records, headers: headCells, navUrl, table})}
|
||||
</TableBody>
|
||||
{records && records.length > 0 && <TableBody className={loader ? 'loader' : ''}>
|
||||
{rowRenders({ records, headers: headCells, navUrl, table })}
|
||||
</TableBody>}
|
||||
</BasicTable>
|
||||
{(!records || records.length === 0)
|
||||
&& <p className="mx-3 my-5 d-flex justify-content-center align-items-center h4">No Records to Display</p>}
|
||||
</TabPanel>
|
||||
&& <p className='mx-3 my-5 d-flex justify-content-center align-items-center h4'>No Records to Display</p>}
|
||||
</TabPanel>;
|
||||
};
|
||||
|
||||
PwTablePanel.propTypes = {
|
||||
@@ -68,10 +68,11 @@ PwTablePanel.propTypes = {
|
||||
headCells: PropTypes.array,
|
||||
id: PropTypes.string,
|
||||
index: PropTypes.number,
|
||||
loader: PropTypes.bool,
|
||||
navUrl: PropTypes.string,
|
||||
records: PropTypes.array,
|
||||
table: PropTypes.string,
|
||||
value: PropTypes.number
|
||||
};
|
||||
|
||||
export default PwTablePanel;
|
||||
export default PwTablePanel;
|
||||
|
||||
@@ -56,12 +56,13 @@ const IOSSwitch = styled((props) => (
|
||||
}
|
||||
}));
|
||||
|
||||
export default function Switch({ checked, onChange, name }) {
|
||||
return <IOSSwitch checked={checked} sx={{ m: 1 }} name={name} onChange={onChange} />;
|
||||
export default function Switch({ disabled, checked, onChange, name }) {
|
||||
return <IOSSwitch disabled={disabled} checked={checked} sx={{ m: 1 }} name={name} onChange={onChange} />;
|
||||
}
|
||||
|
||||
Switch.propTypes = {
|
||||
checked: PropTypes.any,
|
||||
disabled: PropTypes.bool,
|
||||
name: PropTypes.any,
|
||||
onChange: PropTypes.any
|
||||
};
|
||||
|
||||
@@ -25,22 +25,22 @@ const useStyles = makeStyles(() => ({
|
||||
}));
|
||||
|
||||
const Toggles = props => {
|
||||
const {boxSx, gridStyleOverride, inittoggles, md, onChange, title, toggles, typoComponent, typoSx, typoVariant, xs} = props;
|
||||
const {allDisabled, boxSx, gridStyleOverride, selectedToggles, md, onChange, title, toggles, typoComponent, typoSx, typoVariant, xs} = props;
|
||||
const [toggleState, updateToggleState] = useState({});
|
||||
const classes = useStyles();
|
||||
|
||||
useEffect(() => {
|
||||
if (inittoggles && typeof inittoggles === 'string') {
|
||||
const initToggleState = {};
|
||||
inittoggles.split(',').forEach(iToggle => initToggleState[iToggle] = true);
|
||||
updateToggleState(initToggleState);
|
||||
if (typeof selectedToggles === 'string') {
|
||||
const selectedToggleState = {};
|
||||
selectedToggles.split(',').forEach(iToggle => selectedToggleState[iToggle] = true);
|
||||
updateToggleState(selectedToggleState);
|
||||
}
|
||||
}, []);
|
||||
}, [selectedToggles]);
|
||||
|
||||
const handleToggle = (e, toggle) => {
|
||||
const toggleStateClone = {...toggleState, [toggle]: e.target.checked};
|
||||
updateToggleState(toggleStateClone);
|
||||
onChange && onChange(Object.keys(toggleStateClone).join(','));
|
||||
onChange && onChange(toggleStateClone);
|
||||
};
|
||||
|
||||
const switchRenders = toggles => toggles && toggles.map((toggle, key) => {
|
||||
@@ -49,7 +49,7 @@ const Toggles = props => {
|
||||
return <MDBox key={key} display='flex' justifyContent='space-between' alignItems='center' lineHeight={1} className={classes.switchSpacer}
|
||||
sx={{ marginBottom: '20px !important' }}>
|
||||
<MDTypography variant='body2'>{toggle}</MDTypography>
|
||||
<Switch id={id} checked={toggleState[toggle] === undefined ? false : toggleState[toggle]} onChange={e => handleToggle(e, toggle)} />
|
||||
<Switch disabled={allDisabled} id={id} checked={toggleState[toggle] === undefined ? false : toggleState[toggle]} onChange={e => handleToggle(e, toggle)} />
|
||||
</MDBox>;
|
||||
});
|
||||
|
||||
@@ -65,9 +65,10 @@ const Toggles = props => {
|
||||
};
|
||||
|
||||
Toggles.propTypes = {
|
||||
allDisabled: PropTypes.bool,
|
||||
boxSx: PropTypes.object,
|
||||
gridStyleOverride: PropTypes.object,
|
||||
inittoggles: PropTypes.string,
|
||||
selectedToggles: PropTypes.string,
|
||||
md: PropTypes.number,
|
||||
onChange: PropTypes.func,
|
||||
title: PropTypes.string,
|
||||
|
||||
@@ -17,7 +17,7 @@ import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||
import './main.scss';
|
||||
import './main.css';
|
||||
import App from 'App';
|
||||
|
||||
// Soft UI Context Provider
|
||||
|
||||
67
src/main.css
Normal file
67
src/main.css
Normal file
@@ -0,0 +1,67 @@
|
||||
fieldset legend {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.loader {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.loader:before {
|
||||
display: block;
|
||||
content: "";
|
||||
position: absolute;
|
||||
background-color: transparent;
|
||||
background-image: url("./assets/images/favicon.png");
|
||||
background-size: 3rem;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
-webkit-animation: rotating 2s linear infinite;
|
||||
-moz-animation: rotating 2s linear infinite;
|
||||
-ms-animation: rotating 2s linear infinite;
|
||||
-o-animation: rotating 2s linear infinite;
|
||||
animation: rotating 2s linear infinite;
|
||||
z-index: 1050;
|
||||
}
|
||||
|
||||
.loader:after {
|
||||
content: "";
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
position: absolute;
|
||||
z-index: 1040;
|
||||
}
|
||||
|
||||
@-webkit-keyframes rotating {
|
||||
from {
|
||||
-webkit-transform: rotate(0deg);
|
||||
-o-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: rotateY(360deg);
|
||||
-o-transform: rotateY(360deg);
|
||||
transform: rotateY(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes rotating {
|
||||
from {
|
||||
-ms-transform: rotate(0deg);
|
||||
-moz-transform: rotate(0deg);
|
||||
-webkit-transform: rotate(0deg);
|
||||
-o-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
-ms-transform: rotateY(360deg);
|
||||
-moz-transform: rotateY(360deg);
|
||||
-webkit-transform: rotateY(360deg);
|
||||
-o-transform: rotateY(360deg);
|
||||
transform: rotateY(360deg);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
fieldset {
|
||||
legend {
|
||||
width: 0;
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ import WarehouseActions, { WarehouseSelectors } from 'redux/WarehouseRedux';
|
||||
import InventoryActions, { InventorySelectors } from 'redux/InventoryRedux';
|
||||
import RolesActions, { RolesSelectors } from 'redux/RolesRedux';
|
||||
import PermissionsActions, { PermissionsSelectors } from 'redux/PermissionsRedux';
|
||||
import { AuthSelectors } from 'redux/AuthRedux';
|
||||
// import { AuthSelectors } from 'redux/AuthRedux';
|
||||
import UsersActions from 'redux/UsersRedux';
|
||||
|
||||
import schema from 'services/ValidationServices';
|
||||
@@ -73,12 +73,13 @@ function CreateEditUser(props) {
|
||||
const warehouses = useSelector(WarehouseSelectors.getWarehouseDetail);
|
||||
const inventories = useSelector(InventorySelectors.getInventoryDetail);
|
||||
const actions = useSelector(PermissionsSelectors.getActionsDetail);
|
||||
const permissions = useSelector(PermissionsSelectors.getPermissionsDetail);
|
||||
const currentUser = useSelector(AuthSelectors.getUser);
|
||||
const visibilities = useSelector(PermissionsSelectors.getPermissionsDetail);
|
||||
// const currentUser = useSelector(AuthSelectors.getUser);
|
||||
const location = useLocation();
|
||||
const [editedUser, setEditedUser] = useState(location?.state?.user);
|
||||
const [selectedRoles, setSelectedRoles] = useState([]);
|
||||
const [uploadedImg, setUploadedImg] = useState();
|
||||
// const [selectedPermissions, setSelectedPermissions] = useState({});
|
||||
|
||||
useEffect(() => {
|
||||
if (context === 'edit') {
|
||||
@@ -118,7 +119,7 @@ function CreateEditUser(props) {
|
||||
method: 'get'
|
||||
})
|
||||
);
|
||||
(!permissions || permissions.length === 0) &&
|
||||
(!visibilities || visibilities.length === 0) &&
|
||||
dispatch(
|
||||
PermissionsActions.getPermissionsAction({
|
||||
loader: 'loading-request',
|
||||
@@ -149,10 +150,10 @@ function CreateEditUser(props) {
|
||||
visibilities: '',
|
||||
isActive: true,
|
||||
image: '',
|
||||
createdBy: currentUser ? currentUser.fullName : '',
|
||||
createdAt: new Date(),
|
||||
updatedBy: currentUser ? currentUser.fullName : '',
|
||||
updatedAt: new Date()
|
||||
createdBy: '',
|
||||
createdAt: '',
|
||||
updatedBy: '',
|
||||
updatedAt: ''
|
||||
} : {
|
||||
fullName: editedUser ? editedUser.fullName : '',
|
||||
phoneNumber: editedUser ? editedUser.phoneNumber : '',
|
||||
@@ -233,9 +234,31 @@ function CreateEditUser(props) {
|
||||
}
|
||||
});
|
||||
formik.handleChange('roles')(uniqueRoles.map((role) => role.name).join());
|
||||
aggregatePermissions(uniqueRoles);
|
||||
setSelectedRoles(uniqueRoles);
|
||||
};
|
||||
|
||||
const aggregatePermissions = roles => {
|
||||
const actions = [], visibilities = [], warehouses = [], inventories = [];
|
||||
roles.forEach(role => {
|
||||
if (role.permissions) {
|
||||
const currActions = role.permissions.actions;
|
||||
const currVisibilities = role.permissions.allowedUIModules;
|
||||
const currWarehouseScopes = role.permissions.warehouseScopes;
|
||||
const currInventoryScopes = role.permissions.inventoryScopes;
|
||||
currActions.forEach(ac => actions.indexOf(ac) === -1 && actions.push(ac));
|
||||
currVisibilities.forEach(vi => visibilities.indexOf(vi) === -1 && visibilities.push(vi));
|
||||
currWarehouseScopes.forEach(currWh => warehouses.findIndex(wh => wh.id === currWh.id) === -1 && warehouses.push(currWh));
|
||||
currInventoryScopes.forEach(currInv => inventories.findIndex(inv => inv.id === currInv.id) === -1 && inventories.push(currInv));
|
||||
// setSelectedPermissions({...selectedPermissions, actions});
|
||||
}
|
||||
});
|
||||
formik.handleChange('actions')(actions.join(','));
|
||||
formik.handleChange('visibilities')(visibilities.join(','));
|
||||
formik.handleChange('warehouses')(warehouses.map(wh => wh.id).join(','));
|
||||
formik.handleChange('inventories')(inventories.map(inv => inv.id).join(','));
|
||||
};
|
||||
|
||||
const handleFileChange = e => {
|
||||
const [file] = e.target.files;
|
||||
if (file) {
|
||||
@@ -456,40 +479,60 @@ function CreateEditUser(props) {
|
||||
</MDBox>
|
||||
<Grid container spacing={4} sx={{ marginTop: '-6px' }}>
|
||||
<AllocationManager
|
||||
allDisabled={selectedRoles?.length > 0}
|
||||
name="warehouses"
|
||||
gridStyleOverride={{ paddingLeft: '4rem !important' }}
|
||||
initlist={formik.values.warehouses}
|
||||
allocatedList={formik.values.warehouses}
|
||||
list={warehouses}
|
||||
matchProp={{ a: '_id' }}
|
||||
title="Warehouse"
|
||||
onChange={(val) => formik.handleChange('warehouses')(val)}
|
||||
onChange={val => {
|
||||
val = val?.map(obj => obj._id).join(',');
|
||||
// setSelectedPermissions({...selectedPermissions, warehouses: val});
|
||||
formik.handleChange('warehouses')(val);
|
||||
}}
|
||||
/>
|
||||
<AllocationManager
|
||||
allDisabled={selectedRoles?.length > 0}
|
||||
name="inventories"
|
||||
gridStyleOverride={{ paddingRight: '2rem' }}
|
||||
initlist={formik.values.inventories}
|
||||
allocatedList={formik.values.inventories}
|
||||
list={inventories}
|
||||
matchProp={{ a: '_id' }}
|
||||
title="Inventory"
|
||||
onChange={(val) => formik.handleChange('inventories')(val)}
|
||||
onChange={val => {
|
||||
val = val?.map(obj => obj._id).join(',');
|
||||
// setSelectedPermissions({...selectedPermissions, inventories: val});
|
||||
formik.handleChange('inventories')(val);
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid container spacing={4} sx={{ marginTop: '12px'}}>
|
||||
<Toggles
|
||||
allDisabled={selectedRoles?.length > 0}
|
||||
name="actions"
|
||||
gridStyleOverride={{ paddingLeft: '4rem !important' }}
|
||||
title="Actions"
|
||||
toggles={actions}
|
||||
inittoggles={formik.values.actions}
|
||||
onChange={(val) => formik.handleChange('actions')(val)}
|
||||
selectedToggles={formik.values.actions}
|
||||
onChange={val => {
|
||||
val = Object.keys(val).join(',');
|
||||
// setSelectedPermissions({...selectedPermissions, actions: val});
|
||||
formik.handleChange('actions')(val);
|
||||
}}
|
||||
/>
|
||||
<Toggles
|
||||
allDisabled={selectedRoles?.length > 0}
|
||||
name="visibilities"
|
||||
gridStyleOverride={{ paddingRight: '2rem' }}
|
||||
title="Application"
|
||||
toggles={permissions}
|
||||
inittoggles={formik.values.visibilities}
|
||||
onChange={(val) => formik.handleChange('visibilities')(val)}
|
||||
toggles={visibilities}
|
||||
selectedToggles={formik.values.visibilities}
|
||||
onChange={val => {
|
||||
val = Object.keys(val).join(',');
|
||||
// setSelectedPermissions({...selectedPermissions, visibilities: val});
|
||||
formik.handleChange('visibilities')(val);
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<MDBox
|
||||
|
||||
@@ -96,6 +96,8 @@ function UserAccessScreen() {
|
||||
const permissions = useSelector(PermissionsSelectors.getPermissionsDetail);
|
||||
const [userRecords, setUserRecords] = useState([]);
|
||||
const [rolesRecords, setRoleRecords] = useState([]);
|
||||
const [userLoader, setUserLoader] = useState(false);
|
||||
const [roleLoader, setRoleLoader] = useState(false);
|
||||
const [originalUserRecords, setOriginalUserRecords] = useState([]);
|
||||
const [originalRolesRecords, setOriginalRoleRecords] = useState([]);
|
||||
const navigate = useNavigate();
|
||||
@@ -143,35 +145,54 @@ function UserAccessScreen() {
|
||||
|
||||
const rolesHeadCells = [
|
||||
{ id: 'role', label: 'Role', isEditAnchor: true, placement: 'after', value: record => record.name },
|
||||
{ id: 'warehouse', label: 'Warehouse', limitWidth: true, value: record => warehouses && record.permissions?.warehouseScopes && record.permissions?.warehouseScopes?.length === warehouses?.length ? 'All' : record.permissions?.warehouseScopes ? record.permissions?.warehouseScopes.map(sc => sc.name).join(', ') : ''},
|
||||
{ id: 'inventory', label: 'Inventories', limitWidth: true, value: record => inventories && record.permissions?.inventoryScopes && record.permissions?.inventoryScopes?.length === inventories?.length ? 'All' : record.permissions?.inventoryScopes ? record.permissions?.inventoryScopes.map(sc => sc.name).join(', ') : ''},
|
||||
{ id: 'actions', label: 'Actions', limitWidth: true, value: record => actions && record.permissions?.actions && record.permissions?.actions?.length === actions?.length ? 'All' : record.permissions?.actions ? record.permissions?.actions.join(', ') : ''},
|
||||
{ id: 'visibilities', label: 'App Modules', limitWidth: true, value: record => permissions && record.permissions?.allowedUIModules && record.permissions?.allowedUIModules?.length === permissions?.length ? 'All' : record.permissions?.allowedUIModules ? record.permissions?.allowedUIModules.join(', ') : ''},
|
||||
{ id: 'warehouse', label: 'Warehouse', limitWidth: true, value: record => {
|
||||
const roleWh = record.permissions?.warehouseScopes;
|
||||
return warehouses && roleWh && roleWh.length === warehouses.length ? 'All' : roleWh
|
||||
? warehouses.filter(wh => roleWh.findIndex(whCurr => whCurr.id === wh._id) > -1).map(wh => wh.name).join(', ') : '';
|
||||
}
|
||||
},
|
||||
{ id: 'inventory', label: 'Inventories', limitWidth: true, value: record => {
|
||||
const roleIn = record.permissions?.inventoryScopes;
|
||||
return inventories && roleIn && roleIn.length === inventories.length ? 'All' : roleIn
|
||||
? inventories.filter(inv => roleIn.findIndex(inCurr => inCurr.id === inv._id) > -1).map(inv => inv.name).join(', ') : '';
|
||||
}
|
||||
},
|
||||
{ id: 'actions', label: 'Actions', limitWidth: true, value: record => actions && record.permissions?.actions
|
||||
&& record.permissions?.actions?.length === actions?.length ? 'All' : record.permissions?.actions
|
||||
? record.permissions?.actions.join(', ') : ''},
|
||||
{ id: 'visibilities', label: 'App Modules', limitWidth: true, value: record => permissions && record.permissions?.allowedUIModules
|
||||
&& record.permissions?.allowedUIModules?.length === permissions?.length ? 'All' : record.permissions?.allowedUIModules
|
||||
? record.permissions?.allowedUIModules.join(', ') : ''},
|
||||
{ id: 'status', label: 'Status', value: record => record.status === 'ACTIVE' ? <span className={classes.statusActive}>Active</span>
|
||||
: <span className={classes.statusInactive}>Inactive</span> }
|
||||
];
|
||||
|
||||
const usersHandler = () => {
|
||||
setUserLoader(true);
|
||||
dispatch(
|
||||
UsersActions.getUsersAction({
|
||||
loader: 'loading-request',
|
||||
slug: API.GET_USERS_DATA,
|
||||
method: 'get'
|
||||
method: 'get',
|
||||
callback: setUserLoader
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const rolesHandler = () => {
|
||||
setRoleLoader(true);
|
||||
dispatch(
|
||||
RolesActions.getRolesAction({
|
||||
loader: 'loading-request',
|
||||
slug: API.GET_ROLES_DATA,
|
||||
method: 'get'
|
||||
method: 'get',
|
||||
callback: setRoleLoader
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
useMemo(() => rolesHandler(), []);
|
||||
useMemo(() => usersHandler(), []);
|
||||
|
||||
useEffect(() => {
|
||||
if (usersData.length) {
|
||||
@@ -188,7 +209,7 @@ function UserAccessScreen() {
|
||||
let roles = JSON.parse(JSON.stringify(rolesData));
|
||||
roles = roles.map((item) => {
|
||||
item.name = item.name.split('-').join(' ').toUpperCase();
|
||||
item.permissions = item.permissions?.allowedUIModules?.join(',');
|
||||
// item.permissions = item.permissions?.allowedUIModules?.join(',');
|
||||
if (!item.permissions) {
|
||||
item.permissions = 'NA';
|
||||
}
|
||||
@@ -209,7 +230,7 @@ function UserAccessScreen() {
|
||||
let records = currentTab === 0 ? originalUserRecords : originalRolesRecords;
|
||||
records = JSON.parse(JSON.stringify(records));
|
||||
records.forEach(record => record.status = record.status ? 'ACTIVE' : 'INACTIVE');
|
||||
let searchList = currentTab === 0 ? ['fullName', 'phoneNumber', 'role_name', 'status'] : ['name', 'permissions', 'status']
|
||||
let searchList = currentTab === 0 ? ['fullName', 'phoneNumber', 'role_name', 'status'] : ['name', 'permissions', 'status'];
|
||||
const setter = currentTab === 0 ? setUserRecords : setRoleRecords;
|
||||
searchList = searchList.concat(['createdBy.fullName', 'createdAt', 'updatedBy.fullName', 'updatedAt']);
|
||||
const filteredRecords = records.filter(record => searchList.some(field => {
|
||||
@@ -220,7 +241,7 @@ function UserAccessScreen() {
|
||||
field = field[1];
|
||||
}
|
||||
return recordInner && recordInner[field] !== undefined && typeof recordInner[field] === 'string'
|
||||
&& recordInner[field].toLowerCase().indexOf(value?.toLowerCase()) > -1
|
||||
&& recordInner[field].toLowerCase().indexOf(value?.toLowerCase()) > -1;
|
||||
}));
|
||||
records.forEach(record => record.status = record.status === 'ACTIVE');
|
||||
setter(filteredRecords);
|
||||
@@ -238,7 +259,7 @@ function UserAccessScreen() {
|
||||
]}
|
||||
/>
|
||||
<MDBox px={5} py={3}>
|
||||
<Grid container spacing={1} className={classes.margin + " w-100 ms-0"}>
|
||||
<Grid container spacing={1} className={classes.margin + ' w-100 ms-0'}>
|
||||
<Grid item xs={12} sm={4} md={4} className="ps-0 pt-0">
|
||||
<Tabs value={value} className={`p-0 h-100 ${classes.tabs}`} onChange={handleTabs}>
|
||||
<Tab label="Users" onClick={() => usersHandler()} />
|
||||
@@ -275,10 +296,10 @@ function UserAccessScreen() {
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<PwTablePanel classes={classes} headCells={userHeadCells} id="user-list" index={0}
|
||||
records={userRecords} navUrl='/setup/users-access/edit-user' value={value} />
|
||||
<PwTablePanel classes={classes} headCells={rolesHeadCells} id="role-list" index={1}
|
||||
records={rolesRecords} navUrl='/setup/users-access/edit-role' value={value} />
|
||||
<PwTablePanel classes={classes} headCells={userHeadCells} id="user-list" index={0} loader={userLoader}
|
||||
records={userRecords} navUrl='/setup/users-access/edit-user' table="user" value={value} />
|
||||
<PwTablePanel classes={classes} headCells={rolesHeadCells} id="role-list" index={1} loader={roleLoader}
|
||||
records={rolesRecords} navUrl='/setup/users-access/edit-role' table="role" value={value} />
|
||||
</Grid>
|
||||
</MDBox>
|
||||
</DashboardLayout>
|
||||
|
||||
@@ -187,11 +187,18 @@ const protectedRoutes = [
|
||||
component: <CreateEditUser context='new' />
|
||||
},
|
||||
{
|
||||
name: 'Edot User',
|
||||
name: 'Edit User',
|
||||
key: 'edit-user',
|
||||
route: '/setup/users-access/edit-user',
|
||||
hide: true,
|
||||
component: <CreateEditUser context='edit' />
|
||||
},
|
||||
{
|
||||
name: 'Edit Role',
|
||||
key: 'edit-role',
|
||||
route: '/setup/users-access/edit-role',
|
||||
hide: true,
|
||||
component: <CreateEditUserRole context='edit' />
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { AuthorizedAPI } from 'config';
|
||||
import { takeLatest, call, put } from 'redux-saga/effects';
|
||||
import { toast } from 'react-toastify';
|
||||
import RolesActions, { RolesTypes } from '../redux/RolesRedux';
|
||||
import ApiServices from 'services/API/ApiServices';
|
||||
|
||||
@@ -10,6 +11,7 @@ export function* onRequestRolesData({ payload }) {
|
||||
payload?.slug,
|
||||
payload?.data
|
||||
);
|
||||
payload?.callback && payload?.callback(false);
|
||||
if (response?.status === 200) {
|
||||
yield put(
|
||||
RolesActions.getRolesSuccess({
|
||||
@@ -18,6 +20,7 @@ export function* onRequestRolesData({ payload }) {
|
||||
})
|
||||
);
|
||||
} else {
|
||||
toast('Failed to fetch roles');
|
||||
payload.onFailedRolesData(response.data.error);
|
||||
yield put(
|
||||
RolesActions.getRolesFailure({
|
||||
|
||||
@@ -11,6 +11,7 @@ export function* onRequestUsersData({ payload }) {
|
||||
payload?.slug,
|
||||
payload?.data
|
||||
);
|
||||
payload?.callback && payload?.callback(false);
|
||||
if (response?.status === 200) {
|
||||
yield put(
|
||||
UsersActions.getUsersSuccess({
|
||||
@@ -19,6 +20,7 @@ export function* onRequestUsersData({ payload }) {
|
||||
})
|
||||
);
|
||||
} else {
|
||||
toast('Failed to fetch user list');
|
||||
payload.onFailedUsersData(response.data.error);
|
||||
yield put(
|
||||
UsersActions.getUsersFailure({
|
||||
@@ -40,6 +42,7 @@ export function* onCreateUserData({ payload }) {
|
||||
contentType: false
|
||||
}
|
||||
);
|
||||
payload?.callback && payload?.callback(false);
|
||||
if (response?.status === 200) {
|
||||
const data = response.data?.data;
|
||||
const msg = payload.toastMessage.replace('__placeholder__', data && data.fullName ? '"' + data.fullName + '" ' : '');
|
||||
|
||||
Reference in New Issue
Block a user