Files
Denso/srcs/RobotNet10/Components/RobotNet10.MapEditor/Services/State/StationManagerState.cs
2026-07-03 16:31:37 +07:00

260 lines
6.8 KiB
C#

using RobotNet10.MapEditor.Shared.DTOs.Station;
using RobotNet10.MapEditor.Services.API;
namespace RobotNet10.MapEditor.Services.State;
/// <summary>
/// State management for Station Manager
/// </summary>
public class StationManagerState
{
private readonly MapManagerApiService _apiService;
// Context
public Guid? CurrentLayoutLevelId { get; private set; }
// Data
public List<StationDto> Stations { get; private set; } = new();
public StationDto? SelectedStation { get; private set; }
// Filters & Search
public string? SearchQuery { get; set; }
// UI State
public bool IsLoading { get; private set; }
public bool IsSaving { get; private set; }
public string? ErrorMessage { get; private set; }
// Events
public event Action? OnStateChanged;
public StationManagerState(MapManagerApiService apiService)
{
_apiService = apiService;
}
// ==========================================
// PUBLIC METHODS
// ==========================================
/// <summary>
/// Initialize or switch to a different layout level
/// </summary>
public async Task InitializeAsync(Guid layoutLevelId)
{
CurrentLayoutLevelId = layoutLevelId;
await LoadStationsAsync();
}
/// <summary>
/// Load all stations for the current layout level
/// </summary>
public async Task LoadStationsAsync()
{
if (!CurrentLayoutLevelId.HasValue)
{
ErrorMessage = "No layout level selected";
NotifyStateChanged();
return;
}
IsLoading = true;
ErrorMessage = null;
NotifyStateChanged();
try
{
Stations = await _apiService.GetStationsByLevelAsync(CurrentLayoutLevelId.Value);
NotifyStateChanged();
}
catch (Exception ex)
{
ErrorMessage = ex.Message;
Stations = new();
NotifyStateChanged();
}
finally
{
IsLoading = false;
NotifyStateChanged();
}
}
/// <summary>
/// Search stations by StationId or StationName
/// </summary>
public void Search(string? query)
{
SearchQuery = query;
NotifyStateChanged();
}
/// <summary>
/// Select a station for viewing/editing
/// </summary>
public async Task SelectStationAsync(Guid? stationId)
{
if (!stationId.HasValue)
{
SelectedStation = null;
NotifyStateChanged();
return;
}
// Try to find in local list first
SelectedStation = Stations.FirstOrDefault(s => s.Id == stationId.Value);
// If not found or need fresh data, fetch from API
if (SelectedStation == null)
{
try
{
SelectedStation = await _apiService.GetStationAsync(stationId.Value);
}
catch
{
SelectedStation = null;
}
}
NotifyStateChanged();
}
/// <summary>
/// Clear selected station
/// </summary>
public void ClearSelection()
{
SelectedStation = null;
NotifyStateChanged();
}
/// <summary>
/// Create a new station
/// </summary>
public async Task<StationDto> CreateStationAsync(RobotNet10.MapEditor.Shared.DTOs.Requests.CreateStationRequest request)
{
IsSaving = true;
ErrorMessage = null;
NotifyStateChanged();
try
{
var created = await _apiService.CreateStationAsync(request);
await LoadStationsAsync();
await SelectStationAsync(created.Id);
return created;
}
catch (Exception ex)
{
ErrorMessage = ex.Message;
NotifyStateChanged();
throw;
}
finally
{
IsSaving = false;
NotifyStateChanged();
}
}
/// <summary>
/// Update an existing station
/// </summary>
public async Task<StationDto> UpdateStationAsync(Guid stationId, RobotNet10.MapEditor.Shared.DTOs.Requests.UpdateStationRequest request)
{
IsSaving = true;
ErrorMessage = null;
NotifyStateChanged();
try
{
var updated = await _apiService.UpdateStationAsync(stationId, request);
// Update local cache
var index = Stations.FindIndex(s => s.Id == stationId);
if (index >= 0)
{
Stations[index] = updated;
}
// Update selected if it's the same station
if (SelectedStation?.Id == stationId)
{
SelectedStation = updated;
}
NotifyStateChanged();
return updated;
}
catch (Exception ex)
{
ErrorMessage = ex.Message;
NotifyStateChanged();
throw;
}
finally
{
IsSaving = false;
NotifyStateChanged();
}
}
/// <summary>
/// Delete a station
/// </summary>
public async Task DeleteStationAsync(Guid stationId)
{
try
{
await _apiService.DeleteStationAsync(stationId);
// Remove from local list
Stations.RemoveAll(s => s.Id == stationId);
// Clear selection if it was the deleted station
if (SelectedStation?.Id == stationId)
{
SelectedStation = null;
}
NotifyStateChanged();
}
catch (Exception ex)
{
ErrorMessage = ex.Message;
NotifyStateChanged();
throw;
}
}
// ==========================================
// HELPER METHODS
// ==========================================
/// <summary>
/// Get filtered stations based on search query
/// </summary>
public List<StationDto> GetFilteredStations()
{
var query = Stations.AsQueryable();
if (!string.IsNullOrWhiteSpace(SearchQuery))
{
var searchLower = SearchQuery.ToLowerInvariant();
query = query.Where(s =>
s.StationId.ToLower().Contains(searchLower) ||
(s.StationName != null && s.StationName.ToLower().Contains(searchLower)));
}
return query.OrderBy(s => s.StationId).ToList();
}
private void NotifyStateChanged()
{
OnStateChanged?.Invoke();
}
}