Skip to content

Commit 70e18bb

Browse files
authored
Fix automatic scrolling to the bottom of main page content (#10740)
* Fix continious scroll to prevent jumping to the top * Overscan counts * Update * Update * Continious scroll is re-enabled when there is no scrollbar
1 parent 3e084b7 commit 70e18bb

File tree

6 files changed

+28
-4
lines changed

6 files changed

+28
-4
lines changed

src/Aspire.Dashboard/Components/Pages/Resources.razor

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@
127127
Virtualize="true"
128128
GenerateHeader="GenerateHeaderOption.Sticky"
129129
ItemSize="46"
130+
OverscanCount="100"
130131
ItemsProvider="@GetData"
131132
ResizableColumns="true"
132133
ResizeColumnOnAllRows="false"

src/Aspire.Dashboard/Components/Pages/StructuredLogs.razor

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@
122122
RowClass="@GetRowClass"
123123
GenerateHeader="GenerateHeaderOption.Sticky"
124124
ItemSize="46"
125+
OverscanCount="100"
125126
ResizableColumns="true"
126127
ResizeColumnOnAllRows="false"
127128
ItemsProvider="@GetData"

src/Aspire.Dashboard/Components/Pages/StructuredLogs.razor.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ private async ValueTask<GridItemsProviderResult<OtlpLogEntry>> GetData(GridItems
136136
message.Close();
137137
}
138138

139+
Logger.LogTrace("Log data updated. Start index: {RequestStartIndex}, count: {RequestCount}, result item count: {ResultTotalItemCount}", request.StartIndex, request.Count, logs.TotalItemCount);
140+
139141
// Updating the total item count as a field doesn't work because it isn't updated with the grid.
140142
// The workaround is to explicitly update and refresh the control.
141143
_totalItemsCount = logs.TotalItemCount;

src/Aspire.Dashboard/Components/Pages/TraceDetail.razor

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@
109109
RowClass="@GetRowClass"
110110
GridTemplateColumns="@_manager.GetGridTemplateColumns()"
111111
RowSize="DataGridRowSize.Small"
112+
OverscanCount="100"
112113
ShowHover="true"
113114
ItemKey="@(r => r.Span.SpanId)"
114115
OnRowClick="@(r => r.ExecuteOnDefault(d => OnShowPropertiesAsync(d, buttonId: null)))">

src/Aspire.Dashboard/Components/Pages/Traces.razor

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
RowClass="@GetRowClass"
9393
GenerateHeader="GenerateHeaderOption.Sticky"
9494
ItemSize="46"
95+
OverscanCount="100"
9596
ResizableColumns="true"
9697
ResizeColumnOnAllRows="false"
9798
ItemsProvider="@GetData"

src/Aspire.Dashboard/wwwroot/js/app.js

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ window.getIsScrolledToContent = function () {
6262
window.setIsScrolledToContent = function (value) {
6363
if (isScrolledToContent != value) {
6464
isScrolledToContent = value;
65+
console.log(`isScrolledToContent=${isScrolledToContent}`);
6566
}
6667
}
6768

@@ -82,17 +83,30 @@ window.initializeContinuousScroll = function () {
8283

8384
// The scroll event is used to detect when the user scrolls to view content.
8485
container.addEventListener('scroll', () => {
85-
var v = !isScrolledToBottom(container);
86-
setIsScrolledToContent(v);
86+
var atBottom = isScrolledToBottom(container);
87+
if (atBottom === null) {
88+
return;
89+
}
90+
setIsScrolledToContent(!atBottom);
8791
}, { passive: true });
8892

8993
// The ResizeObserver reports changes in the grid size.
9094
// This ensures that the logs are scrolled to the bottom when there are new logs
9195
// unless the user has scrolled to view content.
9296
const observer = new ResizeObserver(function () {
9397
lastScrollHeight = container.scrollHeight;
94-
if (!getIsScrolledToContent()) {
98+
99+
if (lastScrollHeight == container.clientHeight) {
100+
// There is no scrollbar. This could be because there's no content, or the content might have been cleared.
101+
// Reset to default behavior: scroll to bottom
102+
setIsScrolledToContent(false);
103+
return;
104+
}
105+
106+
var isScrolledToContent = getIsScrolledToContent();
107+
if (!isScrolledToContent) {
95108
container.scrollTop = lastScrollHeight;
109+
return;
96110
}
97111
});
98112
for (const child of container.children) {
@@ -108,14 +122,18 @@ function isScrolledToBottom(container) {
108122
if (!getIsScrolledToContent()) {
109123
if (lastScrollHeight != container.scrollHeight) {
110124
console.log(`lastScrollHeight ${lastScrollHeight} doesn't equal container scrollHeight ${container.scrollHeight}.`);
125+
126+
// Unknown because the container size changed.
127+
return null;
111128
}
112129
}
113130

114131
const marginOfError = 5;
115132
const containerScrollBottom = lastScrollHeight - container.clientHeight;
116133
const difference = containerScrollBottom - container.scrollTop;
117134

118-
return difference < marginOfError;
135+
var atBottom = difference < marginOfError;
136+
return atBottom;
119137
}
120138

121139
window.buttonOpenLink = function (element) {

0 commit comments

Comments
 (0)