From 3c406dc03e7fa0fcf526abf957787fb3b5fc2ffe Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 20 Apr 2021 11:11:41 -0400 Subject: [PATCH] [Uptime] make index status api call unblocking (#97225) (#97630) Co-authored-by: Shahzad --- .../__snapshots__/empty_state.test.tsx.snap | 2056 ----------------- .../overview/empty_state/empty_state.test.tsx | 42 +- .../overview/empty_state/empty_state.tsx | 57 +- .../empty_state/empty_state_container.tsx | 11 +- .../monitor_list/monitor_list_container.tsx | 9 + .../overview/query_bar/query_bar.tsx | 4 +- .../overview/query_bar/use_index_pattern.ts | 8 +- .../overview/query_bar/use_query_bar.ts | 4 +- .../uptime/public/hooks/use_telemetry.ts | 4 +- .../plugins/uptime/public/pages/overview.tsx | 14 +- .../public/state/effects/index_pattern.ts | 4 +- 11 files changed, 83 insertions(+), 2130 deletions(-) delete mode 100644 x-pack/plugins/uptime/public/components/overview/empty_state/__snapshots__/empty_state.test.tsx.snap diff --git a/x-pack/plugins/uptime/public/components/overview/empty_state/__snapshots__/empty_state.test.tsx.snap b/x-pack/plugins/uptime/public/components/overview/empty_state/__snapshots__/empty_state.test.tsx.snap deleted file mode 100644 index c106d5d12e54b8..00000000000000 --- a/x-pack/plugins/uptime/public/components/overview/empty_state/__snapshots__/empty_state.test.tsx.snap +++ /dev/null @@ -1,2056 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`EmptyState component does not render empty state with appropriate base path and no docs 1`] = ` - - - , - } - } - /> - } - > - -
- -
- -
- - -
- - - - - - - - - - - - - } - body={ - -

- -

-

- -

-
- } - iconType="logoUptime" - title={ - -

- , - } - } - /> -

-
- } - > -
- - - - -
- - - - - -

- , - } - } - > - No uptime data found in index - - -

-
-
- -
- - -
-

- - If you have not setup heartbeat yet, you can setup heartbeat to start monitoring your services. - -

-

- - If you have setup heartbeat and confirmed data is being sent to Elasticsearch, update your index pattern settings and insure they are aligned with your Heartbeat config. - -

-
-
- - - - - -
- -
- - - - -`; - -exports[`EmptyState component doesn't render child components when count is falsy 1`] = ` - - - , - } - } - /> - } - > - -
- -
- -
- - -
- - - - - - - - - - - - - } - body={ - -

- -

-

- -

-
- } - iconType="logoUptime" - title={ - -

- , - } - } - /> -

-
- } - > -
- - - - -
- - - - - -

- , - } - } - > - No indices found matching pattern - - -

-
-
- -
- - -
-

- - If you have not setup heartbeat yet, you can setup heartbeat to start monitoring your services. - -

-

- - If you have setup heartbeat and confirmed data is being sent to Elasticsearch, update your index pattern settings and insure they are aligned with your Heartbeat config. - -

-
-
- - - - - -
- -
- - - - -`; - -exports[`EmptyState component notifies when index does not exist 1`] = ` - - - , - } - } - /> - } - > - -
- -
- -
- - -
- - - - - - - - - - - - - } - body={ - -

- -

-

- -

-
- } - iconType="logoUptime" - title={ - -

- , - } - } - /> -

-
- } - > -
- - - - -
- - - - - -

- , - } - } - > - No indices found matching pattern - - -

-
-
- -
- - -
-

- - If you have not setup heartbeat yet, you can setup heartbeat to start monitoring your services. - -

-

- - If you have setup heartbeat and confirmed data is being sent to Elasticsearch, update your index pattern settings and insure they are aligned with your Heartbeat config. - -

-
-
- - - - - -
- -
- - - - -`; - -exports[`EmptyState component renders child components when count is truthy 1`] = ` - - - -
- Foo -
-
- Bar -
-
- Baz -
-
-
-
-`; - -exports[`EmptyState component renders error message when an error occurs 1`] = ` - - - - -
- -
- -
- -

- There was an error fetching your data. -

- - } - iconColor="subdued" - iconType="securityApp" - title={ - -

- Error -

-
- } - > -
- - - - -
- - - - - -

- Error -

-
-
- -
- - -
-

- There was an error fetching your data. -

-
-
- - -
- -
- -
- -
- - - - -`; - -exports[`EmptyState component renders loading state if no errors or doc count 1`] = ` - - - - - - - -

- Loading… -

-
- - } - > -
- - - -
- - - - -
- - -

- Loading… -

-
-
- - - -
- - - - -`; diff --git a/x-pack/plugins/uptime/public/components/overview/empty_state/empty_state.test.tsx b/x-pack/plugins/uptime/public/components/overview/empty_state/empty_state.test.tsx index a617ba0db1eb33..d6a64e65110246 100644 --- a/x-pack/plugins/uptime/public/components/overview/empty_state/empty_state.test.tsx +++ b/x-pack/plugins/uptime/public/components/overview/empty_state/empty_state.test.tsx @@ -6,10 +6,11 @@ */ import React from 'react'; +import { screen } from '@testing-library/react'; import { EmptyStateComponent } from './empty_state'; import { StatesIndexStatus } from '../../../../common/runtime_types'; import { HttpFetchError, IHttpFetchError } from 'src/core/public'; -import { mountWithRouter, shallowWithRouter } from '../../../lib'; +import { render } from '../../../lib/helper/rtl_helpers'; describe('EmptyState component', () => { let statesIndexStatus: StatesIndexStatus; @@ -22,23 +23,26 @@ describe('EmptyState component', () => { }); it('renders child components when count is truthy', () => { - const component = shallowWithRouter( + render(
Foo
Bar
Baz
); - expect(component).toMatchSnapshot(); + + expect(screen.getByText('Foo')).toBeInTheDocument(); + expect(screen.getByText('Bar')).toBeInTheDocument(); + expect(screen.getByText('Baz')).toBeInTheDocument(); }); it(`doesn't render child components when count is falsy`, () => { - const component = mountWithRouter( + render( -
Shouldn't be rendered
+
Should not be rendered
); - expect(component).toMatchSnapshot(); + expect(screen.queryByText('Should not be rendered')).toBeNull(); }); it(`renders error message when an error occurs`, () => { @@ -47,21 +51,21 @@ describe('EmptyState component', () => { body: { message: 'There was an error fetching your data.' }, }), ]; - const component = mountWithRouter( + render( -
Shouldn't appear...
+
Should not appear...
); - expect(component).toMatchSnapshot(); + expect(screen.queryByText('Should not appear...')).toBeNull(); }); it('renders loading state if no errors or doc count', () => { - const component = mountWithRouter( + render(
Should appear even while loading...
); - expect(component).toMatchSnapshot(); + expect(screen.queryByText('Should appear even while loading...')).toBeInTheDocument(); }); it('does not render empty state with appropriate base path and no docs', () => { @@ -69,21 +73,25 @@ describe('EmptyState component', () => { docCount: 0, indexExists: true, }; - const component = mountWithRouter( + const text = 'If this is in the snapshot the test should fail'; + render( -
If this is in the snapshot the test should fail
+
{text}
); - expect(component).toMatchSnapshot(); + expect(screen.queryByText(text)).toBeNull(); }); it('notifies when index does not exist', () => { statesIndexStatus.indexExists = false; - const component = mountWithRouter( + + const text = 'This text should not render'; + + render( -
This text should not render
+
{text}
); - expect(component).toMatchSnapshot(); + expect(screen.queryByText(text)).toBeNull(); }); }); diff --git a/x-pack/plugins/uptime/public/components/overview/empty_state/empty_state.tsx b/x-pack/plugins/uptime/public/components/overview/empty_state/empty_state.tsx index 415d9cb5adcc6e..5a28c7c2592d73 100644 --- a/x-pack/plugins/uptime/public/components/overview/empty_state/empty_state.tsx +++ b/x-pack/plugins/uptime/public/components/overview/empty_state/empty_state.tsx @@ -33,36 +33,28 @@ export const EmptyStateComponent = ({ } const { indexExists, docCount } = statesIndexStatus ?? {}; - if (loading && (!indexExists || docCount === 0 || !statesIndexStatus)) { - return ; - } + const isLoading = loading && (!indexExists || docCount === 0 || !statesIndexStatus); + + const noIndicesMessage = ( + {settings?.heartbeatIndices}
}} + /> + ); + + const noUptimeDataMessage = ( + {settings?.heartbeatIndices} }} + /> + ); - if (!indexExists) { - return ( - {settings?.heartbeatIndices}
}} - /> - } - /> - ); - } else if (indexExists && docCount === 0) { - return ( - {settings?.heartbeatIndices} }} - /> - } - /> - ); + if (!indexExists && !isLoading) { + return ; + } else if (indexExists && docCount === 0 && !isLoading) { + return ; } /** * We choose to render the children any time the count > 0, even if @@ -71,6 +63,11 @@ export const EmptyStateComponent = ({ * jittery UX any time the components refresh. This way we'll keep the stale * state displayed during the fetching process. */ - return {children}; + return ( + + {isLoading && } +
{children}
+
+ ); // } }; diff --git a/x-pack/plugins/uptime/public/components/overview/empty_state/empty_state_container.tsx b/x-pack/plugins/uptime/public/components/overview/empty_state/empty_state_container.tsx index 83fd2f78278d26..562e45727dda7d 100644 --- a/x-pack/plugins/uptime/public/components/overview/empty_state/empty_state_container.tsx +++ b/x-pack/plugins/uptime/public/components/overview/empty_state/empty_state_container.tsx @@ -23,15 +23,18 @@ export const EmptyState: React.FC = ({ children }) => { const dispatch = useDispatch(); + const noDataInfo = !data || data?.docCount === 0 || data?.indexExists === false; + useEffect(() => { - if (!data || data?.docCount === 0 || data?.indexExists === false) { + if (noDataInfo) { + // only call when we haven't fetched it already dispatch(indexStatusAction.get()); } - // Don't add data , it will create endless loop - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [dispatch, lastRefresh]); + }, [dispatch, lastRefresh, noDataInfo]); useEffect(() => { + // using separate side effect, we want to call index status, + // every statue indices setting changes dispatch(indexStatusAction.get()); }, [dispatch, heartbeatIndices]); diff --git a/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_container.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_container.tsx index 4fd0a9c0f4b08b..835a89e8f72723 100644 --- a/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_container.tsx +++ b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_container.tsx @@ -12,6 +12,7 @@ import { esKuerySelector, monitorListSelector } from '../../../state/selectors'; import { MonitorListComponent } from './monitor_list'; import { useUrlParams } from '../../../hooks'; import { UptimeRefreshContext } from '../../../contexts'; +import { getConnectorsAction, getMonitorAlertsAction } from '../../../state/alerts/alerts'; export interface MonitorListProps { filters?: string; @@ -65,6 +66,14 @@ export const MonitorList: React.FC = (props) => { query, ]); + useEffect(() => { + dispatch(getMonitorAlertsAction.get()); + }, [dispatch]); + + useEffect(() => { + dispatch(getConnectorsAction.get()); + }, [dispatch]); + return ( { }; export const QueryBar = () => { - const { index_pattern: indexPattern } = useIndexPattern(); - const { search: urlValue } = useGetUrlParams(); const { query, setQuery } = useQueryBar(); + const { index_pattern: indexPattern } = useIndexPattern(query.language ?? SyntaxType.text); + const [inputVal, setInputVal] = useState(query.query); const isInValid = () => { diff --git a/x-pack/plugins/uptime/public/components/overview/query_bar/use_index_pattern.ts b/x-pack/plugins/uptime/public/components/overview/query_bar/use_index_pattern.ts index 49466cf8d00bf3..ab10afb5b231e5 100644 --- a/x-pack/plugins/uptime/public/components/overview/query_bar/use_index_pattern.ts +++ b/x-pack/plugins/uptime/public/components/overview/query_bar/use_index_pattern.ts @@ -9,16 +9,18 @@ import { useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { getIndexPattern } from '../../../state/actions'; import { selectIndexPattern } from '../../../state/selectors'; +import { SyntaxType } from './use_query_bar'; -export const useIndexPattern = () => { +export const useIndexPattern = (queryLanguage?: string) => { const dispatch = useDispatch(); const indexPattern = useSelector(selectIndexPattern); useEffect(() => { - if (!indexPattern.index_pattern) { + // we only use index pattern for kql queries + if (!indexPattern.index_pattern && (!queryLanguage || queryLanguage === SyntaxType.kuery)) { dispatch(getIndexPattern()); } - }, [indexPattern.index_pattern, dispatch]); + }, [indexPattern.index_pattern, dispatch, queryLanguage]); return indexPattern; }; diff --git a/x-pack/plugins/uptime/public/components/overview/query_bar/use_query_bar.ts b/x-pack/plugins/uptime/public/components/overview/query_bar/use_query_bar.ts index caf6b08e8fdeae..9e3691497eab6c 100644 --- a/x-pack/plugins/uptime/public/components/overview/query_bar/use_query_bar.ts +++ b/x-pack/plugins/uptime/public/components/overview/query_bar/use_query_bar.ts @@ -21,8 +21,6 @@ export enum SyntaxType { const SYNTAX_STORAGE = 'uptime:queryBarSyntax'; export const useQueryBar = () => { - const { index_pattern: indexPattern } = useIndexPattern(); - const dispatch = useDispatch(); const { absoluteDateRangeStart, absoluteDateRangeEnd, ...params } = useGetUrlParams(); @@ -46,6 +44,8 @@ export const useQueryBar = () => { } ); + const { index_pattern: indexPattern } = useIndexPattern(query.language); + const updateUrlParams = useUrlParams()[1]; const [esFilters, error] = useUpdateKueryString( diff --git a/x-pack/plugins/uptime/public/hooks/use_telemetry.ts b/x-pack/plugins/uptime/public/hooks/use_telemetry.ts index b9ec9cc5e55162..4ba0179bb54baf 100644 --- a/x-pack/plugins/uptime/public/hooks/use_telemetry.ts +++ b/x-pack/plugins/uptime/public/hooks/use_telemetry.ts @@ -38,6 +38,8 @@ export const useUptimeTelemetry = (page?: UptimePage) => { dateEnd: dateRangeEnd, autoRefreshEnabled: !autorefreshIsPaused, }; - apiService.post(API_URLS.LOG_PAGE_VIEW, params); + setTimeout(() => { + apiService.post(API_URLS.LOG_PAGE_VIEW, params); + }, 100); }, [autorefreshInterval, autorefreshIsPaused, dateRangeEnd, dateRangeStart, page]); }; diff --git a/x-pack/plugins/uptime/public/pages/overview.tsx b/x-pack/plugins/uptime/public/pages/overview.tsx index d478fe1bc1f372..846698bc390dba 100644 --- a/x-pack/plugins/uptime/public/pages/overview.tsx +++ b/x-pack/plugins/uptime/public/pages/overview.tsx @@ -6,17 +6,14 @@ */ import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; -import React, { useEffect } from 'react'; +import React from 'react'; import styled from 'styled-components'; -import { useDispatch } from 'react-redux'; import { useBreadcrumbs } from '../hooks/use_breadcrumbs'; import { useTrackPageview } from '../../../observability/public'; import { MonitorList } from '../components/overview/monitor_list/monitor_list_container'; import { EmptyState, FilterGroup } from '../components/overview'; import { StatusPanel } from '../components/overview/status_panel'; -import { getConnectorsAction, getMonitorAlertsAction } from '../state/alerts/alerts'; -import { useInitApp } from '../hooks/use_init_app'; import { QueryBar } from '../components/overview/query_bar/query_bar'; const EuiFlexItemStyled = styled(EuiFlexItem)` @@ -35,15 +32,6 @@ export const OverviewPageComponent = () => { useTrackPageview({ app: 'uptime', path: 'overview' }); useTrackPageview({ app: 'uptime', path: 'overview', delay: 15000 }); - useInitApp(); - - const dispatch = useDispatch(); - - useEffect(() => { - dispatch(getConnectorsAction.get()); - dispatch(getMonitorAlertsAction.get()); - }, [dispatch]); - useBreadcrumbs([]); // No extra breadcrumbs on overview return ( diff --git a/x-pack/plugins/uptime/public/state/effects/index_pattern.ts b/x-pack/plugins/uptime/public/state/effects/index_pattern.ts index 5142dcc6df0668..687d1fa413ba37 100644 --- a/x-pack/plugins/uptime/public/state/effects/index_pattern.ts +++ b/x-pack/plugins/uptime/public/state/effects/index_pattern.ts @@ -5,13 +5,13 @@ * 2.0. */ -import { takeLatest } from 'redux-saga/effects'; +import { takeLeading } from 'redux-saga/effects'; import { getIndexPattern, getIndexPatternSuccess, getIndexPatternFail } from '../actions'; import { fetchIndexPattern } from '../api'; import { fetchEffectFactory } from './fetch_effect'; export function* fetchIndexPatternEffect() { - yield takeLatest( + yield takeLeading( getIndexPattern, fetchEffectFactory(fetchIndexPattern, getIndexPatternSuccess, getIndexPatternFail) );