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}