mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[Enterprise Search] [Behavioral analytics] Update collection navigation (#154091)
- ✅ Implement Breadcrumb on the top of the page that is represented as Enterprise Search -> Behavioral Analytics -> %collection_name% (if present) - ✅ Implement Navigation on the side menu <img width="1129" alt="image" src="https://user-images.githubusercontent.com/17390745/228927169-b692a4f8-95ca-4b1f-8c52-78f909cb51a1.png">
This commit is contained in:
parent
0ea5cdc52b
commit
1f2f3a801f
10 changed files with 287 additions and 28 deletions
|
@ -24,12 +24,6 @@ import { AnalyticsCollectionToolbarLogic } from './analytics_collection_toolbar/
|
|||
|
||||
import { FetchAnalyticsCollectionLogic } from './fetch_analytics_collection_logic';
|
||||
|
||||
export const collectionViewBreadcrumbs = [
|
||||
i18n.translate('xpack.enterpriseSearch.analytics.collectionsView.breadcrumb', {
|
||||
defaultMessage: 'View collection',
|
||||
}),
|
||||
];
|
||||
|
||||
export const AnalyticsCollectionView: React.FC = () => {
|
||||
const { fetchAnalyticsCollection } = useActions(FetchAnalyticsCollectionLogic);
|
||||
const { setTimeRange } = useActions(AnalyticsCollectionToolbarLogic);
|
||||
|
@ -45,7 +39,8 @@ export const AnalyticsCollectionView: React.FC = () => {
|
|||
<EnterpriseSearchAnalyticsPageTemplate
|
||||
restrictWidth
|
||||
isLoading={isLoading}
|
||||
pageChrome={[...collectionViewBreadcrumbs]}
|
||||
pageChrome={[analyticsCollection?.name]}
|
||||
analyticsName={analyticsCollection?.name}
|
||||
pageViewTelemetry={`View Analytics Collection - ${section}`}
|
||||
pageHeader={{
|
||||
bottomBorder: false,
|
||||
|
|
|
@ -8,13 +8,14 @@
|
|||
import React from 'react';
|
||||
|
||||
jest.mock('../../../shared/layout/nav', () => ({
|
||||
useEnterpriseSearchNav: () => [],
|
||||
useEnterpriseSearchAnalyticsNav: jest.fn().mockReturnValue([]),
|
||||
}));
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import { SetAnalyticsChrome } from '../../../shared/kibana_chrome';
|
||||
import { EnterpriseSearchPageTemplateWrapper } from '../../../shared/layout';
|
||||
import { useEnterpriseSearchAnalyticsNav } from '../../../shared/layout/nav';
|
||||
import { SendEnterpriseSearchTelemetry } from '../../../shared/telemetry';
|
||||
|
||||
import { EnterpriseSearchAnalyticsPageTemplate } from './page_template';
|
||||
|
@ -71,5 +72,23 @@ describe('EnterpriseSearchAnalyticsPageTemplate', () => {
|
|||
expect(wrapper.find(EnterpriseSearchPageTemplateWrapper).prop('isLoading')).toEqual(false);
|
||||
expect(wrapper.find(EnterpriseSearchPageTemplateWrapper).prop('emptyState')).toEqual(<div />);
|
||||
});
|
||||
|
||||
it('passes down analytics name and paths to useEnterpriseSearchAnalyticsNav', () => {
|
||||
const mockAnalyticsName = 'some_analytics_name';
|
||||
shallow(
|
||||
<EnterpriseSearchAnalyticsPageTemplate
|
||||
analyticsName={mockAnalyticsName}
|
||||
pageHeader={{ pageTitle: 'hello world' }}
|
||||
isLoading={false}
|
||||
emptyState={<div />}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(useEnterpriseSearchAnalyticsNav).toHaveBeenCalledWith(mockAnalyticsName, {
|
||||
explorer: '/collections/some_analytics_name/explorer',
|
||||
integration: '/collections/some_analytics_name/integrate',
|
||||
overview: '/collections/some_analytics_name/overview',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,25 +8,45 @@
|
|||
import React from 'react';
|
||||
|
||||
import { ENTERPRISE_SEARCH_CONTENT_PLUGIN } from '../../../../../common/constants';
|
||||
import { SetAnalyticsChrome } from '../../../shared/kibana_chrome';
|
||||
import {
|
||||
EnterpriseSearchPageTemplateWrapper,
|
||||
PageTemplateProps,
|
||||
useEnterpriseSearchNav,
|
||||
} from '../../../shared/layout';
|
||||
import { SendEnterpriseSearchTelemetry } from '../../../shared/telemetry';
|
||||
import { generateEncodedPath } from '../../../shared/encode_path_params';
|
||||
|
||||
export const EnterpriseSearchAnalyticsPageTemplate: React.FC<PageTemplateProps> = ({
|
||||
children,
|
||||
pageChrome,
|
||||
pageViewTelemetry,
|
||||
...pageTemplateProps
|
||||
}) => {
|
||||
import { SetAnalyticsChrome } from '../../../shared/kibana_chrome';
|
||||
import { EnterpriseSearchPageTemplateWrapper, PageTemplateProps } from '../../../shared/layout';
|
||||
import { useEnterpriseSearchAnalyticsNav } from '../../../shared/layout/nav';
|
||||
import { SendEnterpriseSearchTelemetry } from '../../../shared/telemetry';
|
||||
import {
|
||||
COLLECTION_EXPLORER_PATH,
|
||||
COLLECTION_INTEGRATE_PATH,
|
||||
COLLECTION_VIEW_PATH,
|
||||
} from '../../routes';
|
||||
|
||||
interface EnterpriseSearchAnalyticsPageTemplateProps extends PageTemplateProps {
|
||||
analyticsName?: string;
|
||||
}
|
||||
|
||||
export const EnterpriseSearchAnalyticsPageTemplate: React.FC<
|
||||
EnterpriseSearchAnalyticsPageTemplateProps
|
||||
> = ({ children, analyticsName, pageChrome, pageViewTelemetry, ...pageTemplateProps }) => {
|
||||
return (
|
||||
<EnterpriseSearchPageTemplateWrapper
|
||||
{...pageTemplateProps}
|
||||
solutionNav={{
|
||||
items: useEnterpriseSearchNav(),
|
||||
items: useEnterpriseSearchAnalyticsNav(
|
||||
analyticsName,
|
||||
analyticsName
|
||||
? {
|
||||
explorer: generateEncodedPath(COLLECTION_EXPLORER_PATH, {
|
||||
name: analyticsName,
|
||||
}),
|
||||
integration: generateEncodedPath(COLLECTION_INTEGRATE_PATH, {
|
||||
name: analyticsName,
|
||||
}),
|
||||
overview: generateEncodedPath(COLLECTION_VIEW_PATH, {
|
||||
name: analyticsName,
|
||||
}),
|
||||
}
|
||||
: undefined
|
||||
),
|
||||
name: ENTERPRISE_SEARCH_CONTENT_PLUGIN.NAME,
|
||||
}}
|
||||
setPageChrome={pageChrome && <SetAnalyticsChrome trail={pageChrome} />}
|
||||
|
|
|
@ -17,7 +17,12 @@ import { VersionMismatchPage } from '../shared/version_mismatch';
|
|||
import { AnalyticsCollectionView } from './components/analytics_collection_view/analytics_collection_view';
|
||||
import { AnalyticsOverview } from './components/analytics_overview/analytics_overview';
|
||||
|
||||
import { ROOT_PATH, COLLECTION_VIEW_PATH, COLLECTION_INTEGRATE_PATH } from './routes';
|
||||
import {
|
||||
ROOT_PATH,
|
||||
COLLECTION_VIEW_PATH,
|
||||
COLLECTION_INTEGRATE_PATH,
|
||||
COLLECTION_EXPLORER_PATH,
|
||||
} from './routes';
|
||||
|
||||
export const Analytics: React.FC<InitialAppData> = (props) => {
|
||||
const { enterpriseSearchVersion, kibanaVersion } = props;
|
||||
|
@ -40,6 +45,8 @@ export const Analytics: React.FC<InitialAppData> = (props) => {
|
|||
</Route>
|
||||
|
||||
<Route exact path={COLLECTION_INTEGRATE_PATH} />
|
||||
|
||||
<Route exact path={COLLECTION_EXPLORER_PATH} />
|
||||
</Switch>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -9,3 +9,4 @@ export const ROOT_PATH = '/';
|
|||
export const COLLECTIONS_PATH = '/collections';
|
||||
export const COLLECTION_VIEW_PATH = `${COLLECTIONS_PATH}/:name/overview`;
|
||||
export const COLLECTION_INTEGRATE_PATH = `${COLLECTIONS_PATH}/:name/integrate`;
|
||||
export const COLLECTION_EXPLORER_PATH = `${COLLECTIONS_PATH}/:name/explorer`;
|
||||
|
|
|
@ -16,7 +16,11 @@ import { EuiSideNavItemType } from '@elastic/eui';
|
|||
import { DEFAULT_PRODUCT_FEATURES } from '../../../../common/constants';
|
||||
import { ProductAccess } from '../../../../common/types';
|
||||
|
||||
import { useEnterpriseSearchNav, useEnterpriseSearchEngineNav } from './nav';
|
||||
import {
|
||||
useEnterpriseSearchNav,
|
||||
useEnterpriseSearchEngineNav,
|
||||
useEnterpriseSearchAnalyticsNav,
|
||||
} from './nav';
|
||||
|
||||
const DEFAULT_PRODUCT_ACCESS: ProductAccess = {
|
||||
hasAppSearchAccess: true,
|
||||
|
@ -532,3 +536,162 @@ describe('useEnterpriseSearchEngineNav', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('useEnterpriseSearchAnalyticsNav', () => {
|
||||
const baseNavs = [
|
||||
{
|
||||
href: '/app/enterprise_search/overview',
|
||||
id: 'es_overview',
|
||||
name: 'Overview',
|
||||
},
|
||||
{
|
||||
id: 'content',
|
||||
items: [
|
||||
{
|
||||
href: '/app/enterprise_search/content/search_indices',
|
||||
id: 'search_indices',
|
||||
name: 'Indices',
|
||||
},
|
||||
],
|
||||
name: 'Content',
|
||||
},
|
||||
{
|
||||
id: 'enterpriseSearchAnalytics',
|
||||
items: [
|
||||
{
|
||||
href: '/app/enterprise_search/analytics',
|
||||
id: 'analytics_collections',
|
||||
name: 'Collections',
|
||||
},
|
||||
],
|
||||
name: 'Behavioral Analytics',
|
||||
},
|
||||
{
|
||||
id: 'search',
|
||||
items: [
|
||||
{
|
||||
href: '/app/enterprise_search/elasticsearch',
|
||||
id: 'elasticsearch',
|
||||
name: 'Elasticsearch',
|
||||
},
|
||||
{
|
||||
href: '/app/enterprise_search/search_experiences',
|
||||
id: 'searchExperiences',
|
||||
name: 'Search Experiences',
|
||||
},
|
||||
{
|
||||
href: '/app/enterprise_search/app_search',
|
||||
id: 'app_search',
|
||||
name: 'App Search',
|
||||
},
|
||||
{
|
||||
href: '/app/enterprise_search/workplace_search',
|
||||
id: 'workplace_search',
|
||||
name: 'Workplace Search',
|
||||
},
|
||||
],
|
||||
name: 'Search',
|
||||
},
|
||||
];
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
setMockValues({});
|
||||
});
|
||||
|
||||
it('returns basic nav all params are empty', () => {
|
||||
const navItems = useEnterpriseSearchAnalyticsNav();
|
||||
expect(navItems).toEqual(baseNavs);
|
||||
});
|
||||
|
||||
it('returns basic nav if only name provided', () => {
|
||||
const navItems = useEnterpriseSearchAnalyticsNav('my-test-collection');
|
||||
expect(navItems).toEqual(baseNavs);
|
||||
});
|
||||
|
||||
it('returns nav with sub items when name and paths provided', () => {
|
||||
const navItems = useEnterpriseSearchAnalyticsNav('my-test-collection', {
|
||||
explorer: '/explorer-path',
|
||||
integration: '/integration-path',
|
||||
overview: '/overview-path',
|
||||
});
|
||||
expect(navItems).toEqual([
|
||||
{
|
||||
href: '/app/enterprise_search/overview',
|
||||
id: 'es_overview',
|
||||
name: 'Overview',
|
||||
},
|
||||
{
|
||||
id: 'content',
|
||||
items: [
|
||||
{
|
||||
href: '/app/enterprise_search/content/search_indices',
|
||||
id: 'search_indices',
|
||||
name: 'Indices',
|
||||
},
|
||||
],
|
||||
name: 'Content',
|
||||
},
|
||||
{
|
||||
id: 'enterpriseSearchAnalytics',
|
||||
items: [
|
||||
{
|
||||
href: '/app/enterprise_search/analytics',
|
||||
id: 'analytics_collections',
|
||||
items: [
|
||||
{
|
||||
id: 'analytics_collections',
|
||||
items: [
|
||||
{
|
||||
href: '/app/enterprise_search/analytics/overview-path',
|
||||
id: 'enterpriseSearchEngineOverview',
|
||||
name: 'Overview',
|
||||
},
|
||||
{
|
||||
href: '/app/enterprise_search/analytics/explorer-path',
|
||||
id: 'enterpriseSearchEngineIndices',
|
||||
name: 'Explorer',
|
||||
},
|
||||
{
|
||||
href: '/app/enterprise_search/analytics/integration-path',
|
||||
id: 'enterpriseSearchEngineSchema',
|
||||
name: 'Integration',
|
||||
},
|
||||
],
|
||||
name: 'my-test-collection',
|
||||
},
|
||||
],
|
||||
name: 'Collections',
|
||||
},
|
||||
],
|
||||
name: 'Behavioral Analytics',
|
||||
},
|
||||
{
|
||||
id: 'search',
|
||||
items: [
|
||||
{
|
||||
href: '/app/enterprise_search/elasticsearch',
|
||||
id: 'elasticsearch',
|
||||
name: 'Elasticsearch',
|
||||
},
|
||||
{
|
||||
href: '/app/enterprise_search/search_experiences',
|
||||
id: 'searchExperiences',
|
||||
name: 'Search Experiences',
|
||||
},
|
||||
{
|
||||
href: '/app/enterprise_search/app_search',
|
||||
id: 'app_search',
|
||||
name: 'App Search',
|
||||
},
|
||||
{
|
||||
href: '/app/enterprise_search/workplace_search',
|
||||
id: 'workplace_search',
|
||||
name: 'Workplace Search',
|
||||
},
|
||||
],
|
||||
name: 'Search',
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -89,7 +89,6 @@ export const useEnterpriseSearchNav = () => {
|
|||
}),
|
||||
...generateNavLink({
|
||||
shouldNotCreateHref: true,
|
||||
shouldShowActiveForSubroutes: true,
|
||||
to: ANALYTICS_PLUGIN.URL,
|
||||
}),
|
||||
},
|
||||
|
@ -332,3 +331,61 @@ export const useEnterpriseSearchEngineNav = (engineName?: string, isEmptyState?:
|
|||
|
||||
return navItems;
|
||||
};
|
||||
|
||||
export const useEnterpriseSearchAnalyticsNav = (
|
||||
name?: string,
|
||||
paths?: {
|
||||
explorer: string;
|
||||
integration: string;
|
||||
overview: string;
|
||||
}
|
||||
) => {
|
||||
const navItems = useEnterpriseSearchNav();
|
||||
const collectionNav = navItems.find(
|
||||
(item) =>
|
||||
item.id === 'enterpriseSearchAnalytics' && item.items?.[0]?.id === 'analytics_collections'
|
||||
)?.items?.[0];
|
||||
|
||||
if (!name || !paths || !collectionNav) return navItems;
|
||||
|
||||
collectionNav.items = [
|
||||
{
|
||||
id: 'analytics_collections',
|
||||
items: [
|
||||
{
|
||||
id: 'enterpriseSearchEngineOverview',
|
||||
name: i18n.translate('xpack.enterpriseSearch.nav.analyticsCollections.overviewTitle', {
|
||||
defaultMessage: 'Overview',
|
||||
}),
|
||||
...generateNavLink({
|
||||
shouldNotCreateHref: true,
|
||||
to: ANALYTICS_PLUGIN.URL + paths.overview,
|
||||
}),
|
||||
},
|
||||
{
|
||||
id: 'enterpriseSearchEngineIndices',
|
||||
name: i18n.translate('xpack.enterpriseSearch.nav.analyticsCollections.explorerTitle', {
|
||||
defaultMessage: 'Explorer',
|
||||
}),
|
||||
...generateNavLink({
|
||||
shouldNotCreateHref: true,
|
||||
to: ANALYTICS_PLUGIN.URL + paths.explorer,
|
||||
}),
|
||||
},
|
||||
{
|
||||
id: 'enterpriseSearchEngineSchema',
|
||||
name: i18n.translate('xpack.enterpriseSearch.nav.analyticsCollections.integrationTitle', {
|
||||
defaultMessage: 'Integration',
|
||||
}),
|
||||
...generateNavLink({
|
||||
shouldNotCreateHref: true,
|
||||
to: ANALYTICS_PLUGIN.URL + paths.integration,
|
||||
}),
|
||||
},
|
||||
],
|
||||
name,
|
||||
},
|
||||
];
|
||||
|
||||
return navItems;
|
||||
};
|
||||
|
|
|
@ -11437,7 +11437,6 @@
|
|||
"xpack.enterpriseSearch.analytics.collectionsCreate.form.subtitle": "Une collection d'analyse permet de stocker les événements d'analyse pour toute application de recherche que vous créez. Affectez-lui un nom facile à retenir ci-dessous.",
|
||||
"xpack.enterpriseSearch.analytics.collectionsCreate.form.title": "Créer une collection d'analyses",
|
||||
"xpack.enterpriseSearch.analytics.collectionsDelete.action.successMessage": "La collection a été supprimée avec succès",
|
||||
"xpack.enterpriseSearch.analytics.collectionsView.breadcrumb": "Afficher la collection",
|
||||
"xpack.enterpriseSearch.analytics.productCardDescription": "Tableaux de bord et outils permettant de visualiser le comportement des utilisateurs finaux et de mesurer les performances de vos applications de recherche.",
|
||||
"xpack.enterpriseSearch.analytics.productDescription": "Tableaux de bord et outils permettant de visualiser le comportement des utilisateurs finaux et de mesurer les performances de vos applications de recherche.",
|
||||
"xpack.enterpriseSearch.analytics.productName": "Behavioral Analytics",
|
||||
|
|
|
@ -11436,7 +11436,6 @@
|
|||
"xpack.enterpriseSearch.analytics.collectionsCreate.form.subtitle": "分析コレクションには、構築している特定の検索アプリケーションの分析イベントを格納できます。以下で覚えやすい名前を指定してください。",
|
||||
"xpack.enterpriseSearch.analytics.collectionsCreate.form.title": "分析コレクションを作成",
|
||||
"xpack.enterpriseSearch.analytics.collectionsDelete.action.successMessage": "コレクションが正常に削除されました",
|
||||
"xpack.enterpriseSearch.analytics.collectionsView.breadcrumb": "コレクションを表示",
|
||||
"xpack.enterpriseSearch.analytics.productCardDescription": "エンドユーザーの行動を可視化し、検索アプリケーションのパフォーマンスを測定するためのダッシュボードとツール。",
|
||||
"xpack.enterpriseSearch.analytics.productDescription": "エンドユーザーの行動を可視化し、検索アプリケーションのパフォーマンスを測定するためのダッシュボードとツール。",
|
||||
"xpack.enterpriseSearch.analytics.productName": "Behavioral Analytics",
|
||||
|
|
|
@ -11437,7 +11437,6 @@
|
|||
"xpack.enterpriseSearch.analytics.collectionsCreate.form.subtitle": "分析集合为您正在构建的任何给定搜索应用程序提供了一个用于存储分析事件的位置。在下面为其提供好记的名称。",
|
||||
"xpack.enterpriseSearch.analytics.collectionsCreate.form.title": "创建分析集合",
|
||||
"xpack.enterpriseSearch.analytics.collectionsDelete.action.successMessage": "已成功删除此集合",
|
||||
"xpack.enterpriseSearch.analytics.collectionsView.breadcrumb": "查看集合",
|
||||
"xpack.enterpriseSearch.analytics.productCardDescription": "用于对最终用户行为进行可视化并评估搜索应用程序性能的仪表板和工具。",
|
||||
"xpack.enterpriseSearch.analytics.productDescription": "用于对最终用户行为进行可视化并评估搜索应用程序性能的仪表板和工具。",
|
||||
"xpack.enterpriseSearch.analytics.productName": "行为分析",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue