Skip to content

Conversation

@ArgoZhang
Copy link
Member

@ArgoZhang ArgoZhang commented Jan 23, 2026

Link issues

fixes #7571

Summary By Copilot

Regression?

  • Yes
  • No

Risk

  • High
  • Medium
  • Low

Verification

  • Manual (required)
  • Automated

Packaging changes reviewed?

  • Yes
  • No
  • N/A

☑️ Self Check before Merge

⚠️ Please check all items below before review. ⚠️

  • Doc is updated/provided or not needed
  • Demo is updated/provided or not needed
  • Merge the latest code from the main branch

Summary by Sourcery

Simplify the EmbedPDF sample page and surface the new component in the demo navigation and attribute metadata.

New Features:

  • Expose the EmbedPDF component’s attributes in the demo via an AttributeTable entry.
  • Highlight the EmbedPDF demo as a new menu item in the sample navigation.

Enhancements:

  • Streamline the EmbedPDF sample to load PDFs via URL selection buttons instead of injected services and stream-based loading.
  • Remove the TabBarMode option from the EmbedPDF sample usage to match the current component API.
  • Improve component attribute type display by mapping UInt32 to the friendlier alias uint.

Copilot AI review requested due to automatic review settings January 23, 2026 13:25
@bb-auto bb-auto bot added the enhancement New feature or request label Jan 23, 2026
@bb-auto bb-auto bot added this to the v10.2.0 milestone Jan 23, 2026
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Jan 23, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Updates the EmbedPdfs demo to use the new EmbedPDF component via URL-based loading, simplifies the sample UI, and improves supporting infrastructure (menu metadata and attribute type name mapping) for the new component.

Sequence diagram for switching PDFs in the EmbedPdfs demo

sequenceDiagram
    actor User
    participant Browser
    participant EmbedPdfs
    participant EmbedPDF

    User->>Browser: Click Sample.Pdf button
    Browser->>EmbedPdfs: Invoke OnSetUrl("sample.pdf")
    activate EmbedPdfs
    EmbedPdfs->>EmbedPdfs: _url = "./samples/sample.pdf"
    deactivate EmbedPdfs
    EmbedPdfs-->>Browser: Component state updated
    Browser->>Browser: Re-render component tree
    Browser->>EmbedPDF: Render with Url = _url
    EmbedPDF-->>User: Display sample.pdf in viewer

    User->>Browser: Click EBook.Pdf button
    Browser->>EmbedPdfs: Invoke OnSetUrl("ebook.pdf")
    activate EmbedPdfs
    EmbedPdfs->>EmbedPdfs: _url = "./samples/ebook.pdf"
    deactivate EmbedPdfs
    EmbedPdfs-->>Browser: Component state updated
    Browser->>Browser: Re-render component tree
    Browser->>EmbedPDF: Render with Url = _url
    EmbedPDF-->>User: Display ebook.pdf in viewer
Loading

Class diagram for EmbedPdfs and ComponentAttributeCacheService changes

classDiagram
    class EmbedPdfs {
        -EmbedPDFTheme _theme
        -EmbedPDFScrollStrategy _strategy
        -string _url
        -string _streamFileName
        -string _language
        -IEnumerable~SelectedItem~ _languages
        +Task OnSetUrl(string fileName)
    }

    class ComponentAttributeCacheService {
        -static string GetFriendlyTypeName(Type type)
    }

    class Type {
        +string Name
    }

    EmbedPdfs ..> EmbedPDFTheme
    EmbedPdfs ..> EmbedPDFScrollStrategy
    EmbedPdfs ..> SelectedItem
    ComponentAttributeCacheService ..> Type

    class EmbedPDFTheme
    class EmbedPDFScrollStrategy
    class SelectedItem {
        +SelectedItem(string value)
        +SelectedItem(string value, string text)
    }

    class EmbedPDF {
        +string Url
        +string ViewHeight
        +string Language
        +EmbedPDFTheme Theme
        +EmbedPDFScrollStrategy ScrollStrategy
    }

    EmbedPdfs ..> EmbedPDF

    class DemoMenuItem {
        +bool IsNew
        +string Text
        +string Url
    }

    ComponentAttributeCacheService : GetFriendlyTypeName maps "UInt32" -> "uint"
    ComponentAttributeCacheService : GetFriendlyTypeName maps "Int32" -> "int"
    ComponentAttributeCacheService : GetFriendlyTypeName maps "String" -> "string"
    ComponentAttributeCacheService : GetFriendlyTypeName maps "Boolean" -> "bool"
Loading

File-Level Changes

Change Details Files
Refactor EmbedPdfs sample component to load PDFs by URL instead of injected file streams and remove unused TabBarMode support.
  • Remove IWebHostEnvironment and DownloadService DI dependencies and related stream-loading logic.
  • Replace stream-based file selection methods with a single async OnSetUrl helper that builds a relative samples path.
  • Drop the _tabBarMode field and all TabBarMode usage from the sample component and its bindings.
src/BootstrapBlazor.Server/Components/Samples/EmbedPdfs.razor.cs
Update the EmbedPdfs demo UI to match the new EmbedPDF usage and expose basic file selection and attribute documentation.
  • Remove the TabBarMode selection control from the toolbar.
  • Add buttons to switch between sample.pdf and ebook.pdf by invoking OnSetUrl with the corresponding file name.
  • Use EmbedPDF with Url, Theme, and ScrollStrategy parameters only, and add an AttributeTable for EmbedPDF to surface its API.
src/BootstrapBlazor.Server/Components/Samples/EmbedPdfs.razor
Mark the EmbedPdf menu entry as a new demo item.
  • Set IsNew = true on the EmbedPdf demo menu item so it appears as newly added in the navigation.
src/BootstrapBlazor.Server/Extensions/MenusLocalizerExtensions.cs
Improve friendly type name mapping used by the component attribute cache service.
  • Add a mapping from the CLR type name UInt32 to the C# alias uint when generating friendly type names for documented attributes.
src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs

Assessment against linked issues

Issue Objective Addressed Explanation
#7571 Implement an EmbedPDF component in the codebase that can display PDF files with configurable options (e.g., URL, theme, scroll strategy, language).
#7571 Add demo/sample usage and documentation hooks for the EmbedPDF component (sample page wiring, menu entry, and attribute table for props).

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@ArgoZhang ArgoZhang merged commit 665c2a0 into main Jan 23, 2026
6 of 7 checks passed
@ArgoZhang ArgoZhang deleted the feat-pdf branch January 23, 2026 13:26
Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues, and left some high level feedback:

  • The new OnSetUrl method is marked async but never awaited, so it can be made synchronous (void or Task without async) to avoid compiler warnings and unnecessary state machine generation.
  • With the switch from stream-based loading to URL-based loading for PDFs, double-check that any now-unused fields (e.g., _streamFileName) or services (DownloadService, IWebHostEnvironment) are fully removed from the partial class to keep the sample component lean.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new `OnSetUrl` method is marked `async` but never awaited, so it can be made synchronous (`void` or `Task` without `async`) to avoid compiler warnings and unnecessary state machine generation.
- With the switch from stream-based loading to URL-based loading for PDFs, double-check that any now-unused fields (e.g., `_streamFileName`) or services (`DownloadService`, `IWebHostEnvironment`) are fully removed from the partial class to keep the sample component lean.

## Individual Comments

### Comment 1
<location> `src/BootstrapBlazor.Server/Components/Samples/EmbedPdfs.razor.cs:25-28` </location>
<code_context>
-    }
-
-    private void GetSampleStream()
+    private async Task OnSetUrl(string fileName)
     {
-        _url = "";
-        _streamFileName = "sample.pdf";
+        _url = $"./samples/{fileName}";
     }
 }
</code_context>

<issue_to_address>
**suggestion:** Avoid `async` without `await` to remove the CS1998 compiler warning.

Since `OnSetUrl` doesn’t do any asynchronous work but likely needs to match a `Func<Task>` signature, keep the `Task` return type and remove `async` by implementing it as:

```csharp
private Task OnSetUrl(string fileName)
{
    _url = $"./samples/{fileName}";
    return Task.CompletedTask;
}
```

```suggestion
    private Task OnSetUrl(string fileName)
    {
        _url = $"./samples/{fileName}";
        return Task.CompletedTask;
    }
```
</issue_to_address>

### Comment 2
<location> `src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs:149` </location>
<code_context>

         return type.Name switch
         {
+            "UInt32" => "uint",
             "Int32" => "int",
             "String" => "string",
</code_context>

<issue_to_address>
**suggestion:** Consider handling other unsigned primitive aliases for consistency.

Specifically, consider also mapping `UInt16``"ushort"`, `UInt64``"ulong"`, and `Byte``"byte"` (if not already handled) so all primitive numeric types use their keyword forms.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +25 to 28
private async Task OnSetUrl(string fileName)
{
_url = "";
_streamFileName = "sample.pdf";
_url = $"./samples/{fileName}";
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Avoid async without await to remove the CS1998 compiler warning.

Since OnSetUrl doesn’t do any asynchronous work but likely needs to match a Func<Task> signature, keep the Task return type and remove async by implementing it as:

private Task OnSetUrl(string fileName)
{
    _url = $"./samples/{fileName}";
    return Task.CompletedTask;
}
Suggested change
private async Task OnSetUrl(string fileName)
{
_url = "";
_streamFileName = "sample.pdf";
_url = $"./samples/{fileName}";
}
private Task OnSetUrl(string fileName)
{
_url = $"./samples/{fileName}";
return Task.CompletedTask;
}


return type.Name switch
{
"UInt32" => "uint",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Consider handling other unsigned primitive aliases for consistency.

Specifically, consider also mapping UInt16"ushort", UInt64"ulong", and Byte"byte" (if not already handled) so all primitive numeric types use their keyword forms.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds the EmbedPDF component to the demo server by updating the package from beta to stable version, refactoring the demo page to simplify the interface, and adding proper type mapping support for component attributes.

Changes:

  • Updated BootstrapBlazor.EmbedPDF package from version 10.0.0-beta04 to 10.0.0 (stable release)
  • Simplified the EmbedPDF demo by removing stream-based PDF loading and TabBarMode configuration
  • Added UInt32 type mapping in ComponentAttributeCacheService for better type display

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/BootstrapBlazor.Server/Services/ComponentAttributeCacheService.cs Adds UInt32 to uint type mapping for friendly display in component attribute tables
src/BootstrapBlazor.Server/Extensions/MenusLocalizerExtensions.cs Marks the EmbedPdf menu item as new with IsNew flag
src/BootstrapBlazor.Server/Components/Samples/EmbedPdfs.razor.cs Refactors code-behind by removing unused stream handling and simplifying URL switching
src/BootstrapBlazor.Server/Components/Samples/EmbedPdfs.razor Updates UI by removing TabBarMode controls and adding buttons to switch between sample PDFs
src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj Updates EmbedPDF package from beta04 to stable 10.0.0 version

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

}

private void GetSampleStream()
private async Task OnSetUrl(string fileName)
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method OnSetUrl is marked as async but doesn't contain any await operations. This should be changed to a synchronous method by removing the async keyword and changing the return type from Task to void.

Suggested change
private async Task OnSetUrl(string fileName)
private void OnSetUrl(string fileName)

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(EmbedPDF): add EmbedPDF component

2 participants