diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/automated_curation.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/automated_curation.test.tsx
index 2cee5bbbec80b..944d8315452b0 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/automated_curation.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/automated_curation.test.tsx
@@ -8,6 +8,7 @@
import '../../../../__mocks__/shallow_useeffect.mock';
import { setMockActions, setMockValues } from '../../../../__mocks__/kea_logic';
import { mockUseParams } from '../../../../__mocks__/react_router';
+
import '../../../__mocks__/engine_logic.mock';
import React from 'react';
@@ -27,6 +28,7 @@ import { CurationLogic } from './curation_logic';
import { DeleteCurationButton } from './delete_curation_button';
import { PromotedDocuments, OrganicDocuments } from './documents';
+import { History } from './history';
describe('AutomatedCuration', () => {
const values = {
@@ -39,6 +41,7 @@ describe('AutomatedCuration', () => {
suggestion: {
status: 'applied',
},
+ queries: ['foo'],
},
activeQuery: 'query A',
isAutomated: true,
@@ -61,20 +64,46 @@ describe('AutomatedCuration', () => {
expect(wrapper.is(AppSearchPageTemplate));
expect(wrapper.find(PromotedDocuments)).toHaveLength(1);
expect(wrapper.find(OrganicDocuments)).toHaveLength(1);
+ expect(wrapper.find(History)).toHaveLength(0);
});
- it('includes a static tab group', () => {
+ it('includes tabs', () => {
const wrapper = shallow();
- const tabs = getPageHeaderTabs(wrapper).find(EuiTab);
+ let tabs = getPageHeaderTabs(wrapper).find(EuiTab);
- expect(tabs).toHaveLength(2);
+ expect(tabs).toHaveLength(3);
- expect(tabs.at(0).prop('onClick')).toBeUndefined();
expect(tabs.at(0).prop('isSelected')).toBe(true);
expect(tabs.at(1).prop('onClick')).toBeUndefined();
expect(tabs.at(1).prop('isSelected')).toBe(false);
expect(tabs.at(1).prop('disabled')).toBe(true);
+
+ expect(tabs.at(2).prop('isSelected')).toBe(false);
+
+ // Clicking on the History tab shows the history view
+ tabs.at(2).simulate('click');
+
+ tabs = getPageHeaderTabs(wrapper).find(EuiTab);
+
+ expect(tabs.at(0).prop('isSelected')).toBe(false);
+ expect(tabs.at(2).prop('isSelected')).toBe(true);
+
+ expect(wrapper.find(PromotedDocuments)).toHaveLength(0);
+ expect(wrapper.find(OrganicDocuments)).toHaveLength(0);
+ expect(wrapper.find(History)).toHaveLength(1);
+
+ // Clicking back to the Promoted tab shows promoted documents
+ tabs.at(0).simulate('click');
+
+ tabs = getPageHeaderTabs(wrapper).find(EuiTab);
+
+ expect(tabs.at(0).prop('isSelected')).toBe(true);
+ expect(tabs.at(2).prop('isSelected')).toBe(false);
+
+ expect(wrapper.find(PromotedDocuments)).toHaveLength(1);
+ expect(wrapper.find(OrganicDocuments)).toHaveLength(1);
+ expect(wrapper.find(History)).toHaveLength(0);
});
it('initializes CurationLogic with a curationId prop from URL param', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/automated_curation.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/automated_curation.tsx
index fa34fa071b855..276b40ba88677 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/automated_curation.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/automated_curation.tsx
@@ -5,15 +5,18 @@
* 2.0.
*/
-import React from 'react';
+import React, { useState } from 'react';
import { useParams } from 'react-router-dom';
import { useValues, useActions } from 'kea';
import { EuiButton, EuiBadge, EuiLoadingSpinner, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+import { EngineLogic } from '../../engine';
import { AppSearchPageTemplate } from '../../layout';
import { AutomatedIcon } from '../components/automated_icon';
+
import {
AUTOMATED_LABEL,
COVERT_TO_MANUAL_BUTTON_LABEL,
@@ -26,19 +29,25 @@ import { HIDDEN_DOCUMENTS_TITLE, PROMOTED_DOCUMENTS_TITLE } from './constants';
import { CurationLogic } from './curation_logic';
import { DeleteCurationButton } from './delete_curation_button';
import { PromotedDocuments, OrganicDocuments } from './documents';
+import { History } from './history';
+
+const PROMOTED = 'promoted';
+const HISTORY = 'history';
export const AutomatedCuration: React.FC = () => {
const { curationId } = useParams<{ curationId: string }>();
const logic = CurationLogic({ curationId });
const { convertToManual } = useActions(logic);
const { activeQuery, dataLoading, queries, curation } = useValues(logic);
+ const { engineName } = useValues(EngineLogic);
+ const [selectedPageTab, setSelectedPageTab] = useState(PROMOTED);
- // This tab group is meant to visually mirror the dynamic group of tags in the ManualCuration component
const pageTabs = [
{
label: PROMOTED_DOCUMENTS_TITLE,
append: {curation.promoted.length},
- isSelected: true,
+ isSelected: selectedPageTab === PROMOTED,
+ onClick: () => setSelectedPageTab(PROMOTED),
},
{
label: HIDDEN_DOCUMENTS_TITLE,
@@ -46,6 +55,16 @@ export const AutomatedCuration: React.FC = () => {
isSelected: false,
disabled: true,
},
+ {
+ label: i18n.translate(
+ 'xpack.enterpriseSearch.appSearch.engine.curation.detail.historyButtonLabel',
+ {
+ defaultMessage: 'History',
+ }
+ ),
+ isSelected: selectedPageTab === HISTORY,
+ onClick: () => setSelectedPageTab(HISTORY),
+ },
];
return (
@@ -83,8 +102,11 @@ export const AutomatedCuration: React.FC = () => {
}}
isLoading={dataLoading}
>
-
-
+ {selectedPageTab === PROMOTED && }
+ {selectedPageTab === PROMOTED && }
+ {selectedPageTab === HISTORY && (
+
+ )}
);
};
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/history.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/history.test.tsx
new file mode 100644
index 0000000000000..a7f83fb0c61d9
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/history.test.tsx
@@ -0,0 +1,23 @@
+/*
+ * 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 from 'react';
+
+import { shallow } from 'enzyme';
+
+import { EntSearchLogStream } from '../../../../shared/log_stream';
+
+import { History } from './history';
+
+describe('History', () => {
+ it('renders', () => {
+ const wrapper = shallow();
+ expect(wrapper.find(EntSearchLogStream).prop('query')).toEqual(
+ 'appsearch.search_relevance_suggestions.query: some text and event.kind: event and event.dataset: search-relevance-suggestions and appsearch.search_relevance_suggestions.engine: foo and event.action: curation_suggestion'
+ );
+ });
+});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/history.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/history.tsx
new file mode 100644
index 0000000000000..744141372469c
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/history.tsx
@@ -0,0 +1,57 @@
+/*
+ * 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 from 'react';
+
+import { i18n } from '@kbn/i18n';
+
+import { EntSearchLogStream } from '../../../../shared/log_stream';
+import { DataPanel } from '../../data_panel';
+
+interface Props {
+ query: string;
+ engineName: string;
+}
+
+export const History: React.FC = ({ query, engineName }) => {
+ const filters = [
+ `appsearch.search_relevance_suggestions.query: ${query}`,
+ 'event.kind: event',
+ 'event.dataset: search-relevance-suggestions',
+ `appsearch.search_relevance_suggestions.engine: ${engineName}`,
+ 'event.action: curation_suggestion',
+ ];
+
+ return (
+
+ {i18n.translate(
+ 'xpack.enterpriseSearch.appSearch.engine.curation.detail.historyTableTitle',
+ {
+ defaultMessage: 'Automated curation changes',
+ }
+ )}
+
+ }
+ subtitle={i18n.translate(
+ 'xpack.enterpriseSearch.appSearch.engine.curation.detail.historyTableDescription',
+ {
+ defaultMessage: 'A detailed log of recent changes to your automated curation.',
+ }
+ )}
+ hasBorder
+ >
+
+
+ );
+};