insight/src/Web/Insight.Web/Pages/Management/Agents/Index.razor.cs

225 lines
7.2 KiB
C#
Raw Normal View History

2023-09-21 18:58:32 +02:00
using Insight.Infrastructure;
using Insight.Infrastructure.Entities;
using Insight.Web.Components.Containers;
using Insight.Web.Constants;
using Microsoft.AspNetCore.Components;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Driver;
using MudBlazor;
using System.Text.RegularExpressions;
using SortDirection = MudBlazor.SortDirection;
namespace Insight.Web.Pages.Management.Agents;
[Route(Navigation.Management.Agents.Index)]
public partial class Index
{
[Inject] private IMongoDatabase Database { get; init; } = default!;
[Inject] private ISnackbar Snackbar { get; init; } = default!;
private TableContainer<ViewModel>? Container { get; set; }
private string Title { get; set; } = Global.Name;
private List<BreadcrumbItem> Breadcrumbs { get; } = new();
private string? Search { get; set; }
private ViewModel? Model { get; set; }
protected override void OnInitialized()
{
Title = "AgentsInsight";
Breadcrumbs.Add(new BreadcrumbItem("Home", href: Navigation.Home));
Breadcrumbs.Add(new BreadcrumbItem("Agents", href: Navigation.Management.Agents.Index, true));
}
private async Task<TableData<ViewModel>> LoadDataAsync(TableState state)
{
try
{
var filter = Builders<BsonDocument>.Filter.Empty;
if (FilterUnassignedHost)
{
filter &= Builders<BsonDocument>.Filter.Size("hosts", 0);
}
var search = Builders<BsonDocument>.Filter.Empty;
if (string.IsNullOrWhiteSpace(Search) is false)
{
var regex = new BsonRegularExpression(new Regex(Search, RegexOptions.IgnoreCase));
search &= Builders<BsonDocument>.Filter.Regex("serial", regex) |
Builders<BsonDocument>.Filter.Regex("hostname", regex) |
Builders<BsonDocument>.Filter.Regex("version", regex);
}
var query = Database.Agent()
.Aggregate()
.AppendStage<BsonDocument>(new BsonDocument("$lookup", new BsonDocument
{
{ "from", "host" },
{ "localField", "_id" },
{ "foreignField", "_agent" },
{ "as", "hosts" }
}))
.AppendStage<BsonDocument>(new BsonDocument("$addFields", new BsonDocument("host", new BsonDocument("$first", "$hosts"))))
.Match(filter)
.Match(search)
.AppendStage<BsonDocument>(new BsonDocument("$addFields",
new BsonDocument("online_diff",
new BsonDocument("$subtract", new BsonArray
{
DateTime.Now,
"$activity"
}))
))
.AppendStage<BsonDocument>(new BsonDocument("$addFields",
new BsonDocument("online",
new BsonDocument("$and", new BsonArray
{
new BsonDocument("$cond",
new BsonArray
{
new BsonDocument("$isNumber",
new BsonArray
{
"$online_diff"
}), 1, 0
}), new BsonDocument("$lt",
new BsonArray
{
"$online_diff",
60000
})
}))))
.Sort(state.SortDirection switch
{
SortDirection.Ascending => state.SortLabel switch
{
"Serial" => Builders<BsonDocument>.Sort.Ascending("serial"),
"Hostname" => Builders<BsonDocument>.Sort.Ascending("hostname"),
"Version" => Builders<BsonDocument>.Sort.Ascending("version"),
"Assigned" => Builders<BsonDocument>.Sort.Ascending("hosts"),
"Online" => Builders<BsonDocument>.Sort.Ascending("online"),
_ => null
},
SortDirection.Descending => state.SortLabel switch
{
"Serial" => Builders<BsonDocument>.Sort.Descending("serial"),
"Hostname" => Builders<BsonDocument>.Sort.Descending("hostname"),
"Version" => Builders<BsonDocument>.Sort.Descending("version"),
"Assigned" => Builders<BsonDocument>.Sort.Descending("hosts"),
"Online" => Builders<BsonDocument>.Sort.Descending("online"),
_ => null
},
_ => Builders<BsonDocument>.Sort.Ascending("serial")
});
var result = await Database.Agent().GetPagedAsync<AgentEntity, ViewModel>(query, state.Page * state.PageSize, state.PageSize);
return new TableData<ViewModel>()
{
TotalItems = (int)result.Meta.Total,
Items = result.Data
};
}
catch (Exception)
{
Notification.Error(Snackbar);
return new TableData<ViewModel>();
}
}
private async Task OnRefreshAsync()
{
if (Container is null) return;
await Container.RefreshAsync().ConfigureAwait(false);
}
private void OnDelete(ViewModel model)
{
Model = new ViewModel
{
Id = model.Id,
Serial = model?.Serial
};
_deleteDialog?.Toggle();
}
private bool _filter;
private bool Filter
{
get
{
return _filter;
}
set
{
if (value != _filter)
{
_filter = value;
StateHasChanged();
}
}
}
private bool Filtered => FilterUnassignedHost;
private void OnFilterReset()
{
FilterUnassignedHost = false;
}
private bool _filterUnassignedHost;
public bool FilterUnassignedHost
{
get
{
return _filterUnassignedHost;
}
set
{
if (value != _filterUnassignedHost)
{
_filterUnassignedHost = value;
if (Container is not null)
{
_ = Container.RefreshAsync();
}
if (value)
{
Notification.Warning(Snackbar, "Filtered");
}
}
}
}
}
[BsonIgnoreExtraElements]
public class ViewModel
{
[BsonId, BsonRepresentation(BsonType.ObjectId)]
public string? Id { get; set; }
[BsonElement("serial")]
public string? Serial { get; set; }
[BsonElement("hostname")]
public string? Hostname { get; set; }
[BsonElement("version"), BsonRepresentation(BsonType.String)]
public Version? Version { get; set; }
[BsonElement("host")]
public HostEntity? Host { get; set; }
[BsonElement("hosts")]
public List<HostEntity>? Hosts { get; set; }
[BsonElement("online")]
public bool Online { get; set; }
}