-
-
Notifications
You must be signed in to change notification settings - Fork 251
Add LoadingTemplate parameter to BitDataGrid (#11311) #11312
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add LoadingTemplate parameter to BitDataGrid (#11311) #11312
Conversation
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughAdds a Columns render slot, a customizable LoadingTemplate, and Items/ItemsProvider APIs to BitDataGrid. Updates non-virtualized rendering to show a loading row when IsLoading and LoadingTemplate are set. Demo extended with a new loading template example and multiple provider-based samples. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant U as User
participant DG as BitDataGrid
participant DP as ItemsProvider (optional)
participant DS as IQueryable Items (optional)
rect rgba(230,240,255,0.4)
Note over DG: Column definitions
U->>DG: Provide Columns (or ChildContent)
DG->>DG: Render Columns if provided else ChildContent
end
alt ItemsProvider provided
U->>DG: Navigate/Filter/Paginate
DG->>DP: Request items (range, sort, filter)
activate DP
DP-->>DG: Items + total count
deactivate DP
else IQueryable Items provided
DG->>DS: Query items (optionally paged/sorted)
DS-->>DG: Items
end
rect rgba(240,230,255,0.4)
Note over DG: Loading state
U->>DG: Triggers data load
DG->>DG: Set IsLoading = true
alt LoadingTemplate provided AND non-virtualized
DG-->>U: Render single row with LoadingTemplate
else
DG-->>U: Apply "loading" CSS class (no template)
end
DG->>DG: Set IsLoading = false on completion
end
DG-->>U: Render rows (virtualized or not)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Assessment against linked issues
Assessment against linked issues: Out-of-scope changes
Poem
✨ Finishing Touches🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/BitDataGrid.razor.cs (2)
320-348
: LoadingTemplate may never be seen; render immediately on load start and fix CTS disposal.Currently the component doesn’t re-render when loading starts, so the LoadingTemplate won’t show until after data arrives. Also, CTS instances are never disposed.
Apply:
- // Move into a "loading" state, cancelling any earlier-but-still-pending load - _pendingDataLoadCancellationTokenSource?.Cancel(); - var thisLoadCts = _pendingDataLoadCancellationTokenSource = new CancellationTokenSource(); - - if (_virtualizeComponent is not null) - { - // If we're using Virtualize, we have to go through its RefreshDataAsync API otherwise: - // (1) It won't know to update its own internal state if the provider output has changed - // (2) We won't know what slice of data to query for - await _virtualizeComponent.RefreshDataAsync(); - _pendingDataLoadCancellationTokenSource = null; - } - else - { - // If we're not using Virtualize, we build and execute a request against the items provider directly - _lastRefreshedPaginationStateHash = Pagination?.GetHashCode(); - var startIndex = Pagination is null ? 0 : (Pagination.CurrentPageIndex * Pagination.ItemsPerPage); - var request = new BitDataGridItemsProviderRequest<TGridItem>( - startIndex, Pagination?.ItemsPerPage, _sortByColumn, _sortByAscending, thisLoadCts.Token); - var result = await ResolveItemsRequestAsync(request); - if (!thisLoadCts.IsCancellationRequested) - { - _currentNonVirtualizedViewItems = result.Items; - _ariaBodyRowCount = _currentNonVirtualizedViewItems.Count; - Pagination?.SetTotalItemCountAsync(result.TotalItemCount); - _pendingDataLoadCancellationTokenSource = null; - } - } + // Move into a "loading" state; cancel and dispose any previous load + _pendingDataLoadCancellationTokenSource?.Cancel(); + _pendingDataLoadCancellationTokenSource?.Dispose(); + var thisLoadCts = new CancellationTokenSource(); + _pendingDataLoadCancellationTokenSource = thisLoadCts; + + // Re-render immediately so LoadingTemplate/CSS "loading" state is visible + await InvokeAsync(StateHasChanged); + + try + { + if (_virtualizeComponent is not null) + { + // If we're using Virtualize, we have to go through its RefreshDataAsync API otherwise: + // (1) It won't know to update its own internal state if the provider output has changed + // (2) We won't know what slice of data to query for + await _virtualizeComponent.RefreshDataAsync(); + } + else + { + // Build and execute a request against the items provider directly + _lastRefreshedPaginationStateHash = Pagination?.GetHashCode(); + var startIndex = Pagination is null ? 0 : (Pagination.CurrentPageIndex * Pagination.ItemsPerPage); + var request = new BitDataGridItemsProviderRequest<TGridItem>( + startIndex, Pagination?.ItemsPerPage, _sortByColumn, _sortByAscending, thisLoadCts.Token); + var result = await ResolveItemsRequestAsync(request); + if (!thisLoadCts.IsCancellationRequested) + { + _currentNonVirtualizedViewItems = result.Items; + _ariaBodyRowCount = _currentNonVirtualizedViewItems.Count; + Pagination?.SetTotalItemCountAsync(result.TotalItemCount); + } + } + } + finally + { + if (_pendingDataLoadCancellationTokenSource == thisLoadCts) + { + _pendingDataLoadCancellationTokenSource = null; + } + thisLoadCts.Dispose(); + }
356-359
: Respect cancellation in debounce.Pass the request token to Task.Delay to avoid unnecessary delay after cancellation.
Apply:
- await Task.Delay(100); + await Task.Delay(100, request.CancellationToken);
🧹 Nitpick comments (4)
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/DataGrid/BitDataGridDemo.razor (1)
126-131
: Optional: Announce loading to screen readers.Consider adding aria-live/role to the loading container for better a11y when the row appears.
Example:
- <BitStack Alignment="BitAlignment.Center" Style="height:185px"> + <BitStack Alignment="BitAlignment.Center" Style="height:185px" AriaLive="BitAriaLive.Polite" Role="status">src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/BitDataGrid.razor (1)
33-44
: Loading row never spans exactly; compute colspan.Using a hardcoded colspan="100" is brittle. Span actual column count and guard for zero.
Apply:
- <tr> - <td colspan="100"> + <tr> + <td colspan="@Math.Max(1, _columns.Count)"> @LoadingTemplate </td> </tr>src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/BitDataGrid.razor.cs (1)
129-135
: Typo in API doc."rid" → "grid".
Apply:
- /// A callback that supplies data for the rid. + /// A callback that supplies data for the grid.src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/DataGrid/BitDataGridDemo.razor.cs (1)
68-70
: Typo in parameter description."rid" → "grid". This appears in the public docs table.
Apply:
- Description = @"A callback that supplies data for the rid. + Description = @"A callback that supplies data for the grid. You should supply either Items or ItemsProvider, but not both.",
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting
📒 Files selected for processing (5)
src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/BitDataGrid.razor
(2 hunks)src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/BitDataGrid.razor.cs
(5 hunks)src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/DataGrid/BitDataGridDemo.razor
(1 hunks)src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/DataGrid/BitDataGridDemo.razor.cs
(5 hunks)src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/DataGrid/BitDataGridDemo.razor.samples.cs
(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build and test
🔇 Additional comments (2)
src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/BitDataGrid.razor (1)
8-8
: Back-compat alias looks good.Preferring Columns over ChildContent keeps existing usage working.
src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/BitDataGrid.razor.cs (1)
434-435
: Conditional 'loading' class logic looks correct.Only applies CSS loader when no LoadingTemplate is supplied.
closes #11311
Summary by CodeRabbit
New Features
Documentation