From f360785309090ab31b78dd2e581a611fc77f9b78 Mon Sep 17 00:00:00 2001 From: Andres Date: Thu, 20 Mar 2025 20:00:10 -0400 Subject: [PATCH 01/24] Feat: wwwroot JavaScript integration - Updated `HelloReport.razor` to include a new paragraph element for displaying a greeting message. - Added an IIFE in `HelloJavascriptData.js` to manage the `HelloWorld` element and set its content. - Modified `BlazorReportsTemplate.razor` to improve indentation and introduced a `Scripts` parameter for including JavaScript files. - Registered `JavascriptContainer` in `ServiceCollectionExtensions.cs` to manage JavaScript files. - Created `JavascriptContainer.cs` to scan and store JavaScript file contents from the `wwwroot/js` directory. - Updated `ReportService.cs` to utilize `JavascriptContainer` for dynamic script inclusion in reports. --- examples/SimpleReportServer/HelloReport.razor | 2 +- .../wwwroot/js/HelloJavascriptData.js | 11 +++++ .../BlazorReportsTemplate.razor | 47 +++++++++++------- .../Extensions/ServiceCollectionExtensions.cs | 3 ++ .../JavascriptServices/JavascriptContainer.cs | 48 +++++++++++++++++++ src/BlazorReports/Services/ReportService.cs | 7 +++ 6 files changed, 100 insertions(+), 18 deletions(-) create mode 100644 examples/SimpleReportServer/wwwroot/js/HelloJavascriptData.js create mode 100644 src/BlazorReports/Services/JavascriptServices/JavascriptContainer.cs diff --git a/examples/SimpleReportServer/HelloReport.razor b/examples/SimpleReportServer/HelloReport.razor index c0dc338..376f0db 100644 --- a/examples/SimpleReportServer/HelloReport.razor +++ b/examples/SimpleReportServer/HelloReport.razor @@ -1,5 +1,5 @@

Hello @Data.Name

- +

w

@code { [Parameter] public required HelloReportData Data { get; set; } diff --git a/examples/SimpleReportServer/wwwroot/js/HelloJavascriptData.js b/examples/SimpleReportServer/wwwroot/js/HelloJavascriptData.js new file mode 100644 index 0000000..43102c4 --- /dev/null +++ b/examples/SimpleReportServer/wwwroot/js/HelloJavascriptData.js @@ -0,0 +1,11 @@ +(function () { + var helloWorld = document.getElementById('HelloWorld'); + + if (!helloWorld) { + helloWorld = document.createElement('p'); // Create the element + helloWorld.id = 'HelloWorld'; + document.body.appendChild(helloWorld); // Append it to the body + } + + helloWorld.innerHTML = 'Hello World'; // Set text instantly +})(); diff --git a/src/BlazorReports.Components/BlazorReportsTemplate.razor b/src/BlazorReports.Components/BlazorReportsTemplate.razor index d0c4e6d..415fb8c 100644 --- a/src/BlazorReports.Components/BlazorReportsTemplate.razor +++ b/src/BlazorReports.Components/BlazorReportsTemplate.razor @@ -1,29 +1,42 @@ - + + - + + + @foreach (var script in Scripts) + { + + } + + @code { - /// - /// The base styles to be applied to the component. - /// - [Parameter] - public string BaseStyles { get; set; } = ""; - /// - /// The type of the component to be rendered in the html body. - /// - [Parameter] - public Type ChildComponentType { get; set; } = null!; - /// - /// The parameters to be passed to the child component. - /// - [Parameter] - public IDictionary ChildComponentParameters { get; set; } = null!; + /// + /// The base styles to be applied to the component. + /// + [Parameter] + public string BaseStyles { get; set; } = ""; + /// + /// The type of the component to be rendered in the html body. + /// + [Parameter] + public Type ChildComponentType { get; set; } = null!; + /// + /// The parameters to be passed to the child component. + /// + [Parameter] + public IDictionary ChildComponentParameters { get; set; } = null!; + /// + /// The scripts to be included in the html body. + /// + [Parameter] + public Dictionary Scripts { get; set; } = new Dictionary(); } diff --git a/src/BlazorReports/Extensions/ServiceCollectionExtensions.cs b/src/BlazorReports/Extensions/ServiceCollectionExtensions.cs index 3eda7c2..8ba7892 100644 --- a/src/BlazorReports/Extensions/ServiceCollectionExtensions.cs +++ b/src/BlazorReports/Extensions/ServiceCollectionExtensions.cs @@ -2,6 +2,7 @@ using BlazorReports.Services; using BlazorReports.Services.BrowserServices; using BlazorReports.Services.BrowserServices.Factories; +using BlazorReports.Services.JavascriptServices; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing.Constraints; using Microsoft.Extensions.DependencyInjection; @@ -26,6 +27,8 @@ public static IServiceCollection AddBlazorReports( { services.Configure(options ?? (_ => { })); services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); diff --git a/src/BlazorReports/Services/JavascriptServices/JavascriptContainer.cs b/src/BlazorReports/Services/JavascriptServices/JavascriptContainer.cs new file mode 100644 index 0000000..d695af6 --- /dev/null +++ b/src/BlazorReports/Services/JavascriptServices/JavascriptContainer.cs @@ -0,0 +1,48 @@ +using Microsoft.AspNetCore.Hosting; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BlazorReports.Services.JavascriptServices; +internal sealed class JavascriptContainer +{ + /// + /// A dictionary of (FileName -> FileContent) for all .js files. + /// + public Dictionary Scripts { get; } = new(); + + /// + /// Scans the wwwroot/js folder (or any folder you specify) and reads + /// all .js file contents into memory. + /// + public JavascriptContainer(IWebHostEnvironment env) + { + // 1. Get the physical path to the wwwroot folder + var webRootPath = env.WebRootPath; + + // 2. Build path to the "js" subfolder + var jsDir = Path.Combine(webRootPath, "js"); + + if (Directory.Exists(jsDir)) + { + // 3. Get all *.js files recursively + var allJsFiles = Directory.GetFiles(jsDir, "*.js", SearchOption.AllDirectories); + + foreach (var filePath in allJsFiles) + { + // For example: "C:\MyApp\wwwroot\js\somefolder\file.js" + // We'll use the file name (e.g. "file.js") or a relative path as key + var fileName = Path.GetFileName(filePath); + + // 4. Read the file text content + var content = File.ReadAllText(filePath, Encoding.UTF8); + + // 5. Store in the dictionary + Scripts[fileName] = content; + } + } + } + +} diff --git a/src/BlazorReports/Services/ReportService.cs b/src/BlazorReports/Services/ReportService.cs index 6ba3aae..477db72 100644 --- a/src/BlazorReports/Services/ReportService.cs +++ b/src/BlazorReports/Services/ReportService.cs @@ -3,6 +3,7 @@ using BlazorReports.Models; using BlazorReports.Services.BrowserServices; using BlazorReports.Services.BrowserServices.Problems; +using BlazorReports.Services.JavascriptServices; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web; using Microsoft.Extensions.DependencyInjection; @@ -99,6 +100,7 @@ public async ValueTask< { using var scope = serviceProvider.CreateScope(); var loggerFactory = scope.ServiceProvider.GetRequiredService(); + var javascriptContainer = scope.ServiceProvider.GetRequiredService(); var baseStyles = string.Empty; if (!string.IsNullOrEmpty(blazorReport.BaseStyles)) @@ -134,6 +136,11 @@ public async ValueTask< { baseComponentParameters.Add("BaseStyles", baseStyles); } + if (javascriptContainer.Scripts.Count > 0) + { + baseComponentParameters.Add("Scripts", javascriptContainer.Scripts); + } + baseComponentParameters.Add("ChildComponentType", blazorReport.Component); baseComponentParameters.Add("ChildComponentParameters", childComponentParameters); From 2ca5ec9ce26e0411e07245efd252b78c30419230 Mon Sep 17 00:00:00 2001 From: Andres Date: Thu, 20 Mar 2025 20:24:30 -0400 Subject: [PATCH 02/24] fix: script as a string changed to MarkupString --- src/BlazorReports.Components/BlazorReportsTemplate.razor | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/BlazorReports.Components/BlazorReportsTemplate.razor b/src/BlazorReports.Components/BlazorReportsTemplate.razor index 415fb8c..bbca09c 100644 --- a/src/BlazorReports.Components/BlazorReportsTemplate.razor +++ b/src/BlazorReports.Components/BlazorReportsTemplate.razor @@ -9,7 +9,9 @@ @foreach (var script in Scripts) { - + } From 2748df184a5af7d9d765fb3c9ca63beeb229b6e9 Mon Sep 17 00:00:00 2001 From: Andres Date: Thu, 20 Mar 2025 21:02:51 -0400 Subject: [PATCH 03/24] Feat: Signal flag created --- examples/SimpleReportServer/HelloReport.razor | 2 +- .../wwwroot/js/HelloJavascriptData.js | 12 +++ .../Models/BlazorReportJavascriptSettings.cs | 22 +++++ .../Models/BlazorReportsOptions.cs | 4 + .../Services/BrowserServices/Browser.cs | 16 +++ .../Services/BrowserServices/BrowserPage.cs | 98 +++++++++++++++++++ .../Factories/BrowserFactory.cs | 3 +- .../Responses/RuntimeEvaluateResponse.cs | 42 ++++++++ 8 files changed, 197 insertions(+), 2 deletions(-) create mode 100644 src/BlazorReports/Models/BlazorReportJavascriptSettings.cs create mode 100644 src/BlazorReports/Services/BrowserServices/Responses/RuntimeEvaluateResponse.cs diff --git a/examples/SimpleReportServer/HelloReport.razor b/examples/SimpleReportServer/HelloReport.razor index 376f0db..a96d3be 100644 --- a/examples/SimpleReportServer/HelloReport.razor +++ b/examples/SimpleReportServer/HelloReport.razor @@ -1,5 +1,5 @@

Hello @Data.Name

-

w

+

No data was found

@code { [Parameter] public required HelloReportData Data { get; set; } diff --git a/examples/SimpleReportServer/wwwroot/js/HelloJavascriptData.js b/examples/SimpleReportServer/wwwroot/js/HelloJavascriptData.js index 43102c4..9f6ec3e 100644 --- a/examples/SimpleReportServer/wwwroot/js/HelloJavascriptData.js +++ b/examples/SimpleReportServer/wwwroot/js/HelloJavascriptData.js @@ -1,3 +1,6 @@ +window.reportIsReady = false; + + (function () { var helloWorld = document.getElementById('HelloWorld'); @@ -9,3 +12,12 @@ helloWorld.innerHTML = 'Hello World'; // Set text instantly })(); + + + +//Wait 10 seconds and set reportIsReady to true + +setTimeout(function () { + window.reportIsReady = true; +} + , 10000); diff --git a/src/BlazorReports/Models/BlazorReportJavascriptSettings.cs b/src/BlazorReports/Models/BlazorReportJavascriptSettings.cs new file mode 100644 index 0000000..55efb85 --- /dev/null +++ b/src/BlazorReports/Models/BlazorReportJavascriptSettings.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BlazorReports.Models; +/// +/// Settings for the internal javascript api +/// +public class BlazorReportJavascriptSettings +{ + /// + /// The signal that the report is ready + /// + public string ReportIsReadySignal { get; set; } = "reportIsReady"; + /// + /// The amount of time a reports javascript can take until it is considered to have timed out + /// + public TimeSpan ReportTimeout { get; set; } = TimeSpan.FromSeconds(5); + +} diff --git a/src/BlazorReports/Models/BlazorReportsOptions.cs b/src/BlazorReports/Models/BlazorReportsOptions.cs index 86dbebc..dfc1ca3 100644 --- a/src/BlazorReports/Models/BlazorReportsOptions.cs +++ b/src/BlazorReports/Models/BlazorReportsOptions.cs @@ -24,4 +24,8 @@ public class BlazorReportsOptions /// Settings for generating a PDF /// public BlazorReportsPageSettings PageSettings { get; set; } = new(); + /// + /// Javascript api settings + /// + public BlazorReportJavascriptSettings JavascriptSettings { get; set; } = new(); } diff --git a/src/BlazorReports/Services/BrowserServices/Browser.cs b/src/BlazorReports/Services/BrowserServices/Browser.cs index ed94142..2ff541c 100644 --- a/src/BlazorReports/Services/BrowserServices/Browser.cs +++ b/src/BlazorReports/Services/BrowserServices/Browser.cs @@ -21,6 +21,7 @@ internal sealed class Browser( DirectoryInfo dataDirectory, Connection connection, BlazorReportsBrowserOptions browserOptions, + BlazorReportJavascriptSettings javascriptSettings, ILogger logger, IBrowserPageFactory browserPageFactory ) : IAsyncDisposable @@ -91,7 +92,22 @@ out browserPage try { + var reportIsReadyFlagName = javascriptSettings.ReportIsReadySignal; await browserPage.DisplayHtml(html, cancellationToken); + var reportIsReadyFlagHasBeenSet = await browserPage.DoesJsFlagExistAsync( + reportIsReadyFlagName, + cancellationToken + ); + + if (reportIsReadyFlagHasBeenSet) + { + await browserPage.WaitForJsFlagAsync( + reportIsReadyFlagName, + javascriptSettings.ReportTimeout, + cancellationToken + ); + } + await browserPage.ConvertPageToPdf(pipeWriter, pageSettings, cancellationToken); } catch (Exception e) diff --git a/src/BlazorReports/Services/BrowserServices/BrowserPage.cs b/src/BlazorReports/Services/BrowserServices/BrowserPage.cs index e2df393..0382fbd 100644 --- a/src/BlazorReports/Services/BrowserServices/BrowserPage.cs +++ b/src/BlazorReports/Services/BrowserServices/BrowserPage.cs @@ -1,4 +1,5 @@ using System.Buffers; +using System.Diagnostics; using System.IO.Pipelines; using System.Security.Cryptography; using System.Text; @@ -69,6 +70,103 @@ await connection.SendAsync( stoppingToken ); } + /// + /// Checks if a JavaScript flag is set + /// + /// Flag to be checked + /// cancellation token + /// Returns the flag current value + internal async Task CheckIfFlagIsSetAsync(string flagName, CancellationToken stoppingToken = default) + { + await connection.ConnectAsync(stoppingToken); + + BrowserMessage evaluateMessage = new("Runtime.evaluate"); + evaluateMessage.Parameters.Add("expression", $"window.{flagName} === true"); + evaluateMessage.Parameters.Add("returnByValue", true); + evaluateMessage.Parameters.Add("awaitPromise", true); + + bool isFlagSet = false; + + await connection.SendAsync( + evaluateMessage, + RuntimeEvaluateResponseSerializationContext + .Default + .BrowserResultResponseRuntimeEvaluateResponse, + evaluateResponse => + { + if (!evaluateResponse.Result.WasThrown && evaluateResponse.Result.Result?.Type == "boolean") + { + isFlagSet = evaluateResponse.Result.Result?.Value?.GetBoolean() ?? false; + } + }, + stoppingToken + ); + + return isFlagSet; + } + /// + /// Waits for a JavaScript flag to be set + /// + /// + /// + /// + /// + /// + internal async Task WaitForJsFlagAsync(string flagName, TimeSpan timeout, CancellationToken stoppingToken) + { + var stopwatch = Stopwatch.StartNew(); + + while (stopwatch.Elapsed < timeout) + { + bool flagSet = await CheckIfFlagIsSetAsync(flagName, stoppingToken); + if (flagSet) + { + return; + } + + await Task.Delay(500, stoppingToken); // Poll every 500ms + } + + return; + } + /// + /// Checks if a JavaScript flag exists + /// + /// + /// + /// + internal async Task DoesJsFlagExistAsync(string flagName, CancellationToken stoppingToken = default) + { + await connection.ConnectAsync(stoppingToken); + + // JavaScript Expression: Check if the flag exists in the window object + string jsCheck = $"typeof window.{flagName} !== 'undefined'"; + + BrowserMessage evaluateMessage = new("Runtime.evaluate"); + evaluateMessage.Parameters.Add("expression", jsCheck); + evaluateMessage.Parameters.Add("returnByValue", true); + evaluateMessage.Parameters.Add("awaitPromise", true); + + bool flagExists = false; + + await connection.SendAsync( + evaluateMessage, + RuntimeEvaluateResponseSerializationContext + .Default + .BrowserResultResponseRuntimeEvaluateResponse, + evaluateResponse => + { + // If JavaScript returns "true", it means the flag exists + if (evaluateResponse.Result.Result?.Type == "boolean") + { + flagExists = evaluateResponse.Result.Result?.Value?.GetBoolean() ?? false; + } + }, + stoppingToken + ); + + return flagExists; + } internal async ValueTask ConvertPageToPdf( PipeWriter pipeWriter, diff --git a/src/BlazorReports/Services/BrowserServices/Factories/BrowserFactory.cs b/src/BlazorReports/Services/BrowserServices/Factories/BrowserFactory.cs index 4472519..a9d2e3d 100644 --- a/src/BlazorReports/Services/BrowserServices/Factories/BrowserFactory.cs +++ b/src/BlazorReports/Services/BrowserServices/Factories/BrowserFactory.cs @@ -30,7 +30,7 @@ IBrowserPageFactory browserPageFactory public async ValueTask> CreateBrowser() { var browserOptions = options.Value.BrowserOptions; - + var javascriptSettings = options.Value.JavascriptSettings; var browserExecutableLocation = browserOptions.BrowserExecutableLocation is not null ? browserOptions.BrowserExecutableLocation.FullName : BrowserFinder.Find(browserOptions.Browser); @@ -93,6 +93,7 @@ public async ValueTask> CreateBrowser() devToolsActivePortDirectory, connection, browserOptions, + javascriptSettings, browserLogger, browserPageFactory ); diff --git a/src/BlazorReports/Services/BrowserServices/Responses/RuntimeEvaluateResponse.cs b/src/BlazorReports/Services/BrowserServices/Responses/RuntimeEvaluateResponse.cs new file mode 100644 index 0000000..e91ac47 --- /dev/null +++ b/src/BlazorReports/Services/BrowserServices/Responses/RuntimeEvaluateResponse.cs @@ -0,0 +1,42 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace BlazorReports.Services.BrowserServices.Responses; +/// +/// Response returned from the "Runtime.evaluate" DevTools command +/// +/// The evaluation result object if the command succeeded +/// Details about any exception thrown in JS +/// Whether an exception was thrown +public sealed record RuntimeEvaluateResponse( + [property: JsonPropertyName("result")] RuntimeEvaluateResult? Result, + [property: JsonPropertyName("exceptionDetails")] RuntimeEvaluateExceptionDetails? ExceptionDetails, + [property: JsonPropertyName("wasThrown")] bool WasThrown +); + +/// +/// Contains the result of a "Runtime.evaluate" call +/// +/// The type of the result (e.g., "string", "object", "undefined") +/// The raw JSON value (if returnByValue was used) +/// A textual description (especially for objects/functions) +public sealed record RuntimeEvaluateResult( + [property: JsonPropertyName("type")] string? Type, + [property: JsonPropertyName("value")] JsonElement? Value, + [property: JsonPropertyName("description")] string? Description +); + +/// +/// Contains exception details if JS threw an error +/// +/// The error message text +public sealed record RuntimeEvaluateExceptionDetails( + [property: JsonPropertyName("text")] string? Text +); + +/// +/// JSON serialization context for the "Runtime.evaluate" DevTools command +/// +[JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)] +[JsonSerializable(typeof(BrowserResultResponse))] +internal sealed partial class RuntimeEvaluateResponseSerializationContext : JsonSerializerContext; From f595196894372a02b1177ca0e972ae9d926b6a56 Mon Sep 17 00:00:00 2001 From: Andres Date: Thu, 20 Mar 2025 21:54:08 -0400 Subject: [PATCH 04/24] Enhance report management and JavaScript integration - Introduced a new `BlazorReport` class for managing report readiness. - Updated `HelloJavascriptData.js` to set report status and modify HTML content. - Renamed `JavascriptSettings` to `JavascriptInternalSettings` in `BlazorReportsOptions`. - Adjusted `BrowserFactory` and `ReportService` to utilize the new internal settings. - Improved overall structure and clarity of JavaScript interactions in the Blazor application. --- .../wwwroot/js/HelloJavascriptData.js | 32 +++++++------------ .../BlazorReportsTemplate.razor | 30 +++++++++++++++-- .../Models/BlazorReportsOptions.cs | 2 +- .../Factories/BrowserFactory.cs | 2 +- src/BlazorReports/Services/ReportService.cs | 4 +++ 5 files changed, 45 insertions(+), 25 deletions(-) diff --git a/examples/SimpleReportServer/wwwroot/js/HelloJavascriptData.js b/examples/SimpleReportServer/wwwroot/js/HelloJavascriptData.js index 9f6ec3e..f2b3d63 100644 --- a/examples/SimpleReportServer/wwwroot/js/HelloJavascriptData.js +++ b/examples/SimpleReportServer/wwwroot/js/HelloJavascriptData.js @@ -1,23 +1,15 @@ -window.reportIsReady = false; +// Set report status to "processing" +blazorReport.ready(); +// Get the element with id "HelloWorld" +var element = document.getElementById("HelloWorld"); -(function () { - var helloWorld = document.getElementById('HelloWorld'); - - if (!helloWorld) { - helloWorld = document.createElement('p'); // Create the element - helloWorld.id = 'HelloWorld'; - document.body.appendChild(helloWorld); // Append it to the body - } - - helloWorld.innerHTML = 'Hello World'; // Set text instantly -})(); - - - -//Wait 10 seconds and set reportIsReady to true - -setTimeout(function () { - window.reportIsReady = true; +// Set innerHTML to "Hello from JavaScript" +if (element) { + element.innerHTML = "Hello from JavaScript"; } - , 10000); + +// Wait 10 seconds, then mark report as ready +setTimeout(() => { + blazorReport.completed(); +}, 2_000); diff --git a/src/BlazorReports.Components/BlazorReportsTemplate.razor b/src/BlazorReports.Components/BlazorReportsTemplate.razor index bbca09c..a748cf9 100644 --- a/src/BlazorReports.Components/BlazorReportsTemplate.razor +++ b/src/BlazorReports.Components/BlazorReportsTemplate.razor @@ -2,7 +2,26 @@ + @@ -13,23 +32,22 @@ @((MarkupString)@script.Value) } - - - @code { /// /// The base styles to be applied to the component. /// [Parameter] public string BaseStyles { get; set; } = ""; + /// /// The type of the component to be rendered in the html body. /// [Parameter] public Type ChildComponentType { get; set; } = null!; + /// /// The parameters to be passed to the child component. /// @@ -41,4 +59,10 @@ /// [Parameter] public Dictionary Scripts { get; set; } = new Dictionary(); + + /// + /// The name of the JavaScript signal used to indicate when the report is ready. + /// + [Parameter] + public string ReportIsReadySignal { get; set; } = "reportIsReady"; } diff --git a/src/BlazorReports/Models/BlazorReportsOptions.cs b/src/BlazorReports/Models/BlazorReportsOptions.cs index dfc1ca3..57f60ab 100644 --- a/src/BlazorReports/Models/BlazorReportsOptions.cs +++ b/src/BlazorReports/Models/BlazorReportsOptions.cs @@ -27,5 +27,5 @@ public class BlazorReportsOptions /// /// Javascript api settings /// - public BlazorReportJavascriptSettings JavascriptSettings { get; set; } = new(); + public BlazorReportJavascriptSettings JavascriptInternalSettings { get; set; } = new(); } diff --git a/src/BlazorReports/Services/BrowserServices/Factories/BrowserFactory.cs b/src/BlazorReports/Services/BrowserServices/Factories/BrowserFactory.cs index a9d2e3d..a8c3a57 100644 --- a/src/BlazorReports/Services/BrowserServices/Factories/BrowserFactory.cs +++ b/src/BlazorReports/Services/BrowserServices/Factories/BrowserFactory.cs @@ -30,7 +30,7 @@ IBrowserPageFactory browserPageFactory public async ValueTask> CreateBrowser() { var browserOptions = options.Value.BrowserOptions; - var javascriptSettings = options.Value.JavascriptSettings; + var javascriptSettings = options.Value.JavascriptInternalSettings; var browserExecutableLocation = browserOptions.BrowserExecutableLocation is not null ? browserOptions.BrowserExecutableLocation.FullName : BrowserFinder.Find(browserOptions.Browser); diff --git a/src/BlazorReports/Services/ReportService.cs b/src/BlazorReports/Services/ReportService.cs index 477db72..4a5dc80 100644 --- a/src/BlazorReports/Services/ReportService.cs +++ b/src/BlazorReports/Services/ReportService.cs @@ -8,6 +8,7 @@ using Microsoft.AspNetCore.Components.Web; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using OneOf; using OneOf.Types; @@ -101,6 +102,8 @@ public async ValueTask< using var scope = serviceProvider.CreateScope(); var loggerFactory = scope.ServiceProvider.GetRequiredService(); var javascriptContainer = scope.ServiceProvider.GetRequiredService(); + var options = scope.ServiceProvider.GetRequiredService>(); + var javascriptInternalSettings = options.Value.JavascriptInternalSettings; var baseStyles = string.Empty; if (!string.IsNullOrEmpty(blazorReport.BaseStyles)) @@ -142,6 +145,7 @@ public async ValueTask< } + baseComponentParameters.Add("ReportIsReadySignal", javascriptInternalSettings.ReportIsReadySignal); baseComponentParameters.Add("ChildComponentType", blazorReport.Component); baseComponentParameters.Add("ChildComponentParameters", childComponentParameters); From e7e2fa78e48b9dbd5f583ab02e3dc591e134a745 Mon Sep 17 00:00:00 2001 From: Andres Date: Fri, 21 Mar 2025 12:21:41 -0400 Subject: [PATCH 05/24] Feat: Changing Blazor reports to await for a js signal rather than polling. Refactor report status handling and JavaScript integration Updated `HelloJavascriptData.js` to use `notReady()` and dynamic timeout for report readiness. Replaced `ready()` with `notReady()` in `BlazorReportsTemplate.razor` and added `waitForSignal` for improved asynchronous handling. Modified `Browser.cs` to utilize `waitForSignal` for waiting on JavaScript flags. Refactored `WaitForJsFlagAsync` in `BrowserPage.cs` to evaluate JavaScript directly, removing the flag name parameter and enhancing error handling with the new `EvaluateJavaScriptAsync` method. --- .../wwwroot/js/HelloJavascriptData.js | 13 ++--- .../BlazorReportsTemplate.razor | 22 +++++++- .../Services/BrowserServices/Browser.cs | 1 - .../Services/BrowserServices/BrowserPage.cs | 56 ++++++++++++++----- 4 files changed, 68 insertions(+), 24 deletions(-) diff --git a/examples/SimpleReportServer/wwwroot/js/HelloJavascriptData.js b/examples/SimpleReportServer/wwwroot/js/HelloJavascriptData.js index f2b3d63..71779bd 100644 --- a/examples/SimpleReportServer/wwwroot/js/HelloJavascriptData.js +++ b/examples/SimpleReportServer/wwwroot/js/HelloJavascriptData.js @@ -1,7 +1,5 @@ -// Set report status to "processing" -blazorReport.ready(); +blazorReport.notReady(); // Set initial state to "not ready" -// Get the element with id "HelloWorld" var element = document.getElementById("HelloWorld"); // Set innerHTML to "Hello from JavaScript" @@ -9,7 +7,8 @@ if (element) { element.innerHTML = "Hello from JavaScript"; } -// Wait 10 seconds, then mark report as ready -setTimeout(() => { - blazorReport.completed(); -}, 2_000); +// After 2 seconds, set the report as ready using async/await inside a self-invoking function +(async () => { + await new Promise(resolve => setTimeout(resolve, 4000)); + blazorReport.completed(); // Mark report as ready +})(); diff --git a/src/BlazorReports.Components/BlazorReportsTemplate.razor b/src/BlazorReports.Components/BlazorReportsTemplate.razor index a748cf9..0f92a74 100644 --- a/src/BlazorReports.Components/BlazorReportsTemplate.razor +++ b/src/BlazorReports.Components/BlazorReportsTemplate.razor @@ -10,7 +10,7 @@ this.ready(); // Set it to false initially } - ready() { + notReady() { window[this.signalName] = false; } @@ -21,6 +21,26 @@ // Create global instance with the provided signal name window.blazorReport = new BlazorReport("@ReportIsReadySignal"); + + // Function to wait for signal change + window.waitForSignal = (expectedValue = 'ready', timeoutMs = 5000, intervalMs = 50) => { + return new Promise((resolve, reject) => { + const start = Date.now(); + + const check = () => { + if (window.reportSignal === expectedValue) { + clearInterval(interval); + resolve('Signal received'); + } else if (Date.now() - start > timeoutMs) { + clearInterval(interval); + reject(new Error('Timeout waiting for signal')); + } + }; + + const interval = setInterval(check, intervalMs); + check(); // In case it's already ready + }); + }; diff --git a/src/BlazorReports/Services/BrowserServices/Browser.cs b/src/BlazorReports/Services/BrowserServices/Browser.cs index 2ff541c..2b79d84 100644 --- a/src/BlazorReports/Services/BrowserServices/Browser.cs +++ b/src/BlazorReports/Services/BrowserServices/Browser.cs @@ -102,7 +102,6 @@ out browserPage if (reportIsReadyFlagHasBeenSet) { await browserPage.WaitForJsFlagAsync( - reportIsReadyFlagName, javascriptSettings.ReportTimeout, cancellationToken ); diff --git a/src/BlazorReports/Services/BrowserServices/BrowserPage.cs b/src/BlazorReports/Services/BrowserServices/BrowserPage.cs index 0382fbd..209729c 100644 --- a/src/BlazorReports/Services/BrowserServices/BrowserPage.cs +++ b/src/BlazorReports/Services/BrowserServices/BrowserPage.cs @@ -107,28 +107,18 @@ await connection.SendAsync( /// /// Waits for a JavaScript flag to be set /// - /// /// /// /// - /// - internal async Task WaitForJsFlagAsync(string flagName, TimeSpan timeout, CancellationToken stoppingToken) + internal async Task WaitForJsFlagAsync(TimeSpan timeout, CancellationToken stoppingToken) { - var stopwatch = Stopwatch.StartNew(); - - while (stopwatch.Elapsed < timeout) - { - bool flagSet = await CheckIfFlagIsSetAsync(flagName, stoppingToken); - if (flagSet) - { - return; - } + string script = $"waitForSignal('ready', {timeout.TotalMilliseconds})"; - await Task.Delay(500, stoppingToken); // Poll every 500ms - } + var result = await EvaluateJavaScriptAsync(script, stoppingToken); - return; + return result == "Signal received"; } + /// /// Checks if a JavaScript flag exists /// @@ -167,6 +157,42 @@ await connection.SendAsync( return flagExists; } + /// + /// Evaluates JavaScript code + /// + /// + /// + /// + internal async Task EvaluateJavaScriptAsync(string script, CancellationToken stoppingToken) + { + var evaluateMessage = new BrowserMessage("Runtime.evaluate"); + evaluateMessage.Parameters.Add("expression", script); + evaluateMessage.Parameters.Add("returnByValue", true); + evaluateMessage.Parameters.Add("awaitPromise", true); // ✅ Ensures JS Promises resolve + + string? evaluatedValue = null; + + await connection.SendAsync( + evaluateMessage, + RuntimeEvaluateResponseSerializationContext.Default.BrowserResultResponseRuntimeEvaluateResponse, + evaluateResponse => + { + if (evaluateResponse.Result.WasThrown && evaluateResponse.Result.ExceptionDetails is not null) + { + // Handle JS error + return; + } + + if (evaluateResponse.Result.Result?.Type == "string") + { + evaluatedValue = evaluateResponse.Result.Result?.Value?.GetString(); + } + }, + stoppingToken + ); + + return evaluatedValue; + } internal async ValueTask ConvertPageToPdf( PipeWriter pipeWriter, From fb8f516c36d4ad3aad82e38b1bca61afa3b0492d Mon Sep 17 00:00:00 2001 From: Andres Date: Sat, 22 Mar 2025 12:26:21 -0400 Subject: [PATCH 06/24] Fix: changed signals to be transmited from javascript and awaited in javascript also added the CurrentReportJsOptions so people can set javascript options per report or globally. --- examples/SimpleReportServer/HelloReport.razor | 3 +- examples/SimpleReportServer/Program.cs | 14 +++- .../wwwroot/js/HelloJavascriptData.js | 10 +-- .../BlazorReportsTemplate.razor | 14 ++-- src/BlazorReports/Models/BlazorReport.cs | 5 ++ ...orReportCurrentReportJavascriptSettings.cs | 35 +++++++++ .../BlazorReportGlobalJavascriptSettings.cs | 27 +++++++ .../Models/BlazorReportRegistrationOptions.cs | 4 + .../Models/BlazorReportRegistry.cs | 4 + .../Models/BlazorReportsOptions.cs | 2 +- .../Services/BrowserServices/Browser.cs | 26 ++++--- .../Services/BrowserServices/BrowserPage.cs | 4 +- .../BrowserServices/BrowserService.cs | 10 ++- .../Factories/BrowserFactory.cs | 2 +- .../BrowserServices/IBrowserService.cs | 2 + src/BlazorReports/Services/IReportService.cs | 2 + src/BlazorReports/Services/ReportService.cs | 78 ++++++++++++------- 17 files changed, 183 insertions(+), 59 deletions(-) create mode 100644 src/BlazorReports/Models/BlazorReportCurrentReportJavascriptSettings.cs create mode 100644 src/BlazorReports/Models/BlazorReportGlobalJavascriptSettings.cs diff --git a/examples/SimpleReportServer/HelloReport.razor b/examples/SimpleReportServer/HelloReport.razor index a96d3be..4ba2d7f 100644 --- a/examples/SimpleReportServer/HelloReport.razor +++ b/examples/SimpleReportServer/HelloReport.razor @@ -1,5 +1,6 @@

Hello @Data.Name

-

No data was found

+

+ @code { [Parameter] public required HelloReportData Data { get; set; } diff --git a/examples/SimpleReportServer/Program.cs b/examples/SimpleReportServer/Program.cs index d7aefb9..2052c38 100644 --- a/examples/SimpleReportServer/Program.cs +++ b/examples/SimpleReportServer/Program.cs @@ -7,7 +7,11 @@ builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); -builder.Services.AddBlazorReports(); +builder.Services.AddBlazorReports(options => +{ + options.GlobalJavascriptSettings.WaitForCompletedSignalTimeout = TimeSpan.FromSeconds(3); + options.GlobalJavascriptSettings.WaitForJavascriptCompletedSignal = false; +}); var app = builder.Build(); @@ -19,7 +23,13 @@ var reportsGroup = app.MapGroup("reports"); -reportsGroup.MapBlazorReport(); +reportsGroup.MapBlazorReport(opts => +{ + opts.ReportName = "HelloReportPdf"; + opts.OutputFormat = ReportOutputFormat.Pdf; + opts.JavascriptSettings.WaitForJavascriptCompletedSignal = true; + opts.JavascriptSettings.WaitForCompletedSignalTimeout = TimeSpan.FromSeconds(5); +}); reportsGroup.MapBlazorReport(opts => { opts.ReportName = "HelloReportHtml"; diff --git a/examples/SimpleReportServer/wwwroot/js/HelloJavascriptData.js b/examples/SimpleReportServer/wwwroot/js/HelloJavascriptData.js index 71779bd..0f2a417 100644 --- a/examples/SimpleReportServer/wwwroot/js/HelloJavascriptData.js +++ b/examples/SimpleReportServer/wwwroot/js/HelloJavascriptData.js @@ -1,4 +1,3 @@ -blazorReport.notReady(); // Set initial state to "not ready" var element = document.getElementById("HelloWorld"); @@ -7,8 +6,9 @@ if (element) { element.innerHTML = "Hello from JavaScript"; } -// After 2 seconds, set the report as ready using async/await inside a self-invoking function -(async () => { - await new Promise(resolve => setTimeout(resolve, 4000)); +//after 5 seconds complete the report with blazorReport.completed(); // Mark report as ready + +setTimeout(() => { blazorReport.completed(); // Mark report as ready -})(); +}, 5_000) + diff --git a/src/BlazorReports.Components/BlazorReportsTemplate.razor b/src/BlazorReports.Components/BlazorReportsTemplate.razor index 0f92a74..4c524ca 100644 --- a/src/BlazorReports.Components/BlazorReportsTemplate.razor +++ b/src/BlazorReports.Components/BlazorReportsTemplate.razor @@ -7,15 +7,14 @@ class BlazorReport { constructor(signalName) { this.signalName = signalName; - this.ready(); // Set it to false initially } - + notReady() { - window[this.signalName] = false; + window[this.signalName] = "not-ready"; } completed() { - window[this.signalName] = true; + window[this.signalName] = "ready"; } } @@ -23,12 +22,13 @@ window.blazorReport = new BlazorReport("@ReportIsReadySignal"); // Function to wait for signal change - window.waitForSignal = (expectedValue = 'ready', timeoutMs = 5000, intervalMs = 50) => { + window.waitForSignal = (timeoutMs = 5000, intervalMs = 50) => { + var expectedValue = 'ready' return new Promise((resolve, reject) => { const start = Date.now(); const check = () => { - if (window.reportSignal === expectedValue) { + if (window["@ReportIsReadySignal"] === expectedValue) { clearInterval(interval); resolve('Signal received'); } else if (Date.now() - start > timeoutMs) { @@ -85,4 +85,6 @@ /// [Parameter] public string ReportIsReadySignal { get; set; } = "reportIsReady"; + + } diff --git a/src/BlazorReports/Models/BlazorReport.cs b/src/BlazorReports/Models/BlazorReport.cs index 5359173..caaaeb6 100644 --- a/src/BlazorReports/Models/BlazorReport.cs +++ b/src/BlazorReports/Models/BlazorReport.cs @@ -44,4 +44,9 @@ public class BlazorReport /// The page settings to use for the report. /// public BlazorReportsPageSettings? PageSettings { get; set; } + + /// + /// The current report javascript settings. + /// + public required BlazorReportCurrentReportJavascriptSettings CurrentReportJavascriptSettings { get; set; } } diff --git a/src/BlazorReports/Models/BlazorReportCurrentReportJavascriptSettings.cs b/src/BlazorReports/Models/BlazorReportCurrentReportJavascriptSettings.cs new file mode 100644 index 0000000..302c5c2 --- /dev/null +++ b/src/BlazorReports/Models/BlazorReportCurrentReportJavascriptSettings.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BlazorReports.Models; +/// +/// Settings for the internal javascript api +/// +public class BlazorReportCurrentReportJavascriptSettings +{ + /// + /// The signal that the report is ready + /// + public string ReportIsReadySignal { get; set; } = default!; + /// + /// Decides if the report should wait for the complete signal in the javascript + /// + public bool WaitForJavascriptCompletedSignal { get; set; } + /// + /// The amount of time a reports javascript can take until it is considered to have timed out + /// + public TimeSpan? WaitForCompletedSignalTimeout { get; set; } + + + /// + /// The default settings for the current report javascript settings + /// + public static BlazorReportCurrentReportJavascriptSettings Default => new BlazorReportCurrentReportJavascriptSettings + { + WaitForJavascriptCompletedSignal = false, + WaitForCompletedSignalTimeout = TimeSpan.FromSeconds(3) + }; +} diff --git a/src/BlazorReports/Models/BlazorReportGlobalJavascriptSettings.cs b/src/BlazorReports/Models/BlazorReportGlobalJavascriptSettings.cs new file mode 100644 index 0000000..c1cb4ce --- /dev/null +++ b/src/BlazorReports/Models/BlazorReportGlobalJavascriptSettings.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BlazorReports.Models; +/// +/// +/// +public class BlazorReportGlobalJavascriptSettings +{ + /// + /// The signal that the report is ready + /// + public string ReportIsReadySignal { get; set; } = "reportIsReady"; + /// + /// Decides if the report should wait for the complete signal in the javascript. + /// (Default: false) + /// + public bool WaitForJavascriptCompletedSignal { get; set; } + /// + /// The amount of time a reports javascript can take until it is considered to have timed out + /// (Default: null) + /// + public TimeSpan WaitForCompletedSignalTimeout { get; set; } = TimeSpan.FromSeconds(3); +} diff --git a/src/BlazorReports/Models/BlazorReportRegistrationOptions.cs b/src/BlazorReports/Models/BlazorReportRegistrationOptions.cs index 726416b..08fbae4 100644 --- a/src/BlazorReports/Models/BlazorReportRegistrationOptions.cs +++ b/src/BlazorReports/Models/BlazorReportRegistrationOptions.cs @@ -29,4 +29,8 @@ public class BlazorReportRegistrationOptions /// Settings for generating a PDF /// public BlazorReportsPageSettings PageSettings { get; set; } = new(); + /// + /// Javascript api settings + /// + public BlazorReportCurrentReportJavascriptSettings JavascriptSettings { get; set; } = new(); } diff --git a/src/BlazorReports/Models/BlazorReportRegistry.cs b/src/BlazorReports/Models/BlazorReportRegistry.cs index fec0360..7b72451 100644 --- a/src/BlazorReports/Models/BlazorReportRegistry.cs +++ b/src/BlazorReports/Models/BlazorReportRegistry.cs @@ -85,6 +85,8 @@ public BlazorReport AddReport(BlazorReportRegistrationOptions? options = null Component = typeof(T), Data = null, PageSettings = options?.PageSettings, + CurrentReportJavascriptSettings = + options?.JavascriptSettings! ?? BlazorReportCurrentReportJavascriptSettings.Default, }; if (!string.IsNullOrEmpty(options?.BaseStylesPath)) { @@ -137,6 +139,8 @@ public BlazorReport AddReport(BlazorReportRegistrationOptions? options = Component = typeof(T), Data = typeof(TD), PageSettings = options?.PageSettings, + CurrentReportJavascriptSettings = + options?.JavascriptSettings ?? BlazorReportCurrentReportJavascriptSettings.Default, }; if (!string.IsNullOrEmpty(options?.BaseStylesPath)) { diff --git a/src/BlazorReports/Models/BlazorReportsOptions.cs b/src/BlazorReports/Models/BlazorReportsOptions.cs index 57f60ab..9132845 100644 --- a/src/BlazorReports/Models/BlazorReportsOptions.cs +++ b/src/BlazorReports/Models/BlazorReportsOptions.cs @@ -27,5 +27,5 @@ public class BlazorReportsOptions /// /// Javascript api settings /// - public BlazorReportJavascriptSettings JavascriptInternalSettings { get; set; } = new(); + public BlazorReportGlobalJavascriptSettings GlobalJavascriptSettings { get; set; } = new(); } diff --git a/src/BlazorReports/Services/BrowserServices/Browser.cs b/src/BlazorReports/Services/BrowserServices/Browser.cs index 2b79d84..b7ca4fc 100644 --- a/src/BlazorReports/Services/BrowserServices/Browser.cs +++ b/src/BlazorReports/Services/BrowserServices/Browser.cs @@ -21,7 +21,7 @@ internal sealed class Browser( DirectoryInfo dataDirectory, Connection connection, BlazorReportsBrowserOptions browserOptions, - BlazorReportJavascriptSettings javascriptSettings, + BlazorReportGlobalJavascriptSettings globalJavascriptSettings, ILogger logger, IBrowserPageFactory browserPageFactory ) : IAsyncDisposable @@ -36,6 +36,7 @@ public async ValueTask< PipeWriter pipeWriter, string html, BlazorReportsPageSettings pageSettings, + BlazorReportCurrentReportJavascriptSettings currentReportJavascriptSettings, CancellationToken cancellationToken ) { @@ -92,19 +93,20 @@ out browserPage try { - var reportIsReadyFlagName = javascriptSettings.ReportIsReadySignal; - await browserPage.DisplayHtml(html, cancellationToken); - var reportIsReadyFlagHasBeenSet = await browserPage.DoesJsFlagExistAsync( - reportIsReadyFlagName, - cancellationToken - ); + var shouldReportAwaitJavascript = + currentReportJavascriptSettings.WaitForJavascriptCompletedSignal + || globalJavascriptSettings.WaitForJavascriptCompletedSignal; - if (reportIsReadyFlagHasBeenSet) + await browserPage.DisplayHtml(html, cancellationToken); + if (shouldReportAwaitJavascript) { - await browserPage.WaitForJsFlagAsync( - javascriptSettings.ReportTimeout, - cancellationToken - ); + TimeSpan globalTimeout = globalJavascriptSettings.WaitForCompletedSignalTimeout; + TimeSpan? currentReportTimeout = + currentReportJavascriptSettings.WaitForCompletedSignalTimeout; + + TimeSpan timeout = currentReportTimeout ?? globalTimeout; + + await browserPage.WaitForJsFlagAsync(timeout, cancellationToken); } await browserPage.ConvertPageToPdf(pipeWriter, pageSettings, cancellationToken); diff --git a/src/BlazorReports/Services/BrowserServices/BrowserPage.cs b/src/BlazorReports/Services/BrowserServices/BrowserPage.cs index 209729c..e151ef9 100644 --- a/src/BlazorReports/Services/BrowserServices/BrowserPage.cs +++ b/src/BlazorReports/Services/BrowserServices/BrowserPage.cs @@ -112,7 +112,7 @@ await connection.SendAsync( /// internal async Task WaitForJsFlagAsync(TimeSpan timeout, CancellationToken stoppingToken) { - string script = $"waitForSignal('ready', {timeout.TotalMilliseconds})"; + string script = $"waitForSignal({timeout.TotalMilliseconds})"; var result = await EvaluateJavaScriptAsync(script, stoppingToken); @@ -168,7 +168,7 @@ await connection.SendAsync( var evaluateMessage = new BrowserMessage("Runtime.evaluate"); evaluateMessage.Parameters.Add("expression", script); evaluateMessage.Parameters.Add("returnByValue", true); - evaluateMessage.Parameters.Add("awaitPromise", true); // ✅ Ensures JS Promises resolve + evaluateMessage.Parameters.Add("awaitPromise", true); string? evaluatedValue = null; diff --git a/src/BlazorReports/Services/BrowserServices/BrowserService.cs b/src/BlazorReports/Services/BrowserServices/BrowserService.cs index 39f3ade..8e49e37 100644 --- a/src/BlazorReports/Services/BrowserServices/BrowserService.cs +++ b/src/BlazorReports/Services/BrowserServices/BrowserService.cs @@ -48,6 +48,7 @@ IBrowserFactory browserFactory /// The pipe writer to write the report to /// The HTML to use in the report /// The page settings to use in the report + /// The current report javascript settings /// The cancellation token /// The result of the operation public async ValueTask< @@ -56,6 +57,7 @@ public async ValueTask< PipeWriter pipeWriter, string html, BlazorReportsPageSettings pageSettings, + BlazorReportCurrentReportJavascriptSettings currentReportJavascriptSettings, CancellationToken cancellationToken ) { @@ -80,7 +82,13 @@ out var browser return browserStartProblem; } - return await browser.GenerateReport(pipeWriter, html, pageSettings, cancellationToken); + return await browser.GenerateReport( + pipeWriter, + html, + pageSettings, + currentReportJavascriptSettings, + cancellationToken + ); } /// diff --git a/src/BlazorReports/Services/BrowserServices/Factories/BrowserFactory.cs b/src/BlazorReports/Services/BrowserServices/Factories/BrowserFactory.cs index a8c3a57..76ea203 100644 --- a/src/BlazorReports/Services/BrowserServices/Factories/BrowserFactory.cs +++ b/src/BlazorReports/Services/BrowserServices/Factories/BrowserFactory.cs @@ -30,7 +30,7 @@ IBrowserPageFactory browserPageFactory public async ValueTask> CreateBrowser() { var browserOptions = options.Value.BrowserOptions; - var javascriptSettings = options.Value.JavascriptInternalSettings; + var javascriptSettings = options.Value.GlobalJavascriptSettings; var browserExecutableLocation = browserOptions.BrowserExecutableLocation is not null ? browserOptions.BrowserExecutableLocation.FullName : BrowserFinder.Find(browserOptions.Browser); diff --git a/src/BlazorReports/Services/BrowserServices/IBrowserService.cs b/src/BlazorReports/Services/BrowserServices/IBrowserService.cs index 6ec10f6..7ce7e77 100644 --- a/src/BlazorReports/Services/BrowserServices/IBrowserService.cs +++ b/src/BlazorReports/Services/BrowserServices/IBrowserService.cs @@ -17,6 +17,7 @@ public interface IBrowserService /// The pipe writer to write the report to /// The HTML to use in the report /// The page settings to use in the report + /// The current report javascript settings /// The cancellation token /// The result of the operation ValueTask< @@ -25,6 +26,7 @@ public interface IBrowserService PipeWriter pipeWriter, string html, BlazorReportsPageSettings pageSettings, + BlazorReportCurrentReportJavascriptSettings currentReportJavascriptSettings, CancellationToken cancellationToken ); } diff --git a/src/BlazorReports/Services/IReportService.cs b/src/BlazorReports/Services/IReportService.cs index 3f8d66f..9e7184e 100644 --- a/src/BlazorReports/Services/IReportService.cs +++ b/src/BlazorReports/Services/IReportService.cs @@ -17,6 +17,7 @@ public interface IReportService /// /// The pipe writer to write the report to /// The data to use in the report + /// The report to generate /// The cancellation token /// The component to use in the report /// The type of data to use in the report @@ -25,6 +26,7 @@ public interface IReportService OneOf > GenerateReport( PipeWriter pipeWriter, + BlazorReport report, TD data, CancellationToken cancellationToken = default ) diff --git a/src/BlazorReports/Services/ReportService.cs b/src/BlazorReports/Services/ReportService.cs index 4a5dc80..9208047 100644 --- a/src/BlazorReports/Services/ReportService.cs +++ b/src/BlazorReports/Services/ReportService.cs @@ -33,6 +33,7 @@ IBrowserService browserService /// Generates a report using the specified component and data /// /// The pipe writer to write the report to + /// The report to generate /// The data to use in the report /// The cancellation token /// The component to use in the report @@ -42,6 +43,7 @@ public async ValueTask< OneOf > GenerateReport( PipeWriter pipeWriter, + BlazorReport report, TD data, CancellationToken cancellationToken = default ) @@ -76,6 +78,7 @@ public async ValueTask< pipeWriter, html, reportRegistry.DefaultPageSettings, + report.CurrentReportJavascriptSettings, cancellationToken ); } @@ -103,7 +106,7 @@ public async ValueTask< var loggerFactory = scope.ServiceProvider.GetRequiredService(); var javascriptContainer = scope.ServiceProvider.GetRequiredService(); var options = scope.ServiceProvider.GetRequiredService>(); - var javascriptInternalSettings = options.Value.JavascriptInternalSettings; + var javascriptInternalSettings = options.Value.GlobalJavascriptSettings; var baseStyles = string.Empty; if (!string.IsNullOrEmpty(blazorReport.BaseStyles)) @@ -143,38 +146,57 @@ public async ValueTask< { baseComponentParameters.Add("Scripts", javascriptContainer.Scripts); } - - - baseComponentParameters.Add("ReportIsReadySignal", javascriptInternalSettings.ReportIsReadySignal); - baseComponentParameters.Add("ChildComponentType", blazorReport.Component); - baseComponentParameters.Add("ChildComponentParameters", childComponentParameters); - - await using HtmlRenderer htmlRenderer = new(scope.ServiceProvider, loggerFactory); - - if (blazorReport.OutputFormat == ReportOutputFormat.Pdf) + //Checks if the report has a custom signal if not use the global one + if (blazorReport.CurrentReportJavascriptSettings.ReportIsReadySignal is not null) { - var html = await htmlRenderer.Dispatcher.InvokeAsync(async () => - { - ParameterView parameters = ParameterView.FromDictionary(baseComponentParameters); - var output = await htmlRenderer.RenderComponentAsync(parameters); - return output.ToHtmlString(); - }); - - var pageSettings = blazorReport.PageSettings ?? reportRegistry.DefaultPageSettings; - - return await browserService.GenerateReport(pipeWriter, html, pageSettings, cancellationToken); + baseComponentParameters.Add( + "ReportIsReadySignal", + blazorReport.CurrentReportJavascriptSettings.ReportIsReadySignal + ); } else { - var html = await htmlRenderer.Dispatcher.InvokeAsync(async () => - { - ParameterView parameters = ParameterView.FromDictionary(baseComponentParameters); - var output = await htmlRenderer.RenderComponentAsync(parameters); - return output.ToHtmlString(); - }); + baseComponentParameters.Add( + "ReportIsReadySignal", + javascriptInternalSettings.ReportIsReadySignal + ); + + baseComponentParameters.Add("ChildComponentType", blazorReport.Component); + baseComponentParameters.Add("ChildComponentParameters", childComponentParameters); - await pipeWriter.WriteAsync(System.Text.Encoding.UTF8.GetBytes(html), cancellationToken); - return new Success(); + await using HtmlRenderer htmlRenderer = new(scope.ServiceProvider, loggerFactory); + + if (blazorReport.OutputFormat == ReportOutputFormat.Pdf) + { + var html = await htmlRenderer.Dispatcher.InvokeAsync(async () => + { + ParameterView parameters = ParameterView.FromDictionary(baseComponentParameters); + var output = await htmlRenderer.RenderComponentAsync(parameters); + return output.ToHtmlString(); + }); + + var pageSettings = blazorReport.PageSettings ?? reportRegistry.DefaultPageSettings; + + return await browserService.GenerateReport( + pipeWriter, + html, + pageSettings, + blazorReport.CurrentReportJavascriptSettings, + cancellationToken + ); + } + else + { + var html = await htmlRenderer.Dispatcher.InvokeAsync(async () => + { + ParameterView parameters = ParameterView.FromDictionary(baseComponentParameters); + var output = await htmlRenderer.RenderComponentAsync(parameters); + return output.ToHtmlString(); + }); + + await pipeWriter.WriteAsync(System.Text.Encoding.UTF8.GetBytes(html), cancellationToken); + return new Success(); + } } } From 3509cb804dece054dcf27a90d42f941cd43f0ba3 Mon Sep 17 00:00:00 2001 From: Andres Date: Sat, 22 Mar 2025 12:31:58 -0400 Subject: [PATCH 07/24] fix: Included an extra bracket by mistake. --- src/BlazorReports/Services/ReportService.cs | 70 ++++++++++----------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/src/BlazorReports/Services/ReportService.cs b/src/BlazorReports/Services/ReportService.cs index 9208047..91c41be 100644 --- a/src/BlazorReports/Services/ReportService.cs +++ b/src/BlazorReports/Services/ReportService.cs @@ -157,46 +157,46 @@ public async ValueTask< else { baseComponentParameters.Add( - "ReportIsReadySignal", - javascriptInternalSettings.ReportIsReadySignal - ); + "ReportIsReadySignal", + javascriptInternalSettings.ReportIsReadySignal + ); + } - baseComponentParameters.Add("ChildComponentType", blazorReport.Component); - baseComponentParameters.Add("ChildComponentParameters", childComponentParameters); + baseComponentParameters.Add("ChildComponentType", blazorReport.Component); + baseComponentParameters.Add("ChildComponentParameters", childComponentParameters); - await using HtmlRenderer htmlRenderer = new(scope.ServiceProvider, loggerFactory); + await using HtmlRenderer htmlRenderer = new(scope.ServiceProvider, loggerFactory); - if (blazorReport.OutputFormat == ReportOutputFormat.Pdf) + if (blazorReport.OutputFormat == ReportOutputFormat.Pdf) + { + var html = await htmlRenderer.Dispatcher.InvokeAsync(async () => { - var html = await htmlRenderer.Dispatcher.InvokeAsync(async () => - { - ParameterView parameters = ParameterView.FromDictionary(baseComponentParameters); - var output = await htmlRenderer.RenderComponentAsync(parameters); - return output.ToHtmlString(); - }); - - var pageSettings = blazorReport.PageSettings ?? reportRegistry.DefaultPageSettings; - - return await browserService.GenerateReport( - pipeWriter, - html, - pageSettings, - blazorReport.CurrentReportJavascriptSettings, - cancellationToken - ); - } - else + ParameterView parameters = ParameterView.FromDictionary(baseComponentParameters); + var output = await htmlRenderer.RenderComponentAsync(parameters); + return output.ToHtmlString(); + }); + + var pageSettings = blazorReport.PageSettings ?? reportRegistry.DefaultPageSettings; + + return await browserService.GenerateReport( + pipeWriter, + html, + pageSettings, + blazorReport.CurrentReportJavascriptSettings, + cancellationToken + ); + } + else + { + var html = await htmlRenderer.Dispatcher.InvokeAsync(async () => { - var html = await htmlRenderer.Dispatcher.InvokeAsync(async () => - { - ParameterView parameters = ParameterView.FromDictionary(baseComponentParameters); - var output = await htmlRenderer.RenderComponentAsync(parameters); - return output.ToHtmlString(); - }); - - await pipeWriter.WriteAsync(System.Text.Encoding.UTF8.GetBytes(html), cancellationToken); - return new Success(); - } + ParameterView parameters = ParameterView.FromDictionary(baseComponentParameters); + var output = await htmlRenderer.RenderComponentAsync(parameters); + return output.ToHtmlString(); + }); + + await pipeWriter.WriteAsync(System.Text.Encoding.UTF8.GetBytes(html), cancellationToken); + return new Success(); } } From e8337f4ef3858274dd9200ef94664ea0c34f2c63 Mon Sep 17 00:00:00 2001 From: Andres Date: Sat, 22 Mar 2025 15:48:51 -0400 Subject: [PATCH 08/24] Enhance report generation and JavaScript timeout handling - Updated `HelloReport.razor` to display greeting and default message. - Added `SimpleJsTimeoutReport` to `Program.cs` with specific options. - Modified `SimpleJsTimeoutReport.razor` to include an example of JavaScript update and timeout signaling. - Introduced `SimpleJsTimeoutReportData` for timeout management. - Enhanced error handling in `ReportExtensions.cs` to include 408 status code for timeouts. - Implemented `JavascriptTimedoutProblem` in `Browser.cs` for timeout issues. - Improved JavaScript flag handling in `BrowserPage.cs` with better documentation. - Updated `BrowserService.cs` and `IBrowserService.cs` to incorporate new timeout problem in report generation. - Created `JavascriptTimedoutProblem.cs` to define the new timeout problem struct. - Reflected changes in report generation methods in `ReportService.cs`. --- examples/SimpleReportServer/HelloReport.razor | 3 +- examples/SimpleReportServer/Program.cs | 4 +- .../Reports/SimpleJsTimeoutReport.razor | 22 +++++ .../Reports/SimpleJsTimeoutReportData.cs | 6 ++ .../Extensions/ReportExtensions.cs | 8 +- .../Services/BrowserServices/Browser.cs | 14 ++- .../Services/BrowserServices/BrowserPage.cs | 98 +++++++++++-------- .../BrowserServices/BrowserService.cs | 8 +- .../BrowserServices/IBrowserService.cs | 8 +- .../Problems/JavascriptTimedoutProblem.cs | 11 +++ src/BlazorReports/Services/IReportService.cs | 24 ++++- src/BlazorReports/Services/ReportService.cs | 24 ++++- 12 files changed, 175 insertions(+), 55 deletions(-) create mode 100644 examples/SimpleReportServer/Reports/SimpleJsTimeoutReport.razor create mode 100644 examples/SimpleReportServer/Reports/SimpleJsTimeoutReportData.cs create mode 100644 src/BlazorReports/Services/BrowserServices/Problems/JavascriptTimedoutProblem.cs diff --git a/examples/SimpleReportServer/HelloReport.razor b/examples/SimpleReportServer/HelloReport.razor index 4ba2d7f..8275db2 100644 --- a/examples/SimpleReportServer/HelloReport.razor +++ b/examples/SimpleReportServer/HelloReport.razor @@ -1,5 +1,6 @@ +

Hello @Data.Name

-

+

No data

@code { [Parameter] diff --git a/examples/SimpleReportServer/Program.cs b/examples/SimpleReportServer/Program.cs index 2052c38..a897f73 100644 --- a/examples/SimpleReportServer/Program.cs +++ b/examples/SimpleReportServer/Program.cs @@ -2,6 +2,7 @@ using BlazorReports.Models; using ExampleTemplates.Reports; using SimpleReportServer; +using SimpleReportServer.Reports; var builder = WebApplication.CreateSlimBuilder(args); @@ -23,13 +24,14 @@ var reportsGroup = app.MapGroup("reports"); -reportsGroup.MapBlazorReport(opts => +reportsGroup.MapBlazorReport(opts => { opts.ReportName = "HelloReportPdf"; opts.OutputFormat = ReportOutputFormat.Pdf; opts.JavascriptSettings.WaitForJavascriptCompletedSignal = true; opts.JavascriptSettings.WaitForCompletedSignalTimeout = TimeSpan.FromSeconds(5); }); +reportsGroup.MapBlazorReport(); reportsGroup.MapBlazorReport(opts => { opts.ReportName = "HelloReportHtml"; diff --git a/examples/SimpleReportServer/Reports/SimpleJsTimeoutReport.razor b/examples/SimpleReportServer/Reports/SimpleJsTimeoutReport.razor new file mode 100644 index 0000000..4d0f9a0 --- /dev/null +++ b/examples/SimpleReportServer/Reports/SimpleJsTimeoutReport.razor @@ -0,0 +1,22 @@ + +

+ +@code { + [Parameter] + public required SimpleJsTimeoutReportData Data { get; set; } + +} diff --git a/examples/SimpleReportServer/Reports/SimpleJsTimeoutReportData.cs b/examples/SimpleReportServer/Reports/SimpleJsTimeoutReportData.cs new file mode 100644 index 0000000..9360880 --- /dev/null +++ b/examples/SimpleReportServer/Reports/SimpleJsTimeoutReportData.cs @@ -0,0 +1,6 @@ +namespace SimpleReportServer.Reports; + +public record SimpleJsTimeoutReportData(int TimeoutInSeconds) +{ + public TimeSpan TimeSpan => TimeSpan.FromSeconds(TimeoutInSeconds); +}; diff --git a/src/BlazorReports/Extensions/ReportExtensions.cs b/src/BlazorReports/Extensions/ReportExtensions.cs index 3d360a6..e82ac78 100644 --- a/src/BlazorReports/Extensions/ReportExtensions.cs +++ b/src/BlazorReports/Extensions/ReportExtensions.cs @@ -110,7 +110,8 @@ CancellationToken token _ => (int?)null, _ => StatusCodes.Status503ServiceUnavailable, _ => StatusCodes.Status499ClientClosedRequest, - _ => StatusCodes.Status500InternalServerError + _ => StatusCodes.Status500InternalServerError, + _ => StatusCodes.Status408RequestTimeout ); if (errorStatusCode is not null) @@ -121,6 +122,7 @@ CancellationToken token } ) .Produces(200, blazorReport.GetContentType()) + .Produces(StatusCodes.Status408RequestTimeout) .Produces(StatusCodes.Status503ServiceUnavailable); } @@ -174,7 +176,8 @@ CancellationToken token _ => (int?)null, _ => StatusCodes.Status503ServiceUnavailable, _ => StatusCodes.Status499ClientClosedRequest, - _ => StatusCodes.Status500InternalServerError + _ => StatusCodes.Status500InternalServerError, + _ => StatusCodes.Status408RequestTimeout ); if (errorStatusCode is not null) @@ -185,6 +188,7 @@ CancellationToken token } ) .Produces(200, blazorReport.GetContentType()) + .Produces(StatusCodes.Status408RequestTimeout) .Produces(StatusCodes.Status503ServiceUnavailable); } diff --git a/src/BlazorReports/Services/BrowserServices/Browser.cs b/src/BlazorReports/Services/BrowserServices/Browser.cs index b7ca4fc..6bed8dc 100644 --- a/src/BlazorReports/Services/BrowserServices/Browser.cs +++ b/src/BlazorReports/Services/BrowserServices/Browser.cs @@ -31,7 +31,13 @@ IBrowserPageFactory browserPageFactory private readonly SemaphoreSlim _poolLock = new(1, 1); public async ValueTask< - OneOf + OneOf< + Success, + ServerBusyProblem, + OperationCancelledProblem, + BrowserProblem, + JavascriptTimedoutProblem + > > GenerateReport( PipeWriter pipeWriter, string html, @@ -106,7 +112,11 @@ out browserPage TimeSpan timeout = currentReportTimeout ?? globalTimeout; - await browserPage.WaitForJsFlagAsync(timeout, cancellationToken); + var didNotHitTimeOut = await browserPage.WaitForJsFlagAsync(timeout, cancellationToken); + if (!didNotHitTimeOut) + { + return new JavascriptTimedoutProblem(); + } } await browserPage.ConvertPageToPdf(pipeWriter, pageSettings, cancellationToken); diff --git a/src/BlazorReports/Services/BrowserServices/BrowserPage.cs b/src/BlazorReports/Services/BrowserServices/BrowserPage.cs index e151ef9..eb1ecbd 100644 --- a/src/BlazorReports/Services/BrowserServices/BrowserPage.cs +++ b/src/BlazorReports/Services/BrowserServices/BrowserPage.cs @@ -70,13 +70,17 @@ await connection.SendAsync( stoppingToken ); } + /// /// Checks if a JavaScript flag is set /// /// Flag to be checked /// cancellation token /// Returns the flag current value - internal async Task CheckIfFlagIsSetAsync(string flagName, CancellationToken stoppingToken = default) + internal async Task CheckIfFlagIsSetAsync( + string flagName, + CancellationToken stoppingToken = default + ) { await connection.ConnectAsync(stoppingToken); @@ -88,22 +92,23 @@ internal async Task CheckIfFlagIsSetAsync(string flagName, CancellationTok bool isFlagSet = false; await connection.SendAsync( - evaluateMessage, - RuntimeEvaluateResponseSerializationContext - .Default - .BrowserResultResponseRuntimeEvaluateResponse, - evaluateResponse => + evaluateMessage, + RuntimeEvaluateResponseSerializationContext + .Default + .BrowserResultResponseRuntimeEvaluateResponse, + evaluateResponse => + { + if (!evaluateResponse.Result.WasThrown && evaluateResponse.Result.Result?.Type == "boolean") { - if (!evaluateResponse.Result.WasThrown && evaluateResponse.Result.Result?.Type == "boolean") - { - isFlagSet = evaluateResponse.Result.Result?.Value?.GetBoolean() ?? false; - } - }, - stoppingToken + isFlagSet = evaluateResponse.Result.Result?.Value?.GetBoolean() ?? false; + } + }, + stoppingToken ); return isFlagSet; } + /// /// Waits for a JavaScript flag to be set /// @@ -125,7 +130,10 @@ internal async Task WaitForJsFlagAsync(TimeSpan timeout, CancellationToken /// /// /// - internal async Task DoesJsFlagExistAsync(string flagName, CancellationToken stoppingToken = default) + internal async Task DoesJsFlagExistAsync( + string flagName, + CancellationToken stoppingToken = default + ) { await connection.ConnectAsync(stoppingToken); @@ -140,55 +148,63 @@ internal async Task DoesJsFlagExistAsync(string flagName, CancellationToke bool flagExists = false; await connection.SendAsync( - evaluateMessage, - RuntimeEvaluateResponseSerializationContext - .Default - .BrowserResultResponseRuntimeEvaluateResponse, - evaluateResponse => + evaluateMessage, + RuntimeEvaluateResponseSerializationContext + .Default + .BrowserResultResponseRuntimeEvaluateResponse, + evaluateResponse => + { + // If JavaScript returns "true", it means the flag exists + if (evaluateResponse.Result.Result?.Type == "boolean") { - // If JavaScript returns "true", it means the flag exists - if (evaluateResponse.Result.Result?.Type == "boolean") - { - flagExists = evaluateResponse.Result.Result?.Value?.GetBoolean() ?? false; - } - }, - stoppingToken + flagExists = evaluateResponse.Result.Result?.Value?.GetBoolean() ?? false; + } + }, + stoppingToken ); return flagExists; } + /// /// Evaluates JavaScript code /// /// /// /// - internal async Task EvaluateJavaScriptAsync(string script, CancellationToken stoppingToken) + internal async Task EvaluateJavaScriptAsync( + string script, + CancellationToken stoppingToken + ) { var evaluateMessage = new BrowserMessage("Runtime.evaluate"); evaluateMessage.Parameters.Add("expression", script); evaluateMessage.Parameters.Add("returnByValue", true); - evaluateMessage.Parameters.Add("awaitPromise", true); + evaluateMessage.Parameters.Add("awaitPromise", true); string? evaluatedValue = null; await connection.SendAsync( - evaluateMessage, - RuntimeEvaluateResponseSerializationContext.Default.BrowserResultResponseRuntimeEvaluateResponse, - evaluateResponse => + evaluateMessage, + RuntimeEvaluateResponseSerializationContext + .Default + .BrowserResultResponseRuntimeEvaluateResponse, + evaluateResponse => + { + if ( + evaluateResponse.Result.WasThrown && evaluateResponse.Result.ExceptionDetails is not null + ) { - if (evaluateResponse.Result.WasThrown && evaluateResponse.Result.ExceptionDetails is not null) - { - // Handle JS error - return; - } + // Handle JS error + return; + } - if (evaluateResponse.Result.Result?.Type == "string") - { - evaluatedValue = evaluateResponse.Result.Result?.Value?.GetString(); - } - }, - stoppingToken + if (evaluateResponse.Result.Result?.Type == "string") + { + evaluatedValue = evaluateResponse.Result.Result?.Value?.GetString(); + } + }, + stoppingToken ); return evaluatedValue; diff --git a/src/BlazorReports/Services/BrowserServices/BrowserService.cs b/src/BlazorReports/Services/BrowserServices/BrowserService.cs index 8e49e37..c5720b1 100644 --- a/src/BlazorReports/Services/BrowserServices/BrowserService.cs +++ b/src/BlazorReports/Services/BrowserServices/BrowserService.cs @@ -52,7 +52,13 @@ IBrowserFactory browserFactory /// The cancellation token /// The result of the operation public async ValueTask< - OneOf + OneOf< + Success, + ServerBusyProblem, + OperationCancelledProblem, + BrowserProblem, + JavascriptTimedoutProblem + > > GenerateReport( PipeWriter pipeWriter, string html, diff --git a/src/BlazorReports/Services/BrowserServices/IBrowserService.cs b/src/BlazorReports/Services/BrowserServices/IBrowserService.cs index 7ce7e77..f4b310c 100644 --- a/src/BlazorReports/Services/BrowserServices/IBrowserService.cs +++ b/src/BlazorReports/Services/BrowserServices/IBrowserService.cs @@ -21,7 +21,13 @@ public interface IBrowserService /// The cancellation token /// The result of the operation ValueTask< - OneOf + OneOf< + Success, + ServerBusyProblem, + OperationCancelledProblem, + BrowserProblem, + JavascriptTimedoutProblem + > > GenerateReport( PipeWriter pipeWriter, string html, diff --git a/src/BlazorReports/Services/BrowserServices/Problems/JavascriptTimedoutProblem.cs b/src/BlazorReports/Services/BrowserServices/Problems/JavascriptTimedoutProblem.cs new file mode 100644 index 0000000..ca0b129 --- /dev/null +++ b/src/BlazorReports/Services/BrowserServices/Problems/JavascriptTimedoutProblem.cs @@ -0,0 +1,11 @@ + using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BlazorReports.Services.BrowserServices.Problems; +/// +/// Represents a problem where the javascript has timed out +/// +public readonly record struct JavascriptTimedoutProblem; diff --git a/src/BlazorReports/Services/IReportService.cs b/src/BlazorReports/Services/IReportService.cs index 9e7184e..0db014d 100644 --- a/src/BlazorReports/Services/IReportService.cs +++ b/src/BlazorReports/Services/IReportService.cs @@ -23,7 +23,13 @@ public interface IReportService /// The type of data to use in the report /// The generated report ValueTask< - OneOf + OneOf< + Success, + ServerBusyProblem, + OperationCancelledProblem, + BrowserProblem, + JavascriptTimedoutProblem + > > GenerateReport( PipeWriter pipeWriter, BlazorReport report, @@ -43,7 +49,13 @@ public interface IReportService /// The type of data to use in the report /// The generated report ValueTask< - OneOf + OneOf< + Success, + ServerBusyProblem, + OperationCancelledProblem, + BrowserProblem, + JavascriptTimedoutProblem + > > GenerateReport( PipeWriter pipeWriter, BlazorReport blazorReport, @@ -60,7 +72,13 @@ public interface IReportService /// The cancellation token /// The generated report ValueTask< - OneOf + OneOf< + Success, + ServerBusyProblem, + OperationCancelledProblem, + BrowserProblem, + JavascriptTimedoutProblem + > > GenerateReport( PipeWriter pipeWriter, BlazorReport blazorReport, diff --git a/src/BlazorReports/Services/ReportService.cs b/src/BlazorReports/Services/ReportService.cs index 91c41be..39df42f 100644 --- a/src/BlazorReports/Services/ReportService.cs +++ b/src/BlazorReports/Services/ReportService.cs @@ -40,7 +40,13 @@ IBrowserService browserService /// The type of data to use in the report /// The generated report public async ValueTask< - OneOf + OneOf< + Success, + ServerBusyProblem, + OperationCancelledProblem, + BrowserProblem, + JavascriptTimedoutProblem + > > GenerateReport( PipeWriter pipeWriter, BlazorReport report, @@ -93,7 +99,13 @@ public async ValueTask< /// The type of data to use in the report /// The generated report public async ValueTask< - OneOf + OneOf< + Success, + ServerBusyProblem, + OperationCancelledProblem, + BrowserProblem, + JavascriptTimedoutProblem + > > GenerateReport( PipeWriter pipeWriter, BlazorReport blazorReport, @@ -208,7 +220,13 @@ public async ValueTask< /// The cancellation token /// The generated report public ValueTask< - OneOf + OneOf< + Success, + ServerBusyProblem, + OperationCancelledProblem, + BrowserProblem, + JavascriptTimedoutProblem + > > GenerateReport( PipeWriter pipeWriter, BlazorReport blazorReport, From 02427ab6770eb15f30165ff26a7d8b02e9971fa9 Mon Sep 17 00:00:00 2001 From: Andres Date: Sat, 22 Mar 2025 15:49:24 -0400 Subject: [PATCH 09/24] remove:Remove the hello js data from .js to avoid dupplicated logic. --- .../wwwroot/js/HelloJavascriptData.js | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/examples/SimpleReportServer/wwwroot/js/HelloJavascriptData.js b/examples/SimpleReportServer/wwwroot/js/HelloJavascriptData.js index 0f2a417..e69de29 100644 --- a/examples/SimpleReportServer/wwwroot/js/HelloJavascriptData.js +++ b/examples/SimpleReportServer/wwwroot/js/HelloJavascriptData.js @@ -1,14 +0,0 @@ - -var element = document.getElementById("HelloWorld"); - -// Set innerHTML to "Hello from JavaScript" -if (element) { - element.innerHTML = "Hello from JavaScript"; -} - -//after 5 seconds complete the report with blazorReport.completed(); // Mark report as ready - -setTimeout(() => { - blazorReport.completed(); // Mark report as ready -}, 5_000) - From 56b242d796896f429b7355ecff0a2f47be8b992e Mon Sep 17 00:00:00 2001 From: Andres Date: Sat, 22 Mar 2025 18:08:58 -0400 Subject: [PATCH 10/24] chore:fixed formating --- src/BlazorReports/Models/BlazorReportJavascriptSettings.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/BlazorReports/Models/BlazorReportJavascriptSettings.cs b/src/BlazorReports/Models/BlazorReportJavascriptSettings.cs index 55efb85..c4b1137 100644 --- a/src/BlazorReports/Models/BlazorReportJavascriptSettings.cs +++ b/src/BlazorReports/Models/BlazorReportJavascriptSettings.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; namespace BlazorReports.Models; + /// /// Settings for the internal javascript api /// @@ -14,9 +15,9 @@ public class BlazorReportJavascriptSettings /// The signal that the report is ready /// public string ReportIsReadySignal { get; set; } = "reportIsReady"; + /// /// The amount of time a reports javascript can take until it is considered to have timed out /// public TimeSpan ReportTimeout { get; set; } = TimeSpan.FromSeconds(5); - } From d5d05438eb58800ac2b9b3a84d96f31def71f311 Mon Sep 17 00:00:00 2001 From: Andres Date: Sat, 22 Mar 2025 18:18:33 -0400 Subject: [PATCH 11/24] CodeFormating --- Directory.Packages.props | 2 +- examples/SimpleReportServer/Program.cs | 1 + .../BlazorReportCurrentReportJavascriptSettings.cs | 10 ++-------- .../Models/BlazorReportGlobalJavascriptSettings.cs | 6 ------ .../Models/BlazorReportJavascriptSettings.cs | 6 ------ src/BlazorReports/Models/BlazorReportsOptions.cs | 1 + src/BlazorReports/Services/BrowserServices/Browser.cs | 6 +++--- .../Services/BrowserServices/BrowserPage.cs | 9 ++++----- .../Services/BrowserServices/BrowserService.cs | 4 ++-- .../Services/BrowserServices/Connection.cs | 10 +++++----- .../BrowserServices/Factories/BrowserFactory.cs | 8 ++++---- .../Services/BrowserServices/Helpers/ChromeFinder.cs | 2 +- .../Services/BrowserServices/Helpers/EdgeFinder.cs | 2 +- .../Services/BrowserServices/IBrowserService.cs | 2 +- .../Problems/JavascriptTimedoutProblem.cs | 6 ------ .../Responses/PageGetFrameTreeResponse.cs | 2 +- src/BlazorReports/Services/IReportService.cs | 2 +- .../Services/JavascriptServices/JavascriptContainer.cs | 4 ---- src/BlazorReports/Services/ReportService.cs | 2 +- 19 files changed, 29 insertions(+), 56 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 54ec2f0..0ccc88e 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -10,6 +10,6 @@ - + \ No newline at end of file diff --git a/examples/SimpleReportServer/Program.cs b/examples/SimpleReportServer/Program.cs index a897f73..dc20cbc 100644 --- a/examples/SimpleReportServer/Program.cs +++ b/examples/SimpleReportServer/Program.cs @@ -12,6 +12,7 @@ { options.GlobalJavascriptSettings.WaitForCompletedSignalTimeout = TimeSpan.FromSeconds(3); options.GlobalJavascriptSettings.WaitForJavascriptCompletedSignal = false; + options.BrowserOptions.Browser = BlazorReports.Services.BrowserServices.Browsers.Edge; }); var app = builder.Build(); diff --git a/src/BlazorReports/Models/BlazorReportCurrentReportJavascriptSettings.cs b/src/BlazorReports/Models/BlazorReportCurrentReportJavascriptSettings.cs index 302c5c2..bc23c78 100644 --- a/src/BlazorReports/Models/BlazorReportCurrentReportJavascriptSettings.cs +++ b/src/BlazorReports/Models/BlazorReportCurrentReportJavascriptSettings.cs @@ -1,9 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - namespace BlazorReports.Models; /// /// Settings for the internal javascript api @@ -17,11 +11,11 @@ public class BlazorReportCurrentReportJavascriptSettings /// /// Decides if the report should wait for the complete signal in the javascript /// - public bool WaitForJavascriptCompletedSignal { get; set; } + public bool WaitForJavascriptCompletedSignal { get; set; } /// /// The amount of time a reports javascript can take until it is considered to have timed out /// - public TimeSpan? WaitForCompletedSignalTimeout { get; set; } + public TimeSpan? WaitForCompletedSignalTimeout { get; set; } /// diff --git a/src/BlazorReports/Models/BlazorReportGlobalJavascriptSettings.cs b/src/BlazorReports/Models/BlazorReportGlobalJavascriptSettings.cs index c1cb4ce..92517ac 100644 --- a/src/BlazorReports/Models/BlazorReportGlobalJavascriptSettings.cs +++ b/src/BlazorReports/Models/BlazorReportGlobalJavascriptSettings.cs @@ -1,9 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - namespace BlazorReports.Models; /// /// diff --git a/src/BlazorReports/Models/BlazorReportJavascriptSettings.cs b/src/BlazorReports/Models/BlazorReportJavascriptSettings.cs index c4b1137..6372f6e 100644 --- a/src/BlazorReports/Models/BlazorReportJavascriptSettings.cs +++ b/src/BlazorReports/Models/BlazorReportJavascriptSettings.cs @@ -1,9 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - namespace BlazorReports.Models; /// diff --git a/src/BlazorReports/Models/BlazorReportsOptions.cs b/src/BlazorReports/Models/BlazorReportsOptions.cs index 9132845..4a864c4 100644 --- a/src/BlazorReports/Models/BlazorReportsOptions.cs +++ b/src/BlazorReports/Models/BlazorReportsOptions.cs @@ -24,6 +24,7 @@ public class BlazorReportsOptions /// Settings for generating a PDF /// public BlazorReportsPageSettings PageSettings { get; set; } = new(); + /// /// Javascript api settings /// diff --git a/src/BlazorReports/Services/BrowserServices/Browser.cs b/src/BlazorReports/Services/BrowserServices/Browser.cs index 6bed8dc..6f0b9bc 100644 --- a/src/BlazorReports/Services/BrowserServices/Browser.cs +++ b/src/BlazorReports/Services/BrowserServices/Browser.cs @@ -1,6 +1,3 @@ -using System.Collections.Concurrent; -using System.Diagnostics; -using System.IO.Pipelines; using BlazorReports.Models; using BlazorReports.Services.BrowserServices.Factories; using BlazorReports.Services.BrowserServices.Logs; @@ -10,6 +7,9 @@ using Microsoft.Extensions.Logging; using OneOf; using OneOf.Types; +using System.Collections.Concurrent; +using System.Diagnostics; +using System.IO.Pipelines; namespace BlazorReports.Services.BrowserServices; diff --git a/src/BlazorReports/Services/BrowserServices/BrowserPage.cs b/src/BlazorReports/Services/BrowserServices/BrowserPage.cs index eb1ecbd..db8c017 100644 --- a/src/BlazorReports/Services/BrowserServices/BrowserPage.cs +++ b/src/BlazorReports/Services/BrowserServices/BrowserPage.cs @@ -1,14 +1,13 @@ -using System.Buffers; -using System.Diagnostics; -using System.IO.Pipelines; -using System.Security.Cryptography; -using System.Text; using BlazorReports.Enums; using BlazorReports.Models; using BlazorReports.Services.BrowserServices.Logs; using BlazorReports.Services.BrowserServices.Requests; using BlazorReports.Services.BrowserServices.Responses; using Microsoft.Extensions.Logging; +using System.Buffers; +using System.IO.Pipelines; +using System.Security.Cryptography; +using System.Text; namespace BlazorReports.Services.BrowserServices; diff --git a/src/BlazorReports/Services/BrowserServices/BrowserService.cs b/src/BlazorReports/Services/BrowserServices/BrowserService.cs index c5720b1..4767342 100644 --- a/src/BlazorReports/Services/BrowserServices/BrowserService.cs +++ b/src/BlazorReports/Services/BrowserServices/BrowserService.cs @@ -1,5 +1,3 @@ -using System.Collections.Concurrent; -using System.IO.Pipelines; using BlazorReports.Models; using BlazorReports.Services.BrowserServices.Factories; using BlazorReports.Services.BrowserServices.Logs; @@ -8,6 +6,8 @@ using Microsoft.Extensions.Options; using OneOf; using OneOf.Types; +using System.Collections.Concurrent; +using System.IO.Pipelines; namespace BlazorReports.Services.BrowserServices; diff --git a/src/BlazorReports/Services/BrowserServices/Connection.cs b/src/BlazorReports/Services/BrowserServices/Connection.cs index 9f6325d..c082af7 100644 --- a/src/BlazorReports/Services/BrowserServices/Connection.cs +++ b/src/BlazorReports/Services/BrowserServices/Connection.cs @@ -1,14 +1,14 @@ -using System.Buffers; -using System.Collections.Concurrent; -using System.Net.WebSockets; -using System.Text.Json; -using System.Text.Json.Serialization.Metadata; using BlazorReports.Services.BrowserServices.Logs; using BlazorReports.Services.BrowserServices.Problems; using BlazorReports.Services.BrowserServices.Requests; using Microsoft.Extensions.Logging; using OneOf; using OneOf.Types; +using System.Buffers; +using System.Collections.Concurrent; +using System.Net.WebSockets; +using System.Text.Json; +using System.Text.Json.Serialization.Metadata; namespace BlazorReports.Services.BrowserServices; diff --git a/src/BlazorReports/Services/BrowserServices/Factories/BrowserFactory.cs b/src/BlazorReports/Services/BrowserServices/Factories/BrowserFactory.cs index 76ea203..47c6b4d 100644 --- a/src/BlazorReports/Services/BrowserServices/Factories/BrowserFactory.cs +++ b/src/BlazorReports/Services/BrowserServices/Factories/BrowserFactory.cs @@ -1,5 +1,3 @@ -using System.Diagnostics; -using System.Runtime.InteropServices; using BlazorReports.Models; using BlazorReports.Services.BrowserServices.Helpers; using BlazorReports.Services.BrowserServices.Logs; @@ -7,6 +5,8 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using OneOf; +using System.Diagnostics; +using System.Runtime.InteropServices; namespace BlazorReports.Services.BrowserServices.Factories; @@ -30,7 +30,7 @@ IBrowserPageFactory browserPageFactory public async ValueTask> CreateBrowser() { var browserOptions = options.Value.BrowserOptions; - var javascriptSettings = options.Value.GlobalJavascriptSettings; + var globalJavascriptSettings = options.Value.GlobalJavascriptSettings; var browserExecutableLocation = browserOptions.BrowserExecutableLocation is not null ? browserOptions.BrowserExecutableLocation.FullName : BrowserFinder.Find(browserOptions.Browser); @@ -93,7 +93,7 @@ public async ValueTask> CreateBrowser() devToolsActivePortDirectory, connection, browserOptions, - javascriptSettings, + globalJavascriptSettings, browserLogger, browserPageFactory ); diff --git a/src/BlazorReports/Services/BrowserServices/Helpers/ChromeFinder.cs b/src/BlazorReports/Services/BrowserServices/Helpers/ChromeFinder.cs index c641686..8d45c48 100644 --- a/src/BlazorReports/Services/BrowserServices/Helpers/ChromeFinder.cs +++ b/src/BlazorReports/Services/BrowserServices/Helpers/ChromeFinder.cs @@ -1,5 +1,5 @@ -using System.Runtime.InteropServices; using Microsoft.Win32; +using System.Runtime.InteropServices; namespace BlazorReports.Services.BrowserServices.Helpers; diff --git a/src/BlazorReports/Services/BrowserServices/Helpers/EdgeFinder.cs b/src/BlazorReports/Services/BrowserServices/Helpers/EdgeFinder.cs index cc0ea02..699b502 100644 --- a/src/BlazorReports/Services/BrowserServices/Helpers/EdgeFinder.cs +++ b/src/BlazorReports/Services/BrowserServices/Helpers/EdgeFinder.cs @@ -1,5 +1,5 @@ -using System.Runtime.InteropServices; using Microsoft.Win32; +using System.Runtime.InteropServices; namespace BlazorReports.Services.BrowserServices.Helpers; diff --git a/src/BlazorReports/Services/BrowserServices/IBrowserService.cs b/src/BlazorReports/Services/BrowserServices/IBrowserService.cs index f4b310c..11f2004 100644 --- a/src/BlazorReports/Services/BrowserServices/IBrowserService.cs +++ b/src/BlazorReports/Services/BrowserServices/IBrowserService.cs @@ -1,8 +1,8 @@ -using System.IO.Pipelines; using BlazorReports.Models; using BlazorReports.Services.BrowserServices.Problems; using OneOf; using OneOf.Types; +using System.IO.Pipelines; namespace BlazorReports.Services.BrowserServices; diff --git a/src/BlazorReports/Services/BrowserServices/Problems/JavascriptTimedoutProblem.cs b/src/BlazorReports/Services/BrowserServices/Problems/JavascriptTimedoutProblem.cs index ca0b129..3895453 100644 --- a/src/BlazorReports/Services/BrowserServices/Problems/JavascriptTimedoutProblem.cs +++ b/src/BlazorReports/Services/BrowserServices/Problems/JavascriptTimedoutProblem.cs @@ -1,9 +1,3 @@ - using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - namespace BlazorReports.Services.BrowserServices.Problems; /// /// Represents a problem where the javascript has timed out diff --git a/src/BlazorReports/Services/BrowserServices/Responses/PageGetFrameTreeResponse.cs b/src/BlazorReports/Services/BrowserServices/Responses/PageGetFrameTreeResponse.cs index 2c94801..7b0a6b7 100644 --- a/src/BlazorReports/Services/BrowserServices/Responses/PageGetFrameTreeResponse.cs +++ b/src/BlazorReports/Services/BrowserServices/Responses/PageGetFrameTreeResponse.cs @@ -1,5 +1,5 @@ -using System.Text.Json.Serialization; using BlazorReports.Services.BrowserServices.Types; +using System.Text.Json.Serialization; namespace BlazorReports.Services.BrowserServices.Responses; diff --git a/src/BlazorReports/Services/IReportService.cs b/src/BlazorReports/Services/IReportService.cs index 0db014d..6204a16 100644 --- a/src/BlazorReports/Services/IReportService.cs +++ b/src/BlazorReports/Services/IReportService.cs @@ -1,9 +1,9 @@ -using System.IO.Pipelines; using BlazorReports.Models; using BlazorReports.Services.BrowserServices.Problems; using Microsoft.AspNetCore.Components; using OneOf; using OneOf.Types; +using System.IO.Pipelines; namespace BlazorReports.Services; diff --git a/src/BlazorReports/Services/JavascriptServices/JavascriptContainer.cs b/src/BlazorReports/Services/JavascriptServices/JavascriptContainer.cs index d695af6..8f1c47a 100644 --- a/src/BlazorReports/Services/JavascriptServices/JavascriptContainer.cs +++ b/src/BlazorReports/Services/JavascriptServices/JavascriptContainer.cs @@ -1,9 +1,5 @@ using Microsoft.AspNetCore.Hosting; -using System; -using System.Collections.Generic; -using System.Linq; using System.Text; -using System.Threading.Tasks; namespace BlazorReports.Services.JavascriptServices; internal sealed class JavascriptContainer diff --git a/src/BlazorReports/Services/ReportService.cs b/src/BlazorReports/Services/ReportService.cs index 39df42f..fcae5da 100644 --- a/src/BlazorReports/Services/ReportService.cs +++ b/src/BlazorReports/Services/ReportService.cs @@ -1,4 +1,3 @@ -using System.IO.Pipelines; using BlazorReports.Components; using BlazorReports.Models; using BlazorReports.Services.BrowserServices; @@ -11,6 +10,7 @@ using Microsoft.Extensions.Options; using OneOf; using OneOf.Types; +using System.IO.Pipelines; namespace BlazorReports.Services; From 8acd01a966709b6d78927ea92dcff87eb341e004 Mon Sep 17 00:00:00 2001 From: Andres Date: Sat, 22 Mar 2025 19:14:25 -0400 Subject: [PATCH 12/24] Code clean up --- ...azorReportCurrentReportJavascriptSettings.cs | 15 +++++++++------ .../BlazorReportGlobalJavascriptSettings.cs | 5 ++++- .../Models/BlazorReportJavascriptSettings.cs | 17 ----------------- 3 files changed, 13 insertions(+), 24 deletions(-) delete mode 100644 src/BlazorReports/Models/BlazorReportJavascriptSettings.cs diff --git a/src/BlazorReports/Models/BlazorReportCurrentReportJavascriptSettings.cs b/src/BlazorReports/Models/BlazorReportCurrentReportJavascriptSettings.cs index bc23c78..5f77e4a 100644 --- a/src/BlazorReports/Models/BlazorReportCurrentReportJavascriptSettings.cs +++ b/src/BlazorReports/Models/BlazorReportCurrentReportJavascriptSettings.cs @@ -1,4 +1,5 @@ namespace BlazorReports.Models; + /// /// Settings for the internal javascript api /// @@ -8,22 +9,24 @@ public class BlazorReportCurrentReportJavascriptSettings /// The signal that the report is ready /// public string ReportIsReadySignal { get; set; } = default!; + /// /// Decides if the report should wait for the complete signal in the javascript /// public bool WaitForJavascriptCompletedSignal { get; set; } + /// /// The amount of time a reports javascript can take until it is considered to have timed out /// public TimeSpan? WaitForCompletedSignalTimeout { get; set; } - /// /// The default settings for the current report javascript settings /// - public static BlazorReportCurrentReportJavascriptSettings Default => new BlazorReportCurrentReportJavascriptSettings - { - WaitForJavascriptCompletedSignal = false, - WaitForCompletedSignalTimeout = TimeSpan.FromSeconds(3) - }; + public static BlazorReportCurrentReportJavascriptSettings Default => + new BlazorReportCurrentReportJavascriptSettings + { + WaitForJavascriptCompletedSignal = false, + WaitForCompletedSignalTimeout = TimeSpan.FromSeconds(3), + }; } diff --git a/src/BlazorReports/Models/BlazorReportGlobalJavascriptSettings.cs b/src/BlazorReports/Models/BlazorReportGlobalJavascriptSettings.cs index 92517ac..af807f5 100644 --- a/src/BlazorReports/Models/BlazorReportGlobalJavascriptSettings.cs +++ b/src/BlazorReports/Models/BlazorReportGlobalJavascriptSettings.cs @@ -1,6 +1,7 @@ namespace BlazorReports.Models; + /// -/// +/// /// public class BlazorReportGlobalJavascriptSettings { @@ -8,11 +9,13 @@ public class BlazorReportGlobalJavascriptSettings /// The signal that the report is ready /// public string ReportIsReadySignal { get; set; } = "reportIsReady"; + /// /// Decides if the report should wait for the complete signal in the javascript. /// (Default: false) /// public bool WaitForJavascriptCompletedSignal { get; set; } + /// /// The amount of time a reports javascript can take until it is considered to have timed out /// (Default: null) diff --git a/src/BlazorReports/Models/BlazorReportJavascriptSettings.cs b/src/BlazorReports/Models/BlazorReportJavascriptSettings.cs deleted file mode 100644 index 6372f6e..0000000 --- a/src/BlazorReports/Models/BlazorReportJavascriptSettings.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace BlazorReports.Models; - -/// -/// Settings for the internal javascript api -/// -public class BlazorReportJavascriptSettings -{ - /// - /// The signal that the report is ready - /// - public string ReportIsReadySignal { get; set; } = "reportIsReady"; - - /// - /// The amount of time a reports javascript can take until it is considered to have timed out - /// - public TimeSpan ReportTimeout { get; set; } = TimeSpan.FromSeconds(5); -} From 75d063a21d8fdc9779ea730e77fe3339ac6a1bf6 Mon Sep 17 00:00:00 2001 From: Andres Date: Sat, 22 Mar 2025 19:20:48 -0400 Subject: [PATCH 13/24] CSharpier formatting --- .../Models/BlazorReportRegistrationOptions.cs | 1 + .../Services/BrowserServices/Browser.cs | 6 +++--- .../Services/BrowserServices/BrowserPage.cs | 8 ++++---- .../Services/BrowserServices/BrowserService.cs | 4 ++-- .../Services/BrowserServices/Connection.cs | 10 +++++----- .../BrowserServices/Factories/BrowserFactory.cs | 4 ++-- .../BrowserServices/Helpers/ChromeFinder.cs | 2 +- .../BrowserServices/Helpers/EdgeFinder.cs | 2 +- .../Services/BrowserServices/IBrowserService.cs | 2 +- .../Problems/JavascriptTimedoutProblem.cs | 1 + .../Responses/PageGetFrameTreeResponse.cs | 2 +- .../Responses/RuntimeEvaluateResponse.cs | 16 +++++++++------- src/BlazorReports/Services/IReportService.cs | 2 +- .../JavascriptServices/JavascriptContainer.cs | 4 ++-- src/BlazorReports/Services/ReportService.cs | 2 +- 15 files changed, 35 insertions(+), 31 deletions(-) diff --git a/src/BlazorReports/Models/BlazorReportRegistrationOptions.cs b/src/BlazorReports/Models/BlazorReportRegistrationOptions.cs index 08fbae4..da55af3 100644 --- a/src/BlazorReports/Models/BlazorReportRegistrationOptions.cs +++ b/src/BlazorReports/Models/BlazorReportRegistrationOptions.cs @@ -29,6 +29,7 @@ public class BlazorReportRegistrationOptions /// Settings for generating a PDF /// public BlazorReportsPageSettings PageSettings { get; set; } = new(); + /// /// Javascript api settings /// diff --git a/src/BlazorReports/Services/BrowserServices/Browser.cs b/src/BlazorReports/Services/BrowserServices/Browser.cs index 6f0b9bc..6bed8dc 100644 --- a/src/BlazorReports/Services/BrowserServices/Browser.cs +++ b/src/BlazorReports/Services/BrowserServices/Browser.cs @@ -1,3 +1,6 @@ +using System.Collections.Concurrent; +using System.Diagnostics; +using System.IO.Pipelines; using BlazorReports.Models; using BlazorReports.Services.BrowserServices.Factories; using BlazorReports.Services.BrowserServices.Logs; @@ -7,9 +10,6 @@ using Microsoft.Extensions.Logging; using OneOf; using OneOf.Types; -using System.Collections.Concurrent; -using System.Diagnostics; -using System.IO.Pipelines; namespace BlazorReports.Services.BrowserServices; diff --git a/src/BlazorReports/Services/BrowserServices/BrowserPage.cs b/src/BlazorReports/Services/BrowserServices/BrowserPage.cs index db8c017..852f1cf 100644 --- a/src/BlazorReports/Services/BrowserServices/BrowserPage.cs +++ b/src/BlazorReports/Services/BrowserServices/BrowserPage.cs @@ -1,13 +1,13 @@ +using System.Buffers; +using System.IO.Pipelines; +using System.Security.Cryptography; +using System.Text; using BlazorReports.Enums; using BlazorReports.Models; using BlazorReports.Services.BrowserServices.Logs; using BlazorReports.Services.BrowserServices.Requests; using BlazorReports.Services.BrowserServices.Responses; using Microsoft.Extensions.Logging; -using System.Buffers; -using System.IO.Pipelines; -using System.Security.Cryptography; -using System.Text; namespace BlazorReports.Services.BrowserServices; diff --git a/src/BlazorReports/Services/BrowserServices/BrowserService.cs b/src/BlazorReports/Services/BrowserServices/BrowserService.cs index 4767342..c5720b1 100644 --- a/src/BlazorReports/Services/BrowserServices/BrowserService.cs +++ b/src/BlazorReports/Services/BrowserServices/BrowserService.cs @@ -1,3 +1,5 @@ +using System.Collections.Concurrent; +using System.IO.Pipelines; using BlazorReports.Models; using BlazorReports.Services.BrowserServices.Factories; using BlazorReports.Services.BrowserServices.Logs; @@ -6,8 +8,6 @@ using Microsoft.Extensions.Options; using OneOf; using OneOf.Types; -using System.Collections.Concurrent; -using System.IO.Pipelines; namespace BlazorReports.Services.BrowserServices; diff --git a/src/BlazorReports/Services/BrowserServices/Connection.cs b/src/BlazorReports/Services/BrowserServices/Connection.cs index c082af7..9f6325d 100644 --- a/src/BlazorReports/Services/BrowserServices/Connection.cs +++ b/src/BlazorReports/Services/BrowserServices/Connection.cs @@ -1,14 +1,14 @@ +using System.Buffers; +using System.Collections.Concurrent; +using System.Net.WebSockets; +using System.Text.Json; +using System.Text.Json.Serialization.Metadata; using BlazorReports.Services.BrowserServices.Logs; using BlazorReports.Services.BrowserServices.Problems; using BlazorReports.Services.BrowserServices.Requests; using Microsoft.Extensions.Logging; using OneOf; using OneOf.Types; -using System.Buffers; -using System.Collections.Concurrent; -using System.Net.WebSockets; -using System.Text.Json; -using System.Text.Json.Serialization.Metadata; namespace BlazorReports.Services.BrowserServices; diff --git a/src/BlazorReports/Services/BrowserServices/Factories/BrowserFactory.cs b/src/BlazorReports/Services/BrowserServices/Factories/BrowserFactory.cs index 47c6b4d..06a0df3 100644 --- a/src/BlazorReports/Services/BrowserServices/Factories/BrowserFactory.cs +++ b/src/BlazorReports/Services/BrowserServices/Factories/BrowserFactory.cs @@ -1,3 +1,5 @@ +using System.Diagnostics; +using System.Runtime.InteropServices; using BlazorReports.Models; using BlazorReports.Services.BrowserServices.Helpers; using BlazorReports.Services.BrowserServices.Logs; @@ -5,8 +7,6 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using OneOf; -using System.Diagnostics; -using System.Runtime.InteropServices; namespace BlazorReports.Services.BrowserServices.Factories; diff --git a/src/BlazorReports/Services/BrowserServices/Helpers/ChromeFinder.cs b/src/BlazorReports/Services/BrowserServices/Helpers/ChromeFinder.cs index 8d45c48..c641686 100644 --- a/src/BlazorReports/Services/BrowserServices/Helpers/ChromeFinder.cs +++ b/src/BlazorReports/Services/BrowserServices/Helpers/ChromeFinder.cs @@ -1,5 +1,5 @@ -using Microsoft.Win32; using System.Runtime.InteropServices; +using Microsoft.Win32; namespace BlazorReports.Services.BrowserServices.Helpers; diff --git a/src/BlazorReports/Services/BrowserServices/Helpers/EdgeFinder.cs b/src/BlazorReports/Services/BrowserServices/Helpers/EdgeFinder.cs index 699b502..cc0ea02 100644 --- a/src/BlazorReports/Services/BrowserServices/Helpers/EdgeFinder.cs +++ b/src/BlazorReports/Services/BrowserServices/Helpers/EdgeFinder.cs @@ -1,5 +1,5 @@ -using Microsoft.Win32; using System.Runtime.InteropServices; +using Microsoft.Win32; namespace BlazorReports.Services.BrowserServices.Helpers; diff --git a/src/BlazorReports/Services/BrowserServices/IBrowserService.cs b/src/BlazorReports/Services/BrowserServices/IBrowserService.cs index 11f2004..f4b310c 100644 --- a/src/BlazorReports/Services/BrowserServices/IBrowserService.cs +++ b/src/BlazorReports/Services/BrowserServices/IBrowserService.cs @@ -1,8 +1,8 @@ +using System.IO.Pipelines; using BlazorReports.Models; using BlazorReports.Services.BrowserServices.Problems; using OneOf; using OneOf.Types; -using System.IO.Pipelines; namespace BlazorReports.Services.BrowserServices; diff --git a/src/BlazorReports/Services/BrowserServices/Problems/JavascriptTimedoutProblem.cs b/src/BlazorReports/Services/BrowserServices/Problems/JavascriptTimedoutProblem.cs index 3895453..79e791c 100644 --- a/src/BlazorReports/Services/BrowserServices/Problems/JavascriptTimedoutProblem.cs +++ b/src/BlazorReports/Services/BrowserServices/Problems/JavascriptTimedoutProblem.cs @@ -1,4 +1,5 @@ namespace BlazorReports.Services.BrowserServices.Problems; + /// /// Represents a problem where the javascript has timed out /// diff --git a/src/BlazorReports/Services/BrowserServices/Responses/PageGetFrameTreeResponse.cs b/src/BlazorReports/Services/BrowserServices/Responses/PageGetFrameTreeResponse.cs index 7b0a6b7..2c94801 100644 --- a/src/BlazorReports/Services/BrowserServices/Responses/PageGetFrameTreeResponse.cs +++ b/src/BlazorReports/Services/BrowserServices/Responses/PageGetFrameTreeResponse.cs @@ -1,5 +1,5 @@ -using BlazorReports.Services.BrowserServices.Types; using System.Text.Json.Serialization; +using BlazorReports.Services.BrowserServices.Types; namespace BlazorReports.Services.BrowserServices.Responses; diff --git a/src/BlazorReports/Services/BrowserServices/Responses/RuntimeEvaluateResponse.cs b/src/BlazorReports/Services/BrowserServices/Responses/RuntimeEvaluateResponse.cs index e91ac47..f6663dc 100644 --- a/src/BlazorReports/Services/BrowserServices/Responses/RuntimeEvaluateResponse.cs +++ b/src/BlazorReports/Services/BrowserServices/Responses/RuntimeEvaluateResponse.cs @@ -2,6 +2,7 @@ using System.Text.Json.Serialization; namespace BlazorReports.Services.BrowserServices.Responses; + /// /// Response returned from the "Runtime.evaluate" DevTools command /// @@ -9,9 +10,10 @@ namespace BlazorReports.Services.BrowserServices.Responses; /// Details about any exception thrown in JS /// Whether an exception was thrown public sealed record RuntimeEvaluateResponse( - [property: JsonPropertyName("result")] RuntimeEvaluateResult? Result, - [property: JsonPropertyName("exceptionDetails")] RuntimeEvaluateExceptionDetails? ExceptionDetails, - [property: JsonPropertyName("wasThrown")] bool WasThrown + [property: JsonPropertyName("result")] RuntimeEvaluateResult? Result, + [property: JsonPropertyName("exceptionDetails")] + RuntimeEvaluateExceptionDetails? ExceptionDetails, + [property: JsonPropertyName("wasThrown")] bool WasThrown ); /// @@ -21,9 +23,9 @@ public sealed record RuntimeEvaluateResponse( /// The raw JSON value (if returnByValue was used) /// A textual description (especially for objects/functions) public sealed record RuntimeEvaluateResult( - [property: JsonPropertyName("type")] string? Type, - [property: JsonPropertyName("value")] JsonElement? Value, - [property: JsonPropertyName("description")] string? Description + [property: JsonPropertyName("type")] string? Type, + [property: JsonPropertyName("value")] JsonElement? Value, + [property: JsonPropertyName("description")] string? Description ); /// @@ -31,7 +33,7 @@ public sealed record RuntimeEvaluateResult( /// /// The error message text public sealed record RuntimeEvaluateExceptionDetails( - [property: JsonPropertyName("text")] string? Text + [property: JsonPropertyName("text")] string? Text ); /// diff --git a/src/BlazorReports/Services/IReportService.cs b/src/BlazorReports/Services/IReportService.cs index 6204a16..0db014d 100644 --- a/src/BlazorReports/Services/IReportService.cs +++ b/src/BlazorReports/Services/IReportService.cs @@ -1,9 +1,9 @@ +using System.IO.Pipelines; using BlazorReports.Models; using BlazorReports.Services.BrowserServices.Problems; using Microsoft.AspNetCore.Components; using OneOf; using OneOf.Types; -using System.IO.Pipelines; namespace BlazorReports.Services; diff --git a/src/BlazorReports/Services/JavascriptServices/JavascriptContainer.cs b/src/BlazorReports/Services/JavascriptServices/JavascriptContainer.cs index 8f1c47a..976f2b0 100644 --- a/src/BlazorReports/Services/JavascriptServices/JavascriptContainer.cs +++ b/src/BlazorReports/Services/JavascriptServices/JavascriptContainer.cs @@ -1,7 +1,8 @@ -using Microsoft.AspNetCore.Hosting; using System.Text; +using Microsoft.AspNetCore.Hosting; namespace BlazorReports.Services.JavascriptServices; + internal sealed class JavascriptContainer { /// @@ -40,5 +41,4 @@ public JavascriptContainer(IWebHostEnvironment env) } } } - } diff --git a/src/BlazorReports/Services/ReportService.cs b/src/BlazorReports/Services/ReportService.cs index fcae5da..39df42f 100644 --- a/src/BlazorReports/Services/ReportService.cs +++ b/src/BlazorReports/Services/ReportService.cs @@ -1,3 +1,4 @@ +using System.IO.Pipelines; using BlazorReports.Components; using BlazorReports.Models; using BlazorReports.Services.BrowserServices; @@ -10,7 +11,6 @@ using Microsoft.Extensions.Options; using OneOf; using OneOf.Types; -using System.IO.Pipelines; namespace BlazorReports.Services; From 4fd19257d8f7b4707e5fc30b47868be154639179 Mon Sep 17 00:00:00 2001 From: Andres Date: Sat, 22 Mar 2025 19:53:03 -0400 Subject: [PATCH 14/24] remove:HelloReport.razor changes removed. --- examples/SimpleReportServer/HelloReport.razor | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/SimpleReportServer/HelloReport.razor b/examples/SimpleReportServer/HelloReport.razor index 8275db2..95399b9 100644 --- a/examples/SimpleReportServer/HelloReport.razor +++ b/examples/SimpleReportServer/HelloReport.razor @@ -1,6 +1,5 @@

Hello @Data.Name

-

No data

@code { [Parameter] From 12fdfa408ed64e63b5a9bf3f823e3c48565e2d8a Mon Sep 17 00:00:00 2001 From: Andres Date: Sat, 22 Mar 2025 20:09:49 -0400 Subject: [PATCH 15/24] removed:Removed custom options from AddBlazorReports, reverting to default settings. --- examples/SimpleReportServer/Program.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/examples/SimpleReportServer/Program.cs b/examples/SimpleReportServer/Program.cs index dc20cbc..05029fa 100644 --- a/examples/SimpleReportServer/Program.cs +++ b/examples/SimpleReportServer/Program.cs @@ -8,12 +8,7 @@ builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); -builder.Services.AddBlazorReports(options => -{ - options.GlobalJavascriptSettings.WaitForCompletedSignalTimeout = TimeSpan.FromSeconds(3); - options.GlobalJavascriptSettings.WaitForJavascriptCompletedSignal = false; - options.BrowserOptions.Browser = BlazorReports.Services.BrowserServices.Browsers.Edge; -}); +builder.Services.AddBlazorReports(); var app = builder.Build(); From 5135ce0b9363c3e8a8e7b4dddf4145e137990622 Mon Sep 17 00:00:00 2001 From: Andres Date: Sat, 22 Mar 2025 20:11:04 -0400 Subject: [PATCH 16/24] refactor: Renamed SimpleJsTimeoutReport to SimpleJsAsyncReport --- examples/SimpleReportServer/Program.cs | 2 +- .../{SimpleJsTimeoutReport.razor => SimpleJsAsyncReport.razor} | 2 +- ...{SimpleJsTimeoutReportData.cs => SimpleJsAsyncReportData.cs} | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename examples/SimpleReportServer/Reports/{SimpleJsTimeoutReport.razor => SimpleJsAsyncReport.razor} (82%) rename examples/SimpleReportServer/Reports/{SimpleJsTimeoutReportData.cs => SimpleJsAsyncReportData.cs} (64%) diff --git a/examples/SimpleReportServer/Program.cs b/examples/SimpleReportServer/Program.cs index 05029fa..2034b4a 100644 --- a/examples/SimpleReportServer/Program.cs +++ b/examples/SimpleReportServer/Program.cs @@ -20,7 +20,7 @@ var reportsGroup = app.MapGroup("reports"); -reportsGroup.MapBlazorReport(opts => +reportsGroup.MapBlazorReport(opts => { opts.ReportName = "HelloReportPdf"; opts.OutputFormat = ReportOutputFormat.Pdf; diff --git a/examples/SimpleReportServer/Reports/SimpleJsTimeoutReport.razor b/examples/SimpleReportServer/Reports/SimpleJsAsyncReport.razor similarity index 82% rename from examples/SimpleReportServer/Reports/SimpleJsTimeoutReport.razor rename to examples/SimpleReportServer/Reports/SimpleJsAsyncReport.razor index 4d0f9a0..87cc64f 100644 --- a/examples/SimpleReportServer/Reports/SimpleJsTimeoutReport.razor +++ b/examples/SimpleReportServer/Reports/SimpleJsAsyncReport.razor @@ -17,6 +17,6 @@ @code { [Parameter] - public required SimpleJsTimeoutReportData Data { get; set; } + public required SimpleJsAsyncReportData Data { get; set; } } diff --git a/examples/SimpleReportServer/Reports/SimpleJsTimeoutReportData.cs b/examples/SimpleReportServer/Reports/SimpleJsAsyncReportData.cs similarity index 64% rename from examples/SimpleReportServer/Reports/SimpleJsTimeoutReportData.cs rename to examples/SimpleReportServer/Reports/SimpleJsAsyncReportData.cs index 9360880..1e74068 100644 --- a/examples/SimpleReportServer/Reports/SimpleJsTimeoutReportData.cs +++ b/examples/SimpleReportServer/Reports/SimpleJsAsyncReportData.cs @@ -1,6 +1,6 @@ namespace SimpleReportServer.Reports; -public record SimpleJsTimeoutReportData(int TimeoutInSeconds) +public record SimpleJsAsyncReportData(int TimeoutInSeconds) { public TimeSpan TimeSpan => TimeSpan.FromSeconds(TimeoutInSeconds); }; From 23cf4e3d61b2ccc9bb99bcc55aaf4b220c444ec2 Mon Sep 17 00:00:00 2001 From: Andres Date: Sat, 22 Mar 2025 20:11:59 -0400 Subject: [PATCH 17/24] removed:string for the ReportName removed. --- examples/SimpleReportServer/Program.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/SimpleReportServer/Program.cs b/examples/SimpleReportServer/Program.cs index 2034b4a..3d269ae 100644 --- a/examples/SimpleReportServer/Program.cs +++ b/examples/SimpleReportServer/Program.cs @@ -22,7 +22,6 @@ reportsGroup.MapBlazorReport(opts => { - opts.ReportName = "HelloReportPdf"; opts.OutputFormat = ReportOutputFormat.Pdf; opts.JavascriptSettings.WaitForJavascriptCompletedSignal = true; opts.JavascriptSettings.WaitForCompletedSignalTimeout = TimeSpan.FromSeconds(5); From 7ce06c75f926ac49fdfd6dedd67807a6633d7d7c Mon Sep 17 00:00:00 2001 From: Andres Date: Sat, 22 Mar 2025 20:12:47 -0400 Subject: [PATCH 18/24] remove: Eliminated reduntant Output Format specification. --- examples/SimpleReportServer/Program.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/SimpleReportServer/Program.cs b/examples/SimpleReportServer/Program.cs index 3d269ae..5d8bdec 100644 --- a/examples/SimpleReportServer/Program.cs +++ b/examples/SimpleReportServer/Program.cs @@ -22,7 +22,6 @@ reportsGroup.MapBlazorReport(opts => { - opts.OutputFormat = ReportOutputFormat.Pdf; opts.JavascriptSettings.WaitForJavascriptCompletedSignal = true; opts.JavascriptSettings.WaitForCompletedSignalTimeout = TimeSpan.FromSeconds(5); }); From e25e0fc68afe71d090bf686a3a98e9c529c2edff Mon Sep 17 00:00:00 2001 From: Andres Date: Sat, 22 Mar 2025 20:13:15 -0400 Subject: [PATCH 19/24] remove: removed report specific timeout setting. --- examples/SimpleReportServer/Program.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/SimpleReportServer/Program.cs b/examples/SimpleReportServer/Program.cs index 5d8bdec..4425dea 100644 --- a/examples/SimpleReportServer/Program.cs +++ b/examples/SimpleReportServer/Program.cs @@ -23,7 +23,6 @@ reportsGroup.MapBlazorReport(opts => { opts.JavascriptSettings.WaitForJavascriptCompletedSignal = true; - opts.JavascriptSettings.WaitForCompletedSignalTimeout = TimeSpan.FromSeconds(5); }); reportsGroup.MapBlazorReport(); reportsGroup.MapBlazorReport(opts => From a13704ebdd444f4f600c02262faf45c6f78d5698 Mon Sep 17 00:00:00 2001 From: Andres Date: Sat, 22 Mar 2025 20:13:41 -0400 Subject: [PATCH 20/24] chore: improve inline documentation in report script --- examples/SimpleReportServer/Reports/SimpleJsAsyncReport.razor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/SimpleReportServer/Reports/SimpleJsAsyncReport.razor b/examples/SimpleReportServer/Reports/SimpleJsAsyncReport.razor index 87cc64f..f3a2d2e 100644 --- a/examples/SimpleReportServer/Reports/SimpleJsAsyncReport.razor +++ b/examples/SimpleReportServer/Reports/SimpleJsAsyncReport.razor @@ -7,7 +7,7 @@ element.innerHTML = "

Hello from JavaScript

"; } - + // Call the globally defined blazorReport.completed() to let BlazorReports know the report's contents have finished generating. setTimeout(() => { blazorReport.completed(); }, @Data.TimeSpan.TotalMilliseconds) From 380fc595bfad2c2c7d5dcefc2c97b77a99ea5404 Mon Sep 17 00:00:00 2001 From: Andres Date: Sat, 22 Mar 2025 20:32:46 -0400 Subject: [PATCH 21/24] rememove: removal of redundant "!" operator. --- src/BlazorReports/Models/BlazorReportRegistry.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BlazorReports/Models/BlazorReportRegistry.cs b/src/BlazorReports/Models/BlazorReportRegistry.cs index 7b72451..9e24b46 100644 --- a/src/BlazorReports/Models/BlazorReportRegistry.cs +++ b/src/BlazorReports/Models/BlazorReportRegistry.cs @@ -86,7 +86,7 @@ public BlazorReport AddReport(BlazorReportRegistrationOptions? options = null Data = null, PageSettings = options?.PageSettings, CurrentReportJavascriptSettings = - options?.JavascriptSettings! ?? BlazorReportCurrentReportJavascriptSettings.Default, + options?.JavascriptSettings ?? BlazorReportCurrentReportJavascriptSettings.Default, }; if (!string.IsNullOrEmpty(options?.BaseStylesPath)) { From 728d47848901da5763be0e2e6c2044a7165e9e61 Mon Sep 17 00:00:00 2001 From: Andres Date: Sat, 22 Mar 2025 20:39:35 -0400 Subject: [PATCH 22/24] refactor: shouldReportAwaitJavascript moved closer to if statment. --- src/BlazorReports/Services/BrowserServices/Browser.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/BlazorReports/Services/BrowserServices/Browser.cs b/src/BlazorReports/Services/BrowserServices/Browser.cs index 6bed8dc..daa0817 100644 --- a/src/BlazorReports/Services/BrowserServices/Browser.cs +++ b/src/BlazorReports/Services/BrowserServices/Browser.cs @@ -99,11 +99,10 @@ out browserPage try { + await browserPage.DisplayHtml(html, cancellationToken); var shouldReportAwaitJavascript = currentReportJavascriptSettings.WaitForJavascriptCompletedSignal || globalJavascriptSettings.WaitForJavascriptCompletedSignal; - - await browserPage.DisplayHtml(html, cancellationToken); if (shouldReportAwaitJavascript) { TimeSpan globalTimeout = globalJavascriptSettings.WaitForCompletedSignalTimeout; From c96d89fd38a9ff0418ccf1a9448c80246b39927e Mon Sep 17 00:00:00 2001 From: Andres Date: Sat, 22 Mar 2025 20:40:13 -0400 Subject: [PATCH 23/24] rename: JavascriptTimedoutProblem to CompletedSignalTimeoutProblem --- src/BlazorReports/Services/BrowserServices/Browser.cs | 4 ++-- .../Services/BrowserServices/BrowserService.cs | 2 +- .../Services/BrowserServices/IBrowserService.cs | 2 +- ...tTimedoutProblem.cs => CompletedSignalTimeoutProblem.cs} | 2 +- src/BlazorReports/Services/IReportService.cs | 6 +++--- src/BlazorReports/Services/ReportService.cs | 6 +++--- 6 files changed, 11 insertions(+), 11 deletions(-) rename src/BlazorReports/Services/BrowserServices/Problems/{JavascriptTimedoutProblem.cs => CompletedSignalTimeoutProblem.cs} (70%) diff --git a/src/BlazorReports/Services/BrowserServices/Browser.cs b/src/BlazorReports/Services/BrowserServices/Browser.cs index daa0817..fef96e1 100644 --- a/src/BlazorReports/Services/BrowserServices/Browser.cs +++ b/src/BlazorReports/Services/BrowserServices/Browser.cs @@ -36,7 +36,7 @@ public async ValueTask< ServerBusyProblem, OperationCancelledProblem, BrowserProblem, - JavascriptTimedoutProblem + CompletedSignalTimeoutProblem > > GenerateReport( PipeWriter pipeWriter, @@ -114,7 +114,7 @@ out browserPage var didNotHitTimeOut = await browserPage.WaitForJsFlagAsync(timeout, cancellationToken); if (!didNotHitTimeOut) { - return new JavascriptTimedoutProblem(); + return new CompletedSignalTimeoutProblem(); } } diff --git a/src/BlazorReports/Services/BrowserServices/BrowserService.cs b/src/BlazorReports/Services/BrowserServices/BrowserService.cs index c5720b1..26df2ea 100644 --- a/src/BlazorReports/Services/BrowserServices/BrowserService.cs +++ b/src/BlazorReports/Services/BrowserServices/BrowserService.cs @@ -57,7 +57,7 @@ public async ValueTask< ServerBusyProblem, OperationCancelledProblem, BrowserProblem, - JavascriptTimedoutProblem + CompletedSignalTimeoutProblem > > GenerateReport( PipeWriter pipeWriter, diff --git a/src/BlazorReports/Services/BrowserServices/IBrowserService.cs b/src/BlazorReports/Services/BrowserServices/IBrowserService.cs index f4b310c..ddf19b2 100644 --- a/src/BlazorReports/Services/BrowserServices/IBrowserService.cs +++ b/src/BlazorReports/Services/BrowserServices/IBrowserService.cs @@ -26,7 +26,7 @@ public interface IBrowserService ServerBusyProblem, OperationCancelledProblem, BrowserProblem, - JavascriptTimedoutProblem + CompletedSignalTimeoutProblem > > GenerateReport( PipeWriter pipeWriter, diff --git a/src/BlazorReports/Services/BrowserServices/Problems/JavascriptTimedoutProblem.cs b/src/BlazorReports/Services/BrowserServices/Problems/CompletedSignalTimeoutProblem.cs similarity index 70% rename from src/BlazorReports/Services/BrowserServices/Problems/JavascriptTimedoutProblem.cs rename to src/BlazorReports/Services/BrowserServices/Problems/CompletedSignalTimeoutProblem.cs index 79e791c..e2e68e0 100644 --- a/src/BlazorReports/Services/BrowserServices/Problems/JavascriptTimedoutProblem.cs +++ b/src/BlazorReports/Services/BrowserServices/Problems/CompletedSignalTimeoutProblem.cs @@ -3,4 +3,4 @@ namespace BlazorReports.Services.BrowserServices.Problems; /// /// Represents a problem where the javascript has timed out /// -public readonly record struct JavascriptTimedoutProblem; +public readonly record struct CompletedSignalTimeoutProblem; diff --git a/src/BlazorReports/Services/IReportService.cs b/src/BlazorReports/Services/IReportService.cs index 0db014d..d1f5c78 100644 --- a/src/BlazorReports/Services/IReportService.cs +++ b/src/BlazorReports/Services/IReportService.cs @@ -28,7 +28,7 @@ public interface IReportService ServerBusyProblem, OperationCancelledProblem, BrowserProblem, - JavascriptTimedoutProblem + CompletedSignalTimeoutProblem > > GenerateReport( PipeWriter pipeWriter, @@ -54,7 +54,7 @@ public interface IReportService ServerBusyProblem, OperationCancelledProblem, BrowserProblem, - JavascriptTimedoutProblem + CompletedSignalTimeoutProblem > > GenerateReport( PipeWriter pipeWriter, @@ -77,7 +77,7 @@ public interface IReportService ServerBusyProblem, OperationCancelledProblem, BrowserProblem, - JavascriptTimedoutProblem + CompletedSignalTimeoutProblem > > GenerateReport( PipeWriter pipeWriter, diff --git a/src/BlazorReports/Services/ReportService.cs b/src/BlazorReports/Services/ReportService.cs index 39df42f..40dfb0e 100644 --- a/src/BlazorReports/Services/ReportService.cs +++ b/src/BlazorReports/Services/ReportService.cs @@ -45,7 +45,7 @@ public async ValueTask< ServerBusyProblem, OperationCancelledProblem, BrowserProblem, - JavascriptTimedoutProblem + CompletedSignalTimeoutProblem > > GenerateReport( PipeWriter pipeWriter, @@ -104,7 +104,7 @@ public async ValueTask< ServerBusyProblem, OperationCancelledProblem, BrowserProblem, - JavascriptTimedoutProblem + CompletedSignalTimeoutProblem > > GenerateReport( PipeWriter pipeWriter, @@ -225,7 +225,7 @@ public ValueTask< ServerBusyProblem, OperationCancelledProblem, BrowserProblem, - JavascriptTimedoutProblem + CompletedSignalTimeoutProblem > > GenerateReport( PipeWriter pipeWriter, From 3708f094422a99fdfb0aa6328108053078d018a2 Mon Sep 17 00:00:00 2001 From: Andres Date: Sun, 23 Mar 2025 15:19:46 -0400 Subject: [PATCH 24/24] fix:script should be below body to access the DOM --- examples/SimpleReportServer/Reports/SimpleJsAsyncReport.razor | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/SimpleReportServer/Reports/SimpleJsAsyncReport.razor b/examples/SimpleReportServer/Reports/SimpleJsAsyncReport.razor index f3a2d2e..46eb0d0 100644 --- a/examples/SimpleReportServer/Reports/SimpleJsAsyncReport.razor +++ b/examples/SimpleReportServer/Reports/SimpleJsAsyncReport.razor @@ -1,3 +1,5 @@ + +

-

- @code { [Parameter] public required SimpleJsAsyncReportData Data { get; set; }