Shady nagy/blazor enhance (#429)
* - Using cdnjs not nuget on bootstrap and signalr. - Bootstrap modal used for add, edit details and delete. * EditForm inside modal-content * Top close button action added * Removed unused using. * DeleteCookies moved inside AuthService * ApplicationCore removed from BlazorAdmin dependencies * SecureHttpClient removed * Logout from identity manager added * last thing to do in logout from admin is LogoutIdentityManager. * JSRuntime used in AuthService without pass to the functions * Link fixed when logout from MVC
This commit is contained in:
@@ -18,7 +18,6 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\ApplicationCore\ApplicationCore.csproj" />
|
|
||||||
<ProjectReference Include="..\Shared\Shared.csproj" />
|
<ProjectReference Include="..\Shared\Shared.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -3,5 +3,10 @@
|
|||||||
public class Constants
|
public class Constants
|
||||||
{
|
{
|
||||||
public const string API_URL = "https://localhost:5099/api/";
|
public const string API_URL = "https://localhost:5099/api/";
|
||||||
|
|
||||||
|
public static class Roles
|
||||||
|
{
|
||||||
|
public const string ADMINISTRATORS = "Administrators";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Net.Http;
|
|
||||||
using System.Net.Http.Json;
|
|
||||||
using BlazorAdmin.Services;
|
using BlazorAdmin.Services;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using Microsoft.AspNetCore.Components.Authorization;
|
using Microsoft.AspNetCore.Components.Authorization;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Components;
|
|
||||||
using Microsoft.eShopWeb;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Shared.Authorization;
|
using Shared.Authorization;
|
||||||
|
|
||||||
|
|||||||
@@ -1,37 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Net.Http.Json;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using BlazorAdmin.Services.CatalogBrandService;
|
|
||||||
|
|
||||||
namespace BlazorAdmin.Network
|
|
||||||
{
|
|
||||||
public class SecureHttpClient
|
|
||||||
{
|
|
||||||
private readonly HttpClient client;
|
|
||||||
|
|
||||||
public SecureHttpClient(HttpClient client)
|
|
||||||
{
|
|
||||||
this.client = client;
|
|
||||||
|
|
||||||
this.client.DefaultRequestHeaders.Add("Authorization", $"Bearer ");
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<List<CatalogBrand>> GetCatalogBrandsAsync()
|
|
||||||
{
|
|
||||||
var brands = new List<CatalogBrand>();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
brands = (await client.GetFromJsonAsync<CatalogBrandResult>($"{Constants.API_URL}catalog-brands")).CatalogBrands;
|
|
||||||
}
|
|
||||||
catch (AccessTokenNotAvailableException exception)
|
|
||||||
{
|
|
||||||
exception.Redirect();
|
|
||||||
}
|
|
||||||
|
|
||||||
return brands;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -5,82 +5,102 @@
|
|||||||
|
|
||||||
@namespace BlazorAdmin.Pages.CatalogItemPage
|
@namespace BlazorAdmin.Pages.CatalogItemPage
|
||||||
|
|
||||||
<h2 class="esh-body-title">Create</h2>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<EditForm Model="_item" OnValidSubmit="@CreateClick">
|
|
||||||
<DataAnnotationsValidator />
|
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="modal @_modalClass" tabindex="-1" role="dialog" style="display:@_modalDisplay">
|
||||||
<label class="control-label col-md-2">Name</label>
|
<div class="modal-dialog" role="document">
|
||||||
<div class="col-md-3">
|
<div class="modal-content">
|
||||||
<InputText class="form-control" @bind-Value="_item.Name" />
|
<EditForm Model="_item" OnValidSubmit="@CreateClick">
|
||||||
<ValidationMessage For="(() => _item.Name)" />
|
<DataAnnotationsValidator />
|
||||||
</div>
|
<div class="modal-header">
|
||||||
</div>
|
<h5 class="modal-title" id="exampleModalLabel">Create</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close" @onclick="Close">
|
||||||
<div class="form-group">
|
<span aria-hidden="true">×</span>
|
||||||
<label class="control-label col-md-2">Description</label>
|
</button>
|
||||||
<div class="col-md-3">
|
</div>
|
||||||
<InputText class="form-control" @bind-Value="_item.Description" />
|
<div class="modal-body">
|
||||||
<ValidationMessage For="(() => _item.Description)" />
|
@if (_item == null)
|
||||||
</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>
|
<Spinner></Spinner>
|
||||||
}
|
}
|
||||||
</InputSelect>
|
else
|
||||||
<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>
|
<div class="form-group">
|
||||||
|
<label class="control-label col-md-2">Name</label>
|
||||||
|
<div class="col-md-12">
|
||||||
|
<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-12">
|
||||||
|
<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-12">
|
||||||
|
<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-12">
|
||||||
|
<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-12">
|
||||||
|
<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-12 esh-form-information">
|
||||||
|
Uploading images not allowed for this version.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
</InputSelect>
|
</div>
|
||||||
<ValidationMessage For="(() => _item.CatalogTypeId)" />
|
<div class="modal-footer">
|
||||||
</div>
|
<button type="button" class="btn btn-secondary" data-dismiss="modal" @onclick="Close">Cancel</button>
|
||||||
|
<button type="submit" class="btn btn-primary">
|
||||||
|
Create
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</EditForm>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@if (_showCreateModal)
|
||||||
|
{
|
||||||
|
<div class="modal-backdrop fade show"></div>
|
||||||
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
@@ -91,21 +111,35 @@
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public EventCallback<string> OnCloseClick { get; set; }
|
public EventCallback<string> OnCloseClick { get; set; }
|
||||||
|
|
||||||
|
private string _modalDisplay = "none;";
|
||||||
|
private string _modalClass = "";
|
||||||
|
private bool _showCreateModal = false;
|
||||||
private readonly CreateCatalogItemRequest _item = new CreateCatalogItemRequest();
|
private readonly CreateCatalogItemRequest _item = new CreateCatalogItemRequest();
|
||||||
|
|
||||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
private async Task CreateClick()
|
||||||
|
{
|
||||||
|
await new BlazorAdmin.Services.CatalogItemService.Create(Auth).HandleAsync(_item);
|
||||||
|
await OnCloseClick.InvokeAsync(null);
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Open()
|
||||||
{
|
{
|
||||||
Logger.LogInformation("Now loading... /Catalog/Create");
|
Logger.LogInformation("Now loading... /Catalog/Create");
|
||||||
|
|
||||||
_item.CatalogTypeId = Types.First().Id;
|
_item.CatalogTypeId = Types.First().Id;
|
||||||
_item.CatalogBrandId = Brands.First().Id;
|
_item.CatalogBrandId = Brands.First().Id;
|
||||||
|
|
||||||
await base.OnAfterRenderAsync(firstRender);
|
_modalDisplay = "block;";
|
||||||
|
_modalClass = "Show";
|
||||||
|
_showCreateModal = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task CreateClick()
|
public void Close()
|
||||||
{
|
{
|
||||||
await new BlazorAdmin.Services.CatalogItemService.Create(Auth).HandleAsync(_item);
|
_modalDisplay = "none";
|
||||||
await OnCloseClick.InvokeAsync(null);
|
_modalClass = "";
|
||||||
|
_showCreateModal = false;
|
||||||
|
OnCloseClick.InvokeAsync(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,66 +5,89 @@
|
|||||||
|
|
||||||
@namespace BlazorAdmin.Pages.CatalogItemPage
|
@namespace BlazorAdmin.Pages.CatalogItemPage
|
||||||
|
|
||||||
<div class="container">
|
<div class="modal @_modalClass" tabindex="-1" role="dialog" style="display:@_modalDisplay">
|
||||||
<div class="row">
|
<div class="modal-dialog" role="document">
|
||||||
<img class="col-md-6 esh-picture" src="@($"https://localhost:44315/{_item.PictureUri}")">
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="exampleModalLabel">Delete @_item.Name</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close" @onclick="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
@if (_item == null)
|
||||||
|
{
|
||||||
|
<Spinner></Spinner>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<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">
|
<dl class="col-md-6 dl-horizontal">
|
||||||
<dt>
|
<dt>
|
||||||
Name
|
Name
|
||||||
</dt>
|
</dt>
|
||||||
|
|
||||||
<dd>
|
<dd>
|
||||||
@_item.Name
|
@_item.Name
|
||||||
</dd>
|
</dd>
|
||||||
|
|
||||||
<dt>
|
<dt>
|
||||||
Description
|
Description
|
||||||
</dt>
|
</dt>
|
||||||
|
|
||||||
<dd>
|
<dd>
|
||||||
@_item.Description
|
@_item.Description
|
||||||
</dd>
|
</dd>
|
||||||
|
|
||||||
<dt>
|
<dt>
|
||||||
Brand
|
Brand
|
||||||
</dt>
|
</dt>
|
||||||
|
|
||||||
<dd>
|
<dd>
|
||||||
@Services.CatalogBrandService.List.GetBrandName(Brands, _item.CatalogBrandId)
|
@Services.CatalogBrandService.List.GetBrandName(Brands, _item.CatalogBrandId)
|
||||||
</dd>
|
</dd>
|
||||||
|
|
||||||
<dt>
|
<dt>
|
||||||
Type
|
Type
|
||||||
</dt>
|
</dt>
|
||||||
|
|
||||||
<dd>
|
<dd>
|
||||||
@Services.CatalogTypeService.List.GetTypeName(Types, _item.CatalogTypeId)
|
@Services.CatalogTypeService.List.GetTypeName(Types, _item.CatalogTypeId)
|
||||||
</dd>
|
</dd>
|
||||||
<dt>
|
<dt>
|
||||||
Price
|
Price
|
||||||
</dt>
|
</dt>
|
||||||
|
|
||||||
<dd>
|
<dd>
|
||||||
@_item.Price
|
@_item.Price
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal" @onclick="Close">Cancel</button>
|
||||||
|
<button class="btn btn-danger" @onclick="() => DeleteClick(_item.Id)">
|
||||||
|
Delete
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@if (_showDeleteModal)
|
||||||
|
{
|
||||||
|
<div class="modal-backdrop fade show"></div>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
[Parameter]
|
|
||||||
public int Id { get; set; }
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public IEnumerable<CatalogBrand> Brands { get; set; }
|
public IEnumerable<CatalogBrand> Brands { get; set; }
|
||||||
[Parameter]
|
[Parameter]
|
||||||
@@ -73,23 +96,37 @@
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public EventCallback<string> OnCloseClick { get; set; }
|
public EventCallback<string> OnCloseClick { get; set; }
|
||||||
|
|
||||||
|
private string _modalDisplay = "none;";
|
||||||
|
private string _modalClass = "";
|
||||||
|
private bool _showDeleteModal = false;
|
||||||
private CatalogItem _item = new CatalogItem();
|
private CatalogItem _item = new CatalogItem();
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
private async Task DeleteClick(int id)
|
||||||
{
|
|
||||||
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
|
// TODO: Add some kind of "are you sure" check before this
|
||||||
|
|
||||||
await new BlazorAdmin.Services.CatalogItemService.Delete(Auth).HandleAsync(Id);
|
await new BlazorAdmin.Services.CatalogItemService.Delete(Auth).HandleAsync(id);
|
||||||
|
|
||||||
await OnCloseClick.InvokeAsync(null);
|
await OnCloseClick.InvokeAsync(null);
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Open(int id)
|
||||||
|
{
|
||||||
|
Logger.LogInformation("Now loading... /Catalog/Delete/{Id}", id);
|
||||||
|
|
||||||
|
_item = await new GetById(Auth).HandleAsync(id);
|
||||||
|
|
||||||
|
_modalDisplay = "block;";
|
||||||
|
_modalClass = "Show";
|
||||||
|
_showDeleteModal = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
_modalDisplay = "none";
|
||||||
|
_modalClass = "";
|
||||||
|
_showDeleteModal = false;
|
||||||
|
OnCloseClick.InvokeAsync(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,95 +5,127 @@
|
|||||||
|
|
||||||
@namespace BlazorAdmin.Pages.CatalogItemPage
|
@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">
|
<div class="modal @_modalClass" tabindex="-1" role="dialog" style="display:@_modalDisplay">
|
||||||
<dt>
|
<div class="modal-dialog" role="document">
|
||||||
Name
|
<div class="modal-content">
|
||||||
</dt>
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="exampleModalLabel">Details @_item.Name</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close" @onclick="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
|
||||||
<dd>
|
@if (_item == null)
|
||||||
@_item.Name
|
{
|
||||||
</dd>
|
<Spinner></Spinner>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<img class="col-md-6 esh-picture" src="@($"https://localhost:44315/{_item.PictureUri}")">
|
||||||
|
|
||||||
<dt>
|
<dl class="col-md-6 dl-horizontal">
|
||||||
Description
|
<dt>
|
||||||
</dt>
|
Name
|
||||||
|
</dt>
|
||||||
|
|
||||||
<dd>
|
<dd>
|
||||||
@_item.Description
|
@_item.Name
|
||||||
</dd>
|
</dd>
|
||||||
|
|
||||||
<dt>
|
<dt>
|
||||||
Brand
|
Description
|
||||||
</dt>
|
</dt>
|
||||||
|
|
||||||
<dd>
|
<dd>
|
||||||
@Services.CatalogBrandService.List.GetBrandName(Brands, _item.CatalogBrandId)
|
@_item.Description
|
||||||
</dd>
|
</dd>
|
||||||
|
|
||||||
<dt>
|
<dt>
|
||||||
Type
|
Brand
|
||||||
</dt>
|
</dt>
|
||||||
|
|
||||||
<dd>
|
<dd>
|
||||||
@Services.CatalogTypeService.List.GetTypeName(Types, _item.CatalogTypeId)
|
@Services.CatalogBrandService.List.GetBrandName(Brands, _item.CatalogBrandId)
|
||||||
</dd>
|
</dd>
|
||||||
<dt>
|
|
||||||
Price
|
|
||||||
</dt>
|
|
||||||
|
|
||||||
<dd>
|
<dt>
|
||||||
@_item.Price
|
Type
|
||||||
</dd>
|
</dt>
|
||||||
|
|
||||||
</dl>
|
<dd>
|
||||||
|
@Services.CatalogTypeService.List.GetTypeName(Types, _item.CatalogTypeId)
|
||||||
|
</dd>
|
||||||
|
<dt>
|
||||||
|
Price
|
||||||
|
</dt>
|
||||||
|
|
||||||
|
<dd>
|
||||||
|
@_item.Price
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal" @onclick="Close">Close</button>
|
||||||
|
<button class="btn btn-danger" @onclick="EditClick">
|
||||||
|
Edit
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@if (_showDetailsModal)
|
||||||
|
{
|
||||||
|
<div class="modal-backdrop fade show"></div>
|
||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
[Parameter]
|
|
||||||
public int Id { get; set; }
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public IEnumerable<CatalogBrand> Brands { get; set; }
|
public IEnumerable<CatalogBrand> Brands { get; set; }
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public IEnumerable<CatalogType> Types { get; set; }
|
public IEnumerable<CatalogType> Types { get; set; }
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public EventCallback<string> OnCloseClick { get; set; }
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public EventCallback<int> OnEditClick { get; set; }
|
public EventCallback<int> OnEditClick { get; set; }
|
||||||
|
|
||||||
|
private string _modalDisplay = "none;";
|
||||||
|
private string _modalClass = "";
|
||||||
|
private bool _showDetailsModal = false;
|
||||||
private CatalogItem _item = new CatalogItem();
|
private CatalogItem _item = new CatalogItem();
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
public void EditClick()
|
||||||
{
|
{
|
||||||
Logger.LogInformation("Now loading... /Catalog/Details/{Id}", Id);
|
OnEditClick.InvokeAsync(_item.Id);
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
_item = await new GetById(Auth).HandleAsync(Id);
|
public async Task Open(int id)
|
||||||
StateHasChanged();
|
{
|
||||||
|
Logger.LogInformation("Now loading... /Catalog/Details/{Id}", id);
|
||||||
|
|
||||||
await base.OnInitializedAsync();
|
_item = await new GetById(Auth).HandleAsync(id);
|
||||||
|
|
||||||
|
_modalDisplay = "block;";
|
||||||
|
_modalClass = "Show";
|
||||||
|
_showDetailsModal = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
_modalDisplay = "none";
|
||||||
|
_modalClass = "";
|
||||||
|
_showDetailsModal = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,85 +5,104 @@
|
|||||||
|
|
||||||
@namespace BlazorAdmin.Pages.CatalogItemPage
|
@namespace BlazorAdmin.Pages.CatalogItemPage
|
||||||
|
|
||||||
<h2 class="esh-body-title">Edit</h2>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<EditForm Model="_item" OnValidSubmit="@SaveClick">
|
|
||||||
<DataAnnotationsValidator />
|
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="modal @_modalClass" tabindex="-1" role="dialog" style="display:@_modalDisplay">
|
||||||
<label class="control-label col-md-2">Name</label>
|
<div class="modal-dialog" role="document">
|
||||||
<div class="col-md-3">
|
<div class="modal-content">
|
||||||
<InputText class="form-control" @bind-Value="_item.Name" />
|
<EditForm Model="_item" OnValidSubmit="@SaveClick">
|
||||||
<ValidationMessage For="(() => _item.Name)" />
|
<DataAnnotationsValidator />
|
||||||
</div>
|
<div class="modal-header">
|
||||||
</div>
|
<h5 class="modal-title" id="exampleModalLabel">Edit @_item.Name</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close" @onclick="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="form-group">
|
@if (_item == null)
|
||||||
<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>
|
<Spinner></Spinner>
|
||||||
}
|
}
|
||||||
</InputSelect>
|
else
|
||||||
<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>
|
<div class="form-group">
|
||||||
|
<label class="control-label col-md-2">Name</label>
|
||||||
|
<div class="col-md-12">
|
||||||
|
<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-12">
|
||||||
|
<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-12">
|
||||||
|
<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-12">
|
||||||
|
<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-12">
|
||||||
|
<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-12 esh-form-information">
|
||||||
|
Uploading images not allowed for this version.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
</InputSelect>
|
</div>
|
||||||
<ValidationMessage For="(() => _item.CatalogTypeId)" />
|
<div class="modal-footer">
|
||||||
</div>
|
<button type="button" class="btn btn-secondary" data-dismiss="modal" @onclick="Close">Cancel</button>
|
||||||
|
<button type="submit" class="btn btn-primary">
|
||||||
|
Save
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</EditForm>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@if (_showEditModal)
|
||||||
|
{
|
||||||
|
<div class="modal-backdrop fade show"></div>
|
||||||
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
[Parameter]
|
|
||||||
public int Id { get; set; }
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public IEnumerable<CatalogBrand> Brands { get; set; }
|
public IEnumerable<CatalogBrand> Brands { get; set; }
|
||||||
[Parameter]
|
[Parameter]
|
||||||
@@ -92,19 +111,33 @@
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public EventCallback<string> OnCloseClick { get; set; }
|
public EventCallback<string> OnCloseClick { get; set; }
|
||||||
|
|
||||||
|
private string _modalDisplay = "none;";
|
||||||
|
private string _modalClass = "";
|
||||||
|
private bool _showEditModal = false;
|
||||||
private CatalogItem _item = new CatalogItem();
|
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()
|
private async Task SaveClick()
|
||||||
{
|
{
|
||||||
await new BlazorAdmin.Services.CatalogItemService.Edit(Auth).HandleAsync(_item);
|
await new BlazorAdmin.Services.CatalogItemService.Edit(Auth).HandleAsync(_item);
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Open(int id)
|
||||||
|
{
|
||||||
|
Logger.LogInformation("Now loading... /Catalog/Edit/{Id}", id);
|
||||||
|
|
||||||
|
_item = await new GetById(Auth).HandleAsync(id);
|
||||||
|
|
||||||
|
_modalDisplay = "block;";
|
||||||
|
_modalClass = "Show";
|
||||||
|
_showEditModal = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
_modalDisplay = "none";
|
||||||
|
_modalClass = "";
|
||||||
|
_showEditModal = false;
|
||||||
|
OnCloseClick.InvokeAsync(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
@page "/admin"
|
@page "/admin"
|
||||||
@attribute [Authorize(Roles = Microsoft.eShopWeb.ApplicationCore.Constants.AuthorizationConstants.Roles.ADMINISTRATORS)]
|
@attribute [Authorize(Roles = Constants.Roles.ADMINISTRATORS)]
|
||||||
@inject AuthService Auth
|
@inject AuthService Auth
|
||||||
|
@using global::Shared.Authorization
|
||||||
@inherits BlazorAdmin.Helpers.BlazorComponent
|
@inherits BlazorAdmin.Helpers.BlazorComponent
|
||||||
@namespace BlazorAdmin.Pages.CatalogItemPage
|
@namespace BlazorAdmin.Pages.CatalogItemPage
|
||||||
|
|
||||||
@@ -8,75 +9,59 @@
|
|||||||
|
|
||||||
@if (catalogItems == null)
|
@if (catalogItems == null)
|
||||||
{
|
{
|
||||||
<p><em>Loading...</em></p>
|
<Spinner></Spinner>
|
||||||
}
|
}
|
||||||
else
|
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">
|
<p class="esh-link-wrapper">
|
||||||
<thead>
|
<button class="btn btn-primary" @onclick="@(CreateClick)">
|
||||||
<tr>
|
Create New
|
||||||
<th></th>
|
</button>
|
||||||
<th>Item Type</th>
|
</p>
|
||||||
<th>Brand</th>
|
|
||||||
<th>Id</th>
|
<table class="table table-striped table-hover">
|
||||||
<th>Name</th>
|
<thead>
|
||||||
<th>@nameof(CatalogItem.Description)</th>
|
<tr>
|
||||||
<th>@nameof(CatalogItem.Price)</th>
|
<th></th>
|
||||||
<th>Actions</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>
|
||||||
|
<button @onclick="@(() => EditClick(item.Id))" @onclick:stopPropagation="true" class="btn btn-primary">
|
||||||
|
Edit
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button @onclick="@(() => DeleteClick(item.Id))" @onclick:stopPropagation="true" class="btn btn-primary">
|
||||||
|
Delete
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
}
|
||||||
<tbody class="cursor-pointer">
|
</tbody>
|
||||||
@foreach (var item in catalogItems)
|
</table>
|
||||||
{
|
|
||||||
<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">
|
<Details Brands="@catalogBrands" Types="@catalogTypes" @ref="DetailsComponent" OnEditClick="EditClick"></Details>
|
||||||
Delete
|
<Edit Brands="@catalogBrands" Types="@catalogTypes" OnCloseClick="ReloadCatalogItems" @ref="EditComponent"></Edit>
|
||||||
</a>
|
<Create Brands="@catalogBrands" Types="@catalogTypes" OnCloseClick="ReloadCatalogItems" @ref="CreateComponent"></Create>
|
||||||
</td>
|
<Delete Brands="@catalogBrands" Types="@catalogTypes" OnCloseClick="ReloadCatalogItems" @ref="DeleteComponent"></Delete>
|
||||||
</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>
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,11 +12,11 @@ namespace BlazorAdmin.Pages.CatalogItemPage
|
|||||||
private List<CatalogItem> catalogItems = new List<CatalogItem>();
|
private List<CatalogItem> catalogItems = new List<CatalogItem>();
|
||||||
private List<CatalogType> catalogTypes = new List<CatalogType>();
|
private List<CatalogType> catalogTypes = new List<CatalogType>();
|
||||||
private List<CatalogBrand> catalogBrands = new List<CatalogBrand>();
|
private List<CatalogBrand> catalogBrands = new List<CatalogBrand>();
|
||||||
private bool showCreate = false;
|
|
||||||
private bool showDetails = false;
|
private Edit EditComponent { get; set; }
|
||||||
private bool showEdit = false;
|
private Delete DeleteComponent { get; set; }
|
||||||
private bool showDelete = false;
|
private Details DetailsComponent { get; set; }
|
||||||
private int selectedId = 0;
|
private Create CreateComponent { get; set; }
|
||||||
|
|
||||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
{
|
{
|
||||||
@@ -32,58 +32,24 @@ namespace BlazorAdmin.Pages.CatalogItemPage
|
|||||||
await base.OnAfterRenderAsync(firstRender);
|
await base.OnAfterRenderAsync(firstRender);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DetailsClick(int id)
|
private async void DetailsClick(int id)
|
||||||
{
|
{
|
||||||
selectedId = id;
|
await DetailsComponent.Open(id);
|
||||||
showDetails = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateClick()
|
private void CreateClick()
|
||||||
{
|
{
|
||||||
showCreate = true;
|
CreateComponent.Open();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EditClick(int id)
|
private async Task EditClick(int id)
|
||||||
{
|
{
|
||||||
selectedId = id;
|
await EditComponent.Open(id);
|
||||||
showEdit = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DeleteClick(int id)
|
private async Task DeleteClick(int id)
|
||||||
{
|
{
|
||||||
selectedId = id;
|
await DeleteComponent.Open(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()
|
private async Task ReloadCatalogItems()
|
||||||
|
|||||||
@@ -1,27 +1,15 @@
|
|||||||
@page "/logout"
|
@page "/logout"
|
||||||
@inject AuthService AuthService
|
@inject AuthService AuthService
|
||||||
@inject NavigationManager NavigationManager
|
|
||||||
@inject IJSRuntime JSRuntime
|
@inject IJSRuntime JSRuntime
|
||||||
@inherits BlazorAdmin.Helpers.BlazorComponent
|
@inherits BlazorAdmin.Helpers.BlazorComponent
|
||||||
|
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
await AuthService.Logout();
|
await AuthService.Logout();
|
||||||
await DeleteCookies();
|
|
||||||
|
|
||||||
CallRequestRefresh();
|
|
||||||
await new Route(JSRuntime).RouteOutside("/Identity/Account/Login");
|
await new Route(JSRuntime).RouteOutside("/Identity/Account/Login");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task DeleteCookies()
|
|
||||||
{
|
|
||||||
await new Cookies(JSRuntime).DeleteCookie("token");
|
|
||||||
await new Cookies(JSRuntime).DeleteCookie("username");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,9 @@ using System.Net.Http;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using BlazorAdmin.Network;
|
|
||||||
using BlazorAdmin.Services;
|
using BlazorAdmin.Services;
|
||||||
using Blazored.LocalStorage;
|
using Blazored.LocalStorage;
|
||||||
using Microsoft.AspNetCore.Components.Authorization;
|
using Microsoft.AspNetCore.Components.Authorization;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
|
|
||||||
namespace BlazorAdmin
|
namespace BlazorAdmin
|
||||||
{
|
{
|
||||||
@@ -19,7 +17,6 @@ namespace BlazorAdmin
|
|||||||
builder.RootComponents.Add<App>("admin");
|
builder.RootComponents.Add<App>("admin");
|
||||||
|
|
||||||
builder.Services.AddTransient(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
|
builder.Services.AddTransient(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
|
||||||
builder.Services.AddTransient(sp => new SecureHttpClient(sp.GetRequiredService<HttpClient>()));
|
|
||||||
|
|
||||||
builder.Services.AddSingleton<ILocalStorageService, LocalStorageService>();
|
builder.Services.AddSingleton<ILocalStorageService, LocalStorageService>();
|
||||||
builder.Services.AddSingleton<AuthService>();
|
builder.Services.AddSingleton<AuthService>();
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ using System.Text;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BlazorAdmin.JavaScript;
|
using BlazorAdmin.JavaScript;
|
||||||
using Blazored.LocalStorage;
|
using Blazored.LocalStorage;
|
||||||
using Microsoft.AspNetCore.Identity;
|
|
||||||
using Microsoft.JSInterop;
|
using Microsoft.JSInterop;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Shared.Authorization;
|
using Shared.Authorization;
|
||||||
@@ -20,13 +19,15 @@ namespace BlazorAdmin.Services
|
|||||||
{
|
{
|
||||||
private readonly HttpClient _httpClient;
|
private readonly HttpClient _httpClient;
|
||||||
private readonly ILocalStorageService _localStorage;
|
private readonly ILocalStorageService _localStorage;
|
||||||
|
private readonly IJSRuntime _jSRuntime;
|
||||||
public bool IsLoggedIn { get; set; }
|
public bool IsLoggedIn { get; set; }
|
||||||
public string UserName { get; set; }
|
public string UserName { get; set; }
|
||||||
|
|
||||||
public AuthService(HttpClient httpClient, ILocalStorageService localStorage)
|
public AuthService(HttpClient httpClient, ILocalStorageService localStorage, IJSRuntime jSRuntime)
|
||||||
{
|
{
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
_localStorage = localStorage;
|
_localStorage = localStorage;
|
||||||
|
_jSRuntime = jSRuntime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpClient GetHttpClient()
|
public HttpClient GetHttpClient()
|
||||||
@@ -74,10 +75,11 @@ namespace BlazorAdmin.Services
|
|||||||
{
|
{
|
||||||
await _localStorage.RemoveItemAsync("authToken");
|
await _localStorage.RemoveItemAsync("authToken");
|
||||||
await _localStorage.RemoveItemAsync("username");
|
await _localStorage.RemoveItemAsync("username");
|
||||||
|
await DeleteCookies();
|
||||||
RemoveAuthorizationHeader();
|
RemoveAuthorizationHeader();
|
||||||
UserName = null;
|
UserName = null;
|
||||||
IsLoggedIn = false;
|
IsLoggedIn = false;
|
||||||
|
await LogoutIdentityManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task RefreshLoginInfo()
|
public async Task RefreshLoginInfo()
|
||||||
@@ -85,16 +87,26 @@ namespace BlazorAdmin.Services
|
|||||||
await SetLoginData();
|
await SetLoginData();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task RefreshLoginInfoFromCookie(IJSRuntime jSRuntime)
|
public async Task RefreshLoginInfoFromCookie()
|
||||||
{
|
{
|
||||||
var token = await new Cookies(jSRuntime).GetCookie("token");
|
var token = await new Cookies(_jSRuntime).GetCookie("token");
|
||||||
await SaveTokenInLocalStorage(token);
|
await SaveTokenInLocalStorage(token);
|
||||||
|
|
||||||
var username = await new Cookies(jSRuntime).GetCookie("username");
|
var username = await new Cookies(_jSRuntime).GetCookie("username");
|
||||||
await SaveUsernameInLocalStorage(username);
|
await SaveUsernameInLocalStorage(username);
|
||||||
|
|
||||||
await RefreshLoginInfo();
|
await RefreshLoginInfo();
|
||||||
}
|
}
|
||||||
|
private async Task LogoutIdentityManager()
|
||||||
|
{
|
||||||
|
await _httpClient.PostAsync("Identity/Account/Logout", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task DeleteCookies()
|
||||||
|
{
|
||||||
|
await new Cookies(_jSRuntime).DeleteCookie("token");
|
||||||
|
await new Cookies(_jSRuntime).DeleteCookie("username");
|
||||||
|
}
|
||||||
|
|
||||||
private async Task SetLoginData()
|
private async Task SetLoginData()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
using System;
|
using System.Net;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net;
|
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
using System;
|
namespace BlazorAdmin.Services.CatalogItemService
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace BlazorAdmin.Services.CatalogItemService
|
|
||||||
{
|
{
|
||||||
public class DeleteCatalogItemResult
|
public class DeleteCatalogItemResult
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
using System;
|
using System.Net;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
using System;
|
namespace BlazorAdmin.Services.CatalogItemService
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace BlazorAdmin.Services.CatalogItemService
|
|
||||||
{
|
{
|
||||||
public class EditCatalogItemResult
|
public class EditCatalogItemResult
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
using System;
|
using System.Net;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net;
|
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
using System;
|
namespace BlazorAdmin.Services.CatalogItemService
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace BlazorAdmin.Services.CatalogItemService
|
|
||||||
{
|
{
|
||||||
public class GetByIdCatalogItemResult
|
public class GetByIdCatalogItemResult
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
using System;
|
using System.Net;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
@using BlazorAdmin.Services
|
@inject AuthService Auth
|
||||||
@using BlazorAdmin.JavaScript
|
|
||||||
|
|
||||||
@inject AuthService Auth
|
|
||||||
@inject IJSRuntime JSRuntime
|
@inject IJSRuntime JSRuntime
|
||||||
|
|
||||||
@inherits BlazorAdmin.Helpers.BlazorLayoutComponent
|
@inherits BlazorAdmin.Helpers.BlazorLayoutComponent
|
||||||
|
|
||||||
<AuthorizeView Roles=@Microsoft.eShopWeb.ApplicationCore.Constants.AuthorizationConstants.Roles.ADMINISTRATORS>
|
<AuthorizeView Roles=@Constants.Roles.ADMINISTRATORS>
|
||||||
<div class="sidebar">
|
<div class="sidebar">
|
||||||
<NavMenu />
|
<NavMenu />
|
||||||
</div>
|
</div>
|
||||||
@@ -28,7 +25,7 @@
|
|||||||
{
|
{
|
||||||
if (firstRender)
|
if (firstRender)
|
||||||
{
|
{
|
||||||
await Auth.RefreshLoginInfoFromCookie(JSRuntime);
|
await Auth.RefreshLoginInfoFromCookie();
|
||||||
if (!Auth.IsLoggedIn)
|
if (!Auth.IsLoggedIn)
|
||||||
{
|
{
|
||||||
await new Route(JSRuntime).RouteOutside("/Identity/Account/Login");
|
await new Route(JSRuntime).RouteOutside("/Identity/Account/Login");
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
@inject AuthService Auth
|
@inject AuthService Auth
|
||||||
@inherits BlazorAdmin.Helpers.BlazorComponent
|
@inherits BlazorAdmin.Helpers.BlazorComponent
|
||||||
|
|
||||||
@using BlazorAdmin.Services
|
|
||||||
<div class="top-row pl-4 navbar navbar-dark">
|
<div class="top-row pl-4 navbar navbar-dark">
|
||||||
<a class="navbar-brand" href="">eShopOnWeb Admin</a>
|
<a class="navbar-brand" href="">eShopOnWeb Admin</a>
|
||||||
<button class="navbar-toggler" @onclick="ToggleNavMenu">
|
<button class="navbar-toggler" @onclick="ToggleNavMenu">
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
@inject NavigationManager Navigation
|
@inject NavigationManager Navigation
|
||||||
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
|
|
||||||
@code {
|
@code {
|
||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
Navigation.NavigateTo($"authentication/login?returnUrl=" +
|
Navigation.NavigateTo($"Identity/Account/Login?returnUrl=" +
|
||||||
Uri.EscapeDataString(Navigation.Uri));
|
Uri.EscapeDataString(Navigation.Uri));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
9
src/BlazorAdmin/Shared/Spinner.razor
Normal file
9
src/BlazorAdmin/Shared/Spinner.razor
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
@inherits BlazorAdmin.Helpers.BlazorComponent
|
||||||
|
|
||||||
|
@namespace BlazorAdmin.Shared
|
||||||
|
|
||||||
|
<div class="spinner-border" role="status">
|
||||||
|
<span class="sr-only">Loading...</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
@@ -9,7 +9,6 @@
|
|||||||
@using Microsoft.JSInterop
|
@using Microsoft.JSInterop
|
||||||
@using BlazorAdmin
|
@using BlazorAdmin
|
||||||
@using BlazorAdmin.Shared
|
@using BlazorAdmin.Shared
|
||||||
@using BlazorAdmin.Network
|
|
||||||
@using BlazorAdmin.Services
|
@using BlazorAdmin.Services
|
||||||
@using BlazorAdmin.Services.CatalogBrandService
|
@using BlazorAdmin.Services.CatalogBrandService
|
||||||
@using BlazorAdmin.Services.CatalogItemService
|
@using BlazorAdmin.Services.CatalogItemService
|
||||||
|
|||||||
@@ -7,17 +7,16 @@
|
|||||||
"destination": "wwwroot/lib/jquery/"
|
"destination": "wwwroot/lib/jquery/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"provider": "unpkg",
|
"library": "twitter-bootstrap@3.3.7",
|
||||||
"library": "bootstrap@3.3.7",
|
|
||||||
"files": [
|
"files": [
|
||||||
"dist/css/bootstrap.css",
|
"css/bootstrap.css",
|
||||||
"dist/css/bootstrap.css.map",
|
"css/bootstrap.css.map",
|
||||||
"dist/css/bootstrap.min.css",
|
"css/bootstrap.min.css",
|
||||||
"dist/css/bootstrap.min.css.map",
|
"css/bootstrap.min.css.map",
|
||||||
"dist/js/bootstrap.js",
|
"js/bootstrap.js",
|
||||||
"dist/js/bootstrap.min.js"
|
"js/bootstrap.min.js"
|
||||||
],
|
],
|
||||||
"destination": "wwwroot/lib/bootstrap/"
|
"destination": "wwwroot/lib/bootstrap/dist/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"library": "jquery-validation-unobtrusive@3.2.10",
|
"library": "jquery-validation-unobtrusive@3.2.10",
|
||||||
@@ -36,13 +35,12 @@
|
|||||||
"destination": "wwwroot/lib/toastr/"
|
"destination": "wwwroot/lib/toastr/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"provider": "unpkg",
|
"library": "aspnet-signalr@1.0.3",
|
||||||
"library": "@aspnet/signalr@1.0.3",
|
|
||||||
"files": [
|
"files": [
|
||||||
"dist/browser/signalr.js",
|
"signalr.js",
|
||||||
"dist/browser/signalr.min.js"
|
"signalr.min.js"
|
||||||
],
|
],
|
||||||
"destination": "wwwroot/lib/@aspnet/signalr/"
|
"destination": "wwwroot/lib/@aspnet/signalr/dist/browser/"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user