diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_error_log.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_error_log.test.tsx index e37f9abf67de3..ab390f82d022e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_error_log.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_error_log.test.tsx @@ -12,6 +12,7 @@ import { useKibana } from '../../../../common/lib/kibana'; import { EuiSuperDatePicker } from '@elastic/eui'; import { Rule } from '../../../../types'; +import { RefineSearchPrompt } from '../refine_search_prompt'; import { RuleErrorLog } from './rule_error_log'; const useKibanaMock = useKibana as jest.Mocked; @@ -309,4 +310,43 @@ describe('rule_error_log', () => { nowMock.mockRestore(); }); + + it('does not show the refine search prompt normally', async () => { + const wrapper = mountWithIntl( + + ); + + await act(async () => { + await nextTick(); + wrapper.update(); + }); + + expect(wrapper.find(RefineSearchPrompt).text()).toBeFalsy(); + }); + + it('shows the refine search prompt when our queries return too much data', async () => { + loadExecutionLogAggregationsMock.mockResolvedValue({ + ...mockLogResponse, + totalErrors: 1000, + }); + + const wrapper = mountWithIntl( + + ); + + await act(async () => { + await nextTick(); + wrapper.update(); + }); + + expect(wrapper.find(RefineSearchPrompt).text()).toEqual( + 'These are the first 1000 matching your search, refine your search to see others. Back to top.' + ); + }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_error_log.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_error_log.tsx index e47c65ff4e3e9..6eb6c732665e3 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_error_log.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_error_log.tsx @@ -22,6 +22,7 @@ import { } from '@elastic/eui'; import { useKibana } from '../../../../common/lib/kibana'; +import { RefineSearchPrompt } from '../refine_search_prompt'; import { LoadExecutionLogAggregationsProps } from '../../../lib/rule_api'; import { Rule } from '../../../../types'; import { IExecutionErrors } from '../../../../../../alerting/common'; @@ -256,6 +257,10 @@ export const RuleErrorLog = (props: RuleErrorLogProps) => { } }} /> + ); }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_event_log_list.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_event_log_list.test.tsx index 008e19bcb99bf..364afd22586e4 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_event_log_list.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_event_log_list.test.tsx @@ -14,6 +14,7 @@ import { useKibana } from '../../../../common/lib/kibana'; import { EuiSuperDatePicker, EuiDataGrid } from '@elastic/eui'; import { RuleEventLogListStatusFilter } from './rule_event_log_list_status_filter'; import { RuleEventLogList } from './rule_event_log_list'; +import { RefineSearchPrompt } from '../refine_search_prompt'; import { RULE_EXECUTION_DEFAULT_INITIAL_VISIBLE_COLUMNS } from '../../../constants'; import { Rule } from '../../../../types'; @@ -501,4 +502,43 @@ describe('rule_event_log_list', () => { ) ).toEqual([...RULE_EXECUTION_DEFAULT_INITIAL_VISIBLE_COLUMNS, 'num_active_alerts']); }); + + it('does not show the refine search prompt normally', async () => { + const wrapper = mountWithIntl( + + ); + + await act(async () => { + await nextTick(); + wrapper.update(); + }); + + expect(wrapper.find(RefineSearchPrompt).text()).toBeFalsy(); + }); + + it('shows the refine search prompt when our queries return too much data', async () => { + loadExecutionLogAggregationsMock.mockResolvedValue({ + ...mockLogResponse, + total: 1000, + }); + + const wrapper = mountWithIntl( + + ); + + await act(async () => { + await nextTick(); + wrapper.update(); + }); + + expect(wrapper.find(RefineSearchPrompt).text()).toEqual( + 'These are the first 1000 matching your search, refine your search to see others. Back to top.' + ); + }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_event_log_list.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_event_log_list.tsx index cc3bb0b20a203..852ad9e7c8024 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_event_log_list.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_event_log_list.tsx @@ -25,6 +25,7 @@ import { RULE_EXECUTION_DEFAULT_INITIAL_VISIBLE_COLUMNS } from '../../../constan import { RuleEventLogListStatusFilter } from './rule_event_log_list_status_filter'; import { RuleEventLogListCellRenderer, ColumnId } from './rule_event_log_list_cell_renderer'; +import { RefineSearchPrompt } from '../refine_search_prompt'; import { LoadExecutionLogAggregationsProps } from '../../../lib/rule_api'; import { Rule } from '../../../../types'; import { @@ -459,6 +460,10 @@ export const RuleEventLogList = (props: RuleEventLogListProps) => { sorting={sortingProps} pagination={paginationProps} /> + ); }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/refine_search_prompt.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/refine_search_prompt.tsx new file mode 100644 index 0000000000000..2dba47ecdc168 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/refine_search_prompt.tsx @@ -0,0 +1,58 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useMemo } from 'react'; +import { EuiLink, EuiText, useEuiTheme } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; + +interface RefineSearchFooterProps { + documentSize: number; + visibleDocumentSize?: number; + backToTopAnchor: string; +} + +const DEFAULT_VISIBLE_THRESHOLD = 500; + +export const RefineSearchPrompt = (props: RefineSearchFooterProps) => { + const { + documentSize = 0, + visibleDocumentSize = DEFAULT_VISIBLE_THRESHOLD, + backToTopAnchor, + } = props; + + const { euiTheme } = useEuiTheme(); + + const textStyles = useMemo( + () => ({ + backgroundColor: euiTheme.colors.lightestShade, + padding: `${euiTheme.size.m} ${euiTheme.size.base}`, + marginTop: `${euiTheme.size.xs}`, + }), + [euiTheme] + ); + + if (documentSize < visibleDocumentSize) { + return null; + } + + return ( + + +   + + + + + ); +};