Add Blazor WebAssembly Admin Page (#426)
* Added Blazor Client Configured PublicAPI CORS to allow traffic from client * Make admin page home page; remove extra pages Add CatalogType list endpoint * Wired up Types and Brands in the API and the admin list page * Adding a custom HttpClient to talk securely to API * Ardalis/blazor (#419) * Login added * AuthService will handel http request secure and not secure. * Logout added * CatalogBrandService in it is own service * Get token from localstorage when refresh. * used GetAsync * Fixed Login and Logout switch. * CatalogItemService added * CatalogTypeService added & Auth for CatalogType. using not used removed. * Made BlazorComponent and BlazorLayoutComponent for refresh. Index now small enough to be in one file. * Removed the service from program main and use lazy singleton. * used OnInitialized * Refactoring and detecting login status in login.razor * Refactoring login to redirect if user is already logged in * Blazor login with MVC (#420) * Blazor login with MVC * return back the PasswordSignInAsync in Login page * CRUD added (#422) * CRUD added * Unit Test changed to meet new redirect /admin * CreateCatalogItemRequest added. * Action caption added. * Validation added for name and price. * Updated port of api Redirect to returnUrl from login * Add username to /admin; link to my profile * Working on authorization of /admin * Working on custom auth locking down /admin page * Microsoft authorize working.Login.razor removed.Login from SignInMana… (#425) * Microsoft authorize working.Login.razor removed.Login from SignInManager and create token from it.unit test fixed. * GetTokenFromController function used in CustomAuthStateProvider * Cleaned up button styles Refactored to use codebehind for List component Updated Not Authorized view Co-authored-by: Shady Nagy <shadynagi@gmail.com>
This commit is contained in:
111
src/BlazorAdmin/Pages/CatalogItemPage/Create.razor
Normal file
111
src/BlazorAdmin/Pages/CatalogItemPage/Create.razor
Normal file
@@ -0,0 +1,111 @@
|
||||
@inject ILogger<Create> Logger
|
||||
@inject AuthService Auth
|
||||
|
||||
@inherits BlazorAdmin.Helpers.BlazorComponent
|
||||
|
||||
@namespace BlazorAdmin.Pages.CatalogItemPage
|
||||
|
||||
<h2 class="esh-body-title">Create</h2>
|
||||
|
||||
<div>
|
||||
<EditForm Model="_item" OnValidSubmit="@CreateClick">
|
||||
<DataAnnotationsValidator />
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2">Name</label>
|
||||
<div class="col-md-3">
|
||||
<InputText class="form-control" @bind-Value="_item.Name" />
|
||||
<ValidationMessage For="(() => _item.Name)" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2">Description</label>
|
||||
<div class="col-md-3">
|
||||
<InputText class="form-control" @bind-Value="_item.Description" />
|
||||
<ValidationMessage For="(() => _item.Description)" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2">Brand</label>
|
||||
<div class="col-md-3">
|
||||
<InputSelect @bind-Value="_item.CatalogBrandId" class="form-control">
|
||||
@foreach (var brand in Brands)
|
||||
{
|
||||
<option value="@brand.Id">@brand.Name</option>
|
||||
}
|
||||
</InputSelect>
|
||||
<ValidationMessage For="(() => _item.CatalogBrandId)" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2">Type</label>
|
||||
<div class="col-md-3">
|
||||
<InputSelect @bind-Value="_item.CatalogTypeId" class="form-control">
|
||||
@foreach (var type in Types)
|
||||
{
|
||||
<option value="@type.Id">@type.Name</option>
|
||||
}
|
||||
</InputSelect>
|
||||
<ValidationMessage For="(() => _item.CatalogTypeId)" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2">Price</label>
|
||||
<div class="col-md-3">
|
||||
<InputNumber @bind-Value="_item.Price" class="form-control" />
|
||||
<ValidationMessage For="(() => _item.Price)" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2">Picture name</label>
|
||||
<div class="col-md-4 esh-form-information">
|
||||
Uploading images not allowed for this version.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-md-offset-2 col-md-3 text-right esh-button-actions">
|
||||
<a href="" @onclick="@(() => OnCloseClick.InvokeAsync(null))" @onclick:preventDefault class="btn btn-secondary">
|
||||
Cancel
|
||||
</a>
|
||||
<button type="submit" class="btn esh-button btn-primary">
|
||||
Create
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</EditForm>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
|
||||
[Parameter]
|
||||
public IEnumerable<CatalogBrand> Brands { get; set; }
|
||||
[Parameter]
|
||||
public IEnumerable<CatalogType> Types { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<string> OnCloseClick { get; set; }
|
||||
|
||||
private readonly CreateCatalogItemRequest _item = new CreateCatalogItemRequest();
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
Logger.LogInformation("Now loading... /Catalog/Create");
|
||||
|
||||
_item.CatalogTypeId = Types.First().Id;
|
||||
_item.CatalogBrandId = Brands.First().Id;
|
||||
|
||||
await base.OnAfterRenderAsync(firstRender);
|
||||
}
|
||||
|
||||
private async Task CreateClick()
|
||||
{
|
||||
await new BlazorAdmin.Services.CatalogItemService.Create(Auth).HandleAsync(_item);
|
||||
await OnCloseClick.InvokeAsync(null);
|
||||
}
|
||||
}
|
||||
95
src/BlazorAdmin/Pages/CatalogItemPage/Delete.razor
Normal file
95
src/BlazorAdmin/Pages/CatalogItemPage/Delete.razor
Normal file
@@ -0,0 +1,95 @@
|
||||
@inject ILogger<Delete> Logger
|
||||
@inject AuthService Auth
|
||||
|
||||
@inherits BlazorAdmin.Helpers.BlazorComponent
|
||||
|
||||
@namespace BlazorAdmin.Pages.CatalogItemPage
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<img class="col-md-6 esh-picture" src="@($"https://localhost:44315/{_item.PictureUri}")">
|
||||
|
||||
<dl class="col-md-6 dl-horizontal">
|
||||
<dt>
|
||||
Name
|
||||
</dt>
|
||||
|
||||
<dd>
|
||||
@_item.Name
|
||||
</dd>
|
||||
|
||||
<dt>
|
||||
Description
|
||||
</dt>
|
||||
|
||||
<dd>
|
||||
@_item.Description
|
||||
</dd>
|
||||
|
||||
<dt>
|
||||
Brand
|
||||
</dt>
|
||||
|
||||
<dd>
|
||||
@Services.CatalogBrandService.List.GetBrandName(Brands, _item.CatalogBrandId)
|
||||
</dd>
|
||||
|
||||
<dt>
|
||||
Type
|
||||
</dt>
|
||||
|
||||
<dd>
|
||||
@Services.CatalogTypeService.List.GetTypeName(Types, _item.CatalogTypeId)
|
||||
</dd>
|
||||
<dt>
|
||||
Price
|
||||
</dt>
|
||||
|
||||
<dd>
|
||||
@_item.Price
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="form-actions no-color">
|
||||
<a href="" @onclick="@(() => OnCloseClick.InvokeAsync(null))" @onclick:preventDefault class="btn btn-secondary">
|
||||
Cancel
|
||||
</a>
|
||||
<button class="btn btn-danger" @onclick="DeleteClick">
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public int Id { get; set; }
|
||||
[Parameter]
|
||||
public IEnumerable<CatalogBrand> Brands { get; set; }
|
||||
[Parameter]
|
||||
public IEnumerable<CatalogType> Types { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<string> OnCloseClick { get; set; }
|
||||
|
||||
private CatalogItem _item = new CatalogItem();
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
Logger.LogInformation("Now loading... /Catalog/Delete/{Id}", Id);
|
||||
|
||||
_item = await new GetById(Auth).HandleAsync(Id);
|
||||
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
|
||||
private async Task DeleteClick()
|
||||
{
|
||||
// TODO: Add some kind of "are you sure" check before this
|
||||
|
||||
await new BlazorAdmin.Services.CatalogItemService.Delete(Auth).HandleAsync(Id);
|
||||
|
||||
await OnCloseClick.InvokeAsync(null);
|
||||
}
|
||||
}
|
||||
99
src/BlazorAdmin/Pages/CatalogItemPage/Details.razor
Normal file
99
src/BlazorAdmin/Pages/CatalogItemPage/Details.razor
Normal file
@@ -0,0 +1,99 @@
|
||||
@inject ILogger<Details> Logger
|
||||
@inject AuthService Auth
|
||||
|
||||
@inherits BlazorAdmin.Helpers.BlazorComponent
|
||||
|
||||
@namespace BlazorAdmin.Pages.CatalogItemPage
|
||||
|
||||
@if (_item == null)
|
||||
{
|
||||
<p><em>Loading...</em></p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<h2 class="esh-body-title">Details</h2>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<img class="col-md-6 esh-picture" src="@($"https://localhost:44315/{_item.PictureUri}")">
|
||||
|
||||
<dl class="col-md-6 dl-horizontal">
|
||||
<dt>
|
||||
Name
|
||||
</dt>
|
||||
|
||||
<dd>
|
||||
@_item.Name
|
||||
</dd>
|
||||
|
||||
<dt>
|
||||
Description
|
||||
</dt>
|
||||
|
||||
<dd>
|
||||
@_item.Description
|
||||
</dd>
|
||||
|
||||
<dt>
|
||||
Brand
|
||||
</dt>
|
||||
|
||||
<dd>
|
||||
@Services.CatalogBrandService.List.GetBrandName(Brands, _item.CatalogBrandId)
|
||||
</dd>
|
||||
|
||||
<dt>
|
||||
Type
|
||||
</dt>
|
||||
|
||||
<dd>
|
||||
@Services.CatalogTypeService.List.GetTypeName(Types, _item.CatalogTypeId)
|
||||
</dd>
|
||||
<dt>
|
||||
Price
|
||||
</dt>
|
||||
|
||||
<dd>
|
||||
@_item.Price
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="form-actions no-color">
|
||||
<a href="" @onclick="@(() => OnCloseClick.InvokeAsync(null))" @onclick:preventDefault class="btn btn-secondary">
|
||||
Cancel
|
||||
</a>
|
||||
<a href="" @onclick="@(() => OnEditClick.InvokeAsync(_item.Id))" @onclick:preventDefault class="btn btn-secondary">
|
||||
Edit
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
}
|
||||
@code {
|
||||
[Parameter]
|
||||
public int Id { get; set; }
|
||||
[Parameter]
|
||||
public IEnumerable<CatalogBrand> Brands { get; set; }
|
||||
[Parameter]
|
||||
public IEnumerable<CatalogType> Types { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<string> OnCloseClick { get; set; }
|
||||
[Parameter]
|
||||
public EventCallback<int> OnEditClick { get; set; }
|
||||
|
||||
private CatalogItem _item = new CatalogItem();
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
Logger.LogInformation("Now loading... /Catalog/Details/{Id}", Id);
|
||||
|
||||
_item = await new GetById(Auth).HandleAsync(Id);
|
||||
StateHasChanged();
|
||||
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
|
||||
}
|
||||
110
src/BlazorAdmin/Pages/CatalogItemPage/Edit.razor
Normal file
110
src/BlazorAdmin/Pages/CatalogItemPage/Edit.razor
Normal file
@@ -0,0 +1,110 @@
|
||||
@inject ILogger<Edit> Logger
|
||||
@inject AuthService Auth
|
||||
|
||||
@inherits BlazorAdmin.Helpers.BlazorComponent
|
||||
|
||||
@namespace BlazorAdmin.Pages.CatalogItemPage
|
||||
|
||||
<h2 class="esh-body-title">Edit</h2>
|
||||
|
||||
<div>
|
||||
<EditForm Model="_item" OnValidSubmit="@SaveClick">
|
||||
<DataAnnotationsValidator />
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2">Name</label>
|
||||
<div class="col-md-3">
|
||||
<InputText class="form-control" @bind-Value="_item.Name" />
|
||||
<ValidationMessage For="(() => _item.Name)" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2">Description</label>
|
||||
<div class="col-md-3">
|
||||
<InputText class="form-control" @bind-Value="_item.Description" />
|
||||
<ValidationMessage For="(() => _item.Description)" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2">Brand</label>
|
||||
<div class="col-md-3">
|
||||
<InputSelect @bind-Value="_item.CatalogBrandId" class="form-control">
|
||||
@foreach (var brand in Brands)
|
||||
{
|
||||
<option value="@brand.Id">@brand.Name</option>
|
||||
}
|
||||
</InputSelect>
|
||||
<ValidationMessage For="(() => _item.CatalogBrandId)" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2">Type</label>
|
||||
<div class="col-md-3">
|
||||
<InputSelect @bind-Value="_item.CatalogTypeId" class="form-control">
|
||||
@foreach (var type in Types)
|
||||
{
|
||||
<option value="@type.Id">@type.Name</option>
|
||||
}
|
||||
</InputSelect>
|
||||
<ValidationMessage For="(() => _item.CatalogTypeId)" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2">Price</label>
|
||||
<div class="col-md-3">
|
||||
<InputNumber @bind-Value="_item.Price" class="form-control" />
|
||||
<ValidationMessage For="(() => _item.Price)" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label col-md-2">Picture name</label>
|
||||
<div class="col-md-4 esh-form-information">
|
||||
Uploading images not allowed for this version.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-md-offset-2 col-md-3 text-right esh-button-actions">
|
||||
<a href="" @onclick="@(() => OnCloseClick.InvokeAsync(null))" @onclick:preventDefault class="btn btn-secondary">
|
||||
Cancel
|
||||
</a>
|
||||
<button type="submit" class="btn btn-primary">
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</EditForm>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public int Id { get; set; }
|
||||
[Parameter]
|
||||
public IEnumerable<CatalogBrand> Brands { get; set; }
|
||||
[Parameter]
|
||||
public IEnumerable<CatalogType> Types { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<string> OnCloseClick { get; set; }
|
||||
|
||||
private CatalogItem _item = new CatalogItem();
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
Logger.LogInformation("Now loading... /Catalog/Edit/{Id}", Id);
|
||||
|
||||
_item = await new GetById(Auth).HandleAsync(Id);
|
||||
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
|
||||
private async Task SaveClick()
|
||||
{
|
||||
await new BlazorAdmin.Services.CatalogItemService.Edit(Auth).HandleAsync(_item);
|
||||
}
|
||||
}
|
||||
82
src/BlazorAdmin/Pages/CatalogItemPage/List.razor
Normal file
82
src/BlazorAdmin/Pages/CatalogItemPage/List.razor
Normal file
@@ -0,0 +1,82 @@
|
||||
@page "/admin"
|
||||
@attribute [Authorize(Roles = Microsoft.eShopWeb.ApplicationCore.Constants.AuthorizationConstants.Roles.ADMINISTRATORS)]
|
||||
@inject AuthService Auth
|
||||
@inherits BlazorAdmin.Helpers.BlazorComponent
|
||||
@namespace BlazorAdmin.Pages.CatalogItemPage
|
||||
|
||||
<h1>Manage Product Catalog</h1>
|
||||
|
||||
@if (catalogItems == null)
|
||||
{
|
||||
<p><em>Loading...</em></p>
|
||||
}
|
||||
else
|
||||
{
|
||||
@if (!showCreate && !showDetails && !showEdit && !showDelete)
|
||||
{
|
||||
<p class="esh-link-wrapper">
|
||||
<button class="btn btn-primary" @onclick="@(() => CreateClick())">
|
||||
Create New
|
||||
</button>
|
||||
</p>
|
||||
|
||||
<table class="table table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Item Type</th>
|
||||
<th>Brand</th>
|
||||
<th>Id</th>
|
||||
<th>Name</th>
|
||||
<th>@nameof(CatalogItem.Description)</th>
|
||||
<th>@nameof(CatalogItem.Price)</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="cursor-pointer">
|
||||
@foreach (var item in catalogItems)
|
||||
{
|
||||
<tr @onclick="@(() => DetailsClick(item.Id))">
|
||||
<td>
|
||||
<img class="img-thumbnail" src="@($"https://localhost:44315/{item.PictureUri}")">
|
||||
</td>
|
||||
<td>@Services.CatalogTypeService.List.GetTypeName(catalogTypes, item.CatalogTypeId)</td>
|
||||
<td>@Services.CatalogBrandService.List.GetBrandName(catalogBrands, item.CatalogBrandId)</td>
|
||||
<td>@item.Id</td>
|
||||
<td>@item.Name</td>
|
||||
<td>@item.Description</td>
|
||||
<td>@item.Price</td>
|
||||
<td>
|
||||
<a href="" @onclick="@(() => EditClick(item.Id))" @onclick:preventDefault class="btn btn-primary">
|
||||
Edit
|
||||
</a>
|
||||
|
||||
<a href="" @onclick="@(() => DeleteClick(item.Id))" @onclick:preventDefault class="btn btn-primary">
|
||||
Delete
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
@if (showDetails)
|
||||
{
|
||||
<Details Id="@selectedId" Brands="@catalogBrands" Types="@catalogTypes" OnCloseClick="CloseDetailsHandler" OnEditClick="EditDetailsHandler"></Details>
|
||||
}
|
||||
|
||||
@if (showEdit)
|
||||
{
|
||||
<Edit Id="@selectedId" Brands="@catalogBrands" Types="@catalogTypes" OnCloseClick="CloseEditHandler"></Edit>
|
||||
}
|
||||
|
||||
@if (showCreate)
|
||||
{
|
||||
<Create Brands="@catalogBrands" Types="@catalogTypes" OnCloseClick="CloseCreateHandler"></Create>
|
||||
}
|
||||
|
||||
@if (showDelete)
|
||||
{
|
||||
<Delete Id="@selectedId" Brands="@catalogBrands" Types="@catalogTypes" OnCloseClick="CloseDeleteHandler"></Delete>
|
||||
}
|
||||
}
|
||||
95
src/BlazorAdmin/Pages/CatalogItemPage/List.razor.cs
Normal file
95
src/BlazorAdmin/Pages/CatalogItemPage/List.razor.cs
Normal file
@@ -0,0 +1,95 @@
|
||||
using BlazorAdmin.Helpers;
|
||||
using BlazorAdmin.Services.CatalogBrandService;
|
||||
using BlazorAdmin.Services.CatalogItemService;
|
||||
using BlazorAdmin.Services.CatalogTypeService;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BlazorAdmin.Pages.CatalogItemPage
|
||||
{
|
||||
public partial class List : BlazorComponent
|
||||
{
|
||||
private List<CatalogItem> catalogItems = new List<CatalogItem>();
|
||||
private List<CatalogType> catalogTypes = new List<CatalogType>();
|
||||
private List<CatalogBrand> catalogBrands = new List<CatalogBrand>();
|
||||
private bool showCreate = false;
|
||||
private bool showDetails = false;
|
||||
private bool showEdit = false;
|
||||
private bool showDelete = false;
|
||||
private int selectedId = 0;
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
catalogItems = await new BlazorAdmin.Services.CatalogItemService.ListPaged(Auth).HandleAsync(50);
|
||||
catalogTypes = await new BlazorAdmin.Services.CatalogTypeService.List(Auth).HandleAsync();
|
||||
catalogBrands = await new BlazorAdmin.Services.CatalogBrandService.List(Auth).HandleAsync();
|
||||
|
||||
CallRequestRefresh();
|
||||
}
|
||||
|
||||
await base.OnAfterRenderAsync(firstRender);
|
||||
}
|
||||
|
||||
private void DetailsClick(int id)
|
||||
{
|
||||
selectedId = id;
|
||||
showDetails = true;
|
||||
}
|
||||
|
||||
private void CreateClick()
|
||||
{
|
||||
showCreate = true;
|
||||
}
|
||||
|
||||
private void EditClick(int id)
|
||||
{
|
||||
selectedId = id;
|
||||
showEdit = true;
|
||||
}
|
||||
|
||||
private void DeleteClick(int id)
|
||||
{
|
||||
selectedId = id;
|
||||
showDelete = true;
|
||||
}
|
||||
|
||||
private async Task CloseDetailsHandler(string action)
|
||||
{
|
||||
showDetails = false;
|
||||
await ReloadCatalogItems();
|
||||
}
|
||||
|
||||
private void EditDetailsHandler(int id)
|
||||
{
|
||||
showDetails = false;
|
||||
selectedId = id;
|
||||
showEdit = true;
|
||||
}
|
||||
|
||||
private async Task CloseEditHandler(string action)
|
||||
{
|
||||
showEdit = false;
|
||||
await ReloadCatalogItems();
|
||||
}
|
||||
|
||||
private async Task CloseDeleteHandler(string action)
|
||||
{
|
||||
showDelete = false;
|
||||
await ReloadCatalogItems();
|
||||
}
|
||||
|
||||
private async Task CloseCreateHandler(string action)
|
||||
{
|
||||
showCreate = false;
|
||||
await ReloadCatalogItems();
|
||||
}
|
||||
|
||||
private async Task ReloadCatalogItems()
|
||||
{
|
||||
catalogItems = await new BlazorAdmin.Services.CatalogItemService.ListPaged(Auth).HandleAsync(50);
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
27
src/BlazorAdmin/Pages/Logout.razor
Normal file
27
src/BlazorAdmin/Pages/Logout.razor
Normal file
@@ -0,0 +1,27 @@
|
||||
@page "/logout"
|
||||
@inject AuthService AuthService
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject IJSRuntime JSRuntime
|
||||
@inherits BlazorAdmin.Helpers.BlazorComponent
|
||||
|
||||
|
||||
@code {
|
||||
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await AuthService.Logout();
|
||||
await DeleteCookies();
|
||||
|
||||
CallRequestRefresh();
|
||||
await new Route(JSRuntime).RouteOutside("/Identity/Account/Login");
|
||||
}
|
||||
|
||||
private async Task DeleteCookies()
|
||||
{
|
||||
await new Cookies(JSRuntime).DeleteCookie("token");
|
||||
await new Cookies(JSRuntime).DeleteCookie("username");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user