Skip to content

Conversation

@ysmoradi
Copy link
Member

@ysmoradi ysmoradi commented Jun 13, 2025

closes #10988

Summary by CodeRabbit

  • New Features

    • Modal dialog for adding or editing categories is now draggable and restricts dragging to the header area.
    • Modal blocks interaction and navigation when there are unsaved changes, helping prevent accidental data loss.
  • Bug Fixes

    • Improved validation for duplicate category and product names, ensuring checks are performed when adding or modifying items.
  • Style

    • Enhanced modal layout with updated spacing and padding for a cleaner appearance.

@ysmoradi ysmoradi requested review from Copilot and msynk June 13, 2025 11:55
@coderabbitai
Copy link

coderabbitai bot commented Jun 13, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

The changes update the AddOrEditCategoryModal component to improve handling of unsaved changes, including conditional navigation blocking and UI interaction enhancements like making the modal draggable. Validation logic in both Category and Product controllers is optimized and extended to better detect duplicate names when entities are added or modified. Additional UI styling is applied.

Changes

File(s) Change Summary
.../AddOrEditCategoryModal.razor, .../AddOrEditCategoryModal.razor.cs Modal now blocks navigation/interactions on unsaved changes, is draggable, uses new isChanged logic, and updates form reference and button behavior.
.../AddOrEditCategoryModal.razor.scss Adds scoped styles for modal header and stack elements.
.../CategoryController.cs, .../ProductController.cs Optimizes validation logic for duplicate names by caching entry and checking both Added state and property modification.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant AddOrEditCategoryModal
    participant EditForm
    participant NavigationLock

    User->>AddOrEditCategoryModal: Open modal
    AddOrEditCategoryModal->>EditForm: Initialize form
    User->>EditForm: Make changes
    EditForm-->>AddOrEditCategoryModal: isChanged = true
    AddOrEditCategoryModal->>NavigationLock: Activate if isChanged
    User->>AddOrEditCategoryModal: Attempt to close/navigate away
    NavigationLock-->>User: Block navigation if isChanged
    User->>AddOrEditCategoryModal: Save or cancel
    AddOrEditCategoryModal->>NavigationLock: Deactivate if not isChanged
Loading
sequenceDiagram
    participant Controller
    participant DbContext
    participant Database

    Controller->>DbContext: Get entity entry (category/product)
    Controller->>DbContext: Check if state is Added or Name is modified
    DbContext->>Database: Query for existing name
    Database-->>DbContext: Return result
    DbContext-->>Controller: Result
    Controller->>Controller: Throw exception if duplicate found
Loading

Assessment against linked issues

Objective Addressed Explanation
Enhance Categories/Products pages: Improve modal UX, handle unsaved changes, optimize validation (#10988)

Assessment against linked issues: Out-of-scope changes

No out-of-scope changes found.

Poem

In the modal’s gentle light,
Draggable dreams now take flight.
With unsaved changes, navigation’s blocked—
No worries, your edits are locked!
Categories and products, checked for twins,
A rabbit hops—delight begins!
🐇✨

✨ Finishing Touches
🧪 Generate Unit Tests
  • Create PR with Unit Tests
  • Commit Unit Tests in branch 10988
  • Post Copyable Unit Tests in Comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai auto-generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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 PR improves the boilerplate pages for products and categories by refining validation logic on the server side and enhancing the user experience in category modals. Key changes include refactoring validation logic in the Product and Category controllers to use a local variable for database entity entry, and updating the modal behavior in the category component to better handle unsaved changes and modal closure.

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
ProductController.cs Uses a local variable for the database entry and updates the validation condition for duplicate product names.
CategoryController.cs Refactors validation logic similar to products and updates the condition for duplicate category names.
AddOrEditCategoryModal.razor.scss Adds scoped CSS rules via ::deep for improved styling consistency.
AddOrEditCategoryModal.razor.cs Introduces a reference for EditForm to track form modifications.
AddOrEditCategoryModal.razor Adjusts NavigationLock and modal properties to lock navigation when there are unsaved changes and replaces Href with OnClick for closing the modal.
Comments suppressed due to low confidence (4)

src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Controllers/Products/ProductController.cs:176

  • [nitpick] Confirm that the tuple syntax with the square bracket notation for the Localizer is an intentional pattern in our exception messages.
throw new ResourceValidationException((nameof(ProductDto.Name), [Localizer[nameof(AppStrings.DuplicateProductName)]]));

src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Categories/AddOrEditCategoryModal.razor:3

  • [nitpick] Changing the NavigationLock trigger from 'isOpen' to 'isChanged' alters when navigation is prevented; please verify that this behavior aligns with the intended UX for unsaved changes.
@if (isChanged)

src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Categories/AddOrEditCategoryModal.razor:73

  • [nitpick] Switching the button action from using an Href to an OnClick event for closing the modal is clear; please confirm that this change consistently updates the modal behavior across the application.
<BitButton ButtonType="BitButtonType.Button" OnClick="(() => isOpen = false)" Variant="BitVariant.Outline">

src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Categories/AddOrEditCategoryModal.razor.cs:17

  • [nitpick] Consider adding a short comment explaining the purpose of storing a reference to the EditForm to help future maintainers understand its role in tracking form changes.
private EditForm editForm = default!;

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Categories/AddOrEditCategoryModal.razor.cs (1)

3-21: Reset EditContext after save/close to keep isChanged accurate

isChanged keeps returning true after a save or cancel because the underlying EditContext still marks fields as modified. Result:
BitModal Blocking="isChanged" may prevent the modal from closing.
NavigationLock remains active even when modal is closed.

Consider clearing the modified state:

private async Task Save()
{
    …
-    isOpen = false;
+    isOpen = false;
+    editForm?.EditContext?.MarkAsUnmodified(); // extension in Microsoft.AspNetCore.Components.Forms
}

Or recreate the model & EditForm each time ShowModal is called.

src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Categories/AddOrEditCategoryModal.razor (1)

72-74: Minor: use @onclick:stopPropagation to isolate modal buttons

Prevent bubbled clicks accidentally closing the modal if outside click-to-close is enabled in future:

-<BitButton … OnClick="(() => isOpen = false)" …>
+<BitButton … @onclick:stopPropagation OnClick="(() => isOpen = false)" …>
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between 92b5fb0 and 5c2d9f7.

📒 Files selected for processing (5)
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Categories/AddOrEditCategoryModal.razor (3 hunks)
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Categories/AddOrEditCategoryModal.razor.cs (2 hunks)
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Categories/AddOrEditCategoryModal.razor.scss (1 hunks)
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Controllers/Categories/CategoryController.cs (1 hunks)
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Controllers/Products/ProductController.cs (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Categories/AddOrEditCategoryModal.razor.cs (1)
src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/AppDataAnnotationsValidator.cs (1)
  • AppDataAnnotationsValidator (16-251)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build and test
🔇 Additional comments (4)
src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Categories/AddOrEditCategoryModal.razor.scss (1)

24-32: 👍 Scoped spacing looks good

The ::deep rule is the right choice for Blazor CSS isolation and the added gaps/padding improve readability without leaking styles.

src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Categories/AddOrEditCategoryModal.razor (3)

3-6: NavigationLock conditional is correct but watch for null-form race

During the first render editForm is null; isChanged safely returns false, but if the user types before the component captures the reference (very unlikely) the lock might not be added. Acceptable trade-off, just be aware.


8-14: Potentially conflicting Blocking="isChanged" and Cancel logic

When the user clicks cancel with unsaved edits, Blocking is still true, yet isOpen is set to false. Verify that BitModal hides even in blocking mode; otherwise the modal may remain visible but inert.

If the component resists closing, gate the cancel action:

<BitButton ButtonType="BitButtonType.Button"
-          OnClick="(() => isOpen = false)"
+          OnClick="(() => { if (!isChanged) isOpen = false; })"
           Variant="BitVariant.Outline">

32-33: novalidate attribute suppresses browser validation

Good – server-side/Blazor validation handles errors consistently.

@ysmoradi ysmoradi merged commit 7ec347e into bitfoundation:develop Jun 14, 2025
3 checks passed
@ysmoradi ysmoradi deleted the 10988 branch June 14, 2025 14:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Categories / Products pages of the bit Boilerplate need enhancements

1 participant