insight/src/Web/Insight.Web/Pages/Management/Agents/Index.razor.cs
2023-09-21 18:58:32 +02:00

225 lines
No EOL
7.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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; }
}