Browse Source
* Updating Blazor services * Adding Settings and Refactoring Services * WIP - Fighting with DI * Configuring dependencies in both Web Startup and BlazorAdmin Program.cs has them working again. * Everything works; need to optimize calls to ListBrands * LocalStorageBrandService decorator working * Added cache duration of 1 minute * Refactoring to reduce token storage Fixed issue with dropdowns binding to int * Remove token stuff from login; moved to CustomAuthStateProvider * Migrated CatalogTypes to separate service Implemented cache decorator * Ardalis/blazor refactor (#440) * 1. Migrate CatalogItemServices -> CatalogItemService. 3. Add caching to CatalogItemService. * change to $"Loading {key} from local storage" ? * docker settings added. (#441) * docker settings added. * InDocker Removed * InDocker removed from web startup. * removed unused using * no reload list if close without save * startup patch for localhost * file name fixed * removed docker from launchSettings. * Configure logging via appsettings Co-authored-by: Shady Nagy <info@shadynagy.com>main
committed by
GitHub
77 changed files with 866 additions and 534 deletions
@ -0,0 +1,19 @@ |
|||
using System; |
|||
|
|||
namespace BlazorAdmin.Services |
|||
{ |
|||
public class CacheEntry<T> |
|||
{ |
|||
public CacheEntry(T item) |
|||
{ |
|||
Value = item; |
|||
} |
|||
public CacheEntry() |
|||
{ |
|||
|
|||
} |
|||
|
|||
public T Value { get; set; } |
|||
public DateTime DateCreated { get; set; } = DateTime.UtcNow; |
|||
} |
|||
} |
|||
@ -0,0 +1,59 @@ |
|||
using Blazored.LocalStorage; |
|||
using BlazorShared.Interfaces; |
|||
using BlazorShared.Models; |
|||
using Microsoft.Extensions.Logging; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace BlazorAdmin.Services |
|||
{ |
|||
public class CachedCatalogBrandServiceDecorator : ICatalogBrandService |
|||
{ |
|||
// TODO: Make a generic decorator for any LookupData type
|
|||
private readonly ILocalStorageService _localStorageService; |
|||
private readonly CatalogBrandService _catalogBrandService; |
|||
private ILogger<CachedCatalogBrandServiceDecorator> _logger; |
|||
|
|||
public CachedCatalogBrandServiceDecorator(ILocalStorageService localStorageService, |
|||
CatalogBrandService catalogBrandService, |
|||
ILogger<CachedCatalogBrandServiceDecorator> logger) |
|||
{ |
|||
_localStorageService = localStorageService; |
|||
_catalogBrandService = catalogBrandService; |
|||
_logger = logger; |
|||
|
|||
} |
|||
|
|||
public async Task<CatalogBrand> GetById(int id) |
|||
{ |
|||
return (await List()).FirstOrDefault(x => x.Id == id); |
|||
} |
|||
|
|||
public async Task<List<CatalogBrand>> List() |
|||
{ |
|||
string key = "brands"; |
|||
var cacheEntry = await _localStorageService.GetItemAsync<CacheEntry<List<CatalogBrand>>>(key); |
|||
if (cacheEntry != null) |
|||
{ |
|||
_logger.LogInformation("Loading brands from local storage."); |
|||
// TODO: Get Default Cache Duration from Config
|
|||
if (cacheEntry.DateCreated.AddMinutes(1) > DateTime.UtcNow) |
|||
{ |
|||
return cacheEntry.Value; |
|||
} |
|||
else |
|||
{ |
|||
_logger.LogInformation("Cache expired; removing brands from local storage."); |
|||
await _localStorageService.RemoveItemAsync(key); |
|||
} |
|||
} |
|||
|
|||
var brands = await _catalogBrandService.List(); |
|||
var entry = new CacheEntry<List<CatalogBrand>>(brands); |
|||
await _localStorageService.SetItemAsync(key, entry); |
|||
return brands; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,114 @@ |
|||
using Blazored.LocalStorage; |
|||
using BlazorShared.Interfaces; |
|||
using BlazorShared.Models; |
|||
using Microsoft.Extensions.Logging; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace BlazorAdmin.Services |
|||
{ |
|||
public class CachedCatalogItemServiceDecorator : ICatalogItemService |
|||
{ |
|||
private readonly ILocalStorageService _localStorageService; |
|||
private readonly CatalogItemService _catalogItemService; |
|||
private ILogger<CachedCatalogItemServiceDecorator> _logger; |
|||
|
|||
public CachedCatalogItemServiceDecorator(ILocalStorageService localStorageService, |
|||
CatalogItemService catalogItemService, |
|||
ILogger<CachedCatalogItemServiceDecorator> logger) |
|||
{ |
|||
_localStorageService = localStorageService; |
|||
_catalogItemService = catalogItemService; |
|||
_logger = logger; |
|||
} |
|||
|
|||
public async Task<List<CatalogItem>> ListPaged(int pageSize) |
|||
{ |
|||
string key = "items"; |
|||
var cacheEntry = await _localStorageService.GetItemAsync<CacheEntry<List<CatalogItem>>>(key); |
|||
if (cacheEntry != null) |
|||
{ |
|||
_logger.LogInformation("Loading items from local storage."); |
|||
if (cacheEntry.DateCreated.AddMinutes(1) > DateTime.UtcNow) |
|||
{ |
|||
return cacheEntry.Value; |
|||
} |
|||
else |
|||
{ |
|||
_logger.LogInformation($"Loading {key} from local storage."); |
|||
await _localStorageService.RemoveItemAsync(key); |
|||
} |
|||
} |
|||
|
|||
var items = await _catalogItemService.ListPaged(pageSize); |
|||
var entry = new CacheEntry<List<CatalogItem>>(items); |
|||
await _localStorageService.SetItemAsync(key, entry); |
|||
return items; |
|||
} |
|||
|
|||
public async Task<List<CatalogItem>> List() |
|||
{ |
|||
string key = "items"; |
|||
var cacheEntry = await _localStorageService.GetItemAsync<CacheEntry<List<CatalogItem>>>(key); |
|||
if (cacheEntry != null) |
|||
{ |
|||
_logger.LogInformation("Loading items from local storage."); |
|||
if (cacheEntry.DateCreated.AddMinutes(1) > DateTime.UtcNow) |
|||
{ |
|||
return cacheEntry.Value; |
|||
} |
|||
else |
|||
{ |
|||
_logger.LogInformation($"Loading {key} from local storage."); |
|||
await _localStorageService.RemoveItemAsync(key); |
|||
} |
|||
} |
|||
|
|||
var items = await _catalogItemService.List(); |
|||
var entry = new CacheEntry<List<CatalogItem>>(items); |
|||
await _localStorageService.SetItemAsync(key, entry); |
|||
return items; |
|||
} |
|||
|
|||
public async Task<CatalogItem> GetById(int id) |
|||
{ |
|||
return (await List()).FirstOrDefault(x => x.Id == id); |
|||
} |
|||
|
|||
public async Task<CatalogItem> Create(CreateCatalogItemRequest catalogItem) |
|||
{ |
|||
var result = await _catalogItemService.Create(catalogItem); |
|||
await RefreshLocalStorageList(); |
|||
|
|||
return result; |
|||
} |
|||
|
|||
public async Task<CatalogItem> Edit(CatalogItem catalogItem) |
|||
{ |
|||
var result = await _catalogItemService.Edit(catalogItem); |
|||
await RefreshLocalStorageList(); |
|||
|
|||
return result; |
|||
} |
|||
|
|||
public async Task<string> Delete(int id) |
|||
{ |
|||
var result = await _catalogItemService.Delete(id); |
|||
await RefreshLocalStorageList(); |
|||
|
|||
return result; |
|||
} |
|||
|
|||
private async Task RefreshLocalStorageList() |
|||
{ |
|||
string key = "items"; |
|||
|
|||
await _localStorageService.RemoveItemAsync(key); |
|||
var items = await _catalogItemService.List(); |
|||
var entry = new CacheEntry<List<CatalogItem>>(items); |
|||
await _localStorageService.SetItemAsync(key, entry); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,57 @@ |
|||
using Blazored.LocalStorage; |
|||
using BlazorShared.Interfaces; |
|||
using BlazorShared.Models; |
|||
using Microsoft.Extensions.Logging; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace BlazorAdmin.Services |
|||
{ |
|||
public class CachedCatalogTypeServiceDecorator : ICatalogTypeService |
|||
{ |
|||
// TODO: Make a generic decorator for any LookupData type
|
|||
private readonly ILocalStorageService _localStorageService; |
|||
private readonly CatalogTypeService _catalogTypeService; |
|||
private ILogger<CachedCatalogTypeServiceDecorator> _logger; |
|||
|
|||
public CachedCatalogTypeServiceDecorator(ILocalStorageService localStorageService, |
|||
CatalogTypeService catalogTypeService, |
|||
ILogger<CachedCatalogTypeServiceDecorator> logger) |
|||
{ |
|||
_localStorageService = localStorageService; |
|||
_catalogTypeService = catalogTypeService; |
|||
_logger = logger; |
|||
} |
|||
|
|||
public async Task<CatalogType> GetById(int id) |
|||
{ |
|||
return (await List()).FirstOrDefault(x => x.Id == id); |
|||
} |
|||
|
|||
public async Task<List<CatalogType>> List() |
|||
{ |
|||
string key = "types"; |
|||
var cacheEntry = await _localStorageService.GetItemAsync<CacheEntry<List<CatalogType>>>(key); |
|||
if (cacheEntry != null) |
|||
{ |
|||
_logger.LogInformation("Loading types from local storage."); |
|||
if (cacheEntry.DateCreated.AddMinutes(1) > DateTime.UtcNow) |
|||
{ |
|||
return cacheEntry.Value; |
|||
} |
|||
else |
|||
{ |
|||
_logger.LogInformation("Cache expired; removing types from local storage."); |
|||
await _localStorageService.RemoveItemAsync(key); |
|||
} |
|||
} |
|||
|
|||
var types = await _catalogTypeService.List(); |
|||
var entry = new CacheEntry<List<CatalogType>>(types); |
|||
await _localStorageService.SetItemAsync(key, entry); |
|||
return types; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,41 @@ |
|||
using BlazorShared; |
|||
using BlazorShared.Interfaces; |
|||
using BlazorShared.Models; |
|||
using Microsoft.Extensions.Logging; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Net.Http; |
|||
using System.Net.Http.Json; |
|||
using System.Threading.Tasks; |
|||
|
|||
|
|||
namespace BlazorAdmin.Services |
|||
{ |
|||
public class CatalogBrandService : ICatalogBrandService |
|||
{ |
|||
// TODO: Make a generic service for any LookupData type
|
|||
private readonly HttpClient _httpClient; |
|||
private readonly ILogger<CatalogBrandService> _logger; |
|||
private string _apiUrl; |
|||
|
|||
public CatalogBrandService(HttpClient httpClient, |
|||
BaseUrlConfiguration baseUrlConfiguration, |
|||
ILogger<CatalogBrandService> logger) |
|||
{ |
|||
_httpClient = httpClient; |
|||
_logger = logger; |
|||
_apiUrl = baseUrlConfiguration.ApiBase; |
|||
} |
|||
|
|||
public async Task<CatalogBrand> GetById(int id) |
|||
{ |
|||
return (await List()).FirstOrDefault(x => x.Id == id); |
|||
} |
|||
|
|||
public async Task<List<CatalogBrand>> List() |
|||
{ |
|||
_logger.LogInformation("Fetching brands from API."); |
|||
return (await _httpClient.GetFromJsonAsync<CatalogBrandResponse>($"{_apiUrl}catalog-brands"))?.CatalogBrands; |
|||
} |
|||
} |
|||
} |
|||
@ -1,8 +0,0 @@ |
|||
namespace BlazorAdmin.Services.CatalogBrandServices |
|||
{ |
|||
public class CatalogBrand |
|||
{ |
|||
public int Id { get; set; } |
|||
public string Name { get; set; } |
|||
} |
|||
} |
|||
@ -1,33 +0,0 @@ |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Net.Http; |
|||
using System.Net.Http.Json; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace BlazorAdmin.Services.CatalogBrandServices |
|||
{ |
|||
public class List |
|||
{ |
|||
private readonly AuthService _authService; |
|||
private readonly HttpClient _httpClient; |
|||
|
|||
public List(AuthService authService, HttpClient httpClient) |
|||
{ |
|||
_authService = authService; |
|||
_httpClient = httpClient; |
|||
} |
|||
|
|||
public async Task<List<CatalogBrand>> HandleAsync() |
|||
{ |
|||
return (await _httpClient.GetFromJsonAsync<CatalogBrandResult>($"{_authService.ApiUrl}catalog-brands"))?.CatalogBrands; |
|||
} |
|||
|
|||
public static string GetBrandName(IEnumerable<CatalogBrand> brands, int brandId) |
|||
{ |
|||
var type = brands.FirstOrDefault(t => t.Id == brandId); |
|||
|
|||
return type == null ? "None" : type.Name; |
|||
} |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,102 @@ |
|||
using BlazorShared; |
|||
using BlazorShared.Interfaces; |
|||
using BlazorShared.Models; |
|||
using Microsoft.Extensions.Logging; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
|
|||
|
|||
namespace BlazorAdmin.Services |
|||
{ |
|||
public class CatalogItemService : ICatalogItemService |
|||
{ |
|||
private readonly ICatalogBrandService _brandService; |
|||
private readonly ICatalogTypeService _typeService; |
|||
private readonly HttpService _httpService; |
|||
private readonly ILogger<CatalogItemService> _logger; |
|||
private string _apiUrl; |
|||
|
|||
public CatalogItemService(ICatalogBrandService brandService, |
|||
ICatalogTypeService typeService, |
|||
HttpService httpService, |
|||
BaseUrlConfiguration baseUrlConfiguration, |
|||
ILogger<CatalogItemService> logger) |
|||
{ |
|||
_brandService = brandService; |
|||
_typeService = typeService; |
|||
|
|||
_httpService = httpService; |
|||
_logger = logger; |
|||
_apiUrl = baseUrlConfiguration.ApiBase; |
|||
} |
|||
|
|||
public async Task<CatalogItem> Create(CreateCatalogItemRequest catalogItem) |
|||
{ |
|||
return (await _httpService.HttpPost<CreateCatalogItemResponse>("catalog-items", catalogItem)).CatalogItem; |
|||
} |
|||
|
|||
public async Task<CatalogItem> Edit(CatalogItem catalogItem) |
|||
{ |
|||
return (await _httpService.HttpPut<EditCatalogItemResult>("catalog-items", catalogItem)).CatalogItem; |
|||
} |
|||
|
|||
public async Task<string> Delete(int catalogItemId) |
|||
{ |
|||
return (await _httpService.HttpDelete<DeleteCatalogItemResponse>("catalog-items", catalogItemId)).Status; |
|||
} |
|||
|
|||
public async Task<CatalogItem> GetById(int id) |
|||
{ |
|||
var brandListTask = _brandService.List(); |
|||
var typeListTask = _typeService.List(); |
|||
var itemGetTask = _httpService.HttpGet<EditCatalogItemResult>($"catalog-items/{id}"); |
|||
await Task.WhenAll(brandListTask, typeListTask, itemGetTask); |
|||
var brands = brandListTask.Result; |
|||
var types = typeListTask.Result; |
|||
var catalogItem = itemGetTask.Result.CatalogItem; |
|||
catalogItem.CatalogBrand = brands.FirstOrDefault(b => b.Id == catalogItem.CatalogBrandId)?.Name; |
|||
catalogItem.CatalogType = types.FirstOrDefault(t => t.Id == catalogItem.CatalogTypeId)?.Name; |
|||
return catalogItem; |
|||
} |
|||
|
|||
public async Task<List<CatalogItem>> ListPaged(int pageSize) |
|||
{ |
|||
_logger.LogInformation("Fetching catalog items from API."); |
|||
|
|||
var brandListTask = _brandService.List(); |
|||
var typeListTask = _typeService.List(); |
|||
var itemListTask = _httpService.HttpGet<PagedCatalogItemResponse>($"catalog-items?PageSize=10"); |
|||
await Task.WhenAll(brandListTask, typeListTask, itemListTask); |
|||
var brands = brandListTask.Result; |
|||
var types = typeListTask.Result; |
|||
var items = itemListTask.Result.CatalogItems; |
|||
foreach (var item in items) |
|||
{ |
|||
item.CatalogBrand = brands.FirstOrDefault(b => b.Id == item.CatalogBrandId)?.Name; |
|||
item.CatalogType = types.FirstOrDefault(t => t.Id == item.CatalogTypeId)?.Name; |
|||
} |
|||
return items; |
|||
} |
|||
|
|||
public async Task<List<CatalogItem>> List() |
|||
{ |
|||
_logger.LogInformation("Fetching catalog items from API."); |
|||
|
|||
var brandListTask = _brandService.List(); |
|||
var typeListTask = _typeService.List(); |
|||
//TODO: Need to change the api to support full list
|
|||
var itemListTask = _httpService.HttpGet<PagedCatalogItemResponse>($"catalog-items?PageSize=100"); |
|||
await Task.WhenAll(brandListTask, typeListTask, itemListTask); |
|||
var brands = brandListTask.Result; |
|||
var types = typeListTask.Result; |
|||
var items = itemListTask.Result.CatalogItems; |
|||
foreach (var item in items) |
|||
{ |
|||
item.CatalogBrand = brands.FirstOrDefault(b => b.Id == item.CatalogBrandId)?.Name; |
|||
item.CatalogType = types.FirstOrDefault(t => t.Id == item.CatalogTypeId)?.Name; |
|||
} |
|||
return items; |
|||
} |
|||
} |
|||
} |
|||
@ -1,7 +0,0 @@ |
|||
namespace BlazorAdmin.Services.CatalogItemServices |
|||
{ |
|||
public class CreateCatalogItemResult |
|||
{ |
|||
public CatalogItem CatalogItem { get; set; } = new CatalogItem(); |
|||
} |
|||
} |
|||
@ -1,19 +0,0 @@ |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace BlazorAdmin.Services.CatalogItemServices |
|||
{ |
|||
public class Create |
|||
{ |
|||
private readonly HttpService _httpService; |
|||
|
|||
public Create(AuthService authService) |
|||
{ |
|||
_httpService = new HttpService(authService.GetHttpClient(), authService.ApiUrl); |
|||
} |
|||
|
|||
public async Task<CatalogItem> HandleAsync(CreateCatalogItemRequest catalogItem) |
|||
{ |
|||
return (await _httpService.HttpPost<CreateCatalogItemResult>("catalog-items", catalogItem)).CatalogItem; |
|||
} |
|||
} |
|||
} |
|||
@ -1,7 +0,0 @@ |
|||
namespace BlazorAdmin.Services.CatalogItemServices |
|||
{ |
|||
public class DeleteCatalogItemResult |
|||
{ |
|||
public string Status { get; set; } = "Deleted"; |
|||
} |
|||
} |
|||
@ -1,19 +0,0 @@ |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace BlazorAdmin.Services.CatalogItemServices |
|||
{ |
|||
public class Delete |
|||
{ |
|||
private readonly HttpService _httpService; |
|||
|
|||
public Delete(AuthService authService) |
|||
{ |
|||
_httpService = new HttpService(authService.GetHttpClient(), authService.ApiUrl); |
|||
} |
|||
|
|||
public async Task<string> HandleAsync(int catalogItemId) |
|||
{ |
|||
return (await _httpService.HttpDelete<DeleteCatalogItemResult>("catalog-items", catalogItemId)).Status; |
|||
} |
|||
} |
|||
} |
|||
@ -1,19 +0,0 @@ |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace BlazorAdmin.Services.CatalogItemServices |
|||
{ |
|||
public class Edit |
|||
{ |
|||
private readonly HttpService _httpService; |
|||
|
|||
public Edit(AuthService authService) |
|||
{ |
|||
_httpService = new HttpService(authService.GetHttpClient(), authService.ApiUrl); |
|||
} |
|||
|
|||
public async Task<CatalogItem> HandleAsync(CatalogItem catalogItem) |
|||
{ |
|||
return (await _httpService.HttpPut<EditCatalogItemResult>("catalog-items", catalogItem)).CatalogItem; |
|||
} |
|||
} |
|||
} |
|||
@ -1,7 +0,0 @@ |
|||
namespace BlazorAdmin.Services.CatalogItemServices |
|||
{ |
|||
public class GetByIdCatalogItemResult |
|||
{ |
|||
public CatalogItem CatalogItem { get; set; } = new CatalogItem(); |
|||
} |
|||
} |
|||
@ -1,19 +0,0 @@ |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace BlazorAdmin.Services.CatalogItemServices |
|||
{ |
|||
public class GetById |
|||
{ |
|||
private readonly HttpService _httpService; |
|||
|
|||
public GetById(AuthService authService) |
|||
{ |
|||
_httpService = new HttpService(authService.GetHttpClient(), authService.ApiUrl); |
|||
} |
|||
|
|||
public async Task<CatalogItem> HandleAsync(int catalogItemId) |
|||
{ |
|||
return (await _httpService.HttpGet<EditCatalogItemResult>($"catalog-items/{catalogItemId}")).CatalogItem; |
|||
} |
|||
} |
|||
} |
|||
@ -1,21 +0,0 @@ |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace BlazorAdmin.Services.CatalogItemServices |
|||
{ |
|||
public class ListPaged |
|||
{ |
|||
private readonly HttpService _httpService; |
|||
|
|||
public ListPaged(AuthService authService) |
|||
{ |
|||
_httpService = new HttpService(authService.GetHttpClient(), authService.ApiUrl); |
|||
} |
|||
|
|||
public async Task<List<CatalogItem>> HandleAsync(int pageSize) |
|||
{ |
|||
return (await _httpService.HttpGet<PagedCatalogItemResult>($"catalog-items?PageSize={pageSize}")).CatalogItems; |
|||
} |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,40 @@ |
|||
using BlazorShared; |
|||
using BlazorShared.Interfaces; |
|||
using BlazorShared.Models; |
|||
using Microsoft.Extensions.Logging; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Net.Http; |
|||
using System.Net.Http.Json; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace BlazorAdmin.Services |
|||
{ |
|||
public class CatalogTypeService : ICatalogTypeService |
|||
{ |
|||
// TODO: Make a generic service for any LookupData type
|
|||
private readonly HttpClient _httpClient; |
|||
private readonly ILogger<CatalogTypeService> _logger; |
|||
private string _apiUrl; |
|||
|
|||
public CatalogTypeService(HttpClient httpClient, |
|||
BaseUrlConfiguration baseUrlConfiguration, |
|||
ILogger<CatalogTypeService> logger) |
|||
{ |
|||
_httpClient = httpClient; |
|||
_logger = logger; |
|||
_apiUrl = baseUrlConfiguration.ApiBase; |
|||
} |
|||
|
|||
public async Task<CatalogType> GetById(int id) |
|||
{ |
|||
return (await List()).FirstOrDefault(x => x.Id == id); |
|||
} |
|||
|
|||
public async Task<List<CatalogType>> List() |
|||
{ |
|||
_logger.LogInformation("Fetching types from API."); |
|||
return (await _httpClient.GetFromJsonAsync<CatalogTypeResponse>($"{_apiUrl}catalog-types"))?.CatalogTypes; |
|||
} |
|||
} |
|||
} |
|||
@ -1,8 +0,0 @@ |
|||
namespace BlazorAdmin.Services.CatalogTypeServices |
|||
{ |
|||
public class CatalogType |
|||
{ |
|||
public int Id { get; set; } |
|||
public string Name { get; set; } |
|||
} |
|||
} |
|||
@ -1,33 +0,0 @@ |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Net.Http; |
|||
using System.Net.Http.Json; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace BlazorAdmin.Services.CatalogTypeServices |
|||
{ |
|||
public class List |
|||
{ |
|||
private readonly AuthService _authService; |
|||
private readonly HttpClient _httpClient; |
|||
|
|||
public List(AuthService authService, HttpClient httpClient) |
|||
{ |
|||
_authService = authService; |
|||
_httpClient = httpClient; |
|||
} |
|||
|
|||
public async Task<List<CatalogType>> HandleAsync() |
|||
{ |
|||
return (await _httpClient.GetFromJsonAsync<CatalogTypeResult>($"{_authService.ApiUrl}catalog-types"))?.CatalogTypes; |
|||
} |
|||
|
|||
public static string GetTypeName(IEnumerable<CatalogType> types, int typeId) |
|||
{ |
|||
var type = types.FirstOrDefault(t => t.Id == typeId); |
|||
|
|||
return type == null ? "None" : type.Name; |
|||
} |
|||
|
|||
} |
|||
} |
|||
@ -1,22 +1,21 @@ |
|||
using BlazorAdmin.Services.CatalogItemServices; |
|||
using BlazorAdmin.Services; |
|||
using BlazorShared.Interfaces; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
|
|||
namespace BlazorAdmin |
|||
{ |
|||
public static class ServicesConfiguration |
|||
{ |
|||
public static IServiceCollection AddBlazorServices(this IServiceCollection service) |
|||
public static IServiceCollection AddBlazorServices(this IServiceCollection services) |
|||
{ |
|||
service.AddScoped<Create>(); |
|||
service.AddScoped<ListPaged>(); |
|||
service.AddScoped<Delete>(); |
|||
service.AddScoped<Edit>(); |
|||
service.AddScoped<GetById>(); |
|||
services.AddScoped<ICatalogBrandService, CachedCatalogBrandServiceDecorator>(); |
|||
services.AddScoped<CatalogBrandService>(); |
|||
services.AddScoped<ICatalogTypeService, CachedCatalogTypeServiceDecorator>(); |
|||
services.AddScoped<CatalogTypeService>(); |
|||
services.AddScoped<ICatalogItemService, CachedCatalogItemServiceDecorator>(); |
|||
services.AddScoped<CatalogItemService>(); |
|||
|
|||
service.AddScoped<BlazorAdmin.Services.CatalogBrandServices.List>(); |
|||
service.AddScoped<BlazorAdmin.Services.CatalogTypeServices.List>(); |
|||
|
|||
return service; |
|||
return services; |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,38 @@ |
|||
using Microsoft.AspNetCore.Components.Forms; |
|||
|
|||
namespace BlazorAdmin.Shared |
|||
{ |
|||
/// <summary>
|
|||
/// This is needed until 5.0 ships with native support
|
|||
/// https://www.pragimtech.com/blog/blazor/inputselect-does-not-support-system.int32/
|
|||
/// </summary>
|
|||
/// <typeparam name="TValue"></typeparam>
|
|||
public class CustomInputSelect<TValue> : InputSelect<TValue> |
|||
{ |
|||
protected override bool TryParseValueFromString(string value, out TValue result, |
|||
out string validationErrorMessage) |
|||
{ |
|||
if (typeof(TValue) == typeof(int)) |
|||
{ |
|||
if (int.TryParse(value, out var resultInt)) |
|||
{ |
|||
result = (TValue)(object)resultInt; |
|||
validationErrorMessage = null; |
|||
return true; |
|||
} |
|||
else |
|||
{ |
|||
result = default; |
|||
validationErrorMessage = |
|||
$"The selected value {value} is not a valid number."; |
|||
return false; |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
return base.TryParseValueFromString(value, out result, |
|||
out validationErrorMessage); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
{ |
|||
"baseUrls": { |
|||
"apiBase": "http://localhost:5200/api/", |
|||
"webBase": "http://host.docker.internal:5106/" |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
{ |
|||
"baseUrls": { |
|||
"apiBase": "https://localhost:5099/api/", |
|||
"webBase": "https://localhost:44315/" |
|||
}, |
|||
"Logging": { |
|||
"IncludeScopes": false, |
|||
"LogLevel": { |
|||
"Default": "Information", |
|||
"Microsoft": "Warning", |
|||
"System": "Warning" |
|||
} |
|||
} |
|||
} |
|||
@ -1,27 +0,0 @@ |
|||
[ |
|||
{ |
|||
"date": "2018-05-06", |
|||
"temperatureC": 1, |
|||
"summary": "Freezing" |
|||
}, |
|||
{ |
|||
"date": "2018-05-07", |
|||
"temperatureC": 14, |
|||
"summary": "Bracing" |
|||
}, |
|||
{ |
|||
"date": "2018-05-08", |
|||
"temperatureC": -13, |
|||
"summary": "Freezing" |
|||
}, |
|||
{ |
|||
"date": "2018-05-09", |
|||
"temperatureC": -16, |
|||
"summary": "Balmy" |
|||
}, |
|||
{ |
|||
"date": "2018-05-10", |
|||
"temperatureC": -2, |
|||
"summary": "Chilly" |
|||
} |
|||
] |
|||
@ -0,0 +1,10 @@ |
|||
namespace BlazorShared |
|||
{ |
|||
public class BaseUrlConfiguration |
|||
{ |
|||
public const string CONFIG_NAME = "baseUrls"; |
|||
|
|||
public string ApiBase { get; set; } |
|||
public string WebBase { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using BlazorShared.Models; |
|||
|
|||
namespace BlazorShared.Interfaces |
|||
{ |
|||
public interface ICatalogBrandService |
|||
{ |
|||
Task<List<CatalogBrand>> List(); |
|||
Task<CatalogBrand> GetById(int id); |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using BlazorShared.Models; |
|||
|
|||
namespace BlazorShared.Interfaces |
|||
{ |
|||
public interface ICatalogItemService |
|||
{ |
|||
Task<CatalogItem> Create(CreateCatalogItemRequest catalogItem); |
|||
Task<CatalogItem> Edit(CatalogItem catalogItem); |
|||
Task<string> Delete(int id); |
|||
Task<CatalogItem> GetById(int id); |
|||
Task<List<CatalogItem>> ListPaged(int pageSize); |
|||
Task<List<CatalogItem>> List(); |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
using BlazorShared.Models; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace BlazorShared.Interfaces |
|||
{ |
|||
public interface ICatalogTypeService |
|||
{ |
|||
Task<List<CatalogType>> List(); |
|||
Task<CatalogType> GetById(int id); |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
namespace BlazorShared.Models |
|||
{ |
|||
public class CatalogBrand : LookupData |
|||
{ |
|||
} |
|||
} |
|||
@ -1,8 +1,8 @@ |
|||
using System.Collections.Generic; |
|||
|
|||
namespace BlazorAdmin.Services.CatalogBrandServices |
|||
namespace BlazorShared.Models |
|||
{ |
|||
public class CatalogBrandResult |
|||
public class CatalogBrandResponse |
|||
{ |
|||
public List<CatalogBrand> CatalogBrands { get; set; } = new List<CatalogBrand>(); |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
namespace BlazorShared.Models |
|||
{ |
|||
public class CatalogType : LookupData |
|||
{ |
|||
} |
|||
} |
|||
@ -1,8 +1,8 @@ |
|||
using System.Collections.Generic; |
|||
|
|||
namespace BlazorAdmin.Services.CatalogTypeServices |
|||
namespace BlazorShared.Models |
|||
{ |
|||
public class CatalogTypeResult |
|||
public class CatalogTypeResponse |
|||
{ |
|||
public List<CatalogType> CatalogTypes { get; set; } = new List<CatalogType>(); |
|||
} |
|||
@ -1,6 +1,6 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace BlazorAdmin.Services.CatalogItemServices |
|||
namespace BlazorShared.Models |
|||
{ |
|||
public class CreateCatalogItemRequest |
|||
{ |
|||
@ -0,0 +1,7 @@ |
|||
namespace BlazorShared.Models |
|||
{ |
|||
public class CreateCatalogItemResponse |
|||
{ |
|||
public CatalogItem CatalogItem { get; set; } = new CatalogItem(); |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
namespace BlazorShared.Models |
|||
{ |
|||
public class DeleteCatalogItemResponse |
|||
{ |
|||
public string Status { get; set; } = "Deleted"; |
|||
} |
|||
} |
|||
@ -1,4 +1,4 @@ |
|||
namespace BlazorAdmin.Services.CatalogItemServices |
|||
namespace BlazorShared.Models |
|||
{ |
|||
public class EditCatalogItemResult |
|||
{ |
|||
@ -0,0 +1,8 @@ |
|||
namespace BlazorShared.Models |
|||
{ |
|||
public abstract class LookupData |
|||
{ |
|||
public int Id { get; set; } |
|||
public string Name { get; set; } |
|||
} |
|||
} |
|||
@ -1,8 +1,8 @@ |
|||
using System.Collections.Generic; |
|||
|
|||
namespace BlazorAdmin.Services.CatalogItemServices |
|||
namespace BlazorShared.Models |
|||
{ |
|||
public class PagedCatalogItemResult |
|||
public class PagedCatalogItemResponse |
|||
{ |
|||
public List<CatalogItem> CatalogItems { get; set; } = new List<CatalogItem>(); |
|||
public int PageCount { get; set; } = 0; |
|||
@ -0,0 +1,17 @@ |
|||
{ |
|||
"ConnectionStrings": { |
|||
"CatalogConnection": "Server=(localdb)\\mssqllocaldb;Integrated Security=true;Initial Catalog=Microsoft.eShopOnWeb.CatalogDb;", |
|||
"IdentityConnection": "Server=(localdb)\\mssqllocaldb;Integrated Security=true;Initial Catalog=Microsoft.eShopOnWeb.Identity;" |
|||
}, |
|||
"baseUrls": { |
|||
"apiBase": "http://localhost:5200/api/", |
|||
"webBase": "http://host.docker.internal:5106/" |
|||
}, |
|||
"Logging": { |
|||
"LogLevel": { |
|||
"Default": "Information", |
|||
"Microsoft": "Warning", |
|||
"Microsoft.Hosting.Lifetime": "Information" |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
{ |
|||
"ConnectionStrings": { |
|||
"CatalogConnection": "Server=(localdb)\\mssqllocaldb;Integrated Security=true;Initial Catalog=Microsoft.eShopOnWeb.CatalogDb;", |
|||
"IdentityConnection": "Server=(localdb)\\mssqllocaldb;Integrated Security=true;Initial Catalog=Microsoft.eShopOnWeb.Identity;" |
|||
}, |
|||
"baseUrls": { |
|||
"apiBase": "http://localhost:5200/api/", |
|||
"webBase": "http://host.docker.internal:5106/" |
|||
}, |
|||
"Logging": { |
|||
"LogLevel": { |
|||
"Default": "Debug", |
|||
"System": "Information", |
|||
"Microsoft": "Information" |
|||
} |
|||
} |
|||
} |
|||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 27 KiB |
Loading…
Reference in new issue