Updating Blazor Admin (#442)
* 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>
This commit is contained in:
@@ -6,23 +6,5 @@
|
||||
{
|
||||
public const string ADMINISTRATORS = "Administrators";
|
||||
}
|
||||
public static string GetApiUrl(bool inDocker) =>
|
||||
inDocker ? DOCKER_API_URL : API_URL;
|
||||
|
||||
public static string GetWebUrl(bool inDocker) =>
|
||||
inDocker ? DOCKER_WEB_URL : WEB_URL;
|
||||
|
||||
public static string GetWebUrlInternal(bool inDocker) =>
|
||||
inDocker ? DOCKER_WEB_URL.Replace("localhost", "host.docker.internal") : WEB_URL;
|
||||
|
||||
public static string GetOriginWebUrl(bool inDocker) =>
|
||||
GetWebUrl(inDocker).TrimEnd('/');
|
||||
|
||||
private const string API_URL = "https://localhost:5099/api/";
|
||||
private const string DOCKER_API_URL = "http://localhost:5200/api/";
|
||||
|
||||
private const string WEB_URL = "https://localhost:44315/";
|
||||
private const string DOCKER_WEB_URL = "http://localhost:5106/";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace BlazorShared.Authorization
|
||||
public bool IsAuthenticated { get; set; }
|
||||
public string NameClaimType { get; set; }
|
||||
public string RoleClaimType { get; set; }
|
||||
public string Token { get; set; }
|
||||
public IEnumerable<ClaimValue> Claims { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
10
src/BlazorShared/BaseUrlConfiguration.cs
Normal file
10
src/BlazorShared/BaseUrlConfiguration.cs
Normal file
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -6,4 +6,8 @@
|
||||
<AssemblyName>BlazorShared</AssemblyName>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BlazorInputFile" Version="0.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
12
src/BlazorShared/Interfaces/ICatalogBrandService.cs
Normal file
12
src/BlazorShared/Interfaces/ICatalogBrandService.cs
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
16
src/BlazorShared/Interfaces/ICatalogItemService.cs
Normal file
16
src/BlazorShared/Interfaces/ICatalogItemService.cs
Normal file
@@ -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();
|
||||
}
|
||||
}
|
||||
12
src/BlazorShared/Interfaces/ICatalogTypeService.cs
Normal file
12
src/BlazorShared/Interfaces/ICatalogTypeService.cs
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
6
src/BlazorShared/Models/CatalogBrand.cs
Normal file
6
src/BlazorShared/Models/CatalogBrand.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace BlazorShared.Models
|
||||
{
|
||||
public class CatalogBrand : LookupData
|
||||
{
|
||||
}
|
||||
}
|
||||
9
src/BlazorShared/Models/CatalogBrandResponse.cs
Normal file
9
src/BlazorShared/Models/CatalogBrandResponse.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BlazorShared.Models
|
||||
{
|
||||
public class CatalogBrandResponse
|
||||
{
|
||||
public List<CatalogBrand> CatalogBrands { get; set; } = new List<CatalogBrand>();
|
||||
}
|
||||
}
|
||||
88
src/BlazorShared/Models/CatalogItem.cs
Normal file
88
src/BlazorShared/Models/CatalogItem.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using BlazorInputFile;
|
||||
|
||||
namespace BlazorShared.Models
|
||||
{
|
||||
public class CatalogItem
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public int CatalogTypeId { get; set; }
|
||||
public string CatalogType { get; set; } = "NotSet";
|
||||
|
||||
public int CatalogBrandId { get; set; }
|
||||
public string CatalogBrand { get; set; } = "NotSet";
|
||||
|
||||
[Required(ErrorMessage = "The Name field is required")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "The Description field is required")]
|
||||
public string Description { get; set; }
|
||||
|
||||
// decimal(18,2)
|
||||
[RegularExpression(@"^\d+(\.\d{0,2})*$", ErrorMessage = "The field Price must be a positive number with maximum two decimals.")]
|
||||
[Range(0.01, 1000)]
|
||||
[DataType(DataType.Currency)]
|
||||
public decimal Price { get; set; }
|
||||
|
||||
public string PictureUri { get; set; }
|
||||
public string PictureBase64 { get; set; }
|
||||
public string PictureName { get; set; }
|
||||
|
||||
private const int ImageMinimumBytes = 512000;
|
||||
|
||||
public static string IsValidImage(string pictureName, string pictureBase64)
|
||||
{
|
||||
if (string.IsNullOrEmpty(pictureBase64))
|
||||
{
|
||||
return "File not found!";
|
||||
}
|
||||
var fileData = Convert.FromBase64String(pictureBase64);
|
||||
|
||||
if (fileData.Length <= 0)
|
||||
{
|
||||
return "File length is 0!";
|
||||
}
|
||||
|
||||
if (fileData.Length > ImageMinimumBytes)
|
||||
{
|
||||
return "Maximum length is 512KB";
|
||||
}
|
||||
|
||||
if (!IsExtensionValid(pictureName))
|
||||
{
|
||||
return "File is not image";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static async Task<string> DataToBase64(IFileListEntry fileItem)
|
||||
{
|
||||
using ( var reader = new StreamReader(fileItem.Data))
|
||||
{
|
||||
using (var memStream = new MemoryStream())
|
||||
{
|
||||
await reader.BaseStream.CopyToAsync(memStream);
|
||||
var fileData = memStream.ToArray();
|
||||
var encodedBase64 = Convert.ToBase64String(fileData);
|
||||
|
||||
return encodedBase64;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsExtensionValid(string fileName)
|
||||
{
|
||||
var extension = Path.GetExtension(fileName);
|
||||
|
||||
return string.Equals(extension, ".jpg", StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(extension, ".png", StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(extension, ".gif", StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(extension, ".jpeg", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
}
|
||||
6
src/BlazorShared/Models/CatalogType.cs
Normal file
6
src/BlazorShared/Models/CatalogType.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace BlazorShared.Models
|
||||
{
|
||||
public class CatalogType : LookupData
|
||||
{
|
||||
}
|
||||
}
|
||||
9
src/BlazorShared/Models/CatalogTypeResponse.cs
Normal file
9
src/BlazorShared/Models/CatalogTypeResponse.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BlazorShared.Models
|
||||
{
|
||||
public class CatalogTypeResponse
|
||||
{
|
||||
public List<CatalogType> CatalogTypes { get; set; } = new List<CatalogType>();
|
||||
}
|
||||
}
|
||||
28
src/BlazorShared/Models/CreateCatalogItemRequest.cs
Normal file
28
src/BlazorShared/Models/CreateCatalogItemRequest.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace BlazorShared.Models
|
||||
{
|
||||
public class CreateCatalogItemRequest
|
||||
{
|
||||
public int CatalogTypeId { get; set; }
|
||||
|
||||
public int CatalogBrandId { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "The Name field is required")]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
[Required(ErrorMessage = "The Description field is required")]
|
||||
public string Description { get; set; } = string.Empty;
|
||||
|
||||
// decimal(18,2)
|
||||
[RegularExpression(@"^\d+(\.\d{0,2})*$", ErrorMessage = "The field Price must be a positive number with maximum two decimals.")]
|
||||
[Range(0.01, 1000)]
|
||||
[DataType(DataType.Currency)]
|
||||
public decimal Price { get; set; } = 0;
|
||||
|
||||
public string PictureUri { get; set; } = string.Empty;
|
||||
public string PictureBase64 { get; set; } = string.Empty;
|
||||
public string PictureName { get; set; } = string.Empty;
|
||||
|
||||
}
|
||||
}
|
||||
7
src/BlazorShared/Models/CreateCatalogItemResponse.cs
Normal file
7
src/BlazorShared/Models/CreateCatalogItemResponse.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace BlazorShared.Models
|
||||
{
|
||||
public class CreateCatalogItemResponse
|
||||
{
|
||||
public CatalogItem CatalogItem { get; set; } = new CatalogItem();
|
||||
}
|
||||
}
|
||||
7
src/BlazorShared/Models/DeleteCatalogItemResponse.cs
Normal file
7
src/BlazorShared/Models/DeleteCatalogItemResponse.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace BlazorShared.Models
|
||||
{
|
||||
public class DeleteCatalogItemResponse
|
||||
{
|
||||
public string Status { get; set; } = "Deleted";
|
||||
}
|
||||
}
|
||||
7
src/BlazorShared/Models/EditCatalogItemResponse.cs
Normal file
7
src/BlazorShared/Models/EditCatalogItemResponse.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace BlazorShared.Models
|
||||
{
|
||||
public class EditCatalogItemResult
|
||||
{
|
||||
public CatalogItem CatalogItem { get; set; } = new CatalogItem();
|
||||
}
|
||||
}
|
||||
8
src/BlazorShared/Models/LookupData.cs
Normal file
8
src/BlazorShared/Models/LookupData.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace BlazorShared.Models
|
||||
{
|
||||
public abstract class LookupData
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
10
src/BlazorShared/Models/PagedCatalogItemResponse.cs
Normal file
10
src/BlazorShared/Models/PagedCatalogItemResponse.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BlazorShared.Models
|
||||
{
|
||||
public class PagedCatalogItemResponse
|
||||
{
|
||||
public List<CatalogItem> CatalogItems { get; set; } = new List<CatalogItem>();
|
||||
public int PageCount { get; set; } = 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user