update
This commit is contained in:
parent
2bbcc19076
commit
2640fb92c1
8
RobotApp.Client/ClientRenderMode.cs
Normal file
8
RobotApp.Client/ClientRenderMode.cs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
using Microsoft.AspNetCore.Components.Web;
|
||||
|
||||
namespace RobotApp.Client;
|
||||
|
||||
public class ClientRenderMode
|
||||
{
|
||||
public static InteractiveWebAssemblyRenderMode InteractiveWebAssemblyNoPrerender { get; } = new(prerender: false);
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
@inherits LayoutComponentBase
|
||||
@using MudBlazor
|
||||
|
||||
<div class="app-shell">
|
||||
<AuthorizeView>
|
||||
<Authorized>
|
||||
<NavMenu />
|
||||
</Authorized>
|
||||
</AuthorizeView>
|
||||
|
||||
<main class="page">
|
||||
@Body
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<MudPopoverProvider />
|
||||
<MudThemeProvider IsDarkMode />
|
||||
<MudDialogProvider MaxWidth="MaxWidth.ExtraLarge" />
|
||||
<MudSnackbarProvider />
|
||||
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
|
||||
.app-shell {
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
min-width: 100vw;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.page {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
@using Microsoft.AspNetCore.Components.Routing
|
||||
|
||||
<script>
|
||||
function toggleSidebar() {
|
||||
let sidebar = document.querySelector(".sidebar");
|
||||
sidebar.classList.toggle("collapsed");
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="sidebar collapsed">
|
||||
<div class="flex-grow-1 d-flex flex-column">
|
||||
<div class="title">
|
||||
<img src="images/logoLight.svg" alt="PhenikaaX" style="height: 35px;" onclick="toggleSidebar()" />
|
||||
<button class="btn button" onclick="toggleSidebar()">
|
||||
<i class="mdi mdi-menu" style="color: white; font-size: 35px"></i>
|
||||
</button>
|
||||
</div>
|
||||
<hr />
|
||||
@foreach (var nav in Navs)
|
||||
{
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="@nav.Path" Match="@nav.Match">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="nav-icon">
|
||||
<span class="mdi @nav.Icon mdi-36px" aria-hidden="true"></span>
|
||||
</div>
|
||||
<span class="nav-label">@nav.Label</span>
|
||||
</div>
|
||||
</NavLink>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="user">
|
||||
<div>
|
||||
<span class="mdi mdi-account mdi-36px text-white "></span>
|
||||
</div>
|
||||
<AuthorizeView>
|
||||
<Authorized>
|
||||
<div class="nav-label">
|
||||
<MudText Class="text-white name" Typo="Typo.subtitle1">@context.User.Identity?.Name</MudText>
|
||||
</div>
|
||||
</Authorized>
|
||||
</AuthorizeView>
|
||||
<MudSpacer />
|
||||
<form action="Account/Logout" method="post">
|
||||
<AntiforgeryToken />
|
||||
<input type="hidden" name="ReturnUrl" value="" />
|
||||
<button class="btn button">
|
||||
<i class="mdi mdi-logout" style="color: white; font-size: 35px"></i>
|
||||
</button>
|
||||
@* <MudIconButton Class="text-white" ButtonType="@ButtonType.Submit" Icon="@Icons.Material.Filled.Logout" /> *@
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
public class NavModel
|
||||
{
|
||||
public string Icon { get; set; } = "";
|
||||
public string Path { get; set; } = "";
|
||||
public string Label { get; set; } = "";
|
||||
public NavLinkMatch Match { get; set; }
|
||||
}
|
||||
|
||||
public NavModel[] Navs = [
|
||||
new(){Icon = "mdi-view-dashboard", Path="/", Label = "Dashboard", Match = NavLinkMatch.All},
|
||||
new(){Icon = "mdi-map-legend", Path="/Maps-manager", Label = "Mapping", Match = NavLinkMatch.All},
|
||||
];
|
||||
|
||||
private bool collapseNavMenu = true;
|
||||
|
||||
private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;
|
||||
|
||||
private void ToggleNavMenu()
|
||||
{
|
||||
collapseNavMenu = !collapseNavMenu;
|
||||
}
|
||||
}
|
||||
85
RobotApp.Client/MainLayout.razor
Normal file
85
RobotApp.Client/MainLayout.razor
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
@inherits LayoutComponentBase
|
||||
|
||||
<script>
|
||||
function toggleSidebar() {
|
||||
let sidebar = document.querySelector(".sidebar");
|
||||
sidebar.classList.toggle("collapsed");
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="app-shell">
|
||||
<div class="sidebar collapsed">
|
||||
<div class="flex-grow-1 d-flex flex-column">
|
||||
<div class="title">
|
||||
<img src="images/logoLight.svg" alt="PhenikaaX" style="height: 35px;" onclick="toggleSidebar()" />
|
||||
<button class="btn button" onclick="toggleSidebar()">
|
||||
<i class="mdi mdi-menu" style="color: white; font-size: 35px"></i>
|
||||
</button>
|
||||
</div>
|
||||
<hr />
|
||||
@foreach (var nav in Navs)
|
||||
{
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="@nav.Path" Match="@nav.Match">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="nav-icon">
|
||||
<span class="mdi @nav.Icon mdi-36px" aria-hidden="true"></span>
|
||||
</div>
|
||||
<span class="nav-label">@nav.Label</span>
|
||||
</div>
|
||||
</NavLink>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="user">
|
||||
<div>
|
||||
<span class="mdi mdi-account mdi-36px text-white "></span>
|
||||
</div>
|
||||
<AuthorizeView>
|
||||
<Authorized>
|
||||
<div class="nav-label">
|
||||
<MudText Class="text-white" Typo="Typo.subtitle1">@context.User.Identity?.Name</MudText>
|
||||
</div>
|
||||
</Authorized>
|
||||
</AuthorizeView>
|
||||
<MudSpacer />
|
||||
<form action="Account/Logout" method="post">
|
||||
<AntiforgeryToken />
|
||||
<input type="hidden" name="ReturnUrl" value="" />
|
||||
<button class="btn button">
|
||||
<i class="mdi mdi-logout" style="color: white; font-size: 35px"></i>
|
||||
</button>
|
||||
@* <MudIconButton Class="text-white" ButtonType="@ButtonType.Submit" Icon="@Icons.Material.Filled.Logout" /> *@
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<main class="page">
|
||||
@Body
|
||||
</main>
|
||||
</div>
|
||||
|
||||
@code{
|
||||
public class NavModel
|
||||
{
|
||||
public string Icon { get; set; } = "";
|
||||
public string Path { get; set; } = "";
|
||||
public string Label { get; set; } = "";
|
||||
public NavLinkMatch Match { get; set; }
|
||||
}
|
||||
|
||||
public NavModel[] Navs = [
|
||||
new(){Icon = "mdi-view-dashboard", Path="/", Label = "Dashboard", Match = NavLinkMatch.All},
|
||||
new(){Icon = "mdi-map-legend", Path="/maps-manager", Label = "Mapping", Match = NavLinkMatch.All},
|
||||
];
|
||||
|
||||
private bool collapseNavMenu = true;
|
||||
|
||||
private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;
|
||||
|
||||
private void ToggleNavMenu()
|
||||
{
|
||||
collapseNavMenu = !collapseNavMenu;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,3 +1,21 @@
|
|||
.app-shell {
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
min-width: 100vw;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.page {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.sidebar {
|
||||
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
|
||||
12
RobotApp.Client/Pages/AssemblyLayout.razor
Normal file
12
RobotApp.Client/Pages/AssemblyLayout.razor
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
@inherits LayoutComponentBase
|
||||
@layout RobotApp.Client.MainLayout
|
||||
|
||||
<MudThemeProvider @rendermode="InteractiveWebAssemblyNoPrerender" IsDarkMode/>
|
||||
<MudPopoverProvider @rendermode="InteractiveWebAssemblyNoPrerender" />
|
||||
<MudDialogProvider @rendermode="InteractiveWebAssemblyNoPrerender" MaxWidth="MaxWidth.ExtraLarge"
|
||||
CloseButton="false"
|
||||
BackdropClick="false"
|
||||
Position="DialogPosition.Center" />
|
||||
<MudSnackbarProvider @rendermode="InteractiveWebAssemblyNoPrerender" />
|
||||
|
||||
@Body
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
@page "/auth"
|
||||
|
||||
@using Microsoft.AspNetCore.Authorization
|
||||
|
||||
@attribute [Authorize]
|
||||
|
||||
<PageTitle>Auth</PageTitle>
|
||||
|
||||
<h1>You are authenticated</h1>
|
||||
|
||||
<AuthorizeView>
|
||||
Hello @context.User.Identity?.Name!
|
||||
</AuthorizeView>
|
||||
40
RobotApp.Client/Pages/Components/Mapping/MapPreview.razor
Normal file
40
RobotApp.Client/Pages/Components/Mapping/MapPreview.razor
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
@inject HttpClient Http
|
||||
|
||||
<div class="d-flex flex-column h-100 w-100">
|
||||
<span Class="title">@MapName</span>
|
||||
<div class="d-flex flex-grow-1 w-100 flex-column">
|
||||
<div class="map-item">
|
||||
<img src="@imageSrc" alt="map image" onerror="this.onerror=null; this.src='/images/Image-not-found.png';" />
|
||||
</div>
|
||||
<MudButton StartIcon="@Icons.Material.Filled.FileDownload" Class="m-2" Size="Size.Small" Variant="Variant.Filled" Color="Color.Primary" Disabled="Disable">
|
||||
DOWNLOAD
|
||||
</MudButton>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
private bool Disable = true;
|
||||
private string imageSrc = "/images/Image-not-found.png";
|
||||
private string MapName = "Map preview";
|
||||
private Guid MapId = Guid.Empty;
|
||||
|
||||
|
||||
public void SetMapPreview(MapDto? map)
|
||||
{
|
||||
if (map is null)
|
||||
{
|
||||
Disable = true;
|
||||
MapName = "Map preview";
|
||||
imageSrc = "/images/Image-not-found.png";
|
||||
MapId = Guid.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
imageSrc = $"api/Images/map/{map.Id}?t={DateTime.Now}";
|
||||
MapName = map.Name;
|
||||
MapId = map.Id;
|
||||
Disable = false;
|
||||
}
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
.map-item {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: fit-content;
|
||||
}
|
||||
|
||||
.map-item img {
|
||||
justify-content: center;
|
||||
width: 95%;
|
||||
height: 400px;
|
||||
object-fit: contain;
|
||||
border-radius: 10px;
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
height: 77px;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
align-content: center;
|
||||
/*border-bottom: 0.5px solid gray;*/
|
||||
font-size: 30px;
|
||||
flex-wrap: wrap;
|
||||
padding-bottom: .5rem;
|
||||
}
|
||||
|
||||
.map-update-item {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: fit-content;
|
||||
}
|
||||
|
||||
.map-update-item img {
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
object-fit: contain;
|
||||
border-radius: 10px;
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
165
RobotApp.Client/Pages/Components/Mapping/MapTable.razor
Normal file
165
RobotApp.Client/Pages/Components/Mapping/MapTable.razor
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
@inject HttpClient Http
|
||||
|
||||
<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 overflow-hidden">
|
||||
<MudTable @ref="Table" Items="@MapsShow" T="MapDto" Dense Hover ReadOnly FixedHeader RowClass="cursor-pointer" Striped Elevation="10"
|
||||
ServerData="ReloadData" Loading=@IsLoading RowClassFunc="@SelectedRowClassFunc" OnRowClick="RowClickEvent" Height="90vh" HorizontalScrollbar>
|
||||
<ToolBarContent>
|
||||
<MudText Typo="Typo.h6">Maps</MudText>
|
||||
</ToolBarContent>
|
||||
<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>
|
||||
<MudMenuItem Icon="@Icons.Material.Filled.Edit" IconColor="Color.Info">Active</MudMenuItem>
|
||||
<MudMenuItem Icon="@Icons.Material.Filled.Delete" IconColor="Color.Error">Delete</MudMenuItem>
|
||||
</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>
|
||||
|
||||
@code {
|
||||
|
||||
private string txtSearch = "";
|
||||
private bool IsLoading = false;
|
||||
|
||||
private List<MapDto> Maps = [];
|
||||
private List<MapDto> MapsShow = [];
|
||||
|
||||
private int selectedRowNumber = -1;
|
||||
private MapDto MapSelected = new();
|
||||
|
||||
private MudTable<MapDto>? Table;
|
||||
|
||||
private MapPreview? MapPreviewRef;
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
await base.OnAfterRenderAsync(firstRender);
|
||||
if (!firstRender) return;
|
||||
|
||||
// await LoadMaps();
|
||||
}
|
||||
|
||||
private async Task LoadMaps()
|
||||
{
|
||||
try
|
||||
{
|
||||
IsLoading = true;
|
||||
Maps.Clear();
|
||||
StateHasChanged();
|
||||
|
||||
var maps = await Http.GetFromJsonAsync<IEnumerable<MapDto>>($"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(MapDto 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<MapDto>> ReloadData(TableState state, CancellationToken _)
|
||||
{
|
||||
MapsShow.Clear();
|
||||
var tasks = new List<MapDto>();
|
||||
Maps.ForEach(map =>
|
||||
{
|
||||
if (FilterFunc(map)) tasks.Add(map);
|
||||
});
|
||||
MapsShow = tasks.Skip(state.Page * state.PageSize).Take(state.PageSize).ToList();
|
||||
return Task.FromResult(new TableData<MapDto>() { TotalItems = tasks.Count, Items = MapsShow });
|
||||
}
|
||||
|
||||
private void RowClickEvent(TableRowClickEventArgs<MapDto> tableRowClickEventArgs) { }
|
||||
|
||||
private string SelectedRowClassFunc(MapDto 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;
|
||||
// MapPreviewRef?.SetMapPreview(MapSelected);
|
||||
return "selected";
|
||||
}
|
||||
else
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
.map-preview {
|
||||
width: 20%;
|
||||
height: 100%;
|
||||
border-left: 1px solid silver;
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
@page "/counter"
|
||||
|
||||
<PageTitle>Counter</PageTitle>
|
||||
|
||||
<h1>Counter</h1>
|
||||
|
||||
<p role="status">Current count: @currentCount</p>
|
||||
|
||||
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
|
||||
|
||||
@code {
|
||||
private int currentCount = 0;
|
||||
|
||||
private void IncrementCount()
|
||||
{
|
||||
currentCount++;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,181 +1,20 @@
|
|||
@page "/maps-manager"
|
||||
@using MudBlazor
|
||||
@using RobotApp.Common.Shares.Dtos
|
||||
|
||||
@rendermode InteractiveWebAssemblyNoPrerender
|
||||
|
||||
@attribute [Authorize]
|
||||
@inject HttpClient Http
|
||||
|
||||
<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 Class="ms-3" StartIcon="@Icons.Material.Filled.Add" Variant="Variant.Filled" Color="Color.Primary" Size="Size.Large">
|
||||
NEW
|
||||
</MudButton>
|
||||
<div class="d-flex w-100 h-100 p-2 overflow-hidden flex-row">
|
||||
<div style="height: 100%; width: 40%">
|
||||
<RobotApp.Client.Pages.Components.Mapping.MapTable />
|
||||
</div>
|
||||
<div class="d-flex" style="height: 92%">
|
||||
<MudTable Class="w-100" @ref="Table" Items="@MapsShow" T="MapDto" 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 Icon="@Icons.Material.Filled.Edit" IconColor="Color.Info">Edit</MudMenuItem>
|
||||
<MudMenuItem Icon="@Icons.Material.Filled.Delete" IconColor="Color.Error">Delete</MudMenuItem>
|
||||
</MudMenu>
|
||||
</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">
|
||||
<div class="flex-grow-1 h-100" style="width: 60%">
|
||||
<RobotApp.Client.Pages.Components.Mapping.MapView />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
private string txtSearch = "";
|
||||
private bool IsLoading = false;
|
||||
|
||||
private List<MapDto> Maps = [];
|
||||
private List<MapDto> MapsShow = [];
|
||||
|
||||
private int selectedRowNumber = -1;
|
||||
private MapDto MapSelected = new();
|
||||
|
||||
private MudTable<MapDto>? Table; protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
await base.OnAfterRenderAsync(firstRender);
|
||||
if (!firstRender) return;
|
||||
|
||||
await LoadMaps();
|
||||
}
|
||||
|
||||
private async Task LoadMaps()
|
||||
{
|
||||
try
|
||||
{
|
||||
IsLoading = true;
|
||||
Maps.Clear();
|
||||
StateHasChanged();
|
||||
|
||||
var maps = await Http.GetFromJsonAsync<IEnumerable<MapDto>>($"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(MapDto 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<MapDto>> ReloadData(TableState state, CancellationToken _)
|
||||
{
|
||||
MapsShow.Clear();
|
||||
var tasks = new List<MapDto>();
|
||||
Maps.ForEach(map =>
|
||||
{
|
||||
if (FilterFunc(map)) tasks.Add(map);
|
||||
});
|
||||
MapsShow = tasks.Skip(state.Page * state.PageSize).Take(state.PageSize).ToList();
|
||||
return Task.FromResult(new TableData<MapDto>() { TotalItems = tasks.Count, Items = MapsShow });
|
||||
}
|
||||
|
||||
private void RowClickEvent(TableRowClickEventArgs<MapDto> tableRowClickEventArgs) { }
|
||||
|
||||
private string SelectedRowClassFunc(MapDto 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,63 +0,0 @@
|
|||
@page "/weather"
|
||||
|
||||
<PageTitle>Weather</PageTitle>
|
||||
|
||||
<h1>Weather</h1>
|
||||
|
||||
<p>This component demonstrates showing data.</p>
|
||||
|
||||
@if (forecasts == null)
|
||||
{
|
||||
<p><em>Loading...</em></p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th aria-label="Temperature in Celsius">Temp. (C)</th>
|
||||
<th aria-label="Temperature in Farenheit">Temp. (F)</th>
|
||||
<th>Summary</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var forecast in forecasts)
|
||||
{
|
||||
<tr>
|
||||
<td>@forecast.Date.ToShortDateString()</td>
|
||||
<td>@forecast.TemperatureC</td>
|
||||
<td>@forecast.TemperatureF</td>
|
||||
<td>@forecast.Summary</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
|
||||
@code {
|
||||
private WeatherForecast[]? forecasts;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
// Simulate asynchronous loading to demonstrate a loading indicator
|
||||
await Task.Delay(500);
|
||||
|
||||
var startDate = DateOnly.FromDateTime(DateTime.Now);
|
||||
var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" };
|
||||
forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast
|
||||
{
|
||||
Date = startDate.AddDays(index),
|
||||
TemperatureC = Random.Shared.Next(-20, 55),
|
||||
Summary = summaries[Random.Shared.Next(summaries.Length)]
|
||||
}).ToArray();
|
||||
}
|
||||
|
||||
private class WeatherForecast
|
||||
{
|
||||
public DateOnly Date { get; set; }
|
||||
public int TemperatureC { get; set; }
|
||||
public string? Summary { get; set; }
|
||||
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
|
||||
}
|
||||
}
|
||||
16
RobotApp.Client/Pages/_Imports.razor
Normal file
16
RobotApp.Client/Pages/_Imports.razor
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
@layout RobotApp.Client.Pages.AssemblyLayout
|
||||
@using System.Net.Http
|
||||
@using System.Net.Http.Json
|
||||
@using Microsoft.AspNetCore.Components.Authorization
|
||||
@using Microsoft.AspNetCore.Components.Forms
|
||||
@using Microsoft.AspNetCore.Components.Routing
|
||||
@using Microsoft.AspNetCore.Components.Web
|
||||
@using static Microsoft.AspNetCore.Components.Web.RenderMode
|
||||
@using static RobotApp.Client.ClientRenderMode
|
||||
@using Microsoft.AspNetCore.Components.Web.Virtualization
|
||||
@using Microsoft.JSInterop
|
||||
@using RobotApp.Client
|
||||
@using Microsoft.AspNetCore.Authorization
|
||||
@using MudBlazor
|
||||
@using RobotApp.Common.Shares
|
||||
@using RobotApp.Common.Shares.Dtos
|
||||
|
|
@ -1,11 +1,20 @@
|
|||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||
using MudBlazor.Services;
|
||||
using System.Globalization;
|
||||
|
||||
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
|
||||
var builder = WebAssemblyHostBuilder.CreateDefault(args);
|
||||
|
||||
builder.Services.AddAuthorizationCore();
|
||||
builder.Services.AddCascadingAuthenticationState();
|
||||
builder.Services.AddAuthenticationStateDeserialization();
|
||||
builder.Services.AddMudServices();
|
||||
|
||||
builder.Services.AddScoped(_ => new HttpClient() { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
|
||||
builder.Services.AddMudServices(config =>
|
||||
{
|
||||
config.SnackbarConfiguration.VisibleStateDuration = 2000;
|
||||
config.SnackbarConfiguration.HideTransitionDuration = 500;
|
||||
config.SnackbarConfiguration.ShowTransitionDuration = 500;
|
||||
});
|
||||
|
||||
await builder.Build().RunAsync();
|
||||
|
|
|
|||
|
|
@ -18,4 +18,9 @@
|
|||
<ProjectReference Include="..\RobotApp.Common.Shares\RobotApp.Common.Shares.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Models\" />
|
||||
<Folder Include="wwwroot\js\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
@using Microsoft.AspNetCore.Components.Routing
|
||||
@using Microsoft.AspNetCore.Components.Web
|
||||
@using static Microsoft.AspNetCore.Components.Web.RenderMode
|
||||
@using static RobotApp.Client.ClientRenderMode
|
||||
@using Microsoft.AspNetCore.Components.Web.Virtualization
|
||||
@using Microsoft.JSInterop
|
||||
@using RobotApp.Client
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 18
|
||||
VisualStudioVersion = 18.0.11018.127 d18.0
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.14.36511.14 d17.14
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RobotApp", "RobotApp\RobotApp.csproj", "{BF0BB137-2EF9-4E1B-944E-9BF41C5284F7}"
|
||||
EndProject
|
||||
|
|
|
|||
|
|
@ -4,23 +4,23 @@
|
|||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>RobotApp</title>
|
||||
<base href="/" />
|
||||
<link rel="stylesheet" href="@Assets["lib/bootstrap/css/bootstrap.min.css"]" />
|
||||
<link rel="stylesheet" href="@Assets["lib/mdi/font/css/materialdesignicons.min.css"]" />
|
||||
<link rel="stylesheet" href="@Assets["app.css"]" />
|
||||
<link rel="stylesheet" href="@Assets["RobotApp.styles.css"]" />
|
||||
<link rel="stylesheet" href="@Assets["_content/MudBlazor/MudBlazor.min.css"]" />
|
||||
<link rel="icon" type="image/png" href="favicon.png" />
|
||||
<link rel="icon" type="image/svg+xml" href="favicon.svg" />
|
||||
<ImportMap />
|
||||
<ImportMap @rendermode="InteractiveServer" />
|
||||
<HeadOutlet @rendermode="InteractiveServer" />
|
||||
<HeadOutlet />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<CascadingAuthenticationState>
|
||||
<Router AppAssembly="@typeof(Program).Assembly">
|
||||
<Found Context="routeData">
|
||||
<AuthorizeRouteView RouteData="routeData" DefaultLayout="typeof(RobotApp.Client.Layout.MainLayout)">
|
||||
<AuthorizeRouteView RouteData="routeData" DefaultLayout="typeof(RobotApp.Client.MainLayout)">
|
||||
<NotAuthorized>
|
||||
<RedirectToLogin />
|
||||
</NotAuthorized>
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
</Found>
|
||||
<NotFound>
|
||||
<PageTitle>Not found</PageTitle>
|
||||
<LayoutView Layout="typeof(RobotApp.Client.Layout.MainLayout)">
|
||||
<LayoutView Layout="typeof(RobotApp.Client.MainLayout)">
|
||||
<p>Không tìm thấy trang.</p>
|
||||
</LayoutView>
|
||||
</NotFound>
|
||||
|
|
@ -39,7 +39,7 @@
|
|||
<script src="_framework/blazor.web.js"></script>
|
||||
<script src="@Assets["lib/bootstrap/js/bootstrap.bundle.min.js"]"></script>
|
||||
<script src="@Assets["lib/bootstrap/js/bootstrap.min.js"]"></script>
|
||||
<script src="_content/MudBlazor/MudBlazor.min.js"></script>
|
||||
<script src="@Assets["_content/MudBlazor/MudBlazor.min.js"]"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
@page "/"
|
||||
@using Microsoft.AspNetCore.Authorization
|
||||
|
||||
@rendermode InteractiveServer
|
||||
|
||||
@attribute [Authorize]
|
||||
<h1>Welcome to RobotApp!</h1>
|
||||
12
RobotApp/Components/ServerLayout.razor
Normal file
12
RobotApp/Components/ServerLayout.razor
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
@inherits LayoutComponentBase
|
||||
@layout RobotApp.Client.MainLayout
|
||||
|
||||
<MudThemeProvider @rendermode="InteractiveServer" IsDarkMode/>
|
||||
<MudPopoverProvider @rendermode="InteractiveServer" />
|
||||
<MudDialogProvider @rendermode="InteractiveServer" MaxWidth="MaxWidth.ExtraLarge"
|
||||
CloseButton="false"
|
||||
BackdropClick="false"
|
||||
Position="DialogPosition.Center" />
|
||||
<MudSnackbarProvider @rendermode="InteractiveServer" />
|
||||
|
||||
@Body
|
||||
|
|
@ -6,7 +6,6 @@ using RobotApp.Components;
|
|||
using RobotApp.Components.Account;
|
||||
using RobotApp.Data;
|
||||
using RobotApp.Services.Robot;
|
||||
using RobotApp.Client;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\RobotApp.Client\RobotApp.Client.csproj" />
|
||||
<ProjectReference Include="..\RobotApp.Common.Shares\RobotApp.Common.Shares.csproj" />
|
||||
<ProjectReference Include="..\RobotApp.VDA5050\RobotApp.VDA5050.csproj" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="9.0.9" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="9.0.9" />
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Reference in New Issue
Block a user