feedback
This commit is contained in:
parent
24896b8acb
commit
29276f0fb9
11 changed files with 512 additions and 443 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect, useRef } from 'react';
|
||||||
import { styled, useTheme } from '@mui/material/styles';
|
import { styled, useTheme } from '@mui/material/styles';
|
||||||
import Box from '@mui/material/Box';
|
import Box from '@mui/material/Box';
|
||||||
import Drawer from '@mui/material/Drawer';
|
import Drawer from '@mui/material/Drawer';
|
||||||
|
|
@ -18,7 +18,7 @@ import PersonIcon from '@mui/icons-material/Person';
|
||||||
import TextSnippetIcon from '@mui/icons-material/TextSnippet';
|
import TextSnippetIcon from '@mui/icons-material/TextSnippet';
|
||||||
import { makeStyles } from "@mui/styles";
|
import { makeStyles } from "@mui/styles";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router-dom';
|
||||||
|
|
||||||
const drawerWidth = 240;
|
const drawerWidth = 240;
|
||||||
|
|
||||||
|
|
@ -44,14 +44,12 @@ const Main = styled('main', { shouldForwardProp: (prop) => prop !== 'open' })(({
|
||||||
],
|
],
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const NavStyles = makeStyles((theme) => ({
|
const NavStyles = makeStyles((theme) => ({
|
||||||
header: {
|
header: {
|
||||||
borderBottom: "2px solid rgba(0,0,0,0.1)",
|
borderBottom: "2px solid rgba(0,0,0,0.1)",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
},
|
},
|
||||||
title:{
|
title: {
|
||||||
fontWeight: "600!important",
|
fontWeight: "600!important",
|
||||||
fontSize: "1.25rem!important",
|
fontSize: "1.25rem!important",
|
||||||
}
|
}
|
||||||
|
|
@ -62,93 +60,101 @@ const DrawerHeader = styled('div')(({ theme }) => ({
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
padding: theme.spacing(0, 1),
|
padding: theme.spacing(0, 1),
|
||||||
background: 'rgb(246 248 249)',
|
background: 'rgb(246 248 249)',
|
||||||
// necessary for content to be below app bar
|
|
||||||
...theme.mixins.toolbar,
|
...theme.mixins.toolbar,
|
||||||
justifyContent: 'flex-end',
|
justifyContent: 'flex-end',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export default function PersistentDrawerLeft({ handleDrawerClose, open}) {
|
export default function PersistentDrawerLeft({ handleDrawerClose, open }) {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
const drawerRef = useRef(null); // Create a ref for the drawer
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
document.addEventListener('mousedown', handleDrawerClose);
|
const handleClickOutside = (event) => {
|
||||||
|
// Check if the click was outside the drawer
|
||||||
|
if (drawerRef.current && !drawerRef.current.contains(event.target)) {
|
||||||
|
handleDrawerClose();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener('mousedown', handleClickOutside);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
document.removeEventListener('mousedown', handleDrawerClose);
|
document.removeEventListener('mousedown', handleClickOutside);
|
||||||
};
|
};
|
||||||
}, []);
|
}, [handleDrawerClose]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Drawer
|
<Drawer
|
||||||
sx={{
|
ref={drawerRef} // Attach the ref to the Drawer
|
||||||
|
sx={{
|
||||||
|
width: drawerWidth,
|
||||||
|
flexShrink: 0,
|
||||||
|
'& .MuiDrawer-paper': {
|
||||||
width: drawerWidth,
|
width: drawerWidth,
|
||||||
flexShrink: 0,
|
boxSizing: 'border-box',
|
||||||
'& .MuiDrawer-paper': {
|
},
|
||||||
width: drawerWidth,
|
}}
|
||||||
boxSizing: 'border-box',
|
variant="persistent"
|
||||||
},
|
anchor="left"
|
||||||
}}
|
open={open}
|
||||||
variant="persistent"
|
>
|
||||||
anchor="left"
|
<DrawerHeader>
|
||||||
open={open}
|
<IconButton onClick={handleDrawerClose}>
|
||||||
>
|
{theme.direction === 'ltr' ? <ChevronLeftIcon /> : <ChevronRightIcon />}
|
||||||
<DrawerHeader>
|
</IconButton>
|
||||||
<IconButton onClick={handleDrawerClose}>
|
</DrawerHeader>
|
||||||
{theme.direction === 'ltr' ? <ChevronLeftIcon /> : <ChevronRightIcon />}
|
<Divider />
|
||||||
</IconButton>
|
<List>
|
||||||
</DrawerHeader>
|
<ListItem key={'Dashboard'} disablePadding component={Link} to={'dashboard'} selected={location.pathname == '/dashboard'}>
|
||||||
<Divider />
|
<ListItemButton>
|
||||||
<List>
|
<ListItemIcon>
|
||||||
<ListItem key={'Dashboard'} disablePadding component={Link} to={'dashboard'} selected={location.pathname=='/dashboard'}>
|
<PersonIcon />
|
||||||
<ListItemButton>
|
</ListItemIcon>
|
||||||
<ListItemIcon>
|
<ListItemText primary={'Dashboard'} />
|
||||||
<PersonIcon />
|
</ListItemButton>
|
||||||
</ListItemIcon>
|
</ListItem>
|
||||||
<ListItemText primary={'Dashboard'} />
|
<ListItem key={'User'} disablePadding component={Link} to={'user'} selected={location.pathname == '/user'}>
|
||||||
</ListItemButton>
|
<ListItemButton>
|
||||||
</ListItem>
|
<ListItemIcon>
|
||||||
<ListItem key={'User'} disablePadding component={Link} to={'user'} selected={location.pathname=='/user'}>
|
<PersonIcon />
|
||||||
<ListItemButton>
|
</ListItemIcon>
|
||||||
<ListItemIcon>
|
<ListItemText primary={'User'} />
|
||||||
<PersonIcon />
|
</ListItemButton>
|
||||||
</ListItemIcon>
|
</ListItem>
|
||||||
<ListItemText primary={'User'} />
|
<ListItem key={'Quotes'} disablePadding component={Link} to={'quotes'} selected={location.pathname == '/quotes'}>
|
||||||
</ListItemButton>
|
<ListItemButton>
|
||||||
</ListItem>
|
<ListItemIcon>
|
||||||
<ListItem key={'Quotes'} disablePadding component={Link} to={'quotes'} selected={location.pathname=='/quotes'}>
|
<MonetizationOnIcon />
|
||||||
<ListItemButton>
|
</ListItemIcon>
|
||||||
<ListItemIcon>
|
<ListItemText primary={'Quotes'} />
|
||||||
<MonetizationOnIcon />
|
</ListItemButton>
|
||||||
</ListItemIcon>
|
</ListItem>
|
||||||
<ListItemText primary={'Quotes'} />
|
<ListItem key={'WorkOrder'} disablePadding component={Link} to={'workOrder'} selected={location.pathname == '/workOrder'}>
|
||||||
</ListItemButton>
|
<ListItemButton>
|
||||||
</ListItem>
|
<ListItemIcon>
|
||||||
<ListItem key={'WorkOrder'} disablePadding component={Link} to={'workOrder'} selected={location.pathname=='/workOrder'}>
|
<TextSnippetIcon />
|
||||||
<ListItemButton>
|
</ListItemIcon>
|
||||||
<ListItemIcon>
|
<ListItemText primary={'Work Order'} />
|
||||||
<TextSnippetIcon />
|
</ListItemButton>
|
||||||
</ListItemIcon>
|
</ListItem>
|
||||||
<ListItemText primary={'Work Order'} />
|
<ListItem key={'Contacts'} disablePadding component={Link} to={'contacts'} selected={location.pathname == '/contacts'}>
|
||||||
</ListItemButton>
|
<ListItemButton>
|
||||||
</ListItem>
|
<ListItemIcon>
|
||||||
<ListItem key={'Contacts'} disablePadding component={Link} to={'contacts'} selected={location.pathname=='/contacts'}>
|
<TextSnippetIcon />
|
||||||
<ListItemButton>
|
</ListItemIcon>
|
||||||
<ListItemIcon>
|
<ListItemText primary={'Contacts'} />
|
||||||
<TextSnippetIcon />
|
</ListItemButton>
|
||||||
</ListItemIcon>
|
</ListItem>
|
||||||
<ListItemText primary={'Contacts'} />
|
<ListItem key={'AddressBook'} disablePadding component={Link} to={'addressBook'} selected={location.pathname == '/addressBook'}>
|
||||||
</ListItemButton>
|
<ListItemButton>
|
||||||
</ListItem>
|
<ListItemIcon>
|
||||||
<ListItem key={'AddressBook'} disablePadding component={Link} to={'addressBook'} selected={location.pathname=='/addressBook'}>
|
<TextSnippetIcon />
|
||||||
<ListItemButton>
|
</ListItemIcon>
|
||||||
<ListItemIcon>
|
<ListItemText primary={'Address Book'} />
|
||||||
<TextSnippetIcon />
|
</ListItemButton>
|
||||||
</ListItemIcon>
|
</ListItem>
|
||||||
<ListItemText primary={'Address Book'} />
|
</List>
|
||||||
</ListItemButton>
|
</Drawer>
|
||||||
</ListItem>
|
|
||||||
</List>
|
|
||||||
</Drawer>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -6,7 +6,6 @@ import ListHeaderStyles from "./ListHeader.Styles";
|
||||||
const ListHeader = ({ handleClickFormModalOpen, isEmpty, text }) => {
|
const ListHeader = ({ handleClickFormModalOpen, isEmpty, text }) => {
|
||||||
const classes = ListHeaderStyles();
|
const classes = ListHeaderStyles();
|
||||||
return (
|
return (
|
||||||
!isEmpty && (
|
|
||||||
<Box component="span" m={1} className={classes.box}>
|
<Box component="span" m={1} className={classes.box}>
|
||||||
<Typography variant="h6" component="h6">
|
<Typography variant="h6" component="h6">
|
||||||
{text}
|
{text}
|
||||||
|
|
@ -20,7 +19,6 @@ const ListHeader = ({ handleClickFormModalOpen, isEmpty, text }) => {
|
||||||
Add
|
Add
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
export default ListHeader;
|
export default ListHeader;
|
||||||
|
|
|
||||||
|
|
@ -76,28 +76,11 @@ const ItemForm = ({
|
||||||
<Box component="form" onSubmit={handleSubmit} noValidate>
|
<Box component="form" onSubmit={handleSubmit} noValidate>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<DialogContentText className={classes.title}>
|
<DialogContentText className={classes.title}>
|
||||||
{PRIMARY_TEXT}
|
{PRIMARY_TEXT.replace("Item", "Address")}
|
||||||
</DialogContentText>
|
</DialogContentText>
|
||||||
|
|
||||||
<TextField
|
|
||||||
id="Name"
|
|
||||||
label="Name"
|
|
||||||
variant="outlined"
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
margin="normal"
|
|
||||||
required
|
|
||||||
name="Name"
|
|
||||||
value={values.name}
|
|
||||||
onChange={(event) => {
|
|
||||||
const { value } = event.target;
|
|
||||||
handleChangeKV("name", value);
|
|
||||||
}}
|
|
||||||
error={!!errors.FirstName}
|
|
||||||
helperText={errors.FirstName}
|
|
||||||
/>
|
|
||||||
<TextField
|
<TextField
|
||||||
id="Title"
|
id="Title"
|
||||||
label="Title"
|
label="Name"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
margin="normal"
|
margin="normal"
|
||||||
|
|
@ -110,7 +93,23 @@ const ItemForm = ({
|
||||||
}}
|
}}
|
||||||
error={!!errors.LastName}
|
error={!!errors.LastName}
|
||||||
helperText={errors.LastName}
|
helperText={errors.LastName}
|
||||||
/>
|
/>
|
||||||
|
<TextField
|
||||||
|
id="Name"
|
||||||
|
label="Address"
|
||||||
|
variant="outlined"
|
||||||
|
style={{ width: '100%' }}
|
||||||
|
margin="normal"
|
||||||
|
required
|
||||||
|
name="Name"
|
||||||
|
value={values.name}
|
||||||
|
onChange={(event) => {
|
||||||
|
const { value } = event.target;
|
||||||
|
handleChangeKV("name", value);
|
||||||
|
}}
|
||||||
|
error={!!errors.FirstName}
|
||||||
|
helperText={errors.FirstName}
|
||||||
|
/>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<Button onClick={handleClose}>Cancel</Button>
|
<Button onClick={handleClose}>Cancel</Button>
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ const TableItems = ({ items, onEditClick, onDeleteClick }) => {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "name",
|
name: "title",
|
||||||
label: "Name",
|
label: "Name",
|
||||||
options: {
|
options: {
|
||||||
display: true,
|
display: true,
|
||||||
|
|
@ -71,8 +71,8 @@ const TableItems = ({ items, onEditClick, onDeleteClick }) => {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "title",
|
name: "name",
|
||||||
label: "Title",
|
label: "Address",
|
||||||
options: {
|
options: {
|
||||||
display: true,
|
display: true,
|
||||||
filter: true,
|
filter: true,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
export const initialValues =
|
export const initialValues =
|
||||||
{
|
{
|
||||||
"workerOrderNumber": "",
|
"workerOrderNumber": "",
|
||||||
"workerOrderTitle": "",
|
"workerOrderTitle": "PLUMBING JANITORIAL SCRUBBER PIT CLEANOUT 13W",
|
||||||
"description": "",
|
"description": "",
|
||||||
"po": "",
|
"po": "",
|
||||||
"tt": "",
|
"tt": "",
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ const ImageDrawer = ({ item, open, setOpen }) => {
|
||||||
<Typography variant="subtitle1">Upload Images</Typography>
|
<Typography variant="subtitle1">Upload Images</Typography>
|
||||||
<Input
|
<Input
|
||||||
type="file"
|
type="file"
|
||||||
inputProps={{ accept: "image/*", multiple: true }} // Allow multiple files
|
inputProps={{ accept: ".jpg, .jpeg, .png, .pdf, .doc, .docx" }} // Allow multiple files
|
||||||
onChange={handleFileChange}
|
onChange={handleFileChange}
|
||||||
style={{ display: 'none' }}
|
style={{ display: 'none' }}
|
||||||
id="file-input"
|
id="file-input"
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,7 @@ import InputLabel from "@mui/material/InputLabel";
|
||||||
import MenuItem from "@mui/material/MenuItem";
|
import MenuItem from "@mui/material/MenuItem";
|
||||||
import Select from "@mui/material/Select";
|
import Select from "@mui/material/Select";
|
||||||
import CloseIcon from "@mui/icons-material/Close";
|
import CloseIcon from "@mui/icons-material/Close";
|
||||||
import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline';
|
import FormStyles from "./Form.Styles";
|
||||||
import FormStyles from "./Form.Styles";
|
|
||||||
import IconButton from "@mui/material/IconButton";
|
import IconButton from "@mui/material/IconButton";
|
||||||
import Typography from "@mui/material/Typography";
|
import Typography from "@mui/material/Typography";
|
||||||
import useForm from "../../../hooks/useForm";
|
import useForm from "../../../hooks/useForm";
|
||||||
|
|
@ -21,6 +20,7 @@ import SubmitButtonWithLoader from "../../../components/SubmitButtonWithLoader";
|
||||||
import { form_text_builder, API_SUCCESS_MESSAGE } from "../../../constants";
|
import { form_text_builder, API_SUCCESS_MESSAGE } from "../../../constants";
|
||||||
import { getContacts, getCategories, getLocations, getUsers } from '../../contacts/list/api';
|
import { getContacts, getCategories, getLocations, getUsers } from '../../contacts/list/api';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
|
||||||
const ItemForm = ({
|
const ItemForm = ({
|
||||||
item,
|
item,
|
||||||
mode,
|
mode,
|
||||||
|
|
@ -28,6 +28,7 @@ const ItemForm = ({
|
||||||
setOpen,
|
setOpen,
|
||||||
apiCall,
|
apiCall,
|
||||||
setApiStatus,
|
setApiStatus,
|
||||||
|
viewOnly = false // New prop added here
|
||||||
}) => {
|
}) => {
|
||||||
const [isFormLoading, setIsFormLoading] = useState(false);
|
const [isFormLoading, setIsFormLoading] = useState(false);
|
||||||
const [workOrders, setWorkOrders] = useState([]);
|
const [workOrders, setWorkOrders] = useState([]);
|
||||||
|
|
@ -58,7 +59,8 @@ const ItemForm = ({
|
||||||
const [isFormSubmit, setIsFormSubmit] = useState(false);
|
const [isFormSubmit, setIsFormSubmit] = useState(false);
|
||||||
const classes = FormStyles();
|
const classes = FormStyles();
|
||||||
const { PRIMARY_TEXT, SECONDARY_TEXT, BUTTON_TEXT } = form_text_builder(mode);
|
const { PRIMARY_TEXT, SECONDARY_TEXT, BUTTON_TEXT } = form_text_builder(mode);
|
||||||
const { values, errors, handleChangeKV, handleSubmit, setValues } = useForm({
|
|
||||||
|
const { values, errors, handleChangeKV, handleSubmit } = useForm({
|
||||||
initialValues: item,
|
initialValues: item,
|
||||||
onSubmit(values) {
|
onSubmit(values) {
|
||||||
setIsFormLoading(true);
|
setIsFormLoading(true);
|
||||||
|
|
@ -81,11 +83,11 @@ const ItemForm = ({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
validate: (formValues) => {
|
validate: (formValues) => {
|
||||||
if (isFormSubmit) setIsFormSubmit(false);
|
if (isFormSubmit) setIsFormSubmit(false);
|
||||||
|
|
||||||
return formValidation(formValues);
|
return formValidation(formValues);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
setOpen({ open: false });
|
setOpen({ open: false });
|
||||||
};
|
};
|
||||||
|
|
@ -95,7 +97,6 @@ const ItemForm = ({
|
||||||
getContacts().then((response) => { handleSuccess(response, setContacts) });
|
getContacts().then((response) => { handleSuccess(response, setContacts) });
|
||||||
getLocations().then((response) => { handleSuccess(response, setLocations) });
|
getLocations().then((response) => { handleSuccess(response, setLocations) });
|
||||||
getCategories().then((response) => { handleSuccess(response, setCategories) });
|
getCategories().then((response) => { handleSuccess(response, setCategories) });
|
||||||
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
function handleSuccess(response, cb) {
|
function handleSuccess(response, cb) {
|
||||||
|
|
@ -113,269 +114,230 @@ const ItemForm = ({
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
<Box component="form" onSubmit={handleSubmit} noValidate>
|
<Box component="form" onSubmit={handleSubmit} noValidate>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<DialogContentText className={classes.title}>
|
<DialogContentText className={classes.title}>
|
||||||
{PRIMARY_TEXT}
|
{PRIMARY_TEXT}
|
||||||
</DialogContentText>
|
</DialogContentText>
|
||||||
<div>
|
<div style={{ display: 'flex', alignItems: 'flex-start' }}> {/* Changed alignItems to flex-start */}
|
||||||
<InputLabel id="PO-label">WO ID:</InputLabel>
|
{/* Left Section */}
|
||||||
<TextField
|
<div style={{ flex: 1, paddingRight: '0.5rem', display: 'flex', flexDirection: 'column' }}>
|
||||||
id="WOID"
|
{/* Full-width Work Order Title */}
|
||||||
label="WO ID:"
|
<InputLabel id="work-order-title">Work Order Title:</InputLabel>
|
||||||
variant="outlined"
|
<TextField
|
||||||
style={{ width: '100%' }}
|
id="workerOrderTitle"
|
||||||
margin="normal"
|
variant="outlined"
|
||||||
required
|
fullWidth
|
||||||
name="workerOrderNumber"
|
margin="normal"
|
||||||
value={values.workerOrderNumber}
|
value={values?.workerOrderTitle || ''}
|
||||||
onChange={(event) => {
|
onChange={viewOnly ? null : (event) => handleChangeKV("workerOrderTitle", event.target.value)}
|
||||||
const { value } = event.target;
|
error={!!errors.workerOrderTitle}
|
||||||
handleChangeKV("workerOrderNumber", value);
|
helperText={errors.workerOrderTitle}
|
||||||
}}
|
disabled={viewOnly} // Disable if in read-only mode
|
||||||
error={!!errors.workerOrderNumber}
|
/>
|
||||||
helperText={errors.workerOrderNumber}
|
|
||||||
/>
|
{/* Inputs Layout for WO number, PO#, TT# */}
|
||||||
|
<div style={{ display: 'flex', flexWrap: 'wrap', justifyContent: 'space-between' }}>
|
||||||
|
<div style={{ flex: '1 1 30%', paddingRight: '0.5rem' }}>
|
||||||
|
<InputLabel id="wo-number-label">WO Number:</InputLabel>
|
||||||
|
<TextField
|
||||||
|
id="workerOrderNumber"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
value={values?.workerOrderNumber || ''}
|
||||||
|
onChange={viewOnly ? null : (event) => handleChangeKV("workerOrderNumber", event.target.value)}
|
||||||
|
error={!!errors.workerOrderNumber}
|
||||||
|
helperText={errors.workerOrderNumber}
|
||||||
|
disabled={viewOnly} // Disable if in read-only mode
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ flex: '1 1 30%', paddingRight: '0.5rem' }}>
|
||||||
|
<InputLabel id="po-label">PO #:</InputLabel>
|
||||||
|
<TextField
|
||||||
|
id="po"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
value={values?.po || ''}
|
||||||
|
onChange={viewOnly ? null : (event) => handleChangeKV("po", event.target.value)}
|
||||||
|
error={!!errors.po}
|
||||||
|
helperText={errors.po}
|
||||||
|
disabled={viewOnly} // Disable if in read-only mode
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ flex: '1 1 30%' }}>
|
||||||
|
<InputLabel id="tt-label">TT #:</InputLabel>
|
||||||
|
<TextField
|
||||||
|
id="tt"
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
value={values?.tt || ''}
|
||||||
|
onChange={viewOnly ? null : (event) => handleChangeKV("tt", event.target.value)}
|
||||||
|
error={!!errors.tt}
|
||||||
|
helperText={errors.tt}
|
||||||
|
disabled={viewOnly} // Disable if in read-only mode
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Inputs Layout for Priority, Schedule Date, Due Date */}
|
||||||
|
<div style={{ display: 'flex', flexWrap: 'wrap', justifyContent: 'space-between' }}>
|
||||||
|
<div style={{ flex: '1 1 30%', paddingRight: '0.5rem' }}>
|
||||||
|
<InputLabel id="priority-label">Priority:</InputLabel>
|
||||||
|
<Select
|
||||||
|
fullWidth
|
||||||
|
id="priority"
|
||||||
|
value={values?.priority || ''}
|
||||||
|
onChange={viewOnly ? null : (event) => handleChangeKV("priority", event.target.value)}
|
||||||
|
disabled={viewOnly} // Disable if in read-only mode
|
||||||
|
>
|
||||||
|
{priorities.map((priority, index) => (
|
||||||
|
<MenuItem value={priority.value} key={index}>
|
||||||
|
{priority.text}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ flex: '1 1 30%', paddingRight: '0.5rem' }}>
|
||||||
|
<InputLabel id="schedule-date-label">Schedule Date:</InputLabel>
|
||||||
|
<TextField
|
||||||
|
id="scheduleDate"
|
||||||
|
type="date"
|
||||||
|
fullWidth
|
||||||
|
defaultValue={moment(values?.scheduleDate).format("YYYY-MM-DD") || ''}
|
||||||
|
onChange={viewOnly ? null : (event) => handleChangeKV("scheduleDate", event.target.value)}
|
||||||
|
disabled={viewOnly} // Disable if in read-only mode
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ flex: '1 1 30%' }}>
|
||||||
|
<InputLabel id="due-date-label">Due Date:</InputLabel>
|
||||||
|
<TextField
|
||||||
|
id="dueDate"
|
||||||
|
type="date"
|
||||||
|
fullWidth
|
||||||
|
defaultValue={moment(values?.dueDate).format("YYYY-MM-DD") || ''}
|
||||||
|
onChange={viewOnly ? null : (event) => handleChangeKV("dueDate", event.target.value)}
|
||||||
|
disabled={viewOnly} // Disable if in read-only mode
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Inputs Layout for Categories and Work Order Type */}
|
||||||
|
<div style={{ display: 'flex', flexWrap: 'wrap', justifyContent: 'space-between' }}>
|
||||||
|
<div style={{ flex: '1 1 48%', paddingRight: '0.5rem' }}>
|
||||||
|
<InputLabel id="categories-label">Categories:</InputLabel>
|
||||||
|
<Select
|
||||||
|
fullWidth
|
||||||
|
id="categories"
|
||||||
|
value={values.categoryId || ''}
|
||||||
|
onChange={viewOnly ? null : (event) => handleChangeKV("workOrderCategories", event.target.value)}
|
||||||
|
disabled={viewOnly} // Disable if in read-only mode
|
||||||
|
>
|
||||||
|
{categories.map((category) => (
|
||||||
|
<MenuItem value={category.id} key={category.id}>
|
||||||
|
{category.name}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ flex: '1 1 48%' }}>
|
||||||
|
<InputLabel id="work-order-type-label">Work Order Type:</InputLabel>
|
||||||
|
<Select
|
||||||
|
fullWidth
|
||||||
|
id="workOrderType"
|
||||||
|
value={values.workOrderType || ''}
|
||||||
|
onChange={viewOnly ? null : (event) => handleChangeKV("workOrderType", event.target.value)}
|
||||||
|
disabled={viewOnly} // Disable if in read-only mode
|
||||||
|
>
|
||||||
|
{workOrderTypes.map((type) => (
|
||||||
|
<MenuItem value={type.value} key={type.value}>
|
||||||
|
{type.text}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Contact and Dispatcher */}
|
||||||
|
<div style={{ display: 'flex', flexWrap: 'wrap', justifyContent: 'space-between' }}>
|
||||||
|
<div style={{ flex: '1 1 48%', paddingRight: '0.5rem' }}>
|
||||||
|
<InputLabel id="site-contact-label">Site Contact:</InputLabel>
|
||||||
|
<Select
|
||||||
|
fullWidth
|
||||||
|
value={values.contactId || ''}
|
||||||
|
onChange={viewOnly ? null : (event) => handleChangeKV("workOrderContacts", event.target.value)}
|
||||||
|
disabled={viewOnly} // Disable if in read-only mode
|
||||||
|
>
|
||||||
|
{contacts.map((contact) => (
|
||||||
|
<MenuItem value={contact.id} key={contact.id}>
|
||||||
|
{contact.name}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ flex: '1 1 48%' }}>
|
||||||
|
<InputLabel id="dispatcher-label">Dispatcher:</InputLabel>
|
||||||
|
<Select
|
||||||
|
fullWidth
|
||||||
|
value={values.assignTo || ''}
|
||||||
|
onChange={viewOnly ? null : (event) => handleChangeKV("assignTo", event.target.value)}
|
||||||
|
disabled={viewOnly} // Disable if in read-only mode
|
||||||
|
>
|
||||||
|
{users.map((user) => (
|
||||||
|
<MenuItem value={user.id} key={user.id}>
|
||||||
|
{user.firstName}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Location */}
|
||||||
|
<div style={{ flex: '1 1 100%', paddingRight: '0.5rem' }}>
|
||||||
|
<InputLabel id="location-label">Location:</InputLabel>
|
||||||
|
<Select
|
||||||
|
fullWidth
|
||||||
|
value={values.locationId || ''}
|
||||||
|
onChange={viewOnly ? null : (event) => handleChangeKV("locationId", event.target.value)}
|
||||||
|
disabled={viewOnly} // Disable if in read-only mode
|
||||||
|
>
|
||||||
|
{locations.map((location) => (
|
||||||
|
<MenuItem value={location.id} key={location.id}>
|
||||||
|
{location.name}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
<Select
|
|
||||||
labelId="work-order-title-select-label"
|
|
||||||
id="work-order-title-select"
|
|
||||||
fullWidth
|
|
||||||
value={values.workOrderTitle || ''}
|
|
||||||
onChange={(event) => {
|
|
||||||
const { value } = event.target;
|
|
||||||
handleChangeKV("workerOrderTitle", value);
|
|
||||||
}}
|
|
||||||
label="Work Order Title"
|
|
||||||
>
|
|
||||||
{workOrderTitles.map((title, index) => (
|
|
||||||
<MenuItem value={title} key={index}>
|
|
||||||
{title}
|
|
||||||
</MenuItem>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
<InputLabel id="PO-label">Work Order Title:</InputLabel>
|
|
||||||
<TextField
|
|
||||||
id="WorkerOrderTitle"
|
|
||||||
variant="outlined"
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
margin="normal"
|
|
||||||
required
|
|
||||||
name="workerOrderTitle"
|
|
||||||
value={values.workerOrderTitle}
|
|
||||||
onChange={(event) => {
|
|
||||||
const { value } = event.target;
|
|
||||||
handleChangeKV("workerOrderTitle", value);
|
|
||||||
}}
|
|
||||||
error={!!errors.workerOrderTitle}
|
|
||||||
helperText={errors.workerOrderTitle}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<InputLabel id="description-label">Description</InputLabel>
|
|
||||||
<TextField
|
|
||||||
id="Description"
|
|
||||||
label="Description"
|
|
||||||
variant="outlined"
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
margin="normal"
|
|
||||||
required
|
|
||||||
name="description"
|
|
||||||
value={values.description}
|
|
||||||
onChange={(event) => {
|
|
||||||
const { value } = event.target;
|
|
||||||
handleChangeKV("description", value);
|
|
||||||
}}
|
|
||||||
error={!!errors.description}
|
|
||||||
helperText={errors.description}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<InputLabel id="PO-label">PO # :</InputLabel>
|
|
||||||
<TextField
|
|
||||||
id="po"
|
|
||||||
label=""
|
|
||||||
variant="outlined"
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
margin="normal"
|
|
||||||
required
|
|
||||||
name="po"
|
|
||||||
value={values?.po}
|
|
||||||
onChange={(event) => {
|
|
||||||
const { value } = event.target;
|
|
||||||
handleChangeKV("po", value);
|
|
||||||
}}
|
|
||||||
error={!!errors.po}
|
|
||||||
helperText={errors.po}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<InputLabel id="TT-label">TT #</InputLabel>
|
|
||||||
<TextField
|
|
||||||
id="tt"
|
|
||||||
label=""
|
|
||||||
variant="outlined"
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
margin="normal"
|
|
||||||
required
|
|
||||||
name="tt"
|
|
||||||
value={values?.tt}
|
|
||||||
onChange={(event) => {
|
|
||||||
const { value } = event.target;
|
|
||||||
handleChangeKV("tt", value);
|
|
||||||
}}
|
|
||||||
error={!!errors.tt}
|
|
||||||
helperText={errors.tt}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<InputLabel id="Wo-select-date-label">Due Date*</InputLabel>
|
|
||||||
<TextField
|
|
||||||
id="DueDate"
|
|
||||||
label=""
|
|
||||||
variant="outlined"
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
margin="normal"
|
|
||||||
required
|
|
||||||
name="dueDate"
|
|
||||||
type="date"
|
|
||||||
defaultValue={ moment(values.formattedDueDate).format("YYYY-MM-DD")}
|
|
||||||
onChange={(event) => {
|
|
||||||
const { value } = event.target;
|
|
||||||
handleChangeKV("dueDate", value);
|
|
||||||
}}
|
|
||||||
error={!!errors.dueDate}
|
|
||||||
helperText={errors.dueDate}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<InputLabel id="Wo-select-contact-label">POC*</InputLabel>
|
|
||||||
<Select
|
|
||||||
labelId="Wo-select-contact-label"
|
|
||||||
id="wo"
|
|
||||||
fullWidth
|
|
||||||
value={values.contactId}
|
|
||||||
label=""
|
|
||||||
onChange={(event) => {
|
|
||||||
const { value } = event.target;
|
|
||||||
handleChangeKV("workOrderContacts", value?.toString());
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{contacts.map((s, i) => (
|
|
||||||
<MenuItem value={s.id} key={i}>
|
|
||||||
{s.name}
|
|
||||||
</MenuItem>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<InputLabel id="Wo-select-label">Assigned To:*</InputLabel>
|
|
||||||
<Select
|
|
||||||
labelId="AssignTo-label"
|
|
||||||
id="AssignTo"
|
|
||||||
fullWidth
|
|
||||||
value={values.assignTo}
|
|
||||||
label=""
|
|
||||||
onChange={(event) => {
|
|
||||||
const { value } = event.target;
|
|
||||||
handleChangeKV("assignTo", value);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{users.map((s, i) => (
|
|
||||||
<MenuItem value={s.id} key={i}>
|
|
||||||
{s.firstName}
|
|
||||||
</MenuItem>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<InputLabel id="Wo-select-label">Priority:*</InputLabel>
|
|
||||||
<Select
|
|
||||||
labelId="Priority-label"
|
|
||||||
id="Priority"
|
|
||||||
fullWidth
|
|
||||||
value={values.priority}
|
|
||||||
label=""
|
|
||||||
onChange={(event) => {
|
|
||||||
const { value } = event.target;
|
|
||||||
handleChangeKV("priority", value);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{priorities.map((s, i) => (
|
|
||||||
<MenuItem value={s.value} key={i}>
|
|
||||||
{s.text}
|
|
||||||
</MenuItem>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<InputLabel id="work-order-type-select-label">Work Order Type:*</InputLabel>
|
|
||||||
<Select
|
|
||||||
labelId="work-order-type-select-label"
|
|
||||||
id="work-order-type-select"
|
|
||||||
value={values.workOrderType}
|
|
||||||
fullWidth
|
|
||||||
onChange={(event) => {
|
|
||||||
const { value } = event.target;
|
|
||||||
handleChangeKV("workOrderType", value);
|
|
||||||
}}
|
|
||||||
label="Work Order Type"
|
|
||||||
>
|
|
||||||
{workOrderTypes.map((type, index) => (
|
|
||||||
<MenuItem value={type.value} key={index}>
|
|
||||||
{type.text}
|
|
||||||
</MenuItem>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<InputLabel id="Wo-select-label">Location:*</InputLabel>
|
|
||||||
<Select
|
|
||||||
id="Location"
|
|
||||||
fullWidth
|
|
||||||
value={values.locationId}
|
|
||||||
label=""
|
|
||||||
onChange={(event) => {
|
|
||||||
const { value } = event.target;
|
|
||||||
handleChangeKV("locationId", value);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{locations.map((s, i) => (
|
|
||||||
<MenuItem value={s.id} key={i}>
|
|
||||||
{s.name}
|
|
||||||
</MenuItem>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
{/* Right Section for Notes, starts at the same level as Work Order Title */}
|
||||||
<InputLabel id="Wo-select-label">Categories:*</InputLabel>
|
<div style={{ flex: '1', paddingLeft: '0.5rem', marginTop: '1.25rem' }}> {/* Added margin-top to align with the title */}
|
||||||
<Select
|
<InputLabel id="notes-label">Notes:</InputLabel>
|
||||||
labelId="categories-label"
|
<TextField
|
||||||
id="categories"
|
id="notes"
|
||||||
fullWidth
|
variant="outlined"
|
||||||
value={values.categoryId}
|
multiline
|
||||||
label=""
|
rows={10} // Larger textarea
|
||||||
onChange={(event) => {
|
fullWidth
|
||||||
const { value } = event.target;
|
value={values?.notes || ''}
|
||||||
handleChangeKV("workOrderCategories", value?.toString());
|
onChange={viewOnly ? null : (event) => handleChangeKV("notes", event.target.value)}
|
||||||
}}
|
disabled={viewOnly} // Disable if in read-only mode
|
||||||
>
|
/>
|
||||||
{categories.map((s, i) => (
|
</div>
|
||||||
<MenuItem value={s.id} key={i}>
|
|
||||||
{s.name}
|
|
||||||
</MenuItem>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<Button onClick={handleClose}>Cancel</Button>
|
<Button onClick={handleClose}>Close</Button>
|
||||||
<SubmitButtonWithLoader
|
{!viewOnly && (
|
||||||
buttonText={BUTTON_TEXT}
|
<SubmitButtonWithLoader
|
||||||
loading={isFormLoading}
|
buttonText={BUTTON_TEXT}
|
||||||
/>
|
loading={isFormLoading}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
</Box>
|
</Box>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
@ -384,4 +346,4 @@ const ItemForm = ({
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ItemForm;
|
export default ItemForm;
|
||||||
|
|
@ -4,12 +4,35 @@ import IconButton from "@mui/material/IconButton";
|
||||||
import EditOutlined from "@mui/icons-material/EditOutlined";
|
import EditOutlined from "@mui/icons-material/EditOutlined";
|
||||||
import DeleteIcon from "@mui/icons-material/Delete";
|
import DeleteIcon from "@mui/icons-material/Delete";
|
||||||
import SpeakerNotes from '@mui/icons-material/SpeakerNotes';
|
import SpeakerNotes from '@mui/icons-material/SpeakerNotes';
|
||||||
|
import PermMediaIcon from '@mui/icons-material/PermMedia';
|
||||||
|
import Select from "@mui/material/Select";
|
||||||
|
import MenuItem from "@mui/material/MenuItem";
|
||||||
import TableStyles from './TableStyles';
|
import TableStyles from './TableStyles';
|
||||||
import { createTheme, ThemeProvider } from '@mui/material/styles';
|
import { createTheme, ThemeProvider } from '@mui/material/styles';
|
||||||
import PermMediaIcon from '@mui/icons-material/PermMedia';
|
import { post } from '../../../apiUtil';
|
||||||
|
import { API_URL } from '../../../constants';
|
||||||
|
|
||||||
const TableItems = ({ items, onEditClick, onDeleteClick, onOpenNoteClick, onOpenAttachmentsClick }) => {
|
export const EditStatus = (item) => post(`${API_URL}/WorkOrder/EditStatus`, item);
|
||||||
|
export const EditAvettaTask = (item) => post(`${API_URL}/WorkOrder/EditAvettaTask`, item);
|
||||||
|
|
||||||
|
const TableItems = ({ items, onEditClick, onDeleteClick, onOpenNoteClick, onOpenAttachmentsClick, onRowClickViewOnly }) => {
|
||||||
const classes = TableStyles();
|
const classes = TableStyles();
|
||||||
|
|
||||||
|
const statusOptions = [
|
||||||
|
"Open",
|
||||||
|
"Pending",
|
||||||
|
"Assigned",
|
||||||
|
"In Progress",
|
||||||
|
"On Hold",
|
||||||
|
"Cancelled",
|
||||||
|
"Completed"
|
||||||
|
];
|
||||||
|
|
||||||
|
const completionOptions = [
|
||||||
|
"Yes, Complete",
|
||||||
|
"Yes, Incomplete",
|
||||||
|
"No" // Default option
|
||||||
|
];
|
||||||
|
|
||||||
const getMuiTheme = () => {
|
const getMuiTheme = () => {
|
||||||
return createTheme({
|
return createTheme({
|
||||||
|
|
@ -19,49 +42,61 @@ const TableItems = ({ items, onEditClick, onDeleteClick, onOpenNoteClick, onOpen
|
||||||
root: {
|
root: {
|
||||||
backgroundColor: '#98acbf',
|
backgroundColor: '#98acbf',
|
||||||
color: '#fff',
|
color: '#fff',
|
||||||
}
|
cursor: 'col-resize', // Indicate column can be resized
|
||||||
},
|
},
|
||||||
},
|
|
||||||
MUIDataTableSelectCell: {
|
|
||||||
styleOverrides: {
|
|
||||||
headerCell: {
|
|
||||||
backgroundColor: '#98acbf',
|
|
||||||
color: '#fff',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
MUIDataTableBodyRow: {
|
|
||||||
styleOverrides: {
|
|
||||||
root: {
|
|
||||||
'&:nth-of-type(odd)': {
|
|
||||||
backgroundColor: 'rgba(0, 0, 0, 0.02)'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
MUIDataTableBodyCell: {
|
MUIDataTableBodyCell: {
|
||||||
styleOverrides: {
|
styleOverrides: {
|
||||||
root: {
|
root: {
|
||||||
padding: 6,
|
padding: 6,
|
||||||
wordBreak: 'break-all'
|
wordBreak: 'break-all',
|
||||||
}
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MUIDataTableBodyRow: {
|
||||||
|
styleOverrides: {
|
||||||
|
root: {
|
||||||
|
cursor: 'pointer', // Change cursor to pointer for clickable rows
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
|
const updateStatusOnServer = async (id, status) => {
|
||||||
|
try {
|
||||||
|
await EditStatus({ id, status });
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error updating status:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateTaskOnServer = async (id, avettaTask) => {
|
||||||
|
try {
|
||||||
|
await EditAvettaTask({ id, avettaTask });
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error updating Avetta Task:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleRowClick = (rowData, rowMeta) => {
|
||||||
|
const index = rowMeta.dataIndex;
|
||||||
|
const selectedItem = items[index]; // Access the original items array
|
||||||
|
onRowClickViewOnly({ open: true, selectedItem, viewOnly:true }); // Pass the selected item
|
||||||
|
};
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
name: "id",
|
name: "id",
|
||||||
label: "id",
|
label: "ID",
|
||||||
options: {
|
options: {
|
||||||
display: false,
|
display: false,
|
||||||
filter: false,
|
filter: false,
|
||||||
sort: false,
|
sort: false,
|
||||||
viewColumns:false,
|
viewColumns: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "workerOrderNumber",
|
name: "workerOrderNumber",
|
||||||
|
|
@ -70,7 +105,7 @@ const TableItems = ({ items, onEditClick, onDeleteClick, onOpenNoteClick, onOpen
|
||||||
display: true,
|
display: true,
|
||||||
filter: false,
|
filter: false,
|
||||||
sort: true,
|
sort: true,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "workerOrderTitle",
|
name: "workerOrderTitle",
|
||||||
|
|
@ -79,7 +114,7 @@ const TableItems = ({ items, onEditClick, onDeleteClick, onOpenNoteClick, onOpen
|
||||||
display: true,
|
display: true,
|
||||||
filter: false,
|
filter: false,
|
||||||
sort: true,
|
sort: true,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "assignToUserName",
|
name: "assignToUserName",
|
||||||
|
|
@ -88,7 +123,7 @@ const TableItems = ({ items, onEditClick, onDeleteClick, onOpenNoteClick, onOpen
|
||||||
display: true,
|
display: true,
|
||||||
filter: true,
|
filter: true,
|
||||||
sort: false,
|
sort: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "priority",
|
name: "priority",
|
||||||
|
|
@ -97,7 +132,7 @@ const TableItems = ({ items, onEditClick, onDeleteClick, onOpenNoteClick, onOpen
|
||||||
display: true,
|
display: true,
|
||||||
filter: true,
|
filter: true,
|
||||||
sort: false,
|
sort: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "status",
|
name: "status",
|
||||||
|
|
@ -106,7 +141,58 @@ const TableItems = ({ items, onEditClick, onDeleteClick, onOpenNoteClick, onOpen
|
||||||
display: true,
|
display: true,
|
||||||
filter: true,
|
filter: true,
|
||||||
sort: false,
|
sort: false,
|
||||||
}
|
customBodyRender: (value, tableMeta, updateValue) => {
|
||||||
|
return (
|
||||||
|
<Select
|
||||||
|
labelId="status-select-label"
|
||||||
|
id="status-select"
|
||||||
|
value={value || 'Open'}
|
||||||
|
onChange={async (event) => {
|
||||||
|
const newStatus = event.target.value;
|
||||||
|
const rowId = tableMeta.rowData[0];
|
||||||
|
await updateStatusOnServer(rowId, newStatus);
|
||||||
|
updateValue(newStatus);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{statusOptions.map((status) => (
|
||||||
|
<MenuItem value={status} key={status}>
|
||||||
|
{status}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "avettaTask",
|
||||||
|
label: "Avetta Task", // New column
|
||||||
|
options: {
|
||||||
|
display: true,
|
||||||
|
filter: true,
|
||||||
|
sort: false,
|
||||||
|
customBodyRender: (value, tableMeta, updateValue) => {
|
||||||
|
return (
|
||||||
|
<Select
|
||||||
|
labelId="avetta-task-select-label"
|
||||||
|
id="avetta-task-select"
|
||||||
|
value={value || 'No'} // Default to 'No'
|
||||||
|
onChange={async (event) => {
|
||||||
|
const newAvettaTask = event.target.value;
|
||||||
|
const rowId = tableMeta.rowData[0];
|
||||||
|
await updateTaskOnServer(rowId, newAvettaTask); // Update server with new task status
|
||||||
|
updateValue(newAvettaTask);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{completionOptions.map((completion) => (
|
||||||
|
<MenuItem value={completion} key={completion}>
|
||||||
|
{completion}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "formattedDueDate",
|
name: "formattedDueDate",
|
||||||
|
|
@ -115,7 +201,16 @@ const TableItems = ({ items, onEditClick, onDeleteClick, onOpenNoteClick, onOpen
|
||||||
display: true,
|
display: true,
|
||||||
filter: true,
|
filter: true,
|
||||||
sort: false,
|
sort: false,
|
||||||
}
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "formattedAssignDate",
|
||||||
|
label: "AssignDate",
|
||||||
|
options: {
|
||||||
|
display: true,
|
||||||
|
filter: true,
|
||||||
|
sort: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "",
|
name: "",
|
||||||
|
|
@ -124,7 +219,7 @@ const TableItems = ({ items, onEditClick, onDeleteClick, onOpenNoteClick, onOpen
|
||||||
filter: false,
|
filter: false,
|
||||||
sort: false,
|
sort: false,
|
||||||
empty: true,
|
empty: true,
|
||||||
customBodyRender: (value, tableMeta, updateValue) => {
|
customBodyRender: (value, tableMeta) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<IconButton
|
<IconButton
|
||||||
|
|
@ -133,41 +228,25 @@ const TableItems = ({ items, onEditClick, onDeleteClick, onOpenNoteClick, onOpen
|
||||||
className={classes.IconButton}
|
className={classes.IconButton}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
const id = tableMeta.rowData[0];
|
const rowIndex = tableMeta.rowIndex; // Get the index of the row
|
||||||
const _selectedItem = tableMeta.tableData
|
const selectedItem = items[rowIndex]; // Access the original items array
|
||||||
.find(obj => obj.id == id);
|
onEditClick({ open: true, selectedItem }); // Pass the selected item
|
||||||
onEditClick({ open: true, selectedItem: _selectedItem });
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<EditOutlined />
|
<EditOutlined />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<IconButton
|
|
||||||
edge="end"
|
|
||||||
aria-label="delete"
|
|
||||||
className={classes.IconButton}
|
|
||||||
onClick={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
const id = tableMeta.rowData[0];
|
|
||||||
const _selectedItem = tableMeta.tableData
|
|
||||||
.find(obj => obj.id == id);
|
|
||||||
onDeleteClick({ open: true, selectedItem: _selectedItem });
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<DeleteIcon />
|
|
||||||
</IconButton>
|
|
||||||
<IconButton
|
<IconButton
|
||||||
edge="end"
|
edge="end"
|
||||||
aria-label="history"
|
aria-label="history"
|
||||||
className={classes.IconButton}
|
className={classes.IconButton}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
const id = tableMeta.rowData[0];
|
const rowIndex = tableMeta.rowIndex; // Get the index of the row
|
||||||
const _selectedItem = tableMeta.tableData
|
const selectedItem = items[rowIndex]; // Access the original items array
|
||||||
.find(obj => obj.id == id);
|
onOpenNoteClick({ open: true, selectedItem }); // Pass the selected item
|
||||||
onOpenNoteClick({ open: true, selectedItem: _selectedItem });
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SpeakerNotes/>
|
<SpeakerNotes />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<IconButton
|
<IconButton
|
||||||
edge="end"
|
edge="end"
|
||||||
|
|
@ -175,13 +254,25 @@ const TableItems = ({ items, onEditClick, onDeleteClick, onOpenNoteClick, onOpen
|
||||||
className={classes.IconButton}
|
className={classes.IconButton}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
const id = tableMeta.rowData[0];
|
const rowIndex = tableMeta.rowIndex; // Get the index of the row
|
||||||
const _selectedItem = tableMeta.tableData
|
const selectedItem = items[rowIndex]; // Access the original items array
|
||||||
.find(obj => obj.id == id);
|
onOpenAttachmentsClick({ open: true, selectedItem }); // Pass the selected item
|
||||||
onOpenAttachmentsClick({ open: true, selectedItem: _selectedItem });
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<PermMediaIcon/>
|
<PermMediaIcon />
|
||||||
|
</IconButton>
|
||||||
|
<IconButton
|
||||||
|
edge="end"
|
||||||
|
aria-label="delete"
|
||||||
|
className={classes.IconButton}
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
const rowIndex = tableMeta.rowIndex; // Get the index of the row
|
||||||
|
const selectedItem = items[rowIndex]; // Access the original items array
|
||||||
|
onDeleteClick({ open: true, selectedItem }); // Pass the selected item
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<DeleteIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
@ -190,16 +281,13 @@ const TableItems = ({ items, onEditClick, onDeleteClick, onOpenNoteClick, onOpen
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const handleRowClick = (rowData, rowMeta) => {
|
|
||||||
console.log(rowData, rowMeta);
|
|
||||||
};
|
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
filterType: "checkbox",
|
filterType: "checkbox",
|
||||||
rowsPerPage: 50,
|
rowsPerPage: 50,
|
||||||
rowsPerPageOptions: [50, 100, 200],
|
rowsPerPageOptions: [50, 100, 200],
|
||||||
jumpToPage: true,
|
jumpToPage: true,
|
||||||
onRowClick: handleRowClick,
|
onRowClick: handleRowClick,
|
||||||
|
resizableColumns: true, // Enables column resizing
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -212,6 +300,6 @@ const TableItems = ({ items, onEditClick, onDeleteClick, onOpenNoteClick, onOpen
|
||||||
/>
|
/>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default React.memo(TableItems);
|
export default React.memo(TableItems);
|
||||||
|
|
@ -3,7 +3,7 @@ import Form from "../components/Form";
|
||||||
import { EDIT } from "../../../constants";
|
import { EDIT } from "../../../constants";
|
||||||
import { editItems } from "./api";
|
import { editItems } from "./api";
|
||||||
|
|
||||||
const EditItemModal = ({ item, open, setOpen, isEdit, setApiStatus }) => {
|
const EditItemModal = ({ item, open, setOpen, isEdit, setApiStatus, viewOnly = false }) => {
|
||||||
return (
|
return (
|
||||||
isEdit && open && (
|
isEdit && open && (
|
||||||
<Form
|
<Form
|
||||||
|
|
@ -13,6 +13,7 @@ const EditItemModal = ({ item, open, setOpen, isEdit, setApiStatus }) => {
|
||||||
mode={EDIT}
|
mode={EDIT}
|
||||||
apiCall={editItems}
|
apiCall={editItems}
|
||||||
setApiStatus={setApiStatus}
|
setApiStatus={setApiStatus}
|
||||||
|
viewOnly = {viewOnly}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,11 @@ const List = () => {
|
||||||
selectedItem: {},
|
selectedItem: {},
|
||||||
open: false,
|
open: false,
|
||||||
});
|
});
|
||||||
|
const [viewOnlyopen, setViewOnlyopen] = React.useState({
|
||||||
|
selectedItem: {},
|
||||||
|
open: false,
|
||||||
|
viewOnly:false,
|
||||||
|
});
|
||||||
const [noteHistoryModalopen, setNoteHistoryModalopen] = React.useState({
|
const [noteHistoryModalopen, setNoteHistoryModalopen] = React.useState({
|
||||||
selectedItem: {},
|
selectedItem: {},
|
||||||
open: false,
|
open: false,
|
||||||
|
|
@ -80,6 +85,7 @@ const List = () => {
|
||||||
onOpenNoteClick = {setNoteHistoryModalopen}
|
onOpenNoteClick = {setNoteHistoryModalopen}
|
||||||
onOpenAttachmentsClick = {setAttachmentsModalopen}
|
onOpenAttachmentsClick = {setAttachmentsModalopen}
|
||||||
isEmpty={isEmptyList}
|
isEmpty={isEmptyList}
|
||||||
|
onRowClickViewOnly = {setViewOnlyopen}
|
||||||
/>
|
/>
|
||||||
<AddModal
|
<AddModal
|
||||||
open={formModalopen.open}
|
open={formModalopen.open}
|
||||||
|
|
@ -88,12 +94,22 @@ const List = () => {
|
||||||
setApiStatus={setApiStatus}
|
setApiStatus={setApiStatus}
|
||||||
/>
|
/>
|
||||||
<EditModal
|
<EditModal
|
||||||
|
key={"edit"}
|
||||||
item={{ ...formModalopen.selectedItem }}
|
item={{ ...formModalopen.selectedItem }}
|
||||||
open={formModalopen.open}
|
open={formModalopen.open}
|
||||||
setOpen={setFormModalopen}
|
setOpen={setFormModalopen}
|
||||||
isEdit={isEdit}
|
isEdit={isEdit}
|
||||||
setApiStatus={setApiStatus}
|
setApiStatus={setApiStatus}
|
||||||
/>
|
/>
|
||||||
|
<EditModal
|
||||||
|
key={"view"}
|
||||||
|
item={{ ...viewOnlyopen.selectedItem }}
|
||||||
|
open={viewOnlyopen.viewOnly}
|
||||||
|
setOpen={() => setViewOnlyopen({viewOnly:false})}
|
||||||
|
isEdit={viewOnlyopen.viewOnly}
|
||||||
|
setApiStatus={setApiStatus}
|
||||||
|
viewOnly={viewOnlyopen.viewOnly}
|
||||||
|
/>
|
||||||
<NoteHistoryDrawer
|
<NoteHistoryDrawer
|
||||||
item={{ ...noteHistoryModalopen.selectedItem }}
|
item={{ ...noteHistoryModalopen.selectedItem }}
|
||||||
open={noteHistoryModalopen.open}
|
open={noteHistoryModalopen.open}
|
||||||
|
|
|
||||||
|
|
@ -17,14 +17,13 @@ const NoteHistoryDrawer = ({ item, open, setOpen, setApiStatus }) => {
|
||||||
const [note, setNote] = useState('');
|
const [note, setNote] = useState('');
|
||||||
const [noteHistory, setNoteHistory] = useState([]);
|
const [noteHistory, setNoteHistory] = useState([]);
|
||||||
const [comments, setComments] = useState([]);
|
const [comments, setComments] = useState([]);
|
||||||
|
const [loaded, setLoaded] = useState(false);
|
||||||
|
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
if (note.trim()) {
|
if (note.trim()) {
|
||||||
await addComments({id: item.id , Comments: [...noteHistory, note]});
|
await addComments({id: item.id , Comments: [...noteHistory, note]});
|
||||||
setNoteHistory([]);
|
setLoaded(true);
|
||||||
setNote('');
|
|
||||||
setOpen(false);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -42,7 +41,7 @@ const NoteHistoryDrawer = ({ item, open, setOpen, setApiStatus }) => {
|
||||||
setComments(_comments);
|
setComments(_comments);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [item])
|
}, [item,loaded])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue