diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/layout/kibana_header_actions.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/layout/kibana_header_actions.test.tsx
new file mode 100644
index 000000000000..21fc2b235d83
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/layout/kibana_header_actions.test.tsx
@@ -0,0 +1,40 @@
+/*
+ * 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 { setMockValues } from '../../../__mocks__';
+
+import React from 'react';
+
+import { shallow } from 'enzyme';
+
+import { EuiButtonEmpty } from '@elastic/eui';
+
+import { KibanaHeaderActions } from './kibana_header_actions';
+
+describe('KibanaHeaderActions', () => {
+ const values = {
+ engineName: 'foo',
+ };
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ setMockValues(values);
+ });
+
+ it('renders', () => {
+ const wrapper = shallow();
+ expect(wrapper.find(EuiButtonEmpty).exists()).toBe(true);
+ });
+
+ it('does not render a "Query Tester" button if there is no engine available', () => {
+ setMockValues({
+ engineName: '',
+ });
+ const wrapper = shallow();
+ expect(wrapper.find(EuiButtonEmpty).exists()).toBe(false);
+ });
+});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/layout/kibana_header_actions.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/layout/kibana_header_actions.tsx
new file mode 100644
index 000000000000..b2e810962df0
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/layout/kibana_header_actions.tsx
@@ -0,0 +1,33 @@
+/*
+ * 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 { useValues } from 'kea';
+
+import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+
+import { EngineLogic } from '../engine';
+
+export const KibanaHeaderActions: React.FC = () => {
+ const { engineName } = useValues(EngineLogic);
+
+ return (
+
+ {engineName && (
+
+
+ {i18n.translate('xpack.enterpriseSearch.appSearch.engine.queryTesterButtonLabel', {
+ defaultMessage: 'Query tester',
+ })}
+
+
+ )}
+
+ );
+};
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx
index 2a7f25639838..287d46c2dec7 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx
@@ -7,6 +7,7 @@
import { DEFAULT_INITIAL_APP_DATA } from '../../../common/__mocks__';
import { setMockValues, rerender } from '../__mocks__';
+import '../__mocks__/shallow_useeffect.mock';
import '../__mocks__/enterprise_search_url.mock';
import '../__mocks__/react_router_history.mock';
@@ -70,9 +71,10 @@ describe('AppSearchUnconfigured', () => {
describe('AppSearchConfigured', () => {
let wrapper: ShallowWrapper;
+ const renderHeaderActions = jest.fn();
beforeAll(() => {
- setMockValues({ myRole: {} });
+ setMockValues({ myRole: {}, renderHeaderActions });
wrapper = shallow();
});
@@ -83,6 +85,10 @@ describe('AppSearchConfigured', () => {
expect(wrapper.find(EngineRouter)).toHaveLength(1);
});
+ it('renders header actions', () => {
+ expect(renderHeaderActions).toHaveBeenCalled();
+ });
+
it('mounts AppLogic with passed initial data props', () => {
expect(AppLogic).toHaveBeenCalledWith(DEFAULT_INITIAL_APP_DATA);
});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx
index 0b87321d8753..9b59e0e19a5d 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx
@@ -5,7 +5,7 @@
* 2.0.
*/
-import React from 'react';
+import React, { useEffect } from 'react';
import { Route, Redirect, Switch, useRouteMatch } from 'react-router-dom';
import { useValues } from 'kea';
@@ -25,6 +25,7 @@ import { EngineNav, EngineRouter } from './components/engine';
import { EngineCreation } from './components/engine_creation';
import { EnginesOverview, ENGINES_TITLE } from './components/engines';
import { ErrorConnecting } from './components/error_connecting';
+import { KibanaHeaderActions } from './components/layout/kibana_header_actions';
import { Library } from './components/library';
import { MetaEngineCreation } from './components/meta_engine_creation';
import { RoleMappingsRouter } from './components/role_mappings';
@@ -77,8 +78,13 @@ export const AppSearchConfigured: React.FC> = (props) =
const {
myRole: { canManageEngines, canManageMetaEngines, canViewRoleMappings },
} = useValues(AppLogic(props));
+ const { renderHeaderActions } = useValues(KibanaLogic);
const { readOnlyMode } = useValues(HttpLogic);
+ useEffect(() => {
+ renderHeaderActions(KibanaHeaderActions);
+ }, []);
+
return (
{process.env.NODE_ENV === 'development' && (
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/kibana_header_actions.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/kibana_header_actions.tsx
index 0875e8cf0ec0..1dddf54faa7a 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/kibana_header_actions.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/kibana_header_actions.tsx
@@ -7,7 +7,7 @@
import React from 'react';
-import { EuiButtonEmpty, EuiText, EuiFlexGroup, EuiFlexItem, EuiHeaderLinks } from '@elastic/eui';
+import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiHeaderLinks } from '@elastic/eui';
import { externalUrl, getWorkplaceSearchUrl } from '../../../shared/enterprise_search_url';
import { EuiButtonEmptyTo } from '../../../shared/react_router_helpers';
@@ -25,8 +25,9 @@ export const WorkplaceSearchHeaderActions: React.FC = () => {
data-test-subj="PersonalDashboardButton"
iconType="user"
to={PERSONAL_SOURCES_PATH}
+ size="s"
>
- {NAV.PERSONAL_DASHBOARD}
+ {NAV.PERSONAL_DASHBOARD}
@@ -35,8 +36,9 @@ export const WorkplaceSearchHeaderActions: React.FC = () => {
href={getWorkplaceSearchUrl('/search')}
target="_blank"
iconType="search"
+ size="s"
>
- {NAV.SEARCH}
+ {NAV.SEARCH}