From e955cb044fcad83fd9e1c6631eddd95aa7357ad7 Mon Sep 17 00:00:00 2001 From: Rodney Norris Date: Fri, 18 Oct 2024 11:39:21 -0500 Subject: [PATCH] [Search][Serverless] Enabled Onboarding without Feature Flag (#196755) ## Summary This PR removes the feature flag check for the new search onboarding experience in Serverless. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [x] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed --- x-pack/plugins/search_indices/common/index.ts | 2 - .../search_indices/public/feature_flags.ts | 13 ----- .../plugins/search_indices/public/plugin.ts | 8 --- x-pack/plugins/serverless_search/kibana.jsonc | 2 +- .../public/navigation_tree.ts | 31 ++++------- .../serverless_search/public/plugin.ts | 53 +++++++------------ .../plugins/serverless_search/public/types.ts | 4 +- .../services/svl_search_navigation.ts | 3 +- .../search/config.feature_flags.ts | 7 ++- .../functional/test_suites/search/config.ts | 8 ++- .../test_suites/search/console_notebooks.ts | 5 +- .../test_suites/search/index.feature_flags.ts | 4 +- .../functional/test_suites/search/index.ts | 5 +- .../test_suites/search/navigation.ts | 29 +++++++--- 14 files changed, 78 insertions(+), 96 deletions(-) delete mode 100644 x-pack/plugins/search_indices/public/feature_flags.ts diff --git a/x-pack/plugins/search_indices/common/index.ts b/x-pack/plugins/search_indices/common/index.ts index 3b8ffc50812611..e640397e3936d8 100644 --- a/x-pack/plugins/search_indices/common/index.ts +++ b/x-pack/plugins/search_indices/common/index.ts @@ -12,6 +12,4 @@ export const PLUGIN_NAME = 'searchIndices'; export const START_APP_ID: SearchStart = 'elasticsearchStart'; export const INDICES_APP_ID: SearchIndices = 'elasticsearchIndices'; -export const GLOBAL_EMPTY_STATE_FEATURE_FLAG_ID = 'searchIndices:globalEmptyStateEnabled'; - export type { IndicesStatusResponse, UserStartPrivilegesResponse } from './types'; diff --git a/x-pack/plugins/search_indices/public/feature_flags.ts b/x-pack/plugins/search_indices/public/feature_flags.ts deleted file mode 100644 index ec114506d4f8cc..00000000000000 --- a/x-pack/plugins/search_indices/public/feature_flags.ts +++ /dev/null @@ -1,13 +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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { IUiSettingsClient } from '@kbn/core/public'; -import { GLOBAL_EMPTY_STATE_FEATURE_FLAG_ID } from '../common'; - -export function isGlobalEmptyStateEnabled(uiSettings: IUiSettingsClient): boolean { - return uiSettings.get(GLOBAL_EMPTY_STATE_FEATURE_FLAG_ID, false); -} diff --git a/x-pack/plugins/search_indices/public/plugin.ts b/x-pack/plugins/search_indices/public/plugin.ts index 8ff86d4d3c7747..2f9a8ca3cf950d 100644 --- a/x-pack/plugins/search_indices/public/plugin.ts +++ b/x-pack/plugins/search_indices/public/plugin.ts @@ -18,7 +18,6 @@ import type { import { initQueryClient } from './services/query_client'; import { INDICES_APP_ID, START_APP_ID } from '../common'; import { INDICES_APP_BASE, START_APP_BASE } from './routes'; -import { isGlobalEmptyStateEnabled } from './feature_flags'; export class SearchIndicesPlugin implements Plugin @@ -28,13 +27,6 @@ export class SearchIndicesPlugin public setup( core: CoreSetup ): SearchIndicesPluginSetup { - if (!isGlobalEmptyStateEnabled(core.uiSettings)) { - return { - enabled: this.pluginEnabled, - startAppId: START_APP_ID, - startRoute: START_APP_BASE, - }; - } this.pluginEnabled = true; const queryClient = initQueryClient(core.notifications.toasts); diff --git a/x-pack/plugins/serverless_search/kibana.jsonc b/x-pack/plugins/serverless_search/kibana.jsonc index 8ef675723cf0e9..504c346262492a 100644 --- a/x-pack/plugins/serverless_search/kibana.jsonc +++ b/x-pack/plugins/serverless_search/kibana.jsonc @@ -16,6 +16,7 @@ "devTools", "discover", "management", + "searchIndices", "searchprofiler", "security", "serverless", @@ -25,7 +26,6 @@ "optionalPlugins": [ "indexManagement", "searchConnectors", - "searchIndices", "searchInferenceEndpoints", "usageCollection" ], diff --git a/x-pack/plugins/serverless_search/public/navigation_tree.ts b/x-pack/plugins/serverless_search/public/navigation_tree.ts index 5f6819dda16730..3906eb8b2b8642 100644 --- a/x-pack/plugins/serverless_search/public/navigation_tree.ts +++ b/x-pack/plugins/serverless_search/public/navigation_tree.ts @@ -5,27 +5,11 @@ * 2.0. */ -import type { - AppDeepLinkId, - NavigationTreeDefinition, - NodeDefinition, -} from '@kbn/core-chrome-browser'; +import type { NavigationTreeDefinition } from '@kbn/core-chrome-browser'; import { i18n } from '@kbn/i18n'; import { CONNECTORS_LABEL } from '../common/i18n_string'; -const gettingStartedItem: NodeDefinition = { - id: 'gettingStarted', - title: i18n.translate('xpack.serverlessSearch.nav.gettingStarted', { - defaultMessage: 'Getting Started', - }), - link: 'serverlessElasticsearch', - spaceBefore: 'm', -}; - -export const navigationTree = ( - homeLink: AppDeepLinkId = 'serverlessElasticsearch' as AppDeepLinkId, - showGettingStarted: boolean -): NavigationTreeDefinition => ({ +export const navigationTree = (): NavigationTreeDefinition => ({ body: [ { type: 'navGroup', @@ -41,7 +25,7 @@ export const navigationTree = ( title: i18n.translate('xpack.serverlessSearch.nav.home', { defaultMessage: 'Home', }), - link: homeLink, + link: 'elasticsearchStart', spaceBefore: 'm', }, { @@ -146,7 +130,14 @@ export const navigationTree = ( spaceBefore: 'm', children: [{ link: 'maps' }], }, - ...(showGettingStarted ? [gettingStartedItem] : []), + { + id: 'gettingStarted', + title: i18n.translate('xpack.serverlessSearch.nav.gettingStarted', { + defaultMessage: 'Getting Started', + }), + link: 'serverlessElasticsearch', + spaceBefore: 'm', + }, ], }, ], diff --git a/x-pack/plugins/serverless_search/public/plugin.ts b/x-pack/plugins/serverless_search/public/plugin.ts index c223b9a6b11dbc..491252a6d9e9f2 100644 --- a/x-pack/plugins/serverless_search/public/plugin.ts +++ b/x-pack/plugins/serverless_search/public/plugin.ts @@ -73,10 +73,6 @@ export class ServerlessSearchPlugin const homeTitle = i18n.translate('xpack.serverlessSearch.app.home.title', { defaultMessage: 'Home', }); - const useGlobalEmptyState = setupDeps.searchIndices?.enabled ?? false; - const serverlessElasticsearchAppRoute = useGlobalEmptyState - ? '/app/elasticsearch/getting_started' - : '/app/elasticsearch'; core.application.register({ id: 'serverlessElasticsearch', @@ -85,7 +81,7 @@ export class ServerlessSearchPlugin }), euiIconType: 'logoElastic', category: DEFAULT_APP_CATEGORIES.enterpriseSearch, - appRoute: serverlessElasticsearchAppRoute, + appRoute: '/app/elasticsearch/getting_started', async mount({ element, history }: AppMountParameters) { const { renderApp } = await import('./application/elasticsearch'); const [coreStart, services] = await core.getStartServices(); @@ -124,23 +120,21 @@ export class ServerlessSearchPlugin }, }); - if (useGlobalEmptyState) { - const redirectApp = setupDeps.searchIndices!.startAppId; - core.application.register({ - id: 'serverlessHomeRedirect', - title: homeTitle, - appRoute: '/app/elasticsearch', - euiIconType: 'logoElastic', - category: DEFAULT_APP_CATEGORIES.enterpriseSearch, - visibleIn: [], - async mount({}: AppMountParameters) { - const [coreStart] = await core.getStartServices(); - coreStart.chrome.docTitle.change(homeTitle); - coreStart.application.navigateToApp(redirectApp); - return () => {}; - }, - }); - } + const { searchIndices } = setupDeps; + core.application.register({ + id: 'serverlessHomeRedirect', + title: homeTitle, + appRoute: '/app/elasticsearch', + euiIconType: 'logoElastic', + category: DEFAULT_APP_CATEGORIES.enterpriseSearch, + visibleIn: [], + async mount({}: AppMountParameters) { + const [coreStart] = await core.getStartServices(); + coreStart.chrome.docTitle.change(homeTitle); + coreStart.application.navigateToApp(searchIndices.startAppId); + return () => {}; + }, + }); setupDeps.discover.showInlineTopNav(); @@ -152,18 +146,9 @@ export class ServerlessSearchPlugin services: ServerlessSearchPluginStartDependencies ): ServerlessSearchPluginStart { const { serverless, management, indexManagement, security } = services; - const useGlobalEmptyState = services.searchIndices?.enabled ?? false; - const homeRoute = useGlobalEmptyState - ? services.searchIndices!.startRoute - : '/app/elasticsearch'; - serverless.setProjectHome(homeRoute); - - const navigationTree$ = of( - navigationTree( - useGlobalEmptyState ? services.searchIndices?.startAppId : undefined, - useGlobalEmptyState - ) - ); + serverless.setProjectHome(services.searchIndices.startRoute); + + const navigationTree$ = of(navigationTree()); serverless.initNavigation('search', navigationTree$, { dataTestSubj: 'svlSearchSideNav' }); const extendCardNavDefinitions = serverless.getNavigationCards( diff --git a/x-pack/plugins/serverless_search/public/types.ts b/x-pack/plugins/serverless_search/public/types.ts index 65952c963a2a45..19b3f0fa6baa59 100644 --- a/x-pack/plugins/serverless_search/public/types.ts +++ b/x-pack/plugins/serverless_search/public/types.ts @@ -31,7 +31,7 @@ export interface ServerlessSearchPluginSetupDependencies { management: ManagementSetup; serverless: ServerlessPluginSetup; discover: DiscoverSetup; - searchIndices?: SearchIndicesPluginSetup; + searchIndices: SearchIndicesPluginSetup; } export interface ServerlessSearchPluginStartDependencies { @@ -44,5 +44,5 @@ export interface ServerlessSearchPluginStartDependencies { serverless: ServerlessPluginStart; share: SharePluginStart; indexManagement?: IndexManagementPluginStart; - searchIndices?: SearchIndicesPluginStart; + searchIndices: SearchIndicesPluginStart; } diff --git a/x-pack/test_serverless/functional/services/svl_search_navigation.ts b/x-pack/test_serverless/functional/services/svl_search_navigation.ts index cf91aac1127738..1f27cf18ec8cba 100644 --- a/x-pack/test_serverless/functional/services/svl_search_navigation.ts +++ b/x-pack/test_serverless/functional/services/svl_search_navigation.ts @@ -19,7 +19,8 @@ export function SvlSearchNavigationServiceProvider({ async navigateToLandingPage() { await retry.tryForTime(60 * 1000, async () => { await PageObjects.common.navigateToApp('landingPage'); - await testSubjects.existOrFail('svlSearchOverviewPage', { timeout: 2000 }); + // Wait for the side nav, since the landing page will sometimes redirect to index management now + await testSubjects.existOrFail('svlSearchSideNav', { timeout: 2000 }); }); }, async navigateToGettingStartedPage() { diff --git a/x-pack/test_serverless/functional/test_suites/search/config.feature_flags.ts b/x-pack/test_serverless/functional/test_suites/search/config.feature_flags.ts index 85724f48d38ccc..592da3d368c0de 100644 --- a/x-pack/test_serverless/functional/test_suites/search/config.feature_flags.ts +++ b/x-pack/test_serverless/functional/test_suites/search/config.feature_flags.ts @@ -26,7 +26,6 @@ export default createTestConfig({ `--xpack.cloud.organization_url=/account/members`, `--xpack.security.roleManagementEnabled=true`, `--xpack.spaces.maxSpaces=100`, // enables spaces UI capabilities - `--uiSettings.overrides.searchIndices:globalEmptyStateEnabled=true`, // global empty state FF ], // load tests in the index file testFiles: [require.resolve('./index.feature_flags.ts')], @@ -38,6 +37,12 @@ export default createTestConfig({ serverlessElasticsearch: { pathname: '/app/elasticsearch/getting_started', }, + serverlessConnectors: { + pathname: '/app/connectors', + }, + searchPlayground: { + pathname: '/app/search_playground', + }, elasticsearchStart: { pathname: '/app/elasticsearch/start', }, diff --git a/x-pack/test_serverless/functional/test_suites/search/config.ts b/x-pack/test_serverless/functional/test_suites/search/config.ts index 72684674d3c106..b01c80ec2dbb75 100644 --- a/x-pack/test_serverless/functional/test_suites/search/config.ts +++ b/x-pack/test_serverless/functional/test_suites/search/config.ts @@ -33,7 +33,7 @@ export default createTestConfig({ ], apps: { serverlessElasticsearch: { - pathname: '/app/elasticsearch', + pathname: '/app/elasticsearch/getting_started', }, serverlessConnectors: { pathname: '/app/connectors', @@ -41,5 +41,11 @@ export default createTestConfig({ searchPlayground: { pathname: '/app/search_playground', }, + elasticsearchStart: { + pathname: '/app/elasticsearch/start', + }, + elasticsearchIndices: { + pathname: '/app/elasticsearch/indices', + }, }, }); diff --git a/x-pack/test_serverless/functional/test_suites/search/console_notebooks.ts b/x-pack/test_serverless/functional/test_suites/search/console_notebooks.ts index 5cf4a4ceeb856b..8d1377bce93a3b 100644 --- a/x-pack/test_serverless/functional/test_suites/search/console_notebooks.ts +++ b/x-pack/test_serverless/functional/test_suites/search/console_notebooks.ts @@ -7,12 +7,15 @@ import { FtrProviderContext } from '../../ftr_provider_context'; -export default function ({ getPageObjects }: FtrProviderContext) { +export default function ({ getPageObjects, getService }: FtrProviderContext) { const pageObjects = getPageObjects(['svlCommonPage', 'embeddedConsole']); + const svlSearchNavigation = getService('svlSearchNavigation'); describe('Console Notebooks', function () { before(async () => { await pageObjects.svlCommonPage.loginAsViewer(); + + await svlSearchNavigation.navigateToGettingStartedPage(); }); it('has notebooks view available', async () => { diff --git a/x-pack/test_serverless/functional/test_suites/search/index.feature_flags.ts b/x-pack/test_serverless/functional/test_suites/search/index.feature_flags.ts index db9df2e8d913cb..bc9e19f2ae71fb 100644 --- a/x-pack/test_serverless/functional/test_suites/search/index.feature_flags.ts +++ b/x-pack/test_serverless/functional/test_suites/search/index.feature_flags.ts @@ -10,9 +10,7 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ loadTestFile }: FtrProviderContext) { describe('serverless search UI - feature flags', function () { // add tests that require feature flags, defined in config.feature_flags.ts - loadTestFile(require.resolve('./elasticsearch_start.ts')); - loadTestFile(require.resolve('./search_index_detail.ts')); - loadTestFile(require.resolve('./getting_started')); + loadTestFile(require.resolve('../common/platform_security/navigation/management_nav_cards.ts')); loadTestFile(require.resolve('../common/platform_security/roles.ts')); loadTestFile(require.resolve('../common/spaces/multiple_spaces_enabled.ts')); diff --git a/x-pack/test_serverless/functional/test_suites/search/index.ts b/x-pack/test_serverless/functional/test_suites/search/index.ts index fe472f064eb078..903f98c63b776a 100644 --- a/x-pack/test_serverless/functional/test_suites/search/index.ts +++ b/x-pack/test_serverless/functional/test_suites/search/index.ts @@ -11,11 +11,12 @@ export default function ({ loadTestFile }: FtrProviderContext) { describe('serverless search UI', function () { this.tags(['esGate']); - loadTestFile(require.resolve('./getting_started')); loadTestFile(require.resolve('./navigation')); + loadTestFile(require.resolve('./elasticsearch_start.ts')); + loadTestFile(require.resolve('./search_index_detail.ts')); + loadTestFile(require.resolve('./getting_started')); loadTestFile(require.resolve('./connectors/connectors_overview')); loadTestFile(require.resolve('./default_dataview')); - loadTestFile(require.resolve('./index_management')); loadTestFile(require.resolve('./pipelines')); loadTestFile(require.resolve('./cases/attachment_framework')); loadTestFile(require.resolve('./dashboards/build_dashboard')); diff --git a/x-pack/test_serverless/functional/test_suites/search/navigation.ts b/x-pack/test_serverless/functional/test_suites/search/navigation.ts index b0517f31f4463b..f72bc70b1ee1da 100644 --- a/x-pack/test_serverless/functional/test_suites/search/navigation.ts +++ b/x-pack/test_serverless/functional/test_suites/search/navigation.ts @@ -34,12 +34,12 @@ export default function ({ getPageObject, getService }: FtrProviderContext) { // check side nav links await solutionNavigation.sidenav.expectSectionExists('search_project_nav'); await solutionNavigation.sidenav.expectLinkActive({ - deepLinkId: 'serverlessElasticsearch', + deepLinkId: 'elasticsearchStart', }); await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ - deepLinkId: 'serverlessElasticsearch', + deepLinkId: 'elasticsearchStart', }); - await testSubjects.existOrFail(`svlSearchOverviewPage`); + await testSubjects.existOrFail(`elasticsearchStartPage`); // check Data // > Index Management @@ -144,6 +144,21 @@ export default function ({ getPageObject, getService }: FtrProviderContext) { deepLinkId: 'maps', }); + // check Getting Started + await solutionNavigation.sidenav.clickLink({ + deepLinkId: 'serverlessElasticsearch', + }); + await solutionNavigation.sidenav.expectLinkActive({ + deepLinkId: 'serverlessElasticsearch', + }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ text: 'Getting Started' }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ + text: 'Getting Started', + }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ + deepLinkId: 'serverlessElasticsearch', + }); + // Open Project Settings await solutionNavigation.sidenav.openSection('project_settings_project_nav'); // check Project Settings @@ -174,10 +189,10 @@ export default function ({ getPageObject, getService }: FtrProviderContext) { // navigate back to serverless search overview await svlCommonNavigation.clickLogo(); await svlCommonNavigation.sidenav.expectLinkActive({ - deepLinkId: 'serverlessElasticsearch', + deepLinkId: 'elasticsearchStart', }); await svlCommonNavigation.breadcrumbs.expectBreadcrumbExists({ text: `Home` }); - await testSubjects.existOrFail(`svlSearchOverviewPage`); + await testSubjects.existOrFail(`elasticsearchStartPage`); await expectNoPageReload(); }); @@ -248,7 +263,7 @@ export default function ({ getPageObject, getService }: FtrProviderContext) { await solutionNavigation.sidenav.expectLinkExists({ text: 'Dashboards' }); await solutionNavigation.sidenav.expectLinkExists({ text: 'Other tools' }); await solutionNavigation.sidenav.expectLinkExists({ text: 'Maps' }); - // await solutionNavigation.sidenav.expectLinkExists({ text: 'Getting Started' }); + await solutionNavigation.sidenav.expectLinkExists({ text: 'Getting Started' }); await solutionNavigation.sidenav.expectLinkExists({ text: 'Trained models' }); await solutionNavigation.sidenav.expectLinkExists({ text: 'Management' }); @@ -273,7 +288,7 @@ export default function ({ getPageObject, getService }: FtrProviderContext) { 'dashboards', 'otherTools', 'maps', - // 'gettingStarted', + 'gettingStarted', 'project_settings_project_nav', 'ml:modelManagement', 'management',