[Discover] Support "Inspect" in saved search embeddables (#202947)

- Closes https://github.com/elastic/kibana/issues/202301

## Summary

This PR enables "Inspect" option for saved search Dashboard panels.

<img width="1619" alt="Screenshot 2024-12-04 at 16 02 33"
src="https://github.com/user-attachments/assets/a1eab597-4683-4069-b48f-b33b977db578">
<img width="1620" alt="Screenshot 2024-12-04 at 16 02 43"
src="https://github.com/user-attachments/assets/0dc734c3-f930-4397-9b68-69d959400924">
<img width="1618" alt="Screenshot 2024-12-04 at 16 03 03"
src="https://github.com/user-attachments/assets/460d8432-dc14-480e-b49d-81ab743815d2">



### Checklist

- [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
- [x] The PR description includes the appropriate Release Notes section,
and the correct `release_note:*` label is applied per the
[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
This commit is contained in:
Julia Rechkunova 2024-12-05 13:04:01 +01:00 committed by GitHub
parent 58f51fdac7
commit 3f0008ab5d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 20 additions and 13 deletions

View file

@ -8,7 +8,7 @@
*/
import { BehaviorSubject } from 'rxjs';
import type { Adapters } from '@kbn/inspector-plugin/common';
import { SearchSource } from '@kbn/data-plugin/common';
import type { DataView } from '@kbn/data-views-plugin/common';
import { DataTableRecord } from '@kbn/discover-utils';
@ -58,6 +58,7 @@ export const getMockedSearchApi = ({
rows: new BehaviorSubject<DataTableRecord[]>([]),
totalHitCount: new BehaviorSubject<number | undefined>(0),
columnsMeta: new BehaviorSubject<Record<string, DatatableColumnMeta> | undefined>(undefined),
inspectorAdapters: new BehaviorSubject<Adapters>({}),
},
};
};

View file

@ -196,6 +196,7 @@ export const getSearchEmbeddableFactory = ({
savedObjectId: savedObjectId$.getValue(),
discoverServices,
}),
getInspectorAdapters: () => searchEmbeddable.stateManager.inspectorAdapters.getValue(),
},
{
...titleComparators,

View file

@ -69,6 +69,7 @@ describe('initialize fetch', () => {
].map((hit) => buildDataTableRecord(hit, dataViewMock))
);
expect(stateManager.totalHitCount.getValue()).toEqual(2);
expect(stateManager.inspectorAdapters.getValue().requests).toBeDefined();
});
it('should catch and emit error', async () => {

View file

@ -90,7 +90,7 @@ export function initializeFetch({
stateManager: SearchEmbeddableStateManager;
discoverServices: DiscoverServices;
}) {
const requestAdapter = new RequestAdapter();
const inspectorAdapters = { requests: new RequestAdapter() };
let abortController: AbortController | undefined;
const fetchSubscription = combineLatest([fetch$(api), api.savedSearch$, api.dataViews])
@ -127,7 +127,7 @@ export function initializeFetch({
const searchSourceQuery = savedSearch.searchSource.getField('query');
// Log request to inspector
requestAdapter.reset();
inspectorAdapters.requests.reset();
try {
api.dataLoading.next(true);
@ -156,7 +156,7 @@ export function initializeFetch({
filters: fetchContext.filters,
dataView,
abortSignal: currentAbortController.signal,
inspectorAdapters: discoverServices.inspector,
inspectorAdapters,
data: discoverServices.data,
expressions: discoverServices.expressions,
profilesManager: discoverServices.profilesManager,
@ -181,9 +181,9 @@ export function initializeFetch({
abortSignal: currentAbortController.signal,
sessionId: searchSessionId,
inspector: {
adapter: requestAdapter,
title: i18n.translate('discover.embeddable.inspectorRequestDataTitle', {
defaultMessage: 'Data',
adapter: inspectorAdapters.requests,
title: i18n.translate('discover.embeddable.inspectorTableRequestTitle', {
defaultMessage: 'Table',
}),
description: i18n.translate('discover.embeddable.inspectorRequestDescription', {
defaultMessage:
@ -195,7 +195,7 @@ export function initializeFetch({
})
);
const interceptedWarnings: SearchResponseWarning[] = [];
discoverServices.data.search.showWarnings(requestAdapter, (warning) => {
discoverServices.data.search.showWarnings(inspectorAdapters.requests, (warning) => {
interceptedWarnings.push(warning);
return true; // suppress the default behaviour
});
@ -225,6 +225,8 @@ export function initializeFetch({
stateManager.rows.next(next.rows ?? []);
stateManager.totalHitCount.next(next.hitCount);
stateManager.inspectorAdapters.next(inspectorAdapters);
api.fetchWarnings$.next(next.warnings ?? []);
api.fetchContext$.next(next.fetchContext);
if (Object.hasOwn(next, 'columnsMeta')) {

View file

@ -10,7 +10,7 @@
import { pick } from 'lodash';
import deepEqual from 'react-fast-compare';
import { BehaviorSubject, combineLatest, map, Observable, skip } from 'rxjs';
import type { Adapters } from '@kbn/inspector-plugin/common';
import { ISearchSource, SerializedSearchSourceFields } from '@kbn/data-plugin/common';
import { DataView } from '@kbn/data-views-plugin/common';
import { DataTableRecord } from '@kbn/discover-utils/types';
@ -116,6 +116,7 @@ export const initializeSearchEmbeddableApi = async (
const rows$ = new BehaviorSubject<DataTableRecord[]>([]);
const columnsMeta$ = new BehaviorSubject<DataTableColumnsMeta | undefined>(undefined);
const totalHitCount$ = new BehaviorSubject<number | undefined>(undefined);
const inspectorAdapters$ = new BehaviorSubject<Adapters>({});
/**
* The state manager is used to modify the state of the saved search - this should never be
@ -134,6 +135,7 @@ export const initializeSearchEmbeddableApi = async (
totalHitCount: totalHitCount$,
viewMode: savedSearchViewMode$,
density: density$,
inspectorAdapters: inspectorAdapters$,
};
/** The saved search should be the source of truth for all state */

View file

@ -9,6 +9,7 @@
import { DataTableRecord } from '@kbn/discover-utils/types';
import type { DefaultEmbeddableApi } from '@kbn/embeddable-plugin/public';
import { HasInspectorAdapters } from '@kbn/inspector-plugin/public';
import {
EmbeddableApiContext,
HasEditCapabilities,
@ -47,6 +48,7 @@ export type SearchEmbeddableState = Pick<
rows: DataTableRecord[];
columnsMeta: DataTableColumnsMeta | undefined;
totalHitCount: number | undefined;
inspectorAdapters: Record<string, unknown>;
};
export type SearchEmbeddableStateManager = {
@ -55,7 +57,7 @@ export type SearchEmbeddableStateManager = {
export type SearchEmbeddableSerializedAttributes = Omit<
SearchEmbeddableState,
'rows' | 'columnsMeta' | 'totalHitCount' | 'searchSource'
'rows' | 'columnsMeta' | 'totalHitCount' | 'searchSource' | 'inspectorAdapters'
> &
Pick<SerializableSavedSearch, 'serializedSearchSource'>;
@ -98,6 +100,7 @@ export type SearchEmbeddableApi = DefaultEmbeddableApi<
PublishesWritableUnifiedSearch &
HasInPlaceLibraryTransforms &
HasTimeRange &
HasInspectorAdapters &
Partial<HasEditCapabilities & PublishesSavedObjectId>;
export interface PublishesSavedSearch {

View file

@ -2600,7 +2600,6 @@
"discover.documentsAriaLabel": "Documents",
"discover.docViews.logsOverview.title": "Aperçu du log",
"discover.dropZoneTableLabel": "Abandonner la zone pour ajouter un champ en tant que colonne dans la table",
"discover.embeddable.inspectorRequestDataTitle": "Données",
"discover.embeddable.inspectorRequestDescription": "Cette requête interroge Elasticsearch afin de récupérer les données pour la recherche.",
"discover.embeddable.search.dataViewError": "Vue de données {indexPatternId} manquante",
"discover.embeddable.search.displayName": "rechercher",

View file

@ -2599,7 +2599,6 @@
"discover.documentsAriaLabel": "ドキュメント",
"discover.docViews.logsOverview.title": "ログ概要",
"discover.dropZoneTableLabel": "フィールドを列として表に追加するには、ゾーンをドロップします",
"discover.embeddable.inspectorRequestDataTitle": "データ",
"discover.embeddable.inspectorRequestDescription": "このリクエストはElasticsearchにクエリーをかけ、検索データを取得します。",
"discover.embeddable.search.dataViewError": "データビュー{indexPatternId}が見つかりません",
"discover.embeddable.search.displayName": "検索",

View file

@ -2590,7 +2590,6 @@
"discover.documentsAriaLabel": "文档",
"discover.docViews.logsOverview.title": "日志概览",
"discover.dropZoneTableLabel": "放置区域以将字段作为列添加到表中",
"discover.embeddable.inspectorRequestDataTitle": "数据",
"discover.embeddable.inspectorRequestDescription": "此请求将查询 Elasticsearch 以获取搜索的数据。",
"discover.embeddable.search.dataViewError": "缺少数据视图 {indexPatternId}",
"discover.embeddable.search.displayName": "搜索",