test: edit user action frontend
This commit is contained in:
parent
0cc1a63722
commit
74c0d5235b
|
@ -11,7 +11,8 @@ import {
|
|||
TextField,
|
||||
useTheme,
|
||||
Switch,
|
||||
FormControlLabel
|
||||
FormControlLabel,
|
||||
Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper
|
||||
} from '@mui/material';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
@ -26,6 +27,7 @@ import Button from '@mui/material/Button';
|
|||
import { DateTimePicker, LocalizationProvider } from '@mui/x-date-pickers';
|
||||
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
|
||||
import dayjs from 'dayjs';
|
||||
import { UserContext } from 'src/contexts/userContext';
|
||||
|
||||
interface HistoryProps {
|
||||
errorLoadingS3Data: boolean;
|
||||
|
@ -35,7 +37,8 @@ interface HistoryProps {
|
|||
function HistoryOfActions(props: HistoryProps) {
|
||||
const theme = useTheme();
|
||||
const searchParams = new URLSearchParams(location.search);
|
||||
|
||||
const context = useContext(UserContext);
|
||||
const { currentUser } = context;
|
||||
const [history, setHistory] = useState<Action[]>([]);
|
||||
const navigate = useNavigate();
|
||||
const tokencontext = useContext(TokenContext);
|
||||
|
@ -49,8 +52,10 @@ function HistoryOfActions(props: HistoryProps) {
|
|||
description: ''
|
||||
});
|
||||
const { testModeMap, setTestMode } = useTestMode();
|
||||
const isTestMode = testModeMap[props.id]||false;
|
||||
|
||||
const isTestMode = testModeMap[props.id] || false;
|
||||
const [isRowHovered, setHoveredRow] = useState(-1);
|
||||
const [selectedAction, setSelectedAction] = useState<number>(-1);
|
||||
const [editMode, setEditMode] = useState(false);
|
||||
const handleTestModeToggle = () => {
|
||||
setTestMode(props.id,!isTestMode);
|
||||
};
|
||||
|
@ -70,12 +75,47 @@ function HistoryOfActions(props: HistoryProps) {
|
|||
});
|
||||
};
|
||||
|
||||
const resetNewAction = () => {
|
||||
console.log("Reset action to default");
|
||||
setActionDate(dayjs());
|
||||
setNewAction({
|
||||
...newAction,
|
||||
['description']: '',
|
||||
});
|
||||
setEditMode(false);
|
||||
};
|
||||
|
||||
const handleAddActionButton = () => {
|
||||
setOpenModalAddAction(!openModalAddAction);
|
||||
resetNewAction();
|
||||
//setOpenModalAddAction(!openModalAddAction);
|
||||
setOpenModalAddAction(true);
|
||||
};
|
||||
|
||||
const SumbitNewAction = () => {
|
||||
const res = axiosConfig.post(`/InsertNewAction`, newAction).catch((err) => {
|
||||
const endpoint = editMode ? `/UpdateAction` : `/InsertNewAction`;
|
||||
console.log("Add an action", endpoint);
|
||||
const res=axiosConfig.post(endpoint,newAction).catch((err)=>{
|
||||
if (err.response) {
|
||||
// setError(true);
|
||||
// setLoading(false);
|
||||
}
|
||||
});
|
||||
|
||||
if (res){
|
||||
//setOpenModalAddAction(!openModalAddAction);
|
||||
setOpenModalAddAction(false);
|
||||
setEditMode(false);
|
||||
}
|
||||
};
|
||||
|
||||
const deleteUserModalHandleCancel = (e) => {
|
||||
setOpenModalAddAction(false);
|
||||
setEditMode(false);
|
||||
};
|
||||
|
||||
const HandleDelete = (e) => {
|
||||
console.log("Delete this action");
|
||||
const res = axiosConfig.post(`/DeleteAction`, newAction).catch((err) => {
|
||||
if (err.response) {
|
||||
// setError(true);
|
||||
// setLoading(false);
|
||||
|
@ -83,14 +123,12 @@ function HistoryOfActions(props: HistoryProps) {
|
|||
});
|
||||
|
||||
if (res) {
|
||||
setOpenModalAddAction(!openModalAddAction);
|
||||
console.log("Delete this action is successful");
|
||||
setOpenModalAddAction(false);
|
||||
setEditMode(false);
|
||||
}
|
||||
};
|
||||
|
||||
const deleteUserModalHandleCancel = (e) => {
|
||||
setOpenModalAddAction(false);
|
||||
};
|
||||
|
||||
const areRequiredFieldsFilled = () => {
|
||||
for (const field of requiredFields) {
|
||||
if (!newAction[field]) {
|
||||
|
@ -100,6 +138,33 @@ function HistoryOfActions(props: HistoryProps) {
|
|||
return true;
|
||||
};
|
||||
|
||||
const handleSelectOneAction = (action) => {
|
||||
if (selectedAction != action.id) {
|
||||
setSelectedAction(action.id);
|
||||
setSelectedAction(-1);
|
||||
if (action.userName === currentUser.name){
|
||||
console.log("Select this action");
|
||||
setActionDate(dayjs(action.timestamp));
|
||||
setNewAction({ description: action.description, timestamp: action.timestamp });
|
||||
setEditMode(true);
|
||||
setOpenModalAddAction(true);
|
||||
} else {
|
||||
console.log('The user is not authorized to edit this action.');
|
||||
}
|
||||
|
||||
} else {
|
||||
setSelectedAction(-1);
|
||||
}
|
||||
};
|
||||
|
||||
const handleRowMouseEnter = (id) => {
|
||||
setHoveredRow(id);
|
||||
};
|
||||
|
||||
const handleRowMouseLeave = () => {
|
||||
setHoveredRow(-1);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
axiosConfig
|
||||
.get(`/GetHistoryForInstallation?id=${props.id}`)
|
||||
|
@ -112,6 +177,7 @@ function HistoryOfActions(props: HistoryProps) {
|
|||
navigate(routes.login);
|
||||
}
|
||||
});
|
||||
console.log("Update the tab:", openModalAddAction);
|
||||
}, [openModalAddAction]);
|
||||
|
||||
return (
|
||||
|
@ -216,6 +282,21 @@ function HistoryOfActions(props: HistoryProps) {
|
|||
>
|
||||
Cancel
|
||||
</Button>
|
||||
|
||||
{editMode && (
|
||||
<Button
|
||||
sx={{
|
||||
marginLeft: 2,
|
||||
textTransform: 'none',
|
||||
bgcolor: '#ffc04d',
|
||||
color: '#111111',
|
||||
'&:hover': { bgcolor: '#f7b34d' }
|
||||
}}
|
||||
onClick={HandleDelete}
|
||||
>
|
||||
Delete
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</Box>
|
||||
</LocalizationProvider>
|
||||
|
@ -247,209 +328,254 @@ function HistoryOfActions(props: HistoryProps) {
|
|||
|
||||
<Grid item xs={12} md={12}>
|
||||
{history.length > 0 && (
|
||||
// <Card sx={{ marginTop: '10px' }}>
|
||||
// <Divider />
|
||||
// <div>
|
||||
// <div
|
||||
// style={{
|
||||
// height: '40px',
|
||||
// marginBottom: '10px',
|
||||
// display: 'flex',
|
||||
// alignItems: 'center'
|
||||
// }}
|
||||
// >
|
||||
// <div
|
||||
// style={{
|
||||
// flex: 2,
|
||||
// marginTop: '15px',
|
||||
// display: 'flex',
|
||||
// alignItems: 'center',
|
||||
// justifyContent: 'center'
|
||||
// }}
|
||||
// >
|
||||
// <Typography
|
||||
// variant="body1"
|
||||
// color="dimgrey"
|
||||
// fontWeight="bold"
|
||||
// fontSize="1rem"
|
||||
// gutterBottom
|
||||
// noWrap
|
||||
// >
|
||||
// <FormattedMessage id="user" defaultMessage="User" />
|
||||
// </Typography>
|
||||
// </div>
|
||||
//
|
||||
// <div
|
||||
// style={{
|
||||
// flex: 1,
|
||||
// marginTop: '15px',
|
||||
// display: 'flex',
|
||||
// alignItems: 'center',
|
||||
// justifyContent: 'center'
|
||||
// }}
|
||||
// >
|
||||
// <Typography
|
||||
// variant="body1"
|
||||
// color="dimgrey"
|
||||
// fontWeight="bold"
|
||||
// fontSize="1rem"
|
||||
// gutterBottom
|
||||
// noWrap
|
||||
// >
|
||||
// <FormattedMessage id="date" defaultMessage="Date" />
|
||||
// </Typography>
|
||||
// </div>
|
||||
// <div
|
||||
// style={{
|
||||
// flex: 1,
|
||||
// marginTop: '15px',
|
||||
// display: 'flex',
|
||||
// alignItems: 'center',
|
||||
// justifyContent: 'center'
|
||||
// }}
|
||||
// >
|
||||
// <Typography
|
||||
// variant="body1"
|
||||
// color="dimgrey"
|
||||
// fontWeight="bold"
|
||||
// fontSize="1rem"
|
||||
// gutterBottom
|
||||
// noWrap
|
||||
// >
|
||||
// <FormattedMessage id="time" defaultMessage="Time" />
|
||||
// </Typography>
|
||||
// </div>
|
||||
// <div
|
||||
// style={{
|
||||
// flex: 6,
|
||||
// marginTop: '15px',
|
||||
// display: 'flex',
|
||||
// alignItems: 'center',
|
||||
// justifyContent: 'center'
|
||||
// }}
|
||||
// >
|
||||
// <Typography
|
||||
// variant="body1"
|
||||
// color="dimgrey"
|
||||
// fontWeight="bold"
|
||||
// fontSize="1rem"
|
||||
// gutterBottom
|
||||
// noWrap
|
||||
// >
|
||||
// <FormattedMessage
|
||||
// id="description"
|
||||
// defaultMessage="Description"
|
||||
// />
|
||||
// </Typography>
|
||||
// </div>
|
||||
// </div>
|
||||
// <Divider />
|
||||
// <div style={{ maxHeight: '400px', overflowY: 'auto' }}>
|
||||
// {history.map((action, index) => {
|
||||
// // Parse the timestamp string to a Date object
|
||||
// const date = new Date(action.timestamp);
|
||||
//
|
||||
// // Extract the date part (e.g., "2023-05-31")
|
||||
// const datePart = date.toLocaleDateString();
|
||||
//
|
||||
// // Extract the time part (e.g., "12:34:56")
|
||||
// const timePart = date.toLocaleTimeString();
|
||||
//
|
||||
// return (
|
||||
// <React.Fragment key={index}>
|
||||
// <Divider />
|
||||
// <div
|
||||
// style={{
|
||||
// minHeight: '40px',
|
||||
// marginBottom: '10px',
|
||||
// display: 'flex',
|
||||
// alignItems: 'center'
|
||||
// }}
|
||||
// >
|
||||
// <div
|
||||
// style={{
|
||||
// flex: 2,
|
||||
// marginTop: '15px',
|
||||
// display: 'flex',
|
||||
// alignItems: 'center',
|
||||
// justifyContent: 'center'
|
||||
// }}
|
||||
// >
|
||||
// <Typography
|
||||
// variant="body1"
|
||||
// fontWeight="bold"
|
||||
// color="text.primary"
|
||||
// gutterBottom
|
||||
// >
|
||||
// {action.userName}
|
||||
// </Typography>
|
||||
// </div>
|
||||
//
|
||||
// <div
|
||||
// style={{
|
||||
// flex: 1,
|
||||
// marginTop: '15px',
|
||||
// display: 'flex',
|
||||
// alignItems: 'center',
|
||||
// justifyContent: 'center'
|
||||
// }}
|
||||
// >
|
||||
// <Typography
|
||||
// variant="body1"
|
||||
// fontWeight="bold"
|
||||
// color="text.primary"
|
||||
// gutterBottom
|
||||
// >
|
||||
// {datePart}
|
||||
// </Typography>
|
||||
// </div>
|
||||
// <div
|
||||
// style={{
|
||||
// flex: 1,
|
||||
// marginTop: '15px',
|
||||
// display: 'flex',
|
||||
// alignItems: 'center',
|
||||
// justifyContent: 'center'
|
||||
// }}
|
||||
// >
|
||||
// <Typography
|
||||
// variant="body1"
|
||||
// fontWeight="bold"
|
||||
// color="text.primary"
|
||||
// gutterBottom
|
||||
// >
|
||||
// {timePart}
|
||||
// </Typography>
|
||||
// </div>
|
||||
//
|
||||
// <div
|
||||
// style={{
|
||||
// flex: 6,
|
||||
// display: 'flex',
|
||||
// marginTop: '15px',
|
||||
// alignItems: 'center',
|
||||
// justifyContent: 'center'
|
||||
// }}
|
||||
// >
|
||||
// <Typography
|
||||
// variant="body1"
|
||||
// fontWeight="bold"
|
||||
// color="text.primary"
|
||||
// gutterBottom
|
||||
// style={{
|
||||
// whiteSpace: 'normal',
|
||||
// wordBreak: 'break-word'
|
||||
// }}
|
||||
// >
|
||||
// {action.description}
|
||||
// </Typography>
|
||||
// </div>
|
||||
// </div>
|
||||
// </React.Fragment>
|
||||
// );
|
||||
// })}
|
||||
// </div>
|
||||
// </div>
|
||||
// </Card>
|
||||
<Card sx={{ marginTop: '10px' }}>
|
||||
<Divider />
|
||||
<div>
|
||||
<div
|
||||
style={{
|
||||
height: '40px',
|
||||
marginBottom: '10px',
|
||||
display: 'flex',
|
||||
alignItems: 'center'
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
flex: 2,
|
||||
marginTop: '15px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
variant="body1"
|
||||
color="dimgrey"
|
||||
fontWeight="bold"
|
||||
fontSize="1rem"
|
||||
gutterBottom
|
||||
noWrap
|
||||
>
|
||||
<FormattedMessage id="user" defaultMessage="User" />
|
||||
</Typography>
|
||||
</div>
|
||||
<TableContainer component={Paper}>
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>User</TableCell>
|
||||
<TableCell>Date</TableCell>
|
||||
<TableCell>Time</TableCell>
|
||||
<TableCell>Description</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{history.map((action, index) => {
|
||||
const isActionSelected =
|
||||
action.id === selectedAction;
|
||||
const date = new Date(action.timestamp);
|
||||
const datePart = date.toLocaleDateString();
|
||||
const timePart = date.toLocaleTimeString();
|
||||
|
||||
<div
|
||||
style={{
|
||||
flex: 1,
|
||||
marginTop: '15px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
variant="body1"
|
||||
color="dimgrey"
|
||||
fontWeight="bold"
|
||||
fontSize="1rem"
|
||||
gutterBottom
|
||||
noWrap
|
||||
>
|
||||
<FormattedMessage id="date" defaultMessage="Date" />
|
||||
</Typography>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
flex: 1,
|
||||
marginTop: '15px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
variant="body1"
|
||||
color="dimgrey"
|
||||
fontWeight="bold"
|
||||
fontSize="1rem"
|
||||
gutterBottom
|
||||
noWrap
|
||||
>
|
||||
<FormattedMessage id="time" defaultMessage="Time" />
|
||||
</Typography>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
flex: 6,
|
||||
marginTop: '15px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
variant="body1"
|
||||
color="dimgrey"
|
||||
fontWeight="bold"
|
||||
fontSize="1rem"
|
||||
gutterBottom
|
||||
noWrap
|
||||
>
|
||||
<FormattedMessage
|
||||
id="description"
|
||||
defaultMessage="Description"
|
||||
/>
|
||||
</Typography>
|
||||
</div>
|
||||
</div>
|
||||
<Divider />
|
||||
<div style={{ maxHeight: '400px', overflowY: 'auto' }}>
|
||||
{history.map((action, index) => {
|
||||
// Parse the timestamp string to a Date object
|
||||
const date = new Date(action.timestamp);
|
||||
const rowStyles = isRowHovered === action.id
|
||||
? { cursor: 'pointer', backgroundColor: 'lightgray' }
|
||||
: {};
|
||||
|
||||
// Extract the date part (e.g., "2023-05-31")
|
||||
const datePart = date.toLocaleDateString();
|
||||
|
||||
// Extract the time part (e.g., "12:34:56")
|
||||
const timePart = date.toLocaleTimeString();
|
||||
|
||||
return (
|
||||
<React.Fragment key={index}>
|
||||
<Divider />
|
||||
<div
|
||||
style={{
|
||||
minHeight: '40px',
|
||||
marginBottom: '10px',
|
||||
display: 'flex',
|
||||
alignItems: 'center'
|
||||
}}
|
||||
return (
|
||||
<TableRow
|
||||
hover
|
||||
key={action.id}
|
||||
selected={isActionSelected}
|
||||
style={rowStyles}
|
||||
onClick={() => handleSelectOneAction(action)}
|
||||
onMouseEnter={() => handleRowMouseEnter(action.id)}
|
||||
onMouseLeave={handleRowMouseLeave}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
flex: 2,
|
||||
marginTop: '15px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
variant="body1"
|
||||
fontWeight="bold"
|
||||
color="text.primary"
|
||||
gutterBottom
|
||||
>
|
||||
{action.userName}
|
||||
</Typography>
|
||||
</div>
|
||||
|
||||
<div
|
||||
style={{
|
||||
flex: 1,
|
||||
marginTop: '15px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
variant="body1"
|
||||
fontWeight="bold"
|
||||
color="text.primary"
|
||||
gutterBottom
|
||||
>
|
||||
{datePart}
|
||||
</Typography>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
flex: 1,
|
||||
marginTop: '15px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
variant="body1"
|
||||
fontWeight="bold"
|
||||
color="text.primary"
|
||||
gutterBottom
|
||||
>
|
||||
{timePart}
|
||||
</Typography>
|
||||
</div>
|
||||
|
||||
<div
|
||||
style={{
|
||||
flex: 6,
|
||||
display: 'flex',
|
||||
marginTop: '15px',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
variant="body1"
|
||||
fontWeight="bold"
|
||||
color="text.primary"
|
||||
gutterBottom
|
||||
style={{
|
||||
whiteSpace: 'normal',
|
||||
wordBreak: 'break-word'
|
||||
}}
|
||||
>
|
||||
{action.description}
|
||||
</Typography>
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<TableCell>{action.userName}</TableCell>
|
||||
<TableCell>{datePart}</TableCell>
|
||||
<TableCell>{timePart}</TableCell>
|
||||
<TableCell>{action.description}</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Card>
|
||||
)}
|
||||
|
||||
|
|
Loading…
Reference in New Issue