From 389fd95b534ee5f9840c9626662d138eccbd1b23 Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Tue, 5 Oct 2021 18:59:18 -0400 Subject: [PATCH] [7.x] [App Search] Wired up Suggestion detail data (#113796) (#113969) * [App Search] Wired up Suggestion detail data (#113796) * Fix mock value after type update in #113861 * Fix test after type update in #113861 Co-authored-by: Jason Stoltzfus --- .../curation_result_panel.test.tsx | 23 ++ .../curation_result_panel.tsx | 16 +- .../curation_suggestion.test.tsx | 95 +++++++- .../curation_suggestion.tsx | 72 +++++- .../curation_suggestion_logic.test.ts | 230 ++++++++++++++++++ .../curation_suggestion_logic.ts | 131 ++++++++++ .../search_relevance_suggestions.test.ts | 24 ++ .../search_relevance_suggestions.ts | 25 ++ 8 files changed, 591 insertions(+), 25 deletions(-) create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion_logic.test.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion_logic.ts diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_result_panel.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_result_panel.test.tsx index fad4e54721bb35..80d5a874c81025 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_result_panel.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_result_panel.test.tsx @@ -5,6 +5,8 @@ * 2.0. */ +import { setMockValues } from '../../../../../__mocks__/kea_logic'; + import React from 'react'; import { shallow } from 'enzyme'; @@ -14,6 +16,13 @@ import { Result } from '../../../result'; import { CurationResultPanel } from './curation_result_panel'; describe('CurationResultPanel', () => { + const values = { + isMetaEngine: true, + engine: { + schema: {}, + }, + }; + const results = [ { id: { raw: 'foo' }, @@ -25,6 +34,10 @@ describe('CurationResultPanel', () => { }, ]; + beforeAll(() => { + setMockValues(values); + }); + beforeEach(() => { jest.clearAllMocks(); }); @@ -33,6 +46,11 @@ describe('CurationResultPanel', () => { const wrapper = shallow(); expect(wrapper.find('[data-test-subj="suggestedText"]').exists()).toBe(false); expect(wrapper.find(Result).length).toBe(2); + expect(wrapper.find(Result).at(0).props()).toEqual({ + result: results[0], + isMetaEngine: true, + schemaForTypeHighlights: values.engine.schema, + }); }); it('renders a no results message when there are no results', () => { @@ -41,6 +59,11 @@ describe('CurationResultPanel', () => { expect(wrapper.find(Result).length).toBe(0); }); + it('renders the correct count', () => { + const wrapper = shallow(); + expect(wrapper.find('[data-test-subj="curationCount"]').prop('children')).toBe(2); + }); + it('shows text about automation when variant is "suggested"', () => { const wrapper = shallow(); expect(wrapper.find('[data-test-subj="suggestedText"]').exists()).toBe(true); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_result_panel.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_result_panel.tsx index 12bbf07f97bb35..b61355d0b85557 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_result_panel.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_result_panel.tsx @@ -7,6 +7,8 @@ import React from 'react'; +import { useValues } from 'kea'; + import { EuiFlexGroup, EuiFlexItem, @@ -17,6 +19,8 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { EngineLogic } from '../../../engine'; + import { Result } from '../../../result'; import { Result as ResultType } from '../../../result/types'; import './curation_result_panel.scss'; @@ -27,14 +31,14 @@ interface Props { } export const CurationResultPanel: React.FC = ({ variant, results }) => { - // TODO wire up - const count = 3; + const { isMetaEngine, engine } = useValues(EngineLogic); + const count = results.length; return ( <> - {count} + {count} @@ -70,7 +74,11 @@ export const CurationResultPanel: React.FC = ({ variant, results }) => { {results.length > 0 ? ( results.map((result) => ( - + )) ) : ( diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion.test.tsx index 9bfc12dfe7cc20..2dcefa7273c728 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion.test.tsx @@ -5,6 +5,8 @@ * 2.0. */ +import { setMockActions, setMockValues } from '../../../../../__mocks__/kea_logic'; +import '../../../../../__mocks__/shallow_useeffect.mock'; import { mockUseParams } from '../../../../../__mocks__/react_router'; import '../../../../__mocks__/engine_logic.mock'; @@ -14,12 +16,65 @@ import { shallow } from 'enzyme'; import { AppSearchPageTemplate } from '../../../layout'; +import { Result } from '../../../result'; + +import { CurationResultPanel } from './curation_result_panel'; import { CurationSuggestion } from './curation_suggestion'; describe('CurationSuggestion', () => { + const values = { + suggestion: { + query: 'foo', + updated_at: '2021-07-08T14:35:50Z', + promoted: ['1', '2', '3'], + }, + suggestedPromotedDocuments: [ + { + id: { + raw: '1', + }, + _meta: { + id: '1', + engine: 'some-engine', + }, + }, + { + id: { + raw: '2', + }, + _meta: { + id: '2', + engine: 'some-engine', + }, + }, + { + id: { + raw: '3', + }, + _meta: { + id: '3', + engine: 'some-engine', + }, + }, + ], + isMetaEngine: true, + engine: { + schema: {}, + }, + }; + + const actions = { + loadSuggestion: jest.fn(), + }; + + beforeAll(() => { + setMockValues(values); + setMockActions(actions); + }); + beforeEach(() => { jest.clearAllMocks(); - mockUseParams.mockReturnValue({ query: 'some%20query' }); + mockUseParams.mockReturnValue({ query: 'foo' }); }); it('renders', () => { @@ -28,19 +83,21 @@ describe('CurationSuggestion', () => { expect(wrapper.is(AppSearchPageTemplate)).toBe(true); }); - it('displays the decoded query in the title', () => { - const wrapper = shallow(); - - expect(wrapper.prop('pageHeader').pageTitle).toEqual('some query'); + it('loads data on initialization', () => { + shallow(); + expect(actions.loadSuggestion).toHaveBeenCalled(); }); - // TODO This will need to come from somewhere else when wired up - it('displays an empty query if "" is encoded in as the qery', () => { - mockUseParams.mockReturnValue({ query: '%22%22' }); + it('shows suggested promoted documents', () => { + const wrapper = shallow(); + const suggestedResultsPanel = wrapper.find(CurationResultPanel).at(1); + expect(suggestedResultsPanel.prop('results')).toEqual(values.suggestedPromotedDocuments); + }); + it('displays the query in the title', () => { const wrapper = shallow(); - expect(wrapper.prop('pageHeader').pageTitle).toEqual('""'); + expect(wrapper.prop('pageHeader').pageTitle).toEqual('foo'); }); it('displays has a button to display organic results', () => { @@ -52,4 +109,24 @@ describe('CurationSuggestion', () => { wrapper.find('[data-test-subj="showOrganicResults"]').simulate('click'); expect(wrapper.find('[data-test-subj="organicResults"]').exists()).toBe(false); }); + + it('displays proposed organic results', () => { + const wrapper = shallow(); + wrapper.find('[data-test-subj="showOrganicResults"]').simulate('click'); + expect(wrapper.find('[data-test-subj="proposedOrganicResults"]').find(Result).length).toBe(4); + expect(wrapper.find(Result).at(0).prop('isMetaEngine')).toEqual(true); + expect(wrapper.find(Result).at(0).prop('schemaForTypeHighlights')).toEqual( + values.engine.schema + ); + }); + + it('displays current organic results', () => { + const wrapper = shallow(); + wrapper.find('[data-test-subj="showOrganicResults"]').simulate('click'); + expect(wrapper.find('[data-test-subj="currentOrganicResults"]').find(Result).length).toBe(4); + expect(wrapper.find(Result).at(0).prop('isMetaEngine')).toEqual(true); + expect(wrapper.find(Result).at(0).prop('schemaForTypeHighlights')).toEqual( + values.engine.schema + ); + }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion.tsx index 4fab9db47af908..ade78e4914e84a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion.tsx @@ -5,7 +5,9 @@ * 2.0. */ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; + +import { useActions, useValues } from 'kea'; import { EuiButtonEmpty, @@ -19,6 +21,7 @@ import { import { i18n } from '@kbn/i18n'; import { useDecodedParams } from '../../../../utils/encode_path_params'; +import { EngineLogic } from '../../../engine'; import { AppSearchPageTemplate } from '../../../layout'; import { Result } from '../../../result'; import { Result as ResultType } from '../../../result/types'; @@ -27,26 +30,37 @@ import { getCurationsBreadcrumbs } from '../../utils'; import { CurationActionBar } from './curation_action_bar'; import { CurationResultPanel } from './curation_result_panel'; +import { CurationSuggestionLogic } from './curation_suggestion_logic'; import { DATA } from './temp_data'; export const CurationSuggestion: React.FC = () => { const { query } = useDecodedParams(); + const curationSuggestionLogic = CurationSuggestionLogic({ query }); + const { loadSuggestion } = useActions(curationSuggestionLogic); + const { engine, isMetaEngine } = useValues(EngineLogic); + const { suggestion, suggestedPromotedDocuments, dataLoading } = + useValues(curationSuggestionLogic); const [showOrganicResults, setShowOrganicResults] = useState(false); const currentOrganicResults = [...DATA].splice(5, 4); const proposedOrganicResults = [...DATA].splice(2, 4); - const queryTitle = query === '""' ? query : `${query}`; + const suggestionQuery = suggestion?.query || ''; + + useEffect(() => { + loadSuggestion(); + }, []); return ( { -

Current

+

+ {i18n.translate( + 'xpack.enterpriseSearch.appSearch.engine.curations.suggestedCuration.currentTitle', + { defaultMessage: 'Current' } + )} +

-

Suggested

+

+ {i18n.translate( + 'xpack.enterpriseSearch.appSearch.engine.curations.suggestedCuration.suggestionTitle', + { defaultMessage: 'Suggested' } + )} +

- +
@@ -81,7 +105,15 @@ export const CurationSuggestion: React.FC = () => { onClick={() => setShowOrganicResults(!showOrganicResults)} data-test-subj="showOrganicResults" > - {showOrganicResults ? 'Collapse' : 'Expand'} organic search results + {showOrganicResults + ? i18n.translate( + 'xpack.enterpriseSearch.appSearch.engine.curations.suggestedCuration.collapseButtonLabel', + { defaultMessage: 'Collapse organic search results' } + ) + : i18n.translate( + 'xpack.enterpriseSearch.appSearch.engine.curations.suggestedCuration.expandButtonLabel', + { defaultMessage: 'Expand organic search results' } + )} {showOrganicResults && ( <> @@ -90,10 +122,18 @@ export const CurationSuggestion: React.FC = () => { {currentOrganicResults.length > 0 && ( - + {currentOrganicResults.map((result: ResultType) => ( - + ))} @@ -101,10 +141,18 @@ export const CurationSuggestion: React.FC = () => { {proposedOrganicResults.length > 0 && ( - + {proposedOrganicResults.map((result: ResultType) => ( - + ))} diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion_logic.test.ts new file mode 100644 index 00000000000000..9edeab4b658ef8 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion_logic.test.ts @@ -0,0 +1,230 @@ +/* + * 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 { + LogicMounter, + mockFlashMessageHelpers, + mockHttpValues, +} from '../../../../../__mocks__/kea_logic'; + +import '../../../../__mocks__/engine_logic.mock'; + +import { nextTick } from '@kbn/test/jest'; + +import { CurationSuggestion } from '../../types'; + +import { CurationSuggestionLogic } from './curation_suggestion_logic'; + +const DEFAULT_VALUES = { + dataLoading: true, + suggestion: null, + suggestedPromotedDocuments: [], +}; + +const suggestion: CurationSuggestion = { + query: 'foo', + updated_at: '2021-07-08T14:35:50Z', + promoted: ['1', '2', '3'], + status: 'applied', +}; + +const suggestedPromotedDocuments = [ + { + id: { + raw: '1', + }, + _meta: { + id: '1', + engine: 'some-engine', + }, + }, + { + id: { + raw: '2', + }, + _meta: { + id: '2', + engine: 'some-engine', + }, + }, + { + id: { + raw: '3', + }, + _meta: { + id: '3', + engine: 'some-engine', + }, + }, +]; + +const MOCK_RESPONSE = { + meta: { + page: { + current: 1, + size: 10, + total_results: 1, + total_pages: 1, + }, + }, + results: [suggestion], +}; + +const MOCK_DOCUMENTS_RESPONSE = { + results: [ + { + id: { + raw: '2', + }, + _meta: { + id: '2', + engine: 'some-engine', + }, + }, + { + id: { + raw: '1', + }, + _meta: { + id: '1', + engine: 'some-engine', + }, + }, + ], +}; + +describe('CurationSuggestionLogic', () => { + const { mount } = new LogicMounter(CurationSuggestionLogic); + const { flashAPIErrors } = mockFlashMessageHelpers; + const mountLogic = (props: object = {}) => { + mount(props, { query: 'foo-query' }); + }; + + const { http } = mockHttpValues; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('has expected default values', () => { + mountLogic(); + expect(CurationSuggestionLogic.values).toEqual(DEFAULT_VALUES); + }); + + describe('actions', () => { + describe('onSuggestionLoaded', () => { + it('should save the loaded suggestion and promoted documents associated with that suggestion and set dataLoading to false', () => { + mountLogic(); + CurationSuggestionLogic.actions.onSuggestionLoaded({ + suggestion, + suggestedPromotedDocuments, + }); + expect(CurationSuggestionLogic.values).toEqual({ + ...DEFAULT_VALUES, + suggestion, + suggestedPromotedDocuments, + dataLoading: false, + }); + }); + }); + }); + + describe('listeners', () => { + describe('loadSuggestion', () => { + it('should set dataLoading state', () => { + mountLogic({ dataLoading: false }); + + CurationSuggestionLogic.actions.loadSuggestion(); + + expect(CurationSuggestionLogic.values).toEqual({ + ...DEFAULT_VALUES, + dataLoading: true, + }); + }); + + it('should make an API call and trigger onSuggestionLoaded', async () => { + http.post.mockReturnValueOnce(Promise.resolve(MOCK_RESPONSE)); + http.post.mockReturnValueOnce(Promise.resolve(MOCK_DOCUMENTS_RESPONSE)); + mountLogic(); + jest.spyOn(CurationSuggestionLogic.actions, 'onSuggestionLoaded'); + + CurationSuggestionLogic.actions.loadSuggestion(); + await nextTick(); + + expect(http.post).toHaveBeenCalledWith( + '/internal/app_search/engines/some-engine/search_relevance_suggestions/foo-query', + { + body: JSON.stringify({ + page: { + current: 1, + size: 1, + }, + filters: { + status: ['pending'], + type: 'curation', + }, + }), + } + ); + + expect(http.post).toHaveBeenCalledWith('/internal/app_search/engines/some-engine/search', { + query: { query: '' }, + body: JSON.stringify({ + page: { + size: 100, + }, + filters: { + // The results of the first API call are used to make the second http call for document details + id: MOCK_RESPONSE.results[0].promoted, + }, + }), + }); + + expect(CurationSuggestionLogic.actions.onSuggestionLoaded).toHaveBeenCalledWith({ + suggestion: { + query: 'foo', + updated_at: '2021-07-08T14:35:50Z', + promoted: ['1', '2', '3'], + status: 'applied', + }, + // Note that these were re-ordered to match the 'promoted' list above, and since document + // 3 was not found it is not included in this list + suggestedPromotedDocuments: [ + { + id: { + raw: '1', + }, + _meta: { + id: '1', + engine: 'some-engine', + }, + }, + { + id: { + raw: '2', + }, + _meta: { + id: '2', + engine: 'some-engine', + }, + }, + ], + }); + }); + + it('handles errors', async () => { + http.post.mockReturnValueOnce(Promise.reject('error')); + mount(); + + CurationSuggestionLogic.actions.loadSuggestion(); + await nextTick(); + + expect(flashAPIErrors).toHaveBeenCalledWith('error'); + }); + }); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion_logic.ts new file mode 100644 index 00000000000000..d3f27be122060c --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion_logic.ts @@ -0,0 +1,131 @@ +/* + * 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 { kea, MakeLogicType } from 'kea'; + +import { flashAPIErrors } from '../../../../../shared/flash_messages'; +import { HttpLogic } from '../../../../../shared/http'; +import { EngineLogic } from '../../../engine'; +import { Result } from '../../../result/types'; +import { CurationSuggestion } from '../../types'; + +interface CurationSuggestionValues { + dataLoading: boolean; + suggestion: CurationSuggestion | null; + suggestedPromotedDocuments: Result[]; +} + +interface CurationSuggestionActions { + loadSuggestion(): void; + onSuggestionLoaded({ + suggestion, + suggestedPromotedDocuments, + }: { + suggestion: CurationSuggestion; + suggestedPromotedDocuments: Result[]; + }): { + suggestion: CurationSuggestion; + suggestedPromotedDocuments: Result[]; + }; +} + +interface CurationSuggestionProps { + query: CurationSuggestion['query']; +} + +export const CurationSuggestionLogic = kea< + MakeLogicType +>({ + path: ['enterprise_search', 'app_search', 'curations', 'suggestion_logic'], + actions: () => ({ + loadSuggestion: true, + onSuggestionLoaded: ({ suggestion, suggestedPromotedDocuments }) => ({ + suggestion, + suggestedPromotedDocuments, + }), + }), + reducers: () => ({ + dataLoading: [ + true, + { + loadSuggestion: () => true, + onSuggestionLoaded: () => false, + }, + ], + suggestion: [ + null, + { + onSuggestionLoaded: (_, { suggestion }) => suggestion, + }, + ], + suggestedPromotedDocuments: [ + [], + { + onSuggestionLoaded: (_, { suggestedPromotedDocuments }) => suggestedPromotedDocuments, + }, + ], + }), + listeners: ({ actions, props }) => ({ + loadSuggestion: async () => { + const { http } = HttpLogic.values; + const { engineName } = EngineLogic.values; + + try { + const response = await http.post( + `/internal/app_search/engines/${engineName}/search_relevance_suggestions/${props.query}`, + { + body: JSON.stringify({ + page: { + current: 1, + size: 1, + }, + filters: { + status: ['pending'], + type: 'curation', + }, + }), + } + ); + + const suggestion = response.results[0]; + + const searchResponse = await http.post( + `/internal/app_search/engines/${engineName}/search`, + { + query: { query: '' }, + body: JSON.stringify({ + page: { + size: 100, + }, + filters: { + id: suggestion.promoted, + }, + }), + } + ); + + // Filter out docs that were not found and maintain promoted order + const promotedIds: string[] = suggestion.promoted; + const documentDetails = searchResponse.results; + const suggestedPromotedDocuments = promotedIds.reduce((acc: Result[], id: string) => { + const found = documentDetails.find( + (documentDetail: Result) => documentDetail.id.raw === id + ); + if (!found) return acc; + return [...acc, found]; + }, []); + + actions.onSuggestionLoaded({ + suggestion: suggestion as CurationSuggestion, + suggestedPromotedDocuments, + }); + } catch (e) { + flashAPIErrors(e); + } + }, + }), +}); diff --git a/x-pack/plugins/enterprise_search/server/routes/app_search/search_relevance_suggestions.test.ts b/x-pack/plugins/enterprise_search/server/routes/app_search/search_relevance_suggestions.test.ts index 4fc62d18857362..2bdcfb9fe9d58d 100644 --- a/x-pack/plugins/enterprise_search/server/routes/app_search/search_relevance_suggestions.test.ts +++ b/x-pack/plugins/enterprise_search/server/routes/app_search/search_relevance_suggestions.test.ts @@ -115,4 +115,28 @@ describe('search relevance insights routes', () => { }); }); }); + + describe('POST /internal/app_search/engines/{name}/search_relevance_suggestions/{query}', () => { + const mockRouter = new MockRouter({ + method: 'post', + path: '/internal/app_search/engines/{engineName}/search_relevance_suggestions/{query}', + }); + + beforeEach(() => { + registerSearchRelevanceSuggestionsRoutes({ + ...mockDependencies, + router: mockRouter.router, + }); + }); + + it('creates a request to enterprise search', () => { + mockRouter.callRoute({ + params: { engineName: 'some-engine', query: 'foo' }, + }); + + expect(mockRequestHandler.createRequest).toHaveBeenCalledWith({ + path: '/api/as/v0/engines/:engineName/search_relevance_suggestions/:query', + }); + }); + }); }); diff --git a/x-pack/plugins/enterprise_search/server/routes/app_search/search_relevance_suggestions.ts b/x-pack/plugins/enterprise_search/server/routes/app_search/search_relevance_suggestions.ts index 1ba9d9fa0ac53c..8b3b204c24d70c 100644 --- a/x-pack/plugins/enterprise_search/server/routes/app_search/search_relevance_suggestions.ts +++ b/x-pack/plugins/enterprise_search/server/routes/app_search/search_relevance_suggestions.ts @@ -80,4 +80,29 @@ export function registerSearchRelevanceSuggestionsRoutes({ path: '/api/as/v0/engines/:engineName/search_relevance_suggestions/settings', }) ); + + router.post( + { + path: '/internal/app_search/engines/{engineName}/search_relevance_suggestions/{query}', + validate: { + params: schema.object({ + engineName: schema.string(), + query: schema.string(), + }), + body: schema.object({ + page: schema.object({ + current: schema.number(), + size: schema.number(), + }), + filters: schema.object({ + status: schema.arrayOf(schema.string()), + type: schema.string(), + }), + }), + }, + }, + enterpriseSearchRequestHandler.createRequest({ + path: '/api/as/v0/engines/:engineName/search_relevance_suggestions/:query', + }) + ); }