342 lines
17 KiB
Plaintext
342 lines
17 KiB
Plaintext
@using System.Net.Http.Headers
|
|
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
|
|
|
|
@inject ISnackbar Snackbar
|
|
@inject IHttpClientFactory HttpClientFactory
|
|
@inject IDialogService Dialog
|
|
|
|
<div class="d-flex w-100 h-100 flex-column">
|
|
<div class="d-flex flex-row justify-content-between w-100 mb-3">
|
|
<MudText Typo="Typo.h5" Class="d-flex align-items-center">Element Models</MudText>
|
|
<div class="d-flex flex-row pe-2">
|
|
<MudTooltip RootClass="d-flex align-items-center" Text="Create" Placement="Placement.Bottom" Color="Color.Primary" Arrow="true">
|
|
<MudIconButton Icon="@Icons.Material.Filled.Add" Variant="Variant.Text" Color="Color.Primary" Size="Size.Small" OnClick="OpenCreateModel"></MudIconButton>
|
|
</MudTooltip>
|
|
<MudTooltip RootClass="d-flex align-items-center" Text="Edit" Placement="Placement.Bottom" Color="Color.Info" Arrow="true">
|
|
<MudIconButton Icon="@Icons.Material.Filled.Edit" Size="Size.Small" Color="Color.Info" OnClick="OpenUpdateElementModel" />
|
|
</MudTooltip>
|
|
<MudTooltip RootClass="d-flex align-items-center" Text="Delete" Placement="Placement.Bottom" Color="Color.Secondary" Arrow="true">
|
|
<MudIconButton Icon="@Icons.Material.Filled.Delete" Size="Size.Small" Color="Color.Secondary" OnClick="DeleteElementModel" />
|
|
</MudTooltip>
|
|
</div>
|
|
</div>
|
|
<div class="d-flex w-100 flex-grow-1 overflow-x-hidden overflow-y-auto">
|
|
<MudTreeView Class="d-flex w-100 h-100 flex-column" T="ElementModelDto" Hover SelectedValueChanged="ModelSelectedChanged" SelectedValue="ElementModelSelected">
|
|
@foreach (var model in ElementModels)
|
|
{
|
|
<MudTreeViewItem Value="@model" CanExpand="false" Style="border-bottom: 0.5px solid rgba(217, 217, 217, 0.5); "
|
|
Text="@model.Name" EndText="@($"{model.Width}x{model.Height}")" EndTextTypo="Typo.caption" />
|
|
}
|
|
</MudTreeView>
|
|
</div>
|
|
</div>
|
|
|
|
<MudDialog @bind-Visible="@CreateModelIsVisible" DefaultFocus="DefaultFocus.FirstChild">
|
|
<TitleContent>
|
|
<MudText Typo="Typo.h5">Create Element Model</MudText>
|
|
</TitleContent>
|
|
<DialogContent>
|
|
<div class="d-flex flex-column" style="max-height: 700px; overflow-y: auto">
|
|
<MudTextField Class="my-2"
|
|
@bind-Value="ElementModelCreateModel.Name" T="string"
|
|
Label="Name" Required="true" RequiredError="Name is required!"
|
|
Counter="18" Variant="Variant.Outlined"
|
|
Validation="@(new Func<string, IEnumerable<string>>(MapEditorHelper.NameValidation))" />
|
|
<div class="d-flex flex-row">
|
|
<MudNumericField Class="me-2" @bind-Value="ElementModelCreateModel.Width" Label="Width" Step="0.1" Min="0" Variant="Variant.Outlined" />
|
|
<MudNumericField Class="ms-2" @bind-Value="ElementModelCreateModel.Height" Label="Height" Step="0.1" Min="0" Variant="Variant.Outlined" />
|
|
</div>
|
|
<div class="d-flex flex-row justify-content-around">
|
|
<div class="d-flex flex-column me-2">
|
|
<div class="d-flex flex-row align-items-center justify-content-center">
|
|
<InputFile id="fileElementModelImage1Create" OnChange="ElementModelCreateImage1Changed" accept=".png" hidden />
|
|
<MudText>Open</MudText>
|
|
<MudIconButton Variant="Variant.Text" Color="Color.Primary" Icon="@Icons.Material.Filled.CloudUpload" for="fileElementModelImage1Create" HtmlTag="label" />
|
|
</div>
|
|
<div class="d-flex">
|
|
<div class="model-create-item">
|
|
<img alt="Element Model Image Open" src="@ProjectionImageFilePreview1" style="image-rendering: pixelated;" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="d-flex flex-column">
|
|
<div class="d-flex flex-row align-items-center justify-content-center">
|
|
<InputFile id="fileElementModelImage2Create" OnChange="ElementModelCreateImage2Changed" accept=".png" hidden />
|
|
<MudText>Close</MudText>
|
|
<MudIconButton Variant="Variant.Text" Color="Color.Primary" Icon="@Icons.Material.Filled.CloudUpload" for="fileElementModelImage2Create" HtmlTag="label" />
|
|
</div>
|
|
<div class="d-flex">
|
|
<div class="model-create-item">
|
|
<img alt=" Element Model Image Close" src="@ProjectionImageFilePreview2" style="image-rendering: pixelated;" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</DialogContent>
|
|
<DialogActions>
|
|
<MudButton Color="Color.Default" Variant="Variant.Filled" OnClick="(() => CreateModelIsVisible = false)">Cancel</MudButton>
|
|
<MudButton Color="Color.Primary" Variant="Variant.Filled" OnClick="CreateElementModel" Disabled="string.IsNullOrEmpty(ElementModelCreateModel.Name)">Create</MudButton>
|
|
</DialogActions>
|
|
</MudDialog>
|
|
|
|
<MudDialog @bind-Visible="@UpdateElementModelVisible" DefaultFocus="DefaultFocus.FirstChild">
|
|
<TitleContent>
|
|
<MudText Typo="Typo.h5">Update Element Model</MudText>
|
|
</TitleContent>
|
|
<DialogContent>
|
|
<div class="d-flex flex-column" style="max-height: 700px; overflow-y: auto">
|
|
<MudTextField Class="my-2"
|
|
@bind-Value="ElementModelUpdateModel.Name" T="string"
|
|
Label="Name" Required="true" RequiredError="Name is required!"
|
|
Counter="18" Variant="Variant.Outlined"
|
|
Validation="@(new Func<string, IEnumerable<string>>(MapEditorHelper.NameValidation))" />
|
|
<div class="d-flex flex-row">
|
|
<MudNumericField Class="me-2" @bind-Value="ElementModelUpdateModel.Width" Label="Width" Step="0.1" Variant="Variant.Outlined" />
|
|
<MudNumericField Class="ms-2" @bind-Value="ElementModelUpdateModel.Height" Label="Height" Step="0.1" Variant="Variant.Outlined" />
|
|
</div>
|
|
</div>
|
|
</DialogContent>
|
|
<DialogActions>
|
|
<MudButton Color="Color.Default" Variant="Variant.Filled" OnClick="(() => UpdateElementModelVisible = false)">Cancel</MudButton>
|
|
<MudButton Color="Color.Primary" Variant="Variant.Filled" OnClick="UpdateElementModel" Disabled="string.IsNullOrEmpty(ElementModelUpdateModel.Name)">Update</MudButton>
|
|
</DialogActions>
|
|
</MudDialog>
|
|
|
|
|
|
@code {
|
|
[Parameter]
|
|
public List<ElementModelDto> ElementModels { get; set; } = [];
|
|
|
|
[Parameter]
|
|
public MapInfoDto MapInfo { get; set; } = new();
|
|
|
|
[Parameter]
|
|
public EventCallback<ElementModelDto?> ElementModelSelectChanged { get; set; }
|
|
|
|
private string? txtSearch { get; set; }
|
|
|
|
private bool CreateModelIsVisible;
|
|
private ElementModelCreateModel ElementModelCreateModel = new();
|
|
private IBrowserFile? ElementModelCreateImage1 { get; set; }
|
|
private string? ProjectionImageFilePreview1 { get; set; }
|
|
private IBrowserFile? ElementModelCreateImage2 { get; set; }
|
|
private string? ProjectionImageFilePreview2 { get; set; }
|
|
|
|
private ElementModelDto? ElementModelSelected = null;
|
|
|
|
private bool UpdateElementModelVisible;
|
|
private ElementModelUpdateModel ElementModelUpdateModel = new();
|
|
|
|
private HttpClient Http = default!;
|
|
|
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
|
{
|
|
await base.OnAfterRenderAsync(firstRender);
|
|
if (!firstRender) return;
|
|
|
|
Http = HttpClientFactory.CreateClient("MapManagerAPI");
|
|
}
|
|
|
|
private async Task DeleteElementModel()
|
|
{
|
|
if (ElementModelSelected is null) return;
|
|
|
|
var parameters = new DialogParameters<ConfirmDialog>
|
|
{
|
|
{ x => x.Content, $"Tất cả các Element thuộc model này cũng sẽ bị xóa! Bạn có chắc chắn muốn xóa element model {ElementModelSelected.Name} đi không?" },
|
|
{ x => x.ConfirmText, "Delete" },
|
|
{ x => x.Color, Color.Secondary }
|
|
};
|
|
var ConfirmDelete = await Dialog.ShowAsync<ConfirmDialog>("Xoá Element Model", parameters);
|
|
var result = await ConfirmDelete.Result;
|
|
if (result is not null && result.Data is not null && bool.TryParse(result.Data.ToString(), out bool data) && data)
|
|
{
|
|
var response = await Http.DeleteFromJsonAsync<MessageResult>($"api/ElementModels/{ElementModelSelected.Id}");
|
|
if (response is null) Snackbar.Add("Lỗi giao tiếp với hệ thống", Severity.Error);
|
|
else if (!response.IsSuccess) Snackbar.Add(response.Message ?? "Lỗi chưa xác định.", Severity.Error);
|
|
else
|
|
{
|
|
var elementmodel = ElementModels.FirstOrDefault(m => m.Id == ElementModelSelected.Id);
|
|
if (elementmodel is not null)
|
|
{
|
|
ElementModels.Remove(elementmodel);
|
|
await ElementModelSelectChanged.InvokeAsync(null);
|
|
ElementModelSelected = null;
|
|
Snackbar.Add($"Xóa element model thành công.", Severity.Success);
|
|
}
|
|
else Snackbar.Add($"Element Model không tồn tại.", Severity.Warning);
|
|
}
|
|
StateHasChanged();
|
|
}
|
|
}
|
|
|
|
private void OpenCreateModel()
|
|
{
|
|
ElementModelCreateModel.Name = "";
|
|
ElementModelCreateModel.MapId = MapInfo.Id;
|
|
ProjectionImageFilePreview1 = "/images/Image-not-found.png";
|
|
ProjectionImageFilePreview2 = "/images/Image-not-found.png";
|
|
ElementModelCreateImage1 = null;
|
|
ElementModelCreateImage2 = null;
|
|
|
|
CreateModelIsVisible = true;
|
|
StateHasChanged();
|
|
}
|
|
|
|
private async Task CreateElementModel()
|
|
{
|
|
try
|
|
{
|
|
if (ElementModelCreateImage1 is null || string.IsNullOrEmpty(ProjectionImageFilePreview1))
|
|
{
|
|
Snackbar.Add("Ảnh model chưa được chọn.", Severity.Warning);
|
|
return;
|
|
}
|
|
if (ElementModelCreateImage2 is null || string.IsNullOrEmpty(ProjectionImageFilePreview2))
|
|
{
|
|
Snackbar.Add("Ảnh model chưa được chọn.", Severity.Warning);
|
|
return;
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(ElementModelCreateModel.Name))
|
|
{
|
|
Snackbar.Add("Name không được để trống.", Severity.Warning);
|
|
return;
|
|
}
|
|
|
|
var nameInvalid = MapEditorHelper.NameChecking(ElementModelCreateModel.Name);
|
|
if (!nameInvalid.IsSuccess)
|
|
{
|
|
Snackbar.Add(nameInvalid.returnStr, Severity.Warning);
|
|
return;
|
|
}
|
|
|
|
using var content = new MultipartFormDataContent
|
|
{
|
|
{ new StringContent(ElementModelCreateModel.MapId.ToString()), nameof(ElementModelCreateModel.MapId) },
|
|
{ new StringContent(ElementModelCreateModel.Name ?? String.Empty), nameof(ElementModelCreateModel.Name) },
|
|
{ new StringContent(ElementModelCreateModel.Width.ToString()), nameof(ElementModelCreateModel.Width) },
|
|
{ new StringContent(ElementModelCreateModel.Height.ToString()), nameof(ElementModelCreateModel.Height) },
|
|
};
|
|
|
|
var fileContent1 = new StreamContent(ElementModelCreateImage1.OpenReadStream());
|
|
fileContent1.Headers.ContentType = new MediaTypeHeaderValue(ElementModelCreateImage1.ContentType);
|
|
content.Add(fileContent1, "imageOpen", ElementModelCreateImage1.Name);
|
|
|
|
var fileContent2 = new StreamContent(ElementModelCreateImage2.OpenReadStream());
|
|
fileContent2.Headers.ContentType = new MediaTypeHeaderValue(ElementModelCreateImage2.ContentType);
|
|
content.Add(fileContent2, "imageClose", ElementModelCreateImage2.Name);
|
|
|
|
var response = await (await Http.PostAsync("api/ElementModels", content)).Content.ReadFromJsonAsync<MessageResult<ElementModelDto>>();
|
|
if (response is null) Snackbar.Add("Lỗi giao tiếp với hệ thống", Severity.Error);
|
|
else if (!response.IsSuccess) Snackbar.Add(response.Message ?? "Lỗi chưa xác định.", Severity.Error);
|
|
else if (response.Data is null) Snackbar.Add("Hệ thống không thể tạo Element model này", Severity.Error);
|
|
else
|
|
{
|
|
ElementModels.Add(response.Data);
|
|
Snackbar.Add($"Tạo Element model {response.Data.Name} thành công.", Severity.Success);
|
|
}
|
|
|
|
CreateModelIsVisible = false;
|
|
StateHasChanged();
|
|
}
|
|
catch (AccessTokenNotAvailableException ex)
|
|
{
|
|
ex.Redirect();
|
|
return;
|
|
}
|
|
}
|
|
|
|
private async Task ElementModelCreateImage1Changed(InputFileChangeEventArgs e)
|
|
{
|
|
ElementModelCreateImage1 = e.File;
|
|
if (ElementModelCreateImage1 is not null)
|
|
{
|
|
var buffers = new byte[ElementModelCreateImage1.Size];
|
|
var path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
|
await using var fs = new FileStream(path, FileMode.Create);
|
|
await ElementModelCreateImage1.OpenReadStream(ElementModelCreateImage1.Size).CopyToAsync(fs);
|
|
fs.Position = 0;
|
|
await fs.ReadAsync(buffers);
|
|
fs.Close();
|
|
File.Delete(path);
|
|
|
|
ProjectionImageFilePreview1 = $"data:{ElementModelCreateImage1.ContentType};base64,{Convert.ToBase64String(buffers)}";
|
|
StateHasChanged();
|
|
}
|
|
}
|
|
|
|
private async Task ElementModelCreateImage2Changed(InputFileChangeEventArgs e)
|
|
{
|
|
ElementModelCreateImage2 = e.File;
|
|
if (ElementModelCreateImage2 is not null)
|
|
{
|
|
var buffers = new byte[ElementModelCreateImage2.Size];
|
|
var path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
|
await using var fs = new FileStream(path, FileMode.Create);
|
|
await ElementModelCreateImage2.OpenReadStream(ElementModelCreateImage2.Size).CopyToAsync(fs);
|
|
fs.Position = 0;
|
|
await fs.ReadAsync(buffers);
|
|
fs.Close();
|
|
File.Delete(path);
|
|
|
|
ProjectionImageFilePreview2 = $"data:{ElementModelCreateImage2.ContentType};base64,{Convert.ToBase64String(buffers)}";
|
|
StateHasChanged();
|
|
}
|
|
}
|
|
|
|
private async Task ModelSelectedChanged(ElementModelDto model)
|
|
{
|
|
ElementModelSelected = model;
|
|
var elModel = await Http.GetFromJsonAsync<MessageResult<ElementModelDto>>($"api/ElementModels/{ElementModelSelected.Id}");
|
|
if (elModel is null) Snackbar.Add("Lỗi giao tiếp với hệ thống", Severity.Error);
|
|
else if (!elModel.IsSuccess) Snackbar.Add($"Có lỗi xảy ra: {elModel.Message}", Severity.Error);
|
|
else await ElementModelSelectChanged.InvokeAsync(elModel.Data);
|
|
}
|
|
|
|
private void OpenUpdateElementModel()
|
|
{
|
|
if (ElementModelSelected is null) return;
|
|
ElementModelUpdateModel.Id = ElementModelSelected.Id;
|
|
ElementModelUpdateModel.Name = ElementModelSelected.Name;
|
|
ElementModelUpdateModel.Width = ElementModelSelected.Width;
|
|
ElementModelUpdateModel.Height = ElementModelSelected.Height;
|
|
ElementModelUpdateModel.MapId = ElementModelSelected.MapId;
|
|
ElementModelUpdateModel.Content = ElementModelSelected.Content;
|
|
|
|
UpdateElementModelVisible = true;
|
|
StateHasChanged();
|
|
}
|
|
|
|
private async Task UpdateElementModel()
|
|
{
|
|
var result = await (await Http.PutAsJsonAsync($"api/ElementModels", new ElementModelUpdateModel()
|
|
{
|
|
Id = ElementModelUpdateModel.Id,
|
|
Name = ElementModelUpdateModel.Name,
|
|
Width = ElementModelUpdateModel.Width,
|
|
Height = ElementModelUpdateModel.Height,
|
|
MapId = ElementModelUpdateModel.MapId,
|
|
Content = ElementModelUpdateModel.Content,
|
|
})).Content.ReadFromJsonAsync<MessageResult<ElementModelDto>>();
|
|
if (result == null) Snackbar.Add("Lỗi giao tiếp với hệ thống", Severity.Error);
|
|
else if (!result.IsSuccess) Snackbar.Add(result.Message, Severity.Error);
|
|
else if (result.Data is null) Snackbar.Add("Lỗi dữ liệu", Severity.Error);
|
|
else
|
|
{
|
|
var elementModel = ElementModels.FirstOrDefault(m => m.Id == result.Data.Id);
|
|
if (elementModel is not null)
|
|
{
|
|
elementModel.Name = result.Data.Name;
|
|
elementModel.Width = result.Data.Width;
|
|
elementModel.Height = result.Data.Height;
|
|
}
|
|
Snackbar.Add("Cập nhật thành công", Severity.Success);
|
|
}
|
|
|
|
UpdateElementModelVisible = false;
|
|
StateHasChanged();
|
|
}
|
|
}
|