mirror of
https://github.com/grafana/grafana.git
synced 2024-12-01 21:19:28 -06:00
Infinite scroll: share loader with log context + small fixes (#81067)
* Loading indicator: refactor * Infinite scroll: use ref to keep the last scroll * Infinite scroll: share loading indicator with log context * Infinite scrolling: override state * Infinite scroll: clean up imports and dependency array * Logs: disable order while loading * Infinite scroll: update ref before calling shouldLoadMore * Loading indicator: remove unused export * Logs order: move disabled prop to inline field * Formatting * Update betterer file
This commit is contained in:
parent
aa07c4a6b3
commit
e07417dca3
@ -3691,6 +3691,9 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Do not use any type assertions.", "3"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "4"]
|
||||
],
|
||||
"public/app/features/logs/components/LoadingIndicator.tsx:5381": [
|
||||
[0, 0, 0, "Styles should be written using objects.", "0"]
|
||||
],
|
||||
"public/app/features/logs/components/LogDetailsRow.tsx:5381": [
|
||||
[0, 0, 0, "Styles should be written using objects.", "0"],
|
||||
[0, 0, 0, "Styles should be written using objects.", "1"],
|
||||
@ -3763,9 +3766,6 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Styles should be written using objects.", "34"],
|
||||
[0, 0, 0, "Styles should be written using objects.", "35"]
|
||||
],
|
||||
"public/app/features/logs/components/log-context/LoadingIndicator.tsx:5381": [
|
||||
[0, 0, 0, "Styles should be written using objects.", "0"]
|
||||
],
|
||||
"public/app/features/logs/components/log-context/LogRowContextModal.tsx:5381": [
|
||||
[0, 0, 0, "Styles should be written using objects.", "0"],
|
||||
[0, 0, 0, "Styles should be written using objects.", "1"],
|
||||
|
@ -754,9 +754,13 @@ class UnthemedLogs extends PureComponent<Props, State> {
|
||||
</InlineFieldRow>
|
||||
|
||||
<div>
|
||||
<InlineField label="Display results" className={styles.horizontalInlineLabel} transparent>
|
||||
<InlineField
|
||||
label="Display results"
|
||||
className={styles.horizontalInlineLabel}
|
||||
transparent
|
||||
disabled={isFlipping || loading}
|
||||
>
|
||||
<RadioButtonGroup
|
||||
disabled={isFlipping}
|
||||
options={[
|
||||
{
|
||||
label: 'Newest first',
|
||||
|
@ -760,7 +760,8 @@ export const runLoadMoreLogsQueries = createAsyncThunk<void, RunLoadMoreLogsQuer
|
||||
mergeMap(([data, correlations]) => {
|
||||
// For query splitting, otherwise duplicates results
|
||||
if (data.state !== LoadingState.Done) {
|
||||
return of(queryResponse);
|
||||
// While loading, return the previous response and override state, otherwise it's set to Done
|
||||
return of({ ...queryResponse, state: LoadingState.Loading });
|
||||
}
|
||||
return decorateData(
|
||||
combinePanelData(queryResponse, data),
|
||||
|
@ -1,11 +1,12 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { ReactNode, useEffect, useState } from 'react';
|
||||
import React, { ReactNode, useEffect, useRef, useState } from 'react';
|
||||
|
||||
import { AbsoluteTimeRange, LogRowModel, TimeRange } from '@grafana/data';
|
||||
import { convertRawToRange, isRelativeTime, isRelativeTimeRange } from '@grafana/data/src/datetime/rangeutil';
|
||||
import { reportInteraction } from '@grafana/runtime';
|
||||
import { LogsSortOrder, TimeZone } from '@grafana/schema';
|
||||
import { Spinner } from '@grafana/ui';
|
||||
|
||||
import { LoadingIndicator } from './LoadingIndicator';
|
||||
|
||||
export type Props = {
|
||||
children: ReactNode;
|
||||
@ -32,7 +33,7 @@ export const InfiniteScroll = ({
|
||||
const [lowerOutOfRange, setLowerOutOfRange] = useState(false);
|
||||
const [upperLoading, setUpperLoading] = useState(false);
|
||||
const [lowerLoading, setLowerLoading] = useState(false);
|
||||
const [lastScroll, setLastScroll] = useState(scrollElement?.scrollTop || 0);
|
||||
const lastScroll = useRef<number>(scrollElement?.scrollTop || 0);
|
||||
|
||||
useEffect(() => {
|
||||
setUpperOutOfRange(false);
|
||||
@ -56,8 +57,8 @@ export const InfiniteScroll = ({
|
||||
return;
|
||||
}
|
||||
event.stopImmediatePropagation();
|
||||
setLastScroll(scrollElement.scrollTop);
|
||||
const scrollDirection = shouldLoadMore(event, scrollElement, lastScroll);
|
||||
const scrollDirection = shouldLoadMore(event, scrollElement, lastScroll.current);
|
||||
lastScroll.current = scrollElement.scrollTop;
|
||||
if (scrollDirection === ScrollDirection.NoScroll) {
|
||||
return;
|
||||
} else if (scrollDirection === ScrollDirection.Top) {
|
||||
@ -110,7 +111,7 @@ export const InfiniteScroll = ({
|
||||
scrollElement.removeEventListener('scroll', handleScroll);
|
||||
scrollElement.removeEventListener('wheel', handleScroll);
|
||||
};
|
||||
}, [lastScroll, loadMoreLogs, loading, range, rows, scrollElement, sortOrder, timeZone]);
|
||||
}, [loadMoreLogs, loading, range, rows, scrollElement, sortOrder, timeZone]);
|
||||
|
||||
// We allow "now" to move when using relative time, so we hide the message so it doesn't flash.
|
||||
const hideTopMessage = sortOrder === LogsSortOrder.Descending && isRelativeTime(range.raw.to);
|
||||
@ -118,11 +119,11 @@ export const InfiniteScroll = ({
|
||||
|
||||
return (
|
||||
<>
|
||||
{upperLoading && loadingMessage}
|
||||
{upperLoading && <LoadingIndicator adjective={sortOrder === LogsSortOrder.Descending ? 'newer' : 'older'} />}
|
||||
{!hideTopMessage && upperOutOfRange && outOfRangeMessage}
|
||||
{children}
|
||||
{!hideBottomMessage && lowerOutOfRange && outOfRangeMessage}
|
||||
{lowerLoading && loadingMessage}
|
||||
{lowerLoading && <LoadingIndicator adjective={sortOrder === LogsSortOrder.Descending ? 'older' : 'newer'} />}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@ -139,11 +140,6 @@ const outOfRangeMessage = (
|
||||
End of the selected time range.
|
||||
</div>
|
||||
);
|
||||
const loadingMessage = (
|
||||
<div className={styles.messageContainer}>
|
||||
<Spinner />
|
||||
</div>
|
||||
);
|
||||
|
||||
enum ScrollDirection {
|
||||
Top = -1,
|
||||
|
@ -3,17 +3,14 @@ import React from 'react';
|
||||
|
||||
import { Spinner } from '@grafana/ui';
|
||||
|
||||
import { Place } from './types';
|
||||
|
||||
// ideally we'd use `@grafana/ui/LoadingPlaceholder`, but that
|
||||
// one has a large margin-bottom.
|
||||
|
||||
type Props = {
|
||||
place: Place;
|
||||
adjective?: string;
|
||||
};
|
||||
|
||||
export const LoadingIndicator = ({ place }: Props) => {
|
||||
const text = place === 'above' ? 'Loading newer logs...' : 'Loading older logs...';
|
||||
export const LoadingIndicator = ({ adjective = 'newer' }: Props) => {
|
||||
const text = `Loading ${adjective} logs...`;
|
||||
return (
|
||||
<div className={loadingIndicatorStyles}>
|
||||
<div>
|
@ -26,11 +26,10 @@ import { useDispatch } from 'app/types';
|
||||
|
||||
import { dataFrameToLogsModel } from '../../logsModel';
|
||||
import { sortLogRows } from '../../utils';
|
||||
import { LoadingIndicator } from '../LoadingIndicator';
|
||||
import { LogRows } from '../LogRows';
|
||||
|
||||
import { LoadingIndicator } from './LoadingIndicator';
|
||||
import { LogContextButtons } from './LogContextButtons';
|
||||
import { Place } from './types';
|
||||
|
||||
const getStyles = (theme: GrafanaTheme2) => {
|
||||
return {
|
||||
@ -143,6 +142,7 @@ type Section = {
|
||||
loadingState: LoadingState;
|
||||
rows: LogRowModel[];
|
||||
};
|
||||
type Place = 'above' | 'below';
|
||||
type Context = Record<Place, Section>;
|
||||
|
||||
const makeEmptyContext = (): Context => ({
|
||||
@ -518,7 +518,7 @@ export const LogRowContextModal: React.FunctionComponent<LogRowContextModalProps
|
||||
<td className={styles.loadingCell}>
|
||||
{loadingStateAbove !== LoadingState.Done && loadingStateAbove !== LoadingState.Error && (
|
||||
<div ref={aboveLoadingElement}>
|
||||
<LoadingIndicator place="above" />
|
||||
<LoadingIndicator adjective="newer" />
|
||||
</div>
|
||||
)}
|
||||
{loadingStateAbove === LoadingState.Error && <div>Error loading log more logs.</div>}
|
||||
@ -587,7 +587,7 @@ export const LogRowContextModal: React.FunctionComponent<LogRowContextModalProps
|
||||
<td className={styles.loadingCell}>
|
||||
{loadingStateBelow !== LoadingState.Done && loadingStateBelow !== LoadingState.Error && (
|
||||
<div ref={belowLoadingElement}>
|
||||
<LoadingIndicator place="below" />
|
||||
<LoadingIndicator adjective="older" />
|
||||
</div>
|
||||
)}
|
||||
{loadingStateBelow === LoadingState.Error && <div>Error loading log more logs.</div>}
|
||||
|
@ -1 +0,0 @@
|
||||
export type Place = 'above' | 'below';
|
Loading…
Reference in New Issue
Block a user