RobotApp/RobotApp.Client/Pages/RobotConfigManager.razor
Đăng Nguyễn aa2146e383 update
2025-10-30 13:34:44 +07:00

209 lines
8.4 KiB
Plaintext

@page "/robot-config"
@rendermode InteractiveWebAssemblyNoPrerender
@attribute [Authorize]
@using RobotApp.Common.Shares.Dtos
@using RobotApp.Common.Shares.Enums
@inject HttpClient Http
<PageTitle>Robot Configuration</PageTitle>
<div class="d-flex w-100 h-100 p-2 overflow-hidden flex-column">
<div class="rcm-toolbar">
<div class="rcm-toolbar-left">
<label class="rcm-label" for="configType">Config Type</label>
<div class="rcm-select-wrapper">
<select id="configType" class="form-select rcm-select" @bind="SelectedType">
@foreach (var type in Enum.GetValues<RobotConfigType>())
{
<option value="@type">@type</option>
}
</select>
<span class="rcm-select-icon" aria-hidden="true">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path d="M7 10l5 5 5-5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</span>
</div>
</div>
<div class="rcm-toolbar-right">
<div class="rcm-action-group">
<button type="button" class="btn rcm-icon-btn" data-tooltip="Add config" aria-label="Add">
<i class="mdi mdi-plus" aria-hidden="true"></i>
</button>
<button type="button" class="btn rcm-icon-btn" data-tooltip="Update config" aria-label="Update">
<i class="mdi mdi-content-save" aria-hidden="true"></i>
</button>
<button type="button" class="btn rcm-icon-btn rcm-danger" data-tooltip="Delete config" aria-label="Delete">
<i class="mdi mdi-delete" aria-hidden="true"></i>
</button>
</div>
</div>
</div>
<div class="content rcm-content flex-grow-1 d-flex gap-3 mt-3">
<div class="card p-2 config-list rcm-config-list">
<div class="card-body list-body p-0">
@switch (SelectedType)
{
case RobotConfigType.VDA5050:
@RenderList(VdaConfigs, () => SelectVda)
break;
case RobotConfigType.Safety:
@RenderList(SafetyConfigs, () => SelectSafety)
break;
case RobotConfigType.Simulation:
@RenderList(SimulationConfigs, () => SelectSimulation)
break;
case RobotConfigType.PLC:
@RenderList(PlcConfigs, () => SelectPlc)
break;
case RobotConfigType.Core:
@RenderList(CoreConfigs, () => SelectCore)
break;
default:
<div class="p-2">No configs.</div>
break;
}
</div>
</div>
<div class="card p-2 config-content rcm-config-content">
<div class="card-body">
@if (!HasSelection)
{
<div class="text-muted">Select a config from the list or click Add to create one.</div>
}
else
{
@switch (SelectedType)
{
case RobotConfigType.VDA5050:
<RobotApp.Client.Pages.Components.Config.RobotVDA5050Config @bind-Model="SelectedVda" />
break;
case RobotConfigType.Safety:
<RobotApp.Client.Pages.Components.Config.RobotSafetyConfig @bind-Model="SelectedSafety" />
break;
case RobotConfigType.Simulation:
<RobotApp.Client.Pages.Components.Config.RobotSimulationConfig @bind-Model="SelectedSimulation" />
break;
case RobotConfigType.PLC:
<RobotApp.Client.Pages.Components.Config.RobotPLCConfig @bind-Model="SelectedPlc" />
break;
case RobotConfigType.Core:
<RobotApp.Client.Pages.Components.Config.RobotConfig @bind-Model="SelectedCore" />
break;
}
}
</div>
</div>
</div>
</div>
@code {
private List<RobotVDA5050ConfigDto> VdaConfigs { get; } = [];
private List<RobotSafetyConfigDto> SafetyConfigs { get; } = [];
private List<RobotSimulationConfigDto> SimulationConfigs { get; } = [];
private List<RobotPlcConfigDto> PlcConfigs { get; } = [];
private List<RobotConfigDto> CoreConfigs { get; } = [];
private RobotVDA5050ConfigDto? SelectedVda { get; set; }
private RobotSafetyConfigDto? SelectedSafety { get; set; }
private RobotSimulationConfigDto? SelectedSimulation { get; set; }
private RobotPlcConfigDto? SelectedPlc { get; set; }
private RobotConfigDto? SelectedCore { get; set; }
private RobotConfigType SelectedType { get; set; } = RobotConfigType.VDA5050;
private int SelectedIndex { get; set; } = -1;
private bool HasSelection => SelectedIndex >= 0;
RenderFragment RenderList<T>(List<T> list, Func<Action<int>> selectFactory) where T : class
{
return builder =>
{
if (list is null || !list.Any())
{
builder.OpenElement(0, "div");
builder.AddAttribute(1, "class", "p-2 text-muted");
builder.AddContent(2, "No configs found.");
builder.CloseElement();
return;
}
builder.OpenElement(3, "ul");
builder.AddAttribute(4, "class", "list-group list-group-flush");
for (int i = 0; i < list.Count; i++)
{
var item = list[i];
var idx = i;
builder.OpenElement(10 + i * 5, "li");
builder.AddAttribute(11 + i * 5, "class", $"list-group-item {(SelectedIndex==idx ? "active" : "")}");
builder.AddAttribute(12 + i * 5, "style", "cursor:pointer;padding:0.75rem 1rem;");
builder.AddAttribute(13 + i * 5, "onclick", EventCallback.Factory.Create(this, () => selectFactory()(idx)));
// Only show ConfigName
var nameProp = item.GetType().GetProperty("ConfigName");
var name = nameProp?.GetValue(item)?.ToString() ?? "Unnamed";
builder.AddContent(14 + i * 5, name);
// Show active badge at end if IsActive == true
var isActiveProp = item.GetType().GetProperty("IsActive");
var isActive = isActiveProp?.GetValue(item) is bool b && b;
if (isActive)
{
builder.OpenElement(15 + i * 5, "span");
builder.AddAttribute(16 + i * 5, "class", "badge bg-success ms-2 float-end");
builder.AddContent(17 + i * 5, "Active");
builder.CloseElement();
}
builder.CloseElement();
}
builder.CloseElement();
};
}
private Action<int> SelectVda => idx =>
{
SelectedIndex = idx;
SelectedVda = idx >= 0 && idx < VdaConfigs.Count ? VdaConfigs[idx] with { } : null;
StateHasChanged();
};
private Action<int> SelectSafety => idx =>
{
SelectedIndex = idx;
SelectedSafety = idx >= 0 && idx < SafetyConfigs.Count ? SafetyConfigs[idx] with { } : null;
StateHasChanged();
};
private Action<int> SelectSimulation => idx =>
{
SelectedIndex = idx;
SelectedSimulation = idx >= 0 && idx < SimulationConfigs.Count ? SimulationConfigs[idx] with { } : null;
StateHasChanged();
};
private Action<int> SelectPlc => idx =>
{
SelectedIndex = idx;
SelectedPlc = idx >= 0 && idx < PlcConfigs.Count ? PlcConfigs[idx] with { } : null;
StateHasChanged();
};
private Action<int> SelectCore => idx =>
{
SelectedIndex = idx;
SelectedCore = idx >= 0 && idx < CoreConfigs.Count ? CoreConfigs[idx] with { } : null;
StateHasChanged();
};
}