diff --git a/.env.example b/.env.example index 7a240d97..55fe0762 100644 --- a/.env.example +++ b/.env.example @@ -6,7 +6,6 @@ FRONTEND_APP_BASE_URL=http://localhost:80/ MAX_DAYS_IN_CALENDAR=60 BUSINESS_NAME=World Dental CO DENTAL_SERVICES_IMAGES_PATH=/app/dental_services -LANGUAGE=es PLUGINS=" Plugin.ChatBot.dll Plugin.AppointmentReminders.dll diff --git a/DentallApp.sln b/DentallApp.sln index 62818c68..49cc5172 100644 --- a/DentallApp.sln +++ b/DentallApp.sln @@ -42,6 +42,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Elements", "Soluti .env.example = .env.example tests\IntegrationTests\.env.test = tests\IntegrationTests\.env.test tests\IntegrationTests\.env.test.example = tests\IntegrationTests\.env.test.example + src\HostApplication\appsettings.json = src\HostApplication\appsettings.json Directory.Build.props = Directory.Build.props Directory.Packages.props = Directory.Packages.props EndProjectSection diff --git a/src/HostApplication/Extensions/AuthenticationJwtBearer.cs b/src/HostApplication/Extensions/AuthenticationJwtBearer.cs index 7b0c1c3e..e0bcf598 100644 --- a/src/HostApplication/Extensions/AuthenticationJwtBearer.cs +++ b/src/HostApplication/Extensions/AuthenticationJwtBearer.cs @@ -2,7 +2,9 @@ public static class AuthenticationJwtBearer { - public static IServiceCollection AddAuthenticationJwtBearer(this IServiceCollection services, AppSettings settings) + public static IServiceCollection AddAuthenticationJwtBearer( + this IServiceCollection services, + AppSettings settings) { services.AddAuthentication(options => { diff --git a/src/HostApplication/Extensions/LanguageExtensions.cs b/src/HostApplication/Extensions/LanguageExtensions.cs new file mode 100644 index 00000000..65f34454 --- /dev/null +++ b/src/HostApplication/Extensions/LanguageExtensions.cs @@ -0,0 +1,31 @@ +namespace DentallApp.HostApplication.Extensions; + +public static class LanguageExtensions +{ + public static IServiceCollection ConfigureLanguages( + this IServiceCollection services, + IConfiguration configuration) + { + services.Configure(options => + { + List supportedCultures = []; + var languages = configuration.GetLanguages(); + foreach (var language in languages) + supportedCultures.Add(new CultureInfo(language)); + + var defaultLanguage = configuration.GetDefaultLanguage(); + options.DefaultRequestCulture = new RequestCulture(defaultLanguage); + options.SupportedCultures = supportedCultures; + options.SupportedUICultures = supportedCultures; + }); + return services; + } + + public static string[] GetLanguages(this IConfiguration configuration) + => configuration + .GetRequiredSection("Languages") + .Get() ?? []; + + public static string GetDefaultLanguage(this IConfiguration configuration) + => configuration.GetValue("DefaultLanguage") ?? "es"; +} diff --git a/src/HostApplication/Extensions/SwaggerGen.cs b/src/HostApplication/Extensions/SwaggerGen.cs index 43889de2..dcaa358b 100644 --- a/src/HostApplication/Extensions/SwaggerGen.cs +++ b/src/HostApplication/Extensions/SwaggerGen.cs @@ -5,7 +5,8 @@ public static class SwaggerGen public static IServiceCollection AddSwagger(this IServiceCollection services) { services.AddSwaggerGen(options => - { + { + options.OperationFilter(); options.EnableAnnotations(); options.SwaggerDoc("v1", new OpenApiInfo { Title = "DentallApi", Version = "v1" }); options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme @@ -27,7 +28,7 @@ public static IServiceCollection AddSwagger(this IServiceCollection services) Id = "Bearer" } }, - new string[] { } + Array.Empty() } }); var coreAssemblyName = typeof(GetDependentsByCurrentUserIdUseCase).Assembly.GetName().Name; @@ -44,4 +45,31 @@ public static IServiceCollection AddSwagger(this IServiceCollection services) }); return services; } + + private class AcceptLanguageHeaderParameter(IConfiguration configuration) : IOperationFilter + { + public void Apply(OpenApiOperation operation, OperationFilterContext context) + { + operation.Parameters ??= []; + var languageOptions = new List(); + var languages = configuration.GetLanguages(); + var defaultLanguage = configuration.GetDefaultLanguage(); + foreach (var language in languages) + languageOptions.Add(new OpenApiString(language)); + + operation.Parameters.Add(new OpenApiParameter + { + Name = "Accept-Language", + Description = "Language preference for the response.", + In = ParameterLocation.Header, + Required = false, + Schema = new OpenApiSchema + { + Type = "string", + Default = new OpenApiString(defaultLanguage), + Enum = languageOptions + } + }); + } + } } diff --git a/src/HostApplication/GlobalUsings.cs b/src/HostApplication/GlobalUsings.cs index d94d36ca..3f97621b 100644 --- a/src/HostApplication/GlobalUsings.cs +++ b/src/HostApplication/GlobalUsings.cs @@ -16,11 +16,13 @@ global using DentallApp.Shared.Configuration; global using System.Reflection; +global using System.Globalization; global using System.Net; global using System.Text; global using System.Text.Encodings.Web; global using System.Text.Json.Serialization; +global using Microsoft.AspNetCore.Localization; global using Microsoft.AspNetCore.Mvc.ApplicationParts; global using Microsoft.AspNetCore.Authentication; global using Microsoft.AspNetCore.Authentication.JwtBearer; @@ -31,6 +33,8 @@ global using Microsoft.Extensions.Options; global using Microsoft.Extensions.DependencyInjection.Extensions; global using Microsoft.OpenApi.Models; +global using Microsoft.OpenApi.Any; +global using Swashbuckle.AspNetCore.SwaggerGen; global using EntityFramework.Exceptions.Common; global using DotEnv.Core; diff --git a/src/HostApplication/Program.cs b/src/HostApplication/Program.cs index 1bfcadae..f702156d 100644 --- a/src/HostApplication/Program.cs +++ b/src/HostApplication/Program.cs @@ -25,6 +25,7 @@ builder.Services.AddSwagger(); builder.Services.AddAuthenticationJwtBearer(appSettings); builder.Services.AddValidators(); +builder.Services.ConfigureLanguages(builder.Configuration); builder.Services .AddExceptionHandler() @@ -44,8 +45,7 @@ app.UseExceptionHandler("/"); } -app.UseRequestLocalization(appSettings.Language); - +app.UseRequestLocalization(); app.UseWebSockets() .UsePathBase(new PathString("/api")) .UseRouting() diff --git a/src/HostApplication/appsettings.Development.json b/src/HostApplication/appsettings.Development.json deleted file mode 100644 index 7d7d7f5d..00000000 --- a/src/HostApplication/appsettings.Development.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Debug", - "System": "Information", - "Microsoft": "Information" - } - } -} \ No newline at end of file diff --git a/src/HostApplication/appsettings.json b/src/HostApplication/appsettings.json index 6fb79de1..eac9b113 100644 --- a/src/HostApplication/appsettings.json +++ b/src/HostApplication/appsettings.json @@ -1,6 +1,11 @@ { - "MicrosoftAppType": "", - "MicrosoftAppId": "", - "MicrosoftAppPassword": "", - "MicrosoftAppTenantId": "" + "MicrosoftAppType": "", + "MicrosoftAppId": "", + "MicrosoftAppPassword": "", + "MicrosoftAppTenantId": "", + "DefaultLanguage": "es", + "Languages": [ + "es", + "en" + ] } \ No newline at end of file diff --git a/src/Shared/Configuration/AppSettings.cs b/src/Shared/Configuration/AppSettings.cs index 17c6c223..edb260c7 100644 --- a/src/Shared/Configuration/AppSettings.cs +++ b/src/Shared/Configuration/AppSettings.cs @@ -7,7 +7,6 @@ public class AppSettings { public string BusinessName { get; set; } = string.Empty; public string DentalServicesImagesPath { get; set; } = string.Empty; - public string Language { get; set; } = string.Empty; public string AccessTokenKey { get; set; } = string.Empty; public double AccessTokenExpires { get; set; }