Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[8.x] [Search] Refactor: abstracting classic nav items (#196579) #198369

Merged
merged 1 commit into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/deeplinks/search/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@ export const SERVERLESS_ES_SEARCH_INFERENCE_ENDPOINTS_ID = 'searchInferenceEndpo
export const SEARCH_HOMEPAGE = 'searchHomepage';
export const SEARCH_INDICES_START = 'elasticsearchStart';
export const SEARCH_INDICES = 'elasticsearchIndices';
export const SEARCH_ELASTICSEARCH = 'enterpriseSearchElasticsearch';
export const SEARCH_VECTOR_SEARCH = 'enterpriseSearchVectorSearch';
export const SEARCH_SEMANTIC_SEARCH = 'enterpriseSearchSemanticSearch';
export const SEARCH_AI_SEARCH = 'enterpriseSearchAISearch';
14 changes: 13 additions & 1 deletion packages/deeplinks/search/deep_links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ import {
SEARCH_HOMEPAGE,
SEARCH_INDICES_START,
SEARCH_INDICES,
SEARCH_ELASTICSEARCH,
SEARCH_VECTOR_SEARCH,
SEARCH_SEMANTIC_SEARCH,
SEARCH_AI_SEARCH,
} from './constants';

export type EnterpriseSearchApp = typeof ENTERPRISE_SEARCH_APP_ID;
Expand All @@ -38,6 +42,10 @@ export type SearchInferenceEndpointsId = typeof SERVERLESS_ES_SEARCH_INFERENCE_E
export type SearchHomepage = typeof SEARCH_HOMEPAGE;
export type SearchStart = typeof SEARCH_INDICES_START;
export type SearchIndices = typeof SEARCH_INDICES;
export type SearchElasticsearch = typeof SEARCH_ELASTICSEARCH;
export type SearchVectorSearch = typeof SEARCH_VECTOR_SEARCH;
export type SearchSemanticSearch = typeof SEARCH_SEMANTIC_SEARCH;
export type SearchAISearch = typeof SEARCH_AI_SEARCH;

export type ContentLinkId = 'searchIndices' | 'connectors' | 'webCrawlers';

Expand Down Expand Up @@ -65,4 +73,8 @@ export type DeepLinkId =
| `${EnterpriseSearchAppsearchApp}:${AppsearchLinkId}`
| `${EnterpriseSearchRelevanceApp}:${RelevanceLinkId}`
| SearchStart
| SearchIndices;
| SearchIndices
| SearchElasticsearch
| SearchVectorSearch
| SearchSemanticSearch
| SearchAISearch;
4 changes: 4 additions & 0 deletions packages/deeplinks/search/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ export {
ENTERPRISE_SEARCH_WORKPLACESEARCH_APP_ID,
SERVERLESS_ES_APP_ID,
SERVERLESS_ES_CONNECTORS_ID,
SEARCH_ELASTICSEARCH,
SEARCH_VECTOR_SEARCH,
SEARCH_SEMANTIC_SEARCH,
SEARCH_AI_SEARCH,
} from './constants';

export type {
Expand Down
23 changes: 19 additions & 4 deletions x-pack/plugins/enterprise_search/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ import {
ENTERPRISE_SEARCH_ANALYTICS_APP_ID,
ENTERPRISE_SEARCH_APPSEARCH_APP_ID,
ENTERPRISE_SEARCH_WORKPLACESEARCH_APP_ID,
SEARCH_ELASTICSEARCH,
SEARCH_VECTOR_SEARCH,
SEARCH_SEMANTIC_SEARCH,
SEARCH_AI_SEARCH,
} from '@kbn/deeplinks-search';
import { i18n } from '@kbn/i18n';

Expand Down Expand Up @@ -58,7 +62,7 @@ export const ENTERPRISE_SEARCH_CONTENT_PLUGIN = {
};

export const AI_SEARCH_PLUGIN = {
ID: 'enterpriseSearchAISearch',
ID: SEARCH_AI_SEARCH,
NAME: i18n.translate('xpack.enterpriseSearch.aiSearch.productName', {
defaultMessage: 'AI Search',
}),
Expand Down Expand Up @@ -91,7 +95,7 @@ export const ANALYTICS_PLUGIN = {
};

export const ELASTICSEARCH_PLUGIN = {
ID: 'enterpriseSearchElasticsearch',
ID: SEARCH_ELASTICSEARCH,
NAME: i18n.translate('xpack.enterpriseSearch.elasticsearch.productName', {
defaultMessage: 'Elasticsearch',
}),
Expand Down Expand Up @@ -167,7 +171,7 @@ export const VECTOR_SEARCH_PLUGIN = {
defaultMessage:
'Elasticsearch can be used as a vector database, which enables vector search and semantic search use cases.',
}),
ID: 'enterpriseSearchVectorSearch',
ID: SEARCH_VECTOR_SEARCH,
LOGO: 'logoEnterpriseSearch',
NAME: i18n.translate('xpack.enterpriseSearch.vectorSearch.productName', {
defaultMessage: 'Vector Search',
Expand All @@ -184,7 +188,7 @@ export const SEMANTIC_SEARCH_PLUGIN = {
defaultMessage:
'Easily add semantic search to Elasticsearch with inference endpoints and the semantic_text field type, to boost search relevance.',
}),
ID: 'enterpriseSearchSemanticSearch',
ID: SEARCH_SEMANTIC_SEARCH,
LOGO: 'logoEnterpriseSearch',
NAME: i18n.translate('xpack.enterpriseSearch.SemanticSearch.productName', {
defaultMessage: 'Semantic Search',
Expand Down Expand Up @@ -297,3 +301,14 @@ export const CRAWLER = {

// TODO remove this once the connector service types are no longer in "example" state
export const EXAMPLE_CONNECTOR_SERVICE_TYPES = ['opentext_documentum'];

export const GETTING_STARTED_TITLE = i18n.translate('xpack.enterpriseSearch.gettingStarted.title', {
defaultMessage: 'Getting started',
});

export const SEARCH_APPS_BREADCRUMB = i18n.translate(
'xpack.enterpriseSearch.searchApplications.breadcrumb',
{
defaultMessage: 'Search Applications',
}
);
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export const mockKibanaValues = {
data: dataPluginMock.createStartContract(),
esConfig: { elasticsearch_host: 'https://your_deployment_url' },
getChromeStyle$: jest.fn().mockReturnValue(of('classic')),
getNavLinks: jest.fn().mockReturnValue([]),
guidedOnboarding: {},
history: mockHistory,
indexMappingComponent: null,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import React, { useLayoutEffect } from 'react';

import { useValues } from 'kea';

import useObservable from 'react-use/lib/useObservable';

import { SEARCH_PRODUCT_NAME } from '../../../../../common/constants';
import { KibanaLogic } from '../../../shared/kibana';
import { SetSearchPlaygroundChrome } from '../../../shared/kibana_chrome/set_chrome';
import { EnterpriseSearchPageTemplateWrapper, PageTemplateProps } from '../../../shared/layout';
import { useEnterpriseSearchNav } from '../../../shared/layout';
import { SendEnterpriseSearchTelemetry } from '../../../shared/telemetry';

import { PlaygroundHeaderDocsAction } from './header_docs_action';

export type SearchPlaygroundPageTemplateProps = Omit<
PageTemplateProps,
'useEndpointHeaderActions'
> & {
hasSchemaConflicts?: boolean;
restrictWidth?: boolean;
searchApplicationName?: string;
};

export const SearchPlaygroundPageTemplate: React.FC<SearchPlaygroundPageTemplateProps> = ({
children,
pageChrome,
pageViewTelemetry,
searchApplicationName,
hasSchemaConflicts,
restrictWidth = true,
...pageTemplateProps
}) => {
const navItems = useEnterpriseSearchNav();

const { renderHeaderActions, getChromeStyle$ } = useValues(KibanaLogic);
const chromeStyle = useObservable(getChromeStyle$(), 'classic');

useLayoutEffect(() => {
renderHeaderActions(PlaygroundHeaderDocsAction);

return () => {
renderHeaderActions();
};
}, []);

return (
<EnterpriseSearchPageTemplateWrapper
{...pageTemplateProps}
solutionNav={{
items: chromeStyle === 'classic' ? navItems : undefined,
name: SEARCH_PRODUCT_NAME,
}}
restrictWidth={restrictWidth}
setPageChrome={pageChrome && <SetSearchPlaygroundChrome trail={pageChrome} />}
useEndpointHeaderActions={false}
>
{pageViewTelemetry && (
<SendEnterpriseSearchTelemetry action="viewed" metric={pageViewTelemetry} />
)}
{children}
</EnterpriseSearchPageTemplateWrapper>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import { useValues } from 'kea';
import { i18n } from '@kbn/i18n';

import { KibanaLogic } from '../../../shared/kibana';
import { EnterpriseSearchApplicationsPageTemplate } from '../layout/page_template';

import { SearchPlaygroundPageTemplate } from './page_template';

export const Playground: React.FC = () => {
const { searchPlayground } = useValues(KibanaLogic);
Expand All @@ -22,7 +23,7 @@ export const Playground: React.FC = () => {
}
return (
<searchPlayground.PlaygroundProvider>
<EnterpriseSearchApplicationsPageTemplate
<SearchPlaygroundPageTemplate
pageChrome={[
i18n.translate('xpack.enterpriseSearch.content.playground.breadcrumb', {
defaultMessage: 'Playground',
Expand All @@ -33,10 +34,9 @@ export const Playground: React.FC = () => {
panelled={false}
customPageSections
bottomBorder="extended"
docLink="playground"
>
<searchPlayground.Playground />
</EnterpriseSearchApplicationsPageTemplate>
</SearchPlaygroundPageTemplate>
</searchPlayground.PlaygroundProvider>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export const ElasticsearchGuide = () => {
}, []);

return (
<EnterpriseSearchElasticsearchPageTemplate>
<EnterpriseSearchElasticsearchPageTemplate pageChrome={[]}>
{isFlyoutOpen && <CreateApiKeyFlyout onClose={() => setIsFlyoutOpen(false)} />}
<EuiTitle size="l" data-test-subj="elasticsearchGuide">
<h1>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ export const EnterpriseSearchElasticsearchPageTemplate: React.FC<PageTemplatePro
pageViewTelemetry,
...pageTemplateProps
}) => {
const navItems = useEnterpriseSearchNav();
return (
<EnterpriseSearchPageTemplateWrapper
{...pageTemplateProps}
restrictWidth
solutionNav={{
name: SEARCH_PRODUCT_NAME,
items: useEnterpriseSearchNav(),
items: navItems,
}}
setPageChrome={pageChrome && <SetElasticsearchChrome trail={pageChrome} />}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ export const renderApp = (
data: plugins.data,
esConfig,
getChromeStyle$: chrome.getChromeStyle$,
getNavLinks: chrome.navLinks.getAll,
guidedOnboarding,
history,
indexMappingComponent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export interface KibanaLogicProps {
data?: DataPublicPluginStart;
esConfig: ESConfig;
getChromeStyle$: ChromeStart['getChromeStyle$'];
getNavLinks: ChromeStart['navLinks']['getAll'];
guidedOnboarding?: GuidedOnboardingPluginStart;
history: ScopedHistory;
indexMappingComponent?: React.FC<IndexMappingProps>;
Expand Down Expand Up @@ -87,6 +88,7 @@ export interface KibanaValues {
data: DataPublicPluginStart | null;
esConfig: ESConfig;
getChromeStyle$: ChromeStart['getChromeStyle$'];
getNavLinks: ChromeStart['navLinks']['getAll'];
guidedOnboarding: GuidedOnboardingPluginStart | null;
history: ScopedHistory;
indexMappingComponent: React.FC<IndexMappingProps> | null;
Expand Down Expand Up @@ -126,6 +128,7 @@ export const KibanaLogic = kea<MakeLogicType<KibanaValues>>({
data: [props.data || null, {}],
esConfig: [props.esConfig || { elasticsearch_host: ELASTICSEARCH_URL_PLACEHOLDER }, {}],
getChromeStyle$: [props.getChromeStyle$, {}],
getNavLinks: [props.getNavLinks, {}],
guidedOnboarding: [props.guidedOnboarding || null, {}],
history: [props.history, {}],
indexMappingComponent: [props.indexMappingComponent || null, {}],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import {
VECTOR_SEARCH_PLUGIN,
WORKPLACE_SEARCH_PLUGIN,
SEMANTIC_SEARCH_PLUGIN,
APPLICATIONS_PLUGIN,
GETTING_STARTED_TITLE,
} from '../../../../common/constants';

import { stripLeadingSlash } from '../../../../common/strip_slashes';
Expand Down Expand Up @@ -126,7 +128,11 @@ export const useEnterpriseSearchBreadcrumbs = (breadcrumbs: Breadcrumbs = []) =>
]);

export const useAnalyticsBreadcrumbs = (breadcrumbs: Breadcrumbs = []) =>
useSearchBreadcrumbs([{ text: ANALYTICS_PLUGIN.NAME, path: '/' }, ...breadcrumbs]);
useSearchBreadcrumbs([
{ text: APPLICATIONS_PLUGIN.NAV_TITLE },
{ text: ANALYTICS_PLUGIN.NAME, path: '/' },
...breadcrumbs,
]);

export const useElasticsearchBreadcrumbs = (breadcrumbs: Breadcrumbs = []) =>
useSearchBreadcrumbs([
Expand Down Expand Up @@ -161,13 +167,25 @@ export const useSearchExperiencesBreadcrumbs = (breadcrumbs: Breadcrumbs = []) =
useSearchBreadcrumbs([{ text: SEARCH_EXPERIENCES_PLUGIN.NAV_TITLE, path: '/' }, ...breadcrumbs]);

export const useEnterpriseSearchApplicationsBreadcrumbs = (breadcrumbs: Breadcrumbs = []) =>
useSearchBreadcrumbs(breadcrumbs);
useSearchBreadcrumbs([{ text: APPLICATIONS_PLUGIN.NAV_TITLE }, ...breadcrumbs]);

export const useAiSearchBreadcrumbs = (breadcrumbs: Breadcrumbs = []) =>
useSearchBreadcrumbs([{ text: AI_SEARCH_PLUGIN.NAME, path: '/' }, ...breadcrumbs]);
useSearchBreadcrumbs([
{ text: GETTING_STARTED_TITLE },
{ text: AI_SEARCH_PLUGIN.NAME, path: '/' },
...breadcrumbs,
]);

export const useVectorSearchBreadcrumbs = (breadcrumbs: Breadcrumbs = []) =>
useSearchBreadcrumbs([{ text: VECTOR_SEARCH_PLUGIN.NAV_TITLE, path: '/' }, ...breadcrumbs]);
useSearchBreadcrumbs([
{ text: GETTING_STARTED_TITLE },
{ text: VECTOR_SEARCH_PLUGIN.NAV_TITLE, path: '/' },
...breadcrumbs,
]);

export const useSemanticSearchBreadcrumbs = (breadcrumbs: Breadcrumbs = []) =>
useSearchBreadcrumbs([{ text: SEMANTIC_SEARCH_PLUGIN.NAME, path: '/' }, ...breadcrumbs]);
useSearchBreadcrumbs([
{ text: GETTING_STARTED_TITLE },
{ text: SEMANTIC_SEARCH_PLUGIN.NAME, path: '/' },
...breadcrumbs,
]);
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* 2.0.
*/

import { i18n } from '@kbn/i18n';

import {
AI_SEARCH_PLUGIN,
ANALYTICS_PLUGIN,
Expand Down Expand Up @@ -40,7 +42,12 @@ export const searchTitle = (page: Title = []) => generateTitle([...page, SEARCH_
export const analyticsTitle = (page: Title = []) => generateTitle([...page, ANALYTICS_PLUGIN.NAME]);

export const elasticsearchTitle = (page: Title = []) =>
generateTitle([...page, 'Getting started with Elasticsearch']);
generateTitle([
...page,
i18n.translate('xpack.enterpriseSearch.titles.elasticsearch', {
defaultMessage: 'Getting started with Elasticsearch',
}),
]);

export const appSearchTitle = (page: Title = []) =>
generateTitle([...page, APP_SEARCH_PLUGIN.NAME]);
Expand All @@ -61,3 +68,11 @@ export const semanticSearchTitle = (page: Title = []) =>

export const enterpriseSearchContentTitle = (page: Title = []) =>
generateTitle([...page, ENTERPRISE_SEARCH_CONTENT_PLUGIN.NAME]);

export const searchApplicationsTitle = (page: Title = []) =>
generateTitle([
...page,
i18n.translate('xpack.enterpriseSearch.titles.searchApplications', {
defaultMessage: 'Search Applications',
}),
]);
Loading