[Dashboard] Remove mSearch from content management (#210709)

## Summary

Removes the mSearch method from Dashboard content management.

The `mSearch` content management method was designed to be a temporary
implementation of search that allowed searching multiple saved object
types ([see more
[internal]](https://docs.google.com/document/d/1ssYmqSEUPrsuCR4iz8DohkEWekoYrm2yL4QR_fVxXLg/edit?tab=t.0#heading=h.6sj4n6bjcgp5)).
However, the mSearch implementation in the Dashboard Storage class lacks
extensibility as it requires a synchronous `toItemResult` function. As
we start migrating reference handling to the server, we will likely need
transforms that return Promises (ex. `savedObjectToItem`), such as
[retrieving tag saved objects from the SavedObjectTagging
client](https://github.com/elastic/kibana/issues/210619).

The Dashboard `mSearch` method was only used by the dashboard_picker and
this PR replaces its usage with the `search` method.

### Identify risks

There is a slight risk in serverless environments where a browser may
have already loaded the dashboard_picker module but lags behind the
server. In this case, the dashboard picker may fail to retrieve a list
of dashboards due to it calling the now non-existent `mSearch` method
provided by the server. In this case, the user simply needs to refresh
their browser to retrieve the latest UI modules.
This commit is contained in:
Nick Peihl 2025-03-03 11:31:09 -05:00 committed by GitHub
parent 3fc5022e13
commit 2a7e38b0fc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 7 additions and 54 deletions

View file

@ -35,7 +35,6 @@ export const MSearchTable = () => {
},
contentTypes: [
{ contentTypeId: 'map' },
{ contentTypeId: 'dashboard' },
{ contentTypeId: 'visualization' },
{ contentTypeId: 'lens' },
{ contentTypeId: 'search' },

View file

@ -9,10 +9,7 @@
import Boom from '@hapi/boom';
import { tagsToFindOptions } from '@kbn/content-management-utils';
import {
SavedObjectsFindOptions,
SavedObjectsFindResult,
} from '@kbn/core-saved-objects-api-server';
import { SavedObjectsFindOptions } from '@kbn/core-saved-objects-api-server';
import type { Logger } from '@kbn/logging';
import { CreateResult, DeleteResult, SearchQuery } from '@kbn/content-management-plugin/common';
@ -69,57 +66,11 @@ export class DashboardStorage {
}) {
this.logger = logger;
this.throwOnResultValidationError = throwOnResultValidationError ?? false;
this.mSearch = {
savedObjectType: DASHBOARD_SAVED_OBJECT_TYPE,
additionalSearchFields: [],
toItemResult: (ctx: StorageContext, savedObject: SavedObjectsFindResult): DashboardItem => {
const transforms = ctx.utils.getTransforms(cmServicesDefinition);
const { item, error: itemError } = savedObjectToItem(
savedObject as SavedObjectsFindResult<DashboardSavedObjectAttributes>,
false
);
if (itemError) {
throw Boom.badRequest(`Invalid response. ${itemError.message}`);
}
const validationError = transforms.mSearch.out.result.validate(item);
if (validationError) {
if (this.throwOnResultValidationError) {
throw Boom.badRequest(`Invalid response. ${validationError.message}`);
} else {
this.logger.warn(`Invalid response. ${validationError.message}`);
}
}
// Validate DB response and DOWN transform to the request version
const { value, error: resultError } = transforms.mSearch.out.result.down<
DashboardItem,
DashboardItem
>(
item,
undefined, // do not override version
{ validate: false } // validation is done above
);
if (resultError) {
throw Boom.badRequest(`Invalid response. ${resultError.message}`);
}
return value;
},
};
}
private logger: Logger;
private throwOnResultValidationError: boolean;
mSearch: {
savedObjectType: string;
toItemResult: (ctx: StorageContext, savedObject: SavedObjectsFindResult) => DashboardItem;
additionalSearchFields?: string[];
};
async get(ctx: StorageContext, id: string): Promise<DashboardGetOut> {
const transforms = ctx.utils.getTransforms(cmServicesDefinition);
const soClient = await savedObjectClientFromRequest(ctx);

View file

@ -23,6 +23,7 @@ import {
import { i18n } from '@kbn/i18n';
import { ToolbarButton } from '@kbn/shared-ux-button-toolbar';
import { SavedObjectCommon } from '@kbn/saved-objects-finder-plugin/common';
import type { SearchIn, SearchResult } from '@kbn/content-management-plugin/common';
import { contentManagementService } from '../../services/kibana_services';
@ -73,8 +74,11 @@ export function DashboardPicker({ isDisabled, onChange, idsToOmit }: DashboardPi
(async () => {
setIsLoading(true);
const response = await contentManagementService.client.mSearch<DashboardHit>({
contentTypes: [{ contentTypeId: 'dashboard' }],
const response = await contentManagementService.client.search<
SearchIn<'dashboard'>,
SearchResult<DashboardHit>
>({
contentTypeId: 'dashboard',
query: {
text: debouncedQuery ? `${debouncedQuery}*` : undefined,
limit: 30,

View file

@ -43,7 +43,6 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide
`kibana_sample_data_flights`,
`[Flights] Airport Connections (Hover Over Airport)`,
`[Flights] Departures Count Map`,
`[Flights] Global Flight Dashboard`,
`[Flights] Origin Time Delayed`,
`[Flights] Flight Log`,
];