From e3b286e0e793b1143542c72c13b2cdb46b93b3b2 Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Wed, 25 Sep 2024 13:01:40 -0700 Subject: [PATCH 01/23] Initial two-prompts --- .../prompt/no_data_views/impl/src/actions.tsx | 76 ------- .../impl/src/documentation_link.tsx | 5 +- .../impl/src/no_data_views.component.test.tsx | 36 +++- .../impl/src/no_data_views.component.tsx | 185 ++++++++++++++---- .../no_data_views/mocks/src/storybook.ts | 12 +- 5 files changed, 181 insertions(+), 133 deletions(-) delete mode 100644 packages/shared-ux/prompt/no_data_views/impl/src/actions.tsx diff --git a/packages/shared-ux/prompt/no_data_views/impl/src/actions.tsx b/packages/shared-ux/prompt/no_data_views/impl/src/actions.tsx deleted file mode 100644 index 6f2af97df6e04..0000000000000 --- a/packages/shared-ux/prompt/no_data_views/impl/src/actions.tsx +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import { EuiButton, EuiLink, EuiSpacer, EuiText } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n-react'; -import React from 'react'; - -interface NoDataButtonProps { - onClickCreate: (() => void) | undefined; - canCreateNewDataView: boolean; - onTryESQL?: () => void; - esqlDocLink?: string; -} - -const createDataViewText = i18n.translate('sharedUXPackages.noDataViewsPrompt.addDataViewText', { - defaultMessage: 'Create data view', -}); - -export const NoDataButtonLink = ({ - onClickCreate, - canCreateNewDataView, - onTryESQL, - esqlDocLink, -}: NoDataButtonProps) => { - if (!onTryESQL && !canCreateNewDataView) { - return null; - } - - return ( - <> - {canCreateNewDataView && ( - - {createDataViewText} - - )} - {canCreateNewDataView && onTryESQL && } - {onTryESQL && ( - - - - - ), - }} - /> - - - - - - )} - - ); -}; diff --git a/packages/shared-ux/prompt/no_data_views/impl/src/documentation_link.tsx b/packages/shared-ux/prompt/no_data_views/impl/src/documentation_link.tsx index 8e74bead6922e..d190764af947d 100644 --- a/packages/shared-ux/prompt/no_data_views/impl/src/documentation_link.tsx +++ b/packages/shared-ux/prompt/no_data_views/impl/src/documentation_link.tsx @@ -13,9 +13,10 @@ import { FormattedMessage } from '@kbn/i18n-react'; interface Props { href: string; + ['data-test-subj']?: string; } -export function DocumentationLink({ href }: Props) { +export function DocumentationLink({ href, ['data-test-subj']: dataTestSubj }: Props) { return (
@@ -28,7 +29,7 @@ export function DocumentationLink({ href }: Props) {
- + ', () => { ); - expect(component.find(EuiEmptyPrompt).length).toBe(1); - expect(component.find(EuiButton).length).toBe(1); - expect(component.find(DocumentationLink).length).toBe(1); + expect(component.find(EuiEmptyPrompt).length).toBe(2); + expect(component.find(EuiButton).length).toBe(2); + expect(component.find(DocumentationLink).length).toBe(2); + + expect(component.find('EuiButton[data-test-subj="createDataViewButton"]').length).toBe(1); + expect(component.find('DocumentationLink[data-test-subj="docLinkDataViews"]').length).toBe(1); + + expect(component.find('EuiButton[data-test-subj="tryESQLLink"]').length).toBe(1); + expect(component.find('DocumentationLink[data-test-subj="docLinkEsql"]').length).toBe(1); }); - test('does not render button if canCreateNewDataViews is false', () => { + test('does not render "Create data view" button if canCreateNewDataViews is false', () => { const component = mountWithIntl(); - expect(component.find(EuiButton).length).toBe(0); + expect(component.find('EuiButton[data-test-subj="createDataViewButton"]').length).toBe(0); }); - test('does not documentation link if linkToDocumentation is not provided', () => { + test('does not render documentation links if links to documentation are not provided', () => { const component = mountWithIntl( ); - expect(component.find(DocumentationLink).length).toBe(0); + expect(component.find('DocumentationLink[data-test-subj="docLinkDataViews"]').length).toBe(0); + expect(component.find('DocumentationLink[data-test-subj="docLinkEsql"]').length).toBe(0); }); test('onClickCreate', () => { @@ -51,4 +60,15 @@ describe('', () => { expect(onClickCreate).toHaveBeenCalledTimes(1); }); + + test('onClickTryEsql', () => { + const onClickTryEsql = jest.fn(); + const component = mountWithIntl( + + ); + + component.find('button[data-test-subj="tryESQLLink"]').simulate('click'); + + expect(onClickTryEsql).toHaveBeenCalledTimes(1); + }); }); diff --git a/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx b/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx index d5807891e734d..94b6377b5d0d0 100644 --- a/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx +++ b/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx @@ -7,48 +7,42 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import React from 'react'; import { css } from '@emotion/react'; +import React from 'react'; -import { EuiEmptyPrompt, EuiPanel } from '@elastic/eui'; +import { + EuiButton, + EuiEmptyPrompt, + EuiFlexGrid, + EuiFlexItem, + EuiSpacer, + EuiText, + EuiTextAlign, +} from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import { withSuspense } from '@kbn/shared-ux-utility'; import { NoDataViewsPromptComponentProps } from '@kbn/shared-ux-prompt-no-data-views-types'; import { DocumentationLink } from './documentation_link'; -import { NoDataButtonLink } from './actions'; // Using raw value because it is content dependent const MAX_WIDTH = 830; -/** - * A presentational component that is shown in cases when there are no data views created yet. - */ -export const NoDataViewsPrompt = ({ +type PromptAddDataViewsProps = Pick< + NoDataViewsPromptComponentProps, + 'onClickCreate' | 'canCreateNewDataView' | 'dataViewsDocLink' | 'emptyPromptColor' +>; + +const PromptAddDataViews = ({ onClickCreate, canCreateNewDataView, dataViewsDocLink, - onTryESQL, - esqlDocLink, - emptyPromptColor = 'plain', -}: NoDataViewsPromptComponentProps) => { - const title = canCreateNewDataView ? ( + emptyPromptColor, +}: PromptAddDataViewsProps) => { + const title = (

-
- -

- ) : ( -

-

); @@ -69,33 +63,140 @@ export const NoDataViewsPrompt = ({

); - const footer = dataViewsDocLink ? : undefined; - - // Load this illustration lazily - const Illustration = withSuspense( - React.lazy(() => - import('./data_view_illustration').then(({ DataViewIllustration }) => { - return { default: DataViewIllustration }; - }) - ), - - ); + const footer = dataViewsDocLink ? ( + + ) : undefined; - const icon = ; const actions = ( - + <> + {canCreateNewDataView && ( + + + + )} + ); return ( + ); +}; + +type PromptTryEsqlProps = Pick< + NoDataViewsPromptComponentProps, + 'onClickCreate' | 'onTryESQL' | 'esqlDocLink' | 'emptyPromptColor' +>; + +const PromptTryEsql = ({ onTryESQL, esqlDocLink, emptyPromptColor }: PromptTryEsqlProps) => { + const title = ( +

+ +

+ ); + + const body = ( +

+ +

+ ); + + const footer = esqlDocLink ? ( + + ) : undefined; + + const actions = ( + <> + {onTryESQL && ( + + + + )} + + ); + + return ( + ); }; + +/** + * A presentational component that is shown in cases when there are no data views created yet. + */ +export const NoDataViewsPrompt = ({ + onClickCreate, + canCreateNewDataView, + dataViewsDocLink, + onTryESQL, + esqlDocLink, + emptyPromptColor = 'plain', +}: NoDataViewsPromptComponentProps) => { + return ( + <> + + +

+ + + + + +

+
+
+ + + + + + + + + + + + + ); +}; diff --git a/packages/shared-ux/prompt/no_data_views/mocks/src/storybook.ts b/packages/shared-ux/prompt/no_data_views/mocks/src/storybook.ts index 63f46d2008077..cb306203980e4 100644 --- a/packages/shared-ux/prompt/no_data_views/mocks/src/storybook.ts +++ b/packages/shared-ux/prompt/no_data_views/mocks/src/storybook.ts @@ -34,17 +34,19 @@ export class StorybookMock extends AbstractStorybookMock< defaultValue: true, }, dataViewsDocLink: { - options: ['some/link', undefined], - control: { type: 'radio' }, - }, - esqlDocLink: { - options: ['some/link', undefined], + options: ['dataviews/link', undefined], control: { type: 'radio' }, + defaultValue: 'dataviews/link', }, canTryEsql: { control: 'boolean', defaultValue: true, }, + esqlDocLink: { + options: ['esql/link', undefined], + control: { type: 'radio' }, + defaultValue: 'esql/link', + }, }; dependencies = []; From 2bad3559f8c72ec9543780c992cab6cfc0571ff9 Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Wed, 25 Sep 2024 14:54:18 -0700 Subject: [PATCH 02/23] Use new SVG for the ESQL card --- .../impl/src/esql_illustration.svg | 1600 +++++++++++++++++ .../impl/src/esql_illustration.tsx | 24 + 2 files changed, 1624 insertions(+) create mode 100644 packages/shared-ux/prompt/no_data_views/impl/src/esql_illustration.svg create mode 100644 packages/shared-ux/prompt/no_data_views/impl/src/esql_illustration.tsx diff --git a/packages/shared-ux/prompt/no_data_views/impl/src/esql_illustration.svg b/packages/shared-ux/prompt/no_data_views/impl/src/esql_illustration.svg new file mode 100644 index 0000000000000..8720ca042937d --- /dev/null +++ b/packages/shared-ux/prompt/no_data_views/impl/src/esql_illustration.svg @@ -0,0 +1,1600 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/shared-ux/prompt/no_data_views/impl/src/esql_illustration.tsx b/packages/shared-ux/prompt/no_data_views/impl/src/esql_illustration.tsx new file mode 100644 index 0000000000000..a2da4c416ed55 --- /dev/null +++ b/packages/shared-ux/prompt/no_data_views/impl/src/esql_illustration.tsx @@ -0,0 +1,24 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import React from 'react'; + +import png from './esql_illustration.svg'; + +export const EsqlIllustration = () => { + return ( + ES|QL illustration + ); +}; From b2c675d9542c7eedc71d5fc87cf9f8a7a5446987 Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Wed, 25 Sep 2024 14:06:35 -0700 Subject: [PATCH 03/23] use EuiCard instead of EuiEmptyPrompt --- .../impl/src/data_view_illustration.tsx | 11 +- .../impl/src/no_data_views.component.test.tsx | 18 +- .../impl/src/no_data_views.component.tsx | 249 ++++++++++-------- .../translations/translations/fr-FR.json | 5 - .../translations/translations/ja-JP.json | 5 - .../translations/translations/zh-CN.json | 5 - 6 files changed, 163 insertions(+), 130 deletions(-) diff --git a/packages/shared-ux/prompt/no_data_views/impl/src/data_view_illustration.tsx b/packages/shared-ux/prompt/no_data_views/impl/src/data_view_illustration.tsx index cb817225254a9..099cdc87a21eb 100644 --- a/packages/shared-ux/prompt/no_data_views/impl/src/data_view_illustration.tsx +++ b/packages/shared-ux/prompt/no_data_views/impl/src/data_view_illustration.tsx @@ -26,5 +26,14 @@ export const DataViewIllustration = () => { } `; - return Data view illustration; + return ( + Data view illustration + ); }; diff --git a/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.test.tsx b/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.test.tsx index d8833eec02f31..75363c80b67b5 100644 --- a/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.test.tsx +++ b/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.test.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { mountWithIntl } from '@kbn/test-jest-helpers'; -import { EuiButton, EuiEmptyPrompt } from '@elastic/eui'; +import { EuiButton, EuiCard } from '@elastic/eui'; import { NoDataViewsPrompt } from './no_data_views.component'; import { DocumentationLink } from './documentation_link'; @@ -24,7 +24,7 @@ describe('', () => { onTryESQL={jest.fn()} /> ); - expect(component.find(EuiEmptyPrompt).length).toBe(2); + expect(component.find(EuiCard).length).toBe(2); expect(component.find(EuiButton).length).toBe(2); expect(component.find(DocumentationLink).length).toBe(2); @@ -53,10 +53,14 @@ describe('', () => { test('onClickCreate', () => { const onClickCreate = jest.fn(); const component = mountWithIntl( - + ); - component.find('button').simulate('click'); + component.find('button[data-test-subj="createDataViewButton"]').simulate('click'); expect(onClickCreate).toHaveBeenCalledTimes(1); }); @@ -64,7 +68,11 @@ describe('', () => { test('onClickTryEsql', () => { const onClickTryEsql = jest.fn(); const component = mountWithIntl( - + ); component.find('button[data-test-subj="tryESQLLink"]').simulate('click'); diff --git a/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx b/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx index 94b6377b5d0d0..788bca54bdafb 100644 --- a/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx +++ b/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx @@ -12,62 +12,70 @@ import React from 'react'; import { EuiButton, - EuiEmptyPrompt, - EuiFlexGrid, + EuiCard, + EuiFlexGroup, EuiFlexItem, + EuiHorizontalRule, + EuiPanel, EuiSpacer, EuiText, EuiTextAlign, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; +import { withSuspense } from '@kbn/shared-ux-utility'; import { NoDataViewsPromptComponentProps } from '@kbn/shared-ux-prompt-no-data-views-types'; +import { i18n } from '@kbn/i18n'; import { DocumentationLink } from './documentation_link'; -// Using raw value because it is content dependent -const MAX_WIDTH = 830; - -type PromptAddDataViewsProps = Pick< - NoDataViewsPromptComponentProps, - 'onClickCreate' | 'canCreateNewDataView' | 'dataViewsDocLink' | 'emptyPromptColor' ->; +// max width value to use in pixels +const MAX_WIDTH = 770; const PromptAddDataViews = ({ onClickCreate, canCreateNewDataView, dataViewsDocLink, emptyPromptColor, -}: PromptAddDataViewsProps) => { +}: Pick< + NoDataViewsPromptComponentProps, + 'onClickCreate' | 'canCreateNewDataView' | 'dataViewsDocLink' | 'emptyPromptColor' +>) => { + // Load this illustration lazily + const Illustration = withSuspense( + React.lazy(() => + import('./data_view_illustration').then(({ DataViewIllustration }) => { + return { default: DataViewIllustration }; + }) + ), + + ); + + const icon = ; + const title = ( -

- -

+ ); - const body = canCreateNewDataView ? ( -

- -

- ) : ( -

- -

+ const description = ( + <> + {canCreateNewDataView ? ( + + ) : ( + + )} + ); const footer = dataViewsDocLink ? ( - - ) : undefined; - - const actions = ( <> {canCreateNewDataView && ( @@ -77,51 +85,56 @@ const PromptAddDataViews = ({ /> )} + + - ); + ) : undefined; return ( - ); }; -type PromptTryEsqlProps = Pick< +const PromptTryEsql = ({ + onTryESQL, + esqlDocLink, + emptyPromptColor, +}: Pick< NoDataViewsPromptComponentProps, 'onClickCreate' | 'onTryESQL' | 'esqlDocLink' | 'emptyPromptColor' ->; +>) => { + // Load this illustration lazily + const Illustration = withSuspense( + React.lazy(() => + import('./esql_illustration').then(({ EsqlIllustration }) => { + return { default: EsqlIllustration }; + }) + ), + + ); + + const icon = ; -const PromptTryEsql = ({ onTryESQL, esqlDocLink, emptyPromptColor }: PromptTryEsqlProps) => { const title = ( -

- -

+ ); - const body = ( -

- -

+ const description = ( + ); - const footer = esqlDocLink ? ( - - ) : undefined; - - const actions = ( + const footer = ( <> {onTryESQL && ( @@ -131,14 +144,22 @@ const PromptTryEsql = ({ onTryESQL, esqlDocLink, emptyPromptColor }: PromptTryEs /> )} + + {esqlDocLink && } ); return ( - ); }; @@ -155,48 +176,58 @@ export const NoDataViewsPrompt = ({ emptyPromptColor = 'plain', }: NoDataViewsPromptComponentProps) => { return ( - <> - - -

- - - + + + + +

- -

-
-
- - - - - - - - - - - - + + + + +

+
+
+ + + + + + + + + + + + + ); }; diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 28b028fdc3481..7451ad7ea472d 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -7277,9 +7277,6 @@ "sharedUXPackages.fileUpload.uploadCompleteButtonLabel": "Chargement terminé", "sharedUXPackages.fileUpload.uploadDoneToolTipContent": "Votre fichier a bien été chargé !", "sharedUXPackages.fileUpload.uploadingButtonLabel": "Chargement", - "sharedUXPackages.no_data_views.esqlButtonLabel": "Langue : ES|QL", - "sharedUXPackages.no_data_views.esqlDocsLink": "En savoir plus.", - "sharedUXPackages.no_data_views.esqlMessage": "Vous pouvez aussi rechercher vos données en utilisant directement ES|QL. {docsLink}", "sharedUXPackages.noDataConfig.addIntegrationsDescription": "Utilisez Elastic Agent pour collecter des données et créer des solutions Analytics.", "sharedUXPackages.noDataConfig.addIntegrationsTitle": "Ajouter des intégrations", "sharedUXPackages.noDataConfig.analytics": "Analyse", @@ -7301,8 +7298,6 @@ "sharedUXPackages.noDataViewsPrompt.dataViewExplanation": "Les vues de données identifient les données Elasticsearch que vous souhaitez explorer. Vous pouvez faire pointer des vues de données vers un ou plusieurs flux de données, index et alias d'index, tels que vos données de log d'hier, ou vers tous les index contenant vos données de log.", "sharedUXPackages.noDataViewsPrompt.learnMore": "Envie d'en savoir plus ?", "sharedUXPackages.noDataViewsPrompt.noPermission.dataViewExplanation": "Les vues de données identifient les données Elasticsearch que vous souhaitez explorer. Pour créer des vues de données, demandez les autorisations requises à votre administrateur.", - "sharedUXPackages.noDataViewsPrompt.noPermission.title": "Vous devez disposer d'une autorisation pour pouvoir créer des vues de données", - "sharedUXPackages.noDataViewsPrompt.nowCreate": "Créez à présent une vue de données.", "sharedUXPackages.noDataViewsPrompt.readDocumentation": "Lisez les documents", "sharedUXPackages.noDataViewsPrompt.youHaveData": "Vous avez des données dans Elasticsearch.", "sharedUXPackages.prompt.errors.notFound.body": "Désolé, la page que vous recherchez est introuvable. Elle a peut-être été retirée ou renommée, ou peut-être qu'elle n'a jamais existé.", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 7df47bf1efe61..0f8bdcaa3c56f 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -7031,9 +7031,6 @@ "sharedUXPackages.fileUpload.uploadCompleteButtonLabel": "アップロード完了", "sharedUXPackages.fileUpload.uploadDoneToolTipContent": "ファイルは正常にアップロードされました。", "sharedUXPackages.fileUpload.uploadingButtonLabel": "アップロード中", - "sharedUXPackages.no_data_views.esqlButtonLabel": "言語:ES|QL", - "sharedUXPackages.no_data_views.esqlDocsLink": "詳細情報", - "sharedUXPackages.no_data_views.esqlMessage": "あるいは、直接ES|QLを使用してデータをクエリできます。{docsLink}", "sharedUXPackages.noDataConfig.addIntegrationsDescription": "Elasticエージェントを使用して、データを収集し、分析ソリューションを構築します。", "sharedUXPackages.noDataConfig.addIntegrationsTitle": "統合の追加", "sharedUXPackages.noDataConfig.analytics": "分析", @@ -7055,8 +7052,6 @@ "sharedUXPackages.noDataViewsPrompt.dataViewExplanation": "データビューは、探索するElasticsearchデータを特定します。昨日からのログデータ、ログデータを含むすべてのインデックスなど、1つ以上のデータストリーム、インデックス、インデックスエイリアスをデータビューで参照できます。", "sharedUXPackages.noDataViewsPrompt.learnMore": "詳細について", "sharedUXPackages.noDataViewsPrompt.noPermission.dataViewExplanation": "データビューは、探索するElasticsearchデータを特定します。データビューを作成するには、必要な権限を管理者に依頼してください。", - "sharedUXPackages.noDataViewsPrompt.noPermission.title": "データビューを作成するための権限が必要です。", - "sharedUXPackages.noDataViewsPrompt.nowCreate": "ここでデータビューを作成します。", "sharedUXPackages.noDataViewsPrompt.readDocumentation": "ドキュメントを読む", "sharedUXPackages.noDataViewsPrompt.youHaveData": "Elasticsearchにデータがあります。", "sharedUXPackages.prompt.errors.notFound.body": "申し訳ございません。お探しのページは見つかりませんでした。削除または名前変更されたか、そもそも存在していなかった可能性があります。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 581eb4ace7963..6201276610a0e 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -7046,9 +7046,6 @@ "sharedUXPackages.fileUpload.uploadCompleteButtonLabel": "上传完成", "sharedUXPackages.fileUpload.uploadDoneToolTipContent": "您的文件已成功上传!", "sharedUXPackages.fileUpload.uploadingButtonLabel": "正在上传", - "sharedUXPackages.no_data_views.esqlButtonLabel": "语言:ES|QL", - "sharedUXPackages.no_data_views.esqlDocsLink": "了解详情。", - "sharedUXPackages.no_data_views.esqlMessage": "或者,您可以直接使用 ES|QL 查询数据。{docsLink}", "sharedUXPackages.noDataConfig.addIntegrationsDescription": "使用 Elastic 代理收集数据并增建分析解决方案。", "sharedUXPackages.noDataConfig.addIntegrationsTitle": "添加集成", "sharedUXPackages.noDataConfig.analytics": "分析", @@ -7070,8 +7067,6 @@ "sharedUXPackages.noDataViewsPrompt.dataViewExplanation": "数据视图标识您要浏览的 Elasticsearch 数据。您可以将数据视图指向一个或多个数据流、索引和索引别名(例如昨天的日志数据),或包含日志数据的所有索引。", "sharedUXPackages.noDataViewsPrompt.learnMore": "希望了解详情?", "sharedUXPackages.noDataViewsPrompt.noPermission.dataViewExplanation": "数据视图标识您要浏览的 Elasticsearch 数据。要创建数据视图,请联系管理员获得所需权限。", - "sharedUXPackages.noDataViewsPrompt.noPermission.title": "您需要权限以创建数据视图", - "sharedUXPackages.noDataViewsPrompt.nowCreate": "现在,创建数据视图。", "sharedUXPackages.noDataViewsPrompt.readDocumentation": "阅读文档", "sharedUXPackages.noDataViewsPrompt.youHaveData": "您在 Elasticsearch 中有数据。", "sharedUXPackages.prompt.errors.notFound.body": "抱歉,找不到您要查找的页面。该页面可能已移除、重命名,或可能根本不存在。", From 4675e30aa600c288f736122e48016b2825fab835 Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Wed, 25 Sep 2024 17:21:59 -0700 Subject: [PATCH 04/23] Wrap the index pattern management react render tree with NoDataViewsPromptKibanaProvider --- .../no_data_views/impl/src/no_data_views.tsx | 2 + .../prompt/no_data_views/types/index.d.ts | 2 + src/plugins/data_view_management/kibana.jsonc | 1 + .../mount_management_section.tsx | 42 +++++++++++-------- .../data_view_management/public/plugin.ts | 2 + .../data_view_management/tsconfig.json | 1 + 6 files changed, 33 insertions(+), 17 deletions(-) diff --git a/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.tsx b/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.tsx index 43ae5f267ea90..bd50f4e2263d5 100644 --- a/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.tsx +++ b/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.tsx @@ -29,6 +29,7 @@ export const NoDataViewsPrompt = ({ onDataViewCreated, onESQLNavigationComplete, allowAdHocDataView = false, + emptyPromptColor, }: NoDataViewsPromptProps) => { const { canCreateNewDataView, openDataViewEditor, dataViewsDocLink, onTryESQL, esqlDocLink } = useServices(); @@ -82,6 +83,7 @@ export const NoDataViewsPrompt = ({ canCreateNewDataView, dataViewsDocLink, esqlDocLink, + emptyPromptColor, onTryESQL: onTryESQL ? () => { onTryESQL(); diff --git a/packages/shared-ux/prompt/no_data_views/types/index.d.ts b/packages/shared-ux/prompt/no_data_views/types/index.d.ts index 15f9f53c59fe6..5695b15fb078b 100644 --- a/packages/shared-ux/prompt/no_data_views/types/index.d.ts +++ b/packages/shared-ux/prompt/no_data_views/types/index.d.ts @@ -106,4 +106,6 @@ export interface NoDataViewsPromptProps { onDataViewCreated: (dataView: unknown) => void; /** Handler for when try ES|QL is clicked and user has been navigated to try ES|QL in discover. */ onESQLNavigationComplete?: () => void; + /** Empty prompt color **/ + emptyPromptColor?: PanelColor; } diff --git a/src/plugins/data_view_management/kibana.jsonc b/src/plugins/data_view_management/kibana.jsonc index 479e357804140..5b827868ee1e8 100644 --- a/src/plugins/data_view_management/kibana.jsonc +++ b/src/plugins/data_view_management/kibana.jsonc @@ -20,6 +20,7 @@ ], "optionalPlugins": [ "noDataPage", + "share", "spaces" ], "requiredBundles": [ diff --git a/src/plugins/data_view_management/public/management_app/mount_management_section.tsx b/src/plugins/data_view_management/public/management_app/mount_management_section.tsx index 995d5ed977ed3..bcbbdc29e623c 100644 --- a/src/plugins/data_view_management/public/management_app/mount_management_section.tsx +++ b/src/plugins/data_view_management/public/management_app/mount_management_section.tsx @@ -17,6 +17,7 @@ import { StartServicesAccessor } from '@kbn/core/public'; import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render'; import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; import { ManagementAppMountParams } from '@kbn/management-plugin/public'; +import { NoDataViewsPromptKibanaProvider } from '@kbn/shared-ux-prompt-no-data-views'; import { IndexPatternTableWithRouter, EditIndexPatternContainer, @@ -64,6 +65,7 @@ export async function mountManagementSection( dataViews, fieldFormats, unifiedSearch, + share, spaces, savedObjectsManagement, }, @@ -115,23 +117,29 @@ export async function mountManagementSection( ReactDOM.render( - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + , params.element diff --git a/src/plugins/data_view_management/public/plugin.ts b/src/plugins/data_view_management/public/plugin.ts index 77e8c12a13ad0..0d03dc8896fd1 100644 --- a/src/plugins/data_view_management/public/plugin.ts +++ b/src/plugins/data_view_management/public/plugin.ts @@ -21,6 +21,7 @@ import { ManagementSetup } from '@kbn/management-plugin/public'; import { SavedObjectsManagementPluginStart } from '@kbn/saved-objects-management-plugin/public'; import { SpacesPluginStart } from '@kbn/spaces-plugin/public'; import { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; +import { SharePluginStart } from '@kbn/share-plugin/public'; export interface IndexPatternManagementSetupDependencies { management: ManagementSetup; @@ -34,6 +35,7 @@ export interface IndexPatternManagementStartDependencies { dataViewEditor: DataViewEditorStart; dataViews: DataViewsPublicPluginStart; fieldFormats: FieldFormatsStart; + share?: SharePluginStart; spaces?: SpacesPluginStart; unifiedSearch: UnifiedSearchPublicPluginStart; savedObjectsManagement: SavedObjectsManagementPluginStart; diff --git a/src/plugins/data_view_management/tsconfig.json b/src/plugins/data_view_management/tsconfig.json index ea0c96cc66b74..9857dd44829fa 100644 --- a/src/plugins/data_view_management/tsconfig.json +++ b/src/plugins/data_view_management/tsconfig.json @@ -45,6 +45,7 @@ "@kbn/code-editor", "@kbn/react-kibana-mount", "@kbn/rollup", + "@kbn/share-plugin", ], "exclude": [ "target/**/*", From f6ab5d41fb6c2096196a8e63a3a1eb9cf1d23ed9 Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Sun, 29 Sep 2024 21:38:18 -0700 Subject: [PATCH 05/23] useOnTryESQL in data_view_management --- .../index_pattern_table/index_pattern_table.tsx | 14 ++++++++++++-- .../management_app/mount_management_section.tsx | 2 ++ src/plugins/data_view_management/public/types.ts | 2 ++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/plugins/data_view_management/public/components/index_pattern_table/index_pattern_table.tsx b/src/plugins/data_view_management/public/components/index_pattern_table/index_pattern_table.tsx index cb93e01d1cc15..f024a61c319a8 100644 --- a/src/plugins/data_view_management/public/components/index_pattern_table/index_pattern_table.tsx +++ b/src/plugins/data_view_management/public/components/index_pattern_table/index_pattern_table.tsx @@ -26,7 +26,7 @@ import { RouteComponentProps, useLocation, withRouter } from 'react-router-dom'; import useObservable from 'react-use/lib/useObservable'; import { reactRouterNavigate, useKibana } from '@kbn/kibana-react-plugin/public'; -import { NoDataViewsPromptComponent } from '@kbn/shared-ux-prompt-no-data-views'; +import { NoDataViewsPromptComponent, useOnTryESQL } from '@kbn/shared-ux-prompt-no-data-views'; import type { SpacesContextProps } from '@kbn/spaces-plugin/public'; import { DataViewType } from '@kbn/data-views-plugin/public'; import { RollupDeprecationTooltip } from '@kbn/rollup'; @@ -86,6 +86,7 @@ export const IndexPatternTable = ({ application, chrome, dataViews, + share, IndexPatternEditor, spaces, overlays, @@ -116,6 +117,12 @@ export const IndexPatternTable = ({ const hasDataView = useObservable(dataViewController.hasDataView$, defaults.hasDataView); const hasESData = useObservable(dataViewController.hasESData$, defaults.hasEsData); + const useOnTryESQLParams = { + locatorClient: share?.url.locators, + navigateToApp: application.navigateToApp, + }; + const onTryESQL = useOnTryESQL(useOnTryESQLParams); + const handleOnChange = ({ queryText, error }: { queryText: string; error: unknown }) => { if (!error) { setQuery(queryText); @@ -362,7 +369,7 @@ export const IndexPatternTable = ({ ); - if (!hasDataView) + if (!hasDataView) { displayIndexPatternSection = ( <> @@ -370,10 +377,13 @@ export const IndexPatternTable = ({ onClickCreate={() => setShowCreateDialog(true)} canCreateNewDataView={application.capabilities.indexPatterns.save as boolean} dataViewsDocLink={docLinks.links.indexPatterns.introduction} + onTryESQL={onTryESQL} + esqlDocLink={docLinks.links.query.queryESQL} emptyPromptColor={'subdued'} /> ); + } if (!hasDataView && !hasESData) displayIndexPatternSection = ( <> diff --git a/src/plugins/data_view_management/public/management_app/mount_management_section.tsx b/src/plugins/data_view_management/public/management_app/mount_management_section.tsx index bcbbdc29e623c..96e5ae6c96b0c 100644 --- a/src/plugins/data_view_management/public/management_app/mount_management_section.tsx +++ b/src/plugins/data_view_management/public/management_app/mount_management_section.tsx @@ -71,6 +71,7 @@ export async function mountManagementSection( }, indexPatternManagementStart, ] = await getStartServices(); + const canSave = dataViews.getCanSaveSync(); if (!canSave) { @@ -91,6 +92,7 @@ export async function mountManagementSection( chrome, uiSettings, settings, + share, notifications, overlays, unifiedSearch, diff --git a/src/plugins/data_view_management/public/types.ts b/src/plugins/data_view_management/public/types.ts index b7a9279de8001..161ee3b1e21de 100644 --- a/src/plugins/data_view_management/public/types.ts +++ b/src/plugins/data_view_management/public/types.ts @@ -29,6 +29,7 @@ import type { SpacesPluginStart } from '@kbn/spaces-plugin/public'; import type { SavedObjectsManagementPluginStart } from '@kbn/saved-objects-management-plugin/public'; import type { SettingsStart } from '@kbn/core-ui-settings-browser'; import type { NoDataPagePluginSetup } from '@kbn/no-data-page-plugin/public'; +import { SharePluginStart } from '@kbn/share-plugin/public'; import type { IndexPatternManagementStart } from '.'; import type { DataViewMgmtService } from './management_app/data_view_management_service'; @@ -53,6 +54,7 @@ export interface IndexPatternManagmentContext extends StartServices { fieldFormatEditors: IndexPatternFieldEditorStart['fieldFormatEditors']; IndexPatternEditor: DataViewEditorStart['IndexPatternEditorComponent']; fieldFormats: FieldFormatsStart; + share?: SharePluginStart; spaces?: SpacesPluginStart; savedObjectsManagement: SavedObjectsManagementPluginStart; noDataPage?: NoDataPagePluginSetup; From 9edb0cdaa075a8b1835c88f03549f76d5476b21e Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Sun, 29 Sep 2024 21:15:23 -0700 Subject: [PATCH 06/23] Functional tests for ESQL + Dashboard/No-Data --- .../group6/dashboard_esql_no_data.ts | 38 +++++++++++++++++++ .../functional/apps/dashboard/group6/index.ts | 1 + .../apps/management/data_views/_try_esql.ts | 32 ++++++++++++++++ test/functional/apps/management/index.ts | 1 + 4 files changed, 72 insertions(+) create mode 100644 test/functional/apps/dashboard/group6/dashboard_esql_no_data.ts create mode 100644 test/functional/apps/management/data_views/_try_esql.ts diff --git a/test/functional/apps/dashboard/group6/dashboard_esql_no_data.ts b/test/functional/apps/dashboard/group6/dashboard_esql_no_data.ts new file mode 100644 index 0000000000000..550b872674317 --- /dev/null +++ b/test/functional/apps/dashboard/group6/dashboard_esql_no_data.ts @@ -0,0 +1,38 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../../ftr_provider_context'; + +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const kibanaServer = getService('kibanaServer'); + const testSubjects = getService('testSubjects'); + const { dashboard } = getPageObjects(['dashboard']); + + describe('dashboard from esql button on no-data-prompt', () => { + before(async () => { + await kibanaServer.savedObjects.cleanStandardList(); + }); + + it('enables user to create a dashboard with ES|QL from no-data-prompt', async () => { + await dashboard.navigateToApp(); + + await testSubjects.existOrFail('noDataViewsPrompt'); + await testSubjects.click('tryESQLLink'); + + // ensure we have landed on Discover + await testSubjects.existOrFail('switch-to-dataviews'); // "Switch to Classic" app menu button + await testSubjects.existOrFail('discoverNewButton'); + await testSubjects.existOrFail('discoverOpenButton'); + + const codeEditor = await testSubjects.find('kibanaCodeEditor'); + expect(await codeEditor.getAttribute('innerText')).to.contain('FROM logs* | LIMIT 10'); + }); + }); +} diff --git a/test/functional/apps/dashboard/group6/index.ts b/test/functional/apps/dashboard/group6/index.ts index 302ca2e0480a0..340c9b425571b 100644 --- a/test/functional/apps/dashboard/group6/index.ts +++ b/test/functional/apps/dashboard/group6/index.ts @@ -37,5 +37,6 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./dashboard_snapshots')); loadTestFile(require.resolve('./embeddable_library')); loadTestFile(require.resolve('./dashboard_esql_chart')); + loadTestFile(require.resolve('./dashboard_esql_no_data')); }); } diff --git a/test/functional/apps/management/data_views/_try_esql.ts b/test/functional/apps/management/data_views/_try_esql.ts new file mode 100644 index 0000000000000..089f8daaa27a5 --- /dev/null +++ b/test/functional/apps/management/data_views/_try_esql.ts @@ -0,0 +1,32 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../../ftr_provider_context'; + +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const PageObjects = getPageObjects(['settings', 'common']); + const testSubjects = getService('testSubjects'); + + describe('No Data Views: Try ES|QL', () => { + it('navigates to Discover and presents an ES|QL query', async () => { + await PageObjects.settings.navigateTo(); + await PageObjects.settings.clickKibanaIndexPatterns(); + await testSubjects.click('tryESQLLink'); + + // ensure we have landed on Discover + await testSubjects.existOrFail('switch-to-dataviews'); // "Switch to Classic" app menu button + await testSubjects.existOrFail('discoverNewButton'); + await testSubjects.existOrFail('discoverOpenButton'); + + const codeEditor = await testSubjects.find('kibanaCodeEditor'); + expect(await codeEditor.getAttribute('innerText')).to.contain('FROM logs* | LIMIT 10'); + }); + }); +} diff --git a/test/functional/apps/management/index.ts b/test/functional/apps/management/index.ts index f3d26f2e1c6d7..2300543f06d51 100644 --- a/test/functional/apps/management/index.ts +++ b/test/functional/apps/management/index.ts @@ -38,6 +38,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./data_views/_legacy_url_redirect')); loadTestFile(require.resolve('./data_views/_exclude_index_pattern')); loadTestFile(require.resolve('./data_views/_index_pattern_filter')); + loadTestFile(require.resolve('./data_views/_try_esql')); loadTestFile(require.resolve('./data_views/_scripted_fields_filter')); loadTestFile(require.resolve('./_import_objects')); loadTestFile(require.resolve('./data_views/_test_huge_fields')); From db7cbaeb42bdea66b21488f58b9e99d96cedd9fb Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Sun, 29 Sep 2024 00:08:21 -0700 Subject: [PATCH 07/23] add onTryESQL prop to AnalyticsNoDataPage --- .../src/analytics_no_data_page.component.tsx | 12 ++- .../src/analytics_no_data_page.stories.tsx | 4 +- .../impl/src/analytics_no_data_page.test.tsx | 95 +++++++++++++++---- .../impl/src/analytics_no_data_page.tsx | 4 +- .../analytics_no_data/mocks/src/storybook.ts | 18 +++- .../page/analytics_no_data/types/index.d.ts | 2 + .../impl/src/kibana_no_data_page.tsx | 6 +- .../page/kibana_no_data/types/index.d.ts | 2 + .../impl/src/no_data_views.component.tsx | 20 ++-- .../no_data_views/impl/src/no_data_views.tsx | 14 ++- .../no_data_views/mocks/src/storybook.ts | 2 +- .../prompt/no_data_views/types/index.d.ts | 2 + 12 files changed, 139 insertions(+), 42 deletions(-) diff --git a/packages/shared-ux/page/analytics_no_data/impl/src/analytics_no_data_page.component.tsx b/packages/shared-ux/page/analytics_no_data/impl/src/analytics_no_data_page.component.tsx index 41c525c5ca0b0..114b4f2eed9b2 100644 --- a/packages/shared-ux/page/analytics_no_data/impl/src/analytics_no_data_page.component.tsx +++ b/packages/shared-ux/page/analytics_no_data/impl/src/analytics_no_data_page.component.tsx @@ -22,12 +22,14 @@ import { getHasApiKeys$ } from '../lib/get_has_api_keys'; export interface Props { /** Handler for successfully creating a new data view. */ onDataViewCreated: (dataView: unknown) => void; - /** Handler for when try ES|QL is clicked and user has been navigated to try ES|QL in discover. */ - onESQLNavigationComplete?: () => void; /** if set to true allows creation of an ad-hoc dataview from data view editor */ allowAdHocDataView?: boolean; /** if the kibana instance is customly branded */ showPlainSpinner: boolean; + /** If the cluster has data, the user can be prompted to try ES|QL. This click handler customizes the action */ + onTryESQL?: () => void; + /** Handler for when try ES|QL is clicked and user has been navigated to try ES|QL in discover. */ + onESQLNavigationComplete?: () => void; } type AnalyticsNoDataPageProps = Props & @@ -119,9 +121,10 @@ const flavors: { */ export const AnalyticsNoDataPage: React.FC = ({ onDataViewCreated, - onESQLNavigationComplete, allowAdHocDataView, showPlainSpinner, + onTryESQL, + onESQLNavigationComplete, ...services }) => { const { prependBasePath, kibanaGuideDocLink, getHttp: get, pageFlavor } = services; @@ -138,8 +141,9 @@ export const AnalyticsNoDataPage: React.FC = ({ {...{ noDataConfig, onDataViewCreated, - onESQLNavigationComplete, allowAdHocDataView, + onTryESQL, + onESQLNavigationComplete, showPlainSpinner, }} /> diff --git a/packages/shared-ux/page/analytics_no_data/impl/src/analytics_no_data_page.stories.tsx b/packages/shared-ux/page/analytics_no_data/impl/src/analytics_no_data_page.stories.tsx index 3c75cefb38cb2..fa251cb03bdbe 100644 --- a/packages/shared-ux/page/analytics_no_data/impl/src/analytics_no_data_page.stories.tsx +++ b/packages/shared-ux/page/analytics_no_data/impl/src/analytics_no_data_page.stories.tsx @@ -29,8 +29,8 @@ export default { export const Analytics = (params: AnalyticsNoDataPageStorybookParams) => { return ( - - + + ); }; diff --git a/packages/shared-ux/page/analytics_no_data/impl/src/analytics_no_data_page.test.tsx b/packages/shared-ux/page/analytics_no_data/impl/src/analytics_no_data_page.test.tsx index 543c1c4817c5b..6b2d3441ed0d1 100644 --- a/packages/shared-ux/page/analytics_no_data/impl/src/analytics_no_data_page.test.tsx +++ b/packages/shared-ux/page/analytics_no_data/impl/src/analytics_no_data_page.test.tsx @@ -14,6 +14,7 @@ import { getAnalyticsNoDataPageServicesMock, getAnalyticsNoDataPageServicesMockWithCustomBranding, } from '@kbn/shared-ux-page-analytics-no-data-mocks'; +import { NoDataViewsPrompt } from '@kbn/shared-ux-prompt-no-data-views'; import { AnalyticsNoDataPageProvider } from './services'; import { AnalyticsNoDataPage as Component } from './analytics_no_data_page.component'; @@ -29,28 +30,86 @@ describe('AnalyticsNoDataPage', () => { jest.resetAllMocks(); }); - it('renders correctly', async () => { - const component = mountWithIntl( - - - - ); + describe('loading state', () => { + it('renders correctly', async () => { + const component = mountWithIntl( + + + + ); - await act(() => new Promise(setImmediate)); + await act(() => new Promise(setImmediate)); - expect(component.find(Component).length).toBe(1); - expect(component.find(Component).props().onDataViewCreated).toBe(onDataViewCreated); - expect(component.find(Component).props().allowAdHocDataView).toBe(true); + expect(component.find(Component).length).toBe(1); + expect(component.find(Component).props().onDataViewCreated).toBe(onDataViewCreated); + expect(component.find(Component).props().allowAdHocDataView).toBe(true); + }); + + it('passes correct boolean value to showPlainSpinner', async () => { + const component = mountWithIntl( + + + + ); + + await act(async () => { + component.update(); + }); + + expect(component.find(Component).length).toBe(1); + expect(component.find(Component).props().showPlainSpinner).toBe(true); + }); }); - it('passes correct boolean value to showPlainSpinner', () => { - const component = mountWithIntl( - - - - ); + describe('with ES data', () => { + jest.spyOn(services, 'hasESData').mockResolvedValue(true); + jest.spyOn(services, 'hasUserDataView').mockResolvedValue(false); + + it('renders the prompt to create a data view', async () => { + const onTryESQL = jest.fn(); + + await act(async () => { + const component = mountWithIntl( + + + + ); + + await new Promise(setImmediate); + component.update(); + + expect(component.find(Component).length).toBe(1); + expect(component.find(NoDataViewsPrompt).length).toBe(1); + }); + }); + + it('renders the prompt to create a data view with a custom onTryESQL action', async () => { + const onTryESQL = jest.fn(); + + await act(async () => { + const component = mountWithIntl( + + + + ); + + await new Promise(setImmediate); + component.update(); + + const tryESQLLink = component.find('button[data-test-subj="tryESQLLink"]'); + expect(tryESQLLink.length).toBe(1); + tryESQLLink.simulate('click'); - expect(component.find(Component).length).toBe(1); - expect(component.find(Component).props().showPlainSpinner).toBe(true); + expect(onTryESQL).toHaveBeenCalled(); + }); + }); }); }); diff --git a/packages/shared-ux/page/analytics_no_data/impl/src/analytics_no_data_page.tsx b/packages/shared-ux/page/analytics_no_data/impl/src/analytics_no_data_page.tsx index b64a296bbf74a..f7c80705daa58 100644 --- a/packages/shared-ux/page/analytics_no_data/impl/src/analytics_no_data_page.tsx +++ b/packages/shared-ux/page/analytics_no_data/impl/src/analytics_no_data_page.tsx @@ -20,8 +20,9 @@ import { AnalyticsNoDataPage as Component } from './analytics_no_data_page.compo */ export const AnalyticsNoDataPage = ({ onDataViewCreated, - onESQLNavigationComplete, allowAdHocDataView, + onTryESQL, + onESQLNavigationComplete, }: AnalyticsNoDataPageProps) => { const { customBranding, ...services } = useServices(); const showPlainSpinner = useObservable(customBranding.hasCustomBranding$) ?? false; @@ -33,6 +34,7 @@ export const AnalyticsNoDataPage = ({ allowAdHocDataView={allowAdHocDataView} onDataViewCreated={onDataViewCreated} onESQLNavigationComplete={onESQLNavigationComplete} + onTryESQL={onTryESQL} /> ); }; diff --git a/packages/shared-ux/page/analytics_no_data/mocks/src/storybook.ts b/packages/shared-ux/page/analytics_no_data/mocks/src/storybook.ts index c664bb192518c..f8cca693a072c 100644 --- a/packages/shared-ux/page/analytics_no_data/mocks/src/storybook.ts +++ b/packages/shared-ux/page/analytics_no_data/mocks/src/storybook.ts @@ -18,9 +18,14 @@ import type { } from '@kbn/shared-ux-page-analytics-no-data-types'; import { of } from 'rxjs'; +interface PropArguments { + useCustomOnTryESQL: boolean; +} + type ServiceArguments = Pick; -export type Params = ArgumentParams<{}, ServiceArguments> & KibanaNoDataPageStorybookParams; +export type Params = ArgumentParams & + KibanaNoDataPageStorybookParams; const kibanaNoDataMock = new KibanaNoDataPageStorybookMock(); @@ -30,7 +35,13 @@ export class StorybookMock extends AbstractStorybookMock< {}, ServiceArguments > { - propArguments = {}; + propArguments = { + // requires hasESData to be toggled to true + useCustomOnTryESQL: { + control: 'boolean', + defaultValue: false, + }, + }; serviceArguments = { kibanaGuideDocLink: { control: 'text', @@ -59,9 +70,10 @@ export class StorybookMock extends AbstractStorybookMock< }; } - getProps() { + getProps(params: Params) { return { onDataViewCreated: action('onDataViewCreated'), + onTryESQL: params.useCustomOnTryESQL ? action('onTryESQL-from-props') : undefined, }; } } diff --git a/packages/shared-ux/page/analytics_no_data/types/index.d.ts b/packages/shared-ux/page/analytics_no_data/types/index.d.ts index 9fd6653a48b6a..434c271f4176b 100644 --- a/packages/shared-ux/page/analytics_no_data/types/index.d.ts +++ b/packages/shared-ux/page/analytics_no_data/types/index.d.ts @@ -70,6 +70,8 @@ export interface AnalyticsNoDataPageProps { onDataViewCreated: (dataView: unknown) => void; /** if set to true allows creation of an ad-hoc data view from data view editor */ allowAdHocDataView?: boolean; + /** If the cluster has data, the user can be prompted to try ES|QL. This click handler customizes the action */ + onTryESQL?: () => void; /** Handler for when try ES|QL is clicked and user has been navigated to try ES|QL in discover. */ onESQLNavigationComplete?: () => void; } diff --git a/packages/shared-ux/page/kibana_no_data/impl/src/kibana_no_data_page.tsx b/packages/shared-ux/page/kibana_no_data/impl/src/kibana_no_data_page.tsx index 2042d7fa1420d..d74c3aabd5662 100644 --- a/packages/shared-ux/page/kibana_no_data/impl/src/kibana_no_data_page.tsx +++ b/packages/shared-ux/page/kibana_no_data/impl/src/kibana_no_data_page.tsx @@ -20,9 +20,10 @@ import { useServices } from './services'; */ export const KibanaNoDataPage = ({ onDataViewCreated, - onESQLNavigationComplete, noDataConfig, allowAdHocDataView, + onTryESQL, + onESQLNavigationComplete, showPlainSpinner, }: KibanaNoDataPageProps) => { // These hooks are temporary, until this component is moved to a package. @@ -58,8 +59,9 @@ export const KibanaNoDataPage = ({ return ( ); } diff --git a/packages/shared-ux/page/kibana_no_data/types/index.d.ts b/packages/shared-ux/page/kibana_no_data/types/index.d.ts index 56067e9d555f9..b16f8dd76fa45 100644 --- a/packages/shared-ux/page/kibana_no_data/types/index.d.ts +++ b/packages/shared-ux/page/kibana_no_data/types/index.d.ts @@ -59,6 +59,8 @@ export interface KibanaNoDataPageProps { /** if set to true allows creation of an ad-hoc dataview from data view editor */ allowAdHocDataView?: boolean; /** Set to true if the kibana is customly branded */ + /** **/ + onTryESQL?: () => void; showPlainSpinner: boolean; /** Handler for when try ES|QL is clicked and user has been navigated to try ES|QL in discover. */ onESQLNavigationComplete?: () => void; diff --git a/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx b/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx index 788bca54bdafb..2942c7883b576 100644 --- a/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx +++ b/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx @@ -108,6 +108,12 @@ const PromptTryEsql = ({ NoDataViewsPromptComponentProps, 'onClickCreate' | 'onTryESQL' | 'esqlDocLink' | 'emptyPromptColor' >) => { + if (!onTryESQL) { + // we need to handle the case where the Try ES|QL click handler is not set because + // onTryESQL is set via a useEffect that has asynchronous dependencies + return null; + } + // Load this illustration lazily const Illustration = withSuspense( React.lazy(() => @@ -136,14 +142,12 @@ const PromptTryEsql = ({ const footer = ( <> - {onTryESQL && ( - - - - )} + + + {esqlDocLink && } diff --git a/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.tsx b/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.tsx index bd50f4e2263d5..9de41dea9c4ca 100644 --- a/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.tsx +++ b/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.tsx @@ -27,12 +27,20 @@ type CloseDataViewEditorFn = ReturnType { - const { canCreateNewDataView, openDataViewEditor, dataViewsDocLink, onTryESQL, esqlDocLink } = - useServices(); + const { + canCreateNewDataView, + openDataViewEditor, + dataViewsDocLink, + onTryESQL: onTryESQLService, + esqlDocLink, + } = useServices(); + + const onTryESQL = onTryESQLParent ?? onTryESQLService; const closeDataViewEditor = useRef(); diff --git a/packages/shared-ux/prompt/no_data_views/mocks/src/storybook.ts b/packages/shared-ux/prompt/no_data_views/mocks/src/storybook.ts index cb306203980e4..973152201587d 100644 --- a/packages/shared-ux/prompt/no_data_views/mocks/src/storybook.ts +++ b/packages/shared-ux/prompt/no_data_views/mocks/src/storybook.ts @@ -61,7 +61,7 @@ export class StorybookMock extends AbstractStorybookMock< let onTryESQL; if (canTryEsql !== false) { - onTryESQL = action('onTryESQL'); + onTryESQL = action('onTryESQL-from-services'); } return { diff --git a/packages/shared-ux/prompt/no_data_views/types/index.d.ts b/packages/shared-ux/prompt/no_data_views/types/index.d.ts index 5695b15fb078b..e229aab15a29a 100644 --- a/packages/shared-ux/prompt/no_data_views/types/index.d.ts +++ b/packages/shared-ux/prompt/no_data_views/types/index.d.ts @@ -104,6 +104,8 @@ export interface NoDataViewsPromptProps { allowAdHocDataView?: boolean; /** Handler for successfully creating a new data view. */ onDataViewCreated: (dataView: unknown) => void; + /** Handler for someone wanting to try ES|QL. */ + onTryESQL?: () => void; /** Handler for when try ES|QL is clicked and user has been navigated to try ES|QL in discover. */ onESQLNavigationComplete?: () => void; /** Empty prompt color **/ From c854717e1d169f393fc4e2679b978ffa790ccfd5 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Fri, 4 Oct 2024 00:18:26 +0000 Subject: [PATCH 08/23] [CI] Auto-commit changed files from 'node scripts/notice' --- packages/shared-ux/page/analytics_no_data/impl/tsconfig.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/shared-ux/page/analytics_no_data/impl/tsconfig.json b/packages/shared-ux/page/analytics_no_data/impl/tsconfig.json index 659aacfd3874d..ba872e1ecd761 100644 --- a/packages/shared-ux/page/analytics_no_data/impl/tsconfig.json +++ b/packages/shared-ux/page/analytics_no_data/impl/tsconfig.json @@ -23,6 +23,7 @@ "@kbn/i18n-react", "@kbn/core-http-browser", "@kbn/core-http-browser-mocks", + "@kbn/shared-ux-prompt-no-data-views", ], "exclude": [ "target/**/*", From d2a08f3cd6a6fa3b0109ba24e22873630718d6b4 Mon Sep 17 00:00:00 2001 From: Tim Sullivan Date: Thu, 3 Oct 2024 17:37:28 -0700 Subject: [PATCH 09/23] Update packages/shared-ux/page/kibana_no_data/types/index.d.ts --- packages/shared-ux/page/kibana_no_data/types/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared-ux/page/kibana_no_data/types/index.d.ts b/packages/shared-ux/page/kibana_no_data/types/index.d.ts index b16f8dd76fa45..912193cb190eb 100644 --- a/packages/shared-ux/page/kibana_no_data/types/index.d.ts +++ b/packages/shared-ux/page/kibana_no_data/types/index.d.ts @@ -59,7 +59,7 @@ export interface KibanaNoDataPageProps { /** if set to true allows creation of an ad-hoc dataview from data view editor */ allowAdHocDataView?: boolean; /** Set to true if the kibana is customly branded */ - /** **/ + /** If the cluster has data, the user can be prompted to try ES|QL. This click handler customizes the action **/ onTryESQL?: () => void; showPlainSpinner: boolean; /** Handler for when try ES|QL is clicked and user has been navigated to try ES|QL in discover. */ From 4ba2714b3937c8281614d08917e14a232891497f Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Thu, 3 Oct 2024 17:52:59 -0700 Subject: [PATCH 10/23] Polish --- .../impl/src/analytics_no_data_page.component.tsx | 2 +- .../page/analytics_no_data/types/index.d.ts | 2 +- .../page/kibana_no_data/types/index.d.ts | 4 ++-- .../no_data_views/impl/src/no_data_views.tsx | 15 ++++----------- .../prompt/no_data_views/types/index.d.ts | 6 +++--- .../index_pattern_table/index_pattern_table.tsx | 3 +-- 6 files changed, 12 insertions(+), 20 deletions(-) diff --git a/packages/shared-ux/page/analytics_no_data/impl/src/analytics_no_data_page.component.tsx b/packages/shared-ux/page/analytics_no_data/impl/src/analytics_no_data_page.component.tsx index 114b4f2eed9b2..16d1bebd46548 100644 --- a/packages/shared-ux/page/analytics_no_data/impl/src/analytics_no_data_page.component.tsx +++ b/packages/shared-ux/page/analytics_no_data/impl/src/analytics_no_data_page.component.tsx @@ -26,7 +26,7 @@ export interface Props { allowAdHocDataView?: boolean; /** if the kibana instance is customly branded */ showPlainSpinner: boolean; - /** If the cluster has data, the user can be prompted to try ES|QL. This click handler customizes the action */ + /** If the cluster has data, this handler allows the user to try ES|QL */ onTryESQL?: () => void; /** Handler for when try ES|QL is clicked and user has been navigated to try ES|QL in discover. */ onESQLNavigationComplete?: () => void; diff --git a/packages/shared-ux/page/analytics_no_data/types/index.d.ts b/packages/shared-ux/page/analytics_no_data/types/index.d.ts index 434c271f4176b..94bf85500da6b 100644 --- a/packages/shared-ux/page/analytics_no_data/types/index.d.ts +++ b/packages/shared-ux/page/analytics_no_data/types/index.d.ts @@ -70,7 +70,7 @@ export interface AnalyticsNoDataPageProps { onDataViewCreated: (dataView: unknown) => void; /** if set to true allows creation of an ad-hoc data view from data view editor */ allowAdHocDataView?: boolean; - /** If the cluster has data, the user can be prompted to try ES|QL. This click handler customizes the action */ + /** If the cluster has data, this handler allows the user to try ES|QL */ onTryESQL?: () => void; /** Handler for when try ES|QL is clicked and user has been navigated to try ES|QL in discover. */ onESQLNavigationComplete?: () => void; diff --git a/packages/shared-ux/page/kibana_no_data/types/index.d.ts b/packages/shared-ux/page/kibana_no_data/types/index.d.ts index 912193cb190eb..c391149f7efaa 100644 --- a/packages/shared-ux/page/kibana_no_data/types/index.d.ts +++ b/packages/shared-ux/page/kibana_no_data/types/index.d.ts @@ -59,9 +59,9 @@ export interface KibanaNoDataPageProps { /** if set to true allows creation of an ad-hoc dataview from data view editor */ allowAdHocDataView?: boolean; /** Set to true if the kibana is customly branded */ - /** If the cluster has data, the user can be prompted to try ES|QL. This click handler customizes the action **/ - onTryESQL?: () => void; showPlainSpinner: boolean; + /** If the cluster has data, this handler allows the user to try ES|QL */ + onTryESQL?: () => void; /** Handler for when try ES|QL is clicked and user has been navigated to try ES|QL in discover. */ onESQLNavigationComplete?: () => void; } diff --git a/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.tsx b/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.tsx index 9de41dea9c4ca..340147505cb25 100644 --- a/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.tsx +++ b/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.tsx @@ -28,19 +28,13 @@ type CloseDataViewEditorFn = ReturnType { - const { - canCreateNewDataView, - openDataViewEditor, - dataViewsDocLink, - onTryESQL: onTryESQLService, - esqlDocLink, - } = useServices(); + const { canCreateNewDataView, openDataViewEditor, dataViewsDocLink, esqlDocLink, ...services } = + useServices(); - const onTryESQL = onTryESQLParent ?? onTryESQLService; + const onTryESQL = onTryESQLProp ?? services.onTryESQL; const closeDataViewEditor = useRef(); @@ -91,7 +85,6 @@ export const NoDataViewsPrompt = ({ canCreateNewDataView, dataViewsDocLink, esqlDocLink, - emptyPromptColor, onTryESQL: onTryESQL ? () => { onTryESQL(); diff --git a/packages/shared-ux/prompt/no_data_views/types/index.d.ts b/packages/shared-ux/prompt/no_data_views/types/index.d.ts index e229aab15a29a..7bca285bee717 100644 --- a/packages/shared-ux/prompt/no_data_views/types/index.d.ts +++ b/packages/shared-ux/prompt/no_data_views/types/index.d.ts @@ -42,7 +42,7 @@ export interface NoDataViewsPromptServices { openDataViewEditor: (options: DataViewEditorOptions) => () => void; /** A link to information about Data Views in Kibana */ dataViewsDocLink: string; - /** Get a handler for trying ES|QL */ + /** If the cluster has data, this handler allows the user to try ES|QL */ onTryESQL: (() => void) | undefined; /** A link to the documentation for ES|QL */ esqlDocLink: string; @@ -92,7 +92,7 @@ export interface NoDataViewsPromptComponentProps { emptyPromptColor?: EuiEmptyPromptProps['color']; /** Click handler for create button. **/ onClickCreate?: () => void; - /** Handler for someone wanting to try ES|QL. */ + /** If the cluster has data, this handler allows the user to try ES|QL */ onTryESQL?: () => void; /** Link to documentation on ES|QL. */ esqlDocLink?: string; @@ -104,7 +104,7 @@ export interface NoDataViewsPromptProps { allowAdHocDataView?: boolean; /** Handler for successfully creating a new data view. */ onDataViewCreated: (dataView: unknown) => void; - /** Handler for someone wanting to try ES|QL. */ + /** If the cluster has data, this handler allows the user to try ES|QL */ onTryESQL?: () => void; /** Handler for when try ES|QL is clicked and user has been navigated to try ES|QL in discover. */ onESQLNavigationComplete?: () => void; diff --git a/src/plugins/data_view_management/public/components/index_pattern_table/index_pattern_table.tsx b/src/plugins/data_view_management/public/components/index_pattern_table/index_pattern_table.tsx index f024a61c319a8..4512cb520c574 100644 --- a/src/plugins/data_view_management/public/components/index_pattern_table/index_pattern_table.tsx +++ b/src/plugins/data_view_management/public/components/index_pattern_table/index_pattern_table.tsx @@ -369,7 +369,7 @@ export const IndexPatternTable = ({ ); - if (!hasDataView) { + if (!hasDataView) displayIndexPatternSection = ( <> @@ -383,7 +383,6 @@ export const IndexPatternTable = ({ /> ); - } if (!hasDataView && !hasESData) displayIndexPatternSection = ( <> From 4a70ee85dd7784d12623988ab8d839c2018ce0ae Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Fri, 4 Oct 2024 16:00:52 -0700 Subject: [PATCH 11/23] Remove the beta badge --- .../no_data_views/impl/src/no_data_views.component.tsx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx b/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx index 2942c7883b576..cad88e52d5f7d 100644 --- a/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx +++ b/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx @@ -25,7 +25,6 @@ import { FormattedMessage } from '@kbn/i18n-react'; import { withSuspense } from '@kbn/shared-ux-utility'; import { NoDataViewsPromptComponentProps } from '@kbn/shared-ux-prompt-no-data-views-types'; -import { i18n } from '@kbn/i18n'; import { DocumentationLink } from './documentation_link'; // max width value to use in pixels @@ -158,11 +157,6 @@ const PromptTryEsql = ({ hasBorder={true} data-test-subj="noDataViewsPromptTryEsql" display={emptyPromptColor} - betaBadgeProps={{ - label: i18n.translate('sharedUXPackages.noDataViewsPrompt.esqlTechnicalPreviewBadge', { - defaultMessage: 'Technical preview ', - }), - }} {...{ icon, title, description, footer }} /> ); From b15ba4f169865fda3635a26aa6adaa6816c50677 Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Fri, 4 Oct 2024 16:03:56 -0700 Subject: [PATCH 12/23] Undo incorrect code split for loading illustrations --- .../impl/src/no_data_views.component.tsx | 28 +++---------------- 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx b/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx index cad88e52d5f7d..3ea6123bb6dbb 100644 --- a/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx +++ b/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx @@ -16,16 +16,16 @@ import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule, - EuiPanel, EuiSpacer, EuiText, EuiTextAlign, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import { withSuspense } from '@kbn/shared-ux-utility'; import { NoDataViewsPromptComponentProps } from '@kbn/shared-ux-prompt-no-data-views-types'; import { DocumentationLink } from './documentation_link'; +import { DataViewIllustration } from './data_view_illustration'; +import { EsqlIllustration } from './esql_illustration'; // max width value to use in pixels const MAX_WIDTH = 770; @@ -39,17 +39,7 @@ const PromptAddDataViews = ({ NoDataViewsPromptComponentProps, 'onClickCreate' | 'canCreateNewDataView' | 'dataViewsDocLink' | 'emptyPromptColor' >) => { - // Load this illustration lazily - const Illustration = withSuspense( - React.lazy(() => - import('./data_view_illustration').then(({ DataViewIllustration }) => { - return { default: DataViewIllustration }; - }) - ), - - ); - - const icon = ; + const icon = ; const title = ( - import('./esql_illustration').then(({ EsqlIllustration }) => { - return { default: EsqlIllustration }; - }) - ), - - ); - - const icon = ; + const icon = ; const title = ( Date: Fri, 4 Oct 2024 16:14:25 -0700 Subject: [PATCH 13/23] Update functional tests to use new PageObject methods from Discover app --- .../group6/dashboard_esql_no_data.ts | 16 +++++----------- .../apps/management/data_views/_try_esql.ts | 19 ++++++++++--------- test/functional/page_objects/discover_page.ts | 13 +++++++++++++ 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/test/functional/apps/dashboard/group6/dashboard_esql_no_data.ts b/test/functional/apps/dashboard/group6/dashboard_esql_no_data.ts index 550b872674317..4bc60aa22c7b2 100644 --- a/test/functional/apps/dashboard/group6/dashboard_esql_no_data.ts +++ b/test/functional/apps/dashboard/group6/dashboard_esql_no_data.ts @@ -7,32 +7,26 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../ftr_provider_context'; export default function ({ getService, getPageObjects }: FtrProviderContext) { const kibanaServer = getService('kibanaServer'); const testSubjects = getService('testSubjects'); - const { dashboard } = getPageObjects(['dashboard']); + const PageObjects = getPageObjects(['discover', 'dashboard']); - describe('dashboard from esql button on no-data-prompt', () => { + describe('No Data Views: Try ES|QL', () => { before(async () => { await kibanaServer.savedObjects.cleanStandardList(); }); it('enables user to create a dashboard with ES|QL from no-data-prompt', async () => { - await dashboard.navigateToApp(); + await PageObjects.dashboard.navigateToApp(); await testSubjects.existOrFail('noDataViewsPrompt'); await testSubjects.click('tryESQLLink'); - // ensure we have landed on Discover - await testSubjects.existOrFail('switch-to-dataviews'); // "Switch to Classic" app menu button - await testSubjects.existOrFail('discoverNewButton'); - await testSubjects.existOrFail('discoverOpenButton'); - - const codeEditor = await testSubjects.find('kibanaCodeEditor'); - expect(await codeEditor.getAttribute('innerText')).to.contain('FROM logs* | LIMIT 10'); + await PageObjects.discover.expectOnDiscover(); + await PageObjects.discover.expectEsqlStatement('FROM logs* | LIMIT 10'); }); }); } diff --git a/test/functional/apps/management/data_views/_try_esql.ts b/test/functional/apps/management/data_views/_try_esql.ts index 089f8daaa27a5..0203ba39e05ee 100644 --- a/test/functional/apps/management/data_views/_try_esql.ts +++ b/test/functional/apps/management/data_views/_try_esql.ts @@ -7,26 +7,27 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../ftr_provider_context'; export default function ({ getService, getPageObjects }: FtrProviderContext) { - const PageObjects = getPageObjects(['settings', 'common']); + const kibanaServer = getService('kibanaServer'); const testSubjects = getService('testSubjects'); + const PageObjects = getPageObjects(['settings', 'common', 'discover']); describe('No Data Views: Try ES|QL', () => { + before(async () => { + await kibanaServer.savedObjects.cleanStandardList(); + }); + it('navigates to Discover and presents an ES|QL query', async () => { await PageObjects.settings.navigateTo(); await PageObjects.settings.clickKibanaIndexPatterns(); - await testSubjects.click('tryESQLLink'); - // ensure we have landed on Discover - await testSubjects.existOrFail('switch-to-dataviews'); // "Switch to Classic" app menu button - await testSubjects.existOrFail('discoverNewButton'); - await testSubjects.existOrFail('discoverOpenButton'); + await testSubjects.existOrFail('noDataViewsPrompt'); + await testSubjects.click('tryESQLLink'); - const codeEditor = await testSubjects.find('kibanaCodeEditor'); - expect(await codeEditor.getAttribute('innerText')).to.contain('FROM logs* | LIMIT 10'); + await PageObjects.discover.expectOnDiscover(); + await PageObjects.discover.expectEsqlStatement('FROM logs* | LIMIT 10'); }); }); } diff --git a/test/functional/page_objects/discover_page.ts b/test/functional/page_objects/discover_page.ts index 1474e9d315538..46814047c147a 100644 --- a/test/functional/page_objects/discover_page.ts +++ b/test/functional/page_objects/discover_page.ts @@ -32,6 +32,19 @@ export class DiscoverPageObject extends FtrService { private readonly defaultFindTimeout = this.config.get('timeouts.find'); + /** Ensures that navigation to discover has completed */ + public async expectOnDiscover() { + await this.testSubjects.existOrFail('switch-to-dataviews'); // "Switch to Classic" app menu button + await this.testSubjects.existOrFail('discoverNewButton'); + await this.testSubjects.existOrFail('discoverOpenButton'); + } + + /** Ensures that the ES|QL code editor is loaded with a given statement */ + public async expectEsqlStatement(statement: string) { + const codeEditor = await this.testSubjects.find('kibanaCodeEditor'); + expect(await codeEditor.getAttribute('innerText')).to.contain(statement); + } + public async getChartTimespan() { return await this.testSubjects.getAttribute('unifiedHistogramChart', 'data-time-range'); } From 490998429019f66a1e77f5dd0eca006aa6edd474 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Fri, 4 Oct 2024 23:32:24 +0000 Subject: [PATCH 14/23] [CI] Auto-commit changed files from 'node scripts/notice' --- packages/shared-ux/prompt/no_data_views/impl/tsconfig.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/shared-ux/prompt/no_data_views/impl/tsconfig.json b/packages/shared-ux/prompt/no_data_views/impl/tsconfig.json index 673823e620474..2af357080c07c 100644 --- a/packages/shared-ux/prompt/no_data_views/impl/tsconfig.json +++ b/packages/shared-ux/prompt/no_data_views/impl/tsconfig.json @@ -16,8 +16,6 @@ ], "kbn_references": [ "@kbn/i18n-react", - "@kbn/i18n", - "@kbn/shared-ux-utility", "@kbn/test-jest-helpers", "@kbn/shared-ux-prompt-no-data-views-types", "@kbn/shared-ux-prompt-no-data-views-mocks", From f9d90fb7ce80ec3dd2268b011b49558b42759b75 Mon Sep 17 00:00:00 2001 From: Tim Sullivan Date: Mon, 7 Oct 2024 18:13:36 -0700 Subject: [PATCH 15/23] Update packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx Co-authored-by: Liam Thompson <32779855+leemthompo@users.noreply.github.com> --- .../prompt/no_data_views/impl/src/no_data_views.component.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx b/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx index 3ea6123bb6dbb..e2ed5b787c6e2 100644 --- a/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx +++ b/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx @@ -115,7 +115,7 @@ const PromptTryEsql = ({ const description = ( ); From 778f831798993c8e0eb037ffd1cfc969dd32efd8 Mon Sep 17 00:00:00 2001 From: Tim Sullivan Date: Mon, 7 Oct 2024 18:14:26 -0700 Subject: [PATCH 16/23] Update packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx Co-authored-by: Andrea Del Rio --- .../prompt/no_data_views/impl/src/no_data_views.component.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx b/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx index e2ed5b787c6e2..5b69289688ff8 100644 --- a/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx +++ b/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx @@ -172,7 +172,7 @@ export const NoDataViewsPrompt = ({ defaultMessage="You have data in Elasticsearch." /> - + Date: Mon, 7 Oct 2024 18:29:58 -0700 Subject: [PATCH 17/23] disabled button and tooltip for readonly users --- .../impl/src/no_data_views.component.tsx | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx b/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx index 5b69289688ff8..f850de5c5ae18 100644 --- a/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx +++ b/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx @@ -19,6 +19,7 @@ import { EuiSpacer, EuiText, EuiTextAlign, + EuiToolTip, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { NoDataViewsPromptComponentProps } from '@kbn/shared-ux-prompt-no-data-views-types'; @@ -66,13 +67,30 @@ const PromptAddDataViews = ({ const footer = dataViewsDocLink ? ( <> - {canCreateNewDataView && ( + {canCreateNewDataView ? ( + ) : ( + + } + > + + + + )} From ac60f31729fbcb49b2682df8db421a1ca595aa7f Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Tue, 8 Oct 2024 10:30:40 -0700 Subject: [PATCH 18/23] update main CTA text --- .../no_data_views/impl/src/no_data_views.component.tsx | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx b/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx index f850de5c5ae18..c33f4eb8dee11 100644 --- a/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx +++ b/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx @@ -187,15 +187,8 @@ export const NoDataViewsPrompt = ({

- - - -

From 3409fc2b7c3e0baf9d43d5446b1aee3822160faa Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Tue, 8 Oct 2024 17:08:36 -0700 Subject: [PATCH 19/23] fix functional test --- .../functional/apps/data_views/feature_controls/security.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/x-pack/test/functional/apps/data_views/feature_controls/security.ts b/x-pack/test/functional/apps/data_views/feature_controls/security.ts index 1cc62baf0abba..34317932a6b21 100644 --- a/x-pack/test/functional/apps/data_views/feature_controls/security.ts +++ b/x-pack/test/functional/apps/data_views/feature_controls/security.ts @@ -131,10 +131,12 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { expect(navLinks).to.eql(['Stack Management']); }); - it(`index pattern listing doesn't show create button`, async () => { + it(`index pattern listing shows disabled create button`, async () => { await settings.clickKibanaIndexPatterns(); await testSubjects.existOrFail('noDataViewsPrompt'); - await testSubjects.missingOrFail('createDataViewButton'); + const createDataViewButton = await testSubjects.find('createDataViewButton'); + const isDisabled = await createDataViewButton.getAttribute('disabled'); + expect(isDisabled).to.be('true'); }); it(`shows read-only badge`, async () => { From 8d1eb8e17c75e236972dd8fa03e7ea53f32be2fd Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Wed, 9 Oct 2024 10:19:40 -0700 Subject: [PATCH 20/23] add padding around prompt to improve mobile views --- .../impl/src/no_data_views.component.tsx | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx b/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx index c33f4eb8dee11..3bfed37aa0b1a 100644 --- a/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx +++ b/packages/shared-ux/prompt/no_data_views/impl/src/no_data_views.component.tsx @@ -20,6 +20,7 @@ import { EuiText, EuiTextAlign, EuiToolTip, + useEuiPaddingCSS, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { NoDataViewsPromptComponentProps } from '@kbn/shared-ux-prompt-no-data-views-types'; @@ -171,17 +172,22 @@ export const NoDataViewsPrompt = ({ esqlDocLink, emptyPromptColor = 'plain', }: NoDataViewsPromptComponentProps) => { + const cssStyles = [ + css` + max-width: ${MAX_WIDTH}px; + `, + useEuiPaddingCSS('top').m, + useEuiPaddingCSS('right').m, + useEuiPaddingCSS('left').m, + ]; + return ( - +

From 6aeab7f3fe6e6fe6a5acb2971d7bd3433ef5e376 Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Wed, 9 Oct 2024 10:24:33 -0700 Subject: [PATCH 21/23] remove test for button that would not be present in all views --- test/functional/page_objects/discover_page.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/test/functional/page_objects/discover_page.ts b/test/functional/page_objects/discover_page.ts index 46814047c147a..24af94fcd2a34 100644 --- a/test/functional/page_objects/discover_page.ts +++ b/test/functional/page_objects/discover_page.ts @@ -34,7 +34,6 @@ export class DiscoverPageObject extends FtrService { /** Ensures that navigation to discover has completed */ public async expectOnDiscover() { - await this.testSubjects.existOrFail('switch-to-dataviews'); // "Switch to Classic" app menu button await this.testSubjects.existOrFail('discoverNewButton'); await this.testSubjects.existOrFail('discoverOpenButton'); } From 097d6048304c41697b82ba25a8218a78afac7778 Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Wed, 9 Oct 2024 10:37:47 -0700 Subject: [PATCH 22/23] Use es|sql service for expectStatement() --- .../apps/dashboard/group6/dashboard_esql_no_data.ts | 3 ++- test/functional/page_objects/discover_page.ts | 6 ------ test/functional/services/esql.ts | 7 +++++++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/test/functional/apps/dashboard/group6/dashboard_esql_no_data.ts b/test/functional/apps/dashboard/group6/dashboard_esql_no_data.ts index 4bc60aa22c7b2..148cb95a82b11 100644 --- a/test/functional/apps/dashboard/group6/dashboard_esql_no_data.ts +++ b/test/functional/apps/dashboard/group6/dashboard_esql_no_data.ts @@ -12,6 +12,7 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; export default function ({ getService, getPageObjects }: FtrProviderContext) { const kibanaServer = getService('kibanaServer'); const testSubjects = getService('testSubjects'); + const esql = getService('esql'); const PageObjects = getPageObjects(['discover', 'dashboard']); describe('No Data Views: Try ES|QL', () => { @@ -26,7 +27,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await testSubjects.click('tryESQLLink'); await PageObjects.discover.expectOnDiscover(); - await PageObjects.discover.expectEsqlStatement('FROM logs* | LIMIT 10'); + await esql.expectEsqlStatement('FROM logs* | LIMIT 10'); }); }); } diff --git a/test/functional/page_objects/discover_page.ts b/test/functional/page_objects/discover_page.ts index 24af94fcd2a34..ab6356075fd81 100644 --- a/test/functional/page_objects/discover_page.ts +++ b/test/functional/page_objects/discover_page.ts @@ -38,12 +38,6 @@ export class DiscoverPageObject extends FtrService { await this.testSubjects.existOrFail('discoverOpenButton'); } - /** Ensures that the ES|QL code editor is loaded with a given statement */ - public async expectEsqlStatement(statement: string) { - const codeEditor = await this.testSubjects.find('kibanaCodeEditor'); - expect(await codeEditor.getAttribute('innerText')).to.contain(statement); - } - public async getChartTimespan() { return await this.testSubjects.getAttribute('unifiedHistogramChart', 'data-time-range'); } diff --git a/test/functional/services/esql.ts b/test/functional/services/esql.ts index 63836d2c5d2f5..c144c6e8993be 100644 --- a/test/functional/services/esql.ts +++ b/test/functional/services/esql.ts @@ -7,12 +7,19 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ +import expect from '@kbn/expect'; import { FtrService } from '../ftr_provider_context'; export class ESQLService extends FtrService { private readonly retry = this.ctx.getService('retry'); private readonly testSubjects = this.ctx.getService('testSubjects'); + /** Ensures that the ES|QL code editor is loaded with a given statement */ + public async expectEsqlStatement(statement: string) { + const codeEditor = await this.testSubjects.find('ESQLEditor'); + expect(await codeEditor.getAttribute('innerText')).to.contain(statement); + } + public async getHistoryItems(): Promise { const queryHistory = await this.testSubjects.find('ESQLEditor-queryHistory'); const tableBody = await this.retry.try(async () => queryHistory.findByTagName('tbody')); From 4761b04f5f1b5369b477cab5cc57299112da2533 Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Wed, 9 Oct 2024 11:32:35 -0700 Subject: [PATCH 23/23] fix type checking --- test/functional/apps/management/data_views/_try_esql.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/functional/apps/management/data_views/_try_esql.ts b/test/functional/apps/management/data_views/_try_esql.ts index 0203ba39e05ee..276e61c4a721f 100644 --- a/test/functional/apps/management/data_views/_try_esql.ts +++ b/test/functional/apps/management/data_views/_try_esql.ts @@ -12,6 +12,7 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; export default function ({ getService, getPageObjects }: FtrProviderContext) { const kibanaServer = getService('kibanaServer'); const testSubjects = getService('testSubjects'); + const esql = getService('esql'); const PageObjects = getPageObjects(['settings', 'common', 'discover']); describe('No Data Views: Try ES|QL', () => { @@ -27,7 +28,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await testSubjects.click('tryESQLLink'); await PageObjects.discover.expectOnDiscover(); - await PageObjects.discover.expectEsqlStatement('FROM logs* | LIMIT 10'); + await esql.expectEsqlStatement('FROM logs* | LIMIT 10'); }); }); }