Skip to content

Commit a34e480

Browse files
committed
[Logs UI] Refactor log entry data fetching to hooks (#51526)
* Get initialinitial log fetch working with v2 store * Replicate shouldLoadAroundPosition logic within hooks * Reload entries on filter change * Add scroll to load additional entries functionality * Cleanup types types and remove state/remote folder * Typescript cleanup * Remove extraneous console.log * Fix typecheck * Add action to load new entries manually * Typecheck fix * Move v2 store stuff into logs containers * Typecheck fix * More typecheck fix * Remove filterQuery from log highlights redux bridge * Rename LogEntriesDependencies to LogEntriesFetchParams * Fix endless reloading bug * Fix duplicate entry rendering * Make sourceId into a dynamic parameter * Fix bug in pagesAfterEnd not being reported causing endless reload * Fix bugs with live streaming
1 parent c5a1b71 commit a34e480

40 files changed

+620
-941
lines changed

x-pack/legacy/plugins/infra/public/apps/start_app.tsx

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { InfraFrontendLibs } from '../lib/lib';
2121
import { PageRouter } from '../routes';
2222
import { createStore } from '../store';
2323
import { ApolloClientContext } from '../utils/apollo_context';
24+
import { ReduxStateContextProvider } from '../utils/redux_context';
2425
import { HistoryContext } from '../utils/history_context';
2526
import {
2627
useUiSetting$,
@@ -46,15 +47,17 @@ export async function startApp(libs: InfraFrontendLibs) {
4647
<UICapabilitiesProvider>
4748
<EuiErrorBoundary>
4849
<ReduxStoreProvider store={store}>
49-
<ApolloProvider client={libs.apolloClient}>
50-
<ApolloClientContext.Provider value={libs.apolloClient}>
51-
<EuiThemeProvider darkMode={darkMode}>
52-
<HistoryContext.Provider value={history}>
53-
<PageRouter history={history} />
54-
</HistoryContext.Provider>
55-
</EuiThemeProvider>
56-
</ApolloClientContext.Provider>
57-
</ApolloProvider>
50+
<ReduxStateContextProvider>
51+
<ApolloProvider client={libs.apolloClient}>
52+
<ApolloClientContext.Provider value={libs.apolloClient}>
53+
<EuiThemeProvider darkMode={darkMode}>
54+
<HistoryContext.Provider value={history}>
55+
<PageRouter history={history} />
56+
</HistoryContext.Provider>
57+
</EuiThemeProvider>
58+
</ApolloClientContext.Provider>
59+
</ApolloProvider>
60+
</ReduxStateContextProvider>
5861
</ReduxStoreProvider>
5962
</EuiErrorBoundary>
6063
</UICapabilitiesProvider>

x-pack/legacy/plugins/infra/public/components/logging/log_text_stream/loading_item_view.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ interface LogTextStreamLoadingItemViewProps {
1818
hasMore: boolean;
1919
isLoading: boolean;
2020
isStreaming: boolean;
21-
lastStreamingUpdate: number | null;
21+
lastStreamingUpdate: Date | null;
2222
onLoadMore?: () => void;
2323
}
2424

x-pack/legacy/plugins/infra/public/components/logging/log_text_stream/scrollable_log_text_stream_view.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ interface ScrollableLogTextStreamViewProps {
3939
hasMoreBeforeStart: boolean;
4040
hasMoreAfterEnd: boolean;
4141
isStreaming: boolean;
42-
lastLoadedTime: number | null;
42+
lastLoadedTime: Date | null;
4343
target: TimeKey | null;
4444
jumpToTarget: (target: TimeKey) => any;
4545
reportVisibleInterval: (params: {
@@ -143,7 +143,7 @@ export class ScrollableLogTextStreamView extends React.PureComponent<
143143
const hasItems = items.length > 0;
144144
return (
145145
<ScrollableLogTextStreamViewWrapper>
146-
{isReloading && !hasItems ? (
146+
{isReloading && (!isStreaming || !hasItems) ? (
147147
<InfraLoadingPanel
148148
width="100%"
149149
height="100%"

x-pack/legacy/plugins/infra/public/components/logging/log_text_stream/vertical_scroll_panel.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,10 @@ export class VerticalScrollPanel<Child> extends React.PureComponent<
163163
// Flag the scrollTop change that's about to happen as programmatic, as
164164
// opposed to being in direct response to user input
165165
this.nextScrollEventFromCenterTarget = true;
166-
scrollRef.current.scrollTop = targetDimensions.top + targetOffset - scrollViewHeight / 2;
167-
return true;
166+
const currentScrollTop = scrollRef.current.scrollTop;
167+
const newScrollTop = targetDimensions.top + targetOffset - scrollViewHeight / 2;
168+
scrollRef.current.scrollTop = newScrollTop;
169+
return currentScrollTop !== newScrollTop;
168170
}
169171
return false;
170172
};
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
import { ApolloClient } from 'apollo-client';
7+
import { TimeKey } from '../../../../common/time';
8+
import { logEntriesQuery } from '../../../graphql/log_entries.gql_query';
9+
import { useApolloClient } from '../../../utils/apollo_context';
10+
import { LogEntriesResponse } from '.';
11+
12+
const LOAD_CHUNK_SIZE = 200;
13+
14+
type LogEntriesGetter = (
15+
client: ApolloClient<{}>,
16+
countBefore: number,
17+
countAfter: number
18+
) => (params: {
19+
sourceId: string;
20+
timeKey: TimeKey | null;
21+
filterQuery: string | null;
22+
}) => Promise<LogEntriesResponse>;
23+
24+
const getLogEntries: LogEntriesGetter = (client, countBefore, countAfter) => async ({
25+
sourceId,
26+
timeKey,
27+
filterQuery,
28+
}) => {
29+
if (!timeKey) throw new Error('TimeKey is null');
30+
const result = await client.query({
31+
query: logEntriesQuery,
32+
variables: {
33+
sourceId,
34+
timeKey: { time: timeKey.time, tiebreaker: timeKey.tiebreaker },
35+
countBefore,
36+
countAfter,
37+
filterQuery,
38+
},
39+
fetchPolicy: 'no-cache',
40+
});
41+
// Workaround for Typescript. Since we're removing the GraphQL API in another PR or two
42+
// 7.6 goes out I don't think it's worth the effort to actually make this
43+
// typecheck pass
44+
const { source } = result.data as any;
45+
const { logEntriesAround } = source;
46+
return {
47+
entries: logEntriesAround.entries,
48+
entriesStart: logEntriesAround.start,
49+
entriesEnd: logEntriesAround.end,
50+
hasMoreAfterEnd: logEntriesAround.hasMoreAfter,
51+
hasMoreBeforeStart: logEntriesAround.hasMoreBefore,
52+
lastLoadedTime: new Date(),
53+
};
54+
};
55+
56+
export const useGraphQLQueries = () => {
57+
const client = useApolloClient();
58+
if (!client) throw new Error('Unable to get Apollo Client from context');
59+
return {
60+
getLogEntriesAround: getLogEntries(client, LOAD_CHUNK_SIZE, LOAD_CHUNK_SIZE),
61+
getLogEntriesBefore: getLogEntries(client, LOAD_CHUNK_SIZE, 0),
62+
getLogEntriesAfter: getLogEntries(client, 0, LOAD_CHUNK_SIZE),
63+
};
64+
};

0 commit comments

Comments
 (0)