Initial commit
This commit is contained in:
@@ -0,0 +1,259 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user