From 9a79eaabd4fb0293d186e5f1c6b6dac3b2cfdcd2 Mon Sep 17 00:00:00 2001 From: Yan Savitski Date: Thu, 17 Oct 2024 17:14:04 +0200 Subject: [PATCH 01/10] Add view in discover button and small logic improvements --- .../components/indices/details_page.tsx | 63 ++++++++++++------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/x-pack/plugins/search_indices/public/components/indices/details_page.tsx b/x-pack/plugins/search_indices/public/components/indices/details_page.tsx index 4d82ac053f65c..4248e420cb7b3 100644 --- a/x-pack/plugins/search_indices/public/components/indices/details_page.tsx +++ b/x-pack/plugins/search_indices/public/components/indices/details_page.tsx @@ -13,6 +13,7 @@ import { EuiTabbedContent, EuiTabbedContentTab, useEuiTheme, + EuiButton, } from '@elastic/eui'; import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { useParams } from 'react-router-dom'; @@ -63,6 +64,12 @@ export const SearchIndexDetailsPage = () => { await playgroundLocator.navigate({ 'default-index': index.name }); } }, [share, index]); + const navigateToDiscover = useCallback(async () => { + const discoverLocator = share.url.locators.get('DISCOVER_APP_LOCATOR'); + if (discoverLocator && indexName) { + await discoverLocator.navigate({ dataViewSpec: { title: indexName } }); + } + }, [share, indexName]); const [isDocumentsExists, setDocumentsExists] = useState(false); const [isDocumentsLoading, setDocumentsLoading] = useState(true); @@ -194,8 +201,36 @@ export const SearchIndexDetailsPage = () => { bottomBorder={false} rightSideItems={[ - - {!isDocumentsExists ? ( + {isDocumentsExists ? ( + <> + + + + + + + + + + + + ) : ( + { > - ) : ( - - - - )} - + + )} Date: Thu, 17 Oct 2024 17:15:41 +0200 Subject: [PATCH 02/10] Show api reference in menu when docs exists reduce abstraction for rendering buttons --- .../components/indices/details_page.tsx | 2 +- .../indices/details_page_menu_item.tsx | 114 ++++++------------ 2 files changed, 35 insertions(+), 81 deletions(-) diff --git a/x-pack/plugins/search_indices/public/components/indices/details_page.tsx b/x-pack/plugins/search_indices/public/components/indices/details_page.tsx index 4248e420cb7b3..fb1e5a5f234f9 100644 --- a/x-pack/plugins/search_indices/public/components/indices/details_page.tsx +++ b/x-pack/plugins/search_indices/public/components/indices/details_page.tsx @@ -248,7 +248,7 @@ export const SearchIndexDetailsPage = () => { , diff --git a/x-pack/plugins/search_indices/public/components/indices/details_page_menu_item.tsx b/x-pack/plugins/search_indices/public/components/indices/details_page_menu_item.tsx index 77c2d9c6a8ee1..df45cdab7fba7 100644 --- a/x-pack/plugins/search_indices/public/components/indices/details_page_menu_item.tsx +++ b/x-pack/plugins/search_indices/public/components/indices/details_page_menu_item.tsx @@ -14,101 +14,55 @@ import { EuiText, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import React, { MouseEventHandler, ReactElement, useState } from 'react'; +import React, { ReactElement, useState } from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; import { useKibana } from '../../hooks/use_kibana'; -enum MenuItems { - playground = 'playground', - apiReference = 'apiReference', - deleteIndex = 'deleteIndex', -} -interface MenuItemsAction { - href?: string; - onClick?: (() => void) | MouseEventHandler; -} - -const SearchIndexDetailsPageMenuItemPopoverItems = [ - { - type: MenuItems.playground, - iconType: 'launch', - dataTestSubj: 'moreOptionsPlayground', - iconComponent: , - target: undefined, - text: ( - - {i18n.translate('xpack.searchIndices.moreOptions.playgroundLabel', { - defaultMessage: 'Use in Playground', - })} - - ), - color: undefined, - }, - { - type: MenuItems.apiReference, - iconType: 'documentation', - dataTestSubj: 'moreOptionsApiReference', - iconComponent: , - target: '_blank', - text: ( - - {i18n.translate('xpack.searchIndices.moreOptions.apiReferenceLabel', { - defaultMessage: 'API Reference', - })} - - ), - color: undefined, - }, - { - type: MenuItems.deleteIndex, - iconType: 'trash', - dataTestSubj: 'moreOptionsDeleteIndex', - iconComponent: , - target: undefined, - text: ( - - {i18n.translate('xpack.searchIndices.moreOptions.deleteIndexLabel', { - defaultMessage: 'Delete Index', - })} - - ), - color: 'danger', - }, -]; interface SearchIndexDetailsPageMenuItemPopoverProps { handleDeleteIndexModal: () => void; - navigateToPlayground: () => void; + showApiReference: boolean; } export const SearchIndexDetailsPageMenuItemPopover = ({ + showApiReference = false, handleDeleteIndexModal, - navigateToPlayground, }: SearchIndexDetailsPageMenuItemPopoverProps) => { const [showMoreOptions, setShowMoreOptions] = useState(false); const { docLinks } = useKibana().services; - const contextMenuItemsActions: Record = { - playground: { - href: undefined, - onClick: navigateToPlayground, - }, - apiReference: { href: docLinks.links.apiReference, onClick: undefined }, - deleteIndex: { href: undefined, onClick: handleDeleteIndexModal }, - }; - const contextMenuItems: ReactElement[] = SearchIndexDetailsPageMenuItemPopoverItems.map( - (item) => ( + const contextMenuItems = [ + showApiReference && ( } + href={docLinks.links.apiReference} size="s" - onClick={contextMenuItemsActions[item.type]?.onClick} - target={item.target} - data-test-subj={item.dataTestSubj} - color={item.color} + target="_blank" + data-test-subj="moreOptionsApiReference" > - {item.text} + + + - ) - ); + ), + } + size="s" + onClick={handleDeleteIndexModal} + data-test-subj="moreOptionsDeleteIndex" + color="danger" + > + + + + , + ].filter(Boolean) as ReactElement[]; return ( Date: Thu, 17 Oct 2024 17:17:19 +0200 Subject: [PATCH 03/10] Add icon for playground button --- .../search_indices/public/components/indices/details_page.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/plugins/search_indices/public/components/indices/details_page.tsx b/x-pack/plugins/search_indices/public/components/indices/details_page.tsx index fb1e5a5f234f9..b6f819fc51549 100644 --- a/x-pack/plugins/search_indices/public/components/indices/details_page.tsx +++ b/x-pack/plugins/search_indices/public/components/indices/details_page.tsx @@ -220,6 +220,7 @@ export const SearchIndexDetailsPage = () => { isLoading={isDocumentsLoading} data-test-subj="useInPlaygroundLink" onClick={navigateToPlayground} + iconType="launch" fill > Date: Thu, 17 Oct 2024 17:20:08 +0200 Subject: [PATCH 04/10] Add spacer for settings page --- .../public/components/indices/details_page_settings.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/search_indices/public/components/indices/details_page_settings.tsx b/x-pack/plugins/search_indices/public/components/indices/details_page_settings.tsx index d70591c065b13..4e842d98678e3 100644 --- a/x-pack/plugins/search_indices/public/components/indices/details_page_settings.tsx +++ b/x-pack/plugins/search_indices/public/components/indices/details_page_settings.tsx @@ -7,6 +7,7 @@ import React from 'react'; import { useMemo } from 'react'; +import { EuiSpacer } from '@elastic/eui'; import { useKibana } from '../../hooks/use_kibana'; interface SearchIndexDetailsSettingsProps { @@ -20,5 +21,10 @@ export const SearchIndexDetailsSettings = ({ indexName }: SearchIndexDetailsSett [indexManagement, history] ); - return ; + return ( + <> + + + + ); }; From 032dab65a7fb38fde5150b8817d8bf11bc0b356a Mon Sep 17 00:00:00 2001 From: Yan Savitski Date: Thu, 17 Oct 2024 17:44:13 +0200 Subject: [PATCH 05/10] Fix data-test-subj name --- .../search_indices/public/components/indices/details_page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/search_indices/public/components/indices/details_page.tsx b/x-pack/plugins/search_indices/public/components/indices/details_page.tsx index b6f819fc51549..f2c81a2f88974 100644 --- a/x-pack/plugins/search_indices/public/components/indices/details_page.tsx +++ b/x-pack/plugins/search_indices/public/components/indices/details_page.tsx @@ -206,7 +206,7 @@ export const SearchIndexDetailsPage = () => { Date: Thu, 17 Oct 2024 17:47:24 +0200 Subject: [PATCH 06/10] Rename variable --- .../public/components/indices/details_page.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/search_indices/public/components/indices/details_page.tsx b/x-pack/plugins/search_indices/public/components/indices/details_page.tsx index f2c81a2f88974..539bcf6660adb 100644 --- a/x-pack/plugins/search_indices/public/components/indices/details_page.tsx +++ b/x-pack/plugins/search_indices/public/components/indices/details_page.tsx @@ -71,12 +71,12 @@ export const SearchIndexDetailsPage = () => { } }, [share, indexName]); - const [isDocumentsExists, setDocumentsExists] = useState(false); + const [hasDocuments, setHasDocuments] = useState(false); const [isDocumentsLoading, setDocumentsLoading] = useState(true); useEffect(() => { setDocumentsLoading(isInitialLoading); - setDocumentsExists(!(!isInitialLoading && indexDocuments?.results?.data.length === 0)); - }, [indexDocuments, isInitialLoading, setDocumentsExists, setDocumentsLoading]); + setHasDocuments(!(!isInitialLoading && indexDocuments?.results?.data.length === 0)); + }, [indexDocuments, isInitialLoading, setHasDocuments, setDocumentsLoading]); const usageTracker = useUsageTracker(); const detailsPageTabs: EuiTabbedContentTab[] = useMemo(() => { @@ -201,7 +201,7 @@ export const SearchIndexDetailsPage = () => { bottomBorder={false} rightSideItems={[ - {isDocumentsExists ? ( + {hasDocuments ? ( <> { , From 5f54db219788d905fefcb7079f2b906f3ca0f106 Mon Sep 17 00:00:00 2001 From: Yan Savitski Date: Thu, 17 Oct 2024 20:47:53 +0200 Subject: [PATCH 07/10] Create navigate to discover hook --- .../components/indices/details_page.tsx | 8 ++----- .../public/hooks/use_navigate_to_discover.ts | 22 +++++++++++++++++++ 2 files changed, 24 insertions(+), 6 deletions(-) create mode 100644 x-pack/plugins/search_indices/public/hooks/use_navigate_to_discover.ts diff --git a/x-pack/plugins/search_indices/public/components/indices/details_page.tsx b/x-pack/plugins/search_indices/public/components/indices/details_page.tsx index 539bcf6660adb..9ff096488afe3 100644 --- a/x-pack/plugins/search_indices/public/components/indices/details_page.tsx +++ b/x-pack/plugins/search_indices/public/components/indices/details_page.tsx @@ -21,6 +21,7 @@ import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; import { SectionLoading } from '@kbn/es-ui-shared-plugin/public'; import { ApiKeyForm } from '@kbn/search-api-keys-components'; +import { useNavigateToDiscover } from '../../hooks/use_navigate_to_discover'; import { useIndex } from '../../hooks/api/use_index'; import { useKibana } from '../../hooks/use_kibana'; import { ConnectionDetails } from '../connection_details/connection_details'; @@ -64,12 +65,7 @@ export const SearchIndexDetailsPage = () => { await playgroundLocator.navigate({ 'default-index': index.name }); } }, [share, index]); - const navigateToDiscover = useCallback(async () => { - const discoverLocator = share.url.locators.get('DISCOVER_APP_LOCATOR'); - if (discoverLocator && indexName) { - await discoverLocator.navigate({ dataViewSpec: { title: indexName } }); - } - }, [share, indexName]); + const navigateToDiscover = useNavigateToDiscover(indexName); const [hasDocuments, setHasDocuments] = useState(false); const [isDocumentsLoading, setDocumentsLoading] = useState(true); diff --git a/x-pack/plugins/search_indices/public/hooks/use_navigate_to_discover.ts b/x-pack/plugins/search_indices/public/hooks/use_navigate_to_discover.ts new file mode 100644 index 0000000000000..b0239c89c46bc --- /dev/null +++ b/x-pack/plugins/search_indices/public/hooks/use_navigate_to_discover.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useCallback } from 'react'; +import { useKibana } from './use_kibana'; + +const DISCOVER_LOCATOR_ID = 'DISCOVER_APP_LOCATOR'; + +export const useNavigateToDiscover = (indexName: string) => { + const { share } = useKibana().services; + + return useCallback(async () => { + const discoverLocator = share.url.locators.get(DISCOVER_LOCATOR_ID); + if (discoverLocator && indexName) { + await discoverLocator.navigate({ dataViewSpec: { title: indexName } }); + } + }, [share, indexName]); +}; From df56fac320ba83cbed850f7a39d59f74882a1570 Mon Sep 17 00:00:00 2001 From: Yan Savitski Date: Fri, 18 Oct 2024 12:27:24 +0200 Subject: [PATCH 08/10] Add FTR tests --- .../page_objects/svl_search_index_detail_page.ts | 10 ++++++---- .../test_suites/search/search_index_detail.ts | 12 +++++------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/x-pack/test_serverless/functional/page_objects/svl_search_index_detail_page.ts b/x-pack/test_serverless/functional/page_objects/svl_search_index_detail_page.ts index ed11a09c26b66..84e0339e7dfbc 100644 --- a/x-pack/test_serverless/functional/page_objects/svl_search_index_detail_page.ts +++ b/x-pack/test_serverless/functional/page_objects/svl_search_index_detail_page.ts @@ -20,8 +20,10 @@ export function SvlSearchIndexDetailPageProvider({ getService }: FtrProviderCont async expectAPIReferenceDocLinkExists() { await testSubjects.existOrFail('ApiReferenceDoc', { timeout: 2000 }); }, - async expectUseInPlaygroundLinkExists() { + async expectActionItemReplacedWhenHasDocs() { + await testSubjects.missingOrFailt('ApiReferenceDoc', { timeout: 2000 }); await testSubjects.existOrFail('useInPlaygroundLink', { timeout: 5000 }); + await testSubjects.existOrFail('viewInDiscoverLink', { timeout: 5000 }); }, async expectConnectionDetails() { await testSubjects.existOrFail('connectionDetailsEndpoint', { timeout: 2000 }); @@ -76,9 +78,6 @@ export function SvlSearchIndexDetailPageProvider({ getService }: FtrProviderCont async expectMoreOptionsOverviewMenuIsShown() { await testSubjects.existOrFail('moreOptionsContextMenu'); }, - async expectPlaygroundButtonExistsInMoreOptions() { - await testSubjects.existOrFail('moreOptionsPlayground'); - }, async expectToNavigateToPlayground(indexName: string) { await testSubjects.click('moreOptionsPlayground'); expect(await browser.getCurrentUrl()).contain( @@ -89,6 +88,9 @@ export function SvlSearchIndexDetailPageProvider({ getService }: FtrProviderCont async expectAPIReferenceDocLinkExistsInMoreOptions() { await testSubjects.existOrFail('moreOptionsApiReference', { timeout: 2000 }); }, + async expectAPIReferenceDocLinkMissingInMoreOptions() { + await testSubjects.missingOrFailt('moreOptionsApiReference', { timeout: 2000 }); + }, async expectDeleteIndexButtonExistsInMoreOptions() { await testSubjects.existOrFail('moreOptionsDeleteIndex'); }, diff --git a/x-pack/test_serverless/functional/test_suites/search/search_index_detail.ts b/x-pack/test_serverless/functional/test_suites/search/search_index_detail.ts index 78ff5a4d62324..8797826513afc 100644 --- a/x-pack/test_serverless/functional/test_suites/search/search_index_detail.ts +++ b/x-pack/test_serverless/functional/test_suites/search/search_index_detail.ts @@ -46,6 +46,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await pageObjects.svlSearchIndexDetailPage.expectIndexDetailPageHeader(); await pageObjects.svlSearchIndexDetailPage.expectSearchIndexDetailsTabsExists(); await pageObjects.svlSearchIndexDetailPage.expectAPIReferenceDocLinkExists(); + await pageObjects.svlSearchIndexDetailPage.expectAPIReferenceDocLinkMissingInMoreOptions(); }); it('should have embedded dev console', async () => { await testHasEmbeddedConsole(pageObjects); @@ -109,7 +110,10 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await svlSearchNavigation.navigateToIndexDetailPage(indexName); }); it('menu action item should be replaced with playground', async () => { - await pageObjects.svlSearchIndexDetailPage.expectUseInPlaygroundLinkExists(); + await pageObjects.svlSearchIndexDetailPage.expectActionItemReplacedWhenHasDocs(); + }); + it('should have link to API reference doc link in options menu', async () => { + await pageObjects.svlSearchIndexDetailPage.expectAPIReferenceDocLinkExistsInMoreOptions(); }); it('should have index documents', async () => { await pageObjects.svlSearchIndexDetailPage.expectHasIndexDocuments(); @@ -159,12 +163,6 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await pageObjects.svlSearchIndexDetailPage.clickMoreOptionsActionsButton(); await pageObjects.svlSearchIndexDetailPage.expectMoreOptionsOverviewMenuIsShown(); }); - it('should have link to API reference doc link', async () => { - await pageObjects.svlSearchIndexDetailPage.expectAPIReferenceDocLinkExistsInMoreOptions(); - }); - it('should have link to playground', async () => { - await pageObjects.svlSearchIndexDetailPage.expectPlaygroundButtonExistsInMoreOptions(); - }); it('should delete index', async () => { await pageObjects.svlSearchIndexDetailPage.expectDeleteIndexButtonExistsInMoreOptions(); await pageObjects.svlSearchIndexDetailPage.clickDeleteIndexButton(); From 285508749d484a2e77c64d5d65e197411eee4069 Mon Sep 17 00:00:00 2001 From: Yan Savitski Date: Fri, 18 Oct 2024 13:29:27 +0200 Subject: [PATCH 09/10] Fix misspelling --- .../functional/page_objects/svl_search_index_detail_page.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/test_serverless/functional/page_objects/svl_search_index_detail_page.ts b/x-pack/test_serverless/functional/page_objects/svl_search_index_detail_page.ts index 089c806cefe8e..161be50cae410 100644 --- a/x-pack/test_serverless/functional/page_objects/svl_search_index_detail_page.ts +++ b/x-pack/test_serverless/functional/page_objects/svl_search_index_detail_page.ts @@ -21,7 +21,7 @@ export function SvlSearchIndexDetailPageProvider({ getService }: FtrProviderCont await testSubjects.existOrFail('ApiReferenceDoc', { timeout: 2000 }); }, async expectActionItemReplacedWhenHasDocs() { - await testSubjects.missingOrFailt('ApiReferenceDoc', { timeout: 2000 }); + await testSubjects.missingOrFail('ApiReferenceDoc', { timeout: 2000 }); await testSubjects.existOrFail('useInPlaygroundLink', { timeout: 5000 }); await testSubjects.existOrFail('viewInDiscoverLink', { timeout: 5000 }); }, @@ -89,7 +89,7 @@ export function SvlSearchIndexDetailPageProvider({ getService }: FtrProviderCont await testSubjects.existOrFail('moreOptionsApiReference', { timeout: 2000 }); }, async expectAPIReferenceDocLinkMissingInMoreOptions() { - await testSubjects.missingOrFailt('moreOptionsApiReference', { timeout: 2000 }); + await testSubjects.missingOrFail('moreOptionsApiReference', { timeout: 2000 }); }, async expectDeleteIndexButtonExistsInMoreOptions() { await testSubjects.existOrFail('moreOptionsDeleteIndex'); From 2c62b3b01b48ce97e2d6e624a3fcc702e63246e2 Mon Sep 17 00:00:00 2001 From: Yan Savitski Date: Fri, 18 Oct 2024 15:42:17 +0200 Subject: [PATCH 10/10] Update FTR testcase --- .../functional/test_suites/search/search_index_detail.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/test_serverless/functional/test_suites/search/search_index_detail.ts b/x-pack/test_serverless/functional/test_suites/search/search_index_detail.ts index d3a0b826f082f..eeb1487816d7c 100644 --- a/x-pack/test_serverless/functional/test_suites/search/search_index_detail.ts +++ b/x-pack/test_serverless/functional/test_suites/search/search_index_detail.ts @@ -121,6 +121,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await pageObjects.svlSearchIndexDetailPage.expectActionItemReplacedWhenHasDocs(); }); it('should have link to API reference doc link in options menu', async () => { + await pageObjects.svlSearchIndexDetailPage.clickMoreOptionsActionsButton(); await pageObjects.svlSearchIndexDetailPage.expectAPIReferenceDocLinkExistsInMoreOptions(); }); it('should have index documents', async () => {