[SavedObjectFinder] Remove savedObjects.find (#151220)

## Summary

This PR replaces deprecated client-side `savedObjects.find` method with
a server-side one and a corresponding API call. As a result, the
dependencies of the `SavedObjectFinder` component have changed slightly:
instead of `coreStart.savedObjects`, the component is now taking
`coreStart.http`.

If you have been tagged as a reviewer, it means your plugin is using
`SavedObjectFinder` somewhere. To test it, ensure it all works as
previously.

### Checklist

Delete any items that are not applicable to this PR.

~- [] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)~
~ [ ]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials~
- [X] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
~- [ ] Any UI touched in this PR is usable by keyboard only (learn more
about [keyboard
accessibility](https://webaim.org/techniques/keyboard/))~
~- [ ] Any UI touched in this PR does not create any new axe failures
(run axe in browser:
[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),
[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))~
~- [ ] If a plugin configuration key changed, check if it needs to be
allowlisted in the cloud and added to the [docker
list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)~
~- [ ] This renders correctly on smaller devices using a responsive
layout. (You can test this [in your
browser](https://www.browserstack.com/guide/responsive-testing-on-local-server))~
~- [ ] This was checked for [cross-browser
compatibility](https://www.elastic.co/support/matrix#matrix_browsers)~


### For maintainers

- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Maja Grubic 2023-02-16 16:16:32 +01:00 committed by GitHub
parent b94c77780e
commit b4f5fa6ed8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
37 changed files with 373 additions and 201 deletions

View file

@ -39,7 +39,7 @@ export const buildAllDashboardActions = async ({
uiActions.registerAction(clonePanelAction);
uiActions.attachAction(CONTEXT_MENU_TRIGGER, clonePanelAction.id);
const SavedObjectFinder = getSavedObjectFinder(core.savedObjects, uiSettings);
const SavedObjectFinder = getSavedObjectFinder(uiSettings, core.http);
const changeViewAction = new ReplacePanelAction(SavedObjectFinder);
uiActions.registerAction(changeViewAction);
uiActions.attachAction(CONTEXT_MENU_TRIGGER, changeViewAction.id);

View file

@ -6,6 +6,7 @@
* Side Public License, v 1.
*/
import { HttpStart } from '@kbn/core/public';
import { isErrorEmbeddable, openAddPanelFlyout } from '@kbn/embeddable-plugin/public';
import { getSavedObjectFinder } from '@kbn/saved-objects-plugin/public';
@ -18,14 +19,14 @@ export function addFromLibrary(this: DashboardContainer) {
notifications,
usageCollection,
settings: { uiSettings, theme },
dashboardSavedObject: { savedObjectsClient },
embeddable: { getEmbeddableFactories, getEmbeddableFactory },
http,
} = pluginServices.getServices();
if (isErrorEmbeddable(this)) return;
this.openOverlay(
openAddPanelFlyout({
SavedObjectFinder: getSavedObjectFinder({ client: savedObjectsClient }, uiSettings),
SavedObjectFinder: getSavedObjectFinder(uiSettings, http as HttpStart),
reportUiCounter: usageCollection.reportUiCounter,
getAllFactories: getEmbeddableFactories,
getFactory: getEmbeddableFactory,

View file

@ -17,5 +17,6 @@ export const httpServiceFactory: HttpServiceFactory = () => {
return {
basePath: serviceMock.http.basePath,
get: serviceMock.http.get,
};
};

View file

@ -16,10 +16,11 @@ export type HttpServiceFactory = KibanaPluginServiceFactory<
>;
export const httpServiceFactory: HttpServiceFactory = ({ coreStart }) => {
const {
http: { basePath },
http: { basePath, get },
} = coreStart;
return {
basePath,
get,
};
};

View file

@ -6,8 +6,9 @@
* Side Public License, v 1.
*/
import type { CoreSetup } from '@kbn/core/public';
import type { CoreStart } from '@kbn/core/public';
export interface DashboardHTTPService {
basePath: CoreSetup['http']['basePath'];
basePath: CoreStart['http']['basePath'];
get: CoreStart['http']['get'];
}

View file

@ -207,7 +207,7 @@ export class EmbeddablePublicPlugin implements Plugin<EmbeddableSetup, Embeddabl
notifications={core.notifications}
application={core.application}
inspector={inspector}
SavedObjectFinder={getSavedObjectFinder(core.savedObjects, core.uiSettings)}
SavedObjectFinder={getSavedObjectFinder(core.uiSettings, core.http)}
containerContext={containerContext}
theme={theme}
/>

View file

@ -8,3 +8,4 @@
export const PER_PAGE_SETTING = 'savedObjects:perPage';
export const LISTING_LIMIT_SETTING = 'savedObjects:listingLimit';
export type { SavedObjectCommon, FindQueryHTTP, FindResponseHTTP, FinderAttributes } from './types';

View file

@ -0,0 +1,35 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { SavedObject } from '@kbn/core-saved-objects-server';
export type SavedObjectCommon<T = unknown> = SavedObject<T>;
export interface FindQueryHTTP {
perPage?: number;
page?: number;
type: string | string[];
search?: string;
searchFields?: string[];
defaultSearchOperator?: 'AND' | 'OR';
sortField?: string;
sortOrder?: 'asc' | 'desc';
fields?: string | string[];
}
export interface FinderAttributes {
title?: string;
name?: string;
type: string;
}
export interface FindResponseHTTP<T> {
saved_objects: Array<SavedObjectCommon<T>>;
total: number;
page: number;
per_page: number;
}

View file

@ -6,9 +6,5 @@
* Side Public License, v 1.
*/
export type {
SavedObjectMetaData,
SavedObjectFinderUiProps,
FinderAttributes,
} from './saved_object_finder';
export type { SavedObjectMetaData, SavedObjectFinderUiProps } from './saved_object_finder';
export { SavedObjectFinderUi, getSavedObjectFinder } from './saved_object_finder';

View file

@ -52,43 +52,45 @@ describe('SavedObjectsFinder', () => {
},
];
it('should call saved object client on startup', async () => {
it('should call api find on startup', async () => {
const core = coreMock.createStart();
(core.savedObjects.client.find as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ savedObjects: [doc] })
(core.http.get as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ saved_objects: [doc] })
);
core.uiSettings.get.mockImplementation(() => 10);
const wrapper = shallow(
<SavedObjectFinder
savedObjects={core.savedObjects}
http={core.http}
uiSettings={core.uiSettings}
savedObjectMetaData={searchMetaData}
/>
);
wrapper.instance().componentDidMount!();
expect(core.savedObjects.client.find).toHaveBeenCalledWith({
type: ['search'],
fields: ['title', 'name'],
search: undefined,
page: 1,
perPage: 10,
searchFields: ['title^3', 'description', 'name'],
defaultSearchOperator: 'AND',
expect(core.http.get).toHaveBeenCalledWith('/internal/saved-objects-finder/find', {
query: {
type: ['search'],
fields: ['title', 'name'],
search: undefined,
page: 1,
perPage: 10,
searchFields: ['title^3', 'description', 'name'],
defaultSearchOperator: 'AND',
},
});
});
it('should list initial items', async () => {
const core = coreMock.createStart();
(core.savedObjects.client.find as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ savedObjects: [doc] })
(core.http.get as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ saved_objects: [doc] })
);
core.uiSettings.get.mockImplementation(() => 10);
const wrapper = shallow(
<SavedObjectFinder
savedObjects={core.savedObjects}
http={core.http}
uiSettings={core.uiSettings}
savedObjectMetaData={searchMetaData}
/>
@ -104,14 +106,14 @@ describe('SavedObjectsFinder', () => {
it('should call onChoose on item click', async () => {
const chooseStub = sinon.stub();
const core = coreMock.createStart();
(core.savedObjects.client.find as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ savedObjects: [doc] })
(core.http.get as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ saved_objects: [doc] })
);
core.uiSettings.get.mockImplementation(() => 10);
const wrapper = shallow(
<SavedObjectFinder
savedObjects={core.savedObjects}
http={core.http}
uiSettings={core.uiSettings}
onChoose={chooseStub}
savedObjectMetaData={searchMetaData}
@ -129,14 +131,14 @@ describe('SavedObjectsFinder', () => {
describe('sorting', () => {
it('should list items ascending', async () => {
const core = coreMock.createStart();
(core.savedObjects.client.find as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ savedObjects: [doc, doc2] })
(core.http.get as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ saved_objects: [doc, doc2] })
);
core.uiSettings.get.mockImplementation(() => 10);
const wrapper = shallow(
<SavedObjectFinder
savedObjects={core.savedObjects}
http={core.http}
uiSettings={core.uiSettings}
savedObjectMetaData={searchMetaData}
/>
@ -150,14 +152,14 @@ describe('SavedObjectsFinder', () => {
it('should list items descending', async () => {
const core = coreMock.createStart();
(core.savedObjects.client.find as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ savedObjects: [doc, doc2] })
(core.http.get as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ saved_objects: [doc, doc2] })
);
core.uiSettings.get.mockImplementation(() => 10);
const wrapper = shallow(
<SavedObjectFinder
savedObjects={core.savedObjects}
http={core.http}
uiSettings={core.uiSettings}
savedObjectMetaData={searchMetaData}
/>
@ -174,14 +176,14 @@ describe('SavedObjectsFinder', () => {
it('should not show the saved objects which get filtered by showSavedObject', async () => {
const core = coreMock.createStart();
(core.savedObjects.client.find as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ savedObjects: [doc, doc2] })
(core.http.get as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ saved_objects: [doc, doc2] })
);
core.uiSettings.get.mockImplementation(() => 10);
const wrapper = shallow(
<SavedObjectFinder
savedObjects={core.savedObjects}
http={core.http}
uiSettings={core.uiSettings}
savedObjectMetaData={[
{
@ -204,14 +206,14 @@ describe('SavedObjectsFinder', () => {
describe('search', () => {
it('should request filtered list on search input', async () => {
const core = coreMock.createStart();
(core.savedObjects.client.find as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ savedObjects: [doc, doc2] })
(core.http.get as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ saved_objects: [doc, doc2] })
);
core.uiSettings.get.mockImplementation(() => 10);
const wrapper = shallow(
<SavedObjectFinder
savedObjects={core.savedObjects}
http={core.http}
uiSettings={core.uiSettings}
savedObjectMetaData={searchMetaData}
/>
@ -223,25 +225,27 @@ describe('SavedObjectsFinder', () => {
.first()
.simulate('change', { target: { value: 'abc' } });
expect(core.savedObjects.client.find).toHaveBeenCalledWith({
type: ['search'],
fields: ['title', 'name'],
search: 'abc*',
page: 1,
perPage: 10,
searchFields: ['title^3', 'description', 'name'],
defaultSearchOperator: 'AND',
expect(core.http.get).toHaveBeenCalledWith('/internal/saved-objects-finder/find', {
query: {
type: ['search'],
fields: ['title', 'name'],
search: 'abc*',
page: 1,
perPage: 10,
searchFields: ['title^3', 'description', 'name'],
defaultSearchOperator: 'AND',
},
});
});
it('should include additional fields in search if listed in meta data', async () => {
const core = coreMock.createStart();
core.uiSettings.get.mockImplementation(() => 10);
(core.savedObjects.client.find as jest.Mock).mockResolvedValue({ savedObjects: [] });
(core.http.get as jest.Mock).mockResolvedValue({ saved_objects: [] });
const wrapper = shallow(
<SavedObjectFinder
savedObjects={core.savedObjects}
http={core.http}
uiSettings={core.uiSettings}
savedObjectMetaData={[
{
@ -266,27 +270,29 @@ describe('SavedObjectsFinder', () => {
.first()
.simulate('change', { target: { value: 'abc' } });
expect(core.savedObjects.client.find).toHaveBeenCalledWith({
type: ['type1', 'type2'],
fields: ['title', 'name', 'field1', 'field2', 'field3'],
search: 'abc*',
page: 1,
perPage: 10,
searchFields: ['title^3', 'description'],
defaultSearchOperator: 'AND',
expect(core.http.get).toHaveBeenCalledWith('/internal/saved-objects-finder/find', {
query: {
type: ['type1', 'type2'],
fields: ['title', 'name', 'field1', 'field2', 'field3'],
search: 'abc*',
page: 1,
perPage: 10,
searchFields: ['title^3', 'description'],
defaultSearchOperator: 'AND',
},
});
});
it('should respect response order on search input', async () => {
const core = coreMock.createStart();
(core.savedObjects.client.find as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ savedObjects: [doc, doc2] })
(core.http.get as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ saved_objects: [doc, doc2] })
);
core.uiSettings.get.mockImplementation(() => 10);
const wrapper = shallow(
<SavedObjectFinder
savedObjects={core.savedObjects}
http={core.http}
uiSettings={core.uiSettings}
savedObjectMetaData={searchMetaData}
/>
@ -307,14 +313,14 @@ describe('SavedObjectsFinder', () => {
it('should request multiple saved object types at once', async () => {
const core = coreMock.createStart();
(core.savedObjects.client.find as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ savedObjects: [doc, doc2] })
(core.http.get as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ saved_objects: [doc, doc2] })
);
core.uiSettings.get.mockImplementation(() => 10);
const wrapper = shallow(
<SavedObjectFinder
savedObjects={core.savedObjects}
http={core.http}
uiSettings={core.uiSettings}
savedObjectMetaData={[
{
@ -332,14 +338,16 @@ describe('SavedObjectsFinder', () => {
);
wrapper.instance().componentDidMount!();
expect(core.savedObjects.client.find).toHaveBeenCalledWith({
type: ['search', 'vis'],
fields: ['title', 'name'],
search: undefined,
page: 1,
perPage: 10,
searchFields: ['title^3', 'description'],
defaultSearchOperator: 'AND',
expect(core.http.get).toHaveBeenCalledWith('/internal/saved-objects-finder/find', {
query: {
type: ['search', 'vis'],
fields: ['title', 'name'],
search: undefined,
page: 1,
perPage: 10,
searchFields: ['title^3', 'description'],
defaultSearchOperator: 'AND',
},
});
});
@ -359,16 +367,16 @@ describe('SavedObjectsFinder', () => {
it('should not render filter buttons if disabled', async () => {
const core = coreMock.createStart();
(core.savedObjects.client.find as any as jest.SpyInstance).mockImplementation(() =>
(core.http.get as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({
savedObjects: [doc, doc2, doc3],
saved_objects: [doc, doc2, doc3],
})
);
core.uiSettings.get.mockImplementation(() => 10);
const wrapper = shallow(
<SavedObjectFinder
savedObjects={core.savedObjects}
http={core.http}
uiSettings={core.uiSettings}
showFilter={false}
savedObjectMetaData={metaDataConfig}
@ -384,16 +392,16 @@ describe('SavedObjectsFinder', () => {
it('should not render filter buttons if there is only one type in the list', async () => {
const core = coreMock.createStart();
(core.savedObjects.client.find as any as jest.SpyInstance).mockImplementation(() =>
(core.http.get as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({
savedObjects: [doc, doc2],
saved_objects: [doc, doc2],
})
);
core.uiSettings.get.mockImplementation(() => 10);
const wrapper = shallow(
<SavedObjectFinder
savedObjects={core.savedObjects}
http={core.http}
uiSettings={core.uiSettings}
showFilter={true}
savedObjectMetaData={metaDataConfig}
@ -409,16 +417,16 @@ describe('SavedObjectsFinder', () => {
it('should apply filter if selected', async () => {
const core = coreMock.createStart();
(core.savedObjects.client.find as any as jest.SpyInstance).mockImplementation(() =>
(core.http.get as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({
savedObjects: [doc, doc2, doc3],
saved_objects: [doc, doc2, doc3],
})
);
core.uiSettings.get.mockImplementation(() => 10);
const wrapper = shallow(
<SavedObjectFinder
savedObjects={core.savedObjects}
http={core.http}
uiSettings={core.uiSettings}
showFilter={true}
savedObjectMetaData={metaDataConfig}
@ -439,15 +447,15 @@ describe('SavedObjectsFinder', () => {
it('should display no items message if there are no items', async () => {
const core = coreMock.createStart();
(core.savedObjects.client.find as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ savedObjects: [] })
(core.http.get as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ saved_objects: [] })
);
core.uiSettings.get.mockImplementation(() => 10);
const noItemsMessage = <span id="myNoItemsMessage" />;
const wrapper = shallow(
<SavedObjectFinder
savedObjects={core.savedObjects}
http={core.http}
uiSettings={core.uiSettings}
noItemsMessage={noItemsMessage}
savedObjectMetaData={searchMetaData}
@ -470,14 +478,14 @@ describe('SavedObjectsFinder', () => {
it('should show a table pagination with initial per page', async () => {
const core = coreMock.createStart();
(core.savedObjects.client.find as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ savedObjects: longItemList })
(core.http.get as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ saved_objects: longItemList })
);
core.uiSettings.get.mockImplementation(() => 10);
const wrapper = shallow(
<SavedObjectFinder
savedObjects={core.savedObjects}
http={core.http}
uiSettings={core.uiSettings}
initialPageSize={15}
savedObjectMetaData={searchMetaData}
@ -492,14 +500,14 @@ describe('SavedObjectsFinder', () => {
it('should allow switching the page size', async () => {
const core = coreMock.createStart();
(core.savedObjects.client.find as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ savedObjects: longItemList })
(core.http.get as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ saved_objects: longItemList })
);
core.uiSettings.get.mockImplementation(() => 10);
const wrapper = shallow(
<SavedObjectFinder
savedObjects={core.savedObjects}
http={core.http}
uiSettings={core.uiSettings}
initialPageSize={15}
savedObjectMetaData={searchMetaData}
@ -514,14 +522,14 @@ describe('SavedObjectsFinder', () => {
it('should switch page correctly', async () => {
const core = coreMock.createStart();
(core.savedObjects.client.find as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ savedObjects: longItemList })
(core.http.get as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ saved_objects: longItemList })
);
core.uiSettings.get.mockImplementation(() => 10);
const wrapper = shallow(
<SavedObjectFinder
savedObjects={core.savedObjects}
http={core.http}
uiSettings={core.uiSettings}
initialPageSize={15}
savedObjectMetaData={searchMetaData}
@ -536,14 +544,14 @@ describe('SavedObjectsFinder', () => {
it('should show an ordinary pagination for fixed page sizes', async () => {
const core = coreMock.createStart();
(core.savedObjects.client.find as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ savedObjects: longItemList })
(core.http.get as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ saved_objects: longItemList })
);
core.uiSettings.get.mockImplementation(() => 10);
const wrapper = shallow(
<SavedObjectFinder
savedObjects={core.savedObjects}
http={core.http}
uiSettings={core.uiSettings}
fixedPageSize={33}
savedObjectMetaData={searchMetaData}
@ -558,14 +566,14 @@ describe('SavedObjectsFinder', () => {
it('should switch page correctly for fixed page sizes', async () => {
const core = coreMock.createStart();
(core.savedObjects.client.find as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ savedObjects: longItemList })
(core.http.get as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ saved_objects: longItemList })
);
core.uiSettings.get.mockImplementation(() => 10);
const wrapper = shallow(
<SavedObjectFinder
savedObjects={core.savedObjects}
http={core.http}
uiSettings={core.uiSettings}
fixedPageSize={33}
savedObjectMetaData={searchMetaData}
@ -582,11 +590,11 @@ describe('SavedObjectsFinder', () => {
describe('loading state', () => {
it('should display a spinner during initial loading', () => {
const core = coreMock.createStart();
(core.savedObjects.client.find as jest.Mock).mockResolvedValue({ savedObjects: [] });
(core.http.get as jest.Mock).mockResolvedValue({ saved_objects: [] });
const wrapper = shallow(
<SavedObjectFinder
savedObjects={core.savedObjects}
http={core.http}
uiSettings={core.uiSettings}
savedObjectMetaData={searchMetaData}
/>
@ -597,13 +605,13 @@ describe('SavedObjectsFinder', () => {
it('should hide the spinner if data is shown', async () => {
const core = coreMock.createStart();
(core.savedObjects.client.find as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ savedObjects: [doc] })
(core.http.get as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ saved_objects: [doc] })
);
const wrapper = shallow(
<SavedObjectFinder
savedObjects={core.savedObjects}
http={core.http}
uiSettings={core.uiSettings}
savedObjectMetaData={[
{
@ -622,13 +630,13 @@ describe('SavedObjectsFinder', () => {
it('should not show the spinner if there are already items', async () => {
const core = coreMock.createStart();
(core.savedObjects.client.find as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ savedObjects: [doc] })
(core.http.get as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ saved_objects: [doc] })
);
const wrapper = shallow(
<SavedObjectFinder
savedObjects={core.savedObjects}
http={core.http}
uiSettings={core.uiSettings}
savedObjectMetaData={searchMetaData}
/>
@ -649,14 +657,14 @@ describe('SavedObjectsFinder', () => {
it('should render with children', async () => {
const core = coreMock.createStart();
(core.savedObjects.client.find as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ savedObjects: [doc, doc2] })
(core.http.get as any as jest.SpyInstance).mockImplementation(() =>
Promise.resolve({ saved_objects: [doc, doc2] })
);
core.uiSettings.get.mockImplementation(() => 10);
const wrapper = shallow(
<SavedObjectFinder
savedObjects={core.savedObjects}
http={core.http}
uiSettings={core.uiSettings}
savedObjectMetaData={[
{

View file

@ -31,39 +31,34 @@ import {
import { Direction } from '@elastic/eui/src/services/sort/sort_direction';
import { i18n } from '@kbn/i18n';
import {
SimpleSavedObject,
CoreStart,
IUiSettingsClient,
SavedObjectsStart,
} from '@kbn/core/public';
import { CoreStart, IUiSettingsClient, HttpStart } from '@kbn/core/public';
import type {
FinderAttributes,
FindQueryHTTP,
FindResponseHTTP,
SavedObjectCommon,
} from '../../common';
import { LISTING_LIMIT_SETTING } from '../../common';
export interface SavedObjectMetaData<T = unknown> {
type: string;
name: string;
getIconForSavedObject(savedObject: SimpleSavedObject<T>): IconType;
getTooltipForSavedObject?(savedObject: SimpleSavedObject<T>): string;
showSavedObject?(savedObject: SimpleSavedObject<T>): boolean;
getSavedObjectSubType?(savedObject: SimpleSavedObject<T>): string;
getIconForSavedObject(savedObject: SavedObjectCommon<T>): IconType;
getTooltipForSavedObject?(savedObject: SavedObjectCommon<T>): string;
showSavedObject?(savedObject: SavedObjectCommon<T>): boolean;
getSavedObjectSubType?(savedObject: SavedObjectCommon<T>): string;
includeFields?: string[];
defaultSearchField?: string;
}
export interface FinderAttributes {
title?: string;
name?: string;
type: string;
}
interface SavedObjectFinderState {
items: Array<{
title: string | null;
name: string | null;
id: SimpleSavedObject['id'];
type: SimpleSavedObject['type'];
savedObject: SimpleSavedObject<FinderAttributes>;
id: SavedObjectCommon['id'];
type: SavedObjectCommon['type'];
savedObject: SavedObjectCommon<FinderAttributes>;
}>;
query: string;
isFetchingItems: boolean;
@ -77,10 +72,10 @@ interface SavedObjectFinderState {
interface BaseSavedObjectFinder {
onChoose?: (
id: SimpleSavedObject['id'],
type: SimpleSavedObject['type'],
id: SavedObjectCommon['id'],
type: SavedObjectCommon['type'],
name: string,
savedObject: SimpleSavedObject
savedObject: SavedObjectCommon
) => void;
noItemsMessage?: React.ReactNode;
savedObjectMetaData: Array<SavedObjectMetaData<FinderAttributes>>;
@ -100,8 +95,8 @@ interface SavedObjectFinderInitialPageSize extends BaseSavedObjectFinder {
export type SavedObjectFinderProps = SavedObjectFinderFixedPage | SavedObjectFinderInitialPageSize;
export type SavedObjectFinderUiProps = {
savedObjects: CoreStart['savedObjects'];
uiSettings: CoreStart['uiSettings'];
http: CoreStart['http'];
} & SavedObjectFinderProps;
class SavedObjectFinderUi extends React.Component<
@ -134,7 +129,7 @@ class SavedObjectFinderUi extends React.Component<
}, []);
const perPage = this.props.uiSettings.get(LISTING_LIMIT_SETTING);
const resp = await this.props.savedObjects.client.find<FinderAttributes>({
const params: FindQueryHTTP = {
type: Object.keys(metaDataMap),
fields: [...new Set(fields)],
search: query ? `${query}*` : undefined,
@ -142,15 +137,17 @@ class SavedObjectFinderUi extends React.Component<
perPage,
searchFields: ['title^3', 'description', ...additionalSearchFields],
defaultSearchOperator: 'AND',
});
};
const resp = (await this.props.http.get('/internal/saved-objects-finder/find', {
query: params as Record<string, any>,
})) as FindResponseHTTP<FinderAttributes>;
resp.savedObjects = resp.savedObjects.filter((savedObject) => {
resp.saved_objects = resp.saved_objects.filter((savedObject) => {
const metaData = metaDataMap[savedObject.type];
if (metaData.showSavedObject) {
return metaData.showSavedObject(savedObject);
} else {
return true;
}
return true;
});
if (!this.isComponentMounted) {
@ -163,14 +160,11 @@ class SavedObjectFinderUi extends React.Component<
this.setState({
isFetchingItems: false,
page: 0,
items: resp.savedObjects.map((savedObject) => {
const {
attributes: { name, title },
id,
type,
} = savedObject;
items: resp.saved_objects.map((savedObject) => {
const { attributes, id, type } = savedObject;
const { name, title } = attributes as FinderAttributes;
const titleToUse = typeof title === 'string' ? title : '';
const nameToUse = name && typeof name === 'string' ? name : titleToUse;
const nameToUse = name ? name : titleToUse;
return {
title: titleToUse,
name: nameToUse,
@ -533,9 +527,9 @@ class SavedObjectFinderUi extends React.Component<
}
}
const getSavedObjectFinder = (savedObject: SavedObjectsStart, uiSettings: IUiSettingsClient) => {
const getSavedObjectFinder = (uiSettings: IUiSettingsClient, http: HttpStart) => {
return (props: SavedObjectFinderProps) => (
<SavedObjectFinderUi {...props} savedObjects={savedObject} uiSettings={uiSettings} />
<SavedObjectFinderUi {...props} uiSettings={uiSettings} http={http} />
);
};

View file

@ -10,7 +10,8 @@ import { SavedObjectsPublicPlugin } from './plugin';
export type { OnSaveProps, OriginSaveModalProps, SaveModalState, SaveResult } from './save_modal';
export { SavedObjectSaveModal, SavedObjectSaveModalOrigin, showSaveModal } from './save_modal';
export type { SavedObjectFinderUiProps, SavedObjectMetaData, FinderAttributes } from './finder';
export type { SavedObjectFinderUiProps, SavedObjectMetaData } from './finder';
export type { FinderAttributes } from '../common/types';
export { getSavedObjectFinder, SavedObjectFinderUi } from './finder';
export type {
SavedObjectDecorator,

View file

@ -0,0 +1,12 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export const registerRoutesMock = jest.fn();
jest.doMock('./routes', () => ({
registerRoutes: registerRoutesMock,
}));

View file

@ -0,0 +1,37 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { registerRoutesMock } from './plugin.test.mocks';
import { coreMock } from '@kbn/core/server/mocks';
import { SavedObjectsServerPlugin } from './plugin';
import { uiSettings } from './ui_settings';
describe('SavedObjectsPlugin', () => {
let plugin: SavedObjectsServerPlugin;
let coreSetup: ReturnType<typeof coreMock.createSetup>;
beforeEach(() => {
coreSetup = coreMock.createSetup();
plugin = new SavedObjectsServerPlugin();
});
afterEach(() => {
registerRoutesMock.mockReset();
});
describe('#setup', () => {
it('calls `registerRoutes` and `registerSettings` with the correct parameters', () => {
plugin.setup(coreSetup);
expect(coreSetup.uiSettings.register).toHaveBeenCalledWith(uiSettings);
expect(coreSetup.http.createRouter).toHaveBeenCalledTimes(1);
expect(registerRoutesMock).toHaveBeenCalledTimes(1);
});
});
});

View file

@ -6,12 +6,15 @@
* Side Public License, v 1.
*/
import { CoreSetup, Plugin } from '@kbn/core/server';
import type { CoreSetup, Plugin, RequestHandlerContext } from '@kbn/core/server';
import { registerRoutes } from './routes';
import { uiSettings } from './ui_settings';
export class SavedObjectsServerPlugin implements Plugin<object, object> {
public setup(core: CoreSetup) {
core.uiSettings.register(uiSettings);
const router = core.http.createRouter<RequestHandlerContext>();
registerRoutes(router);
return {};
}

View file

@ -0,0 +1,61 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { schema } from '@kbn/config-schema';
import { SavedObjectsRouter } from '../types';
import type { SavedObjectCommon, FindResponseHTTP } from '../../common';
export const registerFindRoute = (router: SavedObjectsRouter) => {
router.get(
{
path: '/internal/saved-objects-finder/find',
validate: {
query: schema.object({
perPage: schema.number({ min: 0, defaultValue: 20 }),
page: schema.number({ min: 0, defaultValue: 1 }),
type: schema.oneOf([schema.string(), schema.arrayOf(schema.string())]),
search: schema.maybe(schema.string()),
defaultSearchOperator: schema.oneOf([schema.literal('AND'), schema.literal('OR')]),
sortField: schema.maybe(schema.string()),
sortOrder: schema.maybe(schema.oneOf([schema.literal('asc'), schema.literal('desc')])),
fields: schema.oneOf([schema.string(), schema.arrayOf(schema.string())], {
defaultValue: [],
}),
searchFields: schema.maybe(schema.arrayOf(schema.string())),
}),
},
options: {
authRequired: 'optional',
},
},
async (ctx, req, res) => {
const savedObjectsClient = (await ctx.core).savedObjects.client;
const { query } = req;
const searchTypes = Array.isArray(query.type) ? query.type : [query.type];
const includedFields = Array.isArray(query.fields) ? query.fields : [query.fields];
const findResponse = await savedObjectsClient.find<SavedObjectCommon<any>>({
...query,
type: searchTypes,
fields: includedFields,
});
const savedObjects = findResponse.saved_objects;
const response: FindResponseHTTP<any> = {
saved_objects: savedObjects,
total: findResponse.total,
per_page: findResponse.per_page,
page: findResponse.page,
};
return res.ok({ body: response });
}
);
};

View file

@ -0,0 +1,14 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { SavedObjectsRouter } from '../types';
import { registerFindRoute } from './find';
export const registerRoutes = (router: SavedObjectsRouter) => {
registerFindRoute(router);
};

View file

@ -0,0 +1,10 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { IRouter, RequestHandlerContext } from '@kbn/core/server';
export type SavedObjectsRouter = IRouter<RequestHandlerContext>;

View file

@ -15,6 +15,7 @@
"@kbn/test-jest-helpers",
"@kbn/utility-types",
"@kbn/config-schema",
"@kbn/core-saved-objects-server",
],
"exclude": [
"target/**/*",

View file

@ -10,8 +10,9 @@ import React from 'react';
import { mountWithIntl } from '@kbn/test-jest-helpers';
import { TypesStart, VisGroups, BaseVisType } from '../vis_types';
import NewVisModal from './new_vis_modal';
import { ApplicationStart, SavedObjectsStart, DocLinksStart } from '@kbn/core/public';
import { ApplicationStart, DocLinksStart } from '@kbn/core/public';
import { embeddablePluginMock } from '@kbn/embeddable-plugin/public/mocks';
import { httpServiceMock } from '@kbn/core-http-browser-mocks';
describe('NewVisModal', () => {
const defaultVisTypeParams = {
@ -75,6 +76,7 @@ describe('NewVisModal', () => {
},
},
};
const http = httpServiceMock.createStartContract({ basePath: '' });
beforeAll(() => {
Object.defineProperty(window, 'location', {
@ -98,7 +100,7 @@ describe('NewVisModal', () => {
uiSettings={uiSettings}
application={{} as ApplicationStart}
docLinks={docLinks as DocLinksStart}
savedObjects={{} as SavedObjectsStart}
http={http}
/>
);
expect(wrapper.find('[data-test-subj="visGroup-aggbased"]').exists()).toBe(true);
@ -115,7 +117,7 @@ describe('NewVisModal', () => {
uiSettings={uiSettings}
application={{} as ApplicationStart}
docLinks={docLinks as DocLinksStart}
savedObjects={{} as SavedObjectsStart}
http={http}
/>
);
expect(wrapper.find('[data-test-subj="visGroup-tools"]').exists()).toBe(true);
@ -131,7 +133,7 @@ describe('NewVisModal', () => {
uiSettings={uiSettings}
application={{} as ApplicationStart}
docLinks={docLinks as DocLinksStart}
savedObjects={{} as SavedObjectsStart}
http={http}
/>
);
expect(wrapper.find('[data-test-subj="visType-vis2"]').exists()).toBe(true);
@ -148,7 +150,7 @@ describe('NewVisModal', () => {
uiSettings={uiSettings}
application={{} as ApplicationStart}
docLinks={docLinks as DocLinksStart}
savedObjects={{} as SavedObjectsStart}
http={http}
/>
);
const visCard = wrapper.find('[data-test-subj="visType-vis"]').last();
@ -167,7 +169,7 @@ describe('NewVisModal', () => {
uiSettings={uiSettings}
application={{} as ApplicationStart}
docLinks={docLinks as DocLinksStart}
savedObjects={{} as SavedObjectsStart}
http={http}
/>
);
const visCard = wrapper.find('[data-test-subj="visType-vis"]').last();
@ -193,7 +195,7 @@ describe('NewVisModal', () => {
application={{ navigateToApp } as unknown as ApplicationStart}
docLinks={docLinks as DocLinksStart}
stateTransfer={stateTransfer}
savedObjects={{} as SavedObjectsStart}
http={http}
/>
);
const visCard = wrapper.find('[data-test-subj="visType-visWithAliasUrl"]').last();
@ -218,7 +220,7 @@ describe('NewVisModal', () => {
uiSettings={uiSettings}
application={{ navigateToApp } as unknown as ApplicationStart}
docLinks={docLinks as DocLinksStart}
savedObjects={{} as SavedObjectsStart}
http={http}
/>
);
const visCard = wrapper.find('[data-test-subj="visType-visWithAliasUrl"]').last();
@ -239,7 +241,7 @@ describe('NewVisModal', () => {
uiSettings={uiSettings}
application={{} as ApplicationStart}
docLinks={docLinks as DocLinksStart}
savedObjects={{} as SavedObjectsStart}
http={http}
/>
);
const aggBasedGroupCard = wrapper

View file

@ -12,12 +12,7 @@ import { EuiModal } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { METRIC_TYPE, UiCounterMetricType } from '@kbn/analytics';
import {
ApplicationStart,
IUiSettingsClient,
SavedObjectsStart,
DocLinksStart,
} from '@kbn/core/public';
import { ApplicationStart, IUiSettingsClient, DocLinksStart, HttpStart } from '@kbn/core/public';
import { EmbeddableStateTransfer } from '@kbn/embeddable-plugin/public';
import { SearchSelection } from './search_selection';
import { GroupSelection } from './group_selection';
@ -34,7 +29,7 @@ interface TypeSelectionProps {
addBasePath: (path: string) => string;
uiSettings: IUiSettingsClient;
docLinks: DocLinksStart;
savedObjects: SavedObjectsStart;
http: HttpStart;
application: ApplicationStart;
outsideVisualizeApp?: boolean;
stateTransfer?: EmbeddableStateTransfer;
@ -97,7 +92,7 @@ class NewVisModal extends React.Component<TypeSelectionProps, TypeSelectionState
onSearchSelected={this.onSearchSelected}
visType={this.state.visType}
uiSettings={this.props.uiSettings}
savedObjects={this.props.savedObjects}
http={this.props.http}
goBack={() => this.setState({ showSearchVisModal: false })}
/>
</EuiModal>

View file

@ -10,7 +10,7 @@ import React from 'react';
import { EuiModalBody, EuiModalHeader, EuiModalHeaderTitle } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import { IUiSettingsClient, SavedObjectsStart } from '@kbn/core/public';
import { IUiSettingsClient, HttpStart } from '@kbn/core/public';
import { SavedObjectFinderUi } from '@kbn/saved-objects-plugin/public';
import type { BaseVisType } from '../../vis_types';
@ -21,7 +21,7 @@ interface SearchSelectionProps {
onSearchSelected: (searchId: string, searchType: string) => void;
visType: BaseVisType;
uiSettings: IUiSettingsClient;
savedObjects: SavedObjectsStart;
http: HttpStart;
goBack: () => void;
}
@ -85,7 +85,7 @@ export class SearchSelection extends React.Component<SearchSelectionProps> {
]}
fixedPageSize={this.fixedPageSize}
uiSettings={this.props.uiSettings}
savedObjects={this.props.savedObjects}
http={this.props.http}
/>
</EuiModalBody>
</React.Fragment>

View file

@ -13,7 +13,6 @@ import { I18nProvider } from '@kbn/i18n-react';
import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public';
import {
getHttp,
getSavedObjects,
getTypes,
getUISettings,
getApplication,
@ -81,7 +80,7 @@ export function showNewVisModal({
visTypesRegistry={getTypes()}
addBasePath={getHttp().basePath.prepend}
uiSettings={getUISettings()}
savedObjects={getSavedObjects()}
http={getHttp()}
application={getApplication()}
docLinks={getDocLinks()}
showAggsSelection={showAggsSelection}

View file

@ -50,6 +50,7 @@
"@kbn/core-overlays-browser",
"@kbn/config-schema",
"@kbn/usage-collection-plugin",
"@kbn/core-http-browser-mocks",
"@kbn/shared-ux-router",
],
"exclude": [

View file

@ -38,7 +38,7 @@ export const AddEmbeddableFlyout: FC<Props> = ({
const embeddablesService = useEmbeddablesService();
const platformService = usePlatformService();
const { getEmbeddableFactories } = embeddablesService;
const { getSavedObjects, getUISettings } = platformService;
const { getHttp, getUISettings } = platformService;
const onAddPanel = useCallback(
(id: string, savedObjectType: string) => {
@ -82,8 +82,8 @@ export const AddEmbeddableFlyout: FC<Props> = ({
savedObjectMetaData={availableSavedObjects}
showFilter={true}
noItemsMessage={strings.getNoItemsText()}
savedObjects={getSavedObjects()}
uiSettings={getUISettings()}
http={getHttp()}
/>
</EuiFlyoutBody>
</EuiFlyout>

View file

@ -45,5 +45,6 @@ export const platformServiceFactory: CanvaPlatformServiceFactory = ({
getSavedObjects: () => coreStart.savedObjects,
getSavedObjectsClient: () => coreStart.savedObjects.client,
getUISettings: () => coreStart.uiSettings,
getHttp: () => coreStart.http,
};
};

View file

@ -13,6 +13,7 @@ import {
ChromeBreadcrumb,
IBasePath,
ChromeStart,
HttpStart,
} from '@kbn/core/public';
import { SpacesPluginStart } from '@kbn/spaces-plugin/public';
@ -37,4 +38,5 @@ export interface CanvasPlatformService {
getSavedObjects: () => SavedObjectsStart;
getSavedObjectsClient: () => SavedObjectsClientContract;
getUISettings: () => IUiSettingsClient;
getHttp: () => HttpStart;
}

View file

@ -36,4 +36,5 @@ export const platformServiceFactory: CanvasPlatformServiceFactory = () => ({
setFullscreen: noop,
redirectLegacyUrl: noop,
getLegacyUrlConflict: undefined,
getHttp: noop,
});

View file

@ -77,7 +77,7 @@ function GuidancePanelComponent(props: GuidancePanelProps) {
const kibana = useKibana<IUnifiedSearchPluginServices>();
const { services, overlays } = kibana;
const { savedObjects, uiSettings, application, data } = services;
const { http, uiSettings, application, data } = services;
const [hasDataViews, setHasDataViews] = useState<boolean>(true);
useEffect(() => {
@ -90,7 +90,7 @@ function GuidancePanelComponent(props: GuidancePanelProps) {
if (!overlays || !application) return null;
const onOpenDatasourcePicker = () => {
openSourceModal({ overlays, savedObjects, uiSettings }, onIndexPatternSelected);
openSourceModal({ overlays, http, uiSettings }, onIndexPatternSelected);
};
let content = (

View file

@ -98,7 +98,6 @@ export function SearchBarComponent(props: SearchBarStateProps & SearchBarProps)
const kibana = useKibana<IUnifiedSearchPluginServices>();
const { services, overlays } = kibana;
const {
savedObjects,
uiSettings,
appName,
unifiedSearch,
@ -132,8 +131,7 @@ export function SearchBarComponent(props: SearchBarStateProps & SearchBarProps)
data-test-subj="graphDatasourceButton"
onClick={() => {
confirmWipeWorkspace(
() =>
openSourceModal({ overlays, savedObjects, uiSettings }, onIndexPatternSelected),
() => openSourceModal({ overlays, http, uiSettings }, onIndexPatternSelected),
i18n.translate('xpack.graph.clearWorkspace.confirmText', {
defaultMessage:
'If you change data sources, your current fields and vertices will be reset.',

View file

@ -14,20 +14,16 @@ import { IndexPatternSavedObject } from '../types';
export interface SourcePickerProps {
onIndexPatternSelected: (indexPattern: IndexPatternSavedObject) => void;
savedObjects: CoreStart['savedObjects'];
http: CoreStart['http'];
uiSettings: CoreStart['uiSettings'];
}
const fixedPageSize = 8;
export function SourcePicker({
savedObjects,
uiSettings,
onIndexPatternSelected,
}: SourcePickerProps) {
export function SourcePicker({ http, uiSettings, onIndexPatternSelected }: SourcePickerProps) {
return (
<SavedObjectFinderUi
savedObjects={savedObjects}
http={http}
uiSettings={uiSettings}
onChoose={(_id, _type, _name, indexPattern) => {
onIndexPatternSelected(indexPattern as IndexPatternSavedObject);

View file

@ -14,11 +14,11 @@ import { IndexPatternSavedObject } from '../types';
export function openSourceModal(
{
overlays,
savedObjects,
http,
uiSettings,
}: {
overlays: KibanaReactOverlays;
savedObjects: CoreStart['savedObjects'];
http: CoreStart['http'];
uiSettings: CoreStart['uiSettings'];
},
onSelected: (indexPattern: IndexPatternSavedObject) => void
@ -26,7 +26,7 @@ export function openSourceModal(
const modalRef = overlays.openModal(
<SourceModal
uiSettings={uiSettings}
savedObjects={savedObjects}
http={http}
onIndexPatternSelected={(indexPattern) => {
onSelected(indexPattern);
modalRef.close();

View file

@ -71,8 +71,8 @@ const mockNavigateToPath = jest.fn();
jest.mock('../../../../../contexts/kibana', () => ({
useMlKibana: () => ({
services: {
savedObjects: {},
uiSettings: {},
http: {},
},
}),
useNavigateToPath: () => mockNavigateToPath,

View file

@ -14,11 +14,11 @@ import {
EuiPageContent_Deprecated as EuiPageContent,
} from '@elastic/eui';
import type { SimpleSavedObject } from '@kbn/core/public';
import { i18n } from '@kbn/i18n';
import { getNestedProperty } from '@kbn/ml-nested-property';
import { SavedObjectFinderUi } from '@kbn/saved-objects-plugin/public';
import { SavedObjectCommon } from '@kbn/saved-objects-plugin/common';
import { useMlKibana, useNavigateToPath } from '../../../../../contexts/kibana';
import { useToastNotificationService } from '../../../../../services/toast_notification_service';
import { getDataViewAndSavedSearch, isCcsIndexPattern } from '../../../../../util/index_utils';
@ -27,7 +27,7 @@ const fixedPageSize: number = 20;
export const SourceSelection: FC = () => {
const {
services: { savedObjects, uiSettings },
services: { http, uiSettings },
} = useMlKibana();
const navigateToPath = useNavigateToPath();
@ -39,7 +39,7 @@ export const SourceSelection: FC = () => {
id: string,
type: string,
fullName: string,
savedObject: SimpleSavedObject
savedObject: SavedObjectCommon
) => {
// Kibana data views including `:` are cross-cluster search indices
// and are not supported by Data Frame Analytics yet. For saved searches
@ -152,7 +152,7 @@ export const SourceSelection: FC = () => {
]}
fixedPageSize={fixedPageSize}
uiSettings={uiSettings}
savedObjects={savedObjects}
http={http}
/>
</EuiPageContent>
</EuiPageBody>

View file

@ -54,7 +54,7 @@ interface Props {
export const ChangeDataViewModal: FC<Props> = ({ onClose }) => {
const {
services: {
savedObjects,
http,
uiSettings,
data: { dataViews },
},
@ -171,7 +171,7 @@ export const ChangeDataViewModal: FC<Props> = ({ onClose }) => {
]}
fixedPageSize={fixedPageSize}
uiSettings={uiSettings}
savedObjects={savedObjects}
http={http}
/>
</>
)}

View file

@ -19,7 +19,7 @@ export interface PageProps {
export const Page: FC<PageProps> = ({ nextStepPath }) => {
const RESULTS_PER_PAGE = 20;
const { uiSettings, savedObjects } = useMlKibana().services;
const { uiSettings, http } = useMlKibana().services;
const navigateToPath = useNavigateToPath();
const onObjectSelection = (id: string, type: string) => {
@ -72,7 +72,7 @@ export const Page: FC<PageProps> = ({ nextStepPath }) => {
]}
fixedPageSize={RESULTS_PER_PAGE}
uiSettings={uiSettings}
savedObjects={savedObjects}
http={http}
/>
</EuiPageContent>
</EuiPageBody>

View file

@ -19,7 +19,7 @@ interface SearchSelectionProps {
const fixedPageSize: number = 8;
export const SearchSelection: FC<SearchSelectionProps> = ({ onSearchSelected }) => {
const { uiSettings, savedObjects } = useAppDependencies();
const { uiSettings, http } = useAppDependencies();
return (
<>
@ -72,7 +72,7 @@ export const SearchSelection: FC<SearchSelectionProps> = ({ onSearchSelected })
]}
fixedPageSize={fixedPageSize}
uiSettings={uiSettings}
savedObjects={savedObjects}
http={http}
/>
</EuiModalBody>
</>