246 lines
8.2 KiB
Plaintext
246 lines
8.2 KiB
Plaintext
@using RobotNet10.FleetManager.Shared.DTOs.Robot
|
|
@using RobotNet10.FleetManager.Shared.DTOs.RobotModel
|
|
@using RobotNet10.FleetManager.Client.Services
|
|
@using RobotNet10.MapEditor.Services.API
|
|
@using RobotNet10.MapEditor.Shared.DTOs.Layout
|
|
@inject ISnackbar Snackbar
|
|
@inject MapManagerApiService MapApiService
|
|
|
|
<MudDialog>
|
|
<TitleContent>
|
|
<MudText Typo="Typo.h6">
|
|
<MudIcon Icon="@Icons.Material.Filled.Edit" Color="Color.Primary" Class="mr-2" />
|
|
Edit Robot
|
|
</MudText>
|
|
</TitleContent>
|
|
<DialogContent>
|
|
<MudStack Spacing="3">
|
|
<MudTextField @bind-Value="request.RobotId"
|
|
Label="Robot ID"
|
|
Variant="Variant.Outlined"
|
|
ErrorText="@GetValidationError("RobotId")"
|
|
HelperText="Unique identifier for the robot" ReadOnly />
|
|
|
|
<MudTextField @bind-Value="request.Name"
|
|
Label="Name"
|
|
Variant="Variant.Outlined"
|
|
ErrorText="@GetValidationError("Name")" />
|
|
|
|
<MudSelect @bind-Value="request.ModelId"
|
|
Label="Robot Model"
|
|
Variant="Variant.Outlined"
|
|
T="Guid ?"
|
|
ErrorText="@GetValidationError("ModelId")">
|
|
@if (isLoadingModels)
|
|
{
|
|
<MudProgressCircular Size="Size.Small" Indeterminate="true" />
|
|
}
|
|
else
|
|
{
|
|
@foreach (var model in robotModels)
|
|
{
|
|
<MudSelectItem Value="@((Guid?)model.Id)">@model.ModelName</MudSelectItem>
|
|
}
|
|
}
|
|
</MudSelect>
|
|
|
|
<MudSelect @bind-Value="request.MapId"
|
|
Label="Map (Optional)"
|
|
Variant="Variant.Outlined"
|
|
Clearable="true"
|
|
T="Guid ?"
|
|
Disabled="@isLoadingMaps"
|
|
ErrorText="@GetValidationError("MapId")">
|
|
@if (isLoadingMaps)
|
|
{
|
|
<MudSelectItem Value="@((Guid?)null)" Disabled="true">Loading maps...</MudSelectItem>
|
|
}
|
|
else if (mapLevels != null && mapLevels.Any())
|
|
{
|
|
<MudSelectItem Value="@((Guid?)null)">No Map</MudSelectItem>
|
|
@foreach (var mapLevel in mapLevels)
|
|
{
|
|
<MudSelectItem Value="@((Guid?)mapLevel.LevelId)">@mapLevel.DisplayName</MudSelectItem>
|
|
}
|
|
}
|
|
else
|
|
{
|
|
<MudSelectItem Value="@((Guid?)null)" Disabled="true">No maps available</MudSelectItem>
|
|
}
|
|
</MudSelect>
|
|
</MudStack>
|
|
</DialogContent>
|
|
<DialogActions>
|
|
<MudButton OnClick="Cancel">Cancel</MudButton>
|
|
<MudButton Color="Color.Primary"
|
|
Variant="Variant.Filled"
|
|
OnClick="Submit"
|
|
Disabled="@isUpdating">
|
|
@if (isUpdating)
|
|
{
|
|
<MudProgressCircular Class="mr-2" Size="Size.Small" Indeterminate="true" />
|
|
<span>Updating...</span>
|
|
}
|
|
else
|
|
{
|
|
<span>Update</span>
|
|
}
|
|
</MudButton>
|
|
</DialogActions>
|
|
</MudDialog>
|
|
|
|
@code {
|
|
[CascadingParameter] private IMudDialogInstance? MudDialog { get; set; }
|
|
[Parameter] public RobotApiService RobotApiService { get; set; } = null!;
|
|
[Parameter] public RobotModelApiService RobotModelApiService { get; set; } = null!;
|
|
[Parameter] public RobotDto Robot { get; set; } = null!;
|
|
|
|
private UpdateRobotRequest request = new();
|
|
private List<RobotModelDto> robotModels = new();
|
|
private List<MapLevelInfo> mapLevels = new();
|
|
private Dictionary<string, string> validationErrors = new();
|
|
private bool isUpdating = false;
|
|
private bool isLoadingModels = true;
|
|
private bool isLoadingMaps = false;
|
|
|
|
protected override void OnInitialized()
|
|
{
|
|
// Pre-fill with existing data
|
|
request.RobotId = Robot.RobotId;
|
|
request.Name = Robot.Name;
|
|
request.ModelId = Robot.ModelId;
|
|
request.MapId = Robot.MapId;
|
|
}
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
{
|
|
await Task.WhenAll(
|
|
LoadRobotModelsAsync(),
|
|
LoadMapsAsync()
|
|
);
|
|
}
|
|
|
|
private async Task LoadRobotModelsAsync()
|
|
{
|
|
isLoadingModels = true;
|
|
try
|
|
{
|
|
robotModels = await RobotModelApiService.GetAllAsync();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Snackbar.Add($"Error loading robot models: {ex.Message}", Severity.Error);
|
|
}
|
|
finally
|
|
{
|
|
isLoadingModels = false;
|
|
StateHasChanged();
|
|
}
|
|
}
|
|
|
|
private async Task LoadMapsAsync()
|
|
{
|
|
isLoadingMaps = true;
|
|
StateHasChanged();
|
|
try
|
|
{
|
|
// Load all layouts (with nested versions and levels)
|
|
var layouts = await MapApiService.SearchLayoutsAsync();
|
|
if (layouts is null) return;
|
|
|
|
// Get all levels from all layouts (not just active layouts)
|
|
mapLevels = new List<MapLevelInfo>();
|
|
|
|
foreach (var layout in layouts.Where(l => l.Versions != null))
|
|
{
|
|
if (layout.Versions is null) continue;
|
|
foreach (var version in layout.Versions.Where(v => v.Levels != null))
|
|
{
|
|
if (version.Levels is null) continue;
|
|
foreach (var level in version.Levels.OrderBy(l => l.LevelOrder))
|
|
{
|
|
mapLevels.Add(new MapLevelInfo
|
|
{
|
|
LevelId = level.Id,
|
|
DisplayName = $"{layout.LayoutName} - {version.Version} - {level.LayoutLevelId}"
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Snackbar.Add($"Error loading maps: {ex.Message}", Severity.Warning);
|
|
mapLevels = new List<MapLevelInfo>();
|
|
}
|
|
finally
|
|
{
|
|
isLoadingMaps = false;
|
|
StateHasChanged();
|
|
}
|
|
}
|
|
|
|
private bool Validate()
|
|
{
|
|
validationErrors.Clear();
|
|
|
|
if (!string.IsNullOrWhiteSpace(request.RobotId) && request.RobotId.Length > 64)
|
|
{
|
|
validationErrors["RobotId"] = "Robot ID must be 64 characters or less";
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(request.Name) && request.Name.Length > 256)
|
|
{
|
|
validationErrors["Name"] = "Name must be 256 characters or less";
|
|
}
|
|
|
|
return validationErrors.Count == 0;
|
|
}
|
|
|
|
private string? GetValidationError(string fieldName)
|
|
{
|
|
return validationErrors.TryGetValue(fieldName, out var error) ? error : null;
|
|
}
|
|
|
|
private void Cancel()
|
|
{
|
|
MudDialog?.Cancel();
|
|
}
|
|
|
|
private async Task Submit()
|
|
{
|
|
if (!Validate())
|
|
{
|
|
Snackbar.Add("Please fix validation errors", Severity.Warning);
|
|
StateHasChanged();
|
|
return;
|
|
}
|
|
|
|
isUpdating = true;
|
|
StateHasChanged();
|
|
|
|
try
|
|
{
|
|
var updated = await RobotApiService.UpdateAsync(Robot.Id, request);
|
|
Snackbar.Add($"Robot '{updated.Name}' updated successfully", Severity.Success);
|
|
MudDialog?.Close(DialogResult.Ok(updated));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Snackbar.Add($"Error updating robot: {ex.Message}", Severity.Error);
|
|
}
|
|
finally
|
|
{
|
|
isUpdating = false;
|
|
StateHasChanged();
|
|
}
|
|
}
|
|
|
|
// Helper class for map level display
|
|
private class MapLevelInfo
|
|
{
|
|
public Guid LevelId { get; set; }
|
|
public string DisplayName { get; set; } = string.Empty;
|
|
}
|
|
}
|