RobotNet/RobotNet.WebApp/Pages/RobotMonitoring.razor
2025-10-15 15:15:53 +07:00

252 lines
8.2 KiB
Plaintext

@page "/robots/monitor"
@attribute [Authorize]
@implements IAsyncDisposable
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@using RobotNet.MapShares.Dtos
@using RobotNet.RobotShares.Dtos
@using RobotNet.RobotShares.Enums
@using RobotNet.Shares
@using RobotNet.WebApp.Clients
@using RobotNet.WebApp.Robots.Components.Monitoring
@inject ISnackbar Snackbar
@inject IHttpClientFactory HttpFactory
@inject RobotHubClient RobotHub
<PageTitle>Robot Monitoring</PageTitle>
<div class="d-flex flex-row w-100 h-100 position-relative">
<div class="d-flex h-100 flex-grow-1 flex-column">
<MonitorToolbar @ref="MonitorToolbarRef" Model="@ToolBarModel" ExpandChanged="ExpandChanged" ButtonEventClick="ButtonEventClick"
CheckedEventClick="ToolbarCheckedClick" MapChanged="MapChanged" RobotChanged="RobotChanged" />
<div class="flex-grow-1 w-100">
<MonitorMap @ref="MonitorMapRef" ShowGrid="@ToolBarModel.ShowGrid" ShowName="@ToolBarModel.ShowName" ShowPath="@ToolBarModel.ShowPath" ShowLaser="@ToolBarModel.ShowLaser" ShowElement="@ToolBarModel.ShowElement"/>
</div>
</div>
<div class="h-100 d-flex flex-column align-items-center" style="width: fit-content; border-left: 2px solid black;">
<MonitorInfomation @ref="@MonitorInfomationRef" />
</div>
<MudOverlay @bind-Visible="IsDeactive" DarkBackground="true" Absolute="true">
<MudText Typo="Typo.h1" Color="@Color.Error" Style="font-weight: bold;">@IsDeactiveText</MudText>
</MudOverlay>
</div>
@code {
private MonitorMap MonitorMapRef = null!;
private MonitorToolbar MonitorToolbarRef = null!;
private MonitorInfomation MonitorInfomationRef = null!;
private MonitorToolBarModel ToolBarModel = new()
{
ShowGrid = false,
ShowName = true,
ShowPath = true,
FocusRobot = false,
ShowLaser = false,
ShowElement = true,
};
private List<MapInfoDto> Maps = [];
private Guid MapIdSelected = new();
private bool IsDeactive = false;
private string IsDeactiveText = "Deactive";
private RobotInfomationDto RobotSelected = new();
protected override async Task OnAfterRenderAsync(bool firstRender)
{
await base.OnAfterRenderAsync(firstRender);
if (!firstRender) return;
RobotHub.MapDeactive += OnDeactive;
RobotHub.UpdateChanged += OnUpdateChanged;
RobotHub.ElementsStateChanged += ElementsStateChanged;
await RobotHub.StartAsync();
await LoadMaps();
}
private async Task LoadMaps()
{
try
{
IsDeactive = true;
IsDeactiveText = "IsLoading...";
Maps.Clear();
StateHasChanged();
using var Http = HttpFactory.CreateClient("MapManagerAPI");
var maps = await Http.GetFromJsonAsync<IEnumerable<MapInfoDto>>($"api/MapsManager?txtSearch=");
if (maps is null || maps.Count() == 0)
{
IsDeactiveText = "Map Empty";
StateHasChanged();
return;
}
var mapsActive = maps.Where(m => m.Active).ToList();
if (mapsActive.Count == 0)
{
IsDeactiveText = "Map Empty";
StateHasChanged();
return;
}
Maps.AddRange(mapsActive ?? []);
if (Maps.Count > 0)
{
MonitorToolbarRef.LoadMaps(Maps, Maps[0]);
await LoadMapData(Maps[0].Id);
}
IsDeactive = false;
StateHasChanged();
}
catch (AccessTokenNotAvailableException ex)
{
ex.Redirect();
return;
}
}
private async Task LoadMapData(Guid Id)
{
try
{
IsDeactive = true;
IsDeactiveText = "IsLoading...";
StateHasChanged();
using var Http = HttpFactory.CreateClient("MapManagerAPI");
var mapDataResult = await Http.GetFromJsonAsync<MessageResult<MapDataDto>>($"api/MapsData/{Id}");
if (mapDataResult is not null && mapDataResult.Data is not null)
{
await MonitorMapRef.LoadMap(null);
await MonitorMapRef.LoadMap(mapDataResult.Data);
MapIdSelected = mapDataResult.Data.Id;
IsDeactive = false;
if (RobotHub.IsConnected) await RobotHub.MapActive(MapIdSelected);
}
else IsDeactiveText = "Map Not Existed";
IsDeactive = false;
StateHasChanged();
}
catch
{
IsDeactiveText = "Map Not Existed";
StateHasChanged();
return;
}
}
private async Task ToolbarCheckedClick(MonitorToolbarCheckedType type, bool value)
{
switch (type)
{
case MonitorToolbarCheckedType.ShowGrid:
ToolBarModel.ShowGrid = value;
break;
case MonitorToolbarCheckedType.ShowName:
ToolBarModel.ShowName = value;
break;
case MonitorToolbarCheckedType.ShowPath:
ToolBarModel.ShowPath = value;
break;
case MonitorToolbarCheckedType.ShowLaser:
ToolBarModel.ShowLaser = value;
break;
case MonitorToolbarCheckedType.ShowElement:
ToolBarModel.ShowElement = value;
break;
case MonitorToolbarCheckedType.FocusRobot:
ToolBarModel.FocusRobot = value;
MonitorMapRef.FocusRobot(value);
if (value) await MonitorMapRef.FocusRobotAsync();
break;
}
StateHasChanged();
}
private void ExpandChanged(bool value) => MonitorInfomationRef.ExpandedClick(value);
private async Task ButtonEventClick(MonitorToolbarButtonType type)
{
switch (type)
{
case MonitorToolbarButtonType.Fit:
await MonitorMapRef.ScaleFitContentAsync();
break;
case MonitorToolbarButtonType.Focus:
await MonitorMapRef.FocusRobotAsync();
break;
case MonitorToolbarButtonType.ZoomIn:
await MonitorMapRef.ScaleZoom(0.5);
break;
case MonitorToolbarButtonType.ZoomOut:
await MonitorMapRef.ScaleZoom(-0.5);
break;
}
}
private async Task MapChanged(MapInfoDto map)
{
if (map.Id != MapIdSelected) await LoadMapData(map.Id);
}
private void RobotChanged(RobotInfomationDto robot)
{
if(robot.RobotId != RobotSelected.RobotId)
{
RobotSelected = robot;
MonitorMapRef.RobotSelectedChange(RobotSelected.RobotId);
}
}
private bool IsUpdateing = false;
private void OnUpdateChanged(IEnumerable<RobotInfomationDto> robotInfos)
{
if (IsUpdateing) return;
IsUpdateing = true;
InvokeAsync(async () =>
{
var robots = robotInfos.Where(r => r.MapId == MapIdSelected).ToList();
await MonitorMapRef.SetRobotPosition([.. robots]);
MonitorToolbarRef.LoadRobots([.. robotInfos]);
var robotSelect = robots.FirstOrDefault(r => r.RobotId == RobotSelected.RobotId);
if (robotSelect is not null) MonitorInfomationRef.UpdateState(robotSelect);
IsUpdateing = false;
});
}
private void ElementsStateChanged(IEnumerable<ElementDto> elementsState)
{
_ = InvokeAsync(() =>
{
var elements = elementsState.Where(e => e.MapId == MapIdSelected).ToList();
MonitorMapRef.ElementStateUpdated([.. elements]);
});
}
private void OnDeactive()
{
IsDeactiveText = "Deactive";
IsDeactive = true;
StateHasChanged();
RobotHub.UpdateChanged -= OnUpdateChanged;
RobotHub.MapDeactive -= OnDeactive;
_ = RobotHub.StopAsync();
}
public async ValueTask DisposeAsync()
{
RobotHub.MapDeactive -= OnDeactive;
RobotHub.UpdateChanged -= OnUpdateChanged;
await RobotHub.StopAsync();
}
}