Merge pull request #80 from kfnawaz/feature/wms-55_develop
Feature/wms 55 develop
This commit is contained in:
7085
package-lock.json
generated
7085
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -10,7 +10,7 @@
|
||||
"dependencies": {
|
||||
"@asseinfo/react-kanban": "2.2.0",
|
||||
"@emotion/cache": "11.4.0",
|
||||
"@emotion/react": "11.4.1",
|
||||
"@emotion/react": "^11.4.1",
|
||||
"@emotion/styled": "11.3.0",
|
||||
"@fullcalendar/daygrid": "5.9.0",
|
||||
"@fullcalendar/interaction": "5.9.0",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as React from 'react';
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import Stack from '@mui/material/Stack';
|
||||
import TextField from '@mui/material/TextField';
|
||||
@@ -6,11 +6,15 @@ import AdapterDateFns from '@mui/lab/AdapterDateFns';
|
||||
import LocalizationProvider from '@mui/lab/LocalizationProvider';
|
||||
import DateTimePicker from '@mui/lab/DateTimePicker';
|
||||
|
||||
export default function DateTimeInput({ disabled }) {
|
||||
const [value, setValue] = React.useState(new Date());
|
||||
export default function DateTimeInput({ disabled, value }) {
|
||||
const [date, setDate] = useState(value || new Date());
|
||||
|
||||
useEffect(() => {
|
||||
setDate(value);
|
||||
}, [value]);
|
||||
|
||||
const handleChange = (newValue) => {
|
||||
setValue(newValue);
|
||||
setDate(newValue);
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -19,7 +23,7 @@ export default function DateTimeInput({ disabled }) {
|
||||
<DateTimePicker
|
||||
disabled={disabled}
|
||||
label=""
|
||||
value={value}
|
||||
value={date}
|
||||
renderInput={(params) => <TextField {...params} />}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
@@ -29,5 +33,6 @@ export default function DateTimeInput({ disabled }) {
|
||||
}
|
||||
|
||||
DateTimeInput.propTypes = {
|
||||
disabled: PropTypes.bool
|
||||
disabled: PropTypes.bool,
|
||||
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.object])
|
||||
};
|
||||
|
||||
@@ -78,6 +78,7 @@ function CreateEditUser(props) {
|
||||
const location = useLocation();
|
||||
const [editedUser, setEditedUser] = useState(location?.state?.user);
|
||||
const [selectedRoles, setSelectedRoles] = useState([]);
|
||||
const [uploadedImg, setUploadedImg] = useState();
|
||||
|
||||
useEffect(() => {
|
||||
if (context === 'edit') {
|
||||
@@ -87,6 +88,7 @@ function CreateEditUser(props) {
|
||||
} else {
|
||||
setEditedUser(editedUser);
|
||||
setSelectedRoles(editedUser.roles);
|
||||
editedUser.image_url && setUploadedImg(editedUser.image_url);
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
@@ -135,48 +137,39 @@ function CreateEditUser(props) {
|
||||
}, []);
|
||||
|
||||
const formik = useFormik({
|
||||
initialValues:
|
||||
context === 'new'
|
||||
? {
|
||||
fullName: '',
|
||||
phoneNumber: '',
|
||||
email: '',
|
||||
password: '',
|
||||
roles: '',
|
||||
warehouses: '',
|
||||
inventories: '',
|
||||
actions: '',
|
||||
visibilities: '',
|
||||
isActive: true,
|
||||
createdBy: currentUser ? currentUser.fullName : '',
|
||||
createdAt: new Date(),
|
||||
updatedBy: currentUser ? currentUser.fullName : '',
|
||||
updatedAt: new Date()
|
||||
}
|
||||
: {
|
||||
fullName: editedUser ? editedUser.fullName : '',
|
||||
phoneNumber: editedUser ? editedUser.phoneNumber : '',
|
||||
email: editedUser ? editedUser.email : '',
|
||||
password: '',
|
||||
roles: editedUser ? editedUser.roles.map((role) => role.name).join(', ') : '',
|
||||
warehouses: editedUser?.permissions?.warehouseScopes
|
||||
? editedUser.permissions.warehouseScopes.map((sc) => sc.id).join(',')
|
||||
: '',
|
||||
inventories: editedUser?.permissions?.inventoryScopes
|
||||
? editedUser.permissions.inventoryScopes.map((sc) => sc.id).join(',')
|
||||
: '',
|
||||
actions: editedUser?.permissions?.actions
|
||||
? editedUser.permissions.actions.join(',')
|
||||
: '',
|
||||
visibilities: editedUser?.permissions?.allowedUIModules
|
||||
? editedUser.permissions.allowedUIModules.join(',')
|
||||
: '',
|
||||
isActive: editedUser && editedUser.isActive !== undefined ? editedUser.isActive : true,
|
||||
createdBy: editedUser ? editedUser.createdBy?.fullName : '',
|
||||
createdAt: editedUser ? editedUser.createdAt : '',
|
||||
updatedBy: editedUser ? editedUser.updatedBy?.fullName : '',
|
||||
updatedAt: editedUser ? editedUser.updatedAt : ''
|
||||
},
|
||||
initialValues: context === 'new' ? {
|
||||
fullName: '',
|
||||
phoneNumber: '',
|
||||
email: '',
|
||||
password: '',
|
||||
roles: '',
|
||||
warehouses: '',
|
||||
inventories: '',
|
||||
actions: '',
|
||||
visibilities: '',
|
||||
isActive: true,
|
||||
image: '',
|
||||
createdBy: currentUser ? currentUser.fullName : '',
|
||||
createdAt: new Date(),
|
||||
updatedBy: currentUser ? currentUser.fullName : '',
|
||||
updatedAt: new Date()
|
||||
} : {
|
||||
fullName: editedUser ? editedUser.fullName : '',
|
||||
phoneNumber: editedUser ? editedUser.phoneNumber : '',
|
||||
email: editedUser ? editedUser.email : '',
|
||||
password: '',
|
||||
roles: editedUser ? editedUser.roles.map(role => role.name).join(', ') : '',
|
||||
warehouses: editedUser?.permissions?.warehouseScopes ? editedUser.permissions.warehouseScopes.map(sc => sc.id).join(',') : '',
|
||||
inventories: editedUser?.permissions?.inventoryScopes ? editedUser.permissions.inventoryScopes.map(sc => sc.id).join(',') : '',
|
||||
actions: editedUser?.permissions?.actions ? editedUser.permissions.actions.join(',') : '',
|
||||
visibilities: editedUser?.permissions?.allowedUIModules ? editedUser.permissions.allowedUIModules.join(',') : '',
|
||||
isActive: editedUser && editedUser.isActive !== undefined ? editedUser.isActive : true,
|
||||
image: editedUser ? editedUser.image_url : EditIcon,
|
||||
createdBy: editedUser ? editedUser.createdBy?.fullName : '',
|
||||
createdAt: editedUser ? editedUser.createdAt : '',
|
||||
updatedBy: editedUser ? editedUser.updatedBy?.fullName : '',
|
||||
updatedAt: editedUser ? editedUser.updatedAt : ''
|
||||
},
|
||||
validationSchema: schema.createUser,
|
||||
onSubmit: (values, { setSubmitting }) => {
|
||||
const onValidationFailed = () => {
|
||||
@@ -202,16 +195,21 @@ function CreateEditUser(props) {
|
||||
delete valuesClone.warehouses;
|
||||
delete valuesClone.actions;
|
||||
delete valuesClone.visibilities;
|
||||
return valuesClone;
|
||||
valuesClone.permissions = JSON.stringify(valuesClone.permissions);
|
||||
valuesClone.roles = selectedRoles && selectedRoles.length > 0 ? selectedRoles.map(role => role._id) : [];
|
||||
const formData = new FormData();
|
||||
Object.keys(valuesClone).forEach(key => formData.append(key, valuesClone[key]));
|
||||
uploadedImg && formData.append('image', uploadedImg);
|
||||
return formData;
|
||||
};
|
||||
values.roles =
|
||||
selectedRoles && selectedRoles.length > 0 ? selectedRoles.map((role) => role._id) : [];
|
||||
dispatch(
|
||||
UsersActions.createUserAction({
|
||||
loader: 'loading-request',
|
||||
slug:
|
||||
context === 'edit' ? API.UPDATE_USER.replace(':id', editedUser._id) : API.CREATE_USER,
|
||||
method: 'post',
|
||||
contentType: false,
|
||||
processData: false,
|
||||
data: adaptPayload(values),
|
||||
onValidationFailed,
|
||||
onSuccessfulSubmission,
|
||||
@@ -238,6 +236,13 @@ function CreateEditUser(props) {
|
||||
setSelectedRoles(uniqueRoles);
|
||||
};
|
||||
|
||||
const handleFileChange = e => {
|
||||
const [file] = e.target.files;
|
||||
if (file) {
|
||||
setUploadedImg(file);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<DashboardLayout className={classes.createEditUserGlobal}>
|
||||
<DashboardNavbar />
|
||||
@@ -262,16 +267,13 @@ function CreateEditUser(props) {
|
||||
>
|
||||
<MDBox sx={{ width: '50%', margin: 'auto' }}>
|
||||
<MDBox sx={{ width: '120px', margin: 'auto', position: 'relative' }}>
|
||||
<MDBox
|
||||
sx={{
|
||||
width: '120px',
|
||||
height: '120px',
|
||||
backgroundColor: '#333333',
|
||||
borderRadius: '50%'
|
||||
}}
|
||||
/>
|
||||
<MDBox sx={{ position: 'absolute', bottom: '0', right: '0', cursor: 'pointer' }}>
|
||||
<img src={EditIcon} alt="img" />
|
||||
<img src={uploadedImg ? typeof uploadedImg === 'string' ? uploadedImg : URL.createObjectURL(uploadedImg) : UserIcon} alt='img' width='120' height='120' style={{borderRadius: '50%'}} />
|
||||
<MDBox sx={{ position: 'absolute', bottom: '0', right: '0' }}>
|
||||
<label htmlFor="image" style={{ cursor: 'pointer' }}>
|
||||
<img src={EditIcon} />
|
||||
</label>
|
||||
<input id='image' name='image' type="file" className='d-none' accept="image/png, image/gif, image/jpeg"
|
||||
onChange={handleFileChange} />
|
||||
</MDBox>
|
||||
</MDBox>
|
||||
<MDBox sx={{ marginBottom: '24px' }}>
|
||||
@@ -426,7 +428,7 @@ function CreateEditUser(props) {
|
||||
<Box component="div" className={classes.labelSize}>
|
||||
Date & Time
|
||||
</Box>
|
||||
<DateTimeInput disabled name="createdAt" value={formik.values.createdAt} />
|
||||
<DateTimeInput disabled name='createdAt' value={new Date(formik.values.createdAt)} />
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<Box component="div" className={classes.labelSize}>
|
||||
@@ -445,7 +447,7 @@ function CreateEditUser(props) {
|
||||
<Box component="div" className={classes.labelSize}>
|
||||
Date & Time
|
||||
</Box>
|
||||
<DateTimeInput disabled name="updatedAt" value={formik.values.updatedAt} />
|
||||
<DateTimeInput disabled name='updatedAt' value={new Date(formik.values.updatedAt)} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
218
src/pages/createEditUserRole/index.js
Normal file
218
src/pages/createEditUserRole/index.js
Normal file
@@ -0,0 +1,218 @@
|
||||
import React from 'react';
|
||||
import MDBox from 'components/MDBox';
|
||||
import DashboardNavbar from 'components/DashboardNavbar';
|
||||
import Footer from 'components/Footer';
|
||||
import DashboardLayout from 'layouts/DashboardLayout';
|
||||
import { makeStyles } from '@mui/styles';
|
||||
import { Box, Grid } from '@mui/material';
|
||||
import MDButton from 'components/Button';
|
||||
import TransferList from 'components/MDTransferList';
|
||||
import DateTimeInput from 'components/DateTimePicker';
|
||||
import Switch from 'components/Switch';
|
||||
import MDTypography from 'components/MDTypography';
|
||||
import MDInput from 'components/MDInput';
|
||||
import TextareaAutosize from '@mui/material/TextareaAutosize';
|
||||
import Typography from '@mui/material/Typography';
|
||||
|
||||
const useStyles = makeStyles(() => ({
|
||||
labelSize: {
|
||||
fontSize: '16px',
|
||||
letterSpacing: '0.01em',
|
||||
color: '#000',
|
||||
marginBottom: '4px'
|
||||
},
|
||||
boxWrap: {
|
||||
backgroundColor: '#fff',
|
||||
border: '1px solid #c2c2c2',
|
||||
borderTop: '3px solid #007aff',
|
||||
display: 'inline-block',
|
||||
padding: '12px',
|
||||
borderRadius: '4px'
|
||||
},
|
||||
noLegend: {
|
||||
display: 'none'
|
||||
},
|
||||
fullWidth: {
|
||||
width: '100%',
|
||||
borderColor: '#d2d6da',
|
||||
borderRadius: '0.375rem'
|
||||
},
|
||||
switchSpacer: {
|
||||
margin: '0',
|
||||
'& .MuiFormControlLabel-root': {
|
||||
margin: '0'
|
||||
},
|
||||
'& .MuiSwitch-root': {
|
||||
margin: '0'
|
||||
}
|
||||
}
|
||||
}));
|
||||
function CreateEditUserRole() {
|
||||
const classes = useStyles();
|
||||
return (
|
||||
<DashboardLayout>
|
||||
<DashboardNavbar />
|
||||
<MDBox px={2} py={3}>
|
||||
<Grid container spacing={2} className={classes.margin}>
|
||||
<Grid item xs={8} md={8}>
|
||||
<Grid container spacing={2} className={classes.margin}>
|
||||
<Grid item xs={12}>
|
||||
<Box component="div" sx={{}} className={classes.labelSize}>
|
||||
Warehouse name
|
||||
</Box>
|
||||
<MDInput fullWidth name="warehousename" type="text" variant="outlined" />
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Box component="div" className={classes.labelSize}>
|
||||
Description
|
||||
</Box>
|
||||
<TextareaAutosize className={classes.fullWidth} minRows={5} />
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Grid container spacing={2} className={classes.margin}>
|
||||
<Grid item xs={6}>
|
||||
<Box component="div" className={classes.labelSize}>
|
||||
Created By
|
||||
</Box>
|
||||
<MDInput fullWidth name="warehousename" type="text" variant="outlined" />
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<Box component="div" className={classes.labelSize}>
|
||||
Date & Time
|
||||
</Box>
|
||||
<DateTimeInput />
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<Box component="div" className={classes.labelSize}>
|
||||
Last Updated by
|
||||
</Box>
|
||||
<MDInput fullWidth name="warehousename" type="text" variant="outlined" />
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<Box component="div" className={classes.labelSize}>
|
||||
Date & Time
|
||||
</Box>
|
||||
<DateTimeInput />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs={4}>
|
||||
<Box component="div" className={classes.labelSize}>
|
||||
Choose avatar component here
|
||||
</Box>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container spacing={4} sx={{ marginTop: '-6px' }}>
|
||||
<Grid item xs={12} md={4}>
|
||||
<MDBox
|
||||
sx={{
|
||||
backgroundColor: '#fff',
|
||||
border: '1px solid #c2c2c2',
|
||||
borderTop: '7px solid #007aff',
|
||||
padding: '12px',
|
||||
borderRadius: '4px'
|
||||
}}
|
||||
>
|
||||
<Typography gutterBottom variant="h6" component="div">
|
||||
Warehouse
|
||||
</Typography>
|
||||
<TransferList />
|
||||
</MDBox>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={4}>
|
||||
<MDBox
|
||||
sx={{
|
||||
backgroundColor: '#fff',
|
||||
border: '1px solid #c2c2c2',
|
||||
borderTop: '7px solid #007aff',
|
||||
padding: '12px',
|
||||
borderRadius: '4px'
|
||||
}}
|
||||
>
|
||||
<Typography gutterBottom variant="h6" component="div">
|
||||
Warehouse
|
||||
</Typography>
|
||||
<TransferList />
|
||||
</MDBox>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container spacing={2} sx={{ marginTop: '12px' }}>
|
||||
<Grid item xs={12} md={3}>
|
||||
<MDBox
|
||||
sx={{
|
||||
backgroundColor: '#fff',
|
||||
border: '1px solid #c2c2c2',
|
||||
borderTop: '7px solid #007aff',
|
||||
padding: '12px',
|
||||
borderRadius: '4px'
|
||||
}}
|
||||
>
|
||||
<Typography gutterBottom variant="h6" component="div">
|
||||
Process
|
||||
</Typography>
|
||||
<MDBox
|
||||
display="flex"
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
lineHeight={1}
|
||||
className={classes.switchSpacer}
|
||||
>
|
||||
<MDTypography variant="body2">Sidenav Mini</MDTypography>
|
||||
<Switch checked />
|
||||
</MDBox>
|
||||
</MDBox>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={3}>
|
||||
<MDBox
|
||||
sx={{
|
||||
backgroundColor: '#fff',
|
||||
border: '1px solid #c2c2c2',
|
||||
borderTop: '7px solid #007aff',
|
||||
padding: '12px',
|
||||
borderRadius: '4px'
|
||||
}}
|
||||
>
|
||||
<Typography gutterBottom variant="h6" component="div">
|
||||
Application
|
||||
</Typography>
|
||||
<MDBox
|
||||
display="flex"
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
lineHeight={1}
|
||||
className={classes.switchSpacer}
|
||||
>
|
||||
<MDTypography variant="body2">Sidenav Mini</MDTypography>
|
||||
<Switch checked />
|
||||
</MDBox>
|
||||
</MDBox>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<MDBox
|
||||
display="flex"
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
lineHeight={1}
|
||||
sx={{ marginBottom: '15px', marginTop: '24px' }}
|
||||
>
|
||||
<MDButton
|
||||
size="medium"
|
||||
color="primary"
|
||||
variant="outlined"
|
||||
type="submit"
|
||||
sx={{ marginRight: '15px' }}
|
||||
>
|
||||
Cancel
|
||||
</MDButton>
|
||||
<MDButton size="medium" color="primary" variant="contained">
|
||||
Save
|
||||
</MDButton>
|
||||
</MDBox>
|
||||
</MDBox>
|
||||
<Footer />
|
||||
</DashboardLayout>
|
||||
);
|
||||
}
|
||||
export default CreateEditUserRole;
|
||||
@@ -1,382 +0,0 @@
|
||||
import React from 'react';
|
||||
import MDBox from 'components/MDBox';
|
||||
import DashboardNavbar from 'components/DashboardNavbar';
|
||||
import DashboardLayout from 'layouts/DashboardLayout';
|
||||
import { makeStyles } from '@mui/styles';
|
||||
import { Box, Grid } from '@mui/material';
|
||||
import MDButton from 'components/Button';
|
||||
import TransferList from 'components/MDTransferList';
|
||||
import DateTimeInput from 'components/DateTimePicker';
|
||||
import Switch from 'components/Switch';
|
||||
import MDTypography from 'components/MDTypography';
|
||||
import MDInput from 'components/MDInput';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import UserIcon from 'assets/images/userIcon.png';
|
||||
import EditIcon from 'assets/images/edit-icon.png';
|
||||
import OutlinedInput from '@mui/material/OutlinedInput';
|
||||
import MenuItem from '@mui/material/MenuItem';
|
||||
import Select from '@mui/material/Select';
|
||||
import Breadcrumbs from 'components/Breadcrumbs';
|
||||
|
||||
const useStyles = makeStyles(() => ({
|
||||
labelSize: {
|
||||
fontSize: '16px',
|
||||
letterSpacing: '0.01em',
|
||||
color: '#000',
|
||||
marginBottom: '4px'
|
||||
},
|
||||
boxWrap: {
|
||||
backgroundColor: '#fff',
|
||||
border: '1px solid #c2c2c2',
|
||||
borderTop: '3px solid #007aff',
|
||||
display: 'inline-block',
|
||||
padding: '12px',
|
||||
borderRadius: '4px'
|
||||
},
|
||||
noLegend: {
|
||||
display: 'none'
|
||||
},
|
||||
fullWidth: {
|
||||
width: '100%',
|
||||
borderColor: '#d2d6da',
|
||||
borderRadius: '0.375rem'
|
||||
},
|
||||
switchSpacer: {
|
||||
margin: '0',
|
||||
'& .MuiFormControlLabel-root': {
|
||||
margin: '0'
|
||||
},
|
||||
'& .MuiSwitch-root': {
|
||||
margin: '0'
|
||||
}
|
||||
}
|
||||
}));
|
||||
function CreateUserRole() {
|
||||
const classes = useStyles();
|
||||
const [personName, setPersonName] = React.useState([]);
|
||||
|
||||
const handleChange = (event) => {
|
||||
const {
|
||||
target: { value }
|
||||
} = event;
|
||||
setPersonName(
|
||||
// On autofill we get a stringified value.
|
||||
typeof value === 'string' ? value.split(',') : value
|
||||
);
|
||||
};
|
||||
return (
|
||||
<DashboardLayout>
|
||||
<DashboardNavbar />
|
||||
<Breadcrumbs
|
||||
title="Role Details"
|
||||
route={[
|
||||
{ name: 'Home', path: '/home' },
|
||||
{ name: 'Setup', path: '/setup' },
|
||||
{ name: 'Access', path: '/setup/users-access' },
|
||||
{ name: 'Role Details' }
|
||||
]}
|
||||
/>
|
||||
<MDBox px={2} sx={{ backgroundColor: '#fff' }}>
|
||||
<MDBox mx={2} sx={{ border: '1px solid #C4C4C4', borderRadius: '4px', padding: '30px' }}>
|
||||
<MDBox sx={{ width: '50%', margin: 'auto' }}>
|
||||
<MDBox sx={{ width: '120px', margin: 'auto', position: 'relative' }}>
|
||||
<MDBox
|
||||
sx={{
|
||||
width: '120px',
|
||||
height: '120px',
|
||||
backgroundColor: '#333333',
|
||||
borderRadius: '50%'
|
||||
}}
|
||||
/>
|
||||
<MDBox sx={{ position: 'absolute', bottom: '0', right: '0', cursor: 'pointer' }}>
|
||||
<img src={EditIcon} alt="img" />
|
||||
</MDBox>
|
||||
</MDBox>
|
||||
<MDBox sx={{ marginBottom: '24px' }}>
|
||||
<Box component="div" sx={{}} className={classes.labelSize}>
|
||||
User Name
|
||||
</Box>
|
||||
<MDInput fullWidth name="warehousename" type="text" variant="outlined" />
|
||||
</MDBox>
|
||||
<MDBox sx={{ marginBottom: '24px' }}>
|
||||
<Box component="div" sx={{}} className={classes.labelSize}>
|
||||
Phone Number
|
||||
</Box>
|
||||
<MDInput fullWidth name="warehousename" type="text" variant="outlined" />
|
||||
</MDBox>
|
||||
<MDBox sx={{ marginBottom: '24px' }}>
|
||||
<Box component="div" sx={{}} className={classes.labelSize}>
|
||||
Role
|
||||
</Box>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', columnGap: '20px' }}>
|
||||
<Box sx={{ width: '70%' }}>
|
||||
<Select
|
||||
multiple
|
||||
displayEmpty
|
||||
value={personName}
|
||||
input={<OutlinedInput />}
|
||||
renderValue={(selected) => {
|
||||
if (selected.length === 0) {
|
||||
return 'Placeholder';
|
||||
}
|
||||
|
||||
return selected.join(', ');
|
||||
}}
|
||||
inputProps={{ 'aria-label': 'Without label' }}
|
||||
sx={{
|
||||
width: '100%'
|
||||
}}
|
||||
onChange={handleChange}
|
||||
>
|
||||
<MenuItem disabled value="">
|
||||
Placeholder
|
||||
</MenuItem>
|
||||
<MenuItem>Lorem Ipsum</MenuItem>
|
||||
</Select>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
width: '30%',
|
||||
border: '1px solid #C4C4C4',
|
||||
borderRadius: '4px'
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
component="div"
|
||||
sx={{
|
||||
fontSize: '16px',
|
||||
lineHeight: '20px',
|
||||
letterSpacing: '0.01em',
|
||||
textTransform: 'capitalize',
|
||||
color: '#000',
|
||||
marginLeft: '10px'
|
||||
}}
|
||||
>
|
||||
Access
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
position: 'relative',
|
||||
left: '20px'
|
||||
}}
|
||||
>
|
||||
<Switch checked />
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</MDBox>
|
||||
<Grid container spacing={2} className={classes.margin}>
|
||||
<Grid item xs={12}>
|
||||
<Grid container spacing={2} className={classes.margin}>
|
||||
<Grid item xs={6}>
|
||||
<Box component="div" className={classes.labelSize}>
|
||||
Created By
|
||||
</Box>
|
||||
<MDInput fullWidth name="warehousename" type="text" variant="outlined" />
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<Box component="div" className={classes.labelSize}>
|
||||
Date & Time
|
||||
</Box>
|
||||
<DateTimeInput />
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<Box component="div" className={classes.labelSize}>
|
||||
Last Updated by
|
||||
</Box>
|
||||
<MDInput fullWidth name="warehousename" type="text" variant="outlined" />
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<Box component="div" className={classes.labelSize}>
|
||||
Date & Time
|
||||
</Box>
|
||||
<DateTimeInput />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</MDBox>
|
||||
</MDBox>
|
||||
|
||||
<Grid container spacing={4} sx={{ marginTop: '-6px' }}>
|
||||
<Grid item xs={12} md={6}>
|
||||
<MDBox
|
||||
sx={{
|
||||
backgroundColor: '#fff',
|
||||
border: '1px solid #c2c2c2',
|
||||
borderTop: '7px solid #007aff',
|
||||
padding: '12px',
|
||||
borderRadius: '4px'
|
||||
}}
|
||||
>
|
||||
<Typography gutterBottom variant="h6" component="div">
|
||||
Warehouse
|
||||
</Typography>
|
||||
<TransferList />
|
||||
</MDBox>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={6}>
|
||||
<MDBox
|
||||
sx={{
|
||||
backgroundColor: '#fff',
|
||||
border: '1px solid #c2c2c2',
|
||||
borderTop: '7px solid #007aff',
|
||||
padding: '12px',
|
||||
borderRadius: '4px'
|
||||
}}
|
||||
>
|
||||
<Typography gutterBottom variant="h6" component="div">
|
||||
Warehouse
|
||||
</Typography>
|
||||
<TransferList />
|
||||
</MDBox>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container spacing={2} sx={{ marginTop: '12px' }}>
|
||||
<Grid item xs={12} md={3}>
|
||||
<MDBox
|
||||
sx={{
|
||||
backgroundColor: '#fff',
|
||||
border: '1px solid #c2c2c2',
|
||||
borderTop: '7px solid #007aff',
|
||||
borderRadius: '4px'
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
gutterBottom
|
||||
variant="h6"
|
||||
component="div"
|
||||
sx={{
|
||||
borderBottom: '1px solid #c2c2c2',
|
||||
padding: '10px 20px',
|
||||
marginBottom: '20px'
|
||||
}}
|
||||
>
|
||||
Process
|
||||
</Typography>
|
||||
<Box sx={{ padding: ' 0px 20px' }}>
|
||||
<MDBox
|
||||
display="flex"
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
lineHeight={1}
|
||||
className={classes.switchSpacer}
|
||||
sx={{ marginBottom: '20px !important' }}
|
||||
>
|
||||
<MDTypography variant="body2">Stock Tracking</MDTypography>
|
||||
<Switch checked />
|
||||
</MDBox>
|
||||
<MDBox
|
||||
display="flex"
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
lineHeight={1}
|
||||
className={classes.switchSpacer}
|
||||
sx={{ marginBottom: '20px !important' }}
|
||||
>
|
||||
<MDTypography variant="body2">Replenishment</MDTypography>
|
||||
<Switch checked />
|
||||
</MDBox>
|
||||
<MDBox
|
||||
display="flex"
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
lineHeight={1}
|
||||
className={classes.switchSpacer}
|
||||
sx={{ marginBottom: '20px !important' }}
|
||||
>
|
||||
<MDTypography variant="body2">Alerting</MDTypography>
|
||||
<Switch checked />
|
||||
</MDBox>
|
||||
</Box>
|
||||
</MDBox>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={3}>
|
||||
<MDBox
|
||||
sx={{
|
||||
backgroundColor: '#fff',
|
||||
border: '1px solid #c2c2c2',
|
||||
borderTop: '7px solid #007aff',
|
||||
borderRadius: '4px'
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
gutterBottom
|
||||
variant="h6"
|
||||
component="div"
|
||||
sx={{
|
||||
borderBottom: '1px solid #c2c2c2',
|
||||
padding: '10px 20px',
|
||||
marginBottom: '20px'
|
||||
}}
|
||||
>
|
||||
Application
|
||||
</Typography>
|
||||
<Box sx={{ padding: ' 0px 20px' }}>
|
||||
<MDBox
|
||||
display="flex"
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
lineHeight={1}
|
||||
className={classes.switchSpacer}
|
||||
sx={{ marginBottom: '20px !important' }}
|
||||
>
|
||||
<MDTypography variant="body2">Home</MDTypography>
|
||||
<Switch checked />
|
||||
</MDBox>
|
||||
<MDBox
|
||||
display="flex"
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
lineHeight={1}
|
||||
className={classes.switchSpacer}
|
||||
sx={{ marginBottom: '20px !important' }}
|
||||
>
|
||||
<MDTypography variant="body2">Setup</MDTypography>
|
||||
<Switch checked />
|
||||
</MDBox>
|
||||
<MDBox
|
||||
display="flex"
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
lineHeight={1}
|
||||
className={classes.switchSpacer}
|
||||
sx={{ marginBottom: '20px !important' }}
|
||||
>
|
||||
<MDTypography variant="body2">Reports</MDTypography>
|
||||
<Switch checked />
|
||||
</MDBox>
|
||||
</Box>
|
||||
</MDBox>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<MDBox
|
||||
display="flex"
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
lineHeight={1}
|
||||
sx={{ marginBottom: '15px', marginTop: '45px', paddingBottom: '30px' }}
|
||||
>
|
||||
<MDButton
|
||||
size="medium"
|
||||
color="error"
|
||||
variant="outlined"
|
||||
type="submit"
|
||||
sx={{ marginRight: '15px' }}
|
||||
>
|
||||
Cancel
|
||||
</MDButton>
|
||||
<MDButton size="medium" color="primary" variant="contained">
|
||||
Save
|
||||
</MDButton>
|
||||
</MDBox>
|
||||
</MDBox>
|
||||
</DashboardLayout>
|
||||
);
|
||||
}
|
||||
export default CreateUserRole;
|
||||
@@ -1,25 +1,28 @@
|
||||
import React, { useEffect, useMemo } from 'react';
|
||||
import moment from 'moment';
|
||||
import React, { useEffect, useState, useMemo } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { styled } from '@mui/material/styles';
|
||||
import { Grid, TableBody, TableCell, TableRow, Tabs, Tab } from '@mui/material';
|
||||
import { makeStyles } from '@mui/styles';
|
||||
import MDBox from 'components/MDBox';
|
||||
import EditIcon from '@mui/icons-material/Edit';
|
||||
|
||||
import DashboardNavbar from 'components/DashboardNavbar';
|
||||
import DashboardLayout from 'layouts/DashboardLayout';
|
||||
import { styled } from '@mui/material/styles';
|
||||
import { makeStyles } from '@mui/styles';
|
||||
import BasicTable from 'components/BasicTable';
|
||||
import { Grid, TableBody, TableCell, TableRow } from '@mui/material';
|
||||
import SearchBar from 'components/SearchBar';
|
||||
import EditIcon from '@mui/icons-material/Edit';
|
||||
import MDButton from 'components/Button';
|
||||
import { useState } from 'react';
|
||||
import { Tabs, Tab } from '@mui/material';
|
||||
import TabPanel from 'components/Tabs';
|
||||
import Breadcrumbs from 'components/Breadcrumbs';
|
||||
|
||||
import WarehouseActions, { WarehouseSelectors } from 'redux/WarehouseRedux';
|
||||
import InventoryActions, { InventorySelectors } from 'redux/InventoryRedux';
|
||||
import PermissionsActions, { PermissionsSelectors } from 'redux/PermissionsRedux';
|
||||
import UsersActions, { UsersSelectors } from 'redux/UsersRedux';
|
||||
import RolesActions, { RolesSelectors } from 'redux/RolesRedux';
|
||||
import { AuthSelectors } from 'redux/AuthRedux';
|
||||
|
||||
import { API } from 'constant';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import moment from 'moment';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import Breadcrumbs from 'components/Breadcrumbs';
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
iconSize: {
|
||||
@@ -34,6 +37,9 @@ const useStyles = makeStyles((theme) => ({
|
||||
statusInactive: {
|
||||
color: 'red'
|
||||
},
|
||||
limitWidth: {
|
||||
maxWidth: '20rem'
|
||||
},
|
||||
margin: {
|
||||
marginBottom: '20px',
|
||||
borderTop: '1px solid #ddd',
|
||||
@@ -53,6 +59,10 @@ const useStyles = makeStyles((theme) => ({
|
||||
overflow: 'hidden',
|
||||
borderRadius: '0.5rem'
|
||||
},
|
||||
rightPlaced: {
|
||||
position: 'absolute',
|
||||
right: 0
|
||||
},
|
||||
tabs: {
|
||||
borderRadius: 0,
|
||||
'& .MuiButtonBase-root.MuiTab-root': {
|
||||
@@ -83,11 +93,22 @@ function UserAccessScreen() {
|
||||
const [value, setValue] = useState(1);
|
||||
const usersData = useSelector(UsersSelectors.getUsersDetail);
|
||||
const rolesData = useSelector(RolesSelectors.getRolesDetail);
|
||||
const currentUser = useSelector(AuthSelectors.getUser);
|
||||
const warehouses = useSelector(WarehouseSelectors.getWarehouseDetail);
|
||||
const inventories = useSelector(InventorySelectors.getInventoryDetail);
|
||||
const actions = useSelector(PermissionsSelectors.getActionsDetail);
|
||||
const permissions = useSelector(PermissionsSelectors.getPermissionsDetail);
|
||||
const [userRecords, setUserRecords] = useState([]);
|
||||
const [rolesRecords, setRoleRecords] = useState([]);
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
(!warehouses || warehouses.length === 0) && dispatch(WarehouseActions.warehouseDataAction({loader: 'loading-request', slug: API.GET_WAREHOUSE_DATA,method: 'get'}));
|
||||
(!inventories || inventories.length === 0) && dispatch(InventoryActions.getInventoryAction({loader: 'loading-request', slug: API.GET_INVENTORY,method: 'get'}));
|
||||
(!rolesData || rolesData.length === 0) && dispatch(RolesActions.getRolesAction({loader: 'loading-request', slug: API.GET_ROLES_DATA, method: 'get'}));
|
||||
(!permissions || permissions.length === 0) && dispatch(PermissionsActions.getPermissionsAction({loader: 'loading-request', slug: API.GET_PERMISSIONS_DATA, method: 'get'}));
|
||||
(!actions || actions.length === 0) && dispatch(PermissionsActions.getActionsAction({loader: 'loading-request', slug: API.GET_ACTIONS_DATA, method: 'get'}));
|
||||
}, []);
|
||||
|
||||
const userHeadCells = [
|
||||
{ id: 'full_name', label: 'User Name', isEditAnchor: true, value: (record) => record.fullName },
|
||||
{ id: 'phone_number', label: 'Phone Number', value: (record) => record.phoneNumber },
|
||||
@@ -122,9 +143,13 @@ function UserAccessScreen() {
|
||||
];
|
||||
|
||||
const rolesHeadCells = [
|
||||
{ id: 'role', label: 'Role' },
|
||||
{ id: 'permissions', label: 'Permissions' },
|
||||
{ id: 'status', label: 'Status' }
|
||||
{ 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: 'status', label: 'Status', value: record => record.status === 'ACTIVE' ? <span className={classes.statusActive}>Active</span>
|
||||
: <span className={classes.statusInactive}>Inactive</span> }
|
||||
];
|
||||
|
||||
const usersHandler = () => {
|
||||
@@ -184,34 +209,32 @@ function UserAccessScreen() {
|
||||
}
|
||||
}));
|
||||
|
||||
const rowRenders =
|
||||
userRecords &&
|
||||
userRecords.map((record) => {
|
||||
const canEdit = (columnConfig) =>
|
||||
columnConfig.isEditAnchor && currentUser.email !== record.email;
|
||||
return (
|
||||
<StyledTableRow key={record.id}>
|
||||
{userHeadCells.map((columnConfig, key) => (
|
||||
<TableCell
|
||||
key={key}
|
||||
onClick={() =>
|
||||
canEdit(columnConfig) &&
|
||||
navigate('/setup/users-access/edit-user', { state: { user: record } })
|
||||
}
|
||||
>
|
||||
{canEdit(columnConfig) ? (
|
||||
<span className={classes.iconwrap}>
|
||||
<EditIcon className={classes.iconSize} />
|
||||
const rowRenders = ({records, headers, navUrl, table}) => {
|
||||
return records && records.map((record, keyouter) => {
|
||||
return <StyledTableRow key={record.id + '-' + keyouter}>
|
||||
{headers.map((columnConfig, key) => {
|
||||
const canEdit = columnConfig.isEditAnchor;
|
||||
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}})}>
|
||||
{canEdit
|
||||
? isAfter
|
||||
? <span className={classes.iconwrap}>
|
||||
<EditIcon className={classes.iconSize + ' ' + classes.rightPlaced}/>
|
||||
{columnConfig.value(record)}
|
||||
</span>
|
||||
) : (
|
||||
<span>{columnConfig.value(record)}</span>
|
||||
)}
|
||||
</TableCell>
|
||||
))}
|
||||
</StyledTableRow>
|
||||
);
|
||||
: <span className={classes.iconwrap}>
|
||||
{columnConfig.value(record)}
|
||||
<EditIcon className={classes.iconSize}/>
|
||||
</span>
|
||||
: <span>{columnConfig.value(record)}</span>}
|
||||
</TableCell>;
|
||||
}
|
||||
)}
|
||||
</StyledTableRow>;
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<DashboardLayout>
|
||||
@@ -269,21 +292,10 @@ function UserAccessScreen() {
|
||||
backgroundColor="#007AFF"
|
||||
color="#fff"
|
||||
>
|
||||
<TableBody>
|
||||
{rolesRecords &&
|
||||
rolesRecords.map((item) => (
|
||||
<StyledTableRow key={item.id}>
|
||||
<TableCell>
|
||||
<div className={classes.iconwrap}>
|
||||
<EditIcon className={classes.iconSize} />
|
||||
{item.name}
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell>{item.permissions}</TableCell>
|
||||
<TableCell>{item.status}</TableCell>
|
||||
</StyledTableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
{rolesRecords && rolesRecords.length > 0
|
||||
? <TableBody>
|
||||
{rowRenders({records: rolesRecords, headers: rolesHeadCells, navUrl: '/setup/users-access/edit-role', table: 'role'})}
|
||||
</TableBody> : <p>No Records to Display</p>}
|
||||
</BasicTable>
|
||||
</TabPanel>
|
||||
<TabPanel value={value} index={1} className={classes.radialBorder}>
|
||||
@@ -294,11 +306,10 @@ function UserAccessScreen() {
|
||||
backgroundColor="#007AFF"
|
||||
color="#fff"
|
||||
>
|
||||
{userRecords && userRecords.length > 0 ? (
|
||||
<TableBody>{rowRenders}</TableBody>
|
||||
) : (
|
||||
'No Records to Display'
|
||||
)}
|
||||
{userRecords && userRecords.length > 0
|
||||
? <TableBody>
|
||||
{rowRenders({records: userRecords, headers: userHeadCells, navUrl: '/setup/users-access/edit-user', table: 'user'})}
|
||||
</TableBody> : <p>No Records to Display</p>}
|
||||
</BasicTable>
|
||||
</TabPanel>
|
||||
</Grid>
|
||||
|
||||
@@ -12,7 +12,7 @@ import NewWarehouseDetails from 'pages/newWarehouseDetails';
|
||||
import EditWarehouseDetails from 'pages/editWarehouseDetails';
|
||||
import LabelingHome from 'pages/labellingHome';
|
||||
import SetupInventory from 'pages/setupInventory';
|
||||
import CreateUserRole from 'pages/createUserRole';
|
||||
import CreateEditUserRole from 'pages/createEditUserRole';
|
||||
import CreateEditUser from 'pages/createEditUser';
|
||||
import WidgetLabel from 'pages/widgetLabel';
|
||||
import ItemListing from 'pages/itemListing';
|
||||
@@ -177,7 +177,7 @@ const protectedRoutes = [
|
||||
key: 'create-role',
|
||||
route: '/setup/users-access/create-role',
|
||||
hide: true,
|
||||
component: <CreateUserRole />
|
||||
component: <CreateEditUserRole />
|
||||
},
|
||||
{
|
||||
name: 'Create User',
|
||||
|
||||
@@ -34,7 +34,11 @@ export function* onCreateUserData({ payload }) {
|
||||
ApiServices[payload?.method],
|
||||
AuthorizedAPI,
|
||||
payload?.slug,
|
||||
payload?.data
|
||||
payload?.data,
|
||||
{
|
||||
processData: false,
|
||||
contentType: false
|
||||
}
|
||||
);
|
||||
if (response?.status === 200) {
|
||||
const data = response.data?.data;
|
||||
@@ -48,8 +52,9 @@ export function* onCreateUserData({ payload }) {
|
||||
})
|
||||
);
|
||||
} else {
|
||||
toast('Something went wrong!');
|
||||
payload.onValidationFailed(response.data?.error);
|
||||
const error = response?.originalError?.response?.data?.error;
|
||||
toast(error && error.indexOf('E11000') > -1 ? 'Email already exists!' : 'Something went wrong!');
|
||||
payload.onValidationFailed();
|
||||
yield put(
|
||||
UsersActions.createUserFailure({
|
||||
loader: payload?.loader,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// REST API SERVICES
|
||||
export default {
|
||||
post: (API, slug, payload) => API.post(slug, payload),
|
||||
post: (API, slug, payload, headers) => headers ? API.post(slug, payload, {headers}) : API.post(slug, payload),
|
||||
get: (API, slug) => API.get(slug),
|
||||
delete: (API, slug) => {
|
||||
return API.delete(slug);
|
||||
|
||||
@@ -68,6 +68,8 @@ const schema = {
|
||||
|
||||
createUser: Yup.object({
|
||||
fullName: Yup.string('Enter Full Name').required('User Name is required'),
|
||||
email: Yup.string('Enter Email').required('Email is required'),
|
||||
password: Yup.string('Enter Password').required('Password is required'),
|
||||
phoneNumber: Yup.string('Enter Phone Numbe').required('Phone Number is required'),
|
||||
roles: Yup.string('Please select at least one role').required('At least one role is required')
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user