[CM] Onboard maps to cross-type search (#155148)

## Summary

Part of https://github.com/elastic/kibana/issues/152224
Follow up to https://github.com/elastic/kibana/issues/153256

This PR onboards maps CM integration into the multi-type search
(`msearch`). It isn't actually used anywhere in the user-facing UI yet,
as first other types need to be migrated to CM.

This PR also adds an example app to test the `msearch` end-to-end.
This commit is contained in:
Anton Dosov 2023-04-21 16:41:08 +02:00 committed by GitHub
parent cfc01d5444
commit 6aa1491c9e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 316 additions and 23 deletions

View file

@ -9,7 +9,9 @@
"browser": true,
"requiredPlugins": [
"contentManagement",
"developerExamples"
"developerExamples",
"kibanaReact",
"savedObjectsTaggingOss"
]
}
}

View file

@ -8,22 +8,67 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { EuiPageTemplate } from '@elastic/eui';
// eslint-disable-next-line no-restricted-imports
import { Router, Switch, Route, Redirect } from 'react-router-dom';
import { RedirectAppLinks } from '@kbn/shared-ux-link-redirect-app';
import { EuiPageTemplate, EuiSideNav } from '@elastic/eui';
import { AppMountParameters, CoreStart } from '@kbn/core/public';
import { StartDeps } from '../types';
import { TodoApp } from './todos';
import { MSearchApp } from './msearch';
export const renderApp = (
{ notifications }: CoreStart,
{ contentManagement }: StartDeps,
{ element }: AppMountParameters
core: CoreStart,
{ contentManagement, savedObjectsTaggingOss }: StartDeps,
{ element, history }: AppMountParameters
) => {
ReactDOM.render(
<EuiPageTemplate offset={0}>
<EuiPageTemplate.Section>
<TodoApp contentClient={contentManagement.client} />
</EuiPageTemplate.Section>
</EuiPageTemplate>,
<Router history={history}>
<RedirectAppLinks coreStart={core}>
<EuiPageTemplate offset={0}>
<EuiPageTemplate.Sidebar>
<EuiSideNav
items={[
{
id: 'Examples',
name: 'Examples',
items: [
{
id: 'todos',
name: 'Todo app',
'data-test-subj': 'todosExample',
href: '/app/contentManagementExamples/todos',
},
{
id: 'msearch',
name: 'MSearch',
'data-test-subj': 'msearchExample',
href: '/app/contentManagementExamples/msearch',
},
],
},
]}
/>
</EuiPageTemplate.Sidebar>
<EuiPageTemplate.Section>
<Switch>
<Redirect from="/" to="/todos" exact />
<Route path="/todos">
<TodoApp contentClient={contentManagement.client} />
</Route>
<Route path="/msearch">
<MSearchApp
contentClient={contentManagement.client}
core={core}
savedObjectsTagging={savedObjectsTaggingOss}
/>
</Route>
</Switch>
</EuiPageTemplate.Section>
</EuiPageTemplate>
</RedirectAppLinks>
</Router>,
element
);

View file

@ -0,0 +1,9 @@
/*
* 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 { MSearchApp } from './msearch_app';

View file

@ -0,0 +1,42 @@
/*
* 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 React from 'react';
import { ContentClientProvider, type ContentClient } from '@kbn/content-management-plugin/public';
import { TableListViewKibanaProvider } from '@kbn/content-management-table-list';
import type { CoreStart } from '@kbn/core/public';
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
import { FormattedRelative, I18nProvider } from '@kbn/i18n-react';
import { SavedObjectTaggingOssPluginStart } from '@kbn/saved-objects-tagging-oss-plugin/public';
import { MSearchTable } from './msearch_table';
export const MSearchApp = (props: {
contentClient: ContentClient;
core: CoreStart;
savedObjectsTagging: SavedObjectTaggingOssPluginStart;
}) => {
return (
<ContentClientProvider contentClient={props.contentClient}>
<I18nProvider>
<TableListViewKibanaProvider
core={{
application: props.core.application,
notifications: props.core.notifications,
overlays: props.core.overlays,
http: props.core.http,
}}
toMountPoint={toMountPoint}
FormattedRelative={FormattedRelative}
savedObjectsTagging={props.savedObjectsTagging.getTaggingApi()}
>
<MSearchTable />
</TableListViewKibanaProvider>
</I18nProvider>
</ContentClientProvider>
);
};

View file

@ -0,0 +1,62 @@
/*
* 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 { TableListView, UserContentCommonSchema } from '@kbn/content-management-table-list';
import { useContentClient } from '@kbn/content-management-plugin/public';
import React from 'react';
import { SavedObjectsFindOptionsReference } from '@kbn/core-saved-objects-api-browser';
const LISTING_LIMIT = 1000;
export const MSearchTable = () => {
const contentClient = useContentClient();
const findItems = async (
searchQuery: string,
refs?: {
references?: SavedObjectsFindOptionsReference[];
referencesToExclude?: SavedObjectsFindOptionsReference[];
}
) => {
const { hits, pagination } = await contentClient.mSearch<UserContentCommonSchema>({
query: {
text: searchQuery,
limit: LISTING_LIMIT,
cursor: '1',
tags: {
included: refs?.references?.map((ref) => ref.id),
excluded: refs?.referencesToExclude?.map((ref) => ref.id),
},
},
contentTypes: [{ contentTypeId: 'map' }], // TODO: improve types to not require objects here?
});
// TODO: needs to have logic of extracting common schema from an unknown mSearch hit: hits.map(hit => cm.convertToCommonSchema(hit))
// for now we just assume that mSearch hit satisfies UserContentCommonSchema
return { hits, total: pagination.total };
};
return (
<TableListView
id="cm-msearch-table"
headingId="cm-msearch-table-heading"
findItems={findItems}
listingLimit={LISTING_LIMIT}
initialPageSize={50}
entityName={`ContentItem`}
entityNamePlural={`ContentItems`}
tableListTitle={`MSearch Demo`}
urlStateEnabled={false}
emptyPrompt={<>No data found. Try to install some sample data first.</>}
onClickTitle={(item) => {
alert(`Clicked item ${item.attributes.title} (${item.id})`);
}}
/>
);
};

View file

@ -11,6 +11,7 @@ import {
ContentManagementPublicStart,
} from '@kbn/content-management-plugin/public';
import { DeveloperExamplesSetup } from '@kbn/developer-examples-plugin/public';
import { SavedObjectTaggingOssPluginStart } from '@kbn/saved-objects-tagging-oss-plugin/public';
export interface SetupDeps {
contentManagement: ContentManagementPublicSetup;
@ -19,4 +20,5 @@ export interface SetupDeps {
export interface StartDeps {
contentManagement: ContentManagementPublicStart;
savedObjectsTaggingOss: SavedObjectTaggingOssPluginStart;
}

View file

@ -19,5 +19,11 @@
"@kbn/developer-examples-plugin",
"@kbn/content-management-plugin",
"@kbn/core-application-browser",
"@kbn/shared-ux-link-redirect-app",
"@kbn/content-management-table-list",
"@kbn/kibana-react-plugin",
"@kbn/i18n-react",
"@kbn/saved-objects-tagging-oss-plugin",
"@kbn/core-saved-objects-api-browser",
]
}