[WMS-55]
Image upload, better error handling, removed warnings, fixed date field not rendering correct date during edit
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": {
|
"dependencies": {
|
||||||
"@asseinfo/react-kanban": "2.2.0",
|
"@asseinfo/react-kanban": "2.2.0",
|
||||||
"@emotion/cache": "11.4.0",
|
"@emotion/cache": "11.4.0",
|
||||||
"@emotion/react": "11.4.1",
|
"@emotion/react": "^11.4.1",
|
||||||
"@emotion/styled": "11.3.0",
|
"@emotion/styled": "11.3.0",
|
||||||
"@fullcalendar/daygrid": "5.9.0",
|
"@fullcalendar/daygrid": "5.9.0",
|
||||||
"@fullcalendar/interaction": "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 PropTypes from 'prop-types';
|
||||||
import Stack from '@mui/material/Stack';
|
import Stack from '@mui/material/Stack';
|
||||||
import TextField from '@mui/material/TextField';
|
import TextField from '@mui/material/TextField';
|
||||||
@@ -6,11 +6,15 @@ import AdapterDateFns from '@mui/lab/AdapterDateFns';
|
|||||||
import LocalizationProvider from '@mui/lab/LocalizationProvider';
|
import LocalizationProvider from '@mui/lab/LocalizationProvider';
|
||||||
import DateTimePicker from '@mui/lab/DateTimePicker';
|
import DateTimePicker from '@mui/lab/DateTimePicker';
|
||||||
|
|
||||||
export default function DateTimeInput({ disabled }) {
|
export default function DateTimeInput({ disabled, value }) {
|
||||||
const [value, setValue] = React.useState(new Date());
|
const [date, setDate] = useState(value || new Date());
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setDate(value);
|
||||||
|
}, [value])
|
||||||
|
|
||||||
const handleChange = (newValue) => {
|
const handleChange = (newValue) => {
|
||||||
setValue(newValue);
|
setDate(newValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -19,7 +23,7 @@ export default function DateTimeInput({ disabled }) {
|
|||||||
<DateTimePicker
|
<DateTimePicker
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
label=""
|
label=""
|
||||||
value={value}
|
value={date}
|
||||||
renderInput={(params) => <TextField {...params} />}
|
renderInput={(params) => <TextField {...params} />}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
/>
|
/>
|
||||||
@@ -29,5 +33,6 @@ export default function DateTimeInput({ disabled }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DateTimeInput.propTypes = {
|
DateTimeInput.propTypes = {
|
||||||
disabled: PropTypes.bool
|
disabled: PropTypes.bool,
|
||||||
|
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.object])
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ function CreateEditUser(props) {
|
|||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const [editedUser, setEditedUser] = useState(location?.state?.user);
|
const [editedUser, setEditedUser] = useState(location?.state?.user);
|
||||||
const [selectedRoles, setSelectedRoles] = useState([]);
|
const [selectedRoles, setSelectedRoles] = useState([]);
|
||||||
|
const [uploadedImg, setUploadedImg] = useState();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (context === 'edit') {
|
if (context === 'edit') {
|
||||||
@@ -86,6 +87,7 @@ function CreateEditUser(props) {
|
|||||||
} else {
|
} else {
|
||||||
setEditedUser(editedUser);
|
setEditedUser(editedUser);
|
||||||
setSelectedRoles(editedUser.roles);
|
setSelectedRoles(editedUser.roles);
|
||||||
|
editedUser.image_url && setUploadedImg(editedUser.image_url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
@@ -110,6 +112,7 @@ function CreateEditUser(props) {
|
|||||||
actions: '',
|
actions: '',
|
||||||
visibilities: '',
|
visibilities: '',
|
||||||
isActive: true,
|
isActive: true,
|
||||||
|
image: '',
|
||||||
createdBy: currentUser ? currentUser.fullName : '',
|
createdBy: currentUser ? currentUser.fullName : '',
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
updatedBy: currentUser ? currentUser.fullName : '',
|
updatedBy: currentUser ? currentUser.fullName : '',
|
||||||
@@ -125,6 +128,7 @@ function CreateEditUser(props) {
|
|||||||
actions: editedUser?.permissions?.actions ? editedUser.permissions.actions.join(',') : '',
|
actions: editedUser?.permissions?.actions ? editedUser.permissions.actions.join(',') : '',
|
||||||
visibilities: editedUser?.permissions?.allowedUIModules ? editedUser.permissions.allowedUIModules.join(',') : '',
|
visibilities: editedUser?.permissions?.allowedUIModules ? editedUser.permissions.allowedUIModules.join(',') : '',
|
||||||
isActive: editedUser && editedUser.isActive !== undefined ? editedUser.isActive : true,
|
isActive: editedUser && editedUser.isActive !== undefined ? editedUser.isActive : true,
|
||||||
|
image: editedUser ? editedUser.image_url : EditIcon,
|
||||||
createdBy: editedUser ? editedUser.createdBy?.fullName : '',
|
createdBy: editedUser ? editedUser.createdBy?.fullName : '',
|
||||||
createdAt: editedUser ? editedUser.createdAt : '',
|
createdAt: editedUser ? editedUser.createdAt : '',
|
||||||
updatedBy: editedUser ? editedUser.updatedBy?.fullName : '',
|
updatedBy: editedUser ? editedUser.updatedBy?.fullName : '',
|
||||||
@@ -150,14 +154,20 @@ function CreateEditUser(props) {
|
|||||||
delete valuesClone.warehouses;
|
delete valuesClone.warehouses;
|
||||||
delete valuesClone.actions;
|
delete valuesClone.actions;
|
||||||
delete valuesClone.visibilities;
|
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(
|
dispatch(
|
||||||
UsersActions.createUserAction({
|
UsersActions.createUserAction({
|
||||||
loader: 'loading-request',
|
loader: 'loading-request',
|
||||||
slug: context === 'edit' ? API.UPDATE_USER.replace(':id', editedUser._id): API.CREATE_USER,
|
slug: context === 'edit' ? API.UPDATE_USER.replace(':id', editedUser._id): API.CREATE_USER,
|
||||||
method: 'post',
|
method: 'post',
|
||||||
|
contentType: false,
|
||||||
|
processData: false,
|
||||||
data: adaptPayload(values),
|
data: adaptPayload(values),
|
||||||
onValidationFailed,
|
onValidationFailed,
|
||||||
onSuccessfulSubmission,
|
onSuccessfulSubmission,
|
||||||
@@ -181,6 +191,13 @@ function CreateEditUser(props) {
|
|||||||
setSelectedRoles(uniqueRoles);
|
setSelectedRoles(uniqueRoles);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleFileChange = e => {
|
||||||
|
const [file] = e.target.files;
|
||||||
|
if (file) {
|
||||||
|
setUploadedImg(file);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DashboardLayout className={classes.createEditUserGlobal}>
|
<DashboardLayout className={classes.createEditUserGlobal}>
|
||||||
<DashboardNavbar />
|
<DashboardNavbar />
|
||||||
@@ -188,9 +205,13 @@ function CreateEditUser(props) {
|
|||||||
<MDBox mx={4} sx={{ border: '1px solid #C4C4C4', borderRadius: '4px', padding: '30px' }}>
|
<MDBox mx={4} sx={{ border: '1px solid #C4C4C4', borderRadius: '4px', padding: '30px' }}>
|
||||||
<MDBox sx={{ width: '50%', margin: 'auto' }}>
|
<MDBox sx={{ width: '50%', margin: 'auto' }}>
|
||||||
<MDBox sx={{ width: '120px', margin: 'auto', position: 'relative' }}>
|
<MDBox sx={{ width: '120px', margin: 'auto', position: 'relative' }}>
|
||||||
<img src={UserIcon} 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', cursor: 'pointer' }}>
|
<MDBox sx={{ position: 'absolute', bottom: '0', right: '0' }}>
|
||||||
<img src={EditIcon} alt='img' />
|
<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>
|
</MDBox>
|
||||||
<MDBox sx={{ marginBottom: '24px' }}>
|
<MDBox sx={{ marginBottom: '24px' }}>
|
||||||
@@ -296,7 +317,7 @@ function CreateEditUser(props) {
|
|||||||
<Box component='div' className={classes.labelSize}>
|
<Box component='div' className={classes.labelSize}>
|
||||||
Date & Time
|
Date & Time
|
||||||
</Box>
|
</Box>
|
||||||
<DateTimeInput disabled name='createdAt' value={formik.values.createdAt} />
|
<DateTimeInput disabled name='createdAt' value={new Date(formik.values.createdAt)} />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6}>
|
<Grid item xs={6}>
|
||||||
<Box component='div' className={classes.labelSize}>
|
<Box component='div' className={classes.labelSize}>
|
||||||
@@ -308,7 +329,7 @@ function CreateEditUser(props) {
|
|||||||
<Box component='div' className={classes.labelSize}>
|
<Box component='div' className={classes.labelSize}>
|
||||||
Date & Time
|
Date & Time
|
||||||
</Box>
|
</Box>
|
||||||
<DateTimeInput disabled name='updatedAt' value={formik.values.updatedAt} />
|
<DateTimeInput disabled name='updatedAt' value={new Date(formik.values.updatedAt)} />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@@ -165,9 +165,9 @@ function UserAccessScreen() {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const rowRenders = userRecords && userRecords.map(record => {
|
const rowRenders = userRecords && userRecords.map((record, keyouter) => {
|
||||||
const canEdit = columnConfig => columnConfig.isEditAnchor && currentUser.email !== record.email;
|
const canEdit = columnConfig => columnConfig.isEditAnchor && currentUser.email !== record.email;
|
||||||
return <StyledTableRow key={record.id}>
|
return <StyledTableRow key={record.id + '-' + keyouter}>
|
||||||
{userHeadCells.map((columnConfig, key) => <TableCell key={key} onClick={() => canEdit(columnConfig) && navigate('/setup/users-access/edit-user', {state: {user: record}})}>
|
{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}>
|
{canEdit(columnConfig) ? <span className={classes.iconwrap}>
|
||||||
<EditIcon className={classes.iconSize}/>
|
<EditIcon className={classes.iconSize}/>
|
||||||
@@ -218,8 +218,8 @@ function UserAccessScreen() {
|
|||||||
>
|
>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{rolesRecords &&
|
{rolesRecords &&
|
||||||
rolesRecords.map((item) => (
|
rolesRecords.map((item, key) => (
|
||||||
<StyledTableRow key={item.id}>
|
<StyledTableRow key={item.id + '-' + key}>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<div className={classes.iconwrap}>
|
<div className={classes.iconwrap}>
|
||||||
<EditIcon className={classes.iconSize} />
|
<EditIcon className={classes.iconSize} />
|
||||||
|
|||||||
@@ -34,7 +34,11 @@ export function* onCreateUserData({ payload }) {
|
|||||||
ApiServices[payload?.method],
|
ApiServices[payload?.method],
|
||||||
AuthorizedAPI,
|
AuthorizedAPI,
|
||||||
payload?.slug,
|
payload?.slug,
|
||||||
payload?.data
|
payload?.data,
|
||||||
|
{
|
||||||
|
processData: false,
|
||||||
|
contentType: false
|
||||||
|
}
|
||||||
);
|
);
|
||||||
if (response?.status === 200) {
|
if (response?.status === 200) {
|
||||||
const data = response.data?.data;
|
const data = response.data?.data;
|
||||||
@@ -48,8 +52,9 @@ export function* onCreateUserData({ payload }) {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
toast('Something went wrong!');
|
const error = response?.originalError?.response?.data?.error;
|
||||||
payload.onValidationFailed(response.data?.error);
|
toast(error && error.indexOf('E11000') > -1 ? 'Email already exists!' : 'Something went wrong!');
|
||||||
|
payload.onValidationFailed();
|
||||||
yield put(
|
yield put(
|
||||||
UsersActions.createUserFailure({
|
UsersActions.createUserFailure({
|
||||||
loader: payload?.loader,
|
loader: payload?.loader,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// REST API SERVICES
|
// REST API SERVICES
|
||||||
export default {
|
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),
|
get: (API, slug) => API.get(slug),
|
||||||
delete: (API, slug) => {
|
delete: (API, slug) => {
|
||||||
return API.delete(slug);
|
return API.delete(slug);
|
||||||
|
|||||||
@@ -68,6 +68,8 @@ const schema = {
|
|||||||
|
|
||||||
createUser: Yup.object({
|
createUser: Yup.object({
|
||||||
fullName: Yup.string('Enter Full Name').required('User Name is required'),
|
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'),
|
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')
|
roles: Yup.string('Please select at least one role').required('At least one role is required')
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user