From 57cca57400001be284a9a4b642fa8b4623658126 Mon Sep 17 00:00:00 2001 From: "hualin.zhu" Date: Tue, 13 Feb 2024 09:18:34 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20add=20partial=20class=20for=20Permi?= =?UTF-8?q?ssionSet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Customers/Caching/CustomerCacheKey.cs | 42 +- .../AddEdit/AddEditCustomerCommand.cs | 92 ++-- .../AddEditCustomerCommandValidator.cs | 13 +- .../Commands/Create/CreateCustomerCommand.cs | 77 ++- .../Create/CreateCustomerCommandValidator.cs | 18 +- .../Commands/Delete/DeleteCustomerCommand.cs | 69 ++- .../Delete/DeleteCustomerCommandValidator.cs | 14 +- .../Commands/Import/ImportCustomersCommand.cs | 151 +++--- .../Import/ImportCustomersCommandValidator.cs | 17 +- .../Commands/Update/UpdateCustomerCommand.cs | 77 ++- .../Update/UpdateCustomerCommandValidator.cs | 15 +- .../Features/Customers/DTOs/CustomerDto.cs | 14 +- .../CustomerCreatedEventHandler.cs | 27 +- .../CustomerDeletedEventHandler.cs | 27 +- .../CustomerUpdatedEventHandler.cs | 27 +- .../Queries/Export/ExportCustomersQuery.cs | 80 +-- .../Queries/GetAll/GetAllCustomersQuery.cs | 25 +- .../Queries/GetById/GetCustomerByIdQuery.cs | 21 +- .../Pagination/CustomersPaginationQuery.cs | 53 +- .../Specifications/CustomerAdvancedFilter.cs | 12 +- .../CustomerAdvancedSpecification.cs | 15 +- .../CustomerByIdSpecification.cs | 2 +- src/Infrastructure/DependencyInjection.cs | 2 +- src/Infrastructure/PermissionSet/Customers.cs | 23 + src/Infrastructure/PermissionSet/Documents.cs | 24 + .../PermissionModules.cs | 2 +- .../Permissions.cs | 59 +- src/Infrastructure/PermissionSet/Products.cs | 38 ++ .../ApplicationDbContextInitializer.cs | 2 +- .../Components/CustomerFormDialog.razor | 48 +- .../CustomersAdvancedSearchComponent.razor | 10 +- src/Server.UI/Pages/Customers/Customers.razor | 505 +++++++++--------- src/Server.UI/_Imports.razor | 4 +- 33 files changed, 806 insertions(+), 799 deletions(-) create mode 100644 src/Infrastructure/PermissionSet/Customers.cs create mode 100644 src/Infrastructure/PermissionSet/Documents.cs rename src/Infrastructure/{Constants/Permission => PermissionSet}/PermissionModules.cs (92%) rename src/Infrastructure/{Constants/Permission => PermissionSet}/Permissions.cs (65%) create mode 100644 src/Infrastructure/PermissionSet/Products.cs diff --git a/src/Application/Features/Customers/Caching/CustomerCacheKey.cs b/src/Application/Features/Customers/Caching/CustomerCacheKey.cs index 8652c14c5..cf6315c7d 100644 --- a/src/Application/Features/Customers/Caching/CustomerCacheKey.cs +++ b/src/Application/Features/Customers/Caching/CustomerCacheKey.cs @@ -5,41 +5,31 @@ namespace CleanArchitecture.Blazor.Application.Features.Customers.Caching; public static class CustomerCacheKey { - public const string GetAllCacheKey = "all-Customers"; private static readonly TimeSpan refreshInterval = TimeSpan.FromHours(3); - private static CancellationTokenSource _tokensource; - - static CustomerCacheKey() - { - _tokensource = new CancellationTokenSource(refreshInterval); - } - - public static MemoryCacheEntryOptions MemoryCacheEntryOptions => - new MemoryCacheEntryOptions().AddExpirationToken(new CancellationChangeToken(SharedExpiryTokenSource().Token)); - - public static string GetPaginationCacheKey(string parameters) - { + public const string GetAllCacheKey = "all-Customers"; + public static string GetPaginationCacheKey(string parameters) { return $"CustomerCacheKey:CustomersWithPaginationQuery,{parameters}"; } - - public static string GetByNameCacheKey(string parameters) - { + public static string GetByNameCacheKey(string parameters) { return $"CustomerCacheKey:GetByNameCacheKey,{parameters}"; } - - public static string GetByIdCacheKey(string parameters) - { + public static string GetByIdCacheKey(string parameters) { return $"CustomerCacheKey:GetByIdCacheKey,{parameters}"; } - + static CustomerCacheKey() + { + _tokensource = new CancellationTokenSource(refreshInterval); + } + private static CancellationTokenSource _tokensource; public static CancellationTokenSource SharedExpiryTokenSource() { - if (_tokensource.IsCancellationRequested) _tokensource = new CancellationTokenSource(refreshInterval); + if (_tokensource.IsCancellationRequested) + { + _tokensource = new CancellationTokenSource(refreshInterval); + } return _tokensource; } + public static void Refresh() => SharedExpiryTokenSource().Cancel(); + public static MemoryCacheEntryOptions MemoryCacheEntryOptions => new MemoryCacheEntryOptions().AddExpirationToken(new CancellationChangeToken(SharedExpiryTokenSource().Token)); +} - public static void Refresh() - { - SharedExpiryTokenSource().Cancel(); - } -} \ No newline at end of file diff --git a/src/Application/Features/Customers/Commands/AddEdit/AddEditCustomerCommand.cs b/src/Application/Features/Customers/Commands/AddEdit/AddEditCustomerCommand.cs index 5da21b515..b649270aa 100644 --- a/src/Application/Features/Customers/Commands/AddEdit/AddEditCustomerCommand.cs +++ b/src/Application/Features/Customers/Commands/AddEdit/AddEditCustomerCommand.cs @@ -1,70 +1,70 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using CleanArchitecture.Blazor.Application.Features.Customers.Caching; using CleanArchitecture.Blazor.Application.Features.Customers.DTOs; - +using CleanArchitecture.Blazor.Application.Features.Customers.Caching; namespace CleanArchitecture.Blazor.Application.Features.Customers.Commands.AddEdit; -public class AddEditCustomerCommand : ICacheInvalidatorRequest> +public class AddEditCustomerCommand: ICacheInvalidatorRequest> { - [Description("Id")] public int Id { get; set; } + [Description("Id")] + public int Id { get; set; } + [Description("Name")] + public string Name {get;set;} = String.Empty; + [Description("Description")] + public string? Description {get;set;} - [Description("Name")] public string Name { get; set; } = string.Empty; - [Description("Description")] public string? Description { get; set; } - - - public string CacheKey => CustomerCacheKey.GetAllCacheKey; - public CancellationTokenSource? SharedExpiryTokenSource => CustomerCacheKey.SharedExpiryTokenSource(); + public string CacheKey => CustomerCacheKey.GetAllCacheKey; + public CancellationTokenSource? SharedExpiryTokenSource => CustomerCacheKey.SharedExpiryTokenSource(); private class Mapping : Profile { public Mapping() { - CreateMap(MemberList.None); - CreateMap(MemberList.None); + CreateMap(MemberList.None); + CreateMap(MemberList.None); + } } } -public class AddEditCustomerCommandHandler : IRequestHandler> -{ - private readonly IApplicationDbContext _context; - private readonly IStringLocalizer _localizer; - private readonly IMapper _mapper; - - public AddEditCustomerCommandHandler( - IApplicationDbContext context, - IStringLocalizer localizer, - IMapper mapper - ) + public class AddEditCustomerCommandHandler : IRequestHandler> { - _context = context; - _localizer = localizer; - _mapper = mapper; - } - - public async Task> Handle(AddEditCustomerCommand request, CancellationToken cancellationToken) - { - if (request.Id > 0) + private readonly IApplicationDbContext _context; + private readonly IMapper _mapper; + private readonly IStringLocalizer _localizer; + public AddEditCustomerCommandHandler( + IApplicationDbContext context, + IStringLocalizer localizer, + IMapper mapper + ) { - var item = await _context.Customers.FindAsync(new object[] { request.Id }, cancellationToken) ?? - throw new NotFoundException($"Customer with id: [{request.Id}] not found."); - item = _mapper.Map(request, item); - // raise a update domain event - item.AddDomainEvent(new CustomerUpdatedEvent(item)); - await _context.SaveChangesAsync(cancellationToken); - return await Result.SuccessAsync(item.Id); + _context = context; + _localizer = localizer; + _mapper = mapper; } - else + public async Task> Handle(AddEditCustomerCommand request, CancellationToken cancellationToken) { - var item = _mapper.Map(request); - // raise a create domain event - item.AddDomainEvent(new CustomerCreatedEvent(item)); - _context.Customers.Add(item); - await _context.SaveChangesAsync(cancellationToken); - return await Result.SuccessAsync(item.Id); + if (request.Id > 0) + { + var item = await _context.Customers.FindAsync(new object[] { request.Id }, cancellationToken) ?? throw new NotFoundException($"Customer with id: [{request.Id}] not found."); + item = _mapper.Map(request, item); + // raise a update domain event + item.AddDomainEvent(new CustomerUpdatedEvent(item)); + await _context.SaveChangesAsync(cancellationToken); + return await Result.SuccessAsync(item.Id); + } + else + { + var item = _mapper.Map(request); + // raise a create domain event + item.AddDomainEvent(new CustomerCreatedEvent(item)); + _context.Customers.Add(item); + await _context.SaveChangesAsync(cancellationToken); + return await Result.SuccessAsync(item.Id); + } + } } -} \ No newline at end of file + diff --git a/src/Application/Features/Customers/Commands/AddEdit/AddEditCustomerCommandValidator.cs b/src/Application/Features/Customers/Commands/AddEdit/AddEditCustomerCommandValidator.cs index 06d3287c1..24bc7cab8 100644 --- a/src/Application/Features/Customers/Commands/AddEdit/AddEditCustomerCommandValidator.cs +++ b/src/Application/Features/Customers/Commands/AddEdit/AddEditCustomerCommandValidator.cs @@ -7,8 +7,11 @@ public class AddEditCustomerCommandValidator : AbstractValidator v.Name) - .MaximumLength(256) - .NotEmpty(); - } -} \ No newline at end of file + RuleFor(v => v.Name) + .MaximumLength(256) + .NotEmpty(); + + } + +} + diff --git a/src/Application/Features/Customers/Commands/Create/CreateCustomerCommand.cs b/src/Application/Features/Customers/Commands/Create/CreateCustomerCommand.cs index 9ec75b071..7022200e2 100644 --- a/src/Application/Features/Customers/Commands/Create/CreateCustomerCommand.cs +++ b/src/Application/Features/Customers/Commands/Create/CreateCustomerCommand.cs @@ -1,56 +1,55 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. - -using CleanArchitecture.Blazor.Application.Features.Customers.Caching; +using System.ComponentModel; using CleanArchitecture.Blazor.Application.Features.Customers.DTOs; +using CleanArchitecture.Blazor.Application.Features.Customers.Caching; namespace CleanArchitecture.Blazor.Application.Features.Customers.Commands.Create; -public class CreateCustomerCommand : ICacheInvalidatorRequest> +public class CreateCustomerCommand: ICacheInvalidatorRequest> { - [Description("Id")] public int Id { get; set; } - - [Description("Name")] public string Name { get; set; } = string.Empty; - - [Description("Description")] public string? Description { get; set; } - - public string CacheKey => CustomerCacheKey.GetAllCacheKey; - public CancellationTokenSource? SharedExpiryTokenSource => CustomerCacheKey.SharedExpiryTokenSource(); - + [Description("Id")] + public int Id { get; set; } + [Description("Name")] + public string Name {get;set;} = String.Empty; + [Description("Description")] + public string? Description {get;set;} + + public string CacheKey => CustomerCacheKey.GetAllCacheKey; + public CancellationTokenSource? SharedExpiryTokenSource => CustomerCacheKey.SharedExpiryTokenSource(); private class Mapping : Profile { public Mapping() { - CreateMap(MemberList.None); - CreateMap(MemberList.None); + CreateMap(MemberList.None); + CreateMap(MemberList.None); } } } - -public class CreateCustomerCommandHandler : IRequestHandler> -{ - private readonly IApplicationDbContext _context; - private readonly IStringLocalizer _localizer; - private readonly IMapper _mapper; - - public CreateCustomerCommandHandler( - IApplicationDbContext context, - IStringLocalizer localizer, - IMapper mapper - ) + + public class CreateCustomerCommandHandler : IRequestHandler> { - _context = context; - _localizer = localizer; - _mapper = mapper; + private readonly IApplicationDbContext _context; + private readonly IMapper _mapper; + private readonly IStringLocalizer _localizer; + public CreateCustomerCommandHandler( + IApplicationDbContext context, + IStringLocalizer localizer, + IMapper mapper + ) + { + _context = context; + _localizer = localizer; + _mapper = mapper; + } + public async Task> Handle(CreateCustomerCommand request, CancellationToken cancellationToken) + { + var item = _mapper.Map(request); + // raise a create domain event + item.AddDomainEvent(new CustomerCreatedEvent(item)); + _context.Customers.Add(item); + await _context.SaveChangesAsync(cancellationToken); + return await Result.SuccessAsync(item.Id); + } } - public async Task> Handle(CreateCustomerCommand request, CancellationToken cancellationToken) - { - var item = _mapper.Map(request); - // raise a create domain event - item.AddDomainEvent(new CustomerCreatedEvent(item)); - _context.Customers.Add(item); - await _context.SaveChangesAsync(cancellationToken); - return await Result.SuccessAsync(item.Id); - } -} \ No newline at end of file diff --git a/src/Application/Features/Customers/Commands/Create/CreateCustomerCommandValidator.cs b/src/Application/Features/Customers/Commands/Create/CreateCustomerCommandValidator.cs index 75aadf0ae..07b663c29 100644 --- a/src/Application/Features/Customers/Commands/Create/CreateCustomerCommandValidator.cs +++ b/src/Application/Features/Customers/Commands/Create/CreateCustomerCommandValidator.cs @@ -5,10 +5,14 @@ namespace CleanArchitecture.Blazor.Application.Features.Customers.Commands.Creat public class CreateCustomerCommandValidator : AbstractValidator { - public CreateCustomerCommandValidator() - { - RuleFor(v => v.Name) - .MaximumLength(256) - .NotEmpty(); - } -} \ No newline at end of file + public CreateCustomerCommandValidator() + { + + RuleFor(v => v.Name) + .MaximumLength(256) + .NotEmpty(); + + } + +} + diff --git a/src/Application/Features/Customers/Commands/Delete/DeleteCustomerCommand.cs b/src/Application/Features/Customers/Commands/Delete/DeleteCustomerCommand.cs index cc5c731e8..0b47278bd 100644 --- a/src/Application/Features/Customers/Commands/Delete/DeleteCustomerCommand.cs +++ b/src/Application/Features/Customers/Commands/Delete/DeleteCustomerCommand.cs @@ -3,50 +3,49 @@ using CleanArchitecture.Blazor.Application.Features.Customers.Caching; + namespace CleanArchitecture.Blazor.Application.Features.Customers.Commands.Delete; -public class DeleteCustomerCommand : ICacheInvalidatorRequest> -{ - public DeleteCustomerCommand(int[] id) + public class DeleteCustomerCommand: ICacheInvalidatorRequest> { + public int[] Id { get; } + public string CacheKey => CustomerCacheKey.GetAllCacheKey; + public CancellationTokenSource? SharedExpiryTokenSource => CustomerCacheKey.SharedExpiryTokenSource(); + public DeleteCustomerCommand(int[] id) + { Id = id; + } } - public int[] Id { get; } - public string CacheKey => CustomerCacheKey.GetAllCacheKey; - public CancellationTokenSource? SharedExpiryTokenSource => CustomerCacheKey.SharedExpiryTokenSource(); -} - -public class DeleteCustomerCommandHandler : - IRequestHandler> - -{ - private readonly IApplicationDbContext _context; - private readonly IStringLocalizer _localizer; - private readonly IMapper _mapper; + public class DeleteCustomerCommandHandler : + IRequestHandler> - public DeleteCustomerCommandHandler( - IApplicationDbContext context, - IStringLocalizer localizer, - IMapper mapper - ) { - _context = context; - _localizer = localizer; - _mapper = mapper; - } - - public async Task> Handle(DeleteCustomerCommand request, CancellationToken cancellationToken) - { - var items = await _context.Customers.Where(x => request.Id.Contains(x.Id)).ToListAsync(cancellationToken); - foreach (var item in items) + private readonly IApplicationDbContext _context; + private readonly IMapper _mapper; + private readonly IStringLocalizer _localizer; + public DeleteCustomerCommandHandler( + IApplicationDbContext context, + IStringLocalizer localizer, + IMapper mapper + ) + { + _context = context; + _localizer = localizer; + _mapper = mapper; + } + public async Task> Handle(DeleteCustomerCommand request, CancellationToken cancellationToken) { - // raise a delete domain event - item.AddDomainEvent(new CustomerDeletedEvent(item)); - _context.Customers.Remove(item); + var items = await _context.Customers.Where(x=>request.Id.Contains(x.Id)).ToListAsync(cancellationToken); + foreach (var item in items) + { + // raise a delete domain event + item.AddDomainEvent(new CustomerDeletedEvent(item)); + _context.Customers.Remove(item); + } + var result = await _context.SaveChangesAsync(cancellationToken); + return await Result.SuccessAsync(result); } - var result = await _context.SaveChangesAsync(cancellationToken); - return await Result.SuccessAsync(result); } -} \ No newline at end of file + diff --git a/src/Application/Features/Customers/Commands/Delete/DeleteCustomerCommandValidator.cs b/src/Application/Features/Customers/Commands/Delete/DeleteCustomerCommandValidator.cs index 93241aac1..32f8fafba 100644 --- a/src/Application/Features/Customers/Commands/Delete/DeleteCustomerCommandValidator.cs +++ b/src/Application/Features/Customers/Commands/Delete/DeleteCustomerCommandValidator.cs @@ -5,8 +5,12 @@ namespace CleanArchitecture.Blazor.Application.Features.Customers.Commands.Delet public class DeleteCustomerCommandValidator : AbstractValidator { - public DeleteCustomerCommandValidator() - { - RuleFor(v => v.Id).NotNull().ForEach(v => v.GreaterThan(0)); - } -} \ No newline at end of file + public DeleteCustomerCommandValidator() + { + + RuleFor(v => v.Id).NotNull().ForEach(v=>v.GreaterThan(0)); + + } +} + + diff --git a/src/Application/Features/Customers/Commands/Import/ImportCustomersCommand.cs b/src/Application/Features/Customers/Commands/Import/ImportCustomersCommand.cs index 42395de1e..8fbb86d39 100644 --- a/src/Application/Features/Customers/Commands/Import/ImportCustomersCommand.cs +++ b/src/Application/Features/Customers/Commands/Import/ImportCustomersCommand.cs @@ -1,99 +1,92 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using CleanArchitecture.Blazor.Application.Features.Customers.Caching; using CleanArchitecture.Blazor.Application.Features.Customers.DTOs; +using CleanArchitecture.Blazor.Application.Features.Customers.Caching; namespace CleanArchitecture.Blazor.Application.Features.Customers.Commands.Import; -public class ImportCustomersCommand : ICacheInvalidatorRequest> -{ - public ImportCustomersCommand(string fileName, byte[] data) + public class ImportCustomersCommand: ICacheInvalidatorRequest> { - FileName = fileName; - Data = data; + public string FileName { get; set; } + public byte[] Data { get; set; } + public string CacheKey => CustomerCacheKey.GetAllCacheKey; + public CancellationTokenSource? SharedExpiryTokenSource => CustomerCacheKey.SharedExpiryTokenSource(); + public ImportCustomersCommand(string fileName,byte[] data) + { + FileName = fileName; + Data = data; + } } - - public string FileName { get; set; } - public byte[] Data { get; set; } - public string CacheKey => CustomerCacheKey.GetAllCacheKey; - public CancellationTokenSource? SharedExpiryTokenSource => CustomerCacheKey.SharedExpiryTokenSource(); -} - -public record class CreateCustomersTemplateCommand : IRequest> -{ -} - -public class ImportCustomersCommandHandler : - IRequestHandler>, - IRequestHandler> -{ - private readonly IApplicationDbContext _context; - private readonly CustomerDto _dto = new(); - private readonly IExcelService _excelService; - private readonly IStringLocalizer _localizer; - private readonly IMapper _mapper; - - public ImportCustomersCommandHandler( - IApplicationDbContext context, - IExcelService excelService, - IStringLocalizer localizer, - IMapper mapper - ) + public record class CreateCustomersTemplateCommand : IRequest> { - _context = context; - _localizer = localizer; - _excelService = excelService; - _mapper = mapper; + } -#nullable disable warnings - public async Task> Handle(ImportCustomersCommand request, CancellationToken cancellationToken) + + public class ImportCustomersCommandHandler : + IRequestHandler>, + IRequestHandler> { - var result = await _excelService.ImportAsync(request.Data, - new Dictionary> + private readonly IApplicationDbContext _context; + private readonly IMapper _mapper; + private readonly IStringLocalizer _localizer; + private readonly IExcelService _excelService; + private readonly CustomerDto _dto = new(); + + public ImportCustomersCommandHandler( + IApplicationDbContext context, + IExcelService excelService, + IStringLocalizer localizer, + IMapper mapper + ) + { + _context = context; + _localizer = localizer; + _excelService = excelService; + _mapper = mapper; + } + #nullable disable warnings + public async Task> Handle(ImportCustomersCommand request, CancellationToken cancellationToken) + { + + var result = await _excelService.ImportAsync(request.Data, mappers: new Dictionary> { - { - _localizer[_dto.GetMemberDescription(x => x.Name)], - (row, item) => item.Name = row[_localizer[_dto.GetMemberDescription(x => x.Name)]].ToString() - }, - { - _localizer[_dto.GetMemberDescription(x => x.Description)], - (row, item) => - item.Description = row[_localizer[_dto.GetMemberDescription(x => x.Description)]].ToString() - } + { _localizer[_dto.GetMemberDescription(x=>x.Name)], (row, item) => item.Name = row[_localizer[_dto.GetMemberDescription(x=>x.Name)]].ToString() }, +{ _localizer[_dto.GetMemberDescription(x=>x.Description)], (row, item) => item.Description = row[_localizer[_dto.GetMemberDescription(x=>x.Description)]].ToString() }, + }, _localizer[_dto.GetClassDescription()]); - if (result.Succeeded && result.Data is not null) - { - foreach (var dto in result.Data) + if (result.Succeeded && result.Data is not null) { - var exists = await _context.Customers.AnyAsync(x => x.Name == dto.Name, cancellationToken); - if (!exists) + foreach (var dto in result.Data) { - var item = _mapper.Map(dto); - // add create domain events if this entity implement the IHasDomainEvent interface - // item.AddDomainEvent(new CustomerCreatedEvent(item)); - await _context.Customers.AddAsync(item, cancellationToken); - } - } - - await _context.SaveChangesAsync(cancellationToken); - return await Result.SuccessAsync(result.Data.Count()); + var exists = await _context.Customers.AnyAsync(x => x.Name == dto.Name, cancellationToken); + if (!exists) + { + var item = _mapper.Map(dto); + // add create domain events if this entity implement the IHasDomainEvent interface + // item.AddDomainEvent(new CustomerCreatedEvent(item)); + await _context.Customers.AddAsync(item, cancellationToken); + } + } + await _context.SaveChangesAsync(cancellationToken); + return await Result.SuccessAsync(result.Data.Count()); + } + else + { + return await Result.FailureAsync(result.Errors); + } } + public async Task> Handle(CreateCustomersTemplateCommand request, CancellationToken cancellationToken) + { + // TODO: Implement ImportCustomersCommandHandler method + var fields = new string[] { + // TODO: Define the fields that should be generate in the template, for example: + _localizer[_dto.GetMemberDescription(x=>x.Name)], +_localizer[_dto.GetMemberDescription(x=>x.Description)], - return await Result.FailureAsync(result.Errors); + }; + var result = await _excelService.CreateTemplateAsync(fields, _localizer[_dto.GetClassDescription()]); + return await Result.SuccessAsync(result); + } } - public async Task> Handle(CreateCustomersTemplateCommand request, - CancellationToken cancellationToken) - { - // TODO: Implement ImportCustomersCommandHandler method - var fields = new string[] - { - // TODO: Define the fields that should be generate in the template, for example: - _localizer[_dto.GetMemberDescription(x => x.Name)], - _localizer[_dto.GetMemberDescription(x => x.Description)] - }; - var result = await _excelService.CreateTemplateAsync(fields, _localizer[_dto.GetClassDescription()]); - return await Result.SuccessAsync(result); - } -} \ No newline at end of file diff --git a/src/Application/Features/Customers/Commands/Import/ImportCustomersCommandValidator.cs b/src/Application/Features/Customers/Commands/Import/ImportCustomersCommandValidator.cs index 6744f8f57..1791c5109 100644 --- a/src/Application/Features/Customers/Commands/Import/ImportCustomersCommandValidator.cs +++ b/src/Application/Features/Customers/Commands/Import/ImportCustomersCommandValidator.cs @@ -5,10 +5,13 @@ namespace CleanArchitecture.Blazor.Application.Features.Customers.Commands.Impor public class ImportCustomersCommandValidator : AbstractValidator { - public ImportCustomersCommandValidator() - { - RuleFor(v => v.Data) - .NotNull() - .NotEmpty(); - } -} \ No newline at end of file + public ImportCustomersCommandValidator() + { + + RuleFor(v => v.Data) + .NotNull() + .NotEmpty(); + + } +} + diff --git a/src/Application/Features/Customers/Commands/Update/UpdateCustomerCommand.cs b/src/Application/Features/Customers/Commands/Update/UpdateCustomerCommand.cs index f1290510c..10f6d1468 100644 --- a/src/Application/Features/Customers/Commands/Update/UpdateCustomerCommand.cs +++ b/src/Application/Features/Customers/Commands/Update/UpdateCustomerCommand.cs @@ -1,57 +1,56 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. - -using CleanArchitecture.Blazor.Application.Features.Customers.Caching; +using System.ComponentModel; using CleanArchitecture.Blazor.Application.Features.Customers.DTOs; +using CleanArchitecture.Blazor.Application.Features.Customers.Caching; namespace CleanArchitecture.Blazor.Application.Features.Customers.Commands.Update; -public class UpdateCustomerCommand : ICacheInvalidatorRequest> +public class UpdateCustomerCommand: ICacheInvalidatorRequest> { - [Description("Id")] public int Id { get; set; } - - [Description("Name")] public string Name { get; set; } = string.Empty; - - [Description("Description")] public string? Description { get; set; } - - public string CacheKey => CustomerCacheKey.GetAllCacheKey; - public CancellationTokenSource? SharedExpiryTokenSource => CustomerCacheKey.SharedExpiryTokenSource(); - + [Description("Id")] + public int Id { get; set; } + [Description("Name")] + public string Name {get;set;} = String.Empty; + [Description("Description")] + public string? Description {get;set;} + + public string CacheKey => CustomerCacheKey.GetAllCacheKey; + public CancellationTokenSource? SharedExpiryTokenSource => CustomerCacheKey.SharedExpiryTokenSource(); private class Mapping : Profile { public Mapping() { - CreateMap(MemberList.None); - CreateMap(MemberList.None); + CreateMap(MemberList.None); + CreateMap(MemberList.None); } } } -public class UpdateCustomerCommandHandler : IRequestHandler> -{ - private readonly IApplicationDbContext _context; - private readonly IStringLocalizer _localizer; - private readonly IMapper _mapper; - - public UpdateCustomerCommandHandler( - IApplicationDbContext context, - IStringLocalizer localizer, - IMapper mapper - ) + public class UpdateCustomerCommandHandler : IRequestHandler> { - _context = context; - _localizer = localizer; - _mapper = mapper; - } + private readonly IApplicationDbContext _context; + private readonly IMapper _mapper; + private readonly IStringLocalizer _localizer; + public UpdateCustomerCommandHandler( + IApplicationDbContext context, + IStringLocalizer localizer, + IMapper mapper + ) + { + _context = context; + _localizer = localizer; + _mapper = mapper; + } + public async Task> Handle(UpdateCustomerCommand request, CancellationToken cancellationToken) + { - public async Task> Handle(UpdateCustomerCommand request, CancellationToken cancellationToken) - { - var item = await _context.Customers.FindAsync(new object[] { request.Id }, cancellationToken) ?? - throw new NotFoundException($"Customer with id: [{request.Id}] not found."); - item = _mapper.Map(request, item); - // raise a update domain event - item.AddDomainEvent(new CustomerUpdatedEvent(item)); - await _context.SaveChangesAsync(cancellationToken); - return await Result.SuccessAsync(item.Id); + var item =await _context.Customers.FindAsync( new object[] { request.Id }, cancellationToken)?? throw new NotFoundException($"Customer with id: [{request.Id}] not found."); + item = _mapper.Map(request, item); + // raise a update domain event + item.AddDomainEvent(new CustomerUpdatedEvent(item)); + await _context.SaveChangesAsync(cancellationToken); + return await Result.SuccessAsync(item.Id); + } } -} \ No newline at end of file + diff --git a/src/Application/Features/Customers/Commands/Update/UpdateCustomerCommandValidator.cs b/src/Application/Features/Customers/Commands/Update/UpdateCustomerCommandValidator.cs index a6335bfdf..35f4d6949 100644 --- a/src/Application/Features/Customers/Commands/Update/UpdateCustomerCommandValidator.cs +++ b/src/Application/Features/Customers/Commands/Update/UpdateCustomerCommandValidator.cs @@ -5,9 +5,12 @@ namespace CleanArchitecture.Blazor.Application.Features.Customers.Commands.Updat public class UpdateCustomerCommandValidator : AbstractValidator { - public UpdateCustomerCommandValidator() - { - RuleFor(v => v.Id).NotNull(); - RuleFor(v => v.Name).MaximumLength(256).NotEmpty(); - } -} \ No newline at end of file + public UpdateCustomerCommandValidator() + { + RuleFor(v => v.Id).NotNull(); + RuleFor(v => v.Name).MaximumLength(256).NotEmpty(); + + } + +} + diff --git a/src/Application/Features/Customers/DTOs/CustomerDto.cs b/src/Application/Features/Customers/DTOs/CustomerDto.cs index 25e085945..f70ab1a2a 100644 --- a/src/Application/Features/Customers/DTOs/CustomerDto.cs +++ b/src/Application/Features/Customers/DTOs/CustomerDto.cs @@ -6,11 +6,12 @@ namespace CleanArchitecture.Blazor.Application.Features.Customers.DTOs; [Description("Customers")] public class CustomerDto { - [Description("Id")] public int Id { get; set; } - - [Description("Name")] public string Name { get; set; } = string.Empty; - - [Description("Description")] public string? Description { get; set; } + [Description("Id")] + public int Id { get; set; } + [Description("Name")] + public string Name {get;set;} = String.Empty; + [Description("Description")] + public string? Description {get;set;} private class Mapping : Profile @@ -20,4 +21,5 @@ public Mapping() CreateMap().ReverseMap(); } } -} \ No newline at end of file +} + diff --git a/src/Application/Features/Customers/EventHandlers/CustomerCreatedEventHandler.cs b/src/Application/Features/Customers/EventHandlers/CustomerCreatedEventHandler.cs index 5e33e672a..6266dc629 100644 --- a/src/Application/Features/Customers/EventHandlers/CustomerCreatedEventHandler.cs +++ b/src/Application/Features/Customers/EventHandlers/CustomerCreatedEventHandler.cs @@ -5,18 +5,17 @@ namespace CleanArchitecture.Blazor.Application.Features.Customers.EventHandlers; public class CustomerCreatedEventHandler : INotificationHandler { - private readonly ILogger _logger; + private readonly ILogger _logger; - public CustomerCreatedEventHandler( - ILogger logger - ) - { - _logger = logger; - } - - public Task Handle(CustomerCreatedEvent notification, CancellationToken cancellationToken) - { - _logger.LogInformation("Domain Event: {DomainEvent}", notification.GetType().FullName); - return Task.CompletedTask; - } -} \ No newline at end of file + public CustomerCreatedEventHandler( + ILogger logger + ) + { + _logger = logger; + } + public Task Handle(CustomerCreatedEvent notification, CancellationToken cancellationToken) + { + _logger.LogInformation("Domain Event: {DomainEvent}", notification.GetType().FullName); + return Task.CompletedTask; + } +} diff --git a/src/Application/Features/Customers/EventHandlers/CustomerDeletedEventHandler.cs b/src/Application/Features/Customers/EventHandlers/CustomerDeletedEventHandler.cs index f910bbd44..94d2bda2d 100644 --- a/src/Application/Features/Customers/EventHandlers/CustomerDeletedEventHandler.cs +++ b/src/Application/Features/Customers/EventHandlers/CustomerDeletedEventHandler.cs @@ -3,20 +3,19 @@ namespace CleanArchitecture.Blazor.Application.Features.Customers.EventHandlers; -public class CustomerDeletedEventHandler : INotificationHandler -{ - private readonly ILogger _logger; - - public CustomerDeletedEventHandler( - ILogger logger - ) + public class CustomerDeletedEventHandler : INotificationHandler { - _logger = logger; - } + private readonly ILogger _logger; - public Task Handle(CustomerDeletedEvent notification, CancellationToken cancellationToken) - { - _logger.LogInformation("Domain Event: {DomainEvent}", notification.GetType().FullName); - return Task.CompletedTask; + public CustomerDeletedEventHandler( + ILogger logger + ) + { + _logger = logger; + } + public Task Handle(CustomerDeletedEvent notification, CancellationToken cancellationToken) + { + _logger.LogInformation("Domain Event: {DomainEvent}", notification.GetType().FullName); + return Task.CompletedTask; + } } -} \ No newline at end of file diff --git a/src/Application/Features/Customers/EventHandlers/CustomerUpdatedEventHandler.cs b/src/Application/Features/Customers/EventHandlers/CustomerUpdatedEventHandler.cs index e30c99136..569cdd1fa 100644 --- a/src/Application/Features/Customers/EventHandlers/CustomerUpdatedEventHandler.cs +++ b/src/Application/Features/Customers/EventHandlers/CustomerUpdatedEventHandler.cs @@ -3,20 +3,19 @@ namespace CleanArchitecture.Blazor.Application.Features.Customers.EventHandlers; -public class CustomerUpdatedEventHandler : INotificationHandler -{ - private readonly ILogger _logger; - - public CustomerUpdatedEventHandler( - ILogger logger - ) + public class CustomerUpdatedEventHandler : INotificationHandler { - _logger = logger; - } + private readonly ILogger _logger; - public Task Handle(CustomerUpdatedEvent notification, CancellationToken cancellationToken) - { - _logger.LogInformation("Domain Event: {DomainEvent}", notification.GetType().FullName); - return Task.CompletedTask; + public CustomerUpdatedEventHandler( + ILogger logger + ) + { + _logger = logger; + } + public Task Handle(CustomerUpdatedEvent notification, CancellationToken cancellationToken) + { + _logger.LogInformation("Domain Event: {DomainEvent}", notification.GetType().FullName); + return Task.CompletedTask; + } } -} \ No newline at end of file diff --git a/src/Application/Features/Customers/Queries/Export/ExportCustomersQuery.cs b/src/Application/Features/Customers/Queries/Export/ExportCustomersQuery.cs index de7b3659c..dc724a3ce 100644 --- a/src/Application/Features/Customers/Queries/Export/ExportCustomersQuery.cs +++ b/src/Application/Features/Customers/Queries/Export/ExportCustomersQuery.cs @@ -3,50 +3,52 @@ using CleanArchitecture.Blazor.Application.Features.Customers.DTOs; using CleanArchitecture.Blazor.Application.Features.Customers.Specifications; +using CleanArchitecture.Blazor.Application.Features.Customers.Queries.Pagination; namespace CleanArchitecture.Blazor.Application.Features.Customers.Queries.Export; public class ExportCustomersQuery : CustomerAdvancedFilter, IRequest> { - public CustomerAdvancedSpecification Specification => new(this); + public CustomerAdvancedSpecification Specification => new CustomerAdvancedSpecification(this); } - + public class ExportCustomersQueryHandler : - IRequestHandler> + IRequestHandler> { - private readonly IApplicationDbContext _context; - private readonly CustomerDto _dto = new(); - private readonly IExcelService _excelService; - private readonly IStringLocalizer _localizer; - private readonly IMapper _mapper; - public ExportCustomersQueryHandler( - IApplicationDbContext context, - IMapper mapper, - IExcelService excelService, - IStringLocalizer localizer - ) - { - _context = context; - _mapper = mapper; - _excelService = excelService; - _localizer = localizer; - } -#nullable disable warnings - public async Task> Handle(ExportCustomersQuery request, CancellationToken cancellationToken) - { - var data = await _context.Customers.ApplySpecification(request.Specification) - .OrderBy($"{request.OrderBy} {request.SortDirection}") - .ProjectTo(_mapper.ConfigurationProvider) - .AsNoTracking() - .ToListAsync(cancellationToken); - var result = await _excelService.ExportAsync(data, - new Dictionary> - { - // TODO: Define the fields that should be exported, for example: - { _localizer[_dto.GetMemberDescription(x => x.Name)], item => item.Name }, - { _localizer[_dto.GetMemberDescription(x => x.Description)], item => item.Description } - } - , _localizer[_dto.GetClassDescription()]); - return await Result.SuccessAsync(result); - } -} \ No newline at end of file + private readonly IApplicationDbContext _context; + private readonly IMapper _mapper; + private readonly IExcelService _excelService; + private readonly IStringLocalizer _localizer; + private readonly CustomerDto _dto = new(); + public ExportCustomersQueryHandler( + IApplicationDbContext context, + IMapper mapper, + IExcelService excelService, + IStringLocalizer localizer + ) + { + _context = context; + _mapper = mapper; + _excelService = excelService; + _localizer = localizer; + } + #nullable disable warnings + public async Task> Handle(ExportCustomersQuery request, CancellationToken cancellationToken) + { + var data = await _context.Customers.ApplySpecification(request.Specification) + .OrderBy($"{request.OrderBy} {request.SortDirection}") + .ProjectTo(_mapper.ConfigurationProvider) + .AsNoTracking() + .ToListAsync(cancellationToken); + var result = await _excelService.ExportAsync(data, + new Dictionary>() + { + // TODO: Define the fields that should be exported, for example: + {_localizer[_dto.GetMemberDescription(x=>x.Name)],item => item.Name}, +{_localizer[_dto.GetMemberDescription(x=>x.Description)],item => item.Description}, + + } + , _localizer[_dto.GetClassDescription()]); + return await Result.SuccessAsync(result); + } +} diff --git a/src/Application/Features/Customers/Queries/GetAll/GetAllCustomersQuery.cs b/src/Application/Features/Customers/Queries/GetAll/GetAllCustomersQuery.cs index 14342b034..9424595ad 100644 --- a/src/Application/Features/Customers/Queries/GetAll/GetAllCustomersQuery.cs +++ b/src/Application/Features/Customers/Queries/GetAll/GetAllCustomersQuery.cs @@ -1,42 +1,43 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using CleanArchitecture.Blazor.Application.Features.Customers.Caching; using CleanArchitecture.Blazor.Application.Features.Customers.DTOs; +using CleanArchitecture.Blazor.Application.Features.Customers.Caching; namespace CleanArchitecture.Blazor.Application.Features.Customers.Queries.GetAll; public class GetAllCustomersQuery : ICacheableRequest> { - public string CacheKey => CustomerCacheKey.GetAllCacheKey; - public MemoryCacheEntryOptions? Options => CustomerCacheKey.MemoryCacheEntryOptions; + public string CacheKey => CustomerCacheKey.GetAllCacheKey; + public MemoryCacheEntryOptions? Options => CustomerCacheKey.MemoryCacheEntryOptions; } public class GetAllCustomersQueryHandler : - IRequestHandler> + IRequestHandler> { private readonly IApplicationDbContext _context; - private readonly IStringLocalizer _localizer; private readonly IMapper _mapper; + private readonly IStringLocalizer _localizer; public GetAllCustomersQueryHandler( IApplicationDbContext context, IMapper mapper, IStringLocalizer localizer - ) + ) { _context = context; _mapper = mapper; _localizer = localizer; } - public async Task> Handle(GetAllCustomersQuery request, - CancellationToken cancellationToken) + public async Task> Handle(GetAllCustomersQuery request, CancellationToken cancellationToken) { var data = await _context.Customers - .ProjectTo(_mapper.ConfigurationProvider) - .AsNoTracking() - .ToListAsync(cancellationToken); + .ProjectTo(_mapper.ConfigurationProvider) + .AsNoTracking() + .ToListAsync(cancellationToken); return data; } -} \ No newline at end of file +} + + diff --git a/src/Application/Features/Customers/Queries/GetById/GetCustomerByIdQuery.cs b/src/Application/Features/Customers/Queries/GetById/GetCustomerByIdQuery.cs index 83e2ee69b..cde636f1f 100644 --- a/src/Application/Features/Customers/Queries/GetById/GetCustomerByIdQuery.cs +++ b/src/Application/Features/Customers/Queries/GetById/GetCustomerByIdQuery.cs @@ -1,31 +1,31 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using CleanArchitecture.Blazor.Application.Features.Customers.Caching; using CleanArchitecture.Blazor.Application.Features.Customers.DTOs; +using CleanArchitecture.Blazor.Application.Features.Customers.Caching; using CleanArchitecture.Blazor.Application.Features.Customers.Specifications; namespace CleanArchitecture.Blazor.Application.Features.Customers.Queries.GetById; public class GetCustomerByIdQuery : ICacheableRequest { - public required int Id { get; set; } - public string CacheKey => CustomerCacheKey.GetByIdCacheKey($"{Id}"); - public MemoryCacheEntryOptions? Options => CustomerCacheKey.MemoryCacheEntryOptions; + public required int Id { get; set; } + public string CacheKey => CustomerCacheKey.GetByIdCacheKey($"{Id}"); + public MemoryCacheEntryOptions? Options => CustomerCacheKey.MemoryCacheEntryOptions; } public class GetCustomerByIdQueryHandler : - IRequestHandler + IRequestHandler { private readonly IApplicationDbContext _context; - private readonly IStringLocalizer _localizer; private readonly IMapper _mapper; + private readonly IStringLocalizer _localizer; public GetCustomerByIdQueryHandler( IApplicationDbContext context, IMapper mapper, IStringLocalizer localizer - ) + ) { _context = context; _mapper = mapper; @@ -35,9 +35,8 @@ IStringLocalizer localizer public async Task Handle(GetCustomerByIdQuery request, CancellationToken cancellationToken) { var data = await _context.Customers.ApplySpecification(new CustomerByIdSpecification(request.Id)) - .ProjectTo(_mapper.ConfigurationProvider) - .FirstAsync(cancellationToken) ?? - throw new NotFoundException($"Customer with id: [{request.Id}] not found."); + .ProjectTo(_mapper.ConfigurationProvider) + .FirstAsync(cancellationToken) ?? throw new NotFoundException($"Customer with id: [{request.Id}] not found."); return data; } -} \ No newline at end of file +} diff --git a/src/Application/Features/Customers/Queries/Pagination/CustomersPaginationQuery.cs b/src/Application/Features/Customers/Queries/Pagination/CustomersPaginationQuery.cs index 2ac032150..e26ed3497 100644 --- a/src/Application/Features/Customers/Queries/Pagination/CustomersPaginationQuery.cs +++ b/src/Application/Features/Customers/Queries/Pagination/CustomersPaginationQuery.cs @@ -1,48 +1,45 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using CleanArchitecture.Blazor.Application.Features.Customers.Caching; using CleanArchitecture.Blazor.Application.Features.Customers.DTOs; +using CleanArchitecture.Blazor.Application.Features.Customers.Caching; using CleanArchitecture.Blazor.Application.Features.Customers.Specifications; namespace CleanArchitecture.Blazor.Application.Features.Customers.Queries.Pagination; public class CustomersWithPaginationQuery : CustomerAdvancedFilter, ICacheableRequest> { - public CustomerAdvancedSpecification Specification => new(this); - public string CacheKey => CustomerCacheKey.GetPaginationCacheKey($"{this}"); - public MemoryCacheEntryOptions? Options => CustomerCacheKey.MemoryCacheEntryOptions; - public override string ToString() { return $"Listview:{ListView}, Search:{Keyword}, {OrderBy}, {SortDirection}, {PageNumber}, {PageSize}"; } + public string CacheKey => CustomerCacheKey.GetPaginationCacheKey($"{this}"); + public MemoryCacheEntryOptions? Options => CustomerCacheKey.MemoryCacheEntryOptions; + public CustomerAdvancedSpecification Specification => new CustomerAdvancedSpecification(this); } - + public class CustomersWithPaginationQueryHandler : - IRequestHandler> + IRequestHandler> { - private readonly IApplicationDbContext _context; - private readonly IStringLocalizer _localizer; - private readonly IMapper _mapper; + private readonly IApplicationDbContext _context; + private readonly IMapper _mapper; + private readonly IStringLocalizer _localizer; - public CustomersWithPaginationQueryHandler( - IApplicationDbContext context, - IMapper mapper, - IStringLocalizer localizer - ) - { - _context = context; - _mapper = mapper; - _localizer = localizer; - } + public CustomersWithPaginationQueryHandler( + IApplicationDbContext context, + IMapper mapper, + IStringLocalizer localizer + ) + { + _context = context; + _mapper = mapper; + _localizer = localizer; + } - public async Task> Handle(CustomersWithPaginationQuery request, - CancellationToken cancellationToken) - { - var data = await _context.Customers.OrderBy($"{request.OrderBy} {request.SortDirection}") - .ProjectToPaginatedDataAsync(request.Specification, request.PageNumber, - request.PageSize, _mapper.ConfigurationProvider, cancellationToken); - return data; - } + public async Task> Handle(CustomersWithPaginationQuery request, CancellationToken cancellationToken) + { + var data = await _context.Customers.OrderBy($"{request.OrderBy} {request.SortDirection}") + .ProjectToPaginatedDataAsync(request.Specification, request.PageNumber, request.PageSize, _mapper.ConfigurationProvider, cancellationToken); + return data; + } } \ No newline at end of file diff --git a/src/Application/Features/Customers/Specifications/CustomerAdvancedFilter.cs b/src/Application/Features/Customers/Specifications/CustomerAdvancedFilter.cs index 05a8e218b..8de6edcfa 100644 --- a/src/Application/Features/Customers/Specifications/CustomerAdvancedFilter.cs +++ b/src/Application/Features/Customers/Specifications/CustomerAdvancedFilter.cs @@ -2,15 +2,17 @@ #nullable disable warnings public enum CustomerListView { - [Description("All")] All, - [Description("My")] My, - [Description("Created Toady")] CreatedToday, - + [Description("All")] + All, + [Description("My")] + My, + [Description("Created Toady")] + CreatedToday, [Description("Created within the last 30 days")] Created30Days } -public class CustomerAdvancedFilter : PaginationFilter +public class CustomerAdvancedFilter: PaginationFilter { public CustomerListView ListView { get; set; } = CustomerListView.All; public UserProfile? CurrentUser { get; set; } diff --git a/src/Application/Features/Customers/Specifications/CustomerAdvancedSpecification.cs b/src/Application/Features/Customers/Specifications/CustomerAdvancedSpecification.cs index df73ceb49..bac39cbd3 100644 --- a/src/Application/Features/Customers/Specifications/CustomerAdvancedSpecification.cs +++ b/src/Application/Features/Customers/Specifications/CustomerAdvancedSpecification.cs @@ -13,12 +13,11 @@ public CustomerAdvancedSpecification(CustomerAdvancedFilter filter) today.AddDays(-30).ToString("yyyy-MM-dd", CultureInfo.CurrentCulture) + " 00:00:00", CultureInfo.CurrentCulture); - Query.Where(q => q.Name != null) - .Where(q => q.Name!.Contains(filter.Keyword) || q.Description!.Contains(filter.Keyword), - !string.IsNullOrEmpty(filter.Keyword)) - .Where(q => q.CreatedBy == filter.CurrentUser.UserId, - filter.ListView == CustomerListView.My && filter.CurrentUser is not null) - .Where(q => q.Created >= start && q.Created <= end, filter.ListView == CustomerListView.CreatedToday) - .Where(q => q.Created >= last30day, filter.ListView == CustomerListView.Created30Days); + Query.Where(q => q.Name != null) + .Where(q => q.Name!.Contains(filter.Keyword) || q.Description!.Contains(filter.Keyword), !string.IsNullOrEmpty(filter.Keyword)) + .Where(q => q.CreatedBy == filter.CurrentUser.UserId, filter.ListView == CustomerListView.My && filter.CurrentUser is not null) + .Where(q => q.Created >= start && q.Created <= end, filter.ListView == CustomerListView.CreatedToday) + .Where(q => q.Created >= last30day, filter.ListView == CustomerListView.Created30Days); + } -} \ No newline at end of file +} diff --git a/src/Application/Features/Customers/Specifications/CustomerByIdSpecification.cs b/src/Application/Features/Customers/Specifications/CustomerByIdSpecification.cs index 9fa9b8f92..b98dccaa5 100644 --- a/src/Application/Features/Customers/Specifications/CustomerByIdSpecification.cs +++ b/src/Application/Features/Customers/Specifications/CustomerByIdSpecification.cs @@ -4,6 +4,6 @@ public class CustomerByIdSpecification : Specification { public CustomerByIdSpecification(int id) { - Query.Where(q => q.Id == id); + Query.Where(q => q.Id == id); } } \ No newline at end of file diff --git a/src/Infrastructure/DependencyInjection.cs b/src/Infrastructure/DependencyInjection.cs index f95c34145..13fdd6d6a 100644 --- a/src/Infrastructure/DependencyInjection.cs +++ b/src/Infrastructure/DependencyInjection.cs @@ -10,7 +10,7 @@ using CleanArchitecture.Blazor.Infrastructure.Configurations; using CleanArchitecture.Blazor.Infrastructure.Constants.ClaimTypes; using CleanArchitecture.Blazor.Infrastructure.Constants.Database; -using CleanArchitecture.Blazor.Infrastructure.Constants.Permission; +using CleanArchitecture.Blazor.Infrastructure.PermissionSet; using CleanArchitecture.Blazor.Infrastructure.Constants.User; using CleanArchitecture.Blazor.Infrastructure.Persistence.Interceptors; using CleanArchitecture.Blazor.Infrastructure.Services.JWT; diff --git a/src/Infrastructure/PermissionSet/Customers.cs b/src/Infrastructure/PermissionSet/Customers.cs new file mode 100644 index 000000000..21a0e5ecb --- /dev/null +++ b/src/Infrastructure/PermissionSet/Customers.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.ComponentModel; + +namespace CleanArchitecture.Blazor.Infrastructure.PermissionSet; + +public static partial class Permissions +{ + [DisplayName("Customers")] + [Description("Customers Permissions")] + public static class Customers + { + public const string View = "Permissions.Customers.View"; + public const string Create = "Permissions.Customers.Create"; + public const string Edit = "Permissions.Customers.Edit"; + public const string Delete = "Permissions.Customers.Delete"; + public const string Search = "Permissions.Customers.Search"; + public const string Export = "Permissions.Customers.Export"; + public const string Import = "Permissions.Customers.Import"; + } +} + diff --git a/src/Infrastructure/PermissionSet/Documents.cs b/src/Infrastructure/PermissionSet/Documents.cs new file mode 100644 index 000000000..71d278d0d --- /dev/null +++ b/src/Infrastructure/PermissionSet/Documents.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CleanArchitecture.Blazor.Infrastructure.PermissionSet; +public static partial class Permissions +{ + [DisplayName("Documents")] + [Description("Documents Permissions")] + public static class Documents + { + public const string View = "Permissions.Documents.View"; + public const string Create = "Permissions.Documents.Create"; + public const string Edit = "Permissions.Documents.Edit"; + public const string Delete = "Permissions.Documents.Delete"; + public const string Search = "Permissions.Documents.Search"; + public const string Export = "Permissions.Documents.Export"; + public const string Import = "Permissions.Documents.Import"; + public const string Download = "Permissions.Documents.Download"; + } +} diff --git a/src/Infrastructure/Constants/Permission/PermissionModules.cs b/src/Infrastructure/PermissionSet/PermissionModules.cs similarity index 92% rename from src/Infrastructure/Constants/Permission/PermissionModules.cs rename to src/Infrastructure/PermissionSet/PermissionModules.cs index 88b12832a..1e8b86168 100644 --- a/src/Infrastructure/Constants/Permission/PermissionModules.cs +++ b/src/Infrastructure/PermissionSet/PermissionModules.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -namespace CleanArchitecture.Blazor.Infrastructure.Constants.Permission; +namespace CleanArchitecture.Blazor.Infrastructure.PermissionSet; public static class PermissionModules { diff --git a/src/Infrastructure/Constants/Permission/Permissions.cs b/src/Infrastructure/PermissionSet/Permissions.cs similarity index 65% rename from src/Infrastructure/Constants/Permission/Permissions.cs rename to src/Infrastructure/PermissionSet/Permissions.cs index 6f49c7ad2..4a9107b69 100644 --- a/src/Infrastructure/Constants/Permission/Permissions.cs +++ b/src/Infrastructure/PermissionSet/Permissions.cs @@ -1,12 +1,12 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.ComponentModel; using System.Reflection; -namespace CleanArchitecture.Blazor.Infrastructure.Constants.Permission; +namespace CleanArchitecture.Blazor.Infrastructure.PermissionSet; -public static class Permissions +public static partial class Permissions { /// /// Returns a list of Permissions. @@ -46,58 +46,9 @@ public static class Logs } - [DisplayName("Products")] - [Description("Products Permissions")] - public static class Products - { - public const string View = "Permissions.Products.View"; - public const string Create = "Permissions.Products.Create"; - public const string Edit = "Permissions.Products.Edit"; - public const string Delete = "Permissions.Products.Delete"; - public const string Search = "Permissions.Products.Search"; - public const string Export = "Permissions.Products.Export"; - public const string Import = "Permissions.Products.Import"; - } - - [DisplayName("Customers")] - [Description("Customers Permissions")] - public static class Customers - { - public const string View = "Permissions.Customers.View"; - public const string Create = "Permissions.Customers.Create"; - public const string Edit = "Permissions.Customers.Edit"; - public const string Delete = "Permissions.Customers.Delete"; - public const string Search = "Permissions.Customers.Search"; - public const string Export = "Permissions.Customers.Export"; - public const string Import = "Permissions.Customers.Import"; - } + - [DisplayName("Categories")] - [Description("Categories Permissions")] - public static class Categories - { - public const string View = "Permissions.Categories.View"; - public const string Create = "Permissions.Categories.Create"; - public const string Edit = "Permissions.Categories.Edit"; - public const string Delete = "Permissions.Categories.Delete"; - public const string Search = "Permissions.Categories.Search"; - public const string Export = "Permissions.Categories.Export"; - public const string Import = "Permissions.Categories.Import"; - } - - [DisplayName("Documents")] - [Description("Documents Permissions")] - public static class Documents - { - public const string View = "Permissions.Documents.View"; - public const string Create = "Permissions.Documents.Create"; - public const string Edit = "Permissions.Documents.Edit"; - public const string Delete = "Permissions.Documents.Delete"; - public const string Search = "Permissions.Documents.Search"; - public const string Export = "Permissions.Documents.Export"; - public const string Import = "Permissions.Documents.Import"; - public const string Download = "Permissions.Documents.Download"; - } + [DisplayName("Dictionaries")] [Description("Dictionaries Permissions")] diff --git a/src/Infrastructure/PermissionSet/Products.cs b/src/Infrastructure/PermissionSet/Products.cs new file mode 100644 index 000000000..5b1bae7e5 --- /dev/null +++ b/src/Infrastructure/PermissionSet/Products.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CleanArchitecture.Blazor.Infrastructure.PermissionSet; +public static partial class Permissions +{ + [DisplayName("Products")] + [Description("Products Permissions")] + public static class Products + { + public const string View = "Permissions.Products.View"; + public const string Create = "Permissions.Products.Create"; + public const string Edit = "Permissions.Products.Edit"; + public const string Delete = "Permissions.Products.Delete"; + public const string Search = "Permissions.Products.Search"; + public const string Export = "Permissions.Products.Export"; + public const string Import = "Permissions.Products.Import"; + } + + + + [DisplayName("Categories")] + [Description("Categories Permissions")] + public static class Categories + { + public const string View = "Permissions.Categories.View"; + public const string Create = "Permissions.Categories.Create"; + public const string Edit = "Permissions.Categories.Edit"; + public const string Delete = "Permissions.Categories.Delete"; + public const string Search = "Permissions.Categories.Search"; + public const string Export = "Permissions.Categories.Export"; + public const string Import = "Permissions.Categories.Import"; + } +} diff --git a/src/Infrastructure/Persistence/ApplicationDbContextInitializer.cs b/src/Infrastructure/Persistence/ApplicationDbContextInitializer.cs index 67d9a44e9..d1bc90f52 100644 --- a/src/Infrastructure/Persistence/ApplicationDbContextInitializer.cs +++ b/src/Infrastructure/Persistence/ApplicationDbContextInitializer.cs @@ -1,7 +1,7 @@ using System.Reflection; using CleanArchitecture.Blazor.Domain.Identity; using CleanArchitecture.Blazor.Infrastructure.Constants.ClaimTypes; -using CleanArchitecture.Blazor.Infrastructure.Constants.Permission; +using CleanArchitecture.Blazor.Infrastructure.PermissionSet; using CleanArchitecture.Blazor.Infrastructure.Constants.Role; using CleanArchitecture.Blazor.Infrastructure.Constants.User; diff --git a/src/Server.UI/Pages/Customers/Components/CustomerFormDialog.razor b/src/Server.UI/Pages/Customers/Components/CustomerFormDialog.razor index fcd3cd876..cf8d9dd03 100644 --- a/src/Server.UI/Pages/Customers/Components/CustomerFormDialog.razor +++ b/src/Server.UI/Pages/Customers/Components/CustomerFormDialog.razor @@ -1,5 +1,5 @@ -@using Severity = Severity -@using CleanArchitecture.Blazor.Application.Features.Customers.Commands.AddEdit +@using CleanArchitecture.Blazor.Application.Features.Customers.Commands.AddEdit + @inherits MudComponentBase @inject IValidationService Validator @inject IStringLocalizer L @@ -9,12 +9,12 @@ @*TODO: define mudform that should be edit fields, for example:*@ - - - - - - + + + + + + @@ -22,19 +22,19 @@ @ConstantString.Cancel @ConstantString.SaveAndNew - @ConstantString.Save + @ConstantString.Save @code { MudForm? _form; - private bool _saving; - private bool _savingnew; - [CascadingParameter] MudDialogInstance MudDialog { get; set; } = default!; - AddEditCustomerCommandValidator _modelValidator = new(); + private bool _saving = false; + private bool _savingnew = false; + [CascadingParameter] + MudDialogInstance MudDialog { get; set; } = default!; + AddEditCustomerCommandValidator _modelValidator = new (); [EditorRequired] [Parameter] public AddEditCustomerCommand model { get; set; } = null!; [Inject] private IMediator _mediator { get; set; } = default!; - async Task Submit() { try @@ -47,11 +47,11 @@ if (result.Succeeded) { MudDialog.Close(DialogResult.Ok(true)); - Snackbar.Add(ConstantString.SaveSuccess, Severity.Info); + Snackbar.Add(ConstantString.SaveSuccess, MudBlazor.Severity.Info); } else { - Snackbar.Add(result.ErrorMessage, Severity.Error); + Snackbar.Add(result.ErrorMessage, MudBlazor.Severity.Error); } } finally @@ -59,7 +59,6 @@ _saving = false; } } - async Task SaveAndNew() { try @@ -67,17 +66,17 @@ _savingnew = true; await _form!.Validate().ConfigureAwait(false); if (!_form!.IsValid) - return; + return; var result = await _mediator.Send(model); if (result.Succeeded) { - Snackbar.Add(ConstantString.SaveSuccess, Severity.Info); + Snackbar.Add(ConstantString.SaveSuccess, MudBlazor.Severity.Info); await Task.Delay(300); - model = new AddEditCustomerCommand(); + model = new AddEditCustomerCommand() { }; } else { - Snackbar.Add(result.ErrorMessage, Severity.Error); + Snackbar.Add(result.ErrorMessage, MudBlazor.Severity.Error); } } finally @@ -85,10 +84,5 @@ _savingnew = false; } } - - void Cancel() - { - MudDialog.Cancel(); - } - + void Cancel() => MudDialog.Cancel(); } \ No newline at end of file diff --git a/src/Server.UI/Pages/Customers/Components/CustomersAdvancedSearchComponent.razor b/src/Server.UI/Pages/Customers/Components/CustomersAdvancedSearchComponent.razor index 4003c3ed1..798b88ae9 100644 --- a/src/Server.UI/Pages/Customers/Components/CustomersAdvancedSearchComponent.razor +++ b/src/Server.UI/Pages/Customers/Components/CustomersAdvancedSearchComponent.razor @@ -13,20 +13,18 @@ TextChanged="TextChanged"> *@ - + @code { - [EditorRequired] [Parameter] public CustomersWithPaginationQuery TRequest { get; set; } = null!; - [EditorRequired] [Parameter] public EventCallback OnConditionChanged { get; set; } + [EditorRequired][Parameter] public CustomersWithPaginationQuery TRequest { get; set; } = null!; + [EditorRequired][Parameter] public EventCallback OnConditionChanged { get; set; } private bool _advancedSearchExpanded; - private async Task TextChanged(string str) { if (_advancedSearchExpanded) { - await OnConditionChanged.InvokeAsync(str); + await OnConditionChanged.InvokeAsync(str); } } - } \ No newline at end of file diff --git a/src/Server.UI/Pages/Customers/Customers.razor b/src/Server.UI/Pages/Customers/Customers.razor index 80c691a1e..05ec9804d 100644 --- a/src/Server.UI/Pages/Customers/Customers.razor +++ b/src/Server.UI/Pages/Customers/Customers.razor @@ -1,240 +1,231 @@ @page "/pages/Customers" -@using Severity = Severity -@using CleanArchitecture.Blazor.Application.Features.Customers.DTOs -@using CleanArchitecture.Blazor.Application.Features.Customers.Queries.Export -@using CleanArchitecture.Blazor.Application.Features.Customers.Queries.Pagination -@using CleanArchitecture.Blazor.Application.Features.Customers.Specifications + @using BlazorDownloadFile @using CleanArchitecture.Blazor.Application.Features.Customers.Caching -@using CleanArchitecture.Blazor.Application.Features.Customers.Commands.AddEdit +@using CleanArchitecture.Blazor.Application.Features.Customers.DTOs +@using CleanArchitecture.Blazor.Application.Features.Customers.Specifications @using CleanArchitecture.Blazor.Application.Features.Customers.Commands.Delete @using CleanArchitecture.Blazor.Application.Features.Customers.Commands.Import +@using CleanArchitecture.Blazor.Application.Features.Customers.Queries.Export +@using CleanArchitecture.Blazor.Application.Features.Customers.Queries.Pagination +@using CleanArchitecture.Blazor.Application.Features.Customers.Commands.AddEdit @using CleanArchitecture.Blazor.Server.UI.Pages.Customers.Components @inject IJSRuntime JS @inject IStringLocalizer L @attribute [Authorize(Policy = Permissions.Customers.View)] @Title + .mud-table-toolbar { + height: 120px !important; + } + - -
-
- -
- @Title - - -
-
-
+ FixedHeader="true" + FixedFooter="true" + Virtualize="true" + @bind-RowsPerPage="_defaultPageSize" + Height="calc(100vh - 330px)" + Loading="@_loading" + MultiSelection="true" + @bind-SelectedItems="_selectedItems" + @bind-SelectedItem="_currentDto" + Hover="true" @ref="_table"> + +
+
+ +
+ @Title + + +
+
+
-
-
- - - @ConstantString.Refresh - - @if (_canCreate) - { - - @ConstantString.New - - - @ConstantString.Clone - - } - @if (_canDelete) - { - - @ConstantString.Delete - - } - @if (_canExport) - { - - @ConstantString.Export - - } - @if (_canImport) - { - - - +
+ + @ConstantString.Refresh + @if (_canCreate) + { + @ConstantString.New + - @if (_uploading) - { - - @ConstantString.Uploading - } - else - { - @ConstantString.Import - } - - - - } - - - @if (_canCreate) + Disabled="@(_selectedItems.Count!=1)" + OnClick="OnClone" + Style="margin-right: 4px; margin-bottom:4px" + IconColor="Color.Surface">@ConstantString.Clone + } + @if (_canDelete) + { + @ConstantString.Delete + } + @if (_canExport) + { + + @ConstantString.Export + + } + @if (_canImport) + { + + + + @if (_uploading) + { + + @ConstantString.Uploading + } + else + { + @ConstantString.Import + } + + + + } + + + @if (_canCreate) + { + @ConstantString.New + } + @if (_canDelete) + { + @ConstantString.Delete + } + +
+ @if (_canSearch) + { + + } + +
+
+ + + + + + @if (_canEdit || _canDelete) { - - @ConstantString.New - + + @if (_canEdit) + { + @ConstantString.Edit + } + @if (_canDelete) + { + @ConstantString.Delete + } + } - @if (_canDelete) + else { - - @ConstantString.Delete - - } - -
- @if (_canSearch) - { - - - } - -
-
- - - - - - @if (_canEdit || _canDelete) - { - - @if (_canEdit) - { - @ConstantString.Edit + Color="Color.Surface"> + @ConstantString.NoAllowed + } - @if (_canDelete) - { - @ConstantString.Delete - } - - } - else - { - - @ConstantString.NoAllowed - - } - - - @*TODO: Define the fields that should be displayed in data table*@ - - -
- @context.Item.Name - @context.Item.Description -
-
-
+ + + @*TODO: Define the fields that should be displayed in data table*@ + + +
+ @context.Item.Name + @context.Item.Description +
+
+
-
- - @ConstantString.NoRecords - - - @ConstantString.Loading - - - - + + + @ConstantString.NoRecords + + + @ConstantString.Loading + + + + + @code { public string? Title { get; private set; } private int _defaultPageSize = 15; - private HashSet _selectedItems = new(); + private HashSet _selectedItems = new HashSet(); private MudDataGrid _table = default!; private CustomerDto _currentDto = new(); private bool _loading; private bool _uploading; private bool _downloading; private bool _exporting; + [Inject] + private IMediator Mediator { get; set; } = default!; + [Inject] + private IMapper Mapper { get; set; } = default!; [CascadingParameter] - private UserProfile? UserProfile{ get; set; } - - [Inject] private IMediator Mediator { get; set; } = default!; - [Inject] private IMapper Mapper { get; set; } = default!; - [CascadingParameter] private Task AuthState { get; set; } = default!; + private Task AuthState { get; set; } = default!; + [CascadingParameter] + private UserProfile? UserProfile { get; set; } - private CustomersWithPaginationQuery Query { get; } = new(); - [Inject] private IBlazorDownloadFileService BlazorDownloadFileService { get; set; } = null!; + private CustomersWithPaginationQuery Query { get; set; } = new(); + [Inject] + private IBlazorDownloadFileService BlazorDownloadFileService { get; set; } = null!; private bool _canSearch; private bool _canCreate; private bool _canEdit; @@ -248,12 +239,11 @@ var state = await AuthState; _canCreate = (await AuthService.AuthorizeAsync(state.User, Permissions.Customers.Create)).Succeeded; _canSearch = (await AuthService.AuthorizeAsync(state.User, Permissions.Customers.Search)).Succeeded; - _canEdit = (await AuthService.AuthorizeAsync(state.User, Permissions.Customers.Edit)).Succeeded; + _canEdit = (await AuthService.AuthorizeAsync(state.User, Permissions.Customers.Edit)).Succeeded; _canDelete = (await AuthService.AuthorizeAsync(state.User, Permissions.Customers.Delete)).Succeeded; _canImport = (await AuthService.AuthorizeAsync(state.User, Permissions.Customers.Import)).Succeeded; _canExport = (await AuthService.AuthorizeAsync(state.User, Permissions.Customers.Export)).Succeeded; } - private async Task> ServerReload(GridState state) { try @@ -265,32 +255,30 @@ Query.PageNumber = state.Page + 1; Query.PageSize = state.PageSize; var result = await Mediator.Send(Query).ConfigureAwait(false); - return new GridData { TotalItems = result.TotalItems, Items = result.Items }; + return new GridData() { TotalItems = result.TotalItems, Items = result.Items }; } finally { _loading = false; } - } + } private async Task OnSearch(string text) { - _selectedItems = new HashSet(); + _selectedItems = new(); Query.Keyword = text; await _table.ReloadServerData(); } - private async Task OnChangedListView(CustomerListView listview) { Query.ListView = listview; await _table.ReloadServerData(); } - private async Task OnRefresh() { CustomerCacheKey.Refresh(); - _selectedItems = new HashSet(); - Query.Keyword = string.Empty; + _selectedItems = new(); + Query.Keyword = string.Empty; await _table.ReloadServerData(); } @@ -298,52 +286,50 @@ { var command = new AddEditCustomerCommand(); var parameters = new DialogParameters - { - { x => x.model, command } - }; + { + { x=>x.model,command }, + }; var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.Medium, FullWidth = true }; var dialog = DialogService.Show - (L["Create a new item"], parameters, options); + (L["Create a new item"], parameters, options); var state = await dialog.Result; if (!state.Canceled) { await _table.ReloadServerData(); } } - private async Task OnClone() { - var copyitem = _selectedItems.First(); - var command = new AddEditCustomerCommand - { - Name = copyitem.Name, - Description = copyitem.Description + var dto = _selectedItems.First(); + var command = new AddEditCustomerCommand(){ + Name = dto.Name, + Description = dto.Description, + }; var parameters = new DialogParameters - { - { x => x.model, command } - }; + { + { x=>x.model,command }, + }; var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.Medium, FullWidth = true }; var dialog = DialogService.Show - (L["Create a new item"], parameters, options); + (L["Create a new item"], parameters, options); var state = await dialog.Result; if (!state.Canceled) { await _table.ReloadServerData(); - _selectedItems.Remove(copyitem); + _selectedItems=new HashSet(); } } - private async Task OnEdit(CustomerDto dto) { var command = Mapper.Map(dto); var parameters = new DialogParameters - { - { x => x.model, command } - }; + { + { x=>x.model,command }, + }; var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.Medium, FullWidth = true }; var dialog = DialogService.Show - (L["Edit the item"], parameters, options); + (L["Edit the item"], parameters, options); var state = await dialog.Result; if (!state.Canceled) { @@ -353,19 +339,19 @@ private async Task OnDelete(CustomerDto dto) { - var command = new DeleteCustomerCommand(new[] { dto.Id }); - var parameters = new DialogParameters - { - { x => x.Command, command }, - { x => x.ContentText, string.Format(ConstantString.DeleteConfirmation, dto.Name) } - }; + var command = new DeleteCustomerCommand(new int[] { dto.Id }); + var parameters = new DialogParameters + { + { x=>x.Command, command }, + { x=>x.ContentText, string.Format(ConstantString.DeleteConfirmation, dto.Id) } + }; var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.Small, FullWidth = true, DisableBackdropClick = true }; var dialog = DialogService.Show(ConstantString.DeleteConfirmationTitle, parameters, options); var state = await dialog.Result; if (!state.Canceled) { - await _table.ReloadServerData(); - _selectedItems.Remove(dto); + await _table.ReloadServerData(); + _selectedItems.Remove(dto); } } @@ -373,45 +359,43 @@ { var command = new DeleteCustomerCommand(_selectedItems.Select(x => x.Id).ToArray()); var parameters = new DialogParameters - { - { x => x.Command, command }, - { x => x.ContentText, string.Format(ConstantString.DeleteConfirmWithSelected, _selectedItems.Count) } - }; + { + { x=>x.Command, command }, + { x=>x.ContentText, string.Format(ConstantString.DeleteConfirmWithSelected,_selectedItems.Count) } + }; var options = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.ExtraSmall, FullWidth = true, DisableBackdropClick = true }; var dialog = DialogService.Show(ConstantString.DeleteConfirmationTitle, parameters, options); var state = await dialog.Result; if (!state.Canceled) { await _table.ReloadServerData(); - _selectedItems = new HashSet(); + _selectedItems = new(); } } private async Task OnExport() { _exporting = true; - var request = new ExportCustomersQuery - { - Keyword = Query.Keyword, - CurrentUser = UserProfile, - ListView = Query.ListView, - OrderBy = _table.SortDefinitions.Values.FirstOrDefault()?.SortBy ?? "Id", - SortDirection = _table.SortDefinitions.Values.FirstOrDefault()?.Descending ?? true ? SortDirection.Descending.ToString() : SortDirection.Ascending.ToString() - }; + var request = new ExportCustomersQuery() + { + Keyword = Query.Keyword, + CurrentUser = UserProfile, + ListView = Query.ListView, + OrderBy = _table.SortDefinitions.Values.FirstOrDefault()?.SortBy ?? "Id", + SortDirection = (_table.SortDefinitions.Values.FirstOrDefault()?.Descending ?? true) ? SortDirection.Descending.ToString() : SortDirection.Ascending.ToString() + }; var result = await Mediator.Send(request); if (result.Succeeded) { - var downloadresult = await BlazorDownloadFileService.DownloadFile($"{L["Customers"]}.xlsx", result.Data, "application/octet-stream"); - Snackbar.Add($"{ConstantString.ExportSuccess}", Severity.Info); + var downloadresult = await BlazorDownloadFileService.DownloadFile($"{L["Customers"]}.xlsx", result.Data, contentType:"application/octet-stream"); + Snackbar.Add($"{ConstantString.ExportSuccess}", MudBlazor.Severity.Info); } else { - Snackbar.Add($"{result.ErrorMessage}", Severity.Error); + Snackbar.Add($"{result.ErrorMessage}", MudBlazor.Severity.Error); } - _exporting = false; } - private async Task OnImportData(IBrowserFile file) { _uploading = true; @@ -422,17 +406,16 @@ if (result.Succeeded) { await _table.ReloadServerData(); - Snackbar.Add($"{ConstantString.ImportSuccess}", Severity.Info); + Snackbar.Add($"{ConstantString.ImportSuccess}", MudBlazor.Severity.Info); } else { foreach (var msg in result.Errors) { - Snackbar.Add($"{msg}", Severity.Error); + Snackbar.Add($"{msg}", MudBlazor.Severity.Error); } } - _uploading = false; } -} \ No newline at end of file +} diff --git a/src/Server.UI/_Imports.razor b/src/Server.UI/_Imports.razor index 6b78d9665..a61029419 100644 --- a/src/Server.UI/_Imports.razor +++ b/src/Server.UI/_Imports.razor @@ -1,4 +1,4 @@ -@using System.Net.Http +@using System.Net.Http @using System.Net.Http.Json @using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Components.Forms @@ -25,7 +25,7 @@ @using CleanArchitecture.Blazor.Application.Common.Extensions @using CleanArchitecture.Blazor.Application.Common.Interfaces @using CleanArchitecture.Blazor.Application.Common.Models -@using CleanArchitecture.Blazor.Infrastructure.Constants.Permission; +@using CleanArchitecture.Blazor.Infrastructure.PermissionSet; @using CleanArchitecture.Blazor.Infrastructure.Constants @using CleanArchitecture.Blazor.Infrastructure.Extensions @using CleanArchitecture.Blazor.Infrastructure.Configurations