[App Search] Convert Result Settings & Relevance Tuning pages to new page template (#102845)
* Convert Result Settings page to new page template + remove wrapper around empty state (auto handled by new page template) + update tests w/ new test helpers * Convert Relevance Tuning page to new page template - Remove old relevance_tuning_layout (which handled breadcrumbs, page header, flash messages, and callouts) in favor of simply using the new templtate + callouts (yay DRYing) - Remove panel wrapper around empty state (handled by new page template) * Update router * [Polish] Spacing & icon polish from Davey see https://github.com/elastic/kibana/pull/101958/files
This commit is contained in:
parent
b161bf03be
commit
e580d5a1e2
11 changed files with 226 additions and 350 deletions
|
@ -114,6 +114,16 @@ export const EngineRouter: React.FC = () => {
|
|||
<SchemaRouter />
|
||||
</Route>
|
||||
)}
|
||||
{canManageEngineRelevanceTuning && (
|
||||
<Route path={ENGINE_RELEVANCE_TUNING_PATH}>
|
||||
<RelevanceTuning />
|
||||
</Route>
|
||||
)}
|
||||
{canManageEngineResultSettings && (
|
||||
<Route path={ENGINE_RESULT_SETTINGS_PATH}>
|
||||
<ResultSettings />
|
||||
</Route>
|
||||
)}
|
||||
{canManageEngineSearchUi && (
|
||||
<Route path={ENGINE_SEARCH_UI_PATH}>
|
||||
<SearchUI />
|
||||
|
@ -131,21 +141,11 @@ export const EngineRouter: React.FC = () => {
|
|||
<CurationsRouter />
|
||||
</Route>
|
||||
)}
|
||||
{canManageEngineRelevanceTuning && (
|
||||
<Route path={ENGINE_RELEVANCE_TUNING_PATH}>
|
||||
<RelevanceTuning />
|
||||
</Route>
|
||||
)}
|
||||
{canManageEngineSynonyms && (
|
||||
<Route path={ENGINE_SYNONYMS_PATH}>
|
||||
<Synonyms />
|
||||
</Route>
|
||||
)}
|
||||
{canManageEngineResultSettings && (
|
||||
<Route path={ENGINE_RESULT_SETTINGS_PATH}>
|
||||
<ResultSettings />
|
||||
</Route>
|
||||
)}
|
||||
{canViewMetaEngineSourceEngines && (
|
||||
<Route path={META_ENGINE_SOURCE_ENGINES_PATH}>
|
||||
<SourceEngines />
|
||||
|
|
|
@ -7,42 +7,40 @@
|
|||
|
||||
import React from 'react';
|
||||
|
||||
import { EuiButton, EuiEmptyPrompt, EuiPanel } from '@elastic/eui';
|
||||
import { EuiButton, EuiEmptyPrompt } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { DOCS_PREFIX } from '../../../routes';
|
||||
|
||||
export const EmptyState: React.FC = () => (
|
||||
<EuiPanel color="subdued">
|
||||
<EuiEmptyPrompt
|
||||
iconType="wrench"
|
||||
title={
|
||||
<h2>
|
||||
{i18n.translate('xpack.enterpriseSearch.appSearch.engine.relevanceTuning.empty.title', {
|
||||
defaultMessage: 'Add documents to tune relevance',
|
||||
})}
|
||||
</h2>
|
||||
<EuiEmptyPrompt
|
||||
iconType="wrench"
|
||||
title={
|
||||
<h2>
|
||||
{i18n.translate('xpack.enterpriseSearch.appSearch.engine.relevanceTuning.empty.title', {
|
||||
defaultMessage: 'Add documents to tune relevance',
|
||||
})}
|
||||
</h2>
|
||||
}
|
||||
body={i18n.translate(
|
||||
'xpack.enterpriseSearch.appSearch.engine.relevanceTuning.empty.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'A schema will be automatically created for you after you index some documents.',
|
||||
}
|
||||
body={i18n.translate(
|
||||
'xpack.enterpriseSearch.appSearch.engine.relevanceTuning.empty.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'A schema will be automatically created for you after you index some documents.',
|
||||
}
|
||||
)}
|
||||
actions={
|
||||
<EuiButton
|
||||
size="s"
|
||||
target="_blank"
|
||||
iconType="popout"
|
||||
href={`${DOCS_PREFIX}/relevance-tuning-guide.html`}
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.appSearch.engine.relevanceTuning.empty.buttonLabel',
|
||||
{ defaultMessage: 'Read the relevance tuning guide' }
|
||||
)}
|
||||
</EuiButton>
|
||||
}
|
||||
/>
|
||||
</EuiPanel>
|
||||
)}
|
||||
actions={
|
||||
<EuiButton
|
||||
size="s"
|
||||
target="_blank"
|
||||
iconType="popout"
|
||||
href={`${DOCS_PREFIX}/relevance-tuning-guide.html`}
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.appSearch.engine.relevanceTuning.empty.buttonLabel',
|
||||
{ defaultMessage: 'Read the relevance tuning guide' }
|
||||
)}
|
||||
</EuiButton>
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -13,14 +13,14 @@ import React from 'react';
|
|||
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import { EuiEmptyPrompt } from '@elastic/eui';
|
||||
|
||||
import { Loading } from '../../../shared/loading';
|
||||
import { UnsavedChangesPrompt } from '../../../shared/unsaved_changes_prompt';
|
||||
import { getPageHeaderActions } from '../../../test_helpers';
|
||||
|
||||
import { EmptyState } from './components';
|
||||
import { RelevanceTuning } from './relevance_tuning';
|
||||
|
||||
import { RelevanceTuningCallouts } from './relevance_tuning_callouts';
|
||||
import { RelevanceTuningForm } from './relevance_tuning_form';
|
||||
import { RelevanceTuningPreview } from './relevance_tuning_preview';
|
||||
|
||||
describe('RelevanceTuning', () => {
|
||||
const values = {
|
||||
|
@ -50,9 +50,9 @@ describe('RelevanceTuning', () => {
|
|||
|
||||
it('renders', () => {
|
||||
const wrapper = subject();
|
||||
expect(wrapper.find(RelevanceTuningCallouts).exists()).toBe(true);
|
||||
expect(wrapper.find(RelevanceTuningForm).exists()).toBe(true);
|
||||
expect(wrapper.find(Loading).exists()).toBe(false);
|
||||
expect(wrapper.find(EmptyState).exists()).toBe(false);
|
||||
expect(wrapper.find(RelevanceTuningPreview).exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('initializes relevance tuning data', () => {
|
||||
|
@ -60,28 +60,6 @@ describe('RelevanceTuning', () => {
|
|||
expect(actions.initializeRelevanceTuning).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('will render an empty message when the engine has no schema', () => {
|
||||
setMockValues({
|
||||
...values,
|
||||
engineHasSchemaFields: false,
|
||||
});
|
||||
const wrapper = subject();
|
||||
expect(wrapper.find(EmptyState).dive().find(EuiEmptyPrompt).exists()).toBe(true);
|
||||
expect(wrapper.find(Loading).exists()).toBe(false);
|
||||
expect(wrapper.find(RelevanceTuningForm).exists()).toBe(false);
|
||||
});
|
||||
|
||||
it('will show a loading message if data is loading', () => {
|
||||
setMockValues({
|
||||
...values,
|
||||
dataLoading: true,
|
||||
});
|
||||
const wrapper = subject();
|
||||
expect(wrapper.find(Loading).exists()).toBe(true);
|
||||
expect(wrapper.find(EmptyState).exists()).toBe(false);
|
||||
expect(wrapper.find(RelevanceTuningForm).exists()).toBe(false);
|
||||
});
|
||||
|
||||
it('will prevent user from leaving the page if there are unsaved changes', () => {
|
||||
setMockValues({
|
||||
...values,
|
||||
|
@ -89,4 +67,31 @@ describe('RelevanceTuning', () => {
|
|||
});
|
||||
expect(subject().find(UnsavedChangesPrompt).prop('hasUnsavedChanges')).toBe(true);
|
||||
});
|
||||
|
||||
describe('header actions', () => {
|
||||
it('renders a Save button that will save the current changes', () => {
|
||||
const buttons = getPageHeaderActions(subject());
|
||||
expect(buttons.children().length).toBe(2);
|
||||
const saveButton = buttons.find('[data-test-subj="SaveRelevanceTuning"]');
|
||||
saveButton.simulate('click');
|
||||
expect(actions.updateSearchSettings).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('renders a Reset button that will remove all weights and boosts', () => {
|
||||
const buttons = getPageHeaderActions(subject());
|
||||
expect(buttons.children().length).toBe(2);
|
||||
const resetButton = buttons.find('[data-test-subj="ResetRelevanceTuning"]');
|
||||
resetButton.simulate('click');
|
||||
expect(actions.resetSearchSettings).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('will not render buttons if the engine has no schema', () => {
|
||||
setMockValues({
|
||||
...values,
|
||||
engineHasSchemaFields: false,
|
||||
});
|
||||
const buttons = getPageHeaderActions(subject());
|
||||
expect(buttons.children().length).toBe(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -9,43 +9,77 @@ import React, { useEffect } from 'react';
|
|||
|
||||
import { useActions, useValues } from 'kea';
|
||||
|
||||
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiButton } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { Loading } from '../../../shared/loading';
|
||||
import { SAVE_BUTTON_LABEL } from '../../../shared/constants';
|
||||
import { UnsavedChangesPrompt } from '../../../shared/unsaved_changes_prompt';
|
||||
import { RESTORE_DEFAULTS_BUTTON_LABEL } from '../../constants';
|
||||
import { getEngineBreadcrumbs } from '../engine';
|
||||
import { AppSearchPageTemplate } from '../layout';
|
||||
|
||||
import { EmptyState } from './components';
|
||||
import { RELEVANCE_TUNING_TITLE } from './constants';
|
||||
import { RelevanceTuningCallouts } from './relevance_tuning_callouts';
|
||||
import { RelevanceTuningForm } from './relevance_tuning_form';
|
||||
import { RelevanceTuningLayout } from './relevance_tuning_layout';
|
||||
import { RelevanceTuningPreview } from './relevance_tuning_preview';
|
||||
|
||||
import { RelevanceTuningLogic } from '.';
|
||||
|
||||
export const RelevanceTuning: React.FC = () => {
|
||||
const { dataLoading, engineHasSchemaFields, unsavedChanges } = useValues(RelevanceTuningLogic);
|
||||
const { initializeRelevanceTuning } = useActions(RelevanceTuningLogic);
|
||||
const { initializeRelevanceTuning, resetSearchSettings, updateSearchSettings } = useActions(
|
||||
RelevanceTuningLogic
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
initializeRelevanceTuning();
|
||||
}, []);
|
||||
|
||||
if (dataLoading) return <Loading />;
|
||||
|
||||
return (
|
||||
<RelevanceTuningLayout>
|
||||
<AppSearchPageTemplate
|
||||
pageChrome={getEngineBreadcrumbs([RELEVANCE_TUNING_TITLE])}
|
||||
pageHeader={{
|
||||
pageTitle: RELEVANCE_TUNING_TITLE,
|
||||
description: i18n.translate(
|
||||
'xpack.enterpriseSearch.appSearch.engine.relevanceTuning.description',
|
||||
{ defaultMessage: 'Set field weights and boosts.' }
|
||||
),
|
||||
rightSideItems: engineHasSchemaFields
|
||||
? [
|
||||
<EuiButton
|
||||
data-test-subj="SaveRelevanceTuning"
|
||||
color="primary"
|
||||
fill
|
||||
onClick={updateSearchSettings}
|
||||
>
|
||||
{SAVE_BUTTON_LABEL}
|
||||
</EuiButton>,
|
||||
<EuiButton
|
||||
data-test-subj="ResetRelevanceTuning"
|
||||
color="danger"
|
||||
onClick={resetSearchSettings}
|
||||
>
|
||||
{RESTORE_DEFAULTS_BUTTON_LABEL}
|
||||
</EuiButton>,
|
||||
]
|
||||
: [],
|
||||
}}
|
||||
isLoading={dataLoading}
|
||||
isEmptyState={!engineHasSchemaFields}
|
||||
emptyState={<EmptyState />}
|
||||
>
|
||||
<UnsavedChangesPrompt hasUnsavedChanges={unsavedChanges} />
|
||||
{engineHasSchemaFields ? (
|
||||
<EuiFlexGroup alignItems="flexStart">
|
||||
<EuiFlexItem grow={3}>
|
||||
<RelevanceTuningForm />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={4}>
|
||||
<RelevanceTuningPreview />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
) : (
|
||||
<EmptyState />
|
||||
)}
|
||||
</RelevanceTuningLayout>
|
||||
<RelevanceTuningCallouts />
|
||||
|
||||
<EuiFlexGroup alignItems="flexStart">
|
||||
<EuiFlexItem grow={3}>
|
||||
<RelevanceTuningForm />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={4}>
|
||||
<RelevanceTuningPreview />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</AppSearchPageTemplate>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -42,7 +42,7 @@ export const RelevanceTuningForm: React.FC = () => {
|
|||
return (
|
||||
<section className="relevanceTuningForm">
|
||||
<form>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiSpacer size="m" />
|
||||
<EuiTitle size="m">
|
||||
<h2>
|
||||
{i18n.translate(
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
/*
|
||||
* 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 { setMockActions, setMockValues } from '../../../__mocks__/kea_logic';
|
||||
import '../../__mocks__/engine_logic.mock';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { shallow, ShallowWrapper } from 'enzyme';
|
||||
|
||||
import { EuiPageHeader } from '@elastic/eui';
|
||||
|
||||
import { RelevanceTuningLayout } from './relevance_tuning_layout';
|
||||
|
||||
describe('RelevanceTuningLayout', () => {
|
||||
const values = {
|
||||
engineHasSchemaFields: true,
|
||||
schemaFieldsWithConflicts: [],
|
||||
};
|
||||
|
||||
const actions = {
|
||||
updateSearchSettings: jest.fn(),
|
||||
resetSearchSettings: jest.fn(),
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
setMockValues(values);
|
||||
setMockActions(actions);
|
||||
});
|
||||
|
||||
const subject = () => shallow(<RelevanceTuningLayout />);
|
||||
const findButtons = (wrapper: ShallowWrapper) =>
|
||||
wrapper.find(EuiPageHeader).prop('rightSideItems') as React.ReactElement[];
|
||||
|
||||
it('renders a Save button that will save the current changes', () => {
|
||||
const buttons = findButtons(subject());
|
||||
expect(buttons.length).toBe(2);
|
||||
const saveButton = shallow(buttons[0]);
|
||||
saveButton.simulate('click');
|
||||
expect(actions.updateSearchSettings).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('renders a Reset button that will remove all weights and boosts', () => {
|
||||
const buttons = findButtons(subject());
|
||||
expect(buttons.length).toBe(2);
|
||||
const resetButton = shallow(buttons[1]);
|
||||
resetButton.simulate('click');
|
||||
expect(actions.resetSearchSettings).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('will not render buttons if the engine has no schema', () => {
|
||||
setMockValues({
|
||||
...values,
|
||||
engineHasSchemaFields: false,
|
||||
});
|
||||
const buttons = findButtons(subject());
|
||||
expect(buttons.length).toBe(0);
|
||||
});
|
||||
});
|
|
@ -1,73 +0,0 @@
|
|||
/*
|
||||
* 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 { useActions, useValues } from 'kea';
|
||||
|
||||
import { EuiPageHeader, EuiButton } from '@elastic/eui';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { SAVE_BUTTON_LABEL } from '../../../shared/constants';
|
||||
import { FlashMessages } from '../../../shared/flash_messages';
|
||||
import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
|
||||
import { RESTORE_DEFAULTS_BUTTON_LABEL } from '../../constants';
|
||||
import { getEngineBreadcrumbs } from '../engine';
|
||||
|
||||
import { RELEVANCE_TUNING_TITLE } from './constants';
|
||||
import { RelevanceTuningCallouts } from './relevance_tuning_callouts';
|
||||
import { RelevanceTuningLogic } from './relevance_tuning_logic';
|
||||
|
||||
export const RelevanceTuningLayout: React.FC = ({ children }) => {
|
||||
const { resetSearchSettings, updateSearchSettings } = useActions(RelevanceTuningLogic);
|
||||
const { engineHasSchemaFields } = useValues(RelevanceTuningLogic);
|
||||
|
||||
const pageHeader = () => (
|
||||
<EuiPageHeader
|
||||
className="relevanceTuningHeader"
|
||||
pageTitle={RELEVANCE_TUNING_TITLE}
|
||||
description={i18n.translate(
|
||||
'xpack.enterpriseSearch.appSearch.engine.relevanceTuning.description',
|
||||
{
|
||||
defaultMessage: 'Set field weights and boosts.',
|
||||
}
|
||||
)}
|
||||
rightSideItems={
|
||||
engineHasSchemaFields
|
||||
? [
|
||||
<EuiButton
|
||||
data-test-subj="SaveRelevanceTuning"
|
||||
color="primary"
|
||||
fill
|
||||
onClick={updateSearchSettings}
|
||||
>
|
||||
{SAVE_BUTTON_LABEL}
|
||||
</EuiButton>,
|
||||
<EuiButton
|
||||
data-test-subj="ResetRelevanceTuning"
|
||||
color="danger"
|
||||
onClick={resetSearchSettings}
|
||||
>
|
||||
{RESTORE_DEFAULTS_BUTTON_LABEL}
|
||||
</EuiButton>,
|
||||
]
|
||||
: []
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<SetPageChrome trail={getEngineBreadcrumbs([RELEVANCE_TUNING_TITLE])} />
|
||||
{pageHeader()}
|
||||
<FlashMessages />
|
||||
<RelevanceTuningCallouts />
|
||||
{children}
|
||||
</>
|
||||
);
|
||||
};
|
|
@ -21,6 +21,7 @@ import { RelevanceTuningLogic } from '.';
|
|||
const emptyCallout = (
|
||||
<EuiEmptyPrompt
|
||||
data-test-subj="EmptyQueryPrompt"
|
||||
iconType="glasses"
|
||||
body={i18n.translate(
|
||||
'xpack.enterpriseSearch.appSearch.engine.relevanceTuning.preview.enterQueryMessage',
|
||||
{
|
||||
|
|
|
@ -7,42 +7,40 @@
|
|||
|
||||
import React from 'react';
|
||||
|
||||
import { EuiButton, EuiEmptyPrompt, EuiPanel } from '@elastic/eui';
|
||||
import { EuiButton, EuiEmptyPrompt } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { DOCS_PREFIX } from '../../../routes';
|
||||
|
||||
export const EmptyState: React.FC = () => (
|
||||
<EuiPanel color="subdued">
|
||||
<EuiEmptyPrompt
|
||||
iconType="gear"
|
||||
title={
|
||||
<h2>
|
||||
{i18n.translate('xpack.enterpriseSearch.appSearch.engine.resultSettings.empty.title', {
|
||||
defaultMessage: 'Add documents to adjust settings',
|
||||
})}
|
||||
</h2>
|
||||
<EuiEmptyPrompt
|
||||
iconType="gear"
|
||||
title={
|
||||
<h2>
|
||||
{i18n.translate('xpack.enterpriseSearch.appSearch.engine.resultSettings.empty.title', {
|
||||
defaultMessage: 'Add documents to adjust settings',
|
||||
})}
|
||||
</h2>
|
||||
}
|
||||
body={i18n.translate(
|
||||
'xpack.enterpriseSearch.appSearch.engine.resultSettings.empty.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'A schema will be automatically created for you after you index some documents.',
|
||||
}
|
||||
body={i18n.translate(
|
||||
'xpack.enterpriseSearch.appSearch.engine.resultSettings.empty.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'A schema will be automatically created for you after you index some documents.',
|
||||
}
|
||||
)}
|
||||
actions={
|
||||
<EuiButton
|
||||
size="s"
|
||||
target="_blank"
|
||||
iconType="popout"
|
||||
href={`${DOCS_PREFIX}/result-settings-guide.html`}
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.appSearch.engine.resultSettings.empty.buttonLabel',
|
||||
{ defaultMessage: 'Read the result settings guide' }
|
||||
)}
|
||||
</EuiButton>
|
||||
}
|
||||
/>
|
||||
</EuiPanel>
|
||||
)}
|
||||
actions={
|
||||
<EuiButton
|
||||
size="s"
|
||||
target="_blank"
|
||||
iconType="popout"
|
||||
href={`${DOCS_PREFIX}/result-settings-guide.html`}
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.appSearch.engine.resultSettings.empty.buttonLabel',
|
||||
{ defaultMessage: 'Read the result settings guide' }
|
||||
)}
|
||||
</EuiButton>
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -13,11 +13,9 @@ import React from 'react';
|
|||
|
||||
import { shallow, ShallowWrapper } from 'enzyme';
|
||||
|
||||
import { EuiPageHeader } from '@elastic/eui';
|
||||
|
||||
import { UnsavedChangesPrompt } from '../../../shared/unsaved_changes_prompt';
|
||||
import { getPageHeaderActions } from '../../../test_helpers';
|
||||
|
||||
import { EmptyState } from './components';
|
||||
import { ResultSettings } from './result_settings';
|
||||
import { ResultSettingsTable } from './result_settings_table';
|
||||
import { SampleResponse } from './sample_response';
|
||||
|
@ -46,8 +44,6 @@ describe('ResultSettings', () => {
|
|||
});
|
||||
|
||||
const subject = () => shallow(<ResultSettings />);
|
||||
const findButtons = (wrapper: ShallowWrapper) =>
|
||||
wrapper.find(EuiPageHeader).prop('rightSideItems') as React.ReactElement[];
|
||||
|
||||
it('renders', () => {
|
||||
const wrapper = subject();
|
||||
|
@ -60,19 +56,10 @@ describe('ResultSettings', () => {
|
|||
expect(actions.initializeResultSettingsData).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('renders a loading screen if data has not loaded yet', () => {
|
||||
setMockValues({
|
||||
dataLoading: true,
|
||||
});
|
||||
const wrapper = subject();
|
||||
expect(wrapper.find(ResultSettingsTable).exists()).toBe(false);
|
||||
expect(wrapper.find(SampleResponse).exists()).toBe(false);
|
||||
});
|
||||
|
||||
it('renders a "save" button that will save the current changes', () => {
|
||||
const buttons = findButtons(subject());
|
||||
expect(buttons.length).toBe(3);
|
||||
const saveButton = shallow(buttons[0]);
|
||||
const buttons = getPageHeaderActions(subject());
|
||||
expect(buttons.children().length).toBe(3);
|
||||
const saveButton = buttons.find('[data-test-subj="SaveResultSettings"]');
|
||||
saveButton.simulate('click');
|
||||
expect(actions.saveResultSettings).toHaveBeenCalled();
|
||||
});
|
||||
|
@ -82,8 +69,8 @@ describe('ResultSettings', () => {
|
|||
...values,
|
||||
stagedUpdates: false,
|
||||
});
|
||||
const buttons = findButtons(subject());
|
||||
const saveButton = shallow(buttons[0]);
|
||||
const buttons = getPageHeaderActions(subject());
|
||||
const saveButton = buttons.find('[data-test-subj="SaveResultSettings"]');
|
||||
expect(saveButton.prop('disabled')).toBe(true);
|
||||
});
|
||||
|
||||
|
@ -93,15 +80,15 @@ describe('ResultSettings', () => {
|
|||
stagedUpdates: true,
|
||||
resultFieldsEmpty: true,
|
||||
});
|
||||
const buttons = findButtons(subject());
|
||||
const saveButton = shallow(buttons[0]);
|
||||
const buttons = getPageHeaderActions(subject());
|
||||
const saveButton = buttons.find('[data-test-subj="SaveResultSettings"]');
|
||||
expect(saveButton.prop('disabled')).toBe(true);
|
||||
});
|
||||
|
||||
it('renders a "restore defaults" button that will reset all values to their defaults', () => {
|
||||
const buttons = findButtons(subject());
|
||||
expect(buttons.length).toBe(3);
|
||||
const resetButton = shallow(buttons[1]);
|
||||
const buttons = getPageHeaderActions(subject());
|
||||
expect(buttons.children().length).toBe(3);
|
||||
const resetButton = buttons.find('[data-test-subj="ResetResultSettings"]');
|
||||
resetButton.simulate('click');
|
||||
expect(actions.confirmResetAllFields).toHaveBeenCalled();
|
||||
});
|
||||
|
@ -111,15 +98,15 @@ describe('ResultSettings', () => {
|
|||
...values,
|
||||
resultFieldsAtDefaultSettings: true,
|
||||
});
|
||||
const buttons = findButtons(subject());
|
||||
const resetButton = shallow(buttons[1]);
|
||||
const buttons = getPageHeaderActions(subject());
|
||||
const resetButton = buttons.find('[data-test-subj="ResetResultSettings"]');
|
||||
expect(resetButton.prop('disabled')).toBe(true);
|
||||
});
|
||||
|
||||
it('renders a "clear" button that will remove all selected options', () => {
|
||||
const buttons = findButtons(subject());
|
||||
expect(buttons.length).toBe(3);
|
||||
const clearButton = shallow(buttons[2]);
|
||||
const buttons = getPageHeaderActions(subject());
|
||||
expect(buttons.children().length).toBe(3);
|
||||
const clearButton = buttons.find('[data-test-subj="ClearResultSettings"]');
|
||||
clearButton.simulate('click');
|
||||
expect(actions.clearAllFields).toHaveBeenCalled();
|
||||
});
|
||||
|
@ -143,17 +130,12 @@ describe('ResultSettings', () => {
|
|||
});
|
||||
|
||||
it('will not render action buttons', () => {
|
||||
const buttons = findButtons(wrapper);
|
||||
expect(buttons.length).toBe(0);
|
||||
});
|
||||
|
||||
it('will not render the main page content', () => {
|
||||
expect(wrapper.find(ResultSettingsTable).exists()).toBe(false);
|
||||
expect(wrapper.find(SampleResponse).exists()).toBe(false);
|
||||
const buttons = getPageHeaderActions(wrapper);
|
||||
expect(buttons.children().length).toBe(0);
|
||||
});
|
||||
|
||||
it('will render an empty state', () => {
|
||||
expect(wrapper.find(EmptyState).exists()).toBe(true);
|
||||
expect(wrapper.prop('isEmptyState')).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -9,17 +9,15 @@ import React, { useEffect } from 'react';
|
|||
|
||||
import { useActions, useValues } from 'kea';
|
||||
|
||||
import { EuiPageHeader, EuiFlexGroup, EuiFlexItem, EuiButton, EuiButtonEmpty } from '@elastic/eui';
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiButton, EuiButtonEmpty } from '@elastic/eui';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { SAVE_BUTTON_LABEL } from '../../../shared/constants';
|
||||
import { FlashMessages } from '../../../shared/flash_messages';
|
||||
import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
|
||||
import { Loading } from '../../../shared/loading';
|
||||
import { UnsavedChangesPrompt } from '../../../shared/unsaved_changes_prompt';
|
||||
import { RESTORE_DEFAULTS_BUTTON_LABEL } from '../../constants';
|
||||
import { getEngineBreadcrumbs } from '../engine';
|
||||
import { AppSearchPageTemplate } from '../layout';
|
||||
|
||||
import { EmptyState } from './components';
|
||||
import { RESULT_SETTINGS_TITLE } from './constants';
|
||||
|
@ -57,59 +55,56 @@ export const ResultSettings: React.FC = () => {
|
|||
initializeResultSettingsData();
|
||||
}, []);
|
||||
|
||||
if (dataLoading) return <Loading />;
|
||||
const hasSchema = Object.keys(schema).length > 0;
|
||||
|
||||
return (
|
||||
<>
|
||||
<SetPageChrome trail={getEngineBreadcrumbs([RESULT_SETTINGS_TITLE])} />
|
||||
<UnsavedChangesPrompt hasUnsavedChanges={stagedUpdates} messageText={UNSAVED_MESSAGE} />
|
||||
<EuiPageHeader
|
||||
pageTitle={RESULT_SETTINGS_TITLE}
|
||||
description={i18n.translate(
|
||||
<AppSearchPageTemplate
|
||||
pageChrome={getEngineBreadcrumbs([RESULT_SETTINGS_TITLE])}
|
||||
pageHeader={{
|
||||
pageTitle: RESULT_SETTINGS_TITLE,
|
||||
description: i18n.translate(
|
||||
'xpack.enterpriseSearch.appSearch.engine.resultSettings.pageDescription',
|
||||
{ defaultMessage: 'Enrich search results and select which fields will appear.' }
|
||||
)}
|
||||
rightSideItems={
|
||||
hasSchema
|
||||
? [
|
||||
<EuiButton
|
||||
data-test-subj="SaveResultSettings"
|
||||
color="primary"
|
||||
fill
|
||||
onClick={saveResultSettings}
|
||||
disabled={resultFieldsEmpty || !stagedUpdates}
|
||||
>
|
||||
{SAVE_BUTTON_LABEL}
|
||||
</EuiButton>,
|
||||
<EuiButton
|
||||
data-test-subj="ResetResultSettings"
|
||||
color="danger"
|
||||
onClick={confirmResetAllFields}
|
||||
disabled={resultFieldsAtDefaultSettings}
|
||||
>
|
||||
{RESTORE_DEFAULTS_BUTTON_LABEL}
|
||||
</EuiButton>,
|
||||
<EuiButtonEmpty data-test-subj="ClearResultSettings" onClick={clearAllFields}>
|
||||
{CLEAR_BUTTON_LABEL}
|
||||
</EuiButtonEmpty>,
|
||||
]
|
||||
: []
|
||||
}
|
||||
/>
|
||||
<FlashMessages />
|
||||
{hasSchema ? (
|
||||
<EuiFlexGroup alignItems="flexStart">
|
||||
<EuiFlexItem grow={5}>
|
||||
<ResultSettingsTable />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={3}>
|
||||
<SampleResponse />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
) : (
|
||||
<EmptyState />
|
||||
)}
|
||||
</>
|
||||
),
|
||||
rightSideItems: hasSchema
|
||||
? [
|
||||
<EuiButton
|
||||
data-test-subj="SaveResultSettings"
|
||||
color="primary"
|
||||
fill
|
||||
onClick={saveResultSettings}
|
||||
disabled={resultFieldsEmpty || !stagedUpdates}
|
||||
>
|
||||
{SAVE_BUTTON_LABEL}
|
||||
</EuiButton>,
|
||||
<EuiButton
|
||||
data-test-subj="ResetResultSettings"
|
||||
color="danger"
|
||||
onClick={confirmResetAllFields}
|
||||
disabled={resultFieldsAtDefaultSettings}
|
||||
>
|
||||
{RESTORE_DEFAULTS_BUTTON_LABEL}
|
||||
</EuiButton>,
|
||||
<EuiButtonEmpty data-test-subj="ClearResultSettings" onClick={clearAllFields}>
|
||||
{CLEAR_BUTTON_LABEL}
|
||||
</EuiButtonEmpty>,
|
||||
]
|
||||
: [],
|
||||
}}
|
||||
isLoading={dataLoading}
|
||||
isEmptyState={!hasSchema}
|
||||
emptyState={<EmptyState />}
|
||||
>
|
||||
<UnsavedChangesPrompt hasUnsavedChanges={stagedUpdates} messageText={UNSAVED_MESSAGE} />
|
||||
|
||||
<EuiFlexGroup alignItems="flexStart">
|
||||
<EuiFlexItem grow={5}>
|
||||
<ResultSettingsTable />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={3}>
|
||||
<SampleResponse />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</AppSearchPageTemplate>
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue