diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_router.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_router.test.tsx
new file mode 100644
index 000000000000..6b04a668b148
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_router.test.tsx
@@ -0,0 +1,21 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import { shallow } from 'enzyme';
+import { Route, Switch } from 'react-router-dom';
+
+import { AnalyticsRouter } from './';
+
+describe('AnalyticsRouter', () => {
+ // Detailed route testing is better done via E2E tests
+ it('renders', () => {
+ const wrapper = shallow();
+
+ expect(wrapper.find(Switch)).toHaveLength(1);
+ expect(wrapper.find(Route)).toHaveLength(8);
+ });
+});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_router.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_router.tsx
new file mode 100644
index 000000000000..117d14f7ca83
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_router.tsx
@@ -0,0 +1,72 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import { Route, Switch } from 'react-router-dom';
+
+import { APP_SEARCH_PLUGIN } from '../../../../../common/constants';
+import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
+import { NotFound } from '../../../shared/not_found';
+import {
+ ENGINE_PATH,
+ ENGINE_ANALYTICS_PATH,
+ ENGINE_ANALYTICS_TOP_QUERIES_PATH,
+ ENGINE_ANALYTICS_TOP_QUERIES_NO_RESULTS_PATH,
+ ENGINE_ANALYTICS_TOP_QUERIES_NO_CLICKS_PATH,
+ ENGINE_ANALYTICS_TOP_QUERIES_WITH_CLICKS_PATH,
+ ENGINE_ANALYTICS_RECENT_QUERIES_PATH,
+ ENGINE_ANALYTICS_QUERY_DETAIL_PATH,
+} from '../../routes';
+import {
+ ANALYTICS_TITLE,
+ TOP_QUERIES,
+ TOP_QUERIES_NO_RESULTS,
+ TOP_QUERIES_NO_CLICKS,
+ TOP_QUERIES_WITH_CLICKS,
+ RECENT_QUERIES,
+} from './constants';
+
+interface Props {
+ engineBreadcrumb: string[];
+}
+export const AnalyticsRouter: React.FC = ({ engineBreadcrumb }) => {
+ const ANALYTICS_BREADCRUMB = [...engineBreadcrumb, ANALYTICS_TITLE];
+
+ return (
+
+
+
+ TODO: Analytics overview
+
+
+
+ TODO: Top queries
+
+
+
+ TODO: Top queries with no results
+
+
+
+ TODO: Top queries with no clicks
+
+
+
+ TODO: Top queries with clicks
+
+
+
+ TODO: Recent queries
+
+
+ TODO: Query detail page
+
+
+
+
+
+ );
+};
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/constants.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/constants.ts
index 9985753d0970..c1087bf4cb2f 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/constants.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/constants.ts
@@ -11,26 +11,46 @@ export const ANALYTICS_TITLE = i18n.translate(
{ defaultMessage: 'Analytics' }
);
+// Total card titles
export const TOTAL_DOCUMENTS = i18n.translate(
'xpack.enterpriseSearch.appSearch.engine.analytics.totalDocuments',
{ defaultMessage: 'Total documents' }
);
-
export const TOTAL_API_OPERATIONS = i18n.translate(
'xpack.enterpriseSearch.appSearch.engine.analytics.totalApiOperations',
{ defaultMessage: 'Total API operations' }
);
-
export const TOTAL_QUERIES = i18n.translate(
'xpack.enterpriseSearch.appSearch.engine.analytics.totalQueries',
{ defaultMessage: 'Total queries' }
);
-
export const TOTAL_CLICKS = i18n.translate(
'xpack.enterpriseSearch.appSearch.engine.analytics.totalClicks',
{ defaultMessage: 'Total clicks' }
);
+// Queries sub-pages
+export const TOP_QUERIES = i18n.translate(
+ 'xpack.enterpriseSearch.appSearch.engine.analytics.topQueriesTitle',
+ { defaultMessage: 'Top queries' }
+);
+export const TOP_QUERIES_NO_RESULTS = i18n.translate(
+ 'xpack.enterpriseSearch.appSearch.engine.analytics.topQueriesNoResultsTitle',
+ { defaultMessage: 'Top queries with no results' }
+);
+export const TOP_QUERIES_NO_CLICKS = i18n.translate(
+ 'xpack.enterpriseSearch.appSearch.engine.analytics.topQueriesNoClicksTitle',
+ { defaultMessage: 'Top queries with no clicks' }
+);
+export const TOP_QUERIES_WITH_CLICKS = i18n.translate(
+ 'xpack.enterpriseSearch.appSearch.engine.analytics.topQueriesWithClicksTitle',
+ { defaultMessage: 'Top queries with clicks' }
+);
+export const RECENT_QUERIES = i18n.translate(
+ 'xpack.enterpriseSearch.appSearch.engine.analytics.recentQueriesTitle',
+ { defaultMessage: 'Recent queries' }
+);
+
// Moment date format conversions
export const SERVER_DATE_FORMAT = 'YYYY-MM-DD';
export const TOOLTIP_DATE_FORMAT = 'MMMM D, YYYY';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/index.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/index.ts
index 3b201b38703d..0ab5ab80e835 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/index.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/index.ts
@@ -5,5 +5,6 @@
*/
export { ANALYTICS_TITLE } from './constants';
+export { AnalyticsRouter } from './analytics_router';
export { AnalyticsChart } from './components';
export { convertToChartData } from './utils';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_nav.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_nav.tsx
index 418ab33457d0..40ae2cef0acb 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_nav.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_nav.tsx
@@ -103,7 +103,11 @@ export const EngineNav: React.FC = () => {
{OVERVIEW_TITLE}
{canViewEngineAnalytics && (
-
+
{ANALYTICS_TITLE}
)}
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.test.tsx
index cbaa347d6573..26c7b3f677fc 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.test.tsx
@@ -19,6 +19,7 @@ import { setQueuedErrorMessage } from '../../../shared/flash_messages';
import { Loading } from '../../../shared/loading';
import { EngineOverview } from '../engine_overview';
+import { AnalyticsRouter } from '../analytics';
import { EngineRouter } from './';
@@ -93,6 +94,6 @@ describe('EngineRouter', () => {
setMockValues({ ...values, myRole: { canViewEngineAnalytics: true } });
const wrapper = shallow();
- expect(wrapper.find('[data-test-subj="AnalyticsTODO"]')).toHaveLength(1);
+ expect(wrapper.find(AnalyticsRouter)).toHaveLength(1);
});
});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.tsx
index 1d2f3f640f34..47fe302ac701 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.tsx
@@ -33,13 +33,13 @@ import {
} from '../../routes';
import { ENGINES_TITLE } from '../engines';
import { OVERVIEW_TITLE } from '../engine_overview';
-import { ANALYTICS_TITLE } from '../analytics';
import { Loading } from '../../../shared/loading';
import { EngineOverview } from '../engine_overview';
+import { AnalyticsRouter } from '../analytics';
+import { DocumentDetail, Documents } from '../documents';
import { EngineLogic } from './';
-import { DocumentDetail, Documents } from '../documents';
export const EngineRouter: React.FC = () => {
const {
@@ -87,8 +87,7 @@ export const EngineRouter: React.FC = () => {
{canViewEngineAnalytics && (
-
- Just testing right now
+
)}
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/routes.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/routes.ts
index ca2ce177617b..e8c6948438fe 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/routes.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/routes.ts
@@ -25,7 +25,12 @@ export const SAMPLE_ENGINE_PATH = '/engines/national-parks-demo';
export const getEngineRoute = (engineName: string) => generatePath(ENGINE_PATH, { engineName });
export const ENGINE_ANALYTICS_PATH = '/analytics';
-// TODO: Analytics sub-pages
+export const ENGINE_ANALYTICS_TOP_QUERIES_PATH = `${ENGINE_ANALYTICS_PATH}/top_queries`;
+export const ENGINE_ANALYTICS_TOP_QUERIES_NO_CLICKS_PATH = `${ENGINE_ANALYTICS_PATH}/top_queries_no_clicks`;
+export const ENGINE_ANALYTICS_TOP_QUERIES_NO_RESULTS_PATH = `${ENGINE_ANALYTICS_PATH}/top_queries_no_results`;
+export const ENGINE_ANALYTICS_TOP_QUERIES_WITH_CLICKS_PATH = `${ENGINE_ANALYTICS_PATH}/top_queries_with_clicks`;
+export const ENGINE_ANALYTICS_RECENT_QUERIES_PATH = `${ENGINE_ANALYTICS_PATH}/recent_queries`;
+export const ENGINE_ANALYTICS_QUERY_DETAIL_PATH = `${ENGINE_ANALYTICS_PATH}/query_detail/:query`;
export const ENGINE_DOCUMENTS_PATH = '/documents';
export const ENGINE_DOCUMENT_DETAIL_PATH = `${ENGINE_DOCUMENTS_PATH}/:documentId`;
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/not_found/not_found.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/not_found/not_found.test.tsx
index 62c0af31cffd..083173c8e7a4 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/not_found/not_found.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/not_found/not_found.test.tsx
@@ -13,6 +13,7 @@ import { shallow } from 'enzyme';
import { EuiButton as EuiButtonExternal, EuiEmptyPrompt } from '@elastic/eui';
import { APP_SEARCH_PLUGIN, WORKPLACE_SEARCH_PLUGIN } from '../../../../common/constants';
+import { SetAppSearchChrome } from '../kibana_chrome';
import { AppSearchLogo } from './assets/app_search_logo';
import { WorkplaceSearchLogo } from './assets/workplace_search_logo';
@@ -51,6 +52,14 @@ describe('NotFound', () => {
expect(prompt.find(EuiButtonExternal).prop('href')).toEqual('https://support.elastic.co');
});
+ it('passes down optional custom breadcrumbs', () => {
+ const wrapper = shallow(
+
+ );
+
+ expect(wrapper.find(SetAppSearchChrome).prop('trail')).toEqual(['Hello', 'World']);
+ });
+
it('does not render anything without a valid product', () => {
const wrapper = shallow();
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/not_found/not_found.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/not_found/not_found.tsx
index d0140b873022..5c76b5dae1e4 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/not_found/not_found.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/not_found/not_found.tsx
@@ -23,6 +23,7 @@ import {
} from '../../../../common/constants';
import { EuiButtonTo } from '../react_router_helpers';
+import { BreadcrumbTrail } from '../kibana_chrome/generate_breadcrumbs';
import { SetAppSearchChrome, SetWorkplaceSearchChrome } from '../kibana_chrome';
import { SendAppSearchTelemetry, SendWorkplaceSearchTelemetry } from '../telemetry';
import { LicensingLogic } from '../licensing';
@@ -37,9 +38,11 @@ interface NotFoundProps {
ID: string;
SUPPORT_URL: string;
};
+ // Optional breadcrumbs
+ breadcrumbs?: BreadcrumbTrail;
}
-export const NotFound: React.FC = ({ product = {} }) => {
+export const NotFound: React.FC = ({ product = {}, breadcrumbs }) => {
const { hasGoldLicense } = useValues(LicensingLogic);
const supportUrl = hasGoldLicense ? LICENSED_SUPPORT_URL : product.SUPPORT_URL;
@@ -64,7 +67,7 @@ export const NotFound: React.FC = ({ product = {} }) => {
return (
<>
-
+