├── .dockerignore ├── .editorconfig ├── .gitattributes ├── .gitignore ├── CH.CleanArchitecture.sln ├── CodeMap.dgml ├── DeveloperGuidelines.txt ├── LICENSE ├── README.md ├── README.txt ├── SecretsManagement.txt ├── Source ├── CH.CleanArchitecture.Common │ ├── Attributes │ │ └── EnsureOneElementAttribute.cs │ ├── CH.CleanArchitecture.Common.csproj │ ├── Converters │ │ └── DateFormatConverter.cs │ ├── Enumerations │ │ ├── LanguageEnum.cs │ │ └── ThemeEnum.cs │ ├── Extensions │ │ ├── DoubleExtensions.cs │ │ ├── EnumExtensions.cs │ │ ├── ListExtensions.cs │ │ ├── ObjectExtensions.cs │ │ ├── QueryableExtensions.cs │ │ ├── ResultExtensions.cs │ │ ├── StreamExtensions.cs │ │ └── StringExtensions.cs │ ├── Notifications │ │ └── NotificationType.cs │ ├── Options │ │ └── QueryOptions.cs │ ├── Paging │ │ ├── PagedResult.cs │ │ └── PagedResultBase.cs │ ├── Results │ │ ├── IResult.cs │ │ ├── IResultError.cs │ │ ├── Result.cs │ │ └── ResultError.cs │ └── StringCipherHelper.cs ├── Core │ ├── CH.CleanArchitecture.Core.Application │ │ ├── Authorization │ │ │ ├── CustomAuthorizationPolicyProvider.cs │ │ │ ├── Handlers │ │ │ │ └── UserOperationAuthorizationHandler.cs │ │ │ ├── Operations │ │ │ │ └── UserOperations.cs │ │ │ ├── OperationsStatics.cs │ │ │ └── Requirements │ │ │ │ └── UserOperationAuthorizationRequirement.cs │ │ ├── BaseCommand.cs │ │ ├── BaseCommandHandler.cs │ │ ├── BaseEvent.cs │ │ ├── BaseEventHandler.cs │ │ ├── BaseMessageHandler.cs │ │ ├── CH.CleanArchitecture.Core.Application.csproj │ │ ├── Commands │ │ │ ├── Orders │ │ │ │ ├── AddOrderItemCommand.cs │ │ │ │ └── CreateNewOrderCommand.cs │ │ │ └── Users │ │ │ │ ├── ActivateUserCommand.cs │ │ │ │ ├── AddRolesCommand.cs │ │ │ │ ├── ChangeUserPasswordCommand.cs │ │ │ │ ├── CreateUserCommand.cs │ │ │ │ ├── DeactivateUserCommand.cs │ │ │ │ ├── RemoveRolesCommand.cs │ │ │ │ ├── UpdateUserDetailsCommand.cs │ │ │ │ └── UpdateUserRolesCommand.cs │ │ ├── Constants │ │ │ └── ApplicationClaimTypes.cs │ │ ├── DTOs │ │ │ ├── ApplicationConfigurationDTO.cs │ │ │ ├── Audit │ │ │ │ ├── AuditHistoryDTO.cs │ │ │ │ └── AuditHistoryDetailsDTO.cs │ │ │ ├── Login │ │ │ │ ├── Login2FARequest.cs │ │ │ │ ├── LoginRequestDTO.cs │ │ │ │ └── LoginResponseDTO.cs │ │ │ ├── Notifications │ │ │ │ ├── NotificationDTO.cs │ │ │ │ ├── SendNotificationBaseDTO.cs │ │ │ │ └── SendNotificationDTO.cs │ │ │ ├── RoleAssignmentRequestDTO.cs │ │ │ └── UpdateUserDetailsDTO.cs │ │ ├── Extensions │ │ │ ├── AuthorizationHandlerContextExtensions.cs │ │ │ ├── ClaimsPrincipalExtensions.cs │ │ │ └── ServiceCollectionExtensions.cs │ │ ├── Interfaces │ │ │ ├── Auth │ │ │ │ ├── IApplicationUserService.cs │ │ │ │ ├── IAuthenticatedUserService.cs │ │ │ │ └── IUserAuthenticationService.cs │ │ │ ├── Communication │ │ │ │ ├── IEmailService.cs │ │ │ │ └── ISMSService.cs │ │ │ ├── Crypto │ │ │ │ ├── IJWTService.cs │ │ │ │ ├── IPasswordGeneratorService.cs │ │ │ │ └── IUrlTokenService.cs │ │ │ ├── ICommand.cs │ │ │ ├── IEvent.cs │ │ │ ├── IQuery.cs │ │ │ ├── IReadModel.cs │ │ │ ├── Repositories │ │ │ │ └── Domain │ │ │ │ │ └── IOrderRepository.cs │ │ │ ├── Shared │ │ │ │ ├── IApplicationConfigurationService.cs │ │ │ │ ├── IAuditHistoryService.cs │ │ │ │ ├── ILocalizationKeyProvider.cs │ │ │ │ ├── ILocalizationService.cs │ │ │ │ └── INotificationService.cs │ │ │ └── Storage │ │ │ │ └── IResourceStore.cs │ │ ├── Mappings │ │ │ ├── Resolvers │ │ │ │ └── PhoneNumberConverter.cs │ │ │ └── UserProfile.cs │ │ ├── Queries │ │ │ ├── Base │ │ │ │ └── IPagedQuery.cs │ │ │ ├── Orders │ │ │ │ ├── GetAllOrdersQuery.cs │ │ │ │ └── GetOrderByIdQuery.cs │ │ │ └── Users │ │ │ │ ├── GetAllUsersQuery.cs │ │ │ │ └── GetUserQuery.cs │ │ ├── ReadModels │ │ │ ├── AddressReadModel.cs │ │ │ ├── Orders │ │ │ │ ├── OrderItemReadModel.cs │ │ │ │ └── OrderReadModel.cs │ │ │ └── User │ │ │ │ └── UserReadModel.cs │ │ ├── ServicesHelper.cs │ │ └── Validators │ │ │ └── CreateNewOrderCommandValidator.cs │ └── CH.CleanArchitecture.Core.Domain │ │ ├── CH.CleanArchitecture.Core.Domain.csproj │ │ ├── Entities │ │ ├── AggregateRootBase.cs │ │ ├── DomainEventBase.cs │ │ ├── OrderAggregate │ │ │ ├── Order.cs │ │ │ └── OrderItem.cs │ │ └── UserAggregate │ │ │ └── User.cs │ │ ├── Enumerations │ │ └── RoleEnum.cs │ │ ├── Events │ │ ├── Order │ │ │ ├── OrderBillingAddressAddedEvent.cs │ │ │ ├── OrderCreatedEvent.cs │ │ │ ├── OrderItemAddedEvent.cs │ │ │ ├── OrderItemQuantityUpdatedEvent.cs │ │ │ └── OrderShippingAddressAddedEvent.cs │ │ └── User │ │ │ ├── UserCreatedEvent.cs │ │ │ └── UserDetailsChangedEvent.cs │ │ └── ValueObjects │ │ ├── Address.cs │ │ └── PhoneNumber.cs ├── Dockerfile ├── Infrastructure │ ├── CH.CleanArchitecture.Infrastructure.Auditing │ │ ├── Attributes │ │ │ └── NotAuditable.cs │ │ ├── AuditUtilities.cs │ │ ├── CH.CleanArchitecture.Infrastructure.Auditing.csproj │ │ ├── Extensions │ │ │ ├── DbContextExtensions.cs │ │ │ └── ModelBuilderExtensions.cs │ │ └── Models │ │ │ ├── AuditHistory.cs │ │ │ └── AuditHistoryDetails.cs │ ├── CH.CleanArchitecture.Infrastructure.Resources │ │ ├── CH.CleanArchitecture.Infrastructure.Resources.csproj │ │ ├── ResourceKeys.cs │ │ ├── ResourceKeys.tt │ │ ├── Services │ │ │ ├── LocalizationKeyProvider.cs │ │ │ └── LocalizationService.cs │ │ ├── SharedResources.Designer.cs │ │ └── SharedResources.resx │ ├── CH.CleanArchitecture.Infrastructure.Shared │ │ ├── CH.CleanArchitecture.Infrastructure.Shared.csproj │ │ ├── Constants │ │ │ └── Constants.cs │ │ ├── Culture │ │ │ └── Providers │ │ │ │ └── UserProfileRequestCultureProvider.cs │ │ └── Extensions │ │ │ └── FormFileExtensions.cs │ └── CH.CleanArchitecture.Infrastructure │ │ ├── CH.CleanArchitecture.Infrastructure.csproj │ │ ├── Constants │ │ └── AppConfigKeys.cs │ │ ├── DbContexts │ │ ├── ApplicationDbContext.cs │ │ ├── DbContextUpdateOperations.cs │ │ └── IdentityDbContext.cs │ │ ├── EntityTypeConfigurations │ │ ├── AddressEntityConfiguration.cs │ │ ├── Application │ │ │ ├── ApplicationConfigurationEntityConfiguration.cs │ │ │ ├── NotificationEntityConfiguration.cs │ │ │ ├── OrderEntityConfiguration.cs │ │ │ └── OrderItemEntityConfiguration.cs │ │ └── Identity │ │ │ ├── ApplicationRoleConfiguration.cs │ │ │ ├── ApplicationUserConfiguration.cs │ │ │ ├── ApplicationUserRoleConfiguration.cs │ │ │ ├── RoleClaimsConfiguration.cs │ │ │ ├── UserClaimsConfiguration.cs │ │ │ ├── UserLoginsConfiguration.cs │ │ │ └── UserTokensConfiguration.cs │ │ ├── Extensions │ │ └── ServiceCollectionExtensions.cs │ │ ├── Factories │ │ └── ApplicationUserClaimsPrincipalFactory.cs │ │ ├── Handlers │ │ └── Queries │ │ │ ├── Orders │ │ │ ├── GetAllOrdersQueryHandler.cs │ │ │ └── GetOrderByIdQueryHandler.cs │ │ │ └── Users │ │ │ ├── GetAllUsersQueryHandler.cs │ │ │ └── GetUserQueryHandler.cs │ │ ├── Mappings │ │ ├── AppProfile.cs │ │ ├── Domain │ │ │ └── OrderProfile.cs │ │ ├── EventProfile.cs │ │ └── UserProfile.cs │ │ ├── Migrations │ │ ├── Application │ │ │ ├── 20230725115215_InitialMigration.Designer.cs │ │ │ ├── 20230725115215_InitialMigration.cs │ │ │ ├── 20230812151259_AddedNotifications.Designer.cs │ │ │ ├── 20230812151259_AddedNotifications.cs │ │ │ └── ApplicationDbContextModelSnapshot.cs │ │ └── Identity │ │ │ ├── 20230725115250_InitialMigration.Designer.cs │ │ │ ├── 20230725115250_InitialMigration.cs │ │ │ └── IdentityDbContextModelSnapshot.cs │ │ ├── Models │ │ ├── AddressEntity.cs │ │ ├── Application │ │ │ ├── ApplicationConfigurationEntity.cs │ │ │ ├── NotificationEntity.cs │ │ │ └── Order │ │ │ │ ├── OrderEntity.cs │ │ │ │ └── OrderItemEntity.cs │ │ └── Identity │ │ │ └── ApplicationUser.cs │ │ ├── Options │ │ ├── EmailSenderOptions.cs │ │ └── StorageOptions.cs │ │ ├── Repositories │ │ ├── DataEntityRepository.cs │ │ ├── EFRepository.cs │ │ ├── ESRepository.cs │ │ └── OrderRepository.cs │ │ └── Services │ │ ├── Auth │ │ ├── ApplicationUserService.cs │ │ ├── DefaultAuthenticatedUserService.cs │ │ └── UserAuthenticationService.cs │ │ ├── Communication │ │ ├── EmailSMTPService.cs │ │ ├── EmailSendGridService.cs │ │ └── SMSService.cs │ │ ├── Crypto │ │ ├── JWTService.cs │ │ ├── PasswordGeneratorIdentityService.cs │ │ └── UrlTokenService.cs │ │ ├── DbInitializer │ │ ├── DbInitializerService.cs │ │ └── IDbInitializerService.cs │ │ ├── Jobs │ │ ├── IScheduledJobService.cs │ │ └── ScheduledJobService.cs │ │ ├── ServiceBusMediator.cs │ │ ├── Shared │ │ ├── ApplicationConfigurationService.cs │ │ ├── AuditHistoryService.cs │ │ └── NotificationService.cs │ │ └── Storage │ │ ├── AWSS3ResourceStore.cs │ │ └── AzureStorageResourceStore.cs └── Presentation │ ├── CH.CleanArchitecture.Presentation.Framework │ ├── CH.CleanArchitecture.Presentation.Framework.csproj │ ├── Components │ │ ├── AuthorizedView.razor │ │ ├── AuthorizedView.razor.cs │ │ ├── BaseComponent.cs │ │ ├── CRUDAnchor.razor │ │ ├── CRUDButton.razor │ │ ├── CRUDButton.razor.cs │ │ ├── DisplayName.razor │ │ ├── LoaderComponent.razor │ │ ├── ModalTemplate.razor │ │ ├── ModalTemplate.razor.cs │ │ ├── Pager.razor │ │ ├── Select2.razor │ │ ├── Select2.razor.cs │ │ ├── TabGroup.razor │ │ ├── TabGroup.razor.cs │ │ ├── TabPage.razor │ │ ├── TabPage.razor.cs │ │ ├── Wizard.razor │ │ ├── Wizard.razor.cs │ │ ├── WizardStep.razor │ │ └── WizardStep.razor.cs │ ├── Enumerations │ │ └── CRUDElementTypeEnum.cs │ ├── Extensions │ │ └── HtmlExtensions.cs │ ├── HangfireDashboardAuthorizationFilter.cs │ ├── Helpers │ │ └── CRUDElementsHelper.cs │ ├── Interfaces │ │ ├── IAuthorizationStateProvider.cs │ │ ├── ICRUDElementHelper.cs │ │ ├── IModalService.cs │ │ └── IToastService.cs │ ├── Models │ │ ├── Select2Item.cs │ │ ├── Select2Pagination.cs │ │ ├── Select2QueryData.cs │ │ ├── Select2QueryParams.cs │ │ └── Select2Response.cs │ ├── Queries │ │ └── DataTablesParameters.cs │ ├── Services │ │ ├── DefaultModalService.cs │ │ └── LoaderService.cs │ ├── WebFrameworkConstants.cs │ └── _Imports.razor │ └── CH.CleanArchitecture.Presentation.Web │ ├── CH.CleanArchitecture.Presentation.Web.csproj │ ├── Constants │ └── Constants.cs │ ├── Controllers │ ├── AuthController.cs │ ├── BaseController.cs │ ├── DeveloperController.cs │ ├── HomeController.cs │ ├── OrdersController.cs │ ├── TestController.cs │ ├── UserProfileController.cs │ └── UsersController.cs │ ├── Enumerations │ └── TempNotificationType.cs │ ├── Extensions │ └── ServiceCollectionExtensions.cs │ ├── Helpers │ └── UserHelper.cs │ ├── Mappings │ ├── AppProfile.cs │ └── Resolvers │ │ ├── LocalizedRolesResolver.cs │ │ └── RolesToMultiSelectResolver.cs │ ├── Middleware │ └── MustChangePasswordMiddleware.cs │ ├── Models │ └── TempNotificationData.cs │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── RazorComponents │ ├── ConfirmationModal.razor │ ├── ConfirmationModal.razor.cs │ ├── DeveloperManagementComponent.razor │ ├── SelectUserComponent.razor │ ├── SelectUserComponent.razor.cs │ └── _Imports.razor │ ├── Services │ ├── AuthenticatedUserService.cs │ ├── AuthorizationStateProvider.cs │ ├── TempNotificationService.cs │ └── ToastService.cs │ ├── Startup.cs │ ├── UrlHelper.cs │ ├── Validators │ ├── Auth │ │ └── LoginValidator.cs │ └── LocalizedDataAnnotationsValidator │ │ ├── Internals │ │ ├── Extensions │ │ │ └── ReflectionExtensions.cs │ │ ├── LocalizedValidationContext.cs │ │ ├── ValidationAttributeStores │ │ │ ├── PropertyStoreItem.cs │ │ │ ├── StoreItem.cs │ │ │ ├── TypeStoreItem.cs │ │ │ └── ValidationAttributeStore.cs │ │ └── Validators │ │ │ ├── LocalizedValidator.cs │ │ │ └── ValidationError.cs │ │ ├── LocalizedDataAnnotationsValidator.cs │ │ └── LocalizedEditContextDataAnnotationsExtensions.cs │ ├── ViewComponents │ ├── FooterViewComponent.cs │ └── TopBarViewComponent.cs │ ├── ViewModels │ ├── ErrorViewModel.cs │ ├── FooterViewModel.cs │ ├── HomeViewModel.cs │ ├── Orders │ │ ├── CreateOrderViewModel.cs │ │ ├── IndexViewModel.cs │ │ └── OrderViewModel.cs │ ├── TopBarViewModel.cs │ └── Users │ │ ├── ChangePasswordModel.cs │ │ ├── CreateUserViewModel.cs │ │ ├── EditUserViewModel.cs │ │ ├── LoginViewModel.cs │ │ └── UserDetailsModel.cs │ ├── Views │ ├── Auth │ │ ├── ChangePassword.cshtml │ │ └── Login.cshtml │ ├── Developer │ │ └── Index.cshtml │ ├── Home │ │ └── Index.cshtml │ ├── Orders │ │ └── Index.cshtml │ ├── Shared │ │ ├── Components │ │ │ ├── Footer │ │ │ │ └── Default.cshtml │ │ │ └── TopBar │ │ │ │ └── Default.cshtml │ │ ├── Error.cshtml │ │ ├── Layouts │ │ │ ├── _BlankLayout.cshtml │ │ │ └── _Layout.cshtml │ │ ├── _BlazorJS.cshtml │ │ ├── _CrudCss.cshtml │ │ ├── _CrudJS.cshtml │ │ ├── _DatatablesCss.cshtml │ │ ├── _DatatablesJS.cshtml │ │ ├── _HeadCss.cshtml │ │ ├── _PageTitle.cshtml │ │ ├── _TitleMeta.cshtml │ │ ├── _ValidationScriptsPartial.cshtml │ │ └── _notifications.cshtml │ ├── UserProfile │ │ ├── Index.cshtml │ │ └── _ChangePassword.cshtml │ ├── Users │ │ ├── Create.cshtml │ │ ├── Details.cshtml │ │ ├── Edit.cshtml │ │ └── Index.cshtml │ ├── _ViewImports.cshtml │ └── _ViewStart.cshtml │ ├── _Imports.razor │ ├── appsettings.Development.json │ ├── appsettings.DockerCompose.json │ ├── appsettings.json │ ├── libman.json │ ├── web.config │ └── wwwroot │ ├── assets │ ├── css │ │ ├── app-dark.css │ │ ├── app.css │ │ ├── bootstrap-dark.css │ │ ├── bootstrap.css │ │ └── icons.css │ ├── fonts │ │ ├── boxicons.eot │ │ ├── boxicons.svg │ │ ├── boxicons.ttf │ │ ├── boxicons.woff │ │ ├── boxicons.woff2 │ │ ├── dripicons-v2.eot │ │ ├── dripicons-v2.svg │ │ ├── dripicons-v2.ttf │ │ ├── dripicons-v2.woff │ │ ├── fa-brands-400.eot │ │ ├── fa-brands-400.svg │ │ ├── fa-brands-400.ttf │ │ ├── fa-brands-400.woff │ │ ├── fa-brands-400.woff2 │ │ ├── fa-regular-400.eot │ │ ├── fa-regular-400.svg │ │ ├── fa-regular-400.ttf │ │ ├── fa-regular-400.woff │ │ ├── fa-regular-400.woff2 │ │ ├── fa-solid-900.eot │ │ ├── fa-solid-900.svg │ │ ├── fa-solid-900.ttf │ │ ├── fa-solid-900.woff │ │ ├── fa-solid-900.woff2 │ │ ├── materialdesignicons-webfont.eot │ │ ├── materialdesignicons-webfont.ttf │ │ ├── materialdesignicons-webfont.woff │ │ ├── materialdesignicons-webfont.woff2 │ │ ├── summernote.eot │ │ ├── summernote.ttf │ │ └── summernote.woff │ ├── images │ │ ├── close.svg │ │ ├── favicon.ico │ │ ├── flags │ │ │ ├── el.png │ │ │ └── en.png │ │ ├── profile-img.png │ │ └── users │ │ │ └── default_avatar.png │ ├── js │ │ ├── app.js │ │ ├── common.js │ │ ├── lang │ │ │ └── jquery.multiLanguage.js │ │ └── pages │ │ │ ├── datatables.init.js │ │ │ ├── form-advanced.init.js │ │ │ ├── form-validation.init.js │ │ │ ├── form-xeditable.init.js │ │ │ └── two-step-verification.init.js │ └── libs │ │ ├── bootstrap-colorpicker │ │ ├── css │ │ │ └── bootstrap-colorpicker.min.css │ │ └── js │ │ │ └── bootstrap-colorpicker.min.js │ │ ├── bootstrap-datepicker │ │ ├── css │ │ │ ├── bootstrap-datepicker.min.css │ │ │ ├── bootstrap-datepicker.standalone.min.css │ │ │ ├── bootstrap-datepicker3.min.css │ │ │ └── bootstrap-datepicker3.standalone.min.css │ │ ├── js │ │ │ └── bootstrap-datepicker.min.js │ │ └── locales │ │ │ ├── bootstrap-datepicker-en-CA.min.js │ │ │ ├── bootstrap-datepicker.ar-tn.min.js │ │ │ ├── bootstrap-datepicker.ar.min.js │ │ │ ├── bootstrap-datepicker.az.min.js │ │ │ ├── bootstrap-datepicker.bg.min.js │ │ │ ├── bootstrap-datepicker.bm.min.js │ │ │ ├── bootstrap-datepicker.bn.min.js │ │ │ ├── bootstrap-datepicker.br.min.js │ │ │ ├── bootstrap-datepicker.bs.min.js │ │ │ ├── bootstrap-datepicker.ca.min.js │ │ │ ├── bootstrap-datepicker.cs.min.js │ │ │ ├── bootstrap-datepicker.cy.min.js │ │ │ ├── bootstrap-datepicker.da.min.js │ │ │ ├── bootstrap-datepicker.de.min.js │ │ │ ├── bootstrap-datepicker.el.min.js │ │ │ ├── bootstrap-datepicker.en-AU.min.js │ │ │ ├── bootstrap-datepicker.en-CA.min.js │ │ │ ├── bootstrap-datepicker.en-GB.min.js │ │ │ ├── bootstrap-datepicker.en-IE.min.js │ │ │ ├── bootstrap-datepicker.en-NZ.min.js │ │ │ ├── bootstrap-datepicker.en-ZA.min.js │ │ │ ├── bootstrap-datepicker.eo.min.js │ │ │ ├── bootstrap-datepicker.es.min.js │ │ │ ├── bootstrap-datepicker.et.min.js │ │ │ ├── bootstrap-datepicker.eu.min.js │ │ │ ├── bootstrap-datepicker.fa.min.js │ │ │ ├── bootstrap-datepicker.fi.min.js │ │ │ ├── bootstrap-datepicker.fo.min.js │ │ │ ├── bootstrap-datepicker.fr-CH.min.js │ │ │ ├── bootstrap-datepicker.fr.min.js │ │ │ ├── bootstrap-datepicker.gl.min.js │ │ │ ├── bootstrap-datepicker.he.min.js │ │ │ ├── bootstrap-datepicker.hi.min.js │ │ │ ├── bootstrap-datepicker.hr.min.js │ │ │ ├── bootstrap-datepicker.hu.min.js │ │ │ ├── bootstrap-datepicker.hy.min.js │ │ │ ├── bootstrap-datepicker.id.min.js │ │ │ ├── bootstrap-datepicker.is.min.js │ │ │ ├── bootstrap-datepicker.it-CH.min.js │ │ │ ├── bootstrap-datepicker.it.min.js │ │ │ ├── bootstrap-datepicker.ja.min.js │ │ │ ├── bootstrap-datepicker.ka.min.js │ │ │ ├── bootstrap-datepicker.kh.min.js │ │ │ ├── bootstrap-datepicker.kk.min.js │ │ │ ├── bootstrap-datepicker.km.min.js │ │ │ ├── bootstrap-datepicker.ko.min.js │ │ │ ├── bootstrap-datepicker.kr.min.js │ │ │ ├── bootstrap-datepicker.lt.min.js │ │ │ ├── bootstrap-datepicker.lv.min.js │ │ │ ├── bootstrap-datepicker.me.min.js │ │ │ ├── bootstrap-datepicker.mk.min.js │ │ │ ├── bootstrap-datepicker.mn.min.js │ │ │ ├── bootstrap-datepicker.ms.min.js │ │ │ ├── bootstrap-datepicker.nl-BE.min.js │ │ │ ├── bootstrap-datepicker.nl.min.js │ │ │ ├── bootstrap-datepicker.no.min.js │ │ │ ├── bootstrap-datepicker.oc.min.js │ │ │ ├── bootstrap-datepicker.pl.min.js │ │ │ ├── bootstrap-datepicker.pt-BR.min.js │ │ │ ├── bootstrap-datepicker.pt.min.js │ │ │ ├── bootstrap-datepicker.ro.min.js │ │ │ ├── bootstrap-datepicker.rs-latin.min.js │ │ │ ├── bootstrap-datepicker.rs.min.js │ │ │ ├── bootstrap-datepicker.ru.min.js │ │ │ ├── bootstrap-datepicker.si.min.js │ │ │ ├── bootstrap-datepicker.sk.min.js │ │ │ ├── bootstrap-datepicker.sl.min.js │ │ │ ├── bootstrap-datepicker.sq.min.js │ │ │ ├── bootstrap-datepicker.sr-latin.min.js │ │ │ ├── bootstrap-datepicker.sr.min.js │ │ │ ├── bootstrap-datepicker.sv.min.js │ │ │ ├── bootstrap-datepicker.sw.min.js │ │ │ ├── bootstrap-datepicker.ta.min.js │ │ │ ├── bootstrap-datepicker.tg.min.js │ │ │ ├── bootstrap-datepicker.th.min.js │ │ │ ├── bootstrap-datepicker.tk.min.js │ │ │ ├── bootstrap-datepicker.tr.min.js │ │ │ ├── bootstrap-datepicker.uk.min.js │ │ │ ├── bootstrap-datepicker.uz-cyrl.min.js │ │ │ ├── bootstrap-datepicker.uz-latn.min.js │ │ │ ├── bootstrap-datepicker.vi.min.js │ │ │ ├── bootstrap-datepicker.zh-CN.min.js │ │ │ └── bootstrap-datepicker.zh-TW.min.js │ │ ├── bootstrap-editable │ │ ├── css │ │ │ └── bootstrap-editable.css │ │ ├── img │ │ │ ├── clear.png │ │ │ └── loading.gif │ │ └── js │ │ │ └── index.js │ │ ├── bootstrap-maxlength │ │ └── bootstrap-maxlength.min.js │ │ ├── bootstrap-timepicker │ │ ├── css │ │ │ └── bootstrap-timepicker.min.css │ │ └── js │ │ │ └── bootstrap-timepicker.min.js │ │ ├── bootstrap-toggle │ │ ├── css │ │ │ └── bootstrap-toggle.css │ │ └── js │ │ │ └── bootstrap-toggle.js │ │ ├── bootstrap-touchspin │ │ ├── jquery.bootstrap-touchspin.min.css │ │ └── jquery.bootstrap-touchspin.min.js │ │ ├── bootstrap │ │ ├── LICENSE │ │ ├── css │ │ │ ├── bootstrap-grid.min.css │ │ │ ├── bootstrap-reboot.min.css │ │ │ └── bootstrap.min.css │ │ ├── dist │ │ │ ├── css │ │ │ │ ├── bootstrap-grid.css │ │ │ │ ├── bootstrap-grid.css.map │ │ │ │ ├── bootstrap-grid.min.css │ │ │ │ ├── bootstrap-grid.min.css.map │ │ │ │ ├── bootstrap-reboot.css │ │ │ │ ├── bootstrap-reboot.css.map │ │ │ │ ├── bootstrap-reboot.min.css │ │ │ │ ├── bootstrap-reboot.min.css.map │ │ │ │ ├── bootstrap.css │ │ │ │ ├── bootstrap.css.map │ │ │ │ ├── bootstrap.min.css │ │ │ │ └── bootstrap.min.css.map │ │ │ └── js │ │ │ │ ├── bootstrap.bundle.js │ │ │ │ ├── bootstrap.bundle.js.map │ │ │ │ ├── bootstrap.bundle.min.js │ │ │ │ ├── bootstrap.bundle.min.js.map │ │ │ │ ├── bootstrap.js │ │ │ │ ├── bootstrap.js.map │ │ │ │ ├── bootstrap.min.js │ │ │ │ └── bootstrap.min.js.map │ │ └── js │ │ │ ├── bootstrap.bundle.min.js │ │ │ └── bootstrap.min.js │ │ ├── chenfengyuan │ │ └── datepicker │ │ │ ├── datepicker.common.js │ │ │ ├── datepicker.esm.js │ │ │ ├── datepicker.min.css │ │ │ └── datepicker.min.js │ │ ├── datatables-net-dateTime │ │ └── js │ │ │ └── dataTables.dateTime.min.js │ │ ├── datatables.net-bs4 │ │ ├── css │ │ │ └── dataTables.bootstrap4.min.css │ │ └── js │ │ │ └── dataTables.bootstrap4.min.js │ │ ├── datatables.net-buttons-bs4 │ │ ├── css │ │ │ └── buttons.bootstrap4.min.css │ │ └── js │ │ │ └── buttons.bootstrap4.min.js │ │ ├── datatables.net-buttons │ │ ├── License.txt │ │ ├── js │ │ │ ├── buttons.colVis.min.js │ │ │ ├── buttons.flash.min.js │ │ │ ├── buttons.html5.min.js │ │ │ ├── buttons.print.min.js │ │ │ └── dataTables.buttons.min.js │ │ └── swf │ │ │ └── flashExport.swf │ │ ├── datatables.net-responsive-bs4 │ │ ├── css │ │ │ └── responsive.bootstrap4.min.css │ │ └── js │ │ │ └── responsive.bootstrap4.min.js │ │ ├── datatables.net-responsive │ │ ├── License.txt │ │ └── js │ │ │ └── dataTables.responsive.min.js │ │ ├── datatables.net │ │ ├── License.txt │ │ └── js │ │ │ └── jquery.dataTables.min.js │ │ ├── dropzone │ │ ├── basic.css │ │ ├── dropzone-amd-module.js │ │ ├── dropzone.css │ │ ├── dropzone.js │ │ └── min │ │ │ ├── basic.min.css │ │ │ ├── dropzone-amd-module.min.js │ │ │ ├── dropzone.min.css │ │ │ └── dropzone.min.js │ │ ├── jquery │ │ ├── LICENSE.txt │ │ ├── dist │ │ │ ├── jquery.js │ │ │ ├── jquery.min.js │ │ │ └── jquery.min.map │ │ ├── jquery.min.js │ │ └── jquery.slim.min.js │ │ ├── jszip │ │ └── jszip.min.js │ │ ├── metismenu │ │ ├── cjs │ │ │ └── index.js │ │ ├── metisMenu.min.css │ │ ├── metisMenu.min.js │ │ └── modules │ │ │ └── index.js │ │ ├── moment │ │ ├── ender.js │ │ ├── locale │ │ │ ├── af.js │ │ │ ├── ar-dz.js │ │ │ ├── ar-kw.js │ │ │ ├── ar-ly.js │ │ │ ├── ar-ma.js │ │ │ ├── ar-sa.js │ │ │ ├── ar-tn.js │ │ │ ├── ar.js │ │ │ ├── az.js │ │ │ ├── be.js │ │ │ ├── bg.js │ │ │ ├── bm.js │ │ │ ├── bn.js │ │ │ ├── bo.js │ │ │ ├── br.js │ │ │ ├── bs.js │ │ │ ├── ca.js │ │ │ ├── cs.js │ │ │ ├── cv.js │ │ │ ├── cy.js │ │ │ ├── da.js │ │ │ ├── de-at.js │ │ │ ├── de-ch.js │ │ │ ├── de.js │ │ │ ├── dv.js │ │ │ ├── el.js │ │ │ ├── en-SG.js │ │ │ ├── en-au.js │ │ │ ├── en-ca.js │ │ │ ├── en-gb.js │ │ │ ├── en-ie.js │ │ │ ├── en-il.js │ │ │ ├── en-nz.js │ │ │ ├── eo.js │ │ │ ├── es-do.js │ │ │ ├── es-us.js │ │ │ ├── es.js │ │ │ ├── et.js │ │ │ ├── eu.js │ │ │ ├── fa.js │ │ │ ├── fi.js │ │ │ ├── fo.js │ │ │ ├── fr-ca.js │ │ │ ├── fr-ch.js │ │ │ ├── fr.js │ │ │ ├── fy.js │ │ │ ├── ga.js │ │ │ ├── gd.js │ │ │ ├── gl.js │ │ │ ├── gom-latn.js │ │ │ ├── gu.js │ │ │ ├── he.js │ │ │ ├── hi.js │ │ │ ├── hr.js │ │ │ ├── hu.js │ │ │ ├── hy-am.js │ │ │ ├── id.js │ │ │ ├── is.js │ │ │ ├── it-ch.js │ │ │ ├── it.js │ │ │ ├── ja.js │ │ │ ├── jv.js │ │ │ ├── ka.js │ │ │ ├── kk.js │ │ │ ├── km.js │ │ │ ├── kn.js │ │ │ ├── ko.js │ │ │ ├── ku.js │ │ │ ├── ky.js │ │ │ ├── lb.js │ │ │ ├── lo.js │ │ │ ├── lt.js │ │ │ ├── lv.js │ │ │ ├── me.js │ │ │ ├── mi.js │ │ │ ├── mk.js │ │ │ ├── ml.js │ │ │ ├── mn.js │ │ │ ├── mr.js │ │ │ ├── ms-my.js │ │ │ ├── ms.js │ │ │ ├── mt.js │ │ │ ├── my.js │ │ │ ├── nb.js │ │ │ ├── ne.js │ │ │ ├── nl-be.js │ │ │ ├── nl.js │ │ │ ├── nn.js │ │ │ ├── pa-in.js │ │ │ ├── pl.js │ │ │ ├── pt-br.js │ │ │ ├── pt.js │ │ │ ├── ro.js │ │ │ ├── ru.js │ │ │ ├── sd.js │ │ │ ├── se.js │ │ │ ├── si.js │ │ │ ├── sk.js │ │ │ ├── sl.js │ │ │ ├── sq.js │ │ │ ├── sr-cyrl.js │ │ │ ├── sr.js │ │ │ ├── ss.js │ │ │ ├── sv.js │ │ │ ├── sw.js │ │ │ ├── ta.js │ │ │ ├── te.js │ │ │ ├── tet.js │ │ │ ├── tg.js │ │ │ ├── th.js │ │ │ ├── tl-ph.js │ │ │ ├── tlh.js │ │ │ ├── tr.js │ │ │ ├── tzl.js │ │ │ ├── tzm-latn.js │ │ │ ├── tzm.js │ │ │ ├── ug-cn.js │ │ │ ├── uk.js │ │ │ ├── ur.js │ │ │ ├── uz-latn.js │ │ │ ├── uz.js │ │ │ ├── vi.js │ │ │ ├── x-pseudo.js │ │ │ ├── yo.js │ │ │ ├── zh-cn.js │ │ │ ├── zh-hk.js │ │ │ └── zh-tw.js │ │ ├── min │ │ │ ├── datetime.js │ │ │ ├── locales.min.js │ │ │ ├── moment-with-locales.min.js │ │ │ └── moment.min.js │ │ ├── moment.js │ │ └── package.js │ │ ├── node-waves │ │ ├── waves.min.css │ │ └── waves.min.js │ │ ├── owl.carousel │ │ ├── assets │ │ │ ├── ajax-loader.gif │ │ │ ├── owl.carousel.min.css │ │ │ ├── owl.theme.default.min.css │ │ │ ├── owl.theme.green.min.css │ │ │ └── owl.video.play.png │ │ └── owl.carousel.min.js │ │ ├── pdfmake │ │ ├── build │ │ │ ├── pdfmake.min.js │ │ │ └── vfs_fonts.js │ │ └── webpack-standardfonts.config.js │ │ ├── select2 │ │ ├── css │ │ │ └── select2.min.css │ │ └── js │ │ │ ├── i18n │ │ │ ├── af.js │ │ │ ├── ar.js │ │ │ ├── az.js │ │ │ ├── bg.js │ │ │ ├── bn.js │ │ │ ├── bs.js │ │ │ ├── build.txt │ │ │ ├── ca.js │ │ │ ├── cs.js │ │ │ ├── da.js │ │ │ ├── de.js │ │ │ ├── dsb.js │ │ │ ├── el.js │ │ │ ├── en.js │ │ │ ├── es.js │ │ │ ├── et.js │ │ │ ├── eu.js │ │ │ ├── fa.js │ │ │ ├── fi.js │ │ │ ├── fr.js │ │ │ ├── gl.js │ │ │ ├── he.js │ │ │ ├── hi.js │ │ │ ├── hr.js │ │ │ ├── hsb.js │ │ │ ├── hu.js │ │ │ ├── hy.js │ │ │ ├── id.js │ │ │ ├── is.js │ │ │ ├── it.js │ │ │ ├── ja.js │ │ │ ├── ka.js │ │ │ ├── km.js │ │ │ ├── ko.js │ │ │ ├── lt.js │ │ │ ├── lv.js │ │ │ ├── mk.js │ │ │ ├── ms.js │ │ │ ├── nb.js │ │ │ ├── ne.js │ │ │ ├── nl.js │ │ │ ├── pl.js │ │ │ ├── ps.js │ │ │ ├── pt-BR.js │ │ │ ├── pt.js │ │ │ ├── ro.js │ │ │ ├── ru.js │ │ │ ├── sk.js │ │ │ ├── sl.js │ │ │ ├── sq.js │ │ │ ├── sr-Cyrl.js │ │ │ ├── sr.js │ │ │ ├── sv.js │ │ │ ├── th.js │ │ │ ├── tk.js │ │ │ ├── tr.js │ │ │ ├── uk.js │ │ │ ├── vi.js │ │ │ ├── zh-CN.js │ │ │ └── zh-TW.js │ │ │ ├── select2.full.min.js │ │ │ └── select2.min.js │ │ └── simplebar │ │ ├── simplebar.esm.js │ │ ├── simplebar.min.css │ │ └── simplebar.min.js │ ├── css │ └── site.css │ ├── js │ ├── select2.blazor.js │ └── site.js │ └── lib │ ├── bootstrap │ ├── LICENSE │ └── dist │ │ ├── css │ │ ├── bootstrap-grid.css │ │ ├── bootstrap-grid.css.map │ │ ├── bootstrap-grid.min.css │ │ ├── bootstrap-grid.min.css.map │ │ ├── bootstrap-reboot.css │ │ ├── bootstrap-reboot.css.map │ │ ├── bootstrap-reboot.min.css │ │ ├── bootstrap-reboot.min.css.map │ │ ├── bootstrap.css │ │ ├── bootstrap.css.map │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ │ └── js │ │ ├── bootstrap.bundle.js │ │ ├── bootstrap.bundle.js.map │ │ ├── bootstrap.bundle.min.js │ │ ├── bootstrap.bundle.min.js.map │ │ ├── bootstrap.js │ │ ├── bootstrap.js.map │ │ ├── bootstrap.min.js │ │ └── bootstrap.min.js.map │ ├── jquery-validation-unobtrusive │ ├── LICENSE.txt │ ├── jquery.validate.unobtrusive.js │ └── jquery.validate.unobtrusive.min.js │ ├── jquery-validation │ ├── LICENSE.md │ └── dist │ │ ├── additional-methods.js │ │ ├── additional-methods.min.js │ │ ├── jquery.validate.js │ │ └── jquery.validate.min.js │ ├── jquery │ ├── LICENSE.txt │ └── dist │ │ ├── jquery.js │ │ ├── jquery.min.js │ │ └── jquery.min.map │ └── parsley.js │ ├── parsley.js │ └── parsley.min.js ├── Tests ├── CH.CleanArchitecture.Common.Tests │ ├── CH.CleanArchitecture.Common.Tests.csproj │ └── StringCipherHelperTests.cs ├── CH.CleanArchitecture.Core.Tests │ ├── Application │ │ └── Commands │ │ │ ├── ActivateUserCommandTests.cs │ │ │ ├── AddRolesTests.cs │ │ │ ├── CreateUserTests.cs │ │ │ ├── DeactivateUserCommandTests.cs │ │ │ └── RemoveRolesTests.cs │ ├── CH.CleanArchitecture.Core.Tests.csproj │ └── Domain │ │ └── OrderTests.cs ├── CH.CleanArchitecture.Infrastructure.Tests │ ├── AuditingTests.cs │ ├── CH.CleanArchitecture.Infrastructure.Tests.csproj │ ├── Crypto │ │ ├── JwtServiceTests.cs │ │ └── UrlTokenServiceTests.cs │ ├── DataEntityRepositoryTests.cs │ └── EventStoreTests.cs └── CH.CleanArchitecture.Tests │ ├── CH.CleanArchitecture.Tests.csproj │ ├── DbContextExtensions.cs │ ├── DbInitializer.cs │ ├── Mocks │ ├── FakeSignInManager.cs │ ├── FakeUserManager.cs │ └── MockAuthenticatedUserService.cs │ ├── ObjectHelper.cs │ └── TestBase.cs ├── azure-pipelines.yml ├── docker-compose.dcproj ├── docker-compose.override.yml └── docker-compose.yml /.dockerignore: -------------------------------------------------------------------------------- 1 | **/.classpath 2 | **/.dockerignore 3 | **/.env 4 | **/.git 5 | **/.gitignore 6 | **/.project 7 | **/.settings 8 | **/.toolstarget 9 | **/.vs 10 | **/.vscode 11 | **/*.*proj.user 12 | **/*.dbmdl 13 | **/*.jfm 14 | **/azds.yaml 15 | **/bin 16 | **/charts 17 | **/docker-compose* 18 | **/Dockerfile* 19 | **/node_modules 20 | **/npm-debug.log 21 | **/obj 22 | **/secrets.dev.yaml 23 | **/values.dev.yaml 24 | LICENSE 25 | README.md -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | Run the following to update/install databases: 2 | 3 | In Package Manager with CH.CleanArchitecture.Infrastructure selected as the Default Project, and have CH.CleanArchitecture.Presentation.Web set as solution startup project 4 | 5 | update-database -context ApplicationDbContext 6 | update-database -context EventStoreDbContext 7 | update-database -context IdentityDbContext -------------------------------------------------------------------------------- /Source/CH.CleanArchitecture.Common/Attributes/EnsureOneElementAttribute.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.ComponentModel.DataAnnotations; 3 | 4 | namespace CH.CleanArchitecture.Common.Attributes 5 | { 6 | public class EnsureOneElementAttribute : ValidationAttribute 7 | { 8 | public override bool IsValid(object value) { 9 | var collection = value as ICollection; 10 | if (collection == null) return false; 11 | return collection.Count > 0; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Source/CH.CleanArchitecture.Common/CH.CleanArchitecture.Common.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Source/CH.CleanArchitecture.Common/Converters/DateFormatConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text.Json; 3 | using System.Text.Json.Serialization; 4 | 5 | namespace CH.CleanArchitecture.Common.Converters 6 | { 7 | public class DateFormatConverter : JsonConverter 8 | { 9 | public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { 10 | return DateTime.Parse(reader.GetString()); 11 | } 12 | 13 | public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) { 14 | writer.WriteStringValue(value.ToUniversalTime().ToString("dd/MM/yyyy")); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Source/CH.CleanArchitecture.Common/Enumerations/LanguageEnum.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Common 2 | { 3 | public enum LanguageEnum 4 | { 5 | Greek, 6 | English 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Source/CH.CleanArchitecture.Common/Enumerations/ThemeEnum.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Common 2 | { 3 | public enum ThemeEnum : byte 4 | { 5 | Light = 0, 6 | Dark = 1 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Source/CH.CleanArchitecture.Common/Extensions/DoubleExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Common.Extensions 2 | { 3 | public static class DoubleExtensions 4 | { 5 | public static double ToMegabytes(this long bytes) { 6 | return (bytes / 1024f) / 1024f; 7 | } 8 | 9 | public static double ToMegabytes(this int bytes) { 10 | return (bytes / 1024f) / 1024f; 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Source/CH.CleanArchitecture.Common/Extensions/EnumExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Reflection; 6 | 7 | namespace CH.CleanArchitecture.Common 8 | { 9 | public static class EnumExtensions 10 | { 11 | public static List ToList(this T value) where T : Enum { 12 | return value.ToString().Split(',').Select(flag => (T)Enum.Parse(typeof(T), flag)).ToList(); 13 | } 14 | 15 | public static string GetDisplayName(this T enumValue) where T : Enum { 16 | return enumValue.GetType() 17 | .GetMember(enumValue.ToString()) 18 | .First() 19 | .GetCustomAttribute()? 20 | .GetName() ?? enumValue.ToString(); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Source/CH.CleanArchitecture.Common/Extensions/QueryableExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | namespace CH.CleanArchitecture.Common 5 | { 6 | public static class QueryableExtensions 7 | { 8 | public static PagedResult GetPaged(this IQueryable query, 9 | int page, int pageSize) where T : class { 10 | var result = new PagedResult(); 11 | result.CurrentPage = page; 12 | result.PageSize = pageSize; 13 | result.RowCount = query.Count(); 14 | 15 | var pageCount = (double)result.RowCount / pageSize; 16 | result.PageCount = (int)Math.Ceiling(pageCount); 17 | 18 | var skip = (page - 1) * pageSize; 19 | result.Results = query.Skip(skip).Take(pageSize).ToList(); 20 | 21 | return result; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /Source/CH.CleanArchitecture.Common/Extensions/StreamExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace CH.CleanArchitecture.Common.Extensions 5 | { 6 | public static class StreamExtensions 7 | { 8 | public static string ToBase64String(this Stream stream) { 9 | byte[] bytes; 10 | using (var memoryStream = new MemoryStream()) { 11 | stream.CopyTo(memoryStream); 12 | bytes = memoryStream.ToArray(); 13 | stream.Close(); 14 | } 15 | 16 | return Convert.ToBase64String(bytes); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Source/CH.CleanArchitecture.Common/Notifications/NotificationType.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Common 2 | { 3 | /// 4 | /// Notification type 5 | /// 6 | public enum NotificationType 7 | { 8 | SMS, 9 | Email, 10 | Portal, 11 | Push 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Source/CH.CleanArchitecture.Common/Paging/PagedResult.cs: -------------------------------------------------------------------------------- 1 | //https://www.codingame.com/playgrounds/5363/paging-with-entity-framework-core 2 | using System.Collections.Generic; 3 | 4 | namespace CH.CleanArchitecture.Common 5 | { 6 | public class PagedResult : PagedResultBase where T : class 7 | { 8 | public IList Results { get; set; } 9 | 10 | public PagedResult() { 11 | Results = new List(); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /Source/CH.CleanArchitecture.Common/Paging/PagedResultBase.cs: -------------------------------------------------------------------------------- 1 | //https://www.codingame.com/playgrounds/5363/paging-with-entity-framework-core 2 | using System; 3 | 4 | namespace CH.CleanArchitecture.Common 5 | { 6 | public abstract class PagedResultBase 7 | { 8 | public int CurrentPage { get; set; } 9 | public int PageCount { get; set; } 10 | public int PageSize { get; set; } 11 | public int RowCount { get; set; } 12 | 13 | public int FirstRowOnPage => (CurrentPage - 1) * PageSize + 1; 14 | 15 | public int LastRowOnPage => Math.Min(CurrentPage * PageSize, RowCount); 16 | 17 | public bool HasPreviousPage => CurrentPage > 1; 18 | 19 | public bool HasNextPage => CurrentPage < PageCount; 20 | } 21 | } -------------------------------------------------------------------------------- /Source/CH.CleanArchitecture.Common/Results/IResult.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace CH.CleanArchitecture.Common 4 | { 5 | public interface IResult 6 | { 7 | IReadOnlyCollection Errors { get; } 8 | string Message { get; } 9 | 10 | bool IsSuccessful { get; } 11 | } 12 | 13 | public interface IResult : IResult 14 | { 15 | T Data { get; } 16 | } 17 | } -------------------------------------------------------------------------------- /Source/CH.CleanArchitecture.Common/Results/IResultError.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Common 2 | { 3 | public interface IResultError 4 | { 5 | string Error { get; } 6 | string Code { get; } 7 | } 8 | } -------------------------------------------------------------------------------- /Source/CH.CleanArchitecture.Common/Results/ResultError.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Common 2 | { 3 | public class ResultError : IResultError 4 | { 5 | public string Error { get; private set; } 6 | 7 | public string Code { get; private set; } 8 | 9 | public ResultError() { 10 | 11 | } 12 | 13 | public ResultError(string error) { 14 | Error = error; 15 | } 16 | 17 | public ResultError(string error, string code) 18 | : this(error) { 19 | Code = code; 20 | } 21 | 22 | public override string ToString() { 23 | return $"Error[{Code}]: {Error}"; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/Authorization/Operations/UserOperations.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Core.Application.Authorization 2 | { 3 | /// 4 | /// Holds s for user 5 | /// 6 | public static class UserOperations 7 | { 8 | public static UserOperationAuthorizationRequirement Create = new UserOperationAuthorizationRequirement { Name = OPERATIONS.USER.CREATE }; 9 | public static UserOperationAuthorizationRequirement Read() => new UserOperationAuthorizationRequirement { Name = OPERATIONS.USER.READ }; 10 | public static UserOperationAuthorizationRequirement Edit() => new UserOperationAuthorizationRequirement { Name = OPERATIONS.USER.EDIT }; 11 | public static UserOperationAuthorizationRequirement Delete() => new UserOperationAuthorizationRequirement { Name = OPERATIONS.USER.DELETE }; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/Authorization/OperationsStatics.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Core.Application.Authorization 2 | { 3 | internal static class OPERATIONS 4 | { 5 | internal static class USER 6 | { 7 | internal const string CREATE = "User.Create"; 8 | internal const string READ = "User.Read"; 9 | internal const string EDIT = "User.Edit"; 10 | internal const string DELETE = "User.Delete"; 11 | } 12 | 13 | internal static class ORDER 14 | { 15 | internal const string CREATE = "Order.Create"; 16 | internal const string READ = "Order.Read"; 17 | internal const string EDIT = "Order.Edit"; 18 | internal const string DELETE = "Order.Delete"; 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/Authorization/Requirements/UserOperationAuthorizationRequirement.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization.Infrastructure; 2 | 3 | namespace CH.CleanArchitecture.Core.Application.Authorization 4 | { 5 | public class UserOperationAuthorizationRequirement : OperationAuthorizationRequirement 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/BaseCommand.cs: -------------------------------------------------------------------------------- 1 | using CH.CleanArchitecture.Common; 2 | using CH.Messaging.Abstractions; 3 | using Microsoft.AspNetCore.Authorization.Infrastructure; 4 | using System.Collections.Generic; 5 | using System.Security.Claims; 6 | 7 | namespace CH.CleanArchitecture.Core.Application 8 | { 9 | public abstract class BaseCommand : IRequest, ICommand 10 | where TResponse : class, IResult 11 | { 12 | public List Requirements { get; private set; } = new(); 13 | public ClaimsPrincipal User { get; set; } 14 | 15 | protected void AddRequirements(params OperationAuthorizationRequirement[] requirements) { 16 | Requirements.AddRange(requirements); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/BaseEvent.cs: -------------------------------------------------------------------------------- 1 | using CH.CleanArchitecture.Common; 2 | using CH.Messaging.Abstractions; 3 | using System; 4 | 5 | namespace CH.CleanArchitecture.Core.Application 6 | { 7 | public abstract class BaseEvent : IRequest, IEvent 8 | { 9 | public Guid EventId => Guid.NewGuid(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/Constants/ApplicationClaimTypes.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Core.Application.Constants 2 | { 3 | public static class ApplicationClaimTypes 4 | { 5 | public static class User 6 | { 7 | public const string MustChangePassword = "user:mustchangepassword"; 8 | public const string Username = "user:name"; 9 | public const string FullName = "user:fullname"; 10 | public const string ProfilePicture = "user:avatar"; 11 | public const string Theme = "user:theme"; 12 | public const string Culture = "localization:culture"; 13 | public const string UiCulture = "localization:uiculture"; 14 | public const string Id = "user:id"; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/DTOs/ApplicationConfigurationDTO.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Core.Application.DTOs 2 | { 3 | public class ApplicationConfigurationDTO 4 | { 5 | public string Id { get; set; } 6 | public string Value { get; set; } 7 | public string Description { get; set; } 8 | public bool IsEncrypted { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/DTOs/Audit/AuditHistoryDetailsDTO.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace CH.CleanArchitecture.Core.Application.DTOs 4 | { 5 | public class AuditHistoryDetailsDTO 6 | { 7 | /// 8 | /// The values after action. 9 | /// Key contains column name and Value the value of the column. 10 | /// 11 | public Dictionary NewValues { get; set; } = new Dictionary(); 12 | 13 | /// 14 | /// The values before the action. 15 | /// Key contains column name and Value the value of the column. 16 | /// 17 | public Dictionary OldValues { get; set; } = new Dictionary(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/DTOs/Login/Login2FARequest.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Core.Application.DTOs 2 | { 3 | public class Login2FARequest 4 | { 5 | public string Code { get; set; } 6 | public bool IsPersisted { get; set; } 7 | public bool RememberClient { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/DTOs/Login/LoginRequestDTO.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Core.Application.DTOs 2 | { 3 | public class LoginRequestDTO 4 | { 5 | public string Username { get; set; } 6 | public string Password { get; set; } 7 | public bool RememberMe { get; set; } //TODO[CH]: Consider removing this? 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/DTOs/Login/LoginResponseDTO.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Core.Application.DTOs 2 | { 3 | public class LoginResponseDTO 4 | { 5 | public string User { get; set; } 6 | public bool Success { get; set; } 7 | public bool Requires2FA { get; set; } 8 | public bool IsLockedOut { get; set; } 9 | public bool IsNotAllowed { get; set; } 10 | 11 | public override string ToString() { 12 | return $"User: {User}, Success: {Success}, Requires2FA: {Requires2FA}, IsLockedOut: {IsLockedOut}, IsNotAllowed: {IsNotAllowed}"; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/DTOs/Notifications/SendNotificationBaseDTO.cs: -------------------------------------------------------------------------------- 1 | using CH.CleanArchitecture.Common; 2 | 3 | namespace CH.CleanArchitecture.Core.Application.DTOs 4 | { 5 | public abstract class SendNotificationBaseDTO 6 | { 7 | public string Title { get; set; } 8 | public string Message { get; set; } 9 | public NotificationType Type { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/DTOs/Notifications/SendNotificationDTO.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace CH.CleanArchitecture.Core.Application.DTOs 4 | { 5 | public class SendNotificationDTO : SendNotificationBaseDTO 6 | { 7 | public List Recipients { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/DTOs/RoleAssignmentRequestDTO.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace CH.CleanArchitecture.Core.Application.DTOs 4 | { 5 | /// 6 | /// Represents a request to add/remove a role to/from a user 7 | /// 8 | public class RoleAssignmentRequestDTO 9 | { 10 | public string Username { get; set; } 11 | public List Roles { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/DTOs/UpdateUserDetailsDTO.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Core.Application.DTOs 2 | { 3 | /// 4 | /// Represents a request to update a user's details 5 | /// 6 | public class UpdateUserDetailsDTO 7 | { 8 | public string Id { get; set; } 9 | public string Email { get; set; } 10 | public string Name { get; set; } 11 | public string PrimaryPhone { get; set; } 12 | public string SecondaryPhone { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/Extensions/AuthorizationHandlerContextExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.AspNetCore.Authorization; 3 | 4 | namespace CH.CleanArchitecture.Core.Application.Extensions 5 | { 6 | public static class AuthorizationHandlerContextExtensions 7 | { 8 | public static void EvaluateRequirement(this AuthorizationHandlerContext context, 9 | IAuthorizationRequirement requirement, Func expression) { 10 | if (expression.Invoke()) { 11 | context.Succeed(requirement); 12 | } 13 | else { 14 | context.Fail(); 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/Interfaces/Auth/IAuthenticatedUserService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Security.Claims; 3 | using CH.CleanArchitecture.Common; 4 | using CH.CleanArchitecture.Core.Domain; 5 | 6 | namespace CH.CleanArchitecture.Core.Application 7 | { 8 | public interface IAuthenticatedUserService 9 | { 10 | string UserId { get; } 11 | public string Username { get; } 12 | public string Name { get; } 13 | public string Culture { get; } 14 | public string UiCulture { get; } 15 | public IEnumerable Roles { get; } 16 | public ThemeEnum Theme { get; } 17 | public ClaimsPrincipal User { get; } 18 | } 19 | } -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/Interfaces/Auth/IUserAuthenticationService.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using CH.CleanArchitecture.Common; 3 | using CH.CleanArchitecture.Core.Application.DTOs; 4 | using CH.CleanArchitecture.Core.Domain.Entities.UserAggregate; 5 | 6 | namespace CH.CleanArchitecture.Core.Application 7 | { 8 | public interface IUserAuthenticationService 9 | { 10 | Task> Login(LoginRequestDTO loginRequest); 11 | Task> LoginWith2fa(Login2FARequest login2faRequest); 12 | Task> LoginWithRecoveryCode(Login2FARequest login2faRequest); 13 | Task> GetTwoFactorAuthenticationUserAsync(); 14 | Task Logout(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/Interfaces/Communication/ISMSService.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using CH.CleanArchitecture.Common; 3 | 4 | namespace CH.CleanArchitecture.Core.Application 5 | { 6 | public interface ISMSService 7 | { 8 | /// 9 | /// Sends an SMS using the system's default SMS number as 'from' 10 | /// 11 | /// 12 | /// 13 | /// 14 | Task SendSMSAsync(string to, string body); 15 | 16 | /// 17 | /// Sends an SMS 18 | /// 19 | /// 20 | /// 21 | /// 22 | /// 23 | Task SendSMSAsync(string from, string to, string body); 24 | } 25 | } -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/Interfaces/Crypto/IJWTService.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Core.Application 2 | { 3 | public interface IJWTService 4 | { 5 | /// 6 | /// Creates a JWT Token 7 | /// 8 | /// 9 | /// 10 | /// 11 | string CreateJWT(object payload, int daysValid); 12 | 13 | /// 14 | /// Validates and reads a JWT token created previously by this service and returns the underlying payload 15 | /// 16 | /// 17 | /// 18 | /// 19 | T ReadJWT(string jwt); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/Interfaces/Crypto/IPasswordGeneratorService.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Core.Application 2 | { 3 | public interface IPasswordGeneratorService 4 | { 5 | string GenerateRandomPassword(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/Interfaces/Crypto/IUrlTokenService.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Core.Application 2 | { 3 | public interface IUrlTokenService 4 | { 5 | /// 6 | /// Creates a safe url token containing the given payload 7 | /// 8 | /// 9 | /// 10 | string CreateSafeUrlToken(object payload); 11 | 12 | /// 13 | /// Reads a safe url token and returns the containing payload 14 | /// 15 | /// 16 | /// 17 | /// 18 | T ReadSafeUrlToken(string token); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/Interfaces/ICommand.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Core.Application 2 | { 3 | /// 4 | /// Marker interface for a Command 5 | /// 6 | public interface ICommand 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/Interfaces/IEvent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CH.CleanArchitecture.Core.Application 4 | { 5 | /// 6 | /// Marker interface for an event 7 | /// 8 | public interface IEvent 9 | { 10 | Guid EventId { get; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/Interfaces/IQuery.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Core.Application 2 | { 3 | /// 4 | /// Marker interface for a Query 5 | /// 6 | public interface IQuery 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/Interfaces/IReadModel.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Core.Application 2 | { 3 | /// 4 | /// Marker interface for a ReadModel 5 | /// 6 | public interface IReadModel 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/Interfaces/Repositories/Domain/IOrderRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using CH.CleanArchitecture.Core.Domain.Entities.OrderAggregate; 4 | using CH.Data.Abstractions; 5 | 6 | namespace CH.CleanArchitecture.Core.Application 7 | { 8 | public interface IOrderRepository : IAggregateRepository 9 | { 10 | Task SaveToEventStoreAsync(Order order); 11 | } 12 | } -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/Interfaces/Shared/ILocalizationKeyProvider.cs: -------------------------------------------------------------------------------- 1 | using CH.CleanArchitecture.Core.Domain; 2 | 3 | namespace CH.CleanArchitecture.Core.Application 4 | { 5 | /// 6 | /// Provides various localization keys for resolving to localized resources 7 | /// 8 | public interface ILocalizationKeyProvider 9 | { 10 | string GetRoleLocalizationKey(RoleEnum role); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/Interfaces/Shared/ILocalizationService.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Localization; 2 | 3 | namespace CH.CleanArchitecture.Core.Application 4 | { 5 | public interface ILocalizationService 6 | { 7 | LocalizedString this[string key] { get; } 8 | 9 | LocalizedString GetLocalizedString(string key); 10 | LocalizedString GetCulturedLocalizedString(string key, string culture); 11 | 12 | string GetLocalizedString(string key, params string[] parameters); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/Interfaces/Storage/IResourceStore.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Threading.Tasks; 3 | 4 | namespace CH.CleanArchitecture.Core.Application 5 | { 6 | /// 7 | /// Abstraction for a resource/file store 8 | /// 9 | public interface IResourceStore 10 | { 11 | Task SaveResourceAsync(Stream stream, string path, bool isPublic, string resourceId); 12 | Task SaveResourceAsync(Stream stream, string path, bool isPublic); 13 | Task DownloadResourceAsync(string containerName, string resourceId); 14 | Task DeleteResourceAsync(string resourceId, string path); 15 | string GetResourceURI(string resourceId, string folder); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/Mappings/Resolvers/PhoneNumberConverter.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | using CH.CleanArchitecture.Core.Domain; 3 | 4 | namespace CH.CleanArchitecture.Core.Application.Mappings 5 | { 6 | public class StringToPhoneNumberConverter : ITypeConverter 7 | { 8 | public PhoneNumber Convert(string source, PhoneNumber destination, ResolutionContext context) { 9 | if (string.IsNullOrWhiteSpace(source)) return null; 10 | 11 | return new PhoneNumber(source); 12 | } 13 | } 14 | 15 | public class PhoneNumberToStringConverter : ITypeConverter 16 | { 17 | public string Convert(PhoneNumber sourceMember, string destination, ResolutionContext context) { 18 | return sourceMember?.Value; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/Mappings/UserProfile.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | using CH.CleanArchitecture.Core.Application.Commands; 3 | using CH.CleanArchitecture.Core.Application.DTOs; 4 | 5 | namespace CH.CleanArchitecture.Core.Application 6 | { 7 | internal class UserProfile : Profile 8 | { 9 | public UserProfile() { 10 | CreateMap(); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/Queries/Base/IPagedQuery.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Core.Application.Queries.Base 2 | { 3 | public interface IPagedQuery 4 | { 5 | public int PageSize { get; set; } 6 | public int Start { get; set; } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/Queries/Orders/GetAllOrdersQuery.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using CH.CleanArchitecture.Common; 3 | using CH.CleanArchitecture.Core.Application.ReadModels; 4 | using CH.Messaging.Abstractions; 5 | 6 | namespace CH.CleanArchitecture.Core.Application.Queries 7 | { 8 | public class GetAllOrdersQuery : IRequest>>, IQuery 9 | { 10 | } 11 | } -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/Queries/Orders/GetOrderByIdQuery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CH.CleanArchitecture.Common; 3 | using CH.CleanArchitecture.Core.Application.ReadModels; 4 | using CH.Messaging.Abstractions; 5 | 6 | namespace CH.CleanArchitecture.Core.Application.Queries 7 | { 8 | public class GetOrderByIdQuery : IRequest>, IQuery 9 | { 10 | public Guid OrderId { get; private set; } 11 | 12 | public GetOrderByIdQuery(Guid orderId) { 13 | OrderId = orderId; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/Queries/Users/GetAllUsersQuery.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using CH.CleanArchitecture.Common; 3 | using CH.CleanArchitecture.Core.Application.ReadModels; 4 | using CH.Messaging.Abstractions; 5 | 6 | namespace CH.CleanArchitecture.Core.Application.Queries 7 | { 8 | public class GetAllUsersQuery : IRequest>>, IQuery 9 | { 10 | public QueryOptions Options { get; set; } 11 | public bool ApplyRoleFilter { get; set; } = true; 12 | } 13 | } -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/Queries/Users/GetUserQuery.cs: -------------------------------------------------------------------------------- 1 | using CH.CleanArchitecture.Common; 2 | using CH.CleanArchitecture.Core.Application.ReadModels; 3 | using CH.Messaging.Abstractions; 4 | 5 | namespace CH.CleanArchitecture.Core.Application.Queries 6 | { 7 | public class GetUserQuery : IRequest>, IQuery 8 | { 9 | public string Id { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/ReadModels/AddressReadModel.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Core.Application.ReadModels 2 | { 3 | public class AddressReadModel : IReadModel 4 | { 5 | public string Line1 { get; set; } 6 | public string Line2 { get; set; } 7 | public string City { get; set; } 8 | public string Postcode { get; set; } 9 | public string Country { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/ReadModels/Orders/OrderItemReadModel.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Core.Application.ReadModels 2 | { 3 | public class OrderItemReadModel : IReadModel 4 | { 5 | public string ProductName { get; set; } 6 | public decimal ProductPrice { get; set; } 7 | public int Quantity { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/ReadModels/Orders/OrderReadModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace CH.CleanArchitecture.Core.Application.ReadModels 5 | { 6 | public class OrderReadModel : IReadModel 7 | { 8 | public Guid Id { get; set; } 9 | public List OrderItems { get; set; } 10 | public decimal TotalAmount { get; set; } 11 | public string TrackingNumber { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/ReadModels/User/UserReadModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using CH.CleanArchitecture.Core.Domain; 4 | 5 | namespace CH.CleanArchitecture.Core.Application.ReadModels 6 | { 7 | public class UserReadModel : IReadModel 8 | { 9 | public string ProfilePicture { get; set; } 10 | public Guid Id { get; set; } 11 | public string Username { get; set; } 12 | public string Name { get; set; } 13 | public string Email { get; set; } 14 | public IReadOnlyCollection Roles { get; set; } 15 | public IReadOnlyCollection LocalizedRoles { get; set; } 16 | public string PhoneNumber { get; set; } 17 | public string Fax { get; set; } 18 | public bool IsActive { get; set; } 19 | } 20 | } -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Application/Validators/CreateNewOrderCommandValidator.cs: -------------------------------------------------------------------------------- 1 | using CH.CleanArchitecture.Core.Application.Commands; 2 | using FluentValidation; 3 | 4 | namespace CH.CleanArchitecture.Core.Application.Validators 5 | { 6 | internal class CreateNewOrderCommandValidator : AbstractValidator 7 | { 8 | public CreateNewOrderCommandValidator() { 9 | 10 | RuleFor(x => x.TrackingNumber) 11 | .NotEmpty().WithMessage("Tracking number must be provided."); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Domain/CH.CleanArchitecture.Core.Domain.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Domain/Entities/OrderAggregate/OrderItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CH.Domain.Abstractions; 3 | 4 | namespace CH.CleanArchitecture.Core.Domain.Entities.OrderAggregate 5 | { 6 | public class OrderItem : IEntity 7 | { 8 | public Guid Id { get; private set; } 9 | public string ProductName { get; private set; } 10 | public decimal ProductPrice { get; private set; } 11 | public int Quantity { get; set; } 12 | 13 | internal OrderItem(string productName, decimal productPrice, int quantity) { 14 | ProductName = productName; 15 | ProductPrice = productPrice; 16 | Quantity = quantity; 17 | } 18 | 19 | 20 | internal void UpdateQuantity(int quantity) { 21 | Quantity = quantity; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Domain/Enumerations/RoleEnum.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Core.Domain 2 | { 3 | public enum RoleEnum 4 | { 5 | User = 2, 6 | Admin = 4, 7 | SuperAdmin = 8 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Domain/ValueObjects/Address.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Core.Domain 2 | { 3 | public class Address 4 | { 5 | public string Line1 { get; set; } 6 | public string Line2 { get; set; } 7 | public string City { get; set; } 8 | public string Postcode { get; set; } 9 | public string Country { get; set; } 10 | 11 | public Address(string line1, string line2, string city, string postCode, string country) { 12 | Line1 = line1; 13 | Line2 = line2; 14 | City = city; 15 | Postcode = postCode; 16 | Country = country; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Source/Core/CH.CleanArchitecture.Core.Domain/ValueObjects/PhoneNumber.cs: -------------------------------------------------------------------------------- 1 | using Ardalis.GuardClauses; 2 | 3 | namespace CH.CleanArchitecture.Core.Domain 4 | { 5 | public class PhoneNumber 6 | { 7 | #region Fields 8 | 9 | public string Value { get; private set; } 10 | 11 | #endregion 12 | 13 | #region Constructor 14 | 15 | private PhoneNumber() { } 16 | public PhoneNumber(string number) { 17 | 18 | Guard.Against.NullOrWhiteSpace(number, nameof(number)); 19 | 20 | Value = number; 21 | } 22 | 23 | #endregion 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Source/Infrastructure/CH.CleanArchitecture.Infrastructure.Auditing/CH.CleanArchitecture.Infrastructure.Auditing.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Source/Infrastructure/CH.CleanArchitecture.Infrastructure.Auditing/Models/AuditHistoryDetails.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace CH.CleanArchitecture.Infrastructure.Auditing 4 | { 5 | /// 6 | /// Changed Values details 7 | /// 8 | public class AuditHistoryDetails 9 | { 10 | /// 11 | /// The values after action. 12 | /// Key contains column name and Value the value of the column. 13 | /// 14 | public Dictionary NewValues { get; set; } = new Dictionary(); 15 | 16 | /// 17 | /// The values before the action. 18 | /// Key contains column name and Value the value of the column. 19 | /// 20 | public Dictionary OldValues { get; set; } = new Dictionary(); 21 | } 22 | } -------------------------------------------------------------------------------- /Source/Infrastructure/CH.CleanArchitecture.Infrastructure.Resources/Services/LocalizationKeyProvider.cs: -------------------------------------------------------------------------------- 1 | using CH.CleanArchitecture.Core.Application; 2 | using CH.CleanArchitecture.Core.Domain; 3 | 4 | namespace CH.CleanArchitecture.Infrastructure.Resources 5 | { 6 | public class LocalizationKeyProvider : ILocalizationKeyProvider 7 | { 8 | public string GetRoleLocalizationKey(RoleEnum role) { 9 | return role switch 10 | { 11 | RoleEnum.User => ResourceKeys.Roles_User, 12 | RoleEnum.Admin => ResourceKeys.Roles_Admin, 13 | RoleEnum.SuperAdmin => ResourceKeys.Roles_SuperAdmin, 14 | _ => role.ToString() 15 | }; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Source/Infrastructure/CH.CleanArchitecture.Infrastructure.Shared/Constants/Constants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace CH.CleanArchitecture.Infrastructure.Shared 8 | { 9 | public static class Constants 10 | { 11 | public const int MaxPhotoUploadSizeMb = 30; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Source/Infrastructure/CH.CleanArchitecture.Infrastructure/EntityTypeConfigurations/AddressEntityConfiguration.cs: -------------------------------------------------------------------------------- 1 | using CH.CleanArchitecture.Infrastructure.Models; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace CH.CleanArchitecture.Infrastructure.EntityTypeConfigurations 6 | { 7 | internal class AddressEntityConfiguration : IEntityTypeConfiguration 8 | { 9 | private readonly string _tableName; 10 | private readonly string _schema; 11 | 12 | public AddressEntityConfiguration(string tableName, string schema) { 13 | _tableName = tableName; 14 | _schema = schema; 15 | } 16 | 17 | public void Configure(EntityTypeBuilder builder) { 18 | builder.ToTable(_tableName, _schema); 19 | builder.Property(a => a.Id).HasDefaultValueSql("newsequentialid()"); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Source/Infrastructure/CH.CleanArchitecture.Infrastructure/EntityTypeConfigurations/Application/NotificationEntityConfiguration.cs: -------------------------------------------------------------------------------- 1 | using CH.CleanArchitecture.Infrastructure.DbContexts; 2 | using CH.CleanArchitecture.Infrastructure.Models; 3 | using Microsoft.EntityFrameworkCore; 4 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 5 | 6 | namespace CH.CleanArchitecture.Infrastructure.EntityTypeConfigurations 7 | { 8 | internal class NotificationEntityConfiguration : IEntityTypeConfiguration 9 | { 10 | public void Configure(EntityTypeBuilder builder) { 11 | builder.ToTable("Notifications", ApplicationDbContext.APP_SCHEMA); 12 | builder.HasKey(e => e.Id); 13 | builder.Property(e => e.Title).IsRequired().HasMaxLength(128); 14 | builder.Property(e => e.Description).HasMaxLength(1024); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Source/Infrastructure/CH.CleanArchitecture.Infrastructure/EntityTypeConfigurations/Application/OrderItemEntityConfiguration.cs: -------------------------------------------------------------------------------- 1 | using CH.CleanArchitecture.Infrastructure.DbContexts; 2 | using CH.CleanArchitecture.Infrastructure.Models; 3 | using Microsoft.EntityFrameworkCore; 4 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 5 | 6 | namespace CH.CleanArchitecture.Infrastructure.EntityTypeConfigurations 7 | { 8 | internal class OrderItemEntityConfiguration : IEntityTypeConfiguration 9 | { 10 | public void Configure(EntityTypeBuilder builder) { 11 | builder.ToTable("OrderItems", ApplicationDbContext.DOMAIN_SCHEMA); 12 | builder.Property(oi => oi.Quantity).IsRequired(); 13 | builder.Property(oi => oi.ProductName).IsRequired(); 14 | builder.Property(oi => oi.ProductPrice).IsRequired(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Source/Infrastructure/CH.CleanArchitecture.Infrastructure/EntityTypeConfigurations/Identity/ApplicationRoleConfiguration.cs: -------------------------------------------------------------------------------- 1 | using CH.CleanArchitecture.Infrastructure.Models; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace CH.CleanArchitecture.Infrastructure.EntityTypeConfigurations 6 | { 7 | internal class ApplicationRoleConfiguration : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) { 10 | builder.ToTable("Roles"); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Source/Infrastructure/CH.CleanArchitecture.Infrastructure/EntityTypeConfigurations/Identity/ApplicationUserConfiguration.cs: -------------------------------------------------------------------------------- 1 | using CH.CleanArchitecture.Infrastructure.Models; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace CH.CleanArchitecture.Infrastructure.EntityTypeConfigurations 6 | { 7 | internal class ApplicationUserConfiguration : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) { 10 | builder.ToTable("Users"); 11 | builder.HasMany(e => e.Roles) 12 | .WithOne() 13 | .HasForeignKey(e => e.UserId) 14 | .IsRequired() 15 | .OnDelete(DeleteBehavior.Cascade); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Source/Infrastructure/CH.CleanArchitecture.Infrastructure/EntityTypeConfigurations/Identity/RoleClaimsConfiguration.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Identity; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace CH.CleanArchitecture.Infrastructure.EntityTypeConfigurations 6 | { 7 | internal class RoleClaimsConfiguration : IEntityTypeConfiguration> 8 | { 9 | public void Configure(EntityTypeBuilder> builder) { 10 | builder.ToTable("RoleClaims"); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Source/Infrastructure/CH.CleanArchitecture.Infrastructure/EntityTypeConfigurations/Identity/UserClaimsConfiguration.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Identity; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace CH.CleanArchitecture.Infrastructure.EntityTypeConfigurations 6 | { 7 | internal class UserClaimsConfiguration : IEntityTypeConfiguration> 8 | { 9 | public void Configure(EntityTypeBuilder> builder) { 10 | builder.ToTable("UserClaims"); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Source/Infrastructure/CH.CleanArchitecture.Infrastructure/EntityTypeConfigurations/Identity/UserLoginsConfiguration.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Identity; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace CH.CleanArchitecture.Infrastructure.EntityTypeConfigurations 6 | { 7 | internal class UserLoginsConfiguration : IEntityTypeConfiguration> 8 | { 9 | public void Configure(EntityTypeBuilder> builder) { 10 | builder.ToTable("UserLogins"); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Source/Infrastructure/CH.CleanArchitecture.Infrastructure/EntityTypeConfigurations/Identity/UserTokensConfiguration.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Identity; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace CH.CleanArchitecture.Infrastructure.EntityTypeConfigurations 6 | { 7 | internal class UserTokensConfiguration : IEntityTypeConfiguration> 8 | { 9 | public void Configure(EntityTypeBuilder> builder) { 10 | builder.ToTable("UserTokens"); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Source/Infrastructure/CH.CleanArchitecture.Infrastructure/Mappings/Domain/OrderProfile.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | using CH.CleanArchitecture.Core.Application.ReadModels; 3 | using CH.CleanArchitecture.Core.Domain.Entities.OrderAggregate; 4 | using CH.CleanArchitecture.Infrastructure.Models; 5 | 6 | namespace CH.CleanArchitecture.Infrastructure.Mappings 7 | { 8 | internal class OrderProfile : Profile 9 | { 10 | public OrderProfile() { 11 | CreateMap().ReverseMap(); 12 | CreateMap(); 13 | CreateMap(); 14 | CreateMap(); 15 | 16 | CreateMap(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Source/Infrastructure/CH.CleanArchitecture.Infrastructure/Mappings/EventProfile.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | 3 | namespace CH.CleanArchitecture.Infrastructure.Mappings 4 | { 5 | internal class EventProfile : Profile 6 | { 7 | public EventProfile() { 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /Source/Infrastructure/CH.CleanArchitecture.Infrastructure/Models/AddressEntity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CH.Data.Abstractions; 3 | 4 | namespace CH.CleanArchitecture.Infrastructure.Models 5 | { 6 | public class AddressEntity : DataEntityBase 7 | { 8 | public string Line1 { get; set; } 9 | public string Line2 { get; set; } 10 | public string City { get; set; } 11 | public string Postcode { get; set; } 12 | public string Country { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Source/Infrastructure/CH.CleanArchitecture.Infrastructure/Models/Application/ApplicationConfigurationEntity.cs: -------------------------------------------------------------------------------- 1 | using CH.Data.Abstractions; 2 | 3 | namespace CH.CleanArchitecture.Infrastructure.Models 4 | { 5 | /// 6 | /// Data entity for application-specific configurations 7 | /// 8 | public class ApplicationConfigurationEntity : DataEntityBase 9 | { 10 | /// 11 | /// Description of the configuration variable. 12 | /// 13 | public string Description { get; set; } 14 | 15 | /// 16 | /// Value of the configuration variable. 17 | /// 18 | public string Value { get; set; } 19 | 20 | /// 21 | /// Indicates whether the field contains an encrypted text. 22 | /// 23 | public bool IsEncrypted { get; set; } 24 | } 25 | } -------------------------------------------------------------------------------- /Source/Infrastructure/CH.CleanArchitecture.Infrastructure/Options/EmailSenderOptions.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Infrastructure.Options 2 | { 3 | internal class EmailSenderOptions 4 | { 5 | /// 6 | /// Indicates whether to use SendGrid as an email sender 7 | /// 8 | public bool UseSendGrid { get; set; } = false; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Source/Infrastructure/CH.CleanArchitecture.Infrastructure/Options/StorageOptions.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Infrastructure.Options 2 | { 3 | public class StorageOptions 4 | { 5 | public string BasePath { get; set; } 6 | public string StorageProvider { get; set; } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Source/Infrastructure/CH.CleanArchitecture.Infrastructure/Services/Auth/DefaultAuthenticatedUserService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Security.Claims; 4 | using CH.CleanArchitecture.Common; 5 | using CH.CleanArchitecture.Core.Application; 6 | using CH.CleanArchitecture.Core.Domain; 7 | 8 | namespace CH.CleanArchitecture.Infrastructure.Services 9 | { 10 | internal class DefaultAuthenticatedUserService : IAuthenticatedUserService 11 | { 12 | public string UserId => string.Empty; 13 | public string Username => string.Empty; 14 | public string Name => string.Empty; 15 | public string Culture => string.Empty; 16 | public string UiCulture => string.Empty; 17 | public IEnumerable Roles => Enumerable.Empty(); 18 | public ThemeEnum Theme => ThemeEnum.Light; 19 | public ClaimsPrincipal User => new ClaimsPrincipal(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Source/Infrastructure/CH.CleanArchitecture.Infrastructure/Services/Communication/SMSService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using CH.CleanArchitecture.Common; 4 | using CH.CleanArchitecture.Core.Application; 5 | 6 | namespace CH.CleanArchitecture.Infrastructure.Services 7 | { 8 | internal class SMSService : ISMSService 9 | { 10 | public Task SendSMSAsync(string to, string body) { 11 | throw new NotImplementedException(); 12 | } 13 | 14 | public Task SendSMSAsync(string from, string to, string body) { 15 | throw new NotImplementedException(); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Source/Infrastructure/CH.CleanArchitecture.Infrastructure/Services/DbInitializer/IDbInitializerService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace CH.CleanArchitecture.Infrastructure.Services 8 | { 9 | public interface IDbInitializerService 10 | { 11 | void Migrate(); 12 | void Seed(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Source/Infrastructure/CH.CleanArchitecture.Infrastructure/Services/Jobs/IScheduledJobService.cs: -------------------------------------------------------------------------------- 1 | using CH.CleanArchitecture.Common; 2 | 3 | namespace CH.CleanArchitecture.Infrastructure.Services 4 | { 5 | public interface IScheduledJobService 6 | { 7 | /// 8 | /// Enrolls the audit purging job 9 | /// 10 | Result EnrollAuditPurgingJob(); 11 | 12 | /// 13 | /// Enrolls the notification purging job 14 | /// 15 | /// 16 | Result EnrollNotificationsPurgingJob(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Framework/Components/AuthorizedView.razor: -------------------------------------------------------------------------------- 1 | @inherits BaseComponent 2 | 3 | @if (Visible) 4 | { 5 | @if (Success != null) 6 | { 7 | @Success 8 | } 9 | else 10 | { 11 | @ChildContent 12 | } 13 | 14 | } 15 | else 16 | { 17 | if (Failed != null) 18 | { 19 | @Failed 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Framework/Components/CRUDButton.razor: -------------------------------------------------------------------------------- 1 | @inherits BaseComponent 2 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Framework/Components/ModalTemplate.razor.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Blazored.Modal; 3 | using Microsoft.AspNetCore.Components; 4 | 5 | namespace CH.CleanArchitecture.Presentation.Framework.Components 6 | { 7 | public partial class ModalTemplate 8 | { 9 | [Parameter] 10 | public string Id { get; set; } 11 | [Parameter] 12 | public BlazoredModalInstance Modal { get; set; } 13 | [Parameter] 14 | public RenderFragment Body { get; set; } 15 | [Parameter] 16 | public RenderFragment Footer { get; set; } 17 | 18 | public async Task Cancel() { 19 | await Modal.CancelAsync(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Framework/Components/Select2.razor: -------------------------------------------------------------------------------- 1 | @typeparam TItem 2 | @inherits Select2Base 3 | 4 | 10 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Framework/Components/TabPage.razor: -------------------------------------------------------------------------------- 1 | @if (Parent.ActivePage == this) 2 | { 3 |
4 |
5 | @ChildContent 6 |
7 |
8 | } 9 | 20 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Framework/Components/WizardStep.razor: -------------------------------------------------------------------------------- 1 | 
2 |
3 |

@Name

4 | 5 | @ChildContent 6 | 7 |
8 |
9 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Framework/Enumerations/CRUDElementTypeEnum.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Presentation.Framework 2 | { 3 | public enum CRUDElementTypeEnum 4 | { 5 | View, 6 | Edit, 7 | Delete, 8 | Save, 9 | Cancel 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Framework/Interfaces/IAuthorizationStateProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Claims; 2 | using System.Threading.Tasks; 3 | using Microsoft.AspNetCore.Authorization; 4 | 5 | namespace CH.CleanArchitecture.Presentation.Framework.Interfaces 6 | { 7 | public interface IAuthorizationStateProvider 8 | { 9 | Task CheckRequirement(ClaimsPrincipal user, IAuthorizationRequirement requirement); 10 | Task CheckRequirement(ClaimsPrincipal user, object resource, IAuthorizationRequirement requirement); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Framework/Interfaces/ICRUDElementHelper.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Presentation.Framework.Interfaces 2 | { 3 | public interface ICRUDElementHelper 4 | { 5 | string GetCRUDIconHTML(CRUDElementTypeEnum type); 6 | string GetCRUDButtonHtml(CRUDElementTypeEnum type); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Framework/Interfaces/IToastService.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Components; 2 | 3 | namespace CH.CleanArchitecture.Presentation.Framework 4 | { 5 | public interface IToastService 6 | { 7 | void ShowSuccess(string message); 8 | void ShowError(string message); 9 | void ShowError(RenderFragment message); 10 | void ShowWarning(string message); 11 | } 12 | } -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Framework/Models/Select2Item.cs: -------------------------------------------------------------------------------- 1 | namespace NEvaldas.Blazor.Select2.Models 2 | { 3 | internal class Select2Item 4 | { 5 | public Select2Item(string id, string text, bool disabled) { 6 | Id = id; 7 | Text = text; 8 | Disabled = disabled; 9 | } 10 | 11 | public string Id { get; } 12 | public bool Disabled { get; } 13 | public bool Selected { get; set; } 14 | public string Text { get; } 15 | public string Html { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Framework/Models/Select2Pagination.cs: -------------------------------------------------------------------------------- 1 | namespace NEvaldas.Blazor.Select2.Models 2 | { 3 | internal class Select2Pagination 4 | { 5 | public Select2Pagination(bool more) => More = more; 6 | 7 | public bool More { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Framework/Models/Select2QueryData.cs: -------------------------------------------------------------------------------- 1 | namespace NEvaldas.Blazor.Select2.Models 2 | { 3 | public class Select2QueryData 4 | { 5 | public int Page { get; set; } 6 | public int Size { get; set; } 7 | public string Term { get; set; } 8 | public string Type { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Framework/Models/Select2QueryParams.cs: -------------------------------------------------------------------------------- 1 | namespace NEvaldas.Blazor.Select2.Models 2 | { 3 | internal class Select2QueryParams 4 | { 5 | public string Type { get; set; } 6 | 7 | public Select2QueryData Data { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Framework/Models/Select2Response.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace NEvaldas.Blazor.Select2.Models 4 | { 5 | internal class Select2Response 6 | { 7 | public Select2Response() { 8 | Results = new List(); 9 | Pagination = new Select2Pagination(false); 10 | } 11 | 12 | public List Results { get; set; } 13 | public Select2Pagination Pagination { get; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Framework/Services/LoaderService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CH.CleanArchitecture.Presentation.Framework.Services 4 | { 5 | public class LoaderService 6 | { 7 | public event Action OnShow; 8 | public event Action OnHide; 9 | 10 | public void Show() { 11 | OnShow?.Invoke(); 12 | } 13 | 14 | public void Hide() { 15 | OnHide?.Invoke(); 16 | } 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Framework/WebFrameworkConstants.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Presentation.Framework 2 | { 3 | public static class WebFrameworkConstants 4 | { 5 | public const string HANGFIRE_DASHBOARD_POLICY_NAME = "HangfireDashboardPolicy"; 6 | } 7 | } -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Framework/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using Microsoft.AspNetCore.Components 2 | @using Microsoft.AspNetCore.Components.Authorization 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using Microsoft.AspNetCore.Http 7 | @using Microsoft.JSInterop 8 | @using System.Net.Http 9 | @using NEvaldas.Blazor.Select2 10 | @using Blazored 11 | @using Faso.Blazor.SpinKit 12 | @using Blazored.Toast 13 | @using Blazored.Toast.Services 14 | @using CH.CleanArchitecture.Presentation.Framework.Services 15 | @using BlazorAnimate 16 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/Constants/Constants.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Presentation.Web.Constants 2 | { 3 | public static class Constants 4 | { 5 | /// 6 | /// Gets a key for notifications list from TempDataDictionary 7 | /// 8 | public static string NotificationListKey => "NotificationList"; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/Controllers/BaseController.cs: -------------------------------------------------------------------------------- 1 | using CH.CleanArchitecture.Core.Application; 2 | using Microsoft.AspNetCore.Authorization; 3 | using Microsoft.AspNetCore.Mvc; 4 | 5 | namespace CH.CleanArchitecture.Presentation.Web.Controllers 6 | { 7 | public abstract class BaseController : Controller 8 | { 9 | protected readonly INotificationService NotificationService; 10 | 11 | public BaseController(INotificationService notificationService) { 12 | NotificationService = notificationService; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/Controllers/DeveloperController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization; 2 | using Microsoft.AspNetCore.Mvc; 3 | 4 | namespace CH.CleanArchitecture.Presentation.Web.Controllers 5 | { 6 | [Authorize(Roles = "SuperAdmin")] 7 | public class DeveloperController : Controller 8 | { 9 | public IActionResult Index() { 10 | return View(); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using CH.CleanArchitecture.Presentation.Web.ViewModels; 3 | using Microsoft.AspNetCore.Authorization; 4 | using Microsoft.AspNetCore.Mvc; 5 | 6 | namespace CH.CleanArchitecture.Presentation.Web.Controllers 7 | { 8 | [Authorize] 9 | public class HomeController : Controller 10 | { 11 | public async Task Index() { 12 | var model = new HomeViewModel(); 13 | 14 | return View(model); 15 | } 16 | 17 | } 18 | } -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/Enumerations/TempNotificationType.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Presentation.Web.Enumerations 2 | { 3 | public enum TempNotificationType 4 | { 5 | Success, 6 | Warning, 7 | Error 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/Models/TempNotificationData.cs: -------------------------------------------------------------------------------- 1 | using CH.CleanArchitecture.Presentation.Web.Enumerations; 2 | 3 | namespace CH.CleanArchitecture.Presentation.Web.Models 4 | { 5 | /// 6 | /// Message structure 7 | /// 8 | public struct TempNotificationData 9 | { 10 | /// 11 | /// Message type (success/warning/error) 12 | /// 13 | public TempNotificationType Type { get; set; } 14 | 15 | /// 16 | /// Message text 17 | /// 18 | public string Message { get; set; } 19 | 20 | /// 21 | /// Get a sets a value indicating whether the message should not be HTML encoded 22 | /// 23 | public bool Encode { get; set; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "IIS Express": { 4 | "commandName": "IISExpress", 5 | "launchBrowser": true, 6 | "environmentVariables": { 7 | "ASPNETCORE_ENVIRONMENT": "Development" 8 | } 9 | }, 10 | "CH.CleanArchitecture.Presentation.Web": { 11 | "commandName": "Project", 12 | "launchBrowser": true, 13 | "environmentVariables": { 14 | "ASPNETCORE_ENVIRONMENT": "Development" 15 | }, 16 | "applicationUrl": "https://localhost:9999;http://localhost:9998" 17 | } 18 | }, 19 | "iisSettings": { 20 | "windowsAuthentication": false, 21 | "anonymousAuthentication": true, 22 | "iisExpress": { 23 | "applicationUrl": "http://localhost:50507/", 24 | "sslPort": 44360 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/RazorComponents/ConfirmationModal.razor: -------------------------------------------------------------------------------- 1 | @inherits BaseComponent 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/RazorComponents/SelectUserComponent.razor: -------------------------------------------------------------------------------- 1 | @inherits BaseComponent 2 | @using CH.CleanArchitecture.Core.Application.ReadModels 3 | 4 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/UrlHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CH.CleanArchitecture.Presentation.Web 4 | { 5 | public class UrlHelper 6 | { 7 | public static string GetReportPhotoUrl(string reportId, Guid photoId) { 8 | return $@"reports/{reportId}/photos/{photoId}"; 9 | } 10 | 11 | public static string GetProjectAttachmentUrl(Guid projectId, Guid attachmentId) { 12 | return $@"projects/{projectId}/attachments/{attachmentId}"; 13 | } 14 | 15 | public static string GetReportExportDownloadUrl(string reportId, Guid exportId) { 16 | return $@"reports/{reportId}/exports/{exportId}"; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/Validators/Auth/LoginValidator.cs: -------------------------------------------------------------------------------- 1 | using CH.CleanArchitecture.Presentation.Web.ViewModels; 2 | using FluentValidation; 3 | 4 | namespace CH.CleanArchitecture.Presentation.Web.Validators 5 | { 6 | public partial class LoginValidator : AbstractValidator 7 | { 8 | public LoginValidator() { 9 | RuleFor(x => x.Username).NotEmpty().WithMessage("Username is required"); 10 | RuleFor(x => x.Password).NotEmpty().WithMessage("Password is required"); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/Validators/LocalizedDataAnnotationsValidator/Internals/Extensions/ReflectionExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | namespace CH.CleanArchitecture.Presentation.Web.Validators.Internals 4 | { 5 | internal static class ReflectionExtensions 6 | { 7 | internal static bool IsPublic(this PropertyInfo p) { 8 | if (!(p.GetMethod != null) || !p.GetMethod.IsPublic) { 9 | if (p.SetMethod != null) { 10 | return p.SetMethod.IsPublic; 11 | } 12 | return false; 13 | } 14 | return true; 15 | } 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/Validators/LocalizedDataAnnotationsValidator/Internals/LocalizedValidationContext.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using CH.CleanArchitecture.Core.Application; 3 | 4 | namespace CH.CleanArchitecture.Presentation.Web.Validators.Internals 5 | { 6 | internal class LocalizedValidationContext 7 | { 8 | internal ILocalizationService Localizer { get; } 9 | 10 | internal ValidationContext Context { get; } 11 | 12 | internal LocalizedValidationContext(ILocalizationService localizer, object instance) { 13 | Localizer = localizer; 14 | Context = new ValidationContext(instance); 15 | } 16 | 17 | internal LocalizedValidationContext(ILocalizationService localizer, ValidationContext context) { 18 | Localizer = localizer; 19 | Context = context; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/Validators/LocalizedDataAnnotationsValidator/LocalizedDataAnnotationsValidator.cs: -------------------------------------------------------------------------------- 1 | using CH.CleanArchitecture.Core.Application; 2 | using Microsoft.AspNetCore.Components; 3 | using Microsoft.AspNetCore.Components.Forms; 4 | 5 | namespace CH.CleanArchitecture.Presentation.Web.Validators 6 | { 7 | public class LocalizedDataAnnotationsValidator : ComponentBase 8 | { 9 | [Inject] 10 | private ILocalizationService Localizer { get; set; } 11 | 12 | [CascadingParameter] 13 | private EditContext CurrentEditContext { get; set; } 14 | 15 | protected override void OnInitialized() { 16 | CurrentEditContext.AddLocalizedDataAnnotationsValidation(Localizer); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/ViewComponents/FooterViewComponent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using System.Threading.Tasks; 4 | using CH.CleanArchitecture.Presentation.Web.ViewModels; 5 | using Microsoft.AspNetCore.Mvc; 6 | 7 | namespace CH.CleanArchitecture.Presentation.Web.ViewComponents 8 | { 9 | [ViewComponent(Name = "Footer")] 10 | public class FooterViewComponent : ViewComponent 11 | { 12 | public async Task InvokeAsync() { 13 | FooterViewModel model = new FooterViewModel(); 14 | model.Date = DateTime.Now; 15 | model.Version = Assembly.GetEntryAssembly().GetName().Version.ToString(); //TODO[CH]: Get proper version here 16 | return View(model); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/ViewComponents/TopBarViewComponent.cs: -------------------------------------------------------------------------------- 1 | using CH.CleanArchitecture.Core.Application; 2 | using CH.CleanArchitecture.Presentation.Web.ViewModels; 3 | using Microsoft.AspNetCore.Mvc; 4 | 5 | namespace CH.CleanArchitecture.Presentation.Web.ViewComponents 6 | { 7 | [ViewComponent(Name = "TopBar")] 8 | public class TopBarViewComponent : ViewComponent 9 | { 10 | private IAuthenticatedUserService _userService; 11 | public TopBarViewComponent(IAuthenticatedUserService userService) { 12 | _userService = userService; 13 | } 14 | 15 | public IViewComponentResult Invoke() { 16 | var model = new TopBarViewModel(); 17 | model.Username = _userService.Username; 18 | model.Roles = _userService.Roles; 19 | 20 | return View(model); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/ViewModels/ErrorViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Presentation.Web.ViewModels 2 | { 3 | public class ErrorViewModel 4 | { 5 | public string RequestId { get; set; } 6 | 7 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); 8 | } 9 | } -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/ViewModels/FooterViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CH.CleanArchitecture.Presentation.Web.ViewModels 4 | { 5 | public class FooterViewModel 6 | { 7 | public DateTime Date { get; set; } 8 | public string Version { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/ViewModels/HomeViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Presentation.Web.ViewModels 2 | { 3 | public class HomeViewModel 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/ViewModels/Orders/CreateOrderViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Presentation.Web.ViewModels.Orders 2 | { 3 | public class CreateOrderViewModel 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/ViewModels/Orders/IndexViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace CH.CleanArchitecture.Presentation.Web.ViewModels.Orders 4 | { 5 | public class IndexViewModel 6 | { 7 | public List Orders { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/ViewModels/Orders/OrderViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CH.CleanArchitecture.Presentation.Web.ViewModels.Orders 4 | { 5 | public class OrderViewModel 6 | { 7 | public Guid Id { get; set; } 8 | public string TrackingNumber { get; set; } 9 | public decimal TotalAmount { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/ViewModels/TopBarViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using CH.CleanArchitecture.Core.Domain; 4 | 5 | namespace CH.CleanArchitecture.Presentation.Web.ViewModels 6 | { 7 | public class TopBarViewModel 8 | { 9 | public string Username { get; set; } 10 | public IEnumerable Roles { get; set; } 11 | public string ProfilePicture { get; set; } 12 | public bool IsAdmin => Roles.Any(r => r >= RoleEnum.Admin); 13 | public bool IsSuperAdmin => Roles.Any(r => r >= RoleEnum.SuperAdmin); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/ViewModels/Users/LoginViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | using CH.CleanArchitecture.Infrastructure.Resources; 3 | 4 | namespace CH.CleanArchitecture.Presentation.Web.ViewModels 5 | { 6 | public class LoginViewModel 7 | { 8 | [Required(ErrorMessage = ResourceKeys.Validations_Required)] 9 | [Display(Name = ResourceKeys.Labels_Username)] 10 | public string Username { get; set; } 11 | [Required(ErrorMessage = ResourceKeys.Validations_Required)] 12 | [Display(Name = ResourceKeys.Labels_Password)] 13 | [DataType(DataType.Password)] 14 | public string Password { get; set; } 15 | 16 | [Display(Name = ResourceKeys.Labels_RememberMe)] 17 | public bool RememberMe { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/Views/Developer/Index.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Developer Management"; 3 | ViewBag.pTitle = "Developer Management"; 4 | ViewBag.pageTitle = "CH.CleanArchitecture"; 5 | } 6 | 7 | 8 | 9 | @section Scripts 10 | { 11 | 12 | } -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/Views/Shared/Components/Footer/Default.cshtml: -------------------------------------------------------------------------------- 1 | @model FooterViewModel 2 |
3 |
4 |
5 |
6 | @Model.Date Clean Architecture by Charalambos Hadjiantoniou 7 |
8 |
9 |
10 | 11 |
12 |
13 |
14 |
15 |
16 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/Views/Shared/_BlazorJS.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/Views/Shared/_DatatablesCss.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/Views/Shared/_HeadCss.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | string bootstrapStyle = "assets/css/bootstrap.css"; 3 | string appStyle = "assets/css/app.css"; 4 | } 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/Views/Shared/_PageTitle.cshtml: -------------------------------------------------------------------------------- 1 |  2 |
3 |
4 |
5 |

@ViewBag.pTitle

6 |
7 |
8 | 12 |
13 |
14 |
15 |
16 |
17 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/Views/Shared/_TitleMeta.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | @ViewBag.Title | CH.CleanArchitecture - Admin Dashboard 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/Views/Shared/_ValidationScriptsPartial.cshtml: -------------------------------------------------------------------------------- 1 |  2 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "Layouts/_Layout"; 3 | } -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using Microsoft.AspNetCore.Components 2 | @using Microsoft.AspNetCore.Components.Authorization 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using Microsoft.AspNetCore.Http 7 | @using Microsoft.JSInterop 8 | @using System.Net.Http 9 | @using NEvaldas.Blazor.Select2 10 | @using CH.CleanArchitecture.Common 11 | @using Blazored.Toast 12 | @using Blazored.Toast.Services 13 | @using Blazored.FluentValidation 14 | @using Plk.Blazor.DragDrop -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/appsettings.DockerCompose.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "UseInMemoryDatabase": false, 10 | "ConnectionStrings": { 11 | "ApplicationConnection": "Server=mssql,1433;Database=CH.CleanArchitecture;User=sa;Password=5b0451546a750925ff20f2f72a036f70364c2cdf170c54ff0893d030e0e617f8;", 12 | "IdentityConnection": "Server=mssql,1433;Database=CH.CleanArchitecture;User=sa;Password=5b0451546a750925ff20f2f72a036f70364c2cdf170c54ff0893d030e0e617f8;" 13 | } 14 | } -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/libman.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0", 3 | "defaultProvider": "cdnjs", 4 | "libraries": [] 5 | } -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/boxicons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/boxicons.eot -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/boxicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/boxicons.ttf -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/boxicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/boxicons.woff -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/boxicons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/boxicons.woff2 -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/dripicons-v2.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/dripicons-v2.eot -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/dripicons-v2.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/dripicons-v2.ttf -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/dripicons-v2.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/dripicons-v2.woff -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/fa-brands-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/fa-brands-400.eot -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/fa-brands-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/fa-brands-400.woff -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/fa-regular-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/fa-regular-400.eot -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/fa-regular-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/fa-regular-400.woff -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/fa-solid-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/fa-solid-900.eot -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/fa-solid-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/fa-solid-900.woff -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/materialdesignicons-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/materialdesignicons-webfont.eot -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/materialdesignicons-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/materialdesignicons-webfont.ttf -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/materialdesignicons-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/materialdesignicons-webfont.woff -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/materialdesignicons-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/materialdesignicons-webfont.woff2 -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/summernote.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/summernote.eot -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/summernote.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/summernote.ttf -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/summernote.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/fonts/summernote.woff -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/images/close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 8 | 9 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/images/favicon.ico -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/images/flags/el.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/images/flags/el.png -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/images/flags/en.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/images/flags/en.png -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/images/profile-img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/images/profile-img.png -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/images/users/default_avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/images/users/default_avatar.png -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/js/pages/datatables.init.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function(){$("#datatable").DataTable(),$("#datatable-buttons").DataTable({lengthChange:!1,buttons:["copy","excel","pdf","colvis"]}).buttons().container().appendTo("#datatable-buttons_wrapper .col-md-6:eq(0)")}); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/js/pages/form-validation.init.js: -------------------------------------------------------------------------------- 1 | !function () { 2 | "use strict"; 3 | window.addEventListener("load", function () { 4 | var t = document.getElementsByClassName("needs-validation"); 5 | Array.prototype.filter.call(t, function (e) { 6 | e.addEventListener("submit", function (t) { 7 | !1 === e.checkValidity() && (t.preventDefault(), t.stopPropagation()), 8 | e.classList.add("was-validated") 9 | }, !1) 10 | }) 11 | }, !1) 12 | } 13 | (), $(document).ready(function () { 14 | $(".custom-validation").parsley() 15 | }); 16 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/js/pages/two-step-verification.init.js: -------------------------------------------------------------------------------- 1 | function moveToNext(t,e){0.btn{position:absolute;right:0;height:50%;padding:0;width:2em;text-align:center;line-height:1}.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-up{border-radius:0 4px 0 0;top:0}.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-down{border-radius:0 0 4px 0;bottom:0} -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/datatables.net-buttons/swf/flashExport.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/datatables.net-buttons/swf/flashExport.swf -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/dropzone/min/basic.min.css: -------------------------------------------------------------------------------- 1 | .dropzone,.dropzone *{box-sizing:border-box}.dropzone{position:relative}.dropzone .dz-preview{position:relative;display:inline-block;width:120px;margin:0.5em}.dropzone .dz-preview .dz-progress{display:block;height:15px;border:1px solid #aaa}.dropzone .dz-preview .dz-progress .dz-upload{display:block;height:100%;width:0;background:green}.dropzone .dz-preview .dz-error-message{color:red;display:none}.dropzone .dz-preview.dz-error .dz-error-message,.dropzone .dz-preview.dz-error .dz-error-mark{display:block}.dropzone .dz-preview.dz-success .dz-success-mark{display:block}.dropzone .dz-preview .dz-error-mark,.dropzone .dz-preview .dz-success-mark{position:absolute;display:none;left:30px;top:30px;width:54px;height:58px;left:50%;margin-left:-27px} 2 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/moment/ender.js: -------------------------------------------------------------------------------- 1 | $.ender({ moment: require('moment') }) 2 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/moment/package.js: -------------------------------------------------------------------------------- 1 | var profile = { 2 | resourceTags: { 3 | ignore: function(filename, mid){ 4 | // only include moment/moment 5 | return mid != "moment/moment"; 6 | }, 7 | amd: function(filename, mid){ 8 | return /\.js$/.test(filename); 9 | } 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/owl.carousel/assets/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/owl.carousel/assets/ajax-loader.gif -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/owl.carousel/assets/owl.video.play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodewrapper/CH.CleanArchitecture/e5a990a4bc65900867c81292f027d49c92474068/Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/owl.carousel/assets/owl.video.play.png -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/pdfmake/webpack-standardfonts.config.js: -------------------------------------------------------------------------------- 1 | var config = require("./webpack.config.js"); 2 | 3 | var rule = {enforce: 'post', test: /pdfkit[/\\]js[/\\]/, loader: "transform-loader?brfs"}; 4 | 5 | config.module.rules.push(rule); 6 | 7 | module.exports = config; -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/af.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/af",[],function(){return{errorLoading:function(){return"Die resultate kon nie gelaai word nie."},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Verwyders asseblief "+n+" character";return 1!=n&&(r+="s"),r},inputTooShort:function(e){return"Voer asseblief "+(e.minimum-e.input.length)+" of meer karakters"},loadingMore:function(){return"Meer resultate word gelaai…"},maximumSelected:function(e){var n="Kies asseblief net "+e.maximum+" item";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"Geen resultate gevind"},searching:function(){return"Besig…"},removeAllItems:function(){return"Verwyder alle items"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/ar.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ar",[],function(){return{errorLoading:function(){return"لا يمكن تحميل النتائج"},inputTooLong:function(n){return"الرجاء حذف "+(n.input.length-n.maximum)+" عناصر"},inputTooShort:function(n){return"الرجاء إضافة "+(n.minimum-n.input.length)+" عناصر"},loadingMore:function(){return"جاري تحميل نتائج إضافية..."},maximumSelected:function(n){return"تستطيع إختيار "+n.maximum+" بنود فقط"},noResults:function(){return"لم يتم العثور على أي نتائج"},searching:function(){return"جاري البحث…"},removeAllItems:function(){return"قم بإزالة كل العناصر"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/az.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/az",[],function(){return{inputTooLong:function(n){return n.input.length-n.maximum+" simvol silin"},inputTooShort:function(n){return n.minimum-n.input.length+" simvol daxil edin"},loadingMore:function(){return"Daha çox nəticə yüklənir…"},maximumSelected:function(n){return"Sadəcə "+n.maximum+" element seçə bilərsiniz"},noResults:function(){return"Nəticə tapılmadı"},searching:function(){return"Axtarılır…"},removeAllItems:function(){return"Bütün elementləri sil"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/bg.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/bg",[],function(){return{inputTooLong:function(n){var e=n.input.length-n.maximum,u="Моля въведете с "+e+" по-малко символ";return e>1&&(u+="a"),u},inputTooShort:function(n){var e=n.minimum-n.input.length,u="Моля въведете още "+e+" символ";return e>1&&(u+="a"),u},loadingMore:function(){return"Зареждат се още…"},maximumSelected:function(n){var e="Можете да направите до "+n.maximum+" ";return n.maximum>1?e+="избора":e+="избор",e},noResults:function(){return"Няма намерени съвпадения"},searching:function(){return"Търсене…"},removeAllItems:function(){return"Премахнете всички елементи"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/bn.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/bn",[],function(){return{errorLoading:function(){return"ফলাফলগুলি লোড করা যায়নি।"},inputTooLong:function(n){var e=n.input.length-n.maximum,u="অনুগ্রহ করে "+e+" টি অক্ষর মুছে দিন।";return 1!=e&&(u="অনুগ্রহ করে "+e+" টি অক্ষর মুছে দিন।"),u},inputTooShort:function(n){return n.minimum-n.input.length+" টি অক্ষর অথবা অধিক অক্ষর লিখুন।"},loadingMore:function(){return"আরো ফলাফল লোড হচ্ছে ..."},maximumSelected:function(n){var e=n.maximum+" টি আইটেম নির্বাচন করতে পারবেন।";return 1!=n.maximum&&(e=n.maximum+" টি আইটেম নির্বাচন করতে পারবেন।"),e},noResults:function(){return"কোন ফলাফল পাওয়া যায়নি।"},searching:function(){return"অনুসন্ধান করা হচ্ছে ..."}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/ca.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/ca",[],function(){return{errorLoading:function(){return"La càrrega ha fallat"},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Si us plau, elimina "+n+" car";return r+=1==n?"àcter":"àcters"},inputTooShort:function(e){var n=e.minimum-e.input.length,r="Si us plau, introdueix "+n+" car";return r+=1==n?"àcter":"àcters"},loadingMore:function(){return"Carregant més resultats…"},maximumSelected:function(e){var n="Només es pot seleccionar "+e.maximum+" element";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"No s'han trobat resultats"},searching:function(){return"Cercant…"},removeAllItems:function(){return"Treu tots els elements"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/da.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/da",[],function(){return{errorLoading:function(){return"Resultaterne kunne ikke indlæses."},inputTooLong:function(e){return"Angiv venligst "+(e.input.length-e.maximum)+" tegn mindre"},inputTooShort:function(e){return"Angiv venligst "+(e.minimum-e.input.length)+" tegn mere"},loadingMore:function(){return"Indlæser flere resultater…"},maximumSelected:function(e){var n="Du kan kun vælge "+e.maximum+" emne";return 1!=e.maximum&&(n+="r"),n},noResults:function(){return"Ingen resultater fundet"},searching:function(){return"Søger…"},removeAllItems:function(){return"Fjern alle elementer"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/de.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/de",[],function(){return{errorLoading:function(){return"Die Ergebnisse konnten nicht geladen werden."},inputTooLong:function(e){return"Bitte "+(e.input.length-e.maximum)+" Zeichen weniger eingeben"},inputTooShort:function(e){return"Bitte "+(e.minimum-e.input.length)+" Zeichen mehr eingeben"},loadingMore:function(){return"Lade mehr Ergebnisse…"},maximumSelected:function(e){var n="Sie können nur "+e.maximum+" Element";return 1!=e.maximum&&(n+="e"),n+=" auswählen"},noResults:function(){return"Keine Übereinstimmungen gefunden"},searching:function(){return"Suche…"},removeAllItems:function(){return"Entferne alle Elemente"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/en.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/en",[],function(){return{errorLoading:function(){return"The results could not be loaded."},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Please delete "+n+" character";return 1!=n&&(r+="s"),r},inputTooShort:function(e){return"Please enter "+(e.minimum-e.input.length)+" or more characters"},loadingMore:function(){return"Loading more results…"},maximumSelected:function(e){var n="You can only select "+e.maximum+" item";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"No results found"},searching:function(){return"Searching…"},removeAllItems:function(){return"Remove all items"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/et.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/et",[],function(){return{inputTooLong:function(e){var n=e.input.length-e.maximum,t="Sisesta "+n+" täht";return 1!=n&&(t+="e"),t+=" vähem"},inputTooShort:function(e){var n=e.minimum-e.input.length,t="Sisesta "+n+" täht";return 1!=n&&(t+="e"),t+=" rohkem"},loadingMore:function(){return"Laen tulemusi…"},maximumSelected:function(e){var n="Saad vaid "+e.maximum+" tulemus";return 1==e.maximum?n+="e":n+="t",n+=" valida"},noResults:function(){return"Tulemused puuduvad"},searching:function(){return"Otsin…"},removeAllItems:function(){return"Eemalda kõik esemed"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/eu.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/eu",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Idatzi ";return n+=1==t?"karaktere bat":t+" karaktere",n+=" gutxiago"},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Idatzi ";return n+=1==t?"karaktere bat":t+" karaktere",n+=" gehiago"},loadingMore:function(){return"Emaitza gehiago kargatzen…"},maximumSelected:function(e){return 1===e.maximum?"Elementu bakarra hauta dezakezu":e.maximum+" elementu hauta ditzakezu soilik"},noResults:function(){return"Ez da bat datorrenik aurkitu"},searching:function(){return"Bilatzen…"},removeAllItems:function(){return"Kendu elementu guztiak"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/fa.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/fa",[],function(){return{errorLoading:function(){return"امکان بارگذاری نتایج وجود ندارد."},inputTooLong:function(n){return"لطفاً "+(n.input.length-n.maximum)+" کاراکتر را حذف نمایید"},inputTooShort:function(n){return"لطفاً تعداد "+(n.minimum-n.input.length)+" کاراکتر یا بیشتر وارد نمایید"},loadingMore:function(){return"در حال بارگذاری نتایج بیشتر..."},maximumSelected:function(n){return"شما تنها می‌توانید "+n.maximum+" آیتم را انتخاب نمایید"},noResults:function(){return"هیچ نتیجه‌ای یافت نشد"},searching:function(){return"در حال جستجو..."},removeAllItems:function(){return"همه موارد را حذف کنید"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/fi.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/fi",[],function(){return{errorLoading:function(){return"Tuloksia ei saatu ladattua."},inputTooLong:function(n){return"Ole hyvä ja anna "+(n.input.length-n.maximum)+" merkkiä vähemmän"},inputTooShort:function(n){return"Ole hyvä ja anna "+(n.minimum-n.input.length)+" merkkiä lisää"},loadingMore:function(){return"Ladataan lisää tuloksia…"},maximumSelected:function(n){return"Voit valita ainoastaan "+n.maximum+" kpl"},noResults:function(){return"Ei tuloksia"},searching:function(){return"Haetaan…"},removeAllItems:function(){return"Poista kaikki kohteet"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/he.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/he",[],function(){return{errorLoading:function(){return"שגיאה בטעינת התוצאות"},inputTooLong:function(n){var e=n.input.length-n.maximum,r="נא למחוק ";return r+=1===e?"תו אחד":e+" תווים"},inputTooShort:function(n){var e=n.minimum-n.input.length,r="נא להכניס ";return r+=1===e?"תו אחד":e+" תווים",r+=" או יותר"},loadingMore:function(){return"טוען תוצאות נוספות…"},maximumSelected:function(n){var e="באפשרותך לבחור עד ";return 1===n.maximum?e+="פריט אחד":e+=n.maximum+" פריטים",e},noResults:function(){return"לא נמצאו תוצאות"},searching:function(){return"מחפש…"},removeAllItems:function(){return"הסר את כל הפריטים"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/hi.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hi",[],function(){return{errorLoading:function(){return"परिणामों को लोड नहीं किया जा सका।"},inputTooLong:function(n){var e=n.input.length-n.maximum,r=e+" अक्षर को हटा दें";return e>1&&(r=e+" अक्षरों को हटा दें "),r},inputTooShort:function(n){return"कृपया "+(n.minimum-n.input.length)+" या अधिक अक्षर दर्ज करें"},loadingMore:function(){return"अधिक परिणाम लोड हो रहे है..."},maximumSelected:function(n){return"आप केवल "+n.maximum+" आइटम का चयन कर सकते हैं"},noResults:function(){return"कोई परिणाम नहीं मिला"},searching:function(){return"खोज रहा है..."},removeAllItems:function(){return"सभी वस्तुओं को हटा दें"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/hr.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hr",[],function(){function n(n){var e=" "+n+" znak";return n%10<5&&n%10>0&&(n%100<5||n%100>19)?n%10>1&&(e+="a"):e+="ova",e}return{errorLoading:function(){return"Preuzimanje nije uspjelo."},inputTooLong:function(e){return"Unesite "+n(e.input.length-e.maximum)},inputTooShort:function(e){return"Unesite još "+n(e.minimum-e.input.length)},loadingMore:function(){return"Učitavanje rezultata…"},maximumSelected:function(n){return"Maksimalan broj odabranih stavki je "+n.maximum},noResults:function(){return"Nema rezultata"},searching:function(){return"Pretraga…"},removeAllItems:function(){return"Ukloni sve stavke"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/hu.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/hu",[],function(){return{errorLoading:function(){return"Az eredmények betöltése nem sikerült."},inputTooLong:function(e){return"Túl hosszú. "+(e.input.length-e.maximum)+" karakterrel több, mint kellene."},inputTooShort:function(e){return"Túl rövid. Még "+(e.minimum-e.input.length)+" karakter hiányzik."},loadingMore:function(){return"Töltés…"},maximumSelected:function(e){return"Csak "+e.maximum+" elemet lehet kiválasztani."},noResults:function(){return"Nincs találat."},searching:function(){return"Keresés…"},removeAllItems:function(){return"Távolítson el minden elemet"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/hy.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hy",[],function(){return{errorLoading:function(){return"Արդյունքները հնարավոր չէ բեռնել։"},inputTooLong:function(n){return"Խնդրում ենք հեռացնել "+(n.input.length-n.maximum)+" նշան"},inputTooShort:function(n){return"Խնդրում ենք մուտքագրել "+(n.minimum-n.input.length)+" կամ ավել նշաններ"},loadingMore:function(){return"Բեռնվում են նոր արդյունքներ․․․"},maximumSelected:function(n){return"Դուք կարող եք ընտրել առավելագույնը "+n.maximum+" կետ"},noResults:function(){return"Արդյունքներ չեն գտնվել"},searching:function(){return"Որոնում․․․"},removeAllItems:function(){return"Հեռացնել բոլոր տարրերը"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/id.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/id",[],function(){return{errorLoading:function(){return"Data tidak boleh diambil."},inputTooLong:function(n){return"Hapuskan "+(n.input.length-n.maximum)+" huruf"},inputTooShort:function(n){return"Masukkan "+(n.minimum-n.input.length)+" huruf lagi"},loadingMore:function(){return"Mengambil data…"},maximumSelected:function(n){return"Anda hanya dapat memilih "+n.maximum+" pilihan"},noResults:function(){return"Tidak ada data yang sesuai"},searching:function(){return"Mencari…"},removeAllItems:function(){return"Hapus semua item"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/is.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/is",[],function(){return{inputTooLong:function(n){var t=n.input.length-n.maximum,e="Vinsamlegast styttið texta um "+t+" staf";return t<=1?e:e+"i"},inputTooShort:function(n){var t=n.minimum-n.input.length,e="Vinsamlegast skrifið "+t+" staf";return t>1&&(e+="i"),e+=" í viðbót"},loadingMore:function(){return"Sæki fleiri niðurstöður…"},maximumSelected:function(n){return"Þú getur aðeins valið "+n.maximum+" atriði"},noResults:function(){return"Ekkert fannst"},searching:function(){return"Leita…"},removeAllItems:function(){return"Fjarlægðu öll atriði"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/it.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/it",[],function(){return{errorLoading:function(){return"I risultati non possono essere caricati."},inputTooLong:function(e){var n=e.input.length-e.maximum,t="Per favore cancella "+n+" caratter";return t+=1!==n?"i":"e"},inputTooShort:function(e){return"Per favore inserisci "+(e.minimum-e.input.length)+" o più caratteri"},loadingMore:function(){return"Caricando più risultati…"},maximumSelected:function(e){var n="Puoi selezionare solo "+e.maximum+" element";return 1!==e.maximum?n+="i":n+="o",n},noResults:function(){return"Nessun risultato trovato"},searching:function(){return"Sto cercando…"},removeAllItems:function(){return"Rimuovi tutti gli oggetti"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/ja.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ja",[],function(){return{errorLoading:function(){return"結果が読み込まれませんでした"},inputTooLong:function(n){return n.input.length-n.maximum+" 文字を削除してください"},inputTooShort:function(n){return"少なくとも "+(n.minimum-n.input.length)+" 文字を入力してください"},loadingMore:function(){return"読み込み中…"},maximumSelected:function(n){return n.maximum+" 件しか選択できません"},noResults:function(){return"対象が見つかりません"},searching:function(){return"検索しています…"},removeAllItems:function(){return"すべてのアイテムを削除"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/ka.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ka",[],function(){return{errorLoading:function(){return"მონაცემების ჩატვირთვა შეუძლებელია."},inputTooLong:function(n){return"გთხოვთ აკრიფეთ "+(n.input.length-n.maximum)+" სიმბოლოთი ნაკლები"},inputTooShort:function(n){return"გთხოვთ აკრიფეთ "+(n.minimum-n.input.length)+" სიმბოლო ან მეტი"},loadingMore:function(){return"მონაცემების ჩატვირთვა…"},maximumSelected:function(n){return"თქვენ შეგიძლიათ აირჩიოთ არაუმეტეს "+n.maximum+" ელემენტი"},noResults:function(){return"რეზულტატი არ მოიძებნა"},searching:function(){return"ძიება…"},removeAllItems:function(){return"ამოიღე ყველა ელემენტი"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/km.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/km",[],function(){return{errorLoading:function(){return"មិនអាចទាញយកទិន្នន័យ"},inputTooLong:function(n){return"សូមលុបចេញ "+(n.input.length-n.maximum)+" អក្សរ"},inputTooShort:function(n){return"សូមបញ្ចូល"+(n.minimum-n.input.length)+" អក្សរ រឺ ច្រើនជាងនេះ"},loadingMore:function(){return"កំពុងទាញយកទិន្នន័យបន្ថែម..."},maximumSelected:function(n){return"អ្នកអាចជ្រើសរើសបានតែ "+n.maximum+" ជម្រើសប៉ុណ្ណោះ"},noResults:function(){return"មិនមានលទ្ធផល"},searching:function(){return"កំពុងស្វែងរក..."},removeAllItems:function(){return"លុបធាតុទាំងអស់"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/ko.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ko",[],function(){return{errorLoading:function(){return"결과를 불러올 수 없습니다."},inputTooLong:function(n){return"너무 깁니다. "+(n.input.length-n.maximum)+" 글자 지워주세요."},inputTooShort:function(n){return"너무 짧습니다. "+(n.minimum-n.input.length)+" 글자 더 입력해주세요."},loadingMore:function(){return"불러오는 중…"},maximumSelected:function(n){return"최대 "+n.maximum+"개까지만 선택 가능합니다."},noResults:function(){return"결과가 없습니다."},searching:function(){return"검색 중…"},removeAllItems:function(){return"모든 항목 삭제"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/lv.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/lv",[],function(){function e(e,n,u,i){return 11===e?n:e%10==1?u:i}return{inputTooLong:function(n){var u=n.input.length-n.maximum,i="Lūdzu ievadiet par "+u;return(i+=" simbol"+e(u,"iem","u","iem"))+" mazāk"},inputTooShort:function(n){var u=n.minimum-n.input.length,i="Lūdzu ievadiet vēl "+u;return i+=" simbol"+e(u,"us","u","us")},loadingMore:function(){return"Datu ielāde…"},maximumSelected:function(n){var u="Jūs varat izvēlēties ne vairāk kā "+n.maximum;return u+=" element"+e(n.maximum,"us","u","us")},noResults:function(){return"Sakritību nav"},searching:function(){return"Meklēšana…"},removeAllItems:function(){return"Noņemt visus vienumus"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/mk.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/mk",[],function(){return{inputTooLong:function(n){var e=(n.input.length,n.maximum,"Ве молиме внесете "+n.maximum+" помалку карактер");return 1!==n.maximum&&(e+="и"),e},inputTooShort:function(n){var e=(n.minimum,n.input.length,"Ве молиме внесете уште "+n.maximum+" карактер");return 1!==n.maximum&&(e+="и"),e},loadingMore:function(){return"Вчитување резултати…"},maximumSelected:function(n){var e="Можете да изберете само "+n.maximum+" ставк";return 1===n.maximum?e+="а":e+="и",e},noResults:function(){return"Нема пронајдено совпаѓања"},searching:function(){return"Пребарување…"},removeAllItems:function(){return"Отстрани ги сите предмети"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/ms.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ms",[],function(){return{errorLoading:function(){return"Keputusan tidak berjaya dimuatkan."},inputTooLong:function(n){return"Sila hapuskan "+(n.input.length-n.maximum)+" aksara"},inputTooShort:function(n){return"Sila masukkan "+(n.minimum-n.input.length)+" atau lebih aksara"},loadingMore:function(){return"Sedang memuatkan keputusan…"},maximumSelected:function(n){return"Anda hanya boleh memilih "+n.maximum+" pilihan"},noResults:function(){return"Tiada padanan yang ditemui"},searching:function(){return"Mencari…"},removeAllItems:function(){return"Keluarkan semua item"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/nb.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/nb",[],function(){return{errorLoading:function(){return"Kunne ikke hente resultater."},inputTooLong:function(e){return"Vennligst fjern "+(e.input.length-e.maximum)+" tegn"},inputTooShort:function(e){return"Vennligst skriv inn "+(e.minimum-e.input.length)+" tegn til"},loadingMore:function(){return"Laster flere resultater…"},maximumSelected:function(e){return"Du kan velge maks "+e.maximum+" elementer"},noResults:function(){return"Ingen treff"},searching:function(){return"Søker…"},removeAllItems:function(){return"Fjern alle elementer"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/ps.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ps",[],function(){return{errorLoading:function(){return"پايلي نه سي ترلاسه کېدای"},inputTooLong:function(n){var e=n.input.length-n.maximum,r="د مهربانۍ لمخي "+e+" توری ړنګ کړئ";return 1!=e&&(r=r.replace("توری","توري")),r},inputTooShort:function(n){return"لږ تر لږه "+(n.minimum-n.input.length)+" يا ډېر توري وليکئ"},loadingMore:function(){return"نوري پايلي ترلاسه کيږي..."},maximumSelected:function(n){var e="تاسو يوازي "+n.maximum+" قلم په نښه کولای سی";return 1!=n.maximum&&(e=e.replace("قلم","قلمونه")),e},noResults:function(){return"پايلي و نه موندل سوې"},searching:function(){return"لټول کيږي..."},removeAllItems:function(){return"ټول توکي لرې کړئ"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/pt-BR.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/pt-BR",[],function(){return{errorLoading:function(){return"Os resultados não puderam ser carregados."},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Apague "+n+" caracter";return 1!=n&&(r+="es"),r},inputTooShort:function(e){return"Digite "+(e.minimum-e.input.length)+" ou mais caracteres"},loadingMore:function(){return"Carregando mais resultados…"},maximumSelected:function(e){var n="Você só pode selecionar "+e.maximum+" ite";return 1==e.maximum?n+="m":n+="ns",n},noResults:function(){return"Nenhum resultado encontrado"},searching:function(){return"Buscando…"},removeAllItems:function(){return"Remover todos os itens"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/pt.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/pt",[],function(){return{errorLoading:function(){return"Os resultados não puderam ser carregados."},inputTooLong:function(e){var r=e.input.length-e.maximum,n="Por favor apague "+r+" ";return n+=1!=r?"caracteres":"caractere"},inputTooShort:function(e){return"Introduza "+(e.minimum-e.input.length)+" ou mais caracteres"},loadingMore:function(){return"A carregar mais resultados…"},maximumSelected:function(e){var r="Apenas pode seleccionar "+e.maximum+" ";return r+=1!=e.maximum?"itens":"item"},noResults:function(){return"Sem resultados"},searching:function(){return"A procurar…"},removeAllItems:function(){return"Remover todos os itens"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/sq.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/sq",[],function(){return{errorLoading:function(){return"Rezultatet nuk mund të ngarkoheshin."},inputTooLong:function(e){var n=e.input.length-e.maximum,t="Të lutem fshi "+n+" karakter";return 1!=n&&(t+="e"),t},inputTooShort:function(e){return"Të lutem shkruaj "+(e.minimum-e.input.length)+" ose më shumë karaktere"},loadingMore:function(){return"Duke ngarkuar më shumë rezultate…"},maximumSelected:function(e){var n="Mund të zgjedhësh vetëm "+e.maximum+" element";return 1!=e.maximum&&(n+="e"),n},noResults:function(){return"Nuk u gjet asnjë rezultat"},searching:function(){return"Duke kërkuar…"},removeAllItems:function(){return"Hiq të gjitha sendet"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/sv.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/sv",[],function(){return{errorLoading:function(){return"Resultat kunde inte laddas."},inputTooLong:function(n){return"Vänligen sudda ut "+(n.input.length-n.maximum)+" tecken"},inputTooShort:function(n){return"Vänligen skriv in "+(n.minimum-n.input.length)+" eller fler tecken"},loadingMore:function(){return"Laddar fler resultat…"},maximumSelected:function(n){return"Du kan max välja "+n.maximum+" element"},noResults:function(){return"Inga träffar"},searching:function(){return"Söker…"},removeAllItems:function(){return"Ta bort alla objekt"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/th.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/th",[],function(){return{errorLoading:function(){return"ไม่สามารถค้นข้อมูลได้"},inputTooLong:function(n){return"โปรดลบออก "+(n.input.length-n.maximum)+" ตัวอักษร"},inputTooShort:function(n){return"โปรดพิมพ์เพิ่มอีก "+(n.minimum-n.input.length)+" ตัวอักษร"},loadingMore:function(){return"กำลังค้นข้อมูลเพิ่ม…"},maximumSelected:function(n){return"คุณสามารถเลือกได้ไม่เกิน "+n.maximum+" รายการ"},noResults:function(){return"ไม่พบข้อมูล"},searching:function(){return"กำลังค้นข้อมูล…"},removeAllItems:function(){return"ลบรายการทั้งหมด"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/tk.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/tk",[],function(){return{errorLoading:function(){return"Netije ýüklenmedi."},inputTooLong:function(e){return e.input.length-e.maximum+" harp bozuň."},inputTooShort:function(e){return"Ýene-de iň az "+(e.minimum-e.input.length)+" harp ýazyň."},loadingMore:function(){return"Köpräk netije görkezilýär…"},maximumSelected:function(e){return"Diňe "+e.maximum+" sanysyny saýlaň."},noResults:function(){return"Netije tapylmady."},searching:function(){return"Gözlenýär…"},removeAllItems:function(){return"Remove all items"}}}),e.define,e.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/tr.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/tr",[],function(){return{errorLoading:function(){return"Sonuç yüklenemedi"},inputTooLong:function(n){return n.input.length-n.maximum+" karakter daha girmelisiniz"},inputTooShort:function(n){return"En az "+(n.minimum-n.input.length)+" karakter daha girmelisiniz"},loadingMore:function(){return"Daha fazla…"},maximumSelected:function(n){return"Sadece "+n.maximum+" seçim yapabilirsiniz"},noResults:function(){return"Sonuç bulunamadı"},searching:function(){return"Aranıyor…"},removeAllItems:function(){return"Tüm öğeleri kaldır"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/vi.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/vi",[],function(){return{inputTooLong:function(n){return"Vui lòng xóa bớt "+(n.input.length-n.maximum)+" ký tự"},inputTooShort:function(n){return"Vui lòng nhập thêm từ "+(n.minimum-n.input.length)+" ký tự trở lên"},loadingMore:function(){return"Đang lấy thêm kết quả…"},maximumSelected:function(n){return"Chỉ có thể chọn được "+n.maximum+" lựa chọn"},noResults:function(){return"Không tìm thấy kết quả"},searching:function(){return"Đang tìm…"},removeAllItems:function(){return"Xóa tất cả các mục"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/zh-CN.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/zh-CN",[],function(){return{errorLoading:function(){return"无法载入结果。"},inputTooLong:function(n){return"请删除"+(n.input.length-n.maximum)+"个字符"},inputTooShort:function(n){return"请再输入至少"+(n.minimum-n.input.length)+"个字符"},loadingMore:function(){return"载入更多结果…"},maximumSelected:function(n){return"最多只能选择"+n.maximum+"个项目"},noResults:function(){return"未找到结果"},searching:function(){return"搜索中…"},removeAllItems:function(){return"删除所有项目"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/assets/libs/select2/js/i18n/zh-TW.js: -------------------------------------------------------------------------------- 1 | /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ 2 | 3 | !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/zh-TW",[],function(){return{inputTooLong:function(n){return"請刪掉"+(n.input.length-n.maximum)+"個字元"},inputTooShort:function(n){return"請再輸入"+(n.minimum-n.input.length)+"個字元"},loadingMore:function(){return"載入中…"},maximumSelected:function(n){return"你只能選擇最多"+n.maximum+"項"},noResults:function(){return"沒有找到相符的項目"},searching:function(){return"搜尋中…"},removeAllItems:function(){return"刪除所有項目"}}}),n.define,n.require}(); -------------------------------------------------------------------------------- /Source/Presentation/CH.CleanArchitecture.Presentation.Web/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) .NET Foundation. All rights reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use 4 | these files except in compliance with the License. You may obtain a copy of the 5 | License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | -------------------------------------------------------------------------------- /Tests/CH.CleanArchitecture.Core.Tests/Application/Commands/RemoveRolesTests.cs: -------------------------------------------------------------------------------- 1 | namespace CH.CleanArchitecture.Core.Tests.Application.Commands 2 | { 3 | public class RemoveRolesTests 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Tests/CH.CleanArchitecture.Infrastructure.Tests/AuditingTests.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using CH.CleanArchitecture.Infrastructure.Models; 3 | using CH.CleanArchitecture.Tests; 4 | using Microsoft.EntityFrameworkCore; 5 | using Xunit; 6 | 7 | namespace CH.CleanArchitecture.Infrastructure.Tests 8 | { 9 | public class AuditingTests : TestBase 10 | { 11 | [Fact] 12 | public void Auditing_OnAdd_AuditableEntity_CreatesAuditHistoryRecord() { 13 | OrderEntity order = new OrderEntity(); 14 | order.TotalAmount = 100; 15 | ApplicationContext.Orders.Add(order); 16 | ApplicationContext.SaveChanges(); 17 | ApplicationContext.DetachAll(); 18 | 19 | var auditHistory = ApplicationContext.AuditHistory.SingleOrDefault(ah => ah.TableName == nameof(OrderEntity) && ah.Kind == EntityState.Added); 20 | 21 | Assert.NotNull(auditHistory); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /Tests/CH.CleanArchitecture.Tests/CH.CleanArchitecture.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Tests/CH.CleanArchitecture.Tests/DbContextExtensions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | 3 | namespace CH.CleanArchitecture.Tests 4 | { 5 | public static class DbContextExtensions 6 | { 7 | public static void DetachAll(this DbContext dbContext) { 8 | foreach (var dbEntityEntry in dbContext.ChangeTracker.Entries().ToArray()) { 9 | if (dbEntityEntry.Entity != null) { 10 | dbEntityEntry.State = EntityState.Detached; 11 | } 12 | } 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Tests/CH.CleanArchitecture.Tests/Mocks/MockAuthenticatedUserService.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Claims; 2 | using CH.CleanArchitecture.Common; 3 | using CH.CleanArchitecture.Core.Application; 4 | using CH.CleanArchitecture.Core.Domain; 5 | 6 | namespace CH.CleanArchitecture.Tests.Mocks 7 | { 8 | internal class MockAuthenticatedUserService : IAuthenticatedUserService 9 | { 10 | public string UserId => "TestingUser"; 11 | 12 | public string Username => "Mr.Tester"; 13 | 14 | public string Name => "Tester Tester"; 15 | 16 | public IEnumerable Roles { get; set; } = new List(); 17 | 18 | public string Culture => "en-GB"; 19 | 20 | public string UiCulture => "en-GB"; 21 | 22 | public ThemeEnum Theme => ThemeEnum.Dark; 23 | 24 | public ClaimsPrincipal User => new(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | trigger: 2 | - develop 3 | 4 | pool: 5 | vmImage: 'windows-latest' 6 | 7 | variables: 8 | solution: '**/*.sln' 9 | buildPlatform: 'Any CPU' 10 | buildConfiguration: 'Release' 11 | 12 | steps: 13 | - task: UseDotNet@2 14 | displayName: 'Use .NET 8 SDK' 15 | inputs: 16 | packageType: 'sdk' 17 | version: '8.0.x' 18 | includePreviewVersions: true 19 | - task: NuGetToolInstaller@1 20 | 21 | - task: DotNetCoreCLI@2 22 | displayName: 'Restore' 23 | inputs: 24 | command: restore 25 | projects: '**/*.csproj' 26 | 27 | - task: DotNetCoreCLI@2 28 | displayName: Build 29 | inputs: 30 | command: build 31 | projects: '**/*.csproj' 32 | arguments: '--configuration $(buildConfiguration)' 33 | 34 | # - task: DotNetCoreCLI@2 35 | # displayName: Test 36 | # inputs: 37 | # command: test 38 | # projects: '**/*Tests/*.csproj' 39 | # arguments: '--configuration $(buildConfiguration)' 40 | -------------------------------------------------------------------------------- /docker-compose.dcproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 2.1 5 | Linux 6 | 3888bd9e-4303-4845-9b91-054088abebb3 7 | LaunchBrowser 8 | {Scheme}://localhost:{ServicePort} 9 | chcleanarchitecture.app 10 | 11 | 12 | 13 | docker-compose.yml 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /docker-compose.override.yml: -------------------------------------------------------------------------------- 1 | version: '3.4' 2 | 3 | services: 4 | chcleanarchitecture.app: 5 | environment: 6 | - ASPNETCORE_ENVIRONMENT=DockerCompose 7 | - ASPNETCORE_URLS=http://+:80 8 | ports: 9 | - "80" 10 | volumes: 11 | - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro 12 | - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.4' 2 | 3 | services: 4 | chcleanarchitecture.app: 5 | image: ${DOCKER_REGISTRY-}chcleanarchitecture-app 6 | build: 7 | context: . 8 | dockerfile: Source/Dockerfile 9 | ports: 10 | - '8001:80' 11 | depends_on: 12 | - mssql 13 | networks: 14 | - chcleanarchitecturedev 15 | restart: on-failure 16 | mssql: 17 | image: "mcr.microsoft.com/mssql/server" 18 | environment: 19 | SA_PASSWORD: "5b0451546a750925ff20f2f72a036f70364c2cdf170c54ff0893d030e0e617f8" 20 | ACCEPT_EULA: "Y" 21 | ports: 22 | - '8433:1433' 23 | networks: 24 | - chcleanarchitecturedev 25 | networks: 26 | chcleanarchitecturedev: 27 | external: false 28 | name: chcleanarchitecturedev --------------------------------------------------------------------------------