diff --git a/src/plugins/discover/public/application/apps/main/components/layout/discover_layout.tsx b/src/plugins/discover/public/application/apps/main/components/layout/discover_layout.tsx index a10674323e5cb..8cc3be810a7ee 100644 --- a/src/plugins/discover/public/application/apps/main/components/layout/discover_layout.tsx +++ b/src/plugins/discover/public/application/apps/main/components/layout/discover_layout.tsx @@ -211,7 +211,14 @@ export function DiscoverLayout({ savedSearchRefetch$.next('reset'); }, [savedSearchRefetch$]); - const contentCentered = resultState === 'uninitialized'; + const onDisableFilters = useCallback(() => { + const disabledFilters = filterManager + .getFilters() + .map((filter) => ({ ...filter, meta: { ...filter.meta, disabled: true } })); + filterManager.setFilters(disabledFilters); + }, [filterManager]); + + const contentCentered = resultState === 'uninitialized' || resultState === 'none'; const showTimeCol = useMemo( () => !uiSettings.get(DOC_HIDE_TIME_COLUMN_SETTING, false) && !!indexPattern.timeFieldName, [uiSettings, indexPattern.timeFieldName] @@ -284,14 +291,19 @@ export function DiscoverLayout({ hasShadow={false} className={classNames('dscPageContent', { 'dscPageContent--centered': contentCentered, + 'dscPageContent--emptyPrompt': resultState === 'none', })} > {resultState === 'none' && ( !f.meta.disabled).length > 0 + } + onDisableFilters={onDisableFilters} /> )} {resultState === 'uninitialized' && ( diff --git a/src/plugins/discover/public/application/apps/main/components/no_results/_no_results.scss b/src/plugins/discover/public/application/apps/main/components/no_results/_no_results.scss index 6500593d57234..b4afc76bb607a 100644 --- a/src/plugins/discover/public/application/apps/main/components/no_results/_no_results.scss +++ b/src/plugins/discover/public/application/apps/main/components/no_results/_no_results.scss @@ -1,3 +1,8 @@ .dscNoResults { - padding: $euiSize; + padding: $euiSizeL; } + +.dscPageContent--emptyPrompt { + // override EUI specificity + max-width: $euiSizeXXL * 19 !important; // sass-lint:disable-line no-important +} \ No newline at end of file diff --git a/src/plugins/discover/public/application/apps/main/components/no_results/assets/no_results_illustration.scss b/src/plugins/discover/public/application/apps/main/components/no_results/assets/no_results_illustration.scss new file mode 100644 index 0000000000000..10e3b807559c8 --- /dev/null +++ b/src/plugins/discover/public/application/apps/main/components/no_results/assets/no_results_illustration.scss @@ -0,0 +1,19 @@ +.dscNoResultsIllustration__decor { + fill: lightOrDarkTheme(#E6EBF2, #294492); +} + +.dscNoResultsIllustration__fly { + fill: lightOrDarkTheme(#294492, #E6EBF2); +} + +@include euiBreakpoint('xs', 's') { + .dscNoResults__illustration > svg { + width: $euiSize * 12; + height: auto; + margin: 0 auto; + } + + .dscNoResults__title { + text-align: center; + } +} diff --git a/src/plugins/discover/public/application/apps/main/components/no_results/assets/no_results_illustration.tsx b/src/plugins/discover/public/application/apps/main/components/no_results/assets/no_results_illustration.tsx new file mode 100644 index 0000000000000..b96fad88f1b44 --- /dev/null +++ b/src/plugins/discover/public/application/apps/main/components/no_results/assets/no_results_illustration.tsx @@ -0,0 +1,124 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import './no_results_illustration.scss'; +import React from 'react'; + +export const NoResultsIllustration = () => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); diff --git a/src/plugins/discover/public/application/apps/main/components/no_results/no_results.test.tsx b/src/plugins/discover/public/application/apps/main/components/no_results/no_results.test.tsx index e7af82cf9504c..3a42a22d1d2eb 100644 --- a/src/plugins/discover/public/application/apps/main/components/no_results/no_results.test.tsx +++ b/src/plugins/discover/public/application/apps/main/components/no_results/no_results.test.tsx @@ -30,13 +30,15 @@ beforeEach(() => { jest.clearAllMocks(); }); -function mountAndFindSubjects(props: DiscoverNoResultsProps) { - const component = mountWithIntl(); +function mountAndFindSubjects(props: Omit) { + const component = mountWithIntl( {}} {...props} />); return { - mainMsg: findTestSubject(component, 'discoverNoResults').length > 0, - timeFieldMsg: findTestSubject(component, 'discoverNoResultsTimefilter').length > 0, - luceneMsg: findTestSubject(component, 'discoverNoResultsLucene').length > 0, - errorMsg: findTestSubject(component, 'discoverNoResultsError').length > 0, + mainMsg: findTestSubject(component, 'discoverNoResults').exists(), + timeFieldMsg: findTestSubject(component, 'discoverNoResultsTimefilter').exists(), + errorMsg: findTestSubject(component, 'discoverNoResultsError').exists(), + adjustSearch: findTestSubject(component, 'discoverNoResultsAdjustSearch').exists(), + adjustFilters: findTestSubject(component, 'discoverNoResultsAdjustFilters').exists(), + disableFiltersButton: findTestSubject(component, 'discoverNoResultsDisableFilters').exists(), }; } @@ -47,8 +49,10 @@ describe('DiscoverNoResults', () => { const result = mountAndFindSubjects({}); expect(result).toMatchInlineSnapshot(` Object { + "adjustFilters": false, + "adjustSearch": false, + "disableFiltersButton": false, "errorMsg": false, - "luceneMsg": false, "mainMsg": true, "timeFieldMsg": false, } @@ -62,8 +66,10 @@ describe('DiscoverNoResults', () => { }); expect(result).toMatchInlineSnapshot(` Object { + "adjustFilters": false, + "adjustSearch": false, + "disableFiltersButton": false, "errorMsg": false, - "luceneMsg": false, "mainMsg": true, "timeFieldMsg": true, } @@ -71,17 +77,16 @@ describe('DiscoverNoResults', () => { }); }); - describe('queryLanguage', () => { - test('supports lucene and renders doc link', () => { - const result = mountAndFindSubjects({ queryLanguage: 'lucene' }); - expect(result).toMatchInlineSnapshot(` - Object { - "errorMsg": false, - "luceneMsg": true, - "mainMsg": true, - "timeFieldMsg": false, - } - `); + describe('filter/query', () => { + test('shows "adjust search" message when having query', () => { + const result = mountAndFindSubjects({ hasQuery: true }); + expect(result).toHaveProperty('adjustSearch', true); + }); + + test('shows "adjust filters" message when having filters', () => { + const result = mountAndFindSubjects({ hasFilters: true }); + expect(result).toHaveProperty('adjustFilters', true); + expect(result).toHaveProperty('disableFiltersButton', true); }); }); @@ -91,12 +96,13 @@ describe('DiscoverNoResults', () => { const result = mountAndFindSubjects({ timeFieldName: 'awesome_time_field', error, - queryLanguage: 'lucene', }); expect(result).toMatchInlineSnapshot(` Object { + "adjustFilters": false, + "adjustSearch": false, + "disableFiltersButton": false, "errorMsg": true, - "luceneMsg": false, "mainMsg": false, "timeFieldMsg": false, } diff --git a/src/plugins/discover/public/application/apps/main/components/no_results/no_results.tsx b/src/plugins/discover/public/application/apps/main/components/no_results/no_results.tsx index 07deb45d1fda2..852c0860fd0c1 100644 --- a/src/plugins/discover/public/application/apps/main/components/no_results/no_results.tsx +++ b/src/plugins/discover/public/application/apps/main/components/no_results/no_results.tsx @@ -8,42 +8,62 @@ import React, { Fragment } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiButton, EuiCallOut, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import { getServices } from '../../../../../kibana_services'; +import { + EuiButton, + EuiCallOut, + EuiFlexGroup, + EuiFlexItem, + EuiSpacer, + EuiTitle, +} from '@elastic/eui'; import { DataPublicPluginStart } from '../../../../../../../data/public'; -import { getLuceneQueryMessage, getTimeFieldMessage } from './no_results_helper'; +import { AdjustSearch, getTimeFieldMessage } from './no_results_helper'; import './_no_results.scss'; +import { NoResultsIllustration } from './assets/no_results_illustration'; export interface DiscoverNoResultsProps { timeFieldName?: string; - queryLanguage?: string; error?: Error; data?: DataPublicPluginStart; + hasQuery?: boolean; + hasFilters?: boolean; + onDisableFilters: () => void; } export function DiscoverNoResults({ timeFieldName, - queryLanguage, error, data, + hasFilters, + hasQuery, + onDisableFilters, }: DiscoverNoResultsProps) { const callOut = !error ? ( - +

- } - color="warning" - iconType="help" - data-test-subj="discoverNoResults" - /> - {timeFieldName ? getTimeFieldMessage() : null} - {queryLanguage === 'lucene' - ? getLuceneQueryMessage(getServices().docLinks.links.query.luceneQuerySyntax) - : null} +

+ + + + + + + + {!!timeFieldName && getTimeFieldMessage()} + {(hasFilters || hasQuery) && ( + + )} + +
) : ( diff --git a/src/plugins/discover/public/application/apps/main/components/no_results/no_results_helper.tsx b/src/plugins/discover/public/application/apps/main/components/no_results/no_results_helper.tsx index 536cdfa42dfaa..25fff5f079619 100644 --- a/src/plugins/discover/public/application/apps/main/components/no_results/no_results_helper.tsx +++ b/src/plugins/discover/public/application/apps/main/components/no_results/no_results_helper.tsx @@ -8,131 +8,83 @@ import React, { Fragment } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiCode, EuiDescriptionList, EuiLink, EuiSpacer, EuiText } from '@elastic/eui'; +import { + EuiDescriptionList, + EuiDescriptionListTitle, + EuiLink, + EuiDescriptionListDescription, + EuiSpacer, +} from '@elastic/eui'; export function getTimeFieldMessage() { return ( - - -

+ + -

-

+ + -

-
+ +
); } -export function getLuceneQueryMessage(link: string) { - const searchExamples = [ - { - description: 200, - title: ( - - - - - - ), - }, - { - description: status:200, - title: ( - - - - - - ), - }, - { - description: status:[400 TO 499], - title: ( - - - - - - ), - }, - { - description: status:[400 TO 499] AND extension:PHP, - title: ( - - - - - - ), - }, - { - description: status:[400 TO 499] AND (extension:php OR extension:html), - title: ( - - - - - - ), - }, - ]; +interface AdjustSearchProps { + onDisableFilters: () => void; + hasFilters?: boolean; + hasQuery?: boolean; +} + +export function AdjustSearch({ hasFilters, hasQuery, onDisableFilters }: AdjustSearchProps) { return ( - - -

- -

-

- - - - ), - }} - /> -

-
- - - + {hasQuery && ( + <> + + + + + + + Try searching for a different combination of terms. + + + + )} + {hasFilters && ( + <> + + + + + + + Try removing or{' '} + + + + . + + + + )}
); } diff --git a/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_index_pattern_prompt/assets/index_pattern_illustration.scss b/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_index_pattern_prompt/assets/index_pattern_illustration.scss index cd0477aba7adf..8133b0dd487d6 100644 --- a/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_index_pattern_prompt/assets/index_pattern_illustration.scss +++ b/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_index_pattern_prompt/assets/index_pattern_illustration.scss @@ -6,4 +6,4 @@ &__dots { fill: $euiColorLightShade; } -} +} \ No newline at end of file diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index e70bf0d412356..dfc2b928ef431 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -1697,16 +1697,8 @@ "discover.localMenu.shareTitle": "共有", "discover.noResults.expandYourTimeRangeTitle": "時間範囲を拡大", "discover.noResults.queryMayNotMatchTitle": "1つ以上の表示されているインデックスに日付フィールドが含まれています。クエリが現在の時間範囲のデータと一致しないか、現在選択された時間範囲にデータがまったく存在しない可能性があります。データが存在する時間範囲に変えることができます。", - "discover.noResults.searchExamples.400to499StatusCodeExampleTitle": "400-499のすべてのステータスコードを検索", - "discover.noResults.searchExamples.400to499StatusCodeWithPhpExtensionExampleTitle": "400-499のphp拡張子のステータスコードを検索", - "discover.noResults.searchExamples.400to499StatusCodeWithPhpOrHtmlExtensionExampleTitle": "400-499のphpまたはhtml拡張子のステータスコードを検索", - "discover.noResults.searchExamples.anyField200StatusCodeExampleTitle": "いずれかのフィールドに数字200が含まれているリクエストを検索", - "discover.noResults.searchExamples.howTosearchForWebServerLogsDescription": "画面上部の検索バーは、ElasticsearchのLucene {queryStringSyntaxLink}サポートを利用します。新規フィールドにパースされたウェブサーバーログの検索方法の例は、次のとおりです。", "discover.noResults.searchExamples.noResultsBecauseOfError": "検索結果の取得中にエラーが発生しました", "discover.noResults.searchExamples.noResultsMatchSearchCriteriaTitle": "検索条件と一致する結果がありません。", - "discover.noResults.searchExamples.queryStringSyntaxLinkText": "クエリ文字列の構文", - "discover.noResults.searchExamples.refineYourQueryTitle": "クエリの調整", - "discover.noResults.searchExamples.statusField200StatusCodeExampleTitle": "ステータスフィールドの200を検索", "discover.noResultsFound": "結果が見つかりませんでした", "discover.notifications.invalidTimeRangeText": "指定された時間範囲が無効です。 (開始:'{from}'、終了:'{to}') ", "discover.notifications.invalidTimeRangeTitle": "無効な時間範囲", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 45380960d7023..ed46f466e3f45 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -1707,16 +1707,8 @@ "discover.localMenu.shareTitle": "共享", "discover.noResults.expandYourTimeRangeTitle": "展开时间范围", "discover.noResults.queryMayNotMatchTitle": "您正在查看的一个或多个索引包含日期字段。您的查询在当前时间范围内可能不匹配任何数据,也可能在当前选定的时间范围内没有任何数据。您可以尝试将时间范围更改为包含数据的时间范围。", - "discover.noResults.searchExamples.400to499StatusCodeExampleTitle": "查找所有介于 400-499 之间的状态代码", - "discover.noResults.searchExamples.400to499StatusCodeWithPhpExtensionExampleTitle": "查找状态代码 400-499 以及扩展名 php", - "discover.noResults.searchExamples.400to499StatusCodeWithPhpOrHtmlExtensionExampleTitle": "查找状态代码 400-499 以及扩展名 php 或 html", - "discover.noResults.searchExamples.anyField200StatusCodeExampleTitle": "查找任意字段包含数字 200 的请求", - "discover.noResults.searchExamples.howTosearchForWebServerLogsDescription": "顶部的搜索栏使用 Elasticsearch 对 Lucene {queryStringSyntaxLink} 的支持。以下是一些示例,说明如何搜索已解析成若干字段的 Web 服务器日志。", "discover.noResults.searchExamples.noResultsBecauseOfError": "检索搜索结果时遇到问题", "discover.noResults.searchExamples.noResultsMatchSearchCriteriaTitle": "没有任何结果匹配您的搜索条件", - "discover.noResults.searchExamples.queryStringSyntaxLinkText": "查询字符串语法", - "discover.noResults.searchExamples.refineYourQueryTitle": "优化您的查询", - "discover.noResults.searchExamples.statusField200StatusCodeExampleTitle": "在状态字段中查找 200", "discover.noResultsFound": "找不到结果", "discover.notifications.invalidTimeRangeText": "提供的时间范围无效。 (自:“{from}”,至:“{to}”) ", "discover.notifications.invalidTimeRangeTitle": "时间范围无效",