@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 Map Manager
IMPORT NEW
Nr Name Width (m) Height (m) Resolution (m/px) OriginX OriginY @(Table?.CurrentPage * Table?.RowsPerPage + MapsShow.IndexOf(context) + 1) @context.Name @context.Width @context.Height @context.Resolution @context.OriginX @context.OriginY
Edit Delete Active
Create New Map
Map Image
Cancel Create
Update Map
Cancel Update
Import New Map
Map Image
Cancel Create
@code { private string txtSearch = ""; private bool IsLoading = false; private List Maps = []; private List MapsShow = []; private MudTable? 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>($"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> ReloadData(TableState state, CancellationToken _) { MapsShow.Clear(); var tasks = new List(); 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() { TotalItems = tasks.Count, Items = MapsShow }); } private void RowClickEvent(TableRowClickEventArgs 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>(); 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>(); 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 { { 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("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($"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(); 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>($"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>(); 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>(); 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(); } }