Add history button

This commit is contained in:
Noe 2024-06-18 16:19:40 +02:00
parent 5fdc7de448
commit 48de0805b9
6 changed files with 473 additions and 291 deletions

View File

@ -564,12 +564,20 @@ public class Controller : ControllerBase
return Ok();
}
[HttpPost(nameof(InsertNewAction))]
public async Task<ActionResult<IEnumerable<Object>>> InsertNewAction([FromBody] UserAction action, Token authToken)
{
var session = Db.GetSession(authToken);
var actionSuccess = await session.RecordUserAction(action);
return actionSuccess ? Ok() : Unauthorized();
}
[HttpPost(nameof(EditInstallationConfig))]
public async Task<ActionResult<IEnumerable<Object>>> EditInstallationConfig([FromBody] Configuration config, Int64 installationId,Token authToken)
{
var session = Db.GetSession(authToken);
//Console.WriteLine(config.GridSetPoint);
// Send configuration changes
var success = await session.SendInstallationConfig(installationId, config);
@ -577,7 +585,15 @@ public class Controller : ControllerBase
// Record configuration change
if (success)
{
var actionSuccess = await session.RecordUserAction(installationId, config);
// Create a new UserAction object
var action = new UserAction
{
InstallationId = installationId,
Timestamp = DateTime.Now,
Description = config.GetConfigurationString()
};
var actionSuccess = await session.RecordUserAction(action);
return actionSuccess?Ok():Unauthorized();
}

View File

@ -102,22 +102,14 @@ public static class SessionMethods
&& await installation.SendConfig(configuration);
}
public static async Task<Boolean> RecordUserAction(this Session? session, Int64 installationId, Configuration newConfiguration)
public static async Task<Boolean> RecordUserAction(this Session? session, UserAction action)
{
var user = session?.User;
var timestamp = DateTime.Now;
if (user is null || user.UserType == 0)
return false;
// Create a new UserAction object
var action = new UserAction
{
UserName = user.Name,
InstallationId = installationId,
Timestamp = timestamp,
Description = newConfiguration.GetConfigurationString()
};
action.UserName = user.Name;
// Save the configuration change to the database
Db.HandleAction(action);

View File

@ -88,7 +88,7 @@ public static partial class Db
}
else
{
Console.WriteLine("---------------Added the new Error to the database-----------------");
Console.WriteLine("---------------Added the new Action to the database-----------------");
Create(newAction);
}
}

View File

@ -59,23 +59,8 @@ public static class RabbitMqManager
//Consumer received a message
if (receivedStatusMessage != null)
{
Console.WriteLine("----------------------------------------------");
int installationId = (int)Db.Installations.Where(f => f.Product == receivedStatusMessage.Product && f.S3BucketId == receivedStatusMessage.InstallationId).Select(f => f.Id).FirstOrDefault();
string installationName = (string)Db.Installations.Where(f => f.Product == receivedStatusMessage.Product && f.S3BucketId == receivedStatusMessage.InstallationId).Select(f => f.InstallationName).FirstOrDefault();
int bucketId = (int)Db.Installations.Where(f => f.Product == receivedStatusMessage.Product && f.S3BucketId == receivedStatusMessage.InstallationId).Select(f => f.S3BucketId).FirstOrDefault();
int productId = (int)Db.Installations.Where(f => f.Product == receivedStatusMessage.Product && f.S3BucketId == receivedStatusMessage.InstallationId).Select(f => f.Product).FirstOrDefault();
string monitorLink = "";
if (productId == 0)
{
monitorLink =
$"https://monitor.innov.energy/installations/list/installation/{bucketId}/batteryview";
}
else
{
monitorLink =
$"https://monitor.innov.energy/salidomo_installations/list/installation/{bucketId}/batteryview";
}
Installation installation = Db.Installations.FirstOrDefault(f => f.Product == receivedStatusMessage.Product && f.S3BucketId == receivedStatusMessage.InstallationId);
int installationId = (int )installation.Id;
Console.WriteLine("Received a message from installation: " + installationId + " , product is: "+receivedStatusMessage.Product+ " and status is: " + receivedStatusMessage.Status);
//This is a heartbit message, just update the timestamp for this installation.
@ -113,17 +98,32 @@ public static class RabbitMqManager
if (receivedStatusMessage.Alarms != null)
{
string monitorLink;
if (installation.Product == 0)
{
monitorLink =
$"https://monitor.innov.energy/installations/list/installation/{installation.S3BucketId}/batteryview";
}
else
{
monitorLink =
$"https://monitor.innov.energy/salidomo_installations/list/installation/{installation.S3BucketId}/batteryview";
}
foreach (var alarm in receivedStatusMessage.Alarms)
{
Error newError = new Error
{
InstallationId = installationId,
InstallationId = installation.Id,
Description = alarm.Description,
Date = alarm.Date,
Time = alarm.Time,
DeviceCreatedTheMessage = alarm.CreatedBy,
Seen = false
}; Console.WriteLine("Add an alarm for installation "+installationId);
};
Console.WriteLine("Add an alarm for installation "+installationId);
// Send replace battery email to support team if this alarm is "NeedToReplaceBattery"
if (alarm.Description == "NeedToReplaceBattery" || alarm.Description == "2 or more string are disabled")
{
@ -132,7 +132,7 @@ public static class RabbitMqManager
string subject = "Battery Alarm: 2 or more strings broken";
string text = $"Dear InnovEnergy Support Team,\n" +
$"\n"+
$"Installation Name: {installationName}\n"+
$"Installation Name: {installation.InstallationName}\n"+
$"\n"+
$"Installation Monitor Link: {monitorLink}\n"+
$"\n"+

View File

@ -1,11 +1,14 @@
import React, { useContext, useEffect, useState } from 'react';
import {
Alert,
Box,
Card,
Container,
Divider,
Grid,
IconButton,
Modal,
TextField,
useTheme
} from '@mui/material';
import Typography from '@mui/material/Typography';
@ -16,6 +19,10 @@ import routes from '../../../Resources/routes.json';
import { useNavigate } from 'react-router-dom';
import { TokenContext } from '../../../contexts/tokenContext';
import { Action } from '../../../interfaces/S3Types';
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';
interface HistoryProps {
errorLoadingS3Data: boolean;
@ -29,7 +36,61 @@ function HistoryOfActions(props: HistoryProps) {
const [history, setHistory] = useState<Action[]>([]);
const navigate = useNavigate();
const tokencontext = useContext(TokenContext);
const [actionDate, setActionDate] = useState(dayjs());
const { removeToken } = tokencontext;
const [openModalAddAction, setOpenModalAddAction] = useState(false);
const requiredFields = ['description', 'timestamp'];
const [newAction, setNewAction] = useState<Partial<Action>>({
installationId: props.id,
timestamp: actionDate.toDate(),
description: ''
});
const handleDateChange = (newdate) => {
setActionDate(newdate);
setNewAction({
...newAction,
['timestamp']: newdate
});
};
const handleChange = (e) => {
const { name, value } = e.target;
setNewAction({
...newAction,
[name]: value
});
};
const handleAddActionButton = () => {
setOpenModalAddAction(!openModalAddAction);
};
const SumbitNewAction = () => {
const res = axiosConfig.post(`/InsertNewAction`, newAction).catch((err) => {
if (err.response) {
// setError(true);
// setLoading(false);
}
});
if (res) {
setOpenModalAddAction(!openModalAddAction);
}
};
const deleteUserModalHandleCancel = (e) => {
setOpenModalAddAction(false);
};
const areRequiredFieldsFilled = () => {
for (const field of requiredFields) {
if (!newAction[field]) {
return false;
}
}
return true;
};
useEffect(() => {
axiosConfig
@ -43,11 +104,122 @@ function HistoryOfActions(props: HistoryProps) {
navigate(routes.login);
}
});
}, []);
}, [openModalAddAction]);
return (
<>
{openModalAddAction && (
<Modal
open={openModalAddAction}
aria-labelledby="error-modal"
aria-describedby="error-modal-description"
>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<Box
sx={{
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: 500,
bgcolor: 'background.paper',
borderRadius: 4,
boxShadow: 24,
p: 4,
display: 'flex',
flexDirection: 'column',
alignItems: 'center'
}}
>
<div>
<DateTimePicker
label="Select Action Date"
name="timestamp"
value={actionDate}
onChange={(newDate) => handleDateChange(newDate.toDate())}
sx={{
width: 450,
marginTop: 2
}}
/>
<TextField
label="Description"
variant="outlined"
name="description"
value={newAction.description}
onChange={handleChange}
fullWidth
multiline
rows={4} // Adding rows prop to make it a multiline field with more space
sx={{
marginBottom: 2,
marginTop: 2,
height: 'auto'
}} // 'auto' height works better with multiline fields
/>
</div>
<div
style={{
display: 'flex',
alignItems: 'center'
}}
>
<Button
sx={{
textTransform: 'none',
bgcolor: '#ffc04d',
color: '#111111',
'&:hover': { bgcolor: '#f7b34d' }
}}
onClick={SumbitNewAction}
disabled={!areRequiredFieldsFilled()}
>
Submit
</Button>
<Button
sx={{
marginLeft: 2,
textTransform: 'none',
bgcolor: '#ffc04d',
color: '#111111',
'&:hover': { bgcolor: '#f7b34d' }
}}
onClick={deleteUserModalHandleCancel}
>
Cancel
</Button>
</div>
</Box>
</LocalizationProvider>
</Modal>
)}
{!openModalAddAction && (
<Container maxWidth="xl">
<Grid container>
<Grid container>
<Grid item xs={6} md={6}>
<Button
variant="contained"
onClick={handleAddActionButton}
sx={{
marginTop: '20px',
backgroundColor: '#ffc04d',
color: '#000000',
'&:hover': { bgcolor: '#f7b34d' }
}}
>
<FormattedMessage
id="add_action"
defaultMessage="Add New Action"
/>
</Button>
</Grid>
</Grid>
<Grid item xs={12} md={12}>
{history.length > 0 && (
<Card sx={{ marginTop: '10px' }}>
@ -302,6 +474,8 @@ function HistoryOfActions(props: HistoryProps) {
)}
</Grid>
</Container>
)}
</>
);
}

View File

@ -21,6 +21,6 @@ export interface Action {
id: number;
userName: string;
installationId: number;
timestamp: string;
description: String;
timestamp: Date;
description: string;
}