feat(CardUpload): support ValidateForm validate function#7432
feat(CardUpload): support ValidateForm validate function#7432
Conversation
Reviewer's GuideImplements ValidateForm integration for CardUpload, aligns card upload validation behavior and styling with AvatarUpload, and improves UploadBase value binding and hover/valid/invalid visuals for card-style uploads. Sequence diagram for ValidateForm integration with CardUploadsequenceDiagram
actor User
participant ValidateForm
participant CardUpload
participant ValidateModule
User->>ValidateForm: Submit_form
ValidateForm->>CardUpload: ToggleMessage(results)
CardUpload->>CardUpload: _results = results
CardUpload->>CardUpload: IsValid = (results.Count == 0)
CardUpload->>CardUpload: IsInValidOnAddItem check
alt First_item_invalid
CardUpload->>ValidateModule: LoadValidateModule() if needed
CardUpload->>ValidateModule: executeUpload([AddId],[{Id=AddId,Error}],null)
else Existing_items_invalid
CardUpload->>ValidateModule: LoadValidateModule() if needed
CardUpload->>ValidateModule: executeUpload(fileValidateIds,invalidItems,AddId)
end
ValidateModule-->>User: Update_card_item_valid_invalid_borders
Class diagram for updated upload validation componentsclassDiagram
class UploadBase_TValue {
TValue CurrentValue
Type ValueType
Task OnFileChange(InputFileChangeEventArgs args)
}
class CardUpload_TValue {
bool IsValid
List~UploadFile~ Files
object ValidateModule
IReadOnlyCollection~ValidationResult~ _results
string ItemClassString
string AddId
bool IsInValidOnAddItem
Task ToggleMessage(IReadOnlyCollection~ValidationResult~ results)
ValueTask ShowValidResult()
ValueTask RemoveValidResult(string validateId)
}
class AvatarUpload_TValue {
bool IsValid
List~UploadFile~ Files
object ValidateModule
IReadOnlyCollection~ValidationResult~ _results
string AddId
bool IsInValidOnAddItem
Task ToggleMessage(IReadOnlyCollection~ValidationResult~ results)
ValueTask RemoveValidResult(string validateId)
}
class ValidateForm {
Task ValidateAsync(IValidateComponent validator, ValidationContext context, Dictionary~string, List~string~~ messages)
}
UploadBase_TValue <|-- CardUpload_TValue
UploadBase_TValue <|-- AvatarUpload_TValue
note for UploadBase_TValue "OnFileChange now sets CurrentValue to IEnumerable UploadFile when TValue is IEnumerable UploadFile, and to IEnumerable IBrowserFile when TValue is IEnumerable IBrowserFile"
note for CardUpload_TValue "Implements ToggleMessage integration with ValidateForm and JS validate module, plus no-op ShowValidResult and guarded RemoveValidResult"
note for AvatarUpload_TValue "Aligns naming IsInValidOnAddItem and its use in ToggleMessage and disposal logic"
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- In
CardUpload.ToggleMessage, the anonymous object initializernew { Id = AddId, _results.First().ErrorMessage }is not valid C# and likely should benew { Id = AddId, ErrorMessage = _results.First().ErrorMessage }to name the second property explicitly. - The CSS change from
.upload .upload-body.is-card .is-invalid .upload-item-bodyto.upload .upload-body.is-card .upload-item.is-invalidsetsborder-coloron the container rather than.upload-item-body; double-check that the border is actually applied on the element that owns the border to avoid the invalid/valid styles not showing. - The override of
RemoveValidResultinCardUploadonly callsbase.RemoveValidResultwhenvalidateIdis non-empty, which changes the behavior for anull/emptyvalidateId(previously used to clear all); verify that this restriction is intentional and that you don’t need to support clearing all validation results for this component.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `CardUpload.ToggleMessage`, the anonymous object initializer `new { Id = AddId, _results.First().ErrorMessage }` is not valid C# and likely should be `new { Id = AddId, ErrorMessage = _results.First().ErrorMessage }` to name the second property explicitly.
- The CSS change from `.upload .upload-body.is-card .is-invalid .upload-item-body` to `.upload .upload-body.is-card .upload-item.is-invalid` sets `border-color` on the container rather than `.upload-item-body`; double-check that the border is actually applied on the element that owns the border to avoid the invalid/valid styles not showing.
- The override of `RemoveValidResult` in `CardUpload` only calls `base.RemoveValidResult` when `validateId` is non-empty, which changes the behavior for a `null`/empty `validateId` (previously used to clear all); verify that this restriction is intentional and that you don’t need to support clearing all validation results for this component.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Pull request overview
This PR adds validation support for the CardUpload component, bringing it to feature parity with AvatarUpload. The changes enable CardUpload to work properly within ValidateForm contexts by implementing the necessary validation methods and visual feedback.
Key changes:
- Implements validation lifecycle methods (
ToggleMessage,ShowValidResult,RemoveValidResult) inCardUpload - Adds support for
IEnumerable<UploadFile>value type binding inUploadBase - Fixes CSS styling for validation states (valid/invalid) on card upload items
- Corrects a typo in
AvatarUpload(IsInValiadOnAddItem→IsInValidOnAddItem)
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/BootstrapBlazor/Components/ValidateForm/ValidateForm.razor.cs | Sets property value to null when no files are selected for upload validation |
| src/BootstrapBlazor/Components/Upload/UploadBase.cs | Adds support for IEnumerable<UploadFile> value type binding before the existing IEnumerable<IBrowserFile> check |
| src/BootstrapBlazor/Components/Upload/InputUpload.razor.scss | Fixes CSS selectors for validation states and prevents hover styling from overriding valid/invalid states |
| src/BootstrapBlazor/Components/Upload/CardUpload.razor.cs | Implements validation methods (ToggleMessage, ShowValidResult, RemoveValidResult) for form validation support |
| src/BootstrapBlazor/Components/Upload/CardUpload.razor | Adds id attributes to upload items and add button for validation targeting |
| src/BootstrapBlazor/Components/Upload/AvatarUpload.razor.cs | Fixes spelling of IsInValidOnAddItem property name (was IsInValiadOnAddItem) |
| src/BootstrapBlazor/BootstrapBlazor.csproj | Bumps version from 10.1.5-beta03 to 10.1.5-beta04 |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| } | ||
|
|
||
| private string? AddId => $"{Id}_new"; | ||
|
|
There was a problem hiding this comment.
The CardUpload component is missing a DisposeAsync override to clean up validation resources, unlike AvatarUpload which implements it at lines 230-250 in AvatarUpload.razor.cs. This override should call ValidateModule.InvokeVoidAsync("disposeUpload", items) to properly clean up JavaScript validation resources when the component is disposed. Consider adding it after the AddId property.
| /// <summary> | |
| /// <inheritdoc/> | |
| /// </summary> | |
| /// <returns></returns> | |
| public override async ValueTask DisposeAsync() | |
| { | |
| if (ValidateModule != null) | |
| { | |
| await ValidateModule.InvokeVoidAsync("disposeUpload", items); | |
| } | |
| await base.DisposeAsync(); | |
| } |
| public override async Task ToggleMessage(IReadOnlyCollection<ValidationResult> results) | ||
| { | ||
| _results = results; | ||
| IsValid = results.Count == 0; | ||
|
|
||
| ValidateModule ??= await LoadValidateModule(); | ||
|
|
||
| var invalidItems = IsInValidOnAddItem | ||
| ? [new { Id = AddId, _results.First().ErrorMessage }] | ||
| : _results.Select(i => new { Id = i.MemberNames.FirstOrDefault(), i.ErrorMessage }).ToList(); | ||
|
|
||
| var items = IsInValidOnAddItem | ||
| ? [AddId] | ||
| : Files.Select(i => i.ValidateId).ToList(); | ||
|
|
||
| var addId = IsInValidOnAddItem ? null : AddId; | ||
| await ValidateModule.InvokeVoidAsync("executeUpload", items, invalidItems, addId); | ||
| } |
There was a problem hiding this comment.
The new validation functionality added to CardUpload (ToggleMessage, ShowValidResult, RemoveValidResult methods) lacks test coverage. Similar functionality in AvatarUpload has comprehensive test coverage in test/UnitTest/Components/UploadAvatarTest.cs (lines 224-287). Consider adding similar tests to ensure the validation features work correctly.
Link issues
fixes #7431
Summary By Copilot
Regression?
Risk
Verification
Packaging changes reviewed?
☑️ Self Check before Merge
Summary by Sourcery
Integrate CardUpload with the validation pipeline and improve upload validation handling and styling.
New Features:
Bug Fixes: