From 139b14c6dd45a641e9f8d24614ba2cb76efb9c3e Mon Sep 17 00:00:00 2001 From: Davis McPhee Date: Thu, 6 Jun 2024 22:27:45 -0300 Subject: [PATCH 1/2] Make _index and _id optional in EsHitRecord to support ES|QL records --- .../src/search/tabify/tabify_docs.ts | 6 ++++-- packages/kbn-discover-utils/src/types.ts | 8 ++++++-- .../kbn-discover-utils/src/utils/format_hit.ts | 10 +++++++--- .../kbn-discover-utils/src/utils/format_value.ts | 4 ++-- .../application/context/services/context.ts | 2 +- .../application/main/data_fetching/fetch_esql.ts | 4 ++-- .../doc_table/components/table_row_details.tsx | 4 ++-- .../public/hooks/use_navigation_props.tsx | 16 +++++++++++----- .../components/doc_viewer_source/source.tsx | 2 +- .../public/hooks/use_es_doc_search.ts | 6 +++++- 10 files changed, 41 insertions(+), 21 deletions(-) diff --git a/packages/kbn-data-service/src/search/tabify/tabify_docs.ts b/packages/kbn-data-service/src/search/tabify/tabify_docs.ts index 2a0aa91fe01f..ceb60b7492d9 100644 --- a/packages/kbn-data-service/src/search/tabify/tabify_docs.ts +++ b/packages/kbn-data-service/src/search/tabify/tabify_docs.ts @@ -36,7 +36,9 @@ interface TabifyDocsOptions { // This is an overwrite of the SearchHit type to add the ignored_field_values. // Can be removed once the estypes.SearchHit knows about ignored_field_values -type Hit = estypes.SearchHit & { ignored_field_values?: Record }; +type Hit = Partial> & { + ignored_field_values?: Record; +}; function flattenAccum( flat: Record, @@ -137,7 +139,7 @@ export function flattenHit(hit: Hit, indexPattern?: DataView, params?: TabifyDoc const isExcludedMetaField = EXCLUDED_META_FIELDS.includes(fieldName) || fieldName.charAt(0) !== '_'; if (!isExcludedMetaField) { - flat[fieldName] = hit[fieldName as keyof estypes.SearchHit]; + flat[fieldName] = hit[fieldName as keyof Hit]; } } } diff --git a/packages/kbn-discover-utils/src/types.ts b/packages/kbn-discover-utils/src/types.ts index 05d9a79b0bbb..b7bc205dd390 100644 --- a/packages/kbn-discover-utils/src/types.ts +++ b/packages/kbn-discover-utils/src/types.ts @@ -10,8 +10,12 @@ import type { SearchHit } from '@elastic/elasticsearch/lib/api/typesWithBodyKey' export type { IgnoredReason, ShouldShowFieldInTableHandler } from './utils'; -export interface EsHitRecord extends Omit { - _source?: Record; +type DiscoverSearchHit = SearchHit>; + +export interface EsHitRecord extends Omit { + _index?: DiscoverSearchHit['_index']; + _id?: DiscoverSearchHit['_id']; + _source?: DiscoverSearchHit['_source']; } /** diff --git a/packages/kbn-discover-utils/src/utils/format_hit.ts b/packages/kbn-discover-utils/src/utils/format_hit.ts index 824c56c71c4c..c0b255d2091c 100644 --- a/packages/kbn-discover-utils/src/utils/format_hit.ts +++ b/packages/kbn-discover-utils/src/utils/format_hit.ts @@ -6,15 +6,19 @@ * Side Public License, v 1. */ -import type { SearchHit } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { i18n } from '@kbn/i18n'; import type { FieldFormatsStart } from '@kbn/field-formats-plugin/public'; import type { DataView } from '@kbn/data-views-plugin/public'; -import type { DataTableRecord, ShouldShowFieldInTableHandler, FormattedHit } from '../types'; +import type { + DataTableRecord, + ShouldShowFieldInTableHandler, + FormattedHit, + EsHitRecord, +} from '../types'; import { formatFieldValue } from './format_value'; const formattedHitCache = new WeakMap< - SearchHit, + EsHitRecord, { formattedHit: FormattedHit; maxEntries: number } >(); diff --git a/packages/kbn-discover-utils/src/utils/format_value.ts b/packages/kbn-discover-utils/src/utils/format_value.ts index 4ee9bd32bcf0..7e7a4bb58b9b 100644 --- a/packages/kbn-discover-utils/src/utils/format_value.ts +++ b/packages/kbn-discover-utils/src/utils/format_value.ts @@ -6,7 +6,6 @@ * Side Public License, v 1. */ -import type { SearchHit } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { FieldFormatsStart } from '@kbn/field-formats-plugin/public'; import { KBN_FIELD_TYPES } from '@kbn/field-types'; import type { DataView, DataViewField } from '@kbn/data-views-plugin/public'; @@ -15,6 +14,7 @@ import type { HtmlContextTypeOptions, TextContextTypeOptions, } from '@kbn/field-formats-plugin/common/types'; +import { EsHitRecord } from '../types'; /** * Formats the value of a specific field using the appropriate field formatter if available @@ -31,7 +31,7 @@ import type { */ export function formatFieldValue( value: unknown, - hit: SearchHit, + hit: EsHitRecord, fieldFormats: FieldFormatsStart, dataView?: DataView, field?: DataViewField, diff --git a/src/plugins/discover/public/application/context/services/context.ts b/src/plugins/discover/public/application/context/services/context.ts index d7dc9978ab6d..a4df96fe0bdb 100644 --- a/src/plugins/discover/public/application/context/services/context.ts +++ b/src/plugins/discover/public/application/context/services/context.ts @@ -58,7 +58,7 @@ export async function fetchSurroundingDocs( rows: DataTableRecord[]; interceptedWarnings: SearchResponseWarning[] | undefined; }> { - if (typeof anchor !== 'object' || anchor === null || !size) { + if (typeof anchor !== 'object' || anchor === null || !anchor.raw._id || !size) { return { rows: [], interceptedWarnings: undefined, diff --git a/src/plugins/discover/public/application/main/data_fetching/fetch_esql.ts b/src/plugins/discover/public/application/main/data_fetching/fetch_esql.ts index 3f54984ae3d3..481e5c418d87 100644 --- a/src/plugins/discover/public/application/main/data_fetching/fetch_esql.ts +++ b/src/plugins/discover/public/application/main/data_fetching/fetch_esql.ts @@ -15,7 +15,7 @@ import type { ExpressionsStart } from '@kbn/expressions-plugin/public'; import type { Datatable } from '@kbn/expressions-plugin/public'; import type { DataView } from '@kbn/data-views-plugin/common'; import { textBasedQueryStateToAstWithValidation } from '@kbn/data-plugin/common'; -import type { DataTableRecord, EsHitRecord } from '@kbn/discover-utils'; +import type { DataTableRecord } from '@kbn/discover-utils'; import type { RecordsFetchResponse } from '../../types'; import type { ProfilesManager } from '../../../context_awareness'; @@ -84,7 +84,7 @@ export function fetchEsql({ finalData = rows.map((row, idx) => { const record: DataTableRecord = { id: String(idx), - raw: row as EsHitRecord, + raw: row, flattened: row, }; diff --git a/src/plugins/discover/public/components/doc_table/components/table_row_details.tsx b/src/plugins/discover/public/components/doc_table/components/table_row_details.tsx index cd203091e30f..313b9e12090a 100644 --- a/src/plugins/discover/public/components/doc_table/components/table_row_details.tsx +++ b/src/plugins/discover/public/components/doc_table/components/table_row_details.tsx @@ -16,8 +16,8 @@ import { useNavigationProps } from '../../../hooks/use_navigation_props'; interface TableRowDetailsProps { children: JSX.Element; colLength: number; - rowIndex: string; - rowId: string; + rowIndex: string | undefined; + rowId: string | undefined; columns: string[]; isTimeBased: boolean; dataView: DataView; diff --git a/src/plugins/discover/public/hooks/use_navigation_props.tsx b/src/plugins/discover/public/hooks/use_navigation_props.tsx index eab1bfb2937c..b02612a69592 100644 --- a/src/plugins/discover/public/hooks/use_navigation_props.tsx +++ b/src/plugins/discover/public/hooks/use_navigation_props.tsx @@ -15,8 +15,8 @@ import { useDiscoverServices } from './use_discover_services'; export interface UseNavigationProps { dataView: DataView; - rowIndex: string; - rowId: string; + rowIndex: string | undefined; + rowId: string | undefined; columns: string[]; savedSearchId?: string; // provided by embeddable only @@ -95,6 +95,9 @@ export const useNavigationProps = ({ ); useEffect(() => { + if (!rowIndex || !rowId) { + return; + } const dataViewId = typeof index === 'object' ? index.id : index; services.locator .getUrl({ dataViewId, ...buildParams() }) @@ -113,6 +116,9 @@ export const useNavigationProps = ({ ]); useEffect(() => { + if (!rowIndex || !rowId) { + return; + } const params = buildParams(); const dataViewId = typeof index === 'object' ? index.id : index; services.locator @@ -139,7 +145,7 @@ export const useNavigationProps = ({ const onOpenSingleDoc: MouseEventHandler = useCallback( (event) => { - if (isModifiedEvent(event)) { + if (isModifiedEvent(event) || !rowIndex || !rowId) { return; } event.preventDefault(); @@ -155,11 +161,11 @@ export const useNavigationProps = ({ const onOpenContextView: MouseEventHandler = useCallback( (event) => { - const params = buildParams(); - if (isModifiedEvent(event)) { + if (isModifiedEvent(event) || !rowId) { return; } event.preventDefault(); + const params = buildParams(); const dataViewId = typeof index === 'object' ? index.id : index; services.locator.getUrl({ dataViewId, ...params }).then((referrer) => services.contextLocator.navigate({ diff --git a/src/plugins/unified_doc_viewer/public/components/doc_viewer_source/source.tsx b/src/plugins/unified_doc_viewer/public/components/doc_viewer_source/source.tsx index 5596ca067df5..430da5e15f1a 100644 --- a/src/plugins/unified_doc_viewer/public/components/doc_viewer_source/source.tsx +++ b/src/plugins/unified_doc_viewer/public/components/doc_viewer_source/source.tsx @@ -23,7 +23,7 @@ import { JSONCodeEditorCommonMemoized } from '../json_code_editor'; interface SourceViewerProps { id: string; - index: string; + index: string | undefined; dataView: DataView; textBasedHits?: DataTableRecord[]; hasLineNumbers: boolean; diff --git a/src/plugins/unified_doc_viewer/public/hooks/use_es_doc_search.ts b/src/plugins/unified_doc_viewer/public/hooks/use_es_doc_search.ts index 1814a34e37e9..57c816a2c801 100644 --- a/src/plugins/unified_doc_viewer/public/hooks/use_es_doc_search.ts +++ b/src/plugins/unified_doc_viewer/public/hooks/use_es_doc_search.ts @@ -26,7 +26,7 @@ export interface EsDocSearchProps { /** * Index in ES to query */ - index: string; + index: string | undefined; /** * DataView entity */ @@ -57,6 +57,10 @@ export function useEsDocSearch({ const useNewFieldsApi = useMemo(() => !uiSettings.get(SEARCH_FIELDS_FROM_SOURCE), [uiSettings]); const requestData = useCallback(async () => { + if (!index) { + return; + } + const singleDocFetchingStartTime = window.performance.now(); try { const result = await lastValueFrom( From 1f22e671c5717d1eb3c9a8b1029f6375e412ace6 Mon Sep 17 00:00:00 2001 From: Davis McPhee Date: Fri, 7 Jun 2024 20:32:26 -0300 Subject: [PATCH 2/2] Fix context.predecessors.test.ts tests --- .../application/context/services/context.predecessors.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/discover/public/application/context/services/context.predecessors.test.ts b/src/plugins/discover/public/application/context/services/context.predecessors.test.ts index 451c38e87399..e60fdb356371 100644 --- a/src/plugins/discover/public/application/context/services/context.predecessors.test.ts +++ b/src/plugins/discover/public/application/context/services/context.predecessors.test.ts @@ -66,6 +66,7 @@ describe('context predecessors', function () { fetchPredecessors = (timeValIso, timeValNr, tieBreakerField, tieBreakerValue, size = 10) => { const anchor = buildDataTableRecord( { + _id: 'test', _source: { [dataView.timeFieldName!]: timeValIso, }, @@ -220,6 +221,7 @@ describe('context predecessors', function () { fetchPredecessors = (timeValIso, timeValNr, tieBreakerField, tieBreakerValue, size = 10) => { const anchor = buildDataTableRecord( { + _id: 'test', _source: { [dataView.timeFieldName!]: timeValIso, },