256 lines
10 KiB
Plaintext
256 lines
10 KiB
Plaintext
@implements IDisposable
|
|
@inject IJSRuntime JSRuntime
|
|
@inject IHttpClientFactory HttpClientFactory
|
|
@inject ISnackbar Snackbar
|
|
|
|
<g>
|
|
@foreach (var edge in Models)
|
|
{
|
|
<Edge Model="edge" DoubleClick="OnEdgeDoubleClick" EditorState="@EditorState" />
|
|
}
|
|
@foreach (var edge in Models)
|
|
{
|
|
<EdgeDirection Model="edge" />
|
|
}
|
|
</g>
|
|
|
|
<MudDialog @bind-Visible="updateEdgeVisible">
|
|
<TitleContent>
|
|
<MudText Typo="Typo.h6">
|
|
Update edge @UpdateModel.Id
|
|
</MudText>
|
|
</TitleContent>
|
|
<DialogContent>
|
|
<div class="d-flex flex-row align-items-center">
|
|
<MudText>
|
|
Length: @SelectModelLength m
|
|
</MudText>
|
|
</div>
|
|
<div class="d-flex flex-row mt-2">
|
|
<div class="d-flex flex-column">
|
|
<div class="mb-2">
|
|
<MudNumericField @bind-Value="UpdateModel.ControlPoint1X" Label="Control Point 1 X" Variant="Variant.Outlined" Margin="Margin.Dense" Step="0.1" ReadOnly=@(MapIsActive) />
|
|
</div>
|
|
<div class="mb-2">
|
|
<MudNumericField @bind-Value="UpdateModel.ControlPoint2X" Label="Control Point 2 X" Variant="Variant.Outlined" Margin="Margin.Dense" Step="0.1" ReadOnly=@(MapIsActive) />
|
|
</div>
|
|
<div class="mb-2">
|
|
<MudSelect @bind-Value="UpdateModel.DirectionAllowed" Label="Direction Allowed" Variant="Variant.Outlined" AnchorOrigin="Origin.BottomLeft" Margin="Margin.Dense" Dense ReadOnly=@(MapIsActive)>
|
|
<MudSelectItem Value="@(DirectionAllowed.None)" />
|
|
<MudSelectItem Value="@(DirectionAllowed.Backward)" />
|
|
<MudSelectItem Value="@(DirectionAllowed.Forward)" />
|
|
<MudSelectItem Value="@(DirectionAllowed.Both)" />
|
|
</MudSelect>
|
|
</div>
|
|
<div class="mb-2">
|
|
<MudNumericField @bind-Value="UpdateModel.AllowedDeviationXy" Label="AllowedDeviationXy" Step="0.01" Min="0" Variant="Variant.Outlined" Margin="Margin.Dense" ReadOnly=@(MapIsActive) />
|
|
</div>
|
|
<div class="mb-2">
|
|
<MudNumericField @bind-Value="UpdateModel.AllowedDeviationTheta" Label="AllowedDeviationTheta" Step="1" Min="0" Max="180" Variant="Variant.Outlined" Margin="Margin.Dense" ReadOnly=@(MapIsActive) />
|
|
</div>
|
|
<div class="d-flex">
|
|
<MudCheckBox @bind-Value="UpdateModel.RotationAllowed" Label="Rotation Allowed" LabelPlacement="Placement.Start" ReadOnly=@(MapIsActive) UncheckedColor="Color.Default" Color="Color.Success" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="d-flex flex-column ms-2">
|
|
<div class="mb-2">
|
|
<MudNumericField @bind-Value="UpdateModel.ControlPoint1Y" Label="Control Point 1 Y" Variant="Variant.Outlined" Margin="Margin.Dense" Step="0.1" ReadOnly=@(MapIsActive) />
|
|
</div>
|
|
<div class="mb-2">
|
|
<MudNumericField @bind-Value="UpdateModel.ControlPoint2Y" Label="Control Point 2 Y" Variant="Variant.Outlined" Margin="Margin.Dense" Step="0.1" ReadOnly=@(MapIsActive) />
|
|
</div>
|
|
<div class="mb-2">
|
|
<MudNumericField @bind-Value="UpdateModel.MaxSpeed" Label="Max Speed" Variant="Variant.Outlined" Margin="Margin.Dense" Step="0.1" Min="0" ReadOnly=@(MapIsActive) />
|
|
</div>
|
|
<div class="mb-2">
|
|
<MudNumericField @bind-Value="UpdateModel.MaxRotationSpeed" Label="Max Rotation Speed" Variant="Variant.Outlined" Margin="Margin.Dense" Step="0.1" Min="0" ReadOnly=@(MapIsActive) />
|
|
</div>
|
|
<div class="mb-2">
|
|
<MudNumericField @bind-Value="UpdateModel.MaxHeight" Label="Max Height" Variant="Variant.Outlined" Margin="Margin.Dense" Step="0.1" Min="0" ReadOnly=@(MapIsActive) />
|
|
</div>
|
|
<div class="mb-2">
|
|
<MudNumericField @bind-Value="UpdateModel.MinHeight" Label="Min Height" Variant="Variant.Outlined" Margin="Margin.Dense" Step="0.1" Min="0" ReadOnly=@(MapIsActive) />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="d-flex flex-column ms-2 flex-grow-1">
|
|
<div class="d-flex flex-row mb-2">
|
|
<MudSelect @bind-Value=ActionSelected Margin="Margin.Dense" T="ActionDto" Label="Action" Variant="Variant.Outlined" Class="w-100" AnchorOrigin="Origin.BottomLeft">
|
|
@foreach (var action in Actions)
|
|
{
|
|
<MudSelectItem Value="@action">@action.Name</MudSelectItem>
|
|
}
|
|
</MudSelect>
|
|
<MudFab Class="ms-2" Color="Color.Secondary" StartIcon="@Icons.Material.Filled.Add" Size="Size.Medium" OnClick="AddAction" />
|
|
</div>
|
|
<div class="paper-action">
|
|
@foreach (var actionId in UpdateModel.Actions)
|
|
{
|
|
<div class="m-1" style="height: fit-content">
|
|
<MudButton Variant="Variant.Filled" Color="Color.Info" Style="text-transform:none" OnClick="(() => DeleteAction(actionId))">
|
|
@(Actions.FirstOrDefault(ac => ac.Id == actionId)?.Name)
|
|
</MudButton>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</DialogContent>
|
|
<DialogActions>
|
|
<MudButton OnClick="CancelUpdateEdge" Class="px-10" Variant="Variant.Filled">Cancel</MudButton>
|
|
<MudButton OnClick="UpdateEdge" Variant="Variant.Filled" Color="Color.Primary" Class="px-10" Disabled=@(MapIsActive || EditorState == EditorState.View)>Update</MudButton>
|
|
</DialogActions>
|
|
</MudDialog>
|
|
|
|
@code {
|
|
[Parameter, EditorRequired]
|
|
public MapEdgeModel Models { get; set; } = null!;
|
|
|
|
[CascadingParameter]
|
|
protected bool MapIsActive { get; set; }
|
|
|
|
[Parameter]
|
|
public EventCallback<EdgeModel?> EdgeSelectedChanged { get; set; }
|
|
|
|
[Parameter]
|
|
public EditorState EditorState { get; set; }
|
|
|
|
private EdgeUpdateModel UpdateModel = new();
|
|
private bool updateEdgeVisible;
|
|
private string ActionsText { get; set; } = "";
|
|
private double SelectModelLength;
|
|
|
|
private List<ActionDto> Actions = [];
|
|
private ActionDto? ActionSelected = null;
|
|
private HttpClient Http = default!;
|
|
|
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
|
{
|
|
await base.OnAfterRenderAsync(firstRender);
|
|
if (!firstRender) return;
|
|
|
|
Http = HttpClientFactory.CreateClient("MapManagerAPI");
|
|
Models.Changed += StateHasChanged;
|
|
Models.EdgeSelectedChanged += async (model) => await EdgeSelectedChanged.InvokeAsync(model);
|
|
}
|
|
|
|
private async Task LoadActionAsync(Guid mapVersionId)
|
|
{
|
|
var result = await Http.GetFromJsonAsync<IEnumerable<ActionDto>>($"api/Actions/{mapVersionId}");
|
|
|
|
if (result is not null && result.Any())
|
|
{
|
|
Actions.Clear();
|
|
Actions.AddRange(result);
|
|
}
|
|
if (Actions.Any()) ActionSelected = Actions.First();
|
|
|
|
StateHasChanged();
|
|
}
|
|
|
|
private void AddAction()
|
|
{
|
|
if (ActionSelected is null) return;
|
|
if (UpdateModel.Actions.Any(action => action == ActionSelected.Id))
|
|
{
|
|
Snackbar.Add("Action đã tồn tại", Severity.Warning);
|
|
return;
|
|
}
|
|
|
|
UpdateModel.Actions = [.. UpdateModel.Actions, ActionSelected.Id];
|
|
StateHasChanged();
|
|
}
|
|
|
|
private void DeleteAction(Guid actionId)
|
|
{
|
|
UpdateModel.Actions = UpdateModel.Actions.Where(a => actionId != a).ToArray();
|
|
StateHasChanged();
|
|
}
|
|
|
|
private async Task OnEdgeDoubleClick(EdgeModel model)
|
|
{
|
|
if (model == null || EditorState != EditorState.NavigationEdit) return;
|
|
|
|
await LoadActionAsync(model.MapId);
|
|
|
|
UpdateModel.Id = model.Id;
|
|
UpdateModel.ControlPoint1X = model.ControlPoint1X;
|
|
UpdateModel.ControlPoint1Y = model.ControlPoint1Y;
|
|
UpdateModel.ControlPoint2X = model.ControlPoint2X;
|
|
UpdateModel.ControlPoint2Y = model.ControlPoint2Y;
|
|
UpdateModel.DirectionAllowed = model.DirectionAllowed;
|
|
UpdateModel.MaxSpeed = model.MaxSpeed;
|
|
UpdateModel.MaxHeight = model.MaxHeight;
|
|
UpdateModel.MinHeight = model.MinHeight;
|
|
UpdateModel.RotationAllowed = model.RotationAllowed;
|
|
UpdateModel.MaxRotationSpeed = model.MaxRotationSpeed;
|
|
UpdateModel.AllowedDeviationXy = model.AllowedDeviationXy;
|
|
UpdateModel.AllowedDeviationTheta = model.AllowedDeviationTheta;
|
|
|
|
UpdateModel.Actions = [];
|
|
var actions = JsonSerializer.Deserialize<Guid[]>(model.Actions);
|
|
if (actions is not null && actions.Length > 0)
|
|
{
|
|
UpdateModel.Actions = [.. actions];
|
|
}
|
|
|
|
SelectModelLength = MapEditorHelper.GetEdgeLength(new()
|
|
{
|
|
TrajectoryDegree = model.TrajectoryDegree,
|
|
X1 = model.X1,
|
|
Y1 = model.Y1,
|
|
X2 = model.X2,
|
|
Y2 = model.Y2,
|
|
ControlPoint1X = model.ControlPoint1X,
|
|
ControlPoint1Y = model.ControlPoint1Y,
|
|
ControlPoint2X = model.ControlPoint2X,
|
|
ControlPoint2Y = model.ControlPoint2Y,
|
|
});
|
|
|
|
updateEdgeVisible = true;
|
|
StateHasChanged();
|
|
}
|
|
|
|
private void CancelUpdateEdge()
|
|
{
|
|
updateEdgeVisible = false;
|
|
StateHasChanged();
|
|
}
|
|
|
|
private async Task UpdateEdge()
|
|
{
|
|
var selectedModel = Models.FirstOrDefault(e => e.Id == UpdateModel.Id);
|
|
|
|
if (selectedModel == null)
|
|
{
|
|
updateEdgeVisible = false;
|
|
StateHasChanged();
|
|
return;
|
|
}
|
|
|
|
var result = await (await Http.PutAsJsonAsync($"api/Edges", UpdateModel)).Content.ReadFromJsonAsync<MessageResult>();
|
|
if (result is null)
|
|
{
|
|
Snackbar.Add("Lỗi giao tiếp với hệ thống", Severity.Error);
|
|
return;
|
|
}
|
|
else if (!result.IsSuccess)
|
|
{
|
|
Snackbar.Add(result.Message, Severity.Error);
|
|
return;
|
|
}
|
|
|
|
selectedModel.UpdateData(UpdateModel);
|
|
updateEdgeVisible = false;
|
|
Snackbar.Add("Cập nhật thành công", Severity.Success);
|
|
StateHasChanged();
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
Models.Changed -= StateHasChanged;
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
}
|