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

[Search] Refactor: abstracting classic nav items #196579

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
47a2808
test: search classic nav - basic
TattdCodeMonkey Oct 14, 2024
9c410a3
refactor: build base sidenav items with a function
TattdCodeMonkey Oct 16, 2024
7d37362
search nav: add support for deep links
TattdCodeMonkey Oct 16, 2024
305e4c4
search: define deeplinks for getting started
TattdCodeMonkey Oct 22, 2024
4055acf
search(nav): exclude empty parent nav items
TattdCodeMonkey Oct 23, 2024
8d6fa57
simplify class nav type
TattdCodeMonkey Oct 23, 2024
8f375a1
search: classic navigation ftr tests
TattdCodeMonkey Oct 23, 2024
cec7693
fix(search): include build in Behavioral Analytics breadcrumb trail
TattdCodeMonkey Oct 23, 2024
e269ff0
fix(search): build pages breadcrumbs & titles
TattdCodeMonkey Oct 23, 2024
3dc20ba
fix(search): add getting started breadcrumb
TattdCodeMonkey Oct 23, 2024
19c8e47
fix(search): add getting started elasticsearch breadcrumbs
TattdCodeMonkey Oct 23, 2024
e3b1f70
fix playground page template
TattdCodeMonkey Oct 23, 2024
e05d61a
fix nav item usage for elasticsearch guide
TattdCodeMonkey Oct 23, 2024
57f52bc
fix(search): ensure nav items dont retain deepLink property
TattdCodeMonkey Oct 23, 2024
2876683
test: expand classic navigation tests
TattdCodeMonkey Oct 23, 2024
e909efe
rely on navlink for license check
TattdCodeMonkey Oct 23, 2024
fc0a455
refactor: move breadcrumb constant to common file
TattdCodeMonkey Oct 23, 2024
aa5e396
refactor: move util functions to helpers file
TattdCodeMonkey Oct 24, 2024
e8d6344
test: update nav tests with nav link titles
TattdCodeMonkey Oct 24, 2024
17b3d9d
chore: fix linting issue with id location
TattdCodeMonkey Oct 24, 2024
da27ded
test: classic nav item generation
TattdCodeMonkey Oct 24, 2024
08634d2
fix: update translations
TattdCodeMonkey Oct 24, 2024
3b462d7
fix: type errors
TattdCodeMonkey Oct 24, 2024
f31ca7b
Merge branch 'main' into search/classic-navigation-deep-links
elasticmachine Oct 28, 2024
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 @@ -341,3 +345,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 @@
/*
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

adding this so that playground and search applications can have different breadcrumbs.

* 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={[]}>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this ensure the breadcrumbs and title component is rendered.

{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();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may not be strictly necessary but useEnterpriseSearchNav now includes a useMemo call so this is more idiomatic usage for a hook IMO

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]);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of the changes in this file are essentially bug fixes I found when writing FTRs for the classic nav.

Our breadcrumbs and page titles were not consistent at all.

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