diff --git a/src/Presentation.Blazor/Components/Layout/MainLayout.razor b/src/Presentation.Blazor/Components/Layout/MainLayout.razor index 4a2b647..2328c56 100644 --- a/src/Presentation.Blazor/Components/Layout/MainLayout.razor +++ b/src/Presentation.Blazor/Components/Layout/MainLayout.razor @@ -1,19 +1,38 @@ @namespace Goodtocode.SemanticKernel.Presentation.Blazor.Components.Layout @inherits LayoutComponentBase +@inject NavigationManager Navigation -
- + + + +
+
+
+ @Body +
+
+
+
+ +
+
+
+ Oops! Something went wrong.
+ @ex.Message +
+ +
+
+
+
-
-
- @Body -
-
-
+@code { + private ErrorBoundary? errorBoundaryRef; -
- An unhandled error has occurred. - Reload - 🗙 -
+ private void OnRecoverAndNavigate() + { + errorBoundaryRef?.Recover(); + Navigation.NavigateTo("/", forceLoad: true); + } +} diff --git a/src/Presentation.Blazor/Components/Layout/MainLayout.razor.css b/src/Presentation.Blazor/Components/Layout/MainLayout.razor.css index 51896df..a4b0fb0 100644 --- a/src/Presentation.Blazor/Components/Layout/MainLayout.razor.css +++ b/src/Presentation.Blazor/Components/Layout/MainLayout.razor.css @@ -15,23 +15,25 @@ main { height: 100vh; } -#blazor-error-ui { - color-scheme: light only; - background: lightyellow; - bottom: 0; - box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); - box-sizing: border-box; - display: none; - left: 0; - padding: 0.6rem 1.25rem 0.7rem 1.25rem; +.error-dialog-backdrop { position: fixed; - width: 100%; - z-index: 1000; + top: 10vh; + left: 0; + width: 100vw; + height: 90vh; + background: rgba(0,0,0,0.3); + display: flex; + align-items: center; + justify-content: center; + z-index: 1050; } - #blazor-error-ui .dismiss { - cursor: pointer; - position: absolute; - right: 0.75rem; - top: 0.5rem; - } +.error-dialog { + background: #fff; + border-radius: 8px; + box-shadow: 0 4px 32px rgba(0,0,0,0.2); + padding: 2rem 2.5rem; + min-width: 320px; + max-width: 90vw; + text-align: center; +} diff --git a/src/Presentation.Blazor/ConfigureServices.cs b/src/Presentation.Blazor/ConfigureServices.cs index ab96c8b..2e11bf9 100644 --- a/src/Presentation.Blazor/ConfigureServices.cs +++ b/src/Presentation.Blazor/ConfigureServices.cs @@ -9,7 +9,10 @@ namespace Goodtocode.SemanticKernel.Presentation.Blazor; public static class ConfigureServices { - + public static bool IsLocal(this IWebHostEnvironment environment) + { + return environment.EnvironmentName.Equals("Local", StringComparison.OrdinalIgnoreCase); + } public static void AddLocalEnvironment(this WebApplicationBuilder builder) { if (builder.Environment.IsEnvironment("Local")) diff --git a/src/Presentation.Blazor/Program.cs b/src/Presentation.Blazor/Program.cs index e5e59ea..e59b5d6 100644 --- a/src/Presentation.Blazor/Program.cs +++ b/src/Presentation.Blazor/Program.cs @@ -22,7 +22,7 @@ var app = builder.Build(); -if (app.Environment.IsDevelopment() || app.Environment.EnvironmentName.Equals("Local", StringComparison.OrdinalIgnoreCase)) +if (app.Environment.IsDevelopment() || app.Environment.IsLocal()) { app.UseDeveloperExceptionPage(); } diff --git a/src/Presentation.WebApi/ConfigureServices.cs b/src/Presentation.WebApi/ConfigureServices.cs index a4f55c9..955f599 100644 --- a/src/Presentation.WebApi/ConfigureServices.cs +++ b/src/Presentation.WebApi/ConfigureServices.cs @@ -9,6 +9,16 @@ namespace Goodtocode.SemanticKernel.Presentation.WebApi; /// public static class ConfigureServices { + /// + /// Determines if the current environment is "Local". + /// + /// The web host environment. + /// True if the environment is "Local"; otherwise, false. + public static bool IsLocal(this IWebHostEnvironment environment) + { + return environment.EnvironmentName.Equals("Local", StringComparison.OrdinalIgnoreCase); + } + /// /// Add Local Environment Configuration to mirror Development /// @@ -31,17 +41,6 @@ public static void AddLocalEnvironment(this WebApplicationBuilder builder) /// public static IServiceCollection AddWebUIServices(this IServiceCollection services) { - //var assemblyVersion = Assembly.GetExecutingAssembly().GetName().Version; - //var majorVersion = $"v{assemblyVersion?.Major ?? 1}"; - //services.AddSwaggerGen(c => - //{ - // c.SwaggerDoc(majorVersion, new OpenApiInfo - // { - // Title = "Semantic Kernel Quick-start for WebAPI", - // Version = majorVersion - // }); - //}); - services.AddControllersWithViews(setupAction => { setupAction.Filters.Add( diff --git a/src/Presentation.WebApi/Program.cs b/src/Presentation.WebApi/Program.cs index 48ac51b..afcdf1f 100644 --- a/src/Presentation.WebApi/Program.cs +++ b/src/Presentation.WebApi/Program.cs @@ -26,7 +26,6 @@ builder.Services.AddSemanticKernelOpenAIServices(builder.Configuration); builder.Services.AddWebUIServices(); builder.Services.AddHealthChecks(); -//AddKeyVaultConfigurationSettings(builder); BuildApiVerAndApiExplorer(builder); builder.Services.AddOpenTelemetry().UseAzureMonitor(options => @@ -36,7 +35,7 @@ var app = builder.Build(); -if (app.Environment.IsDevelopment() || app.Environment.EnvironmentName.Equals("Local", StringComparison.OrdinalIgnoreCase)) +if (app.Environment.IsDevelopment() || app.Environment.IsLocal()) { app.UseSwagger(); UseSwaggerUiConfigs(); @@ -84,15 +83,4 @@ void BuildApiVerAndApiExplorer(WebApplicationBuilder webApplicationBuilder) setup.GroupNameFormat = "'v'VVV"; setup.SubstituteApiVersionInUrl = true; }); -} - -void AddKeyVaultConfigurationSettings(WebApplicationBuilder appBuilder) -{ - if (!appBuilder.Configuration.GetValue("KeyVault:UseKeyVault")) return; - - var azureKeyVaultEndpoint = appBuilder.Configuration["KeyVault:Endpoint"]; - if (azureKeyVaultEndpoint == null) return; - var credential = new DefaultAzureCredential(); - var secretClient = new SecretClient(new Uri(azureKeyVaultEndpoint), credential); - appBuilder.Configuration.AddAzureKeyVault(secretClient, new KeyVaultSecretManager()); -} +} \ No newline at end of file diff --git a/src/Presentation.WebApi/appsettings.Development.json b/src/Presentation.WebApi/appsettings.Development.json index e914fc9..d4c261d 100644 --- a/src/Presentation.WebApi/appsettings.Development.json +++ b/src/Presentation.WebApi/appsettings.Development.json @@ -28,10 +28,6 @@ "Scopes": "api.fullaccess", "SignUpSignInPolicyId": "B2C_1_susi" }, - "KeyVault": { - "UseKeyVault": false, - "Endpoint": "https://{{YOUR_KEYVAULT_NAME}}.vault.azure.net/" - }, "OpenAI": { "ChatCompletionModelId": "gpt-4.1-mini", "TextGenerationModelId": "gpt-3.5-turbo-instruct", diff --git a/src/Presentation.WebApi/appsettings.Production.json b/src/Presentation.WebApi/appsettings.Production.json index e8cfbd2..e6aab2e 100644 --- a/src/Presentation.WebApi/appsettings.Production.json +++ b/src/Presentation.WebApi/appsettings.Production.json @@ -28,10 +28,6 @@ "Scopes": "api.fullaccess", "SignUpSignInPolicyId": "B2C_1_susi" }, - "KeyVault": { - "UseKeyVault": false, - "Endpoint": "https://{{YOUR_KEYVAULT_NAME}}.vault.azure.net/" - }, "OpenAI": { "ChatCompletionModelId": "gpt-4.1", "TextGenerationModelId": "gpt-3.5-turbo-instruct", diff --git a/src/Presentation.WebApi/appsettings.local.json b/src/Presentation.WebApi/appsettings.local.json index 947cbd0..69744d0 100644 --- a/src/Presentation.WebApi/appsettings.local.json +++ b/src/Presentation.WebApi/appsettings.local.json @@ -28,10 +28,6 @@ "Scopes": "api.fullaccess", "SignUpSignInPolicyId": "B2C_1_susi" }, - "KeyVault": { - "UseKeyVault": false, - "Endpoint": "https://{{YOUR_KEYVAULT_NAME}}.vault.azure.net/" - }, "OpenAI": { "ChatCompletionModelId": "gpt-4.1-nano", "TextGenerationModelId": "gpt-3.5-turbo-instruct",