@page "/dock-station-config" @rendermode InteractiveWebAssemblyNoPrerender @using RobotNet10.RobotApp.Client.Services @using RobotNet10.RobotApp.Client.Dialogs @using RobotNet10.RobotApp.Shared.DockStation @inject DockStationConfigState State @inject IDialogService DialogService @inject ISnackbar Snackbar @implements IDisposable Dock Station Config Dock Station Configuration @if (!string.IsNullOrEmpty(State.ErrorMessage)) { @State.ErrorMessage } @* Left Panel - Config List *@ Stations New @if (State.IsLoading && State.Configs.Count == 0) { } else if (State.Configs.Count == 0) { No dock station configs found. } else { @foreach (var config in State.Configs) { @config.StationId @(string.IsNullOrEmpty(config.ConfigName) ? "No name" : config.ConfigName) · @config.MarkerEntryCount marker(s) } } @* Right Panel - Detail View *@ @if (State.SelectedConfig is not null) { var cfg = State.SelectedConfig; @cfg.StationId @(cfg.IsActive ? "Active" : "Inactive") @if (!string.IsNullOrEmpty(cfg.ConfigName)) { @cfg.ConfigName } @if (!string.IsNullOrEmpty(cfg.Description)) { @cfg.Description } Search Area X: @cfg.X.ToString("F3") m Y: @cfg.Y.ToString("F3") m Yaw: @cfg.Yaw.ToString("F4") rad Width: @cfg.Width.ToString("F3") m Length: @cfg.Length.ToString("F3") m Marker Entries (@cfg.MarkerEntries.Count) @foreach (var entry in cfg.MarkerEntries.OrderBy(e => e.Priority)) { Marker: @entry.MarkerId Type: @entry.Type Priority: @entry.Priority Device: @(entry.DeviceId ?? "-") Code: @(entry.Code ?? "-") @if (entry.ReferencePoints.Count > 0) { Reference Points: @string.Join(", ", entry.ReferencePoints.Select(p => $"({p.X:F3}, {p.Y:F3})")) } } Created: @cfg.CreatedAt.ToString("yyyy-MM-dd HH:mm") | Updated: @cfg.UpdatedAt.ToString("yyyy-MM-dd HH:mm") } else { Select a dock station config to view details } @code { protected override async Task OnInitializedAsync() { State.OnStateChanged += StateHasChanged; await State.LoadConfigsAsync(); } public void Dispose() { State.OnStateChanged -= StateHasChanged; } private async Task OnConfigSelected(DockStationConfigSummaryDto? config) { if (config is not null) await State.SelectConfigAsync(config.Id); } private async Task OpenCreateDialog() { var dialog = await DialogService.ShowAsync( "Create Dock Station Config", new DialogParameters { ["Config"] = null }, new DialogOptions { MaxWidth = MaxWidth.Medium, FullWidth = true }); var result = await dialog.Result; if (result is not null && !result.Canceled && result.Data is CreateDockStationConfigRequest request) { try { await State.CreateConfigAsync(request); Snackbar.Add("Dock station config created.", Severity.Success); } catch (Exception ex) { Snackbar.Add($"Error: {ex.Message}", Severity.Error); } } } private async Task OpenEditDialog() { if (State.SelectedConfig is null) return; var dialog = await DialogService.ShowAsync( "Edit Dock Station Config", new DialogParameters { ["Config"] = State.SelectedConfig }, new DialogOptions { MaxWidth = MaxWidth.Medium, FullWidth = true }); var result = await dialog.Result; if (result is not null && !result.Canceled && result.Data is UpdateDockStationConfigRequest request) { try { await State.UpdateConfigAsync(State.SelectedConfig.Id, request); Snackbar.Add("Dock station config updated.", Severity.Success); } catch (Exception ex) { Snackbar.Add($"Error: {ex.Message}", Severity.Error); } } } private async Task OpenDeleteDialog() { if (State.SelectedConfig is null) return; var confirm = await DialogService.ShowMessageBoxAsync( "Confirm Delete", $"Are you sure you want to delete dock station config '{State.SelectedConfig.StationId}'?", yesText: "Delete", cancelText: "Cancel"); if (confirm == true) { try { await State.DeleteConfigAsync(State.SelectedConfig.Id); Snackbar.Add("Dock station config deleted.", Severity.Success); } catch (Exception ex) { Snackbar.Add($"Error: {ex.Message}", Severity.Error); } } } }