-
Notifications
You must be signed in to change notification settings - Fork 1
Refactor report function, improve auth handling in UI #36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -23,7 +23,7 @@ public async Task<List<ProjectListItem>> GetActiveProjectsAsync(CancellationToke | |||||
|
|
||||||
| // Query ConnectWise for projects with "Active" status | ||||||
| var projects = await connectWiseClient.GetListAsync<CWProject>( | ||||||
| "project/projects?conditions=status/name='Active'&orderBy=name", | ||||||
| "project/projects?conditions=status/name contains 'In Progress'&orderBy=name", | ||||||
|
||||||
| "project/projects?conditions=status/name contains 'In Progress'&orderBy=name", | |
| "project/projects?conditions=status/name=\"In Progress\"&orderBy=name", |
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,18 +1,33 @@ | ||||||||||||
| @page "/" | ||||||||||||
| @using System.Net | ||||||||||||
| @inject HttpClient Http | ||||||||||||
| @inject NavigationManager Nav | ||||||||||||
| @inject IJSRuntime JS | ||||||||||||
| @using Markdig | ||||||||||||
|
|
||||||||||||
| <PageTitle>Project Reporting</PageTitle> | ||||||||||||
|
|
||||||||||||
| @if (ShowLoginPrompt) | ||||||||||||
| { | ||||||||||||
| <FluentCard Style="padding:0.5rem 1rem; margin-bottom:1rem;"> | ||||||||||||
| <FluentStack Orientation="Orientation.Horizontal" Gap="10" VerticalAlignment="VerticalAlignment.Center"> | ||||||||||||
| <FluentIcon Value="@(new Icons.Regular.Size20.LockClosed())" /> | ||||||||||||
| <FluentStack> | ||||||||||||
| <strong>@LoginPromptText</strong> | ||||||||||||
| <span>Sign in again to continue.</span> | ||||||||||||
| </FluentStack> | ||||||||||||
| <FluentButton Appearance="Appearance.Accent" OnClick="TriggerLogin">Sign in</FluentButton> | ||||||||||||
| </FluentStack> | ||||||||||||
| </FluentCard> | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| @if (Report is null) | ||||||||||||
| { | ||||||||||||
| <FluentCard Style="padding:1rem; margin-bottom:1rem;"> | ||||||||||||
| <h2>Select a Project</h2> | ||||||||||||
| @if (IsLoadingProjects) | ||||||||||||
| { | ||||||||||||
| <FluentProgressRing/> | ||||||||||||
| <FluentProgressRing /> | ||||||||||||
| <p>Loading projects...</p> | ||||||||||||
| } | ||||||||||||
| else if (!string.IsNullOrEmpty(ErrorMessage)) | ||||||||||||
|
|
@@ -31,8 +46,8 @@ | |||||||||||
| <PropertyColumn Property="@(p => p.Manager)" Title="Manager" /> | ||||||||||||
| <PropertyColumn Property="@(p => p.Company)" Title="Company" /> | ||||||||||||
| <TemplateColumn Title="Actions"> | ||||||||||||
| <FluentButton Appearance="Appearance.Accent" | ||||||||||||
| OnClick="@(() => GenerateReport(context.ProjectId))" | ||||||||||||
| <FluentButton Appearance="Appearance.Accent" | ||||||||||||
| OnClick="@(() => GenerateReport(context.ProjectId))" | ||||||||||||
| Disabled="IsGeneratingReport"> | ||||||||||||
| @(IsGeneratingReport && GeneratingProjectId == context.ProjectId ? "Generating..." : "Generate Report") | ||||||||||||
| </FluentButton> | ||||||||||||
|
|
@@ -82,10 +97,10 @@ else | |||||||||||
| else | ||||||||||||
| { | ||||||||||||
| <FluentDataGrid Items="@Report.Phases.AsQueryable()" GenerateFooter="false"> | ||||||||||||
| <PropertyColumn Property="@(p => p.PhaseName)" Title="Name"/> | ||||||||||||
| <PropertyColumn Property="@(p => p.Status)" Title="Status"/> | ||||||||||||
| <PropertyColumn Property="@(p => p.EstimatedHours)" Title="Est Hrs"/> | ||||||||||||
| <PropertyColumn Property="@(p => p.ActualHours)" Title="Actual Hrs"/> | ||||||||||||
| <PropertyColumn Property="@(p => p.PhaseName)" Title="Name" /> | ||||||||||||
| <PropertyColumn Property="@(p => p.Status)" Title="Status" /> | ||||||||||||
| <PropertyColumn Property="@(p => p.EstimatedHours)" Title="Est Hrs" /> | ||||||||||||
| <PropertyColumn Property="@(p => p.ActualHours)" Title="Actual Hrs" /> | ||||||||||||
| </FluentDataGrid> | ||||||||||||
| } | ||||||||||||
| </FluentTab> | ||||||||||||
|
|
@@ -97,11 +112,11 @@ else | |||||||||||
| else | ||||||||||||
| { | ||||||||||||
| <FluentDataGrid Items="@Report.Tickets.AsQueryable()" GenerateFooter="false"> | ||||||||||||
| <PropertyColumn Property="@(t => t.TicketNumber)" Title="Number"/> | ||||||||||||
| <PropertyColumn Property="@(t => t.Summary)" Title="Summary"/> | ||||||||||||
| <PropertyColumn Property="@(t => t.Status)" Title="Status"/> | ||||||||||||
| <PropertyColumn Property="@(t => t.EstimatedHours)" Title="Est Hrs"/> | ||||||||||||
| <PropertyColumn Property="@(t => t.ActualHours)" Title="Actual Hrs"/> | ||||||||||||
| <PropertyColumn Property="@(t => t.TicketNumber)" Title="Number" /> | ||||||||||||
| <PropertyColumn Property="@(t => t.Summary)" Title="Summary" /> | ||||||||||||
| <PropertyColumn Property="@(t => t.Status)" Title="Status" /> | ||||||||||||
| <PropertyColumn Property="@(t => t.EstimatedHours)" Title="Est Hrs" /> | ||||||||||||
| <PropertyColumn Property="@(t => t.ActualHours)" Title="Actual Hrs" /> | ||||||||||||
| </FluentDataGrid> | ||||||||||||
| } | ||||||||||||
| </FluentTab> | ||||||||||||
|
|
@@ -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; | ||||||||||||
| } | ||||||||||||
|
Comment on lines
+151
to
+155
|
||||||||||||
| 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; | ||||||||||||
| } | ||||||||||||
|
Comment on lines
+183
to
+187
|
||||||||||||
| 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; | ||||||||||||
| } | ||||||||||||
|
Comment on lines
+221
to
+225
|
||||||||||||
| 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); | ||||||||||||
|
||||||||||||
| Nav.NavigateTo("/login?post_login_redirect_uri=.referrer", forceLoad: true); | |
| var currentUri = new Uri(Nav.Uri); | |
| var redirectPath = currentUri.PathAndQuery + currentUri.Fragment; | |
| var encodedRedirect = Uri.EscapeDataString(redirectPath); | |
| Nav.NavigateTo($"/login?post_login_redirect_uri={encodedRedirect}", forceLoad: true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment on line 24 states "Query ConnectWise for projects with 'Active' status" but the code now queries for 'In Progress' status. The comment should be updated to reflect the actual query being performed.