@using RobotNet10.FleetManager.Shared.DTOs.Robot @using RobotNet10.FleetManager.Shared.DTOs.RobotModel @using RobotNet10.FleetManager.Client.Services @using RobotNet10.FleetManager.Client.Components.RobotManager.Dialogs @using RobotNet10.MapEditor.Services.API @using RobotNet10.MapEditor.Shared.DTOs.Layout @using RobotNet10.Shared @using System.Net.Http.Json @inject IDialogService DialogService @inject ISnackbar Snackbar @inject NavigationManager NavigationManager @inject MapManagerApiService MapApiService @inject HttpClient HttpClient @foreach (var model in robotModels) { @model.ModelName } All Maps @if (isLoading) { Loading robots... } else if (robots.Count == 0) { @if (!string.IsNullOrWhiteSpace(searchText) || selectedModelId.HasValue || selectedMapId.HasValue) { No robots found matching the current filters. } else { No robots found. Click "Add Robot" to create one. } } else { Robot ID Name Model Map Status Created Date @context.RobotId @context.Name @(context.ModelName ?? "N/A") @GetMapDisplayName(context.MapId) @if (GetRobotOnlineStatus(context.RobotId)) { Online } else { Offline } @context.CreatedDate.ToString("g")
}
@code { [Parameter] public RobotApiService RobotApiService { get; set; } = null!; [Parameter] public RobotModelApiService RobotModelApiService { get; set; } = null!; [Parameter] public EventCallback OnRobotDeleted { get; set; } [Parameter] public EventCallback OnRobotUpdated { get; set; } private List robots = new(); private List robotModels = new(); private MudTable? table; private bool isLoading = false; private string searchText = string.Empty; private Guid? selectedModelId; private Guid? selectedMapId; private Dictionary mapDisplayNames = new(); private Dictionary robotOnlineStatus = new(); protected override async Task OnInitializedAsync() { await LoadRobotModelsAsync(); await LoadDataAsync(); } protected override async Task OnParametersSetAsync() { await LoadDataAsync(); } public async Task LoadDataAsync() { isLoading = true; StateHasChanged(); try { if (!string.IsNullOrWhiteSpace(searchText)) { robots = await RobotApiService.SearchAsync(searchText); } else { robots = await RobotApiService.GetAllAsync(selectedModelId, selectedMapId); } // Load map display names and online status await LoadMapDisplayNamesAsync(); await LoadRobotOnlineStatusAsync(); table?.ReloadServerData(); } catch (HttpRequestException ex) { Snackbar.Add($"Network error loading robots: {ex.Message}", Severity.Error); robots = new List(); } catch (Exception ex) { Snackbar.Add($"Error loading robots: {ex.Message}", Severity.Error); robots = new List(); } finally { isLoading = false; StateHasChanged(); } } private async Task LoadMapDisplayNamesAsync() { mapDisplayNames.Clear(); var mapIds = robots.Where(r => r.MapId.HasValue).Select(r => r.MapId!.Value).Distinct().ToList(); if (mapIds.Count == 0) return; try { // Load all layouts once var layouts = await MapApiService.SearchLayoutsAsync(); // Create a dictionary to map level ID to layout/version info var levelInfoMap = new Dictionary(); foreach (var layout in layouts) { if (layout.Versions != null) { foreach (var version in layout.Versions) { if (version.Levels != null) { foreach (var level in version.Levels) { levelInfoMap[level.Id] = (layout.LayoutName, version.Version, level.LayoutLevelId); } } } } } // Build display names for each map ID foreach (var mapId in mapIds) { if (levelInfoMap.TryGetValue(mapId, out var info)) { mapDisplayNames[mapId] = $"{info.LayoutName} - {info.Version} - {info.LevelId}"; } else { mapDisplayNames[mapId] = "N/A"; } } } catch (Exception ex) { // If loading fails, set all to N/A foreach (var mapId in mapIds) { mapDisplayNames[mapId] = "N/A"; } Snackbar.Add($"Error loading map information: {ex.Message}", Severity.Warning); } } private async Task LoadRobotOnlineStatusAsync() { robotOnlineStatus.Clear(); var tasks = robots.Select(async robot => { try { var response = await HttpClient.GetAsync($"/api/RobotManager/OnlineStatus/{robot.RobotId}"); if (response.IsSuccessStatusCode) { var result = await response.Content.ReadFromJsonAsync>(); robotOnlineStatus[robot.RobotId] = result?.Data ?? false; } else { robotOnlineStatus[robot.RobotId] = false; } } catch { robotOnlineStatus[robot.RobotId] = false; } }); await Task.WhenAll(tasks); } private string GetMapDisplayName(Guid? mapId) { if (!mapId.HasValue) return "N/A"; return mapDisplayNames.TryGetValue(mapId.Value, out var displayName) ? displayName : "Loading..."; } private bool GetRobotOnlineStatus(string robotId) { return robotOnlineStatus.TryGetValue(robotId, out var isOnline) && isOnline; } private async Task LoadRobotModelsAsync() { try { robotModels = await RobotModelApiService.GetAllAsync(); } catch (Exception ex) { Snackbar.Add($"Error loading robot models: {ex.Message}", Severity.Error); } } private async Task OnSearchTextChanged(string text) { searchText = text; await LoadDataAsync(); } private async Task OnModelFilterChanged() { await LoadDataAsync(); } private async Task OnMapFilterChanged() { await LoadDataAsync(); } private void NavigateToDetail(string robotId) { NavigationManager.NavigateTo($"/robots/{robotId}/detail"); } private async Task HandleEdit(RobotDto robot) { var parameters = new DialogParameters { ["RobotApiService"] = RobotApiService, ["RobotModelApiService"] = RobotModelApiService, ["Robot"] = robot }; var dialog = await DialogService.ShowAsync("Edit Robot", parameters, new DialogOptions { MaxWidth = MaxWidth.Medium, FullWidth = true }); var result = await dialog.Result; if (result != null && !result.Canceled) { await LoadDataAsync(); await OnRobotUpdated.InvokeAsync(); } } private async Task HandleDelete(RobotDto robot) { var parameters = new DialogParameters { ["RobotApiService"] = RobotApiService, ["Robot"] = robot }; var dialog = await DialogService.ShowAsync("Delete Robot", parameters); var result = await dialog.Result; if (result != null && !result.Canceled) { await LoadDataAsync(); await OnRobotDeleted.InvokeAsync(); } } }