Initial commit
This commit is contained in:
@@ -0,0 +1,247 @@
|
||||
@page "/devices"
|
||||
@implements IAsyncDisposable
|
||||
@rendermode InteractiveWebAssemblyNoPrerender
|
||||
|
||||
@using Microsoft.AspNetCore.SignalR.Client
|
||||
@using RobotNet10.RobotApp.Client.Components.Devices
|
||||
@using RobotNet10.RobotApp.Client.Services
|
||||
@using RobotNet10.RobotApp.Client.Shared.Devices
|
||||
@using MudBlazor
|
||||
|
||||
@inject DeviceHubClient DeviceHubClient
|
||||
@inject ISnackbar Snackbar
|
||||
|
||||
<PageTitle>Device Diagnostics</PageTitle>
|
||||
|
||||
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="mt-4">
|
||||
|
||||
<MudPaper Class="pa-4 mb-4">
|
||||
<MudStack Row="true" AlignItems="@AlignItems.Center" Justify="@Justify.SpaceBetween" Spacing="3">
|
||||
<MudText Typo="Typo.h5" Class="mb-4">Device Diagnostics</MudText>
|
||||
<MudStack Row="true" AlignItems="@AlignItems.Center" Spacing="3">
|
||||
<MudTextField @bind-Value="searchText" @bind-Value:after="OnFilterChanged" Placeholder="Search devices..." Class="flex-grow-1"
|
||||
Variant="Variant.Outlined" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Search" Margin="@Margin.Dense" />
|
||||
<MudIconButton Color="Color.Primary" OnClick="RefreshDevices" Disabled="@(!DeviceHubClient.IsConnected || isLoading)" Icon="@Icons.Material.Filled.Refresh" />
|
||||
</MudStack>
|
||||
</MudStack>
|
||||
</MudPaper>
|
||||
@* Loading State *@
|
||||
@if (isLoading)
|
||||
{
|
||||
<MudProgressLinear Color="Color.Primary" Indeterminate="true" Class="mb-4" />
|
||||
}
|
||||
|
||||
@* Device Count Summary *@
|
||||
<MudGrid Class="mb-4">
|
||||
<MudItem xs="12" sm="6" md="3">
|
||||
<MudPaper Class="pa-3 text-center">
|
||||
<MudText Typo="Typo.h6">@devices.Count</MudText>
|
||||
<MudText Typo="Typo.body2" Color="Color.Secondary">Total Devices</MudText>
|
||||
</MudPaper>
|
||||
</MudItem>
|
||||
<MudItem xs="12" sm="6" md="3">
|
||||
<MudPaper Class="pa-3 text-center">
|
||||
<MudText Typo="Typo.h6" Color="Color.Success">@devices.Count(d => d.IsConnected)</MudText>
|
||||
<MudText Typo="Typo.body2" Color="Color.Secondary">Connected</MudText>
|
||||
</MudPaper>
|
||||
</MudItem>
|
||||
<MudItem xs="12" sm="6" md="3">
|
||||
<MudPaper Class="pa-3 text-center">
|
||||
<MudText Typo="Typo.h6" Color="Color.Error">@devices.Count(d => d.Status == DeviceStatus.Error)</MudText>
|
||||
<MudText Typo="Typo.body2" Color="Color.Secondary">Errors</MudText>
|
||||
</MudPaper>
|
||||
</MudItem>
|
||||
<MudItem xs="12" sm="6" md="3">
|
||||
<MudPaper Class="pa-3 text-center">
|
||||
<MudText Typo="Typo.h6" Color="Color.Warning">@devices.Count(d => d.Status == DeviceStatus.Disconnected)</MudText>
|
||||
<MudText Typo="Typo.body2" Color="Color.Secondary">Disconnected</MudText>
|
||||
</MudPaper>
|
||||
</MudItem>
|
||||
</MudGrid>
|
||||
|
||||
@* Devices List *@
|
||||
@if (filteredDevices != null && filteredDevices.Any())
|
||||
{
|
||||
<MudGrid Spacing="2">
|
||||
@foreach (var device in filteredDevices)
|
||||
{
|
||||
<MudItem xs="12" sm="6" md="4" lg="3" xl="2">
|
||||
<DeviceCard Device="@device" />
|
||||
</MudItem>
|
||||
}
|
||||
</MudGrid>
|
||||
}
|
||||
else if (!isLoading && (devices == null || !devices.Any()))
|
||||
{
|
||||
<MudPaper Class="pa-8 text-center">
|
||||
<MudIcon Icon="@Icons.Material.Filled.Devices" Size="Size.Large" Color="Color.Secondary" Class="mb-4" />
|
||||
<MudText Typo="Typo.h6">No devices found</MudText>
|
||||
<MudText Typo="Typo.body2" Color="Color.Secondary">No devices are currently registered in the system.</MudText>
|
||||
</MudPaper>
|
||||
}
|
||||
else if (!isLoading)
|
||||
{
|
||||
<MudPaper Class="pa-8 text-center">
|
||||
<MudText Typo="Typo.h6">No devices match the filter criteria</MudText>
|
||||
</MudPaper>
|
||||
}
|
||||
</MudContainer>
|
||||
|
||||
|
||||
<MudThemeProvider IsDarkMode />
|
||||
<MudPopoverProvider />
|
||||
<MudDialogProvider />
|
||||
<MudSnackbarProvider />
|
||||
|
||||
@code {
|
||||
private List<DeviceDto> devices = [];
|
||||
private List<DeviceDto> filteredDevices = [];
|
||||
private bool isLoading = false;
|
||||
private string searchText = string.Empty;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
DeviceHubClient.DeviceUpdated += OnDeviceUpdated;
|
||||
DeviceHubClient.DeviceStatusChanged += OnDeviceStatusChanged;
|
||||
DeviceHubClient.ConnectionStateChanged += OnConnectionStateChanged;
|
||||
|
||||
await DeviceHubClient.StartAsync();
|
||||
await LoadDevices();
|
||||
}
|
||||
|
||||
private async Task LoadDevices()
|
||||
{
|
||||
try
|
||||
{
|
||||
isLoading = true;
|
||||
if (DeviceHubClient.IsConnected)
|
||||
{
|
||||
devices = (await DeviceHubClient.GetAllDevicesAsync()).ToList();
|
||||
ApplyFilters();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Snackbar.Add($"Error loading devices: {ex.Message}", Severity.Error);
|
||||
}
|
||||
finally
|
||||
{
|
||||
isLoading = false;
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RefreshDevices()
|
||||
{
|
||||
await LoadDevices();
|
||||
}
|
||||
|
||||
private void OnDeviceUpdated(DeviceUpdateDto update)
|
||||
{
|
||||
if (devices == null) return;
|
||||
|
||||
var device = devices.FirstOrDefault(d => d.DeviceId == update.DeviceId);
|
||||
if (device != null)
|
||||
{
|
||||
if (update.Status.HasValue)
|
||||
device.Status = update.Status.Value;
|
||||
if (update.Properties != null)
|
||||
device.Properties = update.Properties;
|
||||
if (update.LastError != null)
|
||||
device.LastError = update.LastError;
|
||||
if (update.LastUpdateTime.HasValue)
|
||||
device.LastUpdateTime = update.LastUpdateTime.Value;
|
||||
if (update.LastConnectedTime.HasValue)
|
||||
device.LastConnectedTime = update.LastConnectedTime;
|
||||
if (update.LastDisconnectedTime.HasValue)
|
||||
device.LastDisconnectedTime = update.LastDisconnectedTime;
|
||||
if (update.ReconnectAttemptCount.HasValue)
|
||||
device.ReconnectAttemptCount = update.ReconnectAttemptCount.Value;
|
||||
|
||||
device.IsConnected = device.Status == DeviceStatus.Connected;
|
||||
ApplyFilters();
|
||||
InvokeAsync(StateHasChanged);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDeviceStatusChanged(string deviceId, DeviceStatus status)
|
||||
{
|
||||
if (devices == null) return;
|
||||
|
||||
var device = devices.FirstOrDefault(d => d.DeviceId == deviceId);
|
||||
if (device != null)
|
||||
{
|
||||
device.Status = status;
|
||||
device.IsConnected = status == DeviceStatus.Connected;
|
||||
ApplyFilters();
|
||||
InvokeAsync(StateHasChanged);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnConnectionStateChanged(HubConnectionState state)
|
||||
{
|
||||
InvokeAsync(StateHasChanged);
|
||||
if (state == HubConnectionState.Connected)
|
||||
{
|
||||
_ = LoadDevices();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnFilterChanged()
|
||||
{
|
||||
ApplyFilters();
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private void ApplyFilters()
|
||||
{
|
||||
if (devices == null)
|
||||
{
|
||||
filteredDevices = [];
|
||||
return;
|
||||
}
|
||||
|
||||
var query = devices.AsEnumerable();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(searchText))
|
||||
{
|
||||
var searchLower = searchText.ToLowerInvariant();
|
||||
query = query.Where(d =>
|
||||
d.DeviceId.ToLowerInvariant().Contains(searchLower) ||
|
||||
d.DeviceName.ToLowerInvariant().Contains(searchLower) ||
|
||||
(d.Description != null && d.Description.ToLowerInvariant().Contains(searchLower))
|
||||
);
|
||||
}
|
||||
|
||||
filteredDevices = query.ToList();
|
||||
}
|
||||
|
||||
private string GetConnectionIcon()
|
||||
{
|
||||
return DeviceHubClient.ConnectionState switch
|
||||
{
|
||||
HubConnectionState.Connected => Icons.Material.Filled.CheckCircle,
|
||||
HubConnectionState.Connecting => Icons.Material.Filled.HourglassEmpty,
|
||||
HubConnectionState.Reconnecting => Icons.Material.Filled.Sync,
|
||||
_ => Icons.Material.Filled.Error
|
||||
};
|
||||
}
|
||||
|
||||
private Color GetConnectionColor()
|
||||
{
|
||||
return DeviceHubClient.ConnectionState switch
|
||||
{
|
||||
HubConnectionState.Connected => Color.Success,
|
||||
HubConnectionState.Connecting => Color.Warning,
|
||||
HubConnectionState.Reconnecting => Color.Warning,
|
||||
_ => Color.Error
|
||||
};
|
||||
}
|
||||
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
DeviceHubClient.DeviceUpdated -= OnDeviceUpdated;
|
||||
DeviceHubClient.DeviceStatusChanged -= OnDeviceStatusChanged;
|
||||
DeviceHubClient.ConnectionStateChanged -= OnConnectionStateChanged;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user