From 664dccf13479159718a87a75b50875a36d5c0406 Mon Sep 17 00:00:00 2001 From: Woody <2997336+MWG-Logan@users.noreply.github.com> Date: Wed, 24 Dec 2025 14:23:04 -0500 Subject: [PATCH] Refactor report function, improve auth handling in UI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Renamed and relocated Azure Function for project completion reports (ProjectCompletionReportFunction → ReportFunction) for better organization. - Broadened "active" project filter to include "In Progress" status in ProjectReportingService. - Enhanced Blazor UI to detect 401 Unauthorized responses and show a login prompt with sign-in button. - Updated staticwebapp.config.json to require authentication for all routes (/*) instead of just /api/*. - Minor UI formatting improvements to data grids. --- ...ionReportFunction.cs => ReportFunction.cs} | 4 +- .../Services/ProjectReportingService.cs | 2 +- Bezalu.ProjectReporting.Web/Pages/Home.razor | 68 +++++++++++++++---- .../staticwebapp.config.json | 8 +-- 4 files changed, 63 insertions(+), 19 deletions(-) rename Bezalu.ProjectReporting.API/Functions/{ProjectCompletionReportFunction.cs => ReportFunction.cs} (99%) diff --git a/Bezalu.ProjectReporting.API/Functions/ProjectCompletionReportFunction.cs b/Bezalu.ProjectReporting.API/Functions/ReportFunction.cs similarity index 99% rename from Bezalu.ProjectReporting.API/Functions/ProjectCompletionReportFunction.cs rename to Bezalu.ProjectReporting.API/Functions/ReportFunction.cs index e7e8bf0..68112c4 100644 --- a/Bezalu.ProjectReporting.API/Functions/ProjectCompletionReportFunction.cs +++ b/Bezalu.ProjectReporting.API/Functions/ReportFunction.cs @@ -10,8 +10,8 @@ namespace Bezalu.ProjectReporting.API.Functions; -public class ProjectCompletionReportFunction( - ILogger logger, +public class ReportFunction( + ILogger logger, IProjectReportingService reportingService) { [Function("GenerateProjectCompletionReport")] diff --git a/Bezalu.ProjectReporting.API/Services/ProjectReportingService.cs b/Bezalu.ProjectReporting.API/Services/ProjectReportingService.cs index 978f03f..7c424f1 100644 --- a/Bezalu.ProjectReporting.API/Services/ProjectReportingService.cs +++ b/Bezalu.ProjectReporting.API/Services/ProjectReportingService.cs @@ -23,7 +23,7 @@ public async Task> GetActiveProjectsAsync(CancellationToke // Query ConnectWise for projects with "Active" status var projects = await connectWiseClient.GetListAsync( - "project/projects?conditions=status/name='Active'&orderBy=name", + "project/projects?conditions=status/name contains 'In Progress'&orderBy=name", cancellationToken) ?? new List(); return projects diff --git a/Bezalu.ProjectReporting.Web/Pages/Home.razor b/Bezalu.ProjectReporting.Web/Pages/Home.razor index 8235ff9..11519e4 100644 --- a/Bezalu.ProjectReporting.Web/Pages/Home.razor +++ b/Bezalu.ProjectReporting.Web/Pages/Home.razor @@ -1,4 +1,5 @@ @page "/" +@using System.Net @inject HttpClient Http @inject NavigationManager Nav @inject IJSRuntime JS @@ -6,13 +7,27 @@ Project Reporting +@if (ShowLoginPrompt) +{ + + + + + @LoginPromptText + Sign in again to continue. + + Sign in + + +} + @if (Report is null) {

Select a Project

@if (IsLoadingProjects) { - +

Loading projects...

} else if (!string.IsNullOrEmpty(ErrorMessage)) @@ -31,8 +46,8 @@ - @(IsGeneratingReport && GeneratingProjectId == context.ProjectId ? "Generating..." : "Generate Report") @@ -82,10 +97,10 @@ else else { - - - - + + + + } @@ -97,11 +112,11 @@ else else { - - - - - + + + + + } @@ -116,6 +131,8 @@ else bool IsGeneratingReport; int GeneratingProjectId; bool IsPdfLoading; + bool ShowLoginPrompt; + string LoginPromptText = "Please sign in to continue."; string? ErrorMessage; string AiSummaryHtml => Report?.AiGeneratedSummary is null ? string.Empty : Markdown.ToHtml(Report.AiGeneratedSummary); @@ -131,6 +148,11 @@ else try { var response = await Http.GetAsync("api/projects"); + if (response.StatusCode == HttpStatusCode.Unauthorized) + { + HandleUnauthorized("Please sign in to load projects."); + return; + } if (!response.IsSuccessStatusCode) { ErrorMessage = $"Failed to load projects: {response.StatusCode}"; @@ -158,6 +180,11 @@ else { var req = new ProjectCompletionReportRequest { ProjectId = projectId }; var httpResp = await Http.PostAsJsonAsync("api/reports/project-completion", req); + if (httpResp.StatusCode == HttpStatusCode.Unauthorized) + { + HandleUnauthorized("Please sign in to generate a report."); + return; + } if (!httpResp.IsSuccessStatusCode) { ErrorMessage = $"Failed to generate report: {httpResp.StatusCode}"; @@ -191,6 +218,11 @@ else try { var httpResp = await Http.PostAsJsonAsync("api/reports/project-completion/pdf", Report); + if (httpResp.StatusCode == HttpStatusCode.Unauthorized) + { + HandleUnauthorized("Please sign in to download the PDF."); + return; + } if (!httpResp.IsSuccessStatusCode) { ErrorMessage = $"Failed to generate PDF: {httpResp.StatusCode}"; @@ -210,4 +242,16 @@ else IsPdfLoading = false; } } + + void HandleUnauthorized(string message) + { + LoginPromptText = message; + ShowLoginPrompt = true; + ErrorMessage = null; + } + + void TriggerLogin() + { + Nav.NavigateTo("/login?post_login_redirect_uri=.referrer", forceLoad: true); + } } \ No newline at end of file diff --git a/Bezalu.ProjectReporting.Web/staticwebapp.config.json b/Bezalu.ProjectReporting.Web/staticwebapp.config.json index 6654357..0143e37 100644 --- a/Bezalu.ProjectReporting.Web/staticwebapp.config.json +++ b/Bezalu.ProjectReporting.Web/staticwebapp.config.json @@ -1,12 +1,12 @@ { "routes": [ - { - "route": "/api/*", - "allowedRoles": ["authenticated"] - }, { "route": "/login", "rewrite": "/.auth/login/aad" + }, + { + "route": "/*", + "allowedRoles": ["authenticated"] } ], "navigationFallback": {