diff --git a/src/plugins/discover/public/components/discover_grid/get_render_cell_value.test.tsx b/src/plugins/discover/public/components/discover_grid/get_render_cell_value.test.tsx index 4479e051b1f264..07ed170258fb11 100644 --- a/src/plugins/discover/public/components/discover_grid/get_render_cell_value.test.tsx +++ b/src/plugins/discover/public/components/discover_grid/get_render_cell_value.test.tsx @@ -96,6 +96,50 @@ describe('Discover grid cell rendering', function () { expect(component.html()).toMatchInlineSnapshot(`"100"`); }); + it('renders bytes column correctly using _source when details is true', () => { + const DiscoverGridCellValue = getRenderCellValueFn( + indexPatternMock, + rowsSource, + rowsSource.map(flatten), + false, + [], + 100 + ); + const component = shallow( + + ); + expect(component.html()).toMatchInlineSnapshot(`"100"`); + }); + + it('renders bytes column correctly using fields when details is true', () => { + const DiscoverGridCellValue = getRenderCellValueFn( + indexPatternMock, + rowsFields, + rowsFields.map(flatten), + false, + [], + 100 + ); + const component = shallow( + + ); + expect(component.html()).toMatchInlineSnapshot(`"100"`); + }); + it('renders _source column correctly', () => { const DiscoverGridCellValue = getRenderCellValueFn( indexPatternMock, @@ -514,13 +558,16 @@ describe('Discover grid cell rendering', function () { /> ); expect(component).toMatchInlineSnapshot(` - - { - "object.value": [ - 100 - ] - } - + `); }); @@ -634,9 +681,15 @@ describe('Discover grid cell rendering', function () { /> ); expect(component).toMatchInlineSnapshot(` - - .gz - + `); const componentWithDetails = shallow( @@ -650,13 +703,14 @@ describe('Discover grid cell rendering', function () { /> ); expect(componentWithDetails).toMatchInlineSnapshot(` - `); }); diff --git a/src/plugins/discover/public/components/discover_grid/get_render_cell_value.tsx b/src/plugins/discover/public/components/discover_grid/get_render_cell_value.tsx index 436281b119bff4..5e1a1a7e39db87 100644 --- a/src/plugins/discover/public/components/discover_grid/get_render_cell_value.tsx +++ b/src/plugins/discover/public/components/discover_grid/get_render_cell_value.tsx @@ -8,8 +8,7 @@ import React, { Fragment, useContext, useEffect } from 'react'; import { euiLightVars as themeLight, euiDarkVars as themeDark } from '@kbn/ui-theme'; -import type { DataView } from 'src/plugins/data/common'; - +import type { DataView, DataViewField } from 'src/plugins/data/common'; import { EuiDataGridCellValueElementProps, EuiDescriptionList, @@ -64,89 +63,35 @@ export const getRenderCellValueFn = return -; } - if ( + /** + * when using the fields api this code is used to show top level objects + * this is used for legacy stuff like displaying products of our ecommerce dataset + */ + const useTopLevelObjectColumns = Boolean( useNewFieldsApi && - !field && - row && - row.fields && - !(row.fields as Record)[columnId] - ) { - const innerColumns = Object.fromEntries( - Object.entries(row.fields as Record).filter(([key]) => { - return key.indexOf(`${columnId}.`) === 0; - }) - ); - if (isDetails) { - // nicely formatted JSON for the expanded view - return {JSON.stringify(innerColumns, null, 2)}; - } - - // Put the most important fields first - const highlights: Record = (row.highlight as Record) ?? {}; - const highlightPairs: Array<[string, string]> = []; - const sourcePairs: Array<[string, string]> = []; - Object.entries(innerColumns).forEach(([key, values]) => { - const subField = indexPattern.getFieldByName(key); - const displayKey = indexPattern.fields.getByName - ? indexPattern.fields.getByName(key)?.displayName - : undefined; - const formatter = subField - ? indexPattern.getFormatterForField(subField) - : { convert: (v: unknown, ...rest: unknown[]) => String(v) }; - const formatted = (values as unknown[]) - .map((val: unknown) => - formatter.convert(val, 'html', { - field: subField, - hit: row, - indexPattern, - }) - ) - .join(', '); - const pairs = highlights[key] ? highlightPairs : sourcePairs; - if (displayKey) { - if (fieldsToShow.includes(displayKey)) { - pairs.push([displayKey, formatted]); - } - } else { - pairs.push([key, formatted]); - } - }); - - return ( - // If you change the styling of this list (specifically something that will change the line-height) - // make sure to adjust the img overwrites attached to dscDiscoverGrid__descriptionListDescription - // in discover_grid.scss - - {[...highlightPairs, ...sourcePairs] - .slice(0, maxDocFieldsDisplayed) - .map(([key, value]) => ( - - {key} - - - ))} - - ); - } + !field && + row?.fields && + !(row.fields as Record)[columnId] + ); - if (typeof rowFlattened[columnId] === 'object' && isDetails) { - return ( - } - width={defaultMonacoEditorWidth} - /> + if (isDetails) { + return renderPopoverContent( + row, + rowFlattened, + field, + columnId, + indexPattern, + useTopLevelObjectColumns ); } - if (field && field.type === '_source') { - if (isDetails) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - return ; - } - const pairs = formatHit(row, indexPattern, fieldsToShow); + if (field?.type === '_source' || useTopLevelObjectColumns) { + const pairs = useTopLevelObjectColumns + ? getTopLevelObjectPairs(row, columnId, indexPattern, fieldsToShow).slice( + 0, + maxDocFieldsDisplayed + ) + : formatHit(row, indexPattern, fieldsToShow); return ( @@ -163,20 +108,6 @@ export const getRenderCellValueFn = ); } - if (!field?.type && rowFlattened && typeof rowFlattened[columnId] === 'object') { - if (isDetails) { - // nicely formatted JSON for the expanded view - return ( - } - width={defaultMonacoEditorWidth} - /> - ); - } - - return <>{formatFieldValue(rowFlattened[columnId], row, indexPattern, field)}; - } - return ( ); }; + +/** + * Helper function to show top level objects + * this is used for legacy stuff like displaying products of our ecommerce dataset + */ +function getInnerColumns(fields: Record, columnId: string) { + return Object.fromEntries( + Object.entries(fields).filter(([key]) => { + return key.indexOf(`${columnId}.`) === 0; + }) + ); +} + +/** + * Helper function for the cell popover + */ +function renderPopoverContent( + rowRaw: ElasticSearchHit, + rowFlattened: Record, + field: DataViewField | undefined, + columnId: string, + dataView: DataView, + useTopLevelObjectColumns: boolean +) { + if (useTopLevelObjectColumns || field?.type === '_source') { + const json = useTopLevelObjectColumns + ? getInnerColumns(rowRaw.fields as Record, columnId) + : rowRaw; + return ( + } width={defaultMonacoEditorWidth} /> + ); + } + + return ( + + ); +} +/** + * Helper function to show top level objects + * this is used for legacy stuff like displaying products of our ecommerce dataset + */ +function getTopLevelObjectPairs( + row: ElasticSearchHit, + columnId: string, + dataView: DataView, + fieldsToShow: string[] +) { + const innerColumns = getInnerColumns(row.fields as Record, columnId); + // Put the most important fields first + const highlights: Record = (row.highlight as Record) ?? {}; + const highlightPairs: Array<[string, string]> = []; + const sourcePairs: Array<[string, string]> = []; + Object.entries(innerColumns).forEach(([key, values]) => { + const subField = dataView.getFieldByName(key); + const displayKey = dataView.fields.getByName + ? dataView.fields.getByName(key)?.displayName + : undefined; + const formatter = subField + ? dataView.getFormatterForField(subField) + : { convert: (v: unknown, ...rest: unknown[]) => String(v) }; + const formatted = (values as unknown[]) + .map((val: unknown) => + formatter.convert(val, 'html', { + field: subField, + hit: row, + indexPattern: dataView, + }) + ) + .join(', '); + const pairs = highlights[key] ? highlightPairs : sourcePairs; + if (displayKey) { + if (fieldsToShow.includes(displayKey)) { + pairs.push([displayKey, formatted]); + } + } else { + pairs.push([key, formatted]); + } + }); + return [...highlightPairs, ...sourcePairs]; +}