55 * 2.0.
66 */
77
8- import React , { useContext , useCallback , useMemo } from 'react' ;
8+ import React , { useContext , useCallback , useMemo , useEffect } from 'react' ;
9+ import usePrevious from 'react-use/lib/usePrevious' ;
910import { LogEntry } from '../../../../common/log_entry' ;
1011import { euiStyled } from '../../../../../../../src/plugins/kibana_react/common' ;
1112import { AutoSizer } from '../../../components/auto_sizer' ;
@@ -14,7 +15,6 @@ import { LogMinimap } from '../../../components/logging/log_minimap';
1415import { ScrollableLogTextStreamView } from '../../../components/logging/log_text_stream' ;
1516import { LogEntryStreamItem } from '../../../components/logging/log_text_stream/item' ;
1617import { PageContent } from '../../../components/page' ;
17- import { LogEntriesState } from '../../../containers/logs/log_entries' ;
1818import { LogFilterState } from '../../../containers/logs/log_filter' ;
1919import {
2020 useLogEntryFlyoutContext ,
@@ -29,6 +29,11 @@ import { ViewLogInContext } from '../../../containers/logs/view_log_in_context';
2929import { WithLogTextviewUrlState } from '../../../containers/logs/with_log_textview' ;
3030import { LogsToolbar } from './page_toolbar' ;
3131import { PageViewLogInContext } from './page_view_log_in_context' ;
32+ import { useLogStreamContext } from '../../../containers/logs/log_stream' ;
33+ import { datemathToEpochMillis , isValidDatemath } from '../../../utils/datemath' ;
34+
35+ // FIXME Duplicated from <LogStream />. See where to put this
36+ const PAGE_THRESHOLD = 2 ;
3237
3338export const LogsPageLogsContent : React . FunctionComponent = ( ) => {
3439 const { sourceConfiguration, sourceId } = useLogSourceContext ( ) ;
@@ -42,16 +47,69 @@ export const LogsPageLogsContent: React.FunctionComponent = () => {
4247 logEntryId : flyoutLogEntryId ,
4348 } = useLogEntryFlyoutContext ( ) ;
4449
45- const [ logEntriesState , logEntriesCallbacks ] = useContext ( LogEntriesState . Context ) ;
50+ const {
51+ startTimestamp,
52+ endTimestamp,
53+ isStreaming,
54+ targetPosition,
55+ visibleMidpointTime,
56+ visibleTimeInterval,
57+ reportVisiblePositions,
58+ jumpToTargetPosition,
59+ startLiveStreaming,
60+ stopLiveStreaming,
61+ startDateExpression,
62+ endDateExpression,
63+ updateDateRange,
64+ } = useContext ( LogPositionState . Context ) ;
65+ const { applyLogFilterQuery } = useContext ( LogFilterState . Context ) ;
66+
4667 const {
4768 isReloading,
4869 entries,
49- hasMoreAfterEnd,
50- hasMoreBeforeStart,
70+ topCursor,
71+ bottomCursor,
72+ hasMoreAfter : hasMoreAfterEnd ,
73+ hasMoreBefore : hasMoreBeforeStart ,
5174 isLoadingMore,
5275 lastLoadedTime,
53- } = logEntriesState ;
54- const { checkForNewEntries } = logEntriesCallbacks ;
76+ fetchEntries,
77+ fetchPreviousEntries,
78+ fetchNextEntries,
79+ } = useLogStreamContext ( ) ;
80+
81+ const prevStartTimestamp = usePrevious ( startTimestamp ) ;
82+ const prevEndTimestamp = usePrevious ( endTimestamp ) ;
83+
84+ // Refetch entries if...
85+ useEffect ( ( ) => {
86+ const isFirstLoad = ! prevStartTimestamp || ! prevEndTimestamp ;
87+
88+ const newDateRangeDoesNotOverlap =
89+ ( prevStartTimestamp != null &&
90+ startTimestamp != null &&
91+ prevStartTimestamp < startTimestamp ) ||
92+ ( prevEndTimestamp != null && endTimestamp != null && prevEndTimestamp > endTimestamp ) ;
93+
94+ const isCenterPointOutsideLoadedRange =
95+ targetPosition != null &&
96+ ( ( topCursor != null && targetPosition . time < topCursor . time ) ||
97+ ( bottomCursor != null && targetPosition . time > bottomCursor . time ) ) ;
98+
99+ if ( isFirstLoad || newDateRangeDoesNotOverlap || isCenterPointOutsideLoadedRange ) {
100+ fetchEntries ( ) ;
101+ }
102+ } , [
103+ fetchEntries ,
104+ prevStartTimestamp ,
105+ prevEndTimestamp ,
106+ startTimestamp ,
107+ endTimestamp ,
108+ targetPosition ,
109+ topCursor ,
110+ bottomCursor ,
111+ ] ) ;
112+
55113 const { logSummaryHighlights, currentHighlightKey, logEntryHighlightsById } = useContext (
56114 LogHighlightsState . Context
57115 ) ;
@@ -67,23 +125,51 @@ export const LogsPageLogsContent: React.FunctionComponent = () => {
67125 [ entries , isReloading , logEntryHighlightsById ]
68126 ) ;
69127
70- const { applyLogFilterQuery } = useContext ( LogFilterState . Context ) ;
71- const {
72- isStreaming,
73- targetPosition,
74- visibleMidpointTime,
75- visibleTimeInterval,
76- reportVisiblePositions,
77- jumpToTargetPosition,
78- startLiveStreaming,
79- stopLiveStreaming,
80- startDateExpression,
81- endDateExpression,
82- updateDateRange,
83- } = useContext ( LogPositionState . Context ) ;
84-
85128 const [ , { setContextEntry } ] = useContext ( ViewLogInContext . Context ) ;
86129
130+ const handleDateRangeExtension = useCallback (
131+ ( newDateRange ) => {
132+ updateDateRange ( newDateRange ) ;
133+
134+ if (
135+ 'startDateExpression' in newDateRange &&
136+ isValidDatemath ( newDateRange . startDateExpression )
137+ ) {
138+ fetchPreviousEntries ( {
139+ force : true ,
140+ extendTo : datemathToEpochMillis ( newDateRange . startDateExpression ) ! ,
141+ } ) ;
142+ }
143+ if ( 'endDateExpression' in newDateRange && isValidDatemath ( newDateRange . endDateExpression ) ) {
144+ fetchNextEntries ( {
145+ force : true ,
146+ extendTo : datemathToEpochMillis ( newDateRange . endDateExpression ) ! ,
147+ } ) ;
148+ }
149+ } ,
150+ [ updateDateRange , fetchPreviousEntries , fetchNextEntries ]
151+ ) ;
152+
153+ const handlePagination = useCallback (
154+ ( params ) => {
155+ reportVisiblePositions ( params ) ;
156+ if ( ! params . fromScroll ) {
157+ return ;
158+ }
159+
160+ if ( isLoadingMore ) {
161+ return ;
162+ }
163+
164+ if ( params . pagesBeforeStart < PAGE_THRESHOLD ) {
165+ fetchPreviousEntries ( ) ;
166+ } else if ( params . pagesAfterEnd < PAGE_THRESHOLD ) {
167+ fetchNextEntries ( ) ;
168+ }
169+ } ,
170+ [ reportVisiblePositions , isLoadingMore , fetchPreviousEntries , fetchNextEntries ]
171+ ) ;
172+
87173 const setFilter = useCallback (
88174 ( filter , flyoutItemId , timeKey ) => {
89175 applyLogFilterQuery ( filter ) ;
@@ -123,8 +209,8 @@ export const LogsPageLogsContent: React.FunctionComponent = () => {
123209 items = { items }
124210 jumpToTarget = { jumpToTargetPosition }
125211 lastLoadedTime = { lastLoadedTime }
126- reloadItems = { checkForNewEntries }
127- reportVisibleInterval = { reportVisiblePositions }
212+ reloadItems = { fetchEntries }
213+ reportVisibleInterval = { handlePagination }
128214 scale = { textScale }
129215 target = { targetPosition }
130216 wrap = { textWrap }
@@ -134,7 +220,7 @@ export const LogsPageLogsContent: React.FunctionComponent = () => {
134220 currentHighlightKey = { currentHighlightKey }
135221 startDateExpression = { startDateExpression }
136222 endDateExpression = { endDateExpression }
137- updateDateRange = { updateDateRange }
223+ updateDateRange = { handleDateRangeExtension }
138224 startLiveStreaming = { startLiveStreaming }
139225 />
140226
0 commit comments