Fixed exoscale keys
This commit is contained in:
parent
6a18e56cf7
commit
ac8f874255
|
@ -100,6 +100,23 @@ public class Controller : ControllerBase
|
|||
.Where(error => error.InstallationId == id)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
[HttpGet(nameof(GetAllWarningsForInstallation))]
|
||||
public ActionResult<IEnumerable<Warning>> GetAllWarningsForInstallation(Int64 id, Token authToken)
|
||||
{
|
||||
var user = Db.GetSession(authToken)?.User;
|
||||
if (user == null)
|
||||
return Unauthorized();
|
||||
|
||||
var installation = Db.GetInstallationById(id);
|
||||
|
||||
if (installation is null || !user.HasAccessTo(installation))
|
||||
return Unauthorized();
|
||||
|
||||
return Db.Warnings
|
||||
.Where(error => error.InstallationId == id)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
[HttpGet(nameof(GetUserById))]
|
||||
public ActionResult<User> GetUserById(Int64 id, Token authToken)
|
||||
|
|
|
@ -2,13 +2,22 @@ using SQLite;
|
|||
|
||||
namespace InnovEnergy.App.Backend.DataTypes;
|
||||
|
||||
public class Error
|
||||
public abstract class LogEntry
|
||||
{
|
||||
[PrimaryKey, AutoIncrement]
|
||||
public Int64 Id { get; set; }
|
||||
public Int64 InstallationId { get; set; }
|
||||
public String ErrorDescription { get; set; } = null!;
|
||||
public String Description { get; set; } = null!;
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public String DeviceCreatedTheError { get; set; } = null!;
|
||||
public String DeviceCreatedTheMessage { get; set; } = null!;
|
||||
public Boolean Seen { get; set; }
|
||||
}
|
||||
|
||||
// Derived class for errors
|
||||
public class Error : LogEntry
|
||||
{
|
||||
}
|
||||
|
||||
public class Warning : LogEntry
|
||||
{
|
||||
}
|
|
@ -13,11 +13,8 @@ namespace InnovEnergy.App.Backend.DataTypes.Methods;
|
|||
public static class ExoCmd
|
||||
{
|
||||
|
||||
private const String Key = "EXOea18f5a82bd358896154c783";
|
||||
private const String Secret = "lYtzU7R5e0L6XKOgBaLVPFr41nEBDxDdXU47zBAEI6M";
|
||||
|
||||
[UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "<Pending>")]
|
||||
public static readonly S3Credentials? S3Creds = JsonSerializer.Deserialize<S3Credentials>(File.OpenRead("./Resources/exoscaleS3.json"));
|
||||
public static readonly S3Credentials S3Credentials = JsonSerializer.Deserialize<S3Credentials>(File.OpenRead("./Resources/exoscaleS3.json"))!;
|
||||
|
||||
private static Byte[] HmacSha256Digest(String message, String secret)
|
||||
{
|
||||
|
@ -47,7 +44,7 @@ public static class ExoCmd
|
|||
//Console.WriteLine("Message to sign:\n" + messageToSign);
|
||||
|
||||
|
||||
var hmac = HmacSha256Digest(messageToSign, Secret);
|
||||
var hmac = HmacSha256Digest(messageToSign, S3Credentials.Secret);
|
||||
return Convert.ToBase64String(hmac);
|
||||
}
|
||||
|
||||
|
@ -76,7 +73,7 @@ public static class ExoCmd
|
|||
|
||||
var unixtime = DateTimeOffset.UtcNow.ToUnixTimeSeconds()+60;
|
||||
|
||||
var authheader = "credential="+Key+",signed-query-args="+",expires="+unixtime+",signature="+BuildSignature("GET", method, unixtime);
|
||||
var authheader = "credential="+S3Credentials.Key+",signed-query-args="+",expires="+unixtime+",signature="+BuildSignature("GET", method, unixtime);
|
||||
|
||||
var client = new HttpClient();
|
||||
|
||||
|
@ -92,10 +89,12 @@ public static class ExoCmd
|
|||
{
|
||||
var url = "https://api-ch-dk-2.exoscale.com/v2/api-key";
|
||||
var method = "api-key";
|
||||
var contentString = $$"""{"role-id": "{{roleName}}", "name":"{{installation.BucketName()}}v2"}""";
|
||||
var contentString = $$"""{"role-id": "{{roleName}}", "name":"{{installation.BucketName()}}"}""";
|
||||
var unixtime = DateTimeOffset.UtcNow.ToUnixTimeSeconds() + 60;
|
||||
|
||||
var authheader = "credential=" + Key + ",expires=" + unixtime + ",signature=" +
|
||||
|
||||
|
||||
var authheader = "credential=" + S3Credentials.Key + ",expires=" + unixtime + ",signature=" +
|
||||
BuildSignature("POST", method, contentString, unixtime);
|
||||
|
||||
var client = new HttpClient();
|
||||
|
@ -143,7 +142,7 @@ public static class ExoCmd
|
|||
|
||||
var unixtime = DateTimeOffset.UtcNow.ToUnixTimeSeconds()+60;
|
||||
|
||||
var authheader = "credential="+Key+",signed-query-args="+",expires="+unixtime+",signature="+BuildSignature("POST", method, contentString, unixtime);
|
||||
var authheader = "credential="+S3Credentials.Key+",signed-query-args="+",expires="+unixtime+",signature="+BuildSignature("POST", method, contentString, unixtime);
|
||||
|
||||
var client = new HttpClient();
|
||||
|
||||
|
@ -171,7 +170,7 @@ public static class ExoCmd
|
|||
|
||||
var unixtime = DateTimeOffset.UtcNow.ToUnixTimeSeconds()+60;
|
||||
|
||||
var authheader = "credential="+Key+",expires="+unixtime+",signature="+BuildSignature("DELETE", method, unixtime);
|
||||
var authheader = "credential="+S3Credentials.Key+",expires="+unixtime+",signature="+BuildSignature("DELETE", method, unixtime);
|
||||
|
||||
var client = new HttpClient();
|
||||
|
||||
|
@ -220,7 +219,7 @@ public static class ExoCmd
|
|||
|
||||
var unixtime = DateTimeOffset.UtcNow.ToUnixTimeSeconds()+60;
|
||||
|
||||
var authheader = "credential="+Key+",signed-query-args="+",expires="+unixtime+",signature="+BuildSignature("POST", method, contentString, unixtime);
|
||||
var authheader = "credential="+S3Credentials.Key+",signed-query-args="+",expires="+unixtime+",signature="+BuildSignature("POST", method, contentString, unixtime);
|
||||
|
||||
var client = new HttpClient();
|
||||
|
||||
|
@ -245,7 +244,7 @@ public static class ExoCmd
|
|||
|
||||
public static async Task<Boolean> CreateBucket(this Installation installation)
|
||||
{
|
||||
var s3Region = new S3Region($"https://{installation.S3Region}.{installation.S3Provider}", S3Creds!);
|
||||
var s3Region = new S3Region($"https://{installation.S3Region}.{installation.S3Provider}", S3Credentials!);
|
||||
return await s3Region.PutBucket(installation.BucketName()) != null;
|
||||
}
|
||||
|
||||
|
@ -272,7 +271,7 @@ public static class ExoCmd
|
|||
// return result.ExitCode == 200;
|
||||
|
||||
|
||||
var s3Region = new S3Region($"https://{installation.S3Region}.{installation.S3Provider}", S3Creds!);
|
||||
var s3Region = new S3Region($"https://{installation.S3Region}.{installation.S3Provider}", S3Credentials!);
|
||||
var url = s3Region.Bucket(installation.BucketName()).Path("config.json");
|
||||
return await url.PutObject(config);
|
||||
|
||||
|
|
|
@ -23,7 +23,8 @@ public static class InstallationMethods
|
|||
|
||||
public static async Task<Boolean> RenewS3Credentials(this Installation installation)
|
||||
{
|
||||
if(installation.S3Key != "") await installation.RevokeReadKey();
|
||||
if(!installation.S3Key.IsNullOrEmpty())
|
||||
await installation.RevokeReadKey();
|
||||
|
||||
var (key,secret) = await installation.CreateReadKey();
|
||||
|
||||
|
|
|
@ -25,6 +25,11 @@ public static partial class Db
|
|||
return Insert(error);
|
||||
}
|
||||
|
||||
public static Boolean Create(Warning warning)
|
||||
{
|
||||
return Insert(warning);
|
||||
}
|
||||
|
||||
public static Boolean Create(Folder folder)
|
||||
{
|
||||
return Insert(folder);
|
||||
|
@ -80,4 +85,30 @@ public static partial class Db
|
|||
Create(newError);
|
||||
}
|
||||
}
|
||||
|
||||
public static void HandleWarning(Warning newWarning,int installationId)
|
||||
{
|
||||
//Find the total number of warnings for this installation
|
||||
var totalWarnings = Warnings.Count(warning => warning.InstallationId == installationId);
|
||||
|
||||
//If there are 100 warnings, remove the one with the oldest timestamp
|
||||
if (totalWarnings == 100)
|
||||
{
|
||||
var oldestWarning =
|
||||
Warnings.Where(warning => warning.InstallationId == installationId)
|
||||
.OrderBy(warning => warning.CreatedAt)
|
||||
.FirstOrDefault();
|
||||
|
||||
//Remove the old error
|
||||
Delete(oldestWarning);
|
||||
|
||||
//Add the new error
|
||||
Create(newWarning);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("---------------Added the new Error to the database-----------------");
|
||||
Create(newWarning);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,21 +12,20 @@ using SQLiteConnection = SQLite.SQLiteConnection;
|
|||
|
||||
namespace InnovEnergy.App.Backend.Database;
|
||||
|
||||
|
||||
public static partial class Db
|
||||
public static partial class Db
|
||||
{
|
||||
private static SQLiteConnection Connection { get; } = InitConnection();
|
||||
|
||||
private static SQLiteConnection InitConnection()
|
||||
{
|
||||
var latestDb = new DirectoryInfo("DbBackups")
|
||||
.GetFiles()
|
||||
.OrderBy(f => f.LastWriteTime)
|
||||
.Last().Name;
|
||||
.GetFiles()
|
||||
.OrderBy(f => f.LastWriteTime)
|
||||
.Last().Name;
|
||||
|
||||
//This is the file connection from the DbBackups folder
|
||||
var fileConnection = new SQLiteConnection("DbBackups/" + latestDb);
|
||||
|
||||
|
||||
//Create a table if it does not exist
|
||||
fileConnection.CreateTable<User>();
|
||||
fileConnection.CreateTable<Installation>();
|
||||
|
@ -36,14 +35,15 @@ public static partial class Db
|
|||
fileConnection.CreateTable<Session>();
|
||||
fileConnection.CreateTable<OrderNumber2Installation>();
|
||||
fileConnection.CreateTable<Error>();
|
||||
|
||||
fileConnection.CreateTable<Warning>();
|
||||
|
||||
return CopyDbToMemory(fileConnection);
|
||||
}
|
||||
|
||||
private static SQLiteConnection CopyDbToMemory(SQLiteConnection fileConnection)
|
||||
{
|
||||
var memoryConnection = new SQLiteConnection(":memory:");
|
||||
|
||||
|
||||
//Create a table if it does not exist in main memory
|
||||
memoryConnection.CreateTable<User>();
|
||||
memoryConnection.CreateTable<Installation>();
|
||||
|
@ -53,7 +53,8 @@ public static partial class Db
|
|||
memoryConnection.CreateTable<Session>();
|
||||
memoryConnection.CreateTable<OrderNumber2Installation>();
|
||||
memoryConnection.CreateTable<Error>();
|
||||
|
||||
memoryConnection.CreateTable<Warning>();
|
||||
|
||||
//Copy all the existing tables from the disk to main memory
|
||||
fileConnection.Table<Session>().ForEach(memoryConnection.Insert);
|
||||
fileConnection.Table<Folder>().ForEach(memoryConnection.Insert);
|
||||
|
@ -63,7 +64,8 @@ public static partial class Db
|
|||
fileConnection.Table<InstallationAccess>().ForEach(memoryConnection.Insert);
|
||||
fileConnection.Table<OrderNumber2Installation>().ForEach(memoryConnection.Insert);
|
||||
fileConnection.Table<Error>().ForEach(memoryConnection.Insert);
|
||||
|
||||
fileConnection.Table<Warning>().ForEach(memoryConnection.Insert);
|
||||
|
||||
return memoryConnection;
|
||||
}
|
||||
|
||||
|
@ -72,21 +74,23 @@ public static partial class Db
|
|||
var filename = "db-" + DateTimeOffset.UtcNow.ToUnixTimeSeconds() + ".sqlite";
|
||||
Connection.Backup("DbBackups/" + filename);
|
||||
}
|
||||
|
||||
public static TableQuery<Session> Sessions => Connection.Table<Session>();
|
||||
public static TableQuery<Folder> Folders => Connection.Table<Folder>();
|
||||
public static TableQuery<Installation> Installations => Connection.Table<Installation>();
|
||||
public static TableQuery<User> Users => Connection.Table<User>();
|
||||
public static TableQuery<FolderAccess> FolderAccess => Connection.Table<FolderAccess>();
|
||||
public static TableQuery<InstallationAccess> InstallationAccess => Connection.Table<InstallationAccess>();
|
||||
public static TableQuery<OrderNumber2Installation> OrderNumber2Installation => Connection.Table<OrderNumber2Installation>();
|
||||
public static TableQuery<Error> Errors => Connection.Table<Error>();
|
||||
public static TableQuery<Warning> Warnings => Connection.Table<Warning>();
|
||||
|
||||
public static TableQuery<Session> Sessions => Connection.Table<Session>();
|
||||
public static TableQuery<Folder> Folders => Connection.Table<Folder>();
|
||||
public static TableQuery<Installation> Installations => Connection.Table<Installation>();
|
||||
public static TableQuery<User> Users => Connection.Table<User>();
|
||||
public static TableQuery<FolderAccess> FolderAccess => Connection.Table<FolderAccess>();
|
||||
public static TableQuery<InstallationAccess> InstallationAccess => Connection.Table<InstallationAccess>();
|
||||
public static TableQuery<OrderNumber2Installation> OrderNumber2Installation => Connection.Table<OrderNumber2Installation>();
|
||||
public static TableQuery<Error> Errors => Connection.Table<Error>();
|
||||
|
||||
public static void Init(){
|
||||
public static void Init()
|
||||
{
|
||||
// used to force static constructor
|
||||
//Since this class is static, we call Init method from the Program.cs to initialize all the fields of the class
|
||||
}
|
||||
|
||||
|
||||
//This is the constructor of the class
|
||||
static Db()
|
||||
{
|
||||
|
@ -100,23 +104,53 @@ public static partial class Db
|
|||
Connection.CreateTable<Session>();
|
||||
Connection.CreateTable<OrderNumber2Installation>();
|
||||
Connection.CreateTable<Error>();
|
||||
Connection.CreateTable<Warning>();
|
||||
});
|
||||
|
||||
UpdateKeys().SupressAwaitWarning();
|
||||
CleanupSessions().SupressAwaitWarning();
|
||||
}
|
||||
|
||||
private static async Task CleanupSessions()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
DeleteStaleSessions();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Console.WriteLine("An error has occured when cleaning stale sessions, exception is:\n"+e);
|
||||
}
|
||||
|
||||
Observable.Interval(TimeSpan.FromHours(0.5))
|
||||
.StartWith(0) // Do it right away (on startup)
|
||||
.ObserveOn(TaskPoolScheduler.Default)
|
||||
.SubscribeOn(TaskPoolScheduler.Default)
|
||||
.SelectMany(Cleanup)
|
||||
.Subscribe();
|
||||
await Task.Delay(TimeSpan.FromHours(0.5));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static async Task UpdateKeys()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
await UpdateS3Urls();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Console.WriteLine("An error has occured when updating S3 keys, exception is:\n"+e);
|
||||
}
|
||||
|
||||
await Task.Delay(TimeSpan.FromHours(24));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static Boolean RunTransaction(Func<Boolean> func)
|
||||
{
|
||||
var savepoint = Connection.SaveTransactionPoint();
|
||||
var success = false;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
success = func();
|
||||
|
@ -131,40 +165,33 @@ public static partial class Db
|
|||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
private static async Task<Boolean> Cleanup(Int64 _)
|
||||
{
|
||||
await UpdateS3Urls();
|
||||
DeleteStaleSessions();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private static void DeleteStaleSessions()
|
||||
{
|
||||
var deadline = DateTime.Now.AddDays((-1)*Session.MaxAge.Days);
|
||||
var deadline = DateTime.Now.AddDays((-1) * Session.MaxAge.Days);
|
||||
Sessions.Delete(s => s.LastSeen < deadline);
|
||||
}
|
||||
|
||||
private static async Task UpdateS3Urls()
|
||||
{
|
||||
var regions = Installations
|
||||
.Select(i => i.S3Region)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
.Select(i => i.S3Region)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
const String provider = "exo.io";
|
||||
|
||||
|
||||
foreach (var region in regions)
|
||||
{
|
||||
var s3Region = new S3Region($"https://{region}.{provider}", ExoCmd.S3Creds!);
|
||||
var s3Region = new S3Region($"https://{region}.{provider}", ExoCmd.S3Credentials!);
|
||||
var bucketList = await s3Region.ListAllBuckets();
|
||||
|
||||
var installations = from bucket in bucketList.Buckets
|
||||
from installation in Installations
|
||||
where installation.BucketName() == bucket.BucketName
|
||||
select installation;
|
||||
|
||||
var installations = from bucket in bucketList.Buckets
|
||||
from installation in Installations
|
||||
where installation.BucketName() == bucket.BucketName
|
||||
select installation;
|
||||
|
||||
foreach (var installation in installations)
|
||||
{
|
||||
await installation.RenewS3Credentials();
|
||||
|
@ -179,12 +206,12 @@ public static partial class Db
|
|||
await user.SendPasswordResetEmail(sessionToken);
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static async Task<Boolean> SendNewUserEmail(User user)
|
||||
{
|
||||
try
|
||||
|
@ -192,7 +219,7 @@ public static partial class Db
|
|||
await user.SendNewUserWelcomeMessage();
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -48,6 +48,20 @@ public static partial class Db
|
|||
return Errors.Delete(error => error.Id == errorToDelete.Id) >0;
|
||||
}
|
||||
}
|
||||
|
||||
public static Boolean Delete(Warning warningToDelete)
|
||||
{
|
||||
var deleteSuccess = RunTransaction(DeleteWarning);
|
||||
if (deleteSuccess)
|
||||
BackupDatabase();
|
||||
return deleteSuccess;
|
||||
|
||||
|
||||
Boolean DeleteWarning()
|
||||
{
|
||||
return Warnings.Delete(error => error.Id == warningToDelete.Id) >0;
|
||||
}
|
||||
}
|
||||
|
||||
public static Boolean Delete(Installation installation)
|
||||
{
|
||||
|
|
|
@ -4,6 +4,6 @@ public class StatusMessage
|
|||
public required int InstallationId { get; init; }
|
||||
public required int Status { get; init; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public String Error { get; init; } = null!;
|
||||
public String DeviceCreatedTheError { get; init; } = null!;
|
||||
public String Description { get; init; } = null!;
|
||||
public String CreatedBy { get; init; } = null!;
|
||||
}
|
|
@ -99,15 +99,30 @@ public static class WebsocketManager
|
|||
Error newError = new Error
|
||||
{
|
||||
InstallationId = receivedStatusMessage.InstallationId,
|
||||
ErrorDescription = receivedStatusMessage.Error,
|
||||
Description = receivedStatusMessage.Description,
|
||||
CreatedAt = receivedStatusMessage.CreatedAt,
|
||||
DeviceCreatedTheError = receivedStatusMessage.DeviceCreatedTheError,
|
||||
DeviceCreatedTheMessage = receivedStatusMessage.CreatedBy,
|
||||
Seen = false
|
||||
};
|
||||
//Create a new error and add it to the database
|
||||
Db.HandleError(newError,receivedStatusMessage.InstallationId);
|
||||
|
||||
}
|
||||
else if (receivedStatusMessage.Status==1)
|
||||
{
|
||||
Console.WriteLine("-----------------------New warning-----------------------");
|
||||
|
||||
Warning newWarning = new Warning
|
||||
{
|
||||
InstallationId = receivedStatusMessage.InstallationId,
|
||||
Description = receivedStatusMessage.Description,
|
||||
CreatedAt = receivedStatusMessage.CreatedAt,
|
||||
DeviceCreatedTheMessage = receivedStatusMessage.CreatedBy,
|
||||
Seen = false
|
||||
};
|
||||
//Create a new error and add it to the database
|
||||
Db.HandleWarning(newWarning,receivedStatusMessage.InstallationId);
|
||||
}
|
||||
|
||||
|
||||
if (!InstallationConnections.ContainsKey(installationId))
|
||||
{
|
||||
|
|
|
@ -4,9 +4,9 @@ namespace InnovEnergy.App.SaliMax.MiddlewareClasses;
|
|||
public class StatusMessage
|
||||
{
|
||||
|
||||
public required int InstallationId { get; init; }
|
||||
public required int Status { get; init; }
|
||||
public required int InstallationId { get; set; }
|
||||
public required int Status { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public String Error { get; set; } = null!;
|
||||
public String DeviceCreatedTheError { get; set; } = null!;
|
||||
public String Description { get; set; } = null!;
|
||||
public String CreatedBy { get; set; } = null!;
|
||||
}
|
|
@ -357,8 +357,14 @@ internal static class Program
|
|||
if (status == 2)
|
||||
{
|
||||
jsonObject.CreatedAt = DateTime.Now;
|
||||
jsonObject.Error = "Battery Temperature High";
|
||||
jsonObject.DeviceCreatedTheError = "Battery/1";
|
||||
jsonObject.Description = "Battery Temperature High";
|
||||
jsonObject.CreatedBy = "Battery/1";
|
||||
}
|
||||
else if (status == 1)
|
||||
{
|
||||
jsonObject.CreatedAt = DateTime.Now;
|
||||
jsonObject.Description = "Temp warning message";
|
||||
jsonObject.CreatedBy = "Battery/4";
|
||||
}
|
||||
|
||||
var message = JsonSerializer.Serialize(jsonObject);
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import axios from 'axios';
|
||||
|
||||
export const axiosConfigWithoutToken = axios.create({
|
||||
//baseURL: 'https://monitor.innov.energy/api'
|
||||
baseURL: 'http://127.0.0.1:7087/api'
|
||||
baseURL: 'https://monitor.innov.energy/api'
|
||||
//baseURL: 'http://127.0.0.1:7087/api'
|
||||
});
|
||||
|
||||
const axiosConfig = axios.create({
|
||||
//baseURL: 'https://monitor.innov.energy/api'
|
||||
baseURL: 'http://127.0.0.1:7087/api'
|
||||
baseURL: 'https://monitor.innov.energy/api'
|
||||
//baseURL: 'http://127.0.0.1:7087/api'
|
||||
});
|
||||
|
||||
axiosConfig.defaults.params = {};
|
||||
|
|
|
@ -17,12 +17,14 @@ import {
|
|||
import Typography from '@mui/material/Typography';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import ErrorIcon from '@mui/icons-material/Error';
|
||||
import WarningIcon from '@mui/icons-material/Warning';
|
||||
import axiosConfig from '../../../Resources/axiosConfig';
|
||||
import { AxiosError, AxiosResponse } from 'axios/index';
|
||||
import routes from '../../../Resources/routes.json';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { TokenContext } from '../../../contexts/tokenContext';
|
||||
import { ErrorMessage } from '../../../interfaces/S3Types';
|
||||
import Button from '@mui/material/Button';
|
||||
|
||||
interface LogProps {
|
||||
errorLoadingS3Data: boolean;
|
||||
|
@ -31,8 +33,11 @@ interface LogProps {
|
|||
|
||||
function Log(props: LogProps) {
|
||||
const theme = useTheme();
|
||||
//const [warnings, setWarnings] = useState<Notification[]>([]);
|
||||
const [warnings, setWarnings] = useState<ErrorMessage[]>([]);
|
||||
const [errors, setErrors] = useState<ErrorMessage[]>([]);
|
||||
const [errorButtonPressed, setErrorButtonPressed] = useState(false);
|
||||
const [warningButtonPressed, setWarningButtonPressed] = useState(false);
|
||||
|
||||
const navigate = useNavigate();
|
||||
const tokencontext = useContext(TokenContext);
|
||||
const { removeToken } = tokencontext;
|
||||
|
@ -49,14 +54,41 @@ function Log(props: LogProps) {
|
|||
navigate(routes.login);
|
||||
}
|
||||
});
|
||||
|
||||
axiosConfig
|
||||
.get(`/GetAllWarningsForInstallation?id=${props.id}`)
|
||||
.then((res: AxiosResponse<ErrorMessage[]>) => {
|
||||
setWarnings(res.data);
|
||||
})
|
||||
.catch((err: AxiosError) => {
|
||||
if (err.response && err.response.status == 401) {
|
||||
removeToken();
|
||||
navigate(routes.login);
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
const handleErrorButtonPressed = () => {
|
||||
setErrorButtonPressed(!errorButtonPressed);
|
||||
};
|
||||
|
||||
const handleWarningButtonPressed = () => {
|
||||
setWarningButtonPressed(!warningButtonPressed);
|
||||
};
|
||||
|
||||
return (
|
||||
<Container maxWidth="xl">
|
||||
<Grid container>
|
||||
<Grid item xs={12} md={12}>
|
||||
{/* IT SHOULD BE {(errors.length > 0 || props.warnings.length > 0) && (*/}
|
||||
{errors.length > 0 && (
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={handleErrorButtonPressed}
|
||||
sx={{ marginTop: '20px' }}
|
||||
>
|
||||
<FormattedMessage id="Show Errors" defaultMessage="Show Errors" />
|
||||
</Button>
|
||||
|
||||
{errorButtonPressed && errors.length > 0 && (
|
||||
<Card sx={{ marginTop: '10px' }}>
|
||||
<Divider />
|
||||
<TableContainer>
|
||||
|
@ -66,7 +98,6 @@ function Log(props: LogProps) {
|
|||
<TableCell>
|
||||
<FormattedMessage id="type" defaultMessage="Type" />
|
||||
</TableCell>
|
||||
|
||||
<TableCell>
|
||||
<FormattedMessage
|
||||
id="description"
|
||||
|
@ -85,13 +116,146 @@ function Log(props: LogProps) {
|
|||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{errors.map((error, index) => {
|
||||
{errors.map((error, index) => (
|
||||
<TableRow hover key={index}>
|
||||
<TableCell>
|
||||
<ErrorIcon
|
||||
sx={{
|
||||
color: 'red',
|
||||
width: 25,
|
||||
height: 25,
|
||||
marginLeft: '5px',
|
||||
marginTop: '8px'
|
||||
}}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Typography
|
||||
variant="body1"
|
||||
fontWeight="bold"
|
||||
color="text.primary"
|
||||
gutterBottom
|
||||
noWrap
|
||||
sx={{ marginTop: '5px', verticalAlign: 'middle' }}
|
||||
>
|
||||
{error.description}
|
||||
</Typography>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Typography
|
||||
variant="body1"
|
||||
fontWeight="bold"
|
||||
color="text.primary"
|
||||
gutterBottom
|
||||
noWrap
|
||||
sx={{ marginTop: '5px', verticalAlign: 'middle' }}
|
||||
>
|
||||
{error.deviceCreatedTheMessage}
|
||||
</Typography>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Typography
|
||||
variant="body1"
|
||||
fontWeight="bold"
|
||||
color="text.primary"
|
||||
gutterBottom
|
||||
noWrap
|
||||
sx={{ marginTop: '5px', verticalAlign: 'middle' }}
|
||||
>
|
||||
{error.createdAt}
|
||||
</Typography>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Typography
|
||||
variant="body1"
|
||||
fontWeight="bold"
|
||||
color="text.primary"
|
||||
gutterBottom
|
||||
noWrap
|
||||
sx={{ marginTop: '5px', verticalAlign: 'middle' }}
|
||||
>
|
||||
{error.seen == false ? 'No' : 'Yes'}
|
||||
</Typography>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Card>
|
||||
)}
|
||||
|
||||
{!props.errorLoadingS3Data &&
|
||||
errorButtonPressed &&
|
||||
errors.length == 0 && (
|
||||
<Alert
|
||||
severity="error"
|
||||
sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
marginTop: '20px'
|
||||
}}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="noerrors"
|
||||
defaultMessage="There are no errors"
|
||||
/>
|
||||
<IconButton
|
||||
color="inherit"
|
||||
size="small"
|
||||
sx={{ marginLeft: '4px' }}
|
||||
></IconButton>
|
||||
</Alert>
|
||||
)}
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={12} md={12}>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={handleWarningButtonPressed}
|
||||
sx={{ marginTop: '20px' }}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="Show Warnings"
|
||||
defaultMessage="Show Warnings"
|
||||
/>
|
||||
</Button>
|
||||
|
||||
{warningButtonPressed && warnings.length > 0 && (
|
||||
<Card sx={{ marginTop: '10px' }}>
|
||||
<Divider />
|
||||
<TableContainer>
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>
|
||||
<FormattedMessage id="type" defaultMessage="Type" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<FormattedMessage
|
||||
id="description"
|
||||
defaultMessage="Description"
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<FormattedMessage id="device" defaultMessage="Device" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<FormattedMessage id="date" defaultMessage="Date" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<FormattedMessage id="seen" defaultMessage="Seen" />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{warnings.map((warning, index) => {
|
||||
return (
|
||||
<TableRow hover key={index}>
|
||||
<TableCell>
|
||||
<ErrorIcon
|
||||
<WarningIcon
|
||||
sx={{
|
||||
color: 'red',
|
||||
color: 'orange',
|
||||
width: 25,
|
||||
height: 25,
|
||||
marginLeft: '5px',
|
||||
|
@ -106,9 +270,9 @@ function Log(props: LogProps) {
|
|||
color="text.primary"
|
||||
gutterBottom
|
||||
noWrap
|
||||
sx={{ marginTop: '5px', marginLeft: '-40px' }}
|
||||
sx={{ marginTop: '5px', verticalAlign: 'middle' }}
|
||||
>
|
||||
{error.errorDescription}
|
||||
{warning.description}
|
||||
</Typography>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
|
@ -120,7 +284,7 @@ function Log(props: LogProps) {
|
|||
noWrap
|
||||
sx={{ marginTop: '5px' }}
|
||||
>
|
||||
{error.deviceCreatedTheError}
|
||||
{warning.deviceCreatedTheMessage}
|
||||
</Typography>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
|
@ -130,9 +294,9 @@ function Log(props: LogProps) {
|
|||
color="text.primary"
|
||||
gutterBottom
|
||||
noWrap
|
||||
sx={{ marginTop: '5px', marginLeft: '-40px' }}
|
||||
sx={{ marginTop: '5px', verticalAlign: 'middle' }}
|
||||
>
|
||||
{error.createdAt}
|
||||
{warning.createdAt}
|
||||
</Typography>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
|
@ -142,106 +306,43 @@ function Log(props: LogProps) {
|
|||
color="text.primary"
|
||||
gutterBottom
|
||||
noWrap
|
||||
sx={{ marginTop: '5px', marginLeft: '10px' }}
|
||||
sx={{ marginTop: '5px', verticalAlign: 'middle' }}
|
||||
>
|
||||
{error.seen == false ? 'No' : 'Yes'}
|
||||
{warning.seen == false ? 'No' : 'Yes'}
|
||||
</Typography>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
|
||||
{/*{props.warnings.map((warning, index) => {*/}
|
||||
{/* return (*/}
|
||||
{/* <TableRow hover key={index}>*/}
|
||||
{/* <TableCell>*/}
|
||||
{/* <WarningIcon*/}
|
||||
{/* sx={{*/}
|
||||
{/* color: '#ffc04d',*/}
|
||||
{/* width: 25,*/}
|
||||
{/* height: 25,*/}
|
||||
{/* marginLeft: '5px',*/}
|
||||
{/* marginTop: '8px'*/}
|
||||
{/* }}*/}
|
||||
{/* />*/}
|
||||
{/* </TableCell>*/}
|
||||
{/* <TableCell>*/}
|
||||
{/* <Typography*/}
|
||||
{/* variant="body1"*/}
|
||||
{/* fontWeight="bold"*/}
|
||||
{/* color="text.primary"*/}
|
||||
{/* gutterBottom*/}
|
||||
{/* noWrap*/}
|
||||
{/* sx={{ marginTop: '10px' }}*/}
|
||||
{/* >*/}
|
||||
{/* {warning.device}*/}
|
||||
{/* </Typography>*/}
|
||||
{/* </TableCell>*/}
|
||||
{/* <TableCell>*/}
|
||||
{/* <Typography*/}
|
||||
{/* variant="body1"*/}
|
||||
{/* fontWeight="bold"*/}
|
||||
{/* color="text.primary"*/}
|
||||
{/* gutterBottom*/}
|
||||
{/* noWrap*/}
|
||||
{/* sx={{ marginTop: '10px' }}*/}
|
||||
{/* >*/}
|
||||
{/* {warning.description}*/}
|
||||
{/* </Typography>*/}
|
||||
{/* </TableCell>*/}
|
||||
{/* <TableCell>*/}
|
||||
{/* <Typography*/}
|
||||
{/* variant="body1"*/}
|
||||
{/* fontWeight="bold"*/}
|
||||
{/* color="text.primary"*/}
|
||||
{/* gutterBottom*/}
|
||||
{/* noWrap*/}
|
||||
{/* sx={{ marginTop: '10px' }}*/}
|
||||
{/* >*/}
|
||||
{/* {warning.date}*/}
|
||||
{/* </Typography>*/}
|
||||
{/* </TableCell>*/}
|
||||
{/* <TableCell>*/}
|
||||
{/* <Typography*/}
|
||||
{/* variant="body1"*/}
|
||||
{/* fontWeight="bold"*/}
|
||||
{/* color="text.primary"*/}
|
||||
{/* gutterBottom*/}
|
||||
{/* noWrap*/}
|
||||
{/* sx={{ marginTop: '10px' }}*/}
|
||||
{/* >*/}
|
||||
{/* {warning.time}*/}
|
||||
{/* </Typography>*/}
|
||||
{/* </TableCell>*/}
|
||||
{/* </TableRow>*/}
|
||||
{/* );*/}
|
||||
{/*})}*/}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Card>
|
||||
)}
|
||||
|
||||
{!props.errorLoadingS3Data && errors.length == 0 && (
|
||||
<Alert
|
||||
severity="error"
|
||||
sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
marginTop: '20px'
|
||||
}}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="noerrors"
|
||||
defaultMessage="There are no errors"
|
||||
/>
|
||||
<IconButton
|
||||
color="inherit"
|
||||
size="small"
|
||||
sx={{ marginLeft: '4px' }}
|
||||
></IconButton>
|
||||
</Alert>
|
||||
)}
|
||||
{!props.errorLoadingS3Data &&
|
||||
warningButtonPressed &&
|
||||
warnings.length == 0 && (
|
||||
<Alert
|
||||
severity="error"
|
||||
sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
//marginBottom: '20px'
|
||||
marginTop: '20px'
|
||||
}}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="nowarnings"
|
||||
defaultMessage="There are no warnings"
|
||||
/>
|
||||
<IconButton
|
||||
color="inherit"
|
||||
size="small"
|
||||
sx={{ marginLeft: '4px' }}
|
||||
></IconButton>
|
||||
</Alert>
|
||||
)}
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={12} md={12} style={{ marginBottom: '20px' }}>
|
||||
|
@ -265,28 +366,6 @@ function Log(props: LogProps) {
|
|||
></IconButton>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
{/*{!props.errorLoadingS3Data && props.warnings.length == 0 && (*/}
|
||||
{/* <Alert*/}
|
||||
{/* severity="error"*/}
|
||||
{/* sx={{*/}
|
||||
{/* display: 'flex',*/}
|
||||
{/* alignItems: 'center',*/}
|
||||
{/* //marginBottom: '20px'*/}
|
||||
{/* marginTop: '20px'*/}
|
||||
{/* }}*/}
|
||||
{/* >*/}
|
||||
{/* <FormattedMessage*/}
|
||||
{/* id="nowarnings"*/}
|
||||
{/* defaultMessage="There are no warnings"*/}
|
||||
{/* />*/}
|
||||
{/* <IconButton*/}
|
||||
{/* color="inherit"*/}
|
||||
{/* size="small"*/}
|
||||
{/* sx={{ marginLeft: '4px' }}*/}
|
||||
{/* ></IconButton>*/}
|
||||
{/* </Alert>*/}
|
||||
{/*)}*/}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Container>
|
||||
|
|
|
@ -8,8 +8,8 @@ export interface I_S3Credentials {
|
|||
|
||||
export interface ErrorMessage {
|
||||
installationId: number;
|
||||
description: string;
|
||||
createdAt: Date;
|
||||
errorDescription: string;
|
||||
deviceCreatedTheError: string;
|
||||
deviceCreatedTheMessage: string;
|
||||
seen: boolean;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue