586 lines
25 KiB
Plaintext
586 lines
25 KiB
Plaintext
@page "/navigation-maps"
|
|
@attribute [Authorize]
|
|
|
|
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
|
|
@using RobotNet.MapShares
|
|
@using RobotNet.MapShares.Dtos
|
|
@using System.Net.Http.Headers
|
|
@using RobotNet.Shares
|
|
@using RobotNet.WebApp.Maps.Components
|
|
|
|
@inject NavigationManager NavManager
|
|
@inject IHttpClientFactory HttpClientFactory
|
|
@inject IJSRuntime JSRuntime
|
|
@inject ISnackbar Snackbar
|
|
@inject IDialogService Dialog
|
|
|
|
<PageTitle>Map Manager</PageTitle>
|
|
|
|
<style>
|
|
.selected {
|
|
background-color: #3399ff !important;
|
|
}
|
|
|
|
.selected > td {
|
|
color: white !important;
|
|
}
|
|
|
|
.selected > td .mud-input {
|
|
color: white !important;
|
|
}
|
|
</style>
|
|
|
|
<div class="d-flex flex-row w-100 h-100 p-2 overflow-hidden">
|
|
<div class="d-flex h-100 flex-column flex-grow-1 pe-2">
|
|
<div class="d-flex justify-content-between align-items-center mb-2">
|
|
<MudTextField Value="txtSearch" T="string" Label="Search" Variant="Variant.Outlined" Adornment="Adornment.End" AdornmentIcon="@Icons.Material.Filled.Search"
|
|
AdornmentColor="Color.Secondary" ValueChanged="TextSearchChanged" Style="max-width: 550px" />
|
|
<MudButton StartIcon="@Icons.Material.Filled.FileUpload" HtmlTag="label" Variant="Variant.Filled" Color="Color.Primary" Size="Size.Large" for="WorkspaceAreaMapImport">
|
|
IMPORT
|
|
</MudButton>
|
|
<MudButton Class="ms-3" StartIcon="@Icons.Material.Filled.Add" Variant="Variant.Filled" Color="Color.Primary" Size="Size.Large" OnClick="OpenCreateMap">
|
|
NEW
|
|
</MudButton>
|
|
<InputFile id="WorkspaceAreaMapImport" OnChange="OnMapImportChanged" accept=".map" hidden />
|
|
</div>
|
|
<div class="d-flex" style="height: 92%">
|
|
<MudTable Class="w-100" @ref="Table" Items="@MapsShow" T="MapInfoDto" Dense=true Hover=true ReadOnly=true FixedHeader=true RowClass="cursor-pointer" Striped="true"
|
|
ServerData="ReloadData" Loading=@IsLoading Outlined="true" RowClassFunc="@SelectedRowClassFunc" OnRowClick="RowClickEvent" Height="95%">
|
|
<HeaderContent>
|
|
<MudTh>Nr</MudTh>
|
|
<MudTh>Name</MudTh>
|
|
<MudTh>Width (m)</MudTh>
|
|
<MudTh>Height (m)</MudTh>
|
|
<MudTh>Resolution (m/px)</MudTh>
|
|
<MudTh>OriginX</MudTh>
|
|
<MudTh>OriginY</MudTh>
|
|
<MudTh></MudTh>
|
|
</HeaderContent>
|
|
<RowTemplate>
|
|
<MudTd DataLabel="Nr">
|
|
@(Table?.CurrentPage * Table?.RowsPerPage + MapsShow.IndexOf(context) + 1)
|
|
</MudTd>
|
|
<MudTd DataLabel="Name">
|
|
@context.Name
|
|
</MudTd>
|
|
<MudTd DataLabel="Width">
|
|
@context.Width
|
|
</MudTd>
|
|
<MudTd DataLabel="Height">
|
|
@context.Height
|
|
</MudTd>
|
|
<MudTd DataLabel="Resolution">
|
|
@context.Resolution
|
|
</MudTd>
|
|
<MudTd DataLabel="OriginX">
|
|
@context.OriginX
|
|
</MudTd>
|
|
<MudTd DataLabel="OriginY">
|
|
@context.OriginY
|
|
</MudTd>
|
|
<MudTd>
|
|
<div class="d-flex flex-row-reverse">
|
|
<MudMenu Icon="@Icons.Material.Filled.MoreVert" AnchorOrigin="Origin.BottomCenter">
|
|
<MudMenuItem OnClick="(() => OpenUpdateMap(context))" Icon="@Icons.Material.Filled.Edit" IconColor="Color.Info">Edit</MudMenuItem>
|
|
<MudMenuItem OnClick="(() => DeleteMap(context.Id))" Icon="@Icons.Material.Filled.Delete" IconColor="Color.Error">Delete</MudMenuItem>
|
|
</MudMenu>
|
|
<MudButton Class="my-2" IconColor="Color.Success" StartIcon="@(context.Active ? @Icons.Material.Outlined.Check : "")" Color="@(context.Active ? Color.Success : Color.Default)" Variant="Variant.Outlined" Size="Size.Small" OnClick="@(async() => await MapActiveToggle(context.Id, !context.Active))">Active</MudButton>
|
|
</div>
|
|
</MudTd>
|
|
</RowTemplate>
|
|
<PagerContent>
|
|
<div class="d-flex w-100 flex-row-reverse">
|
|
<MudTablePager Style="width: 100%;" PageSizeOptions="new[] {25 , 100, 200}" />
|
|
</div>
|
|
</PagerContent>
|
|
</MudTable>
|
|
</div>
|
|
</div>
|
|
<div class="map-preview">
|
|
<NavigationMapPreview @ref="@NavigationMapPreviewRef" MapImageChangedCallBack="MapImageChangedCallBack" />
|
|
</div>
|
|
</div>
|
|
|
|
<MudDialog @bind-Visible="IsCreateMapVisible">
|
|
<TitleContent>
|
|
<MudText Typo="Typo.h6">
|
|
Create New Map
|
|
</MudText>
|
|
</TitleContent>
|
|
<DialogContent>
|
|
<MudContainer Class="d-flex flex-column" Style="max-height: 700px; overflow-y: auto">
|
|
<MudTextField Class="my-2"
|
|
@bind-Value="MapCreateModel.Name" T="string"
|
|
Label="Map's name" Required="true"
|
|
RequiredError="Map name is required!" Counter="18" Variant="Variant.Outlined"
|
|
Validation="@(new Func<string, IEnumerable<string>>(MapEditorHelper.NameValidation))" />
|
|
<div class="d-flex flex-row my-2">
|
|
<MudNumericField Class="me-2" @bind-Value="MapCreateModel.OriginX" Label="Origin X" Step="0.1" Variant="Variant.Outlined" />
|
|
<MudNumericField Class="ms-2" @bind-Value="MapCreateModel.OriginY" Label="Origin Y" Step="0.1" Variant="Variant.Outlined" />
|
|
</div>
|
|
<MudNumericField Class="my-2" @bind-Value="MapCreateModel.Resolution" Label="Resolution" Step="0.1" Variant="Variant.Outlined" Min="0" />
|
|
<div class="d-flex flex-column">
|
|
<div class="d-flex flex-row my-2">
|
|
<InputFile id="fileMapImageCreate" OnChange="MapCreateImageChanged" accept=".png" hidden />
|
|
<MudButton HtmlTag="label"
|
|
Variant="Variant.Filled"
|
|
Color="Color.Primary"
|
|
StartIcon="@Icons.Material.Filled.CloudUpload"
|
|
for="fileMapImageCreate">
|
|
Map Image
|
|
</MudButton>
|
|
</div>
|
|
<div class="d-flex mb-2">
|
|
<div class="map-create-item">
|
|
<img alt="Map Image" src="@ProjectionImageFilePreview" style="image-rendering: pixelated;" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</MudContainer>
|
|
</DialogContent>
|
|
<DialogActions>
|
|
<MudButton OnClick="@(() => IsCreateMapVisible = false)" Variant="Variant.Filled">Cancel</MudButton>
|
|
<MudButton Color="Color.Primary" OnClick="CreateNewMap" Variant="Variant.Filled">Create</MudButton>
|
|
</DialogActions>
|
|
</MudDialog>
|
|
|
|
<MudDialog @bind-Visible="IsUpdateMapVisible">
|
|
<TitleContent>
|
|
<MudText Typo="Typo.h6">
|
|
Update Map
|
|
</MudText>
|
|
</TitleContent>
|
|
<DialogContent>
|
|
<MudContainer Class="d-flex flex-column" Style="max-height: 700px;">
|
|
<MudTextField Class="my-2"
|
|
@bind-Value="MapUpdateModel.Name" T="string"
|
|
Label="Map's name" Required="true"
|
|
RequiredError="Map name is required!" Counter="127" Variant="Variant.Outlined"
|
|
Validation="@(new Func<string, IEnumerable<string>>(MapEditorHelper.NameValidation))" />
|
|
<div class="d-flex flex-row my-2">
|
|
<MudNumericField Class="me-2" @bind-Value="MapUpdateModel.OriginX" Label="Origin X" Step="0.1" Variant="Variant.Outlined" />
|
|
<MudNumericField Class="ms-2" @bind-Value="MapUpdateModel.OriginY" Label="Origin Y" Step="0.1" Variant="Variant.Outlined" />
|
|
</div>
|
|
<MudNumericField Class="my-2" @bind-Value="MapUpdateModel.Resolution" Label="Resolution" Step="0.1" Variant="Variant.Outlined" Min="0" />
|
|
</MudContainer>
|
|
</DialogContent>
|
|
<DialogActions>
|
|
<MudButton OnClick="@(() => IsUpdateMapVisible = false)" Variant="Variant.Filled">Cancel</MudButton>
|
|
<MudButton Color="Color.Primary" OnClick="UpdateMap" Variant="Variant.Filled">Update</MudButton>
|
|
</DialogActions>
|
|
</MudDialog>
|
|
|
|
<MudDialog @bind-Visible="IsImportMapVisible">
|
|
<TitleContent>
|
|
<MudText Typo="Typo.h6">
|
|
Import New Map
|
|
</MudText>
|
|
</TitleContent>
|
|
<DialogContent>
|
|
<MudContainer Class="d-flex flex-column" Style="max-height: 700px; overflow-y: auto">
|
|
<MudTextField Class="my-2"
|
|
@bind-Value="MapImport.Name" T="string"
|
|
Label="Map's name" Required="true"
|
|
RequiredError="Map name is required!" Counter="127" Variant="Variant.Outlined"
|
|
Validation="@(new Func<string, IEnumerable<string>>(MapEditorHelper.NameValidation))" />
|
|
<div class="d-flex flex-row my-2">
|
|
<MudNumericField Class="me-2" @bind-Value="MapImport.Info.OriginX" Label="Origin X" Step="0.1" Variant="Variant.Outlined" ReadOnly />
|
|
<MudNumericField Class="ms-2" @bind-Value="MapImport.Info.OriginY" Label="Origin Y" Step="0.1" Variant="Variant.Outlined" ReadOnly />
|
|
</div>
|
|
<MudNumericField Class="my-2" @bind-Value="MapImport.Info.Resolution" Label="Resolution" Step="0.1" Variant="Variant.Outlined" Min="0" />
|
|
<div class="d-flex mb-2">
|
|
<div class="map-create-item">
|
|
<img alt="Map Image" src="@ProjectionImportImageFilePreview" style="image-rendering: pixelated;" />
|
|
</div>
|
|
</div>
|
|
</MudContainer>
|
|
</DialogContent>
|
|
<DialogActions>
|
|
<MudButton OnClick="@(() => IsImportMapVisible = false)" Variant="Variant.Filled">Cancel</MudButton>
|
|
<MudButton Color="Color.Primary" OnClick="ImportNewMap" Variant="Variant.Filled">Create</MudButton>
|
|
</DialogActions>
|
|
</MudDialog>
|
|
|
|
@code {
|
|
private string txtSearch = "";
|
|
private bool IsLoading = false;
|
|
|
|
private List<MapInfoDto> Maps = [];
|
|
private List<MapInfoDto> MapsShow = [];
|
|
private MudTable<MapInfoDto>? Table;
|
|
|
|
private int selectedRowNumber = -1;
|
|
private MapInfoDto MapSelected = new();
|
|
|
|
private bool IsCreateMapVisible { get; set; }
|
|
private readonly MapCreateModel MapCreateModel = new();
|
|
private IBrowserFile? MapCreateImage { get; set; }
|
|
private string? ProjectionImageFilePreview { get; set; }
|
|
|
|
private bool IsUpdateMapVisible { get; set; }
|
|
private readonly MapUpdateModel MapUpdateModel = new();
|
|
|
|
private NavigationMapPreview NavigationMapPreviewRef = default!;
|
|
|
|
private MapExportDto MapImport = default!;
|
|
private bool IsImportMapVisible { get; set; }
|
|
private string? ProjectionImportImageFilePreview { get; set; }
|
|
private HttpClient Http = default!;
|
|
|
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
|
{
|
|
await base.OnAfterRenderAsync(firstRender);
|
|
if (!firstRender) return;
|
|
|
|
Http = HttpClientFactory.CreateClient("MapManagerAPI");
|
|
await LoadMaps();
|
|
}
|
|
|
|
private async Task LoadMaps()
|
|
{
|
|
try
|
|
{
|
|
IsLoading = true;
|
|
Maps.Clear();
|
|
StateHasChanged();
|
|
|
|
var maps = await Http.GetFromJsonAsync<IEnumerable<MapInfoDto>>($"api/MapsManager?txtSearch={txtSearch}");
|
|
Maps.AddRange(maps ?? []);
|
|
|
|
Table?.ReloadServerData();
|
|
IsLoading = false;
|
|
StateHasChanged();
|
|
}
|
|
catch
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
private void TextSearchChanged(string text)
|
|
{
|
|
txtSearch = text;
|
|
Table?.ReloadServerData();
|
|
}
|
|
|
|
private bool FilterFunc(MapInfoDto map)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(txtSearch))
|
|
return true;
|
|
if (map.Name is not null && map.Name.Contains(txtSearch, StringComparison.OrdinalIgnoreCase))
|
|
return true;
|
|
if ($"{map.Name}".Contains(txtSearch))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
private Task<TableData<MapInfoDto>> ReloadData(TableState state, CancellationToken _)
|
|
{
|
|
MapsShow.Clear();
|
|
var tasks = new List<MapInfoDto>();
|
|
Maps.ForEach(task =>
|
|
{
|
|
if (FilterFunc(task)) tasks.Add(task);
|
|
});
|
|
MapsShow = tasks.Skip(state.Page * state.PageSize).Take(state.PageSize).ToList();
|
|
return Task.FromResult(new TableData<MapInfoDto>() { TotalItems = tasks.Count, Items = MapsShow });
|
|
}
|
|
|
|
private void RowClickEvent(TableRowClickEventArgs<MapInfoDto> tableRowClickEventArgs) { }
|
|
|
|
private string SelectedRowClassFunc(MapInfoDto element, int rowNumber)
|
|
{
|
|
if (selectedRowNumber == rowNumber && Table?.SelectedItem != null && !Table.SelectedItem.Equals(element))
|
|
{
|
|
return string.Empty;
|
|
}
|
|
else if (selectedRowNumber == rowNumber && Table?.SelectedItem != null && Table.SelectedItem.Equals(element))
|
|
{
|
|
return "selected";
|
|
}
|
|
else if (Table?.SelectedItem != null && Table.SelectedItem.Equals(element))
|
|
{
|
|
selectedRowNumber = rowNumber;
|
|
MapSelected = element;
|
|
NavigationMapPreviewRef.SetMapPreview(MapSelected);
|
|
return "selected";
|
|
}
|
|
else
|
|
{
|
|
return string.Empty;
|
|
}
|
|
}
|
|
|
|
private void OpenCreateMap()
|
|
{
|
|
MapCreateModel.Name = string.Empty;
|
|
MapCreateModel.OriginX = 0;
|
|
MapCreateModel.OriginY = 0;
|
|
MapCreateModel.Resolution = 0.1;
|
|
ProjectionImageFilePreview = "/images/Image-not-found.png";
|
|
MapCreateImage = null;
|
|
IsCreateMapVisible = true;
|
|
StateHasChanged();
|
|
}
|
|
|
|
private async Task MapCreateImageChanged(InputFileChangeEventArgs e)
|
|
{
|
|
MapCreateImage = e.File;
|
|
if (MapCreateImage is not null)
|
|
{
|
|
var buffers = new byte[MapCreateImage.Size];
|
|
var path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
|
await using var fs = new FileStream(path, FileMode.Create);
|
|
await MapCreateImage.OpenReadStream(MapCreateImage.Size).CopyToAsync(fs);
|
|
fs.Position = 0;
|
|
await fs.ReadAsync(buffers);
|
|
fs.Close();
|
|
File.Delete(path);
|
|
|
|
ProjectionImageFilePreview = $"data:{MapCreateImage.ContentType};base64,{Convert.ToBase64String(buffers)}";
|
|
StateHasChanged();
|
|
}
|
|
}
|
|
|
|
private async Task CreateNewMap()
|
|
{
|
|
try
|
|
{
|
|
if (MapCreateImage is null || string.IsNullOrEmpty(ProjectionImageFilePreview))
|
|
{
|
|
Snackbar.Add("Ảnh map chưa được chọn.", Severity.Warning);
|
|
return;
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(MapCreateModel.Name))
|
|
{
|
|
Snackbar.Add("Map's name không được để trống.", Severity.Warning);
|
|
return;
|
|
}
|
|
|
|
var nameInvalid = MapEditorHelper.NameChecking(MapCreateModel.Name);
|
|
if (!nameInvalid.IsSuccess)
|
|
{
|
|
Snackbar.Add(nameInvalid.returnStr, Severity.Warning);
|
|
return;
|
|
}
|
|
|
|
using var content = new MultipartFormDataContent
|
|
{
|
|
{ new StringContent(MapCreateModel.Name ?? String.Empty), nameof(MapCreateModel.Name) },
|
|
{ new StringContent(MapCreateModel.OriginX.ToString()), nameof(MapCreateModel.OriginX) },
|
|
{ new StringContent(MapCreateModel.OriginY.ToString()), nameof(MapCreateModel.OriginY) },
|
|
{ new StringContent(MapCreateModel.Resolution.ToString()), nameof(MapCreateModel.Resolution) },
|
|
};
|
|
|
|
var fileContent = new StreamContent(MapCreateImage.OpenReadStream(maxAllowedSize: 20480000));
|
|
fileContent.Headers.ContentType = new MediaTypeHeaderValue(MapCreateImage.ContentType);
|
|
content.Add(fileContent, "Image", MapCreateImage.Name);
|
|
|
|
var response = await (await Http.PostAsync("api/MapsManager", content)).Content.ReadFromJsonAsync<MessageResult<MapInfoDto>>();
|
|
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 bản đồ này", Severity.Error);
|
|
else
|
|
{
|
|
Maps.Add(response.Data);
|
|
Table?.ReloadServerData();
|
|
Snackbar.Add($"Tạo map {MapCreateModel.Name} thành công.", Severity.Success);
|
|
}
|
|
|
|
IsCreateMapVisible = false;
|
|
StateHasChanged();
|
|
}
|
|
catch (AccessTokenNotAvailableException ex)
|
|
{
|
|
ex.Redirect();
|
|
return;
|
|
}
|
|
}
|
|
|
|
private void OpenUpdateMap(MapInfoDto map)
|
|
{
|
|
MapUpdateModel.Id = map.Id;
|
|
MapUpdateModel.Name = map.Name;
|
|
MapUpdateModel.OriginX = map.OriginX;
|
|
MapUpdateModel.OriginY = map.OriginY;
|
|
MapUpdateModel.Resolution = map.Resolution;
|
|
IsUpdateMapVisible = true;
|
|
StateHasChanged();
|
|
}
|
|
|
|
private async Task UpdateMap()
|
|
{
|
|
var nameErrors = MapEditorHelper.NameChecking(MapUpdateModel.Name);
|
|
if (!nameErrors.IsSuccess)
|
|
{
|
|
Snackbar.Add(nameErrors.returnStr, Severity.Warning);
|
|
return;
|
|
}
|
|
|
|
var result = await (await Http.PutAsJsonAsync($"api/MapsManager/{MapUpdateModel.Id}", MapUpdateModel)).Content.ReadFromJsonAsync<MessageResult<MapInfoDto>>();
|
|
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("Dữ liệu không hợp lệ", Severity.Error);
|
|
}
|
|
else
|
|
{
|
|
var map = Maps.FirstOrDefault(map => map.Id == MapUpdateModel.Id);
|
|
if (map is not null)
|
|
{
|
|
map.Name = result.Data.Name;
|
|
map.OriginX = result.Data.OriginX;
|
|
map.OriginY = result.Data.OriginY;
|
|
map.Resolution = result.Data.Resolution;
|
|
map.Width = result.Data.Width;
|
|
map.Height = result.Data.Height;
|
|
map.Active = result.Data.Active;
|
|
Snackbar.Add("Cập nhật thành công", Severity.Success);
|
|
}
|
|
else Snackbar.Add("Map không tồn tại", Severity.Error);
|
|
}
|
|
|
|
IsUpdateMapVisible = false;
|
|
StateHasChanged();
|
|
}
|
|
|
|
private async Task DeleteMap(Guid mapId)
|
|
{
|
|
var parameters = new DialogParameters<ConfirmDialog>
|
|
{
|
|
{ x => x.Content, "Bạn có chắc chắn muốn xóa map đi không?" },
|
|
{ x => x.ConfirmText, "Delete" },
|
|
{ x => x.Color, Color.Secondary }
|
|
};
|
|
var ConfirmDelete = await Dialog.ShowAsync<ConfirmDialog>("Xoá Map", 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/MapsManager/{mapId}");
|
|
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 map = Maps.FirstOrDefault(m => m.Id == mapId);
|
|
if (map is not null)
|
|
{
|
|
if (map.Id == MapSelected.Id)
|
|
{
|
|
NavigationMapPreviewRef.SetMapPreview(null);
|
|
Table?.SetSelectedItem(null);
|
|
selectedRowNumber = -1;
|
|
}
|
|
Maps.Remove(map);
|
|
Table?.ReloadServerData();
|
|
Snackbar.Add($"Xóa map thành công.", Severity.Success);
|
|
}
|
|
else Snackbar.Add($"Map không tồn tại.", Severity.Warning);
|
|
}
|
|
StateHasChanged();
|
|
}
|
|
}
|
|
|
|
private async Task MapActiveToggle(Guid mapId, bool value)
|
|
{
|
|
var result = await (await Http.PutAsJsonAsync($"api/MapsManager/active", new MapActiveModel() { Id = mapId, Active = value })).Content.ReadFromJsonAsync<MessageResult>();
|
|
if (result is null) Snackbar.Add("Lỗi giao tiếp với hệ thống", Severity.Error);
|
|
else if (!result.IsSuccess) Snackbar.Add(result.Message ?? "Lỗi chưa xác định.", Severity.Error);
|
|
else
|
|
{
|
|
var map = Maps.FirstOrDefault(map => map.Id == mapId);
|
|
if (map is not null)
|
|
{
|
|
map.Active = value;
|
|
Snackbar.Add("Cập nhật thành công", Severity.Success);
|
|
}
|
|
else Snackbar.Add($"Map không tồn tại.", Severity.Warning);
|
|
}
|
|
StateHasChanged();
|
|
}
|
|
|
|
private async Task MapImageChangedCallBack(Guid mapId)
|
|
{
|
|
try
|
|
{
|
|
var mapupdate = await Http.GetFromJsonAsync<MessageResult<MapInfoDto>>($"api/MapsManager/{mapId}");
|
|
if (mapupdate is not null && mapupdate.Data is not null)
|
|
{
|
|
var map = Maps.FirstOrDefault(m => m.Id == mapupdate.Data.Id);
|
|
if (map is not null)
|
|
{
|
|
map.Name = mapupdate.Data.Name;
|
|
map.Width = mapupdate.Data.Width;
|
|
map.Height = mapupdate.Data.Height;
|
|
}
|
|
}
|
|
StateHasChanged();
|
|
}
|
|
catch (AccessTokenNotAvailableException ex)
|
|
{
|
|
ex.Redirect();
|
|
return;
|
|
}
|
|
}
|
|
|
|
private async Task OnMapImportChanged(InputFileChangeEventArgs e)
|
|
{
|
|
if (e.File is not null)
|
|
{
|
|
using var content = new MultipartFormDataContent();
|
|
var fileContent = new StreamContent(e.File.OpenReadStream(maxAllowedSize: 10240000));
|
|
if (!string.IsNullOrEmpty(e.File.ContentType)) fileContent.Headers.ContentType = new MediaTypeHeaderValue(e.File.ContentType);
|
|
content.Add(fileContent, "importmap", e.File.Name);
|
|
var response = await (await Http.PostAsync("api/MapExport/decrypt", content)).Content.ReadFromJsonAsync<MessageResult<MapExportDto>>();
|
|
if (response is null) Snackbar.Add("Lỗi giao tiếp với hệ thống", Severity.Error);
|
|
else if (!response.IsSuccess) Snackbar.Add($"Có lỗi xảy ra: {response.Message}", Severity.Error);
|
|
else
|
|
{
|
|
if (response.Data is not null)
|
|
{
|
|
MapImport = response.Data;
|
|
ProjectionImportImageFilePreview = $"data:image/png;base64,{Convert.ToBase64String(response.Data.Data.ImageData)}";
|
|
IsImportMapVisible = true;
|
|
}
|
|
else Snackbar.Add("Dữ liệu không hợp lệ", Severity.Warning);
|
|
}
|
|
StateHasChanged();
|
|
}
|
|
}
|
|
|
|
private async Task ImportNewMap()
|
|
{
|
|
if (string.IsNullOrEmpty(MapImport.Name))
|
|
{
|
|
Snackbar.Add("Map's name không được để trống.", Severity.Warning);
|
|
return;
|
|
}
|
|
|
|
var nameInvalid = MapEditorHelper.NameChecking(MapImport.Name);
|
|
if (!nameInvalid.IsSuccess)
|
|
{
|
|
Snackbar.Add(nameInvalid.returnStr, Severity.Warning);
|
|
return;
|
|
}
|
|
|
|
var response = await (await Http.PostAsJsonAsync("api/MapsManager/import", MapImport)).Content.ReadFromJsonAsync<MessageResult<MapInfoDto>>();
|
|
if (response is null) Snackbar.Add("Lỗi giao tiếp với hệ thống", Severity.Warning);
|
|
else if (!response.IsSuccess) Snackbar.Add($"Có lỗi xảy ra: {response.Message}", Severity.Warning);
|
|
else
|
|
{
|
|
if (response.Data is not null)
|
|
{
|
|
Maps.Add(response.Data);
|
|
Table?.ReloadServerData();
|
|
Snackbar.Add($"Import bản đồ thành công!", Severity.Success);
|
|
}
|
|
else Snackbar.Add("Dữ liệu không hợp lệ", Severity.Warning);
|
|
}
|
|
MapImport = default!;
|
|
IsImportMapVisible = false;
|
|
StateHasChanged();
|
|
}
|
|
}
|